mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-19 19:57:22 +08:00
fix(modal): allow swipe to close animation to be overridden (#20585)
fixes #20577
This commit is contained in:
@ -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';
|
||||
@ -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,
|
||||
@ -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);
|
||||
|
@ -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 {
|
||||
@ -33,7 +34,7 @@
|
||||
font-size: 11px;
|
||||
color: #111;
|
||||
}
|
||||
|
||||
|
||||
ion-list ion-icon {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@ -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>
|
||||
@ -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",
|
||||
@ -450,11 +494,16 @@
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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> => {
|
||||
@ -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 });
|
||||
|
Reference in New Issue
Block a user