# or
yarn add @zag-js/tour @zag-js/svelte
```

## Anatomy

To set up the tooltip correctly, you'll need to understand its anatomy and how
we name its parts.

> Each part includes a `data-part` attribute to help identify them in the DOM.



## Usage

First, import the tooltip package into your project

```jsx
import * as tour from "@zag-js/tour"
```

The tour package exports two key functions:

- `machine` â The state machine logic for the tour widget.
- `connect` â The function that translates the machine's state to JSX attributes
  and event handlers.

Next, import the required hooks and functions for your framework and use the
tour machine in your project ð¥

```svelte
<script lang="ts">
  import * as tour from "@zag-js/tour"
  import { portal, useMachine, normalizeProps } from "@zag-js/svelte"

  const id = $props.id()
  const service = useMachine(tour.machine, { id, steps })
  const api = $derived(tour.connect(service, normalizeProps))
</script>

<div>
  <div>
    <button onclick={() => api.start()}>Start Tour</button>
    <div id="step-1">Step 1</div>
  </div>
  {#if api.step && api.open}
    <div use:portal>
      {#if api.step.backdrop}
        <div {...api.getBackdropProps()}></div>
      {/if}
      <div {...api.getSpotlightProps()}></div>
      <div {...api.getPositionerProps()}>
        <div {...api.getContentProps()}>
          {#if api.step.arrow}
            <div {...api.getArrowProps()}>
              <div {...api.getArrowTipProps()}></div>
            </div>
          {/if}

          <p {...api.getTitleProps()}>{api.step.title}</p>
          <div {...api.getDescriptionProps()}>{api.step.description}</div>
          <div {...api.getProgressTextProps()}>{api.getProgressText()}</div>
          {#if api.step.actions}
            <div>
              {#each api.step.actions as action}
                <button {...api.getActionTriggerProps({ action })}>
                  {action.label}
                </button>
              {/each}
            </div>
          {/if}

          <button {...api.getCloseTriggerProps()}>X</button>
        </div>
      </div>
    </div>
  {/if}
</div>
```

### Using step types

The tour machine supports different types of steps, allowing you to create a
diverse and interactive tour experience. The available step types are defined in
the `StepType` type:

- `"tooltip"`: Displays the step content as a tooltip, typically positioned near
  the target element.

- `"dialog"`: Shows the step content in a modal dialog centered on screen,
  useful for starting or ending the tour. This usually don't have a `target`
  defined.

- `"floating"`: Presents the step content as a floating element, which can be
  positioned flexibly on the screen. This usually don't have a `target` defined.

- `"wait"`: A special type that waits for a specific condition before proceeding
  to the next step.

```tsx
const steps: tour.StepDetails[] = [
  // Tooltip step
  {
    id: "step-1",
    type: "tooltip",
    placement: "top-start",
    target: () => document.querySelector("#target-1"),
    title: "Tooltip Step",
    description: "This is a tooltip step",
  },

  // Dialog step
  {
    id: "step-2",
    type: "dialog",
    title: "Dialog Step",
    description: "This is a dialog step",
  },

  // Floating step
  {
    id: "step-3",
    type: "floating",
    placement: "top-start",
    title: "Floating Step",
    description: "This is a floating step",
  },

  // Wait step
  {
    id: "step-4",
    type: "wait",
    title: "Wait Step",
    description: "This is a wait step",
    effect({ next }) {
      // do something and go next
      // you can also return a cleanup
    },
  },
]
```

### Configuring actions

Every step supports a list of actions that are rendered in the step footer.Use
the `actions` property to define each action.

```tsx
const steps: tour.StepDetails[] = [
  {
    id: "step-1",
    type: "dialog",
    title: "Dialog Step",
    description: "This is a dialog step",
    actions: [{ label: "Show me a tour!", action: "next" }],
  },
]
```

### Changing tooltip placement

Use the `placement` property to define the placement of the tooltip.

```tsx {5}
const steps: tour.StepDetails[] = [
  {
    id: "step-1",
    type: "tooltip",
    placement: "top-start",
    // ...
  },
]
```

### Hiding the arrow

Set `arrow: false` in the step property to hide the tooltip arrow. This is only
useful for tooltip steps.

```tsx {5}
const steps: tour.StepDetails[] = [
  {
    id: "step-1",
    type: "tooltip",
    arrow: false,
  },
]
```

### Hiding the backdrop

Set `backdrop: false` in the step property to hide the backdrop. This applies to
all step types except the `wait` step.

```tsx {5}
const steps: tour.StepDetails[] = [
  {
    id: "step-1",
    type: "dialog",
    backdrop: false,
  },
]
```

### Step Effects

Step effects are functions that are called before a step is opened. They are
useful for adding custom logic to a step.

This function provides the following methods:

- `next()`: Call this method to move to the next step.
- `show()`: Call this method to show the current step.
- `update(details: StepDetails)`: Call this method to update the details of the
  current step (say, after data has been fetched).

```tsx
const steps: tour.StepDetails[] = [
  {
    id: "step-1",
    type: "tooltip",
    effect({ next, show, update }) {
      fetchData().then((res) => {
        // update the step details
        update({ title: res.title })
        // then show show the step
        show()
      })

      return () => {
        // cleanup fetch data
      }
    },
  },
]
```

### Wait Steps

Wait steps are useful when you need to wait for a specific condition before
proceeding to the next step.

Use the step `effect` function to perform an action and then call `next()` to
move to the next step.

> **Note:** You cannot call `show()` in a wait step.

```tsx
const steps: tour.StepDetails[] = [
  {
    id: "step-1",
    type: "wait",
    effect({ next }) {
      const button = document.querySelector("#button")
      const listener = () => next()
      button.addEventListener("click", listener)
      return () => button.removeEventListener("click", listener)
    },
  },
]
```

### Showing progress dots

Use the `api.getProgressPercent()` to show the progress dots.

```tsx
const ProgressBar = () => {
  const service = useMachine(tour.machine, { steps: [] })
  const api = tour.connect(service, normalizeProps)
  return <div>{api.getProgressPercent()}</div>
}
```

### Tracking the lifecycle

As the tour is progressed, events are fired and you can track the lifecycle of
the tour. Here's are the events you can listen to:

- `onStepChange`: Fires when the current step changes.
- `onStatusChange`: Fires when the status of the tour changes.

```tsx
const Lifecycle = () => {
  const service = useMachine(tour.machine, {
    steps: [],
    onStepChange(details) {
      // => { stepId: "step-1", stepIndex: 0, totalSteps: 3, complete: false, progress: 0 }
      console.log(details)
    },
    onStatusChange(status) {
      // => { status: "started" | "skipped" | "completed" | "dismissed" | "not-found" }
      console.log(status)
    },
  })

  const api = tour.connect(service, normalizeProps)
  // ...
}
```

## Styling guide

### Prerequisites

Ensure the `box-sizing` is set to `border-box` for the means of measuring the
tour target.

```css
* {
  box-sizing: border-box;
}
```

Ensure the `body` has a `position` of `relative`.

```css
body {
  position: relative;
}
```

### Overview

Each tour part has a `data-part` attribute that can be used to style them in the
DOM.

```css
[data-scope="tour"][data-part="content"] {
  /* styles for the content part */
}

[data-scope="tour"][data-part="positioner"] {
  /* styles for the positioner part */
}

[data-scope="tour"][data-part="arrow"] {
  /* styles for the arrow part */
}

[data-scope="tour"][data-part="title"] {
  /* styles for the title part */
}

[data-scope="tour"][data-part="description"] {
  /* styles for the description part */
}

[data-scope="tour"][data-part="progress-text"] {
  /* styles for the progress text part */
}

[data-scope="tour"][data-part="action-trigger"] {
  /* styles for the action trigger part */
}

[data-scope="tour"][data-part="backdrop"] {
  /* styles for the backdrop part */
}
```

### Step types

The tour component supports two types: `dialog` and `floating`. You can apply
specific styles based on the tour type:

```css
[data-scope="tour"][data-part="content"][data-type="dialog"] {
  /* styles for content when step is dialog type */
}

[data-scope="tour"][data-part="content"][data-type="floating"] {
  /* styles for content when step is floating type */
}

[data-scope="tour"][data-part="positioner"][data-type="dialog"] {
  /* styles for positioner when step is dialog type */
}

[data-scope="tour"][data-part="positioner"][data-type="floating"] {
  /* styles for positioner when step is floating type */
}
```

### Placement Styles

For floating type tours, you can style based on the placement using the
`data-placement` attribute:

```css
[data-scope="tour"][data-part="positioner"][data-type="floating"][data-placement*="bottom"] {
  /* styles for bottom placement */
}

[data-scope="tour"][data-part="positioner"][data-type="floating"][data-placement*="top"] {
  /* styles for top placement */
}

[data-scope="tour"][data-part="positioner"][data-type="floating"][data-placement*="start"] {
  /* styles for start placement */
}

[data-scope="tour"][data-part="positioner"][data-type="floating"][data-placement*="end"] {
  /* styles for end placement */
}
```

## Methods and Properties

### Machine Context

The tour machine exposes the following context properties:

**`ids`**
Type: `Partial<{ content: string; title: string; description: string; positioner: string; backdrop: string; arrow: string; }>`
Description: The ids of the elements in the tour. Useful for composition.

**`steps`**
Type: `StepDetails[]`
Description: The steps of the tour

**`stepId`**
Type: `string`
Description: The id of the currently highlighted step

**`onStepChange`**
Type: `(details: StepChangeDetails) => void`
Description: Callback when the highlighted step changes

**`onStepsChange`**
Type: `(details: StepsChangeDetails) => void`
Description: Callback when the steps change

**`onStatusChange`**
Type: `(details: StatusChangeDetails) => void`
Description: Callback when the tour is opened or closed

**`closeOnInteractOutside`**
Type: `boolean`
Description: Whether to close the tour when the user clicks outside the tour

**`closeOnEscape`**
Type: `boolean`
Description: Whether to close the tour when the user presses the escape key

**`keyboardNavigation`**
Type: `boolean`
Description: Whether to allow keyboard navigation (right/left arrow keys to navigate between steps)

**`preventInteraction`**
Type: `boolean`
Description: Prevents interaction with the rest of the page while the tour is open

**`spotlightOffset`**
Type: `Point`
Description: The offsets to apply to the spotlight

**`spotlightRadius`**
Type: `number`
Description: The radius of the spotlight clip path

**`translations`**
Type: `IntlTranslations`
Description: The translations for the tour

**`dir`**
Type: `"ltr" | "rtl"`
Description: The document's text/writing direction.

**`id`**
Type: `string`
Description: The unique identifier of the machine.

**`getRootNode`**
Type: `() => ShadowRoot | Node | Document`
Description: A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron.

**`onPointerDownOutside`**
Type: `(event: PointerDownOutsideEvent) => void`
Description: Function called when the pointer is pressed down outside the component

**`onFocusOutside`**
Type: `(event: FocusOutsideEvent) => void`
Description: Function called when the focus is moved outside the component

**`onInteractOutside`**
Type: `(event: InteractOutsideEvent) => void`
Description: Function called when an interaction happens outside the component

### Machine API

The time picker `api` exposes the following methods:

**`open`**
Type: `boolean`
Description: Whether the tour is open

**`totalSteps`**
Type: `number`
Description: The total number of steps

**`stepIndex`**
Type: `number`
Description: The index of the current step

**`step`**
Type: `StepDetails`
Description: The current step details

**`hasNextStep`**
Type: `boolean`
Description: Whether there is a next step

**`hasPrevStep`**
Type: `boolean`
Description: Whether there is a previous step

**`firstStep`**
Type: `boolean`
Description: Whether the current step is the first step

**`lastStep`**
Type: `boolean`
Description: Whether the current step is the last step

**`addStep`**
Type: `(step: StepDetails) => void`
Description: Add a new step to the tour

**`removeStep`**
Type: `(id: string) => void`
Description: Remove a step from the tour

**`updateStep`**
Type: `(id: string, stepOverrides: Partial<StepDetails>) => void`
Description: Update a step in the tour with partial details

**`setSteps`**
Type: `(steps: StepDetails[]) => void`
Description: Set the steps of the tour

**`setStep`**
Type: `(id: string) => void`
Description: Set the current step of the tour

**`start`**
Type: `(id?: string) => void`
Description: Start the tour at a specific step (or the first step if not provided)

**`isValidStep`**
Type: `(id: string) => boolean`
Description: Check if a step is valid

**`isCurrentStep`**
Type: `(id: string) => boolean`
Description: Check if a step is visible

**`next`**
Type: `VoidFunction`
Description: Move to the next step

**`prev`**
Type: `VoidFunction`
Description: Move to the previous step

**`getProgressText`**
Type: `() => string`
Description: Returns the progress text

**`getProgressPercent`**
Type: `() => number`
Description: Returns the progress percent
The TreeView component provides a hierarchical view of data, similar to a file
system explorer. It allows users to expand and collapse branches, select
individual or multiple nodes, and traverse the hierarchy using keyboard
navigation.

## Resources


[Latest version: v1.33.1](https://www.npmjs.com/package/@zag-js/tree-view)
[Logic Visualizer](https://zag-visualizer.vercel.app/tree-view)
[Source Code](https://github.com/chakra-ui/zag/tree/main/packages/machines/tree-view)



**Features**

- Display hierarchical data in a tree structure
- Expand or collapse nodes
- Support for keyboard navigation
- Select single or multiple nodes (depending on the selection mode)
- Perform actions on the nodes, such as deleting them or performing some other
  operation

## Installation

To use the tree view machine in your project, run the following command in your
command line:

```bash
npm install @zag-js/tree-view @zag-js/svelte