Radix UI предоставляет низкоуровневые, полностью контролируемые React-компоненты, которые позволяют строить сложные интерфейсы с высокой степенью кастомизации. Основная идея — разбиение компонентов на логическую основу и визуальное отображение, что обеспечивает гибкость при композиции.
В Radix UI многие сложные компоненты разделены на Root, Trigger, Content и другие вспомогательные элементы.
Пример структуры для модального окна:
import * as Dialog from '@radix-ui/react-dialog';
<Dialog.Root>
<Dialog.Trigger>Открыть модалку</Dialog.Trigger>
<Dialog.Overlay />
<Dialog.Content>
<Dialog.Title>Заголовок модалки</Dialog.Title>
<Dialog.Description>Описание модального окна</Dialog.Description>
</Dialog.Content>
</Dialog.Root>
Dialog.Root отвечает за логическое
состояние (открыто/закрыто).Dialog.Trigger — элемент, который инициирует
открытие.Dialog.Content содержит визуальную часть.Dialog.Overlay создаёт фон с затемнением.Такое разделение позволяет полностью контролировать внешний вид, при этом сохраняя доступность и правильное поведение.
Radix UI использует React Context для передачи состояния между вложенными компонентами. Это позволяет строить гибкие композиции без лишних пропсов.
Пример: Select
import * as Sel ect from '@radix-ui/react-select';
<Sel ect.Root>
<Select.Trigger>
<Select.Value placeholder="Выберите опцию" />
</Select.Trigger>
<Select.Content>
<Select.Item value="option1">Опция 1</Select.Item>
<Select.Item value="option2">Опция 2</Select.Item>
</Select.Content>
</Select.Root>
Select.Item автоматически получает доступ к текущему
выбранному значению через контекст, что избавляет от необходимости
передавать пропсы вручную.
Radix UI не навязывает визуальные компоненты. Можно использовать свои элементы вместо стандартных.
Пример кастомного триггера для Popover:
import * as Popover fr om '@radix-ui/react-popover';
<Popover.Root>
<Popover.Trigger asChild>
<button className="custom-button">Открыть Popover</button>
</Popover.Trigger>
<Popover.Content>
<div className="popover-content">Содержимое Popover</div>
</Popover.Content>
</Popover.Root>
Ключевой момент — asChild, который позволяет передать
собственный React-элемент в качестве триггера, сохраняя всю логику Radix
UI.
Radix UI не включает визуальные анимации по умолчанию, но предоставляет состояния компонента, на основе которых можно создавать анимации через CSS или фреймворки типа Framer Motion.
[data-state="open"] {
opacity: 1;
transform: translateY(0);
transition: opacity 0.2s, transform 0.2s;
}
[data-state="closed"] {
opacity: 0;
transform: translateY(-10px);
}
data-state автоматически ставится Radix
UI.Компоненты Radix UI легко комбинируются между собой, что важно для создания сложных интерфейсов.
Пример меню с подменю:
import * as Menu fr om '@radix-ui/react-menu';
<Menu.Root>
<Menu.Trigger>Меню</Menu.Trigger>
<Menu.Content>
<Menu.Item>Опция 1</Menu.Item>
<Menu.Sub>
<Menu.SubTrigger>Подменю</Menu.SubTrigger>
<Menu.SubContent>
<Menu.Item>Подопция 1</Menu.Item>
<Menu.Item>Подопция 2</Menu.Item>
</Menu.SubContent>
</Menu.Sub>
</Menu.Content>
</Menu.Root>
Menu.Sub создаёт вложенный уровень меню.Radix UI предоставляет возможность полностью контролировать состояние
компонента извне через пропсы open,
onOpenChange, value,
onValueChange.
const [open, setOpen] = useState(false);
<Dialog.Root open={open} onOpenCha nge={setOpen}>
<Dialog.Trigger>Открыть</Dialog.Trigger>
<Dialog.Content>Контент модалки</Dialog.Content>
</Dialog.Root>
Эти подходы позволяют создавать масштабируемые, доступные и полностью настраиваемые интерфейсы, где компоненты легко комбинируются и расширяются, сохраняя согласованность и предсказуемость поведения.