From fe732a198998268f25982215a2d66bfcc1dc42b8 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Fri, 25 Apr 2025 13:03:18 +0200 Subject: [PATCH] perf(material/form-field): set notch outline variable only on relevant element 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. --- .../form-field/_mdc-text-field-structure.scss | 12 ++++----- .../form-field/directives/notched-outline.ts | 27 ++++++++++++------- src/material/form-field/form-field.ts | 6 ++--- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/material/form-field/_mdc-text-field-structure.scss b/src/material/form-field/_mdc-text-field-structure.scss index d053a08fb59b..181e99a45d4c 100644 --- a/src/material/form-field/_mdc-text-field-structure.scss +++ b/src/material/form-field/_mdc-text-field-structure.scss @@ -458,15 +458,16 @@ $token-slots: m2-form-field.get-token-slots(); } .mdc-notched-outline__notch { + $min-value: 'calc(100% - max(12px, #{token-utils.slot(outlined-container-shape)}) * 2)'; flex: 0 0 auto; width: auto; .mdc-text-field--outlined .mdc-notched-outline & { - $shape-var: token-utils.slot(outlined-container-shape); - max-width: min( - var(--mat-form-field-notch-max-width, 100%), - calc(100% - max(12px, #{$shape-var}) * 2) - ); + max-width: min(var(--mat-form-field-notch-max-width, 100%), #{$min-value}); + } + + .mdc-text-field--outlined .mdc-notched-outline--notched & { + max-width: min(100%, #{$min-value}); } .mdc-text-field--outlined .mdc-notched-outline--notched & { @@ -481,7 +482,6 @@ $token-slots: m2-form-field.get-token-slots(); padding-left: 0; padding-right: 8px; border-top: none; - --mat-form-field-notch-max-width: 100%; } [dir='rtl'] .mdc-notched-outline--notched & { diff --git a/src/material/form-field/directives/notched-outline.ts b/src/material/form-field/directives/notched-outline.ts index 6400a2ae6b70..54a00675322c 100644 --- a/src/material/form-field/directives/notched-outline.ts +++ b/src/material/form-field/directives/notched-outline.ts @@ -43,15 +43,14 @@ export class MatFormFieldNotchedOutline implements AfterViewInit { /** Whether the notch should be opened. */ @Input('matFormFieldNotchedOutlineOpen') open: boolean = false; - @ViewChild('notch') _notch: ElementRef; - - constructor(...args: unknown[]); - constructor() {} + @ViewChild('notch') _notch: ElementRef; ngAfterViewInit(): void { - const label = this._elementRef.nativeElement.querySelector('.mdc-floating-label'); + const element = this._elementRef.nativeElement; + const label = element.querySelector('.mdc-floating-label'); + if (label) { - this._elementRef.nativeElement.classList.add('mdc-notched-outline--upgraded'); + element.classList.add('mdc-notched-outline--upgraded'); if (typeof requestAnimationFrame === 'function') { label.style.transitionDuration = '0s'; @@ -60,19 +59,29 @@ export class MatFormFieldNotchedOutline implements AfterViewInit { }); } } else { - this._elementRef.nativeElement.classList.add('mdc-notched-outline--no-label'); + element.classList.add('mdc-notched-outline--no-label'); } } _setNotchWidth(labelWidth: number) { + const notch = this._notch.nativeElement; + if (!this.open || !labelWidth) { - this._notch.nativeElement.style.width = ''; + notch.style.width = ''; } else { const NOTCH_ELEMENT_PADDING = 8; const NOTCH_ELEMENT_BORDER = 1; - this._notch.nativeElement.style.width = `calc(${labelWidth}px * var(--mat-mdc-form-field-floating-label-scale, 0.75) + ${ + notch.style.width = `calc(${labelWidth}px * var(--mat-mdc-form-field-floating-label-scale, 0.75) + ${ NOTCH_ELEMENT_PADDING + NOTCH_ELEMENT_BORDER }px)`; } } + + _setMaxWidth(prefixAndSuffixWidth: number) { + // Set this only on the notch to avoid style recalculations in other parts of the form field. + this._notch.nativeElement.style.setProperty( + '--mat-form-field-notch-max-width', + `calc(100% - ${prefixAndSuffixWidth}px)`, + ); + } } diff --git a/src/material/form-field/form-field.ts b/src/material/form-field/form-field.ts index bed240595668..11149b975fa8 100644 --- a/src/material/form-field/form-field.ts +++ b/src/material/form-field/form-field.ts @@ -794,10 +794,8 @@ export class MatFormField textPrefixContainerWidth + iconSuffixContainerWidth + textSuffixContainerWidth; - this._elementRef.nativeElement.style.setProperty( - '--mat-form-field-notch-max-width', - `calc(100% - ${prefixAndSuffixWidth}px)`, - ); + + this._notchedOutline?._setMaxWidth(prefixAndSuffixWidth); } /** Checks whether the form field is attached to the DOM. */