diff --git a/packages/angular/src/components/ion-nav.ts b/packages/angular/src/components/ion-nav.ts index ea061b463e..2444ffba65 100644 --- a/packages/angular/src/components/ion-nav.ts +++ b/packages/angular/src/components/ion-nav.ts @@ -1,65 +1,33 @@ import { - ChangeDetectorRef, - Component, ComponentFactoryResolver, - ComponentRef, + Directive, ElementRef, Injector, - ReflectiveInjector, Type, - ViewContainerRef, - ViewChild } from '@angular/core'; import { FrameworkDelegate } from '@ionic/core'; -import { getProviders } from '../di/di'; import { AngularComponentMounter } from '../providers/angular-component-mounter'; import { AngularMountingData } from '../types/interfaces'; -const elementToComponentRefMap = new Map>(); - -@Component({ +@Directive({ selector: 'ion-nav', - template: ` -
- ` }) export class IonNavDelegate implements FrameworkDelegate { - @ViewChild('viewport', { read: ViewContainerRef}) viewport: ViewContainerRef; - - constructor(private elementRef: ElementRef, private changeDetection: ChangeDetectorRef, private angularComponentMounter: AngularComponentMounter, private injector: Injector, private componentResolveFactory: ComponentFactoryResolver) { + constructor(private elementRef: ElementRef, private angularComponentMounter: AngularComponentMounter, private componentResolveFactory: ComponentFactoryResolver, private injector: Injector) { this.elementRef.nativeElement.delegate = this; - } - async attachViewToDom(elementOrContainerToMountTo: HTMLIonNavElement, elementOrComponentToMount: Type, - _propsOrDataObj?: any, _classesToAdd?: string[]): Promise { + attachViewToDom(elementOrContainerToMountTo: HTMLIonNavElement, elementOrComponentToMount: Type, _propsOrDataObj?: any, classesToAdd?: string[]): Promise { - const componentProviders = ReflectiveInjector.resolve(getProviders(elementOrContainerToMountTo)); - console.log('componentProviders: ', componentProviders); - - const element = document.createElement('ion-page'); - for (const clazz of _classesToAdd) { - element.classList.add(clazz); - } - - elementOrContainerToMountTo.appendChild(element); - const mountingData = await this.angularComponentMounter.attachViewToDom(element, elementOrComponentToMount, [], this.changeDetection, this.componentResolveFactory, this.injector); - mountingData.element = element; - - elementToComponentRefMap.set(mountingData.angularHostElement, mountingData.componentRef); - - return mountingData; + const hostElement = document.createElement('div'); + return this.angularComponentMounter.attachViewToDom(elementOrContainerToMountTo, hostElement, elementOrComponentToMount, this.componentResolveFactory, this.injector, classesToAdd); } - async removeViewFromDom(_parentElement: HTMLElement, childElement: HTMLElement) { - const componentRef = elementToComponentRefMap.get(childElement); - if (componentRef) { - return this.angularComponentMounter.removeViewFromDom(componentRef); - } - return Promise.resolve(); + removeViewFromDom(_parentElement: HTMLElement, childElement: HTMLElement) { + return this.angularComponentMounter.removeViewFromDom(childElement); } } diff --git a/packages/angular/src/di/di.ts b/packages/angular/src/di/di.ts index cc7ebf5e98..3f0fdd85d6 100644 --- a/packages/angular/src/di/di.ts +++ b/packages/angular/src/di/di.ts @@ -8,10 +8,16 @@ export const NavControllerToken = new InjectionToken('NavControllerToken'); export const ViewControllerToken = new InjectionToken('ViewControllerToken'); export const AppToken = new InjectionToken('AppToken'); -export function getProviders(element: HTMLIonNavElement) { +export function getProviders(element: HTMLElement) { + if (element.tagName !== 'ion-nav') { + element.closest('ion-nav'); + } + + const nearestNavElement = (element.tagName.toLowerCase() === 'ion-nav' ? element : element.closest('ion-nav')) as HTMLIonNavElement; + return [ { - provide: NavControllerToken, useValue: element + provide: NavControllerToken, useValue: nearestNavElement }, { diff --git a/packages/angular/src/index.ts b/packages/angular/src/index.ts index 18ec518f44..4928b0673e 100644 --- a/packages/angular/src/index.ts +++ b/packages/angular/src/index.ts @@ -1,10 +1,13 @@ -export { IonNavDelegate } from './components/ion-nav'; export { IonicAngularModule } from './module'; +/* Directives/Components */ +export { IonNavDelegate } from './components/ion-nav'; +/* Providers */ export { ActionSheetController, ActionSheetProxy } from './providers/action-sheet-controller'; export { AlertController, AlertProxy } from './providers/alert-controller'; export { App } from './providers/app'; export { LoadingController, LoadingProxy } from './providers/loading-controller'; +export { ModalController, ModalProxy } from './providers/modal-controller'; export { NavController } from './providers/nav-controller'; export { ToastController, ToastProxy } from './providers/toast-controller'; \ No newline at end of file diff --git a/packages/angular/src/module.ts b/packages/angular/src/module.ts index 81caad18f0..8a6646dc7e 100644 --- a/packages/angular/src/module.ts +++ b/packages/angular/src/module.ts @@ -1,3 +1,4 @@ +import { CommonModule } from '@angular/common'; import { ModuleWithProviders, NgModule, @@ -11,6 +12,7 @@ import { SelectValueAccessor } from './control-value-accessors/select-value-acce import { TextValueAccessor } from './control-value-accessors/text-value-accessor'; +/* Components */ import { IonNavDelegate } from './components/ion-nav'; /* Providers */ @@ -18,6 +20,7 @@ import { ActionSheetController } from './providers/action-sheet-controller'; import { AlertController } from './providers/alert-controller'; import { AngularComponentMounter } from './providers/angular-component-mounter'; import { LoadingController } from './providers/loading-controller'; +import { ModalController } from './providers/modal-controller'; import { ToastController } from './providers/toast-controller'; @NgModule({ @@ -37,6 +40,9 @@ import { ToastController } from './providers/toast-controller'; SelectValueAccessor, TextValueAccessor ], + imports: [ + CommonModule, + ], schemas: [ CUSTOM_ELEMENTS_SCHEMA ], @@ -50,6 +56,7 @@ export class IonicAngularModule { ActionSheetController, AngularComponentMounter, LoadingController, + ModalController, ToastController ] }; diff --git a/packages/angular/src/providers/angular-component-mounter.ts b/packages/angular/src/providers/angular-component-mounter.ts index dea3dbd7ee..4343cec9f9 100644 --- a/packages/angular/src/providers/angular-component-mounter.ts +++ b/packages/angular/src/providers/angular-component-mounter.ts @@ -1,51 +1,70 @@ import { - ChangeDetectorRef, + ApplicationRef, ComponentFactoryResolver, ComponentRef, Injectable, Injector, NgZone, ReflectiveInjector, - Type, + Type } from '@angular/core'; +import { getProviders } from '../di/di'; import { AngularMountingData } from '../types/interfaces'; +const elementToComponentRefMap = new Map>(); + @Injectable() export class AngularComponentMounter { - constructor(private defaultCfr: ComponentFactoryResolver, private zone: NgZone) { + constructor(private defaultCfr: ComponentFactoryResolver, private zone: NgZone, private appRef: ApplicationRef) { } - attachViewToDom(parentElement: HTMLElement, componentToMount: Type, providers: any[], changeDetection: ChangeDetectorRef, componentResolveFactory: ComponentFactoryResolver, injector: Injector): Promise { + attachViewToDom(parentElement: HTMLElement, hostElement: HTMLElement, componentToMount: Type, componentResolveFactory: ComponentFactoryResolver, injector: Injector, classesToAdd: string[]): Promise { return new Promise((resolve) => { this.zone.run(() => { - console.log('parentElement: ', parentElement); + const crf = componentResolveFactory ? componentResolveFactory : this.defaultCfr; - const mountingData = attachViewToDom(crf, componentToMount, parentElement, providers, changeDetection, injector); + + const mountingData = attachViewToDom(crf, parentElement, hostElement, componentToMount, injector, this.appRef, classesToAdd); resolve(mountingData); }); }); } - removeViewFromDom(componentRef: ComponentRef): Promise { + removeViewFromDom(childElement: HTMLElement): Promise { return new Promise((resolve) => { this.zone.run(() => { - componentRef.destroy(); + removeViewFromDom(childElement); resolve(); }); }); } } -export function attachViewToDom(crf: ComponentFactoryResolver, componentToMount: Type, element: HTMLElement, providers: any, changeDetection: ChangeDetectorRef, injector: Injector): AngularMountingData { - const componentFactory = crf.resolveComponentFactory(componentToMount); - const componentProviders = ReflectiveInjector.resolve(providers); - const childInjector = ReflectiveInjector.fromResolvedProviders(componentProviders, injector); - const componentRef = componentFactory.create(childInjector, [], element); +export function removeViewFromDom(childElement: HTMLElement) { + const componentRef = elementToComponentRefMap.get(childElement); + if (componentRef) { + componentRef.destroy(); + } +} - changeDetection.detectChanges(); +export function attachViewToDom(crf: ComponentFactoryResolver, parentElement: HTMLElement, hostElement: HTMLElement, componentToMount: Type, injector: Injector, appRef: ApplicationRef, classesToAdd: string[]): AngularMountingData { + + const componentProviders = ReflectiveInjector.resolve(getProviders(parentElement)); + const componentFactory = crf.resolveComponentFactory(componentToMount); + const childInjector = ReflectiveInjector.fromResolvedProviders(componentProviders, injector); + const componentRef = componentFactory.create(childInjector, [], hostElement); + for (const clazz of classesToAdd) { + hostElement.classList.add(clazz); + } + + parentElement.appendChild(hostElement); + + appRef.attachView(componentRef.hostView); + + elementToComponentRefMap.set(hostElement, componentRef); return { componentFactory, @@ -53,7 +72,7 @@ export function attachViewToDom(crf: ComponentFactoryResolver, componentToMount: componentRef: componentRef, instance: componentRef.instance, angularHostElement: componentRef.location.nativeElement, - element: componentRef.location.nativeElement, + element: hostElement, }; } diff --git a/packages/angular/src/providers/modal-controller.ts b/packages/angular/src/providers/modal-controller.ts new file mode 100644 index 0000000000..7c07d09737 --- /dev/null +++ b/packages/angular/src/providers/modal-controller.ts @@ -0,0 +1,134 @@ +import { + ComponentFactoryResolver, + Injectable, + Injector, + Type, +} from '@angular/core'; + +import { + FrameworkDelegate, + ModalDismissEvent, + ModalOptions +} from '@ionic/core'; + +import { AngularComponentMounter } from '../providers/angular-component-mounter'; +import { AngularMountingData } from '../types/interfaces'; + +import { ensureElementInBody, hydrateElement } from '../util/util'; + +let modalId = 0; + +@Injectable() +export class ModalController implements FrameworkDelegate { + + constructor(private angularComponentMounter: AngularComponentMounter, private componentResolveFactory: ComponentFactoryResolver, private injector: Injector) { + } + + create(opts?: ModalOptions): ModalProxy { + opts.delegate = this; + return getModalProxy(opts); + } + + attachViewToDom(elementOrContainerToMountTo: HTMLElement, elementOrComponentToMount: Type, _propsOrDataObj?: any, classesToAdd?: string[]): Promise { + + const hostElement = document.createElement('div'); + return this.angularComponentMounter.attachViewToDom(elementOrContainerToMountTo, hostElement, elementOrComponentToMount, this.componentResolveFactory, this.injector, classesToAdd); + } + + removeViewFromDom(_parentElement: HTMLElement, childElement: HTMLElement) { + return this.angularComponentMounter.removeViewFromDom(childElement); + } +} + +export function getModalProxy(opts: ModalOptions) { + return { + id: modalId++, + state: PRESENTING, + opts: opts, + present: function() { return present(this); }, + dismiss: function() { return dismiss(this); }, + onDidDismiss: function(callback: (data: any, role: string) => void) { + (this as ModalProxyInternal).onDidDismissHandler = callback; + }, + onWillDismiss: function(callback: (data: any, role: string) => void) { + (this as ModalProxyInternal).onWillDismissHandler = callback; + }, + }; +} + +export function present(modalProxy: ModalProxyInternal): Promise { + modalProxy.state = PRESENTING; + return loadOverlay(modalProxy.opts).then((modalElement: HTMLIonModalElement) => { + Object.assign(modalElement, modalProxy.opts); + modalProxy.element = modalElement; + + const onDidDismissHandler = (event: ModalDismissEvent) => { + modalElement.removeEventListener(ION_MODAL_DID_DISMISS_EVENT, onDidDismissHandler); + if (modalProxy.onDidDismissHandler) { + modalProxy.onDidDismissHandler(event.detail.data, event.detail.role); + } + }; + + const onWillDismissHandler = (event: ModalDismissEvent) => { + modalElement.removeEventListener(ION_MODAL_WILL_DISMISS_EVENT, onWillDismissHandler); + if (modalProxy.onWillDismissHandler) { + modalProxy.onWillDismissHandler(event.detail.data, event.detail.role); + } + }; + + modalElement.addEventListener(ION_MODAL_DID_DISMISS_EVENT, onDidDismissHandler); + modalElement.addEventListener(ION_MODAL_WILL_DISMISS_EVENT, onWillDismissHandler); + + if (modalProxy.state === PRESENTING) { + return modalElement.present(); + } + + // we'll only ever get here if someone tried to dismiss the overlay or mess with it's internal state + // attribute before it could async load and present itself. + // with that in mind, just return null to make the TS compiler happy + return null; + }); +} + +export function dismiss(modalProxy: ModalProxyInternal): Promise { + modalProxy.state = DISMISSING; + if (modalProxy.element) { + if (modalProxy.state === DISMISSING) { + return modalProxy.element.dismiss(); + } + } + // either we're not in the dismissing state + // or we're calling this before the element is created + // so just return a resolved promise + return Promise.resolve(); +} + +export function loadOverlay(opts: ModalOptions): Promise { + const element = ensureElementInBody('ion-modal-controller') as HTMLIonModalControllerElement; + return hydrateElement(element).then(() => { + return element.create(opts); + }); +} + +export interface ModalProxy { + present(): Promise; + dismiss(): Promise; + onDidDismiss(callback: (data: any, role: string) => void): void; + onWillDismiss(callback: (data: any, role: string) => void): void; +} + +export interface ModalProxyInternal extends ModalProxy { + id: number; + opts: ModalOptions; + state: number; + element: HTMLIonModalElement; + onDidDismissHandler?: (data: any, role: string) => void; + onWillDismissHandler?: (data: any, role: string) => void; +} + +export const PRESENTING = 1; +export const DISMISSING = 2; + +const ION_MODAL_DID_DISMISS_EVENT = 'ionModalDidDismiss'; +const ION_MODAL_WILL_DISMISS_EVENT = 'ionModalWillDismiss'; + diff --git a/packages/angular/src/types/interfaces.ts b/packages/angular/src/types/interfaces.ts index 26d7efae26..1b4d4acfaa 100644 --- a/packages/angular/src/types/interfaces.ts +++ b/packages/angular/src/types/interfaces.ts @@ -12,4 +12,4 @@ export interface AngularMountingData extends FrameworkMountingData { componentRef?: ComponentRef; instance?: any; angularHostElement?: HTMLElement; -} \ No newline at end of file +} diff --git a/packages/core/src/components.d.ts b/packages/core/src/components.d.ts index 43ecf98534..102fb4a16f 100644 --- a/packages/core/src/components.d.ts +++ b/packages/core/src/components.d.ts @@ -1630,6 +1630,7 @@ declare global { enterAnimation?: AnimationBuilder; leaveAnimation?: AnimationBuilder; animate?: boolean; + delegate?: FrameworkDelegate; } } } diff --git a/packages/core/src/components/action-sheet-controller/action-sheet-controller.tsx b/packages/core/src/components/action-sheet-controller/action-sheet-controller.tsx index 60156f591e..ae1979e8a5 100644 --- a/packages/core/src/components/action-sheet-controller/action-sheet-controller.tsx +++ b/packages/core/src/components/action-sheet-controller/action-sheet-controller.tsx @@ -22,7 +22,6 @@ export class ActionSheetController { // give this action sheet a unique id actionSheet.actionSheetId = `action-sheet-${id}`; - actionSheet.style.zIndex = (20000 + id).toString(); // convert the passed in action sheet options into props // that get passed down into the new action sheet diff --git a/packages/core/src/components/action-sheet/action-sheet.tsx b/packages/core/src/components/action-sheet/action-sheet.tsx index 260fb4b721..e4e291a5b2 100644 --- a/packages/core/src/components/action-sheet/action-sheet.tsx +++ b/packages/core/src/components/action-sheet/action-sheet.tsx @@ -125,6 +125,8 @@ export class ActionSheet { } this.ionActionSheetWillPresent.emit(); + this.el.style.zIndex = `${20000 + this.actionSheetId}`; + // get the user's animation fn if one was provided const animationBuilder = this.enterAnimation || this.config.get('actionSheetEnter', this.mode === 'ios' ? iosEnterAnimation : mdEnterAnimation); diff --git a/packages/core/src/components/alert-controller/alert-controller.tsx b/packages/core/src/components/alert-controller/alert-controller.tsx index 7e3758cedf..c23971f9ae 100644 --- a/packages/core/src/components/alert-controller/alert-controller.tsx +++ b/packages/core/src/components/alert-controller/alert-controller.tsx @@ -23,7 +23,6 @@ export class AlertController { // give this action sheet a unique id alert.alertId = `alert-${id}`; - alert.style.zIndex = (20000 + id).toString(); // convert the passed in action sheet options into props // that get passed down into the new action sheet diff --git a/packages/core/src/components/alert/alert.tsx b/packages/core/src/components/alert/alert.tsx index 9dbdcad9ea..544a6575db 100644 --- a/packages/core/src/components/alert/alert.tsx +++ b/packages/core/src/components/alert/alert.tsx @@ -131,6 +131,8 @@ export class Alert { } this.ionAlertWillPresent.emit(); + this.el.style.zIndex = `${20000 + this.alertId}`; + // get the user's animation fn if one was provided const animationBuilder = this.enterAnimation || this.config.get('alertEnter', this.mode === 'ios' ? iosEnterAnimation : mdEnterAnimation); diff --git a/packages/core/src/components/loading-controller/loading-controller.tsx b/packages/core/src/components/loading-controller/loading-controller.tsx index ab8f5c7304..49a8414246 100644 --- a/packages/core/src/components/loading-controller/loading-controller.tsx +++ b/packages/core/src/components/loading-controller/loading-controller.tsx @@ -22,7 +22,6 @@ export class LoadingController { // give this loading a unique id loading.loadingId = `loading-${id}`; - loading.style.zIndex = (20000 + id).toString(); // convert the passed in loading options into props // that get passed down into the new loading diff --git a/packages/core/src/components/loading/loading.tsx b/packages/core/src/components/loading/loading.tsx index b4ace54815..00a112140a 100644 --- a/packages/core/src/components/loading/loading.tsx +++ b/packages/core/src/components/loading/loading.tsx @@ -129,6 +129,8 @@ export class Loading { this.ionLoadingWillPresent.emit(); + this.el.style.zIndex = `${20000 + this.loadingId}`; + // get the user's animation fn if one was provided const animationBuilder = this.enterAnimation || this.config.get('loadingEnter', this.mode === 'ios' ? iosEnterAnimation : mdEnterAnimation); diff --git a/packages/core/src/components/modal-controller/modal-controller.tsx b/packages/core/src/components/modal-controller/modal-controller.tsx index b72a8c5ff0..e60d780ecf 100644 --- a/packages/core/src/components/modal-controller/modal-controller.tsx +++ b/packages/core/src/components/modal-controller/modal-controller.tsx @@ -20,7 +20,6 @@ export class ModalController { // give this modal a unique id modal.modalId = `modal-${id}`; - modal.style.zIndex = (10000 + id).toString(); // convert the passed in modal options into props // that get passed down into the new modal diff --git a/packages/core/src/components/modal/modal.tsx b/packages/core/src/components/modal/modal.tsx index cbb48cb38c..a82c67272a 100644 --- a/packages/core/src/components/modal/modal.tsx +++ b/packages/core/src/components/modal/modal.tsx @@ -4,9 +4,12 @@ import { AnimationBuilder, AnimationController, Config, + FrameworkDelegate, OverlayDismissEvent, OverlayDismissEventDetail } from '../../index'; + +import { DomFrameworkDelegate } from '../../utils/dom-framework-delegate'; import { domControllerAsync, playAnimationAsync } from '../../utils/helpers'; import { createThemedClasses } from '../../utils/theme'; @@ -73,12 +76,13 @@ export class Modal { @Prop() enterAnimation: AnimationBuilder; @Prop() leaveAnimation: AnimationBuilder; @Prop() animate: boolean; + @Prop({ mutable: true }) delegate: FrameworkDelegate; private animation: Animation; - + private usersComponentElement: HTMLElement; @Method() - present() { + async present() { if (this.animation) { this.animation.destroy(); this.animation = null; @@ -86,27 +90,39 @@ export class Modal { this.ionModalWillPresent.emit(); + this.el.style.zIndex = `${20000 + this.modalId}`; + // get the user's animation fn if one was provided const animationBuilder = this.enterAnimation || this.config.get('modalEnter', this.mode === 'ios' ? iosEnterAnimation : mdEnterAnimation); - // build the animation and kick it off - // build the animation and kick it off - return this.animationCtrl.create(animationBuilder, this.el).then(animation => { - this.animation = animation; - if (!this.animate) { - // if the duration is 0, it won't actually animate I don't think - // TODO - validate this - this.animation = animation.duration(0); - } - return playAnimationAsync(animation); - }).then((animation) => { - animation.destroy(); - this.ionModalDidPresent.emit(); - }); + const userComponentParent = this.el.querySelector(`.${USER_COMPONENT_MODAL_CONTAINER_CLASS}`); + if (!this.delegate) { + this.delegate = new DomFrameworkDelegate(); + } + + const cssClasses = ['ion-page']; + if (this.cssClass && this.cssClass.length) { + cssClasses.push(this.cssClass); + } + + // add the modal by default to the data being passed + this.data = this.data || {}; + this.data.modal = this.el; + const mountingData = await this.delegate.attachViewToDom(userComponentParent, this.component, this.data, cssClasses); + this.usersComponentElement = mountingData.element; + this.animation = await this.animationCtrl.create(animationBuilder, this.el); + if (!this.animate) { + // if the duration is 0, it won't actually animate I don't think + // TODO - validate this + this.animation = this.animation.duration(0); + } + await playAnimationAsync(this.animation); + this.animation.destroy(); + this.ionModalDidPresent.emit(); } @Method() - dismiss(data?: any, role?: string) { + async dismiss(data?: any, role?: string) { if (this.animation) { this.animation.destroy(); this.animation = null; @@ -116,25 +132,37 @@ export class Modal { role }); + if (!this.delegate) { + this.delegate = new DomFrameworkDelegate(); + } + // get the user's animation fn if one was provided const animationBuilder = this.leaveAnimation || this.config.get('modalLeave', this.mode === 'ios' ? iosLeaveAnimation : mdLeaveAnimation); - return this.animationCtrl.create(animationBuilder, this.el).then(animation => { - this.animation = animation; - return playAnimationAsync(animation); - }).then((animation) => { - animation.destroy(); - return domControllerAsync(Context.dom.write, () => { - this.el.parentNode.removeChild(this.el); - }); - }).then(() => { - this.ionModalDidDismiss.emit({ - data, - role - }); + this.animation = await this.animationCtrl.create(animationBuilder, this.el); + await playAnimationAsync(this.animation); + this.animation.destroy(); + + + await domControllerAsync(Context.dom.write, () => {}); + + // TODO - Figure out how to make DOM controller work with callbacks that return a promise or are async + const userComponentParent = this.el.querySelector(`.${USER_COMPONENT_MODAL_CONTAINER_CLASS}`); + await this.delegate.removeViewFromDom(userComponentParent, this.usersComponentElement); + + this.el.parentElement.removeChild(this.el); + + this.ionModalDidDismiss.emit({ + data, + role }); } + @Method() + getUserComponentContainer(): HTMLElement { + return this.el.querySelector(`.${USER_COMPONENT_MODAL_CONTAINER_CLASS}`); + } + @Listen('ionDismiss') protected onDismiss(ev: UIEvent) { ev.stopPropagation(); @@ -188,6 +216,7 @@ export interface ModalOptions { enterAnimation?: AnimationBuilder; exitAnimation?: AnimationBuilder; cssClass?: string; + delegate?: FrameworkDelegate; } @@ -213,3 +242,5 @@ export { mdEnterAnimation as mdModalEnterAnimation, mdLeaveAnimation as mdModalLeaveAnimation }; + +export const USER_COMPONENT_MODAL_CONTAINER_CLASS = 'modal-wrapper'; diff --git a/packages/core/src/components/modal/readme.md b/packages/core/src/components/modal/readme.md index ebdf406700..7492997633 100644 --- a/packages/core/src/components/modal/readme.md +++ b/packages/core/src/components/modal/readme.md @@ -32,6 +32,11 @@ string any +#### delegate + +any + + #### enableBackdropDismiss boolean @@ -89,6 +94,11 @@ string any +#### delegate + +any + + #### enableBackdropDismiss boolean @@ -144,6 +154,9 @@ boolean #### dismiss() +#### getUserComponentContainer() + + #### present() diff --git a/packages/core/src/components/modal/test/basic/index.html b/packages/core/src/components/modal/test/basic/index.html index da2ab926db..baea9f3b3b 100644 --- a/packages/core/src/components/modal/test/basic/index.html +++ b/packages/core/src/components/modal/test/basic/index.html @@ -28,10 +28,21 @@