Badge

Inline label with outlined, solid, ghost, and minimal variants.

API Reference

PropTypeDefault
variant"outlined" | "solid" | "ghost" | "minimal""solid"
color"root" | "primary" | "secondary" | "accent" | "info" | "progress" | "success" | "warning" | "danger""root"
size"sm" | "md" | "lg""md"
rounded"none" | "sm" | "md" | "lg" | "full""md"
as"span" | "button""span"

Variants & Colors

Outlined

RootPrimarySecondaryAccentInfoProgressSuccessWarningDanger
<Badge variant="outlined" color="root">Root</Badge>
<Badge variant="outlined" color="primary">Primary</Badge>
<Badge variant="outlined" color="secondary">Secondary</Badge>
<Badge variant="outlined" color="accent">Accent</Badge>
<Badge variant="outlined" color="info">Info</Badge>
<Badge variant="outlined" color="progress">Progress</Badge>
<Badge variant="outlined" color="success">Success</Badge>
<Badge variant="outlined" color="warning">Warning</Badge>
<Badge variant="outlined" color="danger">Danger</Badge>

Solid

default
RootPrimarySecondaryAccentInfoProgressSuccessWarningDanger
<Badge variant="solid" color="root">Root</Badge>
<Badge variant="solid" color="primary">Primary</Badge>
<Badge variant="solid" color="secondary">Secondary</Badge>
<Badge variant="solid" color="accent">Accent</Badge>
<Badge variant="solid" color="info">Info</Badge>
<Badge variant="solid" color="progress">Progress</Badge>
<Badge variant="solid" color="success">Success</Badge>
<Badge variant="solid" color="warning">Warning</Badge>
<Badge variant="solid" color="danger">Danger</Badge>

Ghost

RootPrimarySecondaryAccentInfoProgressSuccessWarningDanger
<Badge variant="ghost" color="root">Root</Badge>
<Badge variant="ghost" color="primary">Primary</Badge>
<Badge variant="ghost" color="secondary">Secondary</Badge>
<Badge variant="ghost" color="accent">Accent</Badge>
<Badge variant="ghost" color="info">Info</Badge>
<Badge variant="ghost" color="progress">Progress</Badge>
<Badge variant="ghost" color="success">Success</Badge>
<Badge variant="ghost" color="warning">Warning</Badge>
<Badge variant="ghost" color="danger">Danger</Badge>

Minimal

RootPrimarySecondaryAccentInfoProgressSuccessWarningDanger
<Badge variant="minimal" color="root">Root</Badge>
<Badge variant="minimal" color="primary">Primary</Badge>
<Badge variant="minimal" color="secondary">Secondary</Badge>
<Badge variant="minimal" color="accent">Accent</Badge>
<Badge variant="minimal" color="info">Info</Badge>
<Badge variant="minimal" color="progress">Progress</Badge>
<Badge variant="minimal" color="success">Success</Badge>
<Badge variant="minimal" color="warning">Warning</Badge>
<Badge variant="minimal" color="danger">Danger</Badge>

Sizes

SmallMediumLarge
<Badge size="sm">Small</Badge>
<Badge size="md">Medium</Badge>
<Badge size="lg">Large</Badge>

Rounded

NoneSmallMediumLargeFull
<Badge rounded="none">None</Badge>
<Badge rounded="sm">Small</Badge>
<Badge rounded="md">Medium</Badge>
<Badge rounded="lg">Large</Badge>
<Badge rounded="full">Full</Badge>

Interactive

as="button"
<Badge as="button" variant="outlined" color="primary">Outlined</Badge>
<Badge as="button" variant="solid" color="primary">Solid</Badge>
<Badge as="button" variant="ghost" color="primary">Ghost</Badge>
<Badge as="button" variant="minimal" color="primary">Minimal</Badge>

Basic Usage

import { Badge } from "@/ui";

<Badge>New</Badge>

Source

src/ui/Badge.tsx
import { cn } from "@/utils";

interface BadgeProps extends React.HTMLAttributes<HTMLElement> {
  variant?: "outlined" | "solid" | "ghost" | "minimal";
  color?: "root" | "primary" | "secondary" | "accent" | "info" | "progress" | "success" | "warning" | "danger";
  size?: "sm" | "md" | "lg";
  rounded?: "none" | "sm" | "md" | "lg" | "full";
  as?: "span" | "button";
}

const outlined: Record<string, string> = {
  root: "border border-root-contrast text-root-contrast",
  primary: "border border-primary text-primary",
  secondary: "border border-secondary text-secondary",
  accent: "border border-accent text-accent",
  info: "border border-info-contrast text-info-contrast",
  progress: "border border-progress-contrast text-progress-contrast",
  success: "border border-success-contrast text-success-contrast",
  warning: "border border-warning-contrast text-warning-contrast",
  danger: "border border-danger-contrast text-danger-contrast",
};

const solid: Record<string, string> = {
  root: "bg-root-contrast text-root",
  primary: "bg-primary text-primary-contrast",
  secondary: "bg-secondary text-secondary-contrast",
  accent: "bg-accent text-accent-contrast",
  info: "bg-info text-info-contrast",
  progress: "bg-progress text-progress-contrast",
  success: "bg-success text-success-contrast",
  warning: "bg-warning text-warning-contrast",
  danger: "bg-danger text-danger-contrast",
};

const ghost: Record<string, string> = {
  root: "bg-root-ghost text-root-contrast",
  primary: "bg-primary-ghost text-primary",
  secondary: "bg-secondary-ghost text-secondary",
  accent: "bg-accent-ghost text-accent",
  info: "bg-info-ghost text-info-contrast",
  progress: "bg-progress-ghost text-progress-contrast",
  success: "bg-success-ghost text-success-contrast",
  warning: "bg-warning-ghost text-warning-contrast",
  danger: "bg-danger-ghost text-danger-contrast",
};

const minimal: Record<string, string> = {
  root: "text-root-contrast",
  primary: "text-primary",
  secondary: "text-secondary",
  accent: "text-accent",
  info: "text-info-contrast",
  progress: "text-progress-contrast",
  success: "text-success-contrast",
  warning: "text-warning-contrast",
  danger: "text-danger-contrast",
};

export function Badge({
  children,
  variant = "solid",
  color = "root",
  size = "md",
  rounded = "md",
  as: Tag = "span",
  className,
  onClick,
  ...props
}: BadgeProps) {
  const isInteractive = Tag === "button" || !!onClick;

  return (
    <Tag
      className={cn(
        "inline-flex items-center font-semibold tracking-wide uppercase",
        rounded === "none" && "rounded-none",
        rounded === "sm" && "rounded-sm",
        rounded === "md" && "rounded-md",
        rounded === "lg" && "rounded-lg",
        rounded === "full" && "rounded-full",
        size === "sm" && "px-2 py-1.5 text-[10px]",
        size === "md" && "px-3 py-2 text-[10px]",
        size === "lg" && "px-4 py-2.5 text-xs",
        variant === "outlined" && outlined[color],
        variant === "solid" && solid[color],
        variant === "ghost" && ghost[color],
        variant === "minimal" && "p-0",
        variant === "minimal" && minimal[color],
        isInteractive && "cursor-pointer transition-colors ...",
        className,
      )}
      onClick={onClick}
      {...props}
    >
      {children}
    </Tag>
  );
}