1. 排行榜悬浮窗关闭后小按钮消失问题 - 修复面板居中模式关闭时按钮位置错误 - 保存并恢复按钮的居中状态 2. 首页tag按钮按素材数量排序 - 添加按素材数量降序排序逻辑 3. 上传弹窗输入框浅色模式文字不可见 - 添加 text-slate-900 确保浅色模式下文字可见 - 添加 placeholder 样式确保占位符正确显示
105 lines
4.4 KiB
TypeScript
105 lines
4.4 KiB
TypeScript
/**
|
||
* Tag 组件
|
||
*
|
||
* 统一的标签组件,遵循三层架构设计,采用苹果美学风格
|
||
* 用于显示分类、类型等标签信息
|
||
* 支持多种颜色(blue、green、orange、purple等)和尺寸(sm、md、lg)
|
||
* 支持点击事件,可用于筛选等功能
|
||
*
|
||
* 苹果美学特点:
|
||
* - 圆角更大(rounded-full)
|
||
* - 背景色更柔和(低饱和度)
|
||
* - 选中状态使用更明显的视觉反馈
|
||
* - 过渡动画更流畅
|
||
*
|
||
* @created 2025-11-22
|
||
* @updated 2025-01-22 - 重新设计为苹果美学风格
|
||
* @component
|
||
*/
|
||
|
||
'use client'
|
||
|
||
import { ReactNode } from 'react'
|
||
import { useThemeStyles, cn } from '@/lib/ui-styles'
|
||
|
||
interface TagProps {
|
||
children: ReactNode
|
||
color?: 'blue' | 'green' | 'orange' | 'purple' | 'indigo' | 'pink' | 'cyan'
|
||
size?: 'xs' | 'sm' | 'md' | 'lg'
|
||
className?: string
|
||
onClick?: () => void
|
||
selected?: boolean
|
||
}
|
||
|
||
export default function Tag({
|
||
children,
|
||
color = 'blue',
|
||
size = 'md',
|
||
className = '',
|
||
onClick,
|
||
selected = false,
|
||
}: TagProps) {
|
||
// 使用主题样式钩子(保留以便将来扩展)
|
||
useThemeStyles()
|
||
|
||
// 苹果美学风格的颜色配置(更柔和的背景,更清晰的文字)
|
||
// 修复:提高未选中状态的文字对比度,确保在素材数量为0时文字仍然可见
|
||
// 2025-12-13: 增强hover状态的文字颜色对比度,使用更深的文字颜色
|
||
const colorClasses = {
|
||
blue: selected
|
||
? 'bg-blue-500 dark:bg-blue-600 text-white border-blue-500 dark:border-blue-600'
|
||
: 'bg-blue-50 dark:bg-blue-900/50 text-blue-700 dark:text-blue-100 border-blue-200 dark:border-blue-700/70 hover:bg-blue-100 dark:hover:bg-blue-800/60 hover:text-blue-900 dark:hover:text-white',
|
||
green: selected
|
||
? 'bg-emerald-500 dark:bg-emerald-600 text-white border-emerald-500 dark:border-emerald-600'
|
||
: 'bg-emerald-50 dark:bg-emerald-900/50 text-emerald-700 dark:text-emerald-100 border-emerald-200 dark:border-emerald-700/70 hover:bg-emerald-100 dark:hover:bg-emerald-800/60 hover:text-emerald-900 dark:hover:text-white',
|
||
orange: selected
|
||
? 'bg-orange-500 dark:bg-orange-600 text-white border-orange-500 dark:border-orange-600'
|
||
: 'bg-orange-50 dark:bg-orange-900/50 text-orange-700 dark:text-orange-100 border-orange-200 dark:border-orange-700/70 hover:bg-orange-100 dark:hover:bg-orange-800/60 hover:text-orange-900 dark:hover:text-white',
|
||
purple: selected
|
||
? 'bg-purple-500 dark:bg-purple-600 text-white border-purple-500 dark:border-purple-600'
|
||
: 'bg-purple-50 dark:bg-purple-900/50 text-purple-700 dark:text-purple-100 border-purple-200 dark:border-purple-700/70 hover:bg-purple-100 dark:hover:bg-purple-800/60 hover:text-purple-900 dark:hover:text-white',
|
||
indigo: selected
|
||
? 'bg-indigo-500 dark:bg-indigo-600 text-white border-indigo-500 dark:border-indigo-600'
|
||
: 'bg-indigo-50 dark:bg-indigo-900/50 text-indigo-700 dark:text-indigo-100 border-indigo-200 dark:border-indigo-700/70 hover:bg-indigo-100 dark:hover:bg-indigo-800/60 hover:text-indigo-900 dark:hover:text-white',
|
||
pink: selected
|
||
? 'bg-pink-500 dark:bg-pink-600 text-white border-pink-500 dark:border-pink-600'
|
||
: 'bg-pink-50 dark:bg-pink-900/50 text-pink-700 dark:text-pink-100 border-pink-200 dark:border-pink-700/70 hover:bg-pink-100 dark:hover:bg-pink-800/60 hover:text-pink-900 dark:hover:text-white',
|
||
cyan: selected
|
||
? 'bg-cyan-500 dark:bg-cyan-600 text-white border-cyan-500 dark:border-cyan-600'
|
||
: 'bg-cyan-50 dark:bg-cyan-900/50 text-cyan-700 dark:text-cyan-100 border-cyan-200 dark:border-cyan-700/70 hover:bg-cyan-100 dark:hover:bg-cyan-800/60 hover:text-cyan-900 dark:hover:text-white',
|
||
}
|
||
|
||
const sizeClasses = {
|
||
xs: 'px-2.5 py-0.5 text-[11px] font-medium',
|
||
sm: 'px-3 py-1 text-xs font-medium',
|
||
md: 'px-4 py-1.5 text-sm font-medium',
|
||
lg: 'px-5 py-2 text-base font-medium',
|
||
} as const
|
||
|
||
// 苹果美学:圆角更大,过渡更流畅,选中状态有阴影
|
||
const baseClasses = cn(
|
||
'inline-flex items-center justify-center',
|
||
'rounded-full border',
|
||
'transition-all duration-200 ease-out',
|
||
'backdrop-blur-sm',
|
||
selected && 'shadow-md scale-105',
|
||
!selected && onClick && 'hover:scale-105 hover:shadow-sm',
|
||
onClick && 'cursor-pointer active:scale-95'
|
||
)
|
||
|
||
return (
|
||
<span
|
||
className={cn(
|
||
baseClasses,
|
||
colorClasses[color],
|
||
sizeClasses[size],
|
||
className
|
||
)}
|
||
onClick={onClick}
|
||
>
|
||
{children}
|
||
</span>
|
||
)
|
||
}
|
||
|