gray
radius
Display

Badge

A small label reporting state the user cannot change. Not interactive and not focusable: if it can be clicked or dismissed, it is a Chip.

Tone

Use tone to say what the state is. Text and background come from the same status scale, so the pair clears AA by construction.

neutralaccentinfosuccesswarningerror
<Badge tone="neutral">neutral</Badge>
<Badge tone="accent">accent</Badge>
<Badge tone="info">info</Badge>
<Badge tone="success">success</Badge>
<Badge tone="warning">warning</Badge>
<Badge tone="error">error</Badge>

Variant

Soft is the tint and the default. Solid is for the badge that has to carry across a busy row, on the text color measured to pass on that fill. Outline puts no fill on the page, which is what a dense list of them wants.

softneutralaccentinfosuccesswarningerror
solidneutralaccentinfosuccesswarningerror
outlineneutralaccentinfosuccesswarningerror
{(['soft', 'solid', 'outline'] as const).map(variant =>
TONES.map(tone => (
<Badge key={tone} tone={tone} variant={variant}>
{tone}
</Badge>
))
)}
A tone carries meaning only to people who can see it. If the meaning matters, put it in the words: “Failed” beside a red badge, not a red badge alone.

Size

Two sizes, and the difference is the type: 12px in a 20px box, or 13px in a 22px one.

smallmedium
<Badge size="s" tone="accent">small</Badge>
<Badge size="m" tone="accent">medium</Badge>

Props

PropTypeDefaultNotes
tone'neutral' | 'accent' | 'info' | 'success' | 'warning' | 'error''neutral'What the state is, not what color it is.
variant'soft' | 'solid' | 'outline''soft'Tinted, filled, or an outline with no fill. The outline border is the tone’s subtle step, the same weight as every other hairline in the system.
size's' | 'm''m'Small is 12px type for a count or an inline marker; medium is 13px.