# Tour URL: https://ark-ui.com/docs/components/tour Source: https://raw.githubusercontent.com/chakra-ui/ark/refs/heads/main/website/src/content/pages/components/tour.mdx A guided tour that helps users understand the interface. --- ## Anatomy ```tsx const tour = useTour({ steps: [...] }) ``` ## Examples **Example: basic** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { MoreHorizontalIcon, SaveIcon, SparklesIcon, UploadIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'welcome', type: 'dialog', title: 'Welcome to the App!', description: "Let's take a quick tour to get you started with the main features.", actions: [{ label: 'Start Tour', action: 'next' }], }, { id: 'upload', type: 'tooltip', title: 'Upload Files', description: 'Click here to upload your files to the cloud.', target: () => document.querySelector('#btn-upload'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'save', type: 'tooltip', title: 'Save Changes', description: 'Save your work to keep your progress.', target: () => document.querySelector('#btn-save'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'more', type: 'tooltip', title: 'More Options', description: 'Access additional settings and actions from this menu.', target: () => document.querySelector('#btn-more'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'complete', type: 'dialog', title: "You're all set!", description: 'You now know the basics. Enjoy using the app!', actions: [{ label: 'Finish', action: 'dismiss' }], }, ] export const Basic = () => { const tour = useTour({ steps }) return (
{(actions) => actions.map((action) => ( )) }
) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { MoreHorizontalIcon, SaveIcon, SparklesIcon, UploadIcon, 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: 'welcome', type: 'dialog', title: 'Welcome to the App!', description: "Let's take a quick tour to get you started with the main features.", actions: [{ label: 'Start Tour', action: 'next' }], }, { id: 'upload', type: 'tooltip', title: 'Upload Files', description: 'Click here to upload your files to the cloud.', target: () => document.querySelector('#btn-upload'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'save', type: 'tooltip', title: 'Save Changes', description: 'Save your work to keep your progress.', target: () => document.querySelector('#btn-save'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'more', type: 'tooltip', title: 'More Options', description: 'Access additional settings and actions from this menu.', target: () => document.querySelector('#btn-more'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'complete', type: 'dialog', title: "You're all set!", description: 'You now know the basics. Enjoy using the app!', actions: [{ label: 'Finish', action: 'dismiss' }], }, ] export const Basic = () => { const tour = useTour({ steps }) return (
{(actions) => ( {(action) => } )}
) } ``` #### Vue ```vue ``` #### Svelte ```svelte
{#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
``` ### Step Types Demonstrate all three step types in a single tour: `dialog` for welcome/completion, `tooltip` anchored to elements, and `floating` for fixed-position content. **Example: mixed-types** #### 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: 'welcome', type: 'dialog', title: 'Welcome!', description: 'This tour demonstrates different step types: dialog, tooltip, and floating.', actions: [{ label: 'Start Tour', action: 'next' }], }, { id: 'tooltip-step', type: 'tooltip', title: 'Tooltip Step', description: 'This step appears as a tooltip anchored to a specific element.', target: () => document.querySelector('#target-element'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'floating-step', type: 'floating', placement: 'bottom-end', title: 'Floating Step', description: 'This step floats at a fixed position on the screen, independent of any target.', actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'complete', type: 'dialog', title: 'Tour Complete!', description: 'You have seen all the different step types available.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const MixedTypes = () => { const tour = useTour({ steps }) return (
Target Element
{(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: 'welcome', type: 'dialog', title: 'Welcome!', description: 'This tour demonstrates different step types: dialog, tooltip, and floating.', actions: [{ label: 'Start Tour', action: 'next' }], }, { id: 'tooltip-step', type: 'tooltip', title: 'Tooltip Step', description: 'This step appears as a tooltip anchored to a specific element.', target: () => document.querySelector('#target-element'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'floating-step', type: 'floating', placement: 'bottom-end', title: 'Floating Step', description: 'This step floats at a fixed position on the screen, independent of any target.', actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'complete', type: 'dialog', title: 'Tour Complete!', description: 'You have seen all the different step types available.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const MixedTypes = () => { const tour = useTour({ steps }) return (
Target Element
{(actions) => ( {(action) => } )}
) } ``` #### Vue ```vue ``` #### Svelte ```svelte
Target Element
{#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
``` ### Progress Display a visual progress indicator at the bottom of the tour content showing how far along the user is. **Example: progress-bar** #### 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: 'step-1', type: 'tooltip', title: 'Progress Tracking', description: 'Watch the progress bar at the bottom as you navigate.', target: () => document.querySelector('#progress-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Halfway There', description: 'The progress bar shows how far along you are.', target: () => document.querySelector('#progress-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Almost Done', description: 'One more step to complete the tour.', target: () => document.querySelector('#progress-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-4', type: 'tooltip', title: 'Complete!', description: 'You have completed all the steps.', target: () => document.querySelector('#progress-4'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const ProgressBar = () => { const tour = useTour({ steps }) return (
Step 1
Step 2
Step 3
Step 4
{(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: 'step-1', type: 'tooltip', title: 'Progress Tracking', description: 'Watch the progress bar at the bottom as you navigate.', target: () => document.querySelector('#progress-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Halfway There', description: 'The progress bar shows how far along you are.', target: () => document.querySelector('#progress-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Almost Done', description: 'One more step to complete the tour.', target: () => document.querySelector('#progress-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-4', type: 'tooltip', title: 'Complete!', description: 'You have completed all the steps.', target: () => document.querySelector('#progress-4'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const ProgressBar = () => { const tour = useTour({ steps }) return (
Step 1
Step 2
Step 3
Step 4
{(actions) => ( {(action) => } )}
) } ``` #### Vue ```vue ``` #### Svelte ```svelte
Step 1
Step 2
Step 3
Step 4
{#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
``` ### Skip Allow users to skip the entire tour at any step by adding a skip action. **Example: skip-tour** #### 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: 'step-1', type: 'tooltip', title: 'First Feature', description: 'You can skip this tour at any time using the Skip button.', target: () => document.querySelector('#item-1'), actions: [ { label: 'Skip', action: 'dismiss' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-2', type: 'tooltip', title: 'Second Feature', description: 'Continue or skip to end the tour early.', target: () => document.querySelector('#item-2'), actions: [ { label: 'Skip', action: 'dismiss' }, { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Final Feature', description: 'This is the last step of the tour.', target: () => document.querySelector('#item-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const SkipTour = () => { const tour = useTour({ steps }) return (
Item 1
Item 2
Item 3
{(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: 'step-1', type: 'tooltip', title: 'First Feature', description: 'You can skip this tour at any time using the Skip button.', target: () => document.querySelector('#item-1'), actions: [ { label: 'Skip', action: 'dismiss' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-2', type: 'tooltip', title: 'Second Feature', description: 'Continue or skip to end the tour early.', target: () => document.querySelector('#item-2'), actions: [ { label: 'Skip', action: 'dismiss' }, { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Final Feature', description: 'This is the last step of the tour.', target: () => document.querySelector('#item-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const SkipTour = () => { const tour = useTour({ steps }) return (
Item 1
Item 2
Item 3
{(actions) => ( {(action) => } )}
) } ``` #### Vue ```vue ``` #### Svelte ```svelte
Item 1
Item 2
Item 3
{#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
``` ### Keyboard Navigation Enable arrow key navigation between tour steps using the `keyboardNavigation` prop. **Example: keyboard-navigation** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { KeyboardIcon, SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'Keyboard Navigation', description: 'Press the right arrow key (→) to go to the next step.', target: () => document.querySelector('#key-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Go Back', description: 'Press the left arrow key (←) to go back.', target: () => document.querySelector('#key-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Close Tour', description: 'Press Escape to close the tour at any time.', target: () => document.querySelector('#key-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const KeyboardNavigation = () => { const tour = useTour({ steps, keyboardNavigation: true }) return (

Use arrow keys to navigate, Escape to close

Step 1
Step 2
Step 3
{(actions) => actions.map((action) => ( )) }
) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { KeyboardIcon, 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: 'step-1', type: 'tooltip', title: 'Keyboard Navigation', description: 'Press the right arrow key to go to the next step.', target: () => document.querySelector('#key-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Go Back', description: 'Press the left arrow key to go back.', target: () => document.querySelector('#key-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Close Tour', description: 'Press Escape to close the tour at any time.', target: () => document.querySelector('#key-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const KeyboardNavigation = () => { const tour = useTour({ steps, keyboardNavigation: true }) return (

Use arrow keys to navigate, Escape to close

Step 1
Step 2
Step 3
{(actions) => ( {(action) => } )}
) } ``` #### Vue ```vue ``` #### Svelte ```svelte

Use arrow keys to navigate, Escape to close

Step 1
Step 2
Step 3
{#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
``` ### Events Listen to tour lifecycle events like `onStepChange` and `onStatusChange` to track user progress. **Example: events** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { 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: 'step-1', type: 'tooltip', title: 'First Step', description: 'Watch the event log below as you navigate.', target: () => document.querySelector('#event-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Second Step', description: 'Each step change triggers an event.', target: () => document.querySelector('#event-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Final Step', description: 'Complete the tour to see the status change.', target: () => document.querySelector('#event-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const Events = () => { const [logs, setLogs] = useState([]) const addLog = (message: string) => { setLogs((prev) => [...prev, message]) } const tour = useTour({ steps, onStepChange(details) { addLog(`Step changed: ${details.stepId}`) }, onStatusChange(details) { addLog(`Status: ${details.status}`) }, }) return (
Step 1
Step 2
Step 3
Event Log: {logs.length === 0 ? (
Start the tour to see events
) : ( logs.map((log, i) => (
{log}
)) )}
{(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, Show, createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'First Step', description: 'Watch the event log below as you navigate.', target: () => document.querySelector('#event-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Second Step', description: 'Each step change triggers an event.', target: () => document.querySelector('#event-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Final Step', description: 'Complete the tour to see the status change.', target: () => document.querySelector('#event-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const Events = () => { const [logs, setLogs] = createSignal([]) const addLog = (message: string) => { setLogs((prev) => [...prev, message]) } const tour = useTour({ steps, onStepChange(details) { addLog(`Step changed: ${details.stepId}`) }, onStatusChange(details) { addLog(`Status: ${details.status}`) }, }) return (
Step 1
Step 2
Step 3
Event Log: 0} fallback={
Start the tour to see events
}> {(log) =>
{log}
}
{(actions) => ( {(action) => } )}
) } ``` #### Vue ```vue ``` #### Svelte ```svelte
Step 1
Step 2
Step 3
Event Log: {#if logs.length === 0}
Start the tour to see events
{:else} {#each logs as log, i (i)}
{log}
{/each} {/if}
{#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 ``` #### 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 ``` #### 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 |