Skip to content

fix(a11y): expose dropdown selection via aria-selected (D4) - #16

Merged
BrianGenisio merged 1 commit into
mainfrom
fix/a11y-d4-dropdown-aria-selected
Aug 12, 2026
Merged

fix(a11y): expose dropdown selection via aria-selected (D4)#16
BrianGenisio merged 1 commit into
mainfrom
fix/a11y-d4-dropdown-aria-selected

Conversation

@BrianGenisio

Copy link
Copy Markdown
Contributor

Summary

Closes #9 ([a11y][D4]). Dropdown options now expose selection programmatically with aria-selected, so the active choice is not conveyed by color/checkmark alone.

Changes

In components/dropdown/:

  • createMenuItem: every role="option" gets aria-selected="true"|"false" from the initial selectedValue
  • selectItem: updates aria-selected alongside the .selected class and checkmark
  • Checkmark remains decorative (aria-hidden); D2/D3 focus and combobox/listbox behavior unchanged

Test plan

  • npm test — Playwright light + dark: preselected dropdown has exactly one aria-selected="true"; after select, selected option is "true" and others "false"; scoped axe clean
  • Existing Tab / Shift+Tab focus suite still green
  • Optional: VoiceOver / accessibility tree confirms selected option announced

Made with Cursor

Set aria-selected on every role=option so screen readers can determine
the active choice; keep the checkmark as a redundant visual cue.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Dropdown options now expose aria-selected="true" or "false" during initial rendering and after selection changes. The checkmark SVG is marked decorative. Playwright tests cover initial and updated selection states in light and dark modes, including accessibility checks. The dropdown documentation now describes the ARIA behavior and related test coverage.

Possibly related issues

  • CodeSignal/learn_bespoke-design-system issue 8 — It also addresses dropdown ARIA semantics, including aria-selected alongside listbox structure.

Possibly related PRs

Fixed issue severity

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the accessibility change to expose dropdown selection through aria-selected.
Description check ✅ Passed The description directly explains the aria-selected implementation, preserved behavior, and test coverage.
Linked Issues check ✅ Passed The changes satisfy issue #9 by adding and updating aria-selected, preserving visual cues, covering both themes, and checking axe results.
Out of Scope Changes check ✅ Passed The documentation, implementation, and tests directly support the linked accessibility objective without unrelated changes.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
tests/dropdown-focus.spec.js (1)

138-189: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add regression checks for the non-color selection cue.

The tests verify aria-selected and axe results, but they do not verify the .selected class or the decorative checkmark. Because the PR objective requires selection to remain visible without relying on color, add these assertions for the preselected and newly selected states. Also verify that deselected options have no checkmark.

Suggested assertions
+      const selectedOption = basic.locator(
+        '[role="option"][aria-selected="true"]',
+      );
+      await expect(selectedOption).toHaveClass(/selected/);
+      await expect(
+        selectedOption.locator(
+          '.dropdown-menu-item-checkmark[aria-hidden="true"]',
+        ),
+      ).toHaveCount(1);
+      await expect(
+        basic.locator(
+          '[role="option"][aria-selected="false"] .dropdown-menu-item-checkmark',
+        ),
+      ).toHaveCount(0);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/dropdown-focus.spec.js` around lines 138 - 189, Add regression
assertions in the preselected and newly selected cases to verify the selected
option has the `.selected` class and its decorative checkmark, while deselected
options have neither the selected class nor a checkmark. Use the existing
`selectionState`/dropdown locators around the tests for `#dropdown-preselected`
and `#dropdown-basic`, preserving the current aria-selected and axe checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/dropdown-focus.spec.js`:
- Around line 138-189: Add regression assertions in the preselected and newly
selected cases to verify the selected option has the `.selected` class and its
decorative checkmark, while deselected options have neither the selected class
nor a checkmark. Use the existing `selectionState`/dropdown locators around the
tests for `#dropdown-preselected` and `#dropdown-basic`, preserving the current
aria-selected and axe checks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: eba2c35c-ea9f-4783-8f5e-8c9df45750b4

📥 Commits

Reviewing files that changed from the base of the PR and between 124c1b0 and 5bb0131.

📒 Files selected for processing (3)
  • components/dropdown/README.md
  • components/dropdown/dropdown.js
  • tests/dropdown-focus.spec.js

@BrianGenisio
BrianGenisio merged commit 15a0288 into main Aug 12, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[a11y][D4] Dropdown selection state is conveyed visually only

1 participant