wui
组件

徽章 Badge

用于展示状态、分类标签或简短元数据的紧凑视觉标记组件。

第三方依赖 · radix-ui第三方依赖 · class-variance-authority

基础用法

徽章的基础展示形态,包含各种内置语义变体与图标搭配:

Loading…

安装与引入

通过 CLI 自动添加组件,或手动复制源码至项目中:

pnpm dlx @wui-design/cli@latest add @wui/badge
安装依赖库
pnpm add radix-ui class-variance-authority clsx tailwind-merge
复制组件源码到 components/ui/badge.tsx
components/ui/badge.tsx
import * as React from "react"
import { Slot } from "radix-ui"
import { cva } from "class-variance-authority"

import { cn } from "@/lib/utils"

const badgeVariants = cva(
  "inline-flex w-fit shrink-0 items-center justify-center gap-1 whitespace-nowrap rounded-full border px-2 py-0.5 text-xs font-medium leading-none outline-none transition-[color,background-color,border-color,box-shadow] duration-200 focus-visible:ring-[3px] focus-visible:ring-ring/35 [&_svg]:pointer-events-none [&_svg]:size-3 [&_svg]:shrink-0",
  {
    variants: {
      variant: {
        default: "border-transparent bg-primary text-primary-foreground [:is(a,button)&]:hover:bg-primary/90",
        secondary:
          "border-transparent bg-secondary text-secondary-foreground [:is(a,button)&]:hover:bg-secondary/80",
        outline: "border-border bg-background text-foreground [:is(a,button)&]:hover:bg-accent [:is(a,button)&]:hover:text-accent-foreground",
        destructive:
          "border-transparent bg-destructive text-destructive-foreground [:is(a,button)&]:hover:bg-destructive/90",
        success: "border-transparent bg-success text-success-foreground [:is(a,button)&]:hover:bg-success/90",
        warning: "border-transparent bg-warning text-warning-foreground [:is(a,button)&]:hover:bg-warning/90",
        info: "border-transparent bg-info text-info-foreground [:is(a,button)&]:hover:bg-info/90",
      },
      size: {
        sm: "min-h-4 px-1.5 text-[10px]",
        default: "min-h-5",
        lg: "min-h-6 px-2.5 text-sm",
      },
    },
    defaultVariants: {
      variant: "default",
      size: "default",
    },
  }
)

export interface BadgeProps extends React.ComponentProps<"span"> {
  /** Visual treatment of the badge. @default "default" */
  variant?:
    | "default"
    | "secondary"
    | "outline"
    | "destructive"
    | "success"
    | "warning"
    | "info"
  /** Height and horizontal padding preset. @default "default" */
  size?: "sm" | "default" | "lg"
  /** Render as the single child element via Radix Slot. @default false */
  asChild?: boolean
}

/**
 * A compact label for status, category, or short metadata. When rendered as a
 * link or button via `asChild`, it gains hover and focus-visible feedback.
 */
function Badge({
  className,
  variant = "default",
  size = "default",
  asChild = false,
  ...props
}: BadgeProps) {
  const Comp = asChild ? Slot.Root : "span"

  return (
    <Comp
      data-slot="badge"
      data-variant={variant}
      data-size={size}
      className={cn(badgeVariants({ variant, size }), className)}
      {...props}
    />
  )
}

export { Badge, badgeVariants }

属性 Props

Badge 支持以下配置属性,并会继承原生 <span> 元素的全部 HTML 属性:

属性类型默认值说明
variant"default" | "secondary" | "outline" | "destructive" | "success" | "warning" | "info""default"徽章的视觉变体与色彩语义主题。
size"sm" | "default" | "lg""default"徽章的物理尺寸与内边距密度。
asChildbooleanfalse是否将样式和属性合并渲染到唯一的子元素(如 <a> 或 <button>)上。
classNamestring—应用于徽章外层元素的额外 CSS 类名。
childrenReact.ReactNode—徽章的内容,可包含文字、图标或状态指示圆点。

事件 Events

作为行内语义标签,Badge 继承原生 span 元素的所有鼠标、键盘及焦点事件回调:

属性类型默认值说明
onClick(event: React.MouseEvent<HTMLSpanElement>) => void—当徽章被点击时触发(例如作为可点击标签或过滤项使用时)。
onMouseEnter(event: React.MouseEvent<HTMLSpanElement>) => void—鼠标指针移入徽章区域时触发。
onMouseLeave(event: React.MouseEvent<HTMLSpanElement>) => void—鼠标指针离开徽章区域时触发。

使用场景与设计规范

Badge 适用于高密度界面中对特定条目进行状态标识、属性归类或突出关键元数据。

  • 状态 vs 分类:表达运行状态、风险等级或处理结果时,使用带语义色彩的 success、warning、destructive 或 info;仅作为普通维度分类、版本标记或技术栈标签时,使用中性的 default、secondary 或 outline,避免色彩过载引发用户误解。
  • 信息简练:徽章应当承载极短的关键词(如 1~3 个词或数字)。长句子或多行说明应使用 Alert 或 Tooltip。
  • 与操作按钮的区别:徽章本质是信息展示,不应承担主要操作职责。若徽章具备跳转功能,可通过 asChild 挂载 <a> 标签并提供清晰的 Hover 悬浮反馈。

场景示例

尺寸预设

提供 sm、default、lg 三种尺寸,便于适配表格密集行、标题右侧或卡片顶部等不同排版环境:

Loading…
  • sm:字号 10px,适合嵌入密集数据表格单元格、行内微标。
  • default:标准尺寸,适用于绝大多数卡片、列表项与面板。
  • lg:字号 14px,适合页面级大标题旁的重要状态或突出标签。

状态指示圆点

在 Badge 内部搭配微型圆点指示灯,能够以极高的信息密度直观表达系统、服务或网络状态;需要引起注意的异常状态可叠加扩散光圈(系统开启“减少动态效果”时自动停止):

Loading…

未读计数与数字滚动

徽章常用于承载未读数、待办数等会实时变化的计数。配合 motion 可以让数字按增减方向上下滚动,徽章出现与消失时轻微缩放,超出上限时显示为 99+:

Loading…

搭配图标

图标能显著提高标签的可识别度。内置样式已对子级 SVG 图标进行了自动居中与尺寸约束:

Loading…

作为链接或交互项 (asChild)

利用 asChild 属性,可以将 Badge 的外观与交互行为直接赋予 <a> 或 <button>,既保留了可点击语义与键盘焦点,又保持了样式一致性。渲染为链接或按钮时,各变体自动获得悬停加深与 focus-visible 焦点环,无需额外样式:

Loading…

业务场景:服务部署列表

在 CI/CD 控制台或云资源面板中,组合使用不同尺寸与变体的徽章,以清晰的视觉层级区分环境、流水线状态与提交信息:

Loading…

无障碍与交互 Accessibility

  • 语义与读屏器:Badge 默认渲染为 <span> 元素。当徽章仅通过颜色或图标表达关键状态时,请确保在文字内容中明确写出状态名称(例如“成功”而不仅仅是绿色勾号),或为读屏器添加 aria-label 辅助说明。
  • 交互与可访问性:当使用 asChild 渲染为交互式链接(<a>)或可交互按钮时,会自动继承原生元素的 Tab 键盘对焦与 Enter / Space 激活能力。
  • 高对比度:内置变体的文字与背景色彩均经过色彩对比度调优,确保在浅色与深色模式下均符合 WCAG 2.1 AA 级可读性标准。