diff --git a/packages/core/src/components/action-sheet/action-sheet.tsx b/packages/core/src/components/action-sheet/action-sheet.tsx index 7166508f79..dad7daf9d6 100644 --- a/packages/core/src/components/action-sheet/action-sheet.tsx +++ b/packages/core/src/components/action-sheet/action-sheet.tsx @@ -1,9 +1,9 @@ import { Component, CssClassMap, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core'; -import { Animation, AnimationBuilder, AnimationController, Config, DomController, OverlayDismissEvent, OverlayDismissEventDetail } from '../../index'; +import { Animation, AnimationBuilder, Config, DomController, OverlayDismissEvent, OverlayDismissEventDetail } from '../../index'; -import { domControllerAsync, isDef, playAnimationAsync } from '../../utils/helpers'; +import { domControllerAsync } from '../../utils/helpers'; import { createThemedClasses, getClassMap } from '../../utils/theme'; -import { OverlayInterface, BACKDROP } from '../../utils/overlays'; +import { OverlayInterface, BACKDROP, overlayAnimation } from '../../utils/overlays'; import iosEnterAnimation from './animations/ios.enter'; import iosLeaveAnimation from './animations/ios.leave'; @@ -23,15 +23,15 @@ import mdLeaveAnimation from './animations/md.leave'; }) export class ActionSheet implements OverlayInterface { + private presented = false; + mode: string; color: string; - - private presented = false; - private animation: Animation | null = null; + animation: Animation; @Element() private el: HTMLElement; - @Prop({ connect: 'ion-animation-controller' }) animationCtrl: AnimationController; + @Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement; @Prop({ context: 'config' }) config: Config; @Prop({ context: 'dom' }) dom: DomController; @Prop() overlayId: number; @@ -178,25 +178,8 @@ export class ActionSheet implements OverlayInterface { }); } - private playAnimation(animationBuilder: AnimationBuilder) { - if (this.animation) { - this.animation.destroy(); - this.animation = null; - } - - return this.animationCtrl.create(animationBuilder, this.el).then(animation => { - this.animation = animation; - // Check if prop animate is false or if the config for animate is defined/false - if (!this.willAnimate || (isDef(this.config.get('willAnimate')) && this.config.get('willAnimate') === false)) { - // 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.animation = null; - }); + private playAnimation(animationBuilder: AnimationBuilder): Promise { + return overlayAnimation(this, animationBuilder, this.willAnimate, this.el, undefined); } protected buttonClick(button: ActionSheetButton) { diff --git a/packages/core/src/components/alert/alert.tsx b/packages/core/src/components/alert/alert.tsx index 800b77b1db..bdf4fc56ab 100644 --- a/packages/core/src/components/alert/alert.tsx +++ b/packages/core/src/components/alert/alert.tsx @@ -1,8 +1,8 @@ import { Component, CssClassMap, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core'; -import { Animation, AnimationBuilder, AnimationController, Config, DomController, OverlayDismissEvent, OverlayDismissEventDetail } from '../../index'; -import { domControllerAsync, playAnimationAsync, autoFocus } from '../../utils/helpers'; +import { Animation, AnimationBuilder, Config, DomController, OverlayDismissEvent, OverlayDismissEventDetail } from '../../index'; +import { domControllerAsync, autoFocus } from '../../utils/helpers'; import { createThemedClasses, getClassMap } from '../../utils/theme'; -import { OverlayInterface, BACKDROP } from '../../utils/overlays'; +import { OverlayInterface, BACKDROP, overlayAnimation } from '../../utils/overlays'; import iosEnterAnimation from './animations/ios.enter'; import iosLeaveAnimation from './animations/ios.leave'; @@ -21,18 +21,19 @@ import mdLeaveAnimation from './animations/md.leave'; } }) export class Alert implements OverlayInterface { - mode: string; - color: string; private presented = false; - private animation: Animation | null = null; private activeId: string; private inputType: string | null = null; private hdrId: string; + animation: Animation; + mode: string; + color: string; + @Element() private el: HTMLElement; - @Prop({ connect: 'ion-animation-controller' }) animationCtrl: AnimationController; + @Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement; @Prop({ context: 'config' }) config: Config; @Prop({ context: 'dom' }) dom: DomController; @Prop() overlayId: number; @@ -264,25 +265,10 @@ export class Alert implements OverlayInterface { return values; } - private playAnimation(animationBuilder: AnimationBuilder) { - if (this.animation) { - this.animation.destroy(); - this.animation = null; - } - - return this.animationCtrl.create(animationBuilder, this.el).then(animation => { - this.animation = animation; - if (!this.willAnimate) { - animation.duration(0); - } - return playAnimationAsync(animation); - }).then(animation => { - animation.destroy(); - this.animation = null; - }); + private playAnimation(animationBuilder: AnimationBuilder): Promise { + return overlayAnimation(this, animationBuilder, this.willAnimate, this.el, undefined); } - private renderCheckbox(inputs: AlertInput[]) { if (inputs.length === 0) return null; diff --git a/packages/core/src/components/loading/loading.tsx b/packages/core/src/components/loading/loading.tsx index f45eaf1405..cc4f511707 100644 --- a/packages/core/src/components/loading/loading.tsx +++ b/packages/core/src/components/loading/loading.tsx @@ -1,13 +1,13 @@ import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core'; -import { Animation, AnimationBuilder, AnimationController, Config, DomController, OverlayDismissEvent, OverlayDismissEventDetail } from '../../index'; -import { domControllerAsync, playAnimationAsync } from '../../utils/helpers'; +import { Animation, AnimationBuilder, Config, DomController, OverlayDismissEvent, OverlayDismissEventDetail } from '../../index'; +import { domControllerAsync } from '../../utils/helpers'; import { createThemedClasses, getClassMap } from '../../utils/theme'; import iosEnterAnimation from './animations/ios.enter'; import iosLeaveAnimation from './animations/ios.leave'; import mdEnterAnimation from './animations/md.enter'; import mdLeaveAnimation from './animations/md.leave'; -import { OverlayInterface, BACKDROP } from '../../utils/overlays'; +import { OverlayInterface, BACKDROP, overlayAnimation } from '../../utils/overlays'; @Component({ tag: 'ion-loading', @@ -21,16 +21,17 @@ import { OverlayInterface, BACKDROP } from '../../utils/overlays'; }) export class Loading implements OverlayInterface { + + private presented = false; + private durationTimeout: any; + + animation: Animation; color: string; mode: string; - private presented = false; - private animation: Animation; - private durationTimeout: any; - @Element() private el: HTMLElement; - @Prop({ connect: 'ion-animation-controller' }) animationCtrl: AnimationController; + @Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement; @Prop({ context: 'config' }) config: Config; @Prop({ context: 'dom' }) dom: DomController; @Prop() overlayId: number; @@ -199,24 +200,8 @@ export class Loading implements OverlayInterface { }); } - private playAnimation(animationBuilder: AnimationBuilder) { - if (this.animation) { - this.animation.destroy(); - this.animation = null; - } - - return this.animationCtrl.create(animationBuilder, this.el).then(animation => { - this.animation = animation; - if (!this.willAnimate) { - // if the duration is 0, it won't actually animate I don't think - // TODO - validate this - animation.duration(0); - } - return playAnimationAsync(animation); - }).then(animation => { - animation.destroy(); - this.animation = null; - }); + private playAnimation(animationBuilder: AnimationBuilder): Promise { + return overlayAnimation(this, animationBuilder, this.willAnimate, this.el, undefined); } hostData() { diff --git a/packages/core/src/components/modal/modal.tsx b/packages/core/src/components/modal/modal.tsx index af50d63092..2b7510ce8f 100644 --- a/packages/core/src/components/modal/modal.tsx +++ b/packages/core/src/components/modal/modal.tsx @@ -1,10 +1,10 @@ import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core'; -import { Animation, AnimationBuilder, AnimationController, Config, DomController, FrameworkDelegate, OverlayDismissEvent, OverlayDismissEventDetail } from '../../index'; +import { Animation, AnimationBuilder, Config, DomController, FrameworkDelegate, OverlayDismissEvent, OverlayDismissEventDetail } from '../../index'; import { DomFrameworkDelegate } from '../../utils/dom-framework-delegate'; -import { domControllerAsync, playAnimationAsync } from '../../utils/helpers'; +import { domControllerAsync } from '../../utils/helpers'; import { createThemedClasses } from '../../utils/theme'; -import { OverlayInterface, BACKDROP } from '../../utils/overlays'; +import { OverlayInterface, BACKDROP, overlayAnimation } from '../../utils/overlays'; import iosEnterAnimation from './animations/ios.enter'; import iosLeaveAnimation from './animations/ios.leave'; @@ -25,14 +25,16 @@ import mdLeaveAnimation from './animations/md.leave'; export class Modal implements OverlayInterface { private presented = false; - private animation: Animation; private usersComponentElement: HTMLElement; + animation: Animation; + @Element() private el: HTMLElement; - @Prop({ connect: 'ion-animation-controller' }) animationCtrl: AnimationController; + @Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement; @Prop({ context: 'config' }) config: Config; @Prop({ context: 'dom' }) dom: DomController; + @Prop() overlayId: number; @Prop({ mutable: true }) delegate: FrameworkDelegate; @@ -208,22 +210,8 @@ export class Modal implements OverlayInterface { }); } - private playAnimation(animationBuilder: AnimationBuilder) { - if (this.animation) { - this.animation.destroy(); - this.animation = null; - } - - return this.animationCtrl.create(animationBuilder, this.el).then(animation => { - this.animation = animation; - if (!this.willAnimate) { - animation.duration(0); - } - return playAnimationAsync(animation); - }).then((animation) => { - animation.destroy(); - this.animation = null; - }); + private playAnimation(animationBuilder: AnimationBuilder): Promise { + return overlayAnimation(this, animationBuilder, this.willAnimate, this.el, undefined); } @Method() diff --git a/packages/core/src/components/picker/picker.tsx b/packages/core/src/components/picker/picker.tsx index 13faa3e11e..d70381e2b0 100644 --- a/packages/core/src/components/picker/picker.tsx +++ b/packages/core/src/components/picker/picker.tsx @@ -1,9 +1,9 @@ import { Component, CssClassMap, Element, Event, EventEmitter, Listen, Method, Prop, State } from '@stencil/core'; -import { Animation, AnimationBuilder, AnimationController, Config, DomController, OverlayDismissEvent, OverlayDismissEventDetail } from '../../index'; +import { Animation, AnimationBuilder, Config, DomController, OverlayDismissEvent, OverlayDismissEventDetail } from '../../index'; -import { domControllerAsync, playAnimationAsync } from '../../utils/helpers'; +import { domControllerAsync } from '../../utils/helpers'; import { getClassMap } from '../../utils/theme'; -import { OverlayInterface } from '../../utils/overlays'; +import { OverlayInterface, overlayAnimation } from '../../utils/overlays'; import iosEnterAnimation from './animations/ios.enter'; import iosLeaveAnimation from './animations/ios.leave'; @@ -21,16 +21,17 @@ import iosLeaveAnimation from './animations/ios.leave'; export class Picker implements OverlayInterface { private presented = false; - private animation: Animation; private durationTimeout: any; private mode: string; + animation: Animation; + @Element() private el: HTMLElement; @State() private showSpinner: boolean = null; @State() private spinner: string; - @Prop({ connect: 'ion-animation-controller' }) animationCtrl: AnimationController; + @Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement; @Prop({ context: 'config' }) config: Config; @Prop({ context: 'dom' }) dom: DomController; @Prop() overlayId: number; @@ -231,22 +232,8 @@ export class Picker implements OverlayInterface { return this.columns; } - private playAnimation(animationBuilder: AnimationBuilder) { - if (this.animation) { - this.animation.destroy(); - this.animation = null; - } - - return this.animationCtrl.create(animationBuilder, this.el).then(animation => { - this.animation = animation; - if (!this.willAnimate) { - animation.duration(0); - } - return playAnimationAsync(animation); - }).then(animation => { - animation.destroy(); - this.animation = null; - }) + private playAnimation(animationBuilder: AnimationBuilder): Promise { + return overlayAnimation(this, animationBuilder, this.willAnimate, this.el, undefined); } private buttonClick(button: PickerButton) { diff --git a/packages/core/src/components/popover/popover.tsx b/packages/core/src/components/popover/popover.tsx index 65031ff59b..6a47bf6d05 100644 --- a/packages/core/src/components/popover/popover.tsx +++ b/packages/core/src/components/popover/popover.tsx @@ -1,10 +1,10 @@ import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core'; -import { Animation, AnimationBuilder, AnimationController, Config, DomController, FrameworkDelegate, OverlayDismissEvent, OverlayDismissEventDetail } from '../../index'; +import { Animation, AnimationBuilder, Config, DomController, FrameworkDelegate, OverlayDismissEvent, OverlayDismissEventDetail } from '../../index'; import { DomFrameworkDelegate } from '../../utils/dom-framework-delegate'; -import { domControllerAsync, playAnimationAsync } from '../../utils/helpers'; +import { domControllerAsync } from '../../utils/helpers'; import { createThemedClasses } from '../../utils/theme'; -import { OverlayInterface, BACKDROP } from '../../utils/overlays'; +import { OverlayInterface, BACKDROP, overlayAnimation } from '../../utils/overlays'; import iosEnterAnimation from './animations/ios.enter'; import iosLeaveAnimation from './animations/ios.leave'; @@ -24,12 +24,13 @@ import mdLeaveAnimation from './animations/md.leave'; export class Popover implements OverlayInterface { private presented = false; - private animation: Animation; private usersComponentElement: HTMLElement; + animation: Animation; + @Element() private el: HTMLElement; - @Prop({ connect: 'ion-animation-controller' }) animationCtrl: AnimationController; + @Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement; @Prop({ context: 'config' }) config: Config; @Prop({ context: 'dom' }) dom: DomController; @Prop({ mutable: true }) delegate: FrameworkDelegate; @@ -224,22 +225,8 @@ export class Popover implements OverlayInterface { }); } - private playAnimation(animationBuilder: AnimationBuilder) { - if (this.animation) { - this.animation.destroy(); - this.animation = null; - } - - return this.animationCtrl.create(animationBuilder, this.el, this.ev).then((animation) => { - this.animation = animation; - if (!this.willAnimate) { - animation.duration(0); - } - return playAnimationAsync(animation); - }).then(animation => { - animation.destroy(); - this.animation = null; - }) + private playAnimation(animationBuilder: AnimationBuilder): Promise { + return overlayAnimation(this, animationBuilder, this.willAnimate, this.el, this.ev); } hostData() { diff --git a/packages/core/src/components/toast/toast.tsx b/packages/core/src/components/toast/toast.tsx index 1afa318639..372070a7d4 100644 --- a/packages/core/src/components/toast/toast.tsx +++ b/packages/core/src/components/toast/toast.tsx @@ -1,9 +1,9 @@ import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core'; -import { Animation, AnimationBuilder, AnimationController, Config, CssClassMap, DomController, OverlayDismissEvent, OverlayDismissEventDetail } from '../../index'; +import { Animation, AnimationBuilder, Config, CssClassMap, DomController, OverlayDismissEvent, OverlayDismissEventDetail } from '../../index'; -import { domControllerAsync, playAnimationAsync } from '../../utils/helpers'; +import { domControllerAsync } from '../../utils/helpers'; import { createThemedClasses, getClassMap } from '../../utils/theme'; -import { OverlayInterface } from '../../utils/overlays'; +import { OverlayInterface, overlayAnimation } from '../../utils/overlays'; import iosEnterAnimation from './animations/ios.enter'; import iosLeaveAnimation from './animations/ios.leave'; @@ -24,14 +24,14 @@ import mdLeaveAnimation from './animations/md.leave'; export class Toast implements OverlayInterface { private presented = false; - private animation: Animation | null; @Element() private el: HTMLElement; mode: string; color: string; + animation: Animation | null; - @Prop({ connect: 'ion-animation-controller' }) animationCtrl: AnimationController; + @Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement; @Prop({ context: 'config' }) config: Config; @Prop({ context: 'dom' }) dom: DomController; @Prop() overlayId: number; @@ -123,6 +123,22 @@ export class Toast implements OverlayInterface { */ @Event() ionToastDidUnload: EventEmitter; + componentDidLoad() { + this.ionToastDidLoad.emit(); + } + + componentDidUnload() { + this.ionToastDidUnload.emit(); + } + + @Listen('ionDismiss') + protected onDismiss(ev: UIEvent) { + ev.stopPropagation(); + ev.preventDefault(); + + this.dismiss(); + } + /** * Present the toast overlay after it has been created. */ @@ -169,38 +185,8 @@ export class Toast implements OverlayInterface { }); } - playAnimation(animationBuilder: AnimationBuilder) { - if (this.animation) { - this.animation.destroy(); - this.animation = null; - } - - return this.animationCtrl.create(animationBuilder, this.el, this.position).then(animation => { - this.animation = animation; - if (!this.willAnimate) { - animation.duration(0); - } - return playAnimationAsync(animation); - }).then((animation) => { - animation.destroy(); - this.animation = null; - }); - } - - componentDidLoad() { - this.ionToastDidLoad.emit(); - } - - componentDidUnload() { - this.ionToastDidUnload.emit(); - } - - @Listen('ionDismiss') - protected onDismiss(ev: UIEvent) { - ev.stopPropagation(); - ev.preventDefault(); - - this.dismiss(); + private playAnimation(animationBuilder: AnimationBuilder): Promise { + return overlayAnimation(this, animationBuilder, this.willAnimate, this.el, this.position); } private wrapperClass(): CssClassMap { diff --git a/packages/core/src/utils/overlays.ts b/packages/core/src/utils/overlays.ts index 89265443a6..634df43eb1 100644 --- a/packages/core/src/utils/overlays.ts +++ b/packages/core/src/utils/overlays.ts @@ -1,3 +1,5 @@ +import { AnimationBuilder, Animation } from ".."; +import { playAnimationAsync } from "./helpers"; let lastId = 1; @@ -56,8 +58,33 @@ export function removeLastOverlay(overlays: OverlayMap) { return toRemove ? toRemove.dismiss() : Promise.resolve(); } +export function overlayAnimation( + overlay: OverlayInterface, + animationBuilder: AnimationBuilder, + animate: boolean, + baseEl: HTMLElement, + opts: any +): Promise { + if (overlay.animation) { + overlay.animation.destroy(); + overlay.animation = null; + } + return overlay.animationCtrl.create(animationBuilder, baseEl, opts).then(animation => { + overlay.animation = animation; + if (!animate) { + animation.duration(0); + } + return playAnimationAsync(animation); + }).then((animation) => { + animation.destroy(); + overlay.animation = null; + }); +} + export interface OverlayInterface { overlayId: number; + animation: Animation; + animationCtrl: HTMLIonAnimationControllerElement; present(): Promise; dismiss(data?: any, role?: string): Promise;