Skip to content

Commit 49be570

Browse files
crisbetojelbourn
authored andcommitted
fix(chips): chip list overriding chip disabled value (#19228)
When a chip list is disabled, it goes through all the chips and sets their `disabled` values. The problem is that this overrides any individual values the consumer may have set. These changes fix the issue by saving the value to a different field. Fixes #19213.
1 parent e61deb9 commit 49be570

File tree

4 files changed

+45
-10
lines changed

4 files changed

+45
-10
lines changed

src/material/chips/chip-list.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,28 @@ describe('MatChipList', () => {
112112
expect(chips.toArray().every(chip => chip.disabled)).toBe(true);
113113
}));
114114

115+
it('should preserve the disabled state of a chip if the list gets re-enabled', () => {
116+
const chipArray = chips.toArray();
117+
118+
chipArray[2].disabled = true;
119+
fixture.detectChanges();
120+
121+
expect(chips.toArray().map(chip => chip.disabled))
122+
.toEqual([false, false, true, false, false]);
123+
124+
chipListInstance.disabled = true;
125+
fixture.detectChanges();
126+
127+
expect(chips.toArray().map(chip => chip.disabled))
128+
.toEqual([true, true, true, true, true]);
129+
130+
chipListInstance.disabled = false;
131+
fixture.detectChanges();
132+
133+
expect(chips.toArray().map(chip => chip.disabled))
134+
.toEqual([false, false, true, false, false]);
135+
});
136+
115137
});
116138

117139
describe('with selected chips', () => {

src/material/chips/chip-list.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,7 @@ export class MatChipList extends _MatChipListMixinBase implements MatFormFieldCo
808808
private _syncChipsState() {
809809
if (this.chips) {
810810
this.chips.forEach(chip => {
811-
chip.disabled = this._disabled;
811+
chip._chipListDisabled = this._disabled;
812812
chip._chipListMultiple = this.multiple;
813813
});
814814
}

src/material/chips/chip.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,13 @@ import {
2929
import {
3030
CanColor,
3131
CanColorCtor,
32-
CanDisable,
33-
CanDisableCtor,
3432
CanDisableRipple,
3533
CanDisableRippleCtor,
3634
HasTabIndex,
3735
HasTabIndexCtor,
3836
mixinTabIndex,
3937
MAT_RIPPLE_GLOBAL_OPTIONS,
4038
mixinColor,
41-
mixinDisabled,
4239
mixinDisableRipple,
4340
RippleConfig,
4441
RippleGlobalOptions,
@@ -71,12 +68,13 @@ export class MatChipSelectionChange {
7168
// Boilerplate for applying mixins to MatChip.
7269
/** @docs-private */
7370
class MatChipBase {
71+
disabled: boolean;
7472
constructor(public _elementRef: ElementRef) {}
7573
}
7674

77-
const _MatChipMixinBase: CanColorCtor & CanDisableRippleCtor & CanDisableCtor &
75+
const _MatChipMixinBase: CanColorCtor & CanDisableRippleCtor &
7876
HasTabIndexCtor & typeof MatChipBase =
79-
mixinTabIndex(mixinColor(mixinDisableRipple(mixinDisabled(MatChipBase)), 'primary'), -1);
77+
mixinTabIndex(mixinColor(mixinDisableRipple(MatChipBase), 'primary'), -1);
8078

8179
/**
8280
* Dummy directive to add CSS class to chip avatar.
@@ -103,7 +101,7 @@ export class MatChipTrailingIcon {}
103101
*/
104102
@Directive({
105103
selector: `mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]`,
106-
inputs: ['color', 'disabled', 'disableRipple', 'tabIndex'],
104+
inputs: ['color', 'disableRipple', 'tabIndex'],
107105
exportAs: 'matChip',
108106
host: {
109107
'class': 'mat-chip mat-focus-indicator',
@@ -124,7 +122,7 @@ export class MatChipTrailingIcon {}
124122
},
125123
})
126124
export class MatChip extends _MatChipMixinBase implements FocusableOption, OnDestroy, CanColor,
127-
CanDisable, CanDisableRipple, RippleTarget, HasTabIndex {
125+
CanDisableRipple, RippleTarget, HasTabIndex {
128126

129127
/** Reference to the RippleRenderer for the chip. */
130128
private _chipRipple: RippleRenderer;
@@ -164,6 +162,9 @@ export class MatChip extends _MatChipMixinBase implements FocusableOption, OnDes
164162
/** Whether the chip list is in multi-selection mode. */
165163
_chipListMultiple: boolean = false;
166164

165+
/** Whether the chip list as a whole is disabled. */
166+
_chipListDisabled: boolean = false;
167+
167168
/** The chip avatar */
168169
@ContentChild(MatChipAvatar) avatar: MatChipAvatar;
169170

@@ -209,6 +210,14 @@ export class MatChip extends _MatChipMixinBase implements FocusableOption, OnDes
209210
}
210211
protected _selectable: boolean = true;
211212

213+
/** Whether the chip is disabled. */
214+
@Input()
215+
get disabled(): boolean { return this._chipListDisabled || this._disabled; }
216+
set disabled(value: boolean) {
217+
this._disabled = coerceBooleanProperty(value);
218+
}
219+
protected _disabled: boolean = false;
220+
212221
/**
213222
* Determines whether or not the chip displays the remove styling and emits (removed) events.
214223
*/

tools/public_api_guard/material/chips.d.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
export declare const MAT_CHIPS_DEFAULT_OPTIONS: InjectionToken<MatChipsDefaultOptions>;
22

3-
export declare class MatChip extends _MatChipMixinBase implements FocusableOption, OnDestroy, CanColor, CanDisable, CanDisableRipple, RippleTarget, HasTabIndex {
3+
export declare class MatChip extends _MatChipMixinBase implements FocusableOption, OnDestroy, CanColor, CanDisableRipple, RippleTarget, HasTabIndex {
44
_animationsDisabled: boolean;
5+
_chipListDisabled: boolean;
56
_chipListMultiple: boolean;
7+
protected _disabled: boolean;
68
_elementRef: ElementRef<HTMLElement>;
79
_hasFocus: boolean;
810
readonly _onBlur: Subject<MatChipEvent>;
@@ -15,6 +17,8 @@ export declare class MatChip extends _MatChipMixinBase implements FocusableOptio
1517
avatar: MatChipAvatar;
1618
chipListSelectable: boolean;
1719
readonly destroyed: EventEmitter<MatChipEvent>;
20+
get disabled(): boolean;
21+
set disabled(value: boolean);
1822
get removable(): boolean;
1923
set removable(value: boolean);
2024
removeIcon: MatChipRemove;
@@ -46,7 +50,7 @@ export declare class MatChip extends _MatChipMixinBase implements FocusableOptio
4650
static ngAcceptInputType_removable: BooleanInput;
4751
static ngAcceptInputType_selectable: BooleanInput;
4852
static ngAcceptInputType_selected: BooleanInput;
49-
static ɵdir: i0.ɵɵDirectiveDefWithMeta<MatChip, "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", ["matChip"], { "color": "color"; "disabled": "disabled"; "disableRipple": "disableRipple"; "tabIndex": "tabIndex"; "selected": "selected"; "value": "value"; "selectable": "selectable"; "removable": "removable"; }, { "selectionChange": "selectionChange"; "destroyed": "destroyed"; "removed": "removed"; }, ["avatar", "trailingIcon", "removeIcon"]>;
53+
static ɵdir: i0.ɵɵDirectiveDefWithMeta<MatChip, "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", ["matChip"], { "color": "color"; "disableRipple": "disableRipple"; "tabIndex": "tabIndex"; "selected": "selected"; "value": "value"; "selectable": "selectable"; "disabled": "disabled"; "removable": "removable"; }, { "selectionChange": "selectionChange"; "destroyed": "destroyed"; "removed": "removed"; }, ["avatar", "trailingIcon", "removeIcon"]>;
5054
static ɵfac: i0.ɵɵFactoryDef<MatChip, [null, null, null, { optional: true; }, { optional: true; }, null, { attribute: "tabindex"; }, { optional: true; }]>;
5155
}
5256

0 commit comments

Comments
 (0)