Tabs
Reduce visual complexity of long forms using tabs.
Use TabNav for navigation links styled as tabs.
Use Segmented Control for switching between views or modes of the same content.
#
#
#
Add the following props to a Tab to add decorations to the tab:
- Add the
countprop to display a gray badge with the count within the Tab. - Add the
countFormatterprop to change the way the count is rendered. - Add the
badgeVariantprop to change the variant of the badge within the Tab. - Add the
tooltipprop to add a tooltip to the text. - Add the
statusIndicatorprop to add an extra indicator to the right of the Tab text.
Use these instead of directly rendering additional components within the Tab itself.
#
There are cases when state of tabs is managed elsewhere. For example, when tabs are switched based on the current URL.
#
Tabs have their own loading state when used with the Skeleton component.
#
#
- When there are many related sections and one section needs to be shown at a time.
- When each tab leads to distinct content sectioned into its own panel — for example, "Overview" vs. "Messages" vs. "Configuration". The user is choosing what to look at.
- When tabs benefit from decorators such as counts, badges, or status indicators (for example, an unread message count or an error state on a section).
#
- When content from multiple tabs needs to be shown at the same time.
- As a way to indicate progress of filling out a form or a similar component.
- As a way to filter content.
- When switching tabs should navigate to a different URL. Use Tab Nav instead.
- When each option is a different view or mode of the same content — for example, rendering one dataset as a list, table, or heatmap, or toggling a chart between daily, weekly, and monthly granularity. Use a Segmented Control instead — the user is choosing how the content renders, not what to look at.
#
Both components present a row of mutually exclusive options, but they differ semantically and for assistive technology:
- Tabs — different content, sectioned into panels. Each panel is its own thing; the user is choosing a destination. Screen readers announce tabs as a navigable tab list with associated panels.
- Segmented Control — same content, different lens. Switching is instant, cheap, and stateless-feeling. It is semantically a radio group styled as buttons — mutually exclusive settings, not destinations — and screen readers announce it as a set of options rather than as navigation.
If you're unsure, ask: "Is the user picking what to see, or how to see it?" Use Tabs for what, Segmented Control for how.
#
- Use sentence case for tab titles.
- Keep tab titles to 3 words max.
#
It is important to directly nest Tab within the parent TabList. Any intermediate elements will break a11y compliance.
#
#
Inherits margin props.
| Name | Default | Description |
|---|---|---|
children | — | ReactNodeTab list and panels. |
index | — | numberIndex of selected tab. |
onChange | — | (index: number) => voidCallback for when user selects a different tab. |
#
| Name | Default | Description |
|---|---|---|
children | — | ReactNodeTabs. |
#
| Name | Default | Description |
|---|---|---|
badgeVariant | — | BadgeProps["variant"]The variant of the badge if a count is provided. |
children | — | stringTab title. |
count | — | numberOptional count to display near the title. |
countFormatter | — | (count: number) => string | numberOptional function to format the count. |
tooltip | — | Omit<TooltipProps, "children">Optional tooltip to add to the text. |
statusIndicator | — | ReactNodeOptional status indicator to place to the right of the text. |
isDisabled | false | booleanIf tab is disabled. |
#
| Name | Default | Description |
|---|---|---|
children | — | ReactNodeTab panels. |
#
| Name | Default | Description |
|---|---|---|
children | — | ReactNodeTab content. |