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>

The root element of the segmented control. Renders as a <fieldset> by default.
PropTypeDefault
React children prop.
The initial value of the group when rendered. Use when you don't need to control the value of the group.
string[]
The document's text/writing direction.
'ltr' | 'rtl'
'ltr'
Whether the group is disabled. When true, prevents user interaction and applies visual styling to indicate the disabled state.
boolean
The layout used to display the segmented control.
-
hug: Content-sized; width matches the items only (default).
-
fill: Full width; items share space evenly.
'hug' | 'fill'
'hug'
Whether the control allows multiple selections or not.
boolean
Function called when the value of the segmented control group changes.
    (
    value: string[],
    ) => void
    Orientation of the segmented control group.
    | 'horizontal'
    | 'vertical'
    'horizontal'
    
    Allows you to replace the component's HTML element with a different tag or component. Learn more
    | ReactElement
    | ((
    props: object,
    ) => ReactElement)
    The size of the segmented control.
    | 'sm'
    | 'md'
    | 'lg'
    'md'
    
    The controlled value of the group.
    string[]
    The variant of the segmented control.
    | 'primary'
    | 'neutral'
    undefined
    
    Description
    React children prop.
    Type
    string[]
    Description
    The initial value of the group when rendered. Use when you don't need to control the value of the group.
    Type
    'ltr' | 'rtl'
    Description
    The document's text/writing direction.
    Type
    boolean
    Description
    Whether the group is disabled. When true, prevents user interaction and applies visual styling to indicate the disabled state.
    Type
    'hug' | 'fill'
    Description
    The layout used to display the segmented control.
    -
    hug: Content-sized; width matches the items only (default).
    -
    fill: Full width; items share space evenly.
    Type
    boolean
    Description
    Whether the control allows multiple selections or not.
    Type
    (
    value: string[],
    ) => void
    Description
    Function called when the value of the segmented control group changes.
      Type
      | 'horizontal'
      | 'vertical'
      Description
      Orientation of the segmented control group.
      Type
      | ReactElement
      | ((
      props: object,
      ) => ReactElement)
      Description
      Allows you to replace the component's HTML element with a different tag or component. Learn more
      Type
      | 'sm'
      | 'md'
      | 'lg'
      Description
      The size of the segmented control.
      Type
      string[]
      Description
      The controlled value of the group.
      Type
      | 'primary'
      | 'neutral'
      Description
      The variant of the segmented control.

      <SegmentedControl.Item>

      The SegmentedControl.Item extends the SegmentedControl.ItemRoot with the following props:

      PropType
      The text for the item.
      Description
      The text for the item.

      Composite API

      <SegmentedControl.ItemRoot>

      A segmented control item container. Renders as a <label> by default.
      PropType
      The value of the item.
      string
      React children prop.
      Whether the item is disabled.
      boolean
      Icon, positioned before the item label if there is one.
      | LucideIcon
      | ReactNode
      Allows you to replace the component's HTML element with a different tag or component. Learn more
      | ReactElement
      | ((
      props: object,
      ) => ReactElement)
      Type
      string
      Description
      The value of the item.
      Description
      React children prop.
      Type
      boolean
      Description
      Whether the item is disabled.
      Type
      | LucideIcon
      | ReactNode
      Description
      Icon, positioned before the item label if there is one.
      Type
      | ReactElement
      | ((
      props: object,
      ) => ReactElement)
      Description
      Allows you to replace the component's HTML element with a different tag or component. Learn more

      <SegmentedControl.ItemText>

      A segmented control item's text. Renders as a <span> by default.
      PropType
      React children prop.
      Allows you to replace the component's HTML element with a different tag or component. Learn more
      | ReactElement
      | ((
      props: object,
      ) => ReactElement)
      Description
      React children prop.
      Type
      | ReactElement
      | ((
      props: object,
      ) => ReactElement)
      Description
      Allows you to replace the component's HTML element with a different tag or component. Learn more

      <SegmentedControl.HiddenInput>

      A segmented control item's hidden input. Renders as an <input type=radio> by default.
      PropType
      Allows you to replace the component's HTML element with a different tag or component. Learn more
      | ReactElement
      | ((
      props: object,
      ) => ReactElement)
      Type
      | ReactElement
      | ((
      props: object,
      ) => ReactElement)
      Description
      Allows you to replace the component's HTML element with a different tag or component. Learn more