diff --git a/core/api.txt b/core/api.txt index 66a07148e2..39d6a5355c 100644 --- a/core/api.txt +++ b/core/api.txt @@ -4,10 +4,10 @@ ion-action-sheet,prop,animated,boolean,true,false,false ion-action-sheet,prop,backdropDismiss,boolean,true,false,false ion-action-sheet,prop,buttons,(string | ActionSheetButton)[],[],false,false ion-action-sheet,prop,cssClass,string | string[] | undefined,undefined,false,false -ion-action-sheet,prop,enterAnimation,((Animation: Animation, baseEl: any, opts?: any) => Promise) | undefined,undefined,false,false +ion-action-sheet,prop,enterAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false ion-action-sheet,prop,header,string | undefined,undefined,false,false ion-action-sheet,prop,keyboardClose,boolean,true,false,false -ion-action-sheet,prop,leaveAnimation,((Animation: Animation, baseEl: any, opts?: any) => Promise) | undefined,undefined,false,false +ion-action-sheet,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false ion-action-sheet,prop,mode,"ios" | "md",undefined,false,false ion-action-sheet,prop,subHeader,string | undefined,undefined,false,false ion-action-sheet,prop,translucent,boolean,false,false,false @@ -41,11 +41,11 @@ ion-alert,prop,animated,boolean,true,false,false ion-alert,prop,backdropDismiss,boolean,true,false,false ion-alert,prop,buttons,(string | AlertButton)[],[],false,false ion-alert,prop,cssClass,string | string[] | undefined,undefined,false,false -ion-alert,prop,enterAnimation,((Animation: Animation, baseEl: any, opts?: any) => Promise) | undefined,undefined,false,false +ion-alert,prop,enterAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false ion-alert,prop,header,string | undefined,undefined,false,false ion-alert,prop,inputs,AlertInput[],[],false,false ion-alert,prop,keyboardClose,boolean,true,false,false -ion-alert,prop,leaveAnimation,((Animation: Animation, baseEl: any, opts?: any) => Promise) | undefined,undefined,false,false +ion-alert,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false ion-alert,prop,message,string | undefined,undefined,false,false ion-alert,prop,mode,"ios" | "md",undefined,false,false ion-alert,prop,subHeader,string | undefined,undefined,false,false @@ -575,9 +575,9 @@ ion-loading,prop,animated,boolean,true,false,false ion-loading,prop,backdropDismiss,boolean,false,false,false ion-loading,prop,cssClass,string | string[] | undefined,undefined,false,false ion-loading,prop,duration,number,0,false,false -ion-loading,prop,enterAnimation,((Animation: Animation, baseEl: any, opts?: any) => Promise) | undefined,undefined,false,false +ion-loading,prop,enterAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false ion-loading,prop,keyboardClose,boolean,true,false,false -ion-loading,prop,leaveAnimation,((Animation: Animation, baseEl: any, opts?: any) => Promise) | undefined,undefined,false,false +ion-loading,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false ion-loading,prop,message,string | undefined,undefined,false,false ion-loading,prop,mode,"ios" | "md",undefined,false,false ion-loading,prop,showBackdrop,boolean,true,false,false @@ -660,7 +660,7 @@ ion-menu-controller,method,isAnimating,isAnimating() => Promise ion-menu-controller,method,isEnabled,isEnabled(menu?: string | null | undefined) => Promise ion-menu-controller,method,isOpen,isOpen(menu?: string | null | undefined) => Promise ion-menu-controller,method,open,open(menu?: string | null | undefined) => Promise -ion-menu-controller,method,registerAnimation,registerAnimation(name: string, animation: AnimationBuilder | ((menu: MenuI) => IonicAnimation)) => Promise +ion-menu-controller,method,registerAnimation,registerAnimation(name: string, animation: AnimationBuilder) => Promise ion-menu-controller,method,swipeGesture,swipeGesture(enable: boolean, menu?: string | null | undefined) => Promise ion-menu-controller,method,toggle,toggle(menu?: string | null | undefined) => Promise @@ -674,9 +674,9 @@ ion-modal,prop,backdropDismiss,boolean,true,false,false ion-modal,prop,component,Function | HTMLElement | null | string,undefined,true,false ion-modal,prop,componentProps,undefined | { [key: string]: any; },undefined,false,false ion-modal,prop,cssClass,string | string[] | undefined,undefined,false,false -ion-modal,prop,enterAnimation,((Animation: Animation, baseEl: any, opts?: any) => Promise) | undefined,undefined,false,false +ion-modal,prop,enterAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false ion-modal,prop,keyboardClose,boolean,true,false,false -ion-modal,prop,leaveAnimation,((Animation: Animation, baseEl: any, opts?: any) => Promise) | undefined,undefined,false,false +ion-modal,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false ion-modal,prop,mode,"ios" | "md",undefined,false,false ion-modal,prop,showBackdrop,boolean,true,false,false ion-modal,method,dismiss,dismiss(data?: any, role?: string | undefined) => Promise @@ -707,7 +707,7 @@ ion-modal-controller,method,getTop,getTop() => Promise Promise) | undefined,undefined,false,false +ion-nav,prop,animation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false ion-nav,prop,root,Function | HTMLElement | ViewController | null | string | undefined,undefined,false,false ion-nav,prop,rootParams,undefined | { [key: string]: any; },undefined,false,false ion-nav,prop,swipeGesture,boolean | undefined,undefined,false,false @@ -744,9 +744,9 @@ ion-picker,prop,buttons,PickerButton[],[],false,false ion-picker,prop,columns,PickerColumn[],[],false,false ion-picker,prop,cssClass,string | string[] | undefined,undefined,false,false ion-picker,prop,duration,number,0,false,false -ion-picker,prop,enterAnimation,((Animation: Animation, baseEl: any, opts?: any) => Promise) | undefined,undefined,false,false +ion-picker,prop,enterAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false ion-picker,prop,keyboardClose,boolean,true,false,false -ion-picker,prop,leaveAnimation,((Animation: Animation, baseEl: any, opts?: any) => Promise) | undefined,undefined,false,false +ion-picker,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false ion-picker,prop,mode,"ios" | "md",undefined,false,false ion-picker,prop,showBackdrop,boolean,true,false,false ion-picker,method,dismiss,dismiss(data?: any, role?: string | undefined) => Promise @@ -783,10 +783,10 @@ ion-popover,prop,backdropDismiss,boolean,true,false,false ion-popover,prop,component,Function | HTMLElement | null | string,undefined,true,false ion-popover,prop,componentProps,undefined | { [key: string]: any; },undefined,false,false ion-popover,prop,cssClass,string | string[] | undefined,undefined,false,false -ion-popover,prop,enterAnimation,((Animation: Animation, baseEl: any, opts?: any) => Promise) | undefined,undefined,false,false +ion-popover,prop,enterAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false ion-popover,prop,event,any,undefined,false,false ion-popover,prop,keyboardClose,boolean,true,false,false -ion-popover,prop,leaveAnimation,((Animation: Animation, baseEl: any, opts?: any) => Promise) | undefined,undefined,false,false +ion-popover,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false ion-popover,prop,mode,"ios" | "md",undefined,false,false ion-popover,prop,showBackdrop,boolean,true,false,false ion-popover,prop,translucent,boolean,false,false,false @@ -933,7 +933,7 @@ ion-router-link,css-prop,--color ion-router-outlet,shadow ion-router-outlet,prop,animated,boolean,true,false,false -ion-router-outlet,prop,animation,((Animation: Animation, baseEl: any, opts?: any) => Promise) | undefined,undefined,false,false +ion-router-outlet,prop,animation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false ion-router-outlet,prop,mode,"ios" | "md",getIonMode(this),false,false ion-row,shadow @@ -1203,10 +1203,10 @@ ion-toast,prop,buttons,(string | ToastButton)[] | undefined,undefined,false,fals ion-toast,prop,color,string | undefined,undefined,false,false ion-toast,prop,cssClass,string | string[] | undefined,undefined,false,false ion-toast,prop,duration,number,0,false,false -ion-toast,prop,enterAnimation,((Animation: Animation, baseEl: any, opts?: any) => Promise) | undefined,undefined,false,false +ion-toast,prop,enterAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false ion-toast,prop,header,string | undefined,undefined,false,false ion-toast,prop,keyboardClose,boolean,false,false,false -ion-toast,prop,leaveAnimation,((Animation: Animation, baseEl: any, opts?: any) => Promise) | undefined,undefined,false,false +ion-toast,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false ion-toast,prop,message,string | undefined,undefined,false,false ion-toast,prop,mode,"ios" | "md",undefined,false,false ion-toast,prop,position,"bottom" | "middle" | "top",'bottom',false,false diff --git a/core/src/components.d.ts b/core/src/components.d.ts index 7cb1da1cd6..5276e6d601 100644 --- a/core/src/components.d.ts +++ b/core/src/components.d.ts @@ -25,13 +25,11 @@ import { HeaderFn, HeaderHeightFn, InputChangeEventDetail, - IonicAnimation, ItemHeightFn, ItemRenderFn, ItemReorderEventDetail, LoadingOptions, MenuChangeEventDetail, - MenuI, ModalOptions, NavComponent, NavOptions, @@ -1416,7 +1414,7 @@ export namespace Components { * @param name The name of the animation to register. * @param animation The animation function to register. */ - 'registerAnimation': (name: string, animation: AnimationBuilder | ((menu: MenuI) => IonicAnimation)) => Promise; + 'registerAnimation': (name: string, animation: AnimationBuilder) => Promise; /** * Enable or disable the ability to swipe open the menu. * @param enable If `true`, the menu swipe gesture should be enabled. diff --git a/core/src/components/action-sheet/animations/ios.enter.ts b/core/src/components/action-sheet/animations/ios.enter.ts index 9e4363869d..faef96ff8f 100644 --- a/core/src/components/action-sheet/animations/ios.enter.ts +++ b/core/src/components/action-sheet/animations/ios.enter.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * iOS Action Sheet Enter Animation */ -export const iosEnterAnimation = (baseEl: HTMLElement): IonicAnimation => { +export const iosEnterAnimation = (baseEl: HTMLElement): Animation => { const baseAnimation = createAnimation(); const backdropAnimation = createAnimation(); const wrapperAnimation = createAnimation(); diff --git a/core/src/components/action-sheet/animations/ios.leave.ts b/core/src/components/action-sheet/animations/ios.leave.ts index 414ebfebfc..25ac7d9254 100644 --- a/core/src/components/action-sheet/animations/ios.leave.ts +++ b/core/src/components/action-sheet/animations/ios.leave.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * iOS Action Sheet Leave Animation */ -export const iosLeaveAnimation = (baseEl: HTMLElement): IonicAnimation => { +export const iosLeaveAnimation = (baseEl: HTMLElement): Animation => { const baseAnimation = createAnimation(); const backdropAnimation = createAnimation(); const wrapperAnimation = createAnimation(); diff --git a/core/src/components/action-sheet/animations/md.enter.ts b/core/src/components/action-sheet/animations/md.enter.ts index 97288a10d3..6d69774407 100644 --- a/core/src/components/action-sheet/animations/md.enter.ts +++ b/core/src/components/action-sheet/animations/md.enter.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * MD Action Sheet Enter Animation */ -export const mdEnterAnimation = (baseEl: HTMLElement): IonicAnimation => { +export const mdEnterAnimation = (baseEl: HTMLElement): Animation => { const baseAnimation = createAnimation(); const backdropAnimation = createAnimation(); const wrapperAnimation = createAnimation(); diff --git a/core/src/components/action-sheet/animations/md.leave.ts b/core/src/components/action-sheet/animations/md.leave.ts index b3251b74f6..b1b6bcd182 100644 --- a/core/src/components/action-sheet/animations/md.leave.ts +++ b/core/src/components/action-sheet/animations/md.leave.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * MD Action Sheet Leave Animation */ -export const mdLeaveAnimation = (baseEl: HTMLElement): IonicAnimation => { +export const mdLeaveAnimation = (baseEl: HTMLElement): Animation => { const baseAnimation = createAnimation(); const backdropAnimation = createAnimation(); const wrapperAnimation = createAnimation(); diff --git a/core/src/components/action-sheet/readme.md b/core/src/components/action-sheet/readme.md index f916b63d01..fcfb07a4e4 100644 --- a/core/src/components/action-sheet/readme.md +++ b/core/src/components/action-sheet/readme.md @@ -249,19 +249,19 @@ export default { ## Properties -| Property | Attribute | Description | Type | Default | -| ----------------- | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ----------- | -| `animated` | `animated` | If `true`, the action sheet will animate. | `boolean` | `true` | -| `backdropDismiss` | `backdrop-dismiss` | If `true`, the action sheet will be dismissed when the backdrop is clicked. | `boolean` | `true` | -| `buttons` | -- | An array of buttons for the action sheet. | `(string \| ActionSheetButton)[]` | `[]` | -| `cssClass` | `css-class` | Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces. | `string \| string[] \| undefined` | `undefined` | -| `enterAnimation` | -- | Animation to use when the action sheet is presented. | `((Animation: Animation, baseEl: any, opts?: any) => Promise) \| undefined` | `undefined` | -| `header` | `header` | Title for the action sheet. | `string \| undefined` | `undefined` | -| `keyboardClose` | `keyboard-close` | If `true`, the keyboard will be automatically dismissed when the overlay is presented. | `boolean` | `true` | -| `leaveAnimation` | -- | Animation to use when the action sheet is dismissed. | `((Animation: Animation, baseEl: any, opts?: any) => Promise) \| undefined` | `undefined` | -| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` | -| `subHeader` | `sub-header` | Subtitle for the action sheet. | `string \| undefined` | `undefined` | -| `translucent` | `translucent` | If `true`, the action sheet will be translucent. Only applies when the mode is `"ios"` and the device supports [`backdrop-filter`](https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter#Browser_compatibility). | `boolean` | `false` | +| Property | Attribute | Description | Type | Default | +| ----------------- | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | ----------- | +| `animated` | `animated` | If `true`, the action sheet will animate. | `boolean` | `true` | +| `backdropDismiss` | `backdrop-dismiss` | If `true`, the action sheet will be dismissed when the backdrop is clicked. | `boolean` | `true` | +| `buttons` | -- | An array of buttons for the action sheet. | `(string \| ActionSheetButton)[]` | `[]` | +| `cssClass` | `css-class` | Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces. | `string \| string[] \| undefined` | `undefined` | +| `enterAnimation` | -- | Animation to use when the action sheet is presented. | `((baseEl: any, opts?: any) => Animation) \| undefined` | `undefined` | +| `header` | `header` | Title for the action sheet. | `string \| undefined` | `undefined` | +| `keyboardClose` | `keyboard-close` | If `true`, the keyboard will be automatically dismissed when the overlay is presented. | `boolean` | `true` | +| `leaveAnimation` | -- | Animation to use when the action sheet is dismissed. | `((baseEl: any, opts?: any) => Animation) \| undefined` | `undefined` | +| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` | +| `subHeader` | `sub-header` | Subtitle for the action sheet. | `string \| undefined` | `undefined` | +| `translucent` | `translucent` | If `true`, the action sheet will be translucent. Only applies when the mode is `"ios"` and the device supports [`backdrop-filter`](https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter#Browser_compatibility). | `boolean` | `false` | ## Events diff --git a/core/src/components/alert/animations/ios.enter.ts b/core/src/components/alert/animations/ios.enter.ts index fcddaf0a02..3abd5cf619 100644 --- a/core/src/components/alert/animations/ios.enter.ts +++ b/core/src/components/alert/animations/ios.enter.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * iOS Alert Enter Animation */ -export const iosEnterAnimation = (baseEl: HTMLElement): IonicAnimation => { +export const iosEnterAnimation = (baseEl: HTMLElement): Animation => { const baseAnimation = createAnimation(); const backdropAnimation = createAnimation(); const wrapperAnimation = createAnimation(); diff --git a/core/src/components/alert/animations/ios.leave.ts b/core/src/components/alert/animations/ios.leave.ts index 975370ee22..7c04453e25 100644 --- a/core/src/components/alert/animations/ios.leave.ts +++ b/core/src/components/alert/animations/ios.leave.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * iOS Alert Leave Animation */ -export const iosLeaveAnimation = (baseEl: HTMLElement): IonicAnimation => { +export const iosLeaveAnimation = (baseEl: HTMLElement): Animation => { const baseAnimation = createAnimation(); const backdropAnimation = createAnimation(); const wrapperAnimation = createAnimation(); diff --git a/core/src/components/alert/animations/md.enter.ts b/core/src/components/alert/animations/md.enter.ts index f682443f95..0e4e6eb612 100644 --- a/core/src/components/alert/animations/md.enter.ts +++ b/core/src/components/alert/animations/md.enter.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * Md Alert Enter Animation */ -export const mdEnterAnimation = (baseEl: HTMLElement): IonicAnimation => { +export const mdEnterAnimation = (baseEl: HTMLElement): Animation => { const baseAnimation = createAnimation(); const backdropAnimation = createAnimation(); const wrapperAnimation = createAnimation(); diff --git a/core/src/components/alert/animations/md.leave.ts b/core/src/components/alert/animations/md.leave.ts index 647fee397f..4d70b0abc0 100644 --- a/core/src/components/alert/animations/md.leave.ts +++ b/core/src/components/alert/animations/md.leave.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * Md Alert Leave Animation */ -export const mdLeaveAnimation = (baseEl: HTMLElement): IonicAnimation => { +export const mdLeaveAnimation = (baseEl: HTMLElement): Animation => { const baseAnimation = createAnimation(); const backdropAnimation = createAnimation(); const wrapperAnimation = createAnimation(); diff --git a/core/src/components/alert/readme.md b/core/src/components/alert/readme.md index 451a95aa09..d83064833b 100644 --- a/core/src/components/alert/readme.md +++ b/core/src/components/alert/readme.md @@ -1025,21 +1025,21 @@ export default { ## Properties -| Property | Attribute | Description | Type | Default | -| ----------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ----------- | -| `animated` | `animated` | If `true`, the alert will animate. | `boolean` | `true` | -| `backdropDismiss` | `backdrop-dismiss` | If `true`, the alert will be dismissed when the backdrop is clicked. | `boolean` | `true` | -| `buttons` | -- | Array of buttons to be added to the alert. | `(string \| AlertButton)[]` | `[]` | -| `cssClass` | `css-class` | Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces. | `string \| string[] \| undefined` | `undefined` | -| `enterAnimation` | -- | Animation to use when the alert is presented. | `((Animation: Animation, baseEl: any, opts?: any) => Promise) \| undefined` | `undefined` | -| `header` | `header` | The main title in the heading of the alert. | `string \| undefined` | `undefined` | -| `inputs` | -- | Array of input to show in the alert. | `AlertInput[]` | `[]` | -| `keyboardClose` | `keyboard-close` | If `true`, the keyboard will be automatically dismissed when the overlay is presented. | `boolean` | `true` | -| `leaveAnimation` | -- | Animation to use when the alert is dismissed. | `((Animation: Animation, baseEl: any, opts?: any) => Promise) \| undefined` | `undefined` | -| `message` | `message` | The main message to be displayed in the alert. `message` can accept either plaintext or HTML as a string. To display characters normally reserved for HTML, they must be escaped. For example `` would become `<Ionic>` For more information: [Security Documentation](https://ionicframework.com/docs/faq/security) | `string \| undefined` | `undefined` | -| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` | -| `subHeader` | `sub-header` | The subtitle in the heading of the alert. Displayed under the title. | `string \| undefined` | `undefined` | -| `translucent` | `translucent` | If `true`, the alert will be translucent. Only applies when the mode is `"ios"` and the device supports [`backdrop-filter`](https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter#Browser_compatibility). | `boolean` | `false` | +| Property | Attribute | Description | Type | Default | +| ----------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | ----------- | +| `animated` | `animated` | If `true`, the alert will animate. | `boolean` | `true` | +| `backdropDismiss` | `backdrop-dismiss` | If `true`, the alert will be dismissed when the backdrop is clicked. | `boolean` | `true` | +| `buttons` | -- | Array of buttons to be added to the alert. | `(string \| AlertButton)[]` | `[]` | +| `cssClass` | `css-class` | Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces. | `string \| string[] \| undefined` | `undefined` | +| `enterAnimation` | -- | Animation to use when the alert is presented. | `((baseEl: any, opts?: any) => Animation) \| undefined` | `undefined` | +| `header` | `header` | The main title in the heading of the alert. | `string \| undefined` | `undefined` | +| `inputs` | -- | Array of input to show in the alert. | `AlertInput[]` | `[]` | +| `keyboardClose` | `keyboard-close` | If `true`, the keyboard will be automatically dismissed when the overlay is presented. | `boolean` | `true` | +| `leaveAnimation` | -- | Animation to use when the alert is dismissed. | `((baseEl: any, opts?: any) => Animation) \| undefined` | `undefined` | +| `message` | `message` | The main message to be displayed in the alert. `message` can accept either plaintext or HTML as a string. To display characters normally reserved for HTML, they must be escaped. For example `` would become `<Ionic>` For more information: [Security Documentation](https://ionicframework.com/docs/faq/security) | `string \| undefined` | `undefined` | +| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` | +| `subHeader` | `sub-header` | The subtitle in the heading of the alert. Displayed under the title. | `string \| undefined` | `undefined` | +| `translucent` | `translucent` | If `true`, the alert will be translucent. Only applies when the mode is `"ios"` and the device supports [`backdrop-filter`](https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter#Browser_compatibility). | `boolean` | `false` | ## Events diff --git a/core/src/components/loading/animations/ios.enter.ts b/core/src/components/loading/animations/ios.enter.ts index 48a7b32d07..e5d3c335f5 100644 --- a/core/src/components/loading/animations/ios.enter.ts +++ b/core/src/components/loading/animations/ios.enter.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * iOS Loading Enter Animation */ -export const iosEnterAnimation = (baseEl: HTMLElement): IonicAnimation => { +export const iosEnterAnimation = (baseEl: HTMLElement): Animation => { const baseAnimation = createAnimation(); const backdropAnimation = createAnimation(); const wrapperAnimation = createAnimation(); diff --git a/core/src/components/loading/animations/ios.leave.ts b/core/src/components/loading/animations/ios.leave.ts index cb15a1a017..fbf56c7167 100644 --- a/core/src/components/loading/animations/ios.leave.ts +++ b/core/src/components/loading/animations/ios.leave.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * iOS Loading Leave Animation */ -export const iosLeaveAnimation = (baseEl: HTMLElement): IonicAnimation => { +export const iosLeaveAnimation = (baseEl: HTMLElement): Animation => { const baseAnimation = createAnimation(); const backdropAnimation = createAnimation(); const wrapperAnimation = createAnimation(); diff --git a/core/src/components/loading/animations/md.enter.ts b/core/src/components/loading/animations/md.enter.ts index 15c6190b60..9a6f45db21 100644 --- a/core/src/components/loading/animations/md.enter.ts +++ b/core/src/components/loading/animations/md.enter.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * Md Loading Enter Animation */ -export const mdEnterAnimation = (baseEl: HTMLElement): IonicAnimation => { +export const mdEnterAnimation = (baseEl: HTMLElement): Animation => { const baseAnimation = createAnimation(); const backdropAnimation = createAnimation(); const wrapperAnimation = createAnimation(); diff --git a/core/src/components/loading/animations/md.leave.ts b/core/src/components/loading/animations/md.leave.ts index c6f27ecf76..6e0ccf4402 100644 --- a/core/src/components/loading/animations/md.leave.ts +++ b/core/src/components/loading/animations/md.leave.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * Md Loading Leave Animation */ -export const mdLeaveAnimation = (baseEl: HTMLElement): IonicAnimation => { +export const mdLeaveAnimation = (baseEl: HTMLElement): Animation => { const baseAnimation = createAnimation(); const backdropAnimation = createAnimation(); const wrapperAnimation = createAnimation(); diff --git a/core/src/components/loading/readme.md b/core/src/components/loading/readme.md index 8d9ff55aab..91b976000d 100644 --- a/core/src/components/loading/readme.md +++ b/core/src/components/loading/readme.md @@ -177,9 +177,9 @@ export default { | `backdropDismiss` | `backdrop-dismiss` | If `true`, the loading indicator will be dismissed when the backdrop is clicked. | `boolean` | `false` | | `cssClass` | `css-class` | Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces. | `string \| string[] \| undefined` | `undefined` | | `duration` | `duration` | Number of milliseconds to wait before dismissing the loading indicator. | `number` | `0` | -| `enterAnimation` | -- | Animation to use when the loading indicator is presented. | `((Animation: Animation, baseEl: any, opts?: any) => Promise) \| undefined` | `undefined` | +| `enterAnimation` | -- | Animation to use when the loading indicator is presented. | `((baseEl: any, opts?: any) => Animation) \| undefined` | `undefined` | | `keyboardClose` | `keyboard-close` | If `true`, the keyboard will be automatically dismissed when the overlay is presented. | `boolean` | `true` | -| `leaveAnimation` | -- | Animation to use when the loading indicator is dismissed. | `((Animation: Animation, baseEl: any, opts?: any) => Promise) \| undefined` | `undefined` | +| `leaveAnimation` | -- | Animation to use when the loading indicator is dismissed. | `((baseEl: any, opts?: any) => Animation) \| undefined` | `undefined` | | `message` | `message` | Optional text content to display in the loading indicator. | `string \| undefined` | `undefined` | | `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` | | `showBackdrop` | `show-backdrop` | If `true`, a backdrop will be displayed behind the loading indicator. | `boolean` | `true` | diff --git a/core/src/components/menu-controller/menu-controller.ts b/core/src/components/menu-controller/menu-controller.ts index 2b30ebda59..7ac2e588f0 100644 --- a/core/src/components/menu-controller/menu-controller.ts +++ b/core/src/components/menu-controller/menu-controller.ts @@ -1,6 +1,6 @@ import { Build, Component, Method } from '@stencil/core'; -import { AnimationBuilder, IonicAnimation, MenuI } from '../../interface'; +import { AnimationBuilder } from '../../interface'; import { menuController } from '../../utils/menu-controller'; @Component({ @@ -149,7 +149,7 @@ export class MenuController { * @param animation The animation function to register. */ @Method() - async registerAnimation(name: string, animation: AnimationBuilder | ((menu: MenuI) => IonicAnimation)) { + async registerAnimation(name: string, animation: AnimationBuilder) { return menuController.registerAnimation(name, animation as any); } } diff --git a/core/src/components/menu-controller/readme.md b/core/src/components/menu-controller/readme.md index ca24a3c64b..9237e2d39c 100644 --- a/core/src/components/menu-controller/readme.md +++ b/core/src/components/menu-controller/readme.md @@ -116,7 +116,7 @@ Type: `Promise` -### `registerAnimation(name: string, animation: AnimationBuilder | ((menu: MenuI) => IonicAnimation)) => Promise` +### `registerAnimation(name: string, animation: AnimationBuilder) => Promise` Registers a new animation that can be used with any `ion-menu` by passing the name of the animation in its `type` property. diff --git a/core/src/components/menu/menu.tsx b/core/src/components/menu/menu.tsx index 9a0d2ebd5f..7c5722ea7f 100644 --- a/core/src/components/menu/menu.tsx +++ b/core/src/components/menu/menu.tsx @@ -2,7 +2,7 @@ import { Build, Component, ComponentInterface, Element, Event, EventEmitter, Hos import { config } from '../../global/config'; import { getIonMode } from '../../global/ionic-global'; -import { Gesture, GestureDetail, IonicAnimation, MenuChangeEventDetail, MenuI, Side } from '../../interface'; +import { Animation, Gesture, GestureDetail, MenuChangeEventDetail, MenuI, Side } from '../../interface'; import { Point, getTimeGivenProgression } from '../../utils/animation/cubic-bezier'; import { GESTURE_CONTROLLER } from '../../utils/gesture'; import { assert, isEndSide as isEnd } from '../../utils/helpers'; @@ -335,7 +335,7 @@ AFTER: private async startAnimation(shouldOpen: boolean, animated: boolean): Promise { const isReversed = !shouldOpen; - const ani = (this.animation as IonicAnimation)! + const ani = (this.animation as Animation)! .direction((isReversed) ? 'reverse' : 'normal') .easing((isReversed) ? this.easingReverse : this.easing); @@ -384,7 +384,7 @@ AFTER: } // the cloned animation should not use an easing curve during seek - (this.animation as IonicAnimation) + (this.animation as Animation) .direction((this._isOpen) ? 'reverse' : 'normal') .progressStart(true); } @@ -539,8 +539,10 @@ AFTER: assert(this._isOpen, 'menu cannot be closed'); this.isAnimating = true; - const ani = (this.animation as IonicAnimation)!.direction('reverse'); + + const ani = (this.animation as Animation)!.direction('reverse'); ani.play({ sync: true }); + this.afterAnimation(false); } diff --git a/core/src/components/modal/animations/ios.enter.ts b/core/src/components/modal/animations/ios.enter.ts index 3c6ce85172..a2a58beed5 100644 --- a/core/src/components/modal/animations/ios.enter.ts +++ b/core/src/components/modal/animations/ios.enter.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * iOS Modal Enter Animation */ -export const iosEnterAnimation = (baseEl: HTMLElement): IonicAnimation => { +export const iosEnterAnimation = (baseEl: HTMLElement): Animation => { const baseAnimation = createAnimation(); const backdropAnimation = createAnimation(); const wrapperAnimation = createAnimation(); diff --git a/core/src/components/modal/animations/ios.leave.ts b/core/src/components/modal/animations/ios.leave.ts index 13a06a028d..ec4dd6a1fc 100644 --- a/core/src/components/modal/animations/ios.leave.ts +++ b/core/src/components/modal/animations/ios.leave.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * iOS Modal Leave Animation */ -export const iosLeaveAnimation = (baseEl: HTMLElement): IonicAnimation => { +export const iosLeaveAnimation = (baseEl: HTMLElement): Animation => { const baseAnimation = createAnimation(); const backdropAnimation = createAnimation(); const wrapperAnimation = createAnimation(); diff --git a/core/src/components/modal/animations/md.enter.ts b/core/src/components/modal/animations/md.enter.ts index f47a670b67..0f0b2b767d 100644 --- a/core/src/components/modal/animations/md.enter.ts +++ b/core/src/components/modal/animations/md.enter.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * Md Modal Enter Animation */ -export const mdEnterAnimation = (baseEl: HTMLElement): IonicAnimation => { +export const mdEnterAnimation = (baseEl: HTMLElement): Animation => { const baseAnimation = createAnimation(); const backdropAnimation = createAnimation(); const wrapperAnimation = createAnimation(); diff --git a/core/src/components/modal/animations/md.leave.ts b/core/src/components/modal/animations/md.leave.ts index 1d655eb909..8827912e81 100644 --- a/core/src/components/modal/animations/md.leave.ts +++ b/core/src/components/modal/animations/md.leave.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * Md Modal Leave Animation */ -export const mdLeaveAnimation = (baseEl: HTMLElement): IonicAnimation => { +export const mdLeaveAnimation = (baseEl: HTMLElement): Animation => { const baseAnimation = createAnimation(); const backdropAnimation = createAnimation(); const wrapperAnimation = createAnimation(); diff --git a/core/src/components/modal/readme.md b/core/src/components/modal/readme.md index 27798674df..dd636eb40a 100644 --- a/core/src/components/modal/readme.md +++ b/core/src/components/modal/readme.md @@ -326,18 +326,18 @@ export default { ## Properties -| Property | Attribute | Description | Type | Default | -| ------------------------ | ------------------ | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ----------- | -| `animated` | `animated` | If `true`, the modal will animate. | `boolean` | `true` | -| `backdropDismiss` | `backdrop-dismiss` | If `true`, the modal will be dismissed when the backdrop is clicked. | `boolean` | `true` | -| `component` _(required)_ | `component` | The component to display inside of the modal. | `Function \| HTMLElement \| null \| string` | `undefined` | -| `componentProps` | -- | The data to pass to the modal component. | `undefined \| { [key: string]: any; }` | `undefined` | -| `cssClass` | `css-class` | Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces. | `string \| string[] \| undefined` | `undefined` | -| `enterAnimation` | -- | Animation to use when the modal is presented. | `((Animation: Animation, baseEl: any, opts?: any) => Promise) \| undefined` | `undefined` | -| `keyboardClose` | `keyboard-close` | If `true`, the keyboard will be automatically dismissed when the overlay is presented. | `boolean` | `true` | -| `leaveAnimation` | -- | Animation to use when the modal is dismissed. | `((Animation: Animation, baseEl: any, opts?: any) => Promise) \| undefined` | `undefined` | -| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` | -| `showBackdrop` | `show-backdrop` | If `true`, a backdrop will be displayed behind the modal. | `boolean` | `true` | +| Property | Attribute | Description | Type | Default | +| ------------------------ | ------------------ | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | ----------- | +| `animated` | `animated` | If `true`, the modal will animate. | `boolean` | `true` | +| `backdropDismiss` | `backdrop-dismiss` | If `true`, the modal will be dismissed when the backdrop is clicked. | `boolean` | `true` | +| `component` _(required)_ | `component` | The component to display inside of the modal. | `Function \| HTMLElement \| null \| string` | `undefined` | +| `componentProps` | -- | The data to pass to the modal component. | `undefined \| { [key: string]: any; }` | `undefined` | +| `cssClass` | `css-class` | Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces. | `string \| string[] \| undefined` | `undefined` | +| `enterAnimation` | -- | Animation to use when the modal is presented. | `((baseEl: any, opts?: any) => Animation) \| undefined` | `undefined` | +| `keyboardClose` | `keyboard-close` | If `true`, the keyboard will be automatically dismissed when the overlay is presented. | `boolean` | `true` | +| `leaveAnimation` | -- | Animation to use when the modal is dismissed. | `((baseEl: any, opts?: any) => Animation) \| undefined` | `undefined` | +| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` | +| `showBackdrop` | `show-backdrop` | If `true`, a backdrop will be displayed behind the modal. | `boolean` | `true` | ## Events diff --git a/core/src/components/nav/nav.tsx b/core/src/components/nav/nav.tsx index abc22b16b3..b2bf8c1871 100644 --- a/core/src/components/nav/nav.tsx +++ b/core/src/components/nav/nav.tsx @@ -2,7 +2,7 @@ import { Build, Component, Element, Event, EventEmitter, Method, Prop, Watch, h import { config } from '../../global/config'; import { getIonMode } from '../../global/ionic-global'; -import { Animation, AnimationBuilder, ComponentProps, FrameworkDelegate, Gesture, IonicAnimation, NavComponent, NavOptions, NavOutlet, NavResult, RouteID, RouteWrite, RouterDirection, TransitionDoneFn, TransitionInstruction, ViewController } from '../../interface'; +import { Animation, AnimationBuilder, ComponentProps, FrameworkDelegate, Gesture, NavComponent, NavOptions, NavOutlet, NavResult, RouteID, RouteWrite, RouterDirection, TransitionDoneFn, TransitionInstruction, ViewController } from '../../interface'; import { Point, getTimeGivenProgression } from '../../utils/animation/cubic-bezier'; import { assert } from '../../utils/helpers'; import { TransitionOptions, lifecycle, setPageHidden, transition } from '../../utils/transition'; @@ -18,7 +18,7 @@ import { VIEW_STATE_ATTACHED, VIEW_STATE_DESTROYED, VIEW_STATE_NEW, convertToVie export class Nav implements NavOutlet { private transInstr: TransitionInstruction[] = []; - private sbAni?: Animation | IonicAnimation; + private sbAni?: Animation; private animationEnabled = true; private useRouter = false; private isTransitioning = false; @@ -825,7 +825,7 @@ export class Nav implements NavOutlet { const opts = ti.opts!; const progressCallback = opts.progressAnimation - ? (ani: IonicAnimation | Animation | undefined) => this.sbAni = ani + ? (ani: Animation | undefined) => this.sbAni = ani : undefined; const mode = getIonMode(this); const enteringEl = enteringView.element!; @@ -986,7 +986,7 @@ export class Nav implements NavOutlet { newStepValue += getTimeGivenProgression(new Point(0, 0), new Point(0.32, 0.72), new Point(0, 1), new Point(1, 1), stepValue); } - (this.sbAni as IonicAnimation).progressEnd(shouldComplete ? 1 : 0, newStepValue, dur); + (this.sbAni as Animation).progressEnd(shouldComplete ? 1 : 0, newStepValue, dur); } } diff --git a/core/src/components/nav/readme.md b/core/src/components/nav/readme.md index dad9afeb8a..ed0464e5e1 100644 --- a/core/src/components/nav/readme.md +++ b/core/src/components/nav/readme.md @@ -10,13 +10,13 @@ Unlike Router Outlet, Nav is not tied to a particular router. This means that if ## Properties -| Property | Attribute | Description | Type | Default | -| -------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ----------- | -| `animated` | `animated` | If `true`, the nav should animate the transition of components. | `boolean` | `true` | -| `animation` | -- | By default `ion-nav` animates transition between pages based in the mode (ios or material design). However, this property allows to create custom transition using `AnimateBuilder` functions. | `((Animation: Animation, baseEl: any, opts?: any) => Promise) \| undefined` | `undefined` | -| `root` | `root` | Root NavComponent to load | `Function \| HTMLElement \| ViewController \| null \| string \| undefined` | `undefined` | -| `rootParams` | -- | Any parameters for the root component | `undefined \| { [key: string]: any; }` | `undefined` | -| `swipeGesture` | `swipe-gesture` | If the nav component should allow for swipe-to-go-back. | `boolean \| undefined` | `undefined` | +| Property | Attribute | Description | Type | Default | +| -------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | ----------- | +| `animated` | `animated` | If `true`, the nav should animate the transition of components. | `boolean` | `true` | +| `animation` | -- | By default `ion-nav` animates transition between pages based in the mode (ios or material design). However, this property allows to create custom transition using `AnimateBuilder` functions. | `((baseEl: any, opts?: any) => Animation) \| undefined` | `undefined` | +| `root` | `root` | Root NavComponent to load | `Function \| HTMLElement \| ViewController \| null \| string \| undefined` | `undefined` | +| `rootParams` | -- | Any parameters for the root component | `undefined \| { [key: string]: any; }` | `undefined` | +| `swipeGesture` | `swipe-gesture` | If the nav component should allow for swipe-to-go-back. | `boolean \| undefined` | `undefined` | ## Events diff --git a/core/src/components/picker/animations/ios.enter.ts b/core/src/components/picker/animations/ios.enter.ts index 8c7f17b80e..d79166f6e1 100644 --- a/core/src/components/picker/animations/ios.enter.ts +++ b/core/src/components/picker/animations/ios.enter.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * iOS Picker Enter Animation */ -export const iosEnterAnimation = (baseEl: HTMLElement): IonicAnimation => { +export const iosEnterAnimation = (baseEl: HTMLElement): Animation => { const baseAnimation = createAnimation(); const backdropAnimation = createAnimation(); const wrapperAnimation = createAnimation(); diff --git a/core/src/components/picker/animations/ios.leave.ts b/core/src/components/picker/animations/ios.leave.ts index d9f388a854..929c20013a 100644 --- a/core/src/components/picker/animations/ios.leave.ts +++ b/core/src/components/picker/animations/ios.leave.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * iOS Picker Leave Animation */ -export const iosLeaveAnimation = (baseEl: HTMLElement): IonicAnimation => { +export const iosLeaveAnimation = (baseEl: HTMLElement): Animation => { const baseAnimation = createAnimation(); const backdropAnimation = createAnimation(); const wrapperAnimation = createAnimation(); diff --git a/core/src/components/picker/readme.md b/core/src/components/picker/readme.md index 69597a7495..392c6dbbb3 100644 --- a/core/src/components/picker/readme.md +++ b/core/src/components/picker/readme.md @@ -9,19 +9,19 @@ A Picker is a dialog that displays a row of buttons and columns underneath. It a ## Properties -| Property | Attribute | Description | Type | Default | -| ----------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ----------- | -| `animated` | `animated` | If `true`, the picker will animate. | `boolean` | `true` | -| `backdropDismiss` | `backdrop-dismiss` | If `true`, the picker will be dismissed when the backdrop is clicked. | `boolean` | `true` | -| `buttons` | -- | Array of buttons to be displayed at the top of the picker. | `PickerButton[]` | `[]` | -| `columns` | -- | Array of columns to be displayed in the picker. | `PickerColumn[]` | `[]` | -| `cssClass` | `css-class` | Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces. | `string \| string[] \| undefined` | `undefined` | -| `duration` | `duration` | Number of milliseconds to wait before dismissing the picker. | `number` | `0` | -| `enterAnimation` | -- | Animation to use when the picker is presented. | `((Animation: Animation, baseEl: any, opts?: any) => Promise) \| undefined` | `undefined` | -| `keyboardClose` | `keyboard-close` | If `true`, the keyboard will be automatically dismissed when the overlay is presented. | `boolean` | `true` | -| `leaveAnimation` | -- | Animation to use when the picker is dismissed. | `((Animation: Animation, baseEl: any, opts?: any) => Promise) \| undefined` | `undefined` | -| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` | -| `showBackdrop` | `show-backdrop` | If `true`, a backdrop will be displayed behind the picker. | `boolean` | `true` | +| Property | Attribute | Description | Type | Default | +| ----------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | ----------- | +| `animated` | `animated` | If `true`, the picker will animate. | `boolean` | `true` | +| `backdropDismiss` | `backdrop-dismiss` | If `true`, the picker will be dismissed when the backdrop is clicked. | `boolean` | `true` | +| `buttons` | -- | Array of buttons to be displayed at the top of the picker. | `PickerButton[]` | `[]` | +| `columns` | -- | Array of columns to be displayed in the picker. | `PickerColumn[]` | `[]` | +| `cssClass` | `css-class` | Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces. | `string \| string[] \| undefined` | `undefined` | +| `duration` | `duration` | Number of milliseconds to wait before dismissing the picker. | `number` | `0` | +| `enterAnimation` | -- | Animation to use when the picker is presented. | `((baseEl: any, opts?: any) => Animation) \| undefined` | `undefined` | +| `keyboardClose` | `keyboard-close` | If `true`, the keyboard will be automatically dismissed when the overlay is presented. | `boolean` | `true` | +| `leaveAnimation` | -- | Animation to use when the picker is dismissed. | `((baseEl: any, opts?: any) => Animation) \| undefined` | `undefined` | +| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` | +| `showBackdrop` | `show-backdrop` | If `true`, a backdrop will be displayed behind the picker. | `boolean` | `true` | ## Events diff --git a/core/src/components/popover/animations/ios.enter.ts b/core/src/components/popover/animations/ios.enter.ts index 21ffa93024..3c94cc3072 100644 --- a/core/src/components/popover/animations/ios.enter.ts +++ b/core/src/components/popover/animations/ios.enter.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * iOS Popover Enter Animation */ -export const iosEnterAnimation = (baseEl: HTMLElement, ev?: Event): IonicAnimation => { +export const iosEnterAnimation = (baseEl: HTMLElement, ev?: Event): Animation => { let originY = 'top'; let originX = 'left'; diff --git a/core/src/components/popover/animations/ios.leave.ts b/core/src/components/popover/animations/ios.leave.ts index 20cffbb893..a83bfddff1 100644 --- a/core/src/components/popover/animations/ios.leave.ts +++ b/core/src/components/popover/animations/ios.leave.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * iOS Popover Leave Animation */ -export const iosLeaveAnimation = (baseEl: HTMLElement): IonicAnimation => { +export const iosLeaveAnimation = (baseEl: HTMLElement): Animation => { const baseAnimation = createAnimation(); const backdropAnimation = createAnimation(); const wrapperAnimation = createAnimation(); diff --git a/core/src/components/popover/animations/md.enter.ts b/core/src/components/popover/animations/md.enter.ts index 308f7e8fc2..b553316e1b 100644 --- a/core/src/components/popover/animations/md.enter.ts +++ b/core/src/components/popover/animations/md.enter.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * Md Popover Enter Animation */ -export const mdEnterAnimation = (baseEl: HTMLElement, ev?: Event): IonicAnimation => { +export const mdEnterAnimation = (baseEl: HTMLElement, ev?: Event): Animation => { const POPOVER_MD_BODY_PADDING = 12; const doc = (baseEl.ownerDocument as any); const isRTL = doc.dir === 'rtl'; diff --git a/core/src/components/popover/animations/md.leave.ts b/core/src/components/popover/animations/md.leave.ts index 98c770eee0..8200b68a30 100644 --- a/core/src/components/popover/animations/md.leave.ts +++ b/core/src/components/popover/animations/md.leave.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * Md Popover Leave Animation */ -export const mdLeaveAnimation = (baseEl: HTMLElement): IonicAnimation => { +export const mdLeaveAnimation = (baseEl: HTMLElement): Animation => { const baseAnimation = createAnimation(); const backdropAnimation = createAnimation(); const wrapperAnimation = createAnimation(); diff --git a/core/src/components/popover/readme.md b/core/src/components/popover/readme.md index 21643d9ecd..e606360c5f 100644 --- a/core/src/components/popover/readme.md +++ b/core/src/components/popover/readme.md @@ -85,20 +85,20 @@ export const PopoverExample: React.FC = () => { ## Properties -| Property | Attribute | Description | Type | Default | -| ------------------------ | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ----------- | -| `animated` | `animated` | If `true`, the popover will animate. | `boolean` | `true` | -| `backdropDismiss` | `backdrop-dismiss` | If `true`, the popover will be dismissed when the backdrop is clicked. | `boolean` | `true` | -| `component` _(required)_ | `component` | The component to display inside of the popover. | `Function \| HTMLElement \| null \| string` | `undefined` | -| `componentProps` | -- | The data to pass to the popover component. | `undefined \| { [key: string]: any; }` | `undefined` | -| `cssClass` | `css-class` | Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces. | `string \| string[] \| undefined` | `undefined` | -| `enterAnimation` | -- | Animation to use when the popover is presented. | `((Animation: Animation, baseEl: any, opts?: any) => Promise) \| undefined` | `undefined` | -| `event` | `event` | The event to pass to the popover animation. | `any` | `undefined` | -| `keyboardClose` | `keyboard-close` | If `true`, the keyboard will be automatically dismissed when the overlay is presented. | `boolean` | `true` | -| `leaveAnimation` | -- | Animation to use when the popover is dismissed. | `((Animation: Animation, baseEl: any, opts?: any) => Promise) \| undefined` | `undefined` | -| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` | -| `showBackdrop` | `show-backdrop` | If `true`, a backdrop will be displayed behind the popover. | `boolean` | `true` | -| `translucent` | `translucent` | If `true`, the popover will be translucent. Only applies when the mode is `"ios"` and the device supports [`backdrop-filter`](https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter#Browser_compatibility). | `boolean` | `false` | +| Property | Attribute | Description | Type | Default | +| ------------------------ | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | ----------- | +| `animated` | `animated` | If `true`, the popover will animate. | `boolean` | `true` | +| `backdropDismiss` | `backdrop-dismiss` | If `true`, the popover will be dismissed when the backdrop is clicked. | `boolean` | `true` | +| `component` _(required)_ | `component` | The component to display inside of the popover. | `Function \| HTMLElement \| null \| string` | `undefined` | +| `componentProps` | -- | The data to pass to the popover component. | `undefined \| { [key: string]: any; }` | `undefined` | +| `cssClass` | `css-class` | Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces. | `string \| string[] \| undefined` | `undefined` | +| `enterAnimation` | -- | Animation to use when the popover is presented. | `((baseEl: any, opts?: any) => Animation) \| undefined` | `undefined` | +| `event` | `event` | The event to pass to the popover animation. | `any` | `undefined` | +| `keyboardClose` | `keyboard-close` | If `true`, the keyboard will be automatically dismissed when the overlay is presented. | `boolean` | `true` | +| `leaveAnimation` | -- | Animation to use when the popover is dismissed. | `((baseEl: any, opts?: any) => Animation) \| undefined` | `undefined` | +| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` | +| `showBackdrop` | `show-backdrop` | If `true`, a backdrop will be displayed behind the popover. | `boolean` | `true` | +| `translucent` | `translucent` | If `true`, the popover will be translucent. Only applies when the mode is `"ios"` and the device supports [`backdrop-filter`](https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter#Browser_compatibility). | `boolean` | `false` | ## Events diff --git a/core/src/components/router-outlet/readme.md b/core/src/components/router-outlet/readme.md index 6c7184f082..5270373873 100644 --- a/core/src/components/router-outlet/readme.md +++ b/core/src/components/router-outlet/readme.md @@ -30,11 +30,11 @@ For handling Router Guards, the older `ionViewCanEnter` and `ionViewCanLeave` ha ## Properties -| Property | Attribute | Description | Type | Default | -| ----------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ------------------ | -| `animated` | `animated` | If `true`, the router-outlet should animate the transition of components. | `boolean` | `true` | -| `animation` | -- | By default `ion-nav` animates transition between pages based in the mode (ios or material design). However, this property allows to create custom transition using `AnimateBuilder` functions. | `((Animation: Animation, baseEl: any, opts?: any) => Promise) \| undefined` | `undefined` | -| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `getIonMode(this)` | +| Property | Attribute | Description | Type | Default | +| ----------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | ------------------ | +| `animated` | `animated` | If `true`, the router-outlet should animate the transition of components. | `boolean` | `true` | +| `animation` | -- | By default `ion-nav` animates transition between pages based in the mode (ios or material design). However, this property allows to create custom transition using `AnimateBuilder` functions. | `((baseEl: any, opts?: any) => Animation) \| undefined` | `undefined` | +| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `getIonMode(this)` | ---------------------------------------------- diff --git a/core/src/components/router-outlet/route-outlet.tsx b/core/src/components/router-outlet/route-outlet.tsx index 9d93140327..48726012f5 100644 --- a/core/src/components/router-outlet/route-outlet.tsx +++ b/core/src/components/router-outlet/route-outlet.tsx @@ -2,7 +2,7 @@ import { Component, ComponentInterface, Element, Event, EventEmitter, Method, Pr import { config } from '../../global/config'; import { getIonMode } from '../../global/ionic-global'; -import { Animation, AnimationBuilder, ComponentProps, ComponentRef, FrameworkDelegate, Gesture, IonicAnimation, NavOutlet, RouteID, RouteWrite, RouterDirection, RouterOutletOptions, SwipeGestureHandler } from '../../interface'; +import { Animation, AnimationBuilder, ComponentProps, ComponentRef, FrameworkDelegate, Gesture, NavOutlet, RouteID, RouteWrite, RouterDirection, RouterOutletOptions, SwipeGestureHandler } from '../../interface'; import { Point, getTimeGivenProgression } from '../../utils/animation/cubic-bezier'; import { attachComponent, detachComponent } from '../../utils/framework-delegate'; import { transition } from '../../utils/transition'; @@ -18,7 +18,7 @@ export class RouterOutlet implements ComponentInterface, NavOutlet { private activeComponent: any; private waitPromise?: Promise; private gesture?: Gesture; - private ani?: IonicAnimation | Animation; + private ani?: Animation; private animationEnabled = true; @Element() el!: HTMLElement; @@ -96,7 +96,7 @@ export class RouterOutlet implements ComponentInterface, NavOutlet { newStepValue += getTimeGivenProgression(new Point(0, 0), new Point(0.32, 0.72), new Point(0, 1), new Point(1, 1), step); } - (this.ani as IonicAnimation).progressEnd(shouldComplete ? 1 : 0, newStepValue, dur); + (this.ani as Animation).progressEnd(shouldComplete ? 1 : 0, newStepValue, dur); } } diff --git a/core/src/components/toast/animations/ios.enter.ts b/core/src/components/toast/animations/ios.enter.ts index 3d5e93a06d..5af7d850f9 100644 --- a/core/src/components/toast/animations/ios.enter.ts +++ b/core/src/components/toast/animations/ios.enter.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * iOS Toast Enter Animation */ -export const iosEnterAnimation = (baseEl: ShadowRoot, position: string): IonicAnimation => { +export const iosEnterAnimation = (baseEl: ShadowRoot, position: string): Animation => { const baseAnimation = createAnimation(); const wrapperAnimation = createAnimation(); diff --git a/core/src/components/toast/animations/ios.leave.ts b/core/src/components/toast/animations/ios.leave.ts index 516edadf74..38a4d0a199 100644 --- a/core/src/components/toast/animations/ios.leave.ts +++ b/core/src/components/toast/animations/ios.leave.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * iOS Toast Leave Animation */ -export const iosLeaveAnimation = (baseEl: ShadowRoot, position: string): IonicAnimation => { +export const iosLeaveAnimation = (baseEl: ShadowRoot, position: string): Animation => { const baseAnimation = createAnimation(); const wrapperAnimation = createAnimation(); diff --git a/core/src/components/toast/animations/md.enter.ts b/core/src/components/toast/animations/md.enter.ts index 50210be35a..d2b696045d 100644 --- a/core/src/components/toast/animations/md.enter.ts +++ b/core/src/components/toast/animations/md.enter.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * MD Toast Enter Animation */ -export const mdEnterAnimation = (baseEl: ShadowRoot, position: string): IonicAnimation => { +export const mdEnterAnimation = (baseEl: ShadowRoot, position: string): Animation => { const baseAnimation = createAnimation(); const wrapperAnimation = createAnimation(); diff --git a/core/src/components/toast/animations/md.leave.ts b/core/src/components/toast/animations/md.leave.ts index 95f07b48b0..c3a1558f65 100644 --- a/core/src/components/toast/animations/md.leave.ts +++ b/core/src/components/toast/animations/md.leave.ts @@ -1,10 +1,10 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../../utils/animation/animation'; /** * md Toast Leave Animation */ -export const mdLeaveAnimation = (baseEl: ShadowRoot): IonicAnimation => { +export const mdLeaveAnimation = (baseEl: ShadowRoot): Animation => { const baseAnimation = createAnimation(); const wrapperAnimation = createAnimation(); diff --git a/core/src/components/toast/readme.md b/core/src/components/toast/readme.md index 44043085d4..69ec03b49e 100644 --- a/core/src/components/toast/readme.md +++ b/core/src/components/toast/readme.md @@ -165,21 +165,21 @@ export const ToastExample: React.FC = () => { ## Properties -| Property | Attribute | Description | Type | Default | -| ---------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ----------- | -| `animated` | `animated` | If `true`, the toast will animate. | `boolean` | `true` | -| `buttons` | -- | An array of buttons for the toast. | `(string \| ToastButton)[] \| undefined` | `undefined` | -| `color` | `color` | The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics). | `string \| undefined` | `undefined` | -| `cssClass` | `css-class` | Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces. | `string \| string[] \| undefined` | `undefined` | -| `duration` | `duration` | How many milliseconds to wait before hiding the toast. By default, it will show until `dismiss()` is called. | `number` | `0` | -| `enterAnimation` | -- | Animation to use when the toast is presented. | `((Animation: Animation, baseEl: any, opts?: any) => Promise) \| undefined` | `undefined` | -| `header` | `header` | Header to be shown in the toast. | `string \| undefined` | `undefined` | -| `keyboardClose` | `keyboard-close` | If `true`, the keyboard will be automatically dismissed when the overlay is presented. | `boolean` | `false` | -| `leaveAnimation` | -- | Animation to use when the toast is dismissed. | `((Animation: Animation, baseEl: any, opts?: any) => Promise) \| undefined` | `undefined` | -| `message` | `message` | Message to be shown in the toast. | `string \| undefined` | `undefined` | -| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` | -| `position` | `position` | The position of the toast on the screen. | `"bottom" \| "middle" \| "top"` | `'bottom'` | -| `translucent` | `translucent` | If `true`, the toast will be translucent. Only applies when the mode is `"ios"` and the device supports [`backdrop-filter`](https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter#Browser_compatibility). | `boolean` | `false` | +| Property | Attribute | Description | Type | Default | +| ---------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | ----------- | +| `animated` | `animated` | If `true`, the toast will animate. | `boolean` | `true` | +| `buttons` | -- | An array of buttons for the toast. | `(string \| ToastButton)[] \| undefined` | `undefined` | +| `color` | `color` | The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics). | `string \| undefined` | `undefined` | +| `cssClass` | `css-class` | Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces. | `string \| string[] \| undefined` | `undefined` | +| `duration` | `duration` | How many milliseconds to wait before hiding the toast. By default, it will show until `dismiss()` is called. | `number` | `0` | +| `enterAnimation` | -- | Animation to use when the toast is presented. | `((baseEl: any, opts?: any) => Animation) \| undefined` | `undefined` | +| `header` | `header` | Header to be shown in the toast. | `string \| undefined` | `undefined` | +| `keyboardClose` | `keyboard-close` | If `true`, the keyboard will be automatically dismissed when the overlay is presented. | `boolean` | `false` | +| `leaveAnimation` | -- | Animation to use when the toast is dismissed. | `((baseEl: any, opts?: any) => Animation) \| undefined` | `undefined` | +| `message` | `message` | Message to be shown in the toast. | `string \| undefined` | `undefined` | +| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` | +| `position` | `position` | The position of the toast on the screen. | `"bottom" \| "middle" \| "top"` | `'bottom'` | +| `translucent` | `translucent` | If `true`, the toast will be translucent. Only applies when the mode is `"ios"` and the device supports [`backdrop-filter`](https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter#Browser_compatibility). | `boolean` | `false` | ## Events diff --git a/core/src/interface.d.ts b/core/src/interface.d.ts index 80e4190cb3..dd3fedc029 100644 --- a/core/src/interface.d.ts +++ b/core/src/interface.d.ts @@ -31,8 +31,7 @@ export * from './components/toggle/toggle-interface'; export * from './components/virtual-scroll/virtual-scroll-interface'; // Types from utils -export { Animation as IonicAnimation } from './utils/animation/animation-interface'; -export * from './utils/animation/old-animation/animation-interface'; +export { Animation, AnimationBuilder } from './utils/animation/animation-interface'; export * from './utils/overlays-interface'; export * from './global/config'; export { Gesture, GestureDetail } from './utils/gesture'; diff --git a/core/src/utils/animation/animation-interface.ts b/core/src/utils/animation/animation-interface.ts index 7b7822d950..063c7a2eaa 100644 --- a/core/src/utils/animation/animation-interface.ts +++ b/core/src/utils/animation/animation-interface.ts @@ -239,3 +239,5 @@ export interface AnimationPlayOptions { export type AnimationPlayTo = 'start' | 'end'; export type AnimationDirection = 'normal' | 'reverse' | 'alternate' | 'alternate-reverse'; export type AnimationFill = 'auto' | 'none' | 'forwards' | 'backwards' | 'both'; + +export type AnimationBuilder = (baseEl: any, opts?: any) => Animation; diff --git a/core/src/utils/animation/old-animation/animation-interface.ts b/core/src/utils/animation/old-animation/animation-interface.ts deleted file mode 100644 index eb658cf80b..0000000000 --- a/core/src/utils/animation/old-animation/animation-interface.ts +++ /dev/null @@ -1,64 +0,0 @@ - -export interface AnimationController { - create(animationBuilder?: AnimationBuilder, baseEl?: any, opts?: any): Promise; -} - -export interface Animation { - new (): any; - parent: Animation | undefined; - hasChildren: boolean; - addElement(el: Node | Node[] | NodeList): Animation; - add(childAnimation: Animation): Animation; - duration(milliseconds: number): Animation; - easing(name: string): Animation; - easingReverse(name: string): Animation; - getDuration(opts?: PlayOptions): number; - getEasing(): string; - from(prop: string, val: any): Animation; - to(prop: string, val: any, clearProperyAfterTransition?: boolean): Animation; - fromTo(prop: string, fromVal: any, toVal: any, clearProperyAfterTransition?: boolean): Animation; - beforeAddClass(className: string): Animation; - beforeRemoveClass(className: string): Animation; - beforeStyles(styles: { [property: string]: any; }): Animation; - beforeClearStyles(propertyNames: string[]): Animation; - beforeAddRead(domReadFn: () => void): Animation; - beforeAddWrite(domWriteFn: () => void): Animation; - afterAddClass(className: string): Animation; - afterRemoveClass(className: string): Animation; - afterStyles(styles: { [property: string]: any; }): Animation; - afterClearStyles(propertyNames: string[]): Animation; - play(opts?: PlayOptions): void; - playSync(): void; - playAsync(opts?: PlayOptions): Promise; - reverse(shouldReverse?: boolean): Animation; - stop(stepValue?: number): void; - progressStart(): void; - progressStep(stepValue: number): void; - progressEnd(shouldComplete: boolean, currentStepValue: number, dur: number): void; - onFinish(callback: (animation?: Animation) => void, opts?: {oneTimeCallback?: boolean, clearExistingCallbacks?: boolean}): Animation; - destroy(): void; - isRoot(): boolean; - hasCompleted: boolean; -} - -export type AnimationBuilder = (Animation: Animation, baseEl: any, opts?: any) => Promise; - -export interface PlayOptions { - duration?: number; - promise?: boolean; -} - -export interface EffectProperty { - effectName: string; - trans: boolean; - wc?: string; - to?: EffectState; - from?: EffectState; - [state: string]: any; -} - -export interface EffectState { - val: any; - num: number; - effectUnit: string; -} diff --git a/core/src/utils/animation/old-animation/animator.ts b/core/src/utils/animation/old-animation/animator.ts deleted file mode 100644 index 72bdd6648d..0000000000 --- a/core/src/utils/animation/old-animation/animator.ts +++ /dev/null @@ -1,1253 +0,0 @@ -import { EffectProperty, EffectState, PlayOptions } from './animation-interface'; -import { transitionEnd } from './transition-end'; - -export const CSS_VALUE_REGEX = /(^-?\d*\.?\d*)(.*)/; -export const DURATION_MIN = 32; -export const TRANSITION_END_FALLBACK_PADDING_MS = 400; - -export const TRANSFORM_PROPS: {[key: string]: number} = { - 'translateX': 1, - 'translateY': 1, - 'translateZ': 1, - - 'scale': 1, - 'scaleX': 1, - 'scaleY': 1, - 'scaleZ': 1, - - 'rotate': 1, - 'rotateX': 1, - 'rotateY': 1, - 'rotateZ': 1, - - 'skewX': 1, - 'skewY': 1, - 'perspective': 1 -}; - -const win = typeof (window as any) !== 'undefined' ? window : {}; -const raf = (win as any).requestAnimationFrame - ? (win as Window).requestAnimationFrame.bind(win) - : (f: FrameRequestCallback) => f(Date.now()); - -export class Animator { - - private _afterAddClasses?: string[]; - private _afterRemoveClasses?: string[]; - private _afterStyles?: { [property: string]: any; }; - private _beforeAddClasses?: string[]; - private _beforeRemoveClasses?: string[]; - private _beforeStyles?: { [property: string]: any; }; - private _childAnimations?: Animator[]; - private _duration?: number; - private _easingName?: string; - private _elements?: HTMLElement[]; - private _fxProperties?: EffectProperty[]; - private _hasDur = false; - private _hasTweenEffect = false; - private _isAsync = false; - private _isReverse = false; - private _onFinishCallbacks?: ((a: Animator) => void)[]; - private _onFinishOneTimeCallbacks?: ((a: Animator) => void)[]; - private _readCallbacks?: (() => void)[]; - private _reversedEasingName?: string; - private _timerId?: any; - private _unregisterTrnsEnd?: (() => void); - private _writeCallbacks?: (() => void)[]; - private _destroyed = false; - - parent: Animator | undefined; - hasChildren = false; - isPlaying = false; - hasCompleted = false; - - addElement(el: Node | Node[] | NodeList | undefined | null): Animator { - if (el != null) { - if ((el as NodeList).length > 0) { - for (let i = 0; i < (el as NodeList).length; i++) { - this._addEl((el as any)[i]); - } - - } else { - this._addEl(el); - } - } - return this; - } - - /** - * NO DOM - */ - private _addEl(el: any) { - if (el.nodeType === 1) { - (this._elements = this._elements || []).push(el); - } - } - - /** - * Add a child animation to this animation. - */ - add(childAnimation: Animator): Animator { - childAnimation.parent = this; - this.hasChildren = true; - (this._childAnimations = this._childAnimations || []).push(childAnimation); - return this; - } - - /** - * Get the duration of this animation. If this animation does - * not have a duration, then it'll get the duration from its parent. - */ - getDuration(opts?: PlayOptions): number { - if (opts && opts.duration !== undefined) { - return opts.duration; - } else if (this._duration !== undefined) { - return this._duration; - } else if (this.parent) { - return this.parent.getDuration(); - } - return 0; - } - - /** - * Returns if the animation is a root one. - */ - isRoot(): boolean { - return !this.parent; - } - - /** - * Set the duration for this animation. - */ - duration(milliseconds: number): Animator { - this._duration = milliseconds; - return this; - } - - /** - * Get the easing of this animation. If this animation does - * not have an easing, then it'll get the easing from its parent. - */ - getEasing(): string | null { - if (this._isReverse && this._reversedEasingName !== undefined) { - return this._reversedEasingName; - } - return this._easingName !== undefined ? this._easingName : (this.parent && this.parent.getEasing()) || null; - } - - /** - * Set the easing for this animation. - */ - easing(name: string): Animator { - this._easingName = name; - return this; - } - - /** - * Set the easing for this reversed animation. - */ - easingReverse(name: string): Animator { - this._reversedEasingName = name; - return this; - } - - /** - * Add the "from" value for a specific property. - */ - from(prop: string, val: any): Animator { - this._addProp('from', prop, val); - return this; - } - - /** - * Add the "to" value for a specific property. - */ - to(prop: string, val: any, clearProperyAfterTransition = false): Animator { - const fx = this._addProp('to', prop, val); - - if (clearProperyAfterTransition) { - // if this effect is a transform then clear the transform effect - // otherwise just clear the actual property - this.afterClearStyles(fx.trans ? ['transform', '-webkit-transform'] : [prop]); - } - - return this; - } - - /** - * Shortcut to add both the "from" and "to" for the same property. - */ - fromTo(prop: string, fromVal: any, toVal: any, clearProperyAfterTransition?: boolean): Animator { - return this.from(prop, fromVal).to(prop, toVal, clearProperyAfterTransition); - } - - /** - * NO DOM - */ - - private _getProp(name: string): EffectProperty | undefined { - if (this._fxProperties) { - return this._fxProperties.find(prop => prop.effectName === name); - } - return undefined; - } - - private _addProp(state: string, prop: string, val: any): EffectProperty { - let fxProp = this._getProp(prop); - - if (!fxProp) { - // first time we've see this EffectProperty - const shouldTrans = (TRANSFORM_PROPS[prop] === 1); - fxProp = { - effectName: prop, - trans: shouldTrans, - - // add the will-change property for transforms or opacity - wc: (shouldTrans ? 'transform' : prop) - } as EffectProperty; - (this._fxProperties = this._fxProperties || []).push(fxProp); - } - - // add from/to EffectState to the EffectProperty - const fxState: EffectState = { - val, - num: 0, - effectUnit: '', - }; - fxProp[state] = fxState; - - if (typeof val === 'string' && val.indexOf(' ') < 0) { - const r = val.match(CSS_VALUE_REGEX); - if (r) { - const num = parseFloat(r[1]); - - if (!isNaN(num)) { - fxState.num = num; - } - fxState.effectUnit = (r[0] !== r[2] ? r[2] : ''); - } - } else if (typeof val === 'number') { - fxState.num = val; - } - - return fxProp; - } - - /** - * Add CSS class to this animation's elements - * before the animation begins. - */ - beforeAddClass(className: string): Animator { - (this._beforeAddClasses = this._beforeAddClasses || []).push(className); - return this; - } - - /** - * Remove CSS class from this animation's elements - * before the animation begins. - */ - beforeRemoveClass(className: string): Animator { - (this._beforeRemoveClasses = this._beforeRemoveClasses || []).push(className); - return this; - } - - /** - * Set CSS inline styles to this animation's elements - * before the animation begins. - */ - beforeStyles(styles: { [property: string]: any; }): Animator { - this._beforeStyles = styles; - return this; - } - - /** - * Clear CSS inline styles from this animation's elements - * before the animation begins. - */ - beforeClearStyles(propertyNames: string[]): Animator { - this._beforeStyles = this._beforeStyles || {}; - for (const prop of propertyNames) { - this._beforeStyles[prop] = ''; - } - return this; - } - - /** - * Add a function which contains DOM reads, which will run - * before the animation begins. - */ - beforeAddRead(domReadFn: () => void): Animator { - (this._readCallbacks = this._readCallbacks || []).push(domReadFn); - return this; - } - - /** - * Add a function which contains DOM writes, which will run - * before the animation begins. - */ - beforeAddWrite(domWriteFn: () => void): Animator { - (this._writeCallbacks = this._writeCallbacks || []).push(domWriteFn); - return this; - } - - /** - * Add CSS class to this animation's elements - * after the animation finishes. - */ - afterAddClass(className: string): Animator { - (this._afterAddClasses = this._afterAddClasses || []).push(className); - return this; - } - - /** - * Remove CSS class from this animation's elements - * after the animation finishes. - */ - afterRemoveClass(className: string): Animator { - (this._afterRemoveClasses = this._afterRemoveClasses || []).push(className); - return this; - } - - /** - * Set CSS inline styles to this animation's elements - * after the animation finishes. - */ - afterStyles(styles: { [property: string]: any; }): Animator { - this._afterStyles = styles; - return this; - } - - /** - * Clear CSS inline styles from this animation's elements - * after the animation finishes. - */ - afterClearStyles(propertyNames: string[]): Animator { - this._afterStyles = this._afterStyles || {}; - for (const prop of propertyNames) { - this._afterStyles[prop] = ''; - } - return this; - } - - /** - * Play the animation. - */ - play(opts?: PlayOptions) { - // If the animation was already invalidated (it did finish), do nothing - if (this._destroyed) { - return; - } - - // this is the top level animation and is in full control - // of when the async play() should actually kick off - // if there is no duration then it'll set the TO property immediately - // if there is a duration, then it'll stage all animations at the - // FROM property and transition duration, wait a few frames, then - // kick off the animation by setting the TO property for each animation - this._isAsync = this._hasDuration(opts); - - // ensure all past transition end events have been cleared - this._clearAsync(); - - // recursively kicks off the correct progress step for each child animation - // ******** DOM WRITE **************** - this._playInit(opts); - - // doubling up RAFs since this animation was probably triggered - // from an input event, and just having one RAF would have this code - // run within the same frame as the triggering input event, and the - // input event probably already did way too much work for one frame - raf(() => { - raf(() => { - this._playDomInspect(opts); - }); - }); - } - - playAsync(opts?: PlayOptions): Promise { - return new Promise(resolve => { - this.onFinish(resolve, { oneTimeCallback: true, clearExistingCallbacks: true }); - this.play(opts); - return this; - }); - } - - playSync() { - // If the animation was already invalidated (it did finish), do nothing - if (!this._destroyed) { - const opts = { duration: 0 }; - this._isAsync = false; - this._clearAsync(); - this._playInit(opts); - this._playDomInspect(opts); - } - } - - /** - * DOM WRITE - * RECURSION - */ - private _playInit(opts: PlayOptions | undefined) { - // always default that an animation does not tween - // a tween requires that an Animation class has an element - // and that it has at least one FROM/TO effect - // and that the FROM/TO effect can tween numeric values - this._hasTweenEffect = false; - this.isPlaying = true; - this.hasCompleted = false; - this._hasDur = (this.getDuration(opts) > DURATION_MIN); - - const children = this._childAnimations; - if (children) { - for (const child of children) { - // ******** DOM WRITE **************** - child._playInit(opts); - } - } - - if (this._hasDur) { - // if there is a duration then we want to start at step 0 - // ******** DOM WRITE **************** - this._progress(0); - - // add the will-change properties - // ******** DOM WRITE **************** - this._willChange(true); - } - } - - /** - * DOM WRITE - * NO RECURSION - * ROOT ANIMATION - */ - _playDomInspect(opts: PlayOptions | undefined) { - // fire off all the "before" function that have DOM READS in them - // elements will be in the DOM, however visibily hidden - // so we can read their dimensions if need be - // ******** DOM READ **************** - // ******** DOM WRITE **************** - this._beforeAnimation(); - - // for the root animation only - // set the async TRANSITION END event - // and run onFinishes when the transition ends - const dur = this.getDuration(opts); - if (this._isAsync) { - this._asyncEnd(dur, true); - } - - // ******** DOM WRITE **************** - this._playProgress(opts); - - if (this._isAsync && !this._destroyed) { - // this animation has a duration so we need another RAF - // for the CSS TRANSITION properties to kick in - raf(() => { - this._playToStep(1); - }); - } - } - - /** - * DOM WRITE - * RECURSION - */ - _playProgress(opts: PlayOptions | undefined) { - const children = this._childAnimations; - if (children) { - for (const child of children) { - // ******** DOM WRITE **************** - child._playProgress(opts); - } - } - - if (this._hasDur) { - // set the CSS TRANSITION duration/easing - // ******** DOM WRITE **************** - this._setTrans(this.getDuration(opts), false); - - } else { - // this animation does not have a duration, so it should not animate - // just go straight to the TO properties and call it done - // ******** DOM WRITE **************** - this._progress(1); - - // since there was no animation, immediately run the after - // ******** DOM WRITE **************** - this._setAfterStyles(); - - // this animation has no duration, so it has finished - // other animations could still be running - this._didFinish(true); - } - } - - /** - * DOM WRITE - * RECURSION - */ - _playToStep(stepValue: number) { - if (!this._destroyed) { - const children = this._childAnimations; - if (children) { - for (const child of children) { - // ******** DOM WRITE **************** - child._playToStep(stepValue); - } - } - - if (this._hasDur) { - // browser had some time to render everything in place - // and the transition duration/easing is set - // now set the TO properties which will trigger the transition to begin - // ******** DOM WRITE **************** - this._progress(stepValue); - } - } - } - - /** - * DOM WRITE - * NO RECURSION - * ROOT ANIMATION - */ - _asyncEnd(dur: number, shouldComplete: boolean) { - const self = this; - - const onTransitionEnd = () => { - // congrats! a successful transition completed! - // ensure transition end events and timeouts have been cleared - self._clearAsync(); - - // ******** DOM WRITE **************** - self._playEnd(); - - // transition finished - self._didFinishAll(shouldComplete, true, false); - }; - - const onTransitionFallback = () => { - // oh noz! the transition end event didn't fire in time! - // instead the fallback timer when first - // if all goes well this fallback should never fire - - // clear the other async end events from firing - self._timerId = undefined; - self._clearAsync(); - - // set the after styles - // ******** DOM WRITE **************** - self._playEnd(shouldComplete ? 1 : 0); - - // transition finished - self._didFinishAll(shouldComplete, true, false); - }; - - // set the TRANSITION END event on one of the transition elements - self._unregisterTrnsEnd = transitionEnd(self._transEl(), onTransitionEnd); - - // set a fallback timeout if the transition end event never fires, or is too slow - // transition end fallback: (animation duration + XXms) - self._timerId = setTimeout(onTransitionFallback, (dur + TRANSITION_END_FALLBACK_PADDING_MS)); - } - - /** - * DOM WRITE - * RECURSION - */ - _playEnd(stepValue?: number) { - const children = this._childAnimations; - if (children) { - for (const child of children) { - // ******** DOM WRITE **************** - child._playEnd(stepValue); - } - } - - if (this._hasDur) { - if (stepValue !== undefined) { - // too late to have a smooth animation, just finish it - // ******** DOM WRITE **************** - this._setTrans(0, true); - - // ensure the ending progress step gets rendered - // ******** DOM WRITE **************** - this._progress(stepValue); - } - - // set the after styles - // ******** DOM WRITE **************** - this._setAfterStyles(); - - // remove the will-change properties - // ******** DOM WRITE **************** - this._willChange(false); - } - } - - /** - * NO DOM - * RECURSION - */ - _hasDuration(opts: PlayOptions | undefined) { - if (this.getDuration(opts) > DURATION_MIN) { - return true; - } - - const children = this._childAnimations; - if (children) { - for (const child of children) { - if (child._hasDuration(opts)) { - return true; - } - } - } - return false; - } - - /** - * NO DOM - * RECURSION - */ - _hasDomReads() { - if (this._readCallbacks && this._readCallbacks.length > 0) { - return true; - } - - const children = this._childAnimations; - if (children) { - for (const child of children) { - if (child._hasDomReads()) { - return true; - } - } - } - return false; - } - - /** - * Immediately stop at the end of the animation. - */ - stop(stepValue = 1) { - // ensure all past transition end events have been cleared - this._clearAsync(); - this._hasDur = true; - this._playEnd(stepValue); - } - - /** - * NO DOM - * NO RECURSION - */ - _clearAsync() { - if (this._unregisterTrnsEnd) { - this._unregisterTrnsEnd(); - } - if (this._timerId) { - clearTimeout(this._timerId); - } - this._timerId = this._unregisterTrnsEnd = undefined; - } - - /** - * DOM WRITE - * NO RECURSION - */ - _progress(stepValue: number) { - // bread 'n butter - let val: any; - const elements = this._elements; - const effects = this._fxProperties; - - if (!elements || elements.length === 0 || !effects || this._destroyed) { - return; - } - - // flip the number if we're going in reverse - if (this._isReverse) { - stepValue = 1 - stepValue; - } - let i = 0; - let j = 0; - let finalTransform = ''; - let fx: EffectProperty; - - for (i = 0; i < effects.length; i++) { - fx = effects[i]; - - if (fx.from && fx.to) { - const fromNum = fx.from.num; - const toNum = fx.to.num; - const tweenEffect = (fromNum !== toNum); - - if (tweenEffect) { - this._hasTweenEffect = true; - } - - if (stepValue === 0) { - // FROM - val = fx.from.val; - - } else if (stepValue === 1) { - // TO - val = fx.to.val; - - } else if (tweenEffect) { - // EVERYTHING IN BETWEEN - const valNum = (((toNum - fromNum) * stepValue) + fromNum); - const unit = fx.to.effectUnit; - val = valNum + unit; - } - - if (val !== null) { - const prop = fx.effectName; - if (fx.trans) { - finalTransform += prop + '(' + val + ') '; - - } else { - for (j = 0; j < elements.length; j++) { - // ******** DOM WRITE **************** - elements[j].style.setProperty(prop, val); - } - } - } - } - } - - // place all transforms on the same property - if (finalTransform.length > 0) { - if (!this._isReverse && stepValue !== 1 || this._isReverse && stepValue !== 0) { - finalTransform += 'translateZ(0px)'; - } - - for (i = 0; i < elements.length; i++) { - // ******** DOM WRITE **************** - elements[i].style.setProperty('transform', finalTransform); - elements[i].style.setProperty('-webkit-transform', finalTransform); - } - } - } - - /** - * DOM WRITE - * NO RECURSION - */ - _setTrans(dur: number, forcedLinearEasing: boolean) { - // Transition is not enabled if there are not effects - const elements = this._elements; - if (!elements || elements.length === 0 || !this._fxProperties) { - return; - } - - // set the TRANSITION properties inline on the element - const easing = (forcedLinearEasing ? 'linear' : this.getEasing()); - const durString = dur + 'ms'; - - for (const { style } of elements) { - if (dur > 0) { - // ******** DOM WRITE **************** - style.transitionDuration = durString; - - // each animation can have a different easing - if (easing !== null) { - // ******** DOM WRITE **************** - style.transitionTimingFunction = easing; - } - } else { - style.transitionDuration = '0'; - } - } - } - - /** - * DOM READ - * DOM WRITE - * RECURSION - */ - _beforeAnimation() { - // fire off all the "before" function that have DOM READS in them - // elements will be in the DOM, however visibily hidden - // so we can read their dimensions if need be - // ******** DOM READ **************** - this._fireBeforeReadFunc(); - - // ******** DOM READS ABOVE / DOM WRITES BELOW **************** - - // fire off all the "before" function that have DOM WRITES in them - // ******** DOM WRITE **************** - this._fireBeforeWriteFunc(); - - // stage all of the before css classes and inline styles - // ******** DOM WRITE **************** - this._setBeforeStyles(); - } - - /** - * DOM WRITE - * RECURSION - */ - _setBeforeStyles() { - const children = this._childAnimations; - if (children) { - for (const child of children) { - child._setBeforeStyles(); - } - } - - const elements = this._elements; - // before the animations have started - // only set before styles if animation is not reversed - if (!elements || elements.length === 0 || this._isReverse) { - return; - } - const addClasses = this._beforeAddClasses; - const removeClasses = this._beforeRemoveClasses; - - for (const el of elements) { - const elementClassList = el.classList; - - // css classes to add before the animation - - if (addClasses) { - for (const c of addClasses) { - // ******** DOM WRITE **************** - elementClassList.add(c); - } - } - - // css classes to remove before the animation - if (removeClasses) { - for (const c of removeClasses) { - // ******** DOM WRITE **************** - elementClassList.remove(c); - } - } - - // inline styles to add before the animation - if (this._beforeStyles) { - for (const [key, value] of Object.entries(this._beforeStyles)) { - // ******** DOM WRITE **************** - el.style.setProperty(key, value); - } - } - } - } - - /** - * DOM READ - * RECURSION - */ - _fireBeforeReadFunc() { - const children = this._childAnimations; - if (children) { - for (const child of children) { - // ******** DOM READ **************** - child._fireBeforeReadFunc(); - } - } - - const readFunctions = this._readCallbacks; - if (readFunctions) { - for (const callback of readFunctions) { - // ******** DOM READ **************** - callback(); - } - } - } - - /** - * DOM WRITE - * RECURSION - */ - _fireBeforeWriteFunc() { - const children = this._childAnimations; - if (children) { - for (const child of children) { - // ******** DOM WRITE **************** - child._fireBeforeWriteFunc(); - } - } - - const writeFunctions = this._writeCallbacks; - if (writeFunctions) { - for (const callback of writeFunctions) { - // ******** DOM WRITE **************** - callback(); - } - } - } - - /** - * DOM WRITE - */ - _setAfterStyles() { - const elements = this._elements; - if (!elements) { - return; - } - for (const el of elements) { - const elementClassList = el.classList; - - // remove the transition duration/easing - // ******** DOM WRITE **************** - el.style.transitionDuration = el.style.transitionTimingFunction = ''; - - if (this._isReverse) { - // finished in reverse direction - - // css classes that were added before the animation should be removed - const beforeAddClasses = this._beforeAddClasses; - if (beforeAddClasses) { - for (const c of beforeAddClasses) { - elementClassList.remove(c); - } - } - - // css classes that were removed before the animation should be added - const beforeRemoveClasses = this._beforeRemoveClasses; - if (beforeRemoveClasses) { - for (const c of beforeRemoveClasses) { - elementClassList.add(c); - } - } - - // inline styles that were added before the animation should be removed - const beforeStyles = this._beforeStyles; - if (beforeStyles) { - for (const propName of Object.keys(beforeStyles)) { - // ******** DOM WRITE **************** - el.style.removeProperty(propName); - } - } - - } else { - // finished in forward direction - - // css classes to add after the animation - const afterAddClasses = this._afterAddClasses; - if (afterAddClasses) { - for (const c of afterAddClasses) { - // ******** DOM WRITE **************** - elementClassList.add(c); - } - } - - // css classes to remove after the animation - const afterRemoveClasses = this._afterRemoveClasses; - if (afterRemoveClasses) { - for (const c of afterRemoveClasses) { - // ******** DOM WRITE **************** - elementClassList.remove(c); - } - } - - // inline styles to add after the animation - const afterStyles = this._afterStyles; - if (afterStyles) { - for (const [key, value] of Object.entries(afterStyles)) { - el.style.setProperty(key, value); - } - } - } - } - } - - /** - * DOM WRITE - * NO RECURSION - */ - _willChange(addWillChange: boolean) { - let wc: string[]; - const effects = this._fxProperties; - let willChange: string; - - if (addWillChange && effects) { - wc = []; - for (const effect of effects) { - const propWC = effect.wc; - if (propWC === 'webkitTransform') { - wc.push('transform', '-webkit-transform'); - - } else if (propWC !== undefined) { - wc.push(propWC); - } - } - willChange = wc.join(','); - - } else { - willChange = ''; - } - - const elements = this._elements; - if (elements) { - for (const el of elements) { - // ******** DOM WRITE **************** - el.style.setProperty('will-change', willChange); - } - } - } - - /** - * Start the animation with a user controlled progress. - */ - progressStart() { - // ensure all past transition end events have been cleared - this._clearAsync(); - - // ******** DOM READ/WRITE **************** - this._beforeAnimation(); - - // ******** DOM WRITE **************** - this._progressStart(); - } - - /** - * DOM WRITE - * RECURSION - */ - _progressStart() { - const children = this._childAnimations; - if (children) { - for (const child of children) { - // ******** DOM WRITE **************** - child._progressStart(); - } - } - - // force no duration, linear easing - // ******** DOM WRITE **************** - this._setTrans(0, true); - // ******** DOM WRITE **************** - this._willChange(true); - } - - /** - * Set the progress step for this animation. - * progressStep() is not debounced, so it should not be called faster than 60FPS. - */ - progressStep(stepValue: number) { - // only update if the last update was more than 16ms ago - stepValue = Math.min(1, Math.max(0, stepValue)); - - const children = this._childAnimations; - if (children) { - for (const child of children) { - // ******** DOM WRITE **************** - child.progressStep(stepValue); - } - } - - // ******** DOM WRITE **************** - this._progress(stepValue); - } - - /** - * End the progress animation. - */ - progressEnd(shouldComplete: boolean, currentStepValue: number, dur = -1) { - if (this._isReverse) { - // if the animation is going in reverse then - // flip the step value: 0 becomes 1, 1 becomes 0 - currentStepValue = 1 - currentStepValue; - } - const stepValue = shouldComplete ? 1 : 0; - const diff = Math.abs(currentStepValue - stepValue); - if (dur < 0) { - dur = this._duration || 0; - } else if (diff < 0.05) { - dur = 0; - } - - this._isAsync = (dur > 30); - - this._progressEnd(shouldComplete, stepValue, dur, this._isAsync); - - if (this._isAsync) { - // for the root animation only - // set the async TRANSITION END event - // and run onFinishes when the transition ends - // ******** DOM WRITE **************** - this._asyncEnd(dur, shouldComplete); - - // this animation has a duration so we need another RAF - // for the CSS TRANSITION properties to kick in - if (!this._destroyed) { - raf(() => { - this._playToStep(stepValue); - }); - } - } - } - - /** - * DOM WRITE - * RECURSION - */ - _progressEnd(shouldComplete: boolean, stepValue: number, dur: number, isAsync: boolean) { - const children = this._childAnimations; - if (children) { - for (const child of children) { - // ******** DOM WRITE **************** - child._progressEnd(shouldComplete, stepValue, dur, isAsync); - } - } - - if (!isAsync) { - // stop immediately - // set all the animations to their final position - // ******** DOM WRITE **************** - this._progress(stepValue); - this._willChange(false); - this._setAfterStyles(); - this._didFinish(shouldComplete); - - } else { - // animate it back to it's ending position - this.isPlaying = true; - this.hasCompleted = false; - this._hasDur = true; - - // ******** DOM WRITE **************** - this._willChange(true); - this._setTrans(dur, false); - } - } - - /** - * Add a callback to fire when the animation has finished. - */ - onFinish(callback: (animation?: any) => void, opts?: {oneTimeCallback?: boolean, clearExistingCallbacks?: boolean}): Animator { - if (opts && opts.clearExistingCallbacks) { - this._onFinishCallbacks = this._onFinishOneTimeCallbacks = undefined; - } - if (opts && opts.oneTimeCallback) { - this._onFinishOneTimeCallbacks = this._onFinishOneTimeCallbacks || []; - this._onFinishOneTimeCallbacks.push(callback); - - } else { - this._onFinishCallbacks = this._onFinishCallbacks || []; - this._onFinishCallbacks.push(callback); - } - return this; - } - - /** - * NO DOM - * RECURSION - */ - _didFinishAll(hasCompleted: boolean, finishAsyncAnimations: boolean, finishNoDurationAnimations: boolean) { - const children = this._childAnimations; - if (children) { - for (const child of children) { - child._didFinishAll(hasCompleted, finishAsyncAnimations, finishNoDurationAnimations); - } - } - - if (finishAsyncAnimations && this._isAsync || finishNoDurationAnimations && !this._isAsync) { - this._didFinish(hasCompleted); - } - } - - /** - * NO RECURSION - */ - _didFinish(hasCompleted: boolean) { - this.isPlaying = false; - this.hasCompleted = hasCompleted; - - if (this._onFinishCallbacks) { - // run all finish callbacks - for (const callback of this._onFinishCallbacks) { - callback(this); - } - } - - if (this._onFinishOneTimeCallbacks) { - // run all "onetime" finish callbacks - for (const callback of this._onFinishOneTimeCallbacks) { - callback(this); - } - this._onFinishOneTimeCallbacks.length = 0; - } - } - - /** - * Reverse the animation. - */ - reverse(shouldReverse = true): Animator { - const children = this._childAnimations; - if (children) { - for (const child of children) { - child.reverse(shouldReverse); - } - } - this._isReverse = !!shouldReverse; - return this; - } - - /** - * Recursively destroy this animation and all child animations. - */ - destroy() { - this._didFinish(false); - this._destroyed = true; - - const children = this._childAnimations; - if (children) { - for (const child of children) { - child.destroy(); - } - } - - this._clearAsync(); - - if (this._elements) { - this._elements.length = 0; - } - - if (this._readCallbacks) { - this._readCallbacks.length = 0; - } - - if (this._writeCallbacks) { - this._writeCallbacks.length = 0; - } - - this.parent = undefined; - - if (this._childAnimations) { - this._childAnimations.length = 0; - } - if (this._onFinishCallbacks) { - this._onFinishCallbacks.length = 0; - } - if (this._onFinishOneTimeCallbacks) { - this._onFinishOneTimeCallbacks.length = 0; - } - } - - /** - * NO DOM - */ - _transEl(): HTMLElement | null { - // get the lowest level element that has an Animator - const children = this._childAnimations; - if (children) { - for (const child of children) { - const targetEl = child._transEl(); - if (targetEl) { - return targetEl; - } - } - } - - return ( - this._hasTweenEffect && - this._hasDur && - this._elements !== undefined && - this._elements.length > 0 ? - this._elements[0] : null - ); - } -} diff --git a/core/src/utils/animation/old-animation/index.ts b/core/src/utils/animation/old-animation/index.ts deleted file mode 100644 index 19fd3d5312..0000000000 --- a/core/src/utils/animation/old-animation/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Animation, AnimationBuilder } from '../../../interface'; - -import { Animator } from './animator'; - -export const create = (animationBuilder?: AnimationBuilder, baseEl?: any, opts?: any): Promise => { - if (animationBuilder) { - return animationBuilder(Animator as any, baseEl, opts); - } - return Promise.resolve(new Animator() as any); -}; diff --git a/core/src/utils/animation/old-animation/transition-end.ts b/core/src/utils/animation/old-animation/transition-end.ts deleted file mode 100644 index a7e51e0dd8..0000000000 --- a/core/src/utils/animation/old-animation/transition-end.ts +++ /dev/null @@ -1,30 +0,0 @@ - -export const transitionEnd = (el: HTMLElement | null, callback: (ev?: TransitionEvent) => void) => { - let unRegTrans: (() => void) | undefined; - const opts: any = { passive: true }; - - const unregister = () => { - if (unRegTrans) { - unRegTrans(); - } - }; - - const onTransitionEnd = (ev: Event) => { - if (el === ev.target) { - unregister(); - callback(ev as TransitionEvent); - } - }; - - if (el) { - el.addEventListener('webkitTransitionEnd', onTransitionEnd, opts); - el.addEventListener('transitionend', onTransitionEnd, opts); - - unRegTrans = () => { - el.removeEventListener('webkitTransitionEnd', onTransitionEnd, opts); - el.removeEventListener('transitionend', onTransitionEnd, opts); - }; - } - - return unregister; -}; diff --git a/core/src/utils/animation/test/animationbuilder/e2e.ts b/core/src/utils/animation/test/animationbuilder/e2e.ts index 9571799e65..cf136e4108 100644 --- a/core/src/utils/animation/test/animationbuilder/e2e.ts +++ b/core/src/utils/animation/test/animationbuilder/e2e.ts @@ -1,10 +1,5 @@ import { E2EPage, newE2EPage } from '@stencil/core/testing'; -test('animation:backwards-compatibility animationbuilder', async () => { - const page = await newE2EPage({ url: '/src/utils/animation/test/animationbuilder?_forceAnimationBuilder=true' }); - await testNavigation(page); -}); - test('animation:backwards-compatibility animation', async () => { const page = await newE2EPage({ url: '/src/utils/animation/test/animationbuilder' }); await testNavigation(page); diff --git a/core/src/utils/animation/test/animationbuilder/index.html b/core/src/utils/animation/test/animationbuilder/index.html index 75a40176e8..7f979a07a3 100644 --- a/core/src/utils/animation/test/animationbuilder/index.html +++ b/core/src/utils/animation/test/animationbuilder/index.html @@ -101,65 +101,6 @@ customElements.define('page-two', PageTwo); customElements.define('page-three', PageThree); - const forceAnimationBuilder = new URLSearchParams(window.location.search).get('ionic:_forceAnimationBuilder'); - if (forceAnimationBuilder) { - window.Ionic.config.navAnimation = (AnimationC, navEl, opts) => { - const TRANSLATEY = 'translateY'; - const OFF_BOTTOM = '40px'; - const CENTER = '0px'; - - const backDirection = (opts.direction === 'back'); - const enteringEl = opts.enteringEl; - const leavingEl = opts.leavingEl; - const ionPageElement = getIonPageElement(enteringEl); - const enteringToolbarEle = ionPageElement.querySelector('ion-toolbar'); - const rootTransition = new AnimationC(); - - rootTransition - .addElement(ionPageElement) - .beforeRemoveClass('ion-page-invisible'); - - // animate the component itself - if (backDirection) { - rootTransition - .duration(opts.duration || 200) - .easing('cubic-bezier(0.47,0,0.745,0.715)'); - - } else { - rootTransition - .duration(opts.duration || 280) - .easing('cubic-bezier(0.36,0.66,0.04,1)') - .fromTo(TRANSLATEY, OFF_BOTTOM, CENTER, true) - .fromTo('opacity', 0.01, 1, true); - } - - // Animate toolbar if it's there - if (enteringToolbarEle) { - const enteringToolBar = new AnimationC(); - enteringToolBar.addElement(enteringToolbarEle); - rootTransition.add(enteringToolBar); - } - - // setup leaving view - if (leavingEl && backDirection) { - // leaving content - rootTransition - .duration(opts.duration || 200) - .easing('cubic-bezier(0.47,0,0.745,0.715)'); - - const leavingPage = new AnimationC(); - leavingPage - .addElement(getIonPageElement(leavingEl)) - .fromTo(TRANSLATEY, CENTER, OFF_BOTTOM) - .fromTo('opacity', 1, 0); - - rootTransition.add(leavingPage); - } - - return Promise.resolve(rootTransition); - }; - } - const getIonPageElement = (element) => { if (element.classList.contains('ion-page')) { return element; diff --git a/core/src/utils/menu-controller/animations/base.ts b/core/src/utils/menu-controller/animations/base.ts index 06ea9880e6..22fa1fbcb4 100644 --- a/core/src/utils/menu-controller/animations/base.ts +++ b/core/src/utils/menu-controller/animations/base.ts @@ -1,4 +1,4 @@ -import { IonicAnimation } from '../../../interface'; +import { Animation } from '../../../interface'; import { createAnimation } from '../../animation/animation'; /** @@ -7,13 +7,16 @@ import { createAnimation } from '../../animation/animation'; * type will provide their own animations for open and close * and registers itself with Menu. */ -export const baseAnimation = (isIos: boolean): IonicAnimation => { + +export const baseAnimation = (isIos: boolean): Animation => { // https://material.io/guidelines/motion/movement.html#movement-movement-in-out-of-screen-bounds // https://material.io/guidelines/motion/duration-easing.html#duration-easing-natural-easing-curves - // "Apply the sharp curve to items temporarily leaving the screen that may return - // from the same exit point. When they return, use the deceleration curve. On mobile, - // this transition typically occurs over 300ms" -- MD Motion Guide + /** + * "Apply the sharp curve to items temporarily leaving the screen that may return + * from the same exit point. When they return, use the deceleration curve. On mobile, + * this transition typically occurs over 300ms" -- MD Motion Guide + */ return createAnimation().duration(isIos ? 400 : 300); }; diff --git a/core/src/utils/menu-controller/animations/overlay.ts b/core/src/utils/menu-controller/animations/overlay.ts index 3fb8f6fadc..1906c7f798 100644 --- a/core/src/utils/menu-controller/animations/overlay.ts +++ b/core/src/utils/menu-controller/animations/overlay.ts @@ -1,4 +1,4 @@ -import { IonicAnimation, MenuI } from '../../../interface'; +import { Animation, MenuI } from '../../../interface'; import { createAnimation } from '../../animation/animation'; import { baseAnimation } from './base'; @@ -8,7 +8,7 @@ import { baseAnimation } from './base'; * The menu slides over the content. The content * itself, which is under the menu, does not move. */ -export const menuOverlayAnimation = (menu: MenuI): IonicAnimation => { +export const menuOverlayAnimation = (menu: MenuI): Animation => { let closedX: string; let openedX: string; const width = menu.width + 8; diff --git a/core/src/utils/menu-controller/animations/push.ts b/core/src/utils/menu-controller/animations/push.ts index 56e41a7ccb..b8de97e6e4 100644 --- a/core/src/utils/menu-controller/animations/push.ts +++ b/core/src/utils/menu-controller/animations/push.ts @@ -1,4 +1,4 @@ -import { IonicAnimation, MenuI } from '../../../interface'; +import { Animation, MenuI } from '../../../interface'; import { createAnimation } from '../../animation/animation'; import { baseAnimation } from './base'; @@ -8,7 +8,7 @@ import { baseAnimation } from './base'; * The content slides over to reveal the menu underneath. * The menu itself also slides over to reveal its bad self. */ -export const menuPushAnimation = (menu: MenuI): IonicAnimation => { +export const menuPushAnimation = (menu: MenuI): Animation => { let contentOpenedX: string; let menuClosedX: string; diff --git a/core/src/utils/menu-controller/animations/reveal.ts b/core/src/utils/menu-controller/animations/reveal.ts index eb7574c838..4dc6ca9054 100644 --- a/core/src/utils/menu-controller/animations/reveal.ts +++ b/core/src/utils/menu-controller/animations/reveal.ts @@ -1,4 +1,4 @@ -import { IonicAnimation, MenuI } from '../../../interface'; +import { Animation, MenuI } from '../../../interface'; import { createAnimation } from '../../animation/animation'; import { baseAnimation } from './base'; @@ -8,7 +8,7 @@ import { baseAnimation } from './base'; * The content slides over to reveal the menu underneath. * The menu itself, which is under the content, does not move. */ -export const menuRevealAnimation = (menu: MenuI): IonicAnimation => { +export const menuRevealAnimation = (menu: MenuI): Animation => { const openedX = (menu.width * (menu.isEndSide ? -1 : 1)) + 'px'; const contentOpen = createAnimation() diff --git a/core/src/utils/menu-controller/index.ts b/core/src/utils/menu-controller/index.ts index c9f3aa0b92..10016699ae 100644 --- a/core/src/utils/menu-controller/index.ts +++ b/core/src/utils/menu-controller/index.ts @@ -1,11 +1,11 @@ -import { AnimationBuilder, IonicAnimation, MenuI } from '../../interface'; +import { AnimationBuilder, MenuI } from '../../interface'; import { menuOverlayAnimation } from './animations/overlay'; import { menuPushAnimation } from './animations/push'; import { menuRevealAnimation } from './animations/reveal'; const createMenuController = () => { - const menuAnimations = new Map IonicAnimation) | AnimationBuilder>(); + const menuAnimations = new Map(); const menus: MenuI[] = []; const open = async (menu?: string | null): Promise => { @@ -122,7 +122,7 @@ const createMenuController = () => { return isAnimatingSync(); }; - const registerAnimation = (name: string, animation: AnimationBuilder | ((menu: MenuI) => IonicAnimation)) => { + const registerAnimation = (name: string, animation: AnimationBuilder) => { menuAnimations.set(name, animation); }; diff --git a/core/src/utils/overlays-interface.ts b/core/src/utils/overlays-interface.ts index 713d4163d1..e4f3ddcda8 100644 --- a/core/src/utils/overlays-interface.ts +++ b/core/src/utils/overlays-interface.ts @@ -1,7 +1,7 @@ import { EventEmitter } from '@stencil/core'; import { HTMLStencilElement } from '@stencil/core/internal'; -import { Animation, AnimationBuilder, IonicAnimation, Mode } from '../interface'; +import { Animation, AnimationBuilder, Mode } from '../interface'; export interface OverlayEventDetail { data?: T; @@ -15,7 +15,7 @@ export interface OverlayInterface { keyboardClose: boolean; overlayIndex: number; presented: boolean; - animation?: Animation | IonicAnimation; + animation?: Animation; enterAnimation?: AnimationBuilder; leaveAnimation?: AnimationBuilder; diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index 369ba58eb1..b0aaeb09fa 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -1,8 +1,5 @@ import { config } from '../global/config'; -import { ActionSheetOptions, AlertOptions, AnimationBuilder, BackButtonEvent, HTMLIonOverlayElement, IonicAnimation, IonicConfig, LoadingOptions, ModalOptions, OverlayInterface, PickerOptions, PopoverOptions, ToastOptions } from '../interface'; - -// TODO: Remove when removing AnimationBuilder -export type IonicAnimationInterface = (baseEl: any, opts: any) => IonicAnimation; +import { ActionSheetOptions, AlertOptions, AnimationBuilder, BackButtonEvent, HTMLIonOverlayElement, IonicConfig, LoadingOptions, ModalOptions, OverlayInterface, PickerOptions, PopoverOptions, ToastOptions } from '../interface'; let lastId = 0; @@ -117,8 +114,8 @@ export const getOverlay = (doc: Document, overlayTag?: string, id?: string): HTM export const present = async ( overlay: OverlayInterface, name: keyof IonicConfig, - iosEnterAnimation: AnimationBuilder | IonicAnimationInterface, - mdEnterAnimation: AnimationBuilder | IonicAnimationInterface, + iosEnterAnimation: AnimationBuilder, + mdEnterAnimation: AnimationBuilder, opts?: any ) => { if (overlay.presented) { @@ -143,8 +140,8 @@ export const dismiss = async ( data: any | undefined, role: string | undefined, name: keyof IonicConfig, - iosLeaveAnimation: AnimationBuilder | IonicAnimationInterface, - mdLeaveAnimation: AnimationBuilder | IonicAnimationInterface, + iosLeaveAnimation: AnimationBuilder, + mdLeaveAnimation: AnimationBuilder, opts?: any ): Promise => { if (!overlay.presented) { @@ -176,7 +173,7 @@ const getAppRoot = (doc: Document) => { const overlayAnimation = async ( overlay: OverlayInterface, - animationBuilder: AnimationBuilder | IonicAnimationInterface, + animationBuilder: AnimationBuilder, baseEl: any, opts: any ): Promise => { @@ -190,24 +187,13 @@ const overlayAnimation = async ( const aniRoot = baseEl.shadowRoot || overlay.el; - /** - * TODO: Remove AnimationBuilder - */ - let animation; - let isAnimationBuilder = true; - try { - const mod = await import('./animation/old-animation'); - animation = await mod.create(animationBuilder as AnimationBuilder, aniRoot, opts); - } catch (err) { - animation = (animationBuilder as IonicAnimationInterface)(aniRoot, opts); - animation.fill('both'); - isAnimationBuilder = false; - } + const animation = animationBuilder(aniRoot, opts); overlay.animation = animation; if (!overlay.animated || !config.getBoolean('animated', true)) { animation.duration(0); } + if (overlay.keyboardClose) { animation.beforeAddWrite(() => { const activeElement = baseEl.ownerDocument!.activeElement as HTMLElement; @@ -216,18 +202,11 @@ const overlayAnimation = async ( } }); } - const animationResult = await animation.play(); - /** - * TODO: Remove AnimationBuilder - */ - const hasCompleted = (typeof animationResult as any === 'undefined') ? true : (animation as any).hasCompleted; - if (isAnimationBuilder) { - animation.destroy(); - } + await animation.play(); overlay.animation = undefined; - return hasCompleted; + return true; }; export const eventMethod = (element: HTMLElement, eventName: string): Promise => { diff --git a/core/src/utils/transition/index.ts b/core/src/utils/transition/index.ts index a1fb1b5aba..0b065a5162 100644 --- a/core/src/utils/transition/index.ts +++ b/core/src/utils/transition/index.ts @@ -1,17 +1,11 @@ import { writeTask } from '@stencil/core'; import { LIFECYCLE_DID_ENTER, LIFECYCLE_DID_LEAVE, LIFECYCLE_WILL_ENTER, LIFECYCLE_WILL_LEAVE } from '../../components/nav/constants'; -import { Animation, AnimationBuilder, IonicAnimation, NavDirection, NavOptions } from '../../interface'; +import { Animation, AnimationBuilder, NavDirection, NavOptions } from '../../interface'; const iosTransitionAnimation = () => import('./ios.transition'); const mdTransitionAnimation = () => import('./md.transition'); -// TODO: Remove when removing AnimationBuilder -export type IonicAnimationInterface = ( - ((navEl: HTMLElement, opts: TransitionOptions) => IonicAnimation) | - ((navEl: HTMLElement, opts: TransitionOptions) => Promise) -); - export const transition = (opts: TransitionOptions): Promise => { return new Promise((resolve, reject) => { writeTask(() => { @@ -66,7 +60,7 @@ const afterTransition = (opts: TransitionOptions) => { } }; -const getAnimationBuilder = async (opts: TransitionOptions): Promise => { +const getAnimationBuilder = async (opts: TransitionOptions): Promise => { if (!opts.leavingEl || !opts.animated || opts.duration === 0) { return undefined; } @@ -82,17 +76,10 @@ const getAnimationBuilder = async (opts: TransitionOptions): Promise => { +const animation = async (animationBuilder: AnimationBuilder, opts: TransitionOptions): Promise => { await waitForReady(opts, true); - let trans: Animation | IonicAnimation; - - try { - const mod = await import('../animation/old-animation'); - trans = await mod.create(animationBuilder as AnimationBuilder, opts.baseEl, opts); - } catch (err) { - trans = (animationBuilder as IonicAnimationInterface)(opts.baseEl, opts) as IonicAnimation; - } + const trans = animationBuilder(opts.baseEl, opts); fireWillEvents(opts.enteringEl, opts.leavingEl); @@ -146,18 +133,11 @@ const notifyViewReady = async (viewIsReady: undefined | ((enteringEl: HTMLElemen } }; -const playTransition = (trans: IonicAnimation | Animation, opts: TransitionOptions): Promise => { +const playTransition = (trans: Animation, opts: TransitionOptions): Promise => { const progressCallback = opts.progressCallback; - // TODO: Remove AnimationBuilder const promise = new Promise(resolve => { - trans.onFinish((currentStep: any) => { - if (typeof currentStep === 'number') { - resolve(currentStep === 1); - } else if ((trans as any).hasCompleted !== undefined) { - resolve((trans as Animation).hasCompleted); - } - }); + trans.onFinish((currentStep: any) => resolve(currentStep === 1)); }); // cool, let's do this, start the transition @@ -244,7 +224,7 @@ const setZIndex = ( }; export interface TransitionOptions extends NavOptions { - progressCallback?: ((ani: IonicAnimation | Animation | undefined) => void); + progressCallback?: ((ani: Animation | undefined) => void); baseEl: any; enteringEl: HTMLElement; leavingEl: HTMLElement | undefined; @@ -252,5 +232,5 @@ export interface TransitionOptions extends NavOptions { export interface TransitionResult { hasCompleted: boolean; - animation?: Animation | IonicAnimation; + animation?: Animation; } diff --git a/core/src/utils/transition/ios.transition.ts b/core/src/utils/transition/ios.transition.ts index 6b8be3d5ca..db2406fa27 100644 --- a/core/src/utils/transition/ios.transition.ts +++ b/core/src/utils/transition/ios.transition.ts @@ -1,4 +1,4 @@ -import { IonicAnimation } from '../../interface'; +import { Animation } from '../../interface'; import { createAnimation } from '../animation/animation'; import { TransitionOptions } from '../transition'; @@ -36,7 +36,7 @@ const getBackButton = (refEl: any, backDirection: boolean) => { return null; }; -const createLargeTitleTransition = (rootAnimation: IonicAnimation, rtl: boolean, backDirection: boolean, enteringEl: any, leavingEl: any) => { +const createLargeTitleTransition = (rootAnimation: Animation, rtl: boolean, backDirection: boolean, enteringEl: any, leavingEl: any) => { const enteringBackButton = getBackButton(enteringEl, backDirection); const leavingLargeTitle = getLargeTitle(leavingEl); @@ -60,7 +60,7 @@ const createLargeTitleTransition = (rootAnimation: IonicAnimation, rtl: boolean, }; }; -const animateBackButton = (rootAnimation: IonicAnimation, rtl: boolean, backDirection: boolean, backButtonEl: any) => { +const animateBackButton = (rootAnimation: Animation, rtl: boolean, backDirection: boolean, backButtonEl: any) => { const backButtonBounds = backButtonEl.getBoundingClientRect(); const BACK_BUTTON_START_OFFSET = (rtl) ? `calc(100% - ${backButtonBounds.right + 4}px)` : `${backButtonBounds.left - 4}px`; const START_TEXT_TRANSLATE = (rtl) ? '7px' : '-7px'; @@ -137,7 +137,7 @@ const animateBackButton = (rootAnimation: IonicAnimation, rtl: boolean, backDire rootAnimation.addAnimation([enteringBackButtonTextAnimation, enteringBackButtonIconAnimation]); }; -const animateLargeTitle = (rootAnimation: IonicAnimation, rtl: boolean, backDirection: boolean, largeTitleEl: any) => { +const animateLargeTitle = (rootAnimation: Animation, rtl: boolean, backDirection: boolean, largeTitleEl: any) => { const largeTitleBounds = largeTitleEl.getBoundingClientRect(); const TITLE_START_OFFSET = (rtl) ? `calc(100% - ${largeTitleBounds.right}px)` : `${largeTitleBounds.left}px`; const START_TRANSLATE = (rtl) ? '-18px' : '18px'; @@ -184,7 +184,7 @@ const animateLargeTitle = (rootAnimation: IonicAnimation, rtl: boolean, backDire rootAnimation.addAnimation(clonedLargeTitleAnimation); }; -export const iosTransitionAnimation = (navEl: HTMLElement, opts: TransitionOptions): IonicAnimation => { +export const iosTransitionAnimation = (navEl: HTMLElement, opts: TransitionOptions): Animation => { try { const EASING = 'cubic-bezier(0.32,0.72,0,1)'; const OPACITY = 'opacity'; diff --git a/core/src/utils/transition/md.transition.ts b/core/src/utils/transition/md.transition.ts index c3619e4026..2f8303ed37 100644 --- a/core/src/utils/transition/md.transition.ts +++ b/core/src/utils/transition/md.transition.ts @@ -1,8 +1,8 @@ -import { IonicAnimation } from '../../interface'; +import { Animation } from '../../interface'; import { createAnimation } from '../animation/animation'; import { TransitionOptions } from '../transition'; -export const mdTransitionAnimation = (_: HTMLElement, opts: TransitionOptions): IonicAnimation => { +export const mdTransitionAnimation = (_: HTMLElement, opts: TransitionOptions): Animation => { const OFF_BOTTOM = '40px'; const CENTER = '0px';