@@ -21,7 +21,7 @@ export interface StepListProps<T> extends CollectionBase<T>, SingleSelection {
2121 /** The key of the initially last completed step (uncontrolled). */
2222 defaultLastCompletedStep ?: Key ,
2323 /** Callback for when the last completed step changes. */
24- onLastCompletedStepChange ?: ( key : Key ) => void ,
24+ onLastCompletedStepChange ?: ( key : Key | null ) => void ,
2525 /** Whether the step list is disabled. Steps will not be focusable or interactive. */
2626 isDisabled ?: boolean ,
2727 /** Whether the step list is read only. Steps will be focusable but non-interactive. */
@@ -38,25 +38,29 @@ export interface StepListState<T> extends SingleSelectListState<T> {
3838export function useStepListState < T extends object > ( props : StepListProps < T > ) : StepListState < T > {
3939 let state = useSingleSelectListState < T > ( props ) ;
4040
41- let [ lastCompletedStep , setLastCompletedStep ] = useControlledState < Key > ( props . lastCompletedStep , props . defaultLastCompletedStep , props . onLastCompletedStepChange ) ;
41+ let [ lastCompletedStep , setLastCompletedStep ] = useControlledState < Key | null > ( props . lastCompletedStep , props . defaultLastCompletedStep ?? null , props . onLastCompletedStepChange ) ;
4242 const { setSelectedKey : realSetSelectedKey , selectedKey, collection} = state ;
4343 const { indexMap, keysLinkedList} = useMemo ( ( ) => buildKeysMaps ( collection ) , [ collection ] ) ;
4444 const selectedIdx = indexMap . get ( selectedKey ) ;
4545
46- const isCompleted = useCallback ( ( step : Key ) => {
46+ const isCompleted = useCallback ( ( step : Key | null | undefined ) => {
4747 if ( step === undefined ) {
4848 return false ;
4949 }
5050
51- return indexMap . get ( step ) <= indexMap . get ( lastCompletedStep ) ;
51+ return ( step !== null &&
52+ lastCompletedStep !== null &&
53+ indexMap . has ( step ) &&
54+ indexMap . has ( lastCompletedStep ) &&
55+ indexMap . get ( step ) ! <= indexMap . get ( lastCompletedStep ) ! ) ;
5256 } , [ indexMap , lastCompletedStep ] ) ;
5357
5458 const findDefaultSelectedKey = useCallback ( ( collection : Collection < Node < T > > | null , disabledKeys : Set < Key > ) => {
55- let selectedKey = null ;
56- if ( collection ) {
59+ let selectedKey : Key | null = null ;
60+ if ( collection && collection . size > 0 ) {
5761 selectedKey = collection . getFirstKey ( ) ;
5862 // loop over keys until we find one that isn't completed or disabled and select that
59- while ( selectedKey !== collection . getLastKey ( ) && ( disabledKeys . has ( selectedKey ) || isCompleted ( selectedKey ) ) ) {
63+ while ( selectedKey !== collection . getLastKey ( ) && selectedKey && ( disabledKeys . has ( selectedKey ) || isCompleted ( selectedKey ) ) ) {
6064 selectedKey = collection . getKeyAfter ( selectedKey ) ;
6165 }
6266 }
@@ -66,18 +70,21 @@ export function useStepListState<T extends object>(props: StepListProps<T>): Ste
6670
6771 useEffect ( ( ) => {
6872 // Ensure a step is always selected (in case no selected key was specified or if selected item was deleted from collection)
69- let selectedKey = state . selectedKey ;
73+ let selectedKey : Key | null = state . selectedKey ;
7074 if ( state . selectionManager . isEmpty || ! state . collection . getItem ( selectedKey ) ) {
7175 selectedKey = findDefaultSelectedKey ( state . collection , state . disabledKeys ) ;
72- state . selectionManager . replaceSelection ( selectedKey ) ;
76+ if ( selectedKey !== null ) {
77+ state . selectionManager . replaceSelection ( selectedKey ) ;
78+ }
7379 }
7480
7581 if ( state . selectionManager . focusedKey == null ) {
7682 state . selectionManager . setFocusedKey ( selectedKey ) ;
7783 }
7884
79- if ( selectedIdx > 0 && selectedIdx > ( indexMap . get ( lastCompletedStep ) ?? - 1 ) + 1 ) {
80- setLastCompletedStep ( keysLinkedList . get ( selectedKey ) ) ;
85+ let lcs = ( lastCompletedStep !== null ? indexMap . get ( lastCompletedStep ) : - 1 ) ?? - 1 ;
86+ if ( selectedIdx !== undefined && selectedIdx > 0 && selectedIdx > lcs + 1 && selectedKey !== null && keysLinkedList . has ( selectedKey ) ) {
87+ setLastCompletedStep ( keysLinkedList . get ( selectedKey ) ! ) ;
8188 }
8289 } ) ;
8390
@@ -111,11 +118,11 @@ export function useStepListState<T extends object>(props: StepListProps<T>): Ste
111118 } ;
112119}
113120
114- function buildKeysMaps < T > ( coll : Collection < Node < T > > ) : { indexMap : Map < Key , number > , keysLinkedList : Map < Key , Key > } {
121+ function buildKeysMaps < T > ( coll : Collection < Node < T > > ) {
115122 const indexMap = new Map < Key , number > ( ) ;
116- const keysLinkedList = new Map < Key , Key > ( ) ;
123+ const keysLinkedList = new Map < Key , Key | undefined > ( ) ;
117124 let i = 0 ;
118- let prev : Node < T > = undefined ;
125+ let prev : Node < T > | undefined = undefined ;
119126 for ( const item of coll ) {
120127 indexMap . set ( item . key , i ) ;
121128 keysLinkedList . set ( item . key , prev ?. key ) ;
0 commit comments