feat: isCompleting

This commit is contained in:
mikezzb
2023-12-03 12:50:56 -05:00
parent 340c929806
commit 859b789018

View File

@ -1,7 +1,8 @@
import React, { createContext, useContext, useEffect, useState } from 'react'; import React, { createContext, useContext, useState } from 'react';
import type { FC } from 'react'; import type { FC } from 'react';
type StepContextType = { type StepContextType = {
isCompleting: boolean;
stepIndex: number; stepIndex: number;
currentStep: number; currentStep: number;
totalSteps: number; totalSteps: number;
@ -15,10 +16,11 @@ const StepContext = createContext<StepContextType | null>(null);
type StepperProps = { type StepperProps = {
children: React.ReactNode; children: React.ReactNode;
onComplete?: () => void; onComplete?: () => void | Promise<void>;
onStepChanged?: (currentStep: number) => void; onStepChanged?: (currentStep: number) => void;
currentStep?: number; // external control prop currentStep?: number; // external control prop
setCurrentStep?: (step: number) => void; // external control function setCurrentStep?: (step: number) => void; // external control function
isAsyncComplete?: boolean;
}; };
export const Stepper: FC<StepperProps> = ({ export const Stepper: FC<StepperProps> = ({
@ -27,8 +29,10 @@ export const Stepper: FC<StepperProps> = ({
onStepChanged, onStepChanged,
currentStep: propCurrentStep, currentStep: propCurrentStep,
setCurrentStep: propSetCurrentStep, setCurrentStep: propSetCurrentStep,
isAsyncComplete,
}) => { }) => {
const [stateCurrentStep, stateSetCurrentStep] = useState(1); const [stateCurrentStep, stateSetCurrentStep] = useState(1);
const [isCompleting, setIsCompleting] = useState(false);
// Determine if props are provided, otherwise use state // Determine if props are provided, otherwise use state
const isControlled = propCurrentStep !== undefined && propSetCurrentStep !== undefined; const isControlled = propCurrentStep !== undefined && propSetCurrentStep !== undefined;
@ -37,24 +41,39 @@ export const Stepper: FC<StepperProps> = ({
const totalSteps = React.Children.count(children); const totalSteps = React.Children.count(children);
const handleComplete = async () => {
if (!onComplete) {
return;
}
if (!isAsyncComplete) {
void onComplete();
return;
}
setIsCompleting(true);
await onComplete();
// handle async complete action
setIsCompleting(false);
};
const handleStepChange = (nextStep: number) => {
setCurrentStep(nextStep);
onStepChanged && onStepChanged(nextStep);
};
const nextStep = () => { const nextStep = () => {
if (currentStep < totalSteps) { if (currentStep < totalSteps) {
setCurrentStep(currentStep + 1); void handleStepChange(currentStep + 1);
} else { } else {
onComplete && onComplete(); void handleComplete();
} }
}; };
const previousStep = () => { const previousStep = () => {
if (currentStep > 1) { if (currentStep > 1) {
setCurrentStep(currentStep - 1); void handleStepChange(currentStep - 1);
} }
}; };
useEffect(() => {
onStepChanged && onStepChanged(currentStep);
}, [currentStep, onStepChanged]);
// Empty stepper // Empty stepper
if (totalSteps === 0) { if (totalSteps === 0) {
return null; return null;
@ -63,6 +82,7 @@ export const Stepper: FC<StepperProps> = ({
const currentChild = React.Children.toArray(children)[currentStep - 1]; const currentChild = React.Children.toArray(children)[currentStep - 1];
const stepContextValue: StepContextType = { const stepContextValue: StepContextType = {
isCompleting,
stepIndex: currentStep - 1, stepIndex: currentStep - 1,
currentStep, currentStep,
totalSteps, totalSteps,