Display
Tag group
A set of tags, such as the filters on a search, each of which can be removed. To type new tags, use Tag input.
Installation
npx sinaui add tag-groupCopy src/lib/ui/TagGroup.svelte, Icon.svelte, announce.ts and tokens.css. No dependencies.
Examples
Search filters
Remove a tag with its ×, or focus it and press Backspace. The others slide over to close the gap.
<script lang="ts">
import Button from '#lib/ui/Button.svelte';
import TagGroup from '#lib/ui/TagGroup.svelte';
const all = [
{ id: 'optics', label: 'Optics' },
{ id: 'baghdad', label: 'Baghdad' },
{ id: 'c9', label: '9th century' },
{ id: 'arabic', label: 'In Arabic' },
{ id: 'scans', label: 'Has scans' }
];
let filters = $state([...all]);
</script>
<div class="filters">
<TagGroup
label="Filters"
tags={filters}
onremove={(t) => (filters = filters.filter((f) => f.id !== t.id))}
empty="No filters: showing everything."
/>
<div class="row">
<Button variant="ghost" size="sm" disabled={!filters.length} onclick={() => (filters = [])}
>Clear all</Button
>
<Button
variant="ghost"
size="sm"
disabled={filters.length === all.length}
onclick={() => (filters = [...all])}
>
Reset
</Button>
</div>
</div>
<style>
.filters {
display: grid;
gap: 0.75rem;
max-inline-size: min(26rem, 100%);
}
/* Centered in the example, lines of tags included. */
.filters :global(.tags),
.row {
justify-content: center;
}
.row {
display: flex;
gap: 0.25rem;
}
</style>Props
| Prop | Type | Default |
|---|---|---|
label | string | required |
tags | { id, label }[] | required |
onremove | (tag) => void; without it, tags can't be removed | |
empty | string, shown with no tags |
Accessibility
- Each removable tag's button is named “Remove Optics”.
- One tab stop; arrow keys move between tags, Backspace or Delete removes one.
- After a removal, focus moves to the next tag, and the removal is announced.