flnxi-Wu/lib/ui-styles.ts

185 lines
8.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 统一的 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',
}
}