Tabs
Switches between related panels on the same page
import { Tabs } from "@nyte-ai/ui/tabs";A row of tabs with one panel visible at a time. Without panels, the list is a switcher whose
onValueChange drives your own view.
Usage
variantstyles the list and its tabs. Nested roots set their own.- Each
Tabs.TabandTabs.Panelneeds a matchingvalue. WithoutdefaultValue, the first tab starts active. valuewithonValueChangecontrols the root.value={null}leaves no tab active.- A hidden panel unmounts unless you pass
keepMounted. A kept panel carrieshidden, so anxstylethat setsdisplaymust also hide it under[hidden]. Tabs.RootandTabs.Panelbring no look of their own. Lay them out withxstyle.- Paint the optional
Tabs.Indicatorwithxstyle.
Anatomy
<Tabs.Root>
<Tabs.List>
<Tabs.Tab />
<Tabs.Indicator />
</Tabs.List>
<Tabs.Panel />
</Tabs.Root>Examples
Basic
<Tabs.Root defaultValue="overview">
<Tabs.List aria-label="Session">
<Tabs.Tab value="overview">Overview</Tabs.Tab>
<Tabs.Tab value="activity">Activity</Tabs.Tab>
</Tabs.List>
<Tabs.Panel value="overview">Three heads, two of them running.</Tabs.Panel>
<Tabs.Panel value="activity">Last run finished 2 minutes ago.</Tabs.Panel>
</Tabs.Root>Segmented
<Tabs.Root variant="segmented" defaultValue="spend">
<Tabs.List aria-label="Usage">
<Tabs.Tab value="spend">Spend</Tabs.Tab>
<Tabs.Tab value="limits">Limits</Tabs.Tab>
<Tabs.Tab value="tools">All tools</Tabs.Tab>
</Tabs.List>
</Tabs.Root>Underline
<Tabs.Root variant="underline" defaultValue="models">
<Tabs.List aria-label="Breakdown">
<Tabs.Tab value="models">Models</Tabs.Tab>
<Tabs.Tab value="tools">Tools</Tabs.Tab>
<Tabs.Tab value="folders">Folders</Tabs.Tab>
</Tabs.List>
</Tabs.Root>Pill
<Tabs.Root variant="pill" defaultValue="plugins">
<Tabs.List aria-label="Inventory">
<Tabs.Tab value="plugins">Plugins</Tabs.Tab>
<Tabs.Tab value="skills">Skills</Tabs.Tab>
<Tabs.Tab value="settings">Settings</Tabs.Tab>
</Tabs.List>
</Tabs.Root>Props
Every part takes xstyle, and className and style as plain values, not functions of state.
See Theming.
Root
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "plain" | "segmented" | "underline" | "pill" | "plain" | segmented fills its track, underline nests in another strip, pill filters a list, and plain switches a surface's content. |
The reference tables below come from Base UI, MIT, © Material-UI SAS.
Groups the tabs and the corresponding panels.
Renders a <div> element.
Root Props:
| Prop | Type | Default | Description |
|---|---|---|---|
| defaultValue | Tabs.Tab.Value | 0 | The default value. Use when the component is not controlled.
When the value is null, no Tab will be active. |
| value | Tabs.Tab.Value | - | The value of the currently active Tab. Use when the component is controlled.
When the value is null, no Tab will be active. |
| onValueChange | ((value: Tabs.Tab.Value, eventDetails: Tabs.Root.ChangeEventDetails) => 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. |
| orientation | Tabs.Root.Orientation | 'horizontal' | The component orientation (layout flow direction). |
| className | string | ((state: Tabs.Root.State) => string | undefined) | - | CSS class applied to the element, or a function that returns a class based on the component's state. |
| style | React.CSSProperties | ((state: Tabs.Root.State) => React.CSSProperties | undefined) | - | Style applied to the element, or a function that returns a style object based on the component's state. |
| render | ReactElement | ((props: HTMLProps, state: Tabs.Root.State) => ReactElement) | - | 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. |
Root Data Attributes:
| Attribute | Type | Description |
|---|---|---|
| data-orientation | 'horizontal' | 'vertical' | Indicates the orientation of the tabs. |
| data-activation-direction | 'left' | 'right' | 'up' | 'down' | 'none' | Indicates the direction of the activation (based on the previous active tab). |
List
Groups the individual tab buttons.
Renders a <div> element.
List Props:
| Prop | Type | Default | Description |
|---|---|---|---|
| activateOnFocus | boolean | false | Whether to automatically change the active tab on arrow key focus. Otherwise, tabs will be activated using Enter or Space key press. |
| loopFocus | 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. |
| className | string | ((state: Tabs.List.State) => string | undefined) | - | CSS class applied to the element, or a function that returns a class based on the component's state. |
| style | React.CSSProperties | ((state: Tabs.List.State) => React.CSSProperties | undefined) | - | Style applied to the element, or a function that returns a style object based on the component's state. |
| render | ReactElement | ((props: HTMLProps, state: Tabs.List.State) => ReactElement) | - | 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. |
List Data Attributes:
| Attribute | Type | Description |
|---|---|---|
| data-orientation | 'horizontal' | 'vertical' | Indicates the orientation of the tabs. |
| data-activation-direction | 'left' | 'right' | 'up' | 'down' | 'none' | Indicates the direction of the activation (based on the previous active tab). |
Tab
An individual interactive tab button that toggles the corresponding panel.
Renders a <button> element.
Tab Props:
| Prop | Type | Default | Description |
|---|---|---|---|
| value* | Tabs.Tab.Value | - | The value of the Tab. |
| nativeButton | 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>). |
| disabled | 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. |
| className | string | ((state: Tabs.Tab.State) => string | undefined) | - | CSS class applied to the element, or a function that returns a class based on the component's state. |
| style | React.CSSProperties | ((state: Tabs.Tab.State) => React.CSSProperties | undefined) | - | Style applied to the element, or a function that returns a style object based on the component's state. |
| render | ReactElement | ((props: HTMLProps, state: Tabs.Tab.State) => ReactElement) | - | 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. |
Tab Data Attributes:
| Attribute | Type | Description |
|---|---|---|
| data-orientation | 'horizontal' | 'vertical' | Indicates the orientation of the tabs. |
| data-disabled | - | Present when the tab is disabled. |
| data-activation-direction | 'left' | 'right' | 'up' | 'down' | 'none' | Indicates the direction of the activation (based on the previous active tab). |
| data-active | - | Present when the tab is active. |
Indicator
A visual indicator that can be styled to match the position of the currently active tab.
Renders a <span> element.
Indicator Props:
| Prop | Type | Default | Description |
|---|---|---|---|
| renderBeforeHydration | boolean | false | Whether to render itself before React hydrates. This minimizes the time that the indicator isn't visible after server-side rendering. |
| className | string | ((state: Tabs.Indicator.State) => string | undefined) | - | CSS class applied to the element, or a function that returns a class based on the component's state. |
| style | React.CSSProperties | ((state: Tabs.Indicator.State) => React.CSSProperties | undefined) | - | Style applied to the element, or a function that returns a style object based on the component's state. |
| render | ReactElement | ((props: HTMLProps, state: Tabs.Indicator.State) => ReactElement) | - | 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. |
Indicator Data Attributes:
| Attribute | Type | Description |
|---|---|---|
| data-orientation | 'horizontal' | 'vertical' | Indicates the orientation of the tabs. |
| data-activation-direction | 'left' | 'right' | 'up' | 'down' | 'none' | Indicates the direction of the activation (based on the previous active tab). |
Indicator CSS Variables:
| Variable | Type | Description |
|---|---|---|
--active-tab-bottom | number | Indicates the distance on the bottom side from the parent's container if the tab is active. |
--active-tab-height | number | Indicates the height of the tab if it is active. |
--active-tab-left | number | Indicates the distance on the left side from the parent's container if the tab is active. |
--active-tab-right | number | Indicates the distance on the right side from the parent's container if the tab is active. |
--active-tab-top | number | Indicates the distance on the top side from the parent's container if the tab is active. |
--active-tab-width | number | Indicates the width of the tab if it is active. |
Panel
A panel displayed when the corresponding tab is active.
Renders a <div> element.
Panel Props:
| Prop | Type | Default | Description |
|---|---|---|---|
| value* | Tabs.Tab.Value | - | The value of the TabPanel. It will be shown when the Tab with the corresponding value is active. |
| className | string | ((state: Tabs.Panel.State) => string | undefined) | - | CSS class applied to the element, or a function that returns a class based on the component's state. |
| style | React.CSSProperties | ((state: Tabs.Panel.State) => React.CSSProperties | undefined) | - | Style applied to the element, or a function that returns a style object based on the component's state. |
| keepMounted | boolean | false | Whether to keep the HTML element in the DOM while the panel is hidden. |
| render | ReactElement | ((props: HTMLProps, state: Tabs.Panel.State) => ReactElement) | - | 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. |
Panel Data Attributes:
| Attribute | Type | Description |
|---|---|---|
| data-orientation | 'horizontal' | 'vertical' | Indicates the orientation of the tabs. |
| data-activation-direction | 'left' | 'right' | 'up' | 'down' | 'none' | Indicates the direction of the activation (based on the previous active tab). |
| data-hidden | - | Present when the panel is hidden. |
| data-index | - | Indicates the index of the tab panel. |
| data-starting-style | - | Present when the panel begins animating in. |
| data-ending-style | - | Present when the panel is animating out. |
Accessibility
- The parts render
role="tablist",role="tab", androle="tabpanel". The indicator rendersrole="presentation". - Label
Tabs.Listwitharia-labeloraria-labelledby. - Arrow keys move focus along the list. Focus wraps at the end unless you pass
loopFocus={false}. - Enter and Space activate the focused tab. With
activateOnFocus, focus activates it.segmentedturnsactivateOnFocuson by default. - A disabled first tab is skipped. Server rendering cannot skip it, so set
defaultValueorvalueto an enabled tab.