Wizard

Wizard — a multi-step flow with a numbered indicator, per-step content, and a Back / Next-or-Finish footer. Control the step via activeStep/onStepChange or run uncontrolled with defaultStep.

Colors (step markers)

Real use · workspace onboarding

Using Wizard

Silica ships one design system through three paths. They share a class vocabulary but are not interchangeable — pick the one that matches what you are building.

Plain HTML — CSS classes

The Tailwind v4 plugin. Works in any framework or none — Rails, Django, PHP, Go, a static file. This path ships no JavaScript, so Wizard is styled but inert: its behavior comes from wizard. For that behavior with no framework, use the node-tree path below.

/* in your CSS */
@import "tailwindcss";
@plugin "@wizeworks/silicaui";

Root class wizard, with 15 modifiers:

  • .wizard
  • .wizard-accent
  • .wizard-content
  • .wizard-error
  • .wizard-footer
  • .wizard-info
  • .wizard-neutral
  • .wizard-primary
  • .wizard-secondary
  • .wizard-step
  • .wizard-step-label
  • .wizard-step-marker
  • .wizard-step-optional
  • .wizard-steps
  • .wizard-success
  • .wizard-warning

React

Typed components over those same classes, with behavior and accessibility from Base UI.

npm i @wizeworks/silicaui-react
import { Wizard } from "@wizeworks/silicaui-react";

Props

PropTypeRequiredDescription
stepsWizardStep[]yes—
activeStepnumbernoControlled active step index.
defaultStepnumbernoUncontrolled initial step index. Default 0.
onStepChange(index: number) => voidno—
colorSilicaColornoAccent color for markers + rail.
linearbooleannoLinear flow: markers can only jump backward (revisit) or stay; forward is via Next. false lets any enabled step be clicked. Default true.
canGoNextbooleannoGate the Next button (e.g. until the active step validates). Default true.
onFinish() => voidnoCalled when Next is pressed on the last step.
backLabelstringno—
nextLabelstringno—
finishLabelstringno—
hideFooterbooleannoHide the built-in Back / Next footer.
childrenReact.ReactNodenoRender your own content instead of the active step's content.

Source of the demo above

The exact file that renders the examples above, so it can never drift from them. It imports a few of this site’s own layout helpers (../lib/…), so read it for the component calls rather than copying it whole.

Show source
import { useState } from "react";
import { Wizard, Input } from "@wizeworks/silicaui-react";
import type { WizardStep } from "@wizeworks/silicaui-react";
import { Section } from "../lib/Section";
import { COLORS } from "../lib/data";

const MINI_STEPS: WizardStep[] = [
    { id: "a", title: "Cart" },
    { id: "b", title: "Shipping" },
    { id: "c", title: "Payment" },
];

const STEPS: WizardStep[] = [
    {
        id: "account",
        title: "Account",
        content: (
            <div className="flex max-w-sm flex-col gap-3">
                <Input placeholder="Work email" type="email" />
                <Input placeholder="Choose a password" type="password" />
            </div>
        ),
    },
    {
        id: "profile",
        title: "Profile",
        content: (
            <div className="flex max-w-sm flex-col gap-3">
                <Input placeholder="Full name" />
                <Input placeholder="Company" />
            </div>
        ),
    },
    {
        id: "billing",
        title: "Billing",
        optional: true,
        content: (
            <div className="flex max-w-sm flex-col gap-3">
                <Input placeholder="Card number" />
                <span className="text-xs opacity-60">
                    Optional — you can add this later from Settings.
                </span>
            </div>
        ),
    },
    {
        id: "review",
        title: "Review",
        content: (
            <p className="max-w-sm text-sm opacity-80">
                You're all set. Review your details and press Finish to create the
                workspace.
            </p>
        ),
    },
];

export function WizardDemo() {
    const [step, setStep] = useState(0);
    const [done, setDone] = useState(false);

    return (
        <>
            <Section title="Colors (step markers)">
                <div className="flex flex-col gap-6">
                    {COLORS.slice(0, 3).map((color) => (
                        <Wizard
                            key={color}
                            color={color}
                            steps={MINI_STEPS}
                            defaultStep={1}
                            hideFooter
                        />
                    ))}
                </div>
            </Section>

            <Section title="Real use · workspace onboarding">
                <Wizard
                    color="primary"
                    steps={STEPS}
                    activeStep={step}
                    onStepChange={setStep}
                    onFinish={() => setDone(true)}
                />
                {done && (
                    <p className="text-sm text-success">
                        🎉 Workspace created — you can close this wizard.
                    </p>
                )}
            </Section>
        </>
    );
}

Vanilla — node tree to HTML

wizard — Back/Next reuse the prev/next roles (already exist). Build a node tree, project it with toHtml(), and let the zero-dependency runtime hydrate it. This is the path for generated or user-authored documents — a site builder, CMS output, a static export.

npm i @wizeworks/silicaui-html @wizeworks/silicaui-behaviors
import { atom, toHtml } from "@wizeworks/silicaui-html";

const node = atom("Wizard", "wizard", { /* props */ }, [/* children */]);
const markup = toHtml(node);

Styling on this path is the class string in the second argument — the same classes as the Plain HTML section above. There is no color prop here; write "wizard wizard-primary" rather than passing a colour as a prop.

Takes children
yes
Hydrated by
wizard

Load @wizeworks/silicaui-behaviors on the page or this markup renders correctly and does nothing.

The full API for Wizard, on every path, is available through the Silica MCP server.