Listbox — это компонент пользовательского интерфейса, предназначенный для выбора одного или нескольких значений из списка. В экосистеме SvelteKit UI-библиотек он играет ключевую роль при создании форм, фильтров, выпадающих списков и интерактивных панелей управления.
В отличие от стандартного <select>, Listbox
предоставляет:
Типичная реализация Listbox строится из нескольких логических частей:
Пример базовой структуры:
<script>
import { Listbox } from '@rgossiaux/svelte-headlessui';
let selected = 'apple';
const items = ['apple', 'banana', 'orange'];
</script>
<Listbox bind:value={selected}>
<Listbox.Button>
{selected}
</Listbox.Button>
<Listbox.Options>
{#each items as item}
<Listbox.Option value={item}>
{item}
</Listbox.Option>
{/each}
</Listbox.Options>
</Listbox>
Svelte предоставляет встроенную реактивность, что упрощает работу с Listbox:
$: selectedLabel = selected.toUpperCase();
Связывание через bind:value позволяет:
Listbox позволяет полностью контролировать рендеринг элементов через слоты:
<Listbox.Option value={item} let:active let:selected>
<div class:selected={selected} class:active={active}>
{item}
</div>
</Listbox.Option>
Состояния:
active — элемент под курсором или в фокусеselected — выбранный элементListbox реализует стандарт WAI-ARIA:
Атрибуты доступности:
role="listbox"role="option"aria-selectedЭто делает компонент доступным для screen reader’ов без дополнительной настройки.
Listbox поддерживает выбор нескольких элементов:
<Listbox bind:value={selectedItems} multiple>
Где selectedItems — массив:
let selectedItems = [];
Логика выбора:
Поскольку большинство Svelte UI библиотек используют headless-подход, стили полностью на стороне разработчика.
Пример:
.option {
padding: 8px;
cursor: pointer;
}
.option.active {
background: #eee;
}
.option.selected {
font-weight: bold;
}
Svelte позволяет легко добавлять анимации:
<script>
import { fade } fr om 'svelte/transition';
</script>
<Listbox.Options transition:fade>
Также доступны:
flyslideListbox можно использовать как часть формы:
<form on:submit={handleSubmit}>
<Listbox bind:value={selected} name="fruit">
Однако важно:
<select>Listbox может работать с данными из API:
let items = [];
onMount(async () => {
const res = await fetch('/api/items');
items = await res.json();
});
Важно учитывать:
При большом количестве элементов:
svelte-virtual)<input bind:value={query} placeholder="Поиск..." />
{#each items.filter(i => i.includes(query)) as item}
{#each groups as group}
<div class="group">{group.name}</div>
{#each group.items as item}
const items = [
{ id: 1, name: 'Apple', icon: '?' }
];
<Listbox.Option value={item}>
{item.icon} {item.name}
</Listbox.Option>
| Компонент | Особенности |
|---|---|
<select> |
Нативный, ограниченный |
| Listbox | Гибкий, настраиваемый |
| Combobox | С поиском и вводом |
valueListbox в SvelteKit часто строится на:
setContext, getContext)Это обеспечивает: