Skip to content

Commit

Permalink
fix(modal): allow swipe to close animation to be overridden (#20585)
Browse files Browse the repository at this point in the history
fixes #20577
  • Loading branch information
liamdebeasi committed Feb 24, 2020
1 parent 3a2d828 commit 8d3ce8d
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 8 deletions.
7 changes: 4 additions & 3 deletions core/src/components/modal/modal.tsx
@@ -1,5 +1,6 @@
import { Component, ComponentInterface, Element, Event, EventEmitter, Host, Method, Prop, h } from '@stencil/core';

import { config } from '../../global/config';
import { getIonMode } from '../../global/ionic-global';
import { Animation, AnimationBuilder, ComponentProps, ComponentRef, FrameworkDelegate, Gesture, OverlayEventDetail, OverlayInterface } from '../../interface';
import { attachComponent, detachComponent } from '../../utils/framework-delegate';
Expand Down Expand Up @@ -150,7 +151,8 @@ export class Modal implements ComponentInterface, OverlayInterface {
// All of the elements needed for the swipe gesture
// should be in the DOM and referenced by now, except
// for the presenting el
const ani = this.animation = iosLeaveAnimation(this.el, this.presentingElement);
const animationBuilder = this.leaveAnimation || config.get('modalLeave', iosLeaveAnimation);
const ani = this.animation = animationBuilder(this.el, this.presentingElement);
this.gesture = createSwipeToCloseGesture(
this.el,
ani,
Expand Down Expand Up @@ -188,9 +190,8 @@ export class Modal implements ComponentInterface, OverlayInterface {
return false;
}

const iosAni = (this.animation === undefined || (role === BACKDROP || role === undefined)) ? iosLeaveAnimation : undefined;
const enteringAnimation = activeAnimations.get(this) || [];
const dismissed = await dismiss(this, data, role, 'modalLeave', iosAni, mdLeaveAnimation, this.presentingElement);
const dismissed = await dismiss(this, data, role, 'modalLeave', iosLeaveAnimation, mdLeaveAnimation, this.presentingElement);

if (dismissed) {
await detachComponent(this.delegate, this.usersElement);
Expand Down
55 changes: 52 additions & 3 deletions core/src/components/modal/test/spec/index.html
Expand Up @@ -13,8 +13,9 @@
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
<script type="module">
import { modalController } from '../../../../dist/ionic/index.esm.js';
import { modalController, createAnimation } from '../../../../dist/ionic/index.esm.js';
window.modalController = modalController;
window.createAnimation = createAnimation;
</script>
<style>
#modal-header {
Expand All @@ -33,7 +34,7 @@
font-size: 11px;
color: #111;
}

ion-list ion-icon {
width: 100%;
height: 100%;
Expand All @@ -57,6 +58,11 @@
</ion-header>

<ion-content>
<ion-item>
<ion-label>Use Custom Animation</ion-label>
<ion-toggle></ion-toggle>
</ion-item>

<ion-list id="list"></ion-list>
</ion-content>
</div>
Expand All @@ -66,6 +72,44 @@
window.addEventListener("ionModalDidDismiss", function (e) { console.log('DidDismiss', e) })
window.addEventListener("ionModalWillDismiss", function (e) { console.log('WillDismiss', e) })

const enterAnimation = (baseEl) => {
const backdropAnimation = createAnimation()
.addElement(baseEl.querySelector('ion-backdrop'))
.fromTo('opacity', '0.01', '0.4');

const wrapperAnimation = createAnimation()
.addElement(baseEl.querySelector('.modal-wrapper'))
.keyframes([
{ offset: 0, opacity: '0', transform: 'scale(0)' },
{ offset: 1, opacity: '0.99', transform: 'scale(1)' }
]);

return createAnimation()
.addElement(baseEl)
.easing('ease-out')
.duration(500)
.addAnimation([backdropAnimation, wrapperAnimation]);
}

const leaveAnimation = (baseEl) => {
const backdropAnimation = createAnimation()
.addElement(baseEl.querySelector('ion-backdrop'))
.fromTo('opacity', '0.4', '0.01');

const wrapperAnimation = createAnimation()
.addElement(baseEl.querySelector('.modal-wrapper'))
.keyframes([
{ offset: 0, opacity: '0.99', transform: 'scale(1)' },
{ offset: 1, opacity: '0', transform: 'scale(0)' }
]);

return createAnimation()
.addElement(baseEl)
.easing('ease-out')
.duration(500)
.addAnimation([backdropAnimation, wrapperAnimation]);
}

const people = [
{
"name": "Miyah Myles",
Expand Down Expand Up @@ -450,11 +494,16 @@ <h3>${p.position}</h3>

presentModal(topModal);
});


const toggle = document.querySelector('ion-toggle');
// present the modal
const modalElement = await modalController.create({
presentingElement: presentingEl,
component: element,
swipeToClose: true
swipeToClose: true,
enterAnimation: (toggle.checked) ? enterAnimation : undefined,
leaveAnimation: (toggle.checked) ? leaveAnimation : undefined,
});
return modalElement;
}
Expand Down
5 changes: 3 additions & 2 deletions core/src/utils/overlays.ts
Expand Up @@ -142,7 +142,7 @@ export const dismiss = async (
data: any | undefined,
role: string | undefined,
name: keyof IonicConfig,
iosLeaveAnimation: AnimationBuilder | undefined,
iosLeaveAnimation: AnimationBuilder,
mdLeaveAnimation: AnimationBuilder,
opts?: any
): Promise<boolean> => {
Expand All @@ -158,7 +158,8 @@ export const dismiss = async (
? overlay.leaveAnimation
: config.get(name, overlay.mode === 'ios' ? iosLeaveAnimation : mdLeaveAnimation);

if (animationBuilder !== undefined) {
// If dismissed via gesture, no need to play leaving animation again
if (role !== 'gesture') {
await overlayAnimation(overlay, animationBuilder, overlay.el, opts);
}
overlay.didDismiss.emit({ data, role });
Expand Down

0 comments on commit 8d3ce8d

Please sign in to comment.