1- import { useEffect , useImperativeHandle , useRef , useState } from 'react'
1+ import { useImperativeHandle , useRef , useState } from 'react'
22
33import { Box , Inline , Text } from '@doist/reactist'
44
@@ -21,7 +21,8 @@ function BaseSuggestionDropdown<TSuggestionItem extends object>({
2121 renderItem,
2222 onItemSelect,
2323} : BaseSuggestionDropdownProps < TSuggestionItem > ) {
24- const selectedItemRef = useRef < HTMLLIElement > ( null )
24+ const itemRefs = useRef < Map < number , HTMLLIElement > > ( new Map ( ) )
25+
2526 const [ selectedIndex , setSelectedIndex ] = useState ( 0 )
2627
2728 const suggestionDropdownStyle : React . CSSProperties = {
@@ -31,36 +32,23 @@ function BaseSuggestionDropdown<TSuggestionItem extends object>({
3132 const areSuggestionsLoading = items . length === 1 && 'isLoading' in items [ 0 ]
3233 const areSuggestionsEmpty = items . length === 0
3334
34- useEffect (
35- function scrollSelectedItemIntoView ( ) {
36- selectedItemRef . current ?. scrollIntoView ( {
37- block : 'nearest' ,
38- } )
39- } ,
40- [ selectedIndex ] ,
41- )
42-
43- useEffect (
44- function autoSelectLastItemIfNeeded ( ) {
45- if ( selectedIndex > items . length ) {
46- setSelectedIndex ( items . length - 1 )
47- }
48- } ,
49- [ items , selectedIndex ] ,
50- )
35+ function updateSelectedItem ( index : number ) {
36+ setSelectedIndex ( index )
37+ itemRefs . current . get ( index ) ?. scrollIntoView ( { block : 'nearest' } )
38+ }
5139
5240 useImperativeHandle (
5341 forwardedRef ,
5442 function exposeKeyboardHandlersToReactRenderer ( ) {
5543 return {
5644 onKeyDown ( { event } ) {
5745 if ( event . key === 'ArrowUp' ) {
58- setSelectedIndex ( ( selectedIndex + items . length - 1 ) % items . length )
46+ updateSelectedItem ( ( selectedIndex + items . length - 1 ) % items . length )
5947 return true
6048 }
6149
6250 if ( event . key === 'ArrowDown' ) {
63- setSelectedIndex ( ( selectedIndex + 1 ) % items . length )
51+ updateSelectedItem ( ( selectedIndex + 1 ) % items . length )
6452 return true
6553 }
6654
@@ -125,7 +113,13 @@ function BaseSuggestionDropdown<TSuggestionItem extends object>({
125113 alignItems = "center"
126114 borderRadius = "standard"
127115 onClick = { ( ) => onItemSelect ( index ) }
128- ref = { index === selectedIndex ? selectedItemRef : null }
116+ ref = { ( node ) => {
117+ if ( node ) {
118+ itemRefs . current . set ( index , node )
119+ } else {
120+ itemRefs . current . delete ( index )
121+ }
122+ } }
129123 >
130124 { renderItem ( item ) }
131125 </ Box >
0 commit comments