@@ -45,7 +45,6 @@ export const KBarResults: React.FC<KBarResultsProps> = (props) => {
4545 if ( event . isComposing ) {
4646 return ;
4747 }
48-
4948 if ( event . key === "ArrowUp" || ( event . ctrlKey && event . key === "p" ) ) {
5049 event . preventDefault ( ) ;
5150 event . stopPropagation ( ) ;
@@ -84,8 +83,9 @@ export const KBarResults: React.FC<KBarResultsProps> = (props) => {
8483 activeRef . current ?. click ( ) ;
8584 }
8685 } ;
87- window . addEventListener ( "keydown" , handler , { capture : true } ) ;
88- return ( ) => window . removeEventListener ( "keydown" , handler , { capture : true } ) ;
86+ window . addEventListener ( "keydown" , handler , { capture : true } ) ;
87+ return ( ) =>
88+ window . removeEventListener ( "keydown" , handler , { capture : true } ) ;
8989 } , [ query ] ) ;
9090
9191 // destructuring here to prevent linter warning to pass
@@ -100,19 +100,47 @@ export const KBarResults: React.FC<KBarResultsProps> = (props) => {
100100 } ) ;
101101 } , [ activeIndex , scrollToIndex ] ) ;
102102
103+ // reset active index only when search or root action changes
103104 React . useEffect ( ( ) => {
104- // TODO(tim): fix scenario where async actions load in
105- // and active index is reset to the first item. i.e. when
106- // users register actions and bust the `useRegisterActions`
107- // cache, we won't want to reset their active index as they
108- // are navigating the list.
109105 query . setActiveIndex (
110106 // avoid setting active index on a group
111- typeof props . items [ START_INDEX ] === "string"
107+ typeof itemsRef . current [ START_INDEX ] === "string"
112108 ? START_INDEX + 1
113109 : START_INDEX
114110 ) ;
115- } , [ search , currentRootActionId , props . items , query ] ) ;
111+ } , [ search , currentRootActionId , query ] ) ;
112+
113+ // adjust active index when items change (ie when actions load async)
114+ React . useEffect ( ( ) => {
115+ const currentIndex = activeIndex ;
116+ const maxIndex = itemsRef . current . length - 1 ;
117+
118+ if ( currentIndex > maxIndex && maxIndex >= 0 ) {
119+ let newIndex = maxIndex ;
120+ if ( typeof itemsRef . current [ newIndex ] === "string" && newIndex > 0 ) {
121+ newIndex -= 1 ;
122+ }
123+ query . setActiveIndex ( newIndex ) ;
124+ } else if (
125+ currentIndex <= maxIndex &&
126+ typeof itemsRef . current [ currentIndex ] === "string"
127+ ) {
128+ let newIndex = currentIndex + 1 ;
129+ if (
130+ newIndex > maxIndex ||
131+ typeof itemsRef . current [ newIndex ] === "string"
132+ ) {
133+ newIndex = currentIndex - 1 ;
134+ }
135+ if (
136+ newIndex >= 0 &&
137+ newIndex <= maxIndex &&
138+ typeof itemsRef . current [ newIndex ] !== "string"
139+ ) {
140+ query . setActiveIndex ( newIndex ) ;
141+ }
142+ }
143+ } , [ props . items , activeIndex , query ] ) ;
116144
117145 const execute = React . useCallback (
118146 ( item : RenderParams [ "item" ] ) => {
0 commit comments