Tour
Install: npm install @mantine/core@9.7.1 @mantine/hooks@9.7.1
Version and compatibility
Pinned Mantine Core 9.7.1 requires React and React DOM ^19.2.0 and matching @mantine/hooks@9.7.1, from the installed npm package's peerDependencies. Do not force it into React 18 or another incompatible version. Explain upgrade impact and agree on a plan with the project owner; do not hide conflicts with --force/--legacy-peer-deps. The native Provider enables theme.respectReducedMotion and uses forceColorScheme for light/dark.
Use case
Guide a user through referenced page targets.
Native props used by this example
These props are extracted from the local typechecked JSX and grouped by their owning native component. This is not an exhaustive prop list; see pinned source signatures and inheritance below.
| Component prop | Explanation |
|---|---|
Button.id | Local DOM identity/marker, not a native business capability. |
Button.onClick | Local click handler; replace demo logic with an explicit business action. |
Tour.active | Active state/index, according to this component's type. |
Tour.onClose | Request to close; update the host's open state. |
Tour.Step.target | Target DOM reference or selector required by this component. |
Tour.Step.title | Heading content for this component. |
Interaction and state checks
Current scenarios: Default. Check actual behavior after selecting supported disabled/error/read-only scenarios; components without those native states do not receive invented universal props. Verify keyboard focus and exits, then connect changed values through the native callback signature.
Business integration boundary
Targets must exist in the same document and have unique selectors. Steps are guidance, not automated completion of the target action.
Host setup
Install pinned @mantine/core and @mantine/hooks, import @mantine/core/styles.css at the entry and use MantineProvider. The example's theme/variant are JGuang-authored host props, not universal native component APIs; forceColorScheme synchronizes the app theme. Native implementation source is a reading reference: use npm exports rather than copying internal engines. This batch covers Core, not dates/charts/forms extension packages. Detailed upstream prose remains English.
Runnable usage
import { useState } from 'react';
import * as M from '@mantine/core';
import '@mantine/core/styles.css';
function ComponentPreview({ variant = 'Default' }: { variant?: string }) {
const [open, setOpen] = useState(false);
return <><M.Button id="tour-target" onClick={() => setOpen(true)}>Start tour</M.Button><M.Tour active={open} onClose={() => setOpen(false)}><M.Tour.Step target="#tour-target" title="Welcome">This is the start button</M.Tour.Step></M.Tour></>;
}
export default function Example({ variant = 'Default', theme = 'light' }: { variant?: string; theme?: 'light' | 'dark' }) {
return <M.MantineProvider forceColorScheme={theme} theme={{ respectReducedMotion: true }}><ComponentPreview variant={variant} /></M.MantineProvider>;
}
Preview states
Default
The example uses the native Mantine API. For supported input demos, change the local variant to Disabled, Invalid or Read only; these are example labels, not new component props. Keep the documented data, controlled values, stores and compound children when adapting the example.
Usage
Tour is a step-by-step guide for application onboarding. It highlights target elements
one by one and displays a tooltip with navigation controls next to each of them.
Tour.Step components must be direct children of Tour.
Complex example
A dashboard onboarding tour: it starts with a centered welcome step, scrolls to targets
inside ScrollArea and changes position and spotlightPadding of individual steps.
Beacon mode
Set mode="beacon" to display pulsing beacons next to all targets instead of a sequential
walkthrough. Users can click beacons in any order to open tooltips. Beacons stay on the page
until active is set to false.
Controlled
Use step and onStepChange props to control the current step. An uncontrolled tour
always starts from defaultStep.
Overlay configuration
withOverlay– display the backdrop overlay,trueby defaultwithOverlayInteraction– allow users to interact with the highlighted element,falseby defaultcloseOnOverlayClick– close the tour when the overlay is clicked,falseby default
Dropdowns rendered in a portal (Select, Menu, etc.) are displayed below the tour.
To use them with withOverlayInteraction, set their zIndex to a value greater than
the tour zIndex, for example comboboxProps={{ zIndex: 10001 }}.
Step targets
target prop of Tour.Step accepts a CSS selector or a ref. Use a selector for elements
that are mounted after the step is activated, a ref must point to an element that is already mounted.
Steps without target
Steps without target are displayed in the center of the screen. Use them for welcome
and completion screens.
Custom content
Tour.Step children can be any React node. To build the tooltip layout yourself,
use compound components. Compound components do not know your steps:
- Pass the total number of steps to
Tour.RootwithstepsCountprop - Find target elements yourself and pass them to
Tour.Overlay(targetRect) andTour.Tooltip(targetElement) - Set a distinct
aria-labelon eachTour.Beacon - To play the exit transition, set
mounted={false}onTour.Tooltipfirst andactive={false}onTour.Rootafter the transition ends
Tooltip position
Set position on Tour.Step to change the tooltip placement. If there is not enough
space, the tooltip flips to the opposite side.
Custom labels
Use labels prop to translate navigation buttons:
Styles API
Keyboard navigation
Arrow keys are ignored while focus is inside the target element or an input.
Set withKeyboardNavigation={false} to disable them.
Accessibility
- The tooltip has
role="dialog", it is labelled by the step title and described by the step body - Focus is moved to the tooltip when it opens and is returned to the previously focused element when the tour closes
- Focus is trapped inside the tooltip while the overlay is displayed
- Step counter changes are announced with
aria-live="polite" - Beacons are buttons labelled with
labels.beaconand the step title, for exampleStart tour: Settings
Source-backed parameter reference
Implementation signatures and types are generated from the pinned local source. Optional props, native inherited types, union branches and never exclusions are preserved. A forwardRef implementation's ref is a React reference, not an additional business prop.
Tour(_props)
export type TourStylesNames =
| 'root'
| 'overlay'
| 'spotlight'
| 'tooltip'
| 'title'
| 'body'
| 'navigation'
| 'closeButton'
| 'stepCounter'
| 'beacon'
| 'beaconPulse'
| 'navigationButton';
export type TourCssVariables = {
root:
| '--tour-z-index'
| '--tour-overlay-color'
| '--tour-tooltip-radius'
| '--tour-tooltip-shadow'
| '--tour-beacon-size'
| '--tour-beacon-color'
| '--tour-color';
};
export interface TourProps extends BoxProps, StylesApiProps<TourFactory>, ElementProps<'div'> {
/** Whether the tour is active @default false */
active?: boolean;
/** Called when the tour is closed */
onClose?: () => void;
/** Controlled current step index */
step?: number;
/** Uncontrolled default step index @default 0 */
defaultStep?: number;
/** Called when step changes */
onStepChange?: (step: number) => void;
/** Called when a step opens */
onStepOpen?: (step: number) => void;
/** Called when a step closes */
onStepClose?: (step: number) => void;
/** Tour mode @default "guided" */
mode?: 'guided' | 'beacon';
/** Whether to display the overlay @default true */
withOverlay?: boolean;
/** Whether pointer events pass through the spotlight cutout to the target element, the rest of the overlay keeps blocking clicks @default false */
withOverlayInteraction?: boolean;
/** Whether to display the close button @default true */
withCloseButton?: boolean;
/** Whether keyboard navigation is enabled in guided mode @default true */
withKeyboardNavigation?: boolean;
/** Whether to scroll target elements into view @default true */
withScrollIntoView?: boolean;
/** Custom scroll handler */
scrollToHandler?: (element: HTMLElement) => void;
/** Padding around the spotlight cutout in px @default 8 */
spotlightPadding?: number;
/** Border radius of the spotlight cutout in px @default 4 */
spotlightRadius?: number;
/** Whether pressing Escape closes the tour @default true */
closeOnEscape?: boolean;
/** Whether clicking the overlay closes the tour, with `withOverlayInteraction` only clicks outside the spotlight cutout close it @default false */
closeOnOverlayClick?: boolean;
/** Labels for tour UI elements */
labels?: Partial<TourLabels>;
/** Whether to render inside a portal @default true */
withinPortal?: boolean;
/** Props passed to the Portal component */
portalProps?: Omit<PortalProps, 'children'>;
/** z-index of the tour @default 10000 */
zIndex?: string | number;
/** Transition props for the tooltip @default { duration: 200, transition: 'pop' } */
transitionProps?: TransitionOverride;
/** Duration of the tooltip position transition between steps in ms @default 300 */
stepTransitionDuration?: number;
/** Max width of the tooltip, tooltip always takes this width if viewport allows @default 360 */
maxWidth?: number;
/** Tour step overlay color @default "rgba(0, 0, 0, 0.5)" */
overlayColor?: string;
/** Key of `theme.colors` or any valid CSS color, controls beacon color and `Tour.Navigation` next button color @default theme.primaryColor */
color?: MantineColor;
/** Key of `theme.shadows` or any valid CSS box-shadow value, controls the tooltip shadow @default 'md' */
tooltipShadow?: string;
/** Tour steps – `Tour.Step` elements must be direct children (arrays are supported, Fragments and wrapper components are not) */
children?: React.ReactNode;
}
export type TourFactory = Factory<{
props: TourProps;
ref: HTMLDivElement;
stylesNames: TourStylesNames;
vars: TourCssVariables;
staticComponents: {
Root: typeof TourRoot;
Step: typeof TourStep;
Overlay: typeof TourOverlay;
Tooltip: typeof TourTooltip;
Title: typeof TourTitle;
Body: typeof TourBody;
Navigation: typeof TourNavigation;
Beacon: typeof TourBeacon;
CloseButton: typeof TourCloseButton;
};
}>;
export type Mod = Record<string, any> | string;
export type BoxMod = Mod | Mod[] | BoxMod[];
export interface BoxProps extends MantineStyleProps {
/** Class added to the root element, if applicable */
className?: string | undefined;
/** Inline style added to root component element, can subscribe to theme defined on MantineProvider */
style?: MantineStyleProp;
/** CSS variables defined on root component element */
__vars?: CssVarsProp;
/** `size` property passed down the HTML element */
__size?: string;
/** Breakpoint above which the component is hidden with `display: none` */
hiddenFrom?: MantineBreakpoint;
/** Breakpoint below which the component is hidden with `display: none` */
visibleFrom?: MantineBreakpoint;
/** Determines whether component should be hidden in light color scheme with `display: none` */
lightHidden?: boolean;
/** Determines whether component should be hidden in dark color scheme with `display: none` */
darkHidden?: boolean;
/** Element modifiers transformed into `data-` attributes, for example, `{ 'data-size': 'xl' }`, falsy values are removed */
mod?: BoxMod;
}
export type ElementProps<
ElementType extends React.ElementType,
PropsToOmit extends string = never,
> = Omit<React.ComponentProps<ElementType>, 'style' | PropsToOmit>;
export interface CSSProperties extends React.CSSProperties {
[key: string]: any;
}
type MantineStyle = CSSProperties | ((theme: MantineTheme) => CSSProperties);
export type MantineStyleProp = MantineStyle | MantineStyle[] | MantineStyleProp[] | undefined;
export type CssVariable = `--${string}`;
export type CssVariables<Variable extends string = CssVariable> = Partial<Record<Variable, string>>;
export type CssVars<Variable extends string = CssVariable> =
| CssVariables<Variable>
| ((theme: MantineTheme) => CssVariables<Variable>)
| CssVars<Variable>[];
export type CssVarsProp<Variable extends string = CssVariable> =
| CssVars<Variable>
| CssVars<Variable>[];
Native and external types
External types remain defined by React or native dependencies, not manually expanded into guessed props. The installed version's TypeScript definitions are authoritative.
Factory<{
props: TourProps;
ref: HTMLDivElement;
stylesNames: TourStylesNames;
vars: TourCssVariables;
staticComponents: {
Root: typeof TourRoot;
Step: typeof TourStep;
Overlay: typeof TourOverlay;
Tooltip: typeof TourTooltip;
Title: typeof TourTitle;
Body: typeof TourBody;
Navigation: typeof TourNavigation;
Beacon: typeof TourBeacon;
CloseButton: typeof TourCloseButton;
};
}>
MantineStyleProps
React.CSSProperties
MantineTheme
Partial<Record<Variable, string>>
Record<Variable, string>
Variable
MantineBreakpoint
Record<string, any>
StylesApiProps<TourFactory>
React.ElementType
Omit<React.ComponentProps<ElementType>, 'style' | PropsToOmit>
React.ComponentProps<ElementType>
ElementType
PropsToOmit
HTMLElement
Partial<TourLabels>
TourLabels
Omit<PortalProps, 'children'>
PortalProps
TransitionOverride
MantineColor
React.ReactNode
HTMLDivElement