Tag Group
import { TagGroup } from '@absoluteui/components/tag-group';import '@absoluteui/components/tag-group/style.css';Using Angular? See Tag Group for Angular.
What it does
Section titled “What it does”Interactive tags such as applied filters, recipients, or labels on a record: removable, selectable (single or multiple), or both. The tags form a grid with one row per tag, as in the React Aria TagGroup: one tag is in the tab sequence, the arrow keys move between tags, Space selects, and Delete or Backspace removes. Static labels are Badge.
When to use
Section titled “When to use”- Applied filters the user can remove one by one.
- A short set of labels the user selects to filter or categorize.
- Recipients or assignees shown as removable chips.
When not to use
Section titled “When not to use”- Static status or category labels: use Badge.
- Choosing values in a form field: use Multi Select (its chips are part of the field).
- Navigation: use Tabs or links.
Examples
Section titled “Examples”Removable applied filters
Section titled “Removable applied filters”import { TagGroup, type TagGroupRemoveDetail } from '@absoluteui/components/tag-group';
const host = document.createElement('div');const status = document.createElement('p');document.body.append(host, status);const filters = TagGroup.create(host, { label: 'Applied filters', removable: true, items: [ { value: 'london', label: 'Location: London' }, { value: 'remote', label: 'Remote' }, { value: 'senior', label: 'Level: Senior' }, ],});host.addEventListener('aui-remove', (event) => { const { item } = (event as CustomEvent<TagGroupRemoveDetail>).detail; status.textContent = `${String(filters.items.length - 1)} filters applied (removed ${item.label})`;});Selectable categories
Section titled “Selectable categories”import { TagGroup, type TagGroupChangeDetail } from '@absoluteui/components/tag-group';
const host = document.createElement('div');const result = document.createElement('p');document.body.append(host, result);TagGroup.create(host, { label: 'Categories', selection: 'multiple', value: ['design'], items: [ { value: 'design', label: 'Design' }, { value: 'engineering', label: 'Engineering' }, { value: 'sales', label: 'Sales' }, { value: 'legal', label: 'Legal', disabled: true }, ],});host.addEventListener('aui-change', (event) => { result.textContent = `Showing: ${(event as CustomEvent<TagGroupChangeDetail>).detail.value.join(', ') || 'all'}`;});import { TagGroup } from '@absoluteui/components/tag-group';import '@absoluteui/components/tag-group/style.css';
const host = document.querySelector<HTMLElement>('#labels');if (host) TagGroup.create(host, { label: 'Labels', items: [{ value: 'bug', label: 'Bug' }, { value: 'ui', label: 'UI' }], removable: true });More usage
Section titled “More usage”import { TagGroup, type TagGroupRemoveDetail } from '@absoluteui/components/tag-group';
const host = document.querySelector<HTMLElement>('#recipients');if (host) { const recipients = TagGroup.create(host, { label: 'Recipients', removable: true, items: [{ value: 'ada', label: 'Ada Lovelace' }, { value: 'grace', label: 'Grace Hopper' }] }); host.addEventListener('aui-remove', (event) => { const { value } = (event as CustomEvent<TagGroupRemoveDetail>).detail; if (recipients.items.length === 1) event.preventDefault(); // keep at least one recipient else console.info(`removed ${value}`); });}Anatomy
Section titled “Anatomy”<div class="aui-tag-group aui-tag-group--{size}" role="grid" aria-label="Applied filters" [aria-multiselectable]> <div class="aui-tag-group__tag [--selected]" role="row" tabindex="0|-1" [aria-selected] [aria-disabled]> <div class="aui-tag-group__cell" role="gridcell"> <span class="aui-tag-group__label">London</span> <button class="aui-tag-group__remove" tabindex="-1" aria-label="Remove London">icon</button> (removable) </div> </div> ...</div>API reference
Section titled “API reference”Factory
Section titled “Factory”TagGroup.create(host: HTMLElement, options: TagGroupOptions): TagGroupGlobal configuration key: tagGroup (see Configuration).
Options
Section titled “Options”| Option | Type | Default | Description |
|---|---|---|---|
label |
string |
Accessible name of the group. Required. | |
items |
readonly TagGroupItem[] |
Tags: { value, label, disabled? } (unique values, at most 1,000). Required. | |
removable |
boolean |
"false" |
Remove button per tag; Delete and Backspace remove the focused tag. |
selection |
'none' | 'single' | 'multiple' |
"none" |
Selection mode. |
value |
readonly string[] |
Selected values. | |
size |
'sm' | 'md' |
"md" |
Tag size. Globally configurable. |
icons |
Partial<TagGroupIcons> |
Icon slot overrides. | |
locale |
string |
"en-US" |
Locale of the remove label and announcement. Globally configurable. Inherited from common configuration. |
Properties
Section titled “Properties”| Property | Type | Description |
|---|---|---|
host |
HTMLElement |
The host element (role=grid while it has tags). |
items |
readonly TagGroupItem[] |
The tags shown, after removals. |
value |
readonly string[] |
Selected values, in tag order. |
options |
Readonly<TagGroupOptions> |
Current options. |
Methods
Section titled “Methods”| Method | Description |
|---|---|
setValue(value: readonly string[]): void |
Set the selected values (no event). |
focus(): void |
Focus the tag in the tab sequence. |
update(options: Partial<TagGroupOptions>): void |
Merge and apply options; focus stays on the same tag. |
destroy(): void |
Remove rendering, attributes, and listeners. |
Events
Section titled “Events”| Event | Detail | Bubbles | Cancelable | Description |
|---|---|---|---|---|
aui-change |
TagGroupChangeDetail |
Yes | No | The user changed the selection (or removed a selected tag): { value }. |
aui-remove |
TagGroupRemoveDetail |
Yes | Yes | The user removes a tag: { value, item }. Prevent it to keep the tag. |
CSS classes
Section titled “CSS classes”All rules live in the aui.components cascade layer, so application styles override them without specificity battles.
| Class | Purpose |
|---|---|
aui-tag-group |
Host. |
aui-tag-group--sm | --md |
Size modifiers. |
aui-tag-group__tag |
A tag (role=row). |
aui-tag-group__tag--selected |
A selected tag. |
aui-tag-group__cell |
The tag’s gridcell. |
aui-tag-group__label |
Tag text. |
aui-tag-group__remove |
Remove button. |
Icon slots
Section titled “Icon slots”| Slot | Default icon |
|---|---|
remove |
close |
Design tokens
Section titled “Design tokens”Tokens this stylesheet reads (verified in CI). Override them in a theme or with the Theme Designer.
--aui-border-width | --aui-color-border-strong | --aui-color-focus-ring | --aui-color-hover | --aui-color-selected | --aui-color-selected-indicator | --aui-color-selected-text | --aui-color-surface | --aui-color-text | --aui-color-text-disabled | --aui-color-text-muted | --aui-duration-fast | --aui-easing-standard | --aui-focus-ring-offset | --aui-focus-ring-width | --aui-font-family-sans | --aui-font-size-sm | --aui-font-size-xs | --aui-icon-size-sm | --aui-line-height-tight | --aui-radius-pill | --aui-space-1 | --aui-space-2 | --aui-space-3
TypeScript definitions
Section titled “TypeScript definitions”type TagGroupSelection = 'none' | 'single' | 'multiple';type TagGroupSize = 'sm' | 'md';interface TagGroupConfig { size: TagGroupSize }interface TagGroupItem { value: string; label: string; disabled?: boolean }interface TagGroupIcons { remove: IconRef }interface TagGroupOptions extends Partial<TagGroupConfig> { label: string; items: readonly TagGroupItem[]; removable?: boolean; selection?: TagGroupSelection; value?: readonly string[]; locale?: string; icons?: Partial<TagGroupIcons>;}interface TagGroupChangeDetail { value: string[] }interface TagGroupRemoveDetail { value: string; item: TagGroupItem }Accessibility
Section titled “Accessibility”Pattern: Grid list (as in the React Aria TagGroup): role=grid with one row per tag and one gridcell per row; roving tabindex over the rows.
Keyboard
Section titled “Keyboard”| Key | Context | Action |
|---|---|---|
| Tab | Group | Moves into the group (to the last focused tag) and out of it. |
| Arrow keys | Tag | Move to the next or previous enabled tag (reading direction aware). |
| Home / End | Tag | First or last enabled tag. |
| Space / Enter | Tag (selection enabled) | Select or deselect the tag. |
| Delete / Backspace | Tag (removable) | Remove the tag; focus moves to the next tag, or the previous one at the end. |
| Element | Role |
|---|---|
| host | grid (absent while empty) |
| tag | row |
| tag content | gridcell |
| remove | button (native, tabindex -1) |
ARIA attributes
Section titled “ARIA attributes”| Attribute | Element | Value |
|---|---|---|
aria-label |
host | the label option |
aria-multiselectable |
host | true with selection ‘multiple’ |
aria-selected |
tag | true or false when selection is enabled; absent otherwise |
aria-disabled |
tag | true for disabled tags |
aria-label |
remove | ‘Remove {label}’ (localized) |
One tag in the tab sequence; after a removal, focus moves to the tag that took its place (or the previous tag).
WCAG 2.2 success criteria addressed
Section titled “WCAG 2.2 success criteria addressed”| Criterion | Level | Note |
|---|---|---|
| 1.3.1 Info and Relationships | A | |
| 1.4.1 Use of Color | A | |
| 2.1.1 Keyboard | A | |
| 2.4.3 Focus Order | A | |
| 4.1.2 Name, Role, Value | A | |
| 4.1.3 Status Messages | AA |
Automated test results: Accessibility and compliance.
Notes and known caveats
Section titled “Notes and known caveats”- Removals are announced (‘{label} removed’) through the polite live region.
- Selected tags differ in more than hue (selection fill and a stronger boundary).
- Grid semantics are announced differently by screen readers; manual verification (NVDA, JAWS, VoiceOver) is pending.
Behavior
Section titled “Behavior”States
Section titled “States”Removable; selection none, single, or multiple; selected; disabled tag; sizes sm and md; empty.
State transitions
Section titled “State transitions”| From | Trigger | To |
|---|---|---|
| tag shown | Delete, Backspace, or the remove button | aui-remove; unless prevented, the tag is removed, focus moves on, and “{label} removed” is announced |
| unselected | Space, Enter, or click (selection enabled) | selected; aui-change |
| selected | Space, Enter, or click | unselected; aui-change |
| single, A selected | select B | B selected, A unselected |
Accessibility notes
Section titled “Accessibility notes”- Removals are announced through the polite live region.
- When the last tag is removed, focus has nowhere to go inside the group: move it in an
aui-removehandler. - Selected tags differ in more than hue.
- The e2e axe run covers three themes; manual screen-reader verification is pending.
Responsive behavior
Section titled “Responsive behavior”Tags wrap onto several lines; long labels are truncated with an ellipsis.
Right-to-left
Section titled “Right-to-left”Arrow keys follow the reading direction; the remove button sits at the inline end.
Theming
Section titled “Theming”The tag tokens and the selection colors are in the contrast gate. Forced colors draw selected tags in Highlight.
Global configuration
Section titled “Global configuration”configureAbsoluteUI({ components: { tagGroup: { size: 'sm' } } });Component configuration
Section titled “Component configuration”Instance size and locale override configuration; configuration changes re-render existing groups.
icons.remove (default close).
Security
Section titled “Security”Labels use textContent; they are never parsed as HTML.
Data handling
Section titled “Data handling”No persistence, network access, or telemetry. A removal changes only the displayed tags; update your own data from aui-remove.
Performance
Section titled “Performance”Each change re-creates the tag elements and restores focus to the same tag.
Supported data scale
Section titled “Supported data scale”Up to 1,000 tags; intended for tens.
Edge cases
Section titled “Edge cases”update({ items })keeps focus on the same tag when it still exists.- A disabled tag cannot be selected or removed; the arrow keys skip it.
- An empty group has no
gridrole and noaria-label(a grid needs rows, and a name needs a role).
Errors
Section titled “Errors”| Code | Category | Cause |
|---|---|---|
TAG_GROUP_OPTIONS |
configuration | Blank label, items that are not an array (or more than 1,000), duplicate or blank values, a blank tag label, an unknown selection mode, or several values with single. |
ICON_UNKNOWN |
configuration | Unknown remove icon. |
CFG_INVALID_VALUE / CFG_UNKNOWN_OPTION |
configuration | Invalid size, locale, or unknown configuration. |
Invalid options throw before the host is modified; an invalid update() leaves the previous state intact.
Known limitations
Section titled “Known limitations”- Removing the last tag leaves focus on the page body.
- Manual screen-reader verification is pending.
Unsupported scenarios
Section titled “Unsupported scenarios”- Editing a tag in place.
- Rich content in tags.