Skip to main content

SegmentedControls

Combines radio buttons and tabs to give multiple options as one element.

Submit feedback
github
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

NameTypeDefaultRequiredDescription
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

See CSS Prop Styling for more information
data-testid
string
--
Suffix used to create a unique ID used for automated testing

See Component Testing for more information
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

NameTypeDefaultRequiredDescription
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

See CSS Prop Styling for more information
data-testid
string
--
Suffix used to create a unique ID used for automated testing

See Component Testing for more information
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 NameDescription
.abyss-segmented-controls-rootRoot element
.abyss-segmented-controls-tabs-containerContainer element for the tabs
.abyss-segmented-controls-content-containerContainer element for the content of the selected tab
.abyss-segmented-controls-selected-backgroundSelected background element

SegmentedControls.Tab Classes

Class NameDescription
.abyss-segmented-controls-tab-rootRoot element
.abyss-segmented-controls-tab-label-containerContainer element
.abyss-segmented-controls-tab-labelLabel element
.abyss-segmented-controls-tab-label-hiddenHidden 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

KeyDescription
TabMoves focus to the active tab
SpaceSelects the currently focused tab
EnterSelects the currently focused tab
Arrow RightMoves focus to the next tab in the group.
Arrow LeftMoves focus to the previous tab in the group.
HomeWhen focused on the active tab, moves focus to the first tab.
EndWhen 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 NameValue
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
Table of Contents