import { useState, useEffect, useCallback, type ReactNode } from 'react'; import { DEFAULT_THEME_MODE, THEME_STORAGE_KEY, ThemeContext, type ThemeMode, } from './themeContext'; export type { ThemeMode } from './themeContext'; export function ThemeProvider({ children }: { children: ReactNode }) { const [mode, setModeState] = useState(() => { const saved = localStorage.getItem(THEME_STORAGE_KEY); return (saved as ThemeMode) || DEFAULT_THEME_MODE; }); // 监听系统主题变化 const [systemIsDark, setSystemIsDark] = useState(() => window.matchMedia('(prefers-color-scheme: dark)').matches ); useEffect(() => { const mql = window.matchMedia('(prefers-color-scheme: dark)'); const handler = (e: MediaQueryListEvent) => setSystemIsDark(e.matches); mql.addEventListener('change', handler); return () => mql.removeEventListener('change', handler); }, []); const isDark = mode === 'dark' || (mode === 'system' && systemIsDark); const setMode = useCallback((newMode: ThemeMode) => { setModeState(newMode); localStorage.setItem(THEME_STORAGE_KEY, newMode); }, []); const toggle = useCallback(() => { setMode(isDark ? 'light' : 'dark'); }, [isDark, setMode]); // 同步到 HTML root,方便 CSS 使用 useEffect(() => { document.documentElement.setAttribute('data-theme', isDark ? 'dark' : 'light'); }, [isDark]); return ( {children} ); }