# Tag Input

- Page: <https://kznlabs.github.io/labsUI/components/tag-input>

## Tag Input (`tag-input`, component)

Free-form tags: Enter or a separator adds, Backspace removes the last, pasting a list adds them all. Duplicates, a max and a validate function keep bad tags in the input. One hidden input per tag.

- Install: `npx @kznlabs/labsui add tag-input`
- Docs: <https://kznlabs.github.io/labsUI/components/tag-input>
- Brings: field, label, use-controllable-state, utils
- npm: clsx@^2.1.1, lucide-react@1.63.0, motion@14.7.1, tailwind-merge@^3.7.0

### API

- `<Tag>`: Removable chip. Springs in and out when rendered inside AnimatePresence (`mode="popLayout"`).
  - `children: ReactNode`: Tag text.
  - `disabled?: boolean`: Hides the remove button.
  - `onRemove?: () => void`: Shows a remove button; its accessible name is "Remove <children>".
- `<TagInput>` (+ <input> props): Free-form tags: type and press Enter or a separator; paste a list to add many; Backspace in an
empty input removes the last tag. `name` submits one hidden input per tag.
  - `defaultValue?: string[]` = `[]`: Tags at first render (uncontrolled).
  - `max?: number`: Most tags allowed; typing stops at the limit.
  - `onValueChange?: (tags: string[]) => void`: Called with every tag after an add or remove.
  - `separators?: string[]` = `[","]`: Keys that commit the typed text, besides Enter. Pasted text is split on these too.
  - `validate?: (tag: string) => boolean`: Return false to reject a tag (it stays in the input). Runs after trimming.
  - `value?: string[]`: Controlled tags; pair with `onValueChange`.

### Usage

```tsx
<TagInput value={tags} onValueChange={setTags} max={5} validate={(t) => t.length <= 24} />
```

### Example: clip-tags.tsx

```tsx
"use client";

import { useState } from "react";
import { Field } from "@/components/ui/field";
import { TagInput } from "@/components/ui/tag-input";

export function ClipTags() {
  const [tags, setTags] = useState<string[]>([]);
  return (
    <Field label="Tags" description="Enter or comma to add.">
      <TagInput
        name="tags"
        value={tags}
        onValueChange={setTags}
        max={5}
        validate={(t) => t.length <= 24}
        placeholder="Add a tag…"
      />
    </Field>
  );
}
```
