Dropdown Menu

Dropdown Menu — это компонент интерфейса, который предоставляет пользователю список опций, скрытых по умолчанию и раскрывающихся при взаимодействии. В SvelteKit реализация таких меню строится на реактивных свойствах и событиях, что позволяет создавать динамичные и доступные интерфейсы без обширного количества кода.

Структура компонента

Базовая структура Dropdown Menu в SvelteKit обычно состоит из трёх ключевых элементов: триггера, контейнера меню и элементов меню.

<script>
  import { onMount } from 'svelte';
  let isOpen = false;

  function toggleMenu() {
    isOpen = !isOpen;
  }

  function closeMenu() {
    isOpen = false;
  }
</script>

<div class="dropdown">
  <button class="dropdown-trigger" on:click={toggleMenu}>
    Выберите опцию
  </button>
  {#if isOpen}
    <ul class="dropdown-menu" on:click|outside={closeMenu}>
      <li class="dropdown-item">Опция 1</li>
      <li class="dropdown-item">Опция 2</li>
      <li class="dropdown-item">Опция 3</li>
    </ul>
  {/if}
</div>

Ключевые моменты:

  • isOpen — реактивная переменная, отвечающая за видимость меню.
  • toggleMenu — функция для переключения состояния меню.
  • on:click|outside — директива SvelteKit для закрытия меню при клике вне области меню (в некоторых UI-библиотеках эта функциональность реализуется встроенными обработчиками).

Работа с элементами меню

Элементы меню (<li class="dropdown-item">) могут быть интерактивными. Для этого можно использовать событие on:click:

<li class="dropdown-item" on:click={() => selectOption('Опция 1')}>Опция 1</li>

<script>
  function selectOption(option) {
    console.log('Выбрана опция:', option);
    isOpen = false;
  }
</script>

Такое поведение обеспечивает мгновенный отклик интерфейса и закрытие меню после выбора.

Управление доступностью (Accessibility)

Dropdown Menu должен быть доступным для клавиатурного управления и экранных читалок. Для этого используются ARIA-атрибуты:

<button
  class="dropdown-trigger"
  aria-haspopup="true"
  aria-expanded={isOpen}
  on:click={toggleMenu}
>
  Выберите опцию
</button>

<ul
  class="dropdown-menu"
  role="menu"
  aria-hidden={!isOpen}
>
  <li role="menuitem" tabindex="0">Опция 1</li>
  <li role="menuitem" tabindex="0">Опция 2</li>
</ul>

Рекомендации:

  • aria-haspopup="true" сообщает, что кнопка открывает меню.
  • aria-expanded динамически отражает состояние меню.
  • role="menu" и role="menuitem" повышают совместимость с экранными читалками.
  • tabindex="0" делает элементы доступными для навигации с клавиатуры.

Стиль и анимации

SvelteKit позволяет интегрировать CSS-анимации и переходы через встроенные директивы transition и animate. Для Dropdown Menu часто применяются плавные эффекты появления и скрытия:

<ul class="dropdown-menu" transition:fade={{ duration: 200 }}>
  <li class="dropdown-item">Опция 1</li>
  <li class="dropdown-item">Опция 2</li>
</ul>

<style>
  .dropdown-menu {
    background: white;
    border: 1px solid #ccc;
    border-radius: 4px;
    position: absolute;
    margin-top: 4px;
    min-width: 150px;
    box-shadow: 0 4px 8px rgba(0,0,0,0.1);
    padding: 0;
    list-style: none;
  }

  .dropdown-item {
    padding: 8px 16px;
    cursor: pointer;
  }

  .dropdown-item:hover {
    background-color: #f5f5f5;
  }
</style>

Использование transition:fade позволяет плавно появляться списку опций, что улучшает визуальное восприятие.

Сложные сценарии

Для динамических приложений Dropdown Menu может содержать вложенные подменю, разделители и опции с чекбоксами или радиокнопками:

<li class="dropdown-item">
  Настройки
  <ul class="submenu">
    <li><input type="checkbox" id="notif" /> <label for="notif">Уведомления</label></li>
    <li><input type="radio" name="theme" id="light" /> <label for="light">Светлая тема</label></li>
  </ul>
</li>

Особенности:

  • Подменю создаются как вложенные списки <ul>.
  • Элементы с чекбоксами и радиокнопками поддерживают реактивное связывание данных через Svelte bind:checked.

Интеграция с UI-библиотеками

Многие библиотеки для SvelteKit (например, Svelte Material UI, Flowbite-Svelte, Shadcn UI) предоставляют готовые Dropdown Menu с расширенными возможностями:

  • Управление состоянием через store.
  • Автоматическое закрытие при клике вне меню.
  • Поддержка клавиатурной навигации по умолчанию.
  • Темизация через пропсы и CSS-переменные.

Пример использования Flowbite-Svelte:

<script>
  import { Dropdown } from 'flowbite-svelte';
</script>

<Dropdown label="Меню">
  <Dropdown.Item>Профиль</Dropdown.Item>
  <Dropdown.Item>Настройки</Dropdown.Item>
  <Dropdown.Item>Выход</Dropdown.Item>
</Dropdown>

Эта интеграция снимает необходимость ручной реализации логики открытия, закрытия и анимаций.

Выводы по архитектуре

Dropdown Menu в SvelteKit строится вокруг реактивных переменных и событий, что обеспечивает компактный код и высокую динамичность. Основные элементы: триггер, контейнер меню, элементы списка. Важны аспекты доступности, плавные анимации и поддержка вложенных структур. Использование UI-библиотек упрощает разработку и обеспечивает готовые, проверенные решения для профессионального интерфейса.