Tag input
Create, edit and remove free-form values using Kakashi’s tag-entry interaction pattern.
Usage
Import TagInput from @commenda/pathfinder/tag-input. Import the compiled stylesheet once. Use Tag input for free-form values; use Multi select when values come from a known set of options.
Examples
Editing and paste
Validation
States
API reference
| Prop | Type | Behavior |
|---|---|---|
labelConditional | string | Required accessible field name; alternatively use aria-label |
hideLabel | boolean | Required accessible field name; alternatively use aria-label |
valueConditional | readonly string[] | Controlled values; callback is required with value |
onValueChangeConditional | (
value: readonly string[]
) => void | Controlled values; callback is required with value |
defaultValue | readonly string[] | Initial uncontrolled values |
entryConfig | ObjectView fields | editable, addOnPaste, addOnTab, delimiter, maxTags, validate |
name | string | Submit each tag as a repeated named value; read with FormData.getAll(name) |
form | string | Submit each tag as a repeated named value; read with FormData.getAll(name) |
readOnly | boolean | Values submit, editing and removal are blocked |
disableConfig | DisableConfigView fields | Blocks editing and omits values from form submission |
description | string | Associated guidance and validation |
errorConfig | ObjectView fields | Associated guidance and validation |
requiredConditional | boolean | Associated guidance and validation |
placeholder | string | The ref targets the entry input |
onBlur | FocusEventHandler<HTMLInputElement> | The ref targets the entry input |
aria-labelConditional | string | Accessible name when the field has no visible label. |
labelConfig | ObjectView fields · 2 shapes | Choose either optionalLabel or help, never both. never excludes the other field. |
id | string | Stable HTML identifier for the component. |
className | string | Additional classes for the component root. |
entryConfigObject fields
| Field | Type | Requirement |
|---|---|---|
editable | boolean | Optional |
addOnPaste | boolean | Optional |
addOnTab | boolean | Optional |
delimiter | string | Optional |
maxTags | number | Optional |
validate | ((tag: string) => string | undefined) | Optional Return a message to reject a tag; undefined accepts it. |
disableConfigObject fields
| Field | Type | Requirement |
|---|---|---|
isDisabled | boolean | Required |
reason | string | Optional |
errorConfigObject fields
| Field | Type | Requirement |
|---|---|---|
message | string | Required |
reveal | "after-blur" | "immediate" | Optional |
labelConfigObject fields
Choose one of these 2 shapes. Do not combine fields excluded by the selected shape.
Option 1
| Field | Type | Requirement |
|---|---|---|
optionalLabel | string | Required |
Do not supply: help.
Option 2
| Field | Type | Requirement |
|---|---|---|
help | string | Required |
Do not supply: optionalLabel.
Keyboard and validation
Enter or the configured delimiter adds a trimmed tag. Duplicates are rejected. Arrow keys navigate tags, Backspace removes a highlighted tag, and editable tags support keyboard editing. Tab retains normal focus navigation unless addOnTab is enabled. Composition input does not create a tag until composition is complete.
Provide unique, nonempty initial values. Validation belongs to the application; the component never treats an email-shaped value as proof of an address or identity. Uncontrolled native resets restore defaults. Controlled resets remain application-owned.
Design rules
- TAG-INPUT-001: Reuse the Dice UI primitive used by Kakashi TagInput; ship Pathfinder’s compiled styling without a runtime Kakashi dependency.
- TAG-INPUT-002: Use the existing field shell and Tag geometry. Wrap long tags without pushing the entry field outside its container.
- TAG-INPUT-003: Announce invalid entries and retain keyboard focus during editing and removal.
- TAG-INPUT-004: Read-only and disabled modes prevent mutations; only enabled values participate in form submission.
Tag input is a Kakashi-derived composition of Input and Tag, not a newly extracted standalone Figma component.