damianricobelli / stepperize

A library for creating step-by-step workflows in your apps
https://stepperize.vercel.app
916 stars 40 forks source link

Form validation and performing actions on navigating steps #21

Closed aubaraka closed 2 months ago

aubaraka commented 3 months ago

Great component but how do I get the react-hook-form validation to be triggered when clicking the next button considering subsequent steps might need actions of their own.

"use client";

import { TeacherForm } from "@/components/forms/TeacherForm";
import { Step, type StepItem, Stepper, useStepper } from "@/components/stepper";
import { Button } from "@/components/ui/button";
import { User } from "@/types";
import React, { Dispatch, SetStateAction } from "react";
import TeacherSubjectChecklist from "./teacherSubject/TeacherSubjectChecklist";

const steps = [{ label: "Bio" }, { label: "Subjects" }] satisfies StepItem[];

export default function TeacherStepper({
  teacher,
  setOpen,
  type = "create",
}: {
  type: "create" | "delete" | "edit";
  teacher?: User;
  setOpen?: Dispatch<SetStateAction<boolean>>;
}) {
  return (
    <div className="flex w-full flex-col gap-4">
      <Stepper
        initialStep={0}
        steps={steps}
        variant="circle-alt"
        //styles={{ "step-label-container": "bg-green-500" }}
      >
        {steps.map(({ label }, index) => {
          switch (label) {
            case "Bio":
              return (
                <Step key={label} label={label}>
                  <TeacherForm
                    type={type}
                    teacher={teacher}
                    setOpen={setOpen}
                  />
                </Step>
              );
            case "Subjects":
              return (
                <Step key={label} label={label}>
                  <TeacherSubjectChecklist />
                </Step>
              );
          }
        })}
        <Footer />
      </Stepper>
    </div>
  );
}

const Footer = () => {
  const {
    nextStep,
    prevStep,
    resetSteps,
    isDisabledStep,
    hasCompletedAllSteps,
    isLastStep,
    isOptionalStep,
  } = useStepper();
  return (
    <>
      {hasCompletedAllSteps && (
        <div className="h-40 flex items-center justify-center my-4 border bg-secondary text-primary rounded-md">
          <h1 className="text-xl">Woohoo! All steps completed! 🎉</h1>
        </div>
      )}
      <div className="w-full flex justify-end gap-2">
        {hasCompletedAllSteps ? (
          <Button size="sm" onClick={resetSteps}>
            Reset
          </Button>
        ) : (
          <>
            <Button
              disabled={isDisabledStep}
              onClick={prevStep}
              size="sm"
              variant="secondary"
            >
              Prev
            </Button>
            <Button size="sm" onClick={nextStep}>
              {isLastStep ? "Finish" : isOptionalStep ? "Skip" : "Next"}
            </Button>
          </>
        )}
      </div>
    </>
  );
};
aubaraka commented 3 months ago

Addressed using forwarRef

damianricobelli commented 2 months ago

I close this issue as you will be able to build what you are looking for in a more customised way through the @stepperize/react library related to this repo.