From 6f66d08ba83abe004db95f5038d99337b663df59 Mon Sep 17 00:00:00 2001 From: Sean Perkins Date: Tue, 25 Jan 2022 12:25:16 -0500 Subject: [PATCH] refactor(modal): move keyboard behavior for gestures into component (#24650) --- core/src/components/modal/gestures/sheet.ts | 49 ++++----------------- core/src/components/modal/modal.tsx | 31 +++++++++++++ core/src/utils/gesture/index.ts | 8 ---- 3 files changed, 39 insertions(+), 49 deletions(-) diff --git a/core/src/components/modal/gestures/sheet.ts b/core/src/components/modal/gestures/sheet.ts index a18193d1f9..1dff393e4b 100644 --- a/core/src/components/modal/gestures/sheet.ts +++ b/core/src/components/modal/gestures/sheet.ts @@ -1,7 +1,6 @@ import { Animation } from '../../../interface'; import { GestureDetail, createGesture } from '../../../utils/gesture'; import { clamp, raf } from '../../../utils/helpers'; -import { KEYBOARD_DID_OPEN } from '../../../utils/keyboard/keyboard'; import { getBackdropValueForSheet } from '../utils'; export const createSheetGesture = ( @@ -43,27 +42,6 @@ export const createSheetGesture = ( const backdropAnimation = animation.childAnimations.find(ani => ani.id === 'backdropAnimation'); const maxBreakpoint = breakpoints[breakpoints.length - 1]; - const keyboardOpenCallback = () => { - /** - * When the native keyboard is opened and the webview - * is resized, the gesture implementation will become unresponsive - * and enter a free-scroll mode. - * - * When the keyboard is opened, we disable the gesture for - * a single frame and re-enable once the contents have repositioned - * from the keyboard placement. - */ - gesture.enable(false); - raf(() => { - gesture.enable(true) - }); - }; - - /* tslint:disable-next-line */ - if (typeof window !== 'undefined') { - window.addEventListener(KEYBOARD_DID_OPEN, keyboardOpenCallback); - } - /** * After the entering animation completes, * we need to set the animation to go from @@ -115,16 +93,13 @@ export const createSheetGesture = ( contentEl.scrollY = false; } - /* tslint:disable-next-line */ - if (typeof document !== 'undefined') { - const activeElement = baseEl.ownerDocument.activeElement as HTMLElement; - if (activeElement.matches('input,ion-input,textarea,ion-textarea')) { - raf(() => { - // Dismisses the open keyboard when the sheet drag gesture is started. - activeElement.blur(); - }); - } - } + raf(() => { + /** + * Dismisses the open keyboard when the sheet drag gesture is started. + * Sets the focus onto the modal element. + */ + baseEl.focus(); + }); animation.progressStart(true, 1 - currentBreakpoint); }; @@ -234,13 +209,6 @@ export const createSheetGesture = ( } }; - const onDestroy = () => { - /* tslint:disable-next-line */ - if (typeof window !== 'undefined') { - window.removeEventListener(KEYBOARD_DID_OPEN, keyboardOpenCallback); - } - } - const gesture = createGesture({ el: wrapperEl, gestureName: 'modalSheet', @@ -250,8 +218,7 @@ export const createSheetGesture = ( canStart, onStart, onMove, - onEnd, - onDestroy + onEnd }); return gesture; }; diff --git a/core/src/components/modal/modal.tsx b/core/src/components/modal/modal.tsx index 4e2f52838e..c1e1a996c5 100644 --- a/core/src/components/modal/modal.tsx +++ b/core/src/components/modal/modal.tsx @@ -5,6 +5,7 @@ import { getIonMode } from '../../global/ionic-global'; import { Animation, AnimationBuilder, ComponentProps, ComponentRef, FrameworkDelegate, Gesture, ModalAttributes, OverlayEventDetail, OverlayInterface } from '../../interface'; import { CoreDelegate, attachComponent, detachComponent } from '../../utils/framework-delegate'; import { raf } from '../../utils/helpers'; +import { KEYBOARD_DID_OPEN } from '../../utils/keyboard/keyboard'; import { BACKDROP, activeAnimations, dismiss, eventMethod, prepareOverlay, present } from '../../utils/overlays'; import { getClassMap } from '../../utils/theme'; import { deepReady } from '../../utils/transition'; @@ -44,6 +45,7 @@ export class Modal implements ComponentInterface, OverlayInterface { private currentBreakpoint?: number; private wrapperEl?: HTMLElement; private backdropEl?: HTMLIonBackdropElement; + private keyboardOpenCallback?: () => void; private inline = false; private workingDelegate?: FrameworkDelegate; @@ -380,6 +382,30 @@ export class Modal implements ComponentInterface, OverlayInterface { this.initSwipeToClose(); } + /* tslint:disable-next-line */ + if (typeof window !== 'undefined') { + this.keyboardOpenCallback = () => { + if (this.gesture) { + /** + * When the native keyboard is opened and the webview + * is resized, the gesture implementation will become unresponsive + * and enter a free-scroll mode. + * + * When the keyboard is opened, we disable the gesture for + * a single frame and re-enable once the contents have repositioned + * from the keyboard placement. + */ + this.gesture.enable(false); + raf(() => { + if (this.gesture) { + this.gesture.enable(true) + } + }); + } + } + window.addEventListener(KEYBOARD_DID_OPEN, this.keyboardOpenCallback); + } + this.currentTransition = undefined; } @@ -474,6 +500,11 @@ export class Modal implements ComponentInterface, OverlayInterface { return false; } + /* tslint:disable-next-line */ + if (typeof window !== 'undefined' && this.keyboardOpenCallback) { + window.removeEventListener(KEYBOARD_DID_OPEN, this.keyboardOpenCallback); + } + /** * When using an inline modal * and presenting a modal it is possible to diff --git a/core/src/utils/gesture/index.ts b/core/src/utils/gesture/index.ts index 063037cdbc..5de39688bb 100644 --- a/core/src/utils/gesture/index.ts +++ b/core/src/utils/gesture/index.ts @@ -231,9 +231,6 @@ export const createGesture = (config: GestureConfig): Gesture => { destroy() { gesture.destroy(); pointerEvents.destroy(); - if (config.onDestroy !== undefined) { - config.onDestroy(); - } } }; }; @@ -328,11 +325,6 @@ export interface GestureConfig { onStart?: GestureCallback; onMove?: GestureCallback; onEnd?: GestureCallback; - /** - * Callback to extend the behavior when a gesture - * handler is destroyed. - */ - onDestroy?: () => void; notCaptured?: GestureCallback; }