1- import React , { Children , cloneElement , isValidElement } from 'react' ;
1+ import React , { Children , isValidElement } from 'react' ;
22
3+ import { Direction } from '@leafygreen-ui/descendants' ;
4+ import { findChild } from '@leafygreen-ui/lib' ;
5+
6+ import { WIZARD_FOOTER_KEY } from '../constants' ;
37import { useWizardControlledValue } from '../utils/useWizardControlledValue/useWizardControlledValue' ;
8+ import { WizardContext } from '../WizardContext/WizardContext' ;
49import { WizardFooter } from '../WizardFooter' ;
510import { WizardStep } from '../WizardStep' ;
611
@@ -16,23 +21,10 @@ export function Wizard({
1621 const {
1722 isControlled,
1823 value : activeStep ,
19- setValue : setInternalActiveStep ,
24+ setValue : setActiveStep ,
2025 } = useWizardControlledValue < number > ( activeStepProp , undefined , 0 ) ;
2126
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 => {
3628 if ( isValidElement ( child ) ) {
3729 const displayName = ( child . type as any ) ?. displayName ;
3830 return displayName && displayName . includes ( 'Step' ) ;
@@ -41,38 +33,41 @@ export function Wizard({
4133 return false ;
4234 } ) ;
4335
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 ) ;
4848 }
4949
50- return false ;
51- } ) ;
50+ onStepChange ?.( getNextStep ( activeStep ) ) ;
51+ } ;
52+
53+ const footerChild = findChild ( children , WIZARD_FOOTER_KEY ) ;
5254
5355 // Get the current step to render
5456 const currentStep = stepChildren [ activeStep ] || null ;
5557
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-
6758 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 >
7671 ) ;
7772}
7873
0 commit comments