import { SegmentedControls } from '@uhg-abyss/web/ui/SegmentedControls';() => { const [activeTab, setActiveTab] = useState('opt-2');
const InnerText = ({ activeTab }) => ( <Card> <Text fontWeight="bold">This is the content for {activeTab}</Text> <Text> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. </Text> </Card> ); return ( <SegmentedControls value={activeTab} onChange={setActiveTab} title="Options"> <SegmentedControls.Tab label="Option 1" value="opt-1"> <InnerText activeTab={activeTab} /> </SegmentedControls.Tab> <SegmentedControls.Tab label="Option 2" value="opt-2"> <InnerText activeTab={activeTab} /> </SegmentedControls.Tab> <SegmentedControls.Tab label="Option 3" value="opt-3"> <InnerText activeTab={activeTab} /> </SegmentedControls.Tab> <SegmentedControls.Tab label="Option 4" value="opt-4"> <InnerText activeTab={activeTab} /> </SegmentedControls.Tab> <SegmentedControls.Tab label="Option 5" value="opt-5"> <InnerText activeTab={activeTab} /> </SegmentedControls.Tab> </SegmentedControls> );};Controlled (value + onChange)
Use the value and onChange props to control the active tab state externally. This approach is useful when you need to manage the tab state within your component or through an external state management solution.
value: Specifies the currently active tab.onChange: Callback function that handles tab changes.
Uncontrolled (initialValue)
In cases where you don't need to control the active tab state, you can use the initialValue prop to specify which tab should be active by default when the component loads. This eliminates the need to use the value and onChange props for managing the active tab state externally.
Title
The title property provides a label that describes the purpose of the set of controls (tabs). This is a required property, as it gives screen reader users important context.
Full width
The fullWidth prop (optional), when set to true, makes the component take all the available horizontal space of its parent container.
Label (individual tab)
Thelabel prop (required) is used to define the display in each Tab.
Tab icon (individual tab)
To insert an IconSymbol into each tab, use the tabIcon prop. It accepts either a string (the name of the IconSymbol to use) or an object of the following type:
{ icon: string; variant: 'filled' | 'outlined';}Tabbable content
Use the tabbableContent prop within the SegmentedControls.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.
SegmentedControls Props
| Name | Type | Default | Required | Description |
|---|---|---|---|---|
children | React.ReactNode | - | - | The content of the SegmentedControls component (individual tabs). |
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. |
fullWidth | boolean | false | - | Whether the SegmentedControls should take up the full width. |
initialValue | string | - | - | Used to set the initial value on load for uncontrolled usage. This value will be used if the value prop is not provided. |
onChange | (tabValue: string) => void | - | - | Callback fired every time tab changes; returns index of selected tab |
title | string | - | The name for the SegmentedControls container; also used as the ARIA label tag for accessibility concerns. | |
value | string | - | - | Used to control state and set active tab |
SegmentedControls.Tab Props
| Name | Type | Default | Required | Description |
|---|---|---|---|---|
ariaLabel | string | - | - | Adds an aria-label to the tab. Use when label is an abbreviation. |
children | React.ReactNode | - | - | The element the tab wraps |
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. |
label | string | - | The label text or element for the Tab. | |
tabbableContent | boolean | true | - | Whether the content inside the tab is tabbable. |
tabIcon | "function" | "article" | "code" | "details" | "html" | "iframe" | "input" | "label" | "link" | "map" | "menu" | "output" | "search" | "script" | "select" | "style" | "table" | "title" | ... 3567 more ... | { ...; } | - | - | The IconSymbol to insert at the start of the Tab |
value | string | number | - | The value of the Tab. |
SegmentedControls Classes
| Class Name | Description |
|---|---|
| .abyss-segmented-controls-root | Root element |
| .abyss-segmented-controls-tabs-container | Container element for the tabs |
| .abyss-segmented-controls-content-container | Container element for the content of the selected tab |
| .abyss-segmented-controls-selected-background | Selected background element |
SegmentedControls.Tab Classes
| Class Name | Description |
|---|---|
| .abyss-segmented-controls-tab-root | Root element |
| .abyss-segmented-controls-tab-label-container | Container element |
| .abyss-segmented-controls-tab-label | Label element |
| .abyss-segmented-controls-tab-label-hidden | Hidden label element |
SegmentedControls at its core functions as a "tabbing" system, similar to simple navigation menu, where no more than one of the buttons can be checked at a time. The title prop is required to provide context for screen readers.
Use the ariaLabel prop in SegmentedControls.Tab when using abbreviated words. This will include an "aria-label" for screen readers.
Adheres to the WAI-ARIA design pattern.
Reduced Motion
Animations and transitions that have been changed when a user has prefers-reduced-motion set to reduced:
- Removed animation of active background color upon switching tabs
Keyboard Interactions
| Key | Description |
|---|---|
| Tab | Moves focus to the active tab |
| Space | Selects the currently focused tab |
| Enter | Selects the currently focused tab |
| Arrow Right | Moves focus to the next tab in the group. |
| Arrow Left | Moves focus to the previous tab in the group. |
| Home | When focused on the active tab, moves focus to the first tab. |
| End | When focused on the active tab, moves focus to the last tab. |
Component Tokens
Note: Click on the token row to copy the token to your clipboard.
SegmentedControls Tokens
| Token Name | Value | |
|---|---|---|
| segmented-controls.color.border.selected-tab | #323334 | |
| segmented-controls.color.surface.container | #F3F3F3 | |
| segmented-controls.color.surface.selected-tab | #FFFFFF | |
| segmented-controls.color.surface.divider | #CBCCCD | |
| segmented-controls.color.text.label.rest | #4B4D4F | |
| segmented-controls.color.text.label.active | #000000 | |
| segmented-controls.color.text.label.hover | #323334 | |
| segmented-controls.color.icon.leading.rest | #4B4D4F | |
| segmented-controls.color.icon.leading.active | #000000 | |
| segmented-controls.color.icon.leading.hover | #323334 | |
| segmented-controls.border-radius.all.container | 500px | |
| segmented-controls.border-radius.all.selected-tab | 500px | |
| segmented-controls.border-width.all.selected-tab | 2px | |
| segmented-controls.border-width.horizontal.divider | 1px | |
| segmented-controls.sizing.all.icon | 20px | |
| segmented-controls.spacing.gap.horizontal.tab | 4px | |
| segmented-controls.spacing.padding.all.container | 4px | |
| segmented-controls.spacing.padding.horizontal.tab | 24px | |
| segmented-controls.spacing.padding.vertical.tab | 8px |