Skip to content

Commit a6f235d

Browse files
crisbetojelbourn
authored andcommitted
fix(form-field): incorrect assumptions about page direction (#17395)
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 017728a commit a6f235d

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,
@@ -231,15 +231,6 @@ export class MatFormField extends _MatFormFieldMixinBase
231231
/** Whether the Angular animations are enabled. */
232232
_animationsEnabled: boolean;
233233

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

356347
if (this._dir) {
357348
this._dir.change.pipe(takeUntil(this._destroyed)).subscribe(() => {
358-
this.updateOutlineGap();
359-
this._previousDirection = this._dir.value;
349+
if (typeof requestAnimationFrame === 'function') {
350+
this._ngZone.runOutsideAngular(() => {
351+
requestAnimationFrame(() => this.updateOutlineGap());
352+
});
353+
} else {
354+
this.updateOutlineGap();
355+
}
360356
});
361357
}
362358
}
@@ -579,7 +575,7 @@ export class MatFormField extends _MatFormFieldMixinBase
579575

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

585581
/** 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
@@ -16,7 +16,7 @@ import {
1616
ViewEncapsulation,
1717
ElementRef,
1818
} from '@angular/core';
19-
import {ComponentFixture, fakeAsync, flush, TestBed} from '@angular/core/testing';
19+
import {ComponentFixture, fakeAsync, flush, TestBed, tick} from '@angular/core/testing';
2020
import {
2121
FormControl,
2222
FormGroup,
@@ -1445,7 +1445,7 @@ describe('MatInput with appearance', () => {
14451445
fakeDirectionality.value = 'rtl';
14461446
fakeDirectionality.change.next('rtl');
14471447
outlineFixture.detectChanges();
1448-
flush();
1448+
tick(16.6); // Angular replaces requestAnimationFrame calls with 16.6ms timeouts in tests.
14491449
outlineFixture.detectChanges();
14501450

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

14861486
let wrapperElement = outlineFixture.nativeElement;
@@ -1494,7 +1494,7 @@ describe('MatInput with appearance', () => {
14941494
fakeDirectionality.value = 'ltr';
14951495
fakeDirectionality.change.next('ltr');
14961496
outlineFixture.detectChanges();
1497-
flush();
1497+
tick(16.6);
14981498
outlineFixture.detectChanges();
14991499

15001500
wrapperElement = outlineFixture.nativeElement;

0 commit comments

Comments
 (0)