Skip to content

Commit 4e60f20

Browse files
committed
Move better sync logic to formfield
1 parent 47df973 commit 4e60f20

File tree

2 files changed

+18
-33
lines changed

2 files changed

+18
-33
lines changed

src/material/form-field/form-field.ts

+15-10
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ export class MatFormField
309309
readonly _hintLabelId = this._idGenerator.getId('mat-mdc-hint-');
310310

311311
// Ids obtained from the fields
312-
private _describedByIds: Array<String> = [];
312+
private _describedByIds: string[] | undefined;
313313

314314
/** Gets the current form field control */
315315
get _control(): MatFormFieldControl<any> {
@@ -708,16 +708,21 @@ export class MatFormField
708708
ids.push(...this._errorChildren.map(error => error.id));
709709
}
710710

711-
let currentIds = this._control.describedByIds ?? [];
712-
let combinedIds: Array<string> = [];
713-
currentIds.forEach(id => {
714-
if (!this._describedByIds.includes(id)) {
715-
combinedIds.push(id);
716-
}
717-
});
718-
combinedIds.concat(...ids);
711+
const existingDescribedBy = this._control.describedByIds;
712+
let toAssign: string[];
713+
714+
// In some cases there might be some `aria-describedby` IDs that were assigned directly,
715+
// like by the `AriaDescriber` (see #30011). Attempt to preserve them by taking the previous
716+
// attribute value and filtering out the IDs that came from the previous `setDescribedByIds`
717+
// call. Note the `|| ids` here allows us to avoid duplicating IDs on the first render.
718+
if (existingDescribedBy) {
719+
const exclude = this._describedByIds || ids;
720+
toAssign = ids.concat(existingDescribedBy.filter(id => id && !exclude.includes(id)));
721+
} else {
722+
toAssign = ids;
723+
}
719724

720-
this._control.setDescribedByIds(combinedIds);
725+
this._control.setDescribedByIds(toAssign);
721726
this._describedByIds = ids;
722727
}
723728
}

src/material/input/input.ts

+3-23
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,6 @@ export class MatInput
114114
private _cleanupIosKeyup: (() => void) | undefined;
115115
private _cleanupWebkitWheel: (() => void) | undefined;
116116

117-
/** `aria-describedby` IDs assigned by the form field. */
118-
private _formFieldDescribedBy: string[] | undefined;
119-
120117
/** Whether the component is being rendered on the server. */
121118
readonly _isServer: boolean;
122119

@@ -563,30 +560,13 @@ export class MatInput
563560

564561
/**
565562
* Implemented as part of MatFormFieldControl.
566-
* @docs-private
563+
* @docs-privatex`
567564
*/
568565
setDescribedByIds(ids: string[]) {
569566
const element = this._elementRef.nativeElement;
570-
const existingDescribedBy = element.getAttribute('aria-describedby');
571-
let toAssign: string[];
572-
573-
// In some cases there might be some `aria-describedby` IDs that were assigned directly,
574-
// like by the `AriaDescriber` (see #30011). Attempt to preserve them by taking the previous
575-
// attribute value and filtering out the IDs that came from the previous `setDescribedByIds`
576-
// call. Note the `|| ids` here allows us to avoid duplicating IDs on the first render.
577-
if (existingDescribedBy) {
578-
const exclude = this._formFieldDescribedBy || ids;
579-
toAssign = ids.concat(
580-
existingDescribedBy.split(' ').filter(id => id && !exclude.includes(id)),
581-
);
582-
} else {
583-
toAssign = ids;
584-
}
585-
586-
this._formFieldDescribedBy = ids;
587567

588-
if (toAssign.length) {
589-
element.setAttribute('aria-describedby', toAssign.join(' '));
568+
if (ids.length) {
569+
element.setAttribute('aria-describedby', ids.join(' '));
590570
} else {
591571
element.removeAttribute('aria-describedby');
592572
}

0 commit comments

Comments
 (0)