Skip to content

Commit

Permalink
feat(bottom-sheet): add result param when dismissing bottom sheet (#9810
Browse files Browse the repository at this point in the history
)

Something that came up while doing the docs. Adds the ability for the consumer to pass back a result from a bottom sheet. Also adds a test for `afterDismissed` since it didn't have one.
  • Loading branch information
crisbeto authored and jelbourn committed Feb 13, 2018
1 parent dcd9c79 commit 98a6910
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 13 deletions.
19 changes: 13 additions & 6 deletions src/lib/bottom-sheet/bottom-sheet-ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {MatBottomSheetContainer} from './bottom-sheet-container';
/**
* Reference to a bottom sheet dispatched from the bottom sheet service.
*/
export class MatBottomSheetRef<T = any> {
export class MatBottomSheetRef<T = any, R = any> {
/** Instance of the component making up the content of the bottom sheet. */
instance: T;

Expand All @@ -29,11 +29,14 @@ export class MatBottomSheetRef<T = any> {
containerInstance: MatBottomSheetContainer;

/** Subject for notifying the user that the bottom sheet has been dismissed. */
private readonly _afterDismissed = new Subject<void>();
private readonly _afterDismissed = new Subject<R | undefined>();

/** Subject for notifying the user that the bottom sheet has opened and appeared. */
private readonly _afterOpened = new Subject<void>();

/** Result to be passed down to the `afterDismissed` stream. */
private _result: R | undefined;

constructor(containerInstance: MatBottomSheetContainer, private _overlayRef: OverlayRef) {
this.containerInstance = containerInstance;

Expand All @@ -54,7 +57,7 @@ export class MatBottomSheetRef<T = any> {
)
.subscribe(() => {
this._overlayRef.dispose();
this._afterDismissed.next();
this._afterDismissed.next(this._result);
this._afterDismissed.complete();
});

Expand All @@ -66,21 +69,25 @@ export class MatBottomSheetRef<T = any> {
}
}

/** Dismisses the bottom sheet. */
dismiss(): void {
/**
* Dismisses the bottom sheet.
* @param result Data to be passed back to the bottom sheet opener.
*/
dismiss(result?: R): void {
if (!this._afterDismissed.closed) {
// Transition the backdrop in parallel to the bottom sheet.
this.containerInstance._animationStateChanged.pipe(
filter(event => event.phaseName === 'start'),
take(1)
).subscribe(() => this._overlayRef.detachBackdrop());

this._result = result;
this.containerInstance.exit();
}
}

/** Gets an observable that is notified when the bottom sheet is finished closing. */
afterDismissed(): Observable<void> {
afterDismissed(): Observable<R | undefined> {
return this._afterDismissed.asObservable();
}

Expand Down
28 changes: 28 additions & 0 deletions src/lib/bottom-sheet/bottom-sheet.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,34 @@ describe('MatBottomSheet', () => {
tick(500);
}));

it('should emit after being dismissed', fakeAsync(() => {
const bottomSheetRef = bottomSheet.open(PizzaMsg);
const spy = jasmine.createSpy('afterDismissed spy');

bottomSheetRef.afterDismissed().subscribe(spy);
viewContainerFixture.detectChanges();

bottomSheetRef.dismiss();
viewContainerFixture.detectChanges();
flush();

expect(spy).toHaveBeenCalledTimes(1);
}));

it('should be able to pass a result back to the dismissed stream', fakeAsync(() => {
const bottomSheetRef = bottomSheet.open<PizzaMsg, any, number>(PizzaMsg);
const spy = jasmine.createSpy('afterDismissed spy');

bottomSheetRef.afterDismissed().subscribe(spy);
viewContainerFixture.detectChanges();

bottomSheetRef.dismiss(1337);
viewContainerFixture.detectChanges();
flush();

expect(spy).toHaveBeenCalledWith(1337);
}));

describe('passing in data', () => {
it('should be able to pass in data', () => {
const config = {
Expand Down
14 changes: 7 additions & 7 deletions src/lib/bottom-sheet/bottom-sheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,18 @@ export class MatBottomSheet {
private _injector: Injector,
@Optional() @SkipSelf() private _parentBottomSheet: MatBottomSheet) {}

open<T, D = any>(component: ComponentType<T>,
config?: MatBottomSheetConfig<D>): MatBottomSheetRef<T>;
open<T, D = any>(template: TemplateRef<T>,
config?: MatBottomSheetConfig<D>): MatBottomSheetRef<T>;
open<T, D = any, R = any>(component: ComponentType<T>,
config?: MatBottomSheetConfig<D>): MatBottomSheetRef<T, R>;
open<T, D = any, R = any>(template: TemplateRef<T>,
config?: MatBottomSheetConfig<D>): MatBottomSheetRef<T, R>;

open<T, D = any>(componentOrTemplateRef: ComponentType<T> | TemplateRef<T>,
config?: MatBottomSheetConfig<D>): MatBottomSheetRef<T> {
open<T, D = any, R = any>(componentOrTemplateRef: ComponentType<T> | TemplateRef<T>,
config?: MatBottomSheetConfig<D>): MatBottomSheetRef<T, R> {

const _config = _applyConfigDefaults(config);
const overlayRef = this._createOverlay(_config);
const container = this._attachContainer(overlayRef, _config);
const ref = new MatBottomSheetRef<T>(container, overlayRef);
const ref = new MatBottomSheetRef<T, R>(container, overlayRef);

if (componentOrTemplateRef instanceof TemplateRef) {
container.attachTemplatePortal(new TemplatePortal<T>(componentOrTemplateRef, null!, {
Expand Down

0 comments on commit 98a6910

Please sign in to comment.