Multi Step Form
A multi step form component
Default
Default multi step form
Profile
Tell us how to contact you.
1
Profile2
Plan3
Notesdefault-example.tsx
1"use client";23import { useMemo, useState } from "react";4import { useFormContext } from "react-hook-form";5import { z } from "zod";6import { MultiStepForm } from "@/registry/ui";7import { Input } from "@/components/ui/input";8import { Label } from "@/components/ui/label";9import { Textarea } from "@/components/ui/textarea";1011type DemoValues = {12 fullName?: string;13 email?: string;14 company?: string;15 plan?: string;16 notes?: string;17};1819const ProfileStep = () => {20 const { register } = useFormContext<DemoValues>();2122 return (23 <div className="space-y-4">24 <div className="space-y-2">25 <Label htmlFor="fullName">Full name</Label>26 <Input27 id="fullName"28 placeholder="Ada Lovelace"29 {...register("fullName")}30 />31 </div>32 <div className="space-y-2">33 <Label htmlFor="email">Email</Label>34 <Input35 id="email"36 type="email"37 placeholder="ada@example.com"38 {...register("email")}39 />40 </div>41 </div>42 );43};4445const PlanStep = () => {46 const { register } = useFormContext<DemoValues>();4748 return (49 <div className="space-y-4">50 <div className="space-y-2">51 <Label htmlFor="company">Company</Label>52 <Input53 id="company"54 placeholder="Analytical Engines Inc."55 {...register("company")}56 />57 </div>58 <div className="space-y-2">59 <Label htmlFor="plan">Plan</Label>60 <Input61 id="plan"62 placeholder="Starter / Pro / Enterprise"63 {...register("plan")}64 />65 </div>66 </div>67 );68};6970const NotesStep = () => {71 const { register } = useFormContext<DemoValues>();7273 return (74 <div className="space-y-2">75 <Label htmlFor="notes">Anything else?</Label>76 <Textarea77 id="notes"78 placeholder="Share context for your setup..."79 className="min-h-28"80 {...register("notes")}81 />82 </div>83 );84}8586export function MultiStepFormDefaultExample() {87 const [submittedData, setSubmittedData] = useState<DemoValues | null>(null);8889 const steps = useMemo(90 () => [91 {92 id: "profile",93 title: "Profile",94 description: "Tell us how to contact you.",95 component: <ProfileStep />,96 validationSchema: z.object({97 fullName: z.string().min(2, "Name is too short"),98 email: z.string().email("Please enter a valid email"),99 }),100 },101 {102 id: "plan",103 title: "Plan",104 description: "Share your team details.",105 component: <PlanStep />,106 validationSchema: z.object({107 company: z.string().min(2, "Company is required"),108 plan: z.string().min(2, "Plan is required"),109 }),110 },111 {112 id: "notes",113 title: "Notes",114 description: "Optional context before submission.",115 component: <NotesStep />,116 isOptional: true,117 },118 ],119 [],120 );121122 return (123 <div className="space-y-4 w-full">124 <MultiStepForm125 steps={steps}126 onSubmit={(data) => setSubmittedData(data)}127 storageKey="multi-step-form-example"128 />129130 {submittedData ? (131 <pre className="rounded-lg border bg-muted/30 p-4 text-xs">132 {JSON.stringify(submittedData, null, 2)}133 </pre>134 ) : null}135 </div>136 );137}
Installation & source
Install via the shadcn CLI or copy the registry files manually.
bash
npx shadcn@latest add @tt-ui/multi-step-form
Props
| Name | Type | Default | Description |
|---|---|---|---|
| steps | array | Required | The steps of the form |
| initialData | object | {} | The initial data of the form |
| onSubmit | function | Required | The function to submit the form |
| className | string | The class name of the form | |
| storageKey | string | multi-step-form | The key to store the form data in localStorage |