diff --git a/angular/package.json b/angular/package.json index a1d5287e3b..b75a0e6b03 100644 --- a/angular/package.json +++ b/angular/package.json @@ -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", diff --git a/angular/scripts/rollup.config.js b/angular/scripts/rollup.config.js new file mode 100644 index 0000000000..30e557b439 --- /dev/null +++ b/angular/scripts/rollup.config.js @@ -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, + }) + ] +}; \ No newline at end of file diff --git a/angular/src/app-initialize.ts b/angular/src/app-initialize.ts index 90b3833b5c..234c61c8b6 100644 --- a/angular/src/app-initialize.ts +++ b/angular/src/app-initialize.ts @@ -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; diff --git a/angular/src/components.d.ts b/angular/src/components.d.ts deleted file mode 100644 index ce07513a86..0000000000 --- a/angular/src/components.d.ts +++ /dev/null @@ -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; - componentOnReady(done: (ele?: this) => void): void; - - forceUpdate(): void; - } - - interface HTMLAttributes {} -} - -import 'ionicons'; -import '@ionic/core'; - diff --git a/angular/src/directives/index.ts b/angular/src/directives/index.ts index f8d82693e8..7b26dad4de 100644 --- a/angular/src/directives/index.ts +++ b/angular/src/directives/index.ts @@ -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'; diff --git a/angular/src/directives/navigation/ion-back-button.ts b/angular/src/directives/navigation/ion-back-button.ts index b59ee89f6d..b10fd6ef24 100644 --- a/angular/src/directives/navigation/ion-back-button.ts +++ b/angular/src/directives/navigation/ion-back-button.ts @@ -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; } diff --git a/angular/src/directives/navigation/ion-router-outlet.ts b/angular/src/directives/navigation/ion-router-outlet.ts index 38aa441bf7..161ab05173 100644 --- a/angular/src/directives/navigation/ion-router-outlet.ts +++ b/angular/src/directives/navigation/ion-router-outlet.ts @@ -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(); @Output('deactivate') deactivateEvents = new EventEmitter(); - @Input() set animated(animated: boolean) { this.nativeEl.animated = animated; } - @Input() set swipeGesture(swipe: boolean) { this._swipeGesture = swipe; diff --git a/angular/src/directives/navigation/ion-tabs.ts b/angular/src/directives/navigation/ion-tabs.ts index 9b04ba9166..99d3372fcd 100644 --- a/angular/src/directives/navigation/ion-tabs.ts +++ b/angular/src/directives/navigation/ion-tabs.ts @@ -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'; diff --git a/angular/src/directives/navigation/router-link-delegate.ts b/angular/src/directives/navigation/router-link-delegate.ts index 221c23ccbb..632202441d 100644 --- a/angular/src/directives/navigation/router-link-delegate.ts +++ b/angular/src/directives/navigation/router-link-delegate.ts @@ -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, diff --git a/angular/src/directives/proxies-list.txt b/angular/src/directives/proxies-list.txt index 1d11508393..b0e675cb97 100644 --- a/angular/src/directives/proxies-list.txt +++ b/angular/src/directives/proxies-list.txt @@ -2,7 +2,7 @@ import * as d from './proxies'; export const DIRECTIVES = [ - d.IonApp, +d.IonApp, d.IonAvatar, d.IonBackButton, d.IonBackdrop, diff --git a/angular/src/directives/proxies-utils.ts b/angular/src/directives/proxies-utils.ts new file mode 100644 index 0000000000..889d35ad1d --- /dev/null +++ b/angular/src/directives/proxies-utils.ts @@ -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)); +} diff --git a/angular/src/directives/proxies.ts b/angular/src/directives/proxies.ts index 14be2a5d64..6fff4598a9 100644 --- a/angular/src/directives/proxies.ts +++ b/angular/src/directives/proxies.ts @@ -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 = 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: '' }) 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: '' }) 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: '', 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: '', inputs: ['visible', 'tappable', 'stopPropagation'] }) export class IonBackdrop { ionBackdropTap!: EventEmitter; - 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: '', 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; ionBlur!: EventEmitter; - 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: '' }) 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: '', 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: '', 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: '', 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: '', 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: '', 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; ionFocus!: EventEmitter; ionBlur!: EventEmitter; - 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: '', 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: '', 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; ionScroll!: EventEmitter; ionScrollEnd!: EventEmitter; - el: HTMLElement + el: HTMLElement; constructor(c: ChangeDetectorRef, r: ElementRef) { c.detach(); this.el = r.nativeElement; @@ -225,7 +199,7 @@ export class IonDatetime { ionChange!: EventEmitter; ionFocus!: EventEmitter; ionBlur!: EventEmitter; - 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: '', 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; ionBlur!: EventEmitter; - 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: '', 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: '', 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: '', 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: '', 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: '', 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: '', inputs: ['alt', 'src'] }) export class IonImg { ionImgDidLoad!: EventEmitter; - 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: '', inputs: ['threshold', 'disabled', 'position'] }) export class IonInfiniteScroll { ionInfinite!: EventEmitter; - 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: '', 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; ionBlur!: EventEmitter; ionFocus!: EventEmitter; - 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: '', 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: '', 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: '' }) 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: '', 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: '', inputs: ['side'] }) export class IonItemOptions { ionSwipe!: EventEmitter; - 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: '', inputs: ['disabled'] }) export class IonItemSliding { ionDrag!: EventEmitter; - 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: '', 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: '', 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: '', 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; ionDidOpen!: EventEmitter; ionDidClose!: EventEmitter; - 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: '', 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: '', 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; ionNavWillChange!: EventEmitter; ionNavDidChange!: EventEmitter; - 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: '' }) 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: '', 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: '', 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: '', 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: '', 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; ionFocus!: EventEmitter; ionBlur!: EventEmitter; - 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: '', inputs: ['allowEmptySelection', 'name', 'value'] }) export class IonRadioGroup { ionChange!: EventEmitter; - el: HTMLElement + el: HTMLElement; constructor(c: ChangeDetectorRef, r: ElementRef) { c.detach(); this.el = r.nativeElement; @@ -618,7 +592,7 @@ export class IonRange { ionChange!: EventEmitter; ionFocus!: EventEmitter; ionBlur!: EventEmitter; - el: HTMLElement + el: HTMLElement; constructor(c: ChangeDetectorRef, r: ElementRef) { c.detach(); this.el = r.nativeElement; @@ -633,7 +607,7 @@ export class IonRefresher { ionRefresh!: EventEmitter; ionPull!: EventEmitter; ionStart!: EventEmitter; - 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: '', 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: '' }) 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: '', inputs: ['disabled'] }) export class IonReorderGroup { ionItemReorder!: EventEmitter; - 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: '', 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: '' }) 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; ionBlur!: EventEmitter; ionFocus!: EventEmitter; - 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; ionStyle!: EventEmitter; - 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: '', inputs: ['mode', 'checked', 'disabled', 'layout', 'value'] }) export class IonSegmentButton { ionSelect!: EventEmitter; - el: HTMLElement + el: HTMLElement; constructor(c: ChangeDetectorRef, r: ElementRef) { c.detach(); this.el = r.nativeElement; @@ -753,7 +727,7 @@ export class IonSelect { ionCancel!: EventEmitter; ionFocus!: EventEmitter; ionBlur!: EventEmitter; - 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: '', 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: '', 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: '' }) 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; ionSlideTouchStart!: EventEmitter; ionSlideTouchEnd!: EventEmitter; - 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: '', 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; ionSplitPaneVisible!: EventEmitter; - 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: '', 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: '', 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: '', 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; ionBlur!: EventEmitter; ionFocus!: EventEmitter; - 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: '' }) 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: '', 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; ionFocus!: EventEmitter; ionBlur!: EventEmitter; - 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: '', inputs: ['color', 'mode'] }) export class IonToolbar { - el: HTMLElement + el: HTMLElement; constructor(c: ChangeDetectorRef, r: ElementRef) { c.detach(); this.el = r.nativeElement; diff --git a/angular/src/directives/virtual-scroll/virtual-scroll.ts b/angular/src/directives/virtual-scroll/virtual-scroll.ts index 4219307a02..4566945069 100644 --- a/angular/src/directives/virtual-scroll/virtual-scroll.ts +++ b/angular/src/directives/virtual-scroll/virtual-scroll.ts @@ -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; + /** * 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: '', 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; - constructor( private zone: NgZone, private iterableDiffers: IterableDiffers, diff --git a/angular/src/index.ts b/angular/src/index.ts index 7f858f8049..f572703fa0 100644 --- a/angular/src/index.ts +++ b/angular/src/index.ts @@ -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'; diff --git a/angular/src/ionic-module.ts b/angular/src/ionic-module.ts index 8adb135eb1..579a11a2d2 100644 --- a/angular/src/ionic-module.ts +++ b/angular/src/ionic-module.ts @@ -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 + } ] }; } diff --git a/angular/src/providers/action-sheet-controller.ts b/angular/src/providers/action-sheet-controller.ts index 1475966da8..49226c725e 100644 --- a/angular/src/providers/action-sheet-controller.ts +++ b/angular/src/providers/action-sheet-controller.ts @@ -3,7 +3,9 @@ import { ActionSheetOptions } from '@ionic/core'; import { OverlayBaseController } from '../util/overlay'; -@Injectable() +@Injectable({ + providedIn: 'root', +}) export class ActionSheetController extends OverlayBaseController { constructor() { super('ion-action-sheet-controller'); diff --git a/angular/src/providers/alert-controller.ts b/angular/src/providers/alert-controller.ts index 05c6cd60bc..b96d732de6 100644 --- a/angular/src/providers/alert-controller.ts +++ b/angular/src/providers/alert-controller.ts @@ -3,7 +3,9 @@ import { AlertOptions } from '@ionic/core'; import { OverlayBaseController } from '../util/overlay'; -@Injectable() +@Injectable({ + providedIn: 'root', +}) export class AlertController extends OverlayBaseController { constructor() { super('ion-alert-controller'); diff --git a/angular/src/providers/config.ts b/angular/src/providers/config.ts index 3e20685429..983ed8d6ea 100644 --- a/angular/src/providers/config.ts +++ b/angular/src/providers/config.ts @@ -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 { diff --git a/angular/src/providers/dom-controller.ts b/angular/src/providers/dom-controller.ts index 08bf0c5f92..7caea0894a 100644 --- a/angular/src/providers/dom-controller.ts +++ b/angular/src/providers/dom-controller.ts @@ -1,6 +1,8 @@ import { Injectable } from '@angular/core'; -@Injectable() +@Injectable({ + providedIn: 'root', +}) export class DomController { read(cb: RafCallback) { diff --git a/angular/src/providers/events.ts b/angular/src/providers/events.ts index 8b8fd440e2..fb55bc29aa 100644 --- a/angular/src/providers/events.ts +++ b/angular/src/providers/events.ts @@ -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(); @@ -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(); - }; -} diff --git a/angular/src/providers/index.ts b/angular/src/providers/index.ts index 8b67f01181..d9f4f70ed5 100644 --- a/angular/src/providers/index.ts +++ b/angular/src/providers/index.ts @@ -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'; diff --git a/angular/src/providers/loading-controller.ts b/angular/src/providers/loading-controller.ts index 614cf477ec..18bab8f83e 100644 --- a/angular/src/providers/loading-controller.ts +++ b/angular/src/providers/loading-controller.ts @@ -3,7 +3,9 @@ import { LoadingOptions } from '@ionic/core'; import { OverlayBaseController } from '../util/overlay'; -@Injectable() +@Injectable({ + providedIn: 'root', +}) export class LoadingController extends OverlayBaseController { constructor() { super('ion-loading-controller'); diff --git a/angular/src/providers/menu-controller.ts b/angular/src/providers/menu-controller.ts index 4a49bf60bb..447f2abdd6 100644 --- a/angular/src/providers/menu-controller.ts +++ b/angular/src/providers/menu-controller.ts @@ -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 { /** diff --git a/angular/src/providers/nav-controller.ts b/angular/src/providers/nav-controller.ts index a246292f43..570f7fc820 100644 --- a/angular/src/providers/nav-controller.ts +++ b/angular/src/providers/nav-controller.ts @@ -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; diff --git a/angular/src/providers/picker-controller.ts b/angular/src/providers/picker-controller.ts index a874e7504f..39cc80c5e7 100644 --- a/angular/src/providers/picker-controller.ts +++ b/angular/src/providers/picker-controller.ts @@ -3,7 +3,9 @@ import { PickerOptions } from '@ionic/core'; import { OverlayBaseController } from '../util/overlay'; -@Injectable() +@Injectable({ + providedIn: 'root', +}) export class PickerController extends OverlayBaseController { constructor() { super('ion-picker-controller'); diff --git a/angular/src/providers/platform.ts b/angular/src/providers/platform.ts index 10d0d9ded2..7e8fdfc83d 100644 --- a/angular/src/providers/platform.ts +++ b/angular/src/providers/platform.ts @@ -6,7 +6,9 @@ export interface BackButtonEmitter extends Subject { subscribeWithPriority(priority: number, callback: () => Promise | void): Subscription; } -@Injectable() +@Injectable({ + providedIn: 'root', +}) export class Platform { private _readyPromise: Promise; diff --git a/angular/src/providers/toast-controller.ts b/angular/src/providers/toast-controller.ts index 8fb7c2f614..ca5ede282e 100644 --- a/angular/src/providers/toast-controller.ts +++ b/angular/src/providers/toast-controller.ts @@ -3,7 +3,9 @@ import { ToastOptions } from '@ionic/core'; import { OverlayBaseController } from '../util/overlay'; -@Injectable() +@Injectable({ + providedIn: 'root', +}) export class ToastController extends OverlayBaseController { constructor() { super('ion-toast-controller'); diff --git a/core/package.json b/core/package.json index 5fe5fa351f..84c1ed799b 100644 --- a/core/package.json +++ b/core/package.json @@ -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", diff --git a/core/src/utils/hardware-back-button.ts b/core/src/utils/hardware-back-button.ts index ae0850d196..24e10caad8 100644 --- a/core/src/utils/hardware-back-button.ts +++ b/core/src/utils/hardware-back-button.ts @@ -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); } }); } diff --git a/core/stencil.config.ts b/core/stencil.config.ts index d95972c0f4..472afee502 100644 --- a/core/stencil.config.ts +++ b/core/stencil.config.ts @@ -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