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

Latest comments (0)

An Animated Guide to Node.js Event Loop

Node.js doesn’t stop from running other operations because of Libuv, a C++ library responsible for the event loop and asynchronously handling tasks such as network requests, DNS resolution, file system operations, data encryption, etc.

What happens under the hood when Node.js works on tasks such as database queries? We will explore it by following this piece of code step by step.