Forms
InputTags
A tag input that renders values as removable badges. Commit tags with Enter, a delimiter, paste, Tab, or blur, and reject duplicates automatically.
Playground
Experiment with different props in real-time.
svelte kit
Basic Usage
Type and press Enter to add a tag.
svelte kit
<script lang="ts">
import { InputTags } from 'sv5ui';
let value = $state(['svelte', 'kit']);
</script>
<InputTags bind:value placeholder="Add a tag..." />Custom Delimiter
The delimiter commits a tag while typing and splits pasted text.
one
<!-- Commit on space; also splits pasted text -->
<InputTags value={['one']} delimiter=" " placeholder="Space to add" />Commit on Tab & Blur
react
<!-- Commit the pending text on Tab and on blur too -->
<InputTags
value={['react']}
addOnTab
addOnBlur
placeholder="Enter, Tab, or blur"
/>Allow Duplicates
By default duplicate entries are rejected. Set allowDuplicates to permit them.
a a
<!-- Allow the same tag more than once -->
<InputTags value={['a', 'a']} allowDuplicates />Limits
Cap the number of tags with max and each tag's length with maxLength.
one two
<!-- Cap the number of tags and the length of each -->
<InputTags value={['one', 'two']} max={3} maxLength={10} />Leading Icon
design
<InputTags value={['design']} leadingIcon="lucide:tag" placeholder="Topics" />Tag Style
Forward props to each tag Badge with tag.
primary subtle
<InputTags
value={['primary', 'subtle']}
tag={{ color: 'primary', variant: 'subtle' }}
/>Variants
tag
tag
tag
tag
<InputTags value={['tag']} variant="outline" />
<InputTags value={['tag']} variant="soft" />
<InputTags value={['tag']} variant="subtle" />
<InputTags value={['tag']} variant="ghost" />Sizes
tag
tag
tag
<InputTags value={['tag']} size="xs" />
<InputTags value={['tag']} size="md" />
<InputTags value={['tag']} size="xl" />Disabled & Readonly
locked
locked
<InputTags value={['locked']} disabled />
<InputTags value={['locked']} readonly />Form Field
Each tag is submitted as its own hidden input, readable with FormData.getAll(name).
Add at least one skill
<script lang="ts">
import { InputTags, FormField } from 'sv5ui';
let skills = $state<string[]>([]);
const error = $derived(skills.length === 0 ? 'Add at least one skill' : '');
</script>
<FormField label="Skills" {error}>
<!-- Submits one hidden input per tag under this name -->
<InputTags bind:value={skills} name="skills" placeholder="Add a skill..." />
</FormField>UI Slots
Use the ui prop to override classes.
| Slot | Description |
|---|---|
root | The field wrapper containing tags and input |
base | The text input element |
tag | Each tag Badge |
tagDelete | The per-tag delete button |
tagDeleteIcon | The delete button icon |
leading | The leading icon/avatar area |
trailing | The trailing icon area |
Props
| Prop | Type | Default |
|---|---|---|
value | string[] | [] |
onValueChange | (value: string[]) => void | - |
max | number | - |
maxLength | number | - |
delimiter | string | ',' |
addOnPaste | boolean | true |
addOnTab | boolean | false |
addOnBlur | boolean | false |
allowDuplicates | boolean | false |
tag | BadgeProps | - |
tagSlot | Snippet<[{ tag, index }]> | - |
deleteIcon | string | icons.close |
leadingIcon | string | - |
trailingIcon | string | - |
avatar | AvatarProps | - |
variant | 'outline' | 'soft' | 'subtle' | 'ghost' | 'none' | 'outline' |
color | ColorType | 'primary' |
size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' |
disabled | boolean | false |
readonly | boolean | false |
required | boolean | false |
name | string | - |
highlight | boolean | false |
ref | HTMLInputElement | null | null |
class | string | - |
ui | Record<Slot, Class> | - |