Skip to content

Commit 74506fe

Browse files
committed
feat: add step index to next and previous step
1 parent c62e567 commit 74506fe

File tree

3 files changed

+64
-10
lines changed

3 files changed

+64
-10
lines changed

src/types.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,18 @@ export type WizardProps = {
1010
};
1111

1212
export type WizardValues = {
13-
/** Go to the next step */
14-
nextStep: () => Promise<void>;
15-
/** Go to the previous step */
16-
previousStep: () => void;
13+
/**
14+
* Go to the next step
15+
*
16+
* @param stepIndex Overwrite the default behaviour by providing a step index
17+
*/
18+
nextStep: (stepIndex?: number) => Promise<void>;
19+
/**
20+
* Go to the previous step
21+
*
22+
* @param stepIndex Overwrite the default behaviour by providing a step index
23+
* */
24+
previousStep: (stepIndex?: number) => void;
1725
/**
1826
* Attach a callback that will be called when calling `nextStep()`
1927
*

src/wizard.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ const Wizard: React.FC<WizardProps> = React.memo(
1616
activeStep < React.Children.toArray(children).length - 1;
1717
hasPreviousStep.current = activeStep > 0;
1818

19-
const goToNextStep = React.useRef(() => {
19+
const goToNextStep = React.useRef((stepIndex?: number) => {
2020
if (hasNextStep.current) {
21-
setActiveStep((activeStep) => activeStep + 1);
21+
setActiveStep((activeStep) => stepIndex ?? activeStep + 1);
2222
}
2323
});
2424

25-
const previousStep = React.useRef(() => {
25+
const previousStep = React.useRef((step?: number) => {
2626
if (hasPreviousStep.current) {
27-
setActiveStep((activeStep) => activeStep - 1);
27+
setActiveStep((activeStep) => step ?? activeStep - 1);
2828
}
2929
});
3030

@@ -33,14 +33,14 @@ const Wizard: React.FC<WizardProps> = React.memo(
3333
nextStepHandler.current = handler;
3434
});
3535

36-
const doNextStep = React.useRef(async () => {
36+
const doNextStep = React.useRef(async (stepIndex?: number) => {
3737
if (hasNextStep.current && nextStepHandler.current) {
3838
try {
3939
setIsLoading(true);
4040
await nextStepHandler.current();
4141
setIsLoading(false);
4242
nextStepHandler.current = null;
43-
goToNextStep.current();
43+
goToNextStep.current(stepIndex);
4444
} catch (error) {
4545
setIsLoading(false);
4646
throw error;

test/useWizard.test.tsx

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,52 @@ describe('useWizard', () => {
9191
});
9292
});
9393

94+
test('should go to passed step index on next step', () => {
95+
const { result } = renderHook(() => useWizard(), {
96+
wrapper: ({ children }: { children: React.ReactNode }) => {
97+
return <Wizard>{children}</Wizard>;
98+
},
99+
initialProps: {
100+
children: (
101+
<>
102+
<p>step 1</p>
103+
<p>step 2</p>
104+
<p>step 3</p>
105+
</>
106+
),
107+
},
108+
});
109+
// Wait for an element to appear
110+
waitFor(() => {
111+
result.current.nextStep(2);
112+
expect(result.current.isFirstStep).toBe(false);
113+
expect(result.current.isLastStep).toBe(true);
114+
});
115+
});
116+
117+
test('should go to passed step index on previous step', () => {
118+
const { result } = renderHook(() => useWizard(), {
119+
wrapper: ({ children }: { children: React.ReactNode }) => {
120+
return <Wizard>{children}</Wizard>;
121+
},
122+
initialProps: {
123+
children: (
124+
<>
125+
<p>step 1</p>
126+
<p>step 2</p>
127+
<p>step 3</p>
128+
</>
129+
),
130+
},
131+
});
132+
// Wait for an element to appear
133+
waitFor(() => {
134+
result.current.previousStep(2);
135+
expect(result.current.isFirstStep).toBe(false);
136+
expect(result.current.isLastStep).toBe(true);
137+
});
138+
});
139+
94140
test('should not go to previous step if first step', () => {
95141
const { result } = renderUseWizardHook();
96142

0 commit comments

Comments
 (0)