{"slug":"segmented-control","title":"Segmented Control","description":"Using the Segmented Control in your project.","contentType":"component","framework":"react","content":"A Segmented control allows users to make a single selection from multiple\nexclusive options, providing a visually distinct and intuitive way of\ninteracting with radio inputs.\n\n## Resources\n\n\n[Latest version: v1.31.0](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 and blur segmented control items\n\n## Installation\n\nTo use segmented control add the radio machine to your project, run the\nfollowing command in your command line:\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\nTo set up the segmented control correctly, you'll need to understand its anatomy\nand how we name its parts.\n\n> Each part includes a `data-part` attribute to help identify them in the DOM.\n\n\n\n## Usage\n\nFirst, import the radio group package into your project\n\n```jsx\nimport * as radio from \"@zag-js/radio-group\"\n```\n\nThe radio package exports two key functions:\n\n- `machine` — The state machine logic for the radio widget.\n- `connect` — The function that translates the machine's state to JSX attributes\n  and event handlers.\n\n> You'll also need to provide a unique `id` to the `useMachine` hook. This is\n> used to ensure that every part has a unique identifier.\n\nNext, import the required hooks and functions for your framework and use the\nradio machine in your project 🔥\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### Disabling the segmented control\n\nTo make a segmented control disabled, set the context's `disabled` property to\ntrue\n\n```jsx {2}\nconst service = useMachine(radio.machine, {\n  disabled: true,\n})\n```\n\n### Making the segmented control readonly\n\nTo make a segmented control readonly, set the context's `readOnly` property to\ntrue\n\n```jsx {2}\nconst service = useMachine(radio.machine, {\n  readOnly: true,\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### 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 }\n    console.log(\"segmented control value is:\", details.value)\n  },\n})\n```\n\n### Usage within forms\n\nTo use segmented control within forms, use the exposed `inputProps` from the\n`connect` function and ensure you pass `name` value to the machine's context. It\nwill render a hidden input and ensure the value changes get propagated to the\nform correctly.\n\n```jsx {2}\nconst service = useMachine(radio.machine, {\n  name: \"fruits\",\n})\n```\n\n## Styling guide\n\nEarlier, we mentioned that each segmented control part has a `data-part`\nattribute added to them to select and style them in the DOM.\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"}