Skip to content

fix(material/select): prevent option selection while disabled - #34044

Closed
Xapollon430 wants to merge 1 commit into
angular:mainfrom
Xapollon430:codex/select-prevent-disabled-option-selection
Closed

Xapollon430 wants to merge 1 commit into
angular:mainfrom
Xapollon430:codex/select-prevent-disabled-option-selection

Conversation

@Xapollon430

@Xapollon430 Xapollon430 commented Nov 2, 2026 •

Copy link
Copy Markdown

Problem

I was playing around with mat-select and noticed a bug where:

  1. Open an enabled Select.
  2. Set disabled to true while its panel is open.
  3. Click an option. The selected value changes and selectionChange fires.

Here is a reproduction video of the issue, recorded before the fix:

angular-material-styled-repro.mp4

This uses published Angular Material 21.2.14, the official Azure Blue prebuilt theme, and a standard mat-form-field. Click "Disable in 3 seconds", open the Select, and wait for the field to turn gray before clicking Orange. The readout shows that the parent is disabled before the selection. There are no forced clicks or custom select, option, or overlay styles.

The original recording was missing styles, which made the issue unclear. I agree that an individually disabled option already has pointer-events: none. This is a different state: the parent Select becomes disabled after opening, while its options are still enabled. In the corrected reproduction, an option has aria-disabled="false" and pointer-events: auto, even though its parent Select reports aria-disabled="true".

A prop update can send disabled=true while someone is choosing an option, for example when an asynchronous request completes or a timer fires. I ran into this sequence while varying component props with Hegel and exercising UI actions with Bombadil in Anta, then reproduced the Angular Material behavior independently with Playwright.

My first thought was to close the panel, since that is what I observed with a native HTML select in Chromium. The HTML option-picking algorithm also stops without selecting an option when the select is disabled.

This PR takes the smaller step of rejecting user selection when the parent Select is disabled. It preserves the current panel behavior and still allows programmatic value changes. Closing the panel when disabled is a reasonable choice too, and I'm happy to adjust the PR to follow Angular Material's preferred pattern. The behavior I'm trying to guarantee is simply that a disabled Select stops accepting user selections.

Validation

  • The regression fails on the original source in Chromium and Firefox.
  • pnpm exec bazel test //src/material/select:unit_tests --test_output=errors: Chromium and Firefox targets pass with the fix.
  • Rechecked the styled browser reproduction: the enabled field turns gray, the parent reports disabled, and a normal click on Orange still changes the value and emits one selectionChange before the fix. No page errors.
  • Current upstream MatOption._selectViaInteraction() still checks only the option's own disabled state.

@google-cla

google-cla Bot commented Nov 2, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@Xapollon430
Xapollon430 marked this pull request as ready for review November 2, 2026 03:19
@pullapprove
pullapprove Bot requested review from andrewseguin and tjshiu November 2, 2026 03:19
@crisbeto

crisbeto commented Nov 2, 2026

Copy link
Copy Markdown
Member

This isn't necessary, the disabled options already have pointer-events: none. Your select looks like it's missing a bunch of structural styles.

@crisbeto crisbeto closed this Nov 2, 2026
@Xapollon430

Xapollon430 commented Nov 2, 2026 •

Copy link
Copy Markdown
Author

Thanks for taking a look, and sorry for the confusion. I've replaced the video with a proper styling so the issue is actually more visible since you could not even see the select being disabled.

The case I'm trying to address is when an enabled select is opened and then the parent select becomes disabled while the panel is still open. The individual options haven't been marked disabled. In the updated recording, the select visibly turns gray, but clicking Orange still changes its value and emits selectionChange. This reproduces with a normal pointer click, without forcing the interaction.

I agree that an individually disabled option already has pointer-events: none. This is about preventing user selection after the parent select becomes disabled. Happy to adjust the approach if there's a preferred way to handle this state.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants