Перейти к основному содержанию

Обзор

Tabs связывает каждую вкладку с соответствующей панелью содержимого с помощью общего value. Сохраняйте уникальность значений в пределах одного корневого элемента. Используйте TabButton для ссылок маршрутов и соседних действий.

Использование

Используйте defaultValue, чтобы задать начальный выбор. Корневой элемент управляет последующими изменениями.
Tabs.Tab принимает startIcon, endIcon, badge и size со значением compact, sm или md (по умолчанию sm). Остальные свойства сохраняют контракт установленного Base UI. Значения не ограничены строками или числами. Ссылочные значения должны иметь одинаковую идентичность во вкладке, панели и корневом элементе. Значение корневого элемента null не выбирает ни одной панели.

Компактные вкладки

Используйте size="compact" для каждой вкладки с короткими элементами управления вводом/выводом внутри карточки. Компактные вкладки имеют минимальную высоту строки 24px, мелкий текст и внутренние отступы содержимого 4px с каждой стороны. Существующие размеры sm и md сохраняют минимальную высоту 40px. Компактные вкладки используют те же индикатор, кольцо фокуса и активацию с клавиатуры, что и другие размеры.

Структура

Разместите вкладки и необязательный индикатор внутри Tabs.List. Разместите их панели рядом со списком, все в пределах одного Tabs.Root.
Задайте списку доступное имя и сопоставьте value каждой вкладки с value её панели. Base UI предоставляет идентификаторы вкладки и панели, а также связи aria-controls и aria-labelledby. Когда вы задаёте пользовательский id для Tabs.Panel, установите aria-controls соответствующего Tabs.Tab в тот же идентификатор. Установленная реализация Base UI 1.8.0 требует этой явной связи. Пользовательские идентификаторы вкладок корректно регистрируются для aria-labelledby панели. Добавьте один Tabs.Indicator, если нужна активная линия подчёркивания. List не добавляет индикатор.

Управляемое состояние и сведения о событиях

Передайте value и обновляйте его с помощью onValueChange, чтобы управлять выбором. Колбэк получает следующее значение и сведения о событии Base UI, включая исходное event, reason, activationDirection и cancel().
Активация пользователем имеет причину none. В неуправляемых корневых элементах автоматический резервный выбор может иметь причину initial, disabled или missing. Автоматический резервный выбор может установить null, если не остаётся включённых вкладок. Эти автоматические изменения нельзя отменить. В управляемых корневых элементах выбор остаётся под управлением приложения. Отмените пользовательское изменение до обновления управляемого состояния или используйте тот же колбэк с неуправляемым корневым элементом:

Активация с клавиатуры, ориентация и направление

Tabs.List по умолчанию использует ручную активацию (activateOnFocus={false}). Клавиши со стрелками перемещают фокус; Enter или Space активируют вкладку в фокусе. Установите activateOnFocus, чтобы выбирать вкладку, когда фокус клавиатуры достигает её. Обе политики работают с управляемым и неуправляемым состоянием.
Горизонтальные списки используют Left и Right; вертикальные — Up и Down. Home и End перемещают фокус на первую и последнюю включённые вкладки. Отключённые вкладки пропускаются. Значение loopFocus по умолчанию — true; установите false, чтобы останавливаться на любой границе. Используйте DirectionProvider для направления клавиатуры RTL и dir="rtl" на корневом элементе для макета. Установите orientation="vertical" для Root, чтобы получить вертикальный список и индикатор.

Время жизни панели

Используйте keepMounted, когда содержимое панели должно сохранять своё состояние, пока она неактивна. Неактивные смонтированные панели остаются скрытыми и не занимают место в макете.

Макет панели

Panel заполняет пространство, оставшееся от списка, и может сжиматься меньше своего содержимого по обеим осям, поэтому остаётся в пределах корневого элемента фиксированной высоты. Чтобы прокручивать его содержимое, задайте overflow: auto для панели или для дочернего элемента, который её заполняет, например дочернего элемента flex: 1 панели с flex-разметкой в столбец.

Нативные свойства, композиция рендеринга и refs

Все пять частей сохраняют нативные свойства, обработчики событий, refs и композицию render Base UI. Их className и style также могут быть функциями состояния части. Элементами по умолчанию являются div для Root, List и Panel, button для Tab и span для Indicator. Refs указывают на фактически отрендеренные элементы.
Согласуйте nativeButton с элементом, скомпонованным для вкладки. Используйте nativeButton={false} для пользовательского интерактивного элемента, который не является нативной кнопкой и передаёт предоставленные свойства и ref. Якорь маршрута следует размещать в TabButton, где маршрут управляет навигацией и aria-current.

Визуальное выделение

Используйте highlighted в Tabs.Tab, чтобы выделить его содержимое независимо от выбора, например когда его настройки открыты. Выбор по-прежнему контролируется Tabs.Root.

Свойства

Сгенерированная справка включает публичные свойства для каждой части. Типы состояния публичных частей и типы сведений о причине/изменении Root доступны из twenty-ui/primitives/navigation.

Tabs.Root

