Skip to content

Tabs

Controlled tab wrapper. Uses `tablist` / `tabpanel` semantics, so reach for it when selecting an option shows or hides associated content panels. To pick a value without swapping panels — a styled radio group for filters, settings, or view modes — use SegmentedControl instead.

Overview content
<TabsStory {...args} />
Overview content
<TabsStory {...args} />
<div style={{display: 'grid', gap: 16}}>
<Tabs {...args} onChange={() => {}} size="sm" value="overview">
<Tab label="Overview" value="overview" />
<Tab label="Activity" value="activity" />
</Tabs>
<Tabs {...args} onChange={() => {}} size="lg" value="overview">
<Tab label="Overview" value="overview" />
<Tab label="Activity" value="activity" />
</Tabs>
</div>
<div style={{display: 'grid', gap: 16}}>
<Tabs {...args} hasDivider={false} onChange={() => {}} value="overview">
<Tab label="Overview" value="overview" />
<Tab label="Activity" value="activity" />
</Tabs>
<Tabs {...args} hasDivider onChange={() => {}} value="overview">
<Tab label="Overview" value="overview" />
<Tab label="Activity" value="activity" />
</Tabs>
</div>
<Tabs {...args} onChange={() => {}} value="overview">
<Tab href="/overview" label="Overview" value="overview" />
<Tab href="/activity" label="Activity" value="activity" />
<Tab href="/settings" label="Settings" value="settings" />
</Tabs>
<Tabs {...args} onChange={() => {}} value="overview">
<Tab as={RouterLink} href="/overview" label="Overview" value="overview" />
<Tab as={RouterLink} href="/activity" label="Activity" value="activity" />
<Tab as={RouterLink} href="/settings" label="Settings" value="settings" />
</Tabs>
<SelectedIconStory {...args} />
<Tabs {...args} onChange={() => {}} value="overview">
<Tab label="Overview" value="overview" />
<Tab isDisabled label="Activity" value="activity" />
<TabMenu
isDisabled
label="More"
options={[{label: 'Reports', value: 'reports'}]}
/>
</Tabs>
<TabMenuOnlyStory {...args} />
<ManyTabsStory {...args} />
<ControlledStory {...args} />
Overview content
<WithPanelsStory {...args} />
<div dir="rtl">
<Tabs {...args} onChange={() => {}} value="overview">
<Tab label="Overview" value="overview" />
<Tab label="Activity" value="activity" />
<Tab label="Settings" value="settings" />
</Tabs>
</div>

Controlled tab wrapper. Uses `tablist` / `tabpanel` semantics, so reach for it when selecting an option shows or hides associated content panels. To pick a value without swapping panels — a styled radio group for filters, settings, or view modes — use SegmentedControl instead.

PropTypeDefaultDescription
children*ReactNodeTab and TabMenu children.
classNamestringAdditional CSS class names applied to the tablist element.
data-testidstringTest ID applied to the tablist element.
hasDividerbooleanfalseWhether to show a bottom divider.
labelstring'Tabs'Accessible label for the tabs.
layout"fill" | "hug"'hug'Tab layout mode.
onChange*(value: string) => voidCalled when a tab is selected.
refRef<HTMLElement>Ref forwarded to the tablist element.
size"sm" | "md" | "lg"'md'Tab size.
styleCSSPropertiesInline styles applied to the tablist element.
value*stringCurrent selected tab value.

A single tab inside `Tabs`.

PropTypeDefaultDescription
asLinkComponentCustom link component used when href is set.
classNamestringAdditional CSS class names applied to the tab.
controlsstringID of the tabpanel controlled by this tab. Use this for in-page tabs, and render the corresponding panel with id={controls}, role="tabpanel", and aria-labelledby pointing to this tab's id.
data-testidstringTest ID applied to the tab.
endContentReactNodeContent rendered after the label.
hrefstringOptional link URL. When set, the tab renders as a link.
iconIconComponentIcon shown before the label.
idstringID applied to the tab element. Provide this with controls when rendering your own tabpanel so the panel can reference the tab with aria-labelledby.
isDisabledbooleanfalseWhether the tab is disabled.
label*stringVisible tab label.
refRef<HTMLElement>Ref forwarded to the tab root.
selectedIconIconComponentIcon shown when selected. Falls back to icon.
styleCSSPropertiesInline styles applied to the tab.
value*stringUnique tab value.

Overflow menu for additional tabs.

PropTypeDefaultDescription
classNamestringAdditional CSS class names applied to the trigger.
data-testidstringTest ID applied to the trigger.
idstringID applied to the menu trigger tab.
isDisabledbooleanfalseWhether the menu trigger is disabled.
label*stringTrigger and menu heading label.
options*ReadonlyArray<TabMenuOption>Menu options.
refRef<HTMLButtonElement>Ref forwarded to the trigger button.
styleCSSPropertiesInline styles applied to the trigger.