TagsInput
An input component for adding, removing, and managing multiple tags or labels.
Usage
Use standalone, or inside TagsInputField.
<TagsInput {...props} />Anatomy
The class attribute values represent part names, and conditional indicates elements that are rendered conditionally. Other attributes represent their corresponding props.
<div class="whole">
<span class="aux" conditional>
{#each values as text, i}
<span class="label">
{#if label}
{label}
{:else}
{text}
{/if}
<button class="extra" type="button" aria-label={removeAriaLabel(text)}>
{#if extra}
{extra}
{:else}
<svg aria-hidden="true" focusable="false">Default Icon</svg>
{/if}
</button>
</span>
{/each}
</span>
<input class="main" {...rest} type="text" aria-invalid aria-errormessage bind:value bind:this={element} />
</div>Props
| Name | Type | Default | Description |
|---|---|---|---|
label | Snippet | - | Tag label content; receives value and variant |
extra | Snippet | - | Remove-button content; receives value and variant |
values | string[] | - | Bindable tag values |
value | string | - | Bindable current input value |
side | <enum> | "left" | When set to "right", swaps the positions of the tags and the input element |
removeAriaLabel | function | - | Function that creates the accessible label for each remove button; defaults to Remove ${text} |
separator | string[] | [",", "\n"] | Characters that split input into tags |
paste | boolean | true | When true, pasted text containing separators is split into multiple tags |
trim | boolean | true | Trims whitespace from tag text when adding |
unique | boolean | true | When true, duplicate values are ignored |
ariaErrMsgId | string | - | Error-message element ID for aria-errormessage |
events | TagsInputEvents | - | Functions that can filter which added or removed tags are committed |
attach | Attachment | - | Svelte attachment on the input |
element | HTMLInputElement | - | Bindable input element |
styling | SVSClass | - | Styling override |
variant | SVSVariant | NEUTRAL | Variant |
Other HTMLInputAttributes are passed to <input> via rest props; class is merged onto the control.
Input attributes such as placeholder and maxlength are passed at the top level.
Styling
To learn more, see Styling.
Variant Management
No automatic switching.
Default Class Name
svs-tags-input
Behavior
Typing a separator commits the segment before it; Enter commits the current input after splitting on separators; pasting text containing a separator commits every segment of the post-paste value and clears the input. With paste:false, pasted text is inserted natively and not split. trim and unique apply per segment, empty segments are dropped, and onadd fires once per commit with the full batch.
Default separators are "," and "\n"; Windows \r\n pastes keep \r only when trim:false.
Accessibility
Keyboard Interactions
| Key | Description |
|---|---|
Enter | Commits the current input after splitting it on the configured separators |
Typing a configured separator commits the segment before it. IME composition is ignored for both Enter handling and separator-based input splitting.
ARIA Roles and Attributes
The component applies these automatically:
- Input (
main):aria-describedby,aria-invalid, andaria-errormessagefrom the surroundingTagsInputFieldcontext or passed attributes. - Remove button (
extra):aria-labelfromremoveAriaLabel, defaulting toRemove ${text}. - Default remove icon:
aria-hidden="true"andfocusable="false".
Provide an accessible name for the input yourself because there is no built-in visible label. Pass aria-label or aria-labelledby through the rest props, or use TagsInput inside a labelled TagsInputField.
Exports
Types
interface TagsInputEvents extends CollectionEvents<string> {}
interface CollectionEvents<T> {
// Return the subset to commit: undefined => all, [] => none.
onadd?: (detail: { values: T[]; added: T[] }) => T[] | void;
onremove?: (detail: { values: T[]; removed: T[] }) => T[] | void;
}
interface TagsInputProps extends Omit<HTMLInputAttributes, "type" | "value"> {
label?: Snippet<[string, string]>; // Snippet<[value,variant]>
extra?: Snippet<[string, string]>; // Snippet<[value,variant]>
values?: string[]; // bindable
value?: string; // bindable
side?: "left" | "right"; // ("left")
removeAriaLabel?: (text: string) => string; // ((text) => `Remove ${text}`)
separator?: string | string[]; // ([",", "\n"]) - characters that split input into tags
paste?: boolean; // (true) - split pasted text on separators into multiple tags
trim?: boolean; // (true)
unique?: boolean; // (true)
ariaErrMsgId?: string;
events?: TagsInputEvents;
attach?: Attachment<HTMLInputElement>;
element?: HTMLInputElement; // bindable
styling?: SVSClass;
variant?: SVSVariant; // (VARIANT.NEUTRAL)
// class & other HTMLInputAttributes are passed to <input> via ...rest (class is merged onto the control)
}
type TagsInputReqdProps = never;
type TagsInputBindProps = "values" | "value" | "element";Others
No additional exports are available.
Examples
The example code uses Tailwind CSS along with SVSClass.