flnxi-Wu/lib/hooks/useThemeStyles.ts
WuYongJie e4dcb6260a
Some checks failed
CI Check / check (push) Has been cancelled
feat: Admin页面重构 & UI三层架构系统
- 创建统一UI三层架构系统(基础层、颜色层、组合层)
- 拆分Admin页面为独立Tab组件(MonitorTab、UsersTab、DepartmentsTab等)
- 提取公共逻辑到Hooks(useToast、useDataFetch、useUserOperations等)
- 提取工具函数(validators、formatters、api等)
- 创建统一弹窗组件(Modal)和useModal Hook
- 添加错误边界和统一状态组件
- 完善类型定义和可访问性支持
- 更新文档(优化记录、优化计划、更新日志)
2025-11-22 15:17:10 +08:00

111 lines
2.8 KiB
TypeScript

/**
* 主题感知的样式 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<ThemeStyles>(() => {
// 初始加载时根据当前主题返回对应样式
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
}