TagInput
An ordered free-form tag editor with native multi-value submission and stale-safe async validation.@gemologic/sheen · formsPlayground
- frontend
- urgent
<TagInput label="Labels" name="labels" defaultValue={["frontend", "urgent"]} description="Press Enter to add a label." />Variant matrix
Project labelsPress Delete to remove. Hold Alt and press an arrow key, Home, or End to reorder.Press Enter to add a label.
- frontend
- urgent
Anatomy
- Package
@gemologic/sheen- Source
packages/ui/src/primitives/TagInput.tsx- Tokens
--sheen-color-bg--sheen-color-border-control--sheen-color-neutral-subtle--sheen-color-focus-ring
Accessibility
Role: labeled text input and native multi-select projectionKeyboard: Enter, Comma, Backspace, Delete, Alt+Arrow keys, Alt+Home, Alt+EndDo
- Use stable exact strings when order and free-form entry both matter.
Do not
- Do not use TagInput for selection from a controlled taxonomy; use MultiCombobox.
Generated props
| Name | Type | Default | Description |
|---|---|---|---|
ref | HTMLDivElement | ((element: HTMLDivElement) => void) | — | Native root reference. |
inputRef | HTMLInputElement | ((element: HTMLInputElement) => void) | — | Native editable-input reference. |
label * | string | — | Required visible field label. |
name | string | — | Native multi-value form name. |
form | string | — | Optional external form ID. |
value | readonly string[] | — | Controlled ordered unique nonempty tag values. |
defaultValue | readonly string[] | — | Initial uncontrolled values restored on uncanceled form reset. |
onValueChange | (value: readonly string[]) => void | — | Receives ordered committed tag values. |
validate | (candidate: string, context: TagInputValidationContext, signal: AbortSignal) => TagInputValidationResult | Promise<TagInputValidationResult> | — | Optional sync or async candidate validator. It receives accepted values and an AbortSignal; stale completions cannot publish. |
onValidationError | (error: unknown) => void | — | Receives unexpected validator failures after the retained draft receives a localized error. |
normalize | (draft: string) => string | — | Synchronous candidate normalization before uniqueness and validation; defaults to trim. |
placeholder | string | — | Editable-input placeholder shown only when no tags exist. |
description | string | — | Supporting text associated with the editor. |
error | string | — | App-owned field error, distinct from candidate validation. |
disabled | boolean | false | Disables editing, removal, reordering, validation, and form submission. |
readOnly | boolean | false | Keeps values and controls inspectable while rejecting changes. |
required | boolean | false | Requires at least one committed tag in the native form projection. |
commitKeys | readonly string[] | — | Keys that validate and commit the current draft; defaults to Enter and comma. |