Created
June 25, 2024 19:49
-
-
Save devrnt/454e20467d1f6af2195df6ebdf92a940 to your computer and use it in GitHub Desktop.
Simple wizard
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useState } from 'react'; | |
type WizardConfig<T> = { | |
[K in keyof T]: { | |
previous?: ((activeStep: keyof T, payload?: any) => keyof T) | keyof T; | |
next?: ((activeStep: keyof T, payload?: any) => keyof T) | keyof T; | |
}; | |
}; | |
type BaseConfig = Record<string, any>; | |
const createWizardConfig = <T extends BaseConfig>( | |
config: WizardConfig<T>, | |
): WizardConfig<T> => config; | |
function useWizard<T extends BaseConfig>(config: WizardConfig<T>) { | |
const [activeStep, setActiveStep] = useState<keyof T>(Object.keys(config)[0]); | |
const previous = (payload?: any) => { | |
const prev = config[activeStep].previous; | |
if (typeof prev === 'function') { | |
const newStep = prev(activeStep, payload); | |
setActiveStep(newStep); | |
} else if (prev !== undefined) { | |
setActiveStep(prev); | |
} | |
}; | |
const next = (payload?: any) => { | |
const next = config[activeStep].next; | |
if (typeof next === 'function') { | |
const newStep = next(activeStep, payload); | |
setActiveStep(newStep); | |
} else if (next !== undefined) { | |
setActiveStep(next); | |
} | |
}; | |
return { active: activeStep, previous, next }; | |
} | |
// Example Usage | |
const onboardingWizard = createWizardConfig({ | |
start: { | |
next: 'personalDetails', | |
}, | |
personalDetails: { | |
previous: () => 'start', | |
next: () => 'end', | |
}, | |
end: { | |
previous: () => 'personalDetails', | |
}, | |
}); | |
const WizardComponent = () => { | |
const { active, previous, next } = useWizard(onboardingWizard); | |
return ( | |
<div> | |
<p>Current Step: {active}</p> | |
<button | |
onClick={() => { | |
previous(); | |
}} | |
> | |
Previous | |
</button> | |
<button | |
onClick={() => { | |
next(); | |
}} | |
> | |
Next | |
</button> | |
</div> | |
); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment