All components
Data Display

Badge

stable
Since 1.2
Compact status or metadata label with six semantic tones plus seven non-semantic accent tones, four treatments, a pill or square shape, three sizes, dots, counts, adornments, and optional press and remove actions.
Data Display
primitive
Display
Documented
import { Badge } from '@ivim/native/components';

When to use

Use when
Labelling the state of a record — active, pending, failed.
Showing a small count or category beside a title.
Don't use when
The values are a filter the user selects — use TagGroup, which announces selection.
The label is the primary action — use Button.
There are several related labels forming a sentence — use BadgeGroup.

Playground

Adjust the controls to preview live prop combinations. The code snippet updates to match the current selection.
Active
tone
tone
variant
variant
shape
shape
size
size
Dot
dot
Label
children
<Badge>Active</Badge>

Example

Tones
Every tone, subtle
neutral
brand
success
warning
error
info
Solid
neutral
brand
success
warning
error
info
Outline and modern
Outline
Modern
Accent tones (non-semantic — for categories, not state)
gray-blue
blue-light
blue
indigo
purple
pink
orange
Shape
Pill (default) and square
Pill
Square
Square composes with every treatment
Subtle
Solid
Outline
Modern
Sizes and adornments
Sizes (sm, md, lg)
Small
Medium
Large
With a status dot
Live
Draft
Failed
With an icon and a count
Verified
Alerts
12
Actions
Actionable (announces as a button)
Removable (separate named control)
Design
Both, as distinct actions

Anatomy

The parts that compose this component.
1
Container
Pill carrying the tone fill, border, and radius.
2
Dot
Optional status indicator before the label.
3
Leading / trailing
Optional icon, flag, or image.
4
Label
The text carrying the meaning.
5
Count
Optional trailing number.
6
Remove control
Separate named button, present only with onRemove.

Guidelines

Do
Put the meaning in the label text; tone reinforces it but is never the only signal.
Do
Use the modern treatment on tinted surfaces, where a subtle badge would disappear.
Do
Keep labels to a word or two — a badge that wraps has become a sentence.
Don't
Add onPress unless the badge really performs an action; a decorative pill with a button role offers something that does nothing.
Don't
Rely on tone alone to distinguish states for colour-blind users.

Props

Public props for this component. Required props are marked; defaults reflect the component implementation.
tone
'neutral' | 'brand' | 'success' | 'warning' | 'error' | 'info' | 'gray-blue' | 'blue-light' | 'blue' | 'indigo' | 'purple' | 'pink' | 'orange'
default: 'neutral'
Colour. The first six are semantic (mapped to status tokens); the seven accent tones are non-semantic — use them for categories, never state.
variant
'subtle' | 'solid' | 'outline' | 'modern'
default: 'subtle'
Treatment. Modern is a neutral surface with a hairline, for tinted backgrounds.
shape
'pill' | 'square'
default: 'pill'
Corner treatment, orthogonal to variant. Pill is full-radius; square is a small rounded rect (Untitled UI pill-color vs badge-color).
size
'sm' | 'md' | 'lg'
default: 'md'
Height, padding, and text scale.
dot / leading / trailing / count
boolean / ReactNode / ReactNode / number
Adornments around the label.
onPress
() => void
Makes the badge a named button.
onRemove
() => void
Adds a separate remove control named "Remove {label}".
aria-label
string
Accessible name when there is no visible label, or when the label is not plain text.

Deviations from Untitled UI

Where this component deliberately differs from Untitled UI's API, and why. These are kept choices, not gaps to close.
Untitled UI
`type` conflates shape and fill (`pill-color` / `badge-color` / `badge-modern`); a single `color` axis with 12 values
Ours
`variant` (`subtle | solid | outline | modern`) × `tone` × `shape` (`pill | square`)
Fill (variant), semantic/accent color (tone), and outline shape (shape) are three orthogonal axes instead of Untitled UI’s conflated `type`. Resolving the earlier Phase 4 decision, the seven non-semantic accent tones (`gray-blue`, `blue-light`, `blue`, `indigo`, `purple`, `pink`, `orange`) were added via accent ramps in `@ivim/isomorphic/branding`, and the `shape` axis expresses the pill-vs-badge distinction.

Accessibility

Roles and screen-reader behavior this component provides, plus keyboard interactions.
A bare badge takes no accessibility role — it is content, and a button role would offer an action that does nothing.
onPress makes it a named button; onRemove adds a separate control named "Remove {label}".
Tone is never the only signal: the label text always carries the meaning (NFR-T4).
Adornments are visual; the accessible name comes from the label or an explicit aria-label.
Tab
Reaches the badge only when it is actionable.
Space / Enter
Activates the badge or its remove control.

Platform & RTL

Behavior that differs across the platforms this component runs on.
Web
Actionable badges get an inset focus ring matched to the pill radius.
iOS
Press feedback from PressableFeedback when actionable.
Android
Adds a ripple when actionable.
RTL
Dots, adornments, and the remove control mirror with the writing direction.

State coverage

Interaction and visual states this component supports.
base
semantic color
density

Token references

Semantic design tokens this component page exercises. Tap one to edit it live.