Tag input

Turn short text values into removable tags.

fieldtags
Preview
Tag input preview
designmotion

When to use

  • Free-form lists of short values like tags, keywords, or emails.
  • Fields where people add values by pressing Enter or comma.

When not to use

  • Use multi-select or chip-group when values come from a fixed list.
  • Use input for a single value.

shadcn CLI

Also installs (1)

  • manicat-foundation
Manual install(+)
registry.jsonjson
{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "tag-input",
  "type": "registry:ui",
  "title": "Tag input",
  "description": "Turn short text values into removable tags.",
  "categories": [
    "inputs"
  ],
  "dependencies": [
    "lucide-react",
    "motion"
  ],
  "registryDependencies": [
    "https://manicat.viraza.net/r/manicat-foundation.json"
  ],
  "files": [
    {
      "path": "registry/components/tag-input/tag-input.tsx",
      "type": "registry:component",
      "target": "@components/manicat/tag-input/tag-input.tsx"
    },
    {
      "path": "registry/components/tag-input/tag-input.module.css",
      "type": "registry:component",
      "target": "@components/manicat/tag-input/tag-input.module.css"
    }
  ],
  "docs": "Docs and live preview: https://uiarc.dev/components/tag-input",
  "meta": {
    "tier": "free",
    "kind": "component",
    "docs": "https://manicat.viraza.net/components/tag-input",
    "markdown": "https://uiarc.dev/components/tag-input/markdown",
    "tags": [
      "field",
      "tags"
    ]
  }
}

Usage

Install the component, then copy this into your app. Change the content and the props to fit your screen.

example.tsxtsx
"use client";

import { useState } from "react";
import { TagInput } from "@/components/manicat/tag-input/tag-input";

export function TagInputExample() {
  const [tags, setTags] = useState(["design", "motion"]);

  return <TagInput label="Topics" value={tags} onValueChange={setTags} placeholder="Add a topic" />;
}

Examples

Real screens rather than isolated props. Switch to Code to copy a whole example into your project.

Post topics Add tags with Enter, remove them with Backspace.

Post topics Add tags with Enter, remove them with Backspace. preview
designmotion

2 of 5 topics used.

Keyboard interactions

KeysAction
Enter / ,Adds the typed text as a tag. Duplicates (case-insensitive) pulse the existing tag instead.
BackspaceAt the start of the input, picks the last tag; pressed again, removes the picked tag.
DeleteRemoves the picked tag.
ArrowLeft / ArrowRightMoves the pick between tags and back to the input.
EscapeClears the pick.

Accessibility

  • Each tag has a remove button labelled "Remove <tag>".
  • Adds, removals, picks, and duplicates are announced in a polite aria-live region.
  • Blurring the input commits any typed draft as a tag.

Motion

  • New tags blur and scale in where the text was typed; removed tags leave and the rest glide on the morph spring. The shell follows wrapped rows on a smooth spring.
  • A ring glides between picked tags. Reduced motion removes layout travel, scale, and blur, keeping fades.

Responsive behavior

  • Tags wrap onto new rows and the shell height follows on a spring, so the field never scrolls horizontally.
  • The text input keeps an 80px minimum, dropping to its own row when the last row is full.

Performance

  • Every tag is a motion element with layout position animation; fine for dozens of tags, not hundreds.
  • Two ResizeObservers track the content and message heights.

Notes for AI

  • Use for free-form values like tags, emails, or keywords. Use multi-select or chip-group when values come from a fixed list.
  • Controlled or uncontrolled. Tags are plain strings; validate or normalize in onValueChange.