Files
clinicpro/assets/admin/stores/uiStore.test.ts
T
hamedandClaude Opus 4.8 62e0cdb518 feat(admin): add orange rgb(241,119,50) as an exact brand-color option
Revert the earlier mis-scoped orange on the personalization panel and
instead expose rgb(241,119,50) as a selectable 'رنگ اصلی' swatch. When
picked it overrides --primary/-600/-700/-soft/-soft2/-ring inline with
exact hex, so every var(--primary) consumer across the whole admin
(buttons, active nav, rings) becomes that orange. Non-fixed hues keep
the oklch hue pipeline (inline overrides removed on switch).

- uiStore: BrandHue interface + optional fixed hex; shared applyBrand()
  helper handles fixed vs hue, dark-aware soft tints
- AdminLayout: reuse applyBrand() (no divergence with store)
- Topbar: swatch shows the exact fixed color
- tests: fixed-color apply, dark soft, and override-cleanup on switch

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 17:06:24 +03:30

98 lines
4.4 KiB
TypeScript

import { describe, it, expect, beforeEach } from 'vitest';
import { useUiStore, HUES } from '@/stores/uiStore';
const initial = useUiStore.getInitialState();
beforeEach(() => {
localStorage.clear();
useUiStore.setState(initial, true);
document.documentElement.className = '';
document.documentElement.removeAttribute('data-theme');
document.documentElement.removeAttribute('data-density');
});
describe('sidebar', () => {
it('toggleSidebar وضعیت را برعکس می‌کند', () => {
expect(useUiStore.getState().sidebarOpen).toBe(true);
useUiStore.getState().toggleSidebar();
expect(useUiStore.getState().sidebarOpen).toBe(false);
});
it('setSidebarOpen مقدار صریح می‌گذارد', () => {
useUiStore.getState().setSidebarOpen(false);
expect(useUiStore.getState().sidebarOpen).toBe(false);
});
});
describe('darkMode + applyTheme', () => {
it('toggleDarkMode کلاس dark و data-theme را روی root می‌گذارد', () => {
useUiStore.getState().toggleDarkMode();
expect(useUiStore.getState().darkMode).toBe(true);
expect(document.documentElement.classList.contains('dark')).toBe(true);
expect(document.documentElement.getAttribute('data-theme')).toBe('dark');
});
it('toggle دوباره به light برمی‌گرداند', () => {
useUiStore.getState().toggleDarkMode();
useUiStore.getState().toggleDarkMode();
expect(useUiStore.getState().darkMode).toBe(false);
expect(document.documentElement.classList.contains('dark')).toBe(false);
expect(document.documentElement.getAttribute('data-theme')).toBe('light');
});
});
describe('density', () => {
it('setDensity مقدار و data-density را تنظیم می‌کند', () => {
useUiStore.getState().setDensity('compact');
expect(useUiStore.getState().density).toBe('compact');
expect(document.documentElement.getAttribute('data-density')).toBe('compact');
});
});
describe('brandHue', () => {
it('setBrandHue متغیرهای CSS را روی root می‌نویسد', () => {
const hue = HUES[2];
useUiStore.getState().setBrandHue(hue);
expect(useUiStore.getState().brandHue).toEqual(hue);
expect(document.documentElement.style.getPropertyValue('--brand-h')).toBe(String(hue.h));
expect(document.documentElement.style.getPropertyValue('--brand-c')).toBe(String(hue.c));
});
it('گزینه نارنجی با رنگ ثابت rgb(241,119,50) وجود دارد', () => {
const orange = HUES.find((h) => h.name === 'نارنجی');
expect(orange?.fixed?.primary).toBe('rgb(241, 119, 50)');
});
it('انتخاب نارنجی، --primary را دقیقاً rgb(241,119,50) و soft روشن را inline می‌کند', () => {
const orange = HUES.find((h) => h.fixed)!;
useUiStore.getState().setBrandHue(orange);
const s = document.documentElement.style;
expect(s.getPropertyValue('--primary')).toBe('rgb(241, 119, 50)');
expect(s.getPropertyValue('--primary-soft')).toBe(orange.fixed!.soft);
expect(s.getPropertyValue('--ring')).toBe(orange.fixed!.ring);
});
it('در حالت تیره، soft تیره اعمال می‌شود', () => {
const orange = HUES.find((h) => h.fixed)!;
useUiStore.getState().toggleDarkMode(); // dark
useUiStore.getState().setBrandHue(orange);
expect(document.documentElement.style.getPropertyValue('--primary-soft'))
.toBe(orange.fixed!.softDark);
});
it('برگشت به hue بدون رنگ ثابت، override اینلاین --primary را پاک می‌کند', () => {
const orange = HUES.find((h) => h.fixed)!;
useUiStore.getState().setBrandHue(orange);
expect(document.documentElement.style.getPropertyValue('--primary')).not.toBe('');
useUiStore.getState().setBrandHue(HUES[0]); // بنفش، بدون fixed
expect(document.documentElement.style.getPropertyValue('--primary')).toBe('');
expect(document.documentElement.style.getPropertyValue('--primary-soft')).toBe('');
});
});
describe('settingsPanel', () => {
it('toggleSettingsPanel وضعیت را برعکس می‌کند', () => {
expect(useUiStore.getState().settingsPanelOpen).toBe(false);
useUiStore.getState().toggleSettingsPanel();
expect(useUiStore.getState().settingsPanelOpen).toBe(true);
});
});