mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-19 19:57:22 +08:00
refactor(all): data -> componentProps
This commit is contained in:
@ -53,7 +53,7 @@ export class ActionSheet implements OverlayInterface {
|
|||||||
* Additional classes to apply for custom CSS. If multiple classes are
|
* Additional classes to apply for custom CSS. If multiple classes are
|
||||||
* provided they should be separated by spaces.
|
* provided they should be separated by spaces.
|
||||||
*/
|
*/
|
||||||
@Prop() cssClass: string;
|
@Prop() cssClass: string | string[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If true, the action sheet will be dismissed when the backdrop is clicked. Defaults to `true`.
|
* If true, the action sheet will be dismissed when the backdrop is clicked. Defaults to `true`.
|
||||||
|
@ -51,7 +51,7 @@ export class Alert implements OverlayInterface {
|
|||||||
* Additional classes to apply for custom CSS. If multiple classes are
|
* Additional classes to apply for custom CSS. If multiple classes are
|
||||||
* provided they should be separated by spaces.
|
* provided they should be separated by spaces.
|
||||||
*/
|
*/
|
||||||
@Prop() cssClass: string;
|
@Prop() cssClass: string | string[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main title in the heading of the alert.
|
* The main title in the heading of the alert.
|
||||||
@ -455,7 +455,7 @@ export interface AlertOptions {
|
|||||||
title?: string;
|
title?: string;
|
||||||
subTitle?: string;
|
subTitle?: string;
|
||||||
message?: string;
|
message?: string;
|
||||||
cssClass?: string;
|
cssClass?: string | string[];
|
||||||
mode?: string;
|
mode?: string;
|
||||||
inputs?: AlertInput[];
|
inputs?: AlertInput[];
|
||||||
buttons?: (AlertButton|string)[];
|
buttons?: (AlertButton|string)[];
|
||||||
@ -480,6 +480,6 @@ export interface AlertInput {
|
|||||||
export interface AlertButton {
|
export interface AlertButton {
|
||||||
text: string;
|
text: string;
|
||||||
role?: string;
|
role?: string;
|
||||||
cssClass?: string;
|
cssClass?: string | string[];
|
||||||
handler?: (value: any) => boolean|void;
|
handler?: (value: any) => boolean|void;
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ export class Loading implements OverlayInterface {
|
|||||||
* Additional classes to apply for custom CSS. If multiple classes are
|
* Additional classes to apply for custom CSS. If multiple classes are
|
||||||
* provided they should be separated by spaces.
|
* provided they should be separated by spaces.
|
||||||
*/
|
*/
|
||||||
@Prop() cssClass: string;
|
@Prop() cssClass: string | string[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If true, the loading indicator will dismiss when the page changes. Defaults to `false`.
|
* If true, the loading indicator will dismiss when the page changes. Defaults to `false`.
|
||||||
@ -222,7 +222,7 @@ export class Loading implements OverlayInterface {
|
|||||||
export interface LoadingOptions {
|
export interface LoadingOptions {
|
||||||
spinner?: string;
|
spinner?: string;
|
||||||
content?: string;
|
content?: string;
|
||||||
cssClass?: string;
|
cssClass?: string | string[];
|
||||||
showBackdrop?: boolean;
|
showBackdrop?: boolean;
|
||||||
dismissOnPageChange?: boolean;
|
dismissOnPageChange?: boolean;
|
||||||
duration?: number;
|
duration?: number;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core';
|
import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core';
|
||||||
import { Animation, AnimationBuilder, Config, FrameworkDelegate } from '../../index';
|
import { Animation, AnimationBuilder, ComponentProps, ComponentRef, Config, FrameworkDelegate } from '../../index';
|
||||||
|
|
||||||
import { createThemedClasses, getClassList } from '../../utils/theme';
|
import { createThemedClasses, getClassList } from '../../utils/theme';
|
||||||
import { BACKDROP, OverlayEventDetail, OverlayInterface, dismiss, eventMethod, present } from '../../utils/overlays';
|
import { BACKDROP, OverlayEventDetail, OverlayInterface, dismiss, eventMethod, present } from '../../utils/overlays';
|
||||||
@ -64,18 +64,18 @@ export class Modal implements OverlayInterface {
|
|||||||
/**
|
/**
|
||||||
* The component to display inside of the modal.
|
* The component to display inside of the modal.
|
||||||
*/
|
*/
|
||||||
@Prop() component: any;
|
@Prop() component: ComponentRef;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The data to pass to the modal component.
|
* The data to pass to the modal component.
|
||||||
*/
|
*/
|
||||||
@Prop() data: any = {};
|
@Prop() componentProps: ComponentProps;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Additional classes to apply for custom CSS. If multiple classes are
|
* Additional classes to apply for custom CSS. If multiple classes are
|
||||||
* provided they should be separated by spaces.
|
* provided they should be separated by spaces.
|
||||||
*/
|
*/
|
||||||
@Prop() cssClass: string;
|
@Prop() cssClass: string | string[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If true, the modal will be dismissed when the backdrop is clicked. Defaults to `true`.
|
* If true, the modal will be dismissed when the backdrop is clicked. Defaults to `true`.
|
||||||
@ -169,15 +169,15 @@ export class Modal implements OverlayInterface {
|
|||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
const container = this.el.querySelector(`.modal-wrapper`);
|
const container = this.el.querySelector(`.modal-wrapper`);
|
||||||
const data = {
|
const componentProps = {
|
||||||
...this.data,
|
...this.componentProps,
|
||||||
modal: this.el
|
modal: this.el
|
||||||
};
|
};
|
||||||
const classes = [
|
const classes = [
|
||||||
...getClassList(this.cssClass),
|
...getClassList(this.cssClass),
|
||||||
'ion-page'
|
'ion-page'
|
||||||
];
|
];
|
||||||
this.usersElement = await attachComponent(this.delegate, container, this.component, classes, data);
|
this.usersElement = await attachComponent(this.delegate, container, this.component, classes, componentProps);
|
||||||
return present(this, 'modalEnter', iosEnterAnimation, mdEnterAnimation);
|
return present(this, 'modalEnter', iosEnterAnimation, mdEnterAnimation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,12 +243,12 @@ const LIFECYCLE_MAP: any = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export interface ModalOptions {
|
export interface ModalOptions {
|
||||||
component: any;
|
component: ComponentRef;
|
||||||
data?: any;
|
componentProps?: ComponentProps;
|
||||||
showBackdrop?: boolean;
|
showBackdrop?: boolean;
|
||||||
enableBackdropDismiss?: boolean;
|
enableBackdropDismiss?: boolean;
|
||||||
enterAnimation?: AnimationBuilder;
|
enterAnimation?: AnimationBuilder;
|
||||||
leaveAnimation?: AnimationBuilder;
|
leaveAnimation?: AnimationBuilder;
|
||||||
cssClass?: string;
|
cssClass?: string | string[];
|
||||||
delegate?: FrameworkDelegate;
|
delegate?: FrameworkDelegate;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { Component, Element, Listen, Prop } from '@stencil/core';
|
import { Component, Element, Listen, Prop } from '@stencil/core';
|
||||||
// import { NavResult } from '../../index';
|
import { ComponentProps } from '../..';
|
||||||
|
import { NavComponent } from '../nav/nav-util';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
tag: 'ion-nav-push',
|
tag: 'ion-nav-push',
|
||||||
@ -7,16 +8,16 @@ import { Component, Element, Listen, Prop } from '@stencil/core';
|
|||||||
export class NavPush {
|
export class NavPush {
|
||||||
|
|
||||||
@Element() el: HTMLElement;
|
@Element() el: HTMLElement;
|
||||||
@Prop() component: any;
|
@Prop() component: NavComponent;
|
||||||
|
@Prop() componentProps: ComponentProps;
|
||||||
@Prop() url: string;
|
@Prop() url: string;
|
||||||
@Prop() data: any;
|
|
||||||
|
|
||||||
@Listen('child:click')
|
@Listen('child:click')
|
||||||
push(): Promise<any> {
|
push(): Promise<any> {
|
||||||
const nav = this.el.closest('ion-nav');
|
const nav = this.el.closest('ion-nav');
|
||||||
const toPush = this.url || this.component;
|
const toPush = this.url || this.component;
|
||||||
if (nav && toPush) {
|
if (nav && toPush) {
|
||||||
return nav.push(toPush, this.data);
|
return nav.push(toPush, this.componentProps);
|
||||||
}
|
}
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import { Component, Element, Listen, Prop } from '@stencil/core';
|
import { Component, Element, Listen, Prop } from '@stencil/core';
|
||||||
|
import { ComponentProps } from '../..';
|
||||||
|
import { NavComponent } from '../nav/nav-util';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
tag: 'ion-nav-set-root',
|
tag: 'ion-nav-set-root',
|
||||||
@ -6,16 +8,16 @@ import { Component, Element, Listen, Prop } from '@stencil/core';
|
|||||||
export class NavSetRoot {
|
export class NavSetRoot {
|
||||||
|
|
||||||
@Element() el: HTMLElement;
|
@Element() el: HTMLElement;
|
||||||
@Prop() component: any;
|
@Prop() component: NavComponent;
|
||||||
|
@Prop() componentProps: ComponentProps;
|
||||||
@Prop() url: string;
|
@Prop() url: string;
|
||||||
@Prop() data: any;
|
|
||||||
|
|
||||||
@Listen('child:click')
|
@Listen('child:click')
|
||||||
push(): Promise<any> {
|
push(): Promise<any> {
|
||||||
const nav = this.el.closest('ion-nav');
|
const nav = this.el.closest('ion-nav');
|
||||||
if (nav) {
|
if (nav) {
|
||||||
const toPush = this.url || this.component;
|
const toPush = this.url || this.component;
|
||||||
return nav.setRoot(toPush, this.data);
|
return nav.setRoot(toPush, this.componentProps);
|
||||||
}
|
}
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ViewController, isViewController } from './view-controller';
|
import { ViewController, isViewController } from './view-controller';
|
||||||
import { Animation, FrameworkDelegate } from '../..';
|
import { Animation, ComponentRef, FrameworkDelegate } from '../..';
|
||||||
|
|
||||||
export function convertToView(page: any, params: any): ViewController|null {
|
export function convertToView(page: any, params: any): ViewController|null {
|
||||||
if (!page) {
|
if (!page) {
|
||||||
@ -38,7 +38,7 @@ export const enum NavDirection {
|
|||||||
Forward = 'forward'
|
Forward = 'forward'
|
||||||
}
|
}
|
||||||
|
|
||||||
export type NavParams = {[key: string]: any};
|
export type NavComponent = ComponentRef | ViewController | Function;
|
||||||
|
|
||||||
export interface NavResult {
|
export interface NavResult {
|
||||||
hasCompleted: boolean;
|
hasCompleted: boolean;
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { Build, Component, Element, Event, EventEmitter, Method, Prop, Watch } from '@stencil/core';
|
import { Build, Component, Element, Event, EventEmitter, Method, Prop, Watch } from '@stencil/core';
|
||||||
import {
|
import {
|
||||||
|
NavComponent,
|
||||||
NavDirection,
|
NavDirection,
|
||||||
NavOptions,
|
NavOptions,
|
||||||
NavParams,
|
|
||||||
NavResult,
|
NavResult,
|
||||||
TransitionDoneFn,
|
TransitionDoneFn,
|
||||||
TransitionInstruction,
|
TransitionInstruction,
|
||||||
@ -12,7 +12,7 @@ import {
|
|||||||
} from './nav-util';
|
} from './nav-util';
|
||||||
|
|
||||||
import { ViewController, isViewController } from './view-controller';
|
import { ViewController, isViewController } from './view-controller';
|
||||||
import { Animation, Config, DomController, FrameworkDelegate, GestureDetail, NavOutlet } from '../..';
|
import { Animation, ComponentProps, Config, DomController, FrameworkDelegate, GestureDetail, NavOutlet } from '../..';
|
||||||
import { RouteID, RouteWrite, RouterDirection } from '../router/utils/interfaces';
|
import { RouteID, RouteWrite, RouterDirection } from '../router/utils/interfaces';
|
||||||
import { AnimationOptions, ViewLifecycle, lifecycle, transition } from '../../utils/transition';
|
import { AnimationOptions, ViewLifecycle, lifecycle, transition } from '../../utils/transition';
|
||||||
import { assert } from '../../utils/helpers';
|
import { assert } from '../../utils/helpers';
|
||||||
@ -25,22 +25,16 @@ import mdTransitionAnimation from './animations/md.transition';
|
|||||||
})
|
})
|
||||||
export class NavControllerBase implements NavOutlet {
|
export class NavControllerBase implements NavOutlet {
|
||||||
|
|
||||||
private _ids = -1;
|
|
||||||
private _init = false;
|
private _init = false;
|
||||||
private _queue: TransitionInstruction[] = [];
|
private _queue: TransitionInstruction[] = [];
|
||||||
private _sbTrns: Animation;
|
private _sbTrns: Animation;
|
||||||
private useRouter = false;
|
private useRouter = false;
|
||||||
isTransitioning = false;
|
isTransitioning = false;
|
||||||
private _destroyed = false;
|
private _destroyed = false;
|
||||||
|
private _views: ViewController[] = [];
|
||||||
|
|
||||||
_views: ViewController[] = [];
|
|
||||||
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
mode: string;
|
mode: string;
|
||||||
|
|
||||||
parent: any;
|
|
||||||
|
|
||||||
@Element() el: HTMLElement;
|
@Element() el: HTMLElement;
|
||||||
|
|
||||||
@Prop({context: 'dom'}) dom: DomController;
|
@Prop({context: 'dom'}) dom: DomController;
|
||||||
@ -50,8 +44,8 @@ export class NavControllerBase implements NavOutlet {
|
|||||||
@Prop({ mutable: true }) swipeBackEnabled: boolean;
|
@Prop({ mutable: true }) swipeBackEnabled: boolean;
|
||||||
@Prop({ mutable: true }) animated: boolean;
|
@Prop({ mutable: true }) animated: boolean;
|
||||||
@Prop() delegate: FrameworkDelegate;
|
@Prop() delegate: FrameworkDelegate;
|
||||||
@Prop() rootParams: any;
|
@Prop() rootParams: ComponentProps;
|
||||||
@Prop() root: any;
|
@Prop() root: NavComponent;
|
||||||
@Watch('root')
|
@Watch('root')
|
||||||
rootChanged() {
|
rootChanged() {
|
||||||
if (this.root) {
|
if (this.root) {
|
||||||
@ -66,7 +60,6 @@ export class NavControllerBase implements NavOutlet {
|
|||||||
@Event() ionNavChanged: EventEmitter<void>;
|
@Event() ionNavChanged: EventEmitter<void>;
|
||||||
|
|
||||||
componentWillLoad() {
|
componentWillLoad() {
|
||||||
this.id = 'n' + (++ctrlIds);
|
|
||||||
this.useRouter = !!document.querySelector('ion-router') && !this.el.closest('[no-router]');
|
this.useRouter = !!document.querySelector('ion-router') && !this.el.closest('[no-router]');
|
||||||
if (this.swipeBackEnabled === undefined) {
|
if (this.swipeBackEnabled === undefined) {
|
||||||
this.swipeBackEnabled = this.config.getBoolean('swipeBackEnabled', this.mode === 'ios');
|
this.swipeBackEnabled = this.config.getBoolean('swipeBackEnabled', this.mode === 'ios');
|
||||||
@ -81,32 +74,44 @@ export class NavControllerBase implements NavOutlet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidUnload() {
|
componentDidUnload() {
|
||||||
this.destroy();
|
const views = this._views;
|
||||||
|
let view: ViewController;
|
||||||
|
for (let i = 0; i < views.length; i++) {
|
||||||
|
view = views[i];
|
||||||
|
lifecycle(view.element, ViewLifecycle.WillUnload);
|
||||||
|
view._destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
// release swipe back gesture and transition
|
||||||
|
this._sbTrns && this._sbTrns.destroy();
|
||||||
|
this._queue = this._views = this._sbTrns = null;
|
||||||
|
|
||||||
|
this._destroyed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Method()
|
@Method()
|
||||||
push(page: any, params?: NavParams, opts?: NavOptions, done?: TransitionDoneFn): Promise<boolean> {
|
push(component: NavComponent, componentProps?: ComponentProps, opts?: NavOptions, done?: TransitionDoneFn): Promise<boolean> {
|
||||||
return this._queueTrns({
|
return this._queueTrns({
|
||||||
insertStart: -1,
|
insertStart: -1,
|
||||||
insertViews: [{ page: page, params: params }],
|
insertViews: [{ page: component, params: componentProps }],
|
||||||
opts: opts,
|
opts: opts,
|
||||||
}, done);
|
}, done);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Method()
|
@Method()
|
||||||
insert(insertIndex: number, page: any, params?: NavParams, opts?: NavOptions, done?: TransitionDoneFn): Promise<boolean> {
|
insert(insertIndex: number, component: NavComponent, componentProps?: ComponentProps, opts?: NavOptions, done?: TransitionDoneFn): Promise<boolean> {
|
||||||
return this._queueTrns({
|
return this._queueTrns({
|
||||||
insertStart: insertIndex,
|
insertStart: insertIndex,
|
||||||
insertViews: [{ page: page, params: params }],
|
insertViews: [{ page: component, params: componentProps }],
|
||||||
opts: opts,
|
opts: opts,
|
||||||
}, done);
|
}, done);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Method()
|
@Method()
|
||||||
insertPages(insertIndex: number, insertPages: any[], opts?: NavOptions, done?: TransitionDoneFn): Promise<boolean> {
|
insertPages(insertIndex: number, insertComponents: NavComponent[], opts?: NavOptions, done?: TransitionDoneFn): Promise<boolean> {
|
||||||
return this._queueTrns({
|
return this._queueTrns({
|
||||||
insertStart: insertIndex,
|
insertStart: insertIndex,
|
||||||
insertViews: insertPages,
|
insertViews: insertComponents,
|
||||||
opts: opts,
|
opts: opts,
|
||||||
}, done);
|
}, done);
|
||||||
}
|
}
|
||||||
@ -121,7 +126,7 @@ export class NavControllerBase implements NavOutlet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Method()
|
@Method()
|
||||||
popTo(indexOrViewCtrl: any, opts?: NavOptions, done?: TransitionDoneFn): Promise<boolean> {
|
popTo(indexOrViewCtrl: number | ViewController, opts?: NavOptions, done?: TransitionDoneFn): Promise<boolean> {
|
||||||
const config: TransitionInstruction = {
|
const config: TransitionInstruction = {
|
||||||
removeStart: -1,
|
removeStart: -1,
|
||||||
removeCount: -1,
|
removeCount: -1,
|
||||||
@ -174,12 +179,12 @@ export class NavControllerBase implements NavOutlet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Method()
|
@Method()
|
||||||
setRoot(pageOrViewCtrl: any, params?: any, opts?: NavOptions, done?: TransitionDoneFn): Promise<boolean> {
|
setRoot(component: NavComponent, componentProps?: ComponentProps, opts?: NavOptions, done?: TransitionDoneFn): Promise<boolean> {
|
||||||
return this.setPages([{ page: pageOrViewCtrl, params: params }], opts, done);
|
return this.setPages([{ page: component, params: componentProps }], opts, done);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Method()
|
@Method()
|
||||||
setPages(pages: any[], opts?: NavOptions, done?: TransitionDoneFn): Promise<boolean> {
|
setPages(views: any[], opts?: NavOptions, done?: TransitionDoneFn): Promise<boolean> {
|
||||||
if (!opts) {
|
if (!opts) {
|
||||||
opts = {};
|
opts = {};
|
||||||
}
|
}
|
||||||
@ -189,7 +194,7 @@ export class NavControllerBase implements NavOutlet {
|
|||||||
}
|
}
|
||||||
return this._queueTrns({
|
return this._queueTrns({
|
||||||
insertStart: 0,
|
insertStart: 0,
|
||||||
insertViews: pages,
|
insertViews: views,
|
||||||
removeStart: 0,
|
removeStart: 0,
|
||||||
removeCount: -1,
|
removeCount: -1,
|
||||||
opts: opts
|
opts: opts
|
||||||
@ -252,12 +257,12 @@ export class NavControllerBase implements NavOutlet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Method()
|
@Method()
|
||||||
getActive(): ViewController {
|
getActive(): ViewController|undefined {
|
||||||
return this._views[this._views.length - 1];
|
return this._views[this._views.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Method()
|
@Method()
|
||||||
getByIndex(index: number): ViewController {
|
getByIndex(index: number): ViewController|undefined {
|
||||||
return this._views[index];
|
return this._views[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,18 +274,10 @@ export class NavControllerBase implements NavOutlet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Method()
|
@Method()
|
||||||
getViews(): Array<ViewController> {
|
getViews(): ViewController[] {
|
||||||
return this._views.slice();
|
return this._views.slice();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a view controller
|
|
||||||
*/
|
|
||||||
@Method()
|
|
||||||
getViewById(id: string): ViewController|undefined {
|
|
||||||
return this._views.find(vc => vc.id === id);
|
|
||||||
}
|
|
||||||
|
|
||||||
indexOf(viewController: ViewController) {
|
indexOf(viewController: ViewController) {
|
||||||
return this._views.indexOf(viewController);
|
return this._views.indexOf(viewController);
|
||||||
}
|
}
|
||||||
@ -674,12 +671,6 @@ export class NavControllerBase implements NavOutlet {
|
|||||||
// create the new entering view
|
// create the new entering view
|
||||||
view._setNav(this);
|
view._setNav(this);
|
||||||
|
|
||||||
// give this inserted view an ID
|
|
||||||
this._ids++;
|
|
||||||
if (!view.id) {
|
|
||||||
view.id = `${this.id}-${this._ids}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// insert the entering view into the correct index in the stack
|
// insert the entering view into the correct index in the stack
|
||||||
this._views.splice(index, 0, view);
|
this._views.splice(index, 0, view);
|
||||||
}
|
}
|
||||||
@ -729,28 +720,6 @@ export class NavControllerBase implements NavOutlet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
|
||||||
const views = this._views;
|
|
||||||
let view: ViewController;
|
|
||||||
for (let i = 0; i < views.length; i++) {
|
|
||||||
view = views[i];
|
|
||||||
lifecycle(view.element, ViewLifecycle.WillUnload);
|
|
||||||
view._destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
// release swipe back gesture and transition
|
|
||||||
this._sbTrns && this._sbTrns.destroy();
|
|
||||||
this._queue = this._views = this._sbTrns = null;
|
|
||||||
|
|
||||||
// Unregister navcontroller
|
|
||||||
if (this.parent && this.parent.unregisterChildNav) {
|
|
||||||
// TODO: event
|
|
||||||
this.parent.unregisterChildNav(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._destroyed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private swipeBackStart() {
|
private swipeBackStart() {
|
||||||
if (this.isTransitioning || this._queue.length > 0) {
|
if (this.isTransitioning || this._queue.length > 0) {
|
||||||
return;
|
return;
|
||||||
@ -837,5 +806,3 @@ export class NavControllerBase implements NavOutlet {
|
|||||||
return dom;
|
return dom;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let ctrlIds = -1;
|
|
||||||
|
@ -207,8 +207,8 @@ describe('NavController', () => {
|
|||||||
hasCompleted, requiresTransition, undefined, undefined, undefined
|
hasCompleted, requiresTransition, undefined, undefined, undefined
|
||||||
);
|
);
|
||||||
expect(nav.length()).toEqual(4);
|
expect(nav.length()).toEqual(4);
|
||||||
expect(nav._views[0].component).toEqual(MockView4);
|
expect(nav.getByIndex(0).component).toEqual(MockView4);
|
||||||
expect(nav._views[nav._views.length - 1].component).toEqual(MockView3);
|
expect(nav.getByIndex(nav.length() - 1).component).toEqual(MockView3);
|
||||||
|
|
||||||
}, 10000);
|
}, 10000);
|
||||||
|
|
||||||
@ -226,7 +226,7 @@ describe('NavController', () => {
|
|||||||
hasCompleted, requiresTransition, view2, view1, NavDirection.Forward
|
hasCompleted, requiresTransition, view2, view1, NavDirection.Forward
|
||||||
);
|
);
|
||||||
expect(nav.length()).toEqual(2);
|
expect(nav.length()).toEqual(2);
|
||||||
expect(nav._views[nav._views.length - 1].component).toEqual(MockView2);
|
expect(nav.getByIndex(nav.length() - 1).component).toEqual(MockView2);
|
||||||
|
|
||||||
}, 10000);
|
}, 10000);
|
||||||
|
|
||||||
@ -242,7 +242,7 @@ describe('NavController', () => {
|
|||||||
hasCompleted, requiresTransition, view2, view1, NavDirection.Forward
|
hasCompleted, requiresTransition, view2, view1, NavDirection.Forward
|
||||||
);
|
);
|
||||||
expect(nav.length()).toEqual(2);
|
expect(nav.length()).toEqual(2);
|
||||||
expect(nav._views[nav._views.length - 1].component).toEqual(MockView2);
|
expect(nav.getByIndex(nav.length() - 1).component).toEqual(MockView2);
|
||||||
|
|
||||||
}, 10000);
|
}, 10000);
|
||||||
|
|
||||||
@ -260,7 +260,7 @@ describe('NavController', () => {
|
|||||||
expect(err).toEqual(rejectReason);
|
expect(err).toEqual(rejectReason);
|
||||||
expect(trnsDone).toHaveBeenCalledWith(hasCompleted, requiresTransition, rejectReason);
|
expect(trnsDone).toHaveBeenCalledWith(hasCompleted, requiresTransition, rejectReason);
|
||||||
expect(nav.length()).toEqual(1);
|
expect(nav.length()).toEqual(1);
|
||||||
expect(nav._views[nav._views.length - 1].component).toEqual(MockView1);
|
expect(nav.getByIndex(nav.length() - 1).component).toEqual(MockView1);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
}, 10000);
|
}, 10000);
|
||||||
@ -980,7 +980,7 @@ describe('NavController', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('destroy', () => {
|
describe('componentDidUnload', () => {
|
||||||
|
|
||||||
it('should not crash when destroyed while transitioning', (done) => {
|
it('should not crash when destroyed while transitioning', (done) => {
|
||||||
const view1 = mockView(MockView1);
|
const view1 = mockView(MockView1);
|
||||||
@ -991,7 +991,7 @@ describe('NavController', () => {
|
|||||||
fail('should never get here');
|
fail('should never get here');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
nav.destroy();
|
nav.componentDidUnload();
|
||||||
}, 10000);
|
}, 10000);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1092,7 +1092,7 @@ function mockView(component ?: any, data ?: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function mockViews(nav: NavControllerBase, views: ViewController[]) {
|
function mockViews(nav: NavControllerBase, views: ViewController[]) {
|
||||||
nav._views = views;
|
nav['_views'] = views;
|
||||||
views.forEach(v => {
|
views.forEach(v => {
|
||||||
v._setNav(nav);
|
v._setNav(nav);
|
||||||
});
|
});
|
||||||
|
@ -59,7 +59,7 @@ export class Picker implements OverlayInterface {
|
|||||||
* Additional classes to apply for custom CSS. If multiple classes are
|
* Additional classes to apply for custom CSS. If multiple classes are
|
||||||
* provided they should be separated by spaces.
|
* provided they should be separated by spaces.
|
||||||
*/
|
*/
|
||||||
@Prop() cssClass: string;
|
@Prop() cssClass: string | string[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of milliseconds to wait before dismissing the picker.
|
* Number of milliseconds to wait before dismissing the picker.
|
||||||
@ -341,14 +341,14 @@ function buttonClass(button: PickerButton): CssClassMap {
|
|||||||
export interface PickerButton {
|
export interface PickerButton {
|
||||||
text?: string;
|
text?: string;
|
||||||
role?: string;
|
role?: string;
|
||||||
cssClass?: string;
|
cssClass?: string | string[];
|
||||||
handler?: (value: any) => boolean|void;
|
handler?: (value: any) => boolean|void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PickerOptions {
|
export interface PickerOptions {
|
||||||
buttons?: PickerButton[];
|
buttons?: PickerButton[];
|
||||||
columns?: PickerColumn[];
|
columns?: PickerColumn[];
|
||||||
cssClass?: string;
|
cssClass?: string | string[];
|
||||||
enableBackdropDismiss?: boolean;
|
enableBackdropDismiss?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,7 +360,7 @@ export interface PickerColumn {
|
|||||||
prefix?: string;
|
prefix?: string;
|
||||||
suffix?: string;
|
suffix?: string;
|
||||||
options: PickerColumnOption[];
|
options: PickerColumnOption[];
|
||||||
cssClass?: string;
|
cssClass?: string | string[];
|
||||||
columnWidth?: string;
|
columnWidth?: string;
|
||||||
prefixWidth?: string;
|
prefixWidth?: string;
|
||||||
suffixWidth?: string;
|
suffixWidth?: string;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core';
|
import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core';
|
||||||
import { Animation, AnimationBuilder, Config, FrameworkDelegate } from '../../index';
|
import { Animation, AnimationBuilder, ComponentProps, ComponentRef, Config, FrameworkDelegate } from '../../index';
|
||||||
|
|
||||||
import { createThemedClasses, getClassList } from '../../utils/theme';
|
import { createThemedClasses, getClassList } from '../../utils/theme';
|
||||||
import { BACKDROP, OverlayEventDetail, OverlayInterface, dismiss, eventMethod, present } from '../../utils/overlays';
|
import { BACKDROP, OverlayEventDetail, OverlayInterface, dismiss, eventMethod, present } from '../../utils/overlays';
|
||||||
@ -63,18 +63,18 @@ export class Popover implements OverlayInterface {
|
|||||||
/**
|
/**
|
||||||
* The component to display inside of the popover.
|
* The component to display inside of the popover.
|
||||||
*/
|
*/
|
||||||
@Prop() component: string;
|
@Prop() component: ComponentRef;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The data to pass to the popover component.
|
* The data to pass to the popover component.
|
||||||
*/
|
*/
|
||||||
@Prop() data: any = {};
|
@Prop() componentProps: ComponentProps;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Additional classes to apply for custom CSS. If multiple classes are
|
* Additional classes to apply for custom CSS. If multiple classes are
|
||||||
* provided they should be separated by spaces.
|
* provided they should be separated by spaces.
|
||||||
*/
|
*/
|
||||||
@Prop() cssClass: string;
|
@Prop() cssClass: string | string[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If true, the popover will be dismissed when the backdrop is clicked. Defaults to `true`.
|
* If true, the popover will be dismissed when the backdrop is clicked. Defaults to `true`.
|
||||||
@ -180,7 +180,7 @@ export class Popover implements OverlayInterface {
|
|||||||
}
|
}
|
||||||
const container = this.el.querySelector('.popover-content');
|
const container = this.el.querySelector('.popover-content');
|
||||||
const data = {
|
const data = {
|
||||||
...this.data,
|
...this.componentProps,
|
||||||
popover: this.el
|
popover: this.el
|
||||||
};
|
};
|
||||||
const classes = [
|
const classes = [
|
||||||
@ -254,14 +254,14 @@ export class Popover implements OverlayInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface PopoverOptions {
|
export interface PopoverOptions {
|
||||||
component: any;
|
component: ComponentRef;
|
||||||
data?: any;
|
componentProps?: ComponentProps;
|
||||||
showBackdrop?: boolean;
|
showBackdrop?: boolean;
|
||||||
enableBackdropDismiss?: boolean;
|
enableBackdropDismiss?: boolean;
|
||||||
translucent?: boolean;
|
translucent?: boolean;
|
||||||
enterAnimation?: AnimationBuilder;
|
enterAnimation?: AnimationBuilder;
|
||||||
leaveAnimation?: AnimationBuilder;
|
leaveAnimation?: AnimationBuilder;
|
||||||
cssClass?: string;
|
cssClass?: string | string[];
|
||||||
ev: Event;
|
ev: Event;
|
||||||
delegate?: FrameworkDelegate;
|
delegate?: FrameworkDelegate;
|
||||||
}
|
}
|
||||||
|
@ -310,7 +310,7 @@ export class Select {
|
|||||||
|
|
||||||
const popoverOpts: PopoverOptions = Object.assign(interfaceOptions, {
|
const popoverOpts: PopoverOptions = Object.assign(interfaceOptions, {
|
||||||
component: 'ion-select-popover',
|
component: 'ion-select-popover',
|
||||||
data: {
|
componentProps: {
|
||||||
title: interfaceOptions.title,
|
title: interfaceOptions.title,
|
||||||
subTitle: interfaceOptions.subTitle,
|
subTitle: interfaceOptions.subTitle,
|
||||||
message: interfaceOptions.message,
|
message: interfaceOptions.message,
|
||||||
|
@ -56,7 +56,7 @@ export class Toast implements OverlayInterface {
|
|||||||
* Additional classes to apply for custom CSS. If multiple classes are
|
* Additional classes to apply for custom CSS. If multiple classes are
|
||||||
* provided they should be separated by spaces.
|
* provided they should be separated by spaces.
|
||||||
*/
|
*/
|
||||||
@Prop() cssClass: string;
|
@Prop() cssClass: string | string[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If true, the toast will dismiss when the page changes. Defaults to `false`.
|
* If true, the toast will dismiss when the page changes. Defaults to `false`.
|
||||||
@ -226,7 +226,7 @@ export class Toast implements OverlayInterface {
|
|||||||
|
|
||||||
export interface ToastOptions {
|
export interface ToastOptions {
|
||||||
message?: string;
|
message?: string;
|
||||||
cssClass?: string;
|
cssClass?: string | string[];
|
||||||
duration?: number;
|
duration?: number;
|
||||||
showCloseButton?: boolean;
|
showCloseButton?: boolean;
|
||||||
closeButtonText?: string;
|
closeButtonText?: string;
|
||||||
|
5
core/src/index.d.ts
vendored
5
core/src/index.d.ts
vendored
@ -59,7 +59,7 @@ export * from './components/modal/modal';
|
|||||||
export { ModalController } from './components/modal-controller/modal-controller';
|
export { ModalController } from './components/modal-controller/modal-controller';
|
||||||
export * from './components/nav/nav';
|
export * from './components/nav/nav';
|
||||||
export { ViewController } from './components/nav/view-controller';
|
export { ViewController } from './components/nav/view-controller';
|
||||||
export { NavParams, NavOptions, TransitionDoneFn} from './components/nav/nav-util';
|
export { NavOptions, TransitionDoneFn} from './components/nav/nav-util';
|
||||||
export { Note } from './components/note/note';
|
export { Note } from './components/note/note';
|
||||||
export { PickerColumnCmp } from './components/picker-column/picker-column';
|
export { PickerColumnCmp } from './components/picker-column/picker-column';
|
||||||
export * from './components/picker/picker';
|
export * from './components/picker/picker';
|
||||||
@ -110,6 +110,9 @@ export { DomController, RafCallback } from './global/dom-controller';
|
|||||||
export { FrameworkDelegate } from './utils/framework-delegate';
|
export { FrameworkDelegate } from './utils/framework-delegate';
|
||||||
export { OverlayEventDetail } from './utils/overlays';
|
export { OverlayEventDetail } from './utils/overlays';
|
||||||
|
|
||||||
|
export type ComponentRef = HTMLElement | string;
|
||||||
|
export type ComponentProps = {[key: string]: any};
|
||||||
|
|
||||||
export interface Config {
|
export interface Config {
|
||||||
get: (key: string, fallback?: any) => any;
|
get: (key: string, fallback?: any) => any;
|
||||||
getBoolean: (key: string, fallback?: boolean) => boolean;
|
getBoolean: (key: string, fallback?: boolean) => boolean;
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
|
import { ComponentRef } from '..';
|
||||||
|
|
||||||
export interface FrameworkDelegate {
|
export interface FrameworkDelegate {
|
||||||
attachViewToDom(container: any, component: any, propsOrDataObj?: any, cssClasses?: string[]): Promise<HTMLElement>;
|
attachViewToDom(container: any, component: any, propsOrDataObj?: any, cssClasses?: string[]): Promise<HTMLElement>;
|
||||||
removeViewFromDom(container: any, component: any): Promise<void>;
|
removeViewFromDom(container: any, component: any): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function attachComponent(delegate: FrameworkDelegate, container: Element, component: string|HTMLElement, cssClasses?: string[], params?: {[key: string]: any}): Promise<HTMLElement> {
|
export function attachComponent(delegate: FrameworkDelegate, container: Element, component: ComponentRef, cssClasses?: string[], componentProps?: {[key: string]: any}): Promise<HTMLElement> {
|
||||||
if (delegate) {
|
if (delegate) {
|
||||||
return delegate.attachViewToDom(container, component, params, cssClasses);
|
return delegate.attachViewToDom(container, component, componentProps, cssClasses);
|
||||||
}
|
}
|
||||||
const el = (typeof component === 'string') ? document.createElement(component) : component;
|
const el = (typeof component === 'string') ? document.createElement(component) : component;
|
||||||
|
|
||||||
cssClasses && cssClasses.forEach(c => el.classList.add(c));
|
cssClasses && cssClasses.forEach(c => el.classList.add(c));
|
||||||
params && Object.assign(el, params);
|
componentProps && Object.assign(el, componentProps);
|
||||||
|
|
||||||
container.appendChild(el);
|
container.appendChild(el);
|
||||||
if ((el as any).componentOnReady) {
|
if ((el as any).componentOnReady) {
|
||||||
|
19
core/src/utils/lazy.ts
Normal file
19
core/src/utils/lazy.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
export function waitUntilVisible(el: HTMLElement, callback?: Function) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
if ('IntersectionObserver' in window) {
|
||||||
|
const io = new IntersectionObserver(data => {
|
||||||
|
if (data[0].isIntersecting) {
|
||||||
|
resolve();
|
||||||
|
io.disconnect();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
io.observe(el);
|
||||||
|
} else {
|
||||||
|
// fall back to setTimeout for Safari and IE
|
||||||
|
setTimeout(() => resolve(), 300);
|
||||||
|
}
|
||||||
|
}).then(() => {
|
||||||
|
callback && callback();
|
||||||
|
});
|
||||||
|
}
|
@ -50,8 +50,11 @@ export function getButtonClassMap(buttonType: string, mode: string): CssClassMap
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getClassList(classes: string | undefined): string[] {
|
export function getClassList(classes: string | string[] | undefined): string[] {
|
||||||
if (classes) {
|
if (classes) {
|
||||||
|
if (Array.isArray(classes)) {
|
||||||
|
return classes;
|
||||||
|
}
|
||||||
return classes
|
return classes
|
||||||
.split(' ')
|
.split(' ')
|
||||||
.filter(c => c.trim() !== '');
|
.filter(c => c.trim() !== '');
|
||||||
@ -59,7 +62,7 @@ export function getClassList(classes: string | undefined): string[] {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getClassMap(classes: string | undefined): CssClassMap {
|
export function getClassMap(classes: string | string[] | undefined): CssClassMap {
|
||||||
const map: CssClassMap = {};
|
const map: CssClassMap = {};
|
||||||
getClassList(classes).forEach(c => map[c] = true);
|
getClassList(classes).forEach(c => map[c] = true);
|
||||||
return map;
|
return map;
|
||||||
|
Reference in New Issue
Block a user