185 lines
8.9 KiB
TypeScript
185 lines
8.9 KiB
TypeScript
/**
|
||
* 统一的 UI 样式工具类
|
||
* 以私有化工作台为默认风格,保留浅色/深色两套配置
|
||
*
|
||
* 推荐使用方式:
|
||
* 1. 在新组件中使用 `useThemeStyles()` Hook(推荐)
|
||
* 2. 在服务端组件或需要向后兼容的地方,继续使用此文件的导出
|
||
*/
|
||
|
||
// 导出主题 Hook(推荐使用)
|
||
export { useThemeStyles, useTheme } from './hooks/useThemeStyles'
|
||
|
||
// 导出两套独立的样式配置
|
||
export { lightStyles, darkStyles } from './ui-styles-theme-exports'
|
||
|
||
// 为了向后兼容,保留原有导出(包含 dark: 前缀)
|
||
// ⚠️ 这些样式会在深色模式下正确工作,但代码较长
|
||
// 建议逐步迁移到 useThemeStyles Hook
|
||
export const cardStyles = {
|
||
// 基础卡片
|
||
base: 'rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 p-5 transition-colors duration-200',
|
||
|
||
// 悬停卡片
|
||
hover: 'rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 hover:border-slate-300 dark:hover:border-slate-600 transition-colors duration-200 p-5',
|
||
|
||
// 大卡片
|
||
large: 'rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 transition-colors duration-200 p-6',
|
||
|
||
// 扁平卡片
|
||
flat: 'rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 p-5 transition-colors duration-200',
|
||
|
||
// 保留兼容字段,但降级为普通卡片
|
||
rainbow: 'rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 p-5 transition-colors duration-200',
|
||
|
||
// 保留兼容字段,但降级为普通卡片
|
||
glass: 'rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 p-5 transition-colors duration-200',
|
||
|
||
// 保留兼容字段,但降级为普通卡片
|
||
neon: 'rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 p-5 transition-colors duration-200',
|
||
} as const
|
||
|
||
export const buttonStyles = {
|
||
// 主要按钮
|
||
primary: 'px-4 py-2 rounded-lg bg-slate-900 dark:bg-slate-100 text-white dark:text-slate-900 font-medium hover:bg-slate-800 dark:hover:bg-white transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed',
|
||
|
||
// 次要按钮
|
||
secondary: 'px-4 py-2 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-800 text-slate-700 dark:text-slate-200 font-medium hover:bg-slate-50 dark:hover:bg-slate-700 transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed',
|
||
|
||
// 幽灵按钮
|
||
ghost: 'px-4 py-2 rounded-lg text-slate-700 dark:text-slate-200 font-medium hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed',
|
||
|
||
// 危险按钮
|
||
danger: 'px-4 py-2 rounded-lg bg-red-600 dark:bg-red-500 text-white font-medium hover:bg-red-700 dark:hover:bg-red-600 transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed',
|
||
|
||
// 成功按钮
|
||
success: 'px-4 py-2 rounded-lg bg-emerald-600 dark:bg-emerald-500 text-white font-medium hover:bg-emerald-700 dark:hover:bg-emerald-600 transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed',
|
||
|
||
// 保留兼容字段,但降级为普通按钮
|
||
rainbow: 'px-4 py-2 rounded-lg bg-slate-900 dark:bg-slate-100 text-white dark:text-slate-900 font-medium hover:bg-slate-800 dark:hover:bg-white transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed',
|
||
|
||
// 保留兼容字段,但降级为普通按钮
|
||
neon: 'px-4 py-2 rounded-lg bg-slate-900 dark:bg-slate-100 text-white dark:text-slate-900 font-medium hover:bg-slate-800 dark:hover:bg-white transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed',
|
||
|
||
// 保留兼容字段,但降级为普通按钮
|
||
glass: 'px-4 py-2 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-800 text-slate-700 dark:text-slate-200 font-medium hover:bg-slate-50 dark:hover:bg-slate-700 transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed',
|
||
} as const
|
||
|
||
export const buttonModifiers = {
|
||
compact: 'px-3 py-1.5 text-sm',
|
||
compactXs: 'px-2 py-1 text-xs',
|
||
icon: 'p-2 rounded-lg',
|
||
block: 'w-full justify-center',
|
||
pill: 'rounded-full',
|
||
} as const
|
||
|
||
export const inputStyles = {
|
||
// 基础输入框 - 确保深色模式完全适配
|
||
base: 'w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-800 text-slate-900 dark:text-white placeholder:text-slate-400 dark:placeholder:text-slate-400 focus:border-slate-900 dark:focus:border-slate-500 focus:ring-2 focus:ring-slate-200 dark:focus:ring-slate-700 outline-none transition-colors',
|
||
// 错误输入框 - 确保深色模式完全适配
|
||
error: 'w-full px-3 py-2 rounded-lg border-2 border-red-500 dark:border-red-600 bg-white dark:bg-slate-800 text-slate-900 dark:text-white placeholder:text-slate-400 dark:placeholder:text-slate-400 focus:ring-2 focus:ring-red-200 dark:focus:ring-red-800 outline-none transition-colors',
|
||
} as const
|
||
|
||
export const inputModifiers = {
|
||
compact: 'px-3 py-2 text-sm rounded-lg',
|
||
compactXs: 'px-2.5 py-1.5 text-xs rounded-lg',
|
||
} as const
|
||
|
||
export const navItemStyles = {
|
||
// 基础导航项
|
||
base: 'px-3 py-2 rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 text-slate-700 dark:text-slate-200 transition-colors duration-200',
|
||
|
||
// 悬停导航项
|
||
hover: 'px-3 py-2 rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 hover:border-slate-300 dark:hover:border-slate-600 hover:bg-slate-50 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-200 transition-colors duration-200',
|
||
|
||
// 激活导航项
|
||
active: 'px-3 py-2 rounded-lg border border-slate-900 dark:border-slate-100 bg-slate-100 dark:bg-slate-700 text-slate-900 dark:text-white transition-colors duration-200',
|
||
|
||
// 保留兼容字段,但降级为普通导航项
|
||
rainbow: 'px-3 py-2 rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 text-slate-700 dark:text-slate-200 transition-colors duration-200',
|
||
|
||
// 标签页导航项 - 确保深色模式完全适配
|
||
tabBase: 'relative pb-4 px-5 font-medium transition-colors duration-200 text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white',
|
||
tabActive: 'relative pb-4 px-5 font-medium transition-colors duration-200 text-slate-900 dark:text-white',
|
||
} as const
|
||
|
||
export const badgeStyles = {
|
||
base: 'px-3 py-1 rounded-lg text-xs font-medium',
|
||
primary: 'px-3 py-1 rounded-lg bg-slate-100 dark:bg-slate-800 text-slate-700 dark:text-slate-300 text-xs font-medium',
|
||
success: 'px-3 py-1 rounded-lg bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-300 text-xs font-medium',
|
||
warning: 'px-3 py-1 rounded-lg bg-yellow-100 dark:bg-yellow-900/30 text-yellow-700 dark:text-yellow-300 text-xs font-medium',
|
||
danger: 'px-3 py-1 rounded-lg bg-red-100 dark:bg-red-900/30 text-red-700 dark:text-red-300 text-xs font-medium',
|
||
} as const
|
||
|
||
export const spacingStyles = {
|
||
section: 'space-y-8', // 区块间距
|
||
card: 'space-y-6', // 卡片内间距
|
||
form: 'space-y-4', // 表单元素间距
|
||
compact: 'space-y-2', // 紧密间距
|
||
} as const
|
||
|
||
/**
|
||
* 组合多个样式类
|
||
*/
|
||
export function cn(...classes: (string | undefined | false | null)[]): string {
|
||
return classes.filter(Boolean).join(' ')
|
||
}
|
||
|
||
/**
|
||
* 运行时根据主题获取样式配置
|
||
* ⚠️ 不推荐使用,建议在组件中使用 useThemeStyles Hook
|
||
*
|
||
* @param theme - 主题 'light' | 'dark'
|
||
* @returns 对应主题的样式配置
|
||
*/
|
||
export function getThemeStyles(theme: 'light' | 'dark') {
|
||
// 动态导入以避免类型冲突
|
||
if (theme === 'dark') {
|
||
return require('./ui-styles-dark')
|
||
}
|
||
return require('./ui-styles-light')
|
||
}
|
||
|
||
/**
|
||
* Section 显示动画类生成器(来自外观设置)
|
||
* @param isVisible - 是否可见
|
||
* @returns 组合后的样式类
|
||
*/
|
||
export function sectionRevealClass(isVisible: boolean): string {
|
||
return cn(
|
||
'transition-opacity duration-300 ease-out',
|
||
isVisible ? 'opacity-100' : 'opacity-0'
|
||
)
|
||
}
|
||
|
||
/**
|
||
* 浮动光球样式类生成器(来自外观设置)
|
||
* @param theme - 主题 'light' | 'dark'
|
||
* @param position - 位置 'topRight' | 'bottomLeft'
|
||
* @returns 样式类字符串
|
||
*/
|
||
export function floatingOrbClass(_theme: 'light' | 'dark', _position: 'topRight' | 'bottomLeft'): string {
|
||
return 'hidden'
|
||
}
|
||
|
||
/**
|
||
* Hero 动态背景样式生成器(来自外观设置)
|
||
* @param isMouseOver - 鼠标是否悬停
|
||
* @param glowPos - 光晕位置 { x: number, y: number }
|
||
* @param theme - 主题 'light' | 'dark'
|
||
* @param baseGradient - 基础渐变背景
|
||
* @returns 背景样式对象
|
||
*/
|
||
export function getHeroDynamicBackground(
|
||
_isMouseOver: boolean,
|
||
_glowPos: { x: number; y: number },
|
||
_theme: 'light' | 'dark',
|
||
baseGradient: string
|
||
): { backgroundImage: string; transition: string } {
|
||
return {
|
||
backgroundImage: baseGradient,
|
||
transition: 'background-color 0.2s ease-out',
|
||
}
|
||
}
|
||
|