fix(drawer): unable to toggle while drawer is animating (#6810)

Fixes #6376.
This commit is contained in:
Kristiyan Kostadinov
2017-10-06 22:23:00 +02:00
committed by Kara
parent 766faa10b7
commit 085827f3f5
2 changed files with 32 additions and 35 deletions
+21 -1
View File
@@ -46,7 +46,6 @@ describe('MatDrawer', () => {
tick();
fixture.detectChanges();
expect(drawer.componentInstance._isAnimating).toBe(false);
expect(testComponent.openCount).toBe(1);
expect(testComponent.closeCount).toBe(0);
expect(getComputedStyle(drawer.nativeElement).visibility).toBe('visible');
@@ -67,6 +66,27 @@ describe('MatDrawer', () => {
expect(getComputedStyle(drawerBackdropElement.nativeElement).visibility).toBe('hidden');
}));
it('should be able to close while the open animation is running', fakeAsync(() => {
const fixture = TestBed.createComponent(BasicTestApp);
fixture.detectChanges();
const testComponent: BasicTestApp = fixture.debugElement.componentInstance;
fixture.debugElement.query(By.css('.open')).nativeElement.click();
fixture.detectChanges();
expect(testComponent.openCount).toBe(0);
expect(testComponent.closeCount).toBe(0);
fixture.debugElement.query(By.css('.close')).nativeElement.click();
fixture.detectChanges();
tick();
fixture.detectChanges();
expect(testComponent.openCount).toBe(1);
expect(testComponent.closeCount).toBe(1);
}));
it('does not throw when created without a drawer', fakeAsync(() => {
expect(() => {
let fixture = TestBed.createComponent(BasicTestApp);
+11 -34
View File
@@ -174,19 +174,9 @@ export class MatDrawer implements AfterContentInit, OnDestroy {
/** Emits whenever the drawer has started animating. */
_animationStarted = new EventEmitter<AnimationEvent>();
/** Whether the drawer is animating. Used to prevent overlapping animations. */
_isAnimating = false;
/** Current state of the sidenav animation. */
_animationState: 'open-instant' | 'open' | 'void' = 'void';
/**
* Promise that resolves when the open/close animation completes. It is here for backwards
* compatibility and should be removed next time we do drawer breaking changes.
* @deprecated
*/
private _currentTogglePromise: Promise<MatDrawerToggleResult> | null;
/** Event emitted when the drawer is fully opened. */
@Output('open') onOpen = new EventEmitter<MatDrawerToggleResult | void>();
@@ -281,27 +271,23 @@ export class MatDrawer implements AfterContentInit, OnDestroy {
* @param isOpen Whether the drawer should be open.
*/
toggle(isOpen: boolean = !this.opened): Promise<MatDrawerToggleResult> {
if (!this._isAnimating) {
this._opened = isOpen;
this._opened = isOpen;
if (isOpen) {
this._animationState = this._enableAnimations ? 'open' : 'open-instant';
} else {
this._animationState = 'void';
}
if (isOpen) {
this._animationState = this._enableAnimations ? 'open' : 'open-instant';
} else {
this._animationState = 'void';
}
this._currentTogglePromise = new Promise(resolve => {
first.call(isOpen ? this.onOpen : this.onClose).subscribe(resolve);
});
if (this._focusTrap) {
this._focusTrap.enabled = this._isFocusTrapEnabled;
}
if (this._focusTrap) {
this._focusTrap.enabled = this._isFocusTrapEnabled;
}
// TODO(crisbeto): This promise is here for backwards-compatibility.
// It should be removed next time we do breaking changes in the drawer.
return this._currentTogglePromise!;
return new Promise(resolve => {
first.call(isOpen ? this.onOpen : this.onClose).subscribe(resolve);
});
}
/**
@@ -316,7 +302,6 @@ export class MatDrawer implements AfterContentInit, OnDestroy {
}
_onAnimationStart(event: AnimationEvent) {
this._isAnimating = true;
this._animationStarted.emit(event);
}
@@ -328,14 +313,6 @@ export class MatDrawer implements AfterContentInit, OnDestroy {
} else if (toState === 'void' && fromState.indexOf('open') === 0) {
this.onClose.emit(new MatDrawerToggleResult('close', true));
}
// Note: as of Angular 4.3, the animations module seems to fire the `start` callback before
// the end if animations are disabled. Make this call async to ensure that it still fires
// at the appropriate time.
Promise.resolve().then(() => {
this._isAnimating = false;
this._currentTogglePromise = null;
});
}
get _width() {