diff --git a/src/material/form-field/form-field.ts b/src/material/form-field/form-field.ts index 241d22409a60..cc16af869f0c 100644 --- a/src/material/form-field/form-field.ts +++ b/src/material/form-field/form-field.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ import {_IdGenerator} from '@angular/cdk/a11y'; -import {Directionality} from '@angular/cdk/bidi'; +import {Direction, Directionality} from '@angular/cdk/bidi'; import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion'; import {Platform} from '@angular/cdk/platform'; import {NgTemplateOutlet} from '@angular/common'; @@ -30,6 +30,7 @@ import { afterRenderEffect, computed, contentChild, + effect, inject, signal, viewChild, @@ -190,13 +191,13 @@ export class MatFormField { _elementRef = inject(ElementRef); private _changeDetectorRef = inject(ChangeDetectorRef); - private _dir = inject(Directionality); private _platform = inject(Platform); private _idGenerator = inject(_IdGenerator); private _ngZone = inject(NgZone); private _defaults = inject(MAT_FORM_FIELD_DEFAULT_OPTIONS, { optional: true, }); + private _currentDirection: Direction; @ViewChild('textField') _textField: ElementRef; @ViewChild('iconPrefixContainer') _iconPrefixContainer: ElementRef; @@ -346,6 +347,7 @@ export class MatFormField constructor() { const defaults = this._defaults; + const dir = inject(Directionality); if (defaults) { if (defaults.appearance) { @@ -357,6 +359,10 @@ export class MatFormField } } + // We need this value inside a `afterRenderEffect`, however at the time of writing, reading the + // signal directly causes a memory leak (see https://github.com/angular/angular/issues/62980). + // TODO(crisbeto): clean this up once the framework issue is resolved. + effect(() => (this._currentDirection = dir.valueSignal())); this._syncOutlineLabelOffset(); } @@ -752,7 +758,6 @@ export class MatFormField * incorporate the horizontal offset into their default text-field styles. */ private _getOutlinedLabelOffset(): OutlinedLabelStyles { - const dir = this._dir.valueSignal(); if (!this._hasOutline() || !this._floatingLabel) { return null; } @@ -776,7 +781,7 @@ export class MatFormField const textSuffixContainerWidth = textSuffixContainer?.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 negate = dir === 'rtl' ? '-1' : '1'; + const negate = this._currentDirection === 'rtl' ? '-1' : '1'; const prefixWidth = `${iconPrefixContainerWidth + textPrefixContainerWidth}px`; const labelOffset = `var(--mat-mdc-form-field-label-offset-x, 0px)`; const labelHorizontalOffset = `calc(${negate} * (${prefixWidth} + ${labelOffset}))`;