diff --git a/core/src/components.d.ts b/core/src/components.d.ts index 7e22619cb9..9198afff58 100644 --- a/core/src/components.d.ts +++ b/core/src/components.d.ts @@ -2265,39 +2265,6 @@ declare global { } -declare global { - - namespace StencilComponents { - interface IonInputShims { - - } - } - - interface HTMLIonInputShimsElement extends StencilComponents.IonInputShims, HTMLStencilElement {} - - var HTMLIonInputShimsElement: { - prototype: HTMLIonInputShimsElement; - new (): HTMLIonInputShimsElement; - }; - interface HTMLElementTagNameMap { - 'ion-input-shims': HTMLIonInputShimsElement; - } - interface ElementTagNameMap { - 'ion-input-shims': HTMLIonInputShimsElement; - } - namespace JSX { - interface IntrinsicElements { - 'ion-input-shims': JSXElements.IonInputShimsAttributes; - } - } - namespace JSXElements { - export interface IonInputShimsAttributes extends HTMLAttributes { - - } - } -} - - declare global { namespace StencilComponents { diff --git a/core/src/components/action-sheet/action-sheet.tsx b/core/src/components/action-sheet/action-sheet.tsx index dfd7cf251e..f642b69ea9 100644 --- a/core/src/components/action-sheet/action-sheet.tsx +++ b/core/src/components/action-sheet/action-sheet.tsx @@ -2,10 +2,10 @@ import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@ import { ActionSheetButton, Animation, AnimationBuilder, Config, CssClassMap, Mode } from '../../interface'; import { BACKDROP, OverlayEventDetail, OverlayInterface, dismiss, eventMethod, isCancel, present } from '../../utils/overlays'; import { createThemedClasses, getClassMap } from '../../utils/theme'; -import iosEnterAnimation from './animations/ios.enter'; -import iosLeaveAnimation from './animations/ios.leave'; -import mdEnterAnimation from './animations/md.enter'; -import mdLeaveAnimation from './animations/md.leave'; +import { iosEnterAnimation } from './animations/ios.enter'; +import { iosLeaveAnimation } from './animations/ios.leave'; +import { mdEnterAnimation } from './animations/md.enter'; +import { mdLeaveAnimation } from './animations/md.leave'; @Component({ diff --git a/core/src/components/action-sheet/animations/ios.enter.ts b/core/src/components/action-sheet/animations/ios.enter.ts index d4aaaecc59..a9a9388572 100644 --- a/core/src/components/action-sheet/animations/ios.enter.ts +++ b/core/src/components/action-sheet/animations/ios.enter.ts @@ -3,7 +3,7 @@ import { Animation } from '../../../interface'; /** * iOS Action Sheet Enter Animation */ -export default function iosEnterAnimation(Animation: Animation, baseEl: HTMLElement): Promise { +export function iosEnterAnimation(Animation: Animation, baseEl: HTMLElement): Promise { const baseAnimation = new Animation(); const backdropAnimation = new Animation(); diff --git a/core/src/components/action-sheet/animations/ios.leave.ts b/core/src/components/action-sheet/animations/ios.leave.ts index 402fb637a6..109271cb82 100644 --- a/core/src/components/action-sheet/animations/ios.leave.ts +++ b/core/src/components/action-sheet/animations/ios.leave.ts @@ -3,7 +3,7 @@ import { Animation } from '../../../interface'; /** * iOS Action Sheet Leave Animation */ -export default function iosLeaveAnimation(Animation: Animation, baseEl: HTMLElement): Promise { +export function iosLeaveAnimation(Animation: Animation, baseEl: HTMLElement): Promise { const baseAnimation = new Animation(); const backdropAnimation = new Animation(); diff --git a/core/src/components/action-sheet/animations/md.enter.ts b/core/src/components/action-sheet/animations/md.enter.ts index 0b1ae4bfaf..5aa12dd735 100644 --- a/core/src/components/action-sheet/animations/md.enter.ts +++ b/core/src/components/action-sheet/animations/md.enter.ts @@ -4,7 +4,7 @@ import { Animation } from '../../../interface'; /** * MD Action Sheet Enter Animation */ -export default function mdEnterAnimation(Animation: Animation, baseEl: HTMLElement): Promise { +export function mdEnterAnimation(Animation: Animation, baseEl: HTMLElement): Promise { const baseAnimation = new Animation(); const backdropAnimation = new Animation(); diff --git a/core/src/components/action-sheet/animations/md.leave.ts b/core/src/components/action-sheet/animations/md.leave.ts index f66b166310..1b15893193 100644 --- a/core/src/components/action-sheet/animations/md.leave.ts +++ b/core/src/components/action-sheet/animations/md.leave.ts @@ -3,7 +3,7 @@ import { Animation } from '../../../interface'; /** * MD Action Sheet Leave Animation */ -export default function mdLeaveAnimation(Animation: Animation, baseEl: HTMLElement): Promise { +export function mdLeaveAnimation(Animation: Animation, baseEl: HTMLElement): Promise { const baseAnimation = new Animation(); const backdropAnimation = new Animation(); diff --git a/core/src/components/alert/alert.tsx b/core/src/components/alert/alert.tsx index 8770f80d33..f4eb15e6cf 100644 --- a/core/src/components/alert/alert.tsx +++ b/core/src/components/alert/alert.tsx @@ -3,10 +3,10 @@ import { AlertButton, AlertInput, Animation, AnimationBuilder, Config, CssClassM import { BACKDROP, OverlayEventDetail, OverlayInterface, dismiss, eventMethod, isCancel, present } from '../../utils/overlays'; import { createThemedClasses, getClassMap } from '../../utils/theme'; -import iosEnterAnimation from './animations/ios.enter'; -import iosLeaveAnimation from './animations/ios.leave'; -import mdEnterAnimation from './animations/md.enter'; -import mdLeaveAnimation from './animations/md.leave'; +import { iosEnterAnimation } from './animations/ios.enter'; +import { iosLeaveAnimation } from './animations/ios.leave'; +import { mdEnterAnimation } from './animations/md.enter'; +import { mdLeaveAnimation } from './animations/md.leave'; @Component({ tag: 'ion-alert', diff --git a/core/src/components/alert/animations/ios.enter.ts b/core/src/components/alert/animations/ios.enter.ts index ad8be62514..ee2e4217a4 100644 --- a/core/src/components/alert/animations/ios.enter.ts +++ b/core/src/components/alert/animations/ios.enter.ts @@ -3,7 +3,7 @@ import { Animation } from '../../../interface'; /** * iOS Alert Enter Animation */ -export default function iosEnterAnimation(Animation: Animation, baseEl: HTMLElement): Promise { +export function iosEnterAnimation(Animation: Animation, baseEl: HTMLElement): Promise { const baseAnimation = new Animation(); const backdropAnimation = new Animation(); diff --git a/core/src/components/alert/animations/ios.leave.ts b/core/src/components/alert/animations/ios.leave.ts index 4306fd3fbf..48656b0c05 100644 --- a/core/src/components/alert/animations/ios.leave.ts +++ b/core/src/components/alert/animations/ios.leave.ts @@ -3,7 +3,7 @@ import { Animation } from '../../../interface'; /** * iOS Alert Leave Animation */ -export default function iosLeaveAnimation(Animation: Animation, baseEl: HTMLElement): Promise { +export function iosLeaveAnimation(Animation: Animation, baseEl: HTMLElement): Promise { const baseAnimation = new Animation(); const backdropAnimation = new Animation(); diff --git a/core/src/components/alert/animations/md.enter.ts b/core/src/components/alert/animations/md.enter.ts index 944d2c9d8e..266f8dbffc 100644 --- a/core/src/components/alert/animations/md.enter.ts +++ b/core/src/components/alert/animations/md.enter.ts @@ -3,7 +3,7 @@ import { Animation } from '../../../interface'; /** * Md Alert Enter Animation */ -export default function mdEnterAnimation(Animation: Animation, baseEl: HTMLElement): Promise { +export function mdEnterAnimation(Animation: Animation, baseEl: HTMLElement): Promise { const baseAnimation = new Animation(); const backdropAnimation = new Animation(); diff --git a/core/src/components/alert/animations/md.leave.ts b/core/src/components/alert/animations/md.leave.ts index bd6cadb749..aca701cc75 100644 --- a/core/src/components/alert/animations/md.leave.ts +++ b/core/src/components/alert/animations/md.leave.ts @@ -3,7 +3,7 @@ import { Animation } from '../../../interface'; /** * Md Alert Leave Animation */ -export default function mdLeaveAnimation(Animation: Animation, baseEl: HTMLElement): Promise { +export function mdLeaveAnimation(Animation: Animation, baseEl: HTMLElement): Promise { const baseAnimation = new Animation(); const backdropAnimation = new Animation(); diff --git a/core/src/components/app/app.ios.scss b/core/src/components/app/app.ios.scss index e970ca3bf9..7d104c9221 100644 --- a/core/src/components/app/app.ios.scss +++ b/core/src/components/app/app.ios.scss @@ -15,8 +15,8 @@ // TODO this can be simplified &.statusbar-padding { .ion-page, + > ion-header, .ion-page > ion-header, - ion-tab ion-nav .ion-page > ion-header, ion-menu > .menu-inner, ion-menu > .menu-inner > ion-header { @include toolbar-statusbar-padding($toolbar-ios-height, $toolbar-ios-padding, $content-ios-padding, $app-ios-statusbar-padding); diff --git a/core/src/components/app/app.tsx b/core/src/components/app/app.tsx index bda5cb2576..878b734cc1 100644 --- a/core/src/components/app/app.tsx +++ b/core/src/components/app/app.tsx @@ -21,6 +21,10 @@ export class App { @Prop({ context: 'window' }) win!: Window; @Prop({ context: 'config' }) config!: Config; + componentDidLoad() { + loadInputShims(this.win, this.config); + } + hostData() { const hybrid = isHybrid(this.win); const statusBar = this.config.getBoolean('statusbarPadding', hybrid); @@ -35,13 +39,17 @@ export class App { render() { const device = this.config.getBoolean('isDevice', isDevice(this.win)); - const inputShims = this.config.getBoolean('inputShims', needInputShims(this.win)); - return [ - inputShims && , , device && , ]; } } + +async function loadInputShims(win: Window, config: Config) { + const inputShims = config.getBoolean('inputShims', needInputShims(win)); + if (inputShims) { + (await import('../../utils/input-shims/input-shims')).startInputShims(win.document, config); + } +} diff --git a/core/src/components/input-shims/input-shims.tsx b/core/src/components/input-shims/input-shims.tsx deleted file mode 100644 index e1997da244..0000000000 --- a/core/src/components/input-shims/input-shims.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import { Component, Listen, Prop } from '@stencil/core'; -import { Config } from '../../interface'; - -import enableHideCaretOnScroll from './hacks/hide-caret'; -import enableInputBlurring from './hacks/input-blurring'; -import enableScrollAssist from './hacks/scroll-assist'; -import enableScrollPadding from './hacks/scroll-padding'; - -const INPUT_BLURRING = true; -const SCROLL_ASSIST = true; -const SCROLL_PADDING = true; -const HIDE_CARET = true; - -@Component({ - tag: 'ion-input-shims', -}) -export class InputShims { - - private didLoad = false; - private hideCaret = false; - private scrollAssist = false; - private keyboardHeight = 0; - private hideCaretMap = new WeakMap(); - private scrollAssistMap = new WeakMap(); - - @Prop({ context: 'config' }) config!: Config; - @Prop({ context: 'document' }) doc!: Document; - - componentDidLoad() { - this.keyboardHeight = this.config.getNumber('keyboardHeight', 290); - this.scrollAssist = this.config.getBoolean('scrollAssist', true); - this.hideCaret = this.config.getBoolean('hideCaretOnScroll', true); - - const inputBlurring = this.config.getBoolean('inputBlurring', true); - if (inputBlurring && INPUT_BLURRING) { - enableInputBlurring(this.doc); - } - - const scrollPadding = this.config.getBoolean('scrollPadding', true); - if (scrollPadding && SCROLL_PADDING) { - enableScrollPadding(this.doc, this.keyboardHeight); - } - - // Input might be already loaded in the DOM before ion-device-hacks did. - // At this point we need to look for all the ion-inputs not registered yet - // and register them. - const inputs = Array.from(this.doc.querySelectorAll('ion-input')); - for (const input of inputs) { - this.registerInput(input); - } - this.didLoad = true; - } - - @Listen('body:ionInputDidLoad') - protected onInputDidLoad(event: any) { - if (this.didLoad) { - this.registerInput(event.target); - } - } - - @Listen('body:ionInputDidUnload') - protected onInputDidUnload(event: any) { - if (this.didLoad) { - this.unregisterInput(event.target); - } - } - - private registerInput(componentEl: HTMLElement) { - const inputEl = componentEl.querySelector('input'); - const scrollEl = componentEl.closest('ion-scroll'); - const contentEl = componentEl.closest('ion-content'); - - if (!inputEl) { - return; - } - - if (HIDE_CARET && scrollEl && this.hideCaret && !this.hideCaretMap.has(componentEl)) { - const rmFn = enableHideCaretOnScroll(componentEl, inputEl, scrollEl); - this.hideCaretMap.set(componentEl, rmFn); - } - - if (SCROLL_ASSIST && contentEl && this.scrollAssist && !this.scrollAssistMap.has(componentEl)) { - const rmFn = enableScrollAssist(componentEl, inputEl, contentEl, this.keyboardHeight); - this.scrollAssistMap.set(componentEl, rmFn); - } - } - - private unregisterInput(componentEl: HTMLElement) { - if (HIDE_CARET && this.hideCaret) { - const fn = this.hideCaretMap.get(componentEl); - fn && fn(); - this.hideCaretMap.delete(componentEl); - } - - if (SCROLL_ASSIST && this.scrollAssist) { - const fn = this.scrollAssistMap.get(componentEl); - fn && fn(); - this.scrollAssistMap.delete(componentEl); - } - } -} diff --git a/core/src/components/loading/animations/ios.enter.ts b/core/src/components/loading/animations/ios.enter.ts index da0ff5d2ea..f3f8001152 100644 --- a/core/src/components/loading/animations/ios.enter.ts +++ b/core/src/components/loading/animations/ios.enter.ts @@ -4,7 +4,7 @@ import { Animation } from '../../../interface'; /** * iOS Loading Enter Animation */ -export default function iosEnterAnimation(Animation: Animation, baseEl: HTMLElement): Promise { +export function iosEnterAnimation(Animation: Animation, baseEl: HTMLElement): Promise { const baseAnimation = new Animation(); const backdropAnimation = new Animation(); diff --git a/core/src/components/loading/animations/ios.leave.ts b/core/src/components/loading/animations/ios.leave.ts index 7909ebfaf4..5d8901190c 100644 --- a/core/src/components/loading/animations/ios.leave.ts +++ b/core/src/components/loading/animations/ios.leave.ts @@ -4,7 +4,7 @@ import { Animation } from '../../../interface'; /** * iOS Loading Leave Animation */ -export default function iosLeaveAnimation(Animation: Animation, baseEl: HTMLElement): Promise { +export function iosLeaveAnimation(Animation: Animation, baseEl: HTMLElement): Promise { const baseAnimation = new Animation(); const backdropAnimation = new Animation(); diff --git a/core/src/components/loading/animations/md.enter.ts b/core/src/components/loading/animations/md.enter.ts index a86659440b..86bcc2875e 100644 --- a/core/src/components/loading/animations/md.enter.ts +++ b/core/src/components/loading/animations/md.enter.ts @@ -3,7 +3,7 @@ import { Animation } from '../../../interface'; /** * Md Loading Enter Animation */ -export default function mdEnterAnimation(Animation: Animation, baseEl: HTMLElement): Promise { +export function mdEnterAnimation(Animation: Animation, baseEl: HTMLElement): Promise { const baseAnimation = new Animation(); const backdropAnimation = new Animation(); diff --git a/core/src/components/loading/animations/md.leave.ts b/core/src/components/loading/animations/md.leave.ts index f46dd05d66..312b2c1260 100644 --- a/core/src/components/loading/animations/md.leave.ts +++ b/core/src/components/loading/animations/md.leave.ts @@ -3,7 +3,7 @@ import { Animation } from '../../../interface'; /** * Md Loading Leave Animation */ -export default function mdLeaveAnimation(Animation: Animation, baseEl: HTMLElement): Promise { +export function mdLeaveAnimation(Animation: Animation, baseEl: HTMLElement): Promise { const baseAnimation = new Animation(); const backdropAnimation = new Animation(); diff --git a/core/src/components/loading/loading.tsx b/core/src/components/loading/loading.tsx index 7e6a859530..bc8fd45d76 100644 --- a/core/src/components/loading/loading.tsx +++ b/core/src/components/loading/loading.tsx @@ -3,11 +3,11 @@ import { Animation, AnimationBuilder, Config, Mode } from '../../interface'; import { BACKDROP, OverlayEventDetail, OverlayInterface, dismiss, eventMethod, present } from '../../utils/overlays'; import { createThemedClasses, getClassMap } from '../../utils/theme'; -import iosEnterAnimation from './animations/ios.enter'; -import iosLeaveAnimation from './animations/ios.leave'; +import { iosEnterAnimation } from './animations/ios.enter'; +import { iosLeaveAnimation } from './animations/ios.leave'; -import mdEnterAnimation from './animations/md.enter'; -import mdLeaveAnimation from './animations/md.leave'; +import { mdEnterAnimation } from './animations/md.enter'; +import { mdLeaveAnimation } from './animations/md.leave'; @Component({ tag: 'ion-loading', diff --git a/core/src/components/menu-controller/animations/base.ts b/core/src/components/menu-controller/animations/base.ts index a7c0115cdc..3fc1817e96 100644 --- a/core/src/components/menu-controller/animations/base.ts +++ b/core/src/components/menu-controller/animations/base.ts @@ -6,7 +6,7 @@ import { Animation } from '../../../interface'; * type will provide their own animations for open and close * and registers itself with Menu. */ -export default function baseAnimation(Animation: Animation): Promise { +export function baseAnimation(Animation: Animation): Promise { // 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 diff --git a/core/src/components/menu-controller/animations/overlay.ts b/core/src/components/menu-controller/animations/overlay.ts index d37d4732f2..3109a111fb 100644 --- a/core/src/components/menu-controller/animations/overlay.ts +++ b/core/src/components/menu-controller/animations/overlay.ts @@ -1,5 +1,5 @@ import { Animation, Menu } from '../../../interface'; -import baseAnimation from './base'; +import { baseAnimation } from './base'; const BOX_SHADOW_WIDTH = 8; /** @@ -8,7 +8,7 @@ const BOX_SHADOW_WIDTH = 8; * The menu slides over the content. The content * itself, which is under the menu, does not move. */ -export default function(Animation: Animation, _: HTMLElement, menu: Menu): Promise { +export function menuOverlayAnimation(Animation: Animation, _: HTMLElement, menu: Menu): Promise { let closedX: string, openedX: string; const width = menu.width + BOX_SHADOW_WIDTH; if (menu.isEndSide) { diff --git a/core/src/components/menu-controller/animations/push.ts b/core/src/components/menu-controller/animations/push.ts index 8c7b19ed18..fcd071cf43 100644 --- a/core/src/components/menu-controller/animations/push.ts +++ b/core/src/components/menu-controller/animations/push.ts @@ -1,5 +1,5 @@ import { Animation, Menu } from '../../../interface'; -import baseAnimation from './base'; +import { baseAnimation } from './base'; /** * @hidden @@ -7,7 +7,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 default function(Animation: Animation, _: HTMLElement, menu: Menu): Promise { +export function menuPushAnimation(Animation: Animation, _: HTMLElement, menu: Menu): Promise { let contentOpenedX: string, menuClosedX: string; const width = menu.width; diff --git a/core/src/components/menu-controller/animations/reveal.ts b/core/src/components/menu-controller/animations/reveal.ts index 4223cd4356..626e54f55c 100644 --- a/core/src/components/menu-controller/animations/reveal.ts +++ b/core/src/components/menu-controller/animations/reveal.ts @@ -1,5 +1,5 @@ import { Animation, Menu } from '../../../interface'; -import baseAnimation from './base'; +import { baseAnimation } from './base'; /** * @hidden @@ -7,7 +7,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 default function(Animation: Animation, _: HTMLElement, menu: Menu): Promise { +export function menuRevealAnimation(Animation: Animation, _: HTMLElement, menu: Menu): Promise { const openedX = (menu.width * (menu.isEndSide ? -1 : 1)) + 'px'; const contentOpen = new Animation() diff --git a/core/src/components/menu-controller/menu-controller.ts b/core/src/components/menu-controller/menu-controller.ts index bdf9c1c51e..e2c3f8842a 100644 --- a/core/src/components/menu-controller/menu-controller.ts +++ b/core/src/components/menu-controller/menu-controller.ts @@ -1,9 +1,9 @@ import { Component, Method, Prop } from '@stencil/core'; import { Animation, AnimationBuilder, Menu } from '../../interface'; -import MenuOverlayAnimation from './animations/overlay'; -import MenuPushAnimation from './animations/push'; -import MenuRevealAnimation from './animations/reveal'; +import { menuOverlayAnimation } from './animations/overlay'; +import { menuPushAnimation } from './animations/push'; +import { menuRevealAnimation } from './animations/reveal'; @Component({ tag: 'ion-menu-controller' @@ -16,9 +16,9 @@ export class MenuController { @Prop({ connect: 'ion-animation-controller' }) animationCtrl!: HTMLIonAnimationControllerElement; constructor() { - this.registerAnimation('reveal', MenuRevealAnimation); - this.registerAnimation('push', MenuPushAnimation); - this.registerAnimation('overlay', MenuOverlayAnimation); + this.registerAnimation('reveal', menuRevealAnimation); + this.registerAnimation('push', menuPushAnimation); + this.registerAnimation('overlay', menuOverlayAnimation); } /** @@ -279,4 +279,4 @@ export class MenuController { } -export { MenuOverlayAnimation, MenuPushAnimation, MenuRevealAnimation }; +export { menuOverlayAnimation, menuPushAnimation, menuRevealAnimation }; diff --git a/core/src/components/modal/animations/ios.enter.ts b/core/src/components/modal/animations/ios.enter.ts index 63ed8e9c43..29790faf07 100644 --- a/core/src/components/modal/animations/ios.enter.ts +++ b/core/src/components/modal/animations/ios.enter.ts @@ -4,7 +4,7 @@ import { Animation } from '../../../interface'; /** * iOS Modal Enter Animation */ -export default function iosEnterAnimation(Animation: Animation, baseEl: HTMLElement): Promise { +export function iosEnterAnimation(Animation: Animation, baseEl: HTMLElement): Promise { const baseAnimation = new Animation(); const backdropAnimation = new Animation(); diff --git a/core/src/components/modal/animations/ios.leave.ts b/core/src/components/modal/animations/ios.leave.ts index 5a50db28a7..8bdcd2b1d1 100644 --- a/core/src/components/modal/animations/ios.leave.ts +++ b/core/src/components/modal/animations/ios.leave.ts @@ -4,7 +4,7 @@ import { Animation } from '../../../interface'; /** * iOS Modal Leave Animation */ -export default function iosLeaveAnimation(Animation: Animation, baseEl: HTMLElement): Promise { +export function iosLeaveAnimation(Animation: Animation, baseEl: HTMLElement): Promise { const baseAnimation = new Animation(); const backdropAnimation = new Animation(); diff --git a/core/src/components/modal/animations/md.enter.ts b/core/src/components/modal/animations/md.enter.ts index f5aa63ed87..6109a53f6a 100644 --- a/core/src/components/modal/animations/md.enter.ts +++ b/core/src/components/modal/animations/md.enter.ts @@ -3,7 +3,7 @@ import { Animation } from '../../../interface'; /** * Md Modal Enter Animation */ -export default function mdEnterAnimation(Animation: Animation, baseEl: HTMLElement): Promise { +export function mdEnterAnimation(Animation: Animation, baseEl: HTMLElement): Promise { const baseAnimation = new Animation(); const backdropAnimation = new Animation(); diff --git a/core/src/components/modal/animations/md.leave.ts b/core/src/components/modal/animations/md.leave.ts index 766c5747bd..87ad21362a 100644 --- a/core/src/components/modal/animations/md.leave.ts +++ b/core/src/components/modal/animations/md.leave.ts @@ -3,7 +3,7 @@ import { Animation } from '../../../interface'; /** * Md Modal Leave Animation */ -export default function mdLeaveAnimation(Animation: Animation, baseEl: HTMLElement): Promise { +export function mdLeaveAnimation(Animation: Animation, baseEl: HTMLElement): Promise { const baseAnimation = new Animation(); const backdropAnimation = new Animation(); diff --git a/core/src/components/modal/modal.tsx b/core/src/components/modal/modal.tsx index 2631426d0c..9da62d69bb 100644 --- a/core/src/components/modal/modal.tsx +++ b/core/src/components/modal/modal.tsx @@ -5,11 +5,11 @@ import { attachComponent, detachComponent } from '../../utils/framework-delegate import { BACKDROP, OverlayEventDetail, OverlayInterface, dismiss, eventMethod, present } from '../../utils/overlays'; import { createThemedClasses, getClassMap } from '../../utils/theme'; -import iosEnterAnimation from './animations/ios.enter'; -import iosLeaveAnimation from './animations/ios.leave'; +import { iosEnterAnimation } from './animations/ios.enter'; +import { iosLeaveAnimation } from './animations/ios.leave'; -import mdEnterAnimation from './animations/md.enter'; -import mdLeaveAnimation from './animations/md.leave'; +import { mdEnterAnimation } from './animations/md.enter'; +import { mdLeaveAnimation } from './animations/md.leave'; @Component({ tag: 'ion-modal', diff --git a/core/src/components/picker/animations/ios.enter.ts b/core/src/components/picker/animations/ios.enter.ts index c70e378ec8..45abc8c74e 100644 --- a/core/src/components/picker/animations/ios.enter.ts +++ b/core/src/components/picker/animations/ios.enter.ts @@ -4,7 +4,7 @@ import { Animation } from '../../../interface'; /** * iOS Picker Enter Animation */ -export default function iosEnterAnimation(Animation: Animation, baseEl: HTMLElement): Promise { +export function iosEnterAnimation(Animation: Animation, baseEl: HTMLElement): Promise { const baseAnimation = new Animation(); const backdropAnimation = new Animation(); diff --git a/core/src/components/picker/animations/ios.leave.ts b/core/src/components/picker/animations/ios.leave.ts index d89aa2a8e8..60d060d303 100644 --- a/core/src/components/picker/animations/ios.leave.ts +++ b/core/src/components/picker/animations/ios.leave.ts @@ -4,7 +4,7 @@ import { Animation } from '../../../interface'; /** * iOS Picker Leave Animation */ -export default function iosLeaveAnimation(Animation: Animation, baseEl: HTMLElement): Promise { +export function iosLeaveAnimation(Animation: Animation, baseEl: HTMLElement): Promise { const baseAnimation = new Animation(); const backdropAnimation = new Animation(); diff --git a/core/src/components/picker/picker.tsx b/core/src/components/picker/picker.tsx index 46c66ddc01..15007b8eb9 100644 --- a/core/src/components/picker/picker.tsx +++ b/core/src/components/picker/picker.tsx @@ -4,8 +4,8 @@ import { Animation, AnimationBuilder, Config, CssClassMap, Mode, PickerButton, P import { OverlayEventDetail, OverlayInterface, dismiss, eventMethod, present } from '../../utils/overlays'; import { getClassMap } from '../../utils/theme'; -import iosEnterAnimation from './animations/ios.enter'; -import iosLeaveAnimation from './animations/ios.leave'; +import { iosEnterAnimation } from './animations/ios.enter'; +import { iosLeaveAnimation } from './animations/ios.leave'; @Component({ tag: 'ion-picker', diff --git a/core/src/components/popover/animations/ios.enter.ts b/core/src/components/popover/animations/ios.enter.ts index a326ab8595..da0105a2c5 100644 --- a/core/src/components/popover/animations/ios.enter.ts +++ b/core/src/components/popover/animations/ios.enter.ts @@ -3,7 +3,7 @@ import { Animation } from '../../../interface'; /** * iOS Popover Enter Animation */ -export default function iosEnterAnimation(Animation: Animation, baseEl: HTMLElement, ev?: Event): Promise { +export function iosEnterAnimation(Animation: Animation, baseEl: HTMLElement, ev?: Event): Promise { 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 409e478df5..c25d0c4e59 100644 --- a/core/src/components/popover/animations/ios.leave.ts +++ b/core/src/components/popover/animations/ios.leave.ts @@ -3,7 +3,7 @@ import { Animation } from '../../../interface'; /** * iOS Popover Leave Animation */ -export default function iosLeaveAnimation(Animation: Animation, baseEl: HTMLElement): Promise { +export function iosLeaveAnimation(Animation: Animation, baseEl: HTMLElement): Promise { const baseAnimation = new Animation(); const backdropAnimation = new Animation(); diff --git a/core/src/components/popover/animations/md.enter.ts b/core/src/components/popover/animations/md.enter.ts index c55835a283..d754683a64 100644 --- a/core/src/components/popover/animations/md.enter.ts +++ b/core/src/components/popover/animations/md.enter.ts @@ -3,7 +3,7 @@ import { Animation } from '../../../interface'; /** * Md Popover Enter Animation */ -export default function mdEnterAnimation(Animation: Animation, baseEl: HTMLElement, ev?: Event): Promise { +export function mdEnterAnimation(Animation: Animation, baseEl: HTMLElement, ev?: Event): Promise { let originY = 'top'; let originX = 'left'; diff --git a/core/src/components/popover/animations/md.leave.ts b/core/src/components/popover/animations/md.leave.ts index 71207074a1..1082d87c4c 100644 --- a/core/src/components/popover/animations/md.leave.ts +++ b/core/src/components/popover/animations/md.leave.ts @@ -3,7 +3,7 @@ import { Animation } from '../../../interface'; /** * Md Popover Leave Animation */ -export default function mdLeaveAnimation(Animation: Animation, baseEl: HTMLElement): Promise { +export function mdLeaveAnimation(Animation: Animation, baseEl: HTMLElement): Promise { const baseAnimation = new Animation(); const backdropAnimation = new Animation(); diff --git a/core/src/components/popover/popover.tsx b/core/src/components/popover/popover.tsx index 28728d06f7..221e8d8774 100644 --- a/core/src/components/popover/popover.tsx +++ b/core/src/components/popover/popover.tsx @@ -5,11 +5,11 @@ import { attachComponent, detachComponent } from '../../utils/framework-delegate import { BACKDROP, OverlayEventDetail, OverlayInterface, dismiss, eventMethod, present } from '../../utils/overlays'; import { createThemedClasses, getClassMap } from '../../utils/theme'; -import iosEnterAnimation from './animations/ios.enter'; -import iosLeaveAnimation from './animations/ios.leave'; +import { iosEnterAnimation } from './animations/ios.enter'; +import { iosLeaveAnimation } from './animations/ios.leave'; -import mdEnterAnimation from './animations/md.enter'; -import mdLeaveAnimation from './animations/md.leave'; +import { mdEnterAnimation } from './animations/md.enter'; +import { mdLeaveAnimation } from './animations/md.leave'; @Component({ tag: 'ion-popover', diff --git a/core/src/components/router/utils/debug.ts b/core/src/components/router/utils/debug.ts index 1b2d3cee1e..04d6f97d10 100644 --- a/core/src/components/router/utils/debug.ts +++ b/core/src/components/router/utils/debug.ts @@ -2,11 +2,12 @@ import { RouteChain } from './interface'; import { generatePath } from './path'; export function printRoutes(routes: RouteChain[]) { - console.debug('%c[ion-core]', 'font-weight: bold', `registered ${routes.length} routes`); + console.groupCollapsed(`[ion-core] registered ${routes.length} routes`); for (const chain of routes) { const path: string[] = []; chain.forEach(r => path.push(...r.path)); const ids = chain.map(r => r.id); console.debug(`%c ${generatePath(path)}`, 'font-weight: bold; padding-left: 20px', '=>\t', `(${ids.join(', ')})`); } + console.groupEnd(); } diff --git a/core/src/components/toast/animations/ios.enter.ts b/core/src/components/toast/animations/ios.enter.ts index c8235d5298..ffd9fc8e5d 100644 --- a/core/src/components/toast/animations/ios.enter.ts +++ b/core/src/components/toast/animations/ios.enter.ts @@ -3,7 +3,7 @@ import { Animation } from '../../../interface'; /** * iOS Toast Enter Animation */ -export default function iosEnterAnimation(Animation: Animation, baseEl: HTMLElement, position: string): Promise { +export function iosEnterAnimation(Animation: Animation, baseEl: HTMLElement, position: string): Promise { const baseAnimation = new Animation(); const wrapperAnimation = new Animation(); diff --git a/core/src/components/toast/animations/ios.leave.ts b/core/src/components/toast/animations/ios.leave.ts index 22c325fc45..5901d6c6df 100644 --- a/core/src/components/toast/animations/ios.leave.ts +++ b/core/src/components/toast/animations/ios.leave.ts @@ -3,7 +3,7 @@ import { Animation } from '../../../interface'; /** * iOS Toast Leave Animation */ -export default function iosLeaveAnimation(Animation: Animation, baseEl: HTMLElement, position: string): Promise { +export function iosLeaveAnimation(Animation: Animation, baseEl: HTMLElement, position: string): Promise { const baseAnimation = new Animation(); const wrapperAnimation = new Animation(); diff --git a/core/src/components/toast/animations/md.enter.ts b/core/src/components/toast/animations/md.enter.ts index 88ae4793e4..50c2d1cf0d 100644 --- a/core/src/components/toast/animations/md.enter.ts +++ b/core/src/components/toast/animations/md.enter.ts @@ -3,7 +3,7 @@ import { Animation } from '../../../interface'; /** * MD Toast Enter Animation */ -export default function mdEnterAnimation(Animation: Animation, baseEl: HTMLElement, position: string): Promise { +export function mdEnterAnimation(Animation: Animation, baseEl: HTMLElement, position: string): Promise { const baseAnimation = new Animation(); const wrapperAnimation = new Animation(); diff --git a/core/src/components/toast/animations/md.leave.ts b/core/src/components/toast/animations/md.leave.ts index a9354cc6cd..ce948e9641 100644 --- a/core/src/components/toast/animations/md.leave.ts +++ b/core/src/components/toast/animations/md.leave.ts @@ -3,7 +3,7 @@ import { Animation } from '../../../interface'; /** * md Toast Leave Animation */ -export default function mdLeaveAnimation(Animation: Animation, baseEl: HTMLElement, position: string): Promise { +export function mdLeaveAnimation(Animation: Animation, baseEl: HTMLElement, position: string): Promise { const baseAnimation = new Animation(); const wrapperAnimation = new Animation(); diff --git a/core/src/components/toast/toast.tsx b/core/src/components/toast/toast.tsx index a55861228a..d81e53799d 100644 --- a/core/src/components/toast/toast.tsx +++ b/core/src/components/toast/toast.tsx @@ -4,11 +4,11 @@ import { Animation, AnimationBuilder, Config, Mode } from '../../interface'; import { OverlayEventDetail, OverlayInterface, dismiss, eventMethod, present } from '../../utils/overlays'; import { createThemedClasses, getClassMap } from '../../utils/theme'; -import iosEnterAnimation from './animations/ios.enter'; -import iosLeaveAnimation from './animations/ios.leave'; +import { iosEnterAnimation } from './animations/ios.enter'; +import { iosLeaveAnimation } from './animations/ios.leave'; -import mdEnterAnimation from './animations/md.enter'; -import mdLeaveAnimation from './animations/md.leave'; +import { mdEnterAnimation } from './animations/md.enter'; +import { mdLeaveAnimation } from './animations/md.leave'; @Component({ tag: 'ion-toast', diff --git a/core/src/utils/animations/ios.transition.ts b/core/src/utils/animations/ios.transition.ts index ad46caa1df..1cc1c856f5 100644 --- a/core/src/utils/animations/ios.transition.ts +++ b/core/src/utils/animations/ios.transition.ts @@ -9,7 +9,7 @@ const TRANSLATEX = 'translateX'; const CENTER = '0%'; const OFF_OPACITY = 0.8; -export default function iosTransitionAnimation(Animation: Animation, navEl: HTMLElement, opts: TransitionOptions): Promise { +export function iosTransitionAnimation(Animation: Animation, navEl: HTMLElement, opts: TransitionOptions): Promise { const isRTL = document.dir === 'rtl'; const OFF_RIGHT = isRTL ? '-99.5%' : '99.5%'; diff --git a/core/src/utils/animations/md.transition.ts b/core/src/utils/animations/md.transition.ts index c7fcae08d8..d8992f979a 100644 --- a/core/src/utils/animations/md.transition.ts +++ b/core/src/utils/animations/md.transition.ts @@ -5,7 +5,7 @@ const TRANSLATEY = 'translateY'; const OFF_BOTTOM = '40px'; const CENTER = '0px'; -export default function mdTransitionAnimation(Animation: Animation, _: HTMLElement, opts: TransitionOptions): Promise { +export function mdTransitionAnimation(Animation: Animation, _: HTMLElement, opts: TransitionOptions): Promise { const enteringEl = opts.enteringEl; const leavingEl = opts.leavingEl; diff --git a/core/src/components/input-shims/hacks/common.ts b/core/src/utils/input-shims/hacks/common.ts similarity index 100% rename from core/src/components/input-shims/hacks/common.ts rename to core/src/utils/input-shims/hacks/common.ts diff --git a/core/src/components/input-shims/hacks/hide-caret.ts b/core/src/utils/input-shims/hacks/hide-caret.ts similarity index 87% rename from core/src/components/input-shims/hacks/hide-caret.ts rename to core/src/utils/input-shims/hacks/hide-caret.ts index d1e41e59cb..005af4571f 100644 --- a/core/src/components/input-shims/hacks/hide-caret.ts +++ b/core/src/utils/input-shims/hacks/hide-caret.ts @@ -1,7 +1,7 @@ import { isFocused, relocateInput } from './common'; -export default function enableHideCaretOnScroll(componentEl: HTMLElement, inputEl: HTMLInputElement, scrollEl: HTMLIonScrollElement) { +export function enableHideCaretOnScroll(componentEl: HTMLElement, inputEl: HTMLInputElement, scrollEl: HTMLIonScrollElement) { if (!scrollEl || !inputEl) { return () => { return; }; } diff --git a/core/src/components/input-shims/hacks/input-blurring.ts b/core/src/utils/input-shims/hacks/input-blurring.ts similarity index 96% rename from core/src/components/input-shims/hacks/input-blurring.ts rename to core/src/utils/input-shims/hacks/input-blurring.ts index c33084a1bb..c0a4f20924 100644 --- a/core/src/components/input-shims/hacks/input-blurring.ts +++ b/core/src/utils/input-shims/hacks/input-blurring.ts @@ -1,7 +1,7 @@ const SKIP_BLURRING = ['INPUT', 'TEXTAREA', 'ION-INPUT', 'ION-TEXTAREA']; -export default function enableInputBlurring(doc: Document) { +export function enableInputBlurring(doc: Document) { console.debug('Input: enableInputBlurring'); let focused = true; diff --git a/core/src/components/input-shims/hacks/scroll-assist.ts b/core/src/utils/input-shims/hacks/scroll-assist.ts similarity index 98% rename from core/src/components/input-shims/hacks/scroll-assist.ts rename to core/src/utils/input-shims/hacks/scroll-assist.ts index 8564072671..fce8369c1c 100644 --- a/core/src/components/input-shims/hacks/scroll-assist.ts +++ b/core/src/utils/input-shims/hacks/scroll-assist.ts @@ -3,7 +3,7 @@ import { isFocused, relocateInput } from './common'; import { getScrollData } from './scroll-data'; -export default function enableScrollAssist( +export function enableScrollAssist( componentEl: HTMLElement, inputEl: HTMLInputElement, contentEl: HTMLIonContentElement, diff --git a/core/src/components/input-shims/hacks/scroll-data.ts b/core/src/utils/input-shims/hacks/scroll-data.ts similarity index 100% rename from core/src/components/input-shims/hacks/scroll-data.ts rename to core/src/utils/input-shims/hacks/scroll-data.ts diff --git a/core/src/components/input-shims/hacks/scroll-padding.ts b/core/src/utils/input-shims/hacks/scroll-padding.ts similarity index 92% rename from core/src/components/input-shims/hacks/scroll-padding.ts rename to core/src/utils/input-shims/hacks/scroll-padding.ts index f48de1e041..86f4d295a4 100644 --- a/core/src/components/input-shims/hacks/scroll-padding.ts +++ b/core/src/utils/input-shims/hacks/scroll-padding.ts @@ -1,6 +1,6 @@ const PADDING_TIMER_KEY = '$ionPaddingTimer'; -export default function enableScrollPadding(doc: Document, keyboardHeight: number) { +export function enableScrollPadding(doc: Document, keyboardHeight: number) { console.debug('Input: enableScrollPadding'); function onFocusin(ev: any) { diff --git a/core/src/components/input-shims/hacks/wip.ts b/core/src/utils/input-shims/hacks/wip.ts similarity index 100% rename from core/src/components/input-shims/hacks/wip.ts rename to core/src/utils/input-shims/hacks/wip.ts diff --git a/core/src/utils/input-shims/input-shims.ts b/core/src/utils/input-shims/input-shims.ts new file mode 100644 index 0000000000..faa8cf66ef --- /dev/null +++ b/core/src/utils/input-shims/input-shims.ts @@ -0,0 +1,83 @@ + +import { Config } from '../../interface'; +import { enableHideCaretOnScroll } from './hacks/hide-caret'; +import { enableInputBlurring } from './hacks/input-blurring'; +import { enableScrollAssist } from './hacks/scroll-assist'; +import { enableScrollPadding } from './hacks/scroll-padding'; + +const INPUT_BLURRING = true; +const SCROLL_ASSIST = true; +const SCROLL_PADDING = true; +const HIDE_CARET = true; + +export function startInputShims( + doc: Document, + config: Config, +) { + const keyboardHeight = config.getNumber('keyboardHeight', 290); + const scrollAssist = config.getBoolean('scrollAssist', true); + const hideCaret = config.getBoolean('hideCaretOnScroll', true); + const inputBlurring = config.getBoolean('inputBlurring', true); + const scrollPadding = config.getBoolean('scrollPadding', true); + + const hideCaretMap = new WeakMap(); + const scrollAssistMap = new WeakMap(); + + function registerInput(componentEl: HTMLElement) { + const inputEl = componentEl.querySelector('input'); + const scrollEl = componentEl.closest('ion-scroll'); + const contentEl = componentEl.closest('ion-content'); + + if (!inputEl) { + return; + } + + if (HIDE_CARET && scrollEl && hideCaret && !hideCaretMap.has(componentEl)) { + const rmFn = enableHideCaretOnScroll(componentEl, inputEl, scrollEl); + hideCaretMap.set(componentEl, rmFn); + } + + if (SCROLL_ASSIST && contentEl && scrollAssist && !scrollAssistMap.has(componentEl)) { + const rmFn = enableScrollAssist(componentEl, inputEl, contentEl, keyboardHeight); + scrollAssistMap.set(componentEl, rmFn); + } + } + + function unregisterInput(componentEl: HTMLElement) { + if (HIDE_CARET && hideCaret) { + const fn = hideCaretMap.get(componentEl); + fn && fn(); + hideCaretMap.delete(componentEl); + } + + if (SCROLL_ASSIST && scrollAssist) { + const fn = scrollAssistMap.get(componentEl); + fn && fn(); + scrollAssistMap.delete(componentEl); + } + } + + if (inputBlurring && INPUT_BLURRING) { + enableInputBlurring(doc); + } + + if (scrollPadding && SCROLL_PADDING) { + enableScrollPadding(doc, keyboardHeight); + } + + // Input might be already loaded in the DOM before ion-device-hacks did. + // At this point we need to look for all the ion-inputs not registered yet + // and register them. + const inputs = Array.from(doc.querySelectorAll('ion-input')); + for (const input of inputs) { + registerInput(input); + } + + doc.body.addEventListener('ionInputDidLoad', (event) => { + registerInput(event.target as any); + }); + + doc.body.addEventListener('ionInputDidUnload', (event) => { + unregisterInput(event.target as any); + }); +} diff --git a/core/src/components/input-shims/readme.md b/core/src/utils/input-shims/readme.md similarity index 100% rename from core/src/components/input-shims/readme.md rename to core/src/utils/input-shims/readme.md diff --git a/core/src/utils/transition.ts b/core/src/utils/transition.ts index d28cb9c037..2c6db90a9d 100644 --- a/core/src/utils/transition.ts +++ b/core/src/utils/transition.ts @@ -1,26 +1,29 @@ import { Animation, AnimationBuilder, NavDirection, NavOptions } from '../interface'; -import iosTransitionAnimation from './animations/ios.transition'; -import mdTransitionAnimation from './animations/md.transition'; +const iosTransitionAnimation = () => import('./animations/ios.transition'); +const mdTransitionAnimation = () => import('./animations/md.transition'); -export function transition(opts: TransitionOptions): Promise { +export async function transition(opts: TransitionOptions): Promise { beforeTransition(opts); - const animationBuilder = getAnimationBuilder(opts); + const animationBuilder = await getAnimationBuilder(opts); return (animationBuilder) ? animation(animationBuilder, opts) : noAnimation(opts); // fast path for no animation } -function getAnimationBuilder(opts: TransitionOptions): AnimationBuilder | undefined { +async function getAnimationBuilder(opts: TransitionOptions): Promise { if (!opts.leavingEl || opts.animated === false || opts.duration === 0) { return undefined; } if (opts.animationBuilder) { return opts.animationBuilder; } - return opts.mode === 'ios' ? iosTransitionAnimation : mdTransitionAnimation; + const builder = (opts.mode === 'ios') + ? (await iosTransitionAnimation()).iosTransitionAnimation + : (await mdTransitionAnimation()).mdTransitionAnimation; + return builder; } function beforeTransition(opts: TransitionOptions) { diff --git a/core/tsconfig.json b/core/tsconfig.json index fb56d321d2..d204d96993 100644 --- a/core/tsconfig.json +++ b/core/tsconfig.json @@ -13,7 +13,7 @@ "dom", "es2017" ], - "module": "es2015", + "module": "esnext", "moduleResolution": "node", "noImplicitAny": true, "noImplicitReturns": true,