Именование и структура

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

Каждый интерфейсный элемент представлен пространством имён, внутри которого находятся подкомпоненты. Такое построение повторяет структуру DOM и описывает роль каждой части интерфейса.

Пример:

import * as Dialog from "@radix-ui/react-dialog";

<Dialog.Root>
  <Dialog.Trigger>Открыть</Dialog.Trigger>
  <Dialog.Portal>
    <Dialog.Overlay />
    <Dialog.Content>
      <Dialog.Title>Заголовок</Dialog.Title>
      <Dialog.Description>Описание</Dialog.Description>
      <Dialog.Close>Закрыть</Dialog.Close>
    </Dialog.Content>
  </Dialog.Portal>
</Dialog.Root>

В данном примере пространство имён Dialog объединяет все элементы, относящиеся к диалоговому окну.

Основные преимущества такого подхода:

  • логическая группировка компонентов
  • предотвращение конфликтов имён
  • предсказуемость API
  • удобная автодополняемость в IDE

Пространства имён компонентов

Компоненты Radix организованы в модульные пространства имён, экспортируемые через wildcard-импорт.

Типичный импорт:

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

После этого все элементы меню доступны через единый объект:

DropdownMenu.Root
DropdownMenu.Trigger
DropdownMenu.Content
DropdownMenu.Item
DropdownMenu.Separator

Это решение выполняет несколько задач:

  • формирует единый контекст компонента
  • делает API читаемым
  • устраняет необходимость длинных уникальных имён

Без пространства имён имена выглядели бы так:

DropdownMenuRoot
DropdownMenuTrigger
DropdownMenuContent

Подобная схема усложняет читаемость и увеличивает количество повторяющихся префиксов.


Базовые типы компонентов

Архитектура Radix UI делит элементы на несколько категорий.

Root

Root — основной контейнер компонента, управляющий состоянием и контекстом.

<Tabs.Root defaultValue="tab1">

Функции Root:

  • хранение состояния
  • управление взаимодействием
  • предоставление контекста дочерним элементам

Root обычно обязателен для корректной работы компонента.


Trigger

Trigger — элемент, инициирующий действие.

Пример:

<Popover.Trigger>Открыть</Popover.Trigger>

Trigger может быть:

  • кнопкой
  • ссылкой
  • кастомным компонентом

Основная роль — изменение состояния Root.


Content

Content содержит основной визуальный интерфейс.

<Popover.Content>
  Контент всплывающего окна
</Popover.Content>

Content отвечает за:

  • отображение интерфейса
  • позиционирование
  • управление фокусом

Portal

Portal перемещает DOM-узел вне обычной иерархии React.

<Dialog.Portal>
  <Dialog.Content />
</Dialog.Portal>

Преимущества порталов:

  • корректный overlay
  • управление z-index
  • изоляция от родительских контейнеров

Portal особенно важен для:

  • модальных окон
  • тултипов
  • контекстных меню

Overlay

Overlay — затемняющий слой, используемый в модальных интерфейсах.

<Dialog.Overlay />

Функции:

  • блокировка взаимодействия с фоном
  • визуальное разделение слоёв
  • улучшение UX

Item

Item представляет отдельный элемент внутри списка или меню.

Пример:

<DropdownMenu.Item>Копировать</DropdownMenu.Item>

Используется в:

  • меню
  • списках
  • селекторах
  • радиогруппах

Group

Group объединяет несколько элементов в логическую группу.

<DropdownMenu.Group>
  <DropdownMenu.Item>Настройки</DropdownMenu.Item>
  <DropdownMenu.Item>Профиль</DropdownMenu.Item>
</DropdownMenu.Group>

Позволяет:

  • структурировать меню
  • управлять фокусом
  • применять групповые стили

Separator

Separator добавляет визуальный разделитель.

<DropdownMenu.Separator />

Назначение:

  • разделение логических блоков
  • улучшение читаемости интерфейса

Label

Label используется для обозначения группы элементов.

<DropdownMenu.Label>Файл</DropdownMenu.Label>

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

  • не интерактивный
  • используется для структуры

Indicator

Indicator показывает активное состояние.

Пример:

<RadioGroup.Indicator />

Используется в:

  • переключателях
  • чекбоксах
  • радиокнопках

Паттерн составных компонентов

Radix реализует архитектуру compound components.

Суть подхода:

  • один компонент разделён на независимые части
  • части взаимодействуют через контекст

Пример Tabs:

<Tabs.Root defaultValue="account">
  <Tabs.List>
    <Tabs.Trigger value="account">Аккаунт</Tabs.Trigger>
    <Tabs.Trigger value="password">Пароль</Tabs.Trigger>
  </Tabs.List>

  <Tabs.Content value="account">
    Настройки аккаунта
  </Tabs.Content>

  <Tabs.Content value="password">
    Изменение пароля
  </Tabs.Content>
</Tabs.Root>

Каждый подкомпонент выполняет строго определённую функцию.


Структура файлов библиотеки

Внутри пакетов Radix структура повторяет архитектуру компонентов.

Типичная структура:

component-name
 ├─ Root.tsx
 ├─ Trigger.tsx
 ├─ Content.tsx
 ├─ Item.tsx
 ├─ context.ts
 ├─ index.ts

Назначение файлов:

Файл Назначение
Root.tsx основной контейнер
Trigger.tsx интерактивный элемент
Content.tsx визуальная часть
context.ts React Context
index.ts экспорт API

Экспорт компонентов

Radix использует barrel export.

Файл index.ts:

export { Root } from "./Root";
export { Trigger } from "./Trigger";
export { Content } from "./Content";

При использовании wildcard-импорта:

import * as Tooltip from "@radix-ui/react-tooltip";

все компоненты становятся частью пространства имён.


Конвенции именования

Radix придерживается следующих правил:

PascalCase

Все компоненты используют PascalCase.

Пример:

DialogRoot
DialogTrigger
DialogContent

Но через namespace:

Dialog.Root
Dialog.Trigger
Dialog.Content

Семантические названия

Имена отражают роль компонента, а не его внешний вид.

Правильно:

Trigger
Content
Overlay

Неправильно:

BlueButton
PopupBox
ShadowLayer

Такой подход делает компоненты независимыми от дизайна.


Единообразие API

Одинаковые роли имеют одинаковые имена во всей библиотеке.

Например:

Роль Имя
главный контейнер Root
инициатор Trigger
содержимое Content
элемент списка Item
группа Group

Это позволяет легко переносить знания между компонентами.


Структура DOM

Radix строит минималистичный DOM, не добавляя лишних обёрток.

Пример:

<Tooltip.Root>
  <Tooltip.Trigger>?</Tooltip.Trigger>
  <Tooltip.Content>
    Подсказка
  </Tooltip.Content>
</Tooltip.Root>

DOM:

<button>?</button>
<div role="tooltip">Подсказка</div>

Отсутствие лишних контейнеров:

  • улучшает производительность
  • упрощает стилизацию
  • уменьшает вложенность

Атрибуты состояния

Radix активно использует data-атрибуты.

Пример:

data-state="open"
data-state="closed"

Это позволяет стилизовать компоненты через CSS:

[data-state="open"] {
  opacity: 1;
}

[data-state="closed"] {
  opacity: 0;
}

Использование префикса Radix

В пользовательских компонентах часто применяют паттерн обёртки.

Пример:

function MyDialog(props) {
  return <Dialog.Root {...props} />;
}

Такие обёртки:

  • адаптируют компоненты под дизайн-систему
  • сохраняют структуру Radix
  • упрощают повторное использование

Иерархическая композиция

Компоненты Radix строятся по принципу контролируемой вложенности.

Пример сложного интерфейса:

<DropdownMenu.Root>
  <DropdownMenu.Trigger />

  <DropdownMenu.Content>
    <DropdownMenu.Group>
      <DropdownMenu.Item />
      <DropdownMenu.Item />
    </DropdownMenu.Group>

    <DropdownMenu.Separator />

    <DropdownMenu.Item />
  </DropdownMenu.Content>
</DropdownMenu.Root>

Такая структура:

  • отражает реальную логику интерфейса
  • упрощает поддержку
  • повышает читаемость кода

Предсказуемость структуры

Благодаря строгим правилам именования можно угадывать API без документации.

Например, если существует компонент:

Accordion

с высокой вероятностью будут доступны:

Accordion.Root
Accordion.Item
Accordion.Trigger
Accordion.Content

Эта предсказуемость значительно ускоряет разработку.


Роль контекста в структуре

Связь между компонентами реализована через React Context.

Root создаёт контекст:

createContext()

Подкомпоненты получают доступ:

useContext()

Это обеспечивает:

  • синхронизацию состояния
  • изоляцию компонентов
  • гибкость композиции

Итоговая модель структуры

Компоненты Radix формируют трёхуровневую архитектуру:

1. Namespace

Dialog
Tooltip
Tabs
DropdownMenu

2. Основные элементы

Root
Trigger
Content

3. Дополнительные части

Item
Group
Label
Separator
Indicator
Overlay
Portal

Такая модель обеспечивает:

  • модульность
  • предсказуемость API
  • масштабируемость интерфейсов
  • единый стиль разработки.