@octopusdeploy/design-system-components
Version:
The design systems component library.
98 lines (97 loc) • 3.49 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.useDialogSteps = useDialogSteps;
const react_1 = require("react");
function useDialogSteps(steps) {
const [currentStepIndex, setCurrentStepIndex] = (0, react_1.useState)(0);
const [isNavigating, setIsNavigating] = (0, react_1.useState)(false);
const stepsRef = (0, react_1.useRef)(steps);
stepsRef.current = steps;
const currentStepIndexRef = (0, react_1.useRef)(currentStepIndex);
currentStepIndexRef.current = currentStepIndex;
const isNavigatingRef = (0, react_1.useRef)(false);
const isFirstStep = currentStepIndex === 0;
const isLastStep = steps.length === 0 || currentStepIndex === steps.length - 1;
const goToNext = (0, react_1.useCallback)(async () => {
if (isNavigatingRef.current)
return false;
const allSteps = stepsRef.current;
const index = currentStepIndexRef.current;
if (index >= allSteps.length - 1)
return false;
const currentStep = allSteps[index];
if (currentStep?.onBeforeNext) {
isNavigatingRef.current = true;
setIsNavigating(true);
let canProceed = false;
try {
canProceed = await currentStep.onBeforeNext();
}
catch {
canProceed = false;
}
finally {
isNavigatingRef.current = false;
setIsNavigating(false);
}
if (!canProceed)
return false;
}
const nextIndex = index + 1;
setCurrentStepIndex(nextIndex);
const nextStep = allSteps[nextIndex];
if (nextStep?.onEnter) {
try {
await nextStep.onEnter();
}
catch {
// onEnter errors are non-blocking — step has already transitioned.
}
}
return true;
}, []);
const goToPrevious = (0, react_1.useCallback)(async () => {
if (isNavigatingRef.current)
return false;
const allSteps = stepsRef.current;
const index = currentStepIndexRef.current;
if (index <= 0)
return false;
const currentStep = allSteps[index];
if (currentStep?.onBeforeBack) {
isNavigatingRef.current = true;
setIsNavigating(true);
let canProceed = false;
try {
canProceed = await currentStep.onBeforeBack();
}
catch {
canProceed = false;
}
finally {
isNavigatingRef.current = false;
setIsNavigating(false);
}
if (!canProceed)
return false;
}
const prevIndex = index - 1;
setCurrentStepIndex(prevIndex);
const prevStep = allSteps[prevIndex];
if (prevStep?.onEnter) {
try {
await prevStep.onEnter();
}
catch {
// onEnter errors are non-blocking — step has already transitioned.
}
}
return true;
}, []);
const reset = (0, react_1.useCallback)(() => {
setCurrentStepIndex(0);
isNavigatingRef.current = false;
setIsNavigating(false);
}, []);
return { currentStepIndex, totalSteps: steps.length, isFirstStep, isLastStep, isNavigating, goToNext, goToPrevious, reset };
}