diff --git a/packages/pluggableWidgets/combobox-web/CHANGELOG.md b/packages/pluggableWidgets/combobox-web/CHANGELOG.md index 8b73cdf53e..d991dc0359 100644 --- a/packages/pluggableWidgets/combobox-web/CHANGELOG.md +++ b/packages/pluggableWidgets/combobox-web/CHANGELOG.md @@ -12,6 +12,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - We fixed an issue where the editability setting was inverted: setting editability to `false` allowed editing, and setting it to `true` prevented editing. The editability condition expression now behaves correctly: `true` means editable, `false` means read-only. +- We improved screen reader accessibility by fixing accessible name announcements, hiding decorative icons, and preventing menu exposure when closed. + ### Breaking changes - The editability fix above is a potential breaking change. Apps that worked around the bug by inverting their editability expression will now have the opposite (incorrect) behavior after upgrading. Review any combobox widgets using a custom editability expression and remove the inversion workaround, otherwise fields may unexpectedly become editable or read-only. diff --git a/packages/pluggableWidgets/combobox-web/e2e/Combobox.spec.js b/packages/pluggableWidgets/combobox-web/e2e/Combobox.spec.js index ec6b9443a3..994893ab65 100644 --- a/packages/pluggableWidgets/combobox-web/e2e/Combobox.spec.js +++ b/packages/pluggableWidgets/combobox-web/e2e/Combobox.spec.js @@ -171,6 +171,23 @@ test.describe("combobox-web", () => { // check if filtered await expect(getOptions(comboBox)).toHaveText(["Antartica", "Australia"]); }); + + test("menu list not in DOM when closed, present when opened", async ({ page }) => { + const comboBox = page.locator(".mx-name-comboBox1"); + await expect(comboBox).toBeVisible({ timeout: 10000 }); + + // Verify menu list is not in DOM when closed + const menuListClosed = comboBox.locator(".widget-combobox-menu-list"); + await expect(menuListClosed).not.toBeVisible(); + + // Open the combobox + await comboBox.click(); + + // Verify menu list is now in DOM and visible + const menuListOpen = comboBox.locator(".widget-combobox-menu-list"); + await expect(menuListOpen).toBeVisible(); + await expect(getOptions(comboBox).first()).toBeVisible(); + }); }); test.describe("menu positioning (floating-ui)", () => { diff --git a/packages/pluggableWidgets/combobox-web/openspec/changes/combobox-validation-a11y/.openspec.yaml b/packages/pluggableWidgets/combobox-web/openspec/changes/combobox-validation-a11y/.openspec.yaml new file mode 100644 index 0000000000..a903f7fe18 --- /dev/null +++ b/packages/pluggableWidgets/combobox-web/openspec/changes/combobox-validation-a11y/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-06-16 diff --git a/packages/pluggableWidgets/combobox-web/openspec/changes/combobox-validation-a11y/design.md b/packages/pluggableWidgets/combobox-web/openspec/changes/combobox-validation-a11y/design.md new file mode 100644 index 0000000000..a4e1b99238 --- /dev/null +++ b/packages/pluggableWidgets/combobox-web/openspec/changes/combobox-validation-a11y/design.md @@ -0,0 +1,109 @@ +## Context + +The combobox widget currently has two accessibility issues affecting screen reader users: + +1. **Decorative icons announced as "image"**: The DownArrow and ClearButton SVG icons are exposed to assistive technologies, causing screen readers to announce them as "image" elements. These icons are purely decorative - they duplicate information already conveyed through the combobox role, button roles, and ARIA labels. + +2. **Empty menu structure exposed**: When the combobox has no options, the `