Skip to content
Folio

Display

Badge

A count or a state, set in mono so it reads as metadata.

Usage

When to reach for it

One fact about one record. If it names what something is ABOUT, that is a Tag.
TSX
import { Badge } from '@misoto22/design'

Notes

A count, a state, a small inline marker.

Mono and small, so it reads as metadata rather than as content. A badge is not interactive — if it can be clicked or dismissed it is a Tag or a button, and giving this one an onClick produces a control a keyboard cannot reach.

Anatomy

Badge anatomy
ElementDescription
ChiprequiredThe <span>: inline-flex on the --radius-sm corner, mono at 12px with wide tracking. The mono face is the whole signal — it is what tells a reader this is metadata rather than a word of the sentence it sits in.
GroundrequiredThe tone’s fill — --stone for neutral, the soft tint of --ok, --warn or --danger for the three status tones, and nothing at all for outline.
BorderrequiredAlways drawn, and transparent for every tone but outline, so the box reserves the pixel either way and swapping tone at runtime moves nothing beside it.
Contentrequiredchildren, with a 6px gap between them — so a StatusDot or a Kbd set beside the text spaces itself without a wrapper.

Best practices

Do

  • Leave tone at neutral unless the badge names a STATE: the three status tones are the only chroma this system spends, and a badge that is red because the page wanted red is the thing the scale exists to prevent.
  • Reach for outline when the badge sits on --stone already — every other tone fills its own ground, and a neutral badge on stone is a chip with no visible edge at all.
  • Keep it to a count, a word, or a short state. It is 12px mono sized for one line, so a phrase in it is prose set in the metadata face and wraps inside a box that was never given a second line.

Don’t

  • A row of them is a Tag list drawn in the wrong component: Badge has no active state, so the filter bar it turns into cannot show which facet is on.
  • A neutral Badge and an inactive Tag are the same corner, the same padding and the same 12px mono, separated by one ink step — so a row that mixes states and topics reads as one undifferentiated run of chips.
  • There is no dismiss affordance here. A × written into children is text inside the accessible name, so the badge is announced as “beta ×” and the close it advertises does not exist.

Examples

tones

Every tone the badge has, with the neutral default first. Leave it at neutral unless the badge names a STATE: the three status tones are the only chroma this system spends, and a badge that is red because the page wanted red is the thing the scale exists to prevent.

12DraftDeployedDegradedFailed

with a status dot

A dot inside the chip rather than beside it. Badge spaces its children 6px apart, so a StatusDot needs no wrapper of its own — and the dot is aria-hidden, so the word next to it has to name the state on its own. Reach for this in a table cell where the row already supplies the subject; a state that is the whole line is a StatusPill.

Deployed Degraded Failed

on a stone ground

The same two words on the ground one of them disappears into. Neutral fills itself with --stone and draws a transparent border, so on a stone panel it is a chip with no visible edge at all; outline is the tone that keeps its hairline. Reach for outline whenever the badge sits on a filled surface.

NeutralOutline

Types

TSX
export type BadgeTone = 'neutral' | 'success' | 'warning' | 'danger' | 'outline'

Accessibility

  • Not interactive. A badge with an onClick is a control a keyboard cannot reach.
  • The status tones double their colour with words, so the meaning survives monochrome and colour-blindness.