zeroclaw/web/src/contexts/themeStorage.ts
Argenis bcdbce0bee
feat(web): add theme system with CSS variables and settings modal (#4133)
- Add ThemeContext with light/dark/system theme support
- Migrate all hardcoded colors to CSS variables
- Add SettingsModal for theme customization
- Add font loader for dynamic font selection
- Add i18n support for Chinese and Turkish locales
- Fix accessibility: add aria-live to pairing error message

Co-authored-by: nanyuantingfeng <nanyuantingfeng@163.com>
2026-03-21 06:22:30 -04:00

45 lines
1.7 KiB
TypeScript

import type { ThemeName, AccentColor, UiFont, MonoFont } from './ThemeContextDef';
import { uiFontStacks, monoFontStacks } from './ThemeContextDef';
export const STORAGE_KEY = 'zeroclaw-theme';
export interface StoredTheme {
theme: ThemeName;
accent: AccentColor;
uiFont: UiFont;
monoFont: MonoFont;
uiFontSize: number;
monoFontSize: number;
}
const DEFAULTS: StoredTheme = {
theme: 'dark',
accent: 'cyan',
uiFont: 'system',
monoFont: 'jetbrains',
uiFontSize: 15,
monoFontSize: 14,
};
const validThemes: ThemeName[] = ['dark', 'light', 'oled', 'system'];
const validAccents: AccentColor[] = ['cyan', 'violet', 'emerald', 'amber', 'rose', 'blue'];
export function loadStored(): StoredTheme {
try {
const raw = localStorage.getItem(STORAGE_KEY);
if (raw) {
const parsed = JSON.parse(raw);
const themeValid = validThemes.includes(parsed.theme);
const accentValid = validAccents.includes(parsed.accent);
const uiFont: UiFont = uiFontStacks[parsed.uiFont as UiFont] ? parsed.uiFont as UiFont : DEFAULTS.uiFont;
const monoFont: MonoFont = monoFontStacks[parsed.monoFont as MonoFont] ? parsed.monoFont as MonoFont : DEFAULTS.monoFont;
const uiFontSize = Number.isFinite(parsed.uiFontSize) ? Math.min(20, Math.max(12, Number(parsed.uiFontSize))) : DEFAULTS.uiFontSize;
const monoFontSize = Number.isFinite(parsed.monoFontSize) ? Math.min(20, Math.max(12, Number(parsed.monoFontSize))) : DEFAULTS.monoFontSize;
if (themeValid && accentValid) {
return { theme: parsed.theme, accent: parsed.accent, uiFont, monoFont, uiFontSize, monoFontSize };
}
}
} catch { /* ignore */ }
return DEFAULTS;
}