Skip to content

Commit 20b8bf0

Browse files
crisbetommalerba
authored andcommitted
fix(form-field): incorrect assumptions about page direction
These changes undo the changes from #15415 because they were making incorrect assumptions about the page starting off as LTR, and they were calling `updateOutlineGap` with an outdated value for the direction. This is causing issues like #17390. I'm not totally sure what was being fixed by these changes, because the test that was added didn't fail even if I reverted all of the changes. From what I can tell the problem #15415 was trying to solve was that the outline gap might be updated too early on a direction change, before the browser has had the chance to recalculate the layout. These changes switch to recalculating inside a `requestAnimationFrame` after direction changes, in order to give the browser enough time to recalculate the layout. Fixes #17390.
1 parent ef92091 commit 20b8bf0

File tree

2 files changed

+13
-17
lines changed

2 files changed

+13
-17
lines changed

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

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {Direction, Directionality} from '@angular/cdk/bidi';
9+
import {Directionality} from '@angular/cdk/bidi';
1010
import {coerceBooleanProperty} from '@angular/cdk/coercion';
1111
import {
1212
AfterContentChecked,
@@ -232,15 +232,6 @@ export class MatFormField extends _MatFormFieldMixinBase
232232
/** Whether the Angular animations are enabled. */
233233
_animationsEnabled: boolean;
234234

235-
/* Holds the previous direction emitted by directionality service change emitter.
236-
This is used in updateOutlineGap() method to update the width and position of the gap in the
237-
outline. Only relevant for the outline appearance. The direction is getting updated in the
238-
UI after directionality service change emission. So the outlines gaps are getting
239-
updated in updateOutlineGap() method before connectionContainer child direction change
240-
in UI. We may get wrong calculations. So we are storing the previous direction to get the
241-
correct outline calculations*/
242-
private _previousDirection: Direction = 'ltr';
243-
244235
/**
245236
* @deprecated
246237
* @breaking-change 8.0.0
@@ -356,8 +347,13 @@ export class MatFormField extends _MatFormFieldMixinBase
356347

357348
if (this._dir) {
358349
this._dir.change.pipe(takeUntil(this._destroyed)).subscribe(() => {
359-
this.updateOutlineGap();
360-
this._previousDirection = this._dir.value;
350+
if (typeof requestAnimationFrame === 'function') {
351+
this._ngZone.runOutsideAngular(() => {
352+
requestAnimationFrame(() => this.updateOutlineGap());
353+
});
354+
} else {
355+
this.updateOutlineGap();
356+
}
361357
});
362358
}
363359
}
@@ -580,7 +576,7 @@ export class MatFormField extends _MatFormFieldMixinBase
580576

581577
/** Gets the start end of the rect considering the current directionality. */
582578
private _getStartEnd(rect: ClientRect): number {
583-
return this._previousDirection === 'rtl' ? rect.right : rect.left;
579+
return (this._dir && this._dir.value === 'rtl') ? rect.right : rect.left;
584580
}
585581

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

src/material/input/input.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
ViewEncapsulation,
1616
ElementRef,
1717
} from '@angular/core';
18-
import {ComponentFixture, fakeAsync, flush, TestBed} from '@angular/core/testing';
18+
import {ComponentFixture, fakeAsync, flush, TestBed, tick} from '@angular/core/testing';
1919
import {
2020
FormControl,
2121
FormGroup,
@@ -1444,7 +1444,7 @@ describe('MatInput with appearance', () => {
14441444
fakeDirectionality.value = 'rtl';
14451445
fakeDirectionality.change.next('rtl');
14461446
outlineFixture.detectChanges();
1447-
flush();
1447+
tick(16.6); // Angular replaces requestAnimationFrame calls with 16.6ms timeouts in tests.
14481448
outlineFixture.detectChanges();
14491449

14501450
expect(outlineFixture.componentInstance.formField.updateOutlineGap).toHaveBeenCalled();
@@ -1479,7 +1479,7 @@ describe('MatInput with appearance', () => {
14791479
fakeDirectionality.value = 'rtl';
14801480
fakeDirectionality.change.next('rtl');
14811481
outlineFixture.detectChanges();
1482-
flush();
1482+
tick(16.6); // Angular replaces requestAnimationFrame calls with 16.6ms timeouts in tests.
14831483
outlineFixture.detectChanges();
14841484

14851485
let wrapperElement = outlineFixture.nativeElement;
@@ -1493,7 +1493,7 @@ describe('MatInput with appearance', () => {
14931493
fakeDirectionality.value = 'ltr';
14941494
fakeDirectionality.change.next('ltr');
14951495
outlineFixture.detectChanges();
1496-
flush();
1496+
tick(16.6);
14971497
outlineFixture.detectChanges();
14981498

14991499
wrapperElement = outlineFixture.nativeElement;

0 commit comments

Comments
 (0)