From 95bfd0664c4e87739d7973b94decd2f3f64d26eb Mon Sep 17 00:00:00 2001 From: Dan Bucholtz Date: Thu, 9 Jun 2016 14:42:11 -0500 Subject: [PATCH] feat(modal): background click and escape key dismiss background click and escape key dismiss closes #6738 --- src/components/modal/modal.ts | 64 +++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 14 deletions(-) diff --git a/src/components/modal/modal.ts b/src/components/modal/modal.ts index ec0a17cf117..fb8d9130987 100644 --- a/src/components/modal/modal.ts +++ b/src/components/modal/modal.ts @@ -1,9 +1,10 @@ -import {Component, ComponentRef, ElementRef, ViewChild, ViewContainerRef, ComponentResolver} from '@angular/core'; +import {Component, ComponentRef, ComponentResolver, ElementRef, HostListener, ViewChild, ViewContainerRef} from '@angular/core'; import {addSelector} from '../../config/bootstrap'; import {Animation} from '../../animations/animation'; import {NavParams} from '../nav/nav-params'; -import {pascalCaseToDashCase} from '../../util/util'; +import {isPresent, pascalCaseToDashCase} from '../../util/util'; +import {Key} from '../../util/key'; import {Transition, TransitionOptions} from '../../transitions/transition'; import {ViewController} from '../nav/view-controller'; import {windowDimensions} from '../../util/dom'; @@ -114,8 +115,11 @@ export class Modal extends ViewController { public modalViewType: string; - constructor(componentType: any, data: any = {}) { + constructor(componentType: any, data: any = {}, opts: ModalOptions = {}) { data.componentType = componentType; + opts.showBackdrop = isPresent(opts.showBackdrop) ? !!opts.showBackdrop : true; + opts.enableBackdropDismiss = isPresent(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : true; + data.opts = opts; super(ModalCmp, data); this.modalViewType = componentType.name; this.viewType = 'modal'; @@ -132,11 +136,20 @@ export class Modal extends ViewController { } /** - * @param {any} componentType Modal - * @param {object} data Modal options + * Create a modal with the following options + * + * | Option | Type | Description | + * |-----------------------|------------|------------------------------------------------------------------------------------------------------------------| + * | showBackdrop |`boolean` | Whether to show the backdrop. Default true. | + * | enableBackdropDismiss |`boolean` | Whether the popover should be dismissed by tapping the backdrop. Default true. | + * + * + * @param {object} componentType The Modal view + * @param {object} data Any data to pass to the Modal view + * @param {object} opts Modal options */ - static create(componentType: any, data = {}) { - return new Modal(componentType, data); + static create(componentType: any, data: any = {}, opts: ModalOptions = {}) { + return new Modal(componentType, data, opts); } // Override the load method and load our child component @@ -153,10 +166,15 @@ export class Modal extends ViewController { } } +export interface ModalOptions { + showBackdrop?: boolean; + enableBackdropDismiss?: boolean; +} + @Component({ selector: 'ion-modal', template: - '' + + '' + '' @@ -165,11 +183,12 @@ export class ModalCmp { @ViewChild('viewport', {read: ViewContainerRef}) viewport: ViewContainerRef; - constructor( - private _compiler: ComponentResolver, - private _navParams: NavParams, - private _viewCtrl: ViewController - ) {} + private d: any; + private enabled: boolean; + + constructor(private _compiler: ComponentResolver, private _navParams: NavParams, private _viewCtrl: ViewController) { + this.d = _navParams.data.opts; + } loadComponent(done: Function) { addSelector(this._navParams.data.componentType, 'ion-modal-inner'); @@ -178,7 +197,7 @@ export class ModalCmp { let componentRef = this.viewport.createComponent(componentFactory, this.viewport.length, this.viewport.parentInjector); this._viewCtrl.setInstance(componentRef.instance); - + this.enabled = true; done(); }); } @@ -186,6 +205,23 @@ export class ModalCmp { ngAfterViewInit() { // intentionally kept empty } + + dismiss(role: any): Promise { + return this._viewCtrl.dismiss(null, role); + } + + bdClick() { + if (this.enabled && this.d.enableBackdropDismiss) { + this.dismiss('backdrop'); + } + } + + @HostListener('body:keyup', ['$event']) + private _keyUp(ev: KeyboardEvent) { + if (this.enabled && this._viewCtrl.isLast() && ev.keyCode === Key.ESCAPE ) { + this.bdClick(); + } + } } /**