fix(a11y): silence server-search announcements while the dropdown is closed - #488
Merged
Conversation
…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
PR Test Results — ✅ all checks passed
Tested commit: |
gnbm
marked this pull request as ready for review
August 7, 2026 15:41
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #486
What happens
On an
onServerSearchinstance, 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:loadingTextonesearchDelayafter the close, then the result count when the host responded.Root cause
closeDropbox()ends withsetSearchValue(''), which on a server instance schedules a fetch of its own, and both serverannounce()sites were effectively unguarded (serverSearch()entirely,setServerOptions()byisInitializedonly). The local path already refuses to announce resets it performs itself (announceSearchResults()); the server path bypassed it.Fix
A new
isSilentServerSearchflag 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:closeDropbox()after its reset — also covering a fetch left pending by emptying the search box before closing (wheresetSearchValue('')early-returns), and responses landing mid hide-transition whileisOpened()is stilltrueopenDropbox()and by every user-driven search, so the silence cannot outlive the closed state — a host push refreshing an open list announces againisInitialized && isOpened(), which also silences the construction-time fetch forced byshowOptionsOnlyOnSearch(previously spoke "Loading results" on a closed, untouched dropdown at page load)Deliberately not done: cancelling
serverSearchTimeoutincloseDropbox()(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 driveonServerSearch/setServerOptions, as the issue requested. Six tests, each written failing before the code change:showOptionsOnlyOnSearchAssertions wait on the fetch actually being issued (a
window.__vsServerharness recordsonServerSearchcalls), not on durations.Verification
tscand ESLint cleandist/docs/assetsartifacts included; CI builds before e2e