Implement M1.5 visual design foundation: tokens, IBM Plex, theme toggle, chart themes

This commit is contained in:
2026-06-05 01:29:10 +03:00
parent 547edb85e4
commit 22f0556ef8
31 changed files with 713 additions and 136 deletions
+20
View File
@@ -0,0 +1,20 @@
import { beforeEach, describe, expect, test } from 'vitest';
import { useAppStore } from './AppStore';
const store = () => useAppStore.getState();
beforeEach(() => store().setTheme('light'));
describe('theme', () => {
test('setTheme sets the theme explicitly', () => {
store().setTheme('dark');
expect(store().uiTheme).toBe('dark');
});
test('toggleTheme flips light ⇄ dark', () => {
expect(store().uiTheme).toBe('light');
store().toggleTheme();
expect(store().uiTheme).toBe('dark');
store().toggleTheme();
expect(store().uiTheme).toBe('light');
});
});
+3
View File
@@ -23,6 +23,8 @@ export interface AppState {
activeModal: ModalName | null;
setTheme: (theme: UiTheme) => void;
/** Flip between light and dark — the header ThemeToggle's action. */
toggleTheme: () => void;
/**
* Low-level modal setter — the single primitive that mutates `activeModal`.
* High-level open/close (snapshot for unsaved-change detection, URL sync,
@@ -37,5 +39,6 @@ export const useAppStore = create<AppState>((set) => ({
activeModal: null,
setTheme: (uiTheme) => set({ uiTheme }),
toggleTheme: () => set((s) => ({ uiTheme: s.uiTheme === 'dark' ? 'light' : 'dark' })),
setActiveModal: (activeModal) => set({ activeModal }),
}));