Components

Tags Input

new

A text field that turns entries into removable tags.

reacttailwind
Press Enter or comma to add. Backspace marks the last topic, then removes it.

Installation

npx shadcn@latest add @blank/tags-input

Usage

import {
  TagsInput,
  TagsInputClear,
  TagsInputInput,
  TagsInputItem,
  TagsInputList,
} from "@/components/ui/tags-input"
<TagsInput defaultValue={["react"]}>
  <TagsInputList />
  <TagsInputInput placeholder="Add a tag…" />
</TagsInput>

Enter or the delimiter commits what is typed; pasted text is split on the delimiter and on new lines. Backspace in an empty field marks the last tag and a second press removes it, so one stray keystroke never deletes anything. The arrow keys walk the marked tag, Delete removes it, Escape lets go.

TagsInputList renders a tag for every value. Pass it a function to render each one yourself, or map the value to TagsInputItem when you control it.

Examples

Validation

onValidate rejects a tag; onInvalid says why — duplicate, max or invalid — so the message can live in FieldError where every other field error does. name submits one hidden input per tag.

ana@acme.com
Paste a comma-separated list to add several at once.

API Reference

TagsInput

PropTypeDefault
value / defaultValuestring[][]
onValueChange(value: string[]) => void—
maxnumberInfinity
allowDuplicatesbooleanfalse
delimiterstring","
addOnPastebooleantrue
addOnBlurbooleanfalse
onValidate(tag: string) => boolean—
onInvalid(tag: string, reason: "duplicate" | "max" | "invalid") => void—
size"default" | "sm""default"
disabled / readOnlybooleanfalse
namestring—

TagsInputList

PropTypeDefault
children(tag: string, index: number) => ReactNodea TagsInputItem per tag

TagsInputItem

PropTypeDefault
indexnumber—
childrenReactNodethe tag text

Marked tags carry data-highlighted. TagsInputInput takes every input prop; put id and aria-invalid on it. TagsInputClear removes every tag and hides itself when there is nothing to clear.