react-use-wizard
Version:
React wizard (stepper) builder without the hassle, powered by hooks.
132 lines (111 loc) • 3.79 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var React = require('react');
/**
* Log messages in the console with a corresponding urgency
*
* @param level The urgency of the message
* @param message The message to log in the console
*/
const log = (level, message) => {
{
const packageName = '[react-use-wizard]';
switch (level) {
case 'warn':
console.warn(packageName + " " + message);
break;
case 'error':
console.error(packageName + " " + message);
break;
default:
console.log(packageName + " " + message);
}
}
};
const WizardContext = /*#__PURE__*/React.createContext(null);
WizardContext.displayName = 'WizardContext';
const Wizard = /*#__PURE__*/React.memo(({
header,
footer,
children,
startIndex = 0
}) => {
const [activeStep, setActiveStep] = React.useState(startIndex);
const [isLoading, setIsLoading] = React.useState(false);
const hasNextStep = React.useRef(true);
const hasPreviousStep = React.useRef(false);
const nextStepHandler = React.useRef(() => {});
hasNextStep.current = activeStep < React.Children.toArray(children).length - 1;
hasPreviousStep.current = activeStep > 0;
const goToNextStep = React.useRef(stepIndex => {
if (hasNextStep.current) {
setActiveStep(activeStep => stepIndex != null ? stepIndex : activeStep + 1);
}
});
const goToPreviousStep = React.useRef(step => {
if (hasPreviousStep.current) {
setActiveStep(activeStep => step != null ? step : activeStep - 1);
}
}); // Callback to attach the step handler
const handleStep = React.useRef(handler => {
nextStepHandler.current = handler;
});
const doNextStep = React.useRef(async stepIndex => {
if (hasNextStep.current && nextStepHandler.current) {
try {
setIsLoading(true);
await nextStepHandler.current();
setIsLoading(false);
nextStepHandler.current = null;
goToNextStep.current(stepIndex);
} catch (error) {
setIsLoading(false);
throw error;
}
} else {
goToNextStep.current(stepIndex);
}
});
const wizardValue = React.useMemo(() => ({
nextStep: doNextStep.current,
previousStep: goToPreviousStep.current,
handleStep: handleStep.current,
isLoading,
activeStep,
isFirstStep: !hasPreviousStep.current,
isLastStep: !hasNextStep.current
}), [activeStep, isLoading]);
const activeStepContent = React.useMemo(() => {
const reactChildren = React.Children.toArray(children);
{
// No steps passed
if (reactChildren.length === 0) {
log('warn', 'Make sure to pass your steps as children in your <Wizard>');
} // The passed start index is invalid
if (activeStep > reactChildren.length) {
log('warn', 'An invalid startIndex is passed to <Wizard>');
} // Invalid header element
if (header && !React.isValidElement(header)) {
log('error', 'Invalid header passed to <Wizard>');
} // Invalid footer element
if (footer && !React.isValidElement(footer)) {
log('error', 'Invalid footer passed to <Wizard>');
}
}
return reactChildren[activeStep];
}, [activeStep, children, header, footer]);
return React.createElement(WizardContext.Provider, {
value: wizardValue
}, React.createElement(React.Fragment, null, header, activeStepContent, footer));
});
const useWizard = () => {
const context = React.useContext(WizardContext);
if (!context && "development" !== "production") {
throw Error('Wrap your step with `Wizard`');
} else {
return context;
}
};
exports.Wizard = Wizard;
exports.useWizard = useWizard;
//# sourceMappingURL=react-use-wizard.cjs.development.js.map