SideNavMenu для вложенных меню

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

Структура SideNavMenu

Компонент SideNavMenu состоит из нескольких ключевых элементов:

  • SideNav — контейнер для всей боковой панели.
  • SideNavMenu — отдельный блок меню, который может содержать вложенные пункты.
  • SideNavMenuItem — конечная точка навигации, представляющая ссылку или действие.
  • SideNavMenuDivider — визуальный разделитель между пунктами меню.

Простейший пример структуры:

<SideNav>
  <SideNavMenu title="Основное меню">
    <SideNavMenuItem href="/dashboard">Панель управления</SideNavMenuItem>
    <SideNavMenuItem href="/settings">Настройки</SideNavMenuItem>
  </SideNavMenu>
</SideNav>

Создание вложенных меню

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

<SideNav>
  <SideNavMenu title="Управление">
    <SideNavMenuItem href="/users">Пользователи</SideNavMenuItem>
    <SideNavMenu title="Проекты">
      <SideNavMenuItem href="/projects/active">Активные</SideNavMenuItem>
      <SideNavMenuItem href="/projects/archived">Архивные</SideNavMenuItem>
    </SideNavMenu>
  </SideNavMenu>
</SideNav>

В этом примере меню «Проекты» вложено в меню «Управление», создавая двухуровневую структуру.

Атрибуты и свойства

SideNavMenu поддерживает следующие ключевые свойства:

  • title — текст заголовка меню.
  • isExpanded — булевый флаг, указывающий, раскрыто ли меню по умолчанию.
  • renderIcon — функция или компонент для отображения иконки рядом с заголовком.
  • on:toggle — событие, вызываемое при раскрытии или закрытии меню.

SideNavMenuItem имеет основные атрибуты:

  • href — ссылка для навигации.
  • isActive — булево значение, определяющее активное состояние элемента.
  • renderIcon — опциональная иконка.
  • on:click — обработчик клика.

Пример с раскрытием меню по умолчанию и иконкой:

<SideNav>
  <SideNavMenu title="Документы" isExpanded={true} renderIcon={DocumentIcon}>
    <SideNavMenuItem href="/docs/reports" isActive={true}>Отчёты</SideNavMenuItem>
    <SideNavMenuItem href="/docs/manuals">Руководства</SideNavMenuItem>
  </SideNavMenu>
</SideNav>

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

Компоненты Carbon Components Svelte позволяют отслеживать пользовательские действия через события:

  • toggle для SideNavMenu — уведомляет о раскрытии или закрытии подменю.
  • click для SideNavMenuItem — позволяет выполнять кастомные действия при выборе пункта.

Пример использования события toggle:

<SideNavMenu title="Проекты" on:toggle={(e) => console.log('Меню проекты', e.detail.isExpanded)}>
  <SideNavMenuItem href="/projects/active">Активные</SideNavMenuItem>
  <SideNavMenuItem href="/projects/archived">Архивные</SideNavMenuItem>
</SideNavMenu>

Стилизация и кастомизация

Carbon Components Svelte наследует систему стилей IBM Carbon, но позволяет настраивать:

  • Размер иконок через CSS-переменные.
  • Цвет активного пункта через классы bx--side-nav__link--current.
  • Визуальные отступы и маргины для вложенных меню через вложенные селекторы.

Пример кастомного стиля для вложенного меню:

.bx--side-nav__link--nested {
  padding-left: 2rem;
  font-weight: 500;
}

Рекомендации по использованию

  • Использовать вложенные меню только для логически связанных элементов.
  • Минимизировать количество уровней вложенности для удобства навигации.
  • Активное состояние меню синхронизировать с текущим маршрутом приложения.
  • Использовать иконки для визуального разделения категорий, особенно при большом количестве пунктов.

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

При использовании SvelteKit или любого роутера рекомендуется связывать isActive с текущим маршрутом:

<script>
  import { page } from '$app/stores';
  import { derived } from 'svelte/store';

  const currentPath = derived(page, $page => $page.url.pathname);
</script>

<SideNavMenu title="Проекты">
  <SideNavMenuItem href="/projects/active" isActive={$currentPath === '/projects/active'}>Активные</SideNavMenuItem>
  <SideNavMenuItem href="/projects/archived" isActive={$currentPath === '/projects/archived'}>Архивные</SideNavMenuItem>
</SideNavMenu>

Это гарантирует, что меню будет автоматически подсвечивать активный пункт при смене маршрута.

Производительность и динамические меню

Вложенные SideNavMenu можно генерировать динамически на основе массива объектов:

<script>
  const menuItems = [
    {
      title: 'Проекты',
      items: [
        { title: 'Активные', href: '/projects/active' },
        { title: 'Архивные', href: '/projects/archived' }
      ]
    },
    {
      title: 'Пользователи',
      items: [
        { title: 'Все пользователи', href: '/users' },
        { title: 'Роли', href: '/roles' }
      ]
    }
  ];
</script>

<SideNav>
  {#each menuItems as menu}
    <SideNavMenu title={menu.title}>
      {#each menu.items as item}
        <SideNavMenuItem href={item.href}>{item.title}</SideNavMenuItem>
      {/each}
    </SideNavMenu>
  {/each}
</SideNav>

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