/** * Tag 组件 * * 统一的标签组件,适合后台筛选与分类展示 * 用于显示分类、类型等标签信息 * 支持少量语义色和尺寸(xs、sm、md、lg) * 支持点击事件,可用于筛选等功能 * * @created 2025-11-22 * @updated 2026-05-25 - 收敛为后台工作台风格 * @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() const colorClasses: Record, string> = { blue: selected ? 'bg-slate-900 dark:bg-slate-100 text-white dark:text-slate-950 border-slate-900 dark:border-slate-100' : 'bg-white dark:bg-slate-900 text-slate-700 dark:text-slate-200 border-slate-300 dark:border-slate-700 hover:bg-slate-50 dark:hover:bg-slate-800', green: selected ? 'bg-emerald-700 dark:bg-emerald-500 text-white border-emerald-700 dark:border-emerald-500' : 'bg-emerald-50 dark:bg-emerald-950/30 text-emerald-800 dark:text-emerald-200 border-emerald-200 dark:border-emerald-800 hover:bg-emerald-100 dark:hover:bg-emerald-950/50', orange: selected ? 'bg-amber-700 dark:bg-amber-500 text-white dark:text-slate-950 border-amber-700 dark:border-amber-500' : 'bg-amber-50 dark:bg-amber-950/30 text-amber-800 dark:text-amber-200 border-amber-200 dark:border-amber-800 hover:bg-amber-100 dark:hover:bg-amber-950/50', purple: selected ? 'bg-slate-700 dark:bg-slate-200 text-white dark:text-slate-950 border-slate-700 dark:border-slate-200' : 'bg-slate-50 dark:bg-slate-900 text-slate-700 dark:text-slate-200 border-slate-300 dark:border-slate-700 hover:bg-slate-100 dark:hover:bg-slate-800', indigo: selected ? 'bg-slate-700 dark:bg-slate-200 text-white dark:text-slate-950 border-slate-700 dark:border-slate-200' : 'bg-slate-50 dark:bg-slate-900 text-slate-700 dark:text-slate-200 border-slate-300 dark:border-slate-700 hover:bg-slate-100 dark:hover:bg-slate-800', pink: selected ? 'bg-slate-700 dark:bg-slate-200 text-white dark:text-slate-950 border-slate-700 dark:border-slate-200' : 'bg-slate-50 dark:bg-slate-900 text-slate-700 dark:text-slate-200 border-slate-300 dark:border-slate-700 hover:bg-slate-100 dark:hover:bg-slate-800', cyan: selected ? 'bg-slate-700 dark:bg-slate-200 text-white dark:text-slate-950 border-slate-700 dark:border-slate-200' : 'bg-slate-50 dark:bg-slate-900 text-slate-700 dark:text-slate-200 border-slate-300 dark:border-slate-700 hover:bg-slate-100 dark:hover:bg-slate-800', } 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-md border', 'transition-colors duration-200 ease-out', onClick && 'cursor-pointer' ) return ( {children} ) }