Root, Item, Indicator

Root в Radix UI является базовым контейнером для компонентов, предоставляющих управление состоянием и контекстом для вложенных элементов. Он используется в таких компонентах, как Tabs, Accordion и других, где требуется централизованное управление поведением дочерних элементов. Основное предназначение Root — оборачивать дочерние элементы и обеспечивать им доступ к состоянию и событиям, не полагаясь на внешний стейт.

import * as Tabs from '@radix-ui/react-tabs';

<Tabs.Root defaultValue="tab1">
  <Tabs.List>
    <Tabs.Trigger value="tab1">Tab 1</Tabs.Trigger>
    <Tabs.Trigger value="tab2">Tab 2</Tabs.Trigger>
  </Tabs.List>
  <Tabs.Content value="tab1">Content 1</Tabs.Content>
  <Tabs.Content value="tab2">Content 2</Tabs.Content>
</Tabs.Root>

В этом примере Tabs.Root управляет активным состоянием вкладки и передает его дочерним компонентам Tabs.Trigger и Tabs.Content. Основные свойства Root:

  • defaultValue — задает начальное значение выбранного элемента.
  • value — управляемое значение для контроля извне.
  • onValueChange — колбэк при изменении выбранного значения.
  • orientation — определяет ориентацию компонента (горизонтальная или вертикальная).

Item

Item представляет собой интерактивный элемент внутри Root-контейнера. Это могут быть вкладки, элементы меню или элементы аккордеона. Item реагирует на события взаимодействия и синхронизируется с Root по значению.

import * as Tabs from '@radix-ui/react-tabs';

<Tabs.Root defaultValue="tab1">
  <Tabs.List>
    <Tabs.Trigger asChild>
      <button>Tab 1</button>
    </Tabs.Trigger>
  </Tabs.List>
  <Tabs.Content value="tab1">Контент для Tab 1</Tabs.Content>
</Tabs.Root>

Ключевые моменты использования Item:

  • value — уникальный идентификатор элемента для сопоставления с состоянием Root.
  • disabled — делает элемент неактивным, исключая его из фокусировки и взаимодействия.
  • asChild — позволяет использовать собственные элементы (например, button, a) вместо стандартного компонента Radix.
  • События клика и фокуса передаются через Root, что обеспечивает синхронизацию состояния.

Item автоматически реагирует на изменения состояния Root. Например, при смене выбранной вкладки Tabs.Trigger обновляет визуальный стиль без необходимости вручную управлять состоянием.


Indicator

Indicator используется для визуализации активного состояния Item. Например, в Tabs это линия под активной вкладкой. Он полностью синхронизирован с Root и автоматически позиционируется относительно выбранного Item.

import * as Tabs from '@radix-ui/react-tabs';
import { styled } from '@stitches/react';

const TabIndicator = styled(Tabs.Indicator, {
  height: 2,
  backgroundColor: 'blue',
  transition: 'transform 0.2s ease, width 0.2s ease',
});

<Tabs.Root defaultValue="tab1">
  <Tabs.List>
    <Tabs.Trigger value="tab1">Tab 1</Tabs.Trigger>
    <Tabs.Trigger value="tab2">Tab 2</Tabs.Trigger>
    <TabIndicator />
  </Tabs.List>
</Tabs.Root>

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

  • Автоматически позиционируется под активным Item.
  • Поддерживает анимацию через CSS-транзишны или стилизацию через @stitches/react.
  • Может быть кастомизирован по цвету, размеру, форме и анимации.
  • В связке с Root и Item, обеспечивает единое управление визуальной обратной связью для пользователя.

Связь Root, Item и Indicator

Root управляет состоянием и предоставляет контекст. Item является интерактивной точкой, которая подписывается на это состояние через value. Indicator визуализирует текущее состояние выбранного Item. Эта архитектура позволяет:

  • Разделить логику и визуализацию.
  • Создавать доступные компоненты с минимальным количеством кода.
  • Легко кастомизировать визуальные элементы без изменения логики поведения.

Пример комплексного использования:

<Tabs.Root defaultValue="tab1">
  <Tabs.List>
    <Tabs.Trigger value="tab1">Первый</Tabs.Trigger>
    <Tabs.Trigger value="tab2">Второй</Tabs.Trigger>
    <Tabs.Indicator />
  </Tabs.List>
  <Tabs.Content value="tab1">Содержимое первой вкладки</Tabs.Content>
  <Tabs.Content value="tab2">Содержимое второй вкладки</Tabs.Content>
</Tabs.Root>

В этом случае:

  • Root управляет состоянием выбранной вкладки.
  • Каждый Item подписан на Root через уникальное значение.
  • Indicator отображает активный Item и плавно обновляется при переключении.

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