Skip to content

Commit 9b3c211

Browse files
feat(material/chips): update chip-list describedby to match input
Fixes #16209: ExpressionChangedAfterItHasBeenCheckedError that occurs when chip-lists are content-projected into a mat-form-field
1 parent fed8fae commit 9b3c211

File tree

2 files changed

+13
-7
lines changed

2 files changed

+13
-7
lines changed

src/material/chips/chip-list.ts

+11-5
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ export class MatChipListChange {
7878
exportAs: 'matChipList',
7979
host: {
8080
'[attr.tabindex]': 'disabled ? null : _tabIndex',
81-
'[attr.aria-describedby]': '_ariaDescribedby || null',
8281
'[attr.aria-required]': 'role ? required : null',
8382
'[attr.aria-disabled]': 'disabled.toString()',
8483
'[attr.aria-invalid]': 'errorState',
@@ -144,9 +143,6 @@ export class MatChipList
144143
/** Uid of the chip list */
145144
_uid: string = `mat-chip-list-${nextUniqueId++}`;
146145

147-
/** The aria-describedby attribute on the chip list for improved a11y. */
148-
_ariaDescribedby: string;
149-
150146
/** Tab index for the chip list. */
151147
_tabIndex = 0;
152148

@@ -177,6 +173,12 @@ export class MatChipList
177173
return this.empty ? null : 'listbox';
178174
}
179175

176+
/**
177+
* Implemented as part of MatFormFieldControl.
178+
* @docs-private
179+
*/
180+
@Input('aria-describedby') userAriaDescribedBy: string;
181+
180182
/** An object used to control when error messages are shown. */
181183
@Input() override errorStateMatcher: ErrorStateMatcher;
182184

@@ -455,7 +457,11 @@ export class MatChipList
455457
* @docs-private
456458
*/
457459
setDescribedByIds(ids: string[]) {
458-
this._ariaDescribedby = ids.join(' ');
460+
if (ids.length) {
461+
this._elementRef.nativeElement.setAttribute('aria-describedby', ids.join(' '));
462+
} else {
463+
this._elementRef.nativeElement.removeAttribute('aria-describedby');
464+
}
459465
}
460466

461467
// Implemented as part of ControlValueAccessor.

tools/public_api_guard/material/chips.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,6 @@ export interface MatChipInputEvent {
181181
export class MatChipList extends _MatChipListBase implements MatFormFieldControl<any>, ControlValueAccessor, AfterContentInit, DoCheck, OnInit, OnDestroy, CanUpdateErrorState {
182182
constructor(_elementRef: ElementRef<HTMLElement>, _changeDetectorRef: ChangeDetectorRef, _dir: Directionality, _parentForm: NgForm, _parentFormGroup: FormGroupDirective, _defaultErrorStateMatcher: ErrorStateMatcher, ngControl: NgControl);
183183
_allowFocusEscape(): void;
184-
_ariaDescribedby: string;
185184
ariaOrientation: 'horizontal' | 'vertical';
186185
_blur(): void;
187186
readonly change: EventEmitter<MatChipListChange>;
@@ -255,6 +254,7 @@ export class MatChipList extends _MatChipListBase implements MatFormFieldControl
255254
_uid: string;
256255
protected _updateFocusForDestroyedChips(): void;
257256
protected _updateTabIndex(): void;
257+
userAriaDescribedBy: string;
258258
_userTabIndex: number | null;
259259
get value(): any;
260260
set value(value: any);
@@ -264,7 +264,7 @@ export class MatChipList extends _MatChipListBase implements MatFormFieldControl
264264
// (undocumented)
265265
writeValue(value: any): void;
266266
// (undocumented)
267-
static ɵcmp: i0.ɵɵComponentDeclaration<MatChipList, "mat-chip-list", ["matChipList"], { "errorStateMatcher": "errorStateMatcher"; "multiple": "multiple"; "compareWith": "compareWith"; "value": "value"; "required": "required"; "placeholder": "placeholder"; "disabled": "disabled"; "ariaOrientation": "aria-orientation"; "selectable": "selectable"; "tabIndex": "tabIndex"; }, { "change": "change"; "valueChange": "valueChange"; }, ["chips"], ["*"]>;
267+
static ɵcmp: i0.ɵɵComponentDeclaration<MatChipList, "mat-chip-list", ["matChipList"], { "userAriaDescribedBy": "aria-describedby"; "errorStateMatcher": "errorStateMatcher"; "multiple": "multiple"; "compareWith": "compareWith"; "value": "value"; "required": "required"; "placeholder": "placeholder"; "disabled": "disabled"; "ariaOrientation": "aria-orientation"; "selectable": "selectable"; "tabIndex": "tabIndex"; }, { "change": "change"; "valueChange": "valueChange"; }, ["chips"], ["*"]>;
268268
// (undocumented)
269269
static ɵfac: i0.ɵɵFactoryDeclaration<MatChipList, [null, null, { optional: true; }, { optional: true; }, { optional: true; }, null, { optional: true; self: true; }]>;
270270
}

0 commit comments

Comments
 (0)