diff --git a/src/material/form-field/form-field.ts b/src/material/form-field/form-field.ts index 6cdb0432570e..e4c324fb92ca 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.io/license */ -import {Direction, Directionality} from '@angular/cdk/bidi'; +import {Directionality} from '@angular/cdk/bidi'; import {coerceBooleanProperty} from '@angular/cdk/coercion'; import { AfterContentChecked, @@ -232,15 +232,6 @@ export class MatFormField extends _MatFormFieldMixinBase /** Whether the Angular animations are enabled. */ _animationsEnabled: boolean; - /* Holds the previous direction emitted by directionality service change emitter. - This is used in updateOutlineGap() method to update the width and position of the gap in the - outline. Only relevant for the outline appearance. The direction is getting updated in the - UI after directionality service change emission. So the outlines gaps are getting - updated in updateOutlineGap() method before connectionContainer child direction change - in UI. We may get wrong calculations. So we are storing the previous direction to get the - correct outline calculations*/ - private _previousDirection: Direction = 'ltr'; - /** * @deprecated * @breaking-change 8.0.0 @@ -356,8 +347,13 @@ export class MatFormField extends _MatFormFieldMixinBase if (this._dir) { this._dir.change.pipe(takeUntil(this._destroyed)).subscribe(() => { - this.updateOutlineGap(); - this._previousDirection = this._dir.value; + if (typeof requestAnimationFrame === 'function') { + this._ngZone.runOutsideAngular(() => { + requestAnimationFrame(() => this.updateOutlineGap()); + }); + } else { + this.updateOutlineGap(); + } }); } } @@ -580,7 +576,7 @@ export class MatFormField extends _MatFormFieldMixinBase /** Gets the start end of the rect considering the current directionality. */ private _getStartEnd(rect: ClientRect): number { - return this._previousDirection === 'rtl' ? rect.right : rect.left; + return (this._dir && this._dir.value === 'rtl') ? rect.right : rect.left; } /** Checks whether the form field is attached to the DOM. */ diff --git a/src/material/input/input.spec.ts b/src/material/input/input.spec.ts index 72772dc18253..83c5226d4c56 100644 --- a/src/material/input/input.spec.ts +++ b/src/material/input/input.spec.ts @@ -15,7 +15,7 @@ import { ViewEncapsulation, ElementRef, } from '@angular/core'; -import {ComponentFixture, fakeAsync, flush, TestBed} from '@angular/core/testing'; +import {ComponentFixture, fakeAsync, flush, TestBed, tick} from '@angular/core/testing'; import { FormControl, FormGroup, @@ -1444,7 +1444,7 @@ describe('MatInput with appearance', () => { fakeDirectionality.value = 'rtl'; fakeDirectionality.change.next('rtl'); outlineFixture.detectChanges(); - flush(); + tick(16.6); // Angular replaces requestAnimationFrame calls with 16.6ms timeouts in tests. outlineFixture.detectChanges(); expect(outlineFixture.componentInstance.formField.updateOutlineGap).toHaveBeenCalled(); @@ -1479,7 +1479,7 @@ describe('MatInput with appearance', () => { fakeDirectionality.value = 'rtl'; fakeDirectionality.change.next('rtl'); outlineFixture.detectChanges(); - flush(); + tick(16.6); // Angular replaces requestAnimationFrame calls with 16.6ms timeouts in tests. outlineFixture.detectChanges(); let wrapperElement = outlineFixture.nativeElement; @@ -1493,7 +1493,7 @@ describe('MatInput with appearance', () => { fakeDirectionality.value = 'ltr'; fakeDirectionality.change.next('ltr'); outlineFixture.detectChanges(); - flush(); + tick(16.6); outlineFixture.detectChanges(); wrapperElement = outlineFixture.nativeElement;