A customizable and accessible tag input component built for shadcn/ui. This component allows users to select multiple tags from an intuitive searchable dropdown, with keyboard navigation support and a clean, modern design.
This component was developed with inspiration from the following projects:
As always, thanks to shadcn-ui and shadcn.
- 🔍 Searchable tag selection
- ⌨️ Full keyboard navigation support
- 🎨 Follows your shadcn theme
- 🧩 Fully customizable
- ♿ Accessible
- 📱 Mobile friendly
- 🏷️ Pill-style tags with remove option
- 🔄 Backspace support for tag removal
- 🎨 Custom theming for displaying tags
- ❌❌ Press the cross twice to clear all
npx shadcn-ui@latest add https://shadcn-tag-input/registry/tag-input.jsonThis will install the component and all required dependencies.
This component requires:
- A Next.js project with shadcn/ui configured
- The following shadcn components installed:
- Command
- Badge
Works with Next-Js 15 with --legacy-peer-deps flag.
import { TagInput } from "@/components/ui/tag-input"; import { useState } from "react"; type Tag = { label: string; value: string; }; export default function Demo() { const [tags, setTags] = useState<Tag[]>([]); const allTags = [ { label: "React", value: "react" }, { label: "Next.js", value: "nextjs" }, { label: "TypeScript", value: "typescript" }, { label: "shadcn/ui", value: "shadcn" }, ]; return ( <TagInput tags={tags} setTags={setTags} allTags={allTags} placeholder="Add frameworks..." /> ); }| Prop | Type | Description | Default |
|---|---|---|---|
tags | Tag<T>[] | Currently selected tags | Required |
setTags | (tags: Tag<T>[]) => void | Function to update tags | Required |
allTags | Tag<T>[] | Array of all available tags | Required |
AllTagsLabel | ({ value }: { value: T }) => React.ReactNode | Custom render function for tag items | Optional |
placeholder | string | Input placeholder text | "Add tag" |
className | string | Additional CSS classes | Optional |
You can customize how tags appear in the dropdown using the AllTagsLabel prop:
function Demo() { return ( <TagInput tags={tags} setTags={setTags} allTags={allTags} AllTagsLabel={({ value }) => ( <div className="flex items-center gap-2"> <Icon name={value} /> <span>{value}</span> </div> )} /> ); }The component is fully controlled, allowing you to manage the tag state in your application:
function Demo() { const [tags, setTags] = useState<Tag[]>([]); const handleTagsChange = (newTags: Tag[]) => { // Add any validation or transformation logic here setTags(newTags); }; return <TagInput tags={tags} setTags={handleTagsChange} allTags={allTags} />; }The component uses your existing shadcn theme and can be customized using Tailwind classes:
<TagInput className="max-w-md" // Add any Tailwind classes for customization />To modify the component:
- Clone the repository
- Install dependencies:
npm install - Make your changes
- Build the registry:
npm run build-registry - Test your changes locally
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License - feel free to use this component in your projects. Or just copy and paste from here. Use this as you please.