Skip to content

ComponentsCollections

Tag Group

A focusable group of compact labels, keywords or filters. Tags can be colored, selected (single or multiple), removed with the keyboard or a button, act as links or actions, and come in soft and outline variants at two sizes.

React AriaSource
Interests
Design
Engineering
Security
Product
Data

Installation

pnpm dlx shadcn@latest add @desyne/tag-group

The CLI installs dependencies and any other components this one uses.

Usage

tsx
import { Tag, TagGroup } from "@/components/ui/tag-group";
tsx
<TagGroup label="Labels">
  <Tag color="danger">bug</Tag>
  <Tag color="info">docs</Tag>
</TagGroup>

When to use

  • Tag Group — a set of short labels users scan, filter by or remove: labels on an issue, active filters, selected skills.
  • Badge — a single, non-interactive status or count.
  • Toggle Button Group — a few mutually exclusive options that behave like buttons in a toolbar.
  • Checkbox Group — many options in a form with their own labels and descriptions.
  • Combo Box with a Tag Group — picking from a long list and showing the picks as tags.

Anatomy

tsx
<TagGroup>          {/* label, list, description, error */}
  <Tag>             {/* role="row" */}
    <Icon />
    Label
    {/* remove button, when onRemove is set */}
  </Tag>
</TagGroup>
PartRendersNotes
TagGroup<div>Root with label, description and errorMessage. data-slot="tag-group".
Tag list<div role="grid">Wrapping flex row of tags. Shows renderEmptyState when empty.
Tag<div role="row">A tag. Plain-string children become its textValue. data-slot="tag".
Remove button<button slot="remove">A small ✕, rendered automatically when the group has onRemove.
Label<span>From label.
Description / error<span slot="…">From description and errorMessage.

Examples

Colors

A color gives a tag the tinted soft look. Without a color, tags use the neutral outline style.

feature
bug
needs review
approved
docs
chore

Variants

Set variant on the group to style every tag: outline (default without a color) or soft. A variant on an individual Tag overrides it.

Outline (default)
frontend
accessibility
good first issue
docs
Soft
frontend
accessibility
good first issue
docs

Sizes

sm (20px) for dense tables and cards, md (24px) by default. Set it on the group or per tag.

Small
stable
v2.4.0
MIT
Medium (default)
stable
v2.4.0
MIT

With icons

Icons are sized to 12px automatically. Pass textValue when children aren't a plain string.

Change type
Feature
Bug fix
Performance
Security
Chore

Single selection

selectionMode="single" turns tags into choice chips. Add disallowEmptySelection so one is always selected. Selected tags always use the solid primary style.

Shipping speed
Economy · 5–8 days
Standard · 3–5 days
Express · 1–2 days
Overnight

Controlled selection

selectedKeys and onSelectionChange own the selection in multiple mode. Handle both a Set of keys and "all".

Favorite cuisines
Italian
Japanese
Mexican
Indian
Thai
Ethiopian
Lebanese

We'll suggest Japanese, Thai places.

Removable tags

onRemove adds a remove button to every tag and enables Backspace / Delete. It receives the keys to remove; useListData makes updating the list a one-liner. renderEmptyState shows when the last tag is gone.

Skills
react
typescript
tailwindcss
react-aria
vitest
Backspace or Delete removes the focused tag.

Disabled tags

disabledKeys keeps tags visible but not focusable, selectable or removable.

Available sizes
XS
S
M
L
XL
XXL
Sold-out sizes are disabled.

Actions

onAction makes tags actionable without selecting them, for suggestions and quick filters.

Popular searches
pricing
refund policy
API rate limits
SSO setup
export data

Click a suggestion to search.

Give tags an href to render them as links. They work with client-side routers through React Aria's RouterProvider.

Related topics
Forms
Dates
Collections
Overlays

Description and error

description explains the group; errorMessage replaces it with red text. Both are linked to the tag list for screen readers. Tag groups have no built-in validation, so decide when to show the error yourself.

Teams you want to hear from
Design
Engineering
Product
Data
Security
Marketing
Sales
You can pick up to 3 teams (4 selected).

Recipes

Tag input

A TextField adds a tag on Enter, with duplicate detection and a maximum count. The tags below are removable.

Press Enter to add.
billing
enterprise
2 of 6 labels

Filter chips

Pill-shaped, single-select chips that filter a list. disallowEmptySelection guarantees an active filter.

All
Design
Engineering
Product
  • Designing accessible date pickers8 min
  • Server components and client islands12 min
  • How we price usage-based plans6 min
  • Color tokens that survive dark mode5 min
  • Zero-downtime Postgres migrations15 min
  • Writing a changelog people read4 min

Active filters bar

Removable soft tags that summarize applied filters, with a "Clear all" action. Each tag's textValue reads the field and value together.

Filters
Status:Open
Assignee:Me
Label:bug
Updated:Last 7 days

Accessibility

  • The tag list is a role="grid" and each tag a role="row", so screen readers announce position and selected state. The group is labelled by label (or aria-label).
  • The whole group is one tab stop; arrow keys move between tags. If the last tag is removed while focused, focus moves to the list itself so it isn't lost.
  • Remove buttons are labelled "Remove" together with the tag text. Keyboard users can also press Backspace / Delete on the focused tag.
  • description and errorMessage are linked with aria-describedby.
  • Colors are decoration only. Put the meaning in the text ("bug", "blocked"), not just the color.

Keyboard

KeyAction
TabMoves focus into and out of the group
← / →Moves between tags (reversed in RTL)
Home / EndMoves to the first / last tag
Space / EnterSelects the tag, triggers onAction or follows a link
Backspace / DeleteRemoves the focused tag (with onRemove)
EscClears the selection

Styling

Data attributes

On each Tag:

AttributePresent when
data-selectedThe tag is selected (solid primary style)
data-focused / data-focus-visibleThe tag has focus / keyboard focus
data-hovered / data-pressedHovered with a mouse / being pressed
data-disabledThe tag is disabled
data-allows-removingThe group has onRemove
data-selection-modesingle or multiple

On the tag list (the element with role="grid"): data-empty, data-focused, data-focus-visible. The root TagGroup is a Tailwind group (group/field).

Slots

data-slotElement
tag-groupRoot
tagEach tag
label, descriptionField text

Tone variables

Like Button, tag colors come from the --tone variable, so a one-off color is just a class:

tsx
<Tag color="primary" className="[--tone:var(--color-pink-600)]">design</Tag>
  • className on TagGroup styles the root (a string). className on Tag accepts a function of the render props.
  • Add rounded-full px-3 to a Tag for pill-shaped chips.

API Reference

TagGroup

Prop

Type

Also accepts every prop of React Aria's TagGroup.

Tag

Prop

Type

  • Badge — static status labels with the same colors.
  • Combo Box — pick from a long list, then show picks as tags.
  • Toggle Button Group — segmented choices.
  • List Box — a vertical list of selectable options.