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 - 添加错误边界和统一状态组件 - 完善类型定义和可访问性支持 - 更新文档(优化记录、优化计划、更新日志)
5.0 KiB
5.0 KiB
深浅色样式分离迁移指南
概述
为了解决深浅色适配问题,我们重构了 UI 样式系统,采用两套独立的配置文件:
- 浅色模式:
lib/ui-styles-light.ts - 深色模式:
lib/ui-styles-dark.ts
优势
之前的问题
- 每个样式字符串都包含
dark:前缀,代码冗长 - 容易遗漏
dark:前缀,导致深色模式显示不正确 - 维护困难,需要在同一字符串中同时考虑两种模式
现在的优势
- ✅ 代码更清晰:每个样式只包含一套类名
- ✅ 更容易维护:修改时只需要考虑一种模式
- ✅ 避免遗漏:不会忘记添加
dark:前缀 - ✅ 类型安全:TypeScript 能更好地检查样式使用
使用方式
方式一:使用 useThemeStyles() Hook(推荐)
适用于客户端组件('use client'):
'use client'
import { useThemeStyles } from '@/lib/ui-styles'
export default function MyComponent() {
// 自动根据当前主题返回对应的样式配置
const styles = useThemeStyles()
return (
<div className={styles.cardStyles.base}>
<button className={styles.buttonStyles.primary}>
主要按钮
</button>
<button className={`${styles.buttonStyles.secondary} ${styles.buttonModifiers.compact}`}>
次要按钮
</button>
</div>
)
}
方式二:继续使用原有导入(向后兼容)
原有的 lib/ui-styles.ts 仍然保留,包含 dark: 前缀的样式:
import { cardStyles, buttonStyles, buttonModifiers } from '@/lib/ui-styles'
export default function MyComponent() {
return (
<div className={cardStyles.base}>
<button className={buttonStyles.primary}>
主要按钮
</button>
</div>
)
}
注意:这种方式仍然可以工作,但建议逐步迁移到 useThemeStyles()。
迁移步骤
1. 将组件改为客户端组件
如果组件是服务端组件,需要添加 'use client':
'use client' // 添加这一行
import { useThemeStyles } from '@/lib/ui-styles'
2. 替换样式导入
之前:
import { cardStyles, buttonStyles } from '@/lib/ui-styles'
export default function MyComponent() {
return (
<div className={cardStyles.base}>
<button className={buttonStyles.primary}>按钮</button>
</div>
)
}
之后:
'use client'
import { useThemeStyles } from '@/lib/ui-styles'
export default function MyComponent() {
const styles = useThemeStyles()
return (
<div className={styles.cardStyles.base}>
<button className={styles.buttonStyles.primary}>按钮</button>
</div>
)
}
3. 批量替换模式
如果有多个组件需要迁移,可以使用搜索替换:
查找:
import { cardStyles, buttonStyles, inputStyles, buttonModifiers } from '@/lib/ui-styles'
替换为:
'use client'
import { useThemeStyles } from '@/lib/ui-styles'
// 在组件内部:
const styles = useThemeStyles()
// 然后使用 styles.cardStyles、styles.buttonStyles 等
可用样式
两套配置的结构完全相同,包含:
-
cardStyles- 卡片样式base,hover,large,flat,rainbow,glass,neon
-
buttonStyles- 按钮样式primary,secondary,ghost,danger,success,rainbow,neon,glass
-
buttonModifiers- 按钮修饰符compact,compactXs,icon,block,pill
-
inputStyles- 输入框样式base,error
-
inputModifiers- 输入框修饰符compact,compactXs
-
navItemStyles- 导航项样式base,hover,active,rainbow,tabBase,tabActive
-
badgeStyles- 徽章样式base,primary,success,warning,danger
-
spacingStyles- 间距样式section,card,form,compact
示例
完整的组件示例
'use client'
import { useThemeStyles } from '@/lib/ui-styles'
import { cn } from '@/lib/ui-styles'
export default function UserCard({ user }: { user: User }) {
const styles = useThemeStyles()
return (
<div className={styles.cardStyles.hover}>
<h3 className="text-lg font-semibold">{user.name}</h3>
<p className="text-sm opacity-75">{user.email}</p>
<div className="mt-4 flex gap-2">
<button className={styles.buttonStyles.primary}>
编辑
</button>
<button className={cn(styles.buttonStyles.secondary, styles.buttonModifiers.compact)}>
删除
</button>
</div>
</div>
)
}
注意事项
- 客户端组件:使用
useThemeStyles()的组件必须是客户端组件(添加'use client') - 主题切换:Hook 会自动监听主题变化,组件会自动更新样式
- 性能:样式配置是静态导入的,不会影响打包大小
- 向后兼容:原有代码仍然可以工作,可以逐步迁移
下一步
- 迁移现有组件到新的样式系统
- 移除
lib/ui-styles.ts中的dark:前缀(迁移完成后) - 统一使用
useThemeStyles()Hook