-
Notifications
You must be signed in to change notification settings - Fork 6.8k
/
Copy pathform-field.html
131 lines (120 loc) · 4.76 KB
/
form-field.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<ng-template #labelTemplate>
<!--
MDC recommends that the text-field is a `<label>` element. This rather complicates the
setup because it would require every form-field control to explicitly set `aria-labelledby`.
This is because the `<label>` itself contains more than the actual label (e.g. prefix, suffix
or other projected content), and screen readers could potentially read out undesired content.
Excluding elements from being printed out requires them to be marked with `aria-hidden`, or
the form control is set to a scoped element for the label (using `aria-labelledby`). Both of
these options seem to complicate the setup because we know exactly what content is rendered
as part of the label, and we don't want to spend resources on walking through projected content
to set `aria-hidden`. Nor do we want to set `aria-labelledby` on every form control if we could
simply link the label to the control using the label `for` attribute.
-->
@if (_hasFloatingLabel()) {
<label
matFormFieldFloatingLabel
[floating]="_shouldLabelFloat()"
[monitorResize]="_hasOutline()"
[id]="_labelId"
[attr.for]="_control.disableAutomaticLabeling ? null : _control.id"
>
<ng-content select="mat-label"></ng-content>
<!--
We set the required marker as a separate element, in order to make it easier to target if
apps want to override it and to be able to set `aria-hidden` so that screen readers don't
pick it up.
-->
@if (!hideRequiredMarker && _control.required) {
<span
aria-hidden="true"
class="mat-mdc-form-field-required-marker mdc-floating-label--required"
></span>
}
</label>
}
</ng-template>
<div
class="mat-mdc-text-field-wrapper mdc-text-field"
#textField
[class.mdc-text-field--filled]="!_hasOutline()"
[class.mdc-text-field--outlined]="_hasOutline()"
[class.mdc-text-field--no-label]="!_hasFloatingLabel()"
[class.mdc-text-field--disabled]="_control.disabled"
[class.mdc-text-field--invalid]="_control.errorState"
(click)="_control.onContainerClick($event)"
>
@if (!_hasOutline() && !_control.disabled) {
<div class="mat-mdc-form-field-focus-overlay"></div>
}
<div class="mat-mdc-form-field-flex">
@if (_hasOutline()) {
<div
matFormFieldNotchedOutline
[matFormFieldNotchedOutlineOpen]="_shouldLabelFloat()"
[matFormFieldHasFloatingLabel]="_hasFloatingLabel()">
@if (!_forceDisplayInfixLabel()) {
<ng-template [ngTemplateOutlet]="labelTemplate"></ng-template>
}
</div>
}
@if (_hasIconPrefix) {
<div class="mat-mdc-form-field-icon-prefix" #iconPrefixContainer>
<ng-content select="[matPrefix], [matIconPrefix]"></ng-content>
</div>
}
@if (_hasTextPrefix) {
<div class="mat-mdc-form-field-text-prefix" #textPrefixContainer>
<ng-content select="[matTextPrefix]"></ng-content>
</div>
}
<div class="mat-mdc-form-field-infix">
@if (!_hasOutline() || _forceDisplayInfixLabel()) {
<ng-template [ngTemplateOutlet]="labelTemplate"></ng-template>
}
<ng-content></ng-content>
</div>
@if (_hasTextSuffix) {
<div class="mat-mdc-form-field-text-suffix" #textSuffixContainer>
<ng-content select="[matTextSuffix]"></ng-content>
</div>
}
@if (_hasIconSuffix) {
<div class="mat-mdc-form-field-icon-suffix" #iconSuffixContainer>
<ng-content select="[matSuffix], [matIconSuffix]"></ng-content>
</div>
}
</div>
@if (!_hasOutline()) {
<div matFormFieldLineRipple></div>
}
</div>
<div
class="mat-mdc-form-field-subscript-wrapper mat-mdc-form-field-bottom-align"
[class.mat-mdc-form-field-subscript-dynamic-size]="subscriptSizing === 'dynamic'">
@let subscriptMessageType = _getSubscriptMessageType();
<!--
Use a single permanent wrapper for both hints and errors so aria-live works correctly,
as having it appear post render will not consistently work. We also do not want to add
additional divs as it causes styling regressions.
-->
<div
aria-atomic="true"
aria-live="polite"
[class.mat-mdc-form-field-error-wrapper]="subscriptMessageType === 'error'"
[class.mat-mdc-form-field-hint-wrapper]="subscriptMessageType === 'hint'">
@switch (subscriptMessageType) {
@case ('error') {
<ng-content select="mat-error, [matError]"></ng-content>
}
@case ('hint') {
@if (hintLabel) {
<mat-hint [id]="_hintLabelId">{{hintLabel}}</mat-hint>
}
<ng-content select="mat-hint:not([align='end'])"></ng-content>
<div class="mat-mdc-form-field-hint-spacer"></div>
<ng-content select="mat-hint[align='end']"></ng-content>
}
}
</div>
</div>