DEV Community

Gabriel Linassi
Gabriel Linassi

Posted on

 

How to create a Steps Wizzard in React

This is a quick tutorial to show you the barebones of how to create a Wizzard Steps component.

import type { NextPage } from 'next';
import React, { useReducer } from 'react';

type StepsProps = {
  children: React.ReactNode;
};

const Steps = ({ children }: StepsProps) => {
  let idx = 0;

  const _children = React.Children.map(children, (child) => {
    if (!React.isValidElement(child)) return null;
    return React.cloneElement(child, { ...child.props, idx: ++idx });
  });

  return <div className="space-y-1">{_children}</div>;
};

type StepProps = {
  title: string;
  children: React.ReactNode;
  idx?: number;
};

const Step = ({ title, idx, children }: StepProps) => {
  return (
    <div className="border border-dashed border-gray-400 p-2">
      <div className="flex gap-2">
        <span className="bg-red-300 px-1">{idx}</span>
        <h4>{title}</h4>
      </div>
      <div className="mt-2">{children}</div>
    </div>
  );
};

const Home: NextPage = () => {
  const [hasWarranty, toggleWarranty] = useReducer((s) => !s, false);

  return (
    <div className="p-4">
      <h1 className="text-2xl">Checkout</h1>
      <button
        onClick={toggleWarranty}
        className="bg-gray-700 px-2 py-1 text-white"
      >
        Toggle Warranty Step
      </button>
      <div className="mt-3">
<Steps>
  <Step title="Contact Details">Step Details</Step>
  <Step title="Aditional Add-Ons">Step Details</Step>
  {hasWarranty && <Step title="Extended Warranty">Step Details</Step>}
  <Step title="Shipping Details">Step Details</Step>
  <Step title="Payment Details">Step Details</Step>
</Steps>
      </div>
    </div>
  );
};

export default Home;

Enter fullscreen mode Exit fullscreen mode

Notice how the <Steps/> injects the idx into the <Step/> component without having to manually enter it.

const Steps = ({ children }: StepsProps) => {
  let idx = 0;

  const _children = React.Children.map(children, (child) => {
    if (!React.isValidElement(child)) return null;
    return React.cloneElement(child, { ...child.props, idx: ++idx });
  });

  return <div className="space-y-1">{_children}</div>;
};
Enter fullscreen mode Exit fullscreen mode

Oldest comments (0)

16 Libraries You Should Know as a React Developer

Being a modern React developer is not about knowing just React itself. To stay competitive, it is highly recommended to explore the whole ecosystem. This article contains some of the most useful React component libraries to speed up your developer workflow.