Accordion компонент

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


Структура Accordion

Стандартный Accordion состоит из двух основных частей:

  1. AccordionItem — отдельная панель с заголовком и содержимым.

  2. AccordionHeader и AccordionPanel — логическая разметка внутри каждой панели:

    • AccordionHeader — кликабельный элемент, который управляет состоянием панели.
    • AccordionPanel — скрываемый блок контента, который появляется при открытии панели.

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

<Accordion>
  <AccordionItem>
    <AccordionHeader>Заголовок панели 1</AccordionHeader>
    <AccordionPanel>
      <p>Содержимое панели 1</p>
    </AccordionPanel>
  </AccordionItem>
  <AccordionItem>
    <AccordionHeader>Заголовок панели 2</AccordionHeader>
    <AccordionPanel>
      <p>Содержимое панели 2</p>
    </AccordionPanel>
  </AccordionItem>
</Accordion>

Управление состоянием

В SvelteKit UI Accordion может быть контролируемым и неконтролируемым:

  • Неконтролируемый: состояние открыто/закрыто управляется внутренне компонентом.
  • Контролируемый: состояние передается через пропсы и может управляться внешним кодом.

Пример контролируемого Accordion:

<script>
  import { Accordion, AccordionItem, AccordionHeader, AccordionPanel } from 'sveltekit-ui';
  let openIndex = 0;

  function toggle(index) {
    openIndex = openIndex === index ? -1 : index;
  }
</script>

<Accordion>
  {#each [0,1,2] as i}
    <AccordionItem>
      <AccordionHeader on:click={() => toggle(i)}>Панель {i + 1}</AccordionHeader>
      <AccordionPanel hidden={openIndex !== i}>
        <p>Содержимое панели {i + 1}</p>
      </AccordionPanel>
    </AccordionItem>
  {/each}
</Accordion>

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

  • hidden или условная отрисовка через {#if} позволяет полностью удалять из DOM закрытые панели, экономя ресурсы.
  • Состояние панели можно хранить в массиве для многоуровневого аккордеона.

Многоуровневый Accordion

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

<Accordion>
  <AccordionItem>
    <AccordionHeader>Основная панель</AccordionHeader>
    <AccordionPanel>
      <Accordion>
        <AccordionItem>
          <AccordionHeader>Подпанель 1</AccordionHeader>
          <AccordionPanel>Содержимое подпанели 1</AccordionPanel>
        </AccordionItem>
        <AccordionItem>
          <AccordionHeader>Подпанель 2</AccordionHeader>
          <AccordionPanel>Содержимое подпанели 2</AccordionPanel>
        </AccordionItem>
      </Accordion>
    </AccordionPanel>
  </AccordionItem>
</Accordion>

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

  • Вложенные аккордеоны наследуют стиль и анимацию родительского компонента.
  • Для каждой вложенной панели можно реализовать отдельное состояние, чтобы избежать конфликтов.

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

SvelteKit UI использует нативные Svelte переходы для плавного открытия и закрытия панелей. Стандартный способ:

<AccordionPanel transition:slide>
  <p>Контент с плавным открытием</p>
</AccordionPanel>
  • slide — стандартный переход для раскрытия по высоте.
  • Можно применять пользовательские переходы с transition:fade или комбинированные эффекты через animate:flip.

Настройка стилей

Accordion поддерживает кастомизацию через классы и CSS-переменные:

<Accordion class="my-accordion">
  <AccordionItem>
    <AccordionHeader class="header-custom">Заголовок</AccordionHeader>
    <AccordionPanel class="panel-custom">
      Контент с кастомными стилями
    </AccordionPanel>
  </AccordionItem>
</Accordion>

<style>
  .my-accordion {
    border: 1px solid #ccc;
    border-radius: 8px;
  }
  .header-custom {
    background: #f0f0f0;
    padding: 12px;
    cursor: pointer;
  }
  .panel-custom {
    padding: 16px;
    background: #fff;
  }
</style>

Советы по стилизации:

  • Использовать переменные для цветов и отступов для соответствия общей теме приложения.
  • Поддерживать фокус и hover состояния через псевдоклассы для улучшения UX.

Доступность

Для доступности Accordion необходимо:

  • Использовать семантические элементы (button для заголовков).
  • Управлять aria-expanded и aria-controls для каждой панели:
<AccordionHeader
  role="button"
  aria-expanded={openIndex === 0}
  aria-controls="panel-0"
>
  Панель 1
</AccordionHeader>
<AccordionPanel id="panel-0" hidden={openIndex !== 0}>
  Контент панели 1
</AccordionPanel>
  • Поддержка клавиатурной навигации: стрелки вверх/вниз для переключения между заголовками.

Интеграция с формами и динамическим контентом

Accordion хорошо сочетается с динамическими списками и формами:

<script>
  let items = [
    { title: 'Панель 1', content: 'Данные 1' },
    { title: 'Панель 2', content: 'Данные 2' }
  ];
</script>

<Accordion>
  {#each items as item}
    <AccordionItem>
      <AccordionHeader>{item.title}</AccordionHeader>
      <AccordionPanel>
        <input type="text" value={item.content} />
      </AccordionPanel>
    </AccordionItem>
  {/each}
</Accordion>
  • Изменения в полях формы внутри панелей автоматически реактивно обновляют данные.
  • Можно добавлять и удалять панели динамически через реактивные массивы.

Лучшие практики

  • Использовать контролируемый режим для сложных интерфейсов с несколькими открытыми панелями.
  • Всегда обеспечивать доступность через aria-атрибуты и семантическую разметку.
  • Минимизировать вложенность, чтобы избежать чрезмерного DOM.
  • Добавлять плавные переходы для улучшения пользовательского опыта.
  • Использовать классы и переменные для единообразной стилизации.

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