diff --git a/src/components/Stepper/Stepper.stories.tsx b/src/components/Stepper/Stepper.stories.tsx new file mode 100644 index 00000000..8a38de0f --- /dev/null +++ b/src/components/Stepper/Stepper.stories.tsx @@ -0,0 +1,21 @@ +import { Stepper } from "./Stepper"; + +export default { title: "Components/Stepper", component: Stepper }; + +export const _Stepper = { + render: () => ( + <> + Step 1/3 + +
+ Step 2/3 + +
+ Step 3/3 + +
+ Step 3/3 (with check completed) + + + ), +}; diff --git a/src/components/Stepper/Stepper.test.tsx b/src/components/Stepper/Stepper.test.tsx new file mode 100644 index 00000000..9dd540ff --- /dev/null +++ b/src/components/Stepper/Stepper.test.tsx @@ -0,0 +1,38 @@ +import "@testing-library/jest-dom"; +import { render, screen, within } from "@testing-library/react"; +import { Stepper } from "."; + +describe("Components | Stepper", () => { + test("it should render", () => { + render(); + + let stepper = screen.getByTestId("stepper"); + + expect(stepper).toBeInTheDocument(); + }); + + test("it has the first step in stepIn mode", () => { + render(); + + let step0 = screen.getByTestId("stepper-item-0"); + let stepIn = within(step0).getByTestId("stepper-step-in"); + + expect(stepIn).toBeInTheDocument(); + }); + + test("it has the 1st step as StepPast mode, the 2nd in stepIn and 3rd as StepNext", () => { + render(); + + let step0 = screen.getByTestId("stepper-item-0"); + let step1 = screen.getByTestId("stepper-item-1"); + let step2 = screen.getByTestId("stepper-item-2"); + + let stepPast = within(step0).getByTestId("stepper-step-past"); + let stepIn = within(step1).getByTestId("stepper-step-in"); + let stepNext = within(step2).getByTestId("stepper-step-next"); + + expect(stepIn).toBeInTheDocument(); + expect(stepPast).toBeInTheDocument(); + expect(stepNext).toBeInTheDocument(); + }); +}); diff --git a/src/components/Stepper/Stepper.tsx b/src/components/Stepper/Stepper.tsx new file mode 100644 index 00000000..89fcb7ee --- /dev/null +++ b/src/components/Stepper/Stepper.tsx @@ -0,0 +1,86 @@ +import { ComponentPropsWithoutRef } from "react"; +import { FiCircle } from "react-icons/fi"; + +export interface StepperProps extends ComponentPropsWithoutRef<"ol"> { + steps: string[]; + step: number; +} + +let baseStepClass = + "flex items-center justify-center w-4 h-4 rounded-full shrink-0"; + +function StepIn() { + return ( + + + + ); +} + +function StepNext() { + return ( + + + + ); +} + +function StepPast() { + return ( + + ); +} + +export function Stepper(props: StepperProps) { + const { step, steps } = props; + + const edgeClass = "after:w-full after:border-b after:inline-block"; + const edgePastClass = edgeClass + " after:border-c-default"; + const edgeNextClass = edgeClass + " after:border-s-success"; + + return ( +
    + {steps.map((s, idx) => { + let isLastStep = idx === steps.length - 1; + let stepClass = isLastStep ? "" : edgeClass; + let flowClass = isLastStep ? "" : edgePastClass; + let textClass = "text-f-primary"; + + let currentStep = ; + + if (idx === step) { + currentStep = ; + } else if (idx < step) { + currentStep = ; + textClass = "text-f-tertiary"; + flowClass = isLastStep ? "" : edgeNextClass; + } + + return ( +
  1. + {currentStep} +
    + {s} +
    +
  2. + ); + })} +
+ ); +} diff --git a/src/components/Stepper/index.ts b/src/components/Stepper/index.ts new file mode 100644 index 00000000..e8df8287 --- /dev/null +++ b/src/components/Stepper/index.ts @@ -0,0 +1 @@ +export * from "./Stepper";