Some checks failed
CI Check / check (push) Has been cancelled
- 创建统一UI三层架构系统(基础层、颜色层、组合层) - 拆分Admin页面为独立Tab组件(MonitorTab、UsersTab、DepartmentsTab等) - 提取公共逻辑到Hooks(useToast、useDataFetch、useUserOperations等) - 提取工具函数(validators、formatters、api等) - 创建统一弹窗组件(Modal)和useModal Hook - 添加错误边界和统一状态组件 - 完善类型定义和可访问性支持 - 更新文档(优化记录、优化计划、更新日志)
111 lines
2.8 KiB
TypeScript
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
|
|
}
|
|
|