@@ -129,6 +129,7 @@ export function Toolbox<T>({
129129 const navigationStack = useNavigationStack < {
130130 items : ListItem < T > [ ] ;
131131 parentItem : ListItem < T > | null ;
132+ activeIndex : number ;
132133 } > ( ) ;
133134
134135 const [ activeIndex , setActiveIndex ] = useState ( SEARCH_BAR_INDEX ) ;
@@ -175,13 +176,19 @@ export function Toolbox<T>({
175176 [ listRef ]
176177 ) ;
177178
179+ const navigateToFirstItem = useCallback ( ( ) => {
180+ const renderedItems = listViewRef . current ?. renderedItems ?? [ ] ;
181+ const firstIndex = getFirstSelectableIndex ( renderedItems ) ;
182+ if ( firstIndex !== SEARCH_BAR_INDEX ) navigateToIndex ( firstIndex ) ;
183+ } , [ navigateToIndex ] ) ;
184+
178185 const clearSearch = useCallback ( ( ) => {
179186 setSearch ( '' ) ;
180187 setSearchedItems ( [ ] ) ;
181188 setSearchLoading ( false ) ;
182189 setIsSearchingInitialItems ( true ) ;
183- setActiveIndex ( SEARCH_BAR_INDEX ) ;
184- } , [ ] ) ;
190+ navigateToIndex ( SEARCH_BAR_INDEX ) ;
191+ } , [ navigateToIndex ] ) ;
185192
186193 const handleSearch = useCallback (
187194 async ( query : string ) => {
@@ -218,7 +225,6 @@ export function Toolbox<T>({
218225
219226 const handleBackTransition = useCallback ( ( ) => {
220227 startTransition ( 'back' ) ;
221- setActiveIndex ( SEARCH_BAR_INDEX ) ;
222228
223229 const previousState = navigationStack . pop ( ) ;
224230
@@ -227,12 +233,17 @@ export function Toolbox<T>({
227233 setCurrentParentItem ( previousState . data . parentItem ) ;
228234 }
229235
230- if ( isSearching ) {
231- clearSearch ( ) ;
232- }
236+ // Reset search state without calling clearSearch (which navigates to search bar).
237+ setSearch ( '' ) ;
238+ setSearchedItems ( [ ] ) ;
239+ setSearchLoading ( false ) ;
240+ setIsSearchingInitialItems ( true ) ;
241+
242+ const restoredIndex = previousState ?. data . activeIndex ?? SEARCH_BAR_INDEX ;
243+ navigateToIndex ( restoredIndex ) ;
233244
234245 onBack ?.( ) ;
235- } , [ navigationStack , isSearching , onBack , clearSearch , startTransition ] ) ;
246+ } , [ navigationStack , onBack , startTransition , navigateToIndex ] ) ;
236247
237248 const handleItemSelect = useCallback (
238249 async ( item : ListItem < T > ) => {
@@ -247,7 +258,11 @@ export function Toolbox<T>({
247258 : item . children ;
248259 navigationStack . push ( {
249260 title : currentParentItem ?. name || title ,
250- data : { items, parentItem : currentParentItem } ,
261+ data : {
262+ items,
263+ parentItem : currentParentItem ,
264+ activeIndex : isSearching ? SEARCH_BAR_INDEX : activeIndex ,
265+ } ,
251266 } ) ;
252267 setItems ( nestedItems ) ;
253268 setCurrentParentItem ( item ) ;
@@ -256,7 +271,17 @@ export function Toolbox<T>({
256271 startTransition ( 'forward' ) ;
257272 setChildrenLoading ( false ) ;
258273 } ,
259- [ navigationStack , currentParentItem , title , items , clearSearch , startTransition , onItemSelect ]
274+ [
275+ navigationStack ,
276+ currentParentItem ,
277+ title ,
278+ items ,
279+ activeIndex ,
280+ isSearching ,
281+ clearSearch ,
282+ startTransition ,
283+ onItemSelect ,
284+ ]
260285 ) ;
261286
262287 useEffect ( ( ) => {
@@ -303,6 +328,7 @@ export function Toolbox<T>({
303328 data : {
304329 items : newInitialItems ,
305330 parentItem : null ,
331+ activeIndex : stackItem . data . activeIndex ,
306332 } ,
307333 } ;
308334 }
@@ -320,6 +346,7 @@ export function Toolbox<T>({
320346 data : {
321347 items : updatedItems ,
322348 parentItem : updatedParentItem ,
349+ activeIndex : stackItem . data . activeIndex ,
323350 } ,
324351 } ;
325352 } ) ;
@@ -356,15 +383,13 @@ export function Toolbox<T>({
356383
357384 const navigateDown = ( ) => {
358385 if ( activeIndex === SEARCH_BAR_INDEX ) {
359- const firstIndex = getFirstSelectableIndex ( renderedItems ) ;
360- if ( firstIndex !== SEARCH_BAR_INDEX ) navigateToIndex ( firstIndex ) ;
386+ navigateToFirstItem ( ) ;
361387 } else {
362388 const nextIndex = getNextSelectableIndex ( renderedItems , activeIndex , 'down' ) ;
363389 if ( nextIndex !== SEARCH_BAR_INDEX ) {
364390 navigateToIndex ( nextIndex ) ;
365391 } else {
366- const firstIndex = getFirstSelectableIndex ( renderedItems ) ;
367- if ( firstIndex !== SEARCH_BAR_INDEX ) navigateToIndex ( firstIndex ) ;
392+ navigateToFirstItem ( ) ;
368393 }
369394 }
370395 } ;
@@ -384,8 +409,9 @@ export function Toolbox<T>({
384409 navigateUp ( ) ;
385410 break ;
386411 }
412+ case ' ' :
387413 case 'Enter' : {
388- if ( activeIndex === SEARCH_BAR_INDEX ) break ;
414+ if ( activeIndex === SEARCH_BAR_INDEX ) return ;
389415
390416 const renderItem = renderedItems [ activeIndex ] ;
391417 if ( renderItem ?. type === 'item' ) {
@@ -411,6 +437,11 @@ export function Toolbox<T>({
411437 break ;
412438 }
413439 case 'Tab' : {
440+ // When on the search bar with text, defer behavior handling to SearchBox
441+ if ( activeIndex === SEARCH_BAR_INDEX && search . length > 0 && ! e . shiftKey ) {
442+ break ;
443+ }
444+
414445 e . preventDefault ( ) ;
415446 if ( e . shiftKey ) {
416447 navigateUp ( ) ;
@@ -423,8 +454,7 @@ export function Toolbox<T>({
423454 if ( activeIndex === SEARCH_BAR_INDEX ) break ;
424455
425456 e . preventDefault ( ) ;
426- const firstIndex = getFirstSelectableIndex ( renderedItems ) ;
427- if ( firstIndex !== SEARCH_BAR_INDEX ) navigateToIndex ( firstIndex ) ;
457+ navigateToFirstItem ( ) ;
428458 break ;
429459 }
430460 case 'End' : {
@@ -443,6 +473,7 @@ export function Toolbox<T>({
443473 activeIndex ,
444474 navigationStack . canGoBack ,
445475 navigateToIndex ,
476+ navigateToFirstItem ,
446477 handleItemSelect ,
447478 handleBackTransition ,
448479 ]
@@ -500,6 +531,7 @@ export function Toolbox<T>({
500531 placeholder = "Search"
501532 inputRef = { searchInputRef }
502533 onNavigationKeyDown = { handleNavigationKeyDown }
534+ navigateToFirstItem = { navigateToFirstItem }
503535 activeDescendantId = { activeDescendantId }
504536 />
505537
0 commit comments