Typeahead with Keyboard Navigation
Build a typeahead: an input connected to a suggestions endpoint, with keyboard navigation. The endpoint is mocked in the starter (fetchSuggestions(query, signal) resolves after a jittered delay and honors an AbortSignal), so a slow old response really can arrive after a newer one. Available as a React template and an HTML/CSS/JS one.
Requirements
- Debounce the query before fetching; ignore queries shorter than
minChars. - A stale response must never overwrite a newer list — abort the in-flight request when the query changes.
- Cache results by query so retyping a query doesn't refetch.
- Arrow keys move the highlight and wrap around; Enter selects the highlighted item; Escape closes the list; clicking an item selects it.
- Selecting an item fills the input and calls
onSelect(item). - ARIA combobox wiring:
role="combobox",aria-expanded,aria-activedescendant, and arole="listbox"ofrole="option"s. - Show loading, empty, and error states.
Hints
Hint 1
Debounce the value, not the handler: in React a useDebouncedValue(query, delay) hook whose effect sets the debounced value in a timeout and clears it in cleanup; in vanilla a debounce(fn, wait) around the search.
Hint 2
Fetch with an AbortController per request and abort the previous one when a new query arrives — in React the effect cleanup is that single line; in vanilla keep the controller in a closure variable.
Hint 3
Keep activeIndex and wrap with modulo in the keydown handler; mousedown + preventDefault on the list keeps the input focused so blur doesn't close it before the click lands.