@gfazioli/mantine-onboarding-tour
A Mantine component enables you to create a onboarding-tour effect using overlays, popovers, and onboarding tours, which enhances element visibility and interactivity.
Migrating from v2 to v3
Breaking changes
1. onOnboardingTourClose has been removed
Replace it with onOnboardingTourComplete, onOnboardingTourSkip, or onOnboardingTourEnd:
If you don't need to distinguish between completion and skip, use onOnboardingTourEnd alone — it fires in both cases.
2. responsive, mobileBreakpoint, and mobilePosition have been removed
The popover is now always responsive. Use responsive objects on popoverProps instead:
Per-step responsive positioning via focusRevealProps:
3. useOnboardingTour hook has been removed from the public API
This hook was internal and created isolated state disconnected from the <OnboardingTour> component. All tour control is available through props and render functions:
4. OnboardingTourStep now requires a generic for custom properties
5. popoverProps type changed to ResponsivePopoverProps
The position, offset, width, and arrowSize properties now accept ResponsiveProp<T> (a scalar or a breakpoint-to-value object). All other PopoverProps work as before.
Installation
After installation import package styles at the root of your application:
You can import styles within a layer @layer mantine-onboarding-tour by importing @gfazioli/mantine-onboarding-tour/styles.layer.css file.
Example
Here is a full page example of an Onboarding Tour.
Open Onboarding Tour example page
Usage
The OnboardingTour component allows to create onboarding experiences for your users.
A simple example of the Onboarding Tour component
👉 New amazing Mantine extension component
John Doe
Scroll the page 👆up or 👇down to remove the focus from the card. In practice, make this component invisible so that the onBlur event will be triggered.
Jane Doe
Scroll the page 👆up or 👇down to remove the focus from the card. In practice, make this component invisible so that the onBlur event will be triggered.
OnboardingTourStep
The OnboardingTourStep interface defines the structure of each step in the tour.
The type is generic: custom properties are type-safe via the T parameter (e.g., OnboardingTourStep<{ price: number }>). See the Custom entry section for an example.
Both header, title, content, and footer can be a string, a React component, or a function that receives tourController and returns a React component.
You can use the OnboardingTourController to access the current step and its properties, such as currentStep.id, currentStep.title, and so on.
You may also set up the focusRevealProps to customize the OnboardingTour.FocusReveal component for each step. This allows you to control the focus and reveal behavior of the tour step.
In this case, focusRevealProps can be either an object of type OnboardingTourFocusRevealProps or a function that receives tourController and returns an object of type OnboardingTourFocusRevealProps.
OnboardingTourController
The OnboardingTourController interface provides the current state of the tour. It also provides a series of actions to interact with the tour, such as the action to go to the next step nextStep() or to end the tour endTour().
Tour Lifecycle Callbacks
The OnboardingTour component provides callbacks to distinguish between different tour endings:
| Callback | When it fires |
|---|---|
onOnboardingTourStart | The tour starts |
onOnboardingTourChange | The active step changes |
onOnboardingTourComplete | The user finishes the last step (clicks "End") |
onOnboardingTourSkip | The user clicks the "Skip" button |
onOnboardingTourEnd | Always fires when the tour ends, whether completed or skipped |
Use onOnboardingTourEnd if you don't need to distinguish between completion and skip. Use onOnboardingTourComplete and onOnboardingTourSkip when you need different behavior (e.g., saving progress, showing a different message).
Define the onboarding tour
You can define your onboarding tour by using the OnboardingTourStep array.
You may also handle the header, title, content, and footer by using the OnBoardingTour component props. In this case the OnboardingTourStep will be ignored.
Anyway, the OnboardingTourStep are always available in the OnboardingTourController and you can use them to display any variant. Fo example,
Custom entry
You may use any custom entry in the OnboardingTourStep list to customize the tour. For example, here we're going to display some extra information in the footer, by using a custom property price:
Then we can use the footer prop to display the price:
Custom Popover Content
You may use the controller to override the default behavior of the tour or to add custom logic to the tour. For example, you could replace the default Popover content with a custom one:
Custom Stepper
The stepper prop allows you to customize the stepper of the tour. For example, you could use it to display a progress bar or a custom list of steps. Currently, the OnboardingTour component use the Mantine Stepper component. You can use the stepperProps and stepperStepProps props to customize the stepper. Of course, you can build your own using the stepper prop.
OnboardingTour.Target
You have to use the OnboardingTour.Target when your tour component are not visible as children of the OnboardingTour component.
For example, here is an example of a tour component that is not a child of the OnboardingTour component.
The above example won't work because we can't get the data-onboarding-tour-id attribute of the AnotherComponent component.
In this case you have to use the OnboardingTour.Target component to make it work. In short, instead of using the data-onboarding-tour-id attribute of the component, you have to wrap your component with OnboardingTour.Target.
You may also set up the focusRevealProps to customize the OnboardingTour.FocusReveal component for each target. This allows you to control the focus and reveal behavior of the tour step.
In this case, focusRevealProps can be either an object of type OnboardingTourFocusRevealProps or a function that receives tourController and returns an object of type OnboardingTourFocusRevealProps.
OnboardingTour.FocusReveal
The OnboardingTour.FocusReveal component allows highlighting and making any component on your page more visible. The highlighting process can be controlled by three main properties:
withOverlay: displays a dark overlay across the entire page except for the highlighted componentwithReveal: scrolls the page to make the component to be highlighted visiblefocusEffect: applies a series of predefined effects when the component is highlighted
Naturally, we have the focused prop that controls when the component should be highlighted.
Note: In all examples, we use the
onBlurevent to remove focus from the component for demonstration purposes. In a real-world scenario, you might also use thefocusedprop to control the focus state.
A simple example of the Focus Reveal component
👉 Scroll up the page to remove the focus
John Doe
Scroll the page 👆up or 👇down to remove the focus from the card. In practice, make this component invisible so that the onBlur event will be triggered.
Jane Doe
Scroll the page 👆up or 👇down to remove the focus from the card. In practice, make this component invisible so that the onBlur event will be triggered.
Uncontrolled Mode
The OnboardingTour.FocusReveal component can also be used in an uncontrolled mode. In this mode, the component will automatically highlight the children.
Simple (uncontrolled) Example
The defaultFocused props is set to true, card below is focused by default
👇
Scroll down
John Doe
Scroll the page 👆up or 👇down to remove the focus from the card. In practice, make this component invisible so that the onBlur event will be triggered.
Disable target interaction
When the target is focused, you can prevent mouse/keyboard interaction with the highlighted element by setting disableTargetInteraction. This is useful when you want users to read the popover content and navigate the tour without interacting with the underlying component.
Disable target interactions
Jane Doe
Scroll the page 👆up or 👇down to remove the focus from the card. In practice, make this component invisible so that the onBlur event will be triggered.
Interaction disabled while focused: pointer events are blocked.
OnboardingTour.FocusReveal.Group
If you want to highlight multiple components, you can use the OnboardingTour.FocusReveal.Group component. This component allows you to highlight multiple components at the same time.
This also allows for controlling multiple OnboardingTour.FocusReveal components simultaneously, setting some common properties for all the components.
Note: The
OnboardingTour.FocusReveal.Groupcomponent does not have thefocusedprop. Instead, use thefocusedprop in theOnboardingTour.FocusRevealcomponent. In addition, thewithRevealprop is set tofalseby default. ThedefaultFocusedprop is set totrueby default.
Group Example
The defaultFocused props is set to true, card below is focused by default
👇
Scroll down
John Doe
Scroll the page 👆up or 👇down to remove the focus from the card. In practice, make this component invisible so that the onBlur event will be triggered.
Jane Doe
Scroll the page 👆up or 👇down to remove the focus from the card. In practice, make this component invisible so that the onBlur event will be triggered.
Jessica Doe
Scroll the page 👆up or 👇down to remove the focus from the card. In practice, make this component invisible so that the onBlur event will be triggered.
Below another example of using the OnboardingTour.FocusReveal.Group component.
Group Example
The defaultFocused props is set to true, card below is focused by default
👇
Scroll down
John Doe
Scroll the page 👆up or 👇down to remove the focus from the card. In practice, make this component invisible so that the onBlur event will be triggered.
Jane Doe
Scroll the page 👆up or 👇down to remove the focus from the card. In practice, make this component invisible so that the onBlur event will be triggered.
Jessica Doe
Scroll the page 👆up or 👇down to remove the focus from the card. In practice, make this component invisible so that the onBlur event will be triggered.
withReveal
The withReveal props scrolls the page to make the component to be highlighted visible. This is useful when the component is not visible on the screen. Internally, the component uses the scrollIntoView method to make the component visible, from the Mantine useScrollIntoView() hook.
Of course, you can customize the scroll behavior by using the revealProps prop. This prop accepts the same properties as the useScrollIntoView() method.
Custom Reveal Props Example
Jane Doe
Scroll the page 👆up or 👇down to remove the focus from the card. In practice, make this component invisible so that the onBlur event will be triggered.
Note: The
onScrollFinishcallback is not available in therevealsPropsprop. Instead, use theonRevealFinishprop.
withOverlay
The withOverlay prop displays a dark overlay across the entire page except for the highlighted component. This is useful when you want to focus the user's attention on a specific component. The overlay is customizable by using the overlayProps prop.
Overlay Example
Jane Doe
Scroll the page 👆up or 👇down to remove the focus from the card. In practice, make this component invisible so that the onBlur event will be triggered.
scrollableRef
The scrollableRef prop allows you to specify a custom scrollable element. This is useful when the component to be highlighted is inside a scrollable container. The scrollableRef prop accepts a React.RefObject<HTMLElement>.
With simple Paper container
Paper container Example
John Doe
Scroll the page 👆up or 👇down to remove the focus from the card. In practice, make this component invisible so that the onBlur event will be triggered.
Below, by using the ScrollArea component, we can create a scrollable container.
ScrollArea
Custom Focus Mode
The OnboardingTour.FocusReveal component allows you to create a custom focus mode. This is useful when you want to create a custom focus effect.
Custom Focused Mode Example
Jane Doe
Scroll the page 👆up or 👇down to remove the focus from the card. In practice, make this component invisible so that the onBlur event will be triggered.
With Popover
In addition to focus and reveal, you can add a Popover display when the element gains focus by using the popoverContent prop.
Popover example
John Doe
Scroll the page 👆up or 👇down to remove the focus from the card. In practice, make this component invisible so that the onBlur event will be triggered.
You can use the popoverProps prop (are the same as the Mantine Popover component. You can find the documentation here) to manipulate the Mantine Popover component.
Popover example
John Doe
Scroll the page 👆up or 👇down to remove the focus from the card. In practice, make this component invisible so that the onBlur event will be triggered.
Example: Cycle
Here are some examples of how to use the OnboardingTour.FocusReveal component in different scenarios.
Cycle Example
Use the arrow keys to cycle through the testimonials
John Doe
Scroll the page 👆up or 👇down to remove the focus from the card. In practice, make this component invisible so that the onBlur event will be triggered.
John Doe
Scroll the page 👆up or 👇down to remove the focus from the card. In practice, make this component invisible so that the onBlur event will be triggered.
John Doe
Scroll the page 👆up or 👇down to remove the focus from the card. In practice, make this component invisible so that the onBlur event will be triggered.
Example: Multiple Focus components
Multiple components Example
Use the arrow keys to cycle through the testimonials
John Doe
Scroll the page 👆up or 👇down to remove the focus from the card. In practice, make this component invisible so that the onBlur event will be triggered.
John Doe
Scroll the page 👆up or 👇down to remove the focus from the card. In practice, make this component invisible so that the onBlur event will be triggered.
John Doe
Scroll the page 👆up or 👇down to remove the focus from the card. In practice, make this component invisible so that the onBlur event will be triggered.
Responsive Behavior
The OnboardingTour component is responsive by default. Popover position, offset, width, and arrowSize accept responsive objects that map Mantine breakpoints to values, powered by useMatches() under the hood.
By default, the popover appears at the bottom on mobile (base) and on the left on larger screens (sm+):
Responsive Demo
Try the full-page responsive demo to see the behavior at different screen sizes:
Open Responsive Onboarding Tour example page
Responsive Props
The following popover props accept responsive objects (ResponsiveProp<T>):
position:FloatingPosition | { base: 'bottom', sm: 'left', lg: 'top' }offset:number | { base: 8, sm: -4 }width:PopoverWidth | { base: 'target', sm: 300 }arrowSize:number | { base: 12, sm: 16 }
All other PopoverProps (e.g., withArrow, radius, shadow, middlewares) work as usual.
Per-Step Responsive Configuration
Each step can define its own responsive positioning via focusRevealProps:
Scroll Behavior
When a step activates, the target element is automatically scrolled into view and centered in the viewport. The Floating UI shift and flip middlewares then ensure the popover stays fully visible regardless of the resolved position.
Cutout Highlight
When the tour is active, a persistent overlay covers the page with a cutout hole around the focused element. By default the cutout has 8px padding and 8px border radius, but you can customize both values at the tour level and per step.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
cutoutPadding | number | 8 | Padding around the cutout highlight area (px) |
cutoutRadius | number | 8 | Border radius of the cutout. Use |
Both props can be set on <OnboardingTour> (tour-level default) and on individual OnboardingTourStep objects (per-step override). The resolution order is: step > tour > default (8).
Circular and custom cutouts
For circular elements like avatars or icon buttons, set cutoutRadius: 9999 on the step. For pill-shaped buttons, use a moderate radius like 24. Steps that don't specify these props inherit the tour-level values.
The avatar and settings icon use cutoutRadius: 9999 for a circular cutout. The notification icon uses the default rectangular cutout.