- Gallery
- Forms & Input
- Tag Input
Tag Input
An input that creates tag badges on Enter press with remove functionality.
Forms & Inputtagsinputbadgeschipsmulti-select
Dependencies
Other dependencies:
@/components/ui/badge@/components/ui/input@/components/ui/card@/components/ui/label
How to use this component
Copy the code below into your project. Make sure you have the required shadcn/ui dependencies installed. Then import and use the component in your pages or layouts.
Code
1"use client";23import { useState, KeyboardEvent } from 'react';4import { Badge } from '@/components/ui/badge';5import { Input } from '@/components/ui/input';6import { Card, CardContent } from '@/components/ui/card';7import { Label } from '@/components/ui/label';8import { X } from 'lucide-react';910export default function TagInput() {11 const [tags, setTags] = useState(['React', 'TypeScript', 'Tailwind']);12 const [inputValue, setInputValue] = useState('');13 const maxTags = 10;1415 const addTag = () => {16 const trimmed = inputValue.trim();17 if (trimmed && !tags.includes(trimmed) && tags.length < maxTags) {18 setTags(prev => [...prev, trimmed]);19 setInputValue('');20 }21 };2223 const removeTag = (tagToRemove: string) => {24 setTags(prev => prev.filter(tag => tag !== tagToRemove));25 };2627 const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {28 if (e.key === 'Enter') {29 e.preventDefault();30 addTag();31 } else if (e.key === 'Backspace' && !inputValue && tags.length > 0) {32 removeTag(tags[tags.length - 1]);33 }34 };3536 return (37 <Card className="w-full max-w-md mx-auto">38 <CardContent className="p-6 space-y-4">39 <div>40 <Label htmlFor="tags">Tags</Label>41 <div className="mt-2 flex flex-wrap items-center gap-2 p-2 border rounded-md min-h-[42px] bg-background">42 {tags.map(tag => (43 <Badge key={tag} variant="secondary" className="gap-1 pr-1">44 {tag}45 <button46 onClick={() => removeTag(tag)}47 className="ml-1 rounded-full hover:bg-muted-foreground/20 p-0.5"48 >49 <X className="w-3 h-3" />50 </button>51 </Badge>52 ))}53 <Input54 id="tags"55 value={inputValue}56 onChange={e => setInputValue(e.target.value)}57 onKeyDown={handleKeyDown}58 placeholder={tags.length === 0 ? 'Type and press Enter...' : ''}59 className="border-0 shadow-none focus-visible:ring-0 focus-visible:ring-offset-0 px-0 h-6 flex-1 min-w-[120px]"60 />61 </div>62 </div>6364 <div className="flex items-center justify-between text-sm">65 <p className="text-muted-foreground">Press Enter to add a tag</p>66 <p className={`text-muted-foreground \` +67 `${tags.length >= maxTags ? 'text-red-500' : ''}`}>68 {tags.length}/{maxTags}69 </p>70 </div>7172 {tags.length >= maxTags && (73 <p className="text-sm text-red-500">Maximum number of tags reached</p>74 )}75 </CardContent>76 </Card>77 );78}