mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-20 12:29:55 +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 { Component, ComponentInterface, Element, Event, EventEmitter, Host, Method, Prop, h } from '@stencil/core';
|
||||||
|
|
||||||
|
import { config } from '../../global/config';
|
||||||
import { getIonMode } from '../../global/ionic-global';
|
import { getIonMode } from '../../global/ionic-global';
|
||||||
import { Animation, AnimationBuilder, ComponentProps, ComponentRef, FrameworkDelegate, Gesture, OverlayEventDetail, OverlayInterface } from '../../interface';
|
import { Animation, AnimationBuilder, ComponentProps, ComponentRef, FrameworkDelegate, Gesture, OverlayEventDetail, OverlayInterface } from '../../interface';
|
||||||
import { attachComponent, detachComponent } from '../../utils/framework-delegate';
|
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
|
// All of the elements needed for the swipe gesture
|
||||||
// should be in the DOM and referenced by now, except
|
// should be in the DOM and referenced by now, except
|
||||||
// for the presenting el
|
// 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.gesture = createSwipeToCloseGesture(
|
||||||
this.el,
|
this.el,
|
||||||
ani,
|
ani,
|
||||||
@ -188,9 +190,8 @@ export class Modal implements ComponentInterface, OverlayInterface {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const iosAni = (this.animation === undefined || (role === BACKDROP || role === undefined)) ? iosLeaveAnimation : undefined;
|
|
||||||
const enteringAnimation = activeAnimations.get(this) || [];
|
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) {
|
if (dismissed) {
|
||||||
await detachComponent(this.delegate, this.usersElement);
|
await detachComponent(this.delegate, this.usersElement);
|
||||||
|
@ -13,8 +13,9 @@
|
|||||||
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
|
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
|
||||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import { modalController } from '../../../../dist/ionic/index.esm.js';
|
import { modalController, createAnimation } from '../../../../dist/ionic/index.esm.js';
|
||||||
window.modalController = modalController;
|
window.modalController = modalController;
|
||||||
|
window.createAnimation = createAnimation;
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
#modal-header {
|
#modal-header {
|
||||||
@ -57,6 +58,11 @@
|
|||||||
</ion-header>
|
</ion-header>
|
||||||
|
|
||||||
<ion-content>
|
<ion-content>
|
||||||
|
<ion-item>
|
||||||
|
<ion-label>Use Custom Animation</ion-label>
|
||||||
|
<ion-toggle></ion-toggle>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
<ion-list id="list"></ion-list>
|
<ion-list id="list"></ion-list>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
</div>
|
</div>
|
||||||
@ -66,6 +72,44 @@
|
|||||||
window.addEventListener("ionModalDidDismiss", function (e) { console.log('DidDismiss', e) })
|
window.addEventListener("ionModalDidDismiss", function (e) { console.log('DidDismiss', e) })
|
||||||
window.addEventListener("ionModalWillDismiss", function (e) { console.log('WillDismiss', 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 = [
|
const people = [
|
||||||
{
|
{
|
||||||
"name": "Miyah Myles",
|
"name": "Miyah Myles",
|
||||||
@ -450,11 +494,16 @@
|
|||||||
|
|
||||||
presentModal(topModal);
|
presentModal(topModal);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const toggle = document.querySelector('ion-toggle');
|
||||||
// present the modal
|
// present the modal
|
||||||
const modalElement = await modalController.create({
|
const modalElement = await modalController.create({
|
||||||
presentingElement: presentingEl,
|
presentingElement: presentingEl,
|
||||||
component: element,
|
component: element,
|
||||||
swipeToClose: true
|
swipeToClose: true,
|
||||||
|
enterAnimation: (toggle.checked) ? enterAnimation : undefined,
|
||||||
|
leaveAnimation: (toggle.checked) ? leaveAnimation : undefined,
|
||||||
});
|
});
|
||||||
return modalElement;
|
return modalElement;
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@ export const dismiss = async (
|
|||||||
data: any | undefined,
|
data: any | undefined,
|
||||||
role: string | undefined,
|
role: string | undefined,
|
||||||
name: keyof IonicConfig,
|
name: keyof IonicConfig,
|
||||||
iosLeaveAnimation: AnimationBuilder | undefined,
|
iosLeaveAnimation: AnimationBuilder,
|
||||||
mdLeaveAnimation: AnimationBuilder,
|
mdLeaveAnimation: AnimationBuilder,
|
||||||
opts?: any
|
opts?: any
|
||||||
): Promise<boolean> => {
|
): Promise<boolean> => {
|
||||||
@ -158,7 +158,8 @@ export const dismiss = async (
|
|||||||
? overlay.leaveAnimation
|
? overlay.leaveAnimation
|
||||||
: config.get(name, overlay.mode === 'ios' ? iosLeaveAnimation : mdLeaveAnimation);
|
: 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);
|
await overlayAnimation(overlay, animationBuilder, overlay.el, opts);
|
||||||
}
|
}
|
||||||
overlay.didDismiss.emit({ data, role });
|
overlay.didDismiss.emit({ data, role });
|
||||||
|
Reference in New Issue
Block a user