diff --git a/src/material/chips/chip-listbox.spec.ts b/src/material/chips/chip-listbox.spec.ts index b87a91e7a7b9..1de4a5c0747e 100644 --- a/src/material/chips/chip-listbox.spec.ts +++ b/src/material/chips/chip-listbox.spec.ts @@ -113,6 +113,15 @@ describe('MatChipListbox', () => { expect(chipListboxNativeElement.hasAttribute('role')).toBe(false); expect(chipListboxNativeElement.hasAttribute('aria-required')).toBe(false); }); + + it('should toggle the chips disabled state based on whether it is disabled', fakeAsync(() => { + fixture.destroy(); + TestBed.resetTestingModule(); + const disabledFixture = createComponent(IndividuallyDisabledChipInsideForm); + disabledFixture.detectChanges(); + flush(); + expect(disabledFixture.componentInstance.chip.disabled).toBe(true); + })); }); describe('with selected chips', () => { @@ -1043,3 +1052,17 @@ class FalsyBasicChipListbox { @ViewChild(MatChipListbox) chipListbox: MatChipListbox; @ViewChildren(MatChipOption) chips: QueryList; } + +// Based on #29783. +@Component({ + template: ` +
+ + Hello + +
+ `, +}) +class IndividuallyDisabledChipInsideForm { + @ViewChild(MatChipOption) chip: MatChipOption; +} diff --git a/src/material/chips/chip-set.ts b/src/material/chips/chip-set.ts index d31cd06bfd38..edcf89b6417a 100644 --- a/src/material/chips/chip-set.ts +++ b/src/material/chips/chip-set.ts @@ -158,12 +158,10 @@ export class MatChipSet implements AfterViewInit, OnDestroy { /** Syncs the chip-set's state with the individual chips. */ protected _syncChipsState() { - if (this._chips) { - this._chips.forEach(chip => { - chip.disabled = this._disabled; - chip._changeDetectorRef.markForCheck(); - }); - } + this._chips?.forEach(chip => { + chip._chipListDisabled = this._disabled; + chip._changeDetectorRef.markForCheck(); + }); } /** Dummy method for subclasses to override. Base chip set cannot be focused. */ diff --git a/src/material/chips/chip.ts b/src/material/chips/chip.ts index 1318d4e2eea8..136f9806c06b 100644 --- a/src/material/chips/chip.ts +++ b/src/material/chips/chip.ts @@ -158,6 +158,9 @@ export class MatChip implements OnInit, AfterViewInit, AfterContentInit, DoCheck /** Id of a span that contains this chip's aria description. */ _ariaDescriptionId = `${this.id}-aria-description`; + /** Whether the chip list is disabled. */ + _chipListDisabled: boolean = false; + private _textElement!: HTMLElement; /** @@ -201,7 +204,13 @@ export class MatChip implements OnInit, AfterViewInit, AfterContentInit, DoCheck /** Whether the chip is disabled. */ @Input({transform: booleanAttribute}) - disabled: boolean = false; + get disabled(): boolean { + return this._disabled || this._chipListDisabled; + } + set disabled(value: boolean) { + this._disabled = value; + } + private _disabled = false; /** Emitted when a chip is to be removed. */ @Output() readonly removed: EventEmitter = new EventEmitter(); diff --git a/tools/public_api_guard/material/chips.md b/tools/public_api_guard/material/chips.md index ebd3ea852775..add6d0721e5a 100644 --- a/tools/public_api_guard/material/chips.md +++ b/tools/public_api_guard/material/chips.md @@ -58,9 +58,11 @@ export class MatChip implements OnInit, AfterViewInit, AfterContentInit, DoCheck protected basicChipAttrName: string; // (undocumented) _changeDetectorRef: ChangeDetectorRef; + _chipListDisabled: boolean; color?: string | null; readonly destroyed: EventEmitter; - disabled: boolean; + get disabled(): boolean; + set disabled(value: boolean); disableRipple: boolean; // (undocumented) protected _document: Document;