[Components](https://oods-foundry.com/components) / primitive

# SegmentedControl

Chooses one of two to five options shown as joined segments.

Generated from @oods/foundry 0.10.1

- Categories

  primitive

- Contexts

  form

- Readiness

  `react-and-vue`

## Playground

This component's contract doesn't list typed props, so the playground shows its documented example.

Documented example `segmented-control-billing-period` : ArrowRight or ArrowLeft from Quarterly, or click Yearly, the neighbouring value emitted once; the consumer owns value.

The render follows the page's theme switch: light, dark or high contrast. Both frameworks render the same example.

The real SegmentedControl, live

React

Billing period

Monthly Quarterly Yearly

Vue

Billing period

Monthly Quarterly Yearly

Events it emits: change, update. Use either render above, and each event shows here with the framework that sent it.



## Code

The documented example. HTML is the markup the React component renders for it, which @oods/component-styles styles.

**React**

```
import { SegmentedControl } from '@oods/components-react';
import '@oods/component-styles/css';

const options = [
  {
    "value": "monthly",
    "label": "Monthly"
  },
  {
    "value": "quarterly",
    "label": "Quarterly"
  },
  {
    "value": "yearly",
    "label": "Yearly"
  }
];

export function Example() {
  return (
    <SegmentedControl
      id="billing-period"
      label="Billing period"
      value="quarterly"
      options={options}
    />
  );
}
```

## Props, slots and events

Contract version 1.1.0. Types are from the React declarations in @oods/components-react.

Props

| Prop | Type | Required | Documented example |
| - | - | - | - |
| `id` | `string` | yes | `billing-period` |
| `label` | `ReactNode` | yes | `Billing period` |
| `options` | `readonly SelectOption[]` | yes | `[{"value":"monthly","label":"Monthly"},{"value":"quarterly","label":"Quarterly"},{"value":"yearly","label":"Yearly"}]` |
| `value` | `string \| undefined` | no | `quarterly` |
| `defaultValue` | `string \| undefined` | no | |
| `name` | `string \| undefined` | no | |
| `size` | `"xs" \| "sm" \| "md" \| "lg" \| undefined` | no | |
| `disabled` | `boolean \| undefined` | no | |

### Slots

label

### Events

change, update

## States

selected, unselected, disabled

## Accessibility

- Role

  `radio`

- How it gets its name

  `label` on `input[type="radio"]:checked`

### Keyboard

Keyboard

| Key | What it does |
| - | - |
| `Tab` | Move focus to the checked option |
| `ArrowRight` | Check and focus the next option |
| `ArrowDown` | Check and focus the next option |
| `ArrowLeft` | Check and focus the previous option |
| `ArrowUp` | Check and focus the previous option |

### Obligations in the contract

- Native radio inputs in a radiogroup named by its visible label through aria-labelledby
- Each option is a radio inside its own label, so the option text names it
- The browser gives the radio-group keyboard: the arrows move and check, and Tab enters at the checked option

One choice from two to five options, each { value, label, disabled }, shown as joined segments in sizes xs, sm, md and lg: 24, 28, 32 and 40px, the button, input and select heights at each size. value (controlled) or defaultValue (uncontrolled) checks one option; with neither, none is checked and Tab enters at the first. name groups the radios and defaults to the id; disabled disables every option. Each change emits change and update with the chosen value. React, Vue and the HTML renderer write one markup, and the HTML needs no script: the native radios carry the keyboard. Icon-only segments and more than one selection are not part of it.

## Tokens

The token roles this component reads.

- `segmented.track`
- `segmented.selected`
- `segmented.ring`
- `segmented.text`
- `segmented.focus`

## Readiness

The evidence recorded for this component, with its label.

`react-and-vue`: catalog_list gives this label when the React and Vue components have complete readiness evidence, but the sweep's generated apps don't use the component in both.

Readiness evidence

| Evidence | React | Vue |
| - | - | - |
| state | implemented-evidence-complete | implemented-evidence-complete |
| versioned contract | passed | passed |
| target implementation | passed | passed |
| package export | passed | passed |
| public declaration | passed | passed |
| dependency closure | passed | passed |
| framework scenario | passed | passed |
| accessibility | verified | verified |
| interaction | verified | verified |
| visual themes | verified | verified |

## Use your own

You can replace this component with your own React or Vue component. Map it, and generated code imports yours at the exact version you name. A contract report, run in a real browser, lists what your component met, what it didn't, and what wasn't checked.

The `component_map` call, with the parts in angle brackets yours to fill:

```
{
  "action": "create",
  "apply": true,
  "externalSystem": "<your design system>",
  "externalComponent": "<YourSegmentedControl>",
  "oodsTraits": [
    "<trait names>"
  ],
  "substitution": {
    "component": "SegmentedControl",
    "react": {
      "package": "<your-package>/react",
      "version": "<exact version>",
      "export": "<YourSegmentedControl>"
    },
    "vue": {
      "package": "<your-package>/vue",
      "version": "<exact version>",
      "export": "<YourSegmentedControl>"
    }
  }
}
```

## How this page was made

Generated at build from the published data, each source with the hash of what was read. [The page's manifest](https://oods-foundry.com/components/segmented-control/manifest.json).

- **Contract**: `@oods/component-contracts@0.10.1 componentContracts.SegmentedControl` `sha256:104b4bc331e3…`
- **Documented example**: `@oods/component-contracts@0.10.1 sharedScenarios segmented-control-billing-period` `sha256:ae731fab8c38…`
- **Catalog entry (catalog_list)**: `generated/0.10.1/system/catalog.json SegmentedControl` `sha256:0452f7037564…`
- **React readiness**: `@oods/components-react@0.10.1 readiness SegmentedControl` `sha256:9a1ae4a69b2c…`
- **Vue readiness**: `@oods/components-vue@0.10.1 readiness SegmentedControl` `sha256:3a8eef718ba2…`
- **Prop types**: `generated/0.10.1/components/prop-types.json SegmentedControl` `sha256:db300a767814…`
