Первый компонент

Radix UI представляет собой набор низкоуровневых компонентов для React, ориентированных на доступность и гибкость. Для работы с библиотекой необходимо установить пакеты через npm или yarn:

npm install @radix-ui/react-primitive @radix-ui/react-portal

или

yarn add @radix-ui/react-primitive @radix-ui/react-portal

Основной подход Radix UI — предоставление unstyled компонентов, которые легко стилизуются с помощью CSS или CSS-in-JS, сохраняя при этом правильное поведение с точки зрения доступности (ARIA, фокус, клавиатурная навигация).

Импорт компонентов

Каждый компонент Radix UI импортируется отдельно. Например, для кнопки (Button) и портала (Portal) используется:

import * as Primitive from '@radix-ui/react-primitive';
import * as Portal from '@radix-ui/react-portal';

Radix UI использует композицию через подкомпоненты, что позволяет комбинировать базовые элементы с дополнительной логикой.

Создание первого компонента: Button

Базовая структура

Компонент Button в Radix UI строится на основе Primitive.Button, который является простым React-элементом с встроенной поддержкой фокуса, клика и клавиатурных событий.

import * as Primitive from '@radix-ui/react-primitive';

const Button = (props) => {
  return <Primitive.Button {...props} className="btn">{props.children}</Primitive.Button>;
};

Здесь:

  • Primitive.Button — основной элемент с поддержкой ARIA и клавиатуры.
  • className="btn" — возможность добавления кастомных стилей.
  • {...props} — передача всех свойств родительского компонента.

Добавление кастомных состояний

Radix UI позволяет использовать состояния взаимодействия, такие как hover, active, focus:

.btn {
  padding: 0.6rem 1.2rem;
  border-radius: 6px;
  background-color: #3b82f6;
  color: #fff;
  border: none;
  cursor: pointer;
  transition: background-color 0.2s;
}

.btn:hover {
  background-color: #2563eb;
}

.btn:focus {
  outline: 2px solid #60a5fa;
  outline-offset: 2px;
}

.btn:active {
  background-color: #1d4ed8;
}

Это позволяет компоненту сохранять все преимущества доступности Radix UI, но при этом выглядеть современно.

Работа с порталами: Portal

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

import * as Portal from '@radix-ui/react-portal';

const Modal = ({ children }) => {
  return (
    <Portal.Root>
      <div className="modal-overlay">
        <div className="modal-content">{children}</div>
      </div>
    </Portal.Root>
  );
};
  • Portal.Root создаёт контейнер для рендеринга вне текущего DOM.
  • Структура overlay + content обеспечивает удобное позиционирование и стилизацию.

Управление состояниями с помощью Radix UI primitives

Компоненты Radix UI часто используют controlled и uncontrolled подходы для управления состояниями. Например, компонент Toggle может быть реализован через Primitive.Button с внутренним состоянием:

import { useState } from 'react';
import * as Primitive from '@radix-ui/react-primitive';

const ToggleButton = () => {
  const [on, setOn] = useState(false);

  return (
    <Primitive.Button
      onCl ick={() => setOn(!on)}
      aria-pressed={on}
      className={`btn ${on ? 'btn-on' : ''}`}
    >
      {on ? 'Включено' : 'Выключено'}
    </Primitive.Button>
  );
};
  • aria-pressed обеспечивает правильное ARIA-состояние.
  • Динамический className позволяет визуально отображать состояние.
.btn-on {
  background-color: #16a34a;
}

Композиция и расширение компонентов

Radix UI ориентирован на композицию через вложенные элементы. Например, создание сложного компонента с тултипом:

import * as Primitive from '@radix-ui/react-primitive';
import * as Portal from '@radix-ui/react-portal';

const TooltipButton = ({ label }) => (
  <Primitive.Root>
    <Primitive.Button className="btn">Нажми меня</Primitive.Button>
    <Portal.Root>
      <div className="tooltip">{label}</div>
    </Portal.Root>
  </Primitive.Root>
);
  • Primitive.Root управляет контейнером для всех вложенных элементов.
  • Использование портала гарантирует корректное позиционирование тултипа поверх других элементов.

Рекомендации по стилям и архитектуре

  1. Использовать CSS-модули или Tailwind для удобной стилизации unstyled компонентов.
  2. Сохранять семантику и ARIA-атрибуты, предоставляемые Radix UI.
  3. Разделять базовую логику компонента и стили, чтобы компоненты оставались переиспользуемыми.
  4. Для сложных UI использовать комбинацию Primitive + Portal + внутренние состояния.

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