/** * 主题感知的样式 Hook * 根据当前主题返回对应的样式配置 */ 'use client' 'use client' import { useEffect, useState } from 'react' import * as lightStyles from '../ui-styles-light' import * as darkStyles from '../ui-styles-dark' // 统一类型定义(两种主题的样式结构相同) type ThemeStyles = typeof lightStyles /** * 检测当前主题 */ function getCurrentTheme(): 'light' | 'dark' { if (typeof document === 'undefined') return 'light' return document.documentElement.classList.contains('dark') ? 'dark' : 'light' } /** * 使用主题样式 Hook * 返回当前主题对应的样式配置,并在主题切换时自动更新 */ export function useThemeStyles(): ThemeStyles { const [theme, setTheme] = useState<'light' | 'dark'>(() => getCurrentTheme()) const [styles, setStyles] = useState(() => { // 初始加载时根据当前主题返回对应样式 if (typeof window !== 'undefined' && getCurrentTheme() === 'dark') { return darkStyles as ThemeStyles } return lightStyles as ThemeStyles }) useEffect(() => { const updateTheme = () => { const newTheme = getCurrentTheme() setTheme(newTheme) // 根据主题返回对应样式(静态导入,类型兼容) setStyles(newTheme === 'dark' ? (darkStyles as ThemeStyles) : (lightStyles as ThemeStyles)) } // 初始设置 updateTheme() // 监听 DOM 变化(主题切换时 class 会变化) const observer = new MutationObserver(updateTheme) const root = document.documentElement observer.observe(root, { attributes: true, attributeFilter: ['class'], }) // 监听 storage 变化(如果其他标签页切换了主题) const handleStorageChange = (e: StorageEvent) => { if (e.key === 'admin-theme-preference') { updateTheme() } } window.addEventListener('storage', handleStorageChange) return () => { observer.disconnect() window.removeEventListener('storage', handleStorageChange) } }, []) return styles } /** * 获取当前主题 */ export function useTheme(): 'light' | 'dark' { const [theme, setTheme] = useState<'light' | 'dark'>(() => getCurrentTheme()) useEffect(() => { const updateTheme = () => { setTheme(getCurrentTheme()) } updateTheme() const observer = new MutationObserver(updateTheme) const root = document.documentElement observer.observe(root, { attributes: true, attributeFilter: ['class'], }) const handleStorageChange = (e: StorageEvent) => { if (e.key === 'admin-theme-preference') { updateTheme() } } window.addEventListener('storage', handleStorageChange) return () => { observer.disconnect() window.removeEventListener('storage', handleStorageChange) } }, []) return theme }