{"slug":"segmented-control","title":"Segmented Control","description":"Using the Segmented Control in your project.","contentType":"component","framework":"react","content":"A segmented control lets users pick one option from a small set.\n\n## Resources\n\n\n[Latest version: v1.35.3](https://www.npmjs.com/package/@zag-js/radio-group)\n[Logic Visualizer](https://zag-visualizer.vercel.app/segmented-control)\n[Source Code](https://github.com/chakra-ui/zag/tree/main/packages/machines/segmented-control)\n\n\n\n**Features**\n\n- Syncs with `disabled` state of fieldset\n- Syncs with form `reset` events\n- Can programmatically set segmented control value\n- Can programmatically focus segmented control items\n\n## Installation\n\nInstall the radio group package:\n\n```bash\nnpm install @zag-js/radio-group @zag-js/react\n# or\nyarn add @zag-js/radio-group @zag-js/react\n```\n\n## Anatomy\n\nCheck the segmented control anatomy and part names.\n\n> Each part includes a `data-part` attribute to help identify them in the DOM.\n\n\n\n## Usage\n\nImport the radio group package:\n\n```jsx\nimport * as radio from \"@zag-js/radio-group\"\n```\n\nThese are the key exports:\n\n- `machine` - State machine logic.\n- `connect` - Maps machine state to JSX props and event handlers.\n\nThen use the framework integration helpers:\n\n```jsx\nimport * as radio from \"@zag-js/radio-group\"\nimport { useMachine, normalizeProps } from \"@zag-js/react\"\n\nconst items = [\n  { label: \"React\", value: \"react\" },\n  { label: \"Angular\", value: \"ng\" },\n  { label: \"Vue\", value: \"vue\" },\n  { label: \"Svelte\", value: \"svelte\" },\n]\n\nfunction Radio() {\n  const service = useMachine(radio.machine, { id: \"1\" })\n\n  const api = radio.connect(service, normalizeProps)\n\n  return (\n    <div {...api.getRootProps()}>\n      <div {...api.getIndicatorProps()} />\n      {items.map((opt) => (\n        <label key={opt.value} {...api.getItemProps({ value: opt.value })}>\n          <span {...api.getItemTextProps({ value: opt.value })}>\n            {opt.label}\n          </span>\n          <input {...api.getItemHiddenInputProps({ value: opt.value })} />\n        </label>\n      ))}\n    </div>\n  )\n}\n```\n\n### Setting the initial value\n\nUse the `defaultValue` property to set the segmented control's initial value.\n\n```jsx {2}\nconst service = useMachine(radio.machine, {\n  defaultValue: \"apple\",\n})\n```\n\n### Controlled segmented value\n\nUse `value` and `onValueChange` for controlled usage.\n\n```jsx\nconst service = useMachine(radio.machine, {\n  value,\n  onValueChange(details) {\n    setValue(details.value)\n  },\n})\n```\n\n### Programmatic value control\n\nUse the connected API when you need imperative updates.\n\n```jsx\napi.setValue(\"orange\")\napi.clearValue()\n```\n\n### Focusing from code\n\nUse `api.focus()` to move focus to the selected item (or first enabled item).\n\n```jsx\napi.focus()\n```\n\n### Listening for changes\n\nWhen the segmented control value changes, the `onValueChange` callback is\ninvoked.\n\n```jsx {2-7}\nconst service = useMachine(radio.machine, {\n  onValueChange(details) {\n    // details => { value: string | null }\n    console.log(\"segmented control value is:\", details.value)\n  },\n})\n```\n\n### Usage within forms\n\nTo use segmented control in forms, set `name` and render\n`api.getItemHiddenInputProps({ value })` for each item.\n\n```jsx {2}\nconst service = useMachine(radio.machine, {\n  name: \"fruits\",\n})\n```\n\n### Vertical orientation\n\nSet `orientation` when you need a vertical layout.\n\n```jsx\nconst service = useMachine(radio.machine, {\n  orientation: \"vertical\",\n})\n```\n\n## Styling guide\n\nEach part includes a `data-part` attribute you can target in CSS.\n\n### Indicator\n\nStyle the segmented control Indicator through the `indicator` part.\n\n```css\n[data-part=\"indicator\"] {\n  /* styles for indicator */\n}\n```\n\n### Focused State\n\nWhen the radio input is focused, the `data-focus` attribute is added to the root\nand label parts.\n\n```css\n[data-part=\"radio\"][data-focus] {\n  /* styles for radio focus state */\n}\n\n[data-part=\"radio-label\"][data-focus] {\n  /* styles for radio label focus state */\n}\n```\n\n### Disabled State\n\nWhen the radio is disabled, the `data-disabled` attribute is added to the root\nand label parts.\n\n```css\n[data-part=\"radio\"][data-disabled] {\n  /* styles for radio disabled state */\n}\n\n[data-part=\"radio-label\"][data-disabled] {\n  /* styles for radio label disabled state */\n}\n```\n\n### Invalid State\n\nWhen the radio is invalid, the `data-invalid` attribute is added to the root and\nlabel parts.\n\n```css\n[data-part=\"radio\"][data-invalid] {\n  /* styles for radio invalid state */\n}\n\n[data-part=\"radio-label\"][data-invalid] {\n  /* styles for radio label invalid state */\n}\n```\n\n## Methods and Properties\n\n### Machine Context\n\nThe radio group machine exposes the following context properties:\n\n<ContextTable name=\"radio-group\" />\n\n### Machine API\n\nThe radio group `api` exposes the following methods:\n\n<ApiTable name=\"radio-group\" />\n\n### Data Attributes\n\n<DataAttrTable name=\"radio-group\" />","package":"@zag-js/radio-group","editUrl":"https://github.com/chakra-ui/zag/edit/main/website/data/components/segmented-control.mdx"}