PParable
All components

Multi-Step Form

Blocks & Slices

A guided wizard block: a numbered role=progressbar header whose gradient fill springs along the track as you advance, step panels that cross-fade and slide in the travel direction while the panel height morphs to fit, and validation-gated Back/Next with a submit step that fires onComplete. Announces each step change through a polite live region and moves focus to the incoming heading; under prefers-reduced-motion steps swap instantly and the bar fills without transition.

Step 1 of 3, Create your account.
Step 1 of 3

Create your account

Work email
jordan@parable.dev
Password
••••••••

Installation

npx shadcn@latest add https://parable-three.vercel.app/r/multi-step-form.json

Runs the shadcn CLI — the component source is copied intocomponents/parable/multi-step-form.tsx. You own it from there.

Usage

The exact code rendering the preview above.

<div className="w-full max-w-[440px]">
    <MultiStepForm
      steps={[
        {
          id: "account",
          title: "Create your account",
          validate: () => true,
          content: (
            <div className="space-y-3">
              <div className="space-y-1.5">
                <span className="flex items-center gap-1.5 text-xs font-medium text-white/50">
                  <Mail className="size-3.5" aria-hidden /> Work email
                </span>
                <div className="flex h-9 items-center rounded-lg border border-white/10 bg-white/[0.04] px-3 text-[13px] text-white/80">
                  jordan@parable.dev
                </div>
              </div>
              <div className="space-y-1.5">
                <span className="flex items-center gap-1.5 text-xs font-medium text-white/50">
                  <Lock className="size-3.5" aria-hidden /> Password
                </span>
                <div className="flex h-9 items-center rounded-lg border border-white/10 bg-white/[0.04] px-3 text-[13px] tracking-[0.3em] text-white/80">
                  ••••••••
                </div>
              </div>
            </div>
          ),
        },
        {
          id: "workspace",
          title: "Set up your workspace",
          content: (
            <div className="space-y-1.5">
              <span className="flex items-center gap-1.5 text-xs font-medium text-white/50">
                <Building2 className="size-3.5" aria-hidden /> Workspace name
              </span>
              <div className="flex h-9 items-center rounded-lg border border-white/10 bg-white/[0.04] px-3 text-[13px] text-white/80">
                Parable Studio
              </div>
              <p className="pt-1 text-[12px] leading-relaxed text-white/45">
                This is where your team collaborates. You can rename it anytime.
              </p>
            </div>
          ),
        },
        {
          id: "review",
          title: "Review & finish",
          content: (
            <div className="space-y-2.5">
              <div className="flex items-center justify-between rounded-lg border border-white/10 bg-white/[0.03] px-3 py-2 text-[13px]">
                <span className="text-white/50">Email</span>
                <span className="text-white/80">jordan@parable.dev</span>
              </div>
              <div className="flex items-center justify-between rounded-lg border border-white/10 bg-white/[0.03] px-3 py-2 text-[13px]">
                <span className="text-white/50">Workspace</span>
                <span className="text-white/80">Parable Studio</span>
              </div>
              <p className="flex items-center gap-1.5 pt-1 text-[12px] text-white/45">
                <Sparkles className="size-3.5 text-violet-300" aria-hidden /> Everything looks good — submit to create your account.
              </p>
            </div>
          ),
        },
      ]}
    />
  </div>

Props

MultiStepFormProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange">

PropTypeDefaultDescription
steps*WizardStep[]Ordered steps the wizard walks through; the last one is the submit step.
onComplete() => voidFires when the final step passes validation and the form is submitted.
currentIndexnumberControlled active-step index. Pair with `onIndexChange`.
defaultIndexnumber0Uncontrolled initial active-step index.
onIndexChange(index: number) => voidFires with the next index on Back / Next / step-marker navigation.
accentstring"#8b5cf6"Accent hex — progress fill, active marker, focus ring. Mirrors `--pb-violet`.
backgroundstring"#0f0f10"Card surface colour. Mirrors the site `--pb-ink` token.
backLabelReact.ReactNode"Back"Label for the back button.
nextLabelReact.ReactNode"Continue"Label for the advance button on non-final steps.
submitLabelReact.ReactNode"Submit"Label for the advance button on the final step.

npm dependencies

  • motion
  • lucide-react