Tag Group
Display, select, and remove a keyboard-navigable collection of tags.
Installation
pnpm dlx shadcn@4.18.0 add @siteplane/tag-groupComplete the one-time setup first. Registry JSON lists source files and dependencies.
For this page’s examples, also install:
pnpm dlx shadcn@4.18.0 add @siteplane/form @siteplane/inputUsage
import { TagGroup, Tag } from "@/siteplane/components/tag-group";
<TagGroup aria-label="Labels">
<Tag>Design</Tag>
</TagGroup>;Composition
TagGroup
└── Tag (direct child or fragment)Tags wrap onto new rows as the group needs. A tag is never wider than the group: a long or unbroken label, such as a URL, ends with an ellipsis and keeps its remove button, and the full text is the label's title, so the group never makes a card or a column wider than the space it has.
Selectable tags
Pass selected and onSelectedChange to make a tag selectable; the application owns the selected set. For a tag that keeps its own state, pass defaultSelected instead.
Removable tags
Pass onRemove to add a remove button and keyboard removal, then remove that tag from your state. Use removeLabel to name each remove button.
Adding and removing tags
Tags animate on their own: a tag you add fades in, a tag you remove fades out, and the tags around it glide to their new place. When a row of tags appears or goes, the height of the group follows instead of jumping. A tag that is leaving is hidden from assistive technology and takes no input; removal by keyboard still moves focus to the next tag. Reduced motion changes the tags at once.
Sizes
Set size on the group; every tag in it uses that size.
API reference
| Prop | Type | Default | Description |
|---|---|---|---|
Tag | sm | md | lg | xl | provider / lg | Tag dimensions. |
Tag | number | -1 | Root fallback focus target. Other div props except role are accepted. |
Tag. | ReactNode | Required | Tag content and extracted text value. |
Tag. | boolean | false | Controlled selected state. |
Tag. | boolean | unset | Initial selection of an uncontrolled tag, which is then selectable without a handler. |
Tag. | (selected: boolean) => void | — | Makes the tag selectable. |
Tag. | () => void | — | Adds remove affordance and keyboard removal. |
Tag. | string | Remove tag | Accessible label for remove action. |
Tag. | boolean | false | Dims the tag and disables its selection and removal. |
Tag motion / span props | TagProps | — | Motion span props except layout, layoutDependency, onClick, role, tabIndex, transition and children. |
Exported types: TagGroupProps, TagProps. These describe the contracts above.
Usage notes
Keep stable React keys when adding and removing tags: an index as the key makes a removed tag leave as its neighbor. Only direct Tag children and fragments enter the collection; do not wrap each Tag in an application component. The group owns the animation of its tags and respects reduced motion; it uses the Motion component, which installs with it. This is not a named form field: serialize selected values in your application.