Select

Компонент 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 с минимальными усилиями:

  • Flowbite-Svelte: готовые классы Tailwind для цвета, тени, размера и состояния.
  • Svelte Material UI: интеграция с Material Design, поддержка outlined, filled, label и helperText.
  • SvelteStrap: Bootstrap-подобные Select с поддержкой 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.

Доступность (Accessibility)

Для компонентов 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-компоненты.