# 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**
```ripple
import { Tour, useTour } from 'ark-ripple/tour';
import { Portal } from 'ark-ripple/portal';
import { Ellipsis, Save, Sparkles, Upload, X } from 'lucide-ripple';
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 component Basic() {
const tour = useTour({ steps });
component children({ actions }) {
for (const action of @actions; key action.label) {
}
}
}
```
### 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**
```ripple
import { Tour, useTour } from 'ark-ripple/tour';
import { Portal } from 'ark-ripple/portal';
import { Sparkles, X } from 'lucide-ripple';
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 component MixedTypes() {
const tour = useTour({ steps });
{'Target Element'}
component children({ actions }) {
for (const action of @actions; key action.label) {
}
}
}
```
### Progress
Display a visual progress indicator at the bottom of the tour content showing how far along the user is.
**Example: progress-bar**
```ripple
import { Tour, useTour } from 'ark-ripple/tour';
import { Portal } from 'ark-ripple/portal';
import { Sparkles, X } from 'lucide-ripple';
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 component ProgressBar() {
const tour = useTour({ steps });
{'Step 1'}
{'Step 2'}
{'Step 3'}
{'Step 4'}
component children({ actions }) {
for (const action of @actions; key action.label) {
}
}
}
```
### Skip
Allow users to skip the entire tour at any step by adding a skip action.
**Example: skip-tour**
```ripple
import { Tour, useTour } from 'ark-ripple/tour';
import { Portal } from 'ark-ripple/portal';
import { Sparkles, X } from 'lucide-ripple';
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 component SkipTour() {
const tour = useTour({ steps });
{'Item 1'}
{'Item 2'}
{'Item 3'}
component children({ actions }) {
for (const action of @actions; key action.label) {
}
}
}
```
### Keyboard Navigation
Enable arrow key navigation between tour steps using the `keyboardNavigation` prop.
**Example: keyboard-navigation**
```ripple
import { Tour, useTour } from 'ark-ripple/tour';
import { Portal } from 'ark-ripple/portal';
import { Keyboard, Sparkles, X } from 'lucide-ripple';
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 component KeyboardNavigation() {
const tour = useTour({ steps, keyboardNavigation: true });
{'Use arrow keys to navigate, Escape to close'}
{'Step 1'}
{'Step 2'}
{'Step 3'}
component children({ actions }) {
for (const action of actions; key action.label) {
}
}
}
```
### Events
Listen to tour lifecycle events like `onStepChange` and `onStatusChange` to track user progress.
**Example: events**
```ripple
import { Tour, useTour } from 'ark-ripple/tour';
import { Portal } from 'ark-ripple/portal';
import { track } from 'ripple';
import { Sparkles, X } from 'lucide-ripple';
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 component Events() {
let logs = track([]);
const tour = useTour(
{
steps,
onStepChange(details) {
@logs = [...@logs, `Step changed: ${details.stepId}`];
},
onStatusChange(details) {
@logs = [...@logs, `Status: ${details.status}`];
},
},
);
{'Step 1'}
{'Step 2'}
{'Step 3'}
{'Event Log:'}
if (@logs.length === 0) {
{'Start the tour to see events'}
} else {
for (const log of @logs; key log) {
{log}
}
}
component children({ actions }) {
for (const action of @actions; key action.label) {
}
}
}
```
### Wait for Click
Use the `effect` function with `waitForEvent` to wait for user interaction before proceeding to the next step.
**Example: wait-for-click**
```ripple
import { Tour, useTour, waitForEvent } from 'ark-ripple/tour';
import { Portal } from 'ark-ripple/portal';
import { Sparkles, X } from 'lucide-ripple';
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 component WaitForClick() {
const tour = useTour({ steps });
component children({ actions }) {
for (const action of @actions; key action.label) {
}
}
}
```
### 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()`.
**Example: async-step**
```ripple
import { Tour, useTour } from 'ark-ripple/tour';
import { Portal } from 'ark-ripple/portal';
import { Sparkles, X } from 'lucide-ripple';
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 component AsyncStep() {
const tour = useTour({ steps });
{'User Profile Card'}
component children({ actions }) {
for (const action of @actions; key action.label) {
}
}
}
```
## 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**
**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 |
### 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 |