{#snippet children(actions)}
{#each actions() as action (action.label)}
{/each}
{/snippet}
```
### Wait for Click
Use the `effect` function with `waitForEvent` to wait for user interaction before proceeding to the next step.
**Example: wait-for-click**
#### React
```tsx
import { Portal } from '@ark-ui/react/portal'
import { Tour, useTour, waitForEvent } from '@ark-ui/react/tour'
import { SparklesIcon, XIcon } from 'lucide-react'
import button from 'styles/button.module.css'
import styles from 'styles/tour.module.css'
const steps: Tour.StepDetails[] = [
{
id: 'intro',
type: 'dialog',
title: 'Interactive Tutorial',
description: 'This tour will guide you through actions. You must complete each step to proceed.',
actions: [{ label: 'Begin', action: 'next' }],
},
{
id: 'click-add',
type: 'tooltip',
title: 'Click the Add Button',
description: 'Click the "Add Item" button to continue.',
target: () => document.querySelector('#btn-add'),
effect({ next, target, show }) {
show()
const [promise, cancel] = waitForEvent(target, 'click')
promise.then(() => next())
return cancel
},
},
{
id: 'click-edit',
type: 'tooltip',
title: 'Click the Edit Button',
description: 'Now click the "Edit" button.',
target: () => document.querySelector('#btn-edit'),
effect({ next, target, show }) {
show()
const [promise, cancel] = waitForEvent(target, 'click')
promise.then(() => next())
return cancel
},
},
{
id: 'click-delete',
type: 'tooltip',
title: 'Click the Delete Button',
description: 'Finally, click the "Delete" button.',
target: () => document.querySelector('#btn-delete'),
effect({ next, target, show }) {
show()
const [promise, cancel] = waitForEvent(target, 'click')
promise.then(() => next())
return cancel
},
},
{
id: 'complete',
type: 'dialog',
title: 'Well Done!',
description: 'You completed all the interactive steps.',
actions: [{ label: 'Finish', action: 'dismiss' }],
},
]
export const WaitForClick = () => {
const tour = useTour({ steps })
return (
{(actions) =>
actions.map((action) => (
))
}
)
}
```
#### Solid
```tsx
import { Tour, useTour, waitForEvent } from '@ark-ui/solid/tour'
import { Portal } from 'solid-js/web'
import { SparklesIcon, XIcon } from 'lucide-solid'
import { For } from 'solid-js'
import button from 'styles/button.module.css'
import styles from 'styles/tour.module.css'
const steps: Tour.StepDetails[] = [
{
id: 'intro',
type: 'dialog',
title: 'Interactive Tutorial',
description: 'This tour will guide you through actions. You must complete each step to proceed.',
actions: [{ label: 'Begin', action: 'next' }],
},
{
id: 'click-add',
type: 'tooltip',
title: 'Click the Add Button',
description: 'Click the "Add Item" button to continue.',
target: () => document.querySelector('#btn-add'),
effect({ next, target, show }) {
show()
const [promise, cancel] = waitForEvent(target, 'click')
promise.then(() => next())
return cancel
},
},
{
id: 'click-edit',
type: 'tooltip',
title: 'Click the Edit Button',
description: 'Now click the "Edit" button.',
target: () => document.querySelector('#btn-edit'),
effect({ next, target, show }) {
show()
const [promise, cancel] = waitForEvent(target, 'click')
promise.then(() => next())
return cancel
},
},
{
id: 'click-delete',
type: 'tooltip',
title: 'Click the Delete Button',
description: 'Finally, click the "Delete" button.',
target: () => document.querySelector('#btn-delete'),
effect({ next, target, show }) {
show()
const [promise, cancel] = waitForEvent(target, 'click')
promise.then(() => next())
return cancel
},
},
{
id: 'complete',
type: 'dialog',
title: 'Well Done!',
description: 'You completed all the interactive steps.',
actions: [{ label: 'Finish', action: 'dismiss' }],
},
]
export const WaitForClick = () => {
const tour = useTour({ steps })
return (
{(actions) => (
{(action) => }
)}
)
}
```
#### Vue
```vue
```
#### Svelte
```svelte
{#snippet children(actions)}
{#each actions() as action (action.label)}
{/each}
{/snippet}
```
### Wait for Input
Create form tutorials that wait for users to enter valid input before advancing.
**Example: wait-for-input**
#### React
```tsx
import { Portal } from '@ark-ui/react/portal'
import { Tour, useTour, waitForEvent } from '@ark-ui/react/tour'
import { SparklesIcon, XIcon } from 'lucide-react'
import button from 'styles/button.module.css'
import styles from 'styles/tour.module.css'
const steps: Tour.StepDetails[] = [
{
id: 'intro',
type: 'dialog',
title: 'Form Tutorial',
description: 'Learn how to fill out the form by following the guided steps.',
actions: [{ label: 'Start', action: 'next' }],
},
{
id: 'enter-name',
type: 'tooltip',
title: 'Enter Your Name',
description: 'Type your name in the input field to continue.',
target: () => document.querySelector('#input-name'),
effect({ next, target, show }) {
show()
const [promise, cancel] = waitForEvent(target, 'input', {
predicate: (el) => el.value.trim().length >= 2,
})
promise.then(() => next())
return cancel
},
},
{
id: 'enter-email',
type: 'tooltip',
title: 'Enter Your Email',
description: 'Now enter a valid email address.',
target: () => document.querySelector('#input-email'),
effect({ next, target, show }) {
show()
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
const [promise, cancel] = waitForEvent(target, 'input', {
predicate: (el) => emailRegex.test(el.value),
})
promise.then(() => next())
return cancel
},
},
{
id: 'check-terms',
type: 'tooltip',
title: 'Accept Terms',
description: 'Check the checkbox to accept the terms.',
target: () => document.querySelector('#checkbox-terms'),
effect({ next, target, show }) {
show()
const [promise, cancel] = waitForEvent(target, 'change', {
predicate: (el) => el.checked,
})
promise.then(() => next())
return cancel
},
},
{
id: 'complete',
type: 'dialog',
title: 'Form Complete!',
description: 'You have successfully filled out the form.',
actions: [{ label: 'Done', action: 'dismiss' }],
},
]
export const WaitForInput = () => {
const tour = useTour({ steps })
return (
{(actions) =>
actions.map((action) => (
))
}
)
}
```
#### Solid
```tsx
import { Tour, useTour, waitForEvent } from '@ark-ui/solid/tour'
import { Portal } from 'solid-js/web'
import { SparklesIcon, XIcon } from 'lucide-solid'
import { For } from 'solid-js'
import button from 'styles/button.module.css'
import styles from 'styles/tour.module.css'
const steps: Tour.StepDetails[] = [
{
id: 'intro',
type: 'dialog',
title: 'Form Tutorial',
description: 'Learn how to fill out the form by following the guided steps.',
actions: [{ label: 'Start', action: 'next' }],
},
{
id: 'enter-name',
type: 'tooltip',
title: 'Enter Your Name',
description: 'Type your name in the input field to continue.',
target: () => document.querySelector('#input-name'),
effect({ next, target, show }) {
show()
const [promise, cancel] = waitForEvent(target, 'input', {
predicate: (el) => el.value.trim().length >= 2,
})
promise.then(() => next())
return cancel
},
},
{
id: 'enter-email',
type: 'tooltip',
title: 'Enter Your Email',
description: 'Now enter a valid email address.',
target: () => document.querySelector('#input-email'),
effect({ next, target, show }) {
show()
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
const [promise, cancel] = waitForEvent(target, 'input', {
predicate: (el) => emailRegex.test(el.value),
})
promise.then(() => next())
return cancel
},
},
{
id: 'check-terms',
type: 'tooltip',
title: 'Accept Terms',
description: 'Check the checkbox to accept the terms.',
target: () => document.querySelector('#checkbox-terms'),
effect({ next, target, show }) {
show()
const [promise, cancel] = waitForEvent(target, 'change', {
predicate: (el) => el.checked,
})
promise.then(() => next())
return cancel
},
},
{
id: 'complete',
type: 'dialog',
title: 'Form Complete!',
description: 'You have successfully filled out the form.',
actions: [{ label: 'Done', action: 'dismiss' }],
},
]
export const WaitForInput = () => {
const tour = useTour({ steps })
return (
{(actions) => (
{(action) => }
)}
)
}
```
#### Vue
```vue
```
#### Svelte
```svelte
{#snippet children(actions)}
{#each actions() as action (action.label)}
{/each}
{/snippet}
```
### Wait for Element
Wait for dynamically rendered elements to appear in the DOM before showing a step.
**Example: wait-for-element**
#### React
```tsx
import { Portal } from '@ark-ui/react/portal'
import { Tour, useTour, waitForElement, waitForEvent } from '@ark-ui/react/tour'
import { PlusIcon, SparklesIcon, XIcon } from 'lucide-react'
import { useState } from 'react'
import button from 'styles/button.module.css'
import styles from 'styles/tour.module.css'
const steps: Tour.StepDetails[] = [
{
id: 'intro',
type: 'dialog',
title: 'Dynamic Elements',
description: 'This tour demonstrates waiting for elements that appear dynamically.',
actions: [{ label: 'Start', action: 'next' }],
},
{
id: 'add-item',
type: 'tooltip',
title: 'Add an Item',
description: 'Click the button to add a new item to the list.',
target: () => document.querySelector('#btn-add-item'),
effect({ next, target, show }) {
show()
const [promise, cancel] = waitForEvent(target, 'click')
promise.then(() => next())
return cancel
},
},
{
id: 'new-item',
type: 'tooltip',
title: 'New Item Added!',
description: 'The tour waited for this element to appear before showing this step.',
target: () => document.querySelector('[data-item="new"]'),
effect({ show }) {
const [promise, cancel] = waitForElement(() => document.querySelector('[data-item="new"]'), {
timeout: 5000,
})
promise.then(() => show())
return () => cancel()
},
actions: [{ label: 'Next', action: 'next' }],
},
{
id: 'complete',
type: 'dialog',
title: 'Tour Complete',
description: 'You learned how to use waitForElement for dynamic content.',
actions: [{ label: 'Done', action: 'dismiss' }],
},
]
export const WaitForElement = () => {
const tour = useTour({ steps })
const [items, setItems] = useState(['Item 1', 'Item 2'])
const addItem = () => {
setItems((prev) => [...prev, `Item ${prev.length + 1}`])
}
return (
{items.map((item, index) => (
2 ? 'new' : undefined}
>
{item}
))}
{(actions) =>
actions.map((action) => (
))
}
)
}
```
#### Solid
```tsx
import { Tour, useTour, waitForElement, waitForEvent } from '@ark-ui/solid/tour'
import { Portal } from 'solid-js/web'
import { PlusIcon, SparklesIcon, XIcon } from 'lucide-solid'
import { For, createSignal } from 'solid-js'
import button from 'styles/button.module.css'
import styles from 'styles/tour.module.css'
const steps: Tour.StepDetails[] = [
{
id: 'intro',
type: 'dialog',
title: 'Dynamic Elements',
description: 'This tour demonstrates waiting for elements that appear dynamically.',
actions: [{ label: 'Start', action: 'next' }],
},
{
id: 'add-item',
type: 'tooltip',
title: 'Add an Item',
description: 'Click the button to add a new item to the list.',
target: () => document.querySelector('#btn-add-item'),
effect({ next, target, show }) {
show()
const [promise, cancel] = waitForEvent(target, 'click')
promise.then(() => next())
return cancel
},
},
{
id: 'new-item',
type: 'tooltip',
title: 'New Item Added!',
description: 'The tour waited for this element to appear before showing this step.',
target: () => document.querySelector('[data-item="new"]'),
effect({ show }) {
const [promise, cancel] = waitForElement(() => document.querySelector('[data-item="new"]'), {
timeout: 5000,
})
promise.then(() => show())
return () => cancel()
},
actions: [{ label: 'Next', action: 'next' }],
},
{
id: 'complete',
type: 'dialog',
title: 'Tour Complete',
description: 'You learned how to use waitForElement for dynamic content.',
actions: [{ label: 'Done', action: 'dismiss' }],
},
]
export const WaitForElement = () => {
const tour = useTour({ steps })
const [items, setItems] = createSignal(['Item 1', 'Item 2'])
const addItem = () => {
setItems((prev) => [...prev, `Item ${prev.length + 1}`])
}
return (
{(item, index) => (
2 ? 'new' : undefined}
>
{item}
)}
{(actions) => (
{(action) => }
)}
)
}
```
#### Vue
```vue
{{ item }}
```
#### Svelte
```svelte
{#each items as item, index (item)}
2 ? 'new' : undefined}>
{item}
{/each}
{#snippet children(actions)}
{#each actions() as action (action.label)}
{/each}
{/snippet}
```
### Async
Load data asynchronously and update step content before displaying it using the `effect` function with `show()` and
`update()`.
**Example: async-step**
#### React
```tsx
import { Portal } from '@ark-ui/react/portal'
import { Tour, useTour } from '@ark-ui/react/tour'
import { SparklesIcon, XIcon } from 'lucide-react'
import button from 'styles/button.module.css'
import styles from 'styles/tour.module.css'
const steps: Tour.StepDetails[] = [
{
id: 'intro',
type: 'dialog',
title: 'Async Data Loading',
description: 'This tour demonstrates loading data before showing a step.',
actions: [{ label: 'Next', action: 'next' }],
},
{
id: 'user-info',
type: 'tooltip',
title: 'Loading...',
description: 'Fetching user data...',
target: () => document.querySelector('#user-card'),
actions: [
{ label: 'Back', action: 'prev' },
{ label: 'Next', action: 'next' },
],
effect({ show, update }) {
const controller = new AbortController()
fetch('https://api.github.com/users/segunadebayo', { signal: controller.signal })
.then((res) => res.json())
.then((data) => {
update({
title: `Welcome, ${data.name || data.login}!`,
description: `You have ${data.public_repos} public repositories and ${data.followers} followers.`,
})
show()
})
.catch(() => {
update({
title: 'User Profile',
description: 'Could not load user data. Please try again.',
})
show()
})
return () => controller.abort()
},
},
{
id: 'complete',
type: 'dialog',
title: 'Tour Complete',
description: 'The async step loaded data from the GitHub API before displaying.',
actions: [{ label: 'Done', action: 'dismiss' }],
},
]
export const AsyncStep = () => {
const tour = useTour({ steps })
return (
User Profile Card
{(actions) =>
actions.map((action) => (
))
}
)
}
```
#### Solid
```tsx
import { Tour, useTour } from '@ark-ui/solid/tour'
import { Portal } from 'solid-js/web'
import { SparklesIcon, XIcon } from 'lucide-solid'
import { For } from 'solid-js'
import button from 'styles/button.module.css'
import styles from 'styles/tour.module.css'
const steps: Tour.StepDetails[] = [
{
id: 'intro',
type: 'dialog',
title: 'Async Data Loading',
description: 'This tour demonstrates loading data before showing a step.',
actions: [{ label: 'Next', action: 'next' }],
},
{
id: 'user-info',
type: 'tooltip',
title: 'Loading...',
description: 'Fetching user data...',
target: () => document.querySelector('#user-card'),
actions: [
{ label: 'Back', action: 'prev' },
{ label: 'Next', action: 'next' },
],
effect({ show, update }) {
const controller = new AbortController()
fetch('https://api.github.com/users/segunadebayo', { signal: controller.signal })
.then((res) => res.json())
.then((data) => {
update({
title: `Welcome, ${data.name || data.login}!`,
description: `You have ${data.public_repos} public repositories and ${data.followers} followers.`,
})
show()
})
.catch(() => {
update({
title: 'User Profile',
description: 'Could not load user data. Please try again.',
})
show()
})
return () => controller.abort()
},
},
{
id: 'complete',
type: 'dialog',
title: 'Tour Complete',
description: 'The async step loaded data from the GitHub API before displaying.',
actions: [{ label: 'Done', action: 'dismiss' }],
},
]
export const AsyncStep = () => {
const tour = useTour({ steps })
return (
User Profile Card
{(actions) => (
{(action) => }
)}
)
}
```
#### Vue
```vue
User Profile Card
```
#### Svelte
```svelte
User Profile Card
{#snippet children(actions)}
{#each actions() as action (action.label)}
{/each}
{/snippet}
```
## Guides
### 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: TourStepDetails[] = [
{
id: 'step-1',
type: 'tooltip',
placement: 'top-start',
target: () => document.querySelector('#target-1'),
title: 'Tooltip Step',
description: 'This is a tooltip step',
},
{
id: 'step-2',
type: 'dialog',
title: 'Dialog Step',
description: 'This is a dialog step',
},
{
id: 'step-3',
type: 'floating',
placement: 'top-start',
title: 'Floating Step',
description: 'This is a floating 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
},
},
]
```
### 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: TourStepDetails[] = [
{
id: 'step-1',
type: 'dialog',
title: 'Dialog Step',
description: 'This is a dialog step',
actions: [{ label: 'Show me a tour!', action: 'next' }],
},
]
```
### Tooltip Placement
Use the `placement` property to define the placement of the tooltip.
```tsx {5}
const steps: TourStepDetails[] = [
{
id: 'step-1',
type: 'tooltip',
placement: 'top-start',
// ...
},
]
```
### Hide Arrow
Set `arrow: false` in the step property to hide the tooltip arrow. This is only useful for tooltip steps.
```tsx {5}
const steps: TourStepDetails[] = [
{
id: 'step-1',
type: 'tooltip',
arrow: false,
},
]
```
### Hide 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: TourStepDetails[] = [
{
id: 'step-1',
type: 'dialog',
backdrop: false,
},
]
```
### 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: TourStepDetails[] = [
{
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
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: TourStepDetails[] = [
{
id: 'step-1',
type: 'wait',
effect({ next }) {
const button = document.querySelector('#button')
const listener = () => next()
button.addEventListener('click', listener)
return () => button.removeEventListener('click', listener)
},
},
]
```
### Styling
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;
}
```
## API Reference
### Props
**Component API Reference**
#### React
**Root Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `tour` | `UseTourReturn` | Yes | |
| `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state |
| `present` | `boolean` | No | Whether the node is present (controlled by the user) |
| `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |
**ActionTrigger Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `action` | `StepAction` | Yes | |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**ActionTrigger Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | action-trigger |
| `[data-type]` | The type of the item |
| `[data-disabled]` | Present when disabled |
**Arrow Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Arrow CSS Variables:**
| Variable | Description |
|----------|-------------|
| `--arrow-size` | The size of the arrow |
| `--arrow-size-half` | Half the size of the arrow |
| `--arrow-background` | Use this variable to style the arrow background |
| `--arrow-offset` | The offset position of the arrow |
**ArrowTip Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Backdrop Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Backdrop Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | backdrop |
| `[data-state]` | "open" | "closed" |
| `[data-type]` | The type of the item |
**Backdrop CSS Variables:**
| Variable | Description |
|----------|-------------|
| `--tour-layer` | The tour layer value for the Backdrop |
| `--layer-index` | The index of the dismissable in the layer stack |
**CloseTrigger Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**CloseTrigger Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | close-trigger |
| `[data-type]` | The type of the item |
**Content Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Content Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | content |
| `[data-state]` | "open" | "closed" |
| `[data-nested]` | popover |
| `[data-has-nested]` | popover |
| `[data-type]` | The type of the item |
| `[data-placement]` | The placement of the content |
| `[data-step]` | |
**Content CSS Variables:**
| Variable | Description |
|----------|-------------|
| `--layer-index` | The index of the dismissable in the layer stack |
| `--nested-layer-count` | The number of nested tours |
**Control Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Description Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Description Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | description |
| `[data-placement]` | The placement of the description |
**Positioner Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Positioner Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | positioner |
| `[data-type]` | The type of the item |
| `[data-placement]` | The placement of the positioner |
**Positioner CSS Variables:**
| Variable | Description |
|----------|-------------|
| `--tour-layer` | The tour layer value for the Positioner |
| `--reference-width` | The width of the reference element |
| `--reference-height` | The height of the root |
| `--available-width` | The available width in viewport |
| `--available-height` | The available height in viewport |
| `--x` | The x position for transform |
| `--y` | The y position for transform |
| `--z-index` | The z-index value |
| `--transform-origin` | The transform origin for animations |
**ProgressText Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Spotlight Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Spotlight CSS Variables:**
| Variable | Description |
|----------|-------------|
| `--tour-layer` | The tour layer value for the Spotlight |
**Title Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Title Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | title |
| `[data-placement]` | The placement of the title |
#### Solid
**Root Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `tour` | `UseTourReturn` | Yes | |
| `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state |
| `present` | `boolean` | No | Whether the node is present (controlled by the user) |
| `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |
**ActionTrigger Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `action` | `StepAction` | Yes | |
| `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**ActionTrigger Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | action-trigger |
| `[data-type]` | The type of the item |
| `[data-disabled]` | Present when disabled |
**Arrow Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Arrow CSS Variables:**
| Variable | Description |
|----------|-------------|
| `--arrow-size` | The size of the arrow |
| `--arrow-size-half` | Half the size of the arrow |
| `--arrow-background` | Use this variable to style the arrow background |
| `--arrow-offset` | The offset position of the arrow |
**ArrowTip Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Backdrop Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Backdrop Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | backdrop |
| `[data-state]` | "open" | "closed" |
| `[data-type]` | The type of the item |
**Backdrop CSS Variables:**
| Variable | Description |
|----------|-------------|
| `--tour-layer` | The tour layer value for the Backdrop |
| `--layer-index` | The index of the dismissable in the layer stack |
**CloseTrigger Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**CloseTrigger Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | close-trigger |
| `[data-type]` | The type of the item |
**Content Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Content Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | content |
| `[data-state]` | "open" | "closed" |
| `[data-nested]` | popover |
| `[data-has-nested]` | popover |
| `[data-type]` | The type of the item |
| `[data-placement]` | The placement of the content |
| `[data-step]` | |
**Content CSS Variables:**
| Variable | Description |
|----------|-------------|
| `--layer-index` | The index of the dismissable in the layer stack |
| `--nested-layer-count` | The number of nested tours |
**Control Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Description Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Description Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | description |
| `[data-placement]` | The placement of the description |
**Positioner Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Positioner Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | positioner |
| `[data-type]` | The type of the item |
| `[data-placement]` | The placement of the positioner |
**Positioner CSS Variables:**
| Variable | Description |
|----------|-------------|
| `--tour-layer` | The tour layer value for the Positioner |
| `--reference-width` | The width of the reference element |
| `--reference-height` | The height of the root |
| `--available-width` | The available width in viewport |
| `--available-height` | The available height in viewport |
| `--x` | The x position for transform |
| `--y` | The y position for transform |
| `--z-index` | The z-index value |
| `--transform-origin` | The transform origin for animations |
**ProgressText Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Spotlight Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Spotlight CSS Variables:**
| Variable | Description |
|----------|-------------|
| `--tour-layer` | The tour layer value for the Spotlight |
**Title Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'h2'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Title Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | title |
| `[data-placement]` | The placement of the title |
#### Vue
**Root Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `tour` | `TourApi` | Yes | |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |
**ActionTrigger Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `action` | `StepAction` | Yes | |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**ActionTrigger Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | action-trigger |
| `[data-type]` | The type of the item |
| `[data-disabled]` | Present when disabled |
**Arrow Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Arrow CSS Variables:**
| Variable | Description |
|----------|-------------|
| `--arrow-size` | The size of the arrow |
| `--arrow-size-half` | Half the size of the arrow |
| `--arrow-background` | Use this variable to style the arrow background |
| `--arrow-offset` | The offset position of the arrow |
**ArrowTip Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Backdrop Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Backdrop Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | backdrop |
| `[data-state]` | "open" | "closed" |
| `[data-type]` | The type of the item |
**Backdrop CSS Variables:**
| Variable | Description |
|----------|-------------|
| `--tour-layer` | The tour layer value for the Backdrop |
| `--layer-index` | The index of the dismissable in the layer stack |
**CloseTrigger Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**CloseTrigger Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | close-trigger |
| `[data-type]` | The type of the item |
**Content Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Content Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | content |
| `[data-state]` | "open" | "closed" |
| `[data-nested]` | popover |
| `[data-has-nested]` | popover |
| `[data-type]` | The type of the item |
| `[data-placement]` | The placement of the content |
| `[data-step]` | |
**Content CSS Variables:**
| Variable | Description |
|----------|-------------|
| `--layer-index` | The index of the dismissable in the layer stack |
| `--nested-layer-count` | The number of nested tours |
**Control Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Description Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Description Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | description |
| `[data-placement]` | The placement of the description |
**Positioner Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Positioner Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | positioner |
| `[data-type]` | The type of the item |
| `[data-placement]` | The placement of the positioner |
**Positioner CSS Variables:**
| Variable | Description |
|----------|-------------|
| `--tour-layer` | The tour layer value for the Positioner |
| `--reference-width` | The width of the reference element |
| `--reference-height` | The height of the root |
| `--available-width` | The available width in viewport |
| `--available-height` | The available height in viewport |
| `--x` | The x position for transform |
| `--y` | The y position for transform |
| `--z-index` | The z-index value |
| `--transform-origin` | The transform origin for animations |
**ProgressText Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Spotlight Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Spotlight CSS Variables:**
| Variable | Description |
|----------|-------------|
| `--tour-layer` | The tour layer value for the Spotlight |
**Title Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Title Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | title |
| `[data-placement]` | The placement of the title |
#### Svelte
**Root Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `tour` | `UseTourReturn` | Yes | |
| `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state |
| `present` | `boolean` | No | Whether the node is present (controlled by the user) |
| `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |
**ActionTrigger Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `action` | `StepAction` | Yes | |
| `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No | |
**ActionTrigger Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | action-trigger |
| `[data-type]` | The type of the item |
| `[data-disabled]` | Present when disabled |
**Arrow Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No | |
**Arrow CSS Variables:**
| Variable | Description |
|----------|-------------|
| `--arrow-size` | The size of the arrow |
| `--arrow-size-half` | Half the size of the arrow |
| `--arrow-background` | Use this variable to style the arrow background |
| `--arrow-offset` | The offset position of the arrow |
**ArrowTip Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No | |
**Backdrop Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No | |
**Backdrop Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | backdrop |
| `[data-state]` | "open" | "closed" |
| `[data-type]` | The type of the item |
**Backdrop CSS Variables:**
| Variable | Description |
|----------|-------------|
| `--tour-layer` | The tour layer value for the Backdrop |
| `--layer-index` | The index of the dismissable in the layer stack |
**CloseTrigger Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No | |
**CloseTrigger Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | close-trigger |
| `[data-type]` | The type of the item |
**Content Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No | |
**Content Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | content |
| `[data-state]` | "open" | "closed" |
| `[data-nested]` | popover |
| `[data-has-nested]` | popover |
| `[data-type]` | The type of the item |
| `[data-placement]` | The placement of the content |
| `[data-step]` | |
**Content CSS Variables:**
| Variable | Description |
|----------|-------------|
| `--layer-index` | The index of the dismissable in the layer stack |
| `--nested-layer-count` | The number of nested tours |
**Context Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `render` | `Snippet<[UseTourContext]>` | Yes | |
**Control Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No | |
**Description Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No | |
**Description Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | description |
| `[data-placement]` | The placement of the description |
**Positioner Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No | |
**Positioner Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | positioner |
| `[data-type]` | The type of the item |
| `[data-placement]` | The placement of the positioner |
**Positioner CSS Variables:**
| Variable | Description |
|----------|-------------|
| `--tour-layer` | The tour layer value for the Positioner |
| `--reference-width` | The width of the reference element |
| `--reference-height` | The height of the root |
| `--available-width` | The available width in viewport |
| `--available-height` | The available height in viewport |
| `--x` | The x position for transform |
| `--y` | The y position for transform |
| `--z-index` | The z-index value |
| `--transform-origin` | The transform origin for animations |
**ProgressText Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No | |
**Spotlight Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No | |
**Spotlight CSS Variables:**
| Variable | Description |
|----------|-------------|
| `--tour-layer` | The tour layer value for the Spotlight |
**Title Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'h2'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No | |
**Title Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | tour |
| `[data-part]` | title |
| `[data-placement]` | The placement of the title |
### Context
**API:**
| Property | Type | Description |
|----------|------|-------------|
| `open` | `boolean` | Whether the tour is open |
| `totalSteps` | `number` | The total number of steps |
| `stepIndex` | `number` | The index of the current step |
| `step` | `StepDetails` | The current step details |
| `hasNextStep` | `boolean` | Whether there is a next step |
| `hasPrevStep` | `boolean` | Whether there is a previous step |
| `firstStep` | `boolean` | Whether the current step is the first step |
| `lastStep` | `boolean` | Whether the current step is the last step |
| `addStep` | `(step: StepDetails) => void` | Add a new step to the tour |
| `removeStep` | `(id: string) => void` | Remove a step from the tour |
| `updateStep` | `(id: string, stepOverrides: Partial) => void` | Update a step in the tour with partial details |
| `setSteps` | `(steps: StepDetails[]) => void` | Set the steps of the tour |
| `setStep` | `(id: string) => void` | Set the current step of the tour |
| `start` | `(id?: string) => void` | Start the tour at a specific step (or the first step if not provided) |
| `isValidStep` | `(id: string) => boolean` | Check if a step is valid |
| `isCurrentStep` | `(id: string) => boolean` | Check if a step is visible |
| `next` | `VoidFunction` | Move to the next step |
| `prev` | `VoidFunction` | Move to the previous step |
| `getProgressText` | `() => string` | Returns the progress text |
| `getProgressPercent` | `() => number` | Returns the progress percent |