Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 96117bc

Browse files
fix(material/form-field): resolve memory leak (#31643)
Inside the form field we have a `afterRenderEffect` that updates the label offset when in outlined mode. The logic for calculating the label offset depends on reading `Directionality.valueSignal` which ends up triggering a memory leak in the framework (angular/angular#62980). These changes add a temporary workaround that removes the `valueSignal` from the signal graph in order to avoid the leak until it's fixed on the framework side.
1 parent 11f9228 commit 96117bc

File tree

1 file changed

+9
-4
lines changed

1 file changed

+9
-4
lines changed

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88
import {_IdGenerator} from '@angular/cdk/a11y';
9-
import {Directionality} from '@angular/cdk/bidi';
9+
import {Direction,Directionality} from '@angular/cdk/bidi';
1010
import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion';
1111
import {Platform} from '@angular/cdk/platform';
1212
import {NgTemplateOutlet} from '@angular/common';
@@ -30,6 +30,7 @@ import {
3030
afterRenderEffect,
3131
computed,
3232
contentChild,
33+
effect,
3334
inject,
3435
signal,
3536
viewChild,
@@ -190,13 +191,13 @@ export class MatFormField
190191
{
191192
_elementRef = inject(ElementRef);
192193
private _changeDetectorRef = inject(ChangeDetectorRef);
193-
private _dir = inject(Directionality);
194194
private _platform = inject(Platform);
195195
private _idGenerator = inject(_IdGenerator);
196196
private _ngZone = inject(NgZone);
197197
private _defaults = inject<MatFormFieldDefaultOptions>(MAT_FORM_FIELD_DEFAULT_OPTIONS, {
198198
optional: true,
199199
});
200+
private _currentDirection: Direction;
200201

201202
@ViewChild('textField') _textField: ElementRef<HTMLElement>;
202203
@ViewChild('iconPrefixContainer') _iconPrefixContainer: ElementRef<HTMLElement>;
@@ -346,6 +347,7 @@ export class MatFormField
346347

347348
constructor() {
348349
const defaults = this._defaults;
350+
const dir = inject(Directionality);
349351

350352
if (defaults) {
351353
if (defaults.appearance) {
@@ -357,6 +359,10 @@ export class MatFormField
357359
}
358360
}
359361

362+
// We need this value inside a `afterRenderEffect`, however at the time of writing, reading the
363+
// signal directly causes a memory leak (see https://github.com/angular/angular/issues/62980).
364+
// TODO(crisbeto): clean this up once the framework issue is resolved.
365+
effect(() => (this._currentDirection = dir.valueSignal()));
360366
this._syncOutlineLabelOffset();
361367
}
362368

@@ -752,7 +758,6 @@ export class MatFormField
752758
* incorporate the horizontal offset into their default text-field styles.
753759
*/
754760
private _getOutlinedLabelOffset(): OutlinedLabelStyles {
755-
const dir = this._dir.valueSignal();
756761
if (!this._hasOutline() || !this._floatingLabel) {
757762
return null;
758763
}
@@ -776,7 +781,7 @@ export class MatFormField
776781
const textSuffixContainerWidth = textSuffixContainer?.getBoundingClientRect().width ?? 0;
777782
// If the directionality is RTL, the x-axis transform needs to be inverted. This
778783
// is because `transformX` does not change based on the page directionality.
779-
const negate = dir === 'rtl' ? '-1' : '1';
784+
const negate = this._currentDirection === 'rtl' ? '-1' : '1';
780785
const prefixWidth = `${iconPrefixContainerWidth + textPrefixContainerWidth}px`;
781786
const labelOffset = `var(--mat-mdc-form-field-label-offset-x, 0px)`;
782787
const labelHorizontalOffset = `calc(${negate} * (${prefixWidth} + ${labelOffset}))`;

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /