npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-zod-multistep-form

v0.0.8

Published

A React hook for managing multi-step forms with Zod schema validation and react-hook-form integration. Simplifies navigation between form steps, handles form state, validation, and error management with ease.

Downloads

16

Readme

React Zod Multi-Step Form Hook

react-zod-multistep-form is a lightweight React hook designed to simplify the management of multi-step forms. It integrates react-hook-form with Zod schema validation to handle form state, validation, and error management across multiple steps. This hook provides a seamless way to navigate between form steps while maintaining robust validation and form control.

Features

  • Multi-step form management: Easily navigate through multiple form steps with built-in state management.
  • Zod schema validation: Integrates Zod for schema-based validation at each step to ensure type safety.
  • React Hook Form integration: Leverages react-hook-form to handle form state, registration, and validation.
  • Error handling: Provides detailed error management for each form step, ensuring validation is respected.
  • Navigation callbacks: Simple goToNextStep and goToPreviousStep functions to handle form step transitions while respecting validation.
  • Field-specific validation: Uses trigger from react-hook-form to validate only the fields in the current step before allowing navigation to the next step.

Installation

npm install react-zod-multistep-form

Usage

Here’s how to use the useMultiStepForm hook in your application:

Step 1: Define your form schema using Zod

import { z } from "zod";

const schema = z.object({
  name: z.string().min(2, "Name is required"),
  age: z.number().min(18, "Must be at least 18"),
});

type FormData = z.infer<typeof schema>;

Step 2: Create form step components

import { StepComponent } from "react-zod-multistep-form";

const NameStep: StepComponent<FormData> = ({ register, errors }) => (
  <div>
    <label>Name</label>
    <input {...register("name")} />
    {errors.name && <p>{errors.name.message}</p>}
  </div>
);

const AgeStep: StepComponent<FormData> = ({ register, errors }) => (
  <div>
    <label>Age</label>
    <input type="number" {...register("age")} />
    {errors.age && <p>{errors.age.message}</p>}
  </div>
);

Step 3: Define your form steps

const steps: Step<FormData>[] = [
  { component: NameStep, fields: ["name"] },
  { component: AgeStep, fields: ["age"] },
];

Step 4: Use useMultiStepForm in your form component

import useMultiStepForm from "react-zod-multistep-form";

const MultiStepForm = () => {
  const {
    CurrentStep,
    goToNextStep,
    goToPreviousStep,
    isFirstStep,
    isLastStep,
    handleSubmit,
    control,
    errors,
    register,
  } = useMultiStepForm<FormData>({
    steps,
    schema,
    initialValues: { name: "", age: 0 },
  });

  const onSubmit = (data: FormData) => {
    console.log(data);
  };

  return (
    <form noValidate onSubmit={handleSubmit(onSubmit)}>
      <CurrentStep control={control} register={register} errors={errors} />
      {!isFirstStep && (
        <button type="button" onClick={() => goToPreviousStep()}>
          Back
        </button>
      )}
      {!isLastStep && (
        <button type="button" onClick={() => goToNextStep()}>
          Next
        </button>
      )}
      {isLastStep && <button type="submit">Submit</button>}
    </form>
  );
};

Using trigger for Field-Specific Validation

The useMultiStepForm hook leverages react-hook-form's trigger function to validate only the fields present in the current step before moving to the next one. This ensures that each form step only validates the fields it's responsible for, enhancing performance and making the validation process more intuitive.

In the goToNextStep function, the trigger method is used with the list of fields from the current step, which ensures that only the fields in that step are validated before the form transitions to the next step. If validation fails, the user is not allowed to move to the next step until the errors are resolved.

Example:

const goToNextStep = useCallback(async () => {
  const isValid = await trigger(steps[currentStepIndex].fields); // Only validate current step fields
  if (!isValid) return;

  setCurrentStepIndex((prevStep) =>
    prevStep < steps.length - 1 ? prevStep + 1 : prevStep
  );
}, [currentStepIndex, steps, trigger]);

This approach ensures that each form step only validates the relevant fields, which makes the process more efficient and prevents unnecessary validation across the entire form.

Optional: Separate out Navigation Button logic

type FormNavButtonsProps = {
  goToPreviousStep: () => void;
  goToNextStep: () => Promise<void>;
  isFirstStep: boolean;
  isLastStep: boolean;
};

export const FormNavButtons: React.FC<FormNavButtonsProps> = ({
  goToPreviousStep,
  goToNextStep,
  isFirstStep,
  isLastStep,
}) => {
  return (
    <nav>
      {!isFirstStep && (
        <button type="button" onClick={goToPreviousStep}>
          Back
        </button>
      )}
      {!isLastStep && (
        <button type="button" onClick={goToNextStep}>
          Next
        </button>
      )}
      {isLastStep && <button type="submit">Submit</button>}
    </nav>
  );
};

Step-by-Step Guide

  1. Define a Zod schema: This schema validates each step of your form.
  2. Create form step components: Use the FormStepComponent type to build form components that handle form fields and errors.
  3. Define form steps: Create an array of objects where each object contains a component and fields that correspond to the Zod schema.
  4. Use the useMultiStepForm hook: Manage form state, navigation, and validation across steps.
  5. Render the form: Use the hook's goToNextStep and goToPreviousStep functions to control navigation between steps.

API Reference

Parameters

The useMultiStepForm hook accepts the following parameters:

  • steps: An array of form steps, each with a component and a list of fields to validate.
  • schema: A Zod schema that defines the structure and validation rules for your form data.
  • initialValues: The initial values for each form field.

The hook also accepts a generic type that can be inferred from your Zod schema, allowing for type-safe form handling.

Return Values

The hook returns an object containing the following properties:

  • CurrentStep: The current form step component to render.
  • currentStepIndex: The index of the current step.
  • setCurrentStepIndex: A function to manually set the current step index.
  • goToNextStep: Function to move to the next step, ensuring the current step's validation passes.
  • goToPreviousStep: Function to move to the previous step.
  • isFirstStep: Boolean indicating if the current step is the first step.
  • isLastStep: Boolean indicating if the current step is the last step.
  • handleSubmit: The form submission handler from react-hook-form.
  • control: The control object from react-hook-form for managing form fields.
  • errors: An object containing validation errors for each form field.
  • register: The register function from react-hook-form for registering form fields.

License

This project is licensed under the Apache License 2.0.


This package simplifies the process of building multi-step forms with Zod validation in React. If you encounter any issues or have suggestions for improvements, feel free to open an issue or contribute to the repository!