Preview
Design guidance
Use Tag Group for a compact set of visible options, such as project labels, content filters, assistant capabilities, onboarding preferences or survey answers. It owns collection selection and limits through Ghost Checkbox Group or Radio Group. Each item delegates to TagItem.Selectable; custom entry is the same TagItem.Input owner. The shared TagItem view owns appearance. Tag Group uses its outline variant at the 32px base size; tags inside an input use the smaller filled style. Use Tag Input when users enter or search for values, and Badge for passive metadata. Give the group an accessible name. The application owns the option list, selected values and any selection limit.
Installation
Install fieldset or field as well when using the labelled example compositions.
Basic usage
Structures
Examples
Single selection
Use radio semantics when users choose one starting point.
Selection limit
Selected tags remain removable when the maximum is reached.
Choose up to 3. 1 selected.
Custom options
Use TagGroup.Input for the dashed, content-sized custom entry. Enter or the Arrow Up button submits the draft. The example owns option insertion and selection. Custom tags hug their content at rest and grow when hover or keyboard focus reveals the Remove button. Touch devices show the button directly.
Leading plus and check
The plus changes to a check when selected.
Trailing plus and check
Keep the same state feedback after the label.
Without icons
Use selection styling alone for compact labels.
More options
Reveal another batch of options with a standard 32px outline Button. The caller owns the list and loading policy; the action does not change selection.
Unavailable tags
Keep unavailable options visible without accepting changes.
Long labels
Long content wraps within the available width.
API reference
See Tag item for standalone selection, icon placement, removal and custom entry.
| Prop | Type | Default | Description |
|---|---|---|---|
type | "single" | "multiple" = "multiple" | Use radio semantics for one value or checkbox semantics for several. | |
value / defaultValue | string | null (single); string[] (multiple) | Controlled selection or initial uncontrolled selection. | |
onValueChange | (value) => void | Receives the next selection; business policy and custom option insertion stay caller-owned. | |
max | number (multiple only) | A non-negative whole-number cap. It blocks new selections and preserves deselection. | |
name / form | string | Forwarded to the semantic controls for native form submission. | |
disabled / readOnly | boolean = false | Blocks changes; disabled values are omitted from submission; readOnly values remain included. | |
className / style / ref | native attributes | Customize layout and connect the root. Content, labels and descriptions remain caller-owned. | |
TagGroup.Item | value: string; disabled?: boolean; size?: "sm" | "base"; variant?: "filled" | "outline" | Delegates to TagItem.Selectable. Defaults to outline/base, leading check and hover removal; the group owns selection. | |
indicator / indicatorPlacement | check | plus | none / leading | trailing | Item options. Defaults to a leading selected check. Plus switches to a check when selected; placement changes the icon side. | |
TagGroup.Input | Input props; onSubmit?: () => void; submitLabel?: string | Dashed content-sized entry composed from InputGroup and Input. onSubmit adds an Arrow Up action and Enter submission; caller owns draft and insertion policy. | |
onRemove / removeLabel | () => void / string (Item) | Marks an option removable. Its width hugs content at rest, then grows to reveal a separate Remove button on hover or keyboard focus; touch devices show it directly. The caller removes its option and selection. |