Components

Tabs

Switches between related panels on the same page

import { Tabs } from "@nyte-ai/ui/tabs";

One list of tabs, one panel visible at a time. Reach for it when the panels are peers and the reader only needs one of them at a time. No Nyte styling here.

Usage

  • Each Tabs.Tab and each Tabs.Panel needs a matching value. Without defaultValue on the root, the first tab starts active.
  • Tabs activate on Enter or Space. activateOnFocus on the list activates them on arrow key focus instead.
  • value with onValueChange controls the root. value={null} leaves no tab active.
  • Tabs.Indicator is optional. Position it from the --active-tab-* CSS variables it publishes.
  • A panel carries data-starting-style and data-ending-style while it animates. data-activation-direction says where the newly active tab sits relative to the previous one, so a panel can slide in from the matching side.
  • A hidden panel unmounts unless you pass keepMounted.

Anatomy

<Tabs.Root>
  <Tabs.List>
    <Tabs.Tab />
    <Tabs.Indicator />
  </Tabs.List>
  <Tabs.Panel />
</Tabs.Root>

Examples

Basic

Three heads, two of them running.
<Tabs.Root defaultValue="overview">
  <Tabs.List>
    <Tabs.Tab value="overview">Overview</Tabs.Tab>
    <Tabs.Tab value="activity">Activity</Tabs.Tab>
    <Tabs.Indicator />
  </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>

To render a tab as an anchor, pass the element to render and set nativeButton={false}.

<Tabs.Root>
  <Tabs.List>
    <Tabs.Tab nativeButton={false} render={<a href="/overview" />} value="overview">
      Overview
    </Tabs.Tab>
  </Tabs.List>
</Tabs.Root>

Props

The reference tables below come from Base UI, MIT, © Material-UI SAS.

Root

Groups the tabs and the corresponding panels. Renders a <div> element.

Root Props:

PropTypeDefaultDescription
defaultValueTabs.Tab.Value0The default value. Use when the component is not controlled. When the value is null, no Tab will be active.
valueTabs.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.
orientationTabs.Root.Orientation'horizontal'The component orientation (layout flow direction).
classNamestring | ((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.
styleReact.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.
renderReactElement | ((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:

AttributeTypeDescription
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:

PropTypeDefaultDescription
activateOnFocusbooleanfalseWhether to automatically change the active tab on arrow key focus. Otherwise, tabs will be activated using Enter or Space key press.
loopFocusbooleantrueWhether to loop keyboard focus back to the first item when the end of the list is reached while using the arrow keys.
classNamestring | ((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.
styleReact.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.
renderReactElement | ((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:

AttributeTypeDescription
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:

PropTypeDefaultDescription
value*Tabs.Tab.Value-The value of the Tab.
nativeButtonbooleantrueWhether 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>).
disabledboolean-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.
classNamestring | ((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.
styleReact.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.
renderReactElement | ((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:

AttributeTypeDescription
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:

PropTypeDefaultDescription
renderBeforeHydrationbooleanfalseWhether to render itself before React hydrates. This minimizes the time that the indicator isn't visible after server-side rendering.
classNamestring | ((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.
styleReact.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.
renderReactElement | ((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:

AttributeTypeDescription
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:

VariableTypeDescription
--active-tab-bottomnumberIndicates the distance on the bottom side from the parent's container if the tab is active.
--active-tab-heightnumberIndicates the height of the tab if it is active.
--active-tab-leftnumberIndicates the distance on the left side from the parent's container if the tab is active.
--active-tab-rightnumberIndicates the distance on the right side from the parent's container if the tab is active.
--active-tab-topnumberIndicates the distance on the top side from the parent's container if the tab is active.
--active-tab-widthnumberIndicates 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:

PropTypeDefaultDescription
value*Tabs.Tab.Value-The value of the TabPanel. It will be shown when the Tab with the corresponding value is active.
classNamestring | ((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.
styleReact.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.
keepMountedbooleanfalseWhether to keep the HTML element in the DOM while the panel is hidden.
renderReactElement | ((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:

AttributeTypeDescription
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", and role="tabpanel". The indicator renders role="presentation".
  • Label Tabs.List with aria-label or aria-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, unless activateOnFocus activates it on focus.
  • A disabled first tab is skipped and the next enabled tab is selected. Server rendering does not know which tabs are disabled, so set defaultValue or value to an enabled tab.
  • The focus ring is yours to draw. See Focus.