import { Tabs } from '@uhg-abyss/web/ui/Tabs';<Tabs title="Tabs Sandbox"> <Tabs.Tab label="Tab 1">Tab 1 Content</Tabs.Tab> <Tabs.Tab label="Tab 2">Tab 2 Content</Tabs.Tab> <Tabs.Tab label="Tab 3">Tab 3 Content</Tabs.Tab></Tabs>Display
The display property determines whether the tab buttons will be displayed horizontally or vertically. The two options are row and column, and the default is row. Additionally, the height property is only applicable to column display.
Title
The title property provides a label that describes the purpose of the set of tabs. This is a required property, as it gives screen reader users important context.
<Tabs title="Tab Group Title"> <Tabs.Tab label="Tab - 1">Tab 1 Content</Tabs.Tab> <Tabs.Tab label="Tab - 2">Tab 2 Content</Tabs.Tab> <Tabs.Tab label="Tab - 3">Tab 3 Content</Tabs.Tab></Tabs>Labels
Use the label prop for the individual tabs to succinctly describe their content.
To add more content to the tabs, we provide the props subLabel, leftAddOn, and rightAddOn. subLabel can be used to provide additional context to the tab label. leftAddOn and rightAddOn take in any React.ReactElement, such as an IconSymbol or Badge, to provide additional information next to the label.
Note: It is recommended by the Abyss Design System to keep rightAddOn as a Badge, while leftAddOn can be completely custom.
Overflow
When there are too many tabs to fit above the content container, the design automatically changes to account for the overflow. Clicking on tabs will scroll them into view, but all tabs are also displayed in a drawer for viewing. In the drawer, tabs are still navigable with arrow keys. This view is especially applicable for mobile devices.
Max width
Use the maxWidth prop for the individual tabs to have a maxWidth, after which the label and subLabel text will wrap.
Active (controlled)
To control the tabs active state, pass in the index of the desired tab to the active prop. This must be used in combination with onTabChange to ensure that the active tab state is always current. If no default state is passed, the active tab will default to the first tab in the sequence.
Initial tab (uncontrolled)
If you do not need to subscribe to the tabs active state, use the initialTab property to set the tab that is active at build time. The default is set to the first tab in the sequence. If used instead of active the active state will be uncontrolled and handled internally by the component.
Tabbable content
Use the tabbableContent prop within the Tabs.Tab component to control the user's ability to tab-key focus the content container. tabbableContent is set to true by default. This prop is useful for addressing possible accessibility concerns.
Height
Use the height property to specify the height of the container. The default is set to null. If height is not specified, the tab container will fit the size of the content. If height is specified, then the content becomes scrollable if the content is larger than the set height. height property is only applicable to column display.
Extra customization
The Tabs.Tab component can be completely customized with the customRender prop. It is a function that receives the isActive state and allows full control over tab content rendering.
Note: using customRender does not follow the patterns defined by our design team. We recommend developers and designers alike to follow our brand-approved design patterns when possible.
Tabs Props
| Name | Type | Default | Required | Description |
|---|---|---|---|---|
active | number | - | - | The index of the active tab |
children | React.ReactNode | - | The individual tabs and their content; must be Tabs.Tab components | |
className | string | - | - | CSS class name to apply to each element within the component |
css | Abyss.CSSProperties | Partial<Record<`abyss-${T}`, Abyss.CSSProperties>> | - | - | Object containing CSS styling to apply; uses the classes listed in the "Integration" tab of the component's documentation |
data-testid | string | - | - | Suffix used to create a unique ID used for automated testing |
disableDefaultProviderProps | boolean | false | - | If set to true, the component will not use the DefaultPropsProvider values. If you aren’t using the DefaultPropsProvider, this prop can be ignored. |
display | "row" | "column" | 'row' | - | The orientation of the Tabs container |
height | string | number | - | - | The height of the Tabs container |
initialTab | number | - | - | Used to indicate initial tab |
onTabChange | (tabIndex: number) => void | - | - | Callback function executed whenever the active tab changes |
tabsListProps | Record<string, unknown> | - | - | Props to be passed to tabs list |
title | string | - | The name for the Tabs container; also used as the ARIA label tag for accessibility concerns |
Tabs.Tab Props
| Name | Type | Default | Required | Description |
|---|---|---|---|---|
children | React.ReactNode | - | - | The contents of the tab |
className | string | - | - | CSS class name to apply to each element within the component |
css | Abyss.CSSProperties | Partial<Record<`abyss-${T}`, Abyss.CSSProperties>> | - | - | Object containing CSS styling to apply; uses the classes listed in the "Integration" tab of the component's documentation |
customRender | (isActive: boolean) => React.ReactNode | - | - | Function to render a custom tab component |
data-testid | string | - | - | Suffix used to create a unique ID used for automated testing |
disableDefaultProviderProps | boolean | false | - | If set to true, the component will not use the DefaultPropsProvider values. If you aren’t using the DefaultPropsProvider, this prop can be ignored. |
label | string | React.ReactElement<any, string | React.JSXElementConstructor<any>> | - | - | The label of the tab |
leftAddOn | React.ReactElement<any, string | React.JSXElementConstructor<any>> | - | - | A space for additional content in the tab to the left of the label, such as an icon or badge |
maxWidth | string | - | - | The optional max width of an individual tab |
rightAddOn | React.ReactElement<any, string | React.JSXElementConstructor<any>> | - | - | A space for additional content in the tab to the right of the label, preferably a badge |
subLabel | string | - | - | The optional sub label of the tab |
tabbableContent | boolean | true | - | If true, the tab content container will be included in the tab order |
Tabs Classes
| Class Name | Description |
|---|---|
| .abyss-tabs-root | Tabs root element |
| .abyss-tabs-list | List of tabs |
| .abyss-tabs-content-container | Container of content in tab |
| .abyss-tabs-drawer | Tabs drawer element when there is overflow |
| .abyss-tabs-drawer-button | Tabs drawer button when there is overflow |
| .abyss-tabs-drawer-list | List of tabs in the drawer |
| .abyss-tabs-extended-border | Tabs border when display is row |
Tabs.Tab Classes
| Class Name | Description |
|---|---|
| .abyss-tabs-tab | Tabs.Tab root element |
| .abyss-tabs-tab-active-line | Line indicating the active tab |
| .abyss-tabs-tab-content | Container of content in tab for label / custom rendering |
| .abyss-tabs-tab-sub-label | Optional sub label for the tab |
| .abyss-tabs-tab-label-section | Container for the label section, including badge |
| .abyss-tabs-tab-label-wrapping | The label when maxWidth is set and wrapping is needed |
Tabs are a set of layered sections of content, known as tab panels, that display one panel of content at a time. Each tab panel has an associated tab element that, when activated, displays the panel. The list of tab elements is arranged along one edge of the currently displayed panel, most commonly the top edge.
The title property is used to populate the aria-label attribute for each Tabs component. This unique label will help distinguish one tab component from another if there are multiple tab components on the same page, which is helpful for screen reader users. Provide a name that reflects the purpose of the tabs.
The tabbableContent property is used within Tabs.Tab to set the tab index of the div element content container. Set false to exclude element from tab focus.
Adheres to the Tabs WAI-ARIA design pattern.
Keyboard Interactions
| Key | Description |
|---|---|
| Tab | When focus moves into the tab list, places focus on the active tab element. If tab list has focus, focus moves to the tab panel. If the tab panel has focus, focus moves to the next focusable element, whether it is inside of the tab panel or outside of it. |
| Left Arrow | When tab list is in focus, moves focus to the previous tab if the tabs are horizontal. |
| Right Arrow | When tab list is in focus, moves focus to the next tab if the tabs are horizontal. |
| Up Arrow | When tab list is in focus, moves focus to the previous tab if the tabs are vertical. |
| Down Arrow | When the tab list is in focus, moves focus to the next tab if the tabs are vertical. |
| Home | When the tab list is in focus, moves focus to the first tab. |
| End | When the tab list is in focus, moves focus to the last tab. |
Component Tokens
Note: Click on the token row to copy the token to your clipboard.
Tabs Tokens
| Token Name | Value | |
|---|---|---|
| tabs.color.surface.container.selected | #FFFFFF | |
| tabs.color.surface.container.rest | #FFFFFF | |
| tabs.color.surface.container.hover | #F3F3F3 | |
| tabs.color.surface.container.active | #E5E5E6 | |
| tabs.color.surface.icon-container | #FFFFFF | |
| tabs.color.border.container.selected | #196ECF | |
| tabs.color.border.container.rest | #CBCCCD | |
| tabs.color.text.label.selected | #323334 | |
| tabs.color.text.label.rest | #196ECF | |
| tabs.color.text.sub-label | #4B4D4F | |
| tabs.color.icon.rest | #196ECF | |
| tabs.color.icon.hover | #004BA0 | |
| tabs.color.icon.active | #002677 | |
| tabs.border-width.bottom.container.selected | 3px | |
| tabs.border-width.bottom.container.default | 1px | |
| tabs.border-width.left.container.selected | 3px | |
| tabs.sizing.all.icon | 24px | |
| tabs.spacing.padding.all.icon-container | 8px | |
| tabs.spacing.padding.all.drawer | 8px | |
| tabs.spacing.padding.vertical.container | 12px | |
| tabs.spacing.padding.horizontal.container | 16px | |
| tabs.spacing.gap.horizontal.label | 8px |