Segmented Control
A segmented control presents a linear set of selectable segments, supporting both single- and multi-select interactions. It offers immediate visual feedback and maintains coherence across related options.
import {SegmentedControl} from "@qualcomm-ui/react/segmented-control"Usage
The SegmentedControl component allows users to make a selection from multiple options, exclusive (similar to radio buttons) or not (similar to checkboxes).
It is typically used for filtering content, sorting elements or switching between views within the same context.
Examples
Simple
Use the simple API to create segmented control items using minimal markup.
<SegmentedControl.Root defaultValue={["chart"]}>
<SegmentedControl.Item text="Chart" value="chart" />
<SegmentedControl.Item text="Table" value="table" />
<SegmentedControl.Item text="Map" value="map" />
</SegmentedControl.Root>
Composite
Build with the composite API for granular control. This API requires you to provide each subcomponent, but gives you full control over the structure and layout.
<SegmentedControl.Root defaultValue={["chart"]}>
<SegmentedControl.ItemRoot value="chart">
<SegmentedControl.ItemText>Chart</SegmentedControl.ItemText>
<SegmentedControl.HiddenInput />
</SegmentedControl.ItemRoot>
<SegmentedControl.ItemRoot value="table">
<SegmentedControl.ItemText>Table</SegmentedControl.ItemText>
<SegmentedControl.HiddenInput />
</SegmentedControl.ItemRoot>
<SegmentedControl.ItemRoot value="map">
<SegmentedControl.ItemText>Map</SegmentedControl.ItemText>
<SegmentedControl.HiddenInput />
</SegmentedControl.ItemRoot>
</SegmentedControl.Root>
Multiple
By default, a segmented control allows for a single selection. Use the multiple prop to create a segmented control that allows for multiple selections.
<SegmentedControl.Root multiple>
<SegmentedControl.Item text="Production" value="prod" />
<SegmentedControl.Item text="Staging" value="staging" />
<SegmentedControl.Item text="Development" value="dev" />
<SegmentedControl.Item text="QA" value="qa" />
</SegmentedControl.Root>
Orientation
Use the orientation prop to control the layout direction of the SegmentedControl. Options include:
horizontal: Items are laid out in a row (default).vertical: Items are laid out in a column.
<SegmentedControl.Root defaultValue={["chart"]} orientation="vertical">
<SegmentedControl.Item text="Chart" value="chart" />
<SegmentedControl.Item text="Table" value="table" />
<SegmentedControl.Item text="Map" value="map" />
</SegmentedControl.Root>
Icon
Use the icon prop on the SegmentedControl.Item or SegmentedControl.ItemRoot components to add icons to the segmented control items.
<SegmentedControl.Root defaultValue={["chart"]}>
<SegmentedControl.Item icon={ChartArea} text="Chart" value="chart" />
<SegmentedControl.Item icon={Table} text="Table" value="table" />
<SegmentedControl.Item icon={Map} text="Map" value="map" />
</SegmentedControl.Root>
Layout
Use the layout prop to control how the SegmentedControl is sized and aligned within its container. Options include:
hug: Content-sized; width matches the items only (default).fill: Full width; items share space evenly.
{(["hug", "fill"] as QdsSegmentedControlLayout[]).map((layout) => (
<SegmentedControl.Root
key={layout}
defaultValue={["chart"]}
layout={layout}
>
<SegmentedControl.Item text="Chart" value="chart" />
<SegmentedControl.Item text="Table" value="table" />
<SegmentedControl.Item text="Map" value="map" />
</SegmentedControl.Root>
))}
Size
Use the size prop to control the size of the segmented control. The available sizes are sm, md (default), and lg.
{(["sm", "md", "lg"] as QdsSegmentedControlSize[]).map((size) => (
<SegmentedControl.Root key={size} defaultValue={["chart"]} size={size}>
<SegmentedControl.Item text="Chart" value="chart" />
<SegmentedControl.Item text="Table" value="table" />
<SegmentedControl.Item text="Map" value="map" />
</SegmentedControl.Root>
))}
Variant
Use the variant prop to control the visual style of the segmented control. The available variants are primary (default) and neutral.
{(["primary", "neutral"] as QdsSegmentedControlVariant[]).map(
(variant) => (
<SegmentedControl.Root
key={variant}
defaultValue={["chart"]}
variant={variant}
>
<SegmentedControl.Item text="Chart" value="chart" />
<SegmentedControl.Item text="Table" value="table" />
<SegmentedControl.Item text="Map" value="map" />
</SegmentedControl.Root>
),
)}
Disabled
Use the segmented control's disabled prop to control the disabled state of the entire control. Use the segmented control item's disabled prop to control the disabled state of individual items.
<SegmentedControl.Root disabled>
<SegmentedControl.Item text="Chart" value="chart" />
<SegmentedControl.Item text="Table" value="table" />
<SegmentedControl.Item text="Map" value="map" />
</SegmentedControl.Root>
Controlled state
Use the value prop to control the selected value of the segmented control. This allows for more complex interactions and integration with form libraries.
<SegmentedControl.Root
multiple
onValueChange={(values) => {
console.log("Selected values:", values?.length ? values : "<none>")
setValue(values)
}}
value={value}
>
<SegmentedControl.Item text="Production" value="prod" />
<SegmentedControl.Item text="Staging" value="staging" />
<SegmentedControl.Item text="Development" value="dev" />
<SegmentedControl.Item text="QA" value="qa" />
</SegmentedControl.Root>
Accessibility
Keyboard Navigation
Users can navigate the segmented control using the keyboard. The following keys are supported:
Tab/Shift + Tab: Move focus between items.Space/Enter: Select the focused item. Unselects an already selected item if multiple is set.
Icon only
While it is possible to use icon-only items in the segmented control, it is important to ensure that they are easily understood and accessible.
Pick meaningful icons and use the aria-label attribute to describe their purpose.
<SegmentedControl.Root defaultValue={["chart"]}>
<SegmentedControl.Item
aria-label="Chart view"
icon={ChartArea}
value="chart"
/>
<SegmentedControl.Item
aria-label="Table view"
icon={Table}
value="table"
/>
<SegmentedControl.Item aria-label="Map view" icon={Map} value="map" />
</SegmentedControl.Root>
API
<SegmentedControl.Root>
string[]
'ltr' | 'rtl'
boolean'hug' | 'fill'
-
hug: Content-sized; width matches the items only (default).-
fill: Full width; items share space evenly.boolean(
value: string[],
) => void
| 'horizontal'
| 'vertical'
| ReactElement
| ((
props: object,
) => ReactElement)
| 'sm'
| 'md'
| 'lg'
string[]
| 'primary'
| 'neutral'
className'qui-segmented-control__root'data-disableddata-layout'hug' | 'fill'
data-orientation| 'horizontal'
| 'vertical'
data-segmented-control-part'group'data-size| 'sm'
| 'md'
| 'lg'
data-variant| 'primary'
| 'neutral'
<SegmentedControl.Item>
The SegmentedControl.Item extends the SegmentedControl.ItemRoot with the following props:
Composite API
<SegmentedControl.ItemRoot>
<label> by default.stringboolean| LucideIcon
| ReactNode
| ReactElement
| ((
props: object,
) => ReactElement)
className'qui-segmented-control__item'data-activedata-checkbox-part'root'data-disableddata-focusdata-focus-visibledata-hoverdata-invaliddata-orientation| 'horizontal'
| 'vertical'
data-readonlydata-size| 'sm'
| 'md'
| 'lg'
data-state| 'checked'
| 'indeterminate'
| 'unchecked'
<SegmentedControl.ItemText>
<span> by default.| ReactElement
| ((
props: object,
) => ReactElement)
className'qui-segmented-control__item-text'data-activedata-checkbox-part'label'data-disableddata-focusdata-focus-visibledata-hoverdata-invaliddata-readonlydata-state| 'checked'
| 'indeterminate'
| 'unchecked'
<SegmentedControl.HiddenInput>
<input type=radio> by
default.| ReactElement
| ((
props: object,
) => ReactElement)
className'qui-segmented-control__item-hidden-input'data-activedata-checkbox-part'hidden-input'data-disableddata-focusdata-focus-visibledata-hoverdata-invaliddata-readonlydata-state| 'checked'
| 'indeterminate'
| 'unchecked'
style
<fieldset>by default.