motif svelteArc

Tag input ported

Turn short text values into removable tags.

Turn short text values into removable tags.

Live specimen

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.

Installation

pnpm add sveltearc

Usage

<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

PropTypeDefaultDescription
labelstring–(Required) Visible label, tied to the input.
valuestring[]–Controlled tag list. Omit (with defaultValue) for uncontrolled use; bindable.
defaultValuestring[][]Initial tags for uncontrolled use.
onValueChange(value: string[]) => void–Fires with the next tag list on every add or remove.
placeholderstring"Add a tag"Placeholder for the inner input, also drawn as the visible overlay.
descriptionstring–Helper copy under the field, linked through aria-describedby.
idstring$props.id()Element id. Falls back to an auto-generated id.

Keyboard Interactions

KeyAction
Enter / ,Adds the current draft as a tag.
BackspacePicks the last tag first, then removes the picked tag.
ArrowLeft / ArrowRightMoves the pick between tags.
EscapeClears the tag pick.
TabMoves 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