Back

Stepper

A React component for building multistep forms with ease.

1 / 4

Component snippet

Create a file called Stepper.tsx with this snippet and paste the types in Import section.

type StepperProps = {
  stepIndex: number;
  totalSteps: number;
  className?: string;
};

Now paste this snippet and import it in your component. and don't forget to customize the component according to your object interface.

const Stepper = ({ stepIndex, totalSteps, className }: StepperProps) => {
  
  if (totalSteps < 2) throw new Error("Stepper needs at least 2 steps");
  const stepPercentage = 100 / totalSteps;
  const stepWidth = `${(stepIndex + 1) * stepPercentage}%`;
  const completedWidth = `${stepIndex * stepPercentage}%`;

  return (
    <div className={`w-full h-1 bg-gray-200 ${className || ""}`}>
      <div
        className="absolute top-0 left-0 h-full bg-blue-300"
        style={{ width: completedWidth }}
      />
      <div
        className="absolute top-0 left-0 h-full bg-blue-700"
        style={{ width: stepWidth }}
      />
    </div>
  );
};

export default Stepper;

Usage

This snippet shows how to use this component. It has some helper functions for updating the state. It is recommended to use this with a useMultistepForm hook.

"use client"

import { IoArrowBack, IoArrowForward } from "react-icons/io5";
import Stepper from "./Stepper";
import { useState } from "react";

const MAX_STEPS = 4

const StepperDemo = () => {

  const [currentStepIndex, setCurrentStepIndex] = useState(0)

  function next() {
    setCurrentStepIndex((i) => {
      if (i >= MAX_STEPS - 1) return i;
      return ++i;
    });
  };

  function back() {
    setCurrentStepIndex((i) => {
      if (i <= 0) return i;
      return --i;
    });
  };

  return (
    <div className="text-zinc-100 relative overflow-hidden bg-zinc-800/70 shadow-md flex justify-between items-center p-6 rounded-xl">
      <Stepper
        className="absolute top-0 right-0"
        totalSteps={MAX_STEPS}
        stepIndex={currentStepIndex}
      />
      <span className="text-sm">
        {currentStepIndex + 1} / {MAX_STEPS}
      </span>
      <div className="flex justify-center items-center text-sm w-fit top-3 left-0 text-zinc-300 hover:text-white cursor-pointer space-x-2">
        <button
          type="button"
          onClick={back}
          disabled={currentStepIndex > 0 ? false : true}
          className="!bg-transparent flex justify-center items-center text-sm text-zinc-300 hover:text-white disabled:cursor-not-allowed cursor-pointer space-x-2"
        >
          <IoArrowBack />
        </button>
        <button
          type="button"
          onClick={next}
          disabled={currentStepIndex < MAX_STEPS - 1 ? false : true}
          className="!bg-transparent flex justify-center items-center text-sm text-zinc-300 hover:text-white disabled:cursor-not-allowed cursor-pointer space-x-2"
        >
          <IoArrowForward />
        </button>
      </div>
    </div>
  )
}

export default StepperDemo

Made by Dhvanit. Visit my portfolio.