SideNav для боковой навигации

SideNav — это компонент боковой навигации, предназначенный для организации навигационных элементов в приложениях с большим количеством разделов. Он позволяет создавать как статические, так и динамические меню с многоуровневой структурой, обеспечивая удобную ориентацию пользователя в интерфейсе. В Svelte версия Carbon Components реализована с полной поддержкой реактивности, что облегчает работу с состоянием раскрытых и выбранных пунктов меню.


Основная структура SideNav

SideNav состоит из нескольких ключевых частей:

  1. SideNav — контейнер всего бокового меню.
  2. SideNavItem — элемент навигации, который может быть ссылкой или контейнером для вложенных пунктов.
  3. SideNavItems — обертка для группы вложенных элементов.
  4. SideNavSwitcher — позволяет переключать состояние свернутого и развернутого меню.

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

<script>
  import { SideNav, SideNavItem, SideNavItems } from 'carbon-components-svelte';
</script>

<SideNav expanded={true} aria-label="Main navigation">
  <SideNavItem href="/dashboard">Dashboard</SideNavItem>
  <SideNavItem>
    Управление
    <SideNavItems>
      <SideNavItem href="/users">Пользователи</SideNavItem>
      <SideNavItem href="/settings">Настройки</SideNavItem>
    </SideNavItems>
  </SideNavItem>
  <SideNavItem href="/reports">Отчеты</SideNavItem>
</SideNav>

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

  • Атрибут expanded контролирует развернутое состояние навигации.
  • Вложенные элементы автоматически отображаются только при разворачивании родительского элемента.
  • Атрибут aria-label необходим для доступности и корректной работы экранных читалок.

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

В Carbon Components Svelte поддерживается реактивное управление раскрытием элементов. Для этого используется двусторонняя привязка через Svelte bind::

<script>
  import { SideNav, SideNavItem, SideNavItems } from 'carbon-components-svelte';
  let expanded = false;
</script>

<SideNav bind:expanded aria-label="Navigation menu">
  <SideNavItem>
    Секции
    <SideNavItems>
      <SideNavItem href="/section1">Секция 1</SideNavItem>
      <SideNavItem href="/section2">Секция 2</SideNavItem>
    </SideNavItems>
  </SideNavItem>
</SideNav>

<button on:click={() => expanded = !expanded}>
  {expanded ? 'Свернуть' : 'Развернуть'} меню
</button>

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

  • Использование bind:expanded позволяет контролировать боковую навигацию извне, например, через кнопки или состояния приложения.
  • Можно применять реактивные условия, чтобы динамически изменять содержимое SideNav в зависимости от данных.

Вложенные элементы и группы

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

<SideNavItem>
  Управление проектами
  <SideNavItems>
    <SideNavItem href="/projects/current">Текущие проекты</SideNavItem>
    <SideNavItem>
      Архив
      <SideNavItems>
        <SideNavItem href="/projects/archived/2022">2022</SideNavItem>
        <SideNavItem href="/projects/archived/2023">2023</SideNavItem>
      </SideNavItems>
    </SideNavItem>
  </SideNavItems>
</SideNavItem>

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

  • Не превышать три уровня вложенности для удобства восприятия.
  • Для больших меню использовать динамическую генерацию элементов через массивы объектов и #each.

Динамическая генерация меню

Меню можно строить динамически, используя массив объектов и цикл #each:

<script>
  import { SideNav, SideNavItem, SideNavItems } from 'carbon-components-svelte';

  const menu = [
    { label: 'Dashboard', href: '/dashboard' },
    {
      label: 'Управление',
      children: [
        { label: 'Пользователи', href: '/users' },
        { label: 'Настройки', href: '/settings' }
      ]
    },
    { label: 'Отчеты', href: '/reports' }
  ];
</script>

<SideNav expanded={true}>
  {#each menu as item}
    {#if item.children}
      <SideNavItem>
        {item.label}
        <SideNavItems>
          {#each item.children as child}
            <SideNavItem href={child.href}>{child.label}</SideNavItem>
          {/each}
        </SideNavItems>
      </SideNavItem>
    {:else}
      <SideNavItem href={item.href}>{item.label}</SideNavItem>
    {/if}
  {/each}
</SideNav>

Преимущества:

  • Позволяет легко интегрировать данные из API или хранилища.
  • Поддерживает динамическое обновление без перерисовки всего меню.

Настройка и стилизация

Carbon Components Svelte предоставляет набор CSS-переменных для настройки внешнего вида SideNav:

  • --cds-sidenav-width — ширина боковой панели.
  • --cds-sidenav-background — фон.
  • --cds-sidenav-color — цвет текста.

Пример применения:

<SideNav style="--cds-sidenav-width: 250px; --cds-sidenav-background: #f4f4f4;">
  ...
</SideNav>

Также можно использовать классы Carbon для тонкой настройки отдельных элементов, например:

<SideNavItem class="bx--side-nav__item--active" href="/dashboard">
  Dashboard
</SideNavItem>

События SideNav

SideNav и SideNavItem генерируют события, которые позволяют реагировать на пользовательские действия:

  • on:select — элемент был выбран.
  • on:toggle — раскрытие/сворачивание вложенного меню.

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

<SideNav on:select={(e) => console.log('Выбран элемент:', e.detail)}>
  <SideNavItem href="/dashboard">Dashboard</SideNavItem>
</SideNav>

Итоговые рекомендации по работе с SideNav

  • Использовать bind:expanded для управления состоянием.
  • Для вложенных меню применять SideNavItems внутри SideNavItem.
  • Строить меню динамически через массив объектов для масштабируемости.
  • Настраивать стили через CSS-переменные и классы Carbon.
  • Обрабатывать события select и toggle для интеграции с логикой приложения.

Эта комбинация возможностей позволяет создавать удобные, гибкие и адаптивные боковые навигации в Svelte-приложениях с использованием Carbon Components.