A small label that states a status or category, like Paid, Overdue or Beta. Not interactive.
DraftIn reviewPaidDue soonOverdue
import { Badge } from "@rdloom/react";
export default function BadgeVariantsExample() {
return (
<div className="flex flex-wrap items-center gap-2">
<Badge>Draft</Badge>
<Badge variant="info">In review</Badge>
<Badge variant="success">Paid</Badge>
<Badge variant="warning">Due soon</Badge>
<Badge variant="danger">Overdue</Badge>
</div>
);
}Installation
CLI
Manual
npm
pnpm
yarn
bun
npx rdloom add badgeCopies the source into src/components/rdloom. Edit it freely: rdloom upgrade merges later versions into your changes.
Use another registry client
npx shadcn@latest add https://rdloom.vimalbhatt.com/r/badge.jsonWorks, but without upgrade tracking.
Usage
import { Badge } from "@rdloom/react";
<div className="flex flex-wrap items-center gap-2">
<Badge>Draft</Badge>
<Badge variant="info">In review</Badge>
<Badge variant="success">Paid</Badge>
<Badge variant="warning">Due soon</Badge>
<Badge variant="danger">Overdue</Badge>
</div>Sizes
BetaBeta
import { Badge } from "@rdloom/react";
export default function BadgeSizesExample() {
return (
<div className="flex items-center gap-2">
<Badge size="sm" variant="info">
Beta
</Badge>
<Badge size="md" variant="info">
Beta
</Badge>
</div>
);
}In a list
- INV-1042Overdue
- INV-1043Paid
- INV-1044Due soon
import { Badge } from "@rdloom/react";
const invoices = [
{ id: "INV-1042", status: "Overdue", variant: "danger" },
{ id: "INV-1043", status: "Paid", variant: "success" },
{ id: "INV-1044", status: "Due soon", variant: "warning" },
] as const;
// The status is written out: the color only helps people who can see it.
export default function BadgeInAListExample() {
return (
<ul className="flex w-72 flex-col gap-2 text-sm">
{invoices.map((invoice) => (
<li key={invoice.id} className="flex items-center justify-between">
<span>{invoice.id}</span>
<Badge variant={invoice.variant}>{invoice.status}</Badge>
</li>
))}
</ul>
);
}API Reference
Defined by the spec. Components also accept the props of the React Aria component they wrap.
| Prop | Type | Default |
|---|---|---|
childrenrequiredThe label. Say what it means in words: color alone never carries the meaning. | node | none |
variantTone: neutral for categories, the others for statuses. | "neutral" | "info" | "success" | "warning" | "danger" | "neutral" |
sizeText and padding size. | "sm" | "md" | "md" |
Accessibility
Role text, WCAG 2.2 AA. Tested with axe and keyboard tests; screen reader checks are in the audit checklist.
Keyboard
Not interactive.
Screen readers announce
- Read in place as ordinary text, e.g. "Order 1042, Overdue"
What your code must do
- The status is in the text, not only the color (a colored dot is decoration)
- Text meets 4.5:1 against every tone's background, in light and dark mode
- It is plain inline text: not focusable, not a button
Guidelines
Use it when
- Showing the status of a record in a list or table
- Tagging something with a short category or version, like Beta
Avoid it when
- Something the user can click or dismiss: use a Button or a tag input
- A count that changes and must be announced: use a live region
Don't
- Using color as the only difference between two badges
- Long sentences inside a badge
- Making a badge a button
Design tokens
The semantic tokens this component uses. Change them once and every component follows; see Design tokens.
--rd-color-text-default--rd-color-surface-subtle--rd-color-border-default--rd-color-feedback-info-subtle--rd-color-feedback-success-subtle--rd-color-feedback-warning-subtle--rd-color-feedback-danger-subtle--rd-color-feedback-info--rd-color-feedback-success--rd-color-feedback-warning--rd-color-feedback-danger