Root, Trigger, Anchor, Portal, Content

Компонент Root в Radix UI выполняет роль контейнера и точки входа для многих интерактивных элементов, таких как выпадающие меню, модальные окна и тултипы. Он управляет состоянием дочерних компонентов и обеспечивает согласованное поведение интерфейса. Обычно Root используется один раз на уровне одного интерактивного элемента и оборачивает остальные компоненты, такие как Trigger и Content.

Ключевые особенности Root:

  • Управление состоянием открытия/закрытия.
  • Поддержка контролируемого и неконтролируемого состояния через пропсы open и onOpenChange.
  • Интеграция с другими компонентами Radix UI для построения комплексных интерфейсов.

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

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

<DropdownMenu.Root>
  <DropdownMenu.Trigger>Меню</DropdownMenu.Trigger>
  <DropdownMenu.Content>
    <DropdownMenu.Item>Пункт 1</DropdownMenu.Item>
    <DropdownMenu.Item>Пункт 2</DropdownMenu.Item>
  </DropdownMenu.Content>
</DropdownMenu.Root>

Trigger

Trigger — компонент, инициирующий открытие или закрытие Root. Он может быть любой интерактивной HTML-элемент (кнопка, ссылка, иконка), но рекомендуется использовать семантически правильные элементы для доступности.

Основные свойства и возможности:

  • asChild позволяет обернуть кастомный элемент, сохранив функциональность Trigger.
  • Поддержка событий клика, фокуса и клавиатуры.
  • Управление открытием Root автоматически при взаимодействии.

Пример с кастомным элементом:

<DropdownMenu.Trigger asChild>
  <button>Открыть меню</button>
</DropdownMenu.Trigger>

Anchor

Anchor используется для позиционирования компонентов Content относительно определённого элемента. Он часто применяется, когда требуется точное расположение тултипов, поповеров и выпадающих меню.

Основные моменты:

  • Anchor не отображает визуально контент, а служит опорой для позиционирования.
  • Работает вместе с библиотекой @radix-ui/react-primitive или напрямую с CSS-свойствами позиционирования.
  • Может быть динамически изменён, что позволяет создавать адаптивные интерфейсы.

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

<DropdownMenu.Anchor>
  <span>Наведи сюда</span>
</DropdownMenu.Anchor>
<DropdownMenu.Content>Содержимое меню</DropdownMenu.Content>

Portal

Portal позволяет рендерить компоненты вне стандартного DOM-дерева родителя. Это важно для элементов, которым требуется независимое позиционирование и контроль z-index, например, модальные окна или всплывающие подсказки.

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

  • Упрощает работу с наложением элементов и перекрытием.
  • Поддерживает анимации и переходы без влияния на родительский контейнер.
  • Полностью совместим с React-порталами, что обеспечивает стабильность рендера.

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

<DropdownMenu.Portal>
  <DropdownMenu.Content>Содержимое меню</DropdownMenu.Content>
</DropdownMenu.Portal>

Content

Content отображает визуальную часть интерактивного элемента и всегда находится внутри Root. Он отвечает за внешний вид, размеры и позиционирование, а также может содержать элементы взаимодействия, такие как Item, Checkbox или Radio.

Особенности компонента Content:

  • Поддержка анимации появления и скрытия через CSS или сторонние библиотеки.
  • Полная кастомизация внешнего вида и структуры через styled-components, Tailwind или обычные CSS-классы.
  • Автоматическое управление фокусом и доступностью: Content получает фокус при открытии и закрывает Root при взаимодействии вне него.

Пример с анимацией:

<DropdownMenu.Content
  sideOffset={5}
  className="dropdown-content"
>
  <DropdownMenu.Item>Пункт 1</DropdownMenu.Item>
  <DropdownMenu.Item>Пункт 2</DropdownMenu.Item>
</DropdownMenu.Content>

Важные параметры Content:

  • side — сторона, с которой Content появляется относительно Trigger.
  • align — выравнивание относительно Trigger (start, center, end).
  • sideOffset и alignOffset — точная настройка позиции для гибкой верстки.

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