SvTagsInput

An editable token / chips input - type to add, click x or Backspace to remove.

SvTagsInput edits a string[] as a row of removable chips: type and press Enter or comma to add a tag, Backspace on an empty draft removes the last, and each chip has an x button. It can reject duplicates and cap the count. It is the styled renderer over the headless createTagsInput core, so add / remove and keyboard handling live in one place. Its label / hint / error chrome comes from SvField.

Basic usage

<script lang="ts">
  import { SvTagsInput } from '@svgrid/grid'
  let skills = $state(['Svelte', 'TypeScript'])
</script>

<SvTagsInput label="Skills" bind:value={skills} placeholder="Add a skill…" />

Props

SvTagsInput extends the shared SvEditorProps (disabled, required, invalid, error, label, hint, dir, name, id, ariaLabel) and adds:

Prop Type Default Description
value string[] [] The tags. Bindable with bind:value.
onChange (tags: string[]) => void - Fires whenever the tag set changes.
placeholder string Add tag… Shown only while there are no tags.
unique boolean true Reject duplicate tags.
max number Infinity Maximum number of tags.
messages Partial<TagsMessages> - Override the add / remove aria-labels.

TagsMessages is { add; remove }.

Patterns

Cap and de-duplicate

Combine max with the default unique to keep a bounded, clean set - useful for recipients or a small skill list:

<SvTagsInput label="To" bind:value={recipients} max={5} />

React to changes

Use onChange to persist or validate as tags come and go:

<SvTagsInput bind:value={labels} onChange={(t) => save(t)} />

Required set with a minimum count

Since the value is a string[], validation is just its length. Combine required with a $derived floor and cap the total with max:

<script lang="ts">
  import { SvTagsInput } from '@svgrid/grid'
  let topics = $state<string[]>([])
  const tooFew = $derived(topics.length > 0 && topics.length < 3)
</script>

<SvTagsInput
  label="Interests"
  required
  max={8}
  bind:value={topics}
  placeholder="Add an interest…"
  invalid={topics.length === 0 || tooFew}
  error={topics.length === 0
    ? 'Add at least one interest'
    : tooFew ? 'Pick at least three' : undefined}
  hint="Up to 8 tags"
/>

Tip: unique is on by default, so duplicate entries are silently rejected - value only ever holds distinct tags, which keeps the length checks honest.

Accessibility

See also