mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-08 23:58:13 +08:00
feat(prop): load controllers w/ prop connect and context
This commit is contained in:
@ -1,15 +0,0 @@
|
||||
import { Component } from '@stencil/core';
|
||||
import { Animator } from './animator';
|
||||
import { Ionic } from '../../index';
|
||||
|
||||
|
||||
@Component({
|
||||
tag: 'ion-animation-controller'
|
||||
})
|
||||
export class AnimationController {
|
||||
|
||||
ionViewWillLoad() {
|
||||
Ionic.registerController('animation', Animator);
|
||||
}
|
||||
|
||||
}
|
||||
22
packages/core/src/components/animation/animation.tsx
Normal file
22
packages/core/src/components/animation/animation.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import { Component, Method } from '@stencil/core';
|
||||
import { Animation, AnimationBuilder } from './animation-interface';
|
||||
import { Animator } from './animator';
|
||||
|
||||
|
||||
@Component({
|
||||
tag: 'ion-animation'
|
||||
})
|
||||
export class AnimationController {
|
||||
|
||||
@Method()
|
||||
create(animationBuilder?: AnimationBuilder, baseElm?: any): Promise<Animation> {
|
||||
return new Promise(resolve => {
|
||||
if (animationBuilder) {
|
||||
resolve(animationBuilder(Animator as any, baseElm));
|
||||
} else {
|
||||
resolve(new Animator() as any);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
import { Component, Element, Prop } from '@stencil/core';
|
||||
import { Ionic, Scroll, ScrollDetail } from '../../index';
|
||||
import { Config, Scroll, ScrollDetail } from '../../index';
|
||||
import { createThemedClasses } from '../../utils/theme';
|
||||
import { getParentElement, getToolbarHeight } from '../../utils/helpers';
|
||||
|
||||
@ -16,6 +16,7 @@ export class Content {
|
||||
private mode: string;
|
||||
private color: string;
|
||||
@Element() private el: HTMLElement;
|
||||
@Prop({ context: 'config' }) config: Config;
|
||||
|
||||
$scroll: Scroll;
|
||||
$scrollDetail: ScrollDetail = {};
|
||||
@ -103,7 +104,7 @@ export class Content {
|
||||
props['ionScrollEnd'] = this.ionScrollEnd.bind(this);
|
||||
}
|
||||
const themedClasses = createThemedClasses(this.mode, this.color, 'content');
|
||||
themedClasses['statusbar-padding'] = Ionic.config.getBoolean('statusbarPadding');
|
||||
themedClasses['statusbar-padding'] = this.config.getBoolean('statusbarPadding');
|
||||
|
||||
return (
|
||||
<ion-scroll style={scrollStyle} props={props} class={themedClasses}>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Component, Element } from '@stencil/core';
|
||||
import { Component, Element, Prop } from '@stencil/core';
|
||||
import { getParentElement, getToolbarHeight } from '../../utils/helpers';
|
||||
import { Ionic } from '../../index';
|
||||
import { Config } from '../../index';
|
||||
|
||||
|
||||
@Component({
|
||||
@ -15,6 +15,7 @@ import { Ionic } from '../../index';
|
||||
})
|
||||
export class Fixed {
|
||||
@Element() private el: HTMLElement;
|
||||
@Prop({ context: 'config' }) config: Config;
|
||||
mode: string;
|
||||
|
||||
hostData() {
|
||||
@ -24,7 +25,7 @@ export class Fixed {
|
||||
|
||||
return {
|
||||
class: {
|
||||
'statusbar-padding': Ionic.config.getBoolean('statusbarPadding')
|
||||
'statusbar-padding': this.config.getBoolean('statusbarPadding')
|
||||
},
|
||||
style: {
|
||||
'margin-top': headerHeight,
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
import { Component } from '@stencil/core';
|
||||
|
||||
|
||||
@Component({
|
||||
tag: 'ion-gesture-ctrl'
|
||||
})
|
||||
export class GestureController {
|
||||
private id: number = 0;
|
||||
private requestedStart: { [eventId: number]: number } = {};
|
||||
@ -1,8 +1,6 @@
|
||||
import { applyStyles, getElementReference, pointerCoordX, pointerCoordY } from '../../utils/helpers';
|
||||
import { BlockerDelegate } from './gesture-controller';
|
||||
import { BlockerDelegate, GestureController, GestureDelegate, BLOCK_ALL } from '../gesture-controller/gesture-controller';
|
||||
import { Component, Element, Event, EventEmitter, Listen, Prop, PropDidChange } from '@stencil/core';
|
||||
import { GestureController, GestureDelegate, BLOCK_ALL } from './gesture-controller';
|
||||
import { Ionic } from '../../index';
|
||||
import { PanRecognizer } from './recognizers';
|
||||
|
||||
|
||||
@ -11,9 +9,9 @@ import { PanRecognizer } from './recognizers';
|
||||
})
|
||||
export class Gesture {
|
||||
@Element() private el: HTMLElement;
|
||||
private ctrl: GestureController;
|
||||
private detail: GestureDetail = {};
|
||||
private positions: number[] = [];
|
||||
private ctrl: GestureController;
|
||||
private gesture: GestureDelegate;
|
||||
private lastTouch = 0;
|
||||
private pan: PanRecognizer;
|
||||
@ -53,8 +51,7 @@ export class Gesture {
|
||||
// in this case, we already know the GestureController and Gesture are already
|
||||
// apart of the same bundle, so it's safe to load it this way
|
||||
// only create one instance of GestureController, and reuse the same one later
|
||||
this.ctrl = Ionic.controllers.gesture = (Ionic.controllers.gesture || new GestureController());
|
||||
|
||||
this.ctrl = Context.gesture = Context.gesture || new GestureController;
|
||||
this.gesture = this.ctrl.createGesture(this.gestureName, this.gesturePriority, this.disableScroll);
|
||||
|
||||
const types = this.type.replace(/\s/g, '').toLowerCase().split(',');
|
||||
@ -66,10 +63,10 @@ export class Gesture {
|
||||
this.hasPress = (types.indexOf('press') > -1);
|
||||
|
||||
if (this.pan || this.hasPress) {
|
||||
Core.enableListener(this, 'touchstart', true, this.attachTo);
|
||||
Core.enableListener(this, 'mousedown', true, this.attachTo);
|
||||
Context.enableListener(this, 'touchstart', true, this.attachTo);
|
||||
Context.enableListener(this, 'mousedown', true, this.attachTo);
|
||||
|
||||
Core.dom.write(() => {
|
||||
Context.dom.write(() => {
|
||||
applyStyles(getElementReference(this.el, this.attachTo), GESTURE_INLINE_STYLES);
|
||||
});
|
||||
}
|
||||
@ -187,7 +184,7 @@ export class Gesture {
|
||||
if (!this.isMoveQueued) {
|
||||
this.isMoveQueued = true;
|
||||
|
||||
Core.dom.write(() => {
|
||||
Context.dom.write(() => {
|
||||
this.isMoveQueued = false;
|
||||
detail.type = 'pan';
|
||||
|
||||
@ -357,17 +354,17 @@ export class Gesture {
|
||||
|
||||
private enableMouse(shouldEnable: boolean) {
|
||||
if (this.requiresMove) {
|
||||
Core.enableListener(this, 'document:mousemove', shouldEnable);
|
||||
Context.enableListener(this, 'document:mousemove', shouldEnable);
|
||||
}
|
||||
Core.enableListener(this, 'document:mouseup', shouldEnable);
|
||||
Context.enableListener(this, 'document:mouseup', shouldEnable);
|
||||
}
|
||||
|
||||
|
||||
private enableTouch(shouldEnable: boolean) {
|
||||
if (this.requiresMove) {
|
||||
Core.enableListener(this, 'touchmove', shouldEnable);
|
||||
Context.enableListener(this, 'touchmove', shouldEnable);
|
||||
}
|
||||
Core.enableListener(this, 'touchend', shouldEnable);
|
||||
Context.enableListener(this, 'touchend', shouldEnable);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,32 +0,0 @@
|
||||
@import "../../themes/ionic.globals";
|
||||
|
||||
|
||||
// Loading Controller
|
||||
// --------------------------------------------------
|
||||
|
||||
ion-loading-controller {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
// Loading Controller Backdrop
|
||||
// --------------------------------------------------
|
||||
|
||||
/// @prop - Color of the backdrop
|
||||
$loading-backdrop-color: #000 !default;
|
||||
|
||||
|
||||
.loading-backdrop {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: $z-index-backdrop;
|
||||
display: block;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
background-color: $loading-backdrop-color;
|
||||
opacity: .01;
|
||||
transform: translateZ(0);
|
||||
}
|
||||
@ -1,26 +1,17 @@
|
||||
import { Component, Listen } from '@stencil/core';
|
||||
import { Ionic } from '../../index';
|
||||
import { LoadingEvent, LoadingOptions, Loading, IonicControllerApi } from '../../index';
|
||||
import { Component, Listen, Method } from '@stencil/core';
|
||||
import { LoadingEvent, LoadingOptions, Loading } from '../../index';
|
||||
|
||||
|
||||
@Component({
|
||||
tag: 'ion-loading-controller',
|
||||
styleUrl: 'loading-controller.scss'
|
||||
tag: 'ion-loading-ctrl'
|
||||
})
|
||||
export class LoadingController implements IonicControllerApi {
|
||||
export class LoadingController {
|
||||
private ids = 0;
|
||||
private loadingResolves: {[loadingId: string]: Function} = {};
|
||||
private loadings: Loading[] = [];
|
||||
private appRoot: Element;
|
||||
|
||||
|
||||
ionViewDidLoad() {
|
||||
this.appRoot = document.querySelector('ion-app') || document.body;
|
||||
Ionic.registerController('loading', this);
|
||||
}
|
||||
|
||||
|
||||
load(opts?: LoadingOptions) {
|
||||
@Method()
|
||||
create(opts?: LoadingOptions) {
|
||||
// create ionic's wrapping ion-loading component
|
||||
const loading = document.createElement('ion-loading');
|
||||
|
||||
@ -35,7 +26,8 @@ export class LoadingController implements IonicControllerApi {
|
||||
Object.assign(loading, opts);
|
||||
|
||||
// append the loading element to the document body
|
||||
this.appRoot.appendChild(loading as any);
|
||||
const appRoot = document.querySelector('ion-app') || document.body;
|
||||
appRoot.appendChild(loading as any);
|
||||
|
||||
// store the resolve function to be called later up when the loading loads
|
||||
return new Promise<Loading>(resolve => {
|
||||
@ -45,7 +37,7 @@ export class LoadingController implements IonicControllerApi {
|
||||
|
||||
|
||||
@Listen('body:ionLoadingDidLoad')
|
||||
viewDidLoad(ev: LoadingEvent) {
|
||||
protected viewDidLoad(ev: LoadingEvent) {
|
||||
const loading = ev.detail.loading;
|
||||
const loadingResolve = this.loadingResolves[loading.id];
|
||||
if (loadingResolve) {
|
||||
@ -56,13 +48,13 @@ export class LoadingController implements IonicControllerApi {
|
||||
|
||||
|
||||
@Listen('body:ionLoadingWillPresent')
|
||||
willPresent(ev: LoadingEvent) {
|
||||
protected willPresent(ev: LoadingEvent) {
|
||||
this.loadings.push(ev.detail.loading);
|
||||
}
|
||||
|
||||
|
||||
@Listen('body:ionLoadingWillDismiss, body:ionLoadingDidUnload')
|
||||
willDismiss(ev: LoadingEvent) {
|
||||
protected willDismiss(ev: LoadingEvent) {
|
||||
const index = this.loadings.indexOf(ev.detail.loading);
|
||||
if (index > -1) {
|
||||
this.loadings.splice(index, 1);
|
||||
@ -71,7 +63,7 @@ export class LoadingController implements IonicControllerApi {
|
||||
|
||||
|
||||
@Listen('body:keyup.escape')
|
||||
escapeKeyUp() {
|
||||
protected escapeKeyUp() {
|
||||
const lastLoading = this.loadings[this.loadings.length - 1];
|
||||
if (lastLoading) {
|
||||
lastLoading.dismiss();
|
||||
|
||||
@ -1,9 +1,13 @@
|
||||
@import "../../themes/ionic.globals";
|
||||
|
||||
|
||||
// Loading Indicator
|
||||
// Loading
|
||||
// --------------------------------------------------
|
||||
|
||||
/// @prop - Color of the backdrop
|
||||
$loading-backdrop-color: #000 !default;
|
||||
|
||||
|
||||
ion-loading {
|
||||
@include position(0, 0, 0, 0);
|
||||
|
||||
@ -27,6 +31,25 @@ ion-loading ion-gesture {
|
||||
visibility: inherit;
|
||||
}
|
||||
|
||||
ion-loading-controller {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.loading-backdrop {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: $z-index-backdrop;
|
||||
display: block;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
background-color: $loading-backdrop-color;
|
||||
opacity: .01;
|
||||
transform: translateZ(0);
|
||||
}
|
||||
|
||||
.loading-wrapper {
|
||||
z-index: $z-index-overlay-wrapper;
|
||||
display: flex;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Animation, AnimationBuilder, Ionic } from '../../index';
|
||||
import { Animation, AnimationBuilder, AnimationController, Config } from '../../index';
|
||||
import { Component, Element, Event, EventEmitter, Listen, Prop, State } from '@stencil/core';
|
||||
|
||||
import iOSEnterAnimation from './animations/ios.enter';
|
||||
@ -32,6 +32,8 @@ export class Loading {
|
||||
@State() private showSpinner: boolean = null;
|
||||
@State() private spinner: string;
|
||||
|
||||
@Prop({ connect: 'ion-animation' }) animationCtrl: AnimationController;
|
||||
@Prop({ context: 'config' }) config: Config;
|
||||
@Prop() cssClass: string;
|
||||
@Prop() content: string;
|
||||
@Prop() dismissOnPageChange: boolean = false;
|
||||
@ -41,38 +43,6 @@ export class Loading {
|
||||
@Prop() id: string;
|
||||
@Prop() showBackdrop: boolean = true;
|
||||
|
||||
@Listen('ionDismiss')
|
||||
onDismiss(ev: UIEvent) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
|
||||
this.dismiss();
|
||||
}
|
||||
|
||||
ionViewDidLoad() {
|
||||
if (!this.spinner) {
|
||||
this.spinner = Ionic.config.get('loadingSpinner', Ionic.config.get('spinner', 'lines'));
|
||||
}
|
||||
|
||||
if (this.showSpinner === null || this.showSpinner === undefined) {
|
||||
this.showSpinner = !!(this.spinner && this.spinner !== 'hide');
|
||||
}
|
||||
this.ionLoadingDidLoad.emit({ loading: this });
|
||||
}
|
||||
|
||||
ionViewDidEnter() {
|
||||
// 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 (typeof this.duration === 'number' && this.duration > 10) {
|
||||
this.durationTimeout = setTimeout(() => this.dismiss(), this.duration);
|
||||
}
|
||||
|
||||
this.ionLoadingDidPresent.emit({ loading: this });
|
||||
}
|
||||
|
||||
present() {
|
||||
return new Promise<void>(resolve => {
|
||||
this._present(resolve);
|
||||
@ -97,16 +67,15 @@ export class Loading {
|
||||
}
|
||||
|
||||
// build the animation and kick it off
|
||||
Ionic.controller('animation').then(Animation => {
|
||||
this.animation = animationBuilder(Animation, this.el);
|
||||
this.animationCtrl.create(animationBuilder, this.el).then(animation => {
|
||||
this.animation = animation;
|
||||
|
||||
this.animation.onFinish((a: any) => {
|
||||
animation.onFinish((a: any) => {
|
||||
a.destroy();
|
||||
this.ionViewDidEnter();
|
||||
resolve();
|
||||
|
||||
}).play();
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@ -118,26 +87,27 @@ export class Loading {
|
||||
this.animation = null;
|
||||
}
|
||||
|
||||
return Ionic.controller('animation').then(Animation => {
|
||||
return new Promise(resolve => {
|
||||
this.ionLoadingWillDismiss.emit({ loading: this });
|
||||
return new Promise(resolve => {
|
||||
this.ionLoadingWillDismiss.emit({ loading: this });
|
||||
|
||||
// get the user's animation fn if one was provided
|
||||
let animationBuilder = this.exitAnimation;
|
||||
// get the user's animation fn if one was provided
|
||||
let animationBuilder = this.exitAnimation;
|
||||
|
||||
if (!animationBuilder) {
|
||||
// user did not provide a custom animation fn
|
||||
// decide from the config which animation to use
|
||||
animationBuilder = iOSLeaveAnimation;
|
||||
}
|
||||
if (!animationBuilder) {
|
||||
// user did not provide a custom animation fn
|
||||
// decide from the config which animation to use
|
||||
animationBuilder = iOSLeaveAnimation;
|
||||
}
|
||||
|
||||
// build the animation and kick it off
|
||||
this.animation = animationBuilder(Animation, this.el);
|
||||
this.animation.onFinish((a: any) => {
|
||||
// build the animation and kick it off
|
||||
this.animationCtrl.create(animationBuilder, this.el).then(animation => {
|
||||
this.animation = animation;
|
||||
|
||||
animation.onFinish((a: any) => {
|
||||
a.destroy();
|
||||
this.ionLoadingDidDismiss.emit({ loading: this });
|
||||
|
||||
Core.dom.write(() => {
|
||||
Context.dom.write(() => {
|
||||
this.el.parentNode.removeChild(this.el);
|
||||
});
|
||||
|
||||
@ -148,11 +118,43 @@ export class Loading {
|
||||
});
|
||||
}
|
||||
|
||||
ionViewDidUnload() {
|
||||
protected ionViewDidUnload() {
|
||||
this.ionLoadingDidUnload.emit({ loading: this });
|
||||
}
|
||||
|
||||
render() {
|
||||
@Listen('ionDismiss')
|
||||
protected onDismiss(ev: UIEvent) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
|
||||
this.dismiss();
|
||||
}
|
||||
|
||||
protected ionViewDidLoad() {
|
||||
if (!this.spinner) {
|
||||
this.spinner = this.config.get('loadingSpinner', this.config.get('spinner', 'lines'));
|
||||
}
|
||||
|
||||
if (this.showSpinner === null || this.showSpinner === undefined) {
|
||||
this.showSpinner = !!(this.spinner && this.spinner !== 'hide');
|
||||
}
|
||||
this.ionLoadingDidLoad.emit({ loading: this });
|
||||
}
|
||||
|
||||
protected ionViewDidEnter() {
|
||||
// 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 (typeof this.duration === 'number' && this.duration > 10) {
|
||||
this.durationTimeout = setTimeout(() => this.dismiss(), this.duration);
|
||||
}
|
||||
|
||||
this.ionLoadingDidPresent.emit({ loading: this });
|
||||
}
|
||||
|
||||
protected render() {
|
||||
let userCssClass = 'loading-content';
|
||||
if (this.cssClass) {
|
||||
userCssClass += ' ' + this.cssClass;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Component, Element, Event, EventEmitter, Prop, PropDidChange } from '@stencil/core';
|
||||
import { Ionic } from '../../index';
|
||||
import { Config } from '../../index';
|
||||
import { MenuController } from './menu-controller';
|
||||
import { MenuType } from './menu-types';
|
||||
|
||||
@ -35,6 +35,8 @@ export class Menu {
|
||||
@Event() ionOpen: EventEmitter;
|
||||
@Event() ionClose: EventEmitter;
|
||||
|
||||
@Prop({ context: 'config' }) config: Config;
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
@ -153,7 +155,7 @@ export class Menu {
|
||||
render() {
|
||||
// normalize the "type"
|
||||
if (!this.type) {
|
||||
this.type = Ionic.config.get('menuType', 'overlay');
|
||||
this.type = this.config.get('menuType', 'overlay');
|
||||
}
|
||||
|
||||
return [
|
||||
@ -193,7 +195,7 @@ export class Menu {
|
||||
if (!this._type) {
|
||||
this._type = this._ctrl.create(this.type, this);
|
||||
|
||||
if (Ionic.config.getBoolean('animate') === false) {
|
||||
if (this.config.getBoolean('animate') === false) {
|
||||
this._type.ani.duration(0);
|
||||
}
|
||||
}
|
||||
@ -309,7 +311,7 @@ export class Menu {
|
||||
this._activeBlock = GESTURE_BLOCKER;
|
||||
|
||||
// add css class
|
||||
Core.dom.write(() => {
|
||||
Context.dom.write(() => {
|
||||
this._cntElm.classList.add('menu-content-open');
|
||||
});
|
||||
|
||||
@ -321,7 +323,7 @@ export class Menu {
|
||||
this._activeBlock = null;
|
||||
|
||||
// remove css classes
|
||||
Core.dom.write(() => {
|
||||
Context.dom.write(() => {
|
||||
this._cntElm.classList.remove('menu-content-open');
|
||||
this._cntElm.classList.remove('show-menu');
|
||||
this._backdropElm.classList.remove('show-menu');
|
||||
@ -479,8 +481,8 @@ export class Menu {
|
||||
const onBackdropClick = this.onBackdropClick.bind(this);
|
||||
|
||||
if (shouldAdd && !this._unregBdClick) {
|
||||
this._unregBdClick = Core.addListener(this._cntElm, 'click', onBackdropClick, { capture: true });
|
||||
this._unregCntClick = Core.addListener(this._cntElm, 'click', onBackdropClick, { capture: true });
|
||||
this._unregBdClick = Context.addListener(this._cntElm, 'click', onBackdropClick, { capture: true });
|
||||
this._unregCntClick = Context.addListener(this._cntElm, 'click', onBackdropClick, { capture: true });
|
||||
|
||||
} else if (!shouldAdd && this._unregBdClick) {
|
||||
this._unregBdClick();
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
@import "../../themes/ionic.globals";
|
||||
|
||||
|
||||
// Modal Controller
|
||||
// --------------------------------------------------
|
||||
|
||||
ion-modal-controller {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
// Modal Controller Backdrop
|
||||
// --------------------------------------------------
|
||||
|
||||
/// @prop - Color of the backdrop
|
||||
$modal-backdrop-color: #000 !default;
|
||||
|
||||
|
||||
.modal-backdrop {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: $z-index-backdrop;
|
||||
display: block;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
background-color: $modal-backdrop-color;
|
||||
opacity: .01;
|
||||
transform: translateZ(0);
|
||||
}
|
||||
|
||||
.modal-backdrop.backdrop-no-tappable {
|
||||
cursor: auto;
|
||||
}
|
||||
@ -1,26 +1,18 @@
|
||||
import { Component, Listen } from '@stencil/core';
|
||||
import { Ionic } from '../../index';
|
||||
import { ModalEvent, ModalOptions, Modal, IonicControllerApi } from '../../index';
|
||||
import { Component, Listen, Method } from '@stencil/core';
|
||||
import { Modal, ModalEvent, ModalOptions } from '../../index';
|
||||
|
||||
|
||||
@Component({
|
||||
tag: 'ion-modal-controller',
|
||||
styleUrl: 'modal-controller.scss'
|
||||
tag: 'ion-modal-ctrl'
|
||||
})
|
||||
export class ModalController implements IonicControllerApi {
|
||||
export class ModalController {
|
||||
private ids = 0;
|
||||
private modalResolves: {[modalId: string]: Function} = {};
|
||||
private modals: Modal[] = [];
|
||||
private appRoot: Element;
|
||||
|
||||
|
||||
ionViewDidLoad() {
|
||||
this.appRoot = document.querySelector('ion-app') || document.body;
|
||||
Ionic.registerController('modal', this);
|
||||
}
|
||||
|
||||
|
||||
load(opts?: ModalOptions) {
|
||||
@Method()
|
||||
create(opts?: ModalOptions) {
|
||||
// create ionic's wrapping ion-modal component
|
||||
const modal = document.createElement('ion-modal');
|
||||
|
||||
@ -35,7 +27,8 @@ export class ModalController implements IonicControllerApi {
|
||||
Object.assign(modal, opts);
|
||||
|
||||
// append the modal element to the document body
|
||||
this.appRoot.appendChild(modal as any);
|
||||
const appRoot = document.querySelector('ion-app') || document.body;
|
||||
appRoot.appendChild(modal as any);
|
||||
|
||||
// store the resolve function to be called later up when the modal loads
|
||||
return new Promise<Modal>(resolve => {
|
||||
@ -45,7 +38,7 @@ export class ModalController implements IonicControllerApi {
|
||||
|
||||
|
||||
@Listen('body:ionModalDidLoad')
|
||||
modalDidLoad(ev: ModalEvent) {
|
||||
protected modalDidLoad(ev: ModalEvent) {
|
||||
const modal = ev.detail.modal;
|
||||
const modalResolve = this.modalResolves[modal.id];
|
||||
if (modalResolve) {
|
||||
@ -56,13 +49,13 @@ export class ModalController implements IonicControllerApi {
|
||||
|
||||
|
||||
@Listen('body:ionModalWillPresent')
|
||||
modalWillPresent(ev: ModalEvent) {
|
||||
protected modalWillPresent(ev: ModalEvent) {
|
||||
this.modals.push(ev.detail.modal);
|
||||
}
|
||||
|
||||
|
||||
@Listen('body:ionModalWillDismiss, body:ionModalDidUnload')
|
||||
modalWillDismiss(ev: ModalEvent) {
|
||||
protected modalWillDismiss(ev: ModalEvent) {
|
||||
const index = this.modals.indexOf(ev.detail.modal);
|
||||
if (index > -1) {
|
||||
this.modals.splice(index, 1);
|
||||
@ -71,7 +64,7 @@ export class ModalController implements IonicControllerApi {
|
||||
|
||||
|
||||
@Listen('body:keyup.escape')
|
||||
escapeKeyUp() {
|
||||
protected escapeKeyUp() {
|
||||
const lastModal = this.modals[this.modals.length - 1];
|
||||
if (lastModal) {
|
||||
lastModal.dismiss();
|
||||
|
||||
@ -22,6 +22,9 @@ $modal-inset-height-small: 500px !default;
|
||||
/// @prop - Height of the large modal inset
|
||||
$modal-inset-height-large: 600px !default;
|
||||
|
||||
/// @prop - Color of the backdrop
|
||||
$modal-backdrop-color: #000 !default;
|
||||
|
||||
|
||||
ion-modal {
|
||||
@include position(0, null, null, 0);
|
||||
@ -36,6 +39,29 @@ ion-modal {
|
||||
contain: strict;
|
||||
}
|
||||
|
||||
ion-modal-controller {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.modal-backdrop {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: $z-index-backdrop;
|
||||
display: block;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
background-color: $modal-backdrop-color;
|
||||
opacity: .01;
|
||||
transform: translateZ(0);
|
||||
}
|
||||
|
||||
.modal-backdrop.backdrop-no-tappable {
|
||||
cursor: auto;
|
||||
}
|
||||
|
||||
.modal-backdrop {
|
||||
@media not all and (min-width: $modal-inset-min-width) and (min-height: $modal-inset-min-height-small) {
|
||||
visibility: hidden;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Component, Element, Event, EventEmitter, Listen, Prop } from '@stencil/core';
|
||||
import { AnimationBuilder, Animation, Ionic } from '../../index';
|
||||
import { AnimationBuilder, AnimationController, Animation } from '../../index';
|
||||
import { createThemedClasses } from '../../utils/theme';
|
||||
|
||||
import iOSEnterAnimation from './animations/ios.enter';
|
||||
@ -27,6 +27,7 @@ export class Modal {
|
||||
@Event() ionModalDidDismiss: EventEmitter;
|
||||
@Event() ionModalDidUnload: EventEmitter;
|
||||
|
||||
@Prop({ connect: 'ion-animation' }) animationCtrl: AnimationController;
|
||||
@Prop() mode: string;
|
||||
@Prop() color: string;
|
||||
@Prop() component: string;
|
||||
@ -38,20 +39,8 @@ export class Modal {
|
||||
@Prop() id: string;
|
||||
@Prop() showBackdrop: boolean = true;
|
||||
|
||||
|
||||
private animation: Animation;
|
||||
|
||||
@Listen('ionDismiss')
|
||||
onDismiss(ev: UIEvent) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
|
||||
this.dismiss();
|
||||
}
|
||||
|
||||
ionViewDidLoad() {
|
||||
this.ionModalDidLoad.emit({ modal: this });
|
||||
}
|
||||
|
||||
present() {
|
||||
return new Promise<void>(resolve => {
|
||||
@ -77,11 +66,11 @@ export class Modal {
|
||||
animationBuilder = iOSEnterAnimation;
|
||||
}
|
||||
|
||||
Ionic.controller('animation').then(Animation => {
|
||||
// build the animation and kick it off
|
||||
this.animation = animationBuilder(Animation, this.el);
|
||||
// build the animation and kick it off
|
||||
this.animationCtrl.create(animationBuilder, this.el).then(animation => {
|
||||
this.animation = animation;
|
||||
|
||||
this.animation.onFinish((a: any) => {
|
||||
animation.onFinish((a: any) => {
|
||||
a.destroy();
|
||||
this.ionModalDidPresent.emit({ modal: this });
|
||||
resolve();
|
||||
@ -109,13 +98,14 @@ export class Modal {
|
||||
}
|
||||
|
||||
// build the animation and kick it off
|
||||
Ionic.controller('animation').then(Animation => {
|
||||
this.animation = animationBuilder(Animation, this.el);
|
||||
this.animation.onFinish((a: any) => {
|
||||
this.animationCtrl.create(animationBuilder, this.el).then(animation => {
|
||||
this.animation = animation;
|
||||
|
||||
animation.onFinish((a: any) => {
|
||||
a.destroy();
|
||||
this.ionModalDidDismiss.emit({ modal: this });
|
||||
|
||||
Core.dom.write(() => {
|
||||
Context.dom.write(() => {
|
||||
this.el.parentNode.removeChild(this.el);
|
||||
});
|
||||
resolve();
|
||||
@ -124,11 +114,23 @@ export class Modal {
|
||||
});
|
||||
}
|
||||
|
||||
ionViewDidUnload() {
|
||||
@Listen('ionDismiss')
|
||||
protected onDismiss(ev: UIEvent) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
|
||||
this.dismiss();
|
||||
}
|
||||
|
||||
protected ionViewDidLoad() {
|
||||
this.ionModalDidLoad.emit({ modal: this });
|
||||
}
|
||||
|
||||
protected ionViewDidUnload() {
|
||||
this.ionModalDidUnload.emit({ modal: this });
|
||||
}
|
||||
|
||||
backdropClick() {
|
||||
protected backdropClick() {
|
||||
if (this.enableBackdropDismiss) {
|
||||
// const opts: NavOptions = {
|
||||
// minClickBlockDuration: 400
|
||||
@ -137,7 +139,7 @@ export class Modal {
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
protected render() {
|
||||
const ThisComponent = this.component;
|
||||
|
||||
let userCssClasses = 'modal-content';
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { Component, Element, Listen, Prop } from '@stencil/core';
|
||||
import { GestureDetail } from '../../index';
|
||||
import { GestureController, GestureDelegate } from '../gesture/gesture-controller';
|
||||
import { Ionic } from '../../index';
|
||||
import { Config, GestureDetail } from '../../index';
|
||||
import { GestureController, GestureDelegate } from '../gesture-controller/gesture-controller';
|
||||
|
||||
|
||||
@Component({
|
||||
@ -20,6 +19,7 @@ export class Scroll {
|
||||
isScrolling: boolean = false;
|
||||
detail: ScrollDetail = {};
|
||||
|
||||
@Prop({ context: 'config'}) config: Config;
|
||||
@Prop() enabled: boolean = true;
|
||||
@Prop() jsScroll: boolean = false;
|
||||
@Prop() ionScrollStart: ScrollCallback;
|
||||
@ -27,11 +27,10 @@ export class Scroll {
|
||||
@Prop() ionScrollEnd: ScrollCallback;
|
||||
|
||||
ionViewDidLoad() {
|
||||
if (Core.isServer) return;
|
||||
if (Context.isServer) return;
|
||||
|
||||
const ctrl = Ionic.controllers.gesture = (Ionic.controllers.gesture || new GestureController());
|
||||
|
||||
this.gesture = ctrl.createGesture('scroll', 100, false);
|
||||
const gestureCtrl = Context.gesture = Context.gesture || new GestureController;
|
||||
this.gesture = gestureCtrl.createGesture('scroll', 100, false);
|
||||
}
|
||||
|
||||
|
||||
@ -44,7 +43,7 @@ export class Scroll {
|
||||
if (!self.queued && self.enabled) {
|
||||
self.queued = true;
|
||||
|
||||
Core.dom.read(function(timeStamp) {
|
||||
Context.dom.read(function(timeStamp) {
|
||||
self.queued = false;
|
||||
self.onScroll(timeStamp || Date.now());
|
||||
});
|
||||
@ -125,7 +124,7 @@ export class Scroll {
|
||||
// haven't scrolled in a while, so it's a scrollend
|
||||
self.isScrolling = false;
|
||||
|
||||
Core.dom.read(function(timeStamp) {
|
||||
Context.dom.read(function(timeStamp) {
|
||||
if (!self.isScrolling) {
|
||||
self.onEnd(timeStamp);
|
||||
}
|
||||
@ -155,9 +154,8 @@ export class Scroll {
|
||||
enableJsScroll(contentTop: number, contentBottom: number) {
|
||||
this.jsScroll = true;
|
||||
|
||||
Core.enableListener(this, 'scroll', false);
|
||||
|
||||
Core.enableListener(this, 'touchstart', true);
|
||||
Context.enableListener(this, 'scroll', false);
|
||||
Context.enableListener(this, 'touchstart', true);
|
||||
|
||||
contentTop; contentBottom;
|
||||
}
|
||||
@ -171,8 +169,8 @@ export class Scroll {
|
||||
return;
|
||||
}
|
||||
|
||||
Core.enableListener(this, 'touchmove', true);
|
||||
Core.enableListener(this, 'touchend', true);
|
||||
Context.enableListener(this, 'touchmove', true);
|
||||
Context.enableListener(this, 'touchend', true);
|
||||
|
||||
throw 'jsScroll: TODO!';
|
||||
}
|
||||
@ -186,8 +184,8 @@ export class Scroll {
|
||||
|
||||
@Listen('touchend', { passive: true, enabled: false })
|
||||
onTouchEnd() {
|
||||
Core.enableListener(this, 'touchmove', false);
|
||||
Core.enableListener(this, 'touchend', false);
|
||||
Context.enableListener(this, 'touchmove', false);
|
||||
Context.enableListener(this, 'touchend', false);
|
||||
|
||||
if (!this.enabled) {
|
||||
return;
|
||||
@ -308,7 +306,7 @@ export class Scroll {
|
||||
if (easedT < 1) {
|
||||
// do not use DomController here
|
||||
// must use nativeRaf in order to fire in the next frame
|
||||
Core.dom.raf(step);
|
||||
Context.dom.raf(step);
|
||||
|
||||
} else {
|
||||
stopScroll = true;
|
||||
@ -322,8 +320,8 @@ export class Scroll {
|
||||
self.isScrolling = true;
|
||||
|
||||
// chill out for a frame first
|
||||
Core.dom.write(() => {
|
||||
Core.dom.write(timeStamp => {
|
||||
Context.dom.write(() => {
|
||||
Context.dom.write(timeStamp => {
|
||||
startTime = timeStamp;
|
||||
step(timeStamp);
|
||||
});
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Component, Prop } from '@stencil/core';
|
||||
import { createThemedClasses } from '../../utils/theme';
|
||||
import { Ionic } from '../../index';
|
||||
import { Config } from '../../index';
|
||||
import { SPINNERS, SpinnerConfig } from './spinner-configs';
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@ export class Spinner {
|
||||
mode: string;
|
||||
color: string;
|
||||
|
||||
@Prop({ context: 'config' }) config: Config;
|
||||
@Prop() duration: number = null;
|
||||
@Prop() name: string;
|
||||
@Prop() paused: boolean = false;
|
||||
@ -45,7 +46,7 @@ export class Spinner {
|
||||
}
|
||||
|
||||
render() {
|
||||
let name = this.name || Ionic.config.get('spinner', 'lines');
|
||||
let name = this.name || this.config.get('spinner', 'lines');
|
||||
if (name === 'ios') {
|
||||
name = this.name = 'lines';
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Component, Element, Prop } from '@stencil/core';
|
||||
import { createThemedClasses } from '../../utils/theme';
|
||||
import { Ionic } from '../../index';
|
||||
import { Config } from '../../index';
|
||||
|
||||
|
||||
/**
|
||||
@ -49,11 +49,11 @@ export class Navbar {
|
||||
@Element() el: HTMLElement;
|
||||
mode: string;
|
||||
color: string;
|
||||
sbPadding: boolean = Ionic.config.getBoolean('statusbarPadding');
|
||||
|
||||
@Prop({ context: 'config' }) config: Config;
|
||||
@Prop() hideBackButton: boolean = false;
|
||||
@Prop() backButtonText: string = Ionic.config.get('backButtonText', 'Back');
|
||||
@Prop() backButtonIcon: string = Ionic.config.get('backButtonIcon');
|
||||
@Prop() backButtonText: string;
|
||||
@Prop() backButtonIcon: string;
|
||||
@Prop() hidden: boolean = false;
|
||||
|
||||
backButtonClick(ev: UIEvent) {
|
||||
@ -73,12 +73,15 @@ export class Navbar {
|
||||
hostData() {
|
||||
return {
|
||||
class: {
|
||||
'statusbar-padding': Ionic.config.getBoolean('statusbarPadding')
|
||||
'statusbar-padding': this.config.getBoolean('statusbarPadding')
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const backButtonIcon = this.backButtonIcon || this.config.get('backButtonText', 'Back');
|
||||
const backButtonText = this.backButtonText || this.config.get('backButtonIcon', 'Back');
|
||||
|
||||
const backgroundCss = createThemedClasses(this.mode, this.color, 'toolbar-background');
|
||||
const contentCss = createThemedClasses(this.mode, this.color, 'toolbar-content');
|
||||
const backButtonCss = createThemedClasses(this.mode, this.color, 'back-button');
|
||||
@ -88,8 +91,10 @@ export class Navbar {
|
||||
return [
|
||||
<div class={backgroundCss}></div>,
|
||||
<button onClick={this.backButtonClick.bind(this)} class={backButtonCss} hidden={this.hideBackButton}>
|
||||
<ion-icon class={backButtonIconCss} name={this.backButtonIcon}></ion-icon>
|
||||
<span class={backButtonTextCss}>{this.backButtonText}</span>
|
||||
if (backButtonIcon) {
|
||||
<ion-icon class={backButtonIconCss} name={backButtonIcon}></ion-icon>
|
||||
}
|
||||
<span class={backButtonTextCss}>{backButtonText}</span>
|
||||
</button>,
|
||||
<slot name='start'></slot>,
|
||||
<slot name='mode-start'></slot>,
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { Component, Element } from '@stencil/core';
|
||||
import { Component, Element, Prop } from '@stencil/core';
|
||||
import { createThemedClasses } from '../../utils/theme';
|
||||
import { Ionic } from '../../index';
|
||||
|
||||
import { Config } from '../../index';
|
||||
|
||||
/**
|
||||
* @name Toolbar
|
||||
@ -104,6 +103,7 @@ import { Ionic } from '../../index';
|
||||
})
|
||||
export class Toolbar {
|
||||
@Element() el: HTMLElement;
|
||||
@Prop({ context: 'config' }) config: Config;
|
||||
mode: string;
|
||||
color: string;
|
||||
|
||||
@ -117,7 +117,7 @@ export class Toolbar {
|
||||
hostData() {
|
||||
return {
|
||||
class: {
|
||||
'statusbar-padding': Ionic.config.getBoolean('statusbarPadding')
|
||||
'statusbar-padding': this.config.getBoolean('statusbarPadding')
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { ConfigApi } from '../index';
|
||||
import { Config } from '../index';
|
||||
import { PlatformConfig } from './platform-configs';
|
||||
|
||||
|
||||
export function createConfigController(configObj: any, platforms: PlatformConfig[]): ConfigApi {
|
||||
export function createConfigController(configObj: any, platforms: PlatformConfig[]): Config {
|
||||
configObj = configObj || {};
|
||||
|
||||
function get(key: string, fallback?: any): any {
|
||||
|
||||
@ -1,95 +1,13 @@
|
||||
import { createConfigController } from './config-controller';
|
||||
import { detectPlatforms, PLATFORM_CONFIGS } from './platform-configs';
|
||||
import { IonicControllerApi, IonicGlobal } from '../index';
|
||||
|
||||
|
||||
// create the Ionic global (if one doesn't exist)
|
||||
const Ionic: IonicGlobal = (window as any).Ionic = (window as any).Ionic || {};
|
||||
|
||||
// used to store the queued controller promises to
|
||||
// be resolved when the controller finishes loading
|
||||
const queuedCtrlResolves: {[ctrlName: string]: any[]} = {};
|
||||
|
||||
// create a container for all of the controllers that get loaded
|
||||
Ionic.controllers = {};
|
||||
|
||||
// create the public method to load controllers
|
||||
Ionic.controller = (ctrlName: string, opts?: any) => {
|
||||
// loading a controller is always async so return a promise
|
||||
return new Promise<any>((resolve: Function) => {
|
||||
// see if we already have the controller loaded
|
||||
const ctrl = Ionic.controllers[ctrlName];
|
||||
if (ctrl) {
|
||||
// we've already loaded this controller
|
||||
// resolve it immediately
|
||||
resolveController(ctrl, resolve, opts);
|
||||
|
||||
} else {
|
||||
// oh noz! we haven't already loaded this controller yet!
|
||||
const ctrlResolveQueue = queuedCtrlResolves[ctrlName];
|
||||
if (ctrlResolveQueue) {
|
||||
// cool we've already "started" to load the controller
|
||||
// but it hasn't finished loading yet, so let's add
|
||||
// this one also to the queue of to-be resolved promises
|
||||
ctrlResolveQueue.push(resolve, opts);
|
||||
|
||||
} else {
|
||||
// looks like we haven't even started the request yet,
|
||||
// let's add the component to the DOM and create
|
||||
// a queue for this controller
|
||||
queuedCtrlResolves[ctrlName] = [resolve, opts];
|
||||
|
||||
// create our controller element
|
||||
// and append it to the body
|
||||
document.body.appendChild(document.createElement(`ion-${ctrlName}-controller`));
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// create the method controllers will call once their instance has loaded
|
||||
Ionic.registerController = (ctrlName: string, ctrl: IonicControllerApi) => {
|
||||
// this method is called when the singleton
|
||||
// instance of our controller initially loads
|
||||
|
||||
// add this controller instance to our map of controller singletons
|
||||
Ionic.controllers[ctrlName] = ctrl;
|
||||
|
||||
// check for to-be resolved controller promises
|
||||
const pendingCtrlResolves = queuedCtrlResolves[ctrlName];
|
||||
if (pendingCtrlResolves) {
|
||||
for (var i = 0; i < pendingCtrlResolves.length; i += 2) {
|
||||
// first arg is the original promise's resolve
|
||||
// which still needs to be resolved
|
||||
// second arg was the originally passed in options
|
||||
resolveController(ctrl, pendingCtrlResolves[i], pendingCtrlResolves[i + 1]);
|
||||
}
|
||||
|
||||
// all good, go ahead and remove from the queue
|
||||
delete queuedCtrlResolves[ctrlName];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function resolveController(ctrl: IonicControllerApi, resolve: Function, opts: any) {
|
||||
if (opts) {
|
||||
// if the call had options passed in then
|
||||
// it should run the controller's load() method
|
||||
// and let the controller's load() do the resolve
|
||||
// which then will resolve the user's promise
|
||||
ctrl.load(opts).then(<any>resolve);
|
||||
|
||||
} else {
|
||||
// no options passed in, so resolve with
|
||||
// the actual controller instance
|
||||
resolve(ctrl);
|
||||
}
|
||||
}
|
||||
const Ionic = (window as any).Ionic = (window as any).Ionic || {};
|
||||
|
||||
|
||||
// create the Ionic.config from raw config object (if it exists)
|
||||
// and convert Ionic.config into a ConfigApi that has a get() fn
|
||||
Ionic.config = createConfigController(
|
||||
Context.config = createConfigController(
|
||||
Ionic.config,
|
||||
detectPlatforms(window.location.href, window.navigator.userAgent, PLATFORM_CONFIGS, 'core')
|
||||
);
|
||||
@ -97,4 +15,4 @@ Ionic.config = createConfigController(
|
||||
|
||||
// get the mode via config settings and set it to
|
||||
// both Ionic and the Core global
|
||||
Core.mode = Ionic.mode = Ionic.config.get('mode', 'md');
|
||||
Context.mode = Context.config.get('mode', 'md');
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { AnimationController } from './components/animation-controller/animation-controller';
|
||||
import { Animation, AnimationBuilder } from './components/animation-controller/animation-interface';
|
||||
import { AnimationController } from './components/animation/animation';
|
||||
import { Animation, AnimationBuilder } from './components/animation/animation-interface';
|
||||
import { Loading, LoadingEvent, LoadingOptions } from './components/loading/loading';
|
||||
import { LoadingController } from './components/loading-controller/loading-controller';
|
||||
import { GestureDetail, GestureCallback } from './components/gesture/gesture';
|
||||
@ -14,33 +14,7 @@ import { SegmentButton, SegmentButtonEvent } from './components/segment-button/s
|
||||
import * as Stencil from '@stencil/core';
|
||||
|
||||
|
||||
export const Ionic: IonicGlobal = (window as any).Ionic;
|
||||
|
||||
|
||||
export interface IonicGlobal extends Stencil.AppGlobal {
|
||||
controllers?: {[ctrlName: string]: any};
|
||||
controller?: IonicController;
|
||||
config: ConfigApi;
|
||||
registerController?: (ctrlName: string, ctrl: any) => void;
|
||||
mode: string;
|
||||
}
|
||||
|
||||
|
||||
export interface IonicController {
|
||||
<AnimationController>(ctrlName: 'animation'): Promise<Animation>;
|
||||
<LoadingController>(ctrlName: 'loading', opts: LoadingOptions): Promise<Loading>;
|
||||
<MenuController>(ctrlName: 'menu'): Promise<MenuController>;
|
||||
<ModalController>(ctrlName: 'modal', opts: ModalOptions): Promise<Modal>;
|
||||
(ctrlName: string, opts?: any): Promise<IonicControllerApi>;
|
||||
}
|
||||
|
||||
|
||||
export interface IonicControllerApi {
|
||||
load?: (opts?: any) => Promise<any>;
|
||||
}
|
||||
|
||||
|
||||
export interface ConfigApi {
|
||||
export interface Config {
|
||||
get: (key: string, fallback?: any) => any;
|
||||
getBoolean: (key: string, fallback?: boolean) => boolean;
|
||||
getNumber: (key: string, fallback?: number) => number;
|
||||
Reference in New Issue
Block a user