Skip to content

Commit 04d2aaa

Browse files
devversionmmalerba
andauthored
fix(material-experimental/mdc-form-field): fix outline notch width (#23005)
* fix(material-experimental/mdc-form-field): fix outline notch width This commit fixes a couple of issues that have been introduced by accident over time: 1. The outline notch width is incorrectly calculated since #21676. This happens because we manually override the label's typography level to `body1` but didn't account for the `font-size` set by the `notched-outline`. This resulted in the computed label width being incorrect. 2. #22089 added `line-height: 0` to fix textarea's accidentally expanding the infix vertically. This breaks custom controls and their alignment. Textarea's behave a little different compared to a native input, and the actual fix seems to be to fix the alignment from `top` to `middle` so that the infix does not try to add additional padding (due to the inherited `body1` line-height and to satisfy `min-height`). Example: https://jsfiddle.net/rpvm4bkL/6/. 3. Typography has been moved with #21676 to the input control (notice how `font: inherit` is removed too). This breaks custom form controls that rely on the typography provided by the form-field (these controls would just inherit typography) 4. Not an actual fix, but a cleanup since 21ab17f added a class to avoid styles from the form-field leaking into standalone inputs. The class has been updated to be more specific that it only matches form-control inputs, and not _any_ type of form control. * fix(material-experimental/mdc-form-field): increase specificity of `line-height: normal` on the floating label Co-authored-by: Miles Malerba <[email protected]>
1 parent 760b456 commit 04d2aaa

15 files changed

+104
-56
lines changed

src/dev-app/mdc-input/mdc-input-demo.html

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,25 @@ <h3>&lt;textarea&gt; with bindable autosize </h3>
731731
<mat-label>Label</mat-label>
732732
<input matInput>
733733
</mat-form-field>
734+
735+
<p>
736+
Textarea alignment
737+
</p>
738+
739+
<mat-form-field appearance="outline">
740+
<mat-label>Textarea</mat-label>
741+
<textarea matInput rows="1"></textarea>
742+
</mat-form-field>
743+
744+
<mat-form-field appearance="outline">
745+
<mat-label>Input</mat-label>
746+
<input matInput>
747+
</mat-form-field>
748+
749+
<mat-form-field appearance="outline">
750+
<mat-label>Input</mat-label>
751+
<input matInput>
752+
</mat-form-field>
734753
</mat-card-content>
735754
</mat-card>
736755

src/material-experimental/mdc-chips/chip-input.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ describe('MDC-based MatChipInput', () => {
141141

142142
it('should set input styling classes', () => {
143143
expect(inputNativeElement.classList).toContain('mat-mdc-input-element');
144-
expect(inputNativeElement.classList).toContain('mat-mdc-form-field-control');
144+
expect(inputNativeElement.classList).toContain('mat-mdc-form-field-input-control');
145145
expect(inputNativeElement.classList).toContain('mat-mdc-chip-input');
146146
expect(inputNativeElement.classList).toContain('mdc-text-field__input');
147147
});

src/material-experimental/mdc-chips/chip-input.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ export class MatChipInput implements MatChipTextControl, AfterContentInit, OnCha
135135
this.inputElement = this._elementRef.nativeElement as HTMLInputElement;
136136

137137
if (formField) {
138-
this.inputElement.classList.add('mat-mdc-form-field-control');
138+
this.inputElement.classList.add('mat-mdc-form-field-input-control');
139139
}
140140
}
141141

src/material-experimental/mdc-form-field/_form-field-native-select.scss

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ $mat-form-field-select-horizontal-end-padding: $mat-form-field-select-arrow-widt
1717
// Remove the native select down arrow and ensure that the native appearance
1818
// does not conflict with the form-field. e.g. Focus indication of the native
1919
// select is undesired since we handle focus as part of the form-field.
20-
select.mat-mdc-form-field-control {
20+
select.mat-mdc-form-field-input-control {
2121
-moz-appearance: none;
2222
-webkit-appearance: none;
2323
background-color: transparent;
@@ -58,7 +58,7 @@ $mat-form-field-select-horizontal-end-padding: $mat-form-field-select-arrow-widt
5858

5959
// Add padding on the end of the native select so that the content does not
6060
// overlap with the Material Design arrow.
61-
.mat-mdc-form-field-control {
61+
.mat-mdc-form-field-input-control {
6262
padding-right: $mat-form-field-select-horizontal-end-padding;
6363
[dir='rtl'] & {
6464
padding-right: 0;
@@ -80,7 +80,7 @@ $mat-form-field-select-horizontal-end-padding: $mat-form-field-select-arrow-widt
8080
$dropdown-icon-color: rgba(mdc-theme-color.prop-value(on-surface), 0.54);
8181
$disabled-dropdown-icon-color: rgba(mdc-theme-color.prop-value(on-surface), 0.38);
8282

83-
select.mat-mdc-form-field-control {
83+
select.mat-mdc-form-field-input-control {
8484
// On dark themes we set the native `select` color to some shade of white,
8585
// however the color propagates to all of the `option` elements, which are
8686
// always on a white background inside the dropdown, causing them to blend in.

src/material-experimental/mdc-form-field/_form-field-sizing.scss

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,3 @@ $mat-form-field-no-label-padding-top: 16px;
3838
// The amount of padding between the icon prefix/suffix and the infix.
3939
// This assumes that the icon will be a 24px square with 12px padding.
4040
$mat-form-field-icon-prefix-infix-padding: 4px;
41-
42-
// The amount of padding between the end of the form-field and the infix for a form-field with no
43-
// icons.
44-
$mat-form-field-end-padding: 16px;

src/material-experimental/mdc-form-field/_form-field-subscript.scss

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
@use '@material/textfield' as mdc-textfield;
22
@use '@material/theme/theme' as mdc-theme;
33
@use '@material/typography' as mdc-typography;
4+
@use '@material/textfield/variables' as mdc-textfield-variables;
45
@use 'form-field-sizing';
56
@use '../mdc-helpers/mdc-helpers';
67
@use '../../material/core/theming/theming';
@@ -13,16 +14,13 @@
1314
position: relative;
1415
}
1516

16-
// The horizontal padding between the edge of the text box and the start of the subscript text.
17-
$subscript-horizontal-padding: 16px;
18-
1917
.mat-mdc-form-field-hint-wrapper,
2018
.mat-mdc-form-field-error-wrapper {
2119
position: absolute;
2220
top: 0;
2321
left: 0;
2422
right: 0;
25-
padding: 0 $subscript-horizontal-padding;
23+
padding: 0 mdc-textfield-variables.$padding-horizontal;
2624
}
2725

2826
.mat-mdc-form-field-bottom-align::before {
@@ -31,14 +29,8 @@
3129
height: 16px;
3230
}
3331

34-
// Scale down icons in the subscript to be the same size as the text.
35-
.mat-mdc-form-field-subscript-wrapper,
36-
.mat-mdc-form-field label {
37-
.mat-icon {
38-
width: 1em;
39-
height: 1em;
40-
font-size: inherit;
41-
}
32+
.mat-mdc-form-field-hint-end {
33+
order: 1;
4234
}
4335

4436
// Clears the floats on the hints. This is necessary for the hint animation to work.

src/material-experimental/mdc-form-field/_form-field-theme.scss

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
@use '@material/notched-outline' as mdc-notched-outline;
44
@use '@material/line-ripple' as mdc-line-ripple;
55
@use '@material/theme/theme-color' as mdc-theme-color;
6-
@use '@material/typography' as mdc-typography;
6+
@use '@material/typography/typography' as mdc-typography;
77
@use '../mdc-helpers/mdc-helpers';
88
@use '../../material/core/typography/typography';
99
@use 'form-field-density';
@@ -72,14 +72,30 @@
7272
@include mdc-line-ripple.core-styles($query: mdc-helpers.$mat-typography-styles-query);
7373
@include form-field-subscript.private-form-field-subscript-typography($config);
7474

75-
// MDC uses the `subtitle1` level for the input label and value, but the spec shows `body1` as
76-
// the correct level.
77-
.mat-mdc-form-field-control,
78-
.mat-mdc-form-field label,
79-
.mat-mdc-form-field-text-prefix,
80-
.mat-mdc-form-field-text-suffix {
75+
// MDC uses `subtitle1` for the input value, placeholder and floating label. The spec
76+
// shows `body1` for text fields though, so we manually override the typography.
77+
// Note: Form controls inherit the typography from the parent form field.
78+
.mat-mdc-form-field,
79+
.mat-mdc-form-field .mdc-floating-label {
8180
@include mdc-typography.typography(body1, $query: mdc-helpers.$mat-typography-styles-query);
8281
}
82+
83+
// Above, we updated the floating label to use the `body1` typography level. The MDC notched
84+
// outline overrides this accidentally (only when the label floats) to a `rem`-based value.
85+
// This results in different label widths when floated/docked and ultimately breaks the notch
86+
// width as it has been measured in the docked state (where `body1` is applied). We try to
87+
// unset these styles set by the `mdc-notched-outline`:
88+
// https://github.com/material-components/material-components-web/blob/master/packages/mdc-notched-outline/_mixins.scss#L272-L292.
89+
.mat-mdc-form-field .mdc-text-field--outlined {
90+
// For the non-upgraded notch label (i.e. when rendered on the server), also
91+
// use the correct `body1` typography level.
92+
.mdc-floating-label--float-above {
93+
font-size: mdc-typography.get-size(body1) * 0.75;
94+
}
95+
.mdc-notched-outline--upgraded .mdc-floating-label--float-above {
96+
font-size: mdc-typography.get-size(body1);
97+
}
98+
}
8399
}
84100
}
85101

src/material-experimental/mdc-form-field/_mdc-text-field-structure-overrides.scss

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
1-
@use 'form-field-sizing';
1+
@use '@material/textfield/variables' as mdc-textfield-variables;
22

33
// Mixin that can be included to override the default MDC text-field
44
// styles to fit our needs. See individual comments for context on why
55
// certain MDC styles need to be modified.
66
@mixin private-text-field-structure-overrides() {
77
// Unset the border set by MDC. We move the border (which serves as the Material Design
88
// text-field bottom line) into its own element. This is necessary because we want the
9-
// bottom-line to span across the whole form-field (including prefixes and suffixes).
10-
.mat-mdc-form-field-control {
9+
// bottom-line to span across the whole form-field (including prefixes and suffixes). Also
10+
// we ensure that font styles are inherited for input elements. We do this because inputs by
11+
// default have explicit font styles from the user agent, and we set the desired font styles
12+
// in the parent `mat-form-field` element (for better custom form-field control support).
13+
// Note: We increase specificity here because the MDC textfield seems to override this,
14+
// depending on the CSS order, with an affix selector joint with the input.
15+
.mat-mdc-form-field-input-control.mat-mdc-form-field-input-control {
16+
font: inherit;
1117
border: none;
1218
}
1319

1420
// In order to ensure proper alignment of the floating label, we reset its line-height.
1521
// The line-height is not important as the element is absolutely positioned and only has one line
1622
// of text.
17-
.mat-mdc-form-field .mdc-floating-label {
23+
.mat-mdc-form-field .mdc-floating-label.mdc-floating-label {
1824
line-height: normal;
1925
}
2026

@@ -24,15 +30,16 @@
2430
// not work for us since we support arbitrary form field controls which don't necessarily
2531
// use an `input` element. We organize the vertical spacing on the infix container.
2632
.mdc-text-field--no-label:not(.mdc-text-field--textarea)
27-
.mat-mdc-form-field-control.mdc-text-field__input,
28-
.mat-mdc-text-field-wrapper .mat-mdc-form-field-control {
33+
.mat-mdc-form-field-input-control.mdc-text-field__input,
34+
.mat-mdc-text-field-wrapper .mat-mdc-form-field-input-control {
2935
height: auto;
3036
}
3137

3238
// Color inputs are a special case, because setting their height to
3339
// `auto` will collapse them. The height value is an arbitrary number
3440
// which was extracted from the user agent styles of Chrome and Firefox.
35-
.mat-mdc-text-field-wrapper .mat-mdc-form-field-control.mdc-text-field__input[type='color'] {
41+
.mat-mdc-text-field-wrapper
42+
.mat-mdc-form-field-input-control.mdc-text-field__input[type='color'] {
3643
height: 23px;
3744
}
3845

@@ -57,8 +64,8 @@
5764
[dir='rtl'] {
5865
// Undo the above padding removals which only apply in LTR languages.
5966
.mat-mdc-text-field-wrapper {
60-
padding-left: form-field-sizing.$mat-form-field-end-padding;
61-
padding-right: form-field-sizing.$mat-form-field-end-padding;
67+
padding-left: mdc-textfield-variables.$padding-horizontal;
68+
padding-right: mdc-textfield-variables.$padding-horizontal;
6269
}
6370
// ...and apply the correct padding resets for RTL languages.
6471
.mat-mdc-form-field-has-icon-suffix .mat-mdc-text-field-wrapper {

src/material-experimental/mdc-form-field/_mdc-text-field-textarea-overrides.scss

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,15 @@
1010
@mixin private-text-field-textarea-overrides() {
1111
// Ensures that textarea elements inside of the form-field have proper vertical spacing
1212
// to account for the floating label. Also ensures that there is no vertical text overflow.
13-
.mat-mdc-textarea-input {
13+
// **Note**: Before changing this selector, make sure the `cdk-textarea-autosize` class is
14+
// still able to override the `resize` property to `none`.
15+
.mat-mdc-form-field-textarea-control {
16+
// Set the vertical alignment for textareas inside form fields to be the middle. This
17+
// ensures that textareas do not stretch the infix container vertically without having
18+
// multiple rows of text. See: https://github.com/angular/components/pull/22089.
19+
vertical-align: middle;
20+
// Textareas by default also allow users to resize the textarea horizontally. This
21+
// causes the textarea to overflow the form-field. We only allow vertical resizing.
1422
resize: vertical;
1523
box-sizing: border-box;
1624
height: auto;

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

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,21 @@
9090
}
9191
}
9292

93+
// Scale down icons in the subscript and floating label to be the same size
94+
// as the text.
95+
.mat-mdc-form-field-subscript-wrapper,
96+
.mat-mdc-form-field label {
97+
.mat-icon {
98+
width: 1em;
99+
height: 1em;
100+
font-size: inherit;
101+
}
102+
}
103+
93104
// Infix that contains the projected content (usually an input or a textarea). We ensure
94105
// that the projected form-field control and content can stretch as needed, but we also
95106
// apply a default infix width to make the form-field's look natural.
96107
.mat-mdc-form-field-infix {
97-
// Prevent extra height from being added around the textarea, which throws off the overall
98-
// height of the form-field
99-
line-height: 0;
100108
flex: auto;
101109
min-width: 0;
102110
width: form-field-sizing.$mat-form-field-default-infix-width;
@@ -105,10 +113,6 @@
105113
box-sizing: border-box;
106114
}
107115

108-
.mat-mdc-form-field-hint-end {
109-
order: 1;
110-
}
111-
112116
// In order to make it possible for developers to disable animations for form-fields,
113117
// we only activate the animation styles if animations are not explicitly disabled.
114118
.mat-mdc-form-field:not(.mat-form-field-no-animations) {

0 commit comments

Comments
 (0)