{"slug":"installation","title":"Getting Started","description":"Setting up Zag UI machines in your project","contentType":"overview","content":"Zag can be used within most JS frameworks like Vue, React, Svelte and Solid.\n\nTo get Zag running, you'll need to:\n\n1. Install the machine for the component you're interested in. Let's say you\n   want to use the `tooltip` machine.\n\n```bash\nnpm install @zag-js/tooltip\n# or\nyarn add @zag-js/tooltip\n```\n\n2. Install the adapter for the framework of your choice. At the moment, Zag is\n   available for React, Vue 3, Svelte and Solid.js. Let's say you use React.\n\n```bash\nnpm install @zag-js/react\n# or\nyarn add @zag-js/react\n```\n\n> Congrats! You're ready to use tooltip machine in your project.\n\n## Using the machine\n\nHere's an example of the tooltip machine used in a React.js project.\n\n```jsx\nimport * as tooltip from \"@zag-js/tooltip\"\nimport { useMachine, normalizeProps } from \"@zag-js/react\"\n\nexport function Tooltip() {\n  const service = useMachine(tooltip.machine, { id: \"1\" })\n\n  const api = tooltip.connect(service, normalizeProps)\n\n  return (\n    <>\n      <button {...api.getTriggerProps()}>Hover me</button>\n      {api.open && (\n        <div {...api.getPositionerProps()}>\n          <div {...api.getContentProps()}>Tooltip</div>\n        </div>\n      )}\n    </>\n  )\n}\n```\n\n### Usage with Vue 3 (JSX)\n\nZag works seamlessly with Vue's JSX approach. Here's how to use the same tooltip\nlogic in Vue:\n\n```jsx\nimport * as tooltip from \"@zag-js/tooltip\"\nimport { normalizeProps, useMachine } from \"@zag-js/vue\"\nimport { computed, defineComponent, h, Fragment } from \"vue\"\n\nexport default defineComponent({\n  name: \"Tooltip\",\n  setup() {\n    const service = useMachine(tooltip.machine, { id: \"1\" })\n    const apiRef = computed(() => tooltip.connect(service, normalizeProps))\n\n    return () => {\n      const api = apiRef.current\n      return (\n        <>\n          <div>\n            <button {...api.getTriggerProps()}>Hover me</button>\n            {api.open && (\n              <div {...api.getPositionerProps()}>\n                <div {...api.getContentProps()}>Tooltip</div>\n              </div>\n            )}\n          </div>\n        </>\n      )\n    }\n  },\n})\n```\n\nThere are some extra functions that need to be used in order to make it work:\n\n- `normalizeProps` - Converts the props of the component into the format that is\n  compatible with Vue.\n- `computed` - Ensures that the tooltip's `api` is always up to date with the\n  current state of the machine.\n\n### Usage with Solid.js\n\nWe love Solid.js and we've added support for it. Here's how to use the same\ntooltip logic in Solid:\n\n```jsx\nimport * as tooltip from \"@zag-js/tooltip\"\nimport { normalizeProps, useMachine } from \"@zag-js/solid\"\nimport { createMemo, createUniqueId, Show } from \"solid-js\"\n\nexport function Tooltip() {\n  const service = useMachine(tooltip.machine, { id: createUniqueId() })\n\n  const api = createMemo(() => tooltip.connect(service, normalizeProps))\n\n  return (\n    <div>\n      <button {...api().getTriggerProps()}>Hover me</button>\n      <Show when={api().open}>\n        <div {...api().getPositionerProps()}>\n          <div {...api().getContentProps()}>Tooltip</div>\n        </div>\n      </Show>\n    </div>\n  )\n}\n```\n\nThere are some extra functions that need to be used in order to make it work:\n\n- `normalizeProps` - Converts the props of the component into the format that is\n  compatible with Solid.\n- `createMemo` - Ensures that the tooltip's `api` is always up to date with the\n  current state of the machine.\n\n### Usage with Svelte\n\nHere's how to use the same tooltip logic in Svelte:\n\n```html\n<script lang=\"ts\">\n  import * as tooltip from \"@zag-js/tooltip\"\n  import { useMachine, normalizeProps } from \"@zag-js/svelte\"\n\n  const service = useMachine(tooltip.machine, { id: \"1\" })\n\n  const api = $derived(tooltip.connect(service, normalizeProps))\n</script>\n\n<div>\n  <button {...api.getTriggerProps()}>Hover me</button>\n  {#if api.open}\n  <div {...api.getPositionerProps()}>\n    <div {...api.getContentProps()}>Tooltip</div>\n  </div>\n  {/if}\n</div>\n```\n\nThere are some extra functions that need to be used in order to make it work:\n\n- `normalizeProps` - Converts the props of the component into the format that is\n  compatible with Svelte.\n- `$derived` - Ensures that the tooltip's `api` is always up to date with the\n  current state of the machine.\n\n### About prop normalization\n\nThere are subtle difference between how JSX attributes are named across\nframeworks like React, Solid, Vue and Svelte. Here are some examples:\n\n**Keydown listener**\n\n- React and Solid: The keydown listener property is `onKeyDown`.\n- Vue: The keydown listener property is `onKeydown`.\n\n**Styles**\n\n- React: Pass a numeric value for margin attributes like `{ marginBottom: 4 }`.\n- Solid: It has to be `{ \"margin-bottom\": \"4px\" }`.\n- Vue: You need to ensure the value is a string with unit.\n  `{ marginBottom: \"4px\" }`.\n\nThese little nuances between frameworks are handled automatically when you use\n`normalizeProps`.\n\n> The goal of Zag is to help you abstract the interaction and accessibility\n> patterns into a statechart so you never have to re-invent the wheel.\n\nThanks for reading! If you're curious about how state machines work, the next\npage will give you a quick overview.","editUrl":"https://github.com/chakra-ui/zag/edit/main/website/data/overview/installation.mdx"}