My first stepper
Build a minimal stepper using defineStepper and useStepper
This page walks you through building a minimal stepper without primitives (no Stepper.List, Stepper.Item, Stepper.Trigger, etc.) and without Scoped or Stepper.Root. You only need defineStepper and useStepper. When you call useStepper() directly in a component, the hook owns the stepper state—no provider required.
Define your steps
defineStepper is the entry point. You pass one object per step (each with at least a unique id) and get back a typed stepper: useStepper, and optionally Scoped, Stepper (primitives). For this example we only use useStepper.
Here we define four steps: Name, Email, Confirm, and Done. You can add any extra fields (title, description, etc.) for your UI.
import { defineStepper } from "@stepperize/react";
const { useStepper } = defineStepper(
{ id: "name", title: "Name" },
{ id: "email", title: "Email" },
{ id: "confirm", title: "Confirm" },
{ id: "done", title: "Done" },
);Use the hook in your component
useStepper returns the stepper instance. Call it inside the component that renders your UI (not at module top level), because the hook uses React state. From the returned stepper you get:
- state —
state.current(current step object),state.isFirst,state.isLast - flow —
flow.switch({ ... })to render content per step (one branch per step id) - navigation —
navigation.next(),navigation.prev(),navigation.goTo(id),navigation.reset()
function MyStepper() {
const stepper = useStepper();
return (
<>
<p>Step: {stepper.state.current.data.title}</p>
<div>
{stepper.flow.switch({
name: () => <p>What is your name?</p>,
email: () => <p>What is your email?</p>,
confirm: () => <p>Confirm.</p>,
done: () => <p>All done!</p>,
})}
</div>
<div>
{!stepper.state.isFirst && (
<button onClick={() => stepper.navigation.prev()}>Back</button>
)}
{stepper.state.isLast ? (
<button onClick={() => stepper.navigation.reset()}>Reset</button>
) : (
<button onClick={() => stepper.navigation.next()}>Next</button>
)}
</div>
</>
);
}Full example
import * as React from "react";
import { } from "@stepperize/react";
const { } = (
{ : "name", : "Name" },
{ : "email", : "Email" },
{ : "confirm", : "Confirm" },
{ : "done", : "Done" },
);
export function () {
const = ();
return (
<>
<>Step: <>{....}</></>
<>
{..({
: () => <>What is your name?</>,
: () => <>What is your email?</>,
: () => <>Please confirm your details.</>,
: () => <>All done!</>,
})}
</>
<>
{.. ? (
< ={() => ..()}>Reset</>
) : (
<>
< ={() => ..()} ={..}>Back</>
< ={() => ..()}>Next</>
</>
)}
</>
</>
);
}- defineStepper — defines your steps and returns
useStepper(and optionallyScoped,Stepper). - useStepper() — returns the stepper instance; when called in a component with no provider, that component owns the stepper state.
- No provider is required: you don't need
ScopedorStepper.Rootfor this pattern.
Result
Step: Name
What is your name?
Last updated on