Tag
A compact pill for status, labels, and metadata. The Tag JSX wrapper
renders an <a-tag> styled tag — there’s no JavaScript, so tone, size,
and case are all plain attributes and the styling is identical whether
you use the wrapper or author the element by hand. Content is composed
from icon, label, value, and iconTrailing props, the same way
Button works.
Play with it in playground.
Tones
Omit tone for the neutral gray tag, or pick a semantic tone. Color
comes from the theme tokens, so every tone tracks light and dark mode
automatically.
<Tag label="Neutral" /><Tag tone="brand" label="Brand" /><Tag tone="info" label="Info" /><Tag tone="success" label="Success" /><Tag tone="warning" label="Warning" /><Tag tone="critical" label="Critical" />tone also accepts any literal CSS color for a one-off tag. The hue is
kept while lightness and chroma are pinned to the named-tone curve.
<Tag tone="#ff1493" label="Magenta" /><Tag tone="rebeccapurple" label="Purple" /><Tag tone="#0d9488" label="Teal" />Icon, label & value
Set icon / iconTrailing for a leading or trailing glyph (scaled to
the pill), and pair label with value for a two-part tag. value is
the primary text (default color and weight); the label sits before it
as a bold “key” (weight 600, same color) with no divider — the weight
contrast does the separating. Tabular figures are always on, so counts,
versions, and timers don’t reflow.
<Tag tone="success" icon="circle-check" label="Build" value="passed" /><Tag tone="info" icon="hourglass" label="Running" value="20m 16s" /><Tag icon="github-logo" label="Commit" value="4f90d13" /><Tag tone="warning" label="Retries" value="3" iconTrailing="refresh" />Segments
For an arbitrary multi-part tag, pass several children instead of
label / value — each segment after the first gets a hairline divider
(a leading icon stays flush). The divider-less label + value
pairing is the exception; everything else segments like this.
<Tag> <span>v2.1.0</span> <span>stable</span> <span>x64</span></Tag><Tag tone="info"> <span>GET</span> <span>200</span> <span>142 ms</span></Tag><Tag tone="critical" icon="warning-triangle"> <span>Exit 137</span> <span>OOM</span></Tag>Size
Three sizes — small (16px), medium (20px, the default — emits no
attribute), and large (24px) — matching Button. Height is intrinsic
(line-height + padding rather than a fixed value), so the text is never
clipped.
<Tag tone="info" size="small" label="Small" /><Tag tone="info" label="Medium" /><Tag tone="info" size="large" label="Large" />Case
Tags are uppercase by default: a tag is a concise marker, not prose, so
at this small size all-caps reads as a label at a glance and keeps a
uniform, scannable shape — the word-shape cues that aid long-form
reading don’t matter for a word or two. Pass nocaps when the case
itself carries meaning — proper names, identifiers, or case-sensitive
IDs. Here all-caps would flatten the brand name to GITHUB; nocaps
keeps it as GitHub.
<Tag icon="github-logo" label="GitHub" value="v1.6.9" /><Tag icon="github-logo" nocaps label="GitHub" value="v1.6.9" /> Playground
Component props
| Prop | Type | Default | Description |
|---|---|---|---|
| icon? | IconShape | — | Leading icon shape. Sits flush before the label, scaled to the pill. |
| iconTrailing? | IconShape | — | Trailing icon shape. Renders last, after the value. |
| label? | string | — | A short "key" shown before the value. When paired with value it
renders bold (weight 600), same color. On its own (no value) it's
treated as the tag's primary text and keeps the default styling. |
| nocaps? | boolean | — | Render in normal (mixed) case instead of the default uppercase (keeps Anta's small body-text letter-spacing; uppercase tracks wider). |
| size? | smallmediumlarge | medium | Size variant. small = 16px tall, medium = 20px, large = 24px
(matching Button). Omit the attribute or pass 'medium' for the
default — both render identically and emit no DOM attribute. |
| tone? | neutralinfobrandsuccesscriticalwarningstring | neutral | Semantic tone, or any literal CSS color ('#ff1493', 'rebeccapurple')
for a one-off custom tone. Named tones map to the --text-2-{tone} /
--bg-4-{tone} palette; a custom color keeps its hue while lightness
and chroma are pinned. 'neutral' (the default) is the gray tag —
the same as omitting tone. |
| value? | string | — | The tag's primary text — a status, count, version, duration, etc. Rendered in the default color and weight, with no divider from the label; the color + weight contrast does the separating. |
Inherited props (children, className, id, style, tabIndex, title)
| Prop | Type | Default | Description |
|---|---|---|---|
| children? | ReactNode | — | Child elements. When provided, replaces the component's default label/content. |
| className? | string | — | CSS class name. Merged with any internal classes by the component. |
| id? | string | — | HTML id attribute. |
| style? | CSSProperties | — | Inline styles applied to the root element. |
| tabIndex? | number | — | Tab order. Set to -1 to skip the element when tabbing. |
| title? | string | — | HTML title attribute — native browser tooltip on hover. |
Component tokens
Override any of these on a single instance
(style={{ '--tag-bg': 'var(--bg-5)' }}) or on a selector wrapping the
tag. The named tones set --tag-text / --tag-bg from the theme
palette; the border derives from --tag-text, so a custom --tag-text
retints it automatically.
| Token | Description |
|---|---|
--tag-text | Primary text (value) and icon color. The hairline border derives from this. |
--tag-bg | Background fill. |
--tag-border | Outer hairline. Defaults to --tag-text at 9% alpha. |
--tag-separator | Divider between segmented children. Defaults to --tag-text at 30% alpha. |
--tag-padding-block--tag-padding-inline | Inner spacing. Drives the intrinsic height (small overrides both). |
--tag-gap | Space between icon / label / value (default 0.6ch). |
--tag-icon-size | Leading / trailing icon size (13px medium, 11px small, 15px large). |
--tag-label-weight | Weight of the label key (default 600). |