refactor(modal): move keyboard behavior for gestures into component (#24650)

This commit is contained in:
Sean Perkins
2022-01-25 12:25:16 -05:00
committed by GitHub
parent 525f01f086
commit 6f66d08ba8
3 changed files with 39 additions and 49 deletions

View File

@ -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();
/**
* 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;
};

View File

@ -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

View File

@ -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;
}