Radix UI предоставляет мощный набор компонентов для создания интерфейсов с высокой доступностью и гибкой кастомизацией. Одной из ключевых возможностей является работа с подменю и вложенными меню, что позволяет организовать сложные навигационные структуры без потери контроля над поведением элементов.
В Radix UI компонент Menu построен на
контролируемой модели состояния, где каждый уровень
меню управляется через отдельные элементы: Menu.Root,
Menu.Trigger, Menu.Content,
Menu.Item, Menu.Sub,
Menu.SubTrigger, Menu.SubContent.
Menu.Root — корневой контейнер меню,
который управляет его открытием и закрытием.Menu.Trigger — элемент, отвечающий за
открытие меню (обычно кнопка или иконка).Menu.Content — контейнер, в котором
располагаются пункты меню.Menu.Item — отдельный пункт меню.Menu.Sub — контейнер для подменю,
включающий собственный SubTrigger и
SubContent.Menu.SubTrigger — пункт меню, при
наведении или клике открывающий подменю.Menu.SubContent — контейнер подменю с
вложенными элементами.Эта структура позволяет создавать иерархические меню любой глубины, сохраняя доступность для клавиатурной навигации и экранных читалок.
Для создания подменю внутри основного меню используется комбинация
Menu.Sub, Menu.SubTrigger и
Menu.SubContent:
<Menu.Root>
<Menu.Trigger>Открыть меню</Menu.Trigger>
<Menu.Content>
<Menu.Item>Пункт 1</Menu.Item>
<Menu.Sub>
<Menu.SubTrigger>Пункт 2 с подменю</Menu.SubTrigger>
<Menu.SubContent>
<Menu.Item>Подпункт 2.1</Menu.Item>
<Menu.Item>Подпункт 2.2</Menu.Item>
</Menu.SubContent>
</Menu.Sub>
<Menu.Item>Пункт 3</Menu.Item>
</Menu.Content>
</Menu.Root>
В этой структуре:
Menu.SubTrigger автоматически получает
стрелку, указывающую на наличие подменю.open и
onOpenChange).Radix UI позволяет контролировать открытие и закрытие
подменю через свойства open и
onOpenChange:
const [openSubMenu, setOpenSubMenu] = React.useState(false);
<Menu.Sub open={openSubMenu} onOpenCha nge={setOpenSubMenu}>
<Menu.SubTrigger>Пункт с подменю</Menu.SubTrigger>
<Menu.SubContent>
<Menu.Item>Подпункт 1</Menu.Item>
<Menu.Item>Подпункт 2</Menu.Item>
</Menu.SubContent>
</Menu.Sub>
Такой подход позволяет реализовать:
Radix UI обеспечивает полностью доступные подменю:
ArrowRight открывает подменю, ArrowLeft
закрывает его.Enter и Space активируют элементы
меню.Подменю и их триггеры можно стилизовать как обычные элементы
Menu.Item:
.menuItem {
padding: 8px 12px;
cursor: pointer;
}
.subTrigger {
display: flex;
justify-content: space-between;
align-items: center;
}
.subContent {
background-color: #fff;
border: 1px solid #ccc;
min-width: 150px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
Дополнительно можно использовать sideOffset и
alignOffset для точного позиционирования подменю
относительно родительского пункта:
<Menu.SubContent sideOffset={5} alignOffset={10}>
...
</Menu.SubContent>
Radix UI поддерживает бесконечную вложенность меню:
<Menu.Sub>
<Menu.SubTrigger>Уровень 1</Menu.SubTrigger>
<Menu.SubContent>
<Menu.Item>Пункт A</Menu.Item>
<Menu.Sub>
<Menu.SubTrigger>Уровень 2</Menu.SubTrigger>
<Menu.SubContent>
<Menu.Item>Пункт B</Menu.Item>
<Menu.Sub>
<Menu.SubTrigger>Уровень 3</Menu.SubTrigger>
<Menu.SubContent>
<Menu.Item>Пункт C</Menu.Item>
</Menu.SubContent>
</Menu.Sub>
</Menu.SubContent>
</Menu.Sub>
</Menu.SubContent>
</Menu.Sub>
Важно следить за переходом фокуса и правильной анимацией, чтобы пользователь всегда видел текущий уровень меню.
sideOffset и alignOffset для
корректного отображения на разных экранах.Portal для Menu.Content и
SubContent, чтобы избежать обрезания контента в контейнерах
с overflow: hidden.Эта архитектура позволяет создавать многоуровневые, полностью доступные и кастомизируемые меню, подходящие для любых интерфейсов, от простых навигационных панелей до сложных инструментальных панелей с множеством опций.