AntaTag
Switch to dark theme
Search documentation
On this page

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.

Playground

Priority

priority sets the emphasis. secondary (the default) is the subtle alpha-tint fill; primary is a solid fill with white text; tertiary is a transparent outline. It composes with every tone — named or custom — and tracks dark mode.

PrimarySecondaryTertiary
<Tag allcaps priority="primary" tone="brand" label="Primary" />
<Tag allcaps tone="brand" label="Secondary" />
<Tag allcaps priority="tertiary" tone="brand" label="Tertiary" />

Tone

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.

NeutralBrandInfoSuccessWarningCritical
<Tag allcaps label="Neutral" />
<Tag allcaps tone="brand" label="Brand" />
<Tag allcaps tone="info" label="Info" />
<Tag allcaps tone="success" label="Success" />
<Tag allcaps tone="warning" label="Warning" />
<Tag allcaps 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.

MagentaPurpleTeal
<Tag allcaps tone="#ff1493" label="Magenta" />
<Tag allcaps tone="rebeccapurple" label="Purple" />
<Tag allcaps tone="#0d9488" label="Teal" />

Every tone — named or custom — paints its fill and border as semi-transparent alpha tints rather than solid colors, so a tag picks up whatever surface sits behind it. Here the same tags sit on a --bg-4 panel instead of the page canvas.

NeutralBrandSuccessCriticalMagentaTeal

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.

SmallMediumLarge
<Tag allcaps tone="info" size="small" label="Small" />
<Tag allcaps tone="info" label="Medium" />
<Tag allcaps tone="info" size="large" label="Large" />

Icon, label, and 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.

BuildpassedRunning20m 16sCommit4f90d13Retries3
<Tag allcaps tone="success" icon="circle-check" label="Build" value="passed" />
<Tag allcaps tone="info" icon="hourglass" label="Running" value="20m 16s" />
<Tag allcaps icon="history" label="Commit" value="4f90d13" />
<Tag allcaps 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.

v2.1.0stablex64GET200142 msExit 137OOM
<Tag allcaps>
<span>v2.1.0</span>
<span>stable</span>
<span>x64</span>
</Tag>
<Tag allcaps tone="info">
<span>GET</span>
<span>200</span>
<span>142 ms</span>
</Tag>
<Tag allcaps tone="critical" icon="warning-triangle">
<span>Exit 137</span>
<span>OOM</span>
</Tag>

Case

Tags are normal (mixed) case by default, so the text is read as written — proper names, identifiers, and case-sensitive IDs keep their shape (GitHub, not GITHUB). Pass allcaps for the uppercase treatment: at this small size all-caps reads as a label at a glance and keeps a uniform, scannable shape, which suits short status words where the exact case carries no meaning. Without a theme, both treatments use 0.1ch tracking. Antune and Antithesis retain their font-specific 0.02ch mixed-case and 0.08ch uppercase tracking. All-caps steps each size down 1px, since caps read larger than mixed case at the same size.

GitHubv1.6.9Running
<Tag icon="external-link" label="GitHub" value="v1.6.9" />
<Tag allcaps label="Running" />

Component props

Prop Type Default Description
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.
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.
tone? neutralbrandcriticalinfosuccesswarningstring neutral Semantic tone, or any literal CSS color ('#ff1493', 'rebeccapurple') for a one-off custom tone. Each tone renders the secondary tag style: --text-3-{tone} text over an alpha tint of the tone's hue (fill + a slightly stronger hairline border). A custom color is tinted the same way, with the text deepened to a readable foreground. 'neutral' (the default) is the gray tag — the same as omitting tone.
priority? primarysecondarytertiary secondary Emphasis level. secondary (the default) is the subtle alpha-tint fill; primary is a solid fill with white text; tertiary is a transparent outline. Omitting it (or passing 'secondary') renders the default and emits no DOM attribute.
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.
allcaps? boolean Render in all-caps instead of the default normal (mixed) case.
icon? IconShape Leading icon shape. Sits flush before the label, scaled to the pill.
iconTrailing? IconShape Trailing icon shape. Renders last, after the value.
Inherited props (children, className, id, slot, style, tabIndex, title)
Prop Type Default Description
children? ReactNode Child elements. When provided, replaces the component's default label/content.
className? string CSS class on the component's root element (merged with the component's own classes). Use it directly for layout and positioning — grid/flex placement, margins, alignment — rather than wrapping the component in a <div>/<span>.
id? string HTML id attribute.
slot? string Assigns the element to a named <slot> of a parent web component (e.g. slot="header" inside a <Card>, slot="footer" inside a <Dialog>).
style? CSSProperties Inline styles on the component's root element. Set layout/positioning here (or via className) directly on the component instead of adding a wrapper.
tabIndex? number Tab order. Set to -1 to skip the element when tabbing.
title? string HTML title attribute — native browser tooltip on hover.

Plus every standard DOM event handler (onClick, onFocus, onKeyDown, …) and any data-* or aria-* attribute — forwarded as-is to the underlying <a-*> element.

Web Component

Use the web component directly when you are not using React or Preact and a native control does not fit.

Use a-tag-label for the key and a-tag-value for its value.

BuildPassed
<a-tag tone="success">
<a-icon shape="check" aria-hidden="true"></a-icon>
<a-tag-label>Build</a-tag-label>
<a-tag-value>Passed</a-tag-value>
</a-tag>

Styling

Reach for the props first: tone sets the color (any CSS color for a custom tone — it derives the fill / border / text in oklch), priority the fill style, size the dimensions.

<Tag allcaps tone="#e0457b" priority="secondary" label="Custom" />

<a-tag> is light-DOM, so for anything a tone can’t give you it’s plain CSS (an un-layered rule beats @layer anta without !important). The .badge class below takes a gradient background (impossible from tone, which is a solid color), 1px corners, and taller vertical padding so it reads completely differently:

StatusActive
a-tag.badge {
background: linear-gradient(135deg, #1f6e5f, #845ec2); /* a tone can't do gradients */
color: #fff;
border-radius: 1px; /* sharp corners */
padding-block: 5px; /* tighter vertical padding */
padding-inline: 14px;
}
a-tag.badge a-tag-label { font-weight: 600; letter-spacing: 0.15ch; }

For a solid recolor, prefer tone / priority — don’t reach for the resolved --tag-bg / --tag-border / --tag-text (they’re recomputed per priority and tone).

Interactive tags

Tag is presentational. Wrap it in an anchor for navigation or a native button for an action. The outer control receives focus and keyboard activation.

Build#42
<a className="tag-link" href="/builds/42">
<Tag tone="info" icon="external-link" label="Build" value="#42" />
</a>
a.tag-link {
display: inline-flex;
text-decoration: none;
cursor: pointer;
}

A removable tag has one interactive child: its remove Button. Keep the label as tag content, give the button an accessible name, and let the segment divider separate it. Remove the tag’s block padding so the small button keeps its target size. The negative focus offset keeps its focus ring inside the tag’s clipped edge.

Frontend
<Tag className="removable-tag" tone="info">
<span>Frontend</span>
<Button priority="quaternary" size="small" icon="x" aria-label="Remove Frontend" />
</Tag>
a-tag.removable-tag {
padding-block: 0;
}
a-tag.removable-tag > a-button {
align-self: stretch;
}
a-tag.removable-tag > a-button:focus-visible {
outline-offset: -2px;
}

When a tag both opens something and removes it, render two sibling controls in a compound layout. Do not place a remove button inside an anchor or button that wraps the tag.