Content для каждой вкладки

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


Основная структура Tabs

Компонент Tabs состоит из трёх базовых элементов:

  1. Tabs.Root – контейнер для всей структуры вкладок. Содержит логику переключения и состояния активной вкладки.
  2. Tabs.List – контейнер для заголовков вкладок (Tabs.Trigger).
  3. Tabs.Content – блок, отображающий содержимое активной вкладки.

Пример базовой структуры:

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

<Tabs.Root defaultValue="tab1">
  <Tabs.List>
    <Tabs.Trigger value="tab1">Вкладка 1</Tabs.Trigger>
    <Tabs.Trigger value="tab2">Вкладка 2</Tabs.Trigger>
    <Tabs.Trigger value="tab3">Вкладка 3</Tabs.Trigger>
  </Tabs.List>

  <Tabs.Content value="tab1">
    Контент первой вкладки
  </Tabs.Content>
  <Tabs.Content value="tab2">
    Контент второй вкладки
  </Tabs.Content>
  <Tabs.Content value="tab3">
    Контент третьей вкладки
  </Tabs.Content>
</Tabs.Root>

Ключевой момент: value в Tabs.Content должно совпадать с value соответствующего Tabs.Trigger. Только тогда содержимое будет правильно отображаться при переключении вкладок.


Управление видимостью и рендеринг

Компонент Tabs.Content по умолчанию скрывает контент неактивных вкладок, используя CSS-свойство display: none. Это позволяет экономить ресурсы браузера и предотвращает лишний рендеринг.

Можно управлять анимацией появления и скрытия с помощью CSS или библиотек типа Framer Motion. Пример с плавным появлением:

.tabsContent {
  opacity: 0;
  transition: opacity 0.3s ease-in-out;
}

.tabsContent[data-state='active'] {
  opacity: 1;
}
<Tabs.Content value="tab1" className="tabsContent">
  Плавно отображаемый контент
</Tabs.Content>

Совет: использование атрибута data-state позволяет создавать кастомные стили для активного и неактивного контента.


Динамическая генерация контента вкладок

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

Пример динамического создания:

const tabsData = [
  { id: 'tab1', title: 'Вкладка 1', content: 'Контент первой вкладки' },
  { id: 'tab2', title: 'Вкладка 2', content: 'Контент второй вкладки' },
  { id: 'tab3', title: 'Вкладка 3', content: 'Контент третьей вкладки' },
];

<Tabs.Root defaultValue={tabsData[0].id}>
  <Tabs.List>
    {tabsData.map(tab => (
      <Tabs.Trigger key={tab.id} value={tab.id}>
        {tab.title}
      </Tabs.Trigger>
    ))}
  </Tabs.List>

  {tabsData.map(tab => (
    <Tabs.Content key={tab.id} value={tab.id}>
      {tab.content}
    </Tabs.Content>
  ))}
</Tabs.Root>

Преимущество: такой подход упрощает поддержку кода и позволяет легко добавлять или удалять вкладки без изменений логики отображения контента.


Поддержка вложенных компонентов и сложного контента

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

Пример с формой внутри вкладки:

<Tabs.Content value="tab1">
  <form>
    <label>
      Имя:
      <input type="text" name="name" />
    </label>
    <button type="submit">Отправить</button>
  </form>
</Tabs.Content>

Особенность: состояние компонентов внутри Tabs.Content сохраняется, если не удалять компонент полностью из DOM. Для полной очистки состояния при переключении можно использовать условный рендеринг ({activeTab === 'tab1' && <Form />}).


Кастомизация и стилизация

Radix UI предоставляет низкоуровневые стили, оставляя разработчику свободу для кастомизации. Для Tabs.Content доступны следующие точки кастомизации:

  • className – для применения CSS-классов.
  • data-state – активен или неактивен (active / inactive).
  • data-orientation – горизонтальная или вертикальная ориентация вкладок (horizontal / vertical).

Пример стилизации для вертикальных вкладок:

.tabsContent[data-orientation='vertical'] {
  padding: 16px;
  border-left: 2px solid #333;
}
<Tabs.Root orientation="vertical" defaultValue="tab1">
  ...
  <Tabs.Content value="tab1">Контент вертикальной вкладки</Tabs.Content>
</Tabs.Root>

Управление фокусом и доступностью

Radix UI автоматически добавляет правильные ARIA-атрибуты для вкладок и контента, что обеспечивает:

  • Навигацию с клавиатуры (Tab, стрелки).
  • Объявление текущей активной вкладки для скринридеров.
  • Соответствие стандартам доступности WAI-ARIA.

Для Tabs.Content используются атрибуты:

  • role="tabpanel" – идентифицирует панель как контент вкладки.
  • aria-labelledby – связывает контент с заголовком вкладки.

Это позволяет создавать полностью доступные интерфейсы без дополнительной ручной работы.


Итоговые рекомендации по работе с Tabs.Content

  • Всегда указывать value, соответствующий Tabs.Trigger.
  • Использовать data-state для кастомных анимаций и стилей.
  • Динамически генерировать вкладки и контент из массива данных для удобного масштабирования.
  • Размещать внутри контента любые React-компоненты, учитывая их жизненный цикл и состояние.
  • Настраивать стили через className и атрибуты ориентации.
  • Полностью использовать встроенную доступность, предоставляемую Radix UI.