mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-20 04:14:21 +08:00
refactor(keyboard): move to utils
This commit is contained in:
37
core/src/components.d.ts
vendored
37
core/src/components.d.ts
vendored
@ -113,6 +113,7 @@ declare global {
|
|||||||
cssClass?: string;
|
cssClass?: string;
|
||||||
enableBackdropDismiss?: boolean;
|
enableBackdropDismiss?: boolean;
|
||||||
enterAnimation?: AnimationBuilder;
|
enterAnimation?: AnimationBuilder;
|
||||||
|
keyboardClose?: boolean;
|
||||||
leaveAnimation?: AnimationBuilder;
|
leaveAnimation?: AnimationBuilder;
|
||||||
overlayId?: number;
|
overlayId?: number;
|
||||||
subTitle?: string;
|
subTitle?: string;
|
||||||
@ -183,6 +184,7 @@ declare global {
|
|||||||
enableBackdropDismiss?: boolean;
|
enableBackdropDismiss?: boolean;
|
||||||
enterAnimation?: AnimationBuilder;
|
enterAnimation?: AnimationBuilder;
|
||||||
inputs?: AlertInput[];
|
inputs?: AlertInput[];
|
||||||
|
keyboardClose?: boolean;
|
||||||
leaveAnimation?: AnimationBuilder;
|
leaveAnimation?: AnimationBuilder;
|
||||||
message?: string;
|
message?: string;
|
||||||
overlayId?: number;
|
overlayId?: number;
|
||||||
@ -1519,36 +1521,6 @@ declare global {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
import {
|
|
||||||
KeyboardController as IonKeyboardController
|
|
||||||
} from './components/keyboard-controller/keyboard-controller';
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface HTMLIonKeyboardControllerElement extends IonKeyboardController, HTMLStencilElement {
|
|
||||||
}
|
|
||||||
var HTMLIonKeyboardControllerElement: {
|
|
||||||
prototype: HTMLIonKeyboardControllerElement;
|
|
||||||
new (): HTMLIonKeyboardControllerElement;
|
|
||||||
};
|
|
||||||
interface HTMLElementTagNameMap {
|
|
||||||
"ion-keyboard-controller": HTMLIonKeyboardControllerElement;
|
|
||||||
}
|
|
||||||
interface ElementTagNameMap {
|
|
||||||
"ion-keyboard-controller": HTMLIonKeyboardControllerElement;
|
|
||||||
}
|
|
||||||
namespace JSX {
|
|
||||||
interface IntrinsicElements {
|
|
||||||
"ion-keyboard-controller": JSXElements.IonKeyboardControllerAttributes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
namespace JSXElements {
|
|
||||||
export interface IonKeyboardControllerAttributes extends HTMLAttributes {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Label as IonLabel
|
Label as IonLabel
|
||||||
} from './components/label/label';
|
} from './components/label/label';
|
||||||
@ -1704,6 +1676,7 @@ declare global {
|
|||||||
duration?: number;
|
duration?: number;
|
||||||
enableBackdropDismiss?: boolean;
|
enableBackdropDismiss?: boolean;
|
||||||
enterAnimation?: AnimationBuilder;
|
enterAnimation?: AnimationBuilder;
|
||||||
|
keyboardClose?: boolean;
|
||||||
leaveAnimation?: AnimationBuilder;
|
leaveAnimation?: AnimationBuilder;
|
||||||
overlayId?: number;
|
overlayId?: number;
|
||||||
showBackdrop?: boolean;
|
showBackdrop?: boolean;
|
||||||
@ -1905,6 +1878,7 @@ declare global {
|
|||||||
delegate?: FrameworkDelegate;
|
delegate?: FrameworkDelegate;
|
||||||
enableBackdropDismiss?: boolean;
|
enableBackdropDismiss?: boolean;
|
||||||
enterAnimation?: AnimationBuilder;
|
enterAnimation?: AnimationBuilder;
|
||||||
|
keyboardClose?: boolean;
|
||||||
leaveAnimation?: AnimationBuilder;
|
leaveAnimation?: AnimationBuilder;
|
||||||
mode?: 'ios' | 'md';
|
mode?: 'ios' | 'md';
|
||||||
overlayId?: number;
|
overlayId?: number;
|
||||||
@ -2162,6 +2136,7 @@ declare global {
|
|||||||
duration?: number;
|
duration?: number;
|
||||||
enableBackdropDismiss?: boolean;
|
enableBackdropDismiss?: boolean;
|
||||||
enterAnimation?: AnimationBuilder;
|
enterAnimation?: AnimationBuilder;
|
||||||
|
keyboardClose?: boolean;
|
||||||
leaveAnimation?: AnimationBuilder;
|
leaveAnimation?: AnimationBuilder;
|
||||||
overlayId?: number;
|
overlayId?: number;
|
||||||
showBackdrop?: boolean;
|
showBackdrop?: boolean;
|
||||||
@ -2263,6 +2238,7 @@ declare global {
|
|||||||
enableBackdropDismiss?: boolean;
|
enableBackdropDismiss?: boolean;
|
||||||
enterAnimation?: AnimationBuilder;
|
enterAnimation?: AnimationBuilder;
|
||||||
ev?: any;
|
ev?: any;
|
||||||
|
keyboardClose?: boolean;
|
||||||
leaveAnimation?: AnimationBuilder;
|
leaveAnimation?: AnimationBuilder;
|
||||||
mode?: 'ios' | 'md';
|
mode?: 'ios' | 'md';
|
||||||
overlayId?: number;
|
overlayId?: number;
|
||||||
@ -3540,6 +3516,7 @@ declare global {
|
|||||||
dismissOnPageChange?: boolean;
|
dismissOnPageChange?: boolean;
|
||||||
duration?: number;
|
duration?: number;
|
||||||
enterAnimation?: AnimationBuilder;
|
enterAnimation?: AnimationBuilder;
|
||||||
|
keyboardClose?: boolean;
|
||||||
leaveAnimation?: AnimationBuilder;
|
leaveAnimation?: AnimationBuilder;
|
||||||
message?: string;
|
message?: string;
|
||||||
overlayId?: number;
|
overlayId?: number;
|
||||||
|
@ -32,6 +32,7 @@ export class ActionSheet implements OverlayInterface {
|
|||||||
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement;
|
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement;
|
||||||
@Prop({ context: 'config' }) config: Config;
|
@Prop({ context: 'config' }) config: Config;
|
||||||
@Prop() overlayId: number;
|
@Prop() overlayId: number;
|
||||||
|
@Prop() keyboardClose = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animation to use when the action sheet is presented.
|
* Animation to use when the action sheet is presented.
|
||||||
|
@ -89,6 +89,11 @@ If true, the action sheet will be dismissed when the backdrop is clicked. Defaul
|
|||||||
Animation to use when the action sheet is presented.
|
Animation to use when the action sheet is presented.
|
||||||
|
|
||||||
|
|
||||||
|
#### keyboardClose
|
||||||
|
|
||||||
|
boolean
|
||||||
|
|
||||||
|
|
||||||
#### leaveAnimation
|
#### leaveAnimation
|
||||||
|
|
||||||
|
|
||||||
@ -160,6 +165,11 @@ If true, the action sheet will be dismissed when the backdrop is clicked. Defaul
|
|||||||
Animation to use when the action sheet is presented.
|
Animation to use when the action sheet is presented.
|
||||||
|
|
||||||
|
|
||||||
|
#### keyboard-close
|
||||||
|
|
||||||
|
boolean
|
||||||
|
|
||||||
|
|
||||||
#### leave-animation
|
#### leave-animation
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core';
|
import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core';
|
||||||
import { Animation, AnimationBuilder, Config, CssClassMap } from '../../index';
|
import { Animation, AnimationBuilder, Config, CssClassMap } from '../../index';
|
||||||
import { createThemedClasses, getClassMap } from '../../utils/theme';
|
import { createThemedClasses, getClassMap } from '../../utils/theme';
|
||||||
import { BACKDROP, OverlayEventDetail, OverlayInterface, autoFocus, dismiss, eventMethod, isCancel, present } from '../../utils/overlays';
|
import { BACKDROP, OverlayEventDetail, OverlayInterface, dismiss, eventMethod, isCancel, present } from '../../utils/overlays';
|
||||||
|
|
||||||
import iosEnterAnimation from './animations/ios.enter';
|
import iosEnterAnimation from './animations/ios.enter';
|
||||||
import iosLeaveAnimation from './animations/ios.leave';
|
import iosLeaveAnimation from './animations/ios.leave';
|
||||||
@ -35,6 +35,7 @@ export class Alert implements OverlayInterface {
|
|||||||
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement;
|
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement;
|
||||||
@Prop({ context: 'config' }) config: Config;
|
@Prop({ context: 'config' }) config: Config;
|
||||||
@Prop() overlayId: number;
|
@Prop() overlayId: number;
|
||||||
|
@Prop() keyboardClose = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animation to use when the alert is presented.
|
* Animation to use when the alert is presented.
|
||||||
@ -150,9 +151,7 @@ export class Alert implements OverlayInterface {
|
|||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
present(): Promise<void> {
|
present(): Promise<void> {
|
||||||
return present(this, 'alertEnter', iosEnterAnimation, mdEnterAnimation).then(() => {
|
return present(this, 'alertEnter', iosEnterAnimation, mdEnterAnimation);
|
||||||
autoFocus(this.el);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -76,6 +76,11 @@ Animation to use when the alert is presented.
|
|||||||
Array of input to show in the alert.
|
Array of input to show in the alert.
|
||||||
|
|
||||||
|
|
||||||
|
#### keyboardClose
|
||||||
|
|
||||||
|
boolean
|
||||||
|
|
||||||
|
|
||||||
#### leaveAnimation
|
#### leaveAnimation
|
||||||
|
|
||||||
|
|
||||||
@ -161,6 +166,11 @@ Animation to use when the alert is presented.
|
|||||||
Array of input to show in the alert.
|
Array of input to show in the alert.
|
||||||
|
|
||||||
|
|
||||||
|
#### keyboard-close
|
||||||
|
|
||||||
|
boolean
|
||||||
|
|
||||||
|
|
||||||
#### leave-animation
|
#### leave-animation
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,212 +0,0 @@
|
|||||||
import { Component, Event, EventEmitter, Prop} from '@stencil/core';
|
|
||||||
import { Config } from '../..';
|
|
||||||
import { KEY_TAB } from './keys';
|
|
||||||
|
|
||||||
let v2KeyboardWillShowHandler: () => void = null;
|
|
||||||
let v2KeyboardWillHideHandler: () => void = null;
|
|
||||||
let v2KeyboardDidShowHandler: () => void = null;
|
|
||||||
let v2KeyboardDidHideHandler: () => void = null;
|
|
||||||
let v1keyboardHide: () => void = null;
|
|
||||||
let v1keyboardShow: () => void = null;
|
|
||||||
let timeoutValue: number = null;
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
tag: 'ion-keyboard-controller'
|
|
||||||
})
|
|
||||||
export class KeyboardController {
|
|
||||||
|
|
||||||
@Prop({context: 'config'}) config: Config;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Emitted before the keyboard has shown.
|
|
||||||
*/
|
|
||||||
@Event() keyboardWillShow: EventEmitter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Emitted after the keyboard has shown.
|
|
||||||
*/
|
|
||||||
@Event() keyboardDidShow: EventEmitter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Emitted before the keyboard has hidden.
|
|
||||||
*/
|
|
||||||
@Event() keyboardWillHide: EventEmitter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Emitted after the keyboard has hidden.
|
|
||||||
*/
|
|
||||||
@Event() keyboardDidHide: EventEmitter;
|
|
||||||
|
|
||||||
componentDidLoad() {
|
|
||||||
componentDidLoadImpl(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
isOpen(): boolean {
|
|
||||||
return hasFocusedTextInput();
|
|
||||||
}
|
|
||||||
|
|
||||||
onClose(callback: Function, pollingInterval: number = KEYBOARD_CLOSE_POLLING, maxPollingChecks: number = KEYBOARD_POLLING_CHECKS_MAX): Promise<any> {
|
|
||||||
|
|
||||||
return onCloseImpl(this, callback, pollingInterval, maxPollingChecks);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function onCloseImpl(keyboardController: KeyboardController, callback: Function, pollingInterval: number, maxPollingChecks: number): Promise<any> {
|
|
||||||
let numChecks = 0;
|
|
||||||
|
|
||||||
const promise: Promise<any> = callback ? null : new Promise((resolve) => {
|
|
||||||
callback = resolve;
|
|
||||||
});
|
|
||||||
|
|
||||||
const checkKeyBoard = () => {
|
|
||||||
if (!keyboardController.isOpen() || numChecks > maxPollingChecks) {
|
|
||||||
setTimeout(() => {
|
|
||||||
callback();
|
|
||||||
}, 400);
|
|
||||||
} else {
|
|
||||||
setTimeout(checkKeyBoard, pollingInterval);
|
|
||||||
}
|
|
||||||
numChecks++;
|
|
||||||
};
|
|
||||||
|
|
||||||
setTimeout(checkKeyBoard, pollingInterval);
|
|
||||||
return promise;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function componentDidLoadImpl(keyboardController: KeyboardController) {
|
|
||||||
focusOutline(document, keyboardController.config.get('focusOutline'));
|
|
||||||
if (keyboardController.config.getBoolean('keyboardResizes', false)) {
|
|
||||||
listenV2(window, keyboardController);
|
|
||||||
} else {
|
|
||||||
listenV1(window, keyboardController);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function listenV2(win: Window, keyboardController: KeyboardController) {
|
|
||||||
v2KeyboardWillShowHandler = () => {
|
|
||||||
keyboardController.keyboardWillShow.emit();
|
|
||||||
};
|
|
||||||
win.addEventListener('keyboardWillShow', v2KeyboardWillShowHandler);
|
|
||||||
|
|
||||||
v2KeyboardWillHideHandler = () => {
|
|
||||||
keyboardController.keyboardWillHide.emit();
|
|
||||||
};
|
|
||||||
win.addEventListener('keyboardWillHide', v2KeyboardWillHideHandler);
|
|
||||||
|
|
||||||
v2KeyboardDidShowHandler = () => {
|
|
||||||
keyboardController.keyboardDidShow.emit();
|
|
||||||
};
|
|
||||||
win.addEventListener('keyboardDidShow', v2KeyboardDidShowHandler);
|
|
||||||
|
|
||||||
v2KeyboardDidHideHandler = () => {
|
|
||||||
keyboardController.keyboardDidHide.emit();
|
|
||||||
};
|
|
||||||
win.addEventListener('keyboardDidHide', v2KeyboardDidHideHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function listenV1(win: Window, keyboardController: KeyboardController) {
|
|
||||||
v1keyboardHide = () => {
|
|
||||||
blurActiveInput(true, keyboardController);
|
|
||||||
};
|
|
||||||
win.addEventListener('native.keyboardhide', v1keyboardHide);
|
|
||||||
|
|
||||||
v1keyboardShow = () => {
|
|
||||||
blurActiveInput(false, keyboardController);
|
|
||||||
};
|
|
||||||
win.addEventListener('native.keyboardshow', v1keyboardShow);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function blurActiveInput(shouldBlur: boolean, keyboardController: KeyboardController) {
|
|
||||||
clearTimeout(timeoutValue);
|
|
||||||
if (shouldBlur) {
|
|
||||||
timeoutValue = setTimeout(() => {
|
|
||||||
if (keyboardController.isOpen()) {
|
|
||||||
focusOutActiveElement();
|
|
||||||
}
|
|
||||||
}, 80) as any as number;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function focusOutline(doc: Document, value: boolean) {
|
|
||||||
/* Focus Outline
|
|
||||||
* --------------------------------------------------
|
|
||||||
* By default, when a keydown event happens from a tab key, then
|
|
||||||
* the 'focus-outline' css class is added to the body element
|
|
||||||
* so focusable elements have an outline. On a mousedown or
|
|
||||||
* touchstart event, then the 'focus-outline' css class is removed.
|
|
||||||
*
|
|
||||||
* Config default overrides:
|
|
||||||
* focusOutline: true - Always add the focus-outline
|
|
||||||
* focusOutline: false - Do not add the focus-outline
|
|
||||||
*/
|
|
||||||
|
|
||||||
let isKeyInputEnabled = false;
|
|
||||||
|
|
||||||
const cssClass = () => {
|
|
||||||
window.requestAnimationFrame(() => {
|
|
||||||
doc.body.classList[isKeyInputEnabled ? 'add' : 'remove']('focus-outline');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
if (value === true) {
|
|
||||||
isKeyInputEnabled = true;
|
|
||||||
return cssClass();
|
|
||||||
} else if (value === false) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const keyDownHandler = (event: KeyboardEvent) => {
|
|
||||||
if (!isKeyInputEnabled && event.keyCode === KEY_TAB) {
|
|
||||||
isKeyInputEnabled = true;
|
|
||||||
enableKeyInput();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const pointerDown = () => {
|
|
||||||
isKeyInputEnabled = false;
|
|
||||||
enableKeyInput();
|
|
||||||
};
|
|
||||||
|
|
||||||
const enableKeyInput = () => {
|
|
||||||
cssClass();
|
|
||||||
|
|
||||||
doc.removeEventListener('mousedown', pointerDown);
|
|
||||||
doc.removeEventListener('touchstart', pointerDown);
|
|
||||||
|
|
||||||
if (isKeyInputEnabled) {
|
|
||||||
doc.addEventListener('mousedown', pointerDown);
|
|
||||||
doc.addEventListener('touchstart', pointerDown);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
doc.addEventListener('keydown', keyDownHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function hasFocusedTextInput() {
|
|
||||||
const activeElement = document.activeElement;
|
|
||||||
if (isTextInput(activeElement) && activeElement.parentElement) {
|
|
||||||
return activeElement.parentElement.querySelector(':focus') === activeElement;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const NON_TEXT_INPUT_REGEX = /^(radio|checkbox|range|file|submit|reset|color|image|button)$/i;
|
|
||||||
|
|
||||||
function isTextInput(el: any) {
|
|
||||||
return !!el &&
|
|
||||||
(el.tagName === 'TEXTAREA'
|
|
||||||
|| el.contentEditable === 'true'
|
|
||||||
|| (el.tagName === 'INPUT' && !(NON_TEXT_INPUT_REGEX.test(el.type))));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function focusOutActiveElement() {
|
|
||||||
const activeElement = document.activeElement as HTMLElement;
|
|
||||||
activeElement && activeElement.blur && activeElement.blur();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const KEYBOARD_CLOSE_POLLING = 150;
|
|
||||||
const KEYBOARD_POLLING_CHECKS_MAX = 100;
|
|
@ -1,9 +0,0 @@
|
|||||||
|
|
||||||
export const KEY_LEFT = 37;
|
|
||||||
export const KEY_UP = 38;
|
|
||||||
export const KEY_RIGHT = 39;
|
|
||||||
export const KEY_DOWN = 40;
|
|
||||||
export const KEY_ENTER = 13;
|
|
||||||
export const KEY_ESCAPE = 27;
|
|
||||||
export const KEY_SPACE = 32;
|
|
||||||
export const KEY_TAB = 9;
|
|
@ -1,33 +0,0 @@
|
|||||||
# ion-keyboard-controller
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Auto Generated Below -->
|
|
||||||
|
|
||||||
|
|
||||||
## Events
|
|
||||||
|
|
||||||
#### keyboardDidHide
|
|
||||||
|
|
||||||
Emitted after the keyboard has hidden.
|
|
||||||
|
|
||||||
|
|
||||||
#### keyboardDidShow
|
|
||||||
|
|
||||||
Emitted after the keyboard has shown.
|
|
||||||
|
|
||||||
|
|
||||||
#### keyboardWillHide
|
|
||||||
|
|
||||||
Emitted before the keyboard has hidden.
|
|
||||||
|
|
||||||
|
|
||||||
#### keyboardWillShow
|
|
||||||
|
|
||||||
Emitted before the keyboard has shown.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------
|
|
||||||
|
|
||||||
*Built with [StencilJS](https://stenciljs.com/)*
|
|
@ -33,6 +33,7 @@ export class Loading implements OverlayInterface {
|
|||||||
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement;
|
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement;
|
||||||
@Prop({ context: 'config' }) config: Config;
|
@Prop({ context: 'config' }) config: Config;
|
||||||
@Prop() overlayId: number;
|
@Prop() overlayId: number;
|
||||||
|
@Prop() keyboardClose = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animation to use when the loading indicator is presented.
|
* Animation to use when the loading indicator is presented.
|
||||||
|
@ -76,6 +76,11 @@ If true, the loading indicator will be dismissed when the backdrop is clicked. D
|
|||||||
Animation to use when the loading indicator is presented.
|
Animation to use when the loading indicator is presented.
|
||||||
|
|
||||||
|
|
||||||
|
#### keyboardClose
|
||||||
|
|
||||||
|
boolean
|
||||||
|
|
||||||
|
|
||||||
#### leaveAnimation
|
#### leaveAnimation
|
||||||
|
|
||||||
|
|
||||||
@ -162,6 +167,11 @@ If true, the loading indicator will be dismissed when the backdrop is clicked. D
|
|||||||
Animation to use when the loading indicator is presented.
|
Animation to use when the loading indicator is presented.
|
||||||
|
|
||||||
|
|
||||||
|
#### keyboard-close
|
||||||
|
|
||||||
|
boolean
|
||||||
|
|
||||||
|
|
||||||
#### leave-animation
|
#### leave-animation
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ export class Modal implements OverlayInterface {
|
|||||||
|
|
||||||
@Prop() overlayId: number;
|
@Prop() overlayId: number;
|
||||||
@Prop() delegate: FrameworkDelegate;
|
@Prop() delegate: FrameworkDelegate;
|
||||||
|
@Prop() keyboardClose = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The color to use from your Sass `$colors` map.
|
* The color to use from your Sass `$colors` map.
|
||||||
|
@ -98,6 +98,11 @@ If true, the modal will be dismissed when the backdrop is clicked. Defaults to `
|
|||||||
Animation to use when the modal is presented.
|
Animation to use when the modal is presented.
|
||||||
|
|
||||||
|
|
||||||
|
#### keyboardClose
|
||||||
|
|
||||||
|
boolean
|
||||||
|
|
||||||
|
|
||||||
#### leaveAnimation
|
#### leaveAnimation
|
||||||
|
|
||||||
|
|
||||||
@ -185,6 +190,11 @@ If true, the modal will be dismissed when the backdrop is clicked. Defaults to `
|
|||||||
Animation to use when the modal is presented.
|
Animation to use when the modal is presented.
|
||||||
|
|
||||||
|
|
||||||
|
#### keyboard-close
|
||||||
|
|
||||||
|
boolean
|
||||||
|
|
||||||
|
|
||||||
#### leave-animation
|
#### leave-animation
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { ViewController, isViewController } from './view-controller';
|
import { ViewController, isViewController } from './view-controller';
|
||||||
import { NavControllerBase } from './nav';
|
import { NavControllerBase } from './nav';
|
||||||
import { Transition } from './transition';
|
import { Transition } from './transition';
|
||||||
|
import { FrameworkDelegate } from '../..';
|
||||||
|
|
||||||
export function convertToView(page: any, params: any): ViewController {
|
export function convertToView(page: any, params: any): ViewController {
|
||||||
if (!page) {
|
if (!page) {
|
||||||
@ -81,11 +82,8 @@ export interface NavOptions {
|
|||||||
id?: string;
|
id?: string;
|
||||||
keyboardClose?: boolean;
|
keyboardClose?: boolean;
|
||||||
progressAnimation?: boolean;
|
progressAnimation?: boolean;
|
||||||
disableApp?: boolean;
|
|
||||||
minClickBlockDuration?: number;
|
|
||||||
ev?: any;
|
ev?: any;
|
||||||
updateUrl?: boolean;
|
delegate?: FrameworkDelegate;
|
||||||
isNavRoot?: boolean;
|
|
||||||
viewIsReady?: () => Promise<any>;
|
viewIsReady?: () => Promise<any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ export class Picker implements OverlayInterface {
|
|||||||
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement;
|
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement;
|
||||||
@Prop({ context: 'config' }) config: Config;
|
@Prop({ context: 'config' }) config: Config;
|
||||||
@Prop() overlayId: number;
|
@Prop() overlayId: number;
|
||||||
|
@Prop() keyboardClose = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animation to use when the picker is presented.
|
* Animation to use when the picker is presented.
|
||||||
@ -145,10 +146,6 @@ export class Picker implements OverlayInterface {
|
|||||||
@Method()
|
@Method()
|
||||||
present(): Promise<void> {
|
present(): Promise<void> {
|
||||||
return present(this, 'pickerEnter', iosEnterAnimation, iosEnterAnimation, undefined).then(() => {
|
return present(this, 'pickerEnter', iosEnterAnimation, iosEnterAnimation, undefined).then(() => {
|
||||||
// blur the currently active element
|
|
||||||
const activeElement: any = document.activeElement;
|
|
||||||
activeElement && activeElement.blur && activeElement.blur();
|
|
||||||
|
|
||||||
// If there is a duration, dismiss after that amount of time
|
// If there is a duration, dismiss after that amount of time
|
||||||
if (this.duration > 10) {
|
if (this.duration > 10) {
|
||||||
this.durationTimeout = setTimeout(() => this.dismiss(), this.duration);
|
this.durationTimeout = setTimeout(() => this.dismiss(), this.duration);
|
||||||
|
@ -52,6 +52,11 @@ If true, the picker will be dismissed when the backdrop is clicked. Defaults to
|
|||||||
Animation to use when the picker is presented.
|
Animation to use when the picker is presented.
|
||||||
|
|
||||||
|
|
||||||
|
#### keyboardClose
|
||||||
|
|
||||||
|
boolean
|
||||||
|
|
||||||
|
|
||||||
#### leaveAnimation
|
#### leaveAnimation
|
||||||
|
|
||||||
|
|
||||||
@ -123,6 +128,11 @@ If true, the picker will be dismissed when the backdrop is clicked. Defaults to
|
|||||||
Animation to use when the picker is presented.
|
Animation to use when the picker is presented.
|
||||||
|
|
||||||
|
|
||||||
|
#### keyboard-close
|
||||||
|
|
||||||
|
boolean
|
||||||
|
|
||||||
|
|
||||||
#### leave-animation
|
#### leave-animation
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ export class Popover implements OverlayInterface {
|
|||||||
@Prop({ context: 'config' }) config: Config;
|
@Prop({ context: 'config' }) config: Config;
|
||||||
@Prop() delegate: FrameworkDelegate;
|
@Prop() delegate: FrameworkDelegate;
|
||||||
@Prop() overlayId: number;
|
@Prop() overlayId: number;
|
||||||
|
@Prop() keyboardClose = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The color to use from your Sass `$colors` map.
|
* The color to use from your Sass `$colors` map.
|
||||||
|
@ -85,6 +85,11 @@ any
|
|||||||
The event to pass to the popover animation.
|
The event to pass to the popover animation.
|
||||||
|
|
||||||
|
|
||||||
|
#### keyboardClose
|
||||||
|
|
||||||
|
boolean
|
||||||
|
|
||||||
|
|
||||||
#### leaveAnimation
|
#### leaveAnimation
|
||||||
|
|
||||||
|
|
||||||
@ -186,6 +191,11 @@ any
|
|||||||
The event to pass to the popover animation.
|
The event to pass to the popover animation.
|
||||||
|
|
||||||
|
|
||||||
|
#### keyboard-close
|
||||||
|
|
||||||
|
boolean
|
||||||
|
|
||||||
|
|
||||||
#### leave-animation
|
#### leave-animation
|
||||||
|
|
||||||
|
|
||||||
|
@ -80,6 +80,11 @@ until `dismiss()` is called.
|
|||||||
Animation to use when the toast is presented.
|
Animation to use when the toast is presented.
|
||||||
|
|
||||||
|
|
||||||
|
#### keyboardClose
|
||||||
|
|
||||||
|
boolean
|
||||||
|
|
||||||
|
|
||||||
#### leaveAnimation
|
#### leaveAnimation
|
||||||
|
|
||||||
|
|
||||||
@ -166,6 +171,11 @@ until `dismiss()` is called.
|
|||||||
Animation to use when the toast is presented.
|
Animation to use when the toast is presented.
|
||||||
|
|
||||||
|
|
||||||
|
#### keyboard-close
|
||||||
|
|
||||||
|
boolean
|
||||||
|
|
||||||
|
|
||||||
#### leave-animation
|
#### leave-animation
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ export class Toast implements OverlayInterface {
|
|||||||
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement;
|
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement;
|
||||||
@Prop({ context: 'config' }) config: Config;
|
@Prop({ context: 'config' }) config: Config;
|
||||||
@Prop() overlayId: number;
|
@Prop() overlayId: number;
|
||||||
|
@Prop() keyboardClose = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animation to use when the toast is presented.
|
* Animation to use when the toast is presented.
|
||||||
|
2
core/src/index.d.ts
vendored
2
core/src/index.d.ts
vendored
@ -44,8 +44,6 @@ export { Item } from './components/item/item';
|
|||||||
export { ItemDivider } from './components/item-divider/item-divider';
|
export { ItemDivider } from './components/item-divider/item-divider';
|
||||||
export { ItemOption } from './components/item-option/item-option';
|
export { ItemOption } from './components/item-option/item-option';
|
||||||
export { ItemSliding } from './components/item-sliding/item-sliding';
|
export { ItemSliding } from './components/item-sliding/item-sliding';
|
||||||
export { KeyboardController } from './components/keyboard-controller/keyboard-controller';
|
|
||||||
export * from './components/keyboard-controller/keys';
|
|
||||||
export { Label } from './components/label/label';
|
export { Label } from './components/label/label';
|
||||||
export { List } from './components/list/list';
|
export { List } from './components/list/list';
|
||||||
export { ListHeader } from './components/list-header/list-header';
|
export { ListHeader } from './components/list-header/list-header';
|
||||||
|
2
core/src/utils/index.ts
Normal file
2
core/src/utils/index.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './haptic';
|
||||||
|
export * from './keyboard';
|
22
core/src/utils/keyboard.ts
Normal file
22
core/src/utils/keyboard.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
export function isTextInputFocused(): boolean {
|
||||||
|
const activeElement = document.activeElement;
|
||||||
|
if (isTextInput(activeElement) && activeElement.parentElement) {
|
||||||
|
return activeElement.parentElement.querySelector(':focus') === activeElement;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function closeKeyboard() {
|
||||||
|
const activeElement = document.activeElement as HTMLElement;
|
||||||
|
activeElement && activeElement.blur && activeElement.blur();
|
||||||
|
}
|
||||||
|
|
||||||
|
const NON_TEXT_INPUT_REGEX = /^(radio|checkbox|range|file|submit|reset|color|image|button)$/i;
|
||||||
|
|
||||||
|
function isTextInput(el: any) {
|
||||||
|
return !!el &&
|
||||||
|
(el.tagName === 'TEXTAREA'
|
||||||
|
|| el.contentEditable === 'true'
|
||||||
|
|| (el.tagName === 'INPUT' && !(NON_TEXT_INPUT_REGEX.test(el.type))));
|
||||||
|
}
|
@ -115,6 +115,9 @@ function overlayAnimation(
|
|||||||
overlay.animation.destroy();
|
overlay.animation.destroy();
|
||||||
overlay.animation = undefined;
|
overlay.animation = undefined;
|
||||||
}
|
}
|
||||||
|
if (overlay.keyboardClose) {
|
||||||
|
closeKeyboard();
|
||||||
|
}
|
||||||
return overlay.animationCtrl.create(animationBuilder, baseEl, opts).then(animation => {
|
return overlay.animationCtrl.create(animationBuilder, baseEl, opts).then(animation => {
|
||||||
overlay.animation = animation;
|
overlay.animation = animation;
|
||||||
if (!overlay.willAnimate) {
|
if (!overlay.willAnimate) {
|
||||||
@ -170,12 +173,15 @@ export function onceEvent(element: HTMLElement, eventName: string, callback: (ev
|
|||||||
element.addEventListener(eventName, handler);
|
element.addEventListener(eventName, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function closeKeyboard() {
|
||||||
|
const activeElement = document.activeElement as HTMLElement;
|
||||||
|
activeElement && activeElement.blur && activeElement.blur();
|
||||||
|
}
|
||||||
|
|
||||||
export function isCancel(role: string): boolean {
|
export function isCancel(role: string): boolean {
|
||||||
return role === 'cancel' || role === BACKDROP;
|
return role === 'cancel' || role === BACKDROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface OverlayEventDetail {
|
export interface OverlayEventDetail {
|
||||||
data?: any;
|
data?: any;
|
||||||
role?: string;
|
role?: string;
|
||||||
@ -185,6 +191,7 @@ export interface OverlayInterface {
|
|||||||
mode: string;
|
mode: string;
|
||||||
el: HTMLElement;
|
el: HTMLElement;
|
||||||
willAnimate: boolean;
|
willAnimate: boolean;
|
||||||
|
keyboardClose: boolean;
|
||||||
config: Config;
|
config: Config;
|
||||||
overlayId: number;
|
overlayId: number;
|
||||||
presented: boolean;
|
presented: boolean;
|
||||||
|
Reference in New Issue
Block a user