Skip to content
EMBOSS
Docs menu

Badge

An etched part-number chip in neutral, semantic, and outline tints — the label text always carries the meaning.

@emboss/badge
Rev 1.0NewCalibratedDriftingClippingSpare

Installation

pnpm dlx shadcn@latest add @emboss/badge

Usage

example.tsx
import { Badge } from "@/components/ui/badge";

export function Example() {
  return <Badge variant="positive">Calibrated</Badge>;
}

API reference

Badge

Extends the native span element.

PropTypeDefaultDescription
variant"neutral" | "accent" | "positive" | "warning" | "danger" | "outline""neutral"Tint of the chip; semantic variants use the matching surface tints.

Source

View source — badge.tsx
badge.tsx
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";

const badgeVariants = cva(
  "tracking-label inline-flex w-fit shrink-0 items-center gap-1 rounded-xs px-1.5 py-0.5 font-mono text-label uppercase select-none [&_svg]:size-3 [&_svg]:shrink-0",
  {
    variants: {
      variant: {
        neutral: "bg-surface-2 text-ink-muted shadow-flush",
        accent: "bg-accent-surface text-ink shadow-flush",
        positive: "bg-positive-surface text-ink shadow-flush",
        warning: "bg-warning-surface text-ink shadow-flush",
        danger: "bg-danger-surface text-ink shadow-flush",
        outline: "text-ink-muted shadow-flush",
      },
    },
    defaultVariants: {
      variant: "neutral",
    },
  },
);

export type BadgeProps = React.ComponentProps<"span"> &
  VariantProps<typeof badgeVariants>;

/**
 * An etched part-number chip. State is always carried by the label text,
 * never by tint alone.
 *
 * @example
 * <Badge variant="positive">Calibrated</Badge>
 */
function Badge({ className, variant, ...props }: BadgeProps) {
  return (
    <span
      data-slot="badge"
      className={cn(badgeVariants({ variant }), className)}
      {...props}
    />
  );
}

export { Badge, badgeVariants };