mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(drawer): unable to toggle while drawer is animating (#6810)
Fixes #6376.
This commit is contained in:
committed by
Kara
parent
766faa10b7
commit
085827f3f5
@@ -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
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user