Tag
Status: stableAccessibility reviewedtenet-ui@0.4.0
import { Tag } from 'tenet-ui';Also accepts every prop of HTMLAttributes<HTMLSpanElement>.
Source: src/components/Tag/Tag.tsx
Usage guidelines
Section titled “Usage guidelines”When to use: a short word attached to an item. Tag is the system’s one pill and has two modes:
- Read-only status or category (no
onRemove):Published,In review,Draft,Culture. Pickvariantby meaning. - Removable chip (
onRemoveset): a user-applied token the user can dismiss — an active filter, a selected recipient, a keyword.
When to use a neighbour instead:
- For a count or presence dot (
3 unread) useBadge. Badge is a number or a dot; Tag is a word. - For a contextual message with a sentence of text use
Banner, not a long Tag. - If the chip’s whole body should toggle a choice, use
SegmentedControlorCheckbox, not a Tag with a click handler on the span. Label(0.3.0 and earlier) is deprecated: it was a second pill with the same variants. Replace<Label variant="success">with<Tag variant="success">. The name is now free of theFormControl.Labelcollision.
- Choose
variantby meaning, never by colour:successfor positive/done,dangerfor problems or blocked,attentionfor pending/needs review,accentfor the active or selected token,mutedfor quiet neutrals (drafts, archived),defaultotherwise. Do not compute your own fills or borders from a hex value — that is the anti-pattern this component removes. - Map data to a variant once, in one place:
const variant = statusVariant[article.status]. - Tag is stateless. Setting
onRemoverenders a real<button>, but Tag never removes itself — your handler must drop the item from the collection you render from. - The remove control is a real
<button>so it is keyboard operable (Tab, then Enter/Space) with a:focus-visiblering. Never replace it with a clickable<span>. - The remove button is named automatically:
Remove ${text}whenchildrenis a string. Ifchildrenis not a plain string (icon + element), passremoveLabel. leadingIconand the ✕ glyph are decorative (aria-hidden); meaning comes from the text and, for removal, the button label. Use an icon fromtenet-ui/iconsat size 16.- Tag text is normal-case, readable words (sentence case, one or two words). Do not uppercase it and do not put a sentence in it.
- A read-only Tag must not carry
onClick; if a status needs to be actionable, put the action in aMenuorButtonnext to it.
Do / Don’t
Section titled “Do / Don’t”- ✅
<Tag variant="success">Published</Tag>— read-only status word. - ✅
<Tag variant="accent" onRemove={() => setFilters((f) => f.filter((x) => x !== id))}>{name}</Tag>— removable filter chip; the parent drops the item. - ✅
<Tag leadingIcon={<UserIcon />} removeLabel="Remove Ada Lovelace">Ada</Tag>— named remove button when children are not a plain string. - ❌
<Tag onRemove={() => {}}>Design</Tag>— a no-op handler; the chip looks removable but nothing happens. - ❌
<span className="pill" style={{ background: 'rgba(79,111,58,.15)', color: '#3c5630' }}>Published</span>— hand-tuned colours; reinvents the component. - ❌
<Label variant="success">Published</Label>— deprecated; useTag.
Examples
Section titled “Examples”6 stories for Tag — open in Storybook
- Default
components-tag--default - Variants
components-tag--variants - Status Pills
components-tag--status-pills - Sizes
components-tag--sizes - With Icon
components-tag--with-icon - Removable
components-tag--removable
The full matrix (all args, controls, accessibility panel) is in Storybook.
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'default' | 'accent' | 'success' | 'danger' | 'attention' | 'muted'TagVariant | default | Semantic color scheme. Pick by meaning, never by raw color: accent for an active/selected token, success / danger / attention for status words, muted for a quiet neutral, default otherwise. |
size | 'small' | 'medium'TagSize | medium | Tag size. |
leadingIcon | ReactNode | — | Optional leading icon rendered before the label; decorative (aria-hidden). |
children | ReactNode | — | The tag label content. |
onRemove | () => void | — | When provided, renders a real remove button. Wire it to drop the tag from your collection. Tag does not remove itself — it has no internal state. |
removeLabel | string | — | Accessible label for the remove button when children is not a plain string. Falls back to the string children, otherwise "Remove". |