"use client"; import React from "react"; import { cva, type VariantProps } from "class-variance-authority"; import { cn } from "@/utils/cn"; /** * Badge 徽章组件 * * Design System 中的徽章组件,用于显示状态、标签等信息。 * * @example * ```tsx * // 默认徽章 * * * // 不同变体 * 成功 * 警告 * 错误 * * // 不同尺寸 * * * * // 圆形徽章 * * ``` */ /** * Badge 变体样式 */ const badgeVariants = cva( // 基础样式 "inline-flex items-center justify-center rounded-full font-medium transition-colors duration-250", { variants: { variant: { default: "bg-gray-100 text-gray-800", primary: "bg-primary-100 text-primary-800", success: "bg-success-100 text-success-800", warning: "bg-warning-100 text-warning-800", error: "bg-error-100 text-error-800", info: "bg-info-100 text-info-800", }, size: { sm: "px-2 py-0.5 text-xs", md: "px-2.5 py-1 text-sm", lg: "px-3 py-1.5 text-base", }, dot: { true: "px-2 py-1", false: "", }, }, defaultVariants: { variant: "default", size: "md", dot: false, }, } ); export type BadgeVariant = VariantProps["variant"]; export type BadgeSize = VariantProps["size"]; export interface BadgeProps extends React.HTMLAttributes, VariantProps { // 子元素 children?: React.ReactNode; // 是否为圆点样式(不显示文字) dot?: boolean; // 圆点颜色(仅当 dot=true 时有效) dotColor?: string; } /** * Badge 徽章组件 */ export function Badge({ variant = "default", size = "md", dot = false, dotColor, className, children, ...props }: BadgeProps) { // 圆点颜色映射 const dotColors = { default: "bg-gray-400", primary: "bg-primary-500", success: "bg-success-500", warning: "bg-warning-500", error: "bg-error-500", info: "bg-info-500", }; // 确保 variant 有默认值 const actualVariant = variant ?? "default"; return (
{dot && ( )} {!dot && children}
); } /** * StatusBadge - 状态徽章 */ export interface StatusBadgeProps extends Omit { status: "online" | "offline" | "busy" | "away"; label?: string; } export function StatusBadge({ status, label, ...props }: StatusBadgeProps) { const statusConfig = { online: { variant: "success" as const, defaultLabel: "在线" }, offline: { variant: "default" as const, defaultLabel: "离线" }, busy: { variant: "error" as const, defaultLabel: "忙碌" }, away: { variant: "warning" as const, defaultLabel: "离开" }, }; const config = statusConfig[status]; return ( {label || config.defaultLabel} ); } /** * CounterBadge - 计数徽章 */ export interface CounterBadgeProps extends Omit { count: number; max?: number; } export function CounterBadge({ count, max = 99, ...props }: CounterBadgeProps) { const displayCount = count > max ? `${max}+` : count; return ( {displayCount} ); }