fix(snack-bar): indicate in afterDismissed whether dismissal was a result of an action (#9154)

Adds a boolean to the `MatSnackBarRef.afterDismissed` result that indicates whether the dismissal came as a result of the user pressing the action button.

Fixes #9147.
This commit is contained in:
Kristiyan Kostadinov
2018-01-23 17:12:27 +01:00
committed by Jeremy Elbourn
parent 68bb44c331
commit 829506ddc7
3 changed files with 48 additions and 13 deletions
+1 -1
View File
@@ -42,7 +42,7 @@ export class SimpleSnackBar {
/** Performs the action on the snack bar. */
action(): void {
this.snackBarRef.closeWithAction();
this.snackBarRef.dismissWithAction();
}
/** If the action button should be shown. */
+28 -8
View File
@@ -11,6 +11,12 @@ import {Observable} from 'rxjs/Observable';
import {Subject} from 'rxjs/Subject';
import {MatSnackBarContainer} from './snack-bar-container';
/** Event that is emitted when a snack bar is dismissed. */
export interface MatSnackBarDismiss {
/** Whether the snack bar was dismissed using the action button. */
dismissedByAction: boolean;
}
/**
* Reference to a snack bar dispatched from the snack bar service.
*/
@@ -24,8 +30,8 @@ export class MatSnackBarRef<T> {
*/
containerInstance: MatSnackBarContainer;
/** Subject for notifying the user that the snack bar has closed. */
private _afterClosed = new Subject<void>();
/** Subject for notifying the user that the snack bar has been dismissed. */
private _afterDismissed = new Subject<MatSnackBarDismiss>();
/** Subject for notifying the user that the snack bar has opened and appeared. */
private _afterOpened = new Subject<void>();
@@ -39,6 +45,9 @@ export class MatSnackBarRef<T> {
*/
private _durationTimeoutId: number;
/** Whether the snack bar was dismissed using the action button. */
private _dismissedByAction = false;
constructor(containerInstance: MatSnackBarContainer,
private _overlayRef: OverlayRef) {
this.containerInstance = containerInstance;
@@ -49,20 +58,30 @@ export class MatSnackBarRef<T> {
/** Dismisses the snack bar. */
dismiss(): void {
if (!this._afterClosed.closed) {
if (!this._afterDismissed.closed) {
this.containerInstance.exit();
}
clearTimeout(this._durationTimeoutId);
}
/** Marks the snackbar action clicked. */
closeWithAction(): void {
dismissWithAction(): void {
if (!this._onAction.closed) {
this._dismissedByAction = true;
this._onAction.next();
this._onAction.complete();
}
}
/**
* Marks the snackbar action clicked.
* @deprecated Use `dismissWithAction` instead.
*/
closeWithAction(): void {
this.dismissWithAction();
}
/** Dismisses the snack bar after some duration */
_dismissAfter(duration: number): void {
this._durationTimeoutId = setTimeout(() => this.dismiss(), duration);
@@ -84,13 +103,14 @@ export class MatSnackBarRef<T> {
this._onAction.complete();
}
this._afterClosed.next();
this._afterClosed.complete();
this._afterDismissed.next({dismissedByAction: this._dismissedByAction});
this._afterDismissed.complete();
this._dismissedByAction = false;
}
/** Gets an observable that is notified when the snack bar is finished closing. */
afterDismissed(): Observable<void> {
return this._afterClosed.asObservable();
afterDismissed(): Observable<MatSnackBarDismiss> {
return this._afterDismissed.asObservable();
}
/** Gets an observable that is notified when the snack bar has opened and appeared. */
+19 -4
View File
@@ -288,7 +288,7 @@ describe('MatSnackBar', () => {
tick(500);
}));
it('should allow manually closing with an action', fakeAsync(() => {
it('should allow manually dismissing with an action', fakeAsync(() => {
const dismissCompleteSpy = jasmine.createSpy('dismiss complete spy');
const actionCompleteSpy = jasmine.createSpy('action complete spy');
const snackBarRef = snackBar.open('Some content');
@@ -297,7 +297,7 @@ describe('MatSnackBar', () => {
snackBarRef.afterDismissed().subscribe(undefined, undefined, dismissCompleteSpy);
snackBarRef.onAction().subscribe(undefined, undefined, actionCompleteSpy);
snackBarRef.closeWithAction();
snackBarRef.dismissWithAction();
viewContainerFixture.detectChanges();
tick();
@@ -307,6 +307,21 @@ describe('MatSnackBar', () => {
tick(500);
}));
it('should indicate in `afterClosed` whether it was dismissed by an action', fakeAsync(() => {
const closeSpy = jasmine.createSpy('dismiss spy');
const snackBarRef = snackBar.open('Some content');
viewContainerFixture.detectChanges();
snackBarRef.afterDismissed().subscribe(closeSpy);
snackBarRef.closeWithAction();
viewContainerFixture.detectChanges();
tick();
expect(closeSpy).toHaveBeenCalledWith(jasmine.objectContaining({dismissedByAction: true}));
tick(500);
}));
it('should complete the onAction stream when not closing via an action', fakeAsync(() => {
const actionCompleteSpy = jasmine.createSpy('action complete spy');
const snackBarRef = snackBar.open('Some content');
@@ -401,7 +416,7 @@ describe('MatSnackBar', () => {
.toBe('Chimichanga', 'Expected the injected data object to be the one the user provided.');
});
it('should allow manually closing with an action', fakeAsync(() => {
it('should allow manually dismissing with an action', fakeAsync(() => {
const dismissCompleteSpy = jasmine.createSpy('dismiss complete spy');
const actionCompleteSpy = jasmine.createSpy('action complete spy');
const snackBarRef = snackBar.openFromComponent(BurritosNotification);
@@ -410,7 +425,7 @@ describe('MatSnackBar', () => {
snackBarRef.afterDismissed().subscribe(undefined, undefined, dismissCompleteSpy);
snackBarRef.onAction().subscribe(undefined, undefined, actionCompleteSpy);
snackBarRef.closeWithAction();
snackBarRef.dismissWithAction();
viewContainerFixture.detectChanges();
tick();