Radix UI предоставляет низкоуровневые, полностью управляемые компоненты для построения пользовательских интерфейсов с высокой доступностью и гибкостью. Одними из ключевых строительных блоков при создании всплывающих интерфейсов (popovers, tooltips, dropdowns и модальных окон) являются компоненты Portal, Content и Viewport. Они позволяют отделить визуальное отображение от логики компонента и управлять рендерингом в DOM с высокой точностью.
Компонент Portal используется для рендеринга
дочерних элементов вне обычной иерархии DOM, где находится родительский
компонент. Это особенно важно для модальных окон, тултипов и
поповер-меню, чтобы избежать влияния стилей родительских контейнеров,
таких как overflow: hidden или z-index.
import * as Portal from '@radix-ui/react-portal';
<Portal.Root>
<div style={{ position: 'absolute', top: 0, left: 0 }}>
Контент в портале
</div>
</Portal.Root>
Особенности Portal:
Radix UI также позволяет создавать несколько порталов с разными
контейнерами через Portal.Root container={...}. Это
полезно, если необходимо рендерить компоненты в разных местах DOM,
например, для модальных окон и глобальных уведомлений.
Компонент Content отвечает за визуальное отображение всплывающего интерфейса. Он управляет позиционированием, анимацией и доступностью. Обычно используется вместе с Popover, Tooltip или Dropdown.
import * as Popover from '@radix-ui/react-popover';
<Popover.Root>
<Popover.Trigger>Открыть поповер</Popover.Trigger>
<Popover.Content side="bottom" align="center">
Это содержимое поповера
</Popover.Content>
</Popover.Root>
Ключевые свойства Content:
side: определяет, с какой стороны триггера отображается
контент (top, right, bottom,
left).align: управляет выравниванием контента относительно
триггера (start, center,
end).sideOffset: задает отступ от триггера, влияя на
расстояние между ним и всплывающим окном.collisionPadding: регулирует пространство вокруг окна
для предотвращения выхода за пределы viewport.Дополнительно: Content может быть полностью
кастомизирован с анимациями, стилями и взаимодействиями с другими
компонентами. Он поддерживает ключевые принципы доступности ARIA,
включая role="dialog" или role="tooltip" при
необходимости.
Компонент Viewport определяет область, в пределах которой Content может располагаться. Он используется для управления видимым пространством и предотвращения выхода элементов за границы видимой области.
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
<DropdownMenu.Root>
<DropdownMenu.Trigger>Меню</DropdownMenu.Trigger>
<DropdownMenu.Content>
<DropdownMenu.Viewport>
<div>Пункт 1</div>
<div>Пункт 2</div>
<div>Пункт 3</div>
</DropdownMenu.Viewport>
</DropdownMenu.Content>
</DropdownMenu.Root>
Особенности Viewport:
При использовании Viewport важно помнить о том, что его размеры и положение могут изменяться динамически. Radix UI автоматически рассчитывает позицию Content относительно Viewport, что предотвращает обрезание и скрытие элементов за пределами окна просмотра.
Эти три компонента работают в связке:
Пример интеграции:
<Popover.Root>
<Popover.Trigger>Открыть поповер</Popover.Trigger>
<Portal.Root>
<Popover.Content side="bottom" align="center">
<Popover.Viewport>
<div>Внутренний контент</div>
</Popover.Viewport>
</Popover.Content>
</Portal.Root>
</Popover.Root>
В этом примере Portal гарантирует, что Popover будет отображаться поверх всего контента страницы, Content управляет позиционированием и выравниванием, а Viewport обеспечивает корректное размещение внутри видимой области.
Эта связка компонентов позволяет создавать сложные интерфейсы с высокой гибкостью и полной поддержкой доступности, минимизируя конфликты стилей и обеспечивая надежное поведение всплывающих элементов.