Drawer и боковые панели

В современных веб-приложениях боковые панели (drawers) используются для организации навигации, фильтров, настроек и дополнительных интерфейсных элементов без перегрузки основного контента. В SvelteKit для реализации таких компонентов часто применяются UI-библиотеки, которые предоставляют готовые абстракции с полной интеграцией в реактивную модель Svelte.


Основные концепции Drawer

Drawer — это панель, которая появляется поверх основного интерфейса или сдвигает контент при открытии. Основные параметры управления:

  • Положение: left, right, top, bottom. Чаще всего боковые панели располагаются слева или справа.
  • Состояние: open или closed. Управляется реактивной переменной.
  • Закрытие по клику вне панели: обеспечивает UX-поведение, когда пользователь кликает по затемнённому фону.
  • Анимация открытия/закрытия: плавные переходы делают интерфейс более дружелюбным.

Пример управления состоянием панели через реактивную переменную:

<script>
  import { Drawer } from 'svelte-ui-lib';
  let isOpen = false;
</script>

<button on:click={() => isOpen = true}>Открыть панель</button>

<Drawer bind:open={isOpen} side="left">
  <h2>Меню</h2>
  <ul>
    <li>Главная</li>
    <li>Профиль</li>
    <li>Настройки</li>
  </ul>
</Drawer>

В этом примере свойство bind:open позволяет синхронизировать состояние Drawer с переменной isOpen. Это ключевая концепция реактивности в Svelte — изменения переменной автоматически обновляют интерфейс.


Слои и оверлей

Drawer обычно сопровождается оверлеем (overlay), который затемняет основной контент и перехватывает клики для закрытия панели. В библиотеке SvelteKit UI оверлей часто настраивается через пропсы:

<Drawer bind:open={isOpen} overlay={true} side="right" closeOnClickOutside={true}>
  <p>Содержимое боковой панели</p>
</Drawer>
  • overlay={true} — добавляет затемнённый фон.
  • closeOnClickOutside={true} — закрывает панель при клике вне её границ.

Оверлей может быть стилизован через CSS-переменные библиотеки, что позволяет менять прозрачность, цвет и z-index без прямого вмешательства в DOM.


Управление размерами и адаптивность

Размер боковой панели можно задавать через CSS или пропсы компонента. Например, в svelte-ui-lib можно указать ширину:

<Drawer bind:open={isOpen} side="left" width="300px">
  <p>Контент панели фиксированной ширины</p>
</Drawer>

Для адаптивного дизайна панели могут занимать:

  • Фиксированную ширину на десктопе.
  • Полную ширину на мобильных устройствах.
<style>
  :global(.drawer-content) {
    width: 80%;
  }

  @media(min-width: 1024px) {
    :global(.drawer-content) {
      width: 300px;
    }
  }
</style>

Вложенные и мульти-дроверы

Иногда требуется несколько панелей одновременно (например, фильтры и меню настроек). В SvelteKit UI поддержка вложенных Drawer осуществляется через независимые состояния:

<script>
  let menuOpen = false;
  let filtersOpen = false;
</script>

<Drawer bind:open={menuOpen} side="left">
  <p>Главное меню</p>
</Drawer>

<Drawer bind:open={filtersOpen} side="right">
  <p>Фильтры товаров</p>
</Drawer>

Важно следить за z-index и оверлеями, чтобы панели корректно перекрывали друг друга.


Интерактивные элементы внутри Drawer

Drawer может содержать любые элементы: формы, кнопки, списки, компоненты SvelteKit UI. Для поддержания хорошей производительности рекомендуется:

  • Использовать ленивую загрузку тяжёлого контента ({#if isOpen}).
  • Минимизировать сложные анимации внутри панели.
  • Обрабатывать события через реактивные переменные и контракты Svelte (on:click, bind:value).

Пример фильтров внутри панели:

<Drawer bind:open={filtersOpen} side="right">
  <h3>Фильтры</h3>
  <label>
    Категория
    <sel ect bind:value={category}>
      <option value="all">Все</option>
      <option value="books">Книги</option>
      <option value="electronics">Электроника</option>
    </select>
  </label>
  <button on:click={applyFilters}>Применить</button>
</Drawer>

Анимации и переходы

SvelteKit UI часто использует встроенные анимации Svelte: slide, fade, fly. Это упрощает создание плавного открытия и закрытия Drawer:

<script>
  import { slide } fr om 'svelte/transition';
  let isOpen = false;
</script>

<Drawer bind:open={isOpen} side="left" transition:slide>
  <p>Слайд-панель с анимацией</p>
</Drawer>

Параметры анимации можно настраивать:

<Drawer bind:open={isOpen} side="left" transition:slide={{ duration: 300, easing: cubicOut }}>
  <p>Настроенный переход</p>
</Drawer>

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

При работе с Drawer важно учитывать:

  • Фокус: при открытии панели фокус должен перемещаться внутрь Drawer.
  • Закрытие через клавишу Escape: обеспечивает поддержку клавиатуры.
  • ARIA-атрибуты: aria-hidden, aria-label и role="dialog" улучшают доступность для screen reader.
<Drawer bind:open={isOpen} side="right" aria-label="Меню фильтров" role="dialog">
  <p>Контент доступной панели</p>
</Drawer>

Интеграция с маршрутизацией SvelteKit

Drawer удобно использовать вместе с навигацией. Например, при смене маршрута автоматически закрывать панель:

<script>
  import { afterNavigate } from '$app/navigation';
  let isOpen = false;

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

Это позволяет сохранять корректное состояние интерфейса при переходах между страницами.


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