Компонент Accordion

Компонент Accordion используется для организации контента в сворачивающиеся панели, позволяя пользователю управлять видимостью блоков информации. В SvelteKit UI реализация аккордеона строится на компонентах, реактивности и событиях, что обеспечивает гибкость и удобство использования.


Структура Accordion

Типичная структура аккордеона включает следующие элементы:

  1. Accordion — контейнер всего компонента.
  2. AccordionItem — отдельный элемент панели.
  3. AccordionHeader — заголовок, по клику на который происходит открытие или закрытие панели.
  4. AccordionPanel — контент панели, который раскрывается при активации.

Пример базовой структуры:

<Accordion>
  <AccordionItem>
    <AccordionHeader>Панель 1</AccordionHeader>
    <AccordionPanel>
      Контент панели 1
    </AccordionPanel>
  </AccordionItem>
  <AccordionItem>
    <AccordionHeader>Панель 2</AccordionHeader>
    <AccordionPanel>
      Контент панели 2
    </AccordionPanel>
  </AccordionItem>
</Accordion>

Реактивность и управление состоянием

Аккордеон управляет состоянием открытых панелей с помощью реактивных переменных и binding. В SvelteKit UI возможно два режима:

  • Одиночное открытие (single) — одновременно открыта только одна панель.
  • Множественное открытие (multiple) — несколько панелей могут быть раскрыты одновременно.
<script>
  import { Accordion, AccordionItem, AccordionHeader, AccordionPanel } from 'sveltekit-ui';
  
  let activePanels = [0]; // Индексы открытых панелей
</script>

<Accordion bind:active={activePanels} multiple={true}>
  <AccordionItem>
    <AccordionHeader>Панель 1</AccordionHeader>
    <AccordionPanel>Контент 1</AccordionPanel>
  </AccordionItem>
  <AccordionItem>
    <AccordionHeader>Панель 2</AccordionHeader>
    <AccordionPanel>Контент 2</AccordionPanel>
  </AccordionItem>
</Accordion>

Ключевой момент: bind:active связывает состояние компонента с переменной в скрипте, что позволяет динамически управлять открытыми панелями через логику приложения.


Настройка внешнего вида

SvelteKit UI предоставляет набор пропсов для кастомизации:

  • multiple — разрешает множественное открытие.
  • disabled — делает элемент недоступным для взаимодействия.
  • transition — задаёт анимацию при раскрытии панели.
  • class / class:active — добавление CSS-классов для стилизации.

Пример кастомного аккордеона с анимацией:

<Accordion multiple={true} class="my-accordion">
  <AccordionItem>
    <AccordionHeader class="header">Панель с анимацией</AccordionHeader>
    <AccordionPanel transition:slide>
      Содержимое с плавным раскрытием
    </AccordionPanel>
  </AccordionItem>
</Accordion>

<style>
  .my-accordion {
    border: 1px solid #ddd;
    border-radius: 6px;
  }
  .header {
    font-weight: bold;
    cursor: pointer;
  }
</style>

Работа с событиями

Аккордеон поддерживает события для отслеживания действий пользователя:

  • on:open — срабатывает при открытии панели.
  • on:close — срабатывает при закрытии панели.
<Accordion on:open={(e) => console.log('Открыта панель', e.detail)}>
  <AccordionItem>
    <AccordionHeader>Панель событий</AccordionHeader>
    <AccordionPanel>Контент панели</AccordionPanel>
  </AccordionItem>
</Accordion>

Важно: e.detail содержит индекс открытой панели, что позволяет интегрировать аккордеон с внешней логикой.


Доступность и навигация с клавиатуры

SvelteKit UI обеспечивает ARIA-поддержку и навигацию с клавиатуры:

  • ArrowDown / ArrowUp — переключение между заголовками.
  • Enter / Space — открытие/закрытие текущей панели.
  • Tab — переход между элементами страницы без нарушения контекста.

Каждый AccordionHeader автоматически получает нужные ARIA-атрибуты:

  • aria-expanded — состояние панели.
  • aria-controls — идентификатор панели, связанной с заголовком.

Динамическое создание панелей

Можно создавать панели аккордеона динамически, используя массив данных и цикл {#each}:

<script>
  let sections = [
    { title: 'Раздел 1', content: 'Контент 1' },
    { title: 'Раздел 2', content: 'Контент 2' },
    { title: 'Раздел 3', content: 'Контент 3' }
  ];
</script>

<Accordion multiple={true}>
  {#each sections as section}
    <AccordionItem>
      <AccordionHeader>{section.title}</AccordionHeader>
      <AccordionPanel>{section.content}</AccordionPanel>
    </AccordionItem>
  {/each}
</Accordion>

Такой подход упрощает интеграцию аккордеона с данными из API или состояния приложения.


Использование с формами и интерактивным контентом

Аккордеон может содержать сложный контент, включая формы, таблицы и компоненты SvelteKit UI:

<Accordion>
  <AccordionItem>
    <AccordionHeader>Форма обратной связи</AccordionHeader>
    <AccordionPanel>
      <form>
        <input type="text" placeholder="Имя" />
        <input type="email" placeholder="Email" />
        <button type="submit">Отправить</button>
      </form>
    </AccordionPanel>
  </AccordionItem>
</Accordion>

Совет: при использовании интерактивного контента важно контролировать фокус и состояние элементов при открытии/закрытии панели.


Поддержка кастомных иконок

Можно заменить стандартные стрелки или добавить собственные индикаторы состояния панели:

<Accordion>
  <AccordionItem>
    <AccordionHeader>
      <span>Панель с иконкой</span>
      <svg class="icon" width="16" height="16">
        <path d="M1 5 L8 12 L15 5" stroke="currentColor" fill="none"/>
      </svg>
    </AccordionHeader>
    <AccordionPanel>Контент панели</AccordionPanel>
  </AccordionItem>
</Accordion>

С помощью CSS и состояния class:active можно анимировать стрелку при раскрытии:

.icon {
  transition: transform 0.3s;
}
.accordion-header.active .icon {
  transform: rotate(180deg);
}

Итоговый набор возможностей Accordion в SvelteKit UI

  • Простое управление открытыми панелями через bind:active.
  • Поддержка множественного и одиночного раскрытия.
  • Настройка стилей, анимаций и кастомных иконок.
  • Работа с событиями открытия/закрытия.
  • ARIA-поддержка и удобная навигация с клавиатуры.
  • Динамическое создание элементов из массивов данных.
  • Совместимость с интерактивным и сложным контентом внутри панелей.

Компонент Accordion в SvelteKit UI сочетает гибкость, реактивность и удобство для построения как простых, так и сложных интерфейсов.