Tutorial
The Tutorial component provides a declarative way to build guided walkthroughs directly inside your UI.
Each Tutorial.Step wraps real elements, highlights them, and displays a tooltip with title and content, creating a structured onboarding or feature tour.
To use the Tutorial component, wrap your existing UI with it and wrap every element you wish to be part of the tutorial with the Tutorial.Step component and provide it with an order prop.
import Tutorial, {TutorialRef} from "@components/Complex/Tutorial/Tutorial";
const App = () => { let ref!: TutorialRef; return ( <> <button onclick={() => ref!.tour()}>Start tutorial?</button> <Tutorial ref={ref} outset={5} > <Tutorial.Step order={1} title="Welcome" content="This is the main menu."> <button>Play</button> </Tutorial.Step>
<Tutorial.Step order={2} title="Settings" content="Change your preferences here." position="bottom"> <button>Settings</button> </Tutorial.Step> </Tutorial> </> );};
export default App;Tutorial Props
Section titled “Tutorial Props”| Prop Name | Type | Default | Description |
|---|---|---|---|
style | JSX.CSSProperties | {} | Inline styles to apply directly to the radial menu’s root element. |
class | string | "" | Additional CSS classes to apply to the radial menu’s root element. |
ref | TutorialRef | undefined | undefined | A reference to the component, providing access to its methods and the underlying HTML element. |
outset | number | 0 | Extra offset (in px) applied between the tooltip/highlight and the target element. Useful when the target has shadows/borders or sits inside tight layouts. |
tooltip | TooltipType<T> | undefined | Custom tooltip component to render instead of the default one. Receives the provided tutorial props (title, content, step, controls). |
onChange | (step: number) => void | undefined | Fired whenever the active tutorial step changes. The callback receives the 1-based step index. |
Ref API
Section titled “Ref API”To interact with the Tutorial programmatically, you can use the TutorialRef interface.
This interface provides access to the component’s root element and exposes methods for controlling its state and selection.
Properties
Section titled “Properties”| Property | Type | Description |
|---|---|---|
element | HTMLDivElement | Root element of the tutorial wrapper. |
progress | Accessor<number> | Current progress in % (0-100). Use it to display custom progress UIs. |
current | Accessor<number> | Current active step (1-based). Returns 0 when the tutorial is not running. |
target | Accessor<HTMLElement | null> | The DOM element currently being highlighted. Useful if you need any specific information about the position or dimensions of the element |
Methods
Section titled “Methods”| Method | Parameters | Return value | Description |
|---|---|---|---|
tour | (step?: number) | void | Starts the tutorial. If a step is provided, starts from that step instead of the first one. |
exit | — | void | Stops the tutorial and clears the active step. |
next | — | void | Moves to the next step, if any. |
previous | — | void | Moves to the previous step, if any. |
pause | — | void | Pauses the tutorial. |
resume | (next?: boolean) | void | Resumes a paused tutorial. If next is true, it will advance to the next step on resume (useful for interactive steps). |
changeStep | (step: number) | void | Jumps directly to the provided step (1-based). Use this when the tutorial should react to external UI events. |
Slots/Components
Section titled “Slots/Components”The Tutorial component exposes:
- Tutorial.Step - defines one step of the tutorial and marks the wrapped UI as the current target.
- Custom Tooltip (via tooltip prop) - lets you fully replace the default tooltip UI.
Tutorial.Step
Section titled “Tutorial.Step”Wraps the element you want to highlight and registers it in the tutorial flow.
Simply wrap the target element with Tutorial.Step and provide the required order prop. Providing title and content will display them in the tooltip for this step.
<Tutorial> <Tutorial.Step order={1} title="Tabs" content="Use these to switch sections."> <Tabs /> </Tutorial.Step>
<Tutorial.Step order={2} title="Side Panel" content="Use it for additional information." position="right" outset={-5}> <SidePanel /> </Tutorial.Step></Tutorial>| Prop Name | Type | Default | Description |
|---|---|---|---|
order | number | — | Required. Controls the order in which the step is shown. |
title | string | undefined | "" | Tooltip title. If omitted, an empty string is used for the step. |
content | string | undefined | "" | Tooltip content. If omitted, an empty string is used for the step. |
outset | number | 0 | Per-step offset. Overrides the Tutorial’s outset for this step only. |
position | top | left | right | bottom | auto | Tooltip placement relative to the target. |
Custom Tooltip
Section titled “Custom Tooltip”You can replace the default tooltip by passing a tooltip prop to Tutorial.
This prop accepts a custom component or a function that returns JSX, allowing you to fully control the tooltip’s layout, animations, and controls.
Provided props
Section titled “Provided props”| Prop Name | Type | Description |
|---|---|---|
title | string | undefined | The current step’s title. Falls back to '' if omitted. |
content | string | JSX.Element | undefined | The tooltip’s main content. Falls back to '' if omitted. |
step | Accessor<number> | The current 1-based step index. |
progress | Accessor<number> | Current tutorial progress (0-100). Useful for showing a progress bar. |
Next | Component<ComponentProps> | Prebuilt “Next” button component. When clicked on the final step, it ends the tutorial. |
Prev | Component<ComponentProps> | Prebuilt “Previous” button component. Navigates back one step. |
To declare a custom tooltip, you need to follow these steps:
- Create a component typed as
TooltipType(you need to import the type) - Pass it to the
tooltipprop of theTutorialcomponent - Use the provided props (
title,content,step,progress,Next,Prev) to build your layout and behavior.
import Tutorial, {TutorialRef} from "@components/Complex/Tutorial/Tutorial";import { TooltipType } from "@components/Complex/Tutorial/TutorialTooltip";import Progress from "@components/Feedback/Progress/Progress";import Flex from "@components/Layout/Flex/Flex";
const MyTooltip: TooltipType = (props) => { return ( <div> <div>{props.title}</div> <div>{props.content}</div> <Progress.Bar progress={props.progress()} /> <Flex> <props.Prev>Previous</props.Prev> <props.Next>Next</props.Next> </Flex> </div> )}
const App = () => { let ref!: TutorialRef; return ( <Tutorial tooltip={MyTooltip}> <Tutorial.Step order={1} title="Tabs" content="Switch between sections here."> <Tabs /> </Tutorial.Step> </Tutorial> );};
export default App;Optionally, you can extend the TooltipType to pass additional custom props to your tooltip component.
interface CustomTooltipProps { customLabel: string;}
const MyTooltip: TooltipType<CustomTooltipProps> = (props) => { return ( <div> <div>{props.title}</div> <div>{props.content}</div> <Progress.Bar progress={props.progress()} /> <Flex> <props.Prev>Previous</props.Prev> <props.Next>Next</props.Next> </Flex> <div>{props.customLabel}</div> </div> )}
const App = () => { return ( <Tutorial tooltip={(props) => <MyTooltip {...props} customLabel="Custom label" />}> {/* ... */} </Tutorial> );};
export default App;Controlling the tutorial programmatically
Section titled “Controlling the tutorial programmatically”You can start, pause, stop, and navigate the tutorial using the TutorialRef methods.
Starting the tutorial
Section titled “Starting the tutorial”The tutorial can be started programmatically using the tour() method from the TutorialRef.
import Tutorial, {TutorialRef} from "@components/Complex/Tutorial/Tutorial";const App = () => { let ref!: TutorialRef;
return ( <> <button onclick={() => ref!.tour()}>Start tutorial?</button> <Tutorial ref={ref} > {/* Steps go here */} </Tutorial> </> );};Pausing and resuming the tutorial
Section titled “Pausing and resuming the tutorial”You can pause the tutorial at any time using the pause() method, and resume it later with the resume() method.
This behavior is useful for interactive steps where user input is required.
import Tutorial, {TutorialRef} from "@components/Complex/Tutorial/Tutorial";const App = () => { let ref!: TutorialRef;
const handleUserInteraction = () => { if (ref.current() === 0) return; // Tutorial not running
if (ref.current() === 3) { // pause on step 3 ref.pause();
// Do something...
setTimeout(() => { // Resume after 2 seconds ref.resume(); }, 2000); } };
return ( <> <div onclick={handleUserInteraction}> <Tutorial ref={ref} > {/* Steps go here */} </Tutorial> </div> </> );};Concluding the tutorial
Section titled “Concluding the tutorial”You can end the tutorial manually at any time using the exit() method from the TutorialRef.
import Tutorial, {TutorialRef} from "@components/Complex/Tutorial/Tutorial";const App = () => { let ref!: TutorialRef;
const handleUserInteraction = () => { if (ref.current() === 0) return; // Tutorial not running
if (ref.current() === 3 && someCondition) { ref.end(); } };
return ( <> <div onclick={handleUserInteraction}> <Tutorial ref={ref} > {/* Steps go here */} </Tutorial> </div> </> );};Reacting to step changes
Section titled “Reacting to step changes”You can use the onChange prop to react to step changes in the tutorial. This is useful if additional logic is needed between certain steps.
import Tutorial, {TutorialRef} from "@components/Complex/Tutorial/Tutorial";const App = () => { let ref!: TutorialRef;
const handleStepChange = (step: number) => { if (step === 2) { console.log("User reached step 2, showing modal..."); // Show a modal or perform other actions }
if (step === 4) { ref.pause(); console.log("Tutorial paused at step 4 for user interaction."); } };
return ( <> <Tutorial onChange={handleStepChange} ref={ref} > {/* Steps go here */} </Tutorial> </> );};Per step customization
Section titled “Per step customization”You can customize individual steps of the tutorial by using the outset and position props on the Tutorial.Step component. This allows for fine-tuning the tooltip’s placement and offset for specific steps.
import Tutorial, {TutorialRef} from "@components/Complex/Tutorial/Tutorial";
const App = () => { let ref!: TutorialRef; return ( <> <Tutorial ref={ref} outset={5} > <Tutorial.Step order={1} outset={10} position='top' title="Welcome" content="This is the main menu." > <button>Play</button> </Tutorial.Step>
<Tutorial.Step order={2} outset={-5} position='right' title="Settings" content="Change your preferences here." > <button>Settings</button> </Tutorial.Step> </Tutorial> </> );};
export default App;Customizing your tooltip’s behavior (Examples)
Section titled “Customizing your tooltip’s behavior (Examples)”You can replace the default tooltip by passing a tooltip prop to Tutorial. The component you provide will receive several props to help you build your custom layout and behavior.
Manually placing the tooltip for specific steps
Section titled “Manually placing the tooltip for specific steps”Sometimes, you may want to adjust the tooltip’s position for a particular step. You can do this by checking the current step and applying classes or inline styles that offset the tooltip as needed.
4 collapsed lines
import Tutorial, {TutorialRef} from "@components/Complex/Tutorial/Tutorial";import { TooltipType } from "@components/Complex/Tutorial/TutorialTooltip";import Flex from "@components/Layout/Flex/Flex";
const MyTooltip: TooltipType = (props) => { return ( <div style={props.step() === 2 ? {position: 'relative', top: '10%'} : {}}> <div>{props.title}</div> <div>{props.content}</div> <Flex> <props.Prev>Previous</props.Prev> <props.Next>Next</props.Next> </Flex> </div>12 collapsed lines
)}
const App = () => { return ( <Tutorial tooltip={MyTooltip}> { /* Steps go here */ } </Tutorial> );};
export default App;Changing the next button’s content for the last step
Section titled “Changing the next button’s content for the last step”You can customize your tooltip with the custom provided props to change the “Next” button’s content on the final step.
4 collapsed lines
import Tutorial, {TutorialRef} from "@components/Complex/Tutorial/Tutorial";import { TooltipType } from "@components/Complex/Tutorial/TutorialTooltip";import Flex from "@components/Layout/Flex/Flex";
const MyTooltip: TooltipType = (props) => { return ( <div> <div>{props.title}</div> <div>{props.content}</div> <Flex> <props.Prev>Previous</props.Prev> <props.Next> {props.progress() === 100 ? 'Done' : 'Next' } </props.Next> </Flex> </div> )}10 collapsed lines
const App = () => { return ( <Tutorial tooltip={MyTooltip}> { /* Steps go here */ } </Tutorial> );};
export default App;Applying conditional classes to control button visibility
Section titled “Applying conditional classes to control button visibility”You can conditionally apply classes and styles to the provided Next and Prev components to control their visibility based on the current step.
4 collapsed lines
import Tutorial, {TutorialRef} from "@components/Complex/Tutorial/Tutorial";import { TooltipType } from "@components/Complex/Tutorial/TutorialTooltip";import Flex from "@components/Layout/Flex/Flex";
const MyTooltip: TooltipType = (props) => { return ( <div> <div>{props.title}</div> <div>{props.content}</div> <Flex> <props.Prev class={props.step() === 1 ? 'control-hidden' : ''}>Previous</props.Prev> <props.Next class={props.step() === 3 ? 'control-hidden' : ''}>Next</props.Next> </Flex> </div> )}10 collapsed lines
const App = () => { return ( <Tutorial tooltip={MyTooltip}> { /* Steps go here */ } </Tutorial> );};
export default App;