Multi-Step Form Flow
A validated wizard with per-step gating, an editable review step, and a real success state.
- Category
- Components
- Added
- 2026-09-01
- Deps
- 2
- Updated
- 2026-09-01
This is a viberdy Pro component
The live preview, the props panel and the write-up are open to everyone. The full source, the AI prompt and CLI install are part of Pro.
Props
"use client";
import { useState, type FormEvent } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { Check, ChevronLeft, ChevronRight, Pencil } from "lucide-react";
type FormData = {
fullName: string;
email: string;
project: string;
teamSize: string;
};
const EMPTY: FormData = { fullName: "", email: "", project: "", teamSize: "1-5" };
const STEPS = ["Account", "Project", "Review"];
function isValidEmail(v: string) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v);
// ---------------------------------------------------------------
// Full source available with a viberdy Pro subscription.
// https://viberdy.dev/pricing
// ---------------------------------------------------------------
}About this component
Chaining a handful of conditionally-rendered form sections behind a single 'step' counter looks like a wizard but usually isn't one: nothing stops a user from reaching step three with an empty required field, and there's rarely a way to revisit an earlier answer without losing progress. This component treats validity as a first-class per-step value that gates the Next button directly, wraps each step in its own form so Enter submits it the same way the button does, and gives the review step real Edit affordances that jump the step index backward without clearing state. The non-obvious detail: because each step is its own <motion.form>, AnimatePresence's mode='wait' needs a stable, unique key per step (the step label) or Framer Motion will cross-fade stale DOM instead of properly unmounting the previous step's inputs. Caveat: validation here is intentionally simple (regex email, length checks) — swap in a schema library like Zod for anything shipping to production with real business rules.
Curator’s note
Next is disabled rather than hidden specifically so users always see what's blocking them, instead of wondering why the button disappeared.
Pairs well with
Matched on shared tags and category — the entries most likely to be used alongside this one.
Form Error Summary
patternsThe error pattern that actually works with a screen reader: focus the summary, link to the fields, punish late.
Floating Label Input
componentsA text input whose label floats from placeholder position into a caption on focus.
File Upload Dropzone
componentsA real drag-and-drop file zone with a live dragover state and file chips.