string | ((state: TabsRootState) => string | undefined)
CSS class applied to the element, or a function that returns a class based on the component’s state.
any
по умолчанию:"0"
The default value. Use when the component is not controlled. When the value is null, no Tab will be active.
((value: any, eventDetails: TabsRootChangeEventDetails) => void)
Callback invoked when new value is being set.The event reason is 'none' for user-initiated changes, such as a click or keyboard navigation; 'initial' for the first automatic selection or fallback in uncontrolled roots when defaultValue is omitted or undefined, including when the implicit initial value is disabled or missing; 'disabled' for automatic fallback when the selected tab becomes disabled in uncontrolled roots; or 'missing' for automatic fallback when the selected tab is removed, or when an explicit defaultValue never matches a mounted tab in uncontrolled roots.For automatic changes, the selected value can be null when no enabled Tab is available as a fallback.Automatic changes cannot be canceled; calling eventDetails.cancel() for 'initial', 'disabled', or 'missing' has no effect.
"horizontal" | "vertical"
по умолчанию:"horizontal"
The component orientation (layout flow direction).
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, TabsRootState>
Allows you to replace the component’s HTML element with a different tag, or compose it with another component.Accepts a ReactElement or a function that returns the element to render.
CSSProperties | ((state: TabsRootState) => CSSProperties | undefined)
Style applied to the element, or a function that returns a style object based on the component’s state.
any
The value of the currently active Tab. Use when the component is controlled. When the value is null, no Tab will be active.

Tabs.List

boolean
по умолчанию:"false"
Whether to automatically change the active tab on arrow key focus. Otherwise, tabs will be activated using <kbd>Enter</kbd> or <kbd>Space</kbd> key press.
string | ((state: TabsListState) => string | undefined)
CSS class applied to the element, or a function that returns a class based on the component’s state.
boolean
по умолчанию:"true"
Whether to loop keyboard focus back to the first item when the end of the list is reached while using the arrow keys.
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, TabsListState>
Allows you to replace the component’s HTML element with a different tag, or compose it with another component.Accepts a ReactElement or a function that returns the element to render.
CSSProperties | ((state: TabsListState) => CSSProperties | undefined)
Style applied to the element, or a function that returns a style object based on the component’s state.

Tabs.Tab

ReactNode
Content rendered after the label, such as a count.
string | ((state: TabsTabState) => string | undefined)
CSS class applied to the element, or a function that returns a class based on the component’s state.
boolean
Whether the Tab is disabled.If a first Tab on a <Tabs.List> is disabled, it won’t initially be selected. Instead, the next enabled Tab will be selected. However, it does not work like this during server-side rendering, as it is not known during pre-rendering which Tabs are disabled. To work around it, ensure that defaultValue or value on <Tabs.Root> is set to an enabled Tab’s value.
ReactNode
Decorative content after the label and before the badge.
boolean
по умолчанию:"false"
Emphasizes the tab content without changing selection.
boolean
по умолчанию:"true"
Whether the component renders a native <button> element when replacing it via the render prop. Set to false if the rendered element is not a button (for example, <div>).
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, TabsTabState>
Allows you to replace the component’s HTML element with a different tag, or compose it with another component.Accepts a ReactElement or a function that returns the element to render.
"compact" | "md" | "sm"
по умолчанию:"sm"
Visual tab size. Compact uses a 24px minimum height, small text, and 4px content padding; sm and md keep a 40px minimum height.
ReactNode
Icon rendered before the label.
CSSProperties | ((state: TabsTabState) => CSSProperties | undefined)
Style applied to the element, or a function that returns a style object based on the component’s state.
any
обязательно
The value of the Tab.

Tabs.Indicator

string | ((state: TabsIndicatorState) => string | undefined)
CSS class applied to the element, or a function that returns a class based on the component’s state.
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, TabsIndicatorState>
Allows you to replace the component’s HTML element with a different tag, or compose it with another component.Accepts a ReactElement or a function that returns the element to render.
boolean
по умолчанию:"false"
Whether to render itself before React hydrates. This minimizes the time that the indicator isn’t visible after server-side rendering.
CSSProperties | ((state: TabsIndicatorState) => CSSProperties | undefined)
Style applied to the element, or a function that returns a style object based on the component’s state.

Tabs.Panel

string | ((state: TabsPanelState) => string | undefined)
CSS class applied to the element, or a function that returns a class based on the component’s state.
boolean
по умолчанию:"false"
Whether to keep the HTML element in the DOM while the panel is hidden.
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, TabsPanelState>
Allows you to replace the component’s HTML element with a different tag, or compose it with another component.Accepts a ReactElement or a function that returns the element to render.
CSSProperties | ((state: TabsPanelState) => CSSProperties | undefined)
Style applied to the element, or a function that returns a style object based on the component’s state.
any
обязательно
The value of the TabPanel. It will be shown when the Tab with the corresponding value is active.

Миграция

Добавьте явный Tabs.Indicator в списки, которые должны сохранять активную линию подчёркивания. Удалите дублирующиеся индикаторы из композиций, которые ранее полагались на добавление индикатора компонентом List. Держите ссылки маршрутов, элементы управления созданием и элементы управления переполнением вне Tabs.List, чьи дочерние элементы выбирают связанные панели.