Badge
Small status labels for categorizing or labeling UI elements.
Badge is a non-interactive inline label built on a <div> with five semantic color variants. Use it for status indicators, category tags, version labels, and count displays. For clickable badges, use a Button instead.
Installation
npm install @designforge/uiUsage
import { Badge } from "@designforge/ui";
export default function App() {
return <Badge>New</Badge>;
}Examples
All variants
Five semantic variants cover the most common label needs. default uses your primary brand color; secondary is muted; outline has no fill; destructive signals errors or removal; success signals active or confirmed states.
import { Badge } from "@designforge/ui";
export default function AllVariants() {
return (
<div className="flex flex-wrap gap-2 items-center">
<Badge variant="default">Default</Badge>
<Badge variant="secondary">Secondary</Badge>
<Badge variant="outline">Outline</Badge>
<Badge variant="destructive">Destructive</Badge>
<Badge variant="success">Success</Badge>
</div>
);
}Status badges
Map application states to semantic variants so color carries consistent meaning throughout your UI.
import { Badge } from "@designforge/ui";
export default function StatusBadges() {
return (
<div className="flex flex-wrap gap-2">
<Badge variant="success">Active</Badge>
<Badge variant="secondary">Pending</Badge>
<Badge variant="destructive">Failed</Badge>
<Badge variant="outline">Draft</Badge>
<Badge variant="default">Published</Badge>
</div>
);
}Inline with text
Badges sit naturally beside headings, list items, and nav links.
import { Badge } from "@designforge/ui";
export default function InContext() {
return (
<div className="flex flex-col gap-3">
<div className="flex items-center gap-2">
<span className="font-semibold">@designforge/ui</span>
<Badge>v1.0</Badge>
<Badge variant="success">Stable</Badge>
</div>
<div className="flex items-center gap-2">
<span>AI Generator</span>
<Badge variant="secondary">Beta</Badge>
</div>
<div className="flex items-center gap-2">
<span>DatePicker</span>
<Badge variant="destructive">Removed in v1</Badge>
</div>
<div className="flex items-center gap-2">
<span>TypeScript</span>
<Badge variant="outline">5.x</Badge>
</div>
</div>
);
}Tag list from array
Map over a data array to render a dynamic set of category tags.
import { Badge } from "@designforge/ui";
const tags = ["React", "TypeScript", "Tailwind", "Radix UI", "CVA"];
export default function TagList() {
return (
<div className="flex flex-wrap gap-2">
{tags.map((tag) => (
<Badge key={tag} variant="secondary">
{tag}
</Badge>
))}
</div>
);
}With icons
Prepend a Lucide icon inside the badge to reinforce meaning visually.
import { Badge } from "@designforge/ui";
import { CheckCircle2, XCircle, Clock } from "lucide-react";
export default function WithIcons() {
return (
<div className="flex flex-wrap gap-2 items-center">
<Badge variant="success">
<CheckCircle2 className="h-3 w-3 mr-1" />
Active
</Badge>
<Badge variant="destructive">
<XCircle className="h-3 w-3 mr-1" />
Deprecated
</Badge>
<Badge variant="secondary">
<Clock className="h-3 w-3 mr-1" />
Pending
</Badge>
</div>
);
}Notification counter overlay
Override sizing via className to create a compact counter badge that overlays an icon button.
import { Badge } from "@designforge/ui";
import { Button } from "@designforge/ui";
import { BellIcon } from "lucide-react";
export default function NotificationCounter() {
return (
<div className="relative inline-flex">
<Button variant="outline" size="icon" aria-label="Notifications, 3 unread">
<BellIcon className="h-4 w-4" />
</Button>
<Badge className="absolute -top-1 -right-1 h-4 min-w-4 px-1 text-[10px]">
3
</Badge>
</div>
);
}Count badges in navigation
Display counts alongside sidebar navigation items or tab labels.
import { Badge } from "@designforge/ui";
export default function NavCounts() {
return (
<div className="flex gap-6 items-center text-sm">
<div className="flex items-center gap-1.5">
Notifications <Badge>12</Badge>
</div>
<div className="flex items-center gap-1.5">
Errors <Badge variant="destructive">3</Badge>
</div>
<div className="flex items-center gap-1.5">
Pull Requests <Badge variant="secondary">7</Badge>
</div>
</div>
);
}API Reference
<Badge>
Renders a <div> element. Accepts all standard HTML div attributes in addition to the props listed below.
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "default" | "secondary" | "destructive" | "outline" | "success" | "default" | Controls the background color and text color of the badge. |
className | string | — | Additional CSS classes merged with default styles via cn(). |
children | ReactNode | — | Badge label content — text, icons, or any inline React nodes. |
All other props (id, style, aria-*, data-*, etc.) are forwarded to the underlying <div> element.
Note:
Badgerenders as a non-interactive<div>. If you need a clickable badge (e.g., for filter chips), wrap it in a<button>or<a>, or use<Button variant="outline">directly.
Accessibility
Badgerenders as a<div>with no implicit ARIA role. Screen readers announce it as generic content within its surrounding text.- Because it is non-interactive, do not attach
onClickdirectly to aBadge. Wrap it in a<button>or<a>to make the entire target focusable and keyboard-operable. - Color alone should never be the sole differentiator. Always include a readable text label so meaning is conveyed without relying on color perception.
- When using
Badgeas a notification counter overlaying another element, incorporate the count into the parent button'saria-label(e.g.,aria-label="Notifications, 3 unread").
Live View
Here is a live contextual rendering of the component directly from our isolated Storybook environment.