Improve Select combobox keyboard navigation and accessible names, and scope Panel Escape to open comboboxes#1134
Merged
shubham-kumar1-eightfold merged 3 commits intoJun 10, 2026
Conversation
|
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1134 +/- ##
=======================================
Coverage 84.38% 84.39%
=======================================
Files 1230 1230
Lines 21427 21433 +6
Branches 8132 8137 +5
=======================================
+ Hits 18081 18088 +7
+ Misses 3260 3259 -1
Partials 86 86 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
3c0f6df to
f466881
Compare
f466881 to
1866685
Compare
… Panel Escape Select: ArrowDown moves focus into the listbox for both filterable and non-filterable selects; restore the input accessible name from textInputProps; use stable valid option ids for aria-activedescendant. Panel: scope the Escape denylist to open comboboxes so Escape closes an open listbox first, then the panel. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1866685 to
df85589
Compare
…d ids Option ids now derive from the Select menu id, so the unit assertions use the exact deterministic ids (uniqueId is mocked to the prefix in tests) and the snapshot is regenerated. No behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5653e2d to
2db8c0d
Compare
schakka-eightfold
approved these changes
Jun 9, 2026
ychhabra-eightfold
approved these changes
Jun 9, 2026
3e388eb to
76a7b02
Compare
…r button Clear aria-activedescendant when the dropdown closes and scope the focusin handler to this Select's own listbox. Add a clearButtonAriaLabel prop (default 'Clear selection') so the clearable button has an accessible name. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
76a7b02 to
e833cf3
Compare
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.
SUMMARY:
Accessibility fixes for the shared
Select(combobox) andPanelcomponents, aligning them with the WAI-ARIA APG Combobox and Dialog patterns. These are product-wide and affect every OctupleSelect/Panelconsumer. The work was driven by an accessibility audit of the "All Filters" panel on the Duplicate Position intake form, and pairs with the consumer-side change in EightfoldAI/vscode#108828.src/components/Select/Select.tsxhandleInputKeyDown,ArrowDownnow moves keyboard focus from the combobox input into the dropdown's option list for both filterable (list-autocomplete) and select-only comboboxes. Previously thefilterable &&guard meant only filterable selects could enter their options by keyboard; plain dropdowns trapped focus on the input. The behavior is now gated on the dropdown being open (dropdownVisible) and callsevent.preventDefault()so the page does not also scroll.ariaLabelnow falls back toselectInputProps?.ariaLabel(ariaLabel ?? selectInputProps?.ariaLabel) instead of being clobbered toundefined. A combobox name supplied viatextInputPropsis now kept and announced.idis now derived from the menu id plus the option index (${selectMenuId.current}-option-${index}) instead ofoption.text + '-' + index. The previous scheme produced invalid and/or duplicatearia-activedescendantIDREFs (e.g. when option text contained spaces or repeated across options); the ids are now stable and unique.aria-activedescendantis cleared when the listbox closes (it would otherwise dangle, pointing at an option that has unmounted) and is scoped to this Select's own options, so navigating one combobox no longer stamps another Select's input.clearButtonAriaLabelprop (default'Clear selection') gives the clearable button an accessible name.src/components/Panel/Panel.tsxescapeTargetSelectordenylist now includes[role="combobox"][aria-expanded="true"]. The Panel's global Escape handler does not close the panel when the Escape target matches this denylist. Scoping the combobox token toaria-expanded="true"produces an "escalating Escape": pressing Escape while a combobox's listbox is open closes only the listbox (the panel stays open); a second Escape (combobox now collapsed, so it no longer matches the denylist) closes the panel. Previously, Escape on a combobox input closed the entire panel in one keystroke.Tests & snapshot
Select.test.tsxoption-id assertions (selection,onOptionsChange,aria-activedescendant, and pill tests) to the new menu-scoped id scheme.Selectsnapshot for the new ids; noPanelsnapshot change.aria-activedescendantbeing cleared on close and scoped per-Select.These changes are standards-aligned with the WAI-ARIA APG Combobox and Dialog patterns; the only API addition is the optional, backward-compatible
clearButtonAriaLabelprop.GITHUB ISSUE (Open Source Contributors)
N/A — internal Eightfold accessibility work (see JIRA below).
JIRA TASK (Eightfold Employees Only):
https://eightfoldai.atlassian.net/browse/ENG-167719
CHANGE TYPE:
TEST COVERAGE:
TEST PLAN:
Combobox keyboard navigation (
Select):Select, then pressArrowDownfrom the input → focus moves into the option list and the first option becomes active; the page does not scroll.Selectand confirmArrowDownstill moves focus into the options (no regression).ArrowDowndoes not jump focus into a hidden list.Accessible name (
Select):textInputProps.ariaLabeland confirm the combobox input is announced with that name (no longerundefined).Option ids / active-descendant (
Select):idis unique and valid, and thataria-activedescendanton the input points at the active option's id while navigating with the keyboard. Verify with options whose text contains spaces and/or duplicate text across options.Escalating Escape (
Panel):Panel, open a combobox's listbox and pressEscape→ only the listbox closes; the panel stays open. PressEscapeagain (combobox now collapsed) → the panel closes.Escapestill closes the panel directly when focus is not on an expanded combobox (no regression to the existinglistbox/menu/tooltip/dropdown/tooltip-wrapper behavior).Cross-repo: validate end-to-end on the "All Filters" panel of the Duplicate Position intake form via EightfoldAI/vscode#108828.