Skip to content

fix: Let type-ahead reach disabled options in Select, Multiselect and OptionList - #5263

Open
amanabiy wants to merge 1 commit into
fix/listbox-home-endfrom
fix/listbox-type-ahead-disabled
Open

amanabiy wants to merge 1 commit into
fix/listbox-home-endfrom
fix/listbox-type-ahead-disabled

Conversation

@amanabiy

@amanabiy amanabiy commented Nov 6, 2026 •

Copy link
Copy Markdown
Member

Description

Up and Down reach disabled options, so their disabled state and reason are announced, but type-ahead skipped them. Type-ahead now matches the same options as Up and Down, including disabled ones, in Select, Multiselect and OptionList. Choosing a disabled option is still ignored. When the Select dropdown is closed, type-ahead selects the match instead of highlighting it, so it keeps skipping disabled options there (skipDisabled), as a native select does.

From the OptionList accessibility review, question 3 (type-ahead and disabled options).

Related links, issue #, if available: AfZkAA6G9O2X

How has this been tested?

Unit tests in use-type-ahead.test.ts (reaches a disabled option; skips it with skipDisabled) and a new select/__tests__/type-ahead.test.tsx (closed: selects the first enabled match; open: highlights the disabled match). The closed Select test fails without skipDisabled. The OptionList test that asserted the old skipping was removed. Unit tests for OptionList, Select, Multiselect, Autosuggest, Property filter and the shared list code pass, and eslint and tsc pass.

Review checklist

The following items are to be evaluated by the author(s) and the reviewer(s).

Correctness

  • Changes include appropriate documentation updates.
  • Changes are backward-compatible if not indicated, see CONTRIBUTING.md.
  • Changes do not include unsupported browser features, see CONTRIBUTING.md.
  • Changes were manually tested for accessibility, see accessibility guidelines.

Security

Testing

  • Changes are covered with new/existing unit tests?
  • Changes are covered with new/existing integration tests?

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@amanabiy
amanabiy force-pushed the fix/listbox-type-ahead-disabled branch from 4cedc15 to 974b177 Compare November 6, 2026 09:13
@amanabiy
amanabiy changed the base branch from feat/add-option-list to fix/listbox-home-end November 6, 2026 09:16
@amanabiy
amanabiy added this pull request to stack #5251 November 6, 2026 09:16
@amanabiy
amanabiy marked this pull request as ready for review November 6, 2026 09:16
@amanabiy
amanabiy requested a review from a team as a code owner November 6, 2026 09:16
@amanabiy
amanabiy requested review from jperals and removed request for a team November 6, 2026 09:16
@codecov

codecov Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (fix/listbox-home-end@5f51d48). Learn more about missing BASE report.

Additional details and impacted files
@@                   Coverage Diff                   @@
##             fix/listbox-home-end    #5263   +/-   ##
=======================================================
  Coverage                        ?   97.85%           
=======================================================
  Files                           ?     1012           
  Lines                           ?    32738           
  Branches                        ?    12130           
=======================================================
  Hits                            ?    32037           
  Misses                          ?      695           
  Partials                        ?        6           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI 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.

🟢 Approval recommended

No active review issues remain for the changes aligning type-ahead highlighting with arrow-key navigation.

No open issues 🎉

What changed in this PR

This PR aligns type-ahead with arrow-key navigation in Select, Multiselect, and OptionList, allowing disabled options to be highlighted so their state and reason can be announced.

Changes:

  • Updates shared type-ahead matching to include disabled options by default.
  • Preserves disabled-option skipping when a closed Select directly selects a match.
  • Adds shared-hook and Select tests and removes the obsolete OptionList skipping test.
File Description
src/​select/​internal.tsx Enables skipDisabled while the dropdown is closed.
src/​select/​__tests__/​type-ahead.test.tsx Tests closed selection and open highlighting behavior.
src/​option-list/​__tests__/​keyboard.test.tsx Removes the test asserting disabled options are skipped.
src/​internal/​components/​listbox/​use-type-ahead.ts Uses highlightable-option matching and adds skipDisabled.
src/​internal/​components/​listbox/​__tests__/​use-type-ahead.test.ts Tests default disabled-option matching and explicit skipping.

Review effort: Balanced

const interactivityCheck = interactiveGroups ? isGroupInteractive : isInteractive;
const filter = (searchText: string) =>
filterOptions(options, searchText, true).filter(option => interactivityCheck(option));
const isMatchable = (option: DropdownOption) =>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Are isMatchable and isHighlightable different conceptually?

This function is the only consumer of isHighlightable, so is this abstraction worth it, or would it be better to have it all here?, like

const isMatchable = (option: DropdownOption) =>
  (interactiveGroups || option.type !== 'parent') && !(skipDisabled && option.disabled);
const filter = (searchText: string) => filterOptions(options, searchText, true).filter(isMatchable);

value.current = newValue;

const nextHighlight = findMatchingOption(options, newValue, highlightedOption, interactiveGroups);
const nextHighlight = findMatchingOption(options, newValue, highlightedOption, interactiveGroups, skipDisabled);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

That's quite a few positional parameters already, plus multiple of them are optional. Could we refactor the findMatchingOption into using named parameters?

expect(listbox).toHaveAttribute('aria-activedescendant', wrapper.findOptionByValue('c')!.getElement().id);
});

test('typing does not highlight a disabled option', () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Instead of removing this test, why not change it accordingly?

Personally, I find this test preferable to the ones added in src/internal/components/listbox/use-type-ahead.ts because it tests the component from the consumer's layer without being tied to any particular implementation.

… OptionList

Up and Down reach disabled options, so their disabled state and reason are announced, but type-ahead skipped them. Type-ahead now matches the same options as Up and Down, including disabled ones. Choosing a disabled option is still ignored. When the Select dropdown is closed, type-ahead selects the match instead of highlighting it, so it keeps skipping disabled options there (skipDisabled), as a native select does.

This branch was successfully deployed

3 active deployments
dev-pages-react18 — f38339d0 Deployed Nov 6, 2026 by jperals via deploy (React 18) / deploy #3226
dev-pages-react16 — f38339d0 Deployed Nov 6, 2026 by jperals via deploy (React 16) / deploy #3226
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.

3 participants