SegmentedController
A segmented controller is a linear set of two or more segments, each of which functions as a button. A segmented controller allows users to select options, switch views, or sort elements.
Installation
npm install --save @godaddy/antaresProps
size?"sm" | "md" | "lg" | undefined—The size of the segmented controller.
className?string | undefined'react-aria-ToggleButtonGroup'Additional class names applied to the root element.
defaultValue?string | undefined—The initial selected value. (uncontrolled)
value?string | undefined—The selected value. (controlled)
onSelectionChange?((value: string) => void) | undefined—Handler that is called when the selection changes.
isDisabled?boolean | undefined—Whether the segmented controller is disabled.
children?ReactNode—The segmented controller items.
orientation?Orientation | undefined'horizontal'The orientation of the the toggle button group.
selectionMode?"single" | "multiple" | undefined'single'Whether single or multiple selection is enabled.
disallowEmptySelection?boolean | undefined—Whether the collection allows empty selection.
selectedKeys?Iterable<RACKey> | undefined—The currently selected keys in the collection (controlled).
defaultSelectedKeys?Iterable<RACKey> | undefined—The initial selected keys in the collection (uncontrolled).
style?StyleOrFunction<ToggleButtonGroupRenderProps> | undefined—The inline [style](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style) for the element. A function may be provided to compute the style based on component state.
render?DOMRenderFunction<"div", ToggleButtonGroupRenderProps> | undefined—Overrides the default DOM element with a custom render function. This allows rendering existing components with built-in styles and behaviors such as router links, animation libraries, and pre-styled components. Requirements: - You must render the expected element type (e.g. if `<button>` is expected, you cannot render an `<a>`). - Only a single root DOM element can be rendered (no fragments). - You must pass through props and ref to the underlying DOM element, merging with your own prop as appropriate.
slot?string | null | undefined—A slot name for the component. Slots allow the component to receive props from a parent component. An explicit `null` value indicates that the local props completely override all props received from a parent.
display?"flex" | "inline-flex" | undefined'flex'The display property for the flex container.
direction?"row" | "column" | "row-reverse" | "column-reverse" | undefined'row'The direction in which to layout children.
wrap?"wrap" | "nowrap" | "wrap-reverse" | undefined—Whether to wrap items onto multiple lines.
padding?Spacing | Spacing[] | undefined—Padding on all sides. Accepts single value or array.
inlinePadding?Spacing | Spacing[] | undefined—Padding on inline (horizontal) direction.
inlinePaddingStart?Spacing | undefined—Padding on inline start (left in LTR).
inlinePaddingEnd?Spacing | undefined—Padding on inline end (right in LTR).
blockPadding?Spacing | Spacing[] | undefined—Padding on block (vertical) direction.
blockPaddingStart?Spacing | undefined—Padding on block start (top).
blockPaddingEnd?Spacing | undefined—Padding on block end (bottom).
elevation?"base" | "card" | "raised" | "overlay" | undefined—Elevation levels for visual depth.
rounding?Rounding | undefined—Rounding values for border radius.
alignSelf?(string & {}) | "auto" | "normal" | "start" | "end" | "center" | "flex-start" | "flex-end" | "self-start" | "self-end" | "stretch" | undefined—In Flex/Grid layout. Cross-axis alignment within flex/grid container.
justifySelf?(string & {}) | "auto" | "normal" | "start" | "end" | "center" | "flex-start" | "flex-end" | "self-start" | "self-end" | "stretch" | "left" | "right" | undefined—In Flex/Grid layout. Main-axis alignment within flex/grid container.
order?string | number | undefined—In Flex/Grid layout. Layout order within flex/grid container.
flex?string | number | undefined—In Flex/Grid layout. Flex shorthand for grow, shrink, and basis.
flexGrow?string | number | undefined—In Flex/Grid layout. How much the item will grow relative to siblings.
flexShrink?string | number | undefined—In Flex/Grid layout. How much the item will shrink relative to siblings.
flexBasis?string | undefined—In Flex/Grid layout. Initial main size before growing/shrinking.
gridArea?string | undefined—In Flex/Grid layout. Named grid area for placement.
gridColumnStart?string | undefined—In Flex/Grid layout. Grid column start line.
gridColumnEnd?string | undefined—In Flex/Grid layout. Grid column end line.
gridRowStart?string | undefined—In Flex/Grid layout. Grid row start line.
gridRowEnd?string | undefined—In Flex/Grid layout. Grid row end line.
justifyContent?(string & {}) | "normal" | "start" | "end" | "center" | "stretch" | "space-around" | "space-between" | "space-evenly" | undefined—The distribution of space around children along the main axis in flex or inline axis in grid
alignContent?(string & {}) | "normal" | "start" | "end" | "center" | "stretch" | "space-around" | "space-between" | "space-evenly" | "baseline" | undefined—The distribution of space around children along the cross axis in flex or block axis in grid
justifyItems?(string & {}) | "normal" | "start" | "end" | "center" | "stretch" | "legacy" | undefined—Defines the default justify-self for all children in a grid container.
alignItems?(string & {}) | "normal" | "start" | "end" | "center" | "stretch" | "baseline" | undefined—Sets the align-self property for each child.
gap?Spacing | Spacing[] | undefined—The gap between children.
columnGap?Spacing | undefined—The gap between columns.
rowGap?Spacing | undefined—The gap between rows.
Examples
Basic
An uncontrolled segmented controller with a default selection. The component manages its own state internally via defaultValue.
import { SegmentedController, SegmentedControllerItem } from '@godaddy/antares';export function BasicExample() { return ( <SegmentedController aria-label="View" defaultValue="day"> <SegmentedControllerItem value="day">Day</SegmentedControllerItem> <SegmentedControllerItem value="week">Week</SegmentedControllerItem> <SegmentedControllerItem value="month">Month</SegmentedControllerItem> </SegmentedController> );}Controlled
Use value and onSelectionChange to fully control the selected segment from parent state.
Current selection: week
import { SegmentedController, SegmentedControllerItem } from '@godaddy/antares';import { useState } from 'react';export function ControlledExample() { const [selected, setSelected] = useState('week'); return ( <> <SegmentedController aria-label="View" value={selected} onSelectionChange={setSelected}> <SegmentedControllerItem value="day">Day</SegmentedControllerItem> <SegmentedControllerItem value="week">Week</SegmentedControllerItem> <SegmentedControllerItem value="month">Month</SegmentedControllerItem> </SegmentedController> <p>Current selection: {selected}</p> </> );}Sizes
Three sizes are available: sm, md (default), and lg.
import { Flex, SegmentedController, SegmentedControllerItem } from '@godaddy/antares';export function SizesExample() { return ( <Flex direction="column" gap="lg" alignItems="start"> <SegmentedController aria-label="View (small)" size="sm" defaultValue="day"> <SegmentedControllerItem value="day">Day sm</SegmentedControllerItem> <SegmentedControllerItem value="week">Week sm</SegmentedControllerItem> <SegmentedControllerItem value="month">Month sm</SegmentedControllerItem> </SegmentedController> <SegmentedController aria-label="View (medium)" size="md" defaultValue="day"> <SegmentedControllerItem value="day">Day md</SegmentedControllerItem> <SegmentedControllerItem value="week">Week md</SegmentedControllerItem> <SegmentedControllerItem value="month">Month md</SegmentedControllerItem> </SegmentedController> <SegmentedController aria-label="View (large)" size="lg" defaultValue="day"> <SegmentedControllerItem value="day">Day lg</SegmentedControllerItem> <SegmentedControllerItem value="week">Week lg</SegmentedControllerItem> <SegmentedControllerItem value="month">Month lg</SegmentedControllerItem> </SegmentedController> </Flex> );}Icon + Text
Segments can include an Icon alongside text for added visual context.
import { Icon, SegmentedController, SegmentedControllerItem } from '@godaddy/antares';export function IconExample() { return ( <SegmentedController aria-label="Layout" defaultValue="list"> <SegmentedControllerItem value="list"> <Icon icon="bulleted-list" /> List </SegmentedControllerItem> <SegmentedControllerItem value="grid"> <Icon icon="grid" /> Grid </SegmentedControllerItem> </SegmentedController> );}Icon Only
For compact layouts, segments can contain only icons. Provide an aria-label on each item so screen readers can identify the action.
import { Icon, SegmentedController, SegmentedControllerItem } from '@godaddy/antares';export function IconOnlyExample() { return ( <SegmentedController aria-label="Layout"> <SegmentedControllerItem value="list" aria-label="List view"> <Icon icon="bulleted-list" /> </SegmentedControllerItem> <SegmentedControllerItem value="grid" aria-label="Grid view"> <Icon icon="grid" /> </SegmentedControllerItem> </SegmentedController> );}Overflow
When the number of options exceeds the width of the container, the component automatically shows scroll buttons to let users navigate. Users can also scroll horizontally to navigate the options.
import { SegmentedController, SegmentedControllerItem } from '@godaddy/antares';export function OverflowExample({ maxWidth = '300px' }: { maxWidth?: string }) { return ( <SegmentedController aria-label="Category" defaultValue="electronics" style={{ maxWidth }}> <SegmentedControllerItem value="electronics">Electronics</SegmentedControllerItem> <SegmentedControllerItem value="clothing">Clothing</SegmentedControllerItem> <SegmentedControllerItem value="home">Home</SegmentedControllerItem> <SegmentedControllerItem value="sports">Sports</SegmentedControllerItem> <SegmentedControllerItem value="toys">Toys</SegmentedControllerItem> </SegmentedController> );}RTL Direction
The segmented controller follows the current layout direction (LTR or RTL). By default, that direction is detected automatically from the browser or system settings.
import { RTLProvider } from '../../../utils/rtl-locale-provider.tsx';import { OverflowExample } from './overflow.tsx';export function RTLExample() { return ( <RTLProvider> <OverflowExample /> </RTLProvider> );}Disabled States
Disable the entire group with isDisabled on the container, or disable individual segments with isDisabled on specific items.
import { SegmentedController, SegmentedControllerItem, Flex } from '@godaddy/antares';export function DisabledExample() { return ( <Flex direction="column" gap="sm" alignItems="start"> <label>Disabled group</label> <SegmentedController aria-label="Disabled group" isDisabled defaultValue="day"> <SegmentedControllerItem value="day">Day</SegmentedControllerItem> <SegmentedControllerItem value="week">Week</SegmentedControllerItem> <SegmentedControllerItem value="month">Month</SegmentedControllerItem> </SegmentedController> <label>Individual disabled</label> <SegmentedController aria-label="Individual disabled" defaultValue="day"> <SegmentedControllerItem value="day">Day</SegmentedControllerItem> <SegmentedControllerItem value="week" isDisabled> Week </SegmentedControllerItem> <SegmentedControllerItem value="month">Month</SegmentedControllerItem> </SegmentedController> </Flex> );}Customization
Data Attributes
Components automatically add data attributes for styling different states:
SegmentedController Container: data-disabled
SegmentedControllerItem: data-selected, data-hovered, data-pressed, data-focus-visible, data-disabled
Accessibility
Keyboard Navigation
- Tab: Moves focus to/from the segmented controller
- Arrow Left/Right: Move to next/previous segment
- Space/Enter: Select the focused segment
ARIA Support
role="radiogroup"on the containerrole="radio"on each segmentaria-checkedindicates selection statearia-disabledfor disabled segmentsaria-labelrequired on the container for screen readers
Best Practices
When to Use a Segmented Controller
- When switching between 2-5 related views within the same context
- When all options should be visible at once
- When the selection immediately changes the displayed content
When Not to Use
- For more than 5 options (use Tabs or Select instead)
- For form input (use RadioGroup instead)