UNPKG

23.7 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5const index$1 = require('./index-a0a08b2a.js');
6const ionicGlobal = require('./ionic-global-06f21c1a.js');
7const frameworkDelegate = require('./framework-delegate-45524d8c.js');
8const overlays = require('./overlays-59863ad4.js');
9const theme = require('./theme-30b7a575.js');
10const index$2 = require('./index-222357e4.js');
11const animation = require('./animation-13cbbb20.js');
12const cubicBezier = require('./cubic-bezier-0b2ccc35.js');
13const index = require('./index-a1dd5c93.js');
14const helpers = require('./helpers-d381ec4d.js');
15require('./hardware-back-button-148ce546.js');
16require('./gesture-controller-29adda71.js');
17
18// Defaults for the card swipe animation
19const SwipeToCloseDefaults = {
20 MIN_PRESENTING_SCALE: 0.93,
21};
22const createSwipeToCloseGesture = (el, animation, onDismiss) => {
23 const height = el.offsetHeight;
24 let isOpen = false;
25 const canStart = (detail) => {
26 const target = detail.event.target;
27 if (target === null ||
28 !target.closest) {
29 return true;
30 }
31 const contentOrFooter = target.closest('ion-content, ion-footer');
32 if (contentOrFooter === null) {
33 return true;
34 }
35 // Target is in the content or the footer so do not start the gesture.
36 // We could be more nuanced here and allow it for content that
37 // does not need to scroll.
38 return false;
39 };
40 const onStart = () => {
41 animation.progressStart(true, (isOpen) ? 1 : 0);
42 };
43 const onMove = (detail) => {
44 const step = helpers.clamp(0.0001, detail.deltaY / height, 0.9999);
45 animation.progressStep(step);
46 };
47 const onEnd = (detail) => {
48 const velocity = detail.velocityY;
49 const step = helpers.clamp(0.0001, detail.deltaY / height, 0.9999);
50 const threshold = (detail.deltaY + velocity * 1000) / height;
51 const shouldComplete = threshold >= 0.5;
52 let newStepValue = (shouldComplete) ? -0.001 : 0.001;
53 if (!shouldComplete) {
54 animation.easing('cubic-bezier(1, 0, 0.68, 0.28)');
55 newStepValue += cubicBezier.getTimeGivenProgression([0, 0], [1, 0], [0.68, 0.28], [1, 1], step)[0];
56 }
57 else {
58 animation.easing('cubic-bezier(0.32, 0.72, 0, 1)');
59 newStepValue += cubicBezier.getTimeGivenProgression([0, 0], [0.32, 0.72], [0, 1], [1, 1], step)[0];
60 }
61 const duration = (shouldComplete) ? computeDuration(step * height, velocity) : computeDuration((1 - step) * height, velocity);
62 isOpen = shouldComplete;
63 gesture.enable(false);
64 animation
65 .onFinish(() => {
66 if (!shouldComplete) {
67 gesture.enable(true);
68 }
69 })
70 .progressEnd((shouldComplete) ? 1 : 0, newStepValue, duration);
71 if (shouldComplete) {
72 onDismiss();
73 }
74 };
75 const gesture = index.createGesture({
76 el,
77 gestureName: 'modalSwipeToClose',
78 gesturePriority: 40,
79 direction: 'y',
80 threshold: 10,
81 canStart,
82 onStart,
83 onMove,
84 onEnd
85 });
86 return gesture;
87};
88const computeDuration = (remaining, velocity) => {
89 return helpers.clamp(400, remaining / Math.abs(velocity * 1.1), 500);
90};
91
92/**
93 * iOS Modal Enter Animation for the Card presentation style
94 */
95const iosEnterAnimation = (baseEl, presentingEl) => {
96 const backdropAnimation = animation.createAnimation()
97 .addElement(baseEl.querySelector('ion-backdrop'))
98 .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
99 .beforeStyles({
100 'pointer-events': 'none'
101 })
102 .afterClearStyles(['pointer-events']);
103 const wrapperAnimation = animation.createAnimation()
104 .addElement(baseEl.querySelectorAll('.modal-wrapper, .modal-shadow'))
105 .beforeStyles({ 'opacity': 1 })
106 .fromTo('transform', 'translateY(100vh)', 'translateY(0vh)');
107 const baseAnimation = animation.createAnimation()
108 .addElement(baseEl)
109 .easing('cubic-bezier(0.32,0.72,0,1)')
110 .duration(500)
111 .addAnimation(wrapperAnimation);
112 if (presentingEl) {
113 const isMobile = window.innerWidth < 768;
114 const hasCardModal = (presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined);
115 const presentingAnimation = animation.createAnimation()
116 .beforeStyles({
117 'transform': 'translateY(0)',
118 'transform-origin': 'top center',
119 'overflow': 'hidden'
120 });
121 const bodyEl = document.body;
122 if (isMobile) {
123 /**
124 * Fallback for browsers that does not support `max()` (ex: Firefox)
125 * No need to worry about statusbar padding since engines like Gecko
126 * are not used as the engine for standlone Cordova/Capacitor apps
127 */
128 const transformOffset = (!CSS.supports('width', 'max(0px, 1px)')) ? '30px' : 'max(30px, var(--ion-safe-area-top))';
129 const modalTransform = hasCardModal ? '-10px' : transformOffset;
130 const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
131 const finalTransform = `translateY(${modalTransform}) scale(${toPresentingScale})`;
132 presentingAnimation
133 .afterStyles({
134 'transform': finalTransform
135 })
136 .beforeAddWrite(() => bodyEl.style.setProperty('background-color', 'black'))
137 .addElement(presentingEl)
138 .keyframes([
139 { offset: 0, filter: 'contrast(1)', transform: 'translateY(0px) scale(1)', borderRadius: '0px' },
140 { offset: 1, filter: 'contrast(0.85)', transform: finalTransform, borderRadius: '10px 10px 0 0' }
141 ]);
142 baseAnimation.addAnimation(presentingAnimation);
143 }
144 else {
145 baseAnimation.addAnimation(backdropAnimation);
146 if (!hasCardModal) {
147 wrapperAnimation.fromTo('opacity', '0', '1');
148 }
149 else {
150 const toPresentingScale = (hasCardModal) ? SwipeToCloseDefaults.MIN_PRESENTING_SCALE : 1;
151 const finalTransform = `translateY(-10px) scale(${toPresentingScale})`;
152 presentingAnimation
153 .afterStyles({
154 'transform': finalTransform
155 })
156 .addElement(presentingEl.querySelector('.modal-wrapper'))
157 .keyframes([
158 { offset: 0, filter: 'contrast(1)', transform: 'translateY(0) scale(1)' },
159 { offset: 1, filter: 'contrast(0.85)', transform: finalTransform }
160 ]);
161 const shadowAnimation = animation.createAnimation()
162 .afterStyles({
163 'transform': finalTransform
164 })
165 .addElement(presentingEl.querySelector('.modal-shadow'))
166 .keyframes([
167 { offset: 0, opacity: '1', transform: 'translateY(0) scale(1)' },
168 { offset: 1, opacity: '0', transform: finalTransform }
169 ]);
170 baseAnimation.addAnimation([presentingAnimation, shadowAnimation]);
171 }
172 }
173 }
174 else {
175 baseAnimation.addAnimation(backdropAnimation);
176 }
177 return baseAnimation;
178};
179
180/**
181 * iOS Modal Leave Animation
182 */
183const iosLeaveAnimation = (baseEl, presentingEl, duration = 500) => {
184 const backdropAnimation = animation.createAnimation()
185 .addElement(baseEl.querySelector('ion-backdrop'))
186 .fromTo('opacity', 'var(--backdrop-opacity)', 0.0);
187 const wrapperAnimation = animation.createAnimation()
188 .addElement(baseEl.querySelectorAll('.modal-wrapper, .modal-shadow'))
189 .beforeStyles({ 'opacity': 1 })
190 .fromTo('transform', 'translateY(0vh)', 'translateY(100vh)');
191 const baseAnimation = animation.createAnimation()
192 .addElement(baseEl)
193 .easing('cubic-bezier(0.32,0.72,0,1)')
194 .duration(duration)
195 .addAnimation(wrapperAnimation);
196 if (presentingEl) {
197 const isMobile = window.innerWidth < 768;
198 const hasCardModal = (presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined);
199 const presentingAnimation = animation.createAnimation()
200 .beforeClearStyles(['transform'])
201 .afterClearStyles(['transform'])
202 .onFinish(currentStep => {
203 // only reset background color if this is the last card-style modal
204 if (currentStep !== 1) {
205 return;
206 }
207 presentingEl.style.setProperty('overflow', '');
208 const numModals = Array.from(bodyEl.querySelectorAll('ion-modal')).filter(m => m.presentingElement !== undefined).length;
209 if (numModals <= 1) {
210 bodyEl.style.setProperty('background-color', '');
211 }
212 });
213 const bodyEl = document.body;
214 if (isMobile) {
215 const transformOffset = (!CSS.supports('width', 'max(0px, 1px)')) ? '30px' : 'max(30px, var(--ion-safe-area-top))';
216 const modalTransform = hasCardModal ? '-10px' : transformOffset;
217 const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
218 const finalTransform = `translateY(${modalTransform}) scale(${toPresentingScale})`;
219 presentingAnimation
220 .addElement(presentingEl)
221 .keyframes([
222 { offset: 0, filter: 'contrast(0.85)', transform: finalTransform, borderRadius: '10px 10px 0 0' },
223 { offset: 1, filter: 'contrast(1)', transform: 'translateY(0px) scale(1)', borderRadius: '0px' }
224 ]);
225 baseAnimation.addAnimation(presentingAnimation);
226 }
227 else {
228 baseAnimation.addAnimation(backdropAnimation);
229 if (!hasCardModal) {
230 wrapperAnimation.fromTo('opacity', '1', '0');
231 }
232 else {
233 const toPresentingScale = (hasCardModal) ? SwipeToCloseDefaults.MIN_PRESENTING_SCALE : 1;
234 const finalTransform = `translateY(-10px) scale(${toPresentingScale})`;
235 presentingAnimation
236 .addElement(presentingEl.querySelector('.modal-wrapper'))
237 .afterStyles({
238 'transform': 'translate3d(0, 0, 0)'
239 })
240 .keyframes([
241 { offset: 0, filter: 'contrast(0.85)', transform: finalTransform },
242 { offset: 1, filter: 'contrast(1)', transform: 'translateY(0) scale(1)' }
243 ]);
244 const shadowAnimation = animation.createAnimation()
245 .addElement(presentingEl.querySelector('.modal-shadow'))
246 .afterStyles({
247 'transform': 'translateY(0) scale(1)'
248 })
249 .keyframes([
250 { offset: 0, opacity: '0', transform: finalTransform },
251 { offset: 1, opacity: '1', transform: 'translateY(0) scale(1)' }
252 ]);
253 baseAnimation.addAnimation([presentingAnimation, shadowAnimation]);
254 }
255 }
256 }
257 else {
258 baseAnimation.addAnimation(backdropAnimation);
259 }
260 return baseAnimation;
261};
262
263/**
264 * Md Modal Enter Animation
265 */
266const mdEnterAnimation = (baseEl) => {
267 const baseAnimation = animation.createAnimation();
268 const backdropAnimation = animation.createAnimation();
269 const wrapperAnimation = animation.createAnimation();
270 backdropAnimation
271 .addElement(baseEl.querySelector('ion-backdrop'))
272 .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
273 .beforeStyles({
274 'pointer-events': 'none'
275 })
276 .afterClearStyles(['pointer-events']);
277 wrapperAnimation
278 .addElement(baseEl.querySelector('.modal-wrapper'))
279 .keyframes([
280 { offset: 0, opacity: 0.01, transform: 'translateY(40px)' },
281 { offset: 1, opacity: 1, transform: 'translateY(0px)' }
282 ]);
283 return baseAnimation
284 .addElement(baseEl)
285 .easing('cubic-bezier(0.36,0.66,0.04,1)')
286 .duration(280)
287 .addAnimation([backdropAnimation, wrapperAnimation]);
288};
289
290/**
291 * Md Modal Leave Animation
292 */
293const mdLeaveAnimation = (baseEl) => {
294 const baseAnimation = animation.createAnimation();
295 const backdropAnimation = animation.createAnimation();
296 const wrapperAnimation = animation.createAnimation();
297 const wrapperEl = baseEl.querySelector('.modal-wrapper');
298 backdropAnimation
299 .addElement(baseEl.querySelector('ion-backdrop'))
300 .fromTo('opacity', 'var(--backdrop-opacity)', 0.0);
301 wrapperAnimation
302 .addElement(wrapperEl)
303 .keyframes([
304 { offset: 0, opacity: 0.99, transform: 'translateY(0px)' },
305 { offset: 1, opacity: 0, transform: 'translateY(40px)' }
306 ]);
307 return baseAnimation
308 .addElement(baseEl)
309 .easing('cubic-bezier(0.47,0,0.745,0.715)')
310 .duration(200)
311 .addAnimation([backdropAnimation, wrapperAnimation]);
312};
313
314const modalIosCss = ".sc-ion-modal-ios-h{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;contain:strict}.overlay-hidden.sc-ion-modal-ios-h{display:none}.modal-wrapper.sc-ion-modal-ios,.modal-shadow.sc-ion-modal-ios{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow.sc-ion-modal-ios{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){.sc-ion-modal-ios-h{--width:600px;--height:500px;--ion-safe-area-top:0px;--ion-safe-area-bottom:0px;--ion-safe-area-right:0px;--ion-safe-area-left:0px}}@media only screen and (min-width: 768px) and (min-height: 768px){.sc-ion-modal-ios-h{--width:600px;--height:600px}}.sc-ion-modal-ios-h:first-of-type{--backdrop-opacity:var(--ion-backdrop-opacity, 0.4)}@media only screen and (min-width: 768px) and (min-height: 600px){.sc-ion-modal-ios-h{--border-radius:10px}}.modal-wrapper.sc-ion-modal-ios{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0)}@media screen and (max-width: 767px){@supports (width: max(0px, 1px)){.modal-card.sc-ion-modal-ios-h{--height:calc(100% - max(30px, var(--ion-safe-area-top)) - 10px)}}@supports not (width: max(0px, 1px)){.modal-card.sc-ion-modal-ios-h{--height:calc(100% - 40px)}}.modal-card.sc-ion-modal-ios-h .modal-wrapper.sc-ion-modal-ios{border-top-left-radius:10px;border-top-right-radius:10px;border-bottom-right-radius:0;border-bottom-left-radius:0}[dir=rtl].sc-ion-modal-ios-h -no-combinator.modal-card.sc-ion-modal-ios-h .modal-wrapper.sc-ion-modal-ios,[dir=rtl] .sc-ion-modal-ios-h -no-combinator.modal-card.sc-ion-modal-ios-h .modal-wrapper.sc-ion-modal-ios,[dir=rtl].modal-card.sc-ion-modal-ios-h .modal-wrapper.sc-ion-modal-ios,[dir=rtl] .modal-card.sc-ion-modal-ios-h .modal-wrapper.sc-ion-modal-ios{border-top-left-radius:10px;border-top-right-radius:10px;border-bottom-right-radius:0;border-bottom-left-radius:0}.modal-card.sc-ion-modal-ios-h{--backdrop-opacity:0;--width:100%;-ms-flex-align:end;align-items:flex-end}.modal-card.sc-ion-modal-ios-h .modal-shadow.sc-ion-modal-ios{display:none}.modal-card.sc-ion-modal-ios-h ion-backdrop.sc-ion-modal-ios{pointer-events:none}}@media screen and (min-width: 768px){.modal-card.sc-ion-modal-ios-h{--width:calc(100% - 120px);--height:calc(100% - (120px + var(--ion-safe-area-top) + var(--ion-safe-area-bottom)));--max-width:720px;--max-height:1000px}.modal-card.sc-ion-modal-ios-h{--backdrop-opacity:0;-webkit-transition:all 0.5s ease-in-out;transition:all 0.5s ease-in-out}.modal-card.sc-ion-modal-ios-h:first-of-type{--backdrop-opacity:0.18}.modal-card.sc-ion-modal-ios-h .modal-shadow.sc-ion-modal-ios{-webkit-box-shadow:0px 0px 30px 10px rgba(0, 0, 0, 0.1);box-shadow:0px 0px 30px 10px rgba(0, 0, 0, 0.1)}}";
315
316const modalMdCss = ".sc-ion-modal-md-h{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;contain:strict}.overlay-hidden.sc-ion-modal-md-h{display:none}.modal-wrapper.sc-ion-modal-md,.modal-shadow.sc-ion-modal-md{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow.sc-ion-modal-md{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){.sc-ion-modal-md-h{--width:600px;--height:500px;--ion-safe-area-top:0px;--ion-safe-area-bottom:0px;--ion-safe-area-right:0px;--ion-safe-area-left:0px}}@media only screen and (min-width: 768px) and (min-height: 768px){.sc-ion-modal-md-h{--width:600px;--height:600px}}.sc-ion-modal-md-h:first-of-type{--backdrop-opacity:var(--ion-backdrop-opacity, 0.32)}@media only screen and (min-width: 768px) and (min-height: 600px){.sc-ion-modal-md-h{--border-radius:2px}.sc-ion-modal-md-h:first-of-type{--box-shadow:0 28px 48px rgba(0, 0, 0, 0.4)}}.modal-wrapper.sc-ion-modal-md{-webkit-transform:translate3d(0, 40px, 0);transform:translate3d(0, 40px, 0);opacity:0.01}";
317
318const Modal = class {
319 constructor(hostRef) {
320 index$1.registerInstance(this, hostRef);
321 this.didPresent = index$1.createEvent(this, "ionModalDidPresent", 7);
322 this.willPresent = index$1.createEvent(this, "ionModalWillPresent", 7);
323 this.willDismiss = index$1.createEvent(this, "ionModalWillDismiss", 7);
324 this.didDismiss = index$1.createEvent(this, "ionModalDidDismiss", 7);
325 // Whether or not modal is being dismissed via gesture
326 this.gestureAnimationDismissing = false;
327 this.presented = false;
328 /**
329 * If `true`, the keyboard will be automatically dismissed when the overlay is presented.
330 */
331 this.keyboardClose = true;
332 /**
333 * If `true`, the modal will be dismissed when the backdrop is clicked.
334 */
335 this.backdropDismiss = true;
336 /**
337 * If `true`, a backdrop will be displayed behind the modal.
338 */
339 this.showBackdrop = true;
340 /**
341 * If `true`, the modal will animate.
342 */
343 this.animated = true;
344 /**
345 * If `true`, the modal can be swiped to dismiss. Only applies in iOS mode.
346 */
347 this.swipeToClose = false;
348 this.onBackdropTap = () => {
349 this.dismiss(undefined, overlays.BACKDROP);
350 };
351 this.onDismiss = (ev) => {
352 ev.stopPropagation();
353 ev.preventDefault();
354 this.dismiss();
355 };
356 this.onLifecycle = (modalEvent) => {
357 const el = this.usersElement;
358 const name = LIFECYCLE_MAP[modalEvent.type];
359 if (el && name) {
360 const ev = new CustomEvent(name, {
361 bubbles: false,
362 cancelable: false,
363 detail: modalEvent.detail
364 });
365 el.dispatchEvent(ev);
366 }
367 };
368 }
369 swipeToCloseChanged(enable) {
370 if (this.gesture) {
371 this.gesture.enable(enable);
372 }
373 else if (enable) {
374 this.initSwipeToClose();
375 }
376 }
377 connectedCallback() {
378 overlays.prepareOverlay(this.el);
379 }
380 /**
381 * Present the modal overlay after it has been created.
382 */
383 async present() {
384 if (this.presented) {
385 return;
386 }
387 const container = this.el.querySelector(`.modal-wrapper`);
388 if (!container) {
389 throw new Error('container is undefined');
390 }
391 const componentProps = Object.assign(Object.assign({}, this.componentProps), { modal: this.el });
392 this.usersElement = await frameworkDelegate.attachComponent(this.delegate, container, this.component, ['ion-page'], componentProps);
393 await index$2.deepReady(this.usersElement);
394 index$1.writeTask(() => this.el.classList.add('show-modal'));
395 await overlays.present(this, 'modalEnter', iosEnterAnimation, mdEnterAnimation, this.presentingElement);
396 if (this.swipeToClose) {
397 this.initSwipeToClose();
398 }
399 }
400 initSwipeToClose() {
401 if (ionicGlobal.getIonMode(this) !== 'ios') {
402 return;
403 }
404 // All of the elements needed for the swipe gesture
405 // should be in the DOM and referenced by now, except
406 // for the presenting el
407 const animationBuilder = this.leaveAnimation || ionicGlobal.config.get('modalLeave', iosLeaveAnimation);
408 const ani = this.animation = animationBuilder(this.el, this.presentingElement);
409 this.gesture = createSwipeToCloseGesture(this.el, ani, () => {
410 /**
411 * While the gesture animation is finishing
412 * it is possible for a user to tap the backdrop.
413 * This would result in the dismiss animation
414 * being played again. Typically this is avoided
415 * by setting `presented = false` on the overlay
416 * component; however, we cannot do that here as
417 * that would prevent the element from being
418 * removed from the DOM.
419 */
420 this.gestureAnimationDismissing = true;
421 this.animation.onFinish(async () => {
422 await this.dismiss(undefined, 'gesture');
423 this.gestureAnimationDismissing = false;
424 });
425 });
426 this.gesture.enable(true);
427 }
428 /**
429 * Dismiss the modal overlay after it has been presented.
430 *
431 * @param data Any data to emit in the dismiss events.
432 * @param role The role of the element that is dismissing the modal. For example, 'cancel' or 'backdrop'.
433 */
434 async dismiss(data, role) {
435 if (this.gestureAnimationDismissing && role !== 'gesture') {
436 return false;
437 }
438 const enteringAnimation = overlays.activeAnimations.get(this) || [];
439 const dismissed = await overlays.dismiss(this, data, role, 'modalLeave', iosLeaveAnimation, mdLeaveAnimation, this.presentingElement);
440 if (dismissed) {
441 await frameworkDelegate.detachComponent(this.delegate, this.usersElement);
442 if (this.animation) {
443 this.animation.destroy();
444 }
445 enteringAnimation.forEach(ani => ani.destroy());
446 }
447 this.animation = undefined;
448 return dismissed;
449 }
450 /**
451 * Returns a promise that resolves when the modal did dismiss.
452 */
453 onDidDismiss() {
454 return overlays.eventMethod(this.el, 'ionModalDidDismiss');
455 }
456 /**
457 * Returns a promise that resolves when the modal will dismiss.
458 */
459 onWillDismiss() {
460 return overlays.eventMethod(this.el, 'ionModalWillDismiss');
461 }
462 render() {
463 const mode = ionicGlobal.getIonMode(this);
464 return (index$1.h(index$1.Host, { "no-router": true, "aria-modal": "true", tabindex: "-1", class: Object.assign({ [mode]: true, [`modal-card`]: this.presentingElement !== undefined && mode === 'ios' }, theme.getClassMap(this.cssClass)), style: {
465 zIndex: `${20000 + this.overlayIndex}`,
466 }, onIonBackdropTap: this.onBackdropTap, onIonDismiss: this.onDismiss, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle }, index$1.h("ion-backdrop", { visible: this.showBackdrop, tappable: this.backdropDismiss }), mode === 'ios' && index$1.h("div", { class: "modal-shadow" }), index$1.h("div", { tabindex: "0" }), index$1.h("div", { role: "dialog", class: "modal-wrapper ion-overlay-wrapper" }), index$1.h("div", { tabindex: "0" })));
467 }
468 get el() { return index$1.getElement(this); }
469 static get watchers() { return {
470 "swipeToClose": ["swipeToCloseChanged"]
471 }; }
472};
473const LIFECYCLE_MAP = {
474 'ionModalDidPresent': 'ionViewDidEnter',
475 'ionModalWillPresent': 'ionViewWillEnter',
476 'ionModalWillDismiss': 'ionViewWillLeave',
477 'ionModalDidDismiss': 'ionViewDidLeave',
478};
479Modal.style = {
480 ios: modalIosCss,
481 md: modalMdCss
482};
483
484exports.ion_modal = Modal;