Tag input ported
Turn short text values into removable tags.
Turn short text values into removable tags.
Loading demo…
Guidance
When to use
- Short text values added one at a time, such as tags, emails, or skills.
- Lists whose items are removed individually with a visible affordance.
- Keyboard-first entry where Enter or comma should commit a value.
When not to use
- Use input for a single text value with no list.
- Use multi-select when the choices come from a fixed set.
- Use textarea for long-form text that should never split into items.
pnpm add sveltearcUsage
<script lang="ts">
import { TagInput } from '$lib/components/tag-input';
let tags = $state(['svelte', 'design']);
</script>
<TagInput label="Tags" bind:value={tags} description="Press Enter to add a tag." />Variants & Examples
Default
Standard appearance and configuration.
<TagInput label="Tags" />API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | – | (Required) Visible label, tied to the input. |
value | string[] | – | Controlled tag list. Omit (with defaultValue) for uncontrolled use; bindable. |
defaultValue | string[] | [] | Initial tags for uncontrolled use. |
onValueChange | (value: string[]) => void | – | Fires with the next tag list on every add or remove. |
placeholder | string | "Add a tag" | Placeholder for the inner input, also drawn as the visible overlay. |
description | string | – | Helper copy under the field, linked through aria-describedby. |
id | string | $props.id() | Element id. Falls back to an auto-generated id. |
Keyboard Interactions
| Key | Action |
|---|---|
Enter / , | Adds the current draft as a tag. |
Backspace | Picks the last tag first, then removes the picked tag. |
ArrowLeft / ArrowRight | Moves the pick between tags. |
Escape | Clears the tag pick. |
Tab | Moves focus to the interactive element. |
Accessibility
- Renders a native input with a real label, so focus and form behavior are native.
- Tag picks and add/remove results announce through a polite live region.
- Duplicates announce instead of silently ignoring the keypress; animated words are aria-hidden with a plain screen reader copy.
Motion
Phase 1 still-port: tag enter/exit, layout glide, pick-ring glide, shell height, and helper word-rise render their static end states; Phase 2 wires the springs without restructuring.
Notes for AI
- List-of-strings entry with removable pills. Duplicates are refused with an announcement.
- Works controlled or with defaultValue; blur commits the draft like Enter.
- Backspace and arrow keys pick a tag first — the next Backspace removes it.
Source of truth: registry/components/tag-input/tag-input.tsx