+
+
+ Textarea
+
+
+
+
+ Input
+
+
+
+
+ Input
+
+
diff --git a/src/material-experimental/mdc-chips/chip-input.spec.ts b/src/material-experimental/mdc-chips/chip-input.spec.ts
index 2388927b48ee..2b7763b7f30f 100644
--- a/src/material-experimental/mdc-chips/chip-input.spec.ts
+++ b/src/material-experimental/mdc-chips/chip-input.spec.ts
@@ -130,7 +130,7 @@ describe('MDC-based MatChipInput', () => {
it('should set input styling classes', () => {
expect(inputNativeElement.classList).toContain('mat-mdc-input-element');
- expect(inputNativeElement.classList).toContain('mat-mdc-form-field-control');
+ expect(inputNativeElement.classList).toContain('mat-mdc-form-field-input-control');
expect(inputNativeElement.classList).toContain('mat-mdc-chip-input');
expect(inputNativeElement.classList).toContain('mdc-text-field__input');
});
diff --git a/src/material-experimental/mdc-chips/chip-input.ts b/src/material-experimental/mdc-chips/chip-input.ts
index a05a970fc5eb..e448051c6cdf 100644
--- a/src/material-experimental/mdc-chips/chip-input.ts
+++ b/src/material-experimental/mdc-chips/chip-input.ts
@@ -134,7 +134,7 @@ export class MatChipInput implements MatChipTextControl, AfterContentInit, OnCha
this.inputElement = this._elementRef.nativeElement as HTMLInputElement;
if (formField) {
- this.inputElement.classList.add('mat-mdc-form-field-control');
+ this.inputElement.classList.add('mat-mdc-form-field-input-control');
}
}
diff --git a/src/material-experimental/mdc-form-field/_form-field-native-select.scss b/src/material-experimental/mdc-form-field/_form-field-native-select.scss
index 0cda173843c2..5978cb082398 100644
--- a/src/material-experimental/mdc-form-field/_form-field-native-select.scss
+++ b/src/material-experimental/mdc-form-field/_form-field-native-select.scss
@@ -18,7 +18,7 @@ $mat-form-field-select-horizontal-end-padding: $mat-form-field-select-arrow-widt
// Remove the native select down arrow and ensure that the native appearance
// does not conflict with the form-field. e.g. Focus indication of the native
// select is undesired since we handle focus as part of the form-field.
- select.mat-mdc-form-field-control {
+ select.mat-mdc-form-field-input-control {
-moz-appearance: none;
-webkit-appearance: none;
background-color: transparent;
@@ -83,7 +83,7 @@ $mat-form-field-select-horizontal-end-padding: $mat-form-field-select-arrow-widt
// Add padding on the end of the native select so that the content does not
// overlap with the Material Design arrow.
- .mat-mdc-form-field-control {
+ .mat-mdc-form-field-input-control {
padding-right: $mat-form-field-select-horizontal-end-padding;
[dir='rtl'] & {
padding-right: 0;
@@ -105,7 +105,7 @@ $mat-form-field-select-horizontal-end-padding: $mat-form-field-select-arrow-widt
$dropdown-icon-color: rgba(mdc-theme-color.prop-value(on-surface), 0.54);
$disabled-dropdown-icon-color: rgba(mdc-theme-color.prop-value(on-surface), 0.38);
- select.mat-mdc-form-field-control {
+ select.mat-mdc-form-field-input-control {
// On dark themes we set the native `select` color to some shade of white,
// however the color propagates to all of the `option` elements, which are
// always on a white background inside the dropdown, causing them to blend in.
diff --git a/src/material-experimental/mdc-form-field/_form-field-sizing.scss b/src/material-experimental/mdc-form-field/_form-field-sizing.scss
index 532fd60171cd..3b3fbcd1174b 100644
--- a/src/material-experimental/mdc-form-field/_form-field-sizing.scss
+++ b/src/material-experimental/mdc-form-field/_form-field-sizing.scss
@@ -38,7 +38,3 @@ $mat-form-field-no-label-padding-top: 16px;
// The amount of padding between the icon prefix/suffix and the infix.
// This assumes that the icon will be a 24px square with 12px padding.
$mat-form-field-icon-prefix-infix-padding: 4px;
-
-// The amount of padding between the end of the form-field and the infix for a form-field with no
-// icons.
-$mat-form-field-end-padding: 16px;
diff --git a/src/material-experimental/mdc-form-field/_form-field-subscript.scss b/src/material-experimental/mdc-form-field/_form-field-subscript.scss
index 3a84607b8dff..4eaa74f2cb2d 100644
--- a/src/material-experimental/mdc-form-field/_form-field-subscript.scss
+++ b/src/material-experimental/mdc-form-field/_form-field-subscript.scss
@@ -1,6 +1,7 @@
@use '@material/textfield' as mdc-textfield;
@use '@material/theme/theme' as mdc-theme;
@use '@material/typography' as mdc-typography;
+@use '@material/textfield/variables' as mdc-textfield-variables;
@use 'form-field-sizing';
@use '../mdc-helpers/mdc-helpers';
@use '../../material/core/theming/theming';
@@ -13,16 +14,13 @@
position: relative;
}
- // The horizontal padding between the edge of the text box and the start of the subscript text.
- $subscript-horizontal-padding: 16px;
-
.mat-mdc-form-field-hint-wrapper,
.mat-mdc-form-field-error-wrapper {
position: absolute;
top: 0;
left: 0;
right: 0;
- padding: 0 $subscript-horizontal-padding;
+ padding: 0 mdc-textfield-variables.$padding-horizontal;
}
.mat-mdc-form-field-bottom-align::before {
@@ -31,14 +29,8 @@
height: 16px;
}
- // Scale down icons in the subscript to be the same size as the text.
- .mat-mdc-form-field-subscript-wrapper,
- .mat-mdc-form-field label {
- .mat-icon {
- width: 1em;
- height: 1em;
- font-size: inherit;
- }
+ .mat-mdc-form-field-hint-end {
+ order: 1;
}
// Clears the floats on the hints. This is necessary for the hint animation to work.
diff --git a/src/material-experimental/mdc-form-field/_form-field-theme.scss b/src/material-experimental/mdc-form-field/_form-field-theme.scss
index 882b95bdf843..3cd6d01776a5 100644
--- a/src/material-experimental/mdc-form-field/_form-field-theme.scss
+++ b/src/material-experimental/mdc-form-field/_form-field-theme.scss
@@ -3,7 +3,7 @@
@use '@material/notched-outline' as mdc-notched-outline;
@use '@material/line-ripple' as mdc-line-ripple;
@use '@material/theme/theme-color' as mdc-theme-color;
-@use '@material/typography' as mdc-typography;
+@use '@material/typography/typography' as mdc-typography;
@use '../mdc-helpers/mdc-helpers';
@use '../../material/core/typography/typography';
@use 'form-field-density';
@@ -72,14 +72,30 @@
@include mdc-line-ripple.core-styles($query: mdc-helpers.$mat-typography-styles-query);
@include form-field-subscript.private-form-field-subscript-typography($config);
- // MDC uses the `subtitle1` level for the input label and value, but the spec shows `body1` as
- // the correct level.
- .mat-mdc-form-field-control,
- .mat-mdc-form-field label,
- .mat-mdc-form-field-text-prefix,
- .mat-mdc-form-field-text-suffix {
+ // MDC uses `subtitle1` for the input value, placeholder and floating label. The spec
+ // shows `body1` for text fields though, so we manually override the typography.
+ // Note: Form controls inherit the typography from the parent form field.
+ .mat-mdc-form-field,
+ .mat-mdc-form-field .mdc-floating-label {
@include mdc-typography.typography(body1, $query: mdc-helpers.$mat-typography-styles-query);
}
+
+ // Above, we updated the floating label to use the `body1` typography level. The MDC notched
+ // outline overrides this accidentally (only when the label floats) to a `rem`-based value.
+ // This results in different label widths when floated/docked and ultimately breaks the notch
+ // width as it has been measured in the docked state (where `body1` is applied). We try to
+ // unset these styles set by the `mdc-notched-outline`:
+ // https://github.com/material-components/material-components-web/blob/master/packages/mdc-notched-outline/_mixins.scss#L272-L292.
+ .mat-mdc-form-field .mdc-text-field--outlined {
+ // For the non-upgraded notch label (i.e. when rendered on the server), also
+ // use the correct `body1` typography level.
+ .mdc-floating-label--float-above {
+ font-size: mdc-typography.get-size(body1) * 0.75;
+ }
+ .mdc-notched-outline--upgraded .mdc-floating-label--float-above {
+ font-size: mdc-typography.get-size(body1);
+ }
+ }
}
}
diff --git a/src/material-experimental/mdc-form-field/_mdc-text-field-structure-overrides.scss b/src/material-experimental/mdc-form-field/_mdc-text-field-structure-overrides.scss
index 9f7c427563c8..23bb2a649925 100644
--- a/src/material-experimental/mdc-form-field/_mdc-text-field-structure-overrides.scss
+++ b/src/material-experimental/mdc-form-field/_mdc-text-field-structure-overrides.scss
@@ -1,4 +1,4 @@
-@use 'form-field-sizing';
+@use '@material/textfield/variables' as mdc-textfield-variables;
@use '../../cdk/a11y';
// Mixin that can be included to override the default MDC text-field
@@ -7,8 +7,12 @@
@mixin private-text-field-structure-overrides() {
// Unset the border set by MDC. We move the border (which serves as the Material Design
// text-field bottom line) into its own element. This is necessary because we want the
- // bottom-line to span across the whole form-field (including prefixes and suffixes).
- .mat-mdc-form-field-control {
+ // bottom-line to span across the whole form-field (including prefixes and suffixes). Also
+ // we ensure that font styles are inherited for input elements. We do this because inputs by
+ // default have explicit font styles from the user agent, and we set the desired font styles
+ // in the parent `mat-form-field` element (for better custom form-field control support).
+ .mat-mdc-form-field-input-control {
+ font: inherit;
border: none;
}
@@ -25,8 +29,8 @@
// not work for us since we support arbitrary form field controls which don't necessarily
// use an `input` element. We organize the vertical spacing on the infix container.
.mdc-text-field--no-label:not(.mdc-text-field--textarea)
- .mat-mdc-form-field-control.mdc-text-field__input,
- .mat-mdc-text-field-wrapper .mat-mdc-form-field-control {
+ .mat-mdc-form-field-input-control.mdc-text-field__input,
+ .mat-mdc-text-field-wrapper .mat-mdc-form-field-input-control {
height: auto;
}
@@ -51,8 +55,8 @@
[dir='rtl'] {
// Undo the above padding removals which only apply in LTR languages.
.mat-mdc-text-field-wrapper {
- padding-left: form-field-sizing.$mat-form-field-end-padding;
- padding-right: form-field-sizing.$mat-form-field-end-padding;
+ padding-left: mdc-textfield-variables.$padding-horizontal;
+ padding-right: mdc-textfield-variables.$padding-horizontal;
}
// ...and apply the correct padding resets for RTL languages.
.mat-mdc-form-field-has-icon-suffix .mat-mdc-text-field-wrapper {
diff --git a/src/material-experimental/mdc-form-field/_mdc-text-field-textarea-overrides.scss b/src/material-experimental/mdc-form-field/_mdc-text-field-textarea-overrides.scss
index 008321138c11..3da0c04619be 100644
--- a/src/material-experimental/mdc-form-field/_mdc-text-field-textarea-overrides.scss
+++ b/src/material-experimental/mdc-form-field/_mdc-text-field-textarea-overrides.scss
@@ -10,7 +10,11 @@
@mixin private-text-field-textarea-overrides() {
// Ensures that textarea elements inside of the form-field have proper vertical spacing
// to account for the floating label. Also ensures that there is no vertical text overflow.
- .mat-mdc-textarea-input {
+ .mat-mdc-form-field-input-control.mat-mdc-textarea-input {
+ // Set the vertical alignment for textareas inside form fields to be the middle. This
+ // ensures that textareas do not stretch the infix container vertically without having
+ // multiple rows of text. See: https://github.com/angular/components/pull/22089.
+ vertical-align: middle;
resize: vertical;
box-sizing: border-box;
height: auto;
diff --git a/src/material-experimental/mdc-form-field/form-field.scss b/src/material-experimental/mdc-form-field/form-field.scss
index 7e0be3ee4377..3293fb0f5bcc 100644
--- a/src/material-experimental/mdc-form-field/form-field.scss
+++ b/src/material-experimental/mdc-form-field/form-field.scss
@@ -88,13 +88,21 @@
}
}
+// Scale down icons in the subscript and floating label to be the same size
+// as the text.
+.mat-mdc-form-field-subscript-wrapper,
+.mat-mdc-form-field label {
+ .mat-icon {
+ width: 1em;
+ height: 1em;
+ font-size: inherit;
+ }
+}
+
// Infix that contains the projected content (usually an input or a textarea). We ensure
// that the projected form-field control and content can stretch as needed, but we also
// apply a default infix width to make the form-field's look natural.
.mat-mdc-form-field-infix {
- // Prevent extra height from being added around the textarea, which throws off the overall
- // height of the form-field
- line-height: 0;
flex: auto;
min-width: 0;
width: form-field-sizing.$mat-form-field-default-infix-width;
@@ -103,10 +111,6 @@
box-sizing: border-box;
}
-.mat-mdc-form-field-hint-end {
- order: 1;
-}
-
// In order to make it possible for developers to disable animations for form-fields,
// we only activate the animation styles if animations are not explicitly disabled.
.mat-mdc-form-field:not(.mat-form-field-no-animations) {
diff --git a/src/material-experimental/mdc-form-field/form-field.ts b/src/material-experimental/mdc-form-field/form-field.ts
index 571152ccc965..a73f11e0d837 100644
--- a/src/material-experimental/mdc-form-field/form-field.ts
+++ b/src/material-experimental/mdc-form-field/form-field.ts
@@ -93,6 +93,12 @@ const DEFAULT_FLOAT_LABEL: FloatLabelType = 'auto';
*/
const FLOATING_LABEL_DEFAULT_DOCKED_TRANSFORM = `translateY(-50%)`;
+/**
+ * Horizontal padding in pixels used by the MDC for the wrapper containing infix.
+ * This value is extracted from MDC's Sass variables. See `$padding-horizontal`.
+ */
+const WRAPPER_HORIZONTAL_PADDING = 16;
+
/** Container for form controls that applies Material Design styling and behavior. */
@Component({
selector: 'mat-form-field',
@@ -691,16 +697,16 @@ export class MatFormField implements AfterViewInit, OnDestroy, AfterContentCheck
}
const iconPrefixContainer = this._iconPrefixContainer?.nativeElement;
const textPrefixContainer = this._textPrefixContainer?.nativeElement;
+ const iconPrefixContainerWidth = iconPrefixContainer?.getBoundingClientRect().width ?? 0;
+ const textPrefixContainerWidth = textPrefixContainer?.getBoundingClientRect().width ?? 0;
// If the directionality is RTL, the x-axis transform needs to be inverted. This
// is because `transformX` does not change based on the page directionality.
const labelHorizontalOffset =
(this._dir.value === 'rtl' ? -1 : 1) * (
- (iconPrefixContainer ?
- // If there's an icon prefix, we disable the default 16px padding,
- // so make sure to account for that.
- (iconPrefixContainer?.getBoundingClientRect().width ?? 0) - 16 : 0
- ) +
- (textPrefixContainer?.getBoundingClientRect().width ?? 0)
+ // If there's an icon prefix, we subtract the default horizontal padding as we
+ // reset the horizontal padding in CSS too.
+ (iconPrefixContainer ? iconPrefixContainerWidth - WRAPPER_HORIZONTAL_PADDING : 0) +
+ textPrefixContainerWidth
);
// Update the transform the floating label to account for the prefix container. Note
diff --git a/src/material-experimental/mdc-input/input.spec.ts b/src/material-experimental/mdc-input/input.spec.ts
index ac0eb7fa00ac..41f608a3719e 100644
--- a/src/material-experimental/mdc-input/input.spec.ts
+++ b/src/material-experimental/mdc-input/input.spec.ts
@@ -903,8 +903,8 @@ describe('MatMdcInput without forms', () => {
const inFormField = fixture.nativeElement.querySelector('.inside');
const outsideFormField = fixture.nativeElement.querySelector('.outside');
- expect(inFormField.classList).toContain('mat-mdc-form-field-control');
- expect(outsideFormField.classList).not.toContain('mat-mdc-form-field-control');
+ expect(inFormField.classList).toContain('mat-mdc-form-field-input-control');
+ expect(outsideFormField.classList).not.toContain('mat-mdc-form-field-input-control');
}));
});
diff --git a/src/material-experimental/mdc-input/input.ts b/src/material-experimental/mdc-input/input.ts
index 329d386fc21a..af01d542ad33 100644
--- a/src/material-experimental/mdc-input/input.ts
+++ b/src/material-experimental/mdc-input/input.ts
@@ -28,7 +28,7 @@ import {MatInput as BaseMatInput} from '@angular/material/input';
'[class.mat-form-field-control]': 'false',
'[class.mat-input-server]': '_isServer',
'[class.mat-mdc-textarea-input]': '_isTextarea',
- '[class.mat-mdc-form-field-control]': '_isInFormField',
+ '[class.mat-mdc-form-field-input-control]': '_isInFormField',
'[class.mdc-text-field__input]': '_isInFormField',
// Native input properties that are overwritten by Angular inputs need to be synced with
// the native input element. Otherwise property bindings for those don't work.
diff --git a/src/material/form-field/.form-field.md.swp b/src/material/form-field/.form-field.md.swp
deleted file mode 100644
index 9039143c4e59..000000000000
Binary files a/src/material/form-field/.form-field.md.swp and /dev/null differ