Badge
When to use
Section titled “When to use”- The status of an item in a list or table: “Paid”, “Overdue”
- A category or stage: “Beta”, “New”
- A count next to a label
Not for something people click or remove — use a Chip or a Button.
Choosing between small labels:
| Component | Use it for | For example |
|---|---|---|
| Badge | The status or category of something, at a glance | “Paid”, “Overdue”, “Beta” |
| Chip | Tags, filters and metadata, often several in a row | “React”, “Remote”, an applied filter |
| Kbd | A key on the keyboard, in text or a tooltip | Press ⌘ K to search |
import { Badge } from '@arun-dev/ui';
export default function BadgeTones() { return ( <> <Badge>neutral</Badge> <Badge tone="success">success</Badge> <Badge tone="warning">warning</Badge> <Badge tone="error">error</Badge> <Badge tone="info">info</Badge> </> );}Playground
Section titled “Playground”Status
<Badge tone="neutral">Status</Badge>Domain vocabulary belongs to your app
Section titled “Domain vocabulary belongs to your app”The design system ships only generic tones. Anything narrower — an article’s difficulty, an order’s status, a build result — is your vocabulary, and mapping it at the call site keeps it type-checked and keeps the library reusable.
import { Badge, type BadgeTone } from '@arun-dev/ui';
type Difficulty = 'beginner' | 'intermediate' | 'advanced';
// Domain vocabulary belongs to your app, not the design system. Map it onto a tone// at the call site, where `satisfies` makes a typo a compile error.const DIFFICULTY = { beginner: { label: 'Beginner', tone: 'success' }, intermediate: { label: 'Intermediate', tone: 'warning' }, advanced: { label: 'Advanced', tone: 'error' },} as const satisfies Record<Difficulty, { label: string; tone: BadgeTone }>;
export default function BadgeDomainMapping() { return ( <> {(Object.keys(DIFFICULTY) as Difficulty[]).map((key) => ( <Badge key={key} tone={DIFFICULTY[key].tone}> {DIFFICULTY[key].label} </Badge> ))} </> );}| Prop | Type | Default | Description |
|---|---|---|---|
tone | 'neutral' | 'success' | 'warning' | 'error' | 'info' | 'neutral' | Generic status tone, backed by the --color-status-* semantic tokens. Map your own domain vocabulary onto a tone at the call site. |
className | string | Concatenated with the component's own classes, never replacing them. | |
render | ReactElement | Element or component to render instead of the default. Props, className, event handlers and ref are merged onto it. | |
ref | Ref<HTMLElement> | Ref to the rendered element. Merged with any ref on the render element. | |
…rest | HTMLAttributes | Anything else is spread onto the rendered element, so id, aria-*, data-* and event handlers all reach the DOM. |
- Tones are backed by the
--color-status-*semantic tokens, so they move with the brand. Override--badge-success-bgto restyle only success badges. neutraladds no tone class, so.badgealone is the neutral appearance.