Components
Tour

Tour

A guided tour that helps users understand the interface.

Loading...

Anatomy

const tour = useTour({ steps: [...] })

<Tour.Root tour={tour}>
  <Tour.Backdrop />
  <Tour.Spotlight />
  <Tour.Positioner>
    <Tour.Content>
      <Tour.Arrow>
        <Tour.ArrowTip />
      </Tour.Arrow>
      <Tour.Title />
      <Tour.Description />
      <Tour.ProgressText />
      <Tour.CloseTrigger />
      <Tour.Actions>
        <Tour.ActionTrigger />
      </Tour.Actions>
    </Tour.Content>
  </Tour.Positioner>
</Tour.Root>

Examples

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.

Progress

Display a visual progress indicator at the bottom of the tour content showing how far along the user is.

Skip

Allow users to skip the entire tour at any step by adding a skip action.

Keyboard Navigation

Enable arrow key navigation between tour steps using the keyboardNavigation prop.

Events

Listen to tour lifecycle events like onStepChange and onStatusChange to track user progress.

Wait for Click

Use the effect function with waitForEvent to wait for user interaction before proceeding to the next step.

Wait for Input

Create form tutorials that wait for users to enter valid input before advancing.

Wait for Element

Wait for dynamically rendered elements to appear in the DOM before showing a step.

Async

Load data asynchronously and update step content before displaying it using the effect function with show() and update().

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.

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.

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.

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.

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.

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).
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.

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.

* {
  box-sizing: border-box;
}

Ensure the body has a position of relative.

body {
  position: relative;
}

API Reference

Props

Root

PropDefaultType
tour
UseTourReturn

immediate
boolean

Whether to synchronize the present change immediately or defer it to the next frame

lazyMountfalse
boolean

Whether to enable lazy mounting

onExitComplete
VoidFunction

Function called when the animation ends in the closed state

present
boolean

Whether the node is present (controlled by the user)

skipAnimationOnMountfalse
boolean

Whether to allow the initial presence animation.

unmountOnExitfalse
boolean

Whether to unmount on exit.

ActionTrigger

Renders a <button> element.

PropDefaultType
action
StepAction

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
AttributeDescription
[data-scope]tour
[data-part]action-trigger
[data-type]The type of the item
[data-disabled]Present when disabled

Arrow

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
CSS VariableDescription
--arrow-sizeThe size of the arrow
--arrow-size-halfHalf the size of the arrow
--arrow-backgroundUse this variable to style the arrow background
--arrow-offsetThe offset position of the arrow

ArrowTip

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

Backdrop

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
AttributeDescription
[data-scope]tour
[data-part]backdrop
[data-state]"open" | "closed"
[data-type]The type of the item
CSS VariableDescription
--tour-layerThe tour layer value for the Backdrop
--layer-indexThe index of the dismissable in the layer stack

CloseTrigger

Renders a <button> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
AttributeDescription
[data-scope]tour
[data-part]close-trigger
[data-type]The type of the item

Content

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
AttributeDescription
[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]
CSS VariableDescription
--layer-indexThe index of the dismissable in the layer stack
--nested-layer-countThe number of nested tours

Control

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

Description

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
AttributeDescription
[data-scope]tour
[data-part]description
[data-placement]The placement of the description

Positioner

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
AttributeDescription
[data-scope]tour
[data-part]positioner
[data-type]The type of the item
[data-placement]The placement of the positioner
CSS VariableDescription
--tour-layerThe tour layer value for the Positioner
--reference-widthThe width of the reference element
--reference-heightThe height of the root
--available-widthThe available width in viewport
--available-heightThe available height in viewport
--xThe x position for transform
--yThe y position for transform
--z-indexThe z-index value
--transform-originThe transform origin for animations

ProgressText

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

Spotlight

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
CSS VariableDescription
--tour-layerThe tour layer value for the Spotlight

Title

Renders a <h2> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
AttributeDescription
[data-scope]tour
[data-part]title
[data-placement]The placement of the title

Context

API

PropertyType
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<StepDetails>) => 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