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;
|
||||
enableBackdropDismiss?: boolean;
|
||||
enterAnimation?: AnimationBuilder;
|
||||
keyboardClose?: boolean;
|
||||
leaveAnimation?: AnimationBuilder;
|
||||
overlayId?: number;
|
||||
subTitle?: string;
|
||||
@ -183,6 +184,7 @@ declare global {
|
||||
enableBackdropDismiss?: boolean;
|
||||
enterAnimation?: AnimationBuilder;
|
||||
inputs?: AlertInput[];
|
||||
keyboardClose?: boolean;
|
||||
leaveAnimation?: AnimationBuilder;
|
||||
message?: string;
|
||||
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 {
|
||||
Label as IonLabel
|
||||
} from './components/label/label';
|
||||
@ -1704,6 +1676,7 @@ declare global {
|
||||
duration?: number;
|
||||
enableBackdropDismiss?: boolean;
|
||||
enterAnimation?: AnimationBuilder;
|
||||
keyboardClose?: boolean;
|
||||
leaveAnimation?: AnimationBuilder;
|
||||
overlayId?: number;
|
||||
showBackdrop?: boolean;
|
||||
@ -1905,6 +1878,7 @@ declare global {
|
||||
delegate?: FrameworkDelegate;
|
||||
enableBackdropDismiss?: boolean;
|
||||
enterAnimation?: AnimationBuilder;
|
||||
keyboardClose?: boolean;
|
||||
leaveAnimation?: AnimationBuilder;
|
||||
mode?: 'ios' | 'md';
|
||||
overlayId?: number;
|
||||
@ -2162,6 +2136,7 @@ declare global {
|
||||
duration?: number;
|
||||
enableBackdropDismiss?: boolean;
|
||||
enterAnimation?: AnimationBuilder;
|
||||
keyboardClose?: boolean;
|
||||
leaveAnimation?: AnimationBuilder;
|
||||
overlayId?: number;
|
||||
showBackdrop?: boolean;
|
||||
@ -2263,6 +2238,7 @@ declare global {
|
||||
enableBackdropDismiss?: boolean;
|
||||
enterAnimation?: AnimationBuilder;
|
||||
ev?: any;
|
||||
keyboardClose?: boolean;
|
||||
leaveAnimation?: AnimationBuilder;
|
||||
mode?: 'ios' | 'md';
|
||||
overlayId?: number;
|
||||
@ -3540,6 +3516,7 @@ declare global {
|
||||
dismissOnPageChange?: boolean;
|
||||
duration?: number;
|
||||
enterAnimation?: AnimationBuilder;
|
||||
keyboardClose?: boolean;
|
||||
leaveAnimation?: AnimationBuilder;
|
||||
message?: string;
|
||||
overlayId?: number;
|
||||
|
@ -32,6 +32,7 @@ export class ActionSheet implements OverlayInterface {
|
||||
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement;
|
||||
@Prop({ context: 'config' }) config: Config;
|
||||
@Prop() overlayId: number;
|
||||
@Prop() keyboardClose = true;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
||||
|
||||
#### keyboardClose
|
||||
|
||||
boolean
|
||||
|
||||
|
||||
#### 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.
|
||||
|
||||
|
||||
#### keyboard-close
|
||||
|
||||
boolean
|
||||
|
||||
|
||||
#### leave-animation
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core';
|
||||
import { Animation, AnimationBuilder, Config, CssClassMap } from '../../index';
|
||||
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 iosLeaveAnimation from './animations/ios.leave';
|
||||
@ -35,6 +35,7 @@ export class Alert implements OverlayInterface {
|
||||
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement;
|
||||
@Prop({ context: 'config' }) config: Config;
|
||||
@Prop() overlayId: number;
|
||||
@Prop() keyboardClose = true;
|
||||
|
||||
/**
|
||||
* Animation to use when the alert is presented.
|
||||
@ -150,9 +151,7 @@ export class Alert implements OverlayInterface {
|
||||
*/
|
||||
@Method()
|
||||
present(): Promise<void> {
|
||||
return present(this, 'alertEnter', iosEnterAnimation, mdEnterAnimation).then(() => {
|
||||
autoFocus(this.el);
|
||||
});
|
||||
return present(this, 'alertEnter', iosEnterAnimation, mdEnterAnimation);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,6 +76,11 @@ Animation to use when the alert is presented.
|
||||
Array of input to show in the alert.
|
||||
|
||||
|
||||
#### keyboardClose
|
||||
|
||||
boolean
|
||||
|
||||
|
||||
#### leaveAnimation
|
||||
|
||||
|
||||
@ -161,6 +166,11 @@ Animation to use when the alert is presented.
|
||||
Array of input to show in the alert.
|
||||
|
||||
|
||||
#### keyboard-close
|
||||
|
||||
boolean
|
||||
|
||||
|
||||
#### 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({ context: 'config' }) config: Config;
|
||||
@Prop() overlayId: number;
|
||||
@Prop() keyboardClose = true;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
||||
|
||||
#### keyboardClose
|
||||
|
||||
boolean
|
||||
|
||||
|
||||
#### 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.
|
||||
|
||||
|
||||
#### keyboard-close
|
||||
|
||||
boolean
|
||||
|
||||
|
||||
#### leave-animation
|
||||
|
||||
|
||||
|
@ -34,6 +34,7 @@ export class Modal implements OverlayInterface {
|
||||
|
||||
@Prop() overlayId: number;
|
||||
@Prop() delegate: FrameworkDelegate;
|
||||
@Prop() keyboardClose = true;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
||||
|
||||
#### keyboardClose
|
||||
|
||||
boolean
|
||||
|
||||
|
||||
#### 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.
|
||||
|
||||
|
||||
#### keyboard-close
|
||||
|
||||
boolean
|
||||
|
||||
|
||||
#### leave-animation
|
||||
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { ViewController, isViewController } from './view-controller';
|
||||
import { NavControllerBase } from './nav';
|
||||
import { Transition } from './transition';
|
||||
import { FrameworkDelegate } from '../..';
|
||||
|
||||
export function convertToView(page: any, params: any): ViewController {
|
||||
if (!page) {
|
||||
@ -81,11 +82,8 @@ export interface NavOptions {
|
||||
id?: string;
|
||||
keyboardClose?: boolean;
|
||||
progressAnimation?: boolean;
|
||||
disableApp?: boolean;
|
||||
minClickBlockDuration?: number;
|
||||
ev?: any;
|
||||
updateUrl?: boolean;
|
||||
isNavRoot?: boolean;
|
||||
delegate?: FrameworkDelegate;
|
||||
viewIsReady?: () => Promise<any>;
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@ export class Picker implements OverlayInterface {
|
||||
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement;
|
||||
@Prop({ context: 'config' }) config: Config;
|
||||
@Prop() overlayId: number;
|
||||
@Prop() keyboardClose = true;
|
||||
|
||||
/**
|
||||
* Animation to use when the picker is presented.
|
||||
@ -145,10 +146,6 @@ export class Picker implements OverlayInterface {
|
||||
@Method()
|
||||
present(): Promise<void> {
|
||||
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 (this.duration > 10) {
|
||||
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.
|
||||
|
||||
|
||||
#### keyboardClose
|
||||
|
||||
boolean
|
||||
|
||||
|
||||
#### 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.
|
||||
|
||||
|
||||
#### keyboard-close
|
||||
|
||||
boolean
|
||||
|
||||
|
||||
#### leave-animation
|
||||
|
||||
|
||||
|
@ -33,6 +33,7 @@ export class Popover implements OverlayInterface {
|
||||
@Prop({ context: 'config' }) config: Config;
|
||||
@Prop() delegate: FrameworkDelegate;
|
||||
@Prop() overlayId: number;
|
||||
@Prop() keyboardClose = true;
|
||||
|
||||
/**
|
||||
* The color to use from your Sass `$colors` map.
|
||||
|
@ -85,6 +85,11 @@ any
|
||||
The event to pass to the popover animation.
|
||||
|
||||
|
||||
#### keyboardClose
|
||||
|
||||
boolean
|
||||
|
||||
|
||||
#### leaveAnimation
|
||||
|
||||
|
||||
@ -186,6 +191,11 @@ any
|
||||
The event to pass to the popover animation.
|
||||
|
||||
|
||||
#### keyboard-close
|
||||
|
||||
boolean
|
||||
|
||||
|
||||
#### leave-animation
|
||||
|
||||
|
||||
|
@ -80,6 +80,11 @@ until `dismiss()` is called.
|
||||
Animation to use when the toast is presented.
|
||||
|
||||
|
||||
#### keyboardClose
|
||||
|
||||
boolean
|
||||
|
||||
|
||||
#### leaveAnimation
|
||||
|
||||
|
||||
@ -166,6 +171,11 @@ until `dismiss()` is called.
|
||||
Animation to use when the toast is presented.
|
||||
|
||||
|
||||
#### keyboard-close
|
||||
|
||||
boolean
|
||||
|
||||
|
||||
#### leave-animation
|
||||
|
||||
|
||||
|
@ -33,6 +33,7 @@ export class Toast implements OverlayInterface {
|
||||
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: HTMLIonAnimationControllerElement;
|
||||
@Prop({ context: 'config' }) config: Config;
|
||||
@Prop() overlayId: number;
|
||||
@Prop() keyboardClose = false;
|
||||
|
||||
/**
|
||||
* 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 { ItemOption } from './components/item-option/item-option';
|
||||
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 { List } from './components/list/list';
|
||||
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 = undefined;
|
||||
}
|
||||
if (overlay.keyboardClose) {
|
||||
closeKeyboard();
|
||||
}
|
||||
return overlay.animationCtrl.create(animationBuilder, baseEl, opts).then(animation => {
|
||||
overlay.animation = animation;
|
||||
if (!overlay.willAnimate) {
|
||||
@ -170,12 +173,15 @@ export function onceEvent(element: HTMLElement, eventName: string, callback: (ev
|
||||
element.addEventListener(eventName, handler);
|
||||
}
|
||||
|
||||
function closeKeyboard() {
|
||||
const activeElement = document.activeElement as HTMLElement;
|
||||
activeElement && activeElement.blur && activeElement.blur();
|
||||
}
|
||||
|
||||
export function isCancel(role: string): boolean {
|
||||
return role === 'cancel' || role === BACKDROP;
|
||||
}
|
||||
|
||||
|
||||
export interface OverlayEventDetail {
|
||||
data?: any;
|
||||
role?: string;
|
||||
@ -185,6 +191,7 @@ export interface OverlayInterface {
|
||||
mode: string;
|
||||
el: HTMLElement;
|
||||
willAnimate: boolean;
|
||||
keyboardClose: boolean;
|
||||
config: Config;
|
||||
overlayId: number;
|
||||
presented: boolean;
|
||||
|
Reference in New Issue
Block a user