Root и Thumb

Библиотека Radix UI предоставляет низкоуровневые компоненты для построения доступных и настраиваемых интерфейсов в React. Два ключевых элемента, которые часто используются вместе в интерактивных контролах, таких как слайдеры и переключатели, — это Root и Thumb. Понимание их структуры и взаимодействия является фундаментом для создания сложных пользовательских интерфейсов.


Компонент Root

Root служит корневым контейнером для интерактивного элемента. В случае слайдера это основной трек, на котором перемещается Thumb. Основные характеристики Root:

  • Контейнер состояния: Root управляет внутренним состоянием компонента, таким как текущая позиция ползунка, минимальное и максимальное значение.
  • Атрибуты доступа: Root автоматически добавляет ARIA-атрибуты для обеспечения доступности. Например, role="slider" и aria-valuenow, которые обновляются при изменении значения.
  • Event handling: Root обрабатывает события мыши и клавиатуры, включая перетаскивание, клики и нажатия клавиш.

Пример базового использования Root в слайдере:

import * as Slider from '@radix-ui/react-slider';

<Slider.Root
  defaultValue={[50]}
  min={0}
  max={100}
  step={1}
  aria-label="Volume"
>
  <Slider.Track>
    <Slider.Range />
  </Slider.Track>
  <Slider.Thumb />
</Slider.Root>

Ключевые моменты Root:

  • defaultValue задаёт начальное положение ползунка.
  • min и max определяют диапазон значений.
  • step контролирует шаг изменения значения.
  • ARIA-атрибуты автоматически синхронизируются с текущим состоянием.

Компонент Thumb

Thumb представляет собой интерактивную ручку, которую пользователь перетаскивает вдоль трека. Основные особенности:

  • Взаимодействие с Root: Thumb получает позицию и события от Root, позволяя изменять значение при перетаскивании.
  • Стилизация и кастомизация: Thumb можно полностью стилизовать через CSS или с помощью библиотек типа Tailwind. Важно, чтобы Thumb оставался доступным и реагировал на фокус клавиатуры.
  • ARIA-совместимость: Thumb наследует атрибуты aria-valuenow, aria-valuemin, aria-valuemax от Root, что делает ползунок полностью доступным для экранных читалок.

Пример кастомного Thumb:

<Slider.Thumb
  className="w-5 h-5 bg-blue-500 rounded-full shadow-md hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-400"
/>

Ключевые моменты Thumb:

  • Обязателен для управления интерактивностью Root.
  • Может содержать анимации и визуальные эффекты при наведении или фокусе.
  • Поддерживает как мышь, так и клавиатуру для перемещения.

Взаимодействие Root и Thumb

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

Передача событий

Root управляет событиями onValueChange и onValueCommit, которые позволяют синхронизировать состояние приложения с позицией Thumb:

<Slider.Root
  defaultValue={[30]}
  min={0}
  max={100}
  step={5}
  onValueCha nge={(value) => console.log('Current value:', value)}
>
  <Slider.Track>
    <Slider.Range />
  </Slider.Track>
  <Slider.Thumb />
</Slider.Root>
  • onValueChange вызывается при каждом перемещении Thumb.
  • onValueCommit срабатывает, когда пользователь завершает взаимодействие (например, отпускает мышь).

Стилизация и кастомизация

Radix UI предоставляет только базовую функциональность. Внешний вид компонентов Root и Thumb полностью настраивается через CSS или CSS-in-JS. Основные подходы:

  1. Track и Range: трек (Track) задаёт фон слайдера, Range отображает заполненную часть.
  2. Thumb: можно добавить тени, анимацию и эффекты при наведении.
  3. Accessibility: при кастомизации сохраняются ARIA-атрибуты, что гарантирует доступность.

Пример интеграции с Tailwind:

<Slider.Root className="relative w-full h-2 bg-gray-200 rounded">
  <Slider.Track className="absolute h-2 bg-gray-400 rounded">
    <Slider.Range className="bg-blue-500 rounded" />
  </Slider.Track>
  <Slider.Thumb className="w-4 h-4 bg-white border-2 border-blue-500 rounded-full shadow-md focus:ring-2 focus:ring-blue-300" />
</Slider.Root>

Поддержка нескольких Thumb

Radix UI позволяет использовать несколько Thumb внутри одного Root для создания диапазонных слайдеров. Каждый Thumb управляет своим значением, а Root координирует их позиции и предотвращает пересечение:

<Slider.Root defaultValue={[20, 80]} min={0} max={100} step={1}>
  <Slider.Track>
    <Slider.Range />
  </Slider.Track>
  <Slider.Thumb />
  <Slider.Thumb />
</Slider.Root>
  • Первый Thumb управляет минимальным значением диапазона.
  • Второй Thumb управляет максимальным значением.
  • Range автоматически отображает заполненный участок между двумя Thumb.

Советы по производительности

  • Избегать ререндеров всего Root при перемещении Thumb: использовать onValueChange для локальных обновлений.
  • Минимизировать DOM-дерево внутри Thumb, чтобы не создавать лишние вычисления при перетаскивании.
  • Оптимизировать стилизацию через классы или CSS-in-JS для плавной анимации.

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