/// Inputs
TagsInput
A token / multi-value field: typed values commit into dismissible Tags inside a sunken input container, with dedupe, max, and validation.
import { TagsInput } from "@protocore/pds";Basics
Type a value and press Enter (or comma) to commit it as a Tag; Backspace on an empty entry removes the last one. Controllable via value / defaultValue (string[]) + onValueChange.
- frankfurt
- prod
Validated, capped
Pass a validate predicate to reject malformed values and max to cap the count — the entry disables once the cap is hit. Rejections are announced through a polite live region.
- ops@protocore.io
Up to 5 addresses. Press Enter or comma to add.
Allowing duplicates
By default values are deduped. Set allowDuplicates when repeats are meaningful (e.g. an ordered pipeline).
- build
- test
- build
When to use it
Use TagsInput to collect an open-ended set of short freeform values — labels, email recipients, keywords — where the options aren't known ahead of time. When users pick from a known list, use a multi-select Combobox or a FilterBar. The committed values render as static Tags, matching the metadata vocabulary used elsewhere.
Usage
Do
- Label the field via a `Field` label or `aria-label` on the entry.
- Use `validate` to keep out malformed values instead of accepting anything.
- Set `max` when there's a real upper bound so the UI can stop accepting input.
- Keep values short — they render as mono metadata tags, not sentences.
Don't
- Don't use TagsInput to pick from a fixed option set — reach for Combobox.
- Don't allow duplicates unless order/repetition carries meaning.
- Don't hide the removal affordance; every tag keeps its × button.
- Don't stuff paragraphs into a tag — that's what Textarea is for.
Accessibility
| Keys | Action |
|---|---|
| Enter / , | Commit the current draft as a tag (configurable via `addOnKeys`). |
| Backspace | When the entry is empty, remove the last tag. |
| Tab | Move to the entry; the entry is the single tab stop for adding values. |
- The text entry is a `role="combobox"` labelled by `aria-label`; each tag has a `Remove <value>` button.
- Adds, removals, duplicates, and rejections are announced via a visually-hidden `aria-live="polite"` region.
- `invalid` sets `aria-invalid` on the entry and a danger border on the container.
TagsInput props
| Prop | Type | Default | Description |
|---|---|---|---|
addOnKeys | string[] | ["Enter", ","] | Keys that commit the current draft as a value. Default `["Enter", ","]`. |
allowDuplicates | boolean | false | Allow the same value more than once. Default `false` (deduped). |
aria-label | string | — | Accessible label for the text entry. |
className | string | — | |
defaultValue | string[] | — | Initial list of values when uncontrolled. |
disabled | boolean | false | Disable adding and removing values. |
invalid | boolean | false | Mark the field invalid — danger border plus `aria-invalid`. |
max | number | — | Maximum number of values. Further additions are ignored once reached. |
onValueChange | ((value: string[]) => void) | — | Fires with the next list whenever a value is added or removed. |
placeholder | string | — | Placeholder for the text entry (shown only while empty). |
size | enum | md | Control height: `sm` (32) · `md` (36, default) · `lg` (40) — the minimum row height. |
style | CSSProperties | — | |
validate | ((value: string, current: string[]) => boolean) | — | Return `false` to reject a candidate before it is added. |
value | string[] | — | Controlled list of values. Pair with `onValueChange`. |