Skip to content

[select] Skip disabled items in typeahead and fix multiple-mode serialization#5025

Open
atomiks wants to merge 1 commit into
mui:masterfrom
atomiks:claude/select-typeahead-multiple-fixes
Open

[select] Skip disabled items in typeahead and fix multiple-mode serialization#5025
atomiks wants to merge 1 commit into
mui:masterfrom
atomiks:claude/select-typeahead-multiple-fixes

Conversation

@atomiks

@atomiks atomiks commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes a few Select correctness issues plus adjacent cleanup, with regression tests.

Bugs

  • Typeahead now skips disabled items. Disabled items register their value/label unconditionally and useTypeahead only skipped invisible elements, so typeahead could stop on a disabled item (and, on a closed trigger, commit it). It now skips disabled items while matching, so a single keypress advances to the next selectable item — matching native <select> and arrow-key navigation — in both open and closed states. This is done via a new opt-in isIndexDisabled predicate on useTypeahead, decoupled from the elementsRef/visibility filter so Select's mounted-but-hidden closed items still match. Menu and Combobox don't pass it, so their behavior is unchanged.
  • Multiple mode no longer passes the whole value array to itemToStringValue. The shared hidden input is nameless in multiple mode (per-value <input>s carry the data), so serializedValue is now ''; previously a user itemToStringValue written for a single item would throw or yield ''.
  • positionerElement.style.maxHeight = 'auto' (invalid, silently ignored) → 'none', so the explicit height governs in align mode and isn't clamped by user CSS.
  • Trigger callback refs no longer fire twice (they were attached via both a merged-ref prop and the useRenderElement ref array).
  • A custom isItemEqualToValue is no longer handed the raw empty array as the "selected value" in multiple mode (undefined when nothing is selected).

Cleanup

  • Remove the write-only keyboardActiveRef and the unconsumed events context field.
  • Use ownerWindow(el).getComputedStyle(el) in SelectPopup (repo convention for realm-sensitive lookups).
  • Drop a stray useStore argument in SelectArrow and unused scroll-arrow refs.
  • Comment fixes (backdrop description + generated docs, parseFloat fallback, outside-press); remove a shipped XXX note.

Tests

  • Typeahead skips a disabled item and commits the next match.
  • Commits nothing when the only typeahead match is disabled.
  • Multiple-mode itemToStringValue isn't invoked with the array.

Typecheck, eslint, prettier, and the Select / Menu / Combobox / useTypeahead suites pass. Based on current master.

@atomiks atomiks added component: select Changes related to the select component. type: bug It doesn't behave as expected. labels Jun 12, 2026
@pkg-pr-new

pkg-pr-new Bot commented Jun 12, 2026

Copy link
Copy Markdown

commit: 78d89a5

@code-infra-dashboard

code-infra-dashboard Bot commented Jun 12, 2026

Copy link
Copy Markdown

Bundle size

Bundle Parsed size Gzip size
@base-ui/react ▼-236B(-0.05%) ▼-53B(-0.04%)

Details of bundle changes

Performance

Total duration: 1,352.76 ms -101.49 ms(-7.0%) | Renders: 50 (+0) | Paint: 2,057.49 ms -126.90 ms(-5.8%)

Test Duration Renders
Checkbox mount (500 instances) 78.13 ms ▼-35.97 ms(-31.5%) 1 (+0)

11 tests within noise — details


Check out the code infra dashboard for more information about this PR.

@netlify

netlify Bot commented Jun 12, 2026

Copy link
Copy Markdown

Deploy Preview for base-ui ready!

Name Link
🔨 Latest commit 78d89a5
🔍 Latest deploy log https://app.netlify.com/projects/base-ui/deploys/6a2baa9e57815e0008719e1b
😎 Deploy Preview https://deploy-preview-5025--base-ui.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@atomiks atomiks force-pushed the claude/select-typeahead-multiple-fixes branch from 2d54c1b to 7e3f5fc Compare June 12, 2026 06:25
@atomiks atomiks changed the title [select] Fix typeahead-disabled commit and multiple-mode serialization [select] Skip disabled items in typeahead and fix multiple-mode serialization Jun 12, 2026
@atomiks atomiks force-pushed the claude/select-typeahead-multiple-fixes branch from 7e3f5fc to 691843e Compare June 12, 2026 06:40
…lization

Bugs: typeahead now skips disabled items while matching, so a single keypress advances to the next selectable item (like native <select> and arrow-key navigation) in both open and closed states — via a new opt-in 'isIndexDisabled' predicate on useTypeahead (Menu/Combobox don't pass it, so they're unchanged); multiple mode no longer passes the whole value array to itemToStringValue (the shared input is nameless); maxHeight:'auto' (invalid no-op) -> 'none' in align mode; trigger callback refs no longer fire twice; empty multiple array compares as undefined (not raw []) for custom isItemEqualToValue.

Cleanup: remove write-only keyboardActiveRef and the unconsumed events context field; drop the stray useStore arg in SelectArrow and the unused scroll-arrow refs; use ownerWindow(el).getComputedStyle per repo convention; comment fixes (SelectBackdrop description + docs, parseFloat fallback, outside-press); remove a shipped XXX note.

Tests: typeahead skips a disabled item and commits the next match; commits nothing when the only match is disabled; multiple-mode itemToStringValue isn't invoked with the array.
@atomiks atomiks force-pushed the claude/select-typeahead-multiple-fixes branch from 691843e to 78d89a5 Compare June 12, 2026 06:43
@atomiks atomiks requested a review from Copilot June 12, 2026 08:13
@atomiks atomiks marked this pull request as ready for review June 12, 2026 08:13

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

Pull request overview

This PR fixes several Select correctness issues, centered on typeahead behavior and multiple-mode form serialization, and adds regression tests to prevent future regressions.

Changes:

  • Extend useTypeahead with an optional isIndexDisabled predicate and use it in Select to skip disabled items during matching (including closed-trigger typeahead).
  • Fix Select multiple-mode serialization so the shared hidden input doesn’t attempt to stringify the entire selected-value array.
  • Misc. Select cleanup (remove unused context fields/refs, realm-safe getComputedStyle, ref wiring) plus regression tests and doc/comment corrections.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/react/src/select/trigger/SelectTrigger.tsx Ref wiring cleanup to prevent duplicate ref-callback firing; clarifies outside-press mouseup handling.
packages/react/src/select/root/SelectRootContext.ts Removes unused context fields (events, keyboardActiveRef) and unused import.
packages/react/src/select/root/SelectRoot.tsx Multiple-mode serialization fix; integrates disabled-skipping into typeahead via new hook predicate; removes unconsumed events plumbing.
packages/react/src/select/root/SelectRoot.test.tsx Adds regression tests for multiple-mode serialization and disabled-skipping typeahead on closed trigger.
packages/react/src/select/popup/SelectPopup.tsx Uses realm-safe ownerWindow(...).getComputedStyle(...); fixes maxHeight assignment; removes unused refs.
packages/react/src/select/item/SelectItem.tsx Ensures custom equality function isn’t called with the raw empty array in multiple mode.
packages/react/src/select/backdrop/SelectBackdrop.tsx Corrects component doc comment (“select popup”).
packages/react/src/select/arrow/SelectArrow.tsx Removes a stray unused argument passed to useStore.
packages/react/src/floating-ui-react/hooks/useTypeahead.ts Adds isIndexDisabled option and skips disabled items while matching.
docs/src/app/(docs)/react/components/select/types.md Updates generated docs text to match Select terminology (“select popup”).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: select Changes related to the select component. type: bug It doesn't behave as expected.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants