Search for a command to run...
A removable chip for user-defined values — keywords, selected filters, picked recipients. Composes Badge and adds a remove affordance.
Tag is Badge plus an optional remove button. It carries every Badge variant
and size; pass onRemove to render a trailing ×. Its squarer rounded-lg
corners set it apart from a status Badge. Without onRemove it's a plain,
non-interactive chip.
The remove button only renders when onRemove is set. It uses control.ghost
and reports through removeLabel for screen readers.
Inherited from Badge — subtle (default) suits user-defined values; outline
and solid raise emphasis.
Inherited from Badge, but Tag defaults to sm — tags usually sit in dense
lists. Step up to default/lg when tags are a primary surface (e.g. the affiliate
product keyword editor uses lg).
| Prop | Type | Default | Description |
|---|---|---|---|
onRemove | () => void | — | When set, renders a trailing remove button that calls this on click. |
removeLabel | string | "Remove" | Accessible label for the remove button. Make it specific (Remove cozy). |
variant | Badge variant | "subtle" | Visual style, forwarded to Badge. |
size | Badge size | "sm" | Padding/typography scale, forwarded to Badge. |
Use Tag for user-defined, removable values — keyword inputs, selected audience members,
applied filters. The body accepts arbitrary children, so leading dots or avatars compose in
front of the label.
Give every onRemove a specific removeLabel (Remove cozy, not Remove) so the affordance
is unambiguous to screen readers in a list of chips.
Keep subtle for categorical values; reserve solid/outline for higher-emphasis selections.
Hand-roll a remove button next to a Badge. That's exactly what Tag replaces — the
trailing-padding tightening and the control.ghost hover come for free.
Use Tag for static status. A non-removable label is a Badge — only reach for Tag when
there's a remove action.