### Install and Develop Stepperize Docs Source: https://github.com/damianricobelli/stepperize/blob/main/apps/docs/README.md Run these commands from the repository root to install dependencies and start the development server for the Stepperize documentation site. The dev server typically runs on localhost:3000. ```bash pnpm install pnpm --filter docs dev ``` -------------------------------- ### Install Dependencies Source: https://github.com/damianricobelli/stepperize/blob/main/CONTRIBUTING.md Install project dependencies using pnpm. ```bash pnpm i ``` -------------------------------- ### Start Development Server Source: https://github.com/damianricobelli/stepperize/blob/main/README.md Start the development server to run the application and view changes in real-time. This command is typically used during the development phase. ```bash pnpm dev ``` -------------------------------- ### Install Conform Dependencies Source: https://github.com/damianricobelli/stepperize/blob/main/apps/docs/content/docs/docs/latest/forms/conform.mdx Install the necessary Conform packages for React and Zod validation. ```bash npm install @conform-to/react @conform-to/zod ``` -------------------------------- ### Quick Start: Basic Wizard Implementation Source: https://github.com/damianricobelli/stepperize/blob/main/packages/react/README.md Define a stepper configuration and use the `useStepper` hook to manage the current step and navigation within a React component. This example shows a simple account, profile, and done step wizard. ```tsx import { defineStepper } from "@stepperize/react"; const wizard = defineStepper([ { id: "account", title: "Account" }, { id: "profile", title: "Profile" }, { id: "done", title: "Done" }, ]); function Wizard() { const stepper = wizard.useStepper(); return (

{stepper.current.title}

{stepper.match({ account: () => , profile: () => , done: () => , })}
); } ``` -------------------------------- ### Complete Stepper Example Source: https://github.com/damianricobelli/stepperize/blob/main/apps/docs/content/docs/docs/latest/getting-started/first-stepper.mdx A full example integrating step definition, hook usage, conditional rendering, and navigation controls within a single component. ```tsx import { defineStepper } from "@stepperize/react"; const signup = defineStepper([ { id: "name", title: "Name" }, { id: "email", title: "Email" }, { id: "confirm", title: "Confirm" }, ]); export function Signup() { const stepper = signup.useStepper(); return (

Step {stepper.index + 1} of {stepper.count}: {stepper.current.title}

{stepper.match({ name: () => , email: () => , confirm: () =>

Review your details.

, })}
); } ``` -------------------------------- ### Install Dependencies for Development Source: https://github.com/damianricobelli/stepperize/blob/main/README.md Install project dependencies using pnpm, which is required for development. This command should be run after cloning the repository. ```bash pnpm install ``` -------------------------------- ### Run Development Docs Server Source: https://github.com/damianricobelli/stepperize/blob/main/CONTRIBUTING.md Start the development server for the documentation, filtering for the 'docs' package. ```bash pnpm dev --filter docs ``` -------------------------------- ### Install TanStack Form Source: https://github.com/damianricobelli/stepperize/blob/main/apps/docs/content/docs/docs/latest/forms/tanstack-form.mdx Install the TanStack Form package using npm. ```bash npm install @tanstack/react-form ``` -------------------------------- ### Install React Package Source: https://github.com/damianricobelli/stepperize/blob/main/apps/docs/content/docs/docs/latest/getting-started/installation.mdx Install the Stepperize React package using your preferred package manager. ```bash pnpm add @stepperize/react ``` ```bash npm install @stepperize/react ``` ```bash yarn add @stepperize/react ``` ```bash bun add @stepperize/react ``` -------------------------------- ### Quick Start: Define and Use a Stepper Source: https://github.com/damianricobelli/stepperize/blob/main/README.md Define a stepper with multiple steps and use the `useStepper` hook to manage its state within a React component. This example demonstrates basic navigation and conditional rendering based on the current step. ```tsx import { defineStepper } from "@stepperize/react"; const checkout = defineStepper([ { id: "shipping", title: "Shipping", description: "Enter your address" }, { id: "payment", title: "Payment", description: "Payment details" }, { id: "review", title: "Review", description: "Confirm your order" }, ]); function Checkout() { const stepper = checkout.useStepper(); return (

{stepper.current.title}

{stepper.current.description}

{stepper.match({ shipping: () => , payment: () => , review: () => , })}
); } ``` -------------------------------- ### Install React Hook Form and Resolver Source: https://github.com/damianricobelli/stepperize/blob/main/apps/docs/content/docs/docs/latest/forms/react-hook-form.mdx Install the necessary packages for React Hook Form and its Zod resolver. ```bash npm install react-hook-form @hookform/resolvers ``` -------------------------------- ### Run Development Server for Docs App Source: https://github.com/damianricobelli/stepperize/blob/main/README.md Start the development server for the documentation application. This command uses pnpm filters to target the docs app. ```bash pnpm --filter docs dev ``` -------------------------------- ### Reusable Component Example Source: https://github.com/damianricobelli/stepperize/blob/main/apps/docs/content/docs/docs/latest/api/react/types.mdx This example demonstrates how to create a reusable `Progress` component that accepts a `Stepper` instance and displays the current step progress. It utilizes the `Stepper` type for type safety. ```APIDOC ## Reusable Component ### Description This example demonstrates how to create a reusable `Progress` component that accepts a `Stepper` instance and displays the current step progress. It utilizes the `Stepper` type for type safety. ### Component Signature ```tsx import type { Step, Stepper } from "@stepperize/react"; function Progress({ stepper }: { stepper: Stepper }) { return (

Step {stepper.index + 1} of {stepper.count}

); } ``` **Note:** If a component can call the generated hook directly, prefer that over passing types around. ``` -------------------------------- ### Install Stepperize React Package Source: https://github.com/damianricobelli/stepperize/blob/main/README.md Install the Stepperize React package using npm. This command adds the necessary library to your project for building step-by-step experiences. ```bash npm install @stepperize/react ``` -------------------------------- ### Checkout Provider Setup Source: https://github.com/damianricobelli/stepperize/blob/main/apps/docs/content/docs/docs/latest/api/react/provider.mdx Sets up the checkout stepper provider with a default initial step. Descendant components can then access the stepper instance using `useStepper`. ```tsx function CheckoutShell() { return ( ); } ``` -------------------------------- ### Syncing Stepper Step with URL Source: https://github.com/damianricobelli/stepperize/blob/main/apps/docs/content/docs/docs/latest/core-concepts/controlled-vs-uncontrolled.mdx This example demonstrates controlling the stepper's step by syncing it with the URL. It also includes handling invalid steps by navigating to a default. ```tsx const stepper = checkout.useStepper({ step: stepFromUrl, onStepChange: (next) => navigate({ search: { step: next } }), onInvalidStep: () => navigate({ search: { step: "shipping" }, replace: true }), }); ``` -------------------------------- ### Complete Guarded Example with React State Source: https://github.com/damianricobelli/stepperize/blob/main/apps/docs/content/docs/docs/latest/forms/schema-validation.mdx An example demonstrating how to keep input in React state until a user clicks 'Continue', using `ctx.validate()` in the `beforeStepChange` guard to validate pending data before committing. ```tsx import { defineStepper } from "@stepperize/react"; import { useState } from "react"; import { z } from "zod"; const shippingSchema = z.object({ address: z.string().min(1, "Address is required"), zip: z.string().regex(/^\d{5}$/, "Enter a 5-digit ZIP"), }); const checkout = defineStepper([ { id: "shipping", title: "Shipping", schema: shippingSchema }, { id: "review", title: "Review" }, ] as const); type Shipping = z.input; export function CheckoutShippingStep() { const [shipping, setShipping] = useState({ address: "", zip: "", }); const [errors, setErrors] = useState([]); const stepper = checkout.useStepper({ beforeStepChange: async ({ direction, validate }) => { if (direction === "prev") return true; const result = await validate(); if (!result.success) { setErrors(result.issues.map((issue) => issue.message)); return false; } setErrors([]); return true; }, }); return (
event.preventDefault()}> {stepper.is("shipping") && ( <> {errors.map((error) => (

{error}

))} )} {stepper.is("review") && ( <>
{JSON.stringify(stepper.data.get("shipping"), null, 2)}
)}
); } ``` -------------------------------- ### Define a Stepper Source: https://github.com/damianricobelli/stepperize/blob/main/apps/docs/content/docs/docs/latest/api/react/primitives.mdx Define a stepper with multiple steps, each having an id, title, and description. This setup is used across all examples. ```tsx import { defineStepper } from "@stepperize/react"; const checkout = defineStepper([ { id: "shipping", title: "Shipping", description: "Delivery address" }, { id: "payment", title: "Payment", description: "Payment method" }, { id: "review", title: "Review", description: "Confirm order" }, ]); ``` -------------------------------- ### Get Helpers Source: https://github.com/damianricobelli/stepperize/blob/main/apps/docs/content/docs/docs/latest/api/react/types.mdx The `Get` helper utility, along with `defineStepper`, allows you to derive specific types based on your stepper definition. This is particularly useful for creating strongly-typed references to step IDs or specific step configurations. ```APIDOC ## Get Helpers ### Description The `Get` helper utility, along with `defineStepper`, allows you to derive specific types based on your stepper definition. This is particularly useful for creating strongly-typed references to step IDs or specific step configurations. ### Usage ```tsx import { defineStepper, type Get } from "@stepperize/react"; const checkout = defineStepper([ { id: "shipping", title: "Shipping" }, { id: "payment", title: "Payment" }, { id: "review", title: "Review" }, ]); type StepId = Get.Id; type PaymentStep = Get.StepById; ``` ``` -------------------------------- ### Expensive Data Table Example with Activity Component Source: https://github.com/damianricobelli/stepperize/blob/main/apps/docs/content/docs/docs/latest/guides/react-activity.mdx This example demonstrates how to use the Activity component to maintain the state of an expensive data table (including query, sort, and selected rows) across different steps in a report builder wizard. It ensures that when the user navigates back to the table step, its UI state is preserved. ```tsx import { defineStepper } from "@stepperize/react"; import { Activity, useMemo, useState } from "react"; type Row = { id: string; name: string; revenue: number; }; const reportFlow = defineStepper([ { id: "filters", title: "Filters" }, { id: "table", title: "Data table" }, { id: "review", title: "Review" }, ] as const); export function ReportBuilder() { const stepper = reportFlow.useStepper(); return ( <> {stepper.steps.map((step) => ( {step.id === "filters" && } {step.id === "table" && } {step.id === "review" && } ))} ); } function ExpensiveTableStep() { const rows = useMemo(() => buildLargeDataset(), []); const [query, setQuery] = useState(""); const [sort, setSort] = useState<"name" | "revenue">("revenue"); const [selected, setSelected] = useState([]); const visibleRows = useMemo( () => rows .filter((row) => row.name.toLowerCase().includes(query.toLowerCase())) .sort((a, b) => sort === "name" ? a.name.localeCompare(b.name) : b.revenue - a.revenue, ), [rows, query, sort], ); return (
setQuery(event.target.value)} /> {visibleRows.map((row) => ( ))}
setSelected((current) => event.target.checked ? [...current, row.id] : current.filter((id) => id !== row.id), ) } /> {row.name} {row.revenue}
); } function FilterStep() { const [region, setRegion] = useState("all"); return (
); } function ReviewStep() { return (

Review

Return to the table: its query, sort, and selected rows are preserved.

); } function buildLargeDataset(): Row[] { return Array.from({ length: 500 }, (_, index) => ({ id: `row-${index}`, name: `Customer ${index + 1}`, revenue: Math.round(1000 + Math.random() * 9000), })); } ``` -------------------------------- ### React Wizard with Stepperize Activity Source: https://github.com/damianricobelli/stepperize/blob/main/apps/docs/content/docs/docs/latest/guides/react-activity.mdx This example demonstrates an uncontrolled Stepperize state for navigation and local React state within each step. It's a copy-pasteable TypeScript example that can be adapted for various form components. ```typescript import { defineStepper } from "@stepperize/react"; import { Activity, useId, useState } from "react"; const signup = defineStepper([ { id: "account", title: "Account" }, { id: "profile", title: "Profile" }, { id: "preferences", title: "Preferences" }, { id: "review", title: "Review" }, ] as const); type StepId = (typeof signup.steps)[number]["id"]; export function PreservedSignupWizard() { const stepper = signup.useStepper(); return (
{stepper.steps.map((step) => ( ))}
Step {stepper.index + 1} of {stepper.count}
); } function StepPanel({ stepId }: { stepId: StepId }) { switch (stepId) { case "account": return ; case "profile": return ; case "preferences": return ; case "review": return ; } } function AccountStep() { const instanceId = useStableInstanceId(); const [name, setName] = useState(""); const [email, setEmail] = useState(""); return (
{JSON.stringify({ name, email }, null, 2)}
); } function ProfileStep() { const instanceId = useStableInstanceId(); const [bio, setBio] = useState(""); return (