Skip to content

Instantly share code, notes, and snippets.

@ChaseH88
Created October 18, 2023 17:49
Show Gist options
  • Save ChaseH88/bae233afc01faf7a944b05e5d6f6a2e4 to your computer and use it in GitHub Desktop.
Save ChaseH88/bae233afc01faf7a944b05e5d6f6a2e4 to your computer and use it in GitHub Desktop.
React and TypeScript hook that allows you to build out your own step wizard component.
import React, { useState, useCallback, useMemo, ReactNode } from 'react';
interface Step {
component: ReactNode;
name: string;
}
interface StepWizardHook {
currentStep: Step;
next: () => void;
back: () => void;
jumpToStepByNumber: (index: number) => void;
jumpToStepByName: (name: string) => void;
canGoBack: boolean;
canGoForward: boolean;
}
export const useStepWizard = (steps: Step[]): StepWizardHook => {
const [currentStepIndex, setCurrentStepIndex] = useState(0);
const canGoBack = useMemo(() => currentStepIndex > 0, [currentStepIndex]);
const canGoForward = useMemo(() => currentStepIndex < steps.length - 1, [currentStepIndex, steps.length]);
const next = useCallback(() => {
if (canGoForward) {
setCurrentStepIndex(currentStepIndex + 1);
}
}, [canGoForward, currentStepIndex]);
const back = useCallback(() => {
if (canGoBack) {
setCurrentStepIndex(currentStepIndex - 1);
}
}, [canGoBack, currentStepIndex]);
const jumpToStepByNumber = useCallback((index: number) => {
if (index >= 0 && index < steps.length) {
setCurrentStepIndex(index);
}
}, [steps.length]);
const jumpToStepByName = useCallback((name: string) => {
const index = steps.findIndex(step => step.name === name);
if (index !== -1) {
setCurrentStepIndex(index);
}
}, [steps]);
return {
currentStep: steps[currentStepIndex],
next,
back,
jumpToStepByNumber,
jumpToStepByName,
canGoBack,
canGoForward,
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment