Skip to content

Commit 0d4326f

Browse files
committed
feat(form-field): expose label content element id for custom controls
Currently, the form-field always creates a label element as sibling to projected form-field controls. For native controls, the label is associated with the controls using the `for` attribute. This doesn't work for custom controls which might not be based on native controls. e.g. the `mat-select`. In those cases, the appropriate aria attributes need to be applied with `aria-labelledby` that refers to the label content element. Since this is a common pattern for custom controls that don't use native controls, we need to expose the element id for the label content. Currently we already do this for the select, but just prefixed it with an underscore. This denotes it as private API while there is obviously a use-case for exposing this publicly. Best example is how the select _needs_ it.
1 parent 198911f commit 0d4326f

File tree

6 files changed

+12
-12
lines changed

6 files changed

+12
-12
lines changed

src/material-experimental/mdc-form-field/form-field.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*ngIf="_hasFloatingLabel()"
66
(cdkObserveContent)="_refreshOutlineNotchWidth()"
77
[cdkObserveContentDisabled]="!_hasOutline()"
8-
[id]="_labelId"
8+
[id]="labelContentId"
99
[attr.for]="_control.id"
1010
[attr.aria-owns]="_control.id">
1111
<ng-content select="mat-label"></ng-content>

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,11 +192,11 @@ export class MatFormField implements AfterViewInit, OnDestroy, AfterContentCheck
192192
}
193193
private _hintLabel = '';
194194

195-
// Unique id for the hint label.
196-
_hintLabelId: string = `mat-hint-${nextUniqueId++}`;
195+
/** Unique id for the label content. */
196+
readonly labelContentId: string = `mat-form-field-label-${nextUniqueId++}`;
197197

198-
// Unique id for the internal form field label.
199-
_labelId = `mat-form-field-label-${nextUniqueId++}`;
198+
// Unique id for the hint label.
199+
readonly _hintLabelId: string = `mat-hint-${nextUniqueId++}`;
200200

201201
/** State of the mat-hint and mat-error animations. */
202202
_subscriptAnimationState: string = '';

src/material/form-field/form-field.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
<label class="mat-form-field-label"
3030
(cdkObserveContent)="updateOutlineGap()"
3131
[cdkObserveContentDisabled]="appearance != 'outline'"
32-
[id]="_labelId"
32+
[id]="labelContentId"
3333
[attr.for]="_control.id"
3434
[attr.aria-owns]="_control.id"
3535
[class.mat-empty]="_control.empty && !_shouldAlwaysFloat"

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,10 @@ export class MatFormField extends _MatFormFieldMixinBase
210210
private _hintLabel = '';
211211

212212
// Unique id for the hint label.
213-
_hintLabelId: string = `mat-hint-${nextUniqueId++}`;
213+
readonly _hintLabelId: string = `mat-hint-${nextUniqueId++}`;
214214

215-
// Unique id for the internal form field label.
216-
_labelId = `mat-form-field-label-${nextUniqueId++}`;
215+
/** Unique id for the label content. */
216+
readonly labelContentId = `mat-form-field-label-${nextUniqueId++}`;
217217

218218
/**
219219
* Whether the label should always float, never float or float as the user types.

src/material/select/select.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1166,7 +1166,7 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
11661166
return null;
11671167
}
11681168

1169-
return this._parentFormField._labelId || null;
1169+
return this._parentFormField.labelContentId || null;
11701170
}
11711171

11721172
/** Determines the `aria-activedescendant` to be set on the host. */

tools/public_api_guard/material/form-field.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,11 @@ export declare class MatFormField extends _MatFormFieldMixinBase implements Afte
2626
_elementRef: ElementRef;
2727
_errorChildren: QueryList<MatError>;
2828
_hintChildren: QueryList<MatHint>;
29-
_hintLabelId: string;
29+
readonly _hintLabelId: string;
3030
_inputContainerRef: ElementRef;
3131
get _labelChild(): MatLabel;
3232
_labelChildNonStatic: MatLabel;
3333
_labelChildStatic: MatLabel;
34-
_labelId: string;
3534
_placeholderChild: MatPlaceholder;
3635
_prefixChildren: QueryList<MatPrefix>;
3736
get _shouldAlwaysFloat(): boolean;
@@ -45,6 +44,7 @@ export declare class MatFormField extends _MatFormFieldMixinBase implements Afte
4544
set hideRequiredMarker(value: boolean);
4645
get hintLabel(): string;
4746
set hintLabel(value: string);
47+
readonly labelContentId: string;
4848
underlineRef: ElementRef;
4949
constructor(_elementRef: ElementRef, _changeDetectorRef: ChangeDetectorRef, labelOptions: LabelOptions, _dir: Directionality, _defaults: MatFormFieldDefaultOptions, _platform: Platform, _ngZone: NgZone, _animationMode: string);
5050
_animateAndLockLabel(): void;

0 commit comments

Comments
 (0)