@@ -9,7 +9,7 @@ import {useFocusZone} from '../hooks/useFocusZone'
99import type { ComponentProps , MandateProps , AriaRole } from '../utils/types'
1010import Spinner from '../Spinner'
1111import { useId } from '../hooks/useId'
12- import { AutocompleteContext } from './AutocompleteContext'
12+ import { AutocompleteContext , AutocompleteDeferredInputContext } from './AutocompleteContext'
1313import type { IconProps } from '@primer/octicons-react'
1414import { PlusIcon } from '@primer/octicons-react'
1515import VisuallyHidden from '../_VisuallyHidden'
@@ -132,14 +132,14 @@ const debounceAnnouncement = debounce((announcement: string) => {
132132
133133function AutocompleteMenu < T extends AutocompleteItemProps > ( props : AutocompleteMenuInternalProps < T > ) {
134134 const autocompleteContext = useContext ( AutocompleteContext )
135- if ( autocompleteContext === null ) {
135+ const deferredInputContext = useContext ( AutocompleteDeferredInputContext )
136+ if ( autocompleteContext === null || deferredInputContext === null ) {
136137 throw new Error ( 'AutocompleteContext returned null values' )
137138 }
138139 const {
139140 activeDescendantRef,
140141 id,
141142 inputRef,
142- inputValue = '' ,
143143 scrollContainerRef,
144144 setAutocompleteSuggestion,
145145 setShowMenu,
@@ -148,6 +148,9 @@ function AutocompleteMenu<T extends AutocompleteItemProps>(props: AutocompleteMe
148148 setSelectedItemLength,
149149 showMenu,
150150 } = autocompleteContext
151+ // Use deferred input value to avoid re-rendering on every keystroke
152+ // This allows filtering large lists without blocking typing
153+ const { deferredInputValue} = deferredInputContext
151154 const {
152155 items,
153156 selectedItemIds,
@@ -226,9 +229,9 @@ function AutocompleteMenu<T extends AutocompleteItemProps>(props: AutocompleteMe
226229 const sortedAndFilteredItemsToRender = useMemo (
227230 ( ) =>
228231 selectableItems
229- . filter ( filterFn ? filterFn : getDefaultItemFilter ( inputValue ) )
232+ . filter ( filterFn ? filterFn : getDefaultItemFilter ( deferredInputValue ) )
230233 . sort ( ( a , b ) => itemSortOrderData [ a . id ] - itemSortOrderData [ b . id ] ) ,
231- [ selectableItems , itemSortOrderData , filterFn , inputValue ] ,
234+ [ selectableItems , itemSortOrderData , filterFn , deferredInputValue ] ,
232235 )
233236
234237 const allItemsToRender = useMemo (
@@ -311,12 +314,14 @@ function AutocompleteMenu<T extends AutocompleteItemProps>(props: AutocompleteMe
311314 )
312315
313316 useEffect ( ( ) => {
314- if ( highlightedItem ?. text ?. startsWith ( inputValue ) && ! selectedItemIds . includes ( highlightedItem . id ) ) {
317+ // Use deferredInputValue to avoid running this effect on every keystroke
318+ // The Input component guards against stale suggestions
319+ if ( highlightedItem ?. text ?. startsWith ( deferredInputValue ) && ! selectedItemIds . includes ( highlightedItem . id ) ) {
315320 setAutocompleteSuggestion ( highlightedItem . text )
316321 } else {
317322 setAutocompleteSuggestion ( '' )
318323 }
319- } , [ highlightedItem , inputValue , selectedItemIds , setAutocompleteSuggestion ] )
324+ } , [ highlightedItem , deferredInputValue , selectedItemIds , setAutocompleteSuggestion ] )
320325
321326 useEffect ( ( ) => {
322327 const itemIdSortResult = [ ...sortedItemIds ] . sort (
0 commit comments