Wizard (Driver)
A component to guide the user's focus across the page with interactive tours.
Examples
Step 1 Target
ID: #step-1
Ignored Element
This element is not part of the tour.
Step 3 Target
ID: #step-3
"use client";
import { useRef, useState } from "react";
import { Button, Card, Wizard, WizardStep } from "@g4rcez/components";
import { Tag } from "@g4rcez/components/tag";
function BasicPageTour() {
const [active, setActive] = useState(false);
const buttonRef = useRef(null);
const steps: WizardStep[] = [
{
element: "#step-1",
title: "First Step (ID Selector)",
description: "This element is selected using a CSS selector string '#step-1'.",
side: "right",
},
{
element: buttonRef,
title: (
<span className="flex gap-2 items-center">
React Node Title <Tag size="small">New</Tag>
</span>
),
description: (
<div className="flex flex-col gap-2">
<span>This description uses a React Node.</span>
<span className="text-xs text-info">You can put anything here!</span>
</div>
),
side: "bottom",
},
{
element: "#step-3",
title: "Third Step",
description: "Back to ID selector.",
side: "top",
onEnter: () => console.log("Entered step 3"),
},
];
return (
<Card title="Driver Demo">
<Button onClick={() => setActive(true)}>Start Tour</Button>
<div className="grid grid-cols-1 gap-8 mt-8 md:grid-cols-2">
<div
id="step-1"
className="p-8 rounded-lg border border-card-border bg-card-background"
>
<h3 className="font-bold">Step 1 Target</h3>
<p className="">ID: #step-1</p>
</div>
<div className="p-8 rounded-lg border opacity-50 border-card-border bg-card-background">
<h3 className="font-bold">Ignored Element</h3>
<p>This element is not part of the tour.</p>
</div>
<div className="flex justify-center items-center p-8 rounded-lg border border-card-border bg-card-background">
<Button ref={buttonRef}>Step 2 Target (Ref)</Button>
</div>
<div
id="step-3"
className="p-8 text-right rounded-lg border border-card-border bg-card-background"
>
<h3 className="font-bold">Step 3 Target</h3>
<p className="">ID: #step-3</p>
</div>
</div>
<Wizard
steps={steps}
active={active}
onClose={() => setActive(false)}
onFinish={() => alert("Tour finished!")}
/>
</Card>
);
}Start a tour on the page, then let the Wizard open the Modal and highlight content inside it.
"use client";
import { useState } from "react";
import { Button, Card, Modal, Wizard, WizardStep } from "@g4rcez/components";
function ModalWizardIntegration() {
const [modalOpen, setModalOpen] = useState(false);
const [modalWizardActive, setModalWizardActive] = useState(false);
const closeModalWizard = () => {
setModalWizardActive(false);
setModalOpen(false);
};
const changeModalOpen = (open: boolean) => {
setModalOpen(open);
if (!open) {
setModalWizardActive(false);
}
};
const modalSteps: WizardStep[] = [
{
element: "#modal-tour-trigger",
title: "Start outside the modal",
description: "This tour starts on the page, then opens a modal for the next step.",
side: "bottom",
},
{
element: "#modal-step-1",
title: "Modal Content",
description: "This step opens the modal and highlights content inside it.",
side: "bottom",
onEnter: () => setModalOpen(true),
},
{
element: "#modal-step-2",
title: "Action Button",
description: "You can guide users through modal interactions.",
side: "top",
},
];
return (
<Card title="Wizard + Modal Integration">
<p className="mb-4">
Start a tour on the page, then let the Wizard open the Modal and highlight content inside it.
</p>
<Button
id="modal-tour-trigger"
onClick={() => {
setModalOpen(false);
setModalWizardActive(true);
}}
>
Start Tour That Opens Modal
</Button>
<Modal
closable
open={modalOpen}
type="dialog"
title="Modal with Wizard Tour"
overlayClickClose
onChange={changeModalOpen}
>
<div className="flex flex-col gap-4">
<p
id="modal-step-1"
className="p-4 rounded-lg border border-card-border bg-card-muted"
>
This is the modal content. The Wizard should appear above this modal overlay.
</p>
<div className="flex gap-2">
<Button id="modal-step-2">Confirm action</Button>
<Button theme="neutral" onClick={closeModalWizard}>
Close
</Button>
</div>
</div>
</Modal>
<Wizard
steps={modalSteps}
active={modalWizardActive}
onClose={closeModalWizard}
onFinish={() => {
closeModalWizard();
alert("Modal tour finished!");
}}
/>
</Card>
);
}When to use Wizard (Driver)
Use when
You need the documented Wizard (Driver) interaction or presentation in a product workflow.
Avoid when
A native HTML element already provides the Wizard (Driver) behavior you need.
Accessibility
Keep the Wizard (Driver) labeled and use its documented keyboard interaction. The component preserves visible focus and communicates state without relying on color alone.
- Keep keyboard focus visible and follow the documented key commands.
- Provide an accessible name and connect descriptions or errors to the control.