perf(angular): bundle size improvements for angular (#16966)

This commit is contained in:
Manu MA
2019-01-07 22:05:36 +01:00
committed by GitHub
parent 45db44abe7
commit 44fb45e2bc
30 changed files with 322 additions and 328 deletions

View File

@ -20,10 +20,11 @@
"url": "https://github.com/ionic-team/ionic.git"
},
"scripts": {
"build": "npm run clean && npm run build.core && npm run build.ng && npm run clean-generated",
"build": "npm run clean && npm run build.core && npm run build.ng && npm run build.fesm && npm run clean-generated",
"build.dev": "npm run clean && npm run build.core.dev && npm run build.ng && npm run clean-generated",
"build.core": "node scripts/build-core.js",
"build.core.dev": "node scripts/build-core.js --dev",
"build.fesm": "rollup --config ./scripts/rollup.config.js",
"build.link": "npm run build && node scripts/link-copy.js",
"build.ng": "./node_modules/.bin/ngc",
"clean": "node scripts/clean.js",
@ -36,9 +37,10 @@
"tsc": "tsc -p .",
"validate": "npm i && npm run lint && npm run test && npm run build"
},
"module": "dist/index.js",
"main": "dist/index.js",
"module": "dist/fesm5.js",
"main": "dist/fesm5.js",
"types": "dist/index.d.ts",
"sideEffects": false,
"files": [
"dist/",
"css/"
@ -48,33 +50,35 @@
"tslib": "^1.9.3"
},
"peerDependencies": {
"@angular-devkit/core": "^7.1.2",
"@angular-devkit/schematics": "^7.1.2",
"@angular/core": "^7.1.3",
"@angular/common": "^7.1.3",
"@angular/forms": "^7.1.3",
"@angular/router": "~7.1.3",
"@angular/compiler": "^7.1.3",
"@angular/compiler-cli": "^7.1.3",
"@angular/platform-browser": "^7.1.3",
"@angular/platform-browser-dynamic": "^7.1.3",
"@angular-devkit/core": "^7.1.4",
"@angular-devkit/schematics": "^7.1.4",
"@angular/core": "^7.1.4",
"@angular/common": "^7.1.4",
"@angular/forms": "^7.1.4",
"@angular/router": "~7.1.4",
"@angular/compiler": "^7.1.4",
"@angular/compiler-cli": "^7.1.4",
"@angular/platform-browser": "^7.1.4",
"@angular/platform-browser-dynamic": "^7.1.4",
"rxjs": ">=6.2.0",
"zone.js": "^0.8.26"
},
"devDependencies": {
"@angular-devkit/core": "^7.1.2",
"@angular-devkit/schematics": "^7.1.2",
"@angular/core": "^7.1.3",
"@angular/common": "^7.1.3",
"@angular/forms": "^7.1.3",
"@angular/router": "^7.1.3",
"@angular/compiler": "^7.1.3",
"@angular/compiler-cli": "^7.1.3",
"@angular/platform-browser": "^7.1.3",
"@angular/platform-browser-dynamic": "^7.1.3",
"@angular-devkit/core": "^7.1.4",
"@angular-devkit/schematics": "^7.1.4",
"@angular/common": "^7.1.4",
"@angular/compiler": "^7.1.4",
"@angular/compiler-cli": "^7.1.4",
"@angular/core": "^7.1.4",
"@angular/forms": "^7.1.4",
"@angular/platform-browser": "^7.1.4",
"@angular/platform-browser-dynamic": "^7.1.4",
"@angular/router": "^7.1.4",
"@types/node": "~10.12.0",
"fs-extra": "^7.0.0",
"glob": "^7.1.3",
"rollup": "^1.0.2",
"rollup-plugin-node-resolve": "^4.0.0",
"rxjs": "^6.2.0",
"tslint": "^5.10.0",
"tslint-ionic-rules": "0.0.21",

View File

@ -0,0 +1,22 @@
import resolve from 'rollup-plugin-node-resolve';
export default {
input: 'dist/index.js',
output: {
file: 'dist/fesm5.js',
format: 'es'
},
external: (id) => {
// inline @ionic/core deps
if (id === '@ionic/core') {
return false;
}
// anything else is external
return !(id.startsWith('.') || id.startsWith('/'));
},
plugins: [
resolve({
module: true,
})
]
};

View File

@ -1,6 +1,4 @@
import { defineCustomElements } from '@ionic/core/loader';
import { addIcons } from 'ionicons';
import { ICON_PATHS } from 'ionicons/icons';
import { Config } from './providers/config';
import { IonicWindow } from './types/interfaces';
@ -10,7 +8,6 @@ export function appInitialize(config: Config) {
const win: IonicWindow | undefined = window as any;
if (typeof win !== 'undefined') {
const Ionic = win.Ionic = win.Ionic || {};
addIcons(ICON_PATHS);
Ionic.config = config;
Ionic.asyncQueue = false;

View File

@ -1,28 +0,0 @@
/**
* This is an autogenerated file created by the Stencil build process.
* It contains typing information for all components that exist in this project
* and imports for stencil collections that might be configured in your stencil.config.js file
*/
import '@stencil/core';
declare global {
namespace JSX {
interface Element {}
export interface IntrinsicElements {}
}
namespace JSXElements {}
interface HTMLStencilElement extends HTMLElement {
componentOnReady(): Promise<this>;
componentOnReady(done: (ele?: this) => void): void;
forceUpdate(): void;
}
interface HTMLAttributes {}
}
import 'ionicons';
import '@ionic/core';

View File

@ -16,3 +16,4 @@ export { IonVirtualScroll } from './virtual-scroll/virtual-scroll';
export { VirtualItem } from './virtual-scroll/virtual-item';
export { VirtualHeader } from './virtual-scroll/virtual-header';
export { VirtualFooter } from './virtual-scroll/virtual-footer';
export * from './proxies';

View File

@ -1,15 +1,15 @@
import { Directive, ElementRef, HostListener, Input, Optional } from '@angular/core';
import { Directive, ElementRef, HostListener, Optional } from '@angular/core';
import { NavController } from '../../providers/nav-controller';
import { IonRouterOutlet } from './ion-router-outlet';
@Directive({
selector: 'ion-back-button'
selector: 'ion-back-button',
inputs: ['defaultHref']
})
export class IonBackButtonDelegate {
@Input()
set defaultHref(value: string | undefined | null) {
this.elementRef.nativeElement.defaultHref = value;
}

View File

@ -1,7 +1,7 @@
import { Attribute, ChangeDetectorRef, ComponentFactoryResolver, ComponentRef, Directive, ElementRef, EventEmitter, Injector, Input, NgZone, OnDestroy, OnInit, Optional, Output, ViewContainerRef } from '@angular/core';
import { Attribute, ChangeDetectorRef, ComponentFactoryResolver, ComponentRef, Directive, ElementRef, EventEmitter, Injector, NgZone, OnDestroy, OnInit, Optional, Output, ViewContainerRef } from '@angular/core';
import { ActivatedRoute, ChildrenOutletContexts, OutletContext, PRIMARY_OUTLET, Router } from '@angular/router';
import { Config } from '../../providers';
import { Config } from '../../providers/config';
import { NavController } from '../../providers/nav-controller';
import { StackController } from './stack-controller';
@ -9,7 +9,8 @@ import { RouteView, getUrl } from './stack-utils';
@Directive({
selector: 'ion-router-outlet',
exportAs: 'outlet'
exportAs: 'outlet',
inputs: ['animated', 'swipeGesture']
})
export class IonRouterOutlet implements OnDestroy, OnInit {
@ -27,12 +28,10 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
@Output('activate') activateEvents = new EventEmitter<any>();
@Output('deactivate') deactivateEvents = new EventEmitter<any>();
@Input()
set animated(animated: boolean) {
this.nativeEl.animated = animated;
}
@Input()
set swipeGesture(swipe: boolean) {
this._swipeGesture = swipe;

View File

@ -1,6 +1,6 @@
import { Component, ContentChild, HostListener, ViewChild } from '@angular/core';
import { NavController } from '../../providers';
import { NavController } from '../../providers/nav-controller';
import { IonTabBar } from '../proxies';
import { IonRouterOutlet } from './ion-router-outlet';

View File

@ -1,5 +1,5 @@
import { LocationStrategy } from '@angular/common';
import { Directive, ElementRef, HostListener, Input, Optional } from '@angular/core';
import { Directive, ElementRef, HostListener, Optional } from '@angular/core';
import { Router, RouterLink } from '@angular/router';
import { RouterDirection } from '@ionic/core';
import { Subscription } from 'rxjs';
@ -8,12 +8,13 @@ import { NavController } from '../../providers/nav-controller';
@Directive({
selector: '[routerLink]',
inputs: ['routerDirection']
})
export class RouterLinkDelegate {
private subscription?: Subscription;
@Input() routerDirection: RouterDirection = 'forward';
routerDirection: RouterDirection = 'forward';
constructor(
private locationStrategy: LocationStrategy,

View File

@ -0,0 +1,26 @@
/* tslint:disable */
import { fromEvent } from 'rxjs';
export function proxyInputs(Cmp: any, inputs: string[]) {
const Prototype = Cmp.prototype;
inputs.forEach(item => {
Object.defineProperty(Prototype, item, {
get() { return this.el[item]; },
set(val: any) { this.el[item] = val; },
});
});
}
export function proxyMethods(Cmp: any, methods: string[]) {
const Prototype = Cmp.prototype;
methods.forEach(methodName => {
Prototype[methodName] = function() {
const args = arguments;
return this.el.componentOnReady().then((el: any) => el[methodName].apply(el, args));
};
});
}
export function proxyOutputs(instance: any, el: any, events: string[]) {
events.forEach(eventName => instance[eventName] = fromEvent(el, eventName));
}

View File

@ -1,40 +1,14 @@
/* tslint:disable */
/* auto-generated angular directive proxies */
import { fromEvent } from 'rxjs';
import { ChangeDetectorRef, Component, ElementRef, EventEmitter } from '@angular/core';
import { Component, ElementRef, ChangeDetectorRef, EventEmitter } from '@angular/core';
import { proxyInputs, proxyMethods, proxyOutputs } from './proxies-utils';
type StencilComponents<T extends keyof StencilElementInterfaces> = StencilElementInterfaces[T];
export function proxyInputs(Cmp: any, inputs: string[]) {
const Prototype = Cmp.prototype;
inputs.forEach(item => {
Object.defineProperty(Prototype, item, {
get() { return this.el[item]; },
set(val: any) { this.el[item] = val; },
});
});
}
export function proxyOutputs(instance: any, el: any, events: string[]) {
events.forEach(eventName => instance[eventName] = fromEvent(el, eventName));
}
export function proxyMethods(Cmp: any, methods: string[]) {
const Prototype = Cmp.prototype;
methods.forEach(methodName => {
Prototype[methodName] = function() {
const args = arguments;
return this.el.componentOnReady().then((el: any) => el[methodName].apply(el, args));
};
});
}
export declare interface IonApp extends StencilComponents<'IonApp'> {}
@Component({ selector: 'ion-app', changeDetection: 0, template: '<ng-content></ng-content>' })
export class IonApp {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -44,7 +18,7 @@ export class IonApp {
export declare interface IonAvatar extends StencilComponents<'IonAvatar'> {}
@Component({ selector: 'ion-avatar', changeDetection: 0, template: '<ng-content></ng-content>' })
export class IonAvatar {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -54,7 +28,7 @@ export class IonAvatar {
export declare interface IonBackButton extends StencilComponents<'IonBackButton'> {}
@Component({ selector: 'ion-back-button', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'defaultHref', 'icon', 'text'] })
export class IonBackButton {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -66,7 +40,7 @@ export declare interface IonBackdrop extends StencilComponents<'IonBackdrop'> {}
@Component({ selector: 'ion-backdrop', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['visible', 'tappable', 'stopPropagation'] })
export class IonBackdrop {
ionBackdropTap!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -78,7 +52,7 @@ proxyInputs(IonBackdrop, ['visible', 'tappable', 'stopPropagation']);
export declare interface IonBadge extends StencilComponents<'IonBadge'> {}
@Component({ selector: 'ion-badge', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
export class IonBadge {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -91,7 +65,7 @@ export declare interface IonButton extends StencilComponents<'IonButton'> {}
export class IonButton {
ionFocus!: EventEmitter<CustomEvent>;
ionBlur!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -103,7 +77,7 @@ proxyInputs(IonButton, ['color', 'mode', 'buttonType', 'disabled', 'expand', 'fi
export declare interface IonButtons extends StencilComponents<'IonButtons'> {}
@Component({ selector: 'ion-buttons', changeDetection: 0, template: '<ng-content></ng-content>' })
export class IonButtons {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -113,7 +87,7 @@ export class IonButtons {
export declare interface IonCard extends StencilComponents<'IonCard'> {}
@Component({ selector: 'ion-card', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
export class IonCard {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -124,7 +98,7 @@ proxyInputs(IonCard, ['color', 'mode']);
export declare interface IonCardContent extends StencilComponents<'IonCardContent'> {}
@Component({ selector: 'ion-card-content', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['mode'] })
export class IonCardContent {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -135,7 +109,7 @@ proxyInputs(IonCardContent, ['mode']);
export declare interface IonCardHeader extends StencilComponents<'IonCardHeader'> {}
@Component({ selector: 'ion-card-header', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'translucent'] })
export class IonCardHeader {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -146,7 +120,7 @@ proxyInputs(IonCardHeader, ['color', 'mode', 'translucent']);
export declare interface IonCardSubtitle extends StencilComponents<'IonCardSubtitle'> {}
@Component({ selector: 'ion-card-subtitle', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
export class IonCardSubtitle {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -157,7 +131,7 @@ proxyInputs(IonCardSubtitle, ['color', 'mode']);
export declare interface IonCardTitle extends StencilComponents<'IonCardTitle'> {}
@Component({ selector: 'ion-card-title', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
export class IonCardTitle {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -171,7 +145,7 @@ export class IonCheckbox {
ionChange!: EventEmitter<CustomEvent>;
ionFocus!: EventEmitter<CustomEvent>;
ionBlur!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -183,7 +157,7 @@ proxyInputs(IonCheckbox, ['color', 'mode', 'name', 'checked', 'disabled', 'value
export declare interface IonChip extends StencilComponents<'IonChip'> {}
@Component({ selector: 'ion-chip', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'outline'] })
export class IonChip {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -194,7 +168,7 @@ proxyInputs(IonChip, ['color', 'mode', 'outline']);
export declare interface IonCol extends StencilComponents<'IonCol'> {}
@Component({ selector: 'ion-col', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['offset', 'offsetXs', 'offsetSm', 'offsetMd', 'offsetLg', 'offsetXl', 'pull', 'pullXs', 'pullSm', 'pullMd', 'pullLg', 'pullXl', 'push', 'pushXs', 'pushSm', 'pushMd', 'pushLg', 'pushXl', 'size', 'sizeXs', 'sizeSm', 'sizeMd', 'sizeLg', 'sizeXl'] })
export class IonCol {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -208,7 +182,7 @@ export class IonContent {
ionScrollStart!: EventEmitter<CustomEvent>;
ionScroll!: EventEmitter<CustomEvent>;
ionScrollEnd!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -225,7 +199,7 @@ export class IonDatetime {
ionChange!: EventEmitter<CustomEvent>;
ionFocus!: EventEmitter<CustomEvent>;
ionBlur!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -238,7 +212,7 @@ proxyInputs(IonDatetime, ['mode', 'name', 'disabled', 'min', 'max', 'displayForm
export declare interface IonFab extends StencilComponents<'IonFab'> {}
@Component({ selector: 'ion-fab', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['horizontal', 'vertical', 'edge', 'activated'] })
export class IonFab {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -252,7 +226,7 @@ export declare interface IonFabButton extends StencilComponents<'IonFabButton'>
export class IonFabButton {
ionFocus!: EventEmitter<CustomEvent>;
ionBlur!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -264,7 +238,7 @@ proxyInputs(IonFabButton, ['mode', 'color', 'activated', 'disabled', 'href', 'ro
export declare interface IonFabList extends StencilComponents<'IonFabList'> {}
@Component({ selector: 'ion-fab-list', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['activated', 'side'] })
export class IonFabList {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -275,7 +249,7 @@ proxyInputs(IonFabList, ['activated', 'side']);
export declare interface IonFooter extends StencilComponents<'IonFooter'> {}
@Component({ selector: 'ion-footer', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['mode', 'translucent'] })
export class IonFooter {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -286,7 +260,7 @@ proxyInputs(IonFooter, ['mode', 'translucent']);
export declare interface IonGrid extends StencilComponents<'IonGrid'> {}
@Component({ selector: 'ion-grid', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['fixed'] })
export class IonGrid {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -297,7 +271,7 @@ proxyInputs(IonGrid, ['fixed']);
export declare interface IonHeader extends StencilComponents<'IonHeader'> {}
@Component({ selector: 'ion-header', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['mode', 'translucent'] })
export class IonHeader {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -308,7 +282,7 @@ proxyInputs(IonHeader, ['mode', 'translucent']);
export declare interface IonIcon extends StencilComponents<'IonIcon'> {}
@Component({ selector: 'ion-icon', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['ariaLabel', 'color', 'icon', 'ios', 'lazy', 'md', 'mode', 'name', 'size', 'src'] })
export class IonIcon {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -320,7 +294,7 @@ export declare interface IonImg extends StencilComponents<'IonImg'> {}
@Component({ selector: 'ion-img', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['alt', 'src'] })
export class IonImg {
ionImgDidLoad!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -333,7 +307,7 @@ export declare interface IonInfiniteScroll extends StencilComponents<'IonInfinit
@Component({ selector: 'ion-infinite-scroll', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['threshold', 'disabled', 'position'] })
export class IonInfiniteScroll {
ionInfinite!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -346,7 +320,7 @@ proxyInputs(IonInfiniteScroll, ['threshold', 'disabled', 'position']);
export declare interface IonInfiniteScrollContent extends StencilComponents<'IonInfiniteScrollContent'> {}
@Component({ selector: 'ion-infinite-scroll-content', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['loadingSpinner', 'loadingText'] })
export class IonInfiniteScrollContent {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -361,7 +335,7 @@ export class IonInput {
ionChange!: EventEmitter<CustomEvent>;
ionBlur!: EventEmitter<CustomEvent>;
ionFocus!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -374,7 +348,7 @@ proxyInputs(IonInput, ['color', 'mode', 'accept', 'autocapitalize', 'autocomplet
export declare interface IonItem extends StencilComponents<'IonItem'> {}
@Component({ selector: 'ion-item', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'button', 'detail', 'detailIcon', 'disabled', 'href', 'lines', 'routerDirection', 'type'] })
export class IonItem {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -385,7 +359,7 @@ proxyInputs(IonItem, ['color', 'mode', 'button', 'detail', 'detailIcon', 'disabl
export declare interface IonItemDivider extends StencilComponents<'IonItemDivider'> {}
@Component({ selector: 'ion-item-divider', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'sticky'] })
export class IonItemDivider {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -396,7 +370,7 @@ proxyInputs(IonItemDivider, ['color', 'mode', 'sticky']);
export declare interface IonItemGroup extends StencilComponents<'IonItemGroup'> {}
@Component({ selector: 'ion-item-group', changeDetection: 0, template: '<ng-content></ng-content>' })
export class IonItemGroup {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -406,7 +380,7 @@ export class IonItemGroup {
export declare interface IonItemOption extends StencilComponents<'IonItemOption'> {}
@Component({ selector: 'ion-item-option', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'disabled', 'expandable', 'href'] })
export class IonItemOption {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -418,7 +392,7 @@ export declare interface IonItemOptions extends StencilComponents<'IonItemOption
@Component({ selector: 'ion-item-options', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['side'] })
export class IonItemOptions {
ionSwipe!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -431,7 +405,7 @@ export declare interface IonItemSliding extends StencilComponents<'IonItemSlidin
@Component({ selector: 'ion-item-sliding', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['disabled'] })
export class IonItemSliding {
ionDrag!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -444,7 +418,7 @@ proxyInputs(IonItemSliding, ['disabled']);
export declare interface IonLabel extends StencilComponents<'IonLabel'> {}
@Component({ selector: 'ion-label', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'position'] })
export class IonLabel {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -455,7 +429,7 @@ proxyInputs(IonLabel, ['color', 'mode', 'position']);
export declare interface IonList extends StencilComponents<'IonList'> {}
@Component({ selector: 'ion-list', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['mode', 'lines', 'inset'] })
export class IonList {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -467,7 +441,7 @@ proxyInputs(IonList, ['mode', 'lines', 'inset']);
export declare interface IonListHeader extends StencilComponents<'IonListHeader'> {}
@Component({ selector: 'ion-list-header', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['mode', 'color'] })
export class IonListHeader {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -482,7 +456,7 @@ export class IonMenu {
ionWillClose!: EventEmitter<CustomEvent>;
ionDidOpen!: EventEmitter<CustomEvent>;
ionDidClose!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -495,7 +469,7 @@ proxyInputs(IonMenu, ['contentId', 'menuId', 'type', 'disabled', 'side', 'swipeG
export declare interface IonMenuButton extends StencilComponents<'IonMenuButton'> {}
@Component({ selector: 'ion-menu-button', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'menu', 'autoHide'] })
export class IonMenuButton {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -506,7 +480,7 @@ proxyInputs(IonMenuButton, ['color', 'mode', 'menu', 'autoHide']);
export declare interface IonMenuToggle extends StencilComponents<'IonMenuToggle'> {}
@Component({ selector: 'ion-menu-toggle', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['menu', 'autoHide'] })
export class IonMenuToggle {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -520,7 +494,7 @@ export class IonNav {
ionNavWillLoad!: EventEmitter<CustomEvent>;
ionNavWillChange!: EventEmitter<CustomEvent>;
ionNavDidChange!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -533,7 +507,7 @@ proxyInputs(IonNav, ['swipeGesture', 'animated', 'animation', 'rootParams', 'roo
export declare interface IonNavPop extends StencilComponents<'IonNavPop'> {}
@Component({ selector: 'ion-nav-pop', changeDetection: 0, template: '<ng-content></ng-content>' })
export class IonNavPop {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -543,7 +517,7 @@ export class IonNavPop {
export declare interface IonNavPush extends StencilComponents<'IonNavPush'> {}
@Component({ selector: 'ion-nav-push', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['component', 'componentProps'] })
export class IonNavPush {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -554,7 +528,7 @@ proxyInputs(IonNavPush, ['component', 'componentProps']);
export declare interface IonNavSetRoot extends StencilComponents<'IonNavSetRoot'> {}
@Component({ selector: 'ion-nav-set-root', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['component', 'componentProps'] })
export class IonNavSetRoot {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -565,7 +539,7 @@ proxyInputs(IonNavSetRoot, ['component', 'componentProps']);
export declare interface IonNote extends StencilComponents<'IonNote'> {}
@Component({ selector: 'ion-note', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
export class IonNote {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -576,7 +550,7 @@ proxyInputs(IonNote, ['color', 'mode']);
export declare interface IonProgressBar extends StencilComponents<'IonProgressBar'> {}
@Component({ selector: 'ion-progress-bar', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['mode', 'type', 'reversed', 'value', 'buffer', 'color'] })
export class IonProgressBar {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -590,7 +564,7 @@ export class IonRadio {
ionSelect!: EventEmitter<CustomEvent>;
ionFocus!: EventEmitter<CustomEvent>;
ionBlur!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -603,7 +577,7 @@ export declare interface IonRadioGroup extends StencilComponents<'IonRadioGroup'
@Component({ selector: 'ion-radio-group', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['allowEmptySelection', 'name', 'value'] })
export class IonRadioGroup {
ionChange!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -618,7 +592,7 @@ export class IonRange {
ionChange!: EventEmitter<CustomEvent>;
ionFocus!: EventEmitter<CustomEvent>;
ionBlur!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -633,7 +607,7 @@ export class IonRefresher {
ionRefresh!: EventEmitter<CustomEvent>;
ionPull!: EventEmitter<CustomEvent>;
ionStart!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -646,7 +620,7 @@ proxyInputs(IonRefresher, ['pullMin', 'pullMax', 'closeDuration', 'snapbackDurat
export declare interface IonRefresherContent extends StencilComponents<'IonRefresherContent'> {}
@Component({ selector: 'ion-refresher-content', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['pullingIcon', 'pullingText', 'refreshingSpinner', 'refreshingText'] })
export class IonRefresherContent {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -657,7 +631,7 @@ proxyInputs(IonRefresherContent, ['pullingIcon', 'pullingText', 'refreshingSpinn
export declare interface IonReorder extends StencilComponents<'IonReorder'> {}
@Component({ selector: 'ion-reorder', changeDetection: 0, template: '<ng-content></ng-content>' })
export class IonReorder {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -668,7 +642,7 @@ export declare interface IonReorderGroup extends StencilComponents<'IonReorderGr
@Component({ selector: 'ion-reorder-group', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['disabled'] })
export class IonReorderGroup {
ionItemReorder!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -681,7 +655,7 @@ proxyInputs(IonReorderGroup, ['disabled']);
export declare interface IonRippleEffect extends StencilComponents<'IonRippleEffect'> {}
@Component({ selector: 'ion-ripple-effect', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['type'] })
export class IonRippleEffect {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -693,7 +667,7 @@ proxyInputs(IonRippleEffect, ['type']);
export declare interface IonRow extends StencilComponents<'IonRow'> {}
@Component({ selector: 'ion-row', changeDetection: 0, template: '<ng-content></ng-content>' })
export class IonRow {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -709,7 +683,7 @@ export class IonSearchbar {
ionClear!: EventEmitter<CustomEvent>;
ionBlur!: EventEmitter<CustomEvent>;
ionFocus!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -724,7 +698,7 @@ export declare interface IonSegment extends StencilComponents<'IonSegment'> {}
export class IonSegment {
ionChange!: EventEmitter<CustomEvent>;
ionStyle!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -737,7 +711,7 @@ export declare interface IonSegmentButton extends StencilComponents<'IonSegmentB
@Component({ selector: 'ion-segment-button', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['mode', 'checked', 'disabled', 'layout', 'value'] })
export class IonSegmentButton {
ionSelect!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -753,7 +727,7 @@ export class IonSelect {
ionCancel!: EventEmitter<CustomEvent>;
ionFocus!: EventEmitter<CustomEvent>;
ionBlur!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -766,7 +740,7 @@ proxyInputs(IonSelect, ['mode', 'disabled', 'cancelText', 'okText', 'placeholder
export declare interface IonSelectOption extends StencilComponents<'IonSelectOption'> {}
@Component({ selector: 'ion-select-option', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['disabled', 'selected', 'value'] })
export class IonSelectOption {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -777,7 +751,7 @@ proxyInputs(IonSelectOption, ['disabled', 'selected', 'value']);
export declare interface IonSkeletonText extends StencilComponents<'IonSkeletonText'> {}
@Component({ selector: 'ion-skeleton-text', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['width'] })
export class IonSkeletonText {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -788,7 +762,7 @@ proxyInputs(IonSkeletonText, ['width']);
export declare interface IonSlide extends StencilComponents<'IonSlide'> {}
@Component({ selector: 'ion-slide', changeDetection: 0, template: '<ng-content></ng-content>' })
export class IonSlide {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -814,7 +788,7 @@ export class IonSlides {
ionSlideReachEnd!: EventEmitter<CustomEvent>;
ionSlideTouchStart!: EventEmitter<CustomEvent>;
ionSlideTouchEnd!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -827,7 +801,7 @@ proxyInputs(IonSlides, ['mode', 'options', 'pager', 'scrollbar']);
export declare interface IonSpinner extends StencilComponents<'IonSpinner'> {}
@Component({ selector: 'ion-spinner', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['color', 'duration', 'name', 'paused'] })
export class IonSpinner {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -840,7 +814,7 @@ export declare interface IonSplitPane extends StencilComponents<'IonSplitPane'>
export class IonSplitPane {
ionChange!: EventEmitter<CustomEvent>;
ionSplitPaneVisible!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -852,7 +826,7 @@ proxyInputs(IonSplitPane, ['contentId', 'disabled', 'when']);
export declare interface IonTabBar extends StencilComponents<'IonTabBar'> {}
@Component({ selector: 'ion-tab-bar', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['mode', 'color', 'selectedTab', 'translucent'] })
export class IonTabBar {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -863,7 +837,7 @@ proxyInputs(IonTabBar, ['mode', 'color', 'selectedTab', 'translucent']);
export declare interface IonTabButton extends StencilComponents<'IonTabButton'> {}
@Component({ selector: 'ion-tab-button', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['selected', 'mode', 'layout', 'href', 'tab', 'disabled'] })
export class IonTabButton {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -874,7 +848,7 @@ proxyInputs(IonTabButton, ['selected', 'mode', 'layout', 'href', 'tab', 'disable
export declare interface IonText extends StencilComponents<'IonText'> {}
@Component({ selector: 'ion-text', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
export class IonText {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -889,7 +863,7 @@ export class IonTextarea {
ionInput!: EventEmitter<CustomEvent>;
ionBlur!: EventEmitter<CustomEvent>;
ionFocus!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -902,7 +876,7 @@ proxyInputs(IonTextarea, ['mode', 'color', 'autocapitalize', 'autofocus', 'clear
export declare interface IonThumbnail extends StencilComponents<'IonThumbnail'> {}
@Component({ selector: 'ion-thumbnail', changeDetection: 0, template: '<ng-content></ng-content>' })
export class IonThumbnail {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -912,7 +886,7 @@ export class IonThumbnail {
export declare interface IonTitle extends StencilComponents<'IonTitle'> {}
@Component({ selector: 'ion-title', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['color'] })
export class IonTitle {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -926,7 +900,7 @@ export class IonToggle {
ionChange!: EventEmitter<CustomEvent>;
ionFocus!: EventEmitter<CustomEvent>;
ionBlur!: EventEmitter<CustomEvent>;
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;
@ -938,7 +912,7 @@ proxyInputs(IonToggle, ['mode', 'color', 'name', 'checked', 'disabled', 'value']
export declare interface IonToolbar extends StencilComponents<'IonToolbar'> {}
@Component({ selector: 'ion-toolbar', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
export class IonToolbar {
el: HTMLElement
el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
this.el = r.nativeElement;

View File

@ -1,7 +1,7 @@
import { ChangeDetectionStrategy, Component, ContentChild, ElementRef, EmbeddedViewRef, Input, IterableDiffer, IterableDiffers, NgZone, SimpleChanges, TrackByFunction } from '@angular/core';
import { ChangeDetectionStrategy, Component, ContentChild, ElementRef, EmbeddedViewRef, IterableDiffer, IterableDiffers, NgZone, SimpleChanges, TrackByFunction } from '@angular/core';
import { Cell, CellType, HeaderFn, ItemHeightFn } from '@ionic/core';
import { proxyInputs, proxyMethods } from '../proxies';
import { proxyInputs, proxyMethods } from '../proxies-utils';
import { VirtualFooter } from './virtual-footer';
import { VirtualHeader } from './virtual-header';
@ -9,6 +9,85 @@ import { VirtualItem } from './virtual-item';
import { VirtualContext } from './virtual-utils';
export declare interface IonVirtualScroll {
/**
* It is important to provide this
* if virtual item height will be significantly larger than the default
* The approximate height of each virtual item template's cell.
* This dimension is used to help determine how many cells should
* be created when initialized, and to help calculate the height of
* the scrollable area. This height value can only use `px` units.
* Note that the actual rendered size of each cell comes from the
* app's CSS, whereas this approximation is used to help calculate
* initial dimensions before the item has been rendered.
*/
approxItemHeight: number;
/**
* The approximate height of each header template's cell.
* This dimension is used to help determine how many cells should
* be created when initialized, and to help calculate the height of
* the scrollable area. This height value can only use `px` units.
* Note that the actual rendered size of each cell comes from the
* app's CSS, whereas this approximation is used to help calculate
* initial dimensions before the item has been rendered.
*/
approxHeaderHeight: number;
/**
* The approximate width of each footer template's cell.
* This dimension is used to help determine how many cells should
* be created when initialized, and to help calculate the height of
* the scrollable area. This height value can only use `px` units.
* Note that the actual rendered size of each cell comes from the
* app's CSS, whereas this approximation is used to help calculate
* initial dimensions before the item has been rendered.
*/
approxFooterHeight: number;
/**
* Section headers and the data used within its given
* template can be dynamically created by passing a function to `headerFn`.
* For example, a large list of contacts usually has dividers between each
* letter in the alphabet. App's can provide their own custom `headerFn`
* which is called with each record within the dataset. The logic within
* the header function can decide if the header template should be used,
* and what data to give to the header template. The function must return
* `null` if a header cell shouldn't be created.
*/
headerFn?: HeaderFn;
/**
* Section footers and the data used within its given
* template can be dynamically created by passing a function to `footerFn`.
* The logic within the footer function can decide if the footer template
* should be used, and what data to give to the footer template. The function
* must return `null` if a footer cell shouldn't be created.
*/
footerFn?: HeaderFn;
/**
* The data that builds the templates within the virtual scroll.
* It's important to note that when this data has changed, then the
* entire virtual scroll is reset, which is an expensive operation and
* should be avoided if possible.
*/
items?: any[];
/**
* An optional function that maps each item within their height.
* When this function is provides, heavy optimizations and fast path can be taked by
* `ion-virtual-scroll` leading to massive performance improvements.
*
* This function allows to skip all DOM reads, which can be Doing so leads
* to massive performance
*/
itemHeight?: ItemHeightFn;
/**
* Same as `ngForTrackBy` which can be used on `ngFor`.
*/
trackBy: TrackByFunction<any>;
/**
* This method marks the tail the items array as dirty, so they can be re-rendered. It's equivalent to calling: ```js * virtualScroll.checkRange(lastItemLen, items.length - lastItemLen); * ```
*/
@ -27,6 +106,16 @@ export declare interface IonVirtualScroll {
selector: 'ion-virtual-scroll',
template: '<ng-content></ng-content>',
changeDetection: ChangeDetectionStrategy.OnPush,
inputs: [
'approxItemHeight',
'approxHeaderHeight',
'approxFooterHeight',
'headerFn',
'footerFn',
'items',
'itemHeight',
'trackBy'
]
})
export class IonVirtualScroll {
@ -38,85 +127,6 @@ export class IonVirtualScroll {
@ContentChild(VirtualHeader) hdrTmp!: VirtualHeader;
@ContentChild(VirtualFooter) ftrTmp!: VirtualFooter;
/**
* It is important to provide this
* if virtual item height will be significantly larger than the default
* The approximate height of each virtual item template's cell.
* This dimension is used to help determine how many cells should
* be created when initialized, and to help calculate the height of
* the scrollable area. This height value can only use `px` units.
* Note that the actual rendered size of each cell comes from the
* app's CSS, whereas this approximation is used to help calculate
* initial dimensions before the item has been rendered.
*/
@Input() approxItemHeight: number;
/**
* The approximate height of each header template's cell.
* This dimension is used to help determine how many cells should
* be created when initialized, and to help calculate the height of
* the scrollable area. This height value can only use `px` units.
* Note that the actual rendered size of each cell comes from the
* app's CSS, whereas this approximation is used to help calculate
* initial dimensions before the item has been rendered.
*/
@Input() approxHeaderHeight: number;
/**
* The approximate width of each footer template's cell.
* This dimension is used to help determine how many cells should
* be created when initialized, and to help calculate the height of
* the scrollable area. This height value can only use `px` units.
* Note that the actual rendered size of each cell comes from the
* app's CSS, whereas this approximation is used to help calculate
* initial dimensions before the item has been rendered.
*/
@Input() approxFooterHeight: number;
/**
* Section headers and the data used within its given
* template can be dynamically created by passing a function to `headerFn`.
* For example, a large list of contacts usually has dividers between each
* letter in the alphabet. App's can provide their own custom `headerFn`
* which is called with each record within the dataset. The logic within
* the header function can decide if the header template should be used,
* and what data to give to the header template. The function must return
* `null` if a header cell shouldn't be created.
*/
@Input() headerFn?: HeaderFn;
/**
* Section footers and the data used within its given
* template can be dynamically created by passing a function to `footerFn`.
* The logic within the footer function can decide if the footer template
* should be used, and what data to give to the footer template. The function
* must return `null` if a footer cell shouldn't be created.
*/
@Input() footerFn?: HeaderFn;
/**
* The data that builds the templates within the virtual scroll.
* It's important to note that when this data has changed, then the
* entire virtual scroll is reset, which is an expensive operation and
* should be avoided if possible.
*/
@Input() items?: any[];
/**
* An optional function that maps each item within their height.
* When this function is provides, heavy optimizations and fast path can be taked by
* `ion-virtual-scroll` leading to massive performance improvements.
*
* This function allows to skip all DOM reads, which can be Doing so leads
* to massive performance
*/
@Input() itemHeight?: ItemHeightFn;
/**
* Same as `ngForTrackBy` which can be used on `ngFor`.
*/
@Input() trackBy: TrackByFunction<any>;
constructor(
private zone: NgZone,
private iterableDiffers: IterableDiffers,

View File

@ -1,17 +1,11 @@
// export module
export { IonicModule } from './ionic-module';
// export auto generated directive
export * from './directives/proxies';
// export custom directives
export * from './directives';
// export custom providers
export * from './providers';
// ionic types
export * from './types/interfaces';
// ionic route reuse strategy
export * from './util/ionic-router-reuse-strategy';
// export module
export { IonicModule } from './ionic-module';

View File

@ -3,8 +3,7 @@ import { APP_INITIALIZER, ModuleWithProviders, NgModule } from '@angular/core';
import { IonicConfig } from '@ionic/core';
import { appInitialize } from './app-initialize';
import * as c from './directives';
import * as d from './directives/proxies';
import * as d from './directives';
import * as p from './providers';
import { ConfigToken } from './providers/config';
@ -84,40 +83,26 @@ const DECLARATIONS = [
d.IonToolbar,
d.IonTitle,
c.IonTabs,
d.IonTabs,
// ngModel accessors
c.BooleanValueAccessor,
c.NumericValueAccessor,
c.RadioValueAccessor,
c.SelectValueAccessor,
c.TextValueAccessor,
d.BooleanValueAccessor,
d.NumericValueAccessor,
d.RadioValueAccessor,
d.SelectValueAccessor,
d.TextValueAccessor,
// navigation
c.IonRouterOutlet,
c.IonBackButtonDelegate,
c.NavDelegate,
c.RouterLinkDelegate,
d.IonRouterOutlet,
d.IonBackButtonDelegate,
d.NavDelegate,
d.RouterLinkDelegate,
// virtual scroll
c.VirtualFooter,
c.VirtualHeader,
c.VirtualItem,
c.IonVirtualScroll
];
const PROVIDERS = [
p.ActionSheetController,
p.AlertController,
p.Config,
p.LoadingController,
p.PickerController,
p.ToastController,
p.MenuController,
p.NavController,
p.Platform,
p.Events,
p.DomController
d.VirtualFooter,
d.VirtualHeader,
d.VirtualItem,
d.IonVirtualScroll
];
@NgModule({
@ -142,8 +127,7 @@ export class IonicModule {
deps: [
ConfigToken
]
},
...PROVIDERS
}
]
};
}

View File

@ -3,7 +3,9 @@ import { ActionSheetOptions } from '@ionic/core';
import { OverlayBaseController } from '../util/overlay';
@Injectable()
@Injectable({
providedIn: 'root',
})
export class ActionSheetController extends OverlayBaseController<ActionSheetOptions, HTMLIonActionSheetElement> {
constructor() {
super('ion-action-sheet-controller');

View File

@ -3,7 +3,9 @@ import { AlertOptions } from '@ionic/core';
import { OverlayBaseController } from '../util/overlay';
@Injectable()
@Injectable({
providedIn: 'root',
})
export class AlertController extends OverlayBaseController<AlertOptions, HTMLIonAlertElement> {
constructor() {
super('ion-alert-controller');

View File

@ -1,8 +1,11 @@
import { InjectionToken } from '@angular/core';
import { Injectable, InjectionToken } from '@angular/core';
import { Config as CoreConfig, IonicConfig } from '@ionic/core';
import { IonicWindow } from '../types/interfaces';
@Injectable({
providedIn: 'root'
})
export class Config {
get(key: keyof IonicConfig, fallback?: any): any {

View File

@ -1,6 +1,8 @@
import { Injectable } from '@angular/core';
@Injectable()
@Injectable({
providedIn: 'root',
})
export class DomController {
read(cb: RafCallback) {

View File

@ -1,7 +1,9 @@
import { Injectable } from '@angular/core';
export type EventHandler = (...args: any[]) => any;
@Injectable()
@Injectable({
providedIn: 'root',
})
export class Events {
private c = new Map<string, EventHandler[]>();
@ -72,21 +74,3 @@ export class Events {
});
}
}
export function setupEvents() {
const events = new Events();
window.addEventListener('online', ev => events.publish('app:online', ev));
window.addEventListener('offline', ev => events.publish('app:offline', ev));
window.addEventListener('orientationchange', ev => events.publish('app:rotated', ev));
return events;
}
export function setupProvideEvents() {
return () => {
return setupEvents();
};
}

View File

@ -11,4 +11,4 @@ export { PopoverController } from './popover-controller';
export { ToastController } from './toast-controller';
export { NavController } from './nav-controller';
export { DomController } from './dom-controller';
export { Config, ConfigToken } from './config';
export { Config } from './config';

View File

@ -3,7 +3,9 @@ import { LoadingOptions } from '@ionic/core';
import { OverlayBaseController } from '../util/overlay';
@Injectable()
@Injectable({
providedIn: 'root',
})
export class LoadingController extends OverlayBaseController<LoadingOptions, HTMLIonLoadingElement> {
constructor() {
super('ion-loading-controller');

View File

@ -3,7 +3,9 @@ import { Injectable } from '@angular/core';
import { proxyMethod } from '../util/util';
const CTRL = 'ion-menu-controller';
@Injectable()
@Injectable({
providedIn: 'root',
})
export class MenuController {
/**

View File

@ -12,7 +12,9 @@ export interface AnimationOptions {
export interface NavigationOptions extends NavigationExtras, AnimationOptions {}
@Injectable()
@Injectable({
providedIn: 'root',
})
export class NavController {
private direction: 'forward' | 'back' | 'root' | 'auto' = DEFAULT_DIRECTION;

View File

@ -3,7 +3,9 @@ import { PickerOptions } from '@ionic/core';
import { OverlayBaseController } from '../util/overlay';
@Injectable()
@Injectable({
providedIn: 'root',
})
export class PickerController extends OverlayBaseController<PickerOptions, HTMLIonPickerElement> {
constructor() {
super('ion-picker-controller');

View File

@ -6,7 +6,9 @@ export interface BackButtonEmitter extends Subject<BackButtonEventDetail> {
subscribeWithPriority(priority: number, callback: () => Promise<any> | void): Subscription;
}
@Injectable()
@Injectable({
providedIn: 'root',
})
export class Platform {
private _readyPromise: Promise<string>;

View File

@ -3,7 +3,9 @@ import { ToastOptions } from '@ionic/core';
import { OverlayBaseController } from '../util/overlay';
@Injectable()
@Injectable({
providedIn: 'root',
})
export class ToastController extends OverlayBaseController<ToastOptions, HTMLIonToastElement> {
constructor() {
super('ion-toast-controller');

View File

@ -16,11 +16,15 @@
"pwa"
],
"main": "dist/index.js",
"module": "dist/esm/es5/index.js",
"unpkg": "dist/ionic.js",
"module": "dist/esm/index.js",
"es2015": "dist/esm/es2017/index.js",
"es2017": "dist/esm/es2017/index.js",
"jsnext:main": "dist/esm/es2017/index.js",
"sideEffects": false,
"types": "dist/types/interface.d.ts",
"collection": "dist/collection/collection-manifest.json",
"webComponents": "dist/web-components.json",
"unpkg": "dist/ionic.js",
"files": [
"dist/",
"css/",
@ -30,7 +34,7 @@
"ionicons": "4.5.1"
},
"devDependencies": {
"@stencil/core": "0.16.2-2",
"@stencil/core": "0.16.2",
"@stencil/sass": "0.1.1",
"@stencil/utils": "latest",
"@types/jest": "^23.3.1",

View File

@ -27,16 +27,16 @@ export function startHardwareBackButton(win: Window) {
if (handlers.length > 0) {
let selectedPriority = Number.MIN_SAFE_INTEGER;
let handler: Handler | undefined;
handlers.forEach(h => {
if (h.priority >= selectedPriority) {
selectedPriority = h.priority;
handler = h.handler;
let selectedHandler: Handler | undefined;
handlers.forEach(({ priority, handler }) => {
if (priority >= selectedPriority) {
selectedPriority = priority;
selectedHandler = handler;
}
});
busy = true;
executeAction(handler).then(() => busy = false);
executeAction(selectedHandler).then(() => busy = false);
}
});
}

View File

@ -82,6 +82,7 @@ export const config: Config = {
useDirectives: false,
componentCorePackage: '@ionic/core',
directivesProxyFile: '../angular/src/directives/proxies.ts',
directivesUtilsFile: '../angular/src/directives/proxies-utils.ts',
directivesArrayFile: '../angular/src/directives/proxies-list.txt',
excludeComponents: [
// overlays