Badge
A short label for a status, category or count, next to what it describes.
In Dense data
See it live
npm run storybookWhen to use it
In Dense data: Alert status in rows.
- Use it when: A state people scan for in a list or table, or a small category label.
- Not when: A message people must read (alert or toast), or an action (a button).
Instead:
Variants
What each variant is for in any design system, then what Dense data decided and why. Each sample is the live story with that variant set.
neutraltoneUsed in Dense dataWhat it is for
A label with no status meaning: a category, a count, a waiting state.
In Dense data
New and False positive: not triaged yet, or a finished outcome that is not a failure.
infotoneUsed in Dense dataWhat it is for
News: worth knowing, nothing to act on.
In Dense data
Investigating: an analyst is on it; news, nothing to act on.
successtoneUsed in Dense dataWhat it is for
Done, healthy or paid.
In Dense data
Resolved: contained and closed.
warningtoneUsed in Dense dataWhat it is for
Needs attention soon; nothing has failed yet.
In Dense data
Escalated: needs a senior analyst soon, still containable.
dangertoneUsed in Dense dataWhat it is for
Failed, blocked or lost; act now.
In Dense data
Breach confirmed: a real loss.
How Dense data uses it
Why it works this way
Badge looks the way it does because of 2 answers about this product. Each card is one answer, in three steps: the answer, what it decided for Badge, and what would move if it changed.
accessibility.count1The answer
Many statuses share one table; color alone is not enough.
2So Badge
- ✓uses neutral: New and False positive: not triaged yet, or a finished outcome that is not a failure.
- ✓uses info: Investigating: an analyst is on it; news, nothing to act on.
- ✓uses success: Resolved: contained and closed.
- ✓uses warning: Escalated: needs a senior analyst soon, still containable.
- ✓uses danger: Breach confirmed: a real loss.
Alert: destructive3If it changed
No other answer follows from it.
content.q11The answer
Most of the screen is numbers and records.
2So Badge
- ✓uses neutral: New and False positive: not triaged yet, or a finished outcome that is not a failure.
- ✓uses info: Investigating: an analyst is on it; news, nothing to act on.
- ✓uses success: Resolved: contained and closed.
- ✓uses warning: Escalated: needs a senior analyst soon, still containable.
- ✓uses danger: Breach confirmed: a real loss.
Sidebar: default Sidebar: outline Empty: default Item: default Item: outline Toggle: default Toggle: outline3If it changed
and 44 answers that follow from it: A lot, Scan and compare, People keep their place, and 41 more.
Words
- Lead with the object, then the state: "Alert 2041 contained."
- Use numbers, not words for numbers.
- One verb per button. No "please", no exclamation marks.
- Use: Investigate, Filter, Assign, Escalated, Resolved. Avoid: Oops, Awesome, Please, Simply.
The labels components use, from the voice tokens:
content.action.commit: Savecontent.action.cancel: Cancelcontent.action.destroy: Deletecontent.action.retry: Retrycontent.action.empty-action: Change filters
See Voice and tone for the whole voice.
Accessibility and keyboard
Test before you ship:
- The status is a word; color and icon add to it, never replace it. undefined
Use it in code
npx open-ds add badge
The component reads only component keys and semantic tokens, so it follows the brand and mode on <html>.
Tokens it reads
Badge reads 17 tokens of its own, each an alias of a semantic token. Each row is one part: its own token, the semantic it aliases, and the value it ends at. Change a semantic and every component that reads it follows; override one of Badge's tokens to change Badge alone.
Dense data decides what changes when you switch theme. Here a switch changes colors only, so the marked rows differ between light and dark; everything else holds steady.
| Part | Its token and the semantic it aliases | Value |
|---|---|---|
| Badge | ||
| Corner | component.badge.radiusradius.badgevar(--badge-radius) | radius.0:0rem |
| Padding, left and right | component.badge.padding-xspace.gap.tightvar(--badge-padding-x) | space.4:0.25rem |
| Text size | component.badge.font-sizetype.caption.font-sizevar(--badge-font-size) | font.size.12:0.75rem |
| Gap | component.badge.gapspace.gap.tightvar(--badge-gap) | space.4:0.25rem |
| Padding, top and bottom | component.badge.padding-ycomponent-spacing-map.hairlinevar(--badge-padding-y) | space.2:0.125rem |
| Weight | component.badge.font-weighttype.label.font-weightvar(--badge-font-weight) | font.weight.500:500 |
| Font family | component.badge.font-familytype.caption.font-familyvar(--badge-font-family) | font.family.ibm-plex-sans:"IBM Plex Sans", system-ui, sans-serif |
| Neutral | ||
| Fill Changes with theme | component.badge.neutral.backgroundcolor.surface.sunkenvar(--badge-neutral-background) | Lightslate.light.100:#EEF1F5Darkslate.dark.100:#262D38 |
| Text Changes with theme | component.badge.neutral.labelcolor.text.secondaryvar(--badge-neutral-label) | Lightslate.light.700:#3D4655Darkslate.dark.500:#C4CBD6 |
| Success | ||
| Fill Changes with theme | component.badge.success.backgroundcolor.status.success.subtlevar(--badge-success-background) | Lightgreen.light.100:#DBF7DFDarkgreen.dark.100:#01351A |
| Text | component.badge.success.labelcolor.text.success-on-lightvar(--badge-success-label) | green.light.800:#023E17 |
| Warning | ||
| Fill Changes with theme | component.badge.warning.backgroundcolor.status.warning.subtlevar(--badge-warning-background) | Lightamber.light.100:#FEE8CFDarkamber.dark.100:#3F2B02 |
| Text | component.badge.warning.labelcolor.text.warning-on-lightvar(--badge-warning-label) | amber.light.800:#462A02 |
| Danger | ||
| Fill Changes with theme | component.badge.danger.backgroundcolor.status.danger.subtlevar(--badge-danger-background) | Lightred.light.100:#FFDBD8Darkred.dark.100:#4C171A |
| Text | component.badge.danger.labelcolor.text.danger-on-lightvar(--badge-danger-label) | red.light.800:#6D0008 |
| Info | ||
| Fill Changes with theme | component.badge.info.backgroundcolor.status.info.subtlevar(--badge-info-background) | Lightblue.light.100:#D3E4FFDarkblue.dark.100:#162C4F |
| Text | component.badge.info.labelcolor.text.info-on-lightvar(--badge-info-label) | blue.light.800:#001A4E |