# TagsInput
An input component for adding, removing, and managing multiple tags or labels.
## Usage
Use standalone, or inside `TagsInputField`.
```svelte
```
## Anatomy
The `class` attribute values represent part names, and `conditional` indicates elements that are rendered conditionally. Other attributes represent their corresponding props.
```svelte
```
## 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` | `` | `"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 `` 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](/docs/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`, and `aria-errormessage` from the surrounding `TagsInputField` context or passed attributes.
- Remove button (`extra`): `aria-label` from `removeAriaLabel`, defaulting to `Remove ${text}`.
- Default remove icon: `aria-hidden="true"` and `focusable="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
```ts
interface TagsInputEvents extends CollectionEvents {}
interface CollectionEvents {
// 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 {
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;
element?: HTMLInputElement; // bindable
styling?: SVSClass;
variant?: SVSVariant; // (VARIANT.NEUTRAL)
// class & other HTMLInputAttributes are passed to 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`.
### Basic
**Code**
```svelte src=TagsInputBasic.svelte
```
### With Interactive Variant
**Code**
```svelte src=TagsInputPract.svelte
{#snippet extra()}
{/snippet}
```