Tag Input
more-shadcn-noair/tag-inputFreeComponent
An input field for entering multiple values, displayed as chips.
Live preview
live · rendered by the registry
Rendered by more-shadcn-noair on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://more-shadcn.noair.fun/r/tag-input.jsonSource
1<script lang="ts">2 import { cn } from '$UTILS$';3 import * as Chip from '$lib/components/ui/chip';4 import { X } from '@lucide/svelte';56 let {7 tags = $bindable([]),8 placeholder = 'Add tag...',9 disabled = false,10 maxTags,11 class: className,12 chipVariant = 'secondary',13 validate,14 onadd,15 onremove16 }: {17 tags: string[];18 placeholder?: string;19 disabled?: boolean;20 maxTags?: number;21 class?: string;22 chipVariant?: 'default' | 'secondary' | 'outline' | 'ghost';23 validate?: (tag: string) => boolean;24 onadd?: (tag: string) => void;25 onremove?: (tag: string) => void;26 } = $props();2728 let inputValue = $state('');29 let inputRef: HTMLInputElement | undefined = $state();3031 function addTag(text: string) {32 const trimmed = text.trim();3334 if (!trimmed) return;35 if (tags.includes(trimmed)) return;36 if (maxTags && tags.length >= maxTags) return;37 if (validate && !validate(trimmed)) return;3839 tags = [...tags, trimmed];40 inputValue = '';41 onadd?.(trimmed);42 }4344 function removeTag(index: number) {45 const removed = tags[index];46 tags = tags.filter((_, i) => i !== index);47 onremove?.(removed);48 }4950 function handleKeydown(e: KeyboardEvent) {51 if (e.key === 'Enter' || e.key === ',') {52 e.preventDefault();53 addTag(inputValue);54 } else if (e.key === 'Backspace' && inputValue === '' && tags.length > 0) {55 removeTag(tags.length - 1);56 }57 }5859 function handleContainerClick() {60 inputRef?.focus();61 }62</script>6364<div65 class={cn(66 'flex min-h-10 w-full flex-wrap items-center gap-2 rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background',67 'focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2',68 disabled && 'cursor-not-allowed opacity-50',69 className70 )}71 onclick={handleContainerClick}72 role="textbox"73 tabindex="-1"74 onkeydown={() => {}}75>76 {#each tags as tag, i}77 <Chip.Root78 variant={chipVariant}79 size="sm"80 removable={!disabled}81 onremove={() => removeTag(i)}82 {disabled}83 class="animate-in zoom-in-50 fade-in-0 duration-200"84 >85 {tag}86 </Chip.Root>87 {/each}8889 <input90 bind:this={inputRef}91 bind:value={inputValue}92 {disabled}93 {placeholder}94 onkeydown={handleKeydown}95 onblur={() => {}}96 class="flex-1 bg-transparent outline-none placeholder:text-muted-foreground min-w-[120px]"97 />98</div>
More from more-shadcn-noair
All 43 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Audioaudio | more-shadcn-noair | Components | Free | no deps | |
| Audio Waveaudio-wave | more-shadcn-noair | Components | Free | no deps | |
| Autocompleteautocomplete | more-shadcn-noair | Components | Free | no deps | |
| Bannerbanner | more-shadcn-noair | Components | Free | no deps | |
| Big Calendarbig-calendar | more-shadcn-noair | Components | Free | no deps | |
| Bottom Navigationbottom-nav | more-shadcn-noair | Components | Free | no deps | |
| Canvascanvas | more-shadcn-noair | Components | Free | no deps | |
| Chipchip | more-shadcn-noair | Components | Free | no deps |
