UNPKG

@triniwiz/nativescript-pager

Version:

A Carousel/Pager plugin for NativeScript

370 lines (365 loc) 16.4 kB
import * as i0 from '@angular/core'; import { EventEmitter, ɵisListLikeIterable, TemplateRef, ViewContainerRef, Directive, ViewChild, Output, ContentChild, Input, InjectionToken, Inject, Host, forwardRef, Component, ChangeDetectionStrategy, NgModule, NO_ERRORS_SCHEMA } from '@angular/core'; import { __decorate } from 'tslib'; import { ObservableArray, isIOS, Trace, LayoutBase, profile } from '@nativescript/core'; import { registerElement, getSingleViewRecursive, isInvisibleNode } from '@nativescript/angular'; import { Pager, PagerItem, PagerLog, PagerError } from '@triniwiz/nativescript-pager'; registerElement("Pager", () => Pager); registerElement("PagerItem", () => PagerItem); const NG_VIEW = "_ngViewRef"; class ItemContext { constructor($implicit, item, index, even, odd) { this.$implicit = $implicit; this.item = item; this.index = index; this.even = even; this.odd = odd; } } class TemplatedItemsComponent { constructor(_elementRef, _iterableDiffers, zone) { this._iterableDiffers = _iterableDiffers; this.zone = zone; this.setupItemView = new EventEmitter(); this.templatedItemsView = _elementRef.nativeElement; this.templatedItemsView.on("itemLoading", this.onItemLoading, this); this.templatedItemsView.on("itemDisposing", this.onItemDisposing, this); } get items() { return this._items; } set items(value) { this._items = value; let needDiffer = true; if (value instanceof ObservableArray) { needDiffer = false; } if (needDiffer && !this._differ && ɵisListLikeIterable(value)) { this._differ = this._iterableDiffers .find(this._items) .create((_index, item) => { return item; }); } this.templatedItemsView.items = this._items; } get selectedIndex() { return this._selectedIndex; } set selectedIndex(value) { this._selectedIndex = value; this.templatedItemsView.selectedIndex = this._selectedIndex; } ngAfterViewInit() { if (!!(this._selectedIndex)) { setTimeout(() => { if (isIOS) { this.templatedItemsView.scrollToIndexAnimated(this._selectedIndex, false); } this.templatedItemsView.selectedIndex = this._selectedIndex; }); } } ngAfterContentInit() { if (Trace.isEnabled()) { PagerLog("TemplatedItemsView.ngAfterContentInit()"); } this.setItemTemplates(); } ngOnDestroy() { this.templatedItemsView.off("itemLoading", this.onItemLoading, this); this.templatedItemsView.off("itemDisposing", this.onItemDisposing, this); } setItemTemplates() { if (!this.items) return; // The itemTemplateQuery may be changed after list items are added that contain <template> inside, // so cache and use only the original template to avoid errors. this.itemTemplate = this.itemTemplateQuery; if (this._templateMap) { if (Trace.isEnabled()) { PagerLog("Setting templates"); } const templates = []; this._templateMap.forEach((value) => { templates.push(value); }); this.templatedItemsView.itemTemplates = templates; } } registerTemplate(key, template) { if (Trace.isEnabled()) { PagerLog(`registerTemplate for key: ${key}`); } if (!this._templateMap) { this._templateMap = new Map(); } const keyedTemplate = { key, createView: this.getItemTemplateViewFactory(template), }; this._templateMap.set(key, keyedTemplate); } onItemLoading(args) { if (!args.view && !this.itemTemplate) { return; } if (!this.items) return; const index = args.index; const items = args.object.items; const currentItem = typeof items.getItem === "function" ? items.getItem(index) : items[index]; let viewRef; if (args.view) { if (Trace.isEnabled()) { PagerLog(`onItemLoading: ${index} - Reusing existing view`); } viewRef = args.view[NG_VIEW]; // Getting angular view from original element (in cases when ProxyViewContainer // is used NativeScript internally wraps it in a StackLayout) if (!viewRef && args.view instanceof LayoutBase && args.view.getChildrenCount() > 0) { viewRef = args.view.getChildAt(0)[NG_VIEW]; } if (!viewRef && Trace.isEnabled()) { PagerError(`ViewReference not found for item ${index}. View recycling is not working`); } } if (!viewRef) { if (Trace.isEnabled()) { PagerLog(`onItemLoading: ${index} - Creating view from template`); } viewRef = this.loader.createEmbeddedView(this.itemTemplate, new ItemContext(), 0); args.view = getItemViewRoot(viewRef); args.view[NG_VIEW] = viewRef; } this.setupViewRef(viewRef, currentItem, index); this.detectChangesOnChild(viewRef, index); } onItemDisposing(args) { if (!args.view) { return; } let viewRef; if (args.view) { if (Trace.isEnabled()) { PagerLog(`onItemDisposing: ${args.index} - Removing angular view`); } viewRef = args.view[NG_VIEW]; // Getting angular view from original element (in cases when ProxyViewContainer // is used NativeScript internally wraps it in a StackLayout) if (!viewRef && args.view instanceof LayoutBase && args.view.getChildrenCount() > 0) { viewRef = args.view.getChildAt(0)[NG_VIEW]; } if (!viewRef && Trace.isEnabled()) { PagerError(`ViewReference not found for item ${args.index}. View disposing is not working`); } } if (viewRef) { if (Trace.isEnabled()) { PagerLog(`onItemDisposing: ${args.index} - Disposing view reference`); } viewRef.destroy(); } } setupViewRef(viewRef, data, index) { const context = viewRef.context; context.$implicit = data; context.item = data; context.index = index; context.even = index % 2 === 0; context.odd = !context.even; this.setupItemView.next({ view: viewRef, data: data, index: index, context: context, }); } getItemTemplateViewFactory(template) { return () => { const viewRef = this.loader.createEmbeddedView(template, new ItemContext(), 0); const resultView = getItemViewRoot(viewRef); resultView[NG_VIEW] = viewRef; return resultView; }; } detectChangesOnChild(viewRef, index) { if (Trace.isEnabled()) { PagerLog(`Manually detect changes in child: ${index}`); } this.zone.run(() => { viewRef.markForCheck(); viewRef.detectChanges(); }); } ngDoCheck() { if (this._differ) { if (Trace.isEnabled()) { PagerLog("ngDoCheck() - execute differ"); } const changes = this._differ.diff(this._items); if (changes) { if (Trace.isEnabled()) { PagerLog("ngDoCheck() - refresh"); } this.templatedItemsView.refresh(); } } } } TemplatedItemsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.2", ngImport: i0, type: TemplatedItemsComponent, deps: [{ token: i0.ElementRef }, { token: i0.IterableDiffers }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); TemplatedItemsComponent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.2", type: TemplatedItemsComponent, inputs: { items: "items", selectedIndex: "selectedIndex" }, outputs: { setupItemView: "setupItemView" }, queries: [{ propertyName: "itemTemplateQuery", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "loader", first: true, predicate: ["loader"], descendants: true, read: ViewContainerRef }], ngImport: i0 }); __decorate([ profile ], TemplatedItemsComponent.prototype, "onItemLoading", null); __decorate([ profile ], TemplatedItemsComponent.prototype, "onItemDisposing", null); __decorate([ profile ], TemplatedItemsComponent.prototype, "detectChangesOnChild", null); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.2", ngImport: i0, type: TemplatedItemsComponent, decorators: [{ type: Directive }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.IterableDiffers }, { type: i0.NgZone }]; }, propDecorators: { loader: [{ type: ViewChild, args: ["loader", { read: ViewContainerRef, static: false }] }], setupItemView: [{ type: Output }], itemTemplateQuery: [{ type: ContentChild, args: [TemplateRef, { static: false }] }], items: [{ type: Input }], selectedIndex: [{ type: Input }], onItemLoading: [], onItemDisposing: [], detectChangesOnChild: [] } }); function getItemViewRoot(viewRef, rootLocator = getSingleViewRecursive) { return rootLocator(viewRef.rootNodes, 0); } const TEMPLATED_ITEMS_COMPONENT = new InjectionToken("TemplatedItemsComponent"); class PagerItemDirective { constructor(templateRef, owner, viewContainer) { this.templateRef = templateRef; this.owner = owner; this.viewContainer = viewContainer; } ensureItem() { if (!this.item) { this.item = new PagerItem(); } } applyConfig() { this.ensureItem(); } ngOnInit() { this.applyConfig(); const viewRef = this.viewContainer.createEmbeddedView(this.templateRef); // Filter out text nodes and comments const realViews = viewRef.rootNodes.filter((node) => !isInvisibleNode(node)); if (realViews.length > 0) { const view = realViews[0]; this.item.addChild(view); this.owner.nativeElement._addChildFromBuilder("PagerItem", this.item); } } } PagerItemDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.2", ngImport: i0, type: PagerItemDirective, deps: [{ token: i0.TemplateRef }, { token: TEMPLATED_ITEMS_COMPONENT, host: true }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive }); PagerItemDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.2", type: PagerItemDirective, selector: "[pagerItem]", ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.2", ngImport: i0, type: PagerItemDirective, decorators: [{ type: Directive, args: [{ selector: "[pagerItem]", }] }], ctorParameters: function () { return [{ type: i0.TemplateRef }, { type: TemplatedItemsComponent, decorators: [{ type: Inject, args: [TEMPLATED_ITEMS_COMPONENT] }, { type: Host }] }, { type: i0.ViewContainerRef }]; } }); class TemplateKeyDirective { constructor(templateRef, comp) { this.templateRef = templateRef; this.comp = comp; } set pagerTemplateKey(value) { if (this.comp && this.templateRef) { this.comp.registerTemplate(value, this.templateRef); } } } TemplateKeyDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.2", ngImport: i0, type: TemplateKeyDirective, deps: [{ token: i0.TemplateRef }, { token: TEMPLATED_ITEMS_COMPONENT, host: true }], target: i0.ɵɵFactoryTarget.Directive }); TemplateKeyDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.2", type: TemplateKeyDirective, selector: "[pagerTemplateKey]", inputs: { pagerTemplateKey: "pagerTemplateKey" }, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.2", ngImport: i0, type: TemplateKeyDirective, decorators: [{ type: Directive, args: [{ selector: "[pagerTemplateKey]" }] }], ctorParameters: function () { return [{ type: i0.TemplateRef }, { type: TemplatedItemsComponent, decorators: [{ type: Inject, args: [TEMPLATED_ITEMS_COMPONENT] }, { type: Host }] }]; }, propDecorators: { pagerTemplateKey: [{ type: Input }] } }); class PagerComponent extends TemplatedItemsComponent { constructor(_elementRef, _iterableDiffers, zone) { super(_elementRef, _iterableDiffers, zone); } get nativeElement() { return this.templatedItemsView; } } PagerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.2", ngImport: i0, type: PagerComponent, deps: [{ token: i0.ElementRef }, { token: i0.IterableDiffers }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); PagerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.2", type: PagerComponent, selector: "Pager", providers: [ { provide: TEMPLATED_ITEMS_COMPONENT, useExisting: forwardRef(() => PagerComponent) } ], usesInheritance: true, ngImport: i0, template: ` <DetachedContainer> <Placeholder #loader></Placeholder> </DetachedContainer>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.2", ngImport: i0, type: PagerComponent, decorators: [{ type: Component, args: [{ selector: 'Pager', template: ` <DetachedContainer> <Placeholder #loader></Placeholder> </DetachedContainer>`, changeDetection: ChangeDetectionStrategy.OnPush, providers: [ { provide: TEMPLATED_ITEMS_COMPONENT, useExisting: forwardRef(() => PagerComponent) } ] }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.IterableDiffers }, { type: i0.NgZone }]; } }); class PagerModule { } PagerModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.2", ngImport: i0, type: PagerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); PagerModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.2.2", ngImport: i0, type: PagerModule, declarations: [PagerComponent, TemplateKeyDirective, PagerItemDirective], exports: [PagerComponent, TemplateKeyDirective, PagerItemDirective] }); PagerModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.2.2", ngImport: i0, type: PagerModule }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.2", ngImport: i0, type: PagerModule, decorators: [{ type: NgModule, args: [{ declarations: [PagerComponent, TemplateKeyDirective, PagerItemDirective], exports: [PagerComponent, TemplateKeyDirective, PagerItemDirective], schemas: [NO_ERRORS_SCHEMA] }] }] }); /** * Generated bundle index. Do not edit. */ export { PagerComponent, PagerItemDirective, PagerModule, TemplateKeyDirective, TemplatedItemsComponent }; //# sourceMappingURL=nativescript-nativescript-pager-angular.mjs.map