Skip to content
GetUrUI

Tag input

New
.md

Text field that turns entries into chips on Enter, comma or paste, validates each one, and springs new chips in while removed ones slide out.

tag inputchipsemailmulti valueformtokens

Installation

$npx shadcn@latest add @geturui/tag-input
Download source (.zip)

Also installs: Field, Tag group

Usage

usage.tsx
1import { TagInput } from "@/components/ui/tag-input";
2
3const EMAIL = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
4
5export function InviteField() {
6  return (
7    <TagInput
8      label="Invite teammates"
9      placeholder="[email protected]"
10      max={6}
11      validate={(tag) => (EMAIL.test(tag) ? null : "Enter a valid email address.")}
12      name="invites"
13    />
14  );
15}

Props

PropTypeDefaultDescription
value / defaultValue / onValueChangestring[]—Controlled or uncontrolled chips.
label / hint / error / requiredReactNode / ReactNode / ReactNode / boolean—Field shell. Validation messages show in the error line until the next keystroke.
maxnumber—Most chips allowed; a counter appears in the label row and turns to a warning when full.
validate(tag, current) => string | null | void—Return a message to reject an entry; the rejected text stays in the field.
allowDuplicatesbooleanfalseDuplicates are rejected case-insensitively unless set.
transform(raw: string) => stringtrimNormalise an entry before validation, such as lowercasing.
addOnBlurbooleantrueTurn leftover text into a chip when the field loses focus.
tagProps(tag: string) => Partial<TagProps>—Per-chip initials, dot or icon.
size"sm" | "md" | "lg""md"Well height 32 / 40 / 48 with matching chip sizes.
namestring—Submits the chips as one comma-joined hidden value.

Accessibility

  • The label targets the text input; hint, error and validation messages are linked with aria-describedby.
  • Enter or comma adds, Backspace on an empty field removes the last chip, Escape clears the draft.
  • Pasting a list split by commas, semicolons, tabs or new lines adds every valid entry at once.
  • Each chip's remove button is labelled with its text, and additions and removals are announced politely.

Related