Skip to content

fix(a11y): silence server-search announcements while the dropdown is closed - #488

Merged
gnbm merged 2 commits into
masterfrom
gm/issue-486
Aug 7, 2026
Merged

fix(a11y): silence server-search announcements while the dropdown is closed#488
gnbm merged 2 commits into
masterfrom
gm/issue-486

Conversation

@gnbm

@gnbm gnbm commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Fixes #486

What happens

On an onServerSearch instance, typing into the search box and closing the dropdown (Escape or click outside) before the debounce elapsed produced two live-region announcements for an interaction the user never made: loadingText one searchDelay after the close, then the result count when the host responded.

Root cause

closeDropbox() ends with setSearchValue(''), which on a server instance schedules a fetch of its own, and both server announce() sites were effectively unguarded (serverSearch() entirely, setServerOptions() by isInitialized only). The local path already refuses to announce resets it performs itself (announceSearchResults()); the server path bypassed it.

Fix

A new isSilentServerSearch flag covering the whole closed period rather than a latch on one scheduled fetch, because the close cannot see everything that is still going to speak:

  • set in closeDropbox() after its reset — also covering a fetch left pending by emptying the search box before closing (where setSearchValue('') early-returns), and responses landing mid hide-transition while isOpened() is still true
  • lifted in openDropbox() and by every user-driven search, so the silence cannot outlive the closed state — a host push refreshing an open list announces again
  • both server announcements are additionally gated on isInitialized && isOpened(), which also silences the construction-time fetch forced by showOptionsOnlyOnSearch (previously spoke "Loading results" on a closed, untouched dropdown at page load)

Deliberately not done: cancelling serverSearchTimeout in closeDropbox() (the issue's secondary suggestion). That close-time fetch is what restores the unfiltered list for the next open, since opening does not search — cancelling it would leave a reopened dropdown showing the previous query's results against an empty search box. The wasted request remains a separate, pre-existing concern.

Coverage

cypress/e2e/a11y-server-search-announcements.cy.ts — the first spec to drive onServerSearch/setServerOptions, as the issue requested. Six tests, each written failing before the code change:

  • announces the in-flight fetch, then the match count, while open
  • silent after close: the close-initiated fetch, its response, and a fetch left pending by clearing the search before closing
  • announces again for options pushed while reopened
  • stays quiet for the page-load fetch forced by showOptionsOnlyOnSearch

Assertions wait on the fetch actually being issued (a window.__vsServer harness records onServerSearch calls), not on durations.

Verification

  • Full Cypress suite: 422 passing / 0 failing across all 26 specs
  • tsc and ESLint clean
  • No dist/docs/assets artifacts included; CI builds before e2e

gnbm added 2 commits August 7, 2026 16:33
…closed

closeDropbox() ends with setSearchValue(''), which on a server-search
instance schedules a fetch of its own - so closing spoke loadingText one
searchDelay after the dropdown had gone, then the result count when the
host responded. Both server announce() sites were effectively unguarded.

isSilentServerSearch now covers the whole closed period: set on close
(after the reset, so it also covers a fetch left pending by clearing the
search before closing, and responses landing mid hide-transition while
isOpened() is still true), lifted on open. Both server announcements are
additionally gated on isOpened(), which also silences the construction-
time fetch forced by showOptionsOnlyOnSearch. The reset fetch itself
stays: it is what restores the unfiltered list for the next open.

Refs #486
First spec to drive onServerSearch/setServerOptions. Pins the fix for
the closed-dropdown announcements in both directions: announces while
open, silent after close (including a fetch left pending by clearing
the search first), announces again after reopen, and stays quiet for
the construction-time fetch forced by showOptionsOnlyOnSearch.

Refs #486
@gnbm gnbm added the bug Something isn't working label Aug 7, 2026
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

PR Test Results — ✅ all checks passed

Check Result Time
Typecheck 2s
ESLint 2s
Stylelint 1s
CI Scripts 1s
Build 3s
a11y-aria-label.cy.ts ✅ 10/10 6s
a11y-close-clears-highlight.cy.ts ✅ 7/7 4s
a11y-escape-close.cy.ts ✅ 6/6 2s
a11y-listbox-multiselectable.cy.ts ✅ 3/3 1s
a11y-live-region.cy.ts ✅ 18/18 6s
a11y-reduced-motion.cy.ts ✅ 3/3 1s
a11y-required-error.cy.ts ✅ 20/20 4s
a11y-search-arrow-navigation.cy.ts ✅ 13/13 7s
a11y-select-all.cy.ts ✅ 7/7 3s
a11y-server-search-announcements.cy.ts ✅ 6/6 4s
a11y-target-size.cy.ts ✅ 5/5 2s
examples.cy.ts ✅ 219/219 1m40s
observer-listener-lifecycle.cy.ts ✅ 7/7 1s
perf-resize-throttle.cy.ts ✅ 3/3 1s
perf-scroll-aria.cy.ts ✅ 6/6 4s
perf-text-measurer.cy.ts ✅ 4/4 3s
secure-text-warning.cy.ts ✅ 4/4 1s
security-ampersand-storage.cy.ts ✅ 16/16 3s
security-chrome-label-props.cy.ts ✅ 10/10 1s
security-classnames-xss.cy.ts ✅ 2/2 1s
security-customdata-xss.cy.ts ✅ 2/2 1s
security-global-defaults.cy.ts ✅ 11/11 1s
security-hidden-input-name.cy.ts ✅ 7/7 1s
security-proto-value.cy.ts ✅ 9/9 1s
security-quote-escaping.cy.ts ✅ 12/12 2s
timer-cleanup.cy.ts ✅ 2/2 1s

Tested commit: 096e946 · Run #15

@gnbm
gnbm marked this pull request as ready for review August 7, 2026 15:41

@os-davidlourenco os-davidlourenco left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@gnbm
gnbm merged commit 360d554 into master Aug 7, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

a11y: server-search announcements fire after the dropdown has closed

2 participants