Компонент Select является базовым элементом управления формами, предназначенным для выбора одного или нескольких значений из списка опций. В SvelteKit его реализация строится на реактивности, декларативной разметке и возможности интеграции с библиотеками UI, такими как Svelte Material UI, SvelteStrap, Flowbite-Svelte или кастомные компоненты.
Ключевые свойства компонента:
value — текущее выбранное значение. Может быть строкой,
числом или объектом.items — массив объектов опций. Каждый объект обычно
содержит свойства label и value.placeholder — текст-заполнитель, отображаемый при
отсутствии выбранного значения.disabled — блокирует выбор.multiple — позволяет выбирать несколько элементов.Пример базового Sel ect с реактивным состоянием:
<script>
import { onMount } fr om 'svelte';
let selected = '';
let options = [
{ label: 'Apple', value: 'apple' },
{ label: 'Orange', value: 'orange' },
{ label: 'Banana', value: 'banana' }
];
</script>
<sel ect bind:value={selected}>
<option disabled value=''>Выберите фрукт</option>
{#each options as option}
<option value={option.value}>{option.label}</option>
{/each}
</select>
<p>Выбрано: {selected}</p>
В этом примере bind:value обеспечивает
двустороннюю привязку между переменной selected и текущим
выбранным значением. Любое изменение в Select автоматически обновляет
переменную.
Для множественного выбора необходимо использовать атрибут
multiple и привязку к массиву:
<script>
let selectedFruits = [];
let fruits = ['Apple', 'Orange', 'Banana', 'Grapes'];
</script>
<select bind:value={selectedFruits} multiple size="4">
{#each fruits as fruit}
<option value={fruit}>{fruit}</option>
{/each}
</select>
<p>Выбрано: {selectedFruits.join(', ')}</p>
Особенности множественного выбора:
size задаёт количество видимых элементов.Библиотеки UI для SvelteKit предоставляют возможность стилизовать Select с минимальными усилиями:
outlined, filled, label
и helperText.size, disabled и multiple.Пример кастомного Select с Flowbite-Svelte:
<script>
import { Select } fr om 'flowbite-svelte';
let fruit = '';
let fruits = ['Apple', 'Orange', 'Banana'];
</script>
<Sel ect bind:value={fruit} placeholder="Выберите фрукт" class="w-64">
{#each fruits as f}
<option value={f}>{f}</option>
{/each}
</Select>
<p>Выбран: {fruit}</p>
Иногда опции содержат дополнительные данные, помимо
label и value. В SvelteKit UI можно
использовать привязку к объектам с последующей обработкой:
<script>
let selectedItem = null;
let options = [
{ id: 1, label: 'Apple', color: 'red' },
{ id: 2, label: 'Orange', color: 'orange' },
{ id: 3, label: 'Banana', color: 'yellow' }
];
</script>
<select bind:value={selectedItem}>
<option disabled value={null}>Выберите фрукт</option>
{#each options as option}
<option value={option}>{option.label}</option>
{/each}
</select>
{#if selectedItem}
<p>Выбран: {selectedItem.label}, цвет: {selectedItem.color}</p>
{/if}
Важно помнить, что при работе с объектами нужно использовать
value={option} вместо строки. Это позволяет сохранять всю
структуру данных выбранной опции.
Select поддерживает стандартные DOM-события change,
focus и blur:
<script>
let selected = '';
function handleChange(event) {
console.log('Новое значение:', event.target.value);
}
</script>
<select bind:value={selected} on:change={handleChange}>
<option disabled value=''>Выберите фрукт</option>
<option value="apple">Apple</option>
<option value="orange">Orange</option>
</select>
bind:value работает автоматически, но обработчики
событий позволяют выполнять побочные эффекты, например, валидацию или
отправку данных на сервер.event.target.selectedOptions
предоставляет доступ ко всем выбранным элементам.В крупных приложениях список опций часто загружается с сервера. Для
этого используют реактивные переменные или await блоки:
<script>
let options = [];
let selected = '';
async function fetchOptions() {
const res = await fetch('/api/fruits');
options = await res.json();
}
fetchOptions();
</script>
{#if options.length === 0}
<p>Загрузка...</p>
{:else}
<select bind:value={selected}>
<option disabled value=''>Выберите фрукт</option>
{#each options as option}
<option value={option.value}>{option.label}</option>
{/each}
</select>
{/if}
<p>Выбрано: {selected}</p>
Особенности асинхронного Select:
bind:value.Для компонентов Select важно соблюдать ARIA-стандарты:
aria-label или <label for>
обеспечивают корректное восприятие скринридерами.disabled делает элемент недоступным для
взаимодействия.aria-multiselectable.Пример доступного Select:
<label for="fruits">Выберите фрукт:</label>
<select id="fruits" bind:value={selected} aria-label="Фрукты">
<option disabled value=''>Выберите фрукт</option>
<option value="apple">Apple</option>
<option value="orange">Orange</option>
</select>
Select полностью совместим с формами и библиотеками валидации, такими как Svelte Forms Lib или кастомные решения:
<script>
import { useForm } fr om 'svelte-forms-lib';
let { values, handleSubmit } = useForm({
initialValues: { fruit: '' },
onSubmit: (values) => console.log(values)
});
</script>
<form on:submit|preventDefault={handleSubmit}>
<select bind:value={values.fruit} required>
<option disabled value=''>Выберите фрукт</option>
<option value="apple">Apple</option>
<option value="orange">Orange</option>
</select>
<button type="submit">Отправить</button>
</form>
bind:value к форме позволяет автоматическую
синхронизацию.required, кастомных ошибок и асинхронной
валидации.Эта систематизация демонстрирует полное использование компонента Select в SvelteKit: от базового варианта до асинхронного, множественного выбора, работы с объектами, интеграции в формы и обеспечения доступности. Все возможности реактивного связывания и поддержки событий позволяют строить гибкие, масштабируемые UI-компоненты.