Overview
Free-form token entry field that turns committed text into removable tags while keeping native input, form, and accessibility wiring intact.
Usage
Guidance
For native forms, pass both name and commitOnSubmit when the expected path is
"type a tag, click Save." TagInput commits a valid pending draft during the
form's submit capture phase, so new FormData(form).getAll(name) includes the
same values as the hidden inputs. Invalid, duplicate, or over-limit drafts use
the existing inline validation path and block that submit attempt.
Use When
- Collecting zero or more short free-form values such as labels, emails, or technologies.
- Letting users review and remove committed values inline before submitting a form.
Avoid When
- Users must choose from a fixed option list — use combobox instead.
- The value is a single free-form string rather than a list — use input instead.
When to use
- Collecting zero or more short free-form values such as labels, emails, or technologies.
- Letting users review and remove committed values inline before submitting a form.
- Users must choose from a fixed option list — use combobox instead.
- The value is a single free-form string rather than a list — use input instead.
Examples
Basic tag input
Commit free-form tags with Enter or a comma delimiter.
Disabled tag input
Mirror a locked field that can be read but not changed.
Maximum tag count
Cap the number of committed tags and surface an inline message when the limit is reached.
Pre-populated tags
Start uncontrolled with existing tags and keep editing in place.
Read-only tags
With `readonly`, the committed tags stay visible but cannot be removed and the pending-tag input rejects new entries — distinct from `disabled`, which also dims the whole control.
Validated email tags
Keep the value controlled and reject entries that are not email addresses.
Props
| Name | Type | Default | Required | Bindable | Description |
|---|---|---|---|---|---|
id | text | Stable id for the visible text input. Falls back to FormField context or a generated id. | |||
value | string[] | [] | bind | Bindable tags. | |
delimiter | string | RegExp | ',' | Key that commits the current input into a tag. Enter always commits separately. | ||
max | number | Maximum number of tags allowed. Non-finite values disable the cap. | |||
validate | (tag: string) => booleanstring | Optional per-tag validation hook. | |||
duplicateValuesAllowed | boolean | false | Allow the same trimmed tag value to appear more than once. | ||
commitOnSubmit | boolean | false | Commit a non-empty pending draft before the parent form submits. | ||
disabled | boolean | Disable the input and chip removal affordances. | |||
readonly | boolean | false | Render the pending-tag input as read-only and make committed tags non-removable. | ||
name | text | Hidden input name used for native form submission. | |||
oninput | unknown | req | |||
onkeydown | unknown | req | |||
onfocus | unknown | req | |||
onblur | unknown | req | |||
required | unknown | req | |||
onchange | (tags: string[]) => void | Fires whenever a commit or removal requests a new tag list. |