Skip to content

Instantly share code, notes, and snippets.

@devrnt
Created June 25, 2024 19:49
Show Gist options
  • Save devrnt/454e20467d1f6af2195df6ebdf92a940 to your computer and use it in GitHub Desktop.
Save devrnt/454e20467d1f6af2195df6ebdf92a940 to your computer and use it in GitHub Desktop.
Simple wizard
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