Tag Group
The tag group
component provides a way to display a group of dismissible tags.
Features
Keyboard navigation
- ArrowLeft and ArrowRight keys can be used to navigate between tags.
- Home and End keys can be used to navigate to the first and last tag respectively.
- Delete key can be used to dismiss a tag.
Example
Football
Cricket
Baseball
Basketball
Tennis
Badminton
Table Tennis
Swimming
Boxing
Sources
+page.svelte
<script lang="ts">
import TagGroup from './TagGroup.svelte'
let favouriteSports: { label: string; value: string }[] = [
{ label: 'Football', value: '⚽' },
{ label: 'Cricket', value: '🏏' },
{ label: 'Baseball', value: '⚾' },
{ label: 'Basketball', value: '🏀' },
{ label: 'Tennis', value: '🎾' },
{ label: 'Badminton', value: '🏸' },
{ label: 'Table Tennis', value: '🏓' },
{ label: 'Swimming', value: '🏊' },
{ label: 'Boxing', value: '🥊' },
]
</script>
<TagGroup label="Favourite sports" bind:options={favouriteSports} />
TagGroup.svelte
<script lang="ts">
import { createTagGroup } from 'louisette'
export let label: string
/** @type {{ label: string; value: string }[]} */
export let options = []
const { tagGroupAttrs, tagAttrs, dismissButtonAttrs } = createTagGroup({
onDismiss: (key) => {
options = options.filter((option) => option.value !== key)
},
})
</script>
<div {...$tagGroupAttrs} class="flex flex-wrap gap-2" aria-label={label}>
{#if options.length > 0}
{#each options as { label, value }}
<div
{...$tagAttrs(value)}
class="flex w-fit place-items-center rounded-md bg-neutral-300 p-2 text-sm font-medium text-neutral-700 dark:bg-neutral-700 dark:text-neutral-300"
>
<span>{label}</span>
<button {...$dismissButtonAttrs(value)}>
<svg
class="ml-1 h-4 w-4 text-neutral-500 dark:text-neutral-400"
fill="currentColor"
viewBox="0 0 20 20"
aria-hidden="true"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M10.7071 10L15.3536 5.35355C15.5488 5.15829 15.5488 4.84171 15.3536 4.64645C15.1583 4.45118 14.8417 4.45118 14.6464 4.64645L10 9.29289L5.35355 4.64645C5.15829 4.45118 4.84171 4.45118 4.64645 4.64645C4.45118 4.84171 4.45118 5.15829 4.64645 5.35355L9.29289 10L4.64645 14.6464C4.45118 14.8417 4.45118 15.1583 4.64645 15.3536C4.84171 15.5488 5.15829 15.5488 5.35355 15.3536L10 10.7071L14.6464 15.3536C14.8417 15.5488 15.1583 15.5488 15.3536 15.3536C15.5488 15.1583 15.5488 14.8417 15.3536 14.6464L10.7071 10Z"
/>
</svg>
</button>
</div>
{/each}
{:else}
<p class="text-sm text-neutral-500 dark:text-neutral-400">
You don't have any favorite sports yet.
</p>
{/if}
</div>