mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-22 13:32:54 +08:00
fix(overlay): fix overlay indexing
This commit is contained in:
7
packages/core/src/components.d.ts
vendored
7
packages/core/src/components.d.ts
vendored
@ -118,6 +118,7 @@ declare global {
|
|||||||
enableBackdropDismiss?: boolean;
|
enableBackdropDismiss?: boolean;
|
||||||
enterAnimation?: AnimationBuilder;
|
enterAnimation?: AnimationBuilder;
|
||||||
leaveAnimation?: AnimationBuilder;
|
leaveAnimation?: AnimationBuilder;
|
||||||
|
overlayId?: number;
|
||||||
subTitle?: string;
|
subTitle?: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
translucent?: boolean;
|
translucent?: boolean;
|
||||||
@ -188,6 +189,7 @@ declare global {
|
|||||||
inputs?: AlertInput[];
|
inputs?: AlertInput[];
|
||||||
leaveAnimation?: AnimationBuilder;
|
leaveAnimation?: AnimationBuilder;
|
||||||
message?: string;
|
message?: string;
|
||||||
|
overlayId?: number;
|
||||||
subTitle?: string;
|
subTitle?: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
translucent?: boolean;
|
translucent?: boolean;
|
||||||
@ -1672,6 +1674,7 @@ declare global {
|
|||||||
enableBackdropDismiss?: boolean;
|
enableBackdropDismiss?: boolean;
|
||||||
enterAnimation?: AnimationBuilder;
|
enterAnimation?: AnimationBuilder;
|
||||||
leaveAnimation?: AnimationBuilder;
|
leaveAnimation?: AnimationBuilder;
|
||||||
|
overlayId?: number;
|
||||||
showBackdrop?: boolean;
|
showBackdrop?: boolean;
|
||||||
spinner?: string;
|
spinner?: string;
|
||||||
translucent?: boolean;
|
translucent?: boolean;
|
||||||
@ -1842,6 +1845,7 @@ declare global {
|
|||||||
enterAnimation?: AnimationBuilder;
|
enterAnimation?: AnimationBuilder;
|
||||||
leaveAnimation?: AnimationBuilder;
|
leaveAnimation?: AnimationBuilder;
|
||||||
mode?: 'ios' | 'md';
|
mode?: 'ios' | 'md';
|
||||||
|
overlayId?: number;
|
||||||
showBackdrop?: boolean;
|
showBackdrop?: boolean;
|
||||||
willAnimate?: boolean;
|
willAnimate?: boolean;
|
||||||
}
|
}
|
||||||
@ -2131,6 +2135,7 @@ declare global {
|
|||||||
enableBackdropDismiss?: boolean;
|
enableBackdropDismiss?: boolean;
|
||||||
enterAnimation?: AnimationBuilder;
|
enterAnimation?: AnimationBuilder;
|
||||||
leaveAnimation?: AnimationBuilder;
|
leaveAnimation?: AnimationBuilder;
|
||||||
|
overlayId?: number;
|
||||||
showBackdrop?: boolean;
|
showBackdrop?: boolean;
|
||||||
willAnimate?: boolean;
|
willAnimate?: boolean;
|
||||||
}
|
}
|
||||||
@ -2232,6 +2237,7 @@ declare global {
|
|||||||
ev?: Event;
|
ev?: Event;
|
||||||
leaveAnimation?: AnimationBuilder;
|
leaveAnimation?: AnimationBuilder;
|
||||||
mode?: 'ios' | 'md';
|
mode?: 'ios' | 'md';
|
||||||
|
overlayId?: number;
|
||||||
showBackdrop?: boolean;
|
showBackdrop?: boolean;
|
||||||
translucent?: boolean;
|
translucent?: boolean;
|
||||||
willAnimate?: boolean;
|
willAnimate?: boolean;
|
||||||
@ -3510,6 +3516,7 @@ declare global {
|
|||||||
enterAnimation?: AnimationBuilder;
|
enterAnimation?: AnimationBuilder;
|
||||||
leaveAnimation?: AnimationBuilder;
|
leaveAnimation?: AnimationBuilder;
|
||||||
message?: string;
|
message?: string;
|
||||||
|
overlayId?: number;
|
||||||
position?: string;
|
position?: string;
|
||||||
showCloseButton?: boolean;
|
showCloseButton?: boolean;
|
||||||
translucent?: boolean;
|
translucent?: boolean;
|
||||||
|
@ -1,29 +1,31 @@
|
|||||||
import { Component, Listen, Method } from '@stencil/core';
|
import { Component, Listen, Method } from '@stencil/core';
|
||||||
import { ActionSheetEvent, ActionSheetOptions, OverlayController } from '../../index';
|
import { ActionSheetEvent, ActionSheetOptions, OverlayController } from '../../index';
|
||||||
|
import { createOverlay, getTopOverlay, dismissOverlay, removeLastOverlay } from '../../utils/overlays';
|
||||||
let ids = 0;
|
|
||||||
const actionSheets = new Map<number, HTMLIonActionSheetElement>();
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
tag: 'ion-action-sheet-controller'
|
tag: 'ion-action-sheet-controller'
|
||||||
})
|
})
|
||||||
export class ActionSheetController implements OverlayController {
|
export class ActionSheetController implements OverlayController {
|
||||||
|
|
||||||
|
private actionSheets = new Map<number, HTMLIonActionSheetElement>();
|
||||||
|
|
||||||
|
|
||||||
@Listen('body:ionActionSheetWillPresent')
|
@Listen('body:ionActionSheetWillPresent')
|
||||||
protected actionSheetWillPresent(ev: ActionSheetEvent) {
|
protected actionSheetWillPresent(ev: ActionSheetEvent) {
|
||||||
actionSheets.set(ev.target.actionSheetId, ev.target);
|
this.actionSheets.set(ev.target.overlayId, ev.target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Listen('body:ionActionSheetWillDismiss, body:ionActionSheetDidUnload')
|
@Listen('body:ionActionSheetWillDismiss')
|
||||||
|
@Listen('body:ionActionSheetDidUnload')
|
||||||
protected actionSheetWillDismiss(ev: ActionSheetEvent) {
|
protected actionSheetWillDismiss(ev: ActionSheetEvent) {
|
||||||
actionSheets.delete(ev.target.actionSheetId);
|
this.actionSheets.delete(ev.target.overlayId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Listen('body:keyup.escape')
|
@Listen('body:keyup.escape')
|
||||||
protected escapeKeyUp() {
|
protected escapeKeyUp() {
|
||||||
removeLastActionSheet();
|
removeLastOverlay(this.actionSheets);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -31,34 +33,15 @@ export class ActionSheetController implements OverlayController {
|
|||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
create(opts?: ActionSheetOptions): Promise<HTMLIonActionSheetElement> {
|
create(opts?: ActionSheetOptions): Promise<HTMLIonActionSheetElement> {
|
||||||
// create ionic's wrapping ion-actionSheet component
|
return createOverlay('ion-action-sheet', opts);
|
||||||
const actionSheetElement = document.createElement('ion-action-sheet');
|
|
||||||
|
|
||||||
// give this actionSheet a unique id
|
|
||||||
actionSheetElement.actionSheetId = ids++;
|
|
||||||
|
|
||||||
// convert the passed in actionSheet options into props
|
|
||||||
// that get passed down into the new actionSheet
|
|
||||||
Object.assign(actionSheetElement, opts);
|
|
||||||
|
|
||||||
// append the actionSheet element to the document body
|
|
||||||
const appRoot = document.querySelector('ion-app') || document.body;
|
|
||||||
appRoot.appendChild(actionSheetElement);
|
|
||||||
|
|
||||||
return actionSheetElement.componentOnReady();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dismiss the open action sheet overlay.
|
* Dismiss the open action sheet overlay.
|
||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
dismiss(data?: any, role?: any, actionSheetId = -1) {
|
dismiss(data?: any, role?: string, actionSheetId = -1) {
|
||||||
actionSheetId = actionSheetId >= 0 ? actionSheetId : getHighestId();
|
return dismissOverlay(data, role, this.actionSheets, actionSheetId);
|
||||||
const actionSheet = actionSheets.get(actionSheetId);
|
|
||||||
if (!actionSheet) {
|
|
||||||
return Promise.reject('action-sheet does not exist');
|
|
||||||
}
|
|
||||||
return actionSheet.dismiss(data, role);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -66,21 +49,6 @@ export class ActionSheetController implements OverlayController {
|
|||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
getTop() {
|
getTop() {
|
||||||
return actionSheets.get(getHighestId());
|
return getTopOverlay(this.actionSheets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getHighestId() {
|
|
||||||
let minimum = -1;
|
|
||||||
actionSheets.forEach((_actionSheet: HTMLIonActionSheetElement, id: number) => {
|
|
||||||
if (id > minimum) {
|
|
||||||
minimum = id;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return minimum;
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeLastActionSheet() {
|
|
||||||
const toRemove = actionSheets.get(getHighestId());
|
|
||||||
return toRemove ? toRemove.dismiss() : Promise.resolve();
|
|
||||||
}
|
|
||||||
|
@ -76,6 +76,8 @@ ion-action-sheet {
|
|||||||
flex-shrink: 2;
|
flex-shrink: 2;
|
||||||
|
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
|
|
||||||
|
overscroll-behavior: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-sheet-group-cancel {
|
.action-sheet-group-cancel {
|
||||||
|
@ -3,6 +3,7 @@ import { Animation, AnimationBuilder, AnimationController, Config, DomController
|
|||||||
|
|
||||||
import { domControllerAsync, isDef, playAnimationAsync } from '../../utils/helpers';
|
import { domControllerAsync, isDef, playAnimationAsync } from '../../utils/helpers';
|
||||||
import { createThemedClasses, getClassMap } from '../../utils/theme';
|
import { createThemedClasses, getClassMap } from '../../utils/theme';
|
||||||
|
import { OverlayInterface, BACKDROP } 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';
|
||||||
@ -20,10 +21,10 @@ import mdLeaveAnimation from './animations/md.leave';
|
|||||||
theme: 'action-sheet'
|
theme: 'action-sheet'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
export class ActionSheet {
|
export class ActionSheet implements OverlayInterface {
|
||||||
|
|
||||||
mode: string;
|
mode: string;
|
||||||
color: string;
|
color: string;
|
||||||
actionSheetId: number;
|
|
||||||
|
|
||||||
private animation: Animation | null = null;
|
private animation: Animation | null = null;
|
||||||
|
|
||||||
@ -32,6 +33,7 @@ export class ActionSheet {
|
|||||||
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: AnimationController;
|
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: AnimationController;
|
||||||
@Prop({ context: 'config' }) config: Config;
|
@Prop({ context: 'config' }) config: Config;
|
||||||
@Prop({ context: 'dom' }) dom: DomController;
|
@Prop({ context: 'dom' }) dom: DomController;
|
||||||
|
@Prop() overlayId: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animation to use when the action sheet is presented.
|
* Animation to use when the action sheet is presented.
|
||||||
@ -128,7 +130,7 @@ export class ActionSheet {
|
|||||||
|
|
||||||
@Listen('ionBackdropTap')
|
@Listen('ionBackdropTap')
|
||||||
protected onBackdropTap() {
|
protected onBackdropTap() {
|
||||||
this.dismiss();
|
this.dismiss(null, BACKDROP);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -138,7 +140,7 @@ export class ActionSheet {
|
|||||||
present() {
|
present() {
|
||||||
this.ionActionSheetWillPresent.emit();
|
this.ionActionSheetWillPresent.emit();
|
||||||
|
|
||||||
this.el.style.zIndex = `${20000 + this.actionSheetId}`;
|
this.el.style.zIndex = `${20000 + this.overlayId}`;
|
||||||
|
|
||||||
// get the user's animation fn if one was provided
|
// get the user's animation fn if one was provided
|
||||||
const animationBuilder = this.enterAnimation || this.config.get('actionSheetEnter', this.mode === 'ios' ? iosEnterAnimation : mdEnterAnimation);
|
const animationBuilder = this.enterAnimation || this.config.get('actionSheetEnter', this.mode === 'ios' ? iosEnterAnimation : mdEnterAnimation);
|
||||||
|
@ -96,6 +96,11 @@ Animation to use when the action sheet is presented.
|
|||||||
Animation to use when the action sheet is dismissed.
|
Animation to use when the action sheet is dismissed.
|
||||||
|
|
||||||
|
|
||||||
|
#### overlayId
|
||||||
|
|
||||||
|
number
|
||||||
|
|
||||||
|
|
||||||
#### subTitle
|
#### subTitle
|
||||||
|
|
||||||
string
|
string
|
||||||
@ -162,6 +167,11 @@ Animation to use when the action sheet is presented.
|
|||||||
Animation to use when the action sheet is dismissed.
|
Animation to use when the action sheet is dismissed.
|
||||||
|
|
||||||
|
|
||||||
|
#### overlay-id
|
||||||
|
|
||||||
|
number
|
||||||
|
|
||||||
|
|
||||||
#### sub-title
|
#### sub-title
|
||||||
|
|
||||||
string
|
string
|
||||||
|
@ -1,27 +1,28 @@
|
|||||||
import { Component, Listen, Method } from '@stencil/core';
|
import { Component, Listen, Method } from '@stencil/core';
|
||||||
import { AlertEvent, AlertOptions, OverlayController } from '../../index';
|
import { AlertEvent, AlertOptions, OverlayController } from '../../index';
|
||||||
|
import { createOverlay, removeLastOverlay, dismissOverlay, getTopOverlay } from '../../utils/overlays';
|
||||||
let ids = 0;
|
|
||||||
const alerts = new Map<number, HTMLIonAlertElement>();
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
tag: 'ion-alert-controller'
|
tag: 'ion-alert-controller'
|
||||||
})
|
})
|
||||||
export class AlertController implements OverlayController {
|
export class AlertController implements OverlayController {
|
||||||
|
|
||||||
|
private alerts = new Map<number, HTMLIonAlertElement>();
|
||||||
|
|
||||||
@Listen('body:ionAlertWillPresent')
|
@Listen('body:ionAlertWillPresent')
|
||||||
protected alertWillPresent(ev: AlertEvent) {
|
protected alertWillPresent(ev: AlertEvent) {
|
||||||
alerts.set(ev.target.alertId, ev.target);
|
this.alerts.set(ev.target.overlayId, ev.target);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Listen('body:ionAlertWillDismiss, body:ionAlertDidUnload')
|
@Listen('body:ionAlertWillDismiss')
|
||||||
|
@Listen('body:ionAlertDidUnload')
|
||||||
protected alertWillDismiss(ev: AlertEvent) {
|
protected alertWillDismiss(ev: AlertEvent) {
|
||||||
alerts.delete(ev.target.alertId);
|
this.alerts.delete(ev.target.overlayId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Listen('body:keyup.escape')
|
@Listen('body:keyup.escape')
|
||||||
protected escapeKeyUp() {
|
protected escapeKeyUp() {
|
||||||
removeLastAlert();
|
removeLastOverlay(this.alerts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -29,21 +30,7 @@ export class AlertController implements OverlayController {
|
|||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
create(opts?: AlertOptions): Promise<HTMLIonAlertElement> {
|
create(opts?: AlertOptions): Promise<HTMLIonAlertElement> {
|
||||||
// create ionic's wrapping ion-alert component
|
return createOverlay('ion-alert', opts);
|
||||||
const alertElement = document.createElement('ion-alert');
|
|
||||||
|
|
||||||
// give this alert a unique id
|
|
||||||
alertElement.alertId = ids++;
|
|
||||||
|
|
||||||
// convert the passed in alert options into props
|
|
||||||
// that get passed down into the new alert
|
|
||||||
Object.assign(alertElement, opts);
|
|
||||||
|
|
||||||
// append the alert element to the document body
|
|
||||||
const appRoot = document.querySelector('ion-app') || document.body;
|
|
||||||
appRoot.appendChild(alertElement);
|
|
||||||
|
|
||||||
return alertElement.componentOnReady();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -51,12 +38,7 @@ export class AlertController implements OverlayController {
|
|||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
dismiss(data?: any, role?: any, alertId = -1) {
|
dismiss(data?: any, role?: any, alertId = -1) {
|
||||||
alertId = alertId >= 0 ? alertId : getHighestId();
|
return dismissOverlay(data, role, this.alerts, alertId);
|
||||||
const alert = alerts.get(alertId);
|
|
||||||
if (!alert) {
|
|
||||||
return Promise.reject('alert does not exist');
|
|
||||||
}
|
|
||||||
return alert.dismiss(data, role);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -64,21 +46,6 @@ export class AlertController implements OverlayController {
|
|||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
getTop() {
|
getTop() {
|
||||||
return alerts.get(getHighestId());
|
return getTopOverlay(this.alerts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getHighestId() {
|
|
||||||
let minimum = -1;
|
|
||||||
alerts.forEach((_alert: HTMLIonAlertElement, id: number) => {
|
|
||||||
if (id > minimum) {
|
|
||||||
minimum = id;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return minimum;
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeLastAlert() {
|
|
||||||
const toRemove = alerts.get(getHighestId());
|
|
||||||
return toRemove ? toRemove.dismiss() : Promise.resolve();
|
|
||||||
}
|
|
||||||
|
@ -108,6 +108,7 @@
|
|||||||
|
|
||||||
-webkit-overflow-scrolling: touch;
|
-webkit-overflow-scrolling: touch;
|
||||||
|
|
||||||
|
overscroll-behavior: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
.alert-ios .alert-tappable {
|
.alert-ios .alert-tappable {
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { Component, CssClassMap, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core';
|
import { Component, CssClassMap, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core';
|
||||||
import { Animation, AnimationBuilder, AnimationController, Config, DomController, OverlayDismissEvent, OverlayDismissEventDetail } from '../../index';
|
import { Animation, AnimationBuilder, AnimationController, Config, DomController, OverlayDismissEvent, OverlayDismissEventDetail } from '../../index';
|
||||||
import { domControllerAsync, playAnimationAsync } from '../../utils/helpers';
|
import { domControllerAsync, playAnimationAsync } from '../../utils/helpers';
|
||||||
|
|
||||||
import { BACKDROP } from '../../utils/overlay-constants';
|
|
||||||
import { createThemedClasses, getClassMap } from '../../utils/theme';
|
import { createThemedClasses, getClassMap } from '../../utils/theme';
|
||||||
|
import { OverlayInterface, BACKDROP } 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';
|
||||||
@ -21,8 +20,7 @@ import mdLeaveAnimation from './animations/md.leave';
|
|||||||
theme: 'alert'
|
theme: 'alert'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
export class Alert {
|
export class Alert implements OverlayInterface {
|
||||||
alertId: number;
|
|
||||||
mode: string;
|
mode: string;
|
||||||
color: string;
|
color: string;
|
||||||
|
|
||||||
@ -36,6 +34,7 @@ export class Alert {
|
|||||||
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: AnimationController;
|
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: AnimationController;
|
||||||
@Prop({ context: 'config' }) config: Config;
|
@Prop({ context: 'config' }) config: Config;
|
||||||
@Prop({ context: 'dom' }) dom: DomController;
|
@Prop({ context: 'dom' }) dom: DomController;
|
||||||
|
@Prop() overlayId: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animation to use when the alert is presented.
|
* Animation to use when the alert is presented.
|
||||||
@ -147,7 +146,7 @@ export class Alert {
|
|||||||
present() {
|
present() {
|
||||||
this.ionAlertWillPresent.emit();
|
this.ionAlertWillPresent.emit();
|
||||||
|
|
||||||
this.el.style.zIndex = `${20000 + this.alertId}`;
|
this.el.style.zIndex = `${20000 + this.overlayId}`;
|
||||||
|
|
||||||
// get the user's animation fn if one was provided
|
// get the user's animation fn if one was provided
|
||||||
const animationBuilder = this.enterAnimation || this.config.get('alertEnter', this.mode === 'ios' ? iosEnterAnimation : mdEnterAnimation);
|
const animationBuilder = this.enterAnimation || this.config.get('alertEnter', this.mode === 'ios' ? iosEnterAnimation : mdEnterAnimation);
|
||||||
@ -347,14 +346,14 @@ export class Alert {
|
|||||||
...themedClasses,
|
...themedClasses,
|
||||||
...getClassMap(this.cssClass)
|
...getClassMap(this.cssClass)
|
||||||
},
|
},
|
||||||
id: this.alertId
|
id: this.overlayId
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const hdrId = `${this.alertId}-hdr`;
|
const hdrId = `alert-${this.overlayId}-hdr`;
|
||||||
const subHdrId = `${this.alertId}-sub-hdr`;
|
const subHdrId = `alert-${this.overlayId}-sub-hdr`;
|
||||||
const msgId = `${this.alertId}-msg`;
|
const msgId = `alert-${this.overlayId}-msg`;
|
||||||
|
|
||||||
if (this.title || !this.subTitle) {
|
if (this.title || !this.subTitle) {
|
||||||
this.hdrId = hdrId;
|
this.hdrId = hdrId;
|
||||||
@ -385,7 +384,7 @@ export class Alert {
|
|||||||
label: i.label,
|
label: i.label,
|
||||||
checked: !!i.checked,
|
checked: !!i.checked,
|
||||||
disabled: !!i.disabled,
|
disabled: !!i.disabled,
|
||||||
id: i.id ? i.id : `alert-input-${this.alertId}-${index}`,
|
id: i.id ? i.id : `alert-input-${this.overlayId}-${index}`,
|
||||||
handler: i.handler ? i.handler : null,
|
handler: i.handler ? i.handler : null,
|
||||||
min: i.min ? i.min : null,
|
min: i.min ? i.min : null,
|
||||||
max: i.max ? i.max : null
|
max: i.max ? i.max : null
|
||||||
|
@ -90,6 +90,11 @@ string
|
|||||||
The main message to be displayed in the alert.
|
The main message to be displayed in the alert.
|
||||||
|
|
||||||
|
|
||||||
|
#### overlayId
|
||||||
|
|
||||||
|
number
|
||||||
|
|
||||||
|
|
||||||
#### subTitle
|
#### subTitle
|
||||||
|
|
||||||
string
|
string
|
||||||
@ -170,6 +175,11 @@ string
|
|||||||
The main message to be displayed in the alert.
|
The main message to be displayed in the alert.
|
||||||
|
|
||||||
|
|
||||||
|
#### overlay-id
|
||||||
|
|
||||||
|
number
|
||||||
|
|
||||||
|
|
||||||
#### sub-title
|
#### sub-title
|
||||||
|
|
||||||
string
|
string
|
||||||
|
@ -54,6 +54,7 @@ export class Backdrop {
|
|||||||
|
|
||||||
hostData() {
|
hostData() {
|
||||||
return {
|
return {
|
||||||
|
tabindex: '-1',
|
||||||
class: {
|
class: {
|
||||||
'backdrop-hide': !this.visible,
|
'backdrop-hide': !this.visible,
|
||||||
'backdrop-no-tappable': !this.tappable,
|
'backdrop-no-tappable': !this.tappable,
|
||||||
|
@ -1,27 +1,28 @@
|
|||||||
import { Component, Listen, Method } from '@stencil/core';
|
import { Component, Listen, Method } from '@stencil/core';
|
||||||
import { LoadingEvent, LoadingOptions, OverlayController } from '../../index';
|
import { LoadingEvent, LoadingOptions, OverlayController } from '../../index';
|
||||||
|
import { createOverlay, dismissOverlay, getTopOverlay, removeLastOverlay } from '../../utils/overlays';
|
||||||
|
|
||||||
let ids = 0;
|
|
||||||
const loadings = new Map<number, HTMLIonLoadingElement>();
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
tag: 'ion-loading-controller'
|
tag: 'ion-loading-controller'
|
||||||
})
|
})
|
||||||
export class LoadingController implements OverlayController {
|
export class LoadingController implements OverlayController {
|
||||||
|
|
||||||
|
private loadings = new Map<number, HTMLIonLoadingElement>();
|
||||||
|
|
||||||
@Listen('body:ionLoadingWillPresent')
|
@Listen('body:ionLoadingWillPresent')
|
||||||
protected loadingWillPresent(ev: LoadingEvent) {
|
protected loadingWillPresent(ev: LoadingEvent) {
|
||||||
loadings.set(ev.target.loadingId, ev.target);
|
this.loadings.set(ev.target.overlayId, ev.target);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Listen('body:ionLoadingWillDismiss, body:ionLoadingDidUnload')
|
@Listen('body:ionLoadingWillDismiss, body:ionLoadingDidUnload')
|
||||||
protected loadingWillDismiss(ev: LoadingEvent) {
|
protected loadingWillDismiss(ev: LoadingEvent) {
|
||||||
loadings.delete(ev.target.loadingId);
|
this.loadings.delete(ev.target.overlayId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Listen('body:keyup.escape')
|
@Listen('body:keyup.escape')
|
||||||
protected escapeKeyUp() {
|
protected escapeKeyUp() {
|
||||||
removeLastLoading();
|
removeLastOverlay(this.loadings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -29,31 +30,15 @@ export class LoadingController implements OverlayController {
|
|||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
create(opts?: LoadingOptions): Promise<HTMLIonLoadingElement> {
|
create(opts?: LoadingOptions): Promise<HTMLIonLoadingElement> {
|
||||||
// create ionic's wrapping ion-loading component
|
return createOverlay('ion-loading', opts);
|
||||||
const loadingElement = document.createElement('ion-loading');
|
|
||||||
|
|
||||||
// give this loading a unique id
|
|
||||||
loadingElement.loadingId = ids++;
|
|
||||||
|
|
||||||
// convert the passed in loading options into props
|
|
||||||
// that get passed down into the new loading
|
|
||||||
Object.assign(loadingElement, opts);
|
|
||||||
|
|
||||||
// append the loading element to the document body
|
|
||||||
const appRoot = document.querySelector('ion-app') || document.body;
|
|
||||||
appRoot.appendChild(loadingElement);
|
|
||||||
|
|
||||||
return loadingElement.componentOnReady();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dismiss the open loading overlay.
|
* Dismiss the open loading overlay.
|
||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
dismiss(data?: any, role?: any, loadingId = -1) {
|
dismiss(data?: any, role?: string, loadingId = -1) {
|
||||||
loadingId = loadingId >= 0 ? loadingId : getHighestId();
|
return dismissOverlay(data, role, this.loadings, loadingId);
|
||||||
const loading = loadings.get(loadingId);
|
|
||||||
return loading.dismiss(data, role);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -61,21 +46,6 @@ export class LoadingController implements OverlayController {
|
|||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
getTop() {
|
getTop() {
|
||||||
return loadings.get(getHighestId());
|
return getTopOverlay(this.loadings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getHighestId() {
|
|
||||||
let minimum = -1;
|
|
||||||
loadings.forEach((_loading: HTMLIonLoadingElement, id: number) => {
|
|
||||||
if (id > minimum) {
|
|
||||||
minimum = id;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return minimum;
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeLastLoading() {
|
|
||||||
const toRemove = loadings.get(getHighestId());
|
|
||||||
return toRemove ? toRemove.dismiss() : Promise.resolve();
|
|
||||||
}
|
|
||||||
|
@ -7,6 +7,7 @@ import iosEnterAnimation from './animations/ios.enter';
|
|||||||
import iosLeaveAnimation from './animations/ios.leave';
|
import iosLeaveAnimation from './animations/ios.leave';
|
||||||
import mdEnterAnimation from './animations/md.enter';
|
import mdEnterAnimation from './animations/md.enter';
|
||||||
import mdLeaveAnimation from './animations/md.leave';
|
import mdLeaveAnimation from './animations/md.leave';
|
||||||
|
import { OverlayInterface, BACKDROP } from '../../utils/overlays';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
tag: 'ion-loading',
|
tag: 'ion-loading',
|
||||||
@ -18,10 +19,10 @@ import mdLeaveAnimation from './animations/md.leave';
|
|||||||
theme: 'loading'
|
theme: 'loading'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
export class Loading {
|
|
||||||
|
export class Loading implements OverlayInterface {
|
||||||
color: string;
|
color: string;
|
||||||
mode: string;
|
mode: string;
|
||||||
loadingId: number;
|
|
||||||
|
|
||||||
private animation: Animation;
|
private animation: Animation;
|
||||||
private durationTimeout: any;
|
private durationTimeout: any;
|
||||||
@ -31,6 +32,7 @@ export class Loading {
|
|||||||
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: AnimationController;
|
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: AnimationController;
|
||||||
@Prop({ context: 'config' }) config: Config;
|
@Prop({ context: 'config' }) config: Config;
|
||||||
@Prop({ context: 'dom' }) dom: DomController;
|
@Prop({ context: 'dom' }) dom: DomController;
|
||||||
|
@Prop() overlayId: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animation to use when the loading indicator is presented.
|
* Animation to use when the loading indicator is presented.
|
||||||
@ -153,7 +155,7 @@ export class Loading {
|
|||||||
|
|
||||||
@Listen('ionBackdropTap')
|
@Listen('ionBackdropTap')
|
||||||
protected onBackdropTap() {
|
protected onBackdropTap() {
|
||||||
this.dismiss();
|
this.dismiss(null, BACKDROP);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -163,7 +165,7 @@ export class Loading {
|
|||||||
present() {
|
present() {
|
||||||
this.ionLoadingWillPresent.emit();
|
this.ionLoadingWillPresent.emit();
|
||||||
|
|
||||||
this.el.style.zIndex = `${20000 + this.loadingId}`;
|
this.el.style.zIndex = `${20000 + this.overlayId}`;
|
||||||
|
|
||||||
// get the user's animation fn if one was provided
|
// get the user's animation fn if one was provided
|
||||||
const animationBuilder = this.enterAnimation || this.config.get('loadingEnter', this.mode === 'ios' ? iosEnterAnimation : mdEnterAnimation);
|
const animationBuilder = this.enterAnimation || this.config.get('loadingEnter', this.mode === 'ios' ? iosEnterAnimation : mdEnterAnimation);
|
||||||
|
@ -83,6 +83,11 @@ Animation to use when the loading indicator is presented.
|
|||||||
Animation to use when the loading indicator is dismissed.
|
Animation to use when the loading indicator is dismissed.
|
||||||
|
|
||||||
|
|
||||||
|
#### overlayId
|
||||||
|
|
||||||
|
number
|
||||||
|
|
||||||
|
|
||||||
#### showBackdrop
|
#### showBackdrop
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
@ -164,6 +169,11 @@ Animation to use when the loading indicator is presented.
|
|||||||
Animation to use when the loading indicator is dismissed.
|
Animation to use when the loading indicator is dismissed.
|
||||||
|
|
||||||
|
|
||||||
|
#### overlay-id
|
||||||
|
|
||||||
|
number
|
||||||
|
|
||||||
|
|
||||||
#### show-backdrop
|
#### show-backdrop
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
|
@ -1,27 +1,28 @@
|
|||||||
import { Component, Listen, Method } from '@stencil/core';
|
import { Component, Listen, Method } from '@stencil/core';
|
||||||
import { ModalEvent, ModalOptions, OverlayController } from '../../index';
|
import { ModalEvent, ModalOptions, OverlayController } from '../../index';
|
||||||
|
import { createOverlay, dismissOverlay, getTopOverlay, removeLastOverlay } from '../../utils/overlays';
|
||||||
|
|
||||||
let ids = 0;
|
|
||||||
const modals = new Map<number, HTMLIonModalElement>();
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
tag: 'ion-modal-controller'
|
tag: 'ion-modal-controller'
|
||||||
})
|
})
|
||||||
export class ModalController implements OverlayController {
|
export class ModalController implements OverlayController {
|
||||||
|
|
||||||
|
private modals = new Map<number, HTMLIonModalElement>();
|
||||||
|
|
||||||
@Listen('body:ionModalWillPresent')
|
@Listen('body:ionModalWillPresent')
|
||||||
protected modalWillPresent(ev: ModalEvent) {
|
protected modalWillPresent(ev: ModalEvent) {
|
||||||
modals.set(ev.target.modalId, ev.target);
|
this.modals.set(ev.target.overlayId, ev.target);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Listen('body:ionModalWillDismiss, body:ionModalDidUnload')
|
@Listen('body:ionModalWillDismiss, body:ionModalDidUnload')
|
||||||
protected modalWillDismiss(ev: ModalEvent) {
|
protected modalWillDismiss(ev: ModalEvent) {
|
||||||
modals.delete(ev.target.modalId);
|
this.modals.delete(ev.target.overlayId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Listen('body:keyup.escape')
|
@Listen('body:keyup.escape')
|
||||||
protected escapeKeyUp() {
|
protected escapeKeyUp() {
|
||||||
removeLastModal();
|
removeLastOverlay(this.modals);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -29,21 +30,7 @@ export class ModalController implements OverlayController {
|
|||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
create(opts?: ModalOptions): Promise<HTMLIonModalElement> {
|
create(opts?: ModalOptions): Promise<HTMLIonModalElement> {
|
||||||
// create ionic's wrapping ion-modal component
|
return createOverlay('ion-modal', opts);
|
||||||
const modalElement = document.createElement('ion-modal');
|
|
||||||
|
|
||||||
// give this modal a unique id
|
|
||||||
modalElement.modalId = ids++;
|
|
||||||
|
|
||||||
// convert the passed in modal options into props
|
|
||||||
// that get passed down into the new modal
|
|
||||||
Object.assign(modalElement, opts);
|
|
||||||
|
|
||||||
// append the modal element to the document body
|
|
||||||
const appRoot = document.querySelector('ion-app') || document.body;
|
|
||||||
appRoot.appendChild(modalElement);
|
|
||||||
|
|
||||||
return modalElement.componentOnReady();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -51,12 +38,7 @@ export class ModalController implements OverlayController {
|
|||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
dismiss(data?: any, role?: any, modalId = -1) {
|
dismiss(data?: any, role?: any, modalId = -1) {
|
||||||
modalId = modalId >= 0 ? modalId : getHighestId();
|
return dismissOverlay(data, role, this.modals, modalId);
|
||||||
const modal = modals.get(modalId);
|
|
||||||
if (!modal) {
|
|
||||||
return Promise.reject('modal does not exist');
|
|
||||||
}
|
|
||||||
return modal.dismiss(data, role);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -64,21 +46,6 @@ export class ModalController implements OverlayController {
|
|||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
getTop() {
|
getTop() {
|
||||||
return modals.get(getHighestId());
|
return getTopOverlay(this.modals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getHighestId() {
|
|
||||||
let minimum = -1;
|
|
||||||
modals.forEach((_modal: HTMLIonModalElement, id: number) => {
|
|
||||||
if (id > minimum) {
|
|
||||||
minimum = id;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return minimum;
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeLastModal() {
|
|
||||||
const toRemove = modals.get(getHighestId());
|
|
||||||
return toRemove ? toRemove.dismiss() : Promise.resolve();
|
|
||||||
}
|
|
||||||
|
@ -4,6 +4,7 @@ import { Animation, AnimationBuilder, AnimationController, Config, DomController
|
|||||||
import { DomFrameworkDelegate } from '../../utils/dom-framework-delegate';
|
import { DomFrameworkDelegate } from '../../utils/dom-framework-delegate';
|
||||||
import { domControllerAsync, playAnimationAsync } from '../../utils/helpers';
|
import { domControllerAsync, playAnimationAsync } from '../../utils/helpers';
|
||||||
import { createThemedClasses } from '../../utils/theme';
|
import { createThemedClasses } from '../../utils/theme';
|
||||||
|
import { OverlayInterface, BACKDROP } 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';
|
||||||
@ -21,8 +22,7 @@ import mdLeaveAnimation from './animations/md.leave';
|
|||||||
theme: 'modal'
|
theme: 'modal'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
export class Modal {
|
export class Modal implements OverlayInterface {
|
||||||
modalId: number;
|
|
||||||
|
|
||||||
private animation: Animation;
|
private animation: Animation;
|
||||||
private usersComponentElement: HTMLElement;
|
private usersComponentElement: HTMLElement;
|
||||||
@ -32,7 +32,7 @@ export class Modal {
|
|||||||
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: AnimationController;
|
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: AnimationController;
|
||||||
@Prop({ context: 'config' }) config: Config;
|
@Prop({ context: 'config' }) config: Config;
|
||||||
@Prop({ context: 'dom' }) dom: DomController;
|
@Prop({ context: 'dom' }) dom: DomController;
|
||||||
|
@Prop() overlayId: number;
|
||||||
@Prop({ mutable: true }) delegate: FrameworkDelegate;
|
@Prop({ mutable: true }) delegate: FrameworkDelegate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -138,10 +138,7 @@ export class Modal {
|
|||||||
|
|
||||||
@Listen('ionBackdropTap')
|
@Listen('ionBackdropTap')
|
||||||
protected onBackdropTap() {
|
protected onBackdropTap() {
|
||||||
// const opts: NavOptions = {
|
this.dismiss(null, BACKDROP);
|
||||||
// minClickBlockDuration: 400
|
|
||||||
// };
|
|
||||||
this.dismiss();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -156,7 +153,7 @@ export class Modal {
|
|||||||
|
|
||||||
this.ionModalWillPresent.emit();
|
this.ionModalWillPresent.emit();
|
||||||
|
|
||||||
this.el.style.zIndex = `${20000 + this.modalId}`;
|
this.el.style.zIndex = `${20000 + this.overlayId}`;
|
||||||
|
|
||||||
// get the user's animation fn if one was provided
|
// get the user's animation fn if one was provided
|
||||||
const animationBuilder = this.enterAnimation || this.config.get('modalEnter', this.mode === 'ios' ? iosEnterAnimation : mdEnterAnimation);
|
const animationBuilder = this.enterAnimation || this.config.get('modalEnter', this.mode === 'ios' ? iosEnterAnimation : mdEnterAnimation);
|
||||||
|
@ -114,6 +114,11 @@ Possible values are: `"ios"` or `"md"`.
|
|||||||
For more information, see [Platform Styles](/docs/theming/platform-specific-styles).
|
For more information, see [Platform Styles](/docs/theming/platform-specific-styles).
|
||||||
|
|
||||||
|
|
||||||
|
#### overlayId
|
||||||
|
|
||||||
|
number
|
||||||
|
|
||||||
|
|
||||||
#### showBackdrop
|
#### showBackdrop
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
@ -196,6 +201,11 @@ Possible values are: `"ios"` or `"md"`.
|
|||||||
For more information, see [Platform Styles](/docs/theming/platform-specific-styles).
|
For more information, see [Platform Styles](/docs/theming/platform-specific-styles).
|
||||||
|
|
||||||
|
|
||||||
|
#### overlay-id
|
||||||
|
|
||||||
|
number
|
||||||
|
|
||||||
|
|
||||||
#### show-backdrop
|
#### show-backdrop
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
|
@ -1,27 +1,28 @@
|
|||||||
import { Component, Listen, Method } from '@stencil/core';
|
import { Component, Listen, Method } from '@stencil/core';
|
||||||
import { OverlayController, PickerEvent, PickerOptions } from '../../index';
|
import { OverlayController, PickerEvent, PickerOptions } from '../../index';
|
||||||
|
import { createOverlay, getTopOverlay, removeLastOverlay, dismissOverlay } from '../../utils/overlays';
|
||||||
|
|
||||||
let ids = 0;
|
|
||||||
const pickers = new Map<number, HTMLIonPickerElement>();
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
tag: 'ion-picker-controller'
|
tag: 'ion-picker-controller'
|
||||||
})
|
})
|
||||||
export class PickerController implements OverlayController {
|
export class PickerController implements OverlayController {
|
||||||
|
|
||||||
|
private pickers = new Map<number, HTMLIonPickerElement>();
|
||||||
|
|
||||||
@Listen('body:ionPickerWillPresent')
|
@Listen('body:ionPickerWillPresent')
|
||||||
protected pickerWillPresent(ev: PickerEvent) {
|
protected pickerWillPresent(ev: PickerEvent) {
|
||||||
pickers.set(ev.target.pickerId, ev.target);
|
this.pickers.set(ev.target.overlayId, ev.target);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Listen('body:ionPickerWillDismiss, body:ionPickerDidUnload')
|
@Listen('body:ionPickerWillDismiss, body:ionPickerDidUnload')
|
||||||
protected pickerWillDismiss(ev: PickerEvent) {
|
protected pickerWillDismiss(ev: PickerEvent) {
|
||||||
pickers.delete(ev.target.pickerId);
|
this.pickers.delete(ev.target.overlayId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Listen('body:keyup.escape')
|
@Listen('body:keyup.escape')
|
||||||
protected escapeKeyUp() {
|
protected escapeKeyUp() {
|
||||||
removeLastPicker();
|
removeLastOverlay(this.pickers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -29,21 +30,7 @@ export class PickerController implements OverlayController {
|
|||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
create(opts?: PickerOptions): Promise<HTMLIonPickerElement> {
|
create(opts?: PickerOptions): Promise<HTMLIonPickerElement> {
|
||||||
// create ionic's wrapping ion-picker component
|
return createOverlay('ion-picker', opts);
|
||||||
const pickerElement = document.createElement('ion-picker');
|
|
||||||
|
|
||||||
// give this picker a unique id
|
|
||||||
pickerElement.pickerId = ids++;
|
|
||||||
|
|
||||||
// convert the passed in picker options into props
|
|
||||||
// that get passed down into the new picker
|
|
||||||
Object.assign(pickerElement, opts);
|
|
||||||
|
|
||||||
// append the picker element to the document body
|
|
||||||
const appRoot = document.querySelector('ion-app') || document.body;
|
|
||||||
appRoot.appendChild(pickerElement);
|
|
||||||
|
|
||||||
return pickerElement.componentOnReady();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -51,12 +38,7 @@ export class PickerController implements OverlayController {
|
|||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
dismiss(data?: any, role?: any, pickerId = -1) {
|
dismiss(data?: any, role?: any, pickerId = -1) {
|
||||||
pickerId = pickerId >= 0 ? pickerId : getHighestId();
|
return dismissOverlay(data, role, this.pickers, pickerId);
|
||||||
const picker = pickers.get(pickerId);
|
|
||||||
if (!picker) {
|
|
||||||
return Promise.reject('picker does not exist');
|
|
||||||
}
|
|
||||||
return picker.dismiss(data, role);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -64,21 +46,6 @@ export class PickerController implements OverlayController {
|
|||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
getTop() {
|
getTop() {
|
||||||
return pickers.get(getHighestId());
|
return getTopOverlay(this.pickers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getHighestId() {
|
|
||||||
let minimum = -1;
|
|
||||||
pickers.forEach((_picker: HTMLIonPickerElement, id: number) => {
|
|
||||||
if (id > minimum) {
|
|
||||||
minimum = id;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return minimum;
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeLastPicker() {
|
|
||||||
const toRemove = pickers.get(getHighestId());
|
|
||||||
return toRemove ? toRemove.dismiss() : Promise.resolve();
|
|
||||||
}
|
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import { Component, CssClassMap, Element, Event, EventEmitter, Listen, Method, Prop, State } from '@stencil/core';
|
import { Component, CssClassMap, Element, Event, EventEmitter, Listen, Method, Prop, State } from '@stencil/core';
|
||||||
import { Animation, AnimationBuilder, AnimationController, Config, DomController, OverlayDismissEvent, OverlayDismissEventDetail } from '../../index';
|
import { Animation, AnimationBuilder, AnimationController, Config, DomController, OverlayDismissEvent, OverlayDismissEventDetail } from '../../index';
|
||||||
|
|
||||||
import { domControllerAsync, playAnimationAsync } from '../../utils/helpers';
|
import { domControllerAsync, playAnimationAsync } from '../../utils/helpers';
|
||||||
|
import { getClassMap } from '../../utils/theme';
|
||||||
|
import { OverlayInterface } 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';
|
||||||
import { getClassMap } from '../../utils/theme';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
tag: 'ion-picker',
|
tag: 'ion-picker',
|
||||||
@ -16,13 +18,12 @@ import { getClassMap } from '../../utils/theme';
|
|||||||
theme: 'picker'
|
theme: 'picker'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
export class Picker {
|
export class Picker implements OverlayInterface {
|
||||||
|
|
||||||
private animation: Animation;
|
private animation: Animation;
|
||||||
private durationTimeout: any;
|
private durationTimeout: any;
|
||||||
private mode: string;
|
private mode: string;
|
||||||
|
|
||||||
pickerId: number;
|
|
||||||
|
|
||||||
@Element() private el: HTMLElement;
|
@Element() private el: HTMLElement;
|
||||||
|
|
||||||
@State() private showSpinner: boolean = null;
|
@State() private showSpinner: boolean = null;
|
||||||
@ -31,6 +32,7 @@ export class Picker {
|
|||||||
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: AnimationController;
|
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: AnimationController;
|
||||||
@Prop({ context: 'config' }) config: Config;
|
@Prop({ context: 'config' }) config: Config;
|
||||||
@Prop({ context: 'dom' }) dom: DomController;
|
@Prop({ context: 'dom' }) dom: DomController;
|
||||||
|
@Prop() overlayId: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animation to use when the picker is presented.
|
* Animation to use when the picker is presented.
|
||||||
@ -120,7 +122,7 @@ export class Picker {
|
|||||||
|
|
||||||
this.ionPickerWillPresent.emit();
|
this.ionPickerWillPresent.emit();
|
||||||
|
|
||||||
this.el.style.zIndex = `${20000 + this.pickerId}`;
|
this.el.style.zIndex = `${20000 + this.overlayId}`;
|
||||||
|
|
||||||
// get the user's animation fn if one was provided
|
// get the user's animation fn if one was provided
|
||||||
const animationBuilder = this.enterAnimation || this.config.get('pickerEnter', iosEnterAnimation);
|
const animationBuilder = this.enterAnimation || this.config.get('pickerEnter', iosEnterAnimation);
|
||||||
|
@ -59,6 +59,11 @@ Animation to use when the picker is presented.
|
|||||||
Animation to use when the picker is dismissed.
|
Animation to use when the picker is dismissed.
|
||||||
|
|
||||||
|
|
||||||
|
#### overlayId
|
||||||
|
|
||||||
|
number
|
||||||
|
|
||||||
|
|
||||||
#### showBackdrop
|
#### showBackdrop
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
@ -125,6 +130,11 @@ Animation to use when the picker is presented.
|
|||||||
Animation to use when the picker is dismissed.
|
Animation to use when the picker is dismissed.
|
||||||
|
|
||||||
|
|
||||||
|
#### overlay-id
|
||||||
|
|
||||||
|
number
|
||||||
|
|
||||||
|
|
||||||
#### show-backdrop
|
#### show-backdrop
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
|
@ -1,27 +1,27 @@
|
|||||||
import { Component, Listen, Method } from '@stencil/core';
|
import { Component, Listen, Method } from '@stencil/core';
|
||||||
import { OverlayController, PopoverEvent, PopoverOptions } from '../../index';
|
import { OverlayController, PopoverEvent, PopoverOptions } from '../../index';
|
||||||
|
import { createOverlay, dismissOverlay, getTopOverlay, removeLastOverlay } from '../../utils/overlays';
|
||||||
let ids = 0;
|
|
||||||
const popovers = new Map<number, HTMLIonPopoverElement>();
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
tag: 'ion-popover-controller'
|
tag: 'ion-popover-controller'
|
||||||
})
|
})
|
||||||
export class PopoverController implements OverlayController {
|
export class PopoverController implements OverlayController {
|
||||||
|
|
||||||
|
private popovers = new Map<number, HTMLIonPopoverElement>();
|
||||||
|
|
||||||
@Listen('body:ionPopoverWillPresent')
|
@Listen('body:ionPopoverWillPresent')
|
||||||
protected popoverWillPresent(ev: PopoverEvent) {
|
protected popoverWillPresent(ev: PopoverEvent) {
|
||||||
popovers.set(ev.target.popoverId, ev.target);
|
this.popovers.set(ev.target.overlayId, ev.target);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Listen('body:ionPopoverWillDismiss, body:ionPopoverDidUnload')
|
@Listen('body:ionPopoverWillDismiss, body:ionPopoverDidUnload')
|
||||||
protected popoverWillDismiss(ev: PopoverEvent) {
|
protected popoverWillDismiss(ev: PopoverEvent) {
|
||||||
popovers.delete(ev.target.popoverId);
|
this.popovers.delete(ev.target.overlayId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Listen('body:keyup.escape')
|
@Listen('body:keyup.escape')
|
||||||
protected escapeKeyUp() {
|
protected escapeKeyUp() {
|
||||||
removeLastPopover();
|
removeLastOverlay(this.popovers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -29,21 +29,7 @@ export class PopoverController implements OverlayController {
|
|||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
create(opts?: PopoverOptions): Promise<HTMLIonPopoverElement> {
|
create(opts?: PopoverOptions): Promise<HTMLIonPopoverElement> {
|
||||||
// create ionic's wrapping ion-popover component
|
return createOverlay('ion-popover', opts);
|
||||||
const popoverElement = document.createElement('ion-popover');
|
|
||||||
|
|
||||||
// give this popover a unique id
|
|
||||||
popoverElement.popoverId = ids++;
|
|
||||||
|
|
||||||
// convert the passed in popover options into props
|
|
||||||
// that get passed down into the new popover
|
|
||||||
Object.assign(popoverElement, opts);
|
|
||||||
|
|
||||||
// append the popover element to the document body
|
|
||||||
const appRoot = document.querySelector('ion-app') || document.body;
|
|
||||||
appRoot.appendChild(popoverElement);
|
|
||||||
|
|
||||||
return popoverElement.componentOnReady();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -51,12 +37,7 @@ export class PopoverController implements OverlayController {
|
|||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
dismiss(data?: any, role?: any, popoverId = -1) {
|
dismiss(data?: any, role?: any, popoverId = -1) {
|
||||||
popoverId = popoverId >= 0 ? popoverId : getHighestId();
|
return dismissOverlay(data, role, this.popovers, popoverId);
|
||||||
const popover = popovers.get(popoverId);
|
|
||||||
if (!popover) {
|
|
||||||
return Promise.reject('popover does not exist');
|
|
||||||
}
|
|
||||||
return popover.dismiss(data, role);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -64,21 +45,6 @@ export class PopoverController implements OverlayController {
|
|||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
getTop() {
|
getTop() {
|
||||||
return popovers.get(getHighestId());
|
return getTopOverlay(this.popovers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getHighestId() {
|
|
||||||
let minimum = -1;
|
|
||||||
popovers.forEach((_popover: HTMLIonPopoverElement, id: number) => {
|
|
||||||
if (id > minimum) {
|
|
||||||
minimum = id;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return minimum;
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeLastPopover() {
|
|
||||||
const toRemove = popovers.get(getHighestId());
|
|
||||||
return toRemove ? toRemove.dismiss() : Promise.resolve();
|
|
||||||
}
|
|
||||||
|
@ -4,6 +4,7 @@ import { Animation, AnimationBuilder, AnimationController, Config, DomController
|
|||||||
import { DomFrameworkDelegate } from '../../utils/dom-framework-delegate';
|
import { DomFrameworkDelegate } from '../../utils/dom-framework-delegate';
|
||||||
import { domControllerAsync, playAnimationAsync } from '../../utils/helpers';
|
import { domControllerAsync, playAnimationAsync } from '../../utils/helpers';
|
||||||
import { createThemedClasses } from '../../utils/theme';
|
import { createThemedClasses } from '../../utils/theme';
|
||||||
|
import { OverlayInterface, BACKDROP } 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';
|
||||||
@ -20,8 +21,7 @@ import mdLeaveAnimation from './animations/md.leave';
|
|||||||
theme: 'popover'
|
theme: 'popover'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
export class Popover {
|
export class Popover implements OverlayInterface {
|
||||||
popoverId: number;
|
|
||||||
|
|
||||||
private animation: Animation;
|
private animation: Animation;
|
||||||
private usersComponentElement: HTMLElement;
|
private usersComponentElement: HTMLElement;
|
||||||
@ -32,6 +32,7 @@ export class Popover {
|
|||||||
@Prop({ context: 'config' }) config: Config;
|
@Prop({ context: 'config' }) config: Config;
|
||||||
@Prop({ context: 'dom' }) dom: DomController;
|
@Prop({ context: 'dom' }) dom: DomController;
|
||||||
@Prop({ mutable: true }) delegate: FrameworkDelegate;
|
@Prop({ mutable: true }) delegate: FrameworkDelegate;
|
||||||
|
@Prop() overlayId: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The color to use from your Sass `$colors` map.
|
* The color to use from your Sass `$colors` map.
|
||||||
@ -150,7 +151,7 @@ export class Popover {
|
|||||||
|
|
||||||
@Listen('ionBackdropTap')
|
@Listen('ionBackdropTap')
|
||||||
protected onBackdropTap() {
|
protected onBackdropTap() {
|
||||||
this.dismiss();
|
this.dismiss(null, BACKDROP);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -164,7 +165,7 @@ export class Popover {
|
|||||||
}
|
}
|
||||||
this.ionPopoverWillPresent.emit();
|
this.ionPopoverWillPresent.emit();
|
||||||
|
|
||||||
this.el.style.zIndex = `${10000 + this.popoverId}`;
|
this.el.style.zIndex = `${10000 + this.overlayId}`;
|
||||||
|
|
||||||
// get the user's animation fn if one was provided
|
// get the user's animation fn if one was provided
|
||||||
const animationBuilder = this.enterAnimation || this.config.get('popoverEnter', this.mode === 'ios' ? iosEnterAnimation : mdEnterAnimation);
|
const animationBuilder = this.enterAnimation || this.config.get('popoverEnter', this.mode === 'ios' ? iosEnterAnimation : mdEnterAnimation);
|
||||||
|
@ -101,6 +101,11 @@ Possible values are: `"ios"` or `"md"`.
|
|||||||
For more information, see [Platform Styles](/docs/theming/platform-specific-styles).
|
For more information, see [Platform Styles](/docs/theming/platform-specific-styles).
|
||||||
|
|
||||||
|
|
||||||
|
#### overlayId
|
||||||
|
|
||||||
|
number
|
||||||
|
|
||||||
|
|
||||||
#### showBackdrop
|
#### showBackdrop
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
@ -197,6 +202,11 @@ Possible values are: `"ios"` or `"md"`.
|
|||||||
For more information, see [Platform Styles](/docs/theming/platform-specific-styles).
|
For more information, see [Platform Styles](/docs/theming/platform-specific-styles).
|
||||||
|
|
||||||
|
|
||||||
|
#### overlay-id
|
||||||
|
|
||||||
|
number
|
||||||
|
|
||||||
|
|
||||||
#### show-backdrop
|
#### show-backdrop
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
|
@ -1,27 +1,28 @@
|
|||||||
import { Component, Listen, Method } from '@stencil/core';
|
import { Component, Listen, Method } from '@stencil/core';
|
||||||
import { OverlayController, ToastEvent, ToastOptions } from '../../index';
|
import { OverlayController, ToastEvent, ToastOptions } from '../../index';
|
||||||
|
import { createOverlay, dismissOverlay, getTopOverlay, removeLastOverlay } from '../../utils/overlays';
|
||||||
|
|
||||||
let ids = 0;
|
|
||||||
const toasts = new Map<number, HTMLIonToastElement>();
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
tag: 'ion-toast-controller'
|
tag: 'ion-toast-controller'
|
||||||
})
|
})
|
||||||
export class ToastController implements OverlayController {
|
export class ToastController implements OverlayController {
|
||||||
|
|
||||||
|
private toasts = new Map<number, HTMLIonToastElement>();
|
||||||
|
|
||||||
@Listen('body:ionToastWillPresent')
|
@Listen('body:ionToastWillPresent')
|
||||||
protected toastWillPresent(ev: ToastEvent) {
|
protected toastWillPresent(ev: ToastEvent) {
|
||||||
toasts.set(ev.target.toastId, ev.target);
|
this.toasts.set(ev.target.overlayId, ev.target);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Listen('body:ionToastWillDismiss, body:ionToastDidUnload')
|
@Listen('body:ionToastWillDismiss, body:ionToastDidUnload')
|
||||||
protected toastWillDismiss(ev: ToastEvent) {
|
protected toastWillDismiss(ev: ToastEvent) {
|
||||||
toasts.delete(ev.target.toastId);
|
this.toasts.delete(ev.target.overlayId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Listen('body:keyup.escape')
|
@Listen('body:keyup.escape')
|
||||||
protected escapeKeyUp() {
|
protected escapeKeyUp() {
|
||||||
removeLastToast();
|
removeLastOverlay(this.toasts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -29,21 +30,7 @@ export class ToastController implements OverlayController {
|
|||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
create(opts?: ToastOptions): Promise<HTMLIonToastElement> {
|
create(opts?: ToastOptions): Promise<HTMLIonToastElement> {
|
||||||
// create ionic's wrapping ion-toast component
|
return createOverlay('ion-toast', opts);
|
||||||
const toastElement = document.createElement('ion-toast');
|
|
||||||
|
|
||||||
// give this toast a unique id
|
|
||||||
toastElement.toastId = ids++;
|
|
||||||
|
|
||||||
// convert the passed in toast options into props
|
|
||||||
// that get passed down into the new toast
|
|
||||||
Object.assign(toastElement, opts);
|
|
||||||
|
|
||||||
// append the toast element to the document body
|
|
||||||
const appRoot = document.querySelector('ion-app') || document.body;
|
|
||||||
appRoot.appendChild(toastElement);
|
|
||||||
|
|
||||||
return toastElement.componentOnReady();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -51,12 +38,7 @@ export class ToastController implements OverlayController {
|
|||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
dismiss(data?: any, role?: any, toastId = -1) {
|
dismiss(data?: any, role?: any, toastId = -1) {
|
||||||
toastId = toastId >= 0 ? toastId : getHighestId();
|
return dismissOverlay(data, role, this.toasts, toastId);
|
||||||
const toast = toasts.get(toastId);
|
|
||||||
if (!toast) {
|
|
||||||
return Promise.reject('toast does not exist');
|
|
||||||
}
|
|
||||||
return toast.dismiss(data, role);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -64,21 +46,6 @@ export class ToastController implements OverlayController {
|
|||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
getTop() {
|
getTop() {
|
||||||
return toasts.get(getHighestId());
|
return getTopOverlay(this.toasts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getHighestId() {
|
|
||||||
let minimum = -1;
|
|
||||||
toasts.forEach((_toast: HTMLIonToastElement, id: number) => {
|
|
||||||
if (id > minimum) {
|
|
||||||
minimum = id;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return minimum;
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeLastToast() {
|
|
||||||
const toRemove = toasts.get(getHighestId());
|
|
||||||
return toRemove ? toRemove.dismiss() : Promise.resolve();
|
|
||||||
}
|
|
||||||
|
@ -94,6 +94,11 @@ string
|
|||||||
Message to be shown in the toast.
|
Message to be shown in the toast.
|
||||||
|
|
||||||
|
|
||||||
|
#### overlayId
|
||||||
|
|
||||||
|
number
|
||||||
|
|
||||||
|
|
||||||
#### position
|
#### position
|
||||||
|
|
||||||
string
|
string
|
||||||
@ -175,6 +180,11 @@ string
|
|||||||
Message to be shown in the toast.
|
Message to be shown in the toast.
|
||||||
|
|
||||||
|
|
||||||
|
#### overlay-id
|
||||||
|
|
||||||
|
number
|
||||||
|
|
||||||
|
|
||||||
#### position
|
#### position
|
||||||
|
|
||||||
string
|
string
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
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, AnimationController, Config, CssClassMap, DomController, OverlayDismissEvent, OverlayDismissEventDetail } from '../../index';
|
import { Animation, AnimationBuilder, AnimationController, Config, CssClassMap, DomController, OverlayDismissEvent, OverlayDismissEventDetail } from '../../index';
|
||||||
import { domControllerAsync, playAnimationAsync } from '../../utils/helpers';
|
|
||||||
|
|
||||||
|
import { domControllerAsync, playAnimationAsync } from '../../utils/helpers';
|
||||||
import { createThemedClasses, getClassMap } from '../../utils/theme';
|
import { createThemedClasses, getClassMap } from '../../utils/theme';
|
||||||
|
import { OverlayInterface } 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';
|
||||||
@ -20,10 +21,9 @@ import mdLeaveAnimation from './animations/md.leave';
|
|||||||
theme: 'toast'
|
theme: 'toast'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
export class Toast {
|
export class Toast implements OverlayInterface {
|
||||||
private animation: Animation | null;
|
|
||||||
|
|
||||||
toastId: number;
|
private animation: Animation | null;
|
||||||
|
|
||||||
@Element() private el: HTMLElement;
|
@Element() private el: HTMLElement;
|
||||||
|
|
||||||
@ -33,6 +33,7 @@ export class Toast {
|
|||||||
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: AnimationController;
|
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: AnimationController;
|
||||||
@Prop({ context: 'config' }) config: Config;
|
@Prop({ context: 'config' }) config: Config;
|
||||||
@Prop({ context: 'dom' }) dom: DomController;
|
@Prop({ context: 'dom' }) dom: DomController;
|
||||||
|
@Prop() overlayId: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animation to use when the toast is presented.
|
* Animation to use when the toast is presented.
|
||||||
|
@ -50,6 +50,16 @@ export function assert(bool: boolean, msg: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function autoFocus(containerEl: HTMLElement): HTMLElement {
|
||||||
|
const focusableEls = containerEl.querySelectorAll('a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [tabindex="0"]');
|
||||||
|
if (focusableEls.length > 0) {
|
||||||
|
const el = focusableEls[0] as HTMLInputElement;
|
||||||
|
el.focus();
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
export function toDashCase(str: string) {
|
export function toDashCase(str: string) {
|
||||||
return str.replace(/([A-Z])/g, (g) => '-' + g[0].toLowerCase());
|
return str.replace(/([A-Z])/g, (g) => '-' + g[0].toLowerCase());
|
||||||
}
|
}
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
|
|
||||||
export const BACKDROP = 'backdrop';
|
|
62
packages/core/src/utils/overlays.ts
Normal file
62
packages/core/src/utils/overlays.ts
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
|
||||||
|
export const BACKDROP = 'backdrop';
|
||||||
|
|
||||||
|
export interface OverlayInterface {
|
||||||
|
overlayId: number;
|
||||||
|
|
||||||
|
present(): Promise<void>;
|
||||||
|
dismiss(data?: any, role?: string): Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HTMLIonOverlayElement extends HTMLStencilElement, OverlayInterface {}
|
||||||
|
|
||||||
|
export type OverlayMap = Map<number, HTMLIonOverlayElement>;
|
||||||
|
|
||||||
|
let lastId = 1;
|
||||||
|
|
||||||
|
export function createOverlay<T extends HTMLIonOverlayElement>
|
||||||
|
(tagName: string, opts: any): Promise<T> {
|
||||||
|
// create ionic's wrapping ion-alert component
|
||||||
|
const element = document.createElement(tagName) as T;
|
||||||
|
|
||||||
|
// give this alert a unique id
|
||||||
|
element.overlayId = lastId++;
|
||||||
|
|
||||||
|
// convert the passed in alert options into props
|
||||||
|
// that get passed down into the new alert
|
||||||
|
Object.assign(element, opts);
|
||||||
|
|
||||||
|
// append the alert element to the document body
|
||||||
|
const appRoot = document.querySelector('ion-app') || document.body;
|
||||||
|
appRoot.appendChild(element);
|
||||||
|
|
||||||
|
return element.componentOnReady();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function dismissOverlay(data: any, role: any, overlays: OverlayMap, id: number): Promise<void> {
|
||||||
|
id = id >= 0 ? id : getHighestId(overlays);
|
||||||
|
const overlay = overlays.get(id);
|
||||||
|
if (!overlay) {
|
||||||
|
return Promise.reject('overlay does not exist');
|
||||||
|
}
|
||||||
|
return overlay.dismiss(data, role);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getTopOverlay(overlays: Map<number, any>) {
|
||||||
|
return overlays.get(getHighestId(overlays));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getHighestId(overlays: Map<number, any>) {
|
||||||
|
let minimum = -1;
|
||||||
|
overlays.forEach((_, id: number) => {
|
||||||
|
if (id > minimum) {
|
||||||
|
minimum = id;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return minimum;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function removeLastOverlay(overlays: OverlayMap) {
|
||||||
|
const toRemove = getTopOverlay(overlays);
|
||||||
|
return toRemove ? toRemove.dismiss() : Promise.resolve();
|
||||||
|
}
|
Reference in New Issue
Block a user