GitHub

Badge

A small visual indicator used to highlight status, category, or count. Supports multiple semantic variants and three sizes with automatic dark mode support.

AccessibleDark Mode6 Variants3 Sizes

Install

$npx react-principles add badge
01

Theme Preview

All six variants across both themes — rendered with forced styling so the comparison is accurate regardless of the current app theme.

Light
DefaultSuccessWarningErrorInfoOutline
sm →Activemd →Reviewlg →Pending
Dark
DefaultSuccessWarningErrorInfoOutline
sm →Activemd →Reviewlg →Pending
Size
DefaultSuccessWarningErrorInfoOutline
03

Code Snippet

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

// Variants
<Badge variant="default">Default</Badge>
<Badge variant="success">Active</Badge>
<Badge variant="warning">Pending</Badge>
<Badge variant="error">Inactive</Badge>
<Badge variant="info">Review</Badge>
<Badge variant="outline">Draft</Badge>

// Sizes
<Badge size="sm" variant="success">Small</Badge>
<Badge size="md" variant="info">Medium</Badge>
<Badge size="lg" variant="default">Large</Badge>

Backward compatible: API lama <Badge /> tetap didukung, canonical style pakai <Badge />.

04

Copy-Paste (Single File)

Badge.tsx
import type { ReactNode } from "react";
import { cn } from "@/lib/utils";

export type BadgeVariant = "default" | "success" | "warning" | "error" | "info" | "outline";
export type BadgeSize = "sm" | "md" | "lg";

export interface BadgeProps {
  variant?: BadgeVariant;
  size?: BadgeSize;
  children: ReactNode;
  className?: string;
}

const VARIANT_CLASSES: Record<BadgeVariant, string> = {
  default: "bg-slate-100 text-slate-700 dark:bg-slate-800 dark:text-slate-300",
  success: "bg-green-100 text-green-700 dark:bg-green-900/40 dark:text-green-400",
  warning: "bg-amber-100 text-amber-700 dark:bg-amber-900/40 dark:text-amber-400",
  error: "bg-red-100 text-red-700 dark:bg-red-900/40 dark:text-red-400",
  info: "bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-400",
  outline: "border border-slate-300 text-slate-600 dark:border-slate-600 dark:text-slate-400",
};

const SIZE_CLASSES: Record<BadgeSize, string> = {
  sm: "text-[10px] px-2 py-0.5",
  md: "text-xs px-2.5 py-0.5",
  lg: "text-sm px-3 py-1",
};

export function Badge({ variant = "default", size = "md", children, className }: BadgeProps) {
  return (
    <span
      className={cn(
        "inline-flex items-center font-medium rounded-full",
        VARIANT_CLASSES[variant],
        SIZE_CLASSES[size],
        className,
      )}
    >
      {children}
    </span>
  );
}
05

Props

PropTypeDefaultDescription
variant"default" | "success" | "warning" | "error" | "info" | "outline""default"Controls the color scheme of the badge.
size"sm" | "md" | "lg""md"Controls padding and font size.
childrenReactNodeThe label content displayed inside the badge.
classNamestringAdditional CSS classes merged via cn().
react-principles