@@ -12,6 +12,7 @@ import useArrowKeyFocusManager from '@hooks/useArrowKeyFocusManager';
1212import useDebounce from '@hooks/useDebounce' ;
1313import useKeyboardShortcut from '@hooks/useKeyboardShortcut' ;
1414import useKeyboardState from '@hooks/useKeyboardState' ;
15+ import usePrevious from '@hooks/usePrevious' ;
1516import useSafeAreaPaddings from '@hooks/useSafeAreaPaddings' ;
1617import useScrollEnabled from '@hooks/useScrollEnabled' ;
1718import useSingleExecution from '@hooks/useSingleExecution' ;
@@ -288,7 +289,6 @@ function BaseSelectionList<TItem extends ListItem>({
288289 onFocusChange = { ( v : boolean ) => ( isTextInputFocusedRef . current = v ) }
289290 showLoadingPlaceholder = { showLoadingPlaceholder }
290291 isLoadingNewOptions = { isLoadingNewOptions }
291- setFocusedIndex = { setFocusedIndex }
292292 />
293293 ) ;
294294 } ;
@@ -392,6 +392,52 @@ function BaseSelectionList<TItem extends ListItem>({
392392 [ data . length , scrollToIndex , setFocusedIndex ] ,
393393 ) ;
394394
395+ const prevSearchValue = usePrevious ( textInputOptions ?. value ) ;
396+ const prevSelectedOptionsLength = usePrevious ( dataDetails . selectedOptions . length ) ;
397+ const prevAllOptionsLength = usePrevious ( data . length ) ;
398+
399+ useEffect ( ( ) => {
400+ const currentSearchValue = textInputOptions ?. value ;
401+ const searchChanged = prevSearchValue !== currentSearchValue ;
402+ const selectedOptionsChanged = dataDetails . selectedOptions . length !== prevSelectedOptionsLength ;
403+ // Focus shouldn't be changed if: input value is the same or data length is 0
404+ // shouldUpdateFocusedIndex is true => other function handles the focus
405+ if ( ( ! searchChanged && ! selectedOptionsChanged ) || data . length === 0 || shouldUpdateFocusedIndex ) {
406+ return ;
407+ }
408+
409+ // Clearing search
410+ if ( prevSearchValue && ! currentSearchValue ) {
411+ const foundSelectedItemIndex = data . findIndex ( isItemSelected ) ;
412+
413+ if ( foundSelectedItemIndex !== - 1 && ! canSelectMultiple ) {
414+ scrollToIndex ( foundSelectedItemIndex ) ;
415+ setFocusedIndex ( foundSelectedItemIndex ) ;
416+ return ;
417+ }
418+ }
419+
420+ // Remove focus (-1) if the search is idle or if the user is just toggling options without changing the list content
421+ // Otherwise (e.g. when filtering/typing), focus on the first item (0)
422+ const isSearchIdle = ! prevSearchValue && ! currentSearchValue ;
423+ const newSelectedIndex = isSearchIdle || ( selectedOptionsChanged && prevAllOptionsLength === data . length ) ? - 1 : 0 ;
424+
425+ scrollToIndex ( newSelectedIndex ) ;
426+ setFocusedIndex ( newSelectedIndex ) ;
427+ } , [
428+ canSelectMultiple ,
429+ data ,
430+ dataDetails . selectedOptions . length ,
431+ isItemSelected ,
432+ prevAllOptionsLength ,
433+ prevSelectedOptionsLength ,
434+ prevSearchValue ,
435+ scrollToIndex ,
436+ setFocusedIndex ,
437+ shouldUpdateFocusedIndex ,
438+ textInputOptions ?. value ,
439+ ] ) ;
440+
395441 useEffect ( ( ) => {
396442 if ( ! itemFocusTimeoutRef . current ) {
397443 return ;
0 commit comments