1
- import React , { Children , cloneElement , isValidElement } from 'react' ;
1
+ import React , { Children , isValidElement } from 'react' ;
2
2
3
+ import { Direction } from '@leafygreen-ui/descendants' ;
4
+ import { findChild } from '@leafygreen-ui/lib' ;
5
+
6
+ import { WIZARD_FOOTER_KEY } from '../constants' ;
3
7
import { useWizardControlledValue } from '../utils/useWizardControlledValue/useWizardControlledValue' ;
8
+ import { WizardContext } from '../WizardContext/WizardContext' ;
4
9
import { WizardFooter } from '../WizardFooter' ;
5
10
import { WizardStep } from '../WizardStep' ;
6
11
@@ -16,23 +21,10 @@ export function Wizard({
16
21
const {
17
22
isControlled,
18
23
value : activeStep ,
19
- setValue : setInternalActiveStep ,
24
+ setValue : setActiveStep ,
20
25
} = useWizardControlledValue < number > ( activeStepProp , undefined , 0 ) ;
21
26
22
- // Handle step changes
23
- const handleStepChange = ( newStep : number ) => {
24
- if ( ! isControlled ) {
25
- setInternalActiveStep ( newStep ) ;
26
- }
27
- onStepChange ?.( newStep ) ;
28
- } ;
29
-
30
- // Filter children to separate steps from footer
31
- const childrenArray = Children . toArray ( children ) ;
32
-
33
- // For now, we'll look for components with displayName ending in 'Step' or 'Footer'
34
- // This will be more precise once Wizard.Step and Wizard.Footer are implemented
35
- const stepChildren = childrenArray . filter ( child => {
27
+ const stepChildren = Children . toArray ( children ) . filter ( child => {
36
28
if ( isValidElement ( child ) ) {
37
29
const displayName = ( child . type as any ) ?. displayName ;
38
30
return displayName && displayName . includes ( 'Step' ) ;
@@ -41,38 +33,41 @@ export function Wizard({
41
33
return false ;
42
34
} ) ;
43
35
44
- const footerChild = childrenArray . find ( child => {
45
- if ( isValidElement ( child ) ) {
46
- const displayName = ( child . type as any ) ?. displayName ;
47
- return displayName && displayName . includes ( 'Footer' ) ;
36
+ const updateStep = ( direction : Direction ) => {
37
+ const getNextStep = ( curr : number ) => {
38
+ switch ( direction ) {
39
+ case Direction . Next :
40
+ return Math . min ( curr + 1 , stepChildren . length - 1 ) ;
41
+ case Direction . Prev :
42
+ return Math . max ( curr - 1 , 0 ) ;
43
+ }
44
+ } ;
45
+
46
+ if ( ! isControlled ) {
47
+ setActiveStep ( getNextStep ) ;
48
48
}
49
49
50
- return false ;
51
- } ) ;
50
+ onStepChange ?.( getNextStep ( activeStep ) ) ;
51
+ } ;
52
+
53
+ const footerChild = findChild ( children , WIZARD_FOOTER_KEY ) ;
52
54
53
55
// Get the current step to render
54
56
const currentStep = stepChildren [ activeStep ] || null ;
55
57
56
- // Clone footer with step navigation handlers if it exists
57
- const clonedFooter =
58
- footerChild && isValidElement ( footerChild )
59
- ? cloneElement ( footerChild as React . ReactElement < any > , {
60
- activeStep,
61
- totalSteps : stepChildren . length ,
62
- onStepChange : handleStepChange ,
63
- isControlled,
64
- } )
65
- : null ;
66
-
67
58
return (
68
- < div className = { wizardContainerStyles } >
69
- < code > activeStep: { activeStep } </ code >
70
- { /* Render current step */ }
71
- < div className = { stepContentStyles } > { currentStep } </ div >
72
-
73
- { /* Render footer */ }
74
- { clonedFooter }
75
- </ div >
59
+ < WizardContext . Provider
60
+ value = { {
61
+ activeStep,
62
+ updateStep,
63
+ } }
64
+ >
65
+ < div className = { wizardContainerStyles } >
66
+ < div className = { stepContentStyles } > { currentStep } </ div >
67
+ { /* Render footer */ }
68
+ { footerChild }
69
+ </ div >
70
+ </ WizardContext . Provider >
76
71
) ;
77
72
}
78
73
0 commit comments