feat(web): 多主题系统 — 4 套主题 + CSS 变量 + Ant Design 动态主题
- CSS 变量层: :root 默认 blue, [data-theme] 覆盖 warm/dark/emerald - Ant Design: ConfigProvider 按 ThemeName 切换 token + algorithm - ThemeSwitcher: 下拉面板含 4 主题色块预览 + localStorage 持久化 - useThemeMode: 从 store 读取主题名替代色值比对(修复 33 页面暗色失效) - index.html: 添加 Noto Serif SC 字体(warm 主题衬线标题)
This commit is contained in:
@@ -1,15 +1,64 @@
|
||||
import { create } from 'zustand';
|
||||
|
||||
export type ThemeName = 'blue' | 'warm' | 'dark' | 'emerald';
|
||||
|
||||
export interface ThemeOption {
|
||||
key: ThemeName;
|
||||
label: string;
|
||||
desc: string;
|
||||
preview: { primary: string; bg: string; surface: string };
|
||||
}
|
||||
|
||||
export const THEME_OPTIONS: ThemeOption[] = [
|
||||
{
|
||||
key: 'blue',
|
||||
label: '信任蓝',
|
||||
desc: '专业沉稳 · 企业风格',
|
||||
preview: { primary: '#2563EB', bg: '#F8FAFC', surface: '#FFFFFF' },
|
||||
},
|
||||
{
|
||||
key: 'warm',
|
||||
label: '温润东方',
|
||||
desc: '暖色人文 · 医疗关怀',
|
||||
preview: { primary: '#C4623A', bg: '#F5F0EB', surface: '#FFFFFF' },
|
||||
},
|
||||
{
|
||||
key: 'dark',
|
||||
label: '深邃夜色',
|
||||
desc: '暗色护眼 · 深度专注',
|
||||
preview: { primary: '#60A5FA', bg: '#0F172A', surface: '#1E293B' },
|
||||
},
|
||||
{
|
||||
key: 'emerald',
|
||||
label: '翡翠清雅',
|
||||
desc: '清新自然 · 健康生机',
|
||||
preview: { primary: '#5B7A5E', bg: '#F4F7F4', surface: '#FFFFFF' },
|
||||
},
|
||||
];
|
||||
|
||||
const STORAGE_KEY = 'hms-theme';
|
||||
|
||||
function loadTheme(): ThemeName {
|
||||
try {
|
||||
const saved = localStorage.getItem(STORAGE_KEY);
|
||||
if (saved && THEME_OPTIONS.some((t) => t.key === saved)) return saved as ThemeName;
|
||||
} catch {}
|
||||
return 'blue';
|
||||
}
|
||||
|
||||
interface AppState {
|
||||
theme: 'light' | 'dark';
|
||||
theme: ThemeName;
|
||||
sidebarCollapsed: boolean;
|
||||
toggleSidebar: () => void;
|
||||
setTheme: (theme: 'light' | 'dark') => void;
|
||||
setTheme: (theme: ThemeName) => void;
|
||||
}
|
||||
|
||||
export const useAppStore = create<AppState>((set) => ({
|
||||
theme: 'light',
|
||||
theme: loadTheme(),
|
||||
sidebarCollapsed: false,
|
||||
toggleSidebar: () => set((s) => ({ sidebarCollapsed: !s.sidebarCollapsed })),
|
||||
setTheme: (theme) => set({ theme }),
|
||||
setTheme: (theme) => {
|
||||
try { localStorage.setItem(STORAGE_KEY, theme); } catch {}
|
||||
set({ theme });
|
||||
},
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user