build69
build69  /  Components  /  Text Inputs  /  TagInput

TagInput

v1.0.17Updated 19 Oct 2026

Gmail / GitHub-style inline chip input. Type-then-commit on Enter / comma / semicolon / Tab; backspace deletes last chip; paste comma-separated splits into multiple tags; autocomplete dropdown with arrow-key nav + pinned

Preview

Live · 14 stories
DefaultOpen ↗
▸Why this is recommendedformtagschipsmulti-input+6

The default, out-of-the-box TagInput.

Recommended for+14
  • ✓Gmail-style recipient pickers
  • ✓GitHub-issue label editors
  • ✓Tag / topic pickers with create-new
  • ✓Skill / interest selectors
Tags+6
formtagschipsmulti-inputautocompleterecipientslabelsreorderdnddefault
Features+4
  • Type-then-commit on Enter / comma / semicolon / Tab
  • Backspace at empty input deletes last chip
  • Paste comma-separated splits into multiple tags
  • Autocomplete dropdown with arrow-key nav
  • Pinned Create-new row in the suggestion popover
  • Max-tags cap + N/max counter
  • Per-tag tone / icon / meta / disabled / invalid
  • Reorderable via @dnd-kit (lazy bundle)
  • Async suggestions via onSearchChange + loading
  • Custom renderTag slot
  • Labelled by FormField: id and aria-* land on the text input (role=combobox); FormField hint / error join the component validation message in aria-describedby; at max the chip group takes the id and the field name
Not recommended for−2
  • ✕Static visible tag cluster (use TagCloud)
  • ✕Single-select (use Combobox)
  • ✕Free-text comment field (use Textarea)

Install

Ask your agent, or call the MCP tool directly. The resolved bundle is written into your project.

get_registry_item({ name: "TagInput" })

Usage

import { TagInput } from '@/components/inputs/tag-input';

<TagInput
  value={tags}
  onValueChange={setTags}
  suggestions={people}
  onSearchChange={fetchPeople}
  loading={loading}
  max={10}
  showCounter
  reorderable
  placeholder="Add recipients…"
/>

Tick variants in the left menu — each adds a tab with that variant’s real story source, the same code the preview above renders.

Props

PropTypeRequired
value

Current tags

TagInputTag[]yes
onValueChange

Tag change callback

functionyes
suggestions

Autocomplete options

TagInputTag[]—
allowCreate

Allow tags not in suggestions (default true)

boolean—
validate

Per-input validation

(raw: string) => TagInputValidation—
commitKeys

Keys that commit (default Enter / , / ; / Tab)

string[]—
max

Max tag count

number—
showCounter

Show N/max counter

boolean—
reorderable

Enable drag-to-reorder

boolean—
onSearchChange

Async fetch hook

(q: string) => void—
loading

Async suggestion loading state

boolean—
renderTag

Custom chip renderer

function—
variant

Visual variant

'default' | 'outline' | 'subtle'—
size

Size scale

'sm' | 'default' | 'lg'—
aria-label

Accessible name of the text input (the ARIA combobox)

string—
aria-labelledby

Id(s) of the element(s) that label the text input; wins over a FormField label

string—
id

DOM id set on the text input (the chip group while max is reached); FormField clones its field id in, and its label then names the control

string—
aria-describedby

Id(s) of hint or error text describing the text input (FormField clones this in)

string—
aria-invalid

Mark the text input invalid; FormField clones this in from its error prop

boolean—
aria-required

Mark the text input required; FormField clones this in from its required prop

boolean—

Related