{"slug":"switch","title":"Switch","description":"Using the switch machine in your project.","contentType":"component","framework":"react","content":"A switch allows users to turn an individual option on or off.\n\n## Resources\n\n\n[Latest version: v1.31.0](https://www.npmjs.com/package/@zag-js/switch)\n[Logic Visualizer](https://zag-visualizer.vercel.app/switch)\n[Source Code](https://github.com/chakra-ui/zag/tree/main/packages/machines/switch)\n\n\n\n**Features**\n\n- Sync with `disabled` state of fieldset\n- Sync with form `reset` events\n- Can be toggled programmatically\n\n## Installation\n\nTo use the switch machine in your project, run the following command in your\ncommand line:\n\n```bash\nnpm install @zag-js/switch @zag-js/react\n# or\nyarn add @zag-js/switch @zag-js/react\n```\n\n## Anatomy\n\nTo set up the switch correctly, you'll need to understand its anatomy and how we\nname 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 switch package into your project\n\n```jsx\nimport * as zagSwitch from \"@zag-js/switch\"\n```\n\nThe switch package exports two key functions:\n\n- `machine` — The state machine logic for the switch widget.\n- `connect` — The function that translates the machine's state to JSX attributes\n  and event handlers.\n\nNext, import the required hooks and functions for your framework and use the\nswitch machine in your project 🔥\n\n```jsx\nimport * as zagSwitch from \"@zag-js/switch\"\nimport { useMachine, normalizeProps } from \"@zag-js/react\"\n\nfunction Checkbox() {\n  const service = useMachine(zagSwitch.machine, { id: \"1\" })\n\n  const api = zagSwitch.connect(service, normalizeProps)\n\n  return (\n    <label {...api.getRootProps()}>\n      <input {...api.getHiddenInputProps()} />\n      <span {...api.getControlProps()}>\n        <span {...api.getThumbProps()} />\n      </span>\n      <span {...api.getLabelProps()}>{api.checked ? \"On\" : \"Off\"}</span>\n    </label>\n  )\n}\n```\n\n### Disabling the switch\n\nTo make a switch disabled, set the `disabled` property to `true`.\n\n```jsx {3}\nconst service = useMachine(zagSwitch.machine, {\n  disabled: true,\n})\n```\n\n### Making it checked by default\n\nUse the `defaultChecked` property to make a switch checked by default.\n\n```jsx {3}\nconst service = useMachine(zagSwitch.machine, {\n  defaultChecked: true,\n})\n```\n\n### Listening for changes\n\nWhen the switch value changes, the `onCheckedChange` callback is invoked.\n\n```jsx {3-5}\nconst service = useMachine(zagSwitch.machine, {\n  onCheckedChange(details) {\n    // details => { checked: boolean }\n    console.log(\"switch is:\", details.checked ? \"On\" : \"Off\")\n  },\n})\n```\n\n### Usage within forms\n\nTo use switch within forms, use the exposed `inputProps` from the `connect`\nfunction and ensure you pass `name` value to the machine's context. It will\nrender a hidden input and ensure the value changes get propagated to the form\ncorrectly.\n\n```jsx {3}\nconst service = useMachine(zagSwitch.machine, {\n  name: \"feature\",\n})\n```\n\n## Styling guide\n\nEarlier, we mentioned that each switch part has a `data-part` attribute added to\nthem to select and style them in the DOM.\n\n### Focused State\n\nWhen the switch input is focused, the `data-focus` attribute is added to the\nroot, control and label parts.\n\n```css\n[data-part=\"root\"][data-focus] {\n  /* styles for root focus state */\n}\n\n[data-part=\"control\"][data-focus] {\n  /* styles for control focus state */\n}\n\n[data-part=\"label\"][data-focus] {\n  /* styles for label focus state */\n}\n```\n\n### Disabled State\n\nWhen the switch is disabled, the `data-disabled` attribute is added to the root,\ncontrol and label parts.\n\n```css\n[data-part=\"root\"][data-disabled] {\n  /* styles for root disabled state */\n}\n\n[data-part=\"control\"][data-disabled] {\n  /* styles for control disabled state */\n}\n\n[data-part=\"label\"][data-disabled] {\n  /* styles for label disabled state */\n}\n```\n\n### Invalid State\n\nWhen the switch is invalid, the `data-invalid` attribute is added to the root,\ncontrol and label parts.\n\n```css\n[data-part=\"root\"][data-invalid] {\n  /* styles for root invalid state */\n}\n\n[data-part=\"control\"][data-invalid] {\n  /* styles for control invalid state */\n}\n\n[data-part=\"label\"][data-invalid] {\n  /* styles for label invalid state */\n}\n```\n\n## Methods and Properties\n\n### Machine Context\n\nThe switch machine exposes the following context properties:\n\n**`ids`**\nType: `Partial<{ root: string; hiddenInput: string; control: string; label: string; thumb: string; }>`\nDescription: The ids of the elements in the switch. Useful for composition.\n\n**`label`**\nType: `string`\nDescription: Specifies the localized strings that identifies the accessibility elements and their states\n\n**`disabled`**\nType: `boolean`\nDescription: Whether the switch is disabled.\n\n**`invalid`**\nType: `boolean`\nDescription: If `true`, the switch is marked as invalid.\n\n**`required`**\nType: `boolean`\nDescription: If `true`, the switch input is marked as required,\n\n**`readOnly`**\nType: `boolean`\nDescription: Whether the switch is read-only\n\n**`onCheckedChange`**\nType: `(details: CheckedChangeDetails) => void`\nDescription: Function to call when the switch is clicked.\n\n**`checked`**\nType: `boolean`\nDescription: The controlled checked state of the switch\n\n**`defaultChecked`**\nType: `boolean`\nDescription: The initial checked state of the switch when rendered.\nUse when you don't need to control the checked state of the switch.\n\n**`name`**\nType: `string`\nDescription: The name of the input field in a switch\n(Useful for form submission).\n\n**`form`**\nType: `string`\nDescription: The id of the form that the switch belongs to\n\n**`value`**\nType: `string | number`\nDescription: The value of switch input. Useful for form submission.\n\n**`dir`**\nType: `\"ltr\" | \"rtl\"`\nDescription: The document's text/writing direction.\n\n**`id`**\nType: `string`\nDescription: The unique identifier of the machine.\n\n**`getRootNode`**\nType: `() => ShadowRoot | Node | Document`\nDescription: A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron.\n\n### Machine API\n\nThe switch `api` exposes the following methods:\n\n**`checked`**\nType: `boolean`\nDescription: Whether the switch is checked\n\n**`disabled`**\nType: `boolean`\nDescription: Whether the switch is disabled\n\n**`focused`**\nType: `boolean`\nDescription: Whether the switch is focused\n\n**`setChecked`**\nType: `(checked: boolean) => void`\nDescription: Sets the checked state of the switch.\n\n**`toggleChecked`**\nType: `VoidFunction`\nDescription: Toggles the checked state of the switch.\n\n### Data Attributes\n\n**`Root`**\n\n**`data-active`**: Present when active or pressed\n**`data-focus`**: Present when focused\n**`data-focus-visible`**: Present when focused with keyboard\n**`data-readonly`**: Present when read-only\n**`data-hover`**: Present when hovered\n**`data-disabled`**: Present when disabled\n**`data-state`**: \"checked\" | \"unchecked\"\n**`data-invalid`**: Present when invalid\n**`data-required`**: Present when required\n\n**`Label`**\n\n**`data-active`**: Present when active or pressed\n**`data-focus`**: Present when focused\n**`data-focus-visible`**: Present when focused with keyboard\n**`data-readonly`**: Present when read-only\n**`data-hover`**: Present when hovered\n**`data-disabled`**: Present when disabled\n**`data-state`**: \"checked\" | \"unchecked\"\n**`data-invalid`**: Present when invalid\n**`data-required`**: Present when required\n\n**`Thumb`**\n\n**`data-active`**: Present when active or pressed\n**`data-focus`**: Present when focused\n**`data-focus-visible`**: Present when focused with keyboard\n**`data-readonly`**: Present when read-only\n**`data-hover`**: Present when hovered\n**`data-disabled`**: Present when disabled\n**`data-state`**: \"checked\" | \"unchecked\"\n**`data-invalid`**: Present when invalid\n**`data-required`**: Present when required\n\n**`Control`**\n\n**`data-active`**: Present when active or pressed\n**`data-focus`**: Present when focused\n**`data-focus-visible`**: Present when focused with keyboard\n**`data-readonly`**: Present when read-only\n**`data-hover`**: Present when hovered\n**`data-disabled`**: Present when disabled\n**`data-state`**: \"checked\" | \"unchecked\"\n**`data-invalid`**: Present when invalid\n**`data-required`**: Present when required\n\n## Accessibility\n\nAdheres to the\n[Switch WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/switch/)\n\n### Keyboard Interactions\n\n**`Space + Enter`**\nDescription: Toggle the switch","package":"@zag-js/switch","editUrl":"https://github.com/chakra-ui/zag/edit/main/website/data/components/switch.mdx"}