Indicate progress through numbered steps in multi-step workflows.
Here's the <Stepper /> component in action.
// StepperContext.jsimport { useState, cloneElement, Children, type ReactElement, type ReactNode } from 'react'import { Button } from '../buttons/button'import { Flex } from '../layout/flex'
interface StepperProps { initialStep?: number children: ReactElement | ReactElement[]}
const Stepper = ({ initialStep = 0, children }: StepperProps) => { const [currentStep, setCurrentStep] = useState(initialStep)
const goToNextStep = () => setCurrentStep(prev => prev + 1) const goToPreviousStep = () => setCurrentStep(prev => prev - 1)
return ( <div className="stepper flex flex-col gap-fluid-4"> {Children.map(children, (child, index) => { if (child.type === Step || child.type === StepperNavigation) { return cloneElement(child, { currentStep, goToNextStep, goToPreviousStep, index }) } return child })} </div> )}
interface StepProps { currentStep?: number index?: number children: ReactNode}
const Step = ({ currentStep, index, children }: StepProps) => { return <div className={`step ${currentStep === index ? 'active block' : 'hidden'}`}>{currentStep === index && children}</div>}
interface StepperNavigationProps { currentStep?: number goToNextStep?: () => void goToPreviousStep?: () => void}
const StepperNavigation = ({ currentStep, goToNextStep, goToPreviousStep }: StepperNavigationProps) => { return ( <Flex gap="4"> <Button variant="secondary" onPress={goToPreviousStep} isDisabled={currentStep === 0}> Previous </Button> <Button variant="secondary" onPress={goToNextStep} isDisabled={false}> Next </Button> </Flex> )}
export { Stepper, Step, StepperNavigation }