Структура элементов меню

Radix UI предоставляет высоко настраиваемые и доступные компоненты интерфейса, одним из которых является Menu. Правильная структура элементов меню играет ключевую роль в обеспечении как удобства использования, так и соответствия стандартам доступности (accessibility, a11y).

В Radix UI меню строится из нескольких базовых компонентов:

  • Menu.Root — корневой компонент меню, управляющий состоянием открытия/закрытия.
  • Menu.Trigger — элемент, который открывает меню, чаще всего кнопка.
  • Menu.Content — контейнер для элементов меню.
  • Menu.Item — отдельный пункт меню.
  • Menu.Group — логическая группа пунктов меню с опциональным заголовком.
  • Menu.Label — заголовок группы или всего меню.
  • Menu.Separator — визуальный разделитель между пунктами или группами.
  • Menu.CheckboxItem / Menu.RadioItem — пункты меню с состоянием выбора.

Иерархия компонентов

Иерархия компонентов в Radix UI строится строго по принципу Root → Trigger → Content → Item. Ошибки в иерархии могут привести к некорректной работе фокуса и потере доступности.

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

import * as Menu from '@radix-ui/react-menu';

<Menu.Root>
  <Menu.Trigger>Открыть меню</Menu.Trigger>
  <Menu.Content>
    <Menu.Item onSel ect={() => console.log('Первый пункт')}>Пункт 1</Menu.Item>
    <Menu.Item onSel ect={() => console.log('Второй пункт')}>Пункт 2</Menu.Item>
    <Menu.Separator />
    <Menu.Group>
      <Menu.Label>Дополнительно</Menu.Label>
      <Menu.Item onSel ect={() => console.log('Третий пункт')}>Пункт 3</Menu.Item>
    </Menu.Group>
  </Menu.Content>
</Menu.Root>

Особенности использования Menu.Group и Menu.Label

  • Menu.Group позволяет объединять элементы меню в логические блоки.
  • Menu.Label внутри группы обеспечивает семантическую структуру для пользователей экранных читалок.

Рекомендация: каждый блок, который требует пояснения или имеет смысловой контекст, оформлять через Menu.Group с Menu.Label.

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

Для интерактивных меню часто используют Menu.CheckboxItem и Menu.RadioItem. Они позволяют реализовать мультивыбор и выбор из нескольких опций:

<Menu.Root>
  <Menu.Trigger>Настройки</Menu.Trigger>
  <Menu.Content>
    <Menu.CheckboxItem checked={true} onCheckedCha nge={() => console.log('Состояние изменено')}>
      Включить уведомления
    </Menu.CheckboxItem>
    <Menu.RadioGroup value="option1" onValueCha nge={(val) => console.log(val)}>
      <Menu.RadioItem value="option1">Опция 1</Menu.RadioItem>
      <Menu.RadioItem value="option2">Опция 2</Menu.RadioItem>
    </Menu.RadioGroup>
  </Menu.Content>
</Menu.Root>

Ключевой момент: Menu.RadioItem должен находиться внутри Menu.RadioGroup, иначе управление состоянием станет некорректным.

Разделители и визуальная организация

Menu.Separator используется для логического отделения элементов и групп.

  • Разделители не должны быть интерактивными.
  • Они помогают пользователю быстро ориентироваться в большом меню.

Взаимодействие с клавиатурой

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

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

Важно сохранять правильную структуру: любой элемент, не являющийся Menu.Item, Menu.CheckboxItem или Menu.RadioItem, должен находиться внутри Menu.Content для корректной навигации с клавиатуры.

Кастомизация и стилизация

  • Menu.Content поддерживает передачу классов или стилей через className и style.
  • Для анимаций открывания меню используется библиотека Radix Animations или CSS-трансформации.
  • Все дочерние элементы наследуют контекст состояния (open, highlighted), что позволяет менять их внешний вид динамически.

Практические рекомендации

  1. Поддержка доступности: всегда использовать Menu.Label для заголовков групп.
  2. Логическая структура: разделять пункты меню на группы и использовать Menu.Separator для визуальной организации.
  3. Управление состоянием: интерактивные элементы (CheckboxItem, RadioItem) должны корректно обновлять состояние через пропсы checked и value.
  4. Навигация клавиатурой: не нарушать иерархию компонентов, чтобы Radix UI автоматически обрабатывал фокус.

Эта структура обеспечивает консистентность меню, корректное поведение на разных устройствах и полную поддержку accessibility, что является одной из ключевых целей Radix UI.