A cached, race-free, accessible autocomplete
searchApi(q) in the starter returns up to 5 words starting with q. Two-letter queries are slow (400 ms), longer ones fast (100 ms), so answers can arrive out of order. Each call is recorded in window.searchCalls.
Build the combobox: <input id="search" role="combobox" aria-autocomplete="list" aria-controls="results" aria-expanded=...> and <ul id="results" role="listbox"> with one <li role="option" id={"opt-" + i} aria-selected=...> per result.
Fetch suggestions for the trimmed, lower-case text (debouncing by about 150 ms is recommended). Never show an answer for an old query, and cache answers by query in a Map so a repeated query makes no new call.
Keyboard: ArrowDown/ArrowUp move the highlight, which is named by the input's aria-activedescendant and marked aria-selected="true"; Enter puts the highlighted option's text in the input and closes the list (aria-expanded="false"); Escape closes the list.
What Check tests
- The input is a combobox that controls a listbox
- A slow, old answer never replaces the newer one
- ArrowDown moves the highlight, named by aria-activedescendant
- Enter chooses the highlighted option and closes the list
- A repeated query is answered from the cache
- Escape closes the list
Stuck? One hint at a time
The solution unlocks after your first Check. Try first: that is where the learning happens.
Your page
Console
Nothing logged yet.