WuYongJie 63ec6b7dfb fix: 修复排行榜按钮消失、tag排序和输入框浅色模式问题
1. 排行榜悬浮窗关闭后小按钮消失问题
   - 修复面板居中模式关闭时按钮位置错误
   - 保存并恢复按钮的居中状态

2. 首页tag按钮按素材数量排序
   - 添加按素材数量降序排序逻辑

3. 上传弹窗输入框浅色模式文字不可见
   - 添加 text-slate-900 确保浅色模式下文字可见
   - 添加 placeholder 样式确保占位符正确显示
2025-12-14 21:41:29 +08:00

105 lines
4.4 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.

/**
* 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>
)
}