# SegmentedControl A horizontal control composed of mutually exclusive segments, used to switch between related options. ## Import ```tsx import { SegmentedControl } from '@coinbase/cds-web/controls/SegmentedControl' ``` ## Examples SegmentedControl uses native radio inputs with labels to provide an accessible, compact switch between options. It supports both text labels and icon options. ### Basics Pass an array of `options` with `value` and `label` properties. Use `value` and `onChange` for controlled usage, or omit them for uncontrolled behavior. The component manages its own state when uncontrolled. ```jsx live function SegmentedControlBasic() { const options = [ { value: 'eth', label: 'ETH' }, { value: 'usd', label: 'USD' }, { value: 'btc', label: 'BTC' }, ]; const [selected, setSelected] = useState('eth'); return ( Selected: {selected} ); } ``` #### Uncontrolled When you omit `value` and `onChange`, SegmentedControl manages selection internally. Use `onChange` only when you need to react to changes. ```jsx live function SegmentedControlUncontrolled() { const options = [ { value: 'list', label: 'List' }, { value: 'grid', label: 'Grid' }, ]; return ; } ``` ### Icons For icon-only segments, set `type="icon"` and provide `iconSize` and options with `label` as an icon name. Use `accessibilityLabel` on each option for screen readers. ```jsx live function SegmentedControlIcons() { const options = [ { value: 'eth', label: 'ethereum', accessibilityLabel: 'Ethereum' }, { value: 'usd', label: 'cashUSD', accessibilityLabel: 'US Dollar' }, ]; const [value, setValue] = useState('eth'); return ( ); } ``` You can also set `active` to `true` to apply an active icon style. ```jsx live function SegmentedControlActiveIcons() { const options = [ { value: 'eth', label: 'ethereum', accessibilityLabel: 'Ethereum', active: true }, { value: 'usd', label: 'cashUSD', accessibilityLabel: 'US Dollar' }, ]; const [value, setValue] = useState('eth'); return ( ); } ``` ### Disabled Disable the entire control with the `disabled` prop. ```jsx live function SegmentedControlDisabled() { const options = [ { value: 'option1', label: 'Option 1' }, { value: 'option2', label: 'Option 2' }, ]; return ; } ``` ### Accessibility Provide `accessibilityLabel` on each option when using icons so screen readers can announce the segment. For text options, the label text is used automatically. ```jsx live function SegmentedControlAccessible() { const options = [ { value: 'eth', label: 'ethereum', accessibilityLabel: 'View in Ethereum' }, { value: 'usd', label: 'cashUSD', accessibilityLabel: 'View in US Dollars' }, ]; const [value, setValue] = useState('eth'); return ( ); } ``` ## Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `iconSize` | `xs \| s \| m \| l` | Yes | `-` | - | | `options` | `TextOptions \| IconOptions` | Yes | `-` | The options to render as an array of values and labels The options to render as an array of values and IconNames | | `block` | `boolean` | No | `-` | Expand to 100% of parent width | | `disabled` | `boolean` | No | `-` | - | | `key` | `Key \| null` | No | `-` | - | | `onChange` | `((value: string) => void)` | No | `-` | Callback fired when an option is selected | | `ref` | `((instance: HTMLInputElement \| null) => void) \| RefObject \| null` | No | `-` | - | | `testID` | `string` | No | `-` | Used to locate this element in unit and end-to-end tests. Under the hood, testID translates to data-testid on Web. On Mobile, testID stays the same - testID | | `type` | `text \| icon` | No | `-` | - | | `value` | `string` | No | `-` | The selected value |