DEV Community

babycat
babycat

Posted on

Keep an Accessible Combobox Stable When Search Results Arrive Out of Order

An accessible combobox can follow the correct ARIA pattern and still become unusable when two search responses arrive in the wrong order.

Reproduce this sequence:

  1. Type ca, then quickly type cat.
  2. The cat response arrives first and highlights cat facts.
  3. The slower ca response arrives and replaces the list.
  4. aria-activedescendant now points to an option that no longer exists.

IME input adds another boundary: searching during composition can send partial text the user has not committed.

I would model the request generation explicitly:

let generation = 0;
let composing = false;

async function search(query: string) {
  const mine = ++generation;
  const options = await fetchOptions(query);
  if (mine !== generation || composing) return;
  render(options);
  restoreActiveOptionByKey();
}
Enter fullscreen mode Exit fullscreen mode

The stable key matters. An array index cannot preserve the active option when ranking changes.

Regression matrix

Input Injected failure Expected evidence
cacat first request delayed only cat results render
Arrow Down result refresh active key survives or resets visibly
Escape response arrives afterward popup stays closed
IME composition network is fast no request until compositionend

A Playwright test should assert focus remains on the input, every aria-activedescendant resolves to a live element, and Escape invalidates outstanding generations. A manual screen-reader pass should confirm result-count announcements are not emitted for discarded responses.

The WAI-ARIA Authoring Practices combobox pattern defines the keyboard contract. The missing production step is testing that contract under asynchronous replacement, not only against static example data.

Which stale-response failure has been hardest to reproduce in your search UI?

Top comments (0)