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. */