{"slug":"whats-a-machine","title":"What is a machine?","description":"A brief explanation of the state machine concept","contentType":"overview","content":"A state machine is a tool for modeling stateful, reactive systems. It is useful\nfor declaratively describing the behavior of an application or component.\n\nTo model any logic as using the state machine pattern, it must have:\n\n- A finite number of states.\n- A finite number of transitions between states.\n\n## Creating a state machine\n\nConsider a simple toggle or switch component that consists of two states,\n`active` and `inactive`. The initial state will be `active`\n\nThe supported transitions that can happen here:\n\n- In the `active` state, when we click the toggle, it should transition to the\n  `inactive` state\n- In the `inactive` state, when we click the toggle, it should transition to the\n  `active` state\n\nHere's how we'll model the logic in code:\n\n```jsx\nimport { createMachine } from \"@zag-js/core\"\n\nconst machine = createMachine({\n  // initial state\n  initialState() {\n    return \"active\"\n  },\n  // the finite states\n  states: {\n    active: {\n      on: {\n        CLICK: {\n          // go to inactive\n          target: \"inactive\",\n        },\n      },\n    },\n    inactive: {\n      on: {\n        CLICK: {\n          // go to active\n          target: \"active\",\n        },\n      },\n    },\n  },\n})\n```\n\n### TypeScript Guide\n\nFor TypeScript projects, you can add type definitions to make your machine\ntype-safe:\n\n```tsx\nimport { createMachine, type Service } from \"@zag-js/core\"\nimport type { NormalizeProps, PropTypes } from \"@zag-js/types\"\n\ninterface ToggleSchema {\n  state: \"active\" | \"inactive\"\n  event: { type: \"CLICK\" }\n}\n\nexport const machine = createMachine<ToggleSchema>({\n  // ... same as above\n})\n```\n\n## Writing the connect function\n\nNow that we've modelled the component logic, let's map that to DOM attributes\nand event handlers following the\n[WAI-ARIA](https://www.w3.org/TR/wai-aria-practices-1.1/examples/checkbox/checkbox-1/checkbox-1.html)\nspecification for the switch component.\n\nWe'll write a function called `connect` to do this.\n\n```jsx\nfunction connect(service, normalize) {\n  const { state, send } = service\n  const active = state.matches(\"active\")\n  return {\n    active,\n    getButtonProps() {\n      return normalize.button({\n        type: \"button\",\n        role: \"switch\",\n        \"aria-checked\": active,\n        onClick() {\n          send({ type: \"CLICK\" })\n        },\n      })\n    },\n  }\n}\n```\n\n### TypeScript Guide\n\nFor TypeScript projects, you can add type definitions to make your connect\nfunction type-safe:\n\n```tsx\nimport { type Service } from \"@zag-js/core\"\nimport type { NormalizeProps, PropTypes } from \"@zag-js/types\"\n\ninterface ToggleSchema {\n  state: \"active\" | \"inactive\"\n  event: { type: \"CLICK\" }\n}\n\nexport function connect<T extends PropTypes>(\n  service: Service<ToggleSchema>,\n  normalize: NormalizeProps<T>,\n) {\n  const { state, send } = service\n  const active = state.matches(\"active\")\n  return {\n    active,\n    getButtonProps() {\n      return normalize.button({\n        type: \"button\",\n        role: \"switch\",\n        \"aria-checked\": active,\n        onClick() {\n          send({ type: \"CLICK\" })\n        },\n      })\n    },\n  }\n}\n```\n\n## Consuming the state machine\n\nHere's how to consume the toggle machine logic and connect in React.js.\n\n```jsx\nimport { useMachine, normalizeProps } from \"@zag-js/react\"\nimport { machine, connect } from \"./toggle\"\n\nfunction Toggle() {\n  const service = useMachine(machine)\n  const api = connect(service, normalizeProps)\n\n  return (\n    <button\n      {...api.getButtonProps()}\n      style={{\n        width: \"40px\",\n        height: \"24px\",\n        borderRadius: \"999px\",\n        background: api.active ? \"green\" : \"gray\",\n      }}\n    >\n      {api.active ? \"ON\" : \"OFF\"}\n    </button>\n  )\n}\n```\n\nThat's it! Now you've learned the fundamentals of a component state machine.\n\n## Next Steps\n\nNow that you understand the basics, learn about the advanced concepts that power Zag machines:\n\n- [Building Machines Guide](/guides/building-machines) - Deep dive into context (bindable), watch/track, computed, refs, and more","editUrl":"https://github.com/chakra-ui/zag/edit/main/website/data/overview/whats-a-machine.mdx"}