Badge
A Badge shows users the status, a count, or a category of a record.
When to Use
- for the status of a record in a Table or a list, such as “Paid” or “Overdue”
- for a column of statuses, with
dot - for a short figure next to a title, like the change of “12.5%” on a dashboard Card
- for work in progress on one record, like “Syncing”, with a Spinner
When Not to Use
- for a message with a title and a description (use an Alert)
- for an action (use a Button)
- for the count on a Sidebar item (use
SidebarMenuBadgein Sidebar) - for the mark on the corner of an Avatar (use
AvatarBadgein Avatar)
Anatomy
| Element | Usage |
|---|---|
| Label | Required |
| Container | Required |
| Icon | Optional |
| Dot | Optional |
Variants
| Variant | Purpose |
|---|---|
default | The one label in a view that needs the most emphasis |
secondary | A status that is neither good nor bad, such as “Sent” or “Draft” |
outline | A category or a count |
ghost | A label within a line of text |
link | A Badge rendered as a link that should look like one |
destructive | An error or a loss, such as “Overdue” |
success | A good outcome, such as “Paid” |
warning | A state that needs attention, such as “Awaiting payment” |
See Color for the three status colors.
Dot
When dot is set, the fill is replaced by a marker in the variant’s color. The marker leads each label, so users can scan a column of statuses from top to bottom.
The variant changes only the color, so the label must state the status: color can’t be the only sign of it, as WCAG 2.2 SC 1.4.1 Use of Color requires.
Behavior
A Badge is as wide as its label. The label doesn’t wrap, and the Badge doesn’t shrink in a flex row, so a label that is wider than its container will overflow it. Nothing happens when users click a Badge unless it is rendered as a link.
Content
| String | Rule | Example | Counterexample |
|---|---|---|---|
| Label | Use sentence case | “Awaiting payment” | “Awaiting Payment” |
| Label | State the status itself, in one or two words | “Overdue” | “This invoice is overdue” |
Accessibility
A Badge isn’t focusable and has no keys. When it is rendered as an a with an href, it is a link in the tab order. A Badge isn’t a live region, so a status that changes while the page is open isn’t announced.
Requirements
The label must state the status in words so that users who can’t tell the colors apart can read it. The variant sets only a color, and WCAG 2.2 SC 1.4.1 Use of Color doesn’t allow color to be the only sign of a status.
Set aria-hidden on an icon in a Badge. See Iconography for the rule.
Installation
npx shadcn@latest add @summit/badgeUsage
import { Badge } from '@/components/ui/badge';
<Badge variant="secondary">Draft</Badge>;Show a Status
To show a status, set the variant that matches it, and set dot for the marker.
<Badge variant="destructive" dot>
Overdue
</Badge>With an Icon
To place an icon before or after the label, mark it with data-icon="inline-start" or data-icon="inline-end".
import { CheckIcon } from '@phosphor-icons/react';
<Badge variant="success">
<CheckIcon aria-hidden data-icon="inline-start" />
Paid
</Badge>;As a Link
To render a Badge as a link, pass an a to render, which replaces the span.
<Badge variant="outline" render={<a href="/invoices?status=overdue" />}>
2 overdue
</Badge>API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'default' | 'secondary' | 'destructive' | 'success' | 'warning' | 'outline' | 'ghost' | 'link' | 'default' | The fill and the text color |
dot | boolean | false | Shows a marker before the label and removes the fill |
render | An element or a function that returns one | None | The element to render in place of the span |
Other props are passed to the element. See the Base UI useRender documentation for render.