<script lang="ts">
import { TagsInput } from '@skeletonlabs/skeleton-svelte';
</script>
<TagsInput defaultValue={['Vanilla', 'Chocolate', 'Strawberry']}>
<TagsInput.Label>Label</TagsInput.Label>
<TagsInput.Control>
<TagsInput.Context>
{#snippet children(tagsInput)}
{#each tagsInput().value as value, index (index)}
<TagsInput.Item {value} {index}>
<TagsInput.ItemPreview>
<TagsInput.ItemText>{value}</TagsInput.ItemText>
<TagsInput.ItemDeleteTrigger />
</TagsInput.ItemPreview>
<TagsInput.ItemInput />
</TagsInput.Item>
{/each}
{/snippet}
</TagsInput.Context>
<TagsInput.Input placeholder="Add a flavor..." />
</TagsInput.Control>
<TagsInput.ClearTrigger>Clear All</TagsInput.ClearTrigger>
<TagsInput.HiddenInput />
</TagsInput>
import { TagsInput } from '@skeletonlabs/skeleton-react';
export default function Default() {
return (
<TagsInput defaultValue={['Vanilla', 'Chocolate', 'Strawberry']}>
<TagsInput.Label>Label</TagsInput.Label>
<TagsInput.Control>
<TagsInput.Context>
{(tagsInput) =>
tagsInput.value.map((value, index) => (
<TagsInput.Item key={index} value={value} index={index}>
<TagsInput.ItemPreview>
<TagsInput.ItemText>{value}</TagsInput.ItemText>
<TagsInput.ItemDeleteTrigger />
</TagsInput.ItemPreview>
<TagsInput.ItemInput />
</TagsInput.Item>
))
}
</TagsInput.Context>
<TagsInput.Input placeholder="Add a flavor..." />
</TagsInput.Control>
<TagsInput.ClearTrigger>Clear All</TagsInput.ClearTrigger>
<TagsInput.HiddenInput />
</TagsInput>
);
}
Controlled
<script lang="ts">
import { TagsInput } from '@skeletonlabs/skeleton-svelte';
</script>
<TagsInput defaultValue={['Vanilla', 'Chocolate', 'Strawberry']}>
<TagsInput.Label>Label</TagsInput.Label>
<TagsInput.Control>
<TagsInput.Context>
{#snippet children(tagsInput)}
{#each tagsInput().value as value, index (index)}
<TagsInput.Item {value} {index}>
<TagsInput.ItemPreview>
<TagsInput.ItemText>{value}</TagsInput.ItemText>
<TagsInput.ItemDeleteTrigger />
</TagsInput.ItemPreview>
<TagsInput.ItemInput />
</TagsInput.Item>
{/each}
{/snippet}
</TagsInput.Context>
<TagsInput.Input placeholder="Add a flavor..." />
</TagsInput.Control>
<TagsInput.ClearTrigger>Clear All</TagsInput.ClearTrigger>
<TagsInput.HiddenInput />
</TagsInput>
import { TagsInput } from '@skeletonlabs/skeleton-react';
export default function Default() {
return (
<TagsInput defaultValue={['Vanilla', 'Chocolate', 'Strawberry']}>
<TagsInput.Label>Label</TagsInput.Label>
<TagsInput.Control>
<TagsInput.Context>
{(tagsInput) =>
tagsInput.value.map((value, index) => (
<TagsInput.Item key={index} value={value} index={index}>
<TagsInput.ItemPreview>
<TagsInput.ItemText>{value}</TagsInput.ItemText>
<TagsInput.ItemDeleteTrigger />
</TagsInput.ItemPreview>
<TagsInput.ItemInput />
</TagsInput.Item>
))
}
</TagsInput.Context>
<TagsInput.Input placeholder="Add a flavor..." />
</TagsInput.Control>
<TagsInput.ClearTrigger>Clear All</TagsInput.ClearTrigger>
<TagsInput.HiddenInput />
</TagsInput>
);
}
Custom Icon
<script lang="ts">
import { CircleXIcon } from '@lucide/svelte';
import { TagsInput } from '@skeletonlabs/skeleton-svelte';
</script>
<TagsInput defaultValue={['Vanilla', 'Chocolate', 'Strawberry']}>
<TagsInput.Control>
<TagsInput.Context>
{#snippet children(tagsInput)}
{#each tagsInput().value as value, index (index)}
<TagsInput.Item {value} {index}>
<TagsInput.ItemPreview>
<TagsInput.ItemText>{value}</TagsInput.ItemText>
<TagsInput.ItemDeleteTrigger>
<CircleXIcon class="size-4" />
</TagsInput.ItemDeleteTrigger>
</TagsInput.ItemPreview>
<TagsInput.ItemInput />
</TagsInput.Item>
{/each}
{/snippet}
</TagsInput.Context>
<TagsInput.Input placeholder="Add a flavor..." />
</TagsInput.Control>
<TagsInput.HiddenInput />
</TagsInput>
import { TagsInput } from '@skeletonlabs/skeleton-react';
import { CircleXIcon } from 'lucide-react';
export default function Default() {
return (
<TagsInput defaultValue={['Vanilla', 'Chocolate', 'Strawberry']}>
<TagsInput.Control>
<TagsInput.Context>
{(tagsInput) =>
tagsInput.value.map((value, index) => (
<TagsInput.Item key={index} value={value} index={index}>
<TagsInput.ItemPreview>
<TagsInput.ItemText>{value}</TagsInput.ItemText>
<TagsInput.ItemDeleteTrigger>
<CircleXIcon className="size-4" />
</TagsInput.ItemDeleteTrigger>
</TagsInput.ItemPreview>
<TagsInput.ItemInput />
</TagsInput.Item>
))
}
</TagsInput.Context>
<TagsInput.Input placeholder="Add a flavor..." />
</TagsInput.Control>
<TagsInput.HiddenInput />
</TagsInput>
);
}
Color
<script lang="ts">
import { TagsInput } from '@skeletonlabs/skeleton-svelte';
</script>
<TagsInput defaultValue={['Vanilla', 'Chocolate', 'Strawberry']}>
<TagsInput.Control>
<TagsInput.Context>
{#snippet children(tagsInput)}
{#each tagsInput().value as value, index (index)}
<TagsInput.Item {value} {index}>
<TagsInput.ItemPreview class="preset-filled-secondary-500">
<TagsInput.ItemText>{value}</TagsInput.ItemText>
<TagsInput.ItemDeleteTrigger />
</TagsInput.ItemPreview>
<TagsInput.ItemInput />
</TagsInput.Item>
{/each}
{/snippet}
</TagsInput.Context>
<TagsInput.Input placeholder="Add a flavor..." />
</TagsInput.Control>
<TagsInput.HiddenInput />
</TagsInput>
import { TagsInput } from '@skeletonlabs/skeleton-react';
export default function Default() {
return (
<TagsInput defaultValue={['Vanilla', 'Chocolate', 'Strawberry']}>
<TagsInput.Control>
<TagsInput.Context>
{(tagsInput) =>
tagsInput.value.map((value, index) => (
<TagsInput.Item key={index} value={value} index={index}>
<TagsInput.ItemPreview className="preset-filled-secondary-500">
<TagsInput.ItemText>{value}</TagsInput.ItemText>
<TagsInput.ItemDeleteTrigger />
</TagsInput.ItemPreview>
<TagsInput.ItemInput />
</TagsInput.Item>
))
}
</TagsInput.Context>
<TagsInput.Input placeholder="Add a flavor..." />
</TagsInput.Control>
<TagsInput.HiddenInput />
</TagsInput>
);
}
Provider Pattern
Use the Provider Pattern to gain access to the inner component APIs.
<script lang="ts">
import { TagsInput, useTagsInput } from '@skeletonlabs/skeleton-svelte';
const id = $props.id();
const tagsInput = useTagsInput({
id,
defaultValue: ['Vanilla', 'Chocolate', 'Strawberry'],
});
</script>
<div class="w-full space-y-4">
<TagsInput.Provider value={tagsInput}>
<TagsInput.Control>
<TagsInput.Context>
{#snippet children(tagsInput)}
{#each tagsInput().value as value, index (index)}
<TagsInput.Item {value} {index}>
<TagsInput.ItemPreview>
<TagsInput.ItemText>{value}</TagsInput.ItemText>
<TagsInput.ItemDeleteTrigger />
</TagsInput.ItemPreview>
<TagsInput.ItemInput />
</TagsInput.Item>
{/each}
{/snippet}
</TagsInput.Context>
<TagsInput.Input placeholder="Add a flavor..." />
</TagsInput.Control>
<TagsInput.HiddenInput />
</TagsInput.Provider>
<!-- Programmatic Controls -->
<div class="card preset-outlined-surface-200-800 flex justify-center items-center py-4">
<button class="btn preset-filled" onclick={() => tagsInput().clearValue()}>Clear Tags</button>
</div>
</div>
import { TagsInput, useTagsInput } from '@skeletonlabs/skeleton-react';
export default function Default() {
const tagsInput = useTagsInput({
defaultValue: ['Vanilla', 'Chocolate', 'Strawberry'],
});
return (
<div className="w-full space-y-4">
<TagsInput.Provider value={tagsInput}>
<TagsInput.Control>
<TagsInput.Context>
{(tagsInput) =>
tagsInput.value.map((value, index) => (
<TagsInput.Item key={index} value={value} index={index}>
<TagsInput.ItemPreview>
<TagsInput.ItemText>{value}</TagsInput.ItemText>
<TagsInput.ItemDeleteTrigger />
</TagsInput.ItemPreview>
<TagsInput.ItemInput />
</TagsInput.Item>
))
}
</TagsInput.Context>
<TagsInput.Input placeholder="Add a flavor..." />
</TagsInput.Control>
<TagsInput.HiddenInput />
</TagsInput.Provider>
{/* Programmatic Controls */}
<div className="card preset-outlined-surface-200-800 flex justify-center items-center py-4">
<button className="btn preset-filled" onClick={() => tagsInput.clearValue()}>
Clear Tags
</button>
</div>
</div>
);
}
Direction
<script lang="ts">
import { TagsInput } from '@skeletonlabs/skeleton-svelte';
</script>
<TagsInput defaultValue={['Vanilla', 'Chocolate', 'Strawberry']} dir="rtl">
<TagsInput.Label>Label</TagsInput.Label>
<TagsInput.Control>
<TagsInput.Context>
{#snippet children(tagsInput)}
{#each tagsInput().value as value, index (index)}
<TagsInput.Item {value} {index}>
<TagsInput.ItemPreview>
<TagsInput.ItemText>{value}</TagsInput.ItemText>
<TagsInput.ItemDeleteTrigger />
</TagsInput.ItemPreview>
<TagsInput.ItemInput />
</TagsInput.Item>
{/each}
{/snippet}
</TagsInput.Context>
<TagsInput.Input placeholder="Add a flavor..." />
</TagsInput.Control>
<TagsInput.ClearTrigger>Clear All</TagsInput.ClearTrigger>
<TagsInput.HiddenInput />
</TagsInput>
import { TagsInput } from '@skeletonlabs/skeleton-react';
export default function Default() {
return (
<TagsInput defaultValue={['Vanilla', 'Chocolate', 'Strawberry']} dir="rtl">
<TagsInput.Label>Label</TagsInput.Label>
<TagsInput.Control>
<TagsInput.Context>
{(tagsInput) =>
tagsInput.value.map((value, index) => (
<TagsInput.Item key={index} value={value} index={index}>
<TagsInput.ItemPreview>
<TagsInput.ItemText>{value}</TagsInput.ItemText>
<TagsInput.ItemDeleteTrigger />
</TagsInput.ItemPreview>
<TagsInput.ItemInput />
</TagsInput.Item>
))
}
</TagsInput.Context>
<TagsInput.Input placeholder="Add a flavor..." />
</TagsInput.Control>
<TagsInput.ClearTrigger>Clear All</TagsInput.ClearTrigger>
<TagsInput.HiddenInput />
</TagsInput>
);
}
API Reference
Root
| Property | Default | Type |
|---|---|---|
ids | - | Partial<{ root: string; input: string; hiddenInput: string; clearBtn: string; label: string; control: string; item: (opts: ItemProps) => string; itemDeleteTrigger: (opts: ItemProps) => string; itemInput: (opts: ItemProps) => string; }> | undefined The ids of the elements in the tags input. Useful for composition. |
translations | - | IntlTranslations | undefinedSpecifies the localized strings that identifies the accessibility elements and their states |
maxLength | - | number | undefinedThe max length of the input. |
delimiter | "," | string | RegExp | undefinedThe character that serves has: - event key to trigger the addition of a new tag - character used to split tags when pasting into the input |
autoFocus | - | boolean | undefinedWhether the input should be auto-focused |
disabled | - | boolean | undefinedWhether the tags input should be disabled |
readOnly | - | boolean | undefinedWhether the tags input should be read-only |
invalid | - | boolean | undefinedWhether the tags input is invalid |
required | - | boolean | undefinedWhether the tags input is required |
editable | true | boolean | undefinedWhether a tag can be edited after creation, by pressing `Enter` or double clicking. |
inputValue | - | string | undefinedThe controlled tag input's value |
defaultInputValue | - | string | undefinedThe initial tag input value when rendered. Use when you don't need to control the tag input value. |
value | - | string[] | undefinedThe controlled tag value |
defaultValue | - | string[] | undefinedThe initial tag value when rendered. Use when you don't need to control the tag value. |
onValueChange | - | ((details: ValueChangeDetails) => void) | undefinedCallback fired when the tag values is updated |
onInputValueChange | - | ((details: InputValueChangeDetails) => void) | undefinedCallback fired when the input value is updated |
onHighlightChange | - | ((details: HighlightChangeDetails) => void) | undefinedCallback fired when a tag is highlighted by pointer or keyboard navigation |
onValueInvalid | - | ((details: ValidityChangeDetails) => void) | undefinedCallback fired when the max tag count is reached or the `validateTag` function returns `false` |
validate | - | ((details: ValidateArgs) => boolean) | undefinedReturns a boolean that determines whether a tag can be added. Useful for preventing duplicates or invalid tag values. |
blurBehavior | - | "clear" | "add" | undefinedThe behavior of the tags input when the input is blurred - `"add"`: add the input value as a new tag - `"clear"`: clear the input value |
addOnPaste | false | boolean | undefinedWhether to add a tag when you paste values into the tag input |
max | Infinity | number | undefinedThe max number of tags |
allowOverflow | - | boolean | undefinedWhether to allow tags to exceed max. In this case, we'll attach `data-invalid` to the root |
name | - | string | undefinedThe name attribute for the input. Useful for form submissions |
form | - | string | undefinedThe associate form of the underlying input element. |
dir | "ltr" | "ltr" | "rtl" | undefinedThe document's text/writing direction. |
getRootNode | - | (() => ShadowRoot | Node | Document) | undefinedA root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. |
onPointerDownOutside | - | ((event: PointerDownOutsideEvent) => void) | undefinedFunction called when the pointer is pressed down outside the component |
onFocusOutside | - | ((event: FocusOutsideEvent) => void) | undefinedFunction called when the focus is moved outside the component |
onInteractOutside | - | ((event: InteractOutsideEvent) => void) | undefinedFunction called when an interaction happens outside the component |
element | - | ((attributes: HTMLAttributes<"div">) => Element) | undefinedRender the element yourself |
RootProvider
| Property | Default | Type |
|---|---|---|
value | - | TagsInputApi<PropTypes> |
element | - | ((attributes: HTMLAttributes<"div">) => Element) | undefinedRender the element yourself |
RootContext
| Property | Default | Type |
|---|---|---|
children | - | (tagsInput: TagsInputApi<PropTypes>) => ReactNode |
Label
| Property | Default | Type |
|---|---|---|
element | - | ((attributes: HTMLAttributes<"label">) => Element) | undefinedRender the element yourself |
Control
| Property | Default | Type |
|---|---|---|
element | - | ((attributes: HTMLAttributes<"div">) => Element) | undefinedRender the element yourself |
Item
| Property | Default | Type |
|---|---|---|
index | - | string | number |
value | - | string |
disabled | - | boolean | undefined |
element | - | ((attributes: HTMLAttributes<"span">) => Element) | undefinedRender the element yourself |
ItemPreview
| Property | Default | Type |
|---|---|---|
element | - | ((attributes: HTMLAttributes<"div">) => Element) | undefinedRender the element yourself |
ItemText
| Property | Default | Type |
|---|---|---|
element | - | ((attributes: HTMLAttributes<"span">) => Element) | undefinedRender the element yourself |
ItemDeleteTrigger
| Property | Default | Type |
|---|---|---|
element | - | ((attributes: HTMLAttributes<"button">) => Element) | undefinedRender the element yourself |
ItemInput
| Property | Default | Type |
|---|---|---|
element | - | ((attributes: HTMLAttributes<"input">) => Element) | undefinedRender the element yourself |
Input
| Property | Default | Type |
|---|---|---|
element | - | ((attributes: HTMLAttributes<"input">) => Element) | undefinedRender the element yourself |
ClearTrigger
| Property | Default | Type |
|---|---|---|
element | - | ((attributes: HTMLAttributes<"button">) => Element) | undefinedRender the element yourself |
HiddenInput
| Property | Default | Type |
|---|---|---|
element | - | ((attributes: HTMLAttributes<"input">) => Element) | undefinedRender the element yourself |