Skip to content

Commit 6c9678e

Browse files
authored
perf(material/form-field): set notch outline variable only on relevant element (#30955)
We were setting the `--mat-form-field-notch-max-width` on the entire form field which can cause style recalculations. These changes move to the relevant element only.
1 parent 6ffe9c7 commit 6c9678e

File tree

3 files changed

+26
-19
lines changed

3 files changed

+26
-19
lines changed

src/material/form-field/_mdc-text-field-structure.scss

+6-6
Original file line numberDiff line numberDiff line change
@@ -458,15 +458,16 @@ $token-slots: m2-form-field.get-token-slots();
458458
}
459459

460460
.mdc-notched-outline__notch {
461+
$min-value: 'calc(100% - max(12px, #{token-utils.slot(outlined-container-shape)}) * 2)';
461462
flex: 0 0 auto;
462463
width: auto;
463464

464465
.mdc-text-field--outlined .mdc-notched-outline & {
465-
$shape-var: token-utils.slot(outlined-container-shape);
466-
max-width: min(
467-
var(--mat-form-field-notch-max-width, 100%),
468-
calc(100% - max(12px, #{$shape-var}) * 2)
469-
);
466+
max-width: min(var(--mat-form-field-notch-max-width, 100%), #{$min-value});
467+
}
468+
469+
.mdc-text-field--outlined .mdc-notched-outline--notched & {
470+
max-width: min(100%, #{$min-value});
470471
}
471472

472473
.mdc-text-field--outlined .mdc-notched-outline--notched & {
@@ -481,7 +482,6 @@ $token-slots: m2-form-field.get-token-slots();
481482
padding-left: 0;
482483
padding-right: 8px;
483484
border-top: none;
484-
--mat-form-field-notch-max-width: 100%;
485485
}
486486

487487
[dir='rtl'] .mdc-notched-outline--notched & {

src/material/form-field/directives/notched-outline.ts

+18-9
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,14 @@ export class MatFormFieldNotchedOutline implements AfterViewInit {
4343
/** Whether the notch should be opened. */
4444
@Input('matFormFieldNotchedOutlineOpen') open: boolean = false;
4545

46-
@ViewChild('notch') _notch: ElementRef;
47-
48-
constructor(...args: unknown[]);
49-
constructor() {}
46+
@ViewChild('notch') _notch: ElementRef<HTMLElement>;
5047

5148
ngAfterViewInit(): void {
52-
const label = this._elementRef.nativeElement.querySelector<HTMLElement>('.mdc-floating-label');
49+
const element = this._elementRef.nativeElement;
50+
const label = element.querySelector<HTMLElement>('.mdc-floating-label');
51+
5352
if (label) {
54-
this._elementRef.nativeElement.classList.add('mdc-notched-outline--upgraded');
53+
element.classList.add('mdc-notched-outline--upgraded');
5554

5655
if (typeof requestAnimationFrame === 'function') {
5756
label.style.transitionDuration = '0s';
@@ -60,19 +59,29 @@ export class MatFormFieldNotchedOutline implements AfterViewInit {
6059
});
6160
}
6261
} else {
63-
this._elementRef.nativeElement.classList.add('mdc-notched-outline--no-label');
62+
element.classList.add('mdc-notched-outline--no-label');
6463
}
6564
}
6665

6766
_setNotchWidth(labelWidth: number) {
67+
const notch = this._notch.nativeElement;
68+
6869
if (!this.open || !labelWidth) {
69-
this._notch.nativeElement.style.width = '';
70+
notch.style.width = '';
7071
} else {
7172
const NOTCH_ELEMENT_PADDING = 8;
7273
const NOTCH_ELEMENT_BORDER = 1;
73-
this._notch.nativeElement.style.width = `calc(${labelWidth}px * var(--mat-mdc-form-field-floating-label-scale, 0.75) + ${
74+
notch.style.width = `calc(${labelWidth}px * var(--mat-mdc-form-field-floating-label-scale, 0.75) + ${
7475
NOTCH_ELEMENT_PADDING + NOTCH_ELEMENT_BORDER
7576
}px)`;
7677
}
7778
}
79+
80+
_setMaxWidth(prefixAndSuffixWidth: number) {
81+
// Set this only on the notch to avoid style recalculations in other parts of the form field.
82+
this._notch.nativeElement.style.setProperty(
83+
'--mat-form-field-notch-max-width',
84+
`calc(100% - ${prefixAndSuffixWidth}px)`,
85+
);
86+
}
7887
}

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

+2-4
Original file line numberDiff line numberDiff line change
@@ -794,10 +794,8 @@ export class MatFormField
794794
textPrefixContainerWidth +
795795
iconSuffixContainerWidth +
796796
textSuffixContainerWidth;
797-
this._elementRef.nativeElement.style.setProperty(
798-
'--mat-form-field-notch-max-width',
799-
`calc(100% - ${prefixAndSuffixWidth}px)`,
800-
);
797+
798+
this._notchedOutline?._setMaxWidth(prefixAndSuffixWidth);
801799
}
802800

803801
/** Checks whether the form field is attached to the DOM. */

0 commit comments

Comments
 (0)