diff --git a/src/material/core/option/option-parent.ts b/src/material/core/option/option-parent.ts index 8df8908f35a5..82d1e0e8c00e 100644 --- a/src/material/core/option/option-parent.ts +++ b/src/material/core/option/option-parent.ts @@ -15,6 +15,7 @@ import {InjectionToken, Signal} from '@angular/core'; */ export interface MatOptionParentComponent { disableRipple?: boolean | Signal; + disableOptions?: boolean; multiple?: boolean; inertGroups?: boolean; hideSingleSelectionIndicator?: boolean; diff --git a/src/material/core/option/option.ts b/src/material/core/option/option.ts index a4a893b25489..8e261da06278 100644 --- a/src/material/core/option/option.ts +++ b/src/material/core/option/option.ts @@ -241,7 +241,7 @@ export class MatOption implements FocusableOption, AfterViewChecked, On * determine if the select's view -> model callback should be invoked.` */ _selectViaInteraction(): void { - if (!this.disabled) { + if (!this.disabled && !this._parent?.disableOptions) { this._selected = this.multiple ? !this._selected : true; this._changeDetectorRef.markForCheck(); this._emitSelectionChangeEvent(true); diff --git a/src/material/select/select.spec.ts b/src/material/select/select.spec.ts index 9728ec2d78ac..ae407afa9f24 100644 --- a/src/material/select/select.spec.ts +++ b/src/material/select/select.spec.ts @@ -1932,6 +1932,22 @@ describe('MatSelect', () => { expect(trigger.textContent!.trim()).toBe('PIZZA'); }); + it('should not select an option when disabled while open', () => { + fixture.componentInstance.control.setValue('pizza-1'); + fixture.detectChanges(); + trigger.click(); + fixture.detectChanges(); + const selectionChange = jasmine.createSpy('selectionChange'); + fixture.componentInstance.select.selectionChange.subscribe(selectionChange); + fixture.componentInstance.control.disable({emitEvent: false}); + fixture.detectChanges(); + const option = getOverlayHost(fixture)!.querySelector('mat-option') as HTMLElement; + option.click(); + fixture.detectChanges(); + expect(fixture.componentInstance.control.value).toBe('pizza-1'); + expect(selectionChange).not.toHaveBeenCalled(); + }); + it('should not select disabled options', () => { trigger.click(); fixture.detectChanges(); diff --git a/src/material/select/select.ts b/src/material/select/select.ts index 59415b689663..57cdbde6eaa4 100644 --- a/src/material/select/select.ts +++ b/src/material/select/select.ts @@ -387,6 +387,11 @@ export class MatSelect @Input({transform: booleanAttribute}) disabled: boolean = false; + /** Whether options are disabled by the select. */ + get disableOptions(): boolean { + return this.disabled; + } + /** Whether ripples in the select are disabled. */ @Input({transform: booleanAttribute}) get disableRipple() {