blob: 4f515754e2586844a4aff762fb113ac70d577d1b [file] [log] [blame]
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/common'), require('@angular/cdk/portal'), require('@angular/core'), require('@angular/platform-browser'), require('rxjs'), require('rxjs/operators')) :
typeof define === 'function' && define.amd ? define('@covalent/core/virtual-scroll', ['exports', '@angular/common', '@angular/cdk/portal', '@angular/core', '@angular/platform-browser', 'rxjs', 'rxjs/operators'], factory) :
(factory((global.covalent = global.covalent || {}, global.covalent.core = global.covalent.core || {}, global.covalent.core['virtual-scroll'] = {}),global.ng.common,global.ng.cdk.portal,global.ng.core,global.ng.platformBrowser,global.rxjs,global.rxjs.operators));
}(this, (function (exports,common,portal,core,platformBrowser,rxjs,operators) { 'use strict';
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b)
if (b.hasOwnProperty(p))
d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
var TdVirtualScrollRowDirective = /** @class */ (function (_super) {
__extends(TdVirtualScrollRowDirective, _super);
function TdVirtualScrollRowDirective(templateRef, viewContainerRef) {
return _super.call(this, templateRef, viewContainerRef) || this;
}
TdVirtualScrollRowDirective.decorators = [
{ type: core.Directive, args: [{ selector: '[tdVirtualScrollRow]' },] }
];
/** @nocollapse */
TdVirtualScrollRowDirective.ctorParameters = function () {
return [
{ type: core.TemplateRef },
{ type: core.ViewContainerRef }
];
};
return TdVirtualScrollRowDirective;
}(portal.TemplatePortalDirective));
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/** @type {?} */
var TD_VIRTUAL_OFFSET = 2;
/** @type {?} */
var SCROLL_DEBOUNCE = 200;
var TdVirtualScrollContainerComponent = /** @class */ (function () {
function TdVirtualScrollContainerComponent(_elementRef, _domSanitizer, _renderer, _changeDetectorRef) {
this._elementRef = _elementRef;
this._domSanitizer = _domSanitizer;
this._renderer = _renderer;
this._changeDetectorRef = _changeDetectorRef;
this._subs = [];
this._bottom = new rxjs.Subject();
this._initialized = false;
this._totalHeight = 0;
this._hostHeight = 0;
this._scrollVerticalOffset = 0;
this._fromRow = 0;
this._toRow = 0;
/**
* bottom: function
* Method to be executed when user scrolled to the last item of the list.
* An [ITdVirtualScrollBottomEvent] event is emitted
*/
this.bottom = new core.EventEmitter();
/**
* trackBy?: TrackByFunction
* This accepts the same trackBy function [ngFor] does.
* https://angular.io/api/core/TrackByFunction
*/
this.trackBy = function (index, item) {
return item;
};
}
Object.defineProperty(TdVirtualScrollContainerComponent.prototype, "data", {
get: /**
* @return {?}
*/ function () {
return this._data;
},
/**
* data: any[]
* List of items to virtually iterate on.
*/
set: /**
* data: any[]
* List of items to virtually iterate on.
* @param {?} data
* @return {?}
*/ function (data) {
this._data = data;
if (this._initialized) {
this._calculateVirtualRows();
}
this._changeDetectorRef.markForCheck();
},
enumerable: true,
configurable: true
});
Object.defineProperty(TdVirtualScrollContainerComponent.prototype, "virtualData", {
get: /**
* @return {?}
*/ function () {
return this._virtualData;
},
enumerable: true,
configurable: true
});
Object.defineProperty(TdVirtualScrollContainerComponent.prototype, "rowHeight", {
get: /**
* @return {?}
*/ function () {
if (this._rows && this._rows.toArray()[0]) {
return this._rows.toArray()[0].nativeElement.getBoundingClientRect().height;
}
return 0;
},
enumerable: true,
configurable: true
});
Object.defineProperty(TdVirtualScrollContainerComponent.prototype, "totalHeight", {
get: /**
* @return {?}
*/ function () {
return this._totalHeight;
},
enumerable: true,
configurable: true
});
Object.defineProperty(TdVirtualScrollContainerComponent.prototype, "fromRow", {
get: /**
* @return {?}
*/ function () {
return this._fromRow;
},
enumerable: true,
configurable: true
});
Object.defineProperty(TdVirtualScrollContainerComponent.prototype, "toRow", {
get: /**
* @return {?}
*/ function () {
return this._toRow;
},
enumerable: true,
configurable: true
});
Object.defineProperty(TdVirtualScrollContainerComponent.prototype, "offsetTransform", {
get: /**
* @return {?}
*/ function () {
return this._offsetTransform;
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
TdVirtualScrollContainerComponent.prototype.ngAfterViewInit = /**
* @return {?}
*/
function () {
var _this = this;
this._subs.push(this._rows.changes.subscribe(function () {
_this._calculateVirtualRows();
}));
this._initialized = true;
this._calculateVirtualRows();
this._subs.push(this._bottom.pipe(operators.debounceTime(SCROLL_DEBOUNCE)).subscribe(function () {
_this.bottom.emit({
lastRow: _this._data[_this._data.length - 1],
lastIndex: _this.toRow,
});
}));
};
/**
* @return {?}
*/
TdVirtualScrollContainerComponent.prototype.ngAfterViewChecked = /**
* @return {?}
*/
function () {
/** @type {?} */
var newHostHeight = this._elementRef.nativeElement.getBoundingClientRect().height;
if (this._hostHeight !== newHostHeight) {
this._hostHeight = newHostHeight;
if (this._initialized) {
this._calculateVirtualRows();
}
}
};
/**
* @return {?}
*/
TdVirtualScrollContainerComponent.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
if (this._subs) {
this._subs.forEach(function (sub) {
sub.unsubscribe();
});
}
};
/**
* @param {?} event
* @return {?}
*/
TdVirtualScrollContainerComponent.prototype.handleScroll = /**
* @param {?} event
* @return {?}
*/
function (event) {
/** @type {?} */
var element = (( /** @type {?} */(event.target)));
if (element) {
/** @type {?} */
var verticalScroll = element.scrollTop;
if (this._scrollVerticalOffset !== verticalScroll) {
this._scrollVerticalOffset = verticalScroll;
if (this._initialized) {
this._calculateVirtualRows();
}
}
if (this._initialized) {
// check to see if bottom was hit to throw the bottom event
if ((this._data.length * this.rowHeight) - (verticalScroll + this._hostHeight) === 0) {
this._bottom.next();
}
}
}
};
/**
* Method to refresh and recalculate the virtual rows
* e.g. after changing the [data] content
*/
/**
* Method to refresh and recalculate the virtual rows
* e.g. after changing the [data] content
* @return {?}
*/
TdVirtualScrollContainerComponent.prototype.refresh = /**
* Method to refresh and recalculate the virtual rows
* e.g. after changing the [data] content
* @return {?}
*/
function () {
this._calculateVirtualRows();
};
/**
* Method to scroll to a specific row of the list.
*/
/**
* Method to scroll to a specific row of the list.
* @param {?} row
* @return {?}
*/
TdVirtualScrollContainerComponent.prototype.scrollTo = /**
* Method to scroll to a specific row of the list.
* @param {?} row
* @return {?}
*/
function (row) {
this._elementRef.nativeElement.scrollTop = row * this.rowHeight;
this._changeDetectorRef.markForCheck();
};
/**
* Method to scroll to the start of the list.
*/
/**
* Method to scroll to the start of the list.
* @return {?}
*/
TdVirtualScrollContainerComponent.prototype.scrollToStart = /**
* Method to scroll to the start of the list.
* @return {?}
*/
function () {
this.scrollTo(0);
this._changeDetectorRef.markForCheck();
};
/**
* Method to scroll to the end of the list.
*/
/**
* Method to scroll to the end of the list.
* @return {?}
*/
TdVirtualScrollContainerComponent.prototype.scrollToEnd = /**
* Method to scroll to the end of the list.
* @return {?}
*/
function () {
this.scrollTo(this.totalHeight / this.rowHeight);
this._changeDetectorRef.markForCheck();
};
/**
* @return {?}
*/
TdVirtualScrollContainerComponent.prototype._calculateVirtualRows = /**
* @return {?}
*/
function () {
var _this = this;
if (this._data) {
this._totalHeight = this._data.length * this.rowHeight;
/** @type {?} */
var fromRow = Math.floor((this._scrollVerticalOffset / this.rowHeight)) - TD_VIRTUAL_OFFSET;
this._fromRow = fromRow > 0 ? fromRow : 0;
/** @type {?} */
var range = Math.floor((this._hostHeight / this.rowHeight)) + (TD_VIRTUAL_OFFSET * 2);
/** @type {?} */
var toRow = range + this.fromRow;
if (isFinite(toRow) && toRow > this._data.length) {
toRow = this._data.length;
}
else if (!isFinite(toRow)) {
toRow = TD_VIRTUAL_OFFSET;
}
this._toRow = toRow;
}
else {
this._totalHeight = 0;
this._fromRow = 0;
this._toRow = 0;
}
/** @type {?} */
var offset = 0;
if (this._scrollVerticalOffset > (TD_VIRTUAL_OFFSET * this.rowHeight)) {
offset = this.fromRow * this.rowHeight;
}
this._offsetTransform = this._domSanitizer.bypassSecurityTrustStyle('translateY(' + (offset - this.totalHeight) + 'px)');
if (this._data) {
this._virtualData = this.data.slice(this.fromRow, this.toRow);
}
// mark for check at the end of the queue so we are sure
// that the changes will be marked
Promise.resolve().then(function () {
_this._changeDetectorRef.markForCheck();
});
};
TdVirtualScrollContainerComponent.decorators = [
{ type: core.Component, args: [{
selector: 'td-virtual-scroll-container',
template: "<div [style.height.px]=\"totalHeight\"></div>\n<div [style.transform]=\"offsetTransform\"\n [style.position]=\"'absolute'\"\n [style.width.%]=\"100\">\n <ng-template let-row\n let-index=\"index\"\n ngFor\n [ngForOf]=\"virtualData\"\n [ngForTrackBy]=\"trackBy\">\n <div #rowElement\n [style.width.%]=\"100\">\n <ng-template *ngIf=\"_rowTemplate\"\n [ngTemplateOutlet]=\"_rowTemplate.templateRef\"\n [ngTemplateOutletContext]=\"{row: row,\n index: (fromRow + index),\n first: (fromRow + index) === 0,\n last: (fromRow + index) === (data.length - 1),\n odd: ((fromRow + index + 1) % 2) === 1,\n even: ((fromRow + index + 1) % 2) === 0}\">\n </ng-template>\n </div>\n </ng-template>\n</div>",
changeDetection: core.ChangeDetectionStrategy.OnPush,
styles: [":host{display:block;height:100%;width:100%;overflow:auto;position:relative}"]
}] }
];
/** @nocollapse */
TdVirtualScrollContainerComponent.ctorParameters = function () {
return [
{ type: core.ElementRef },
{ type: platformBrowser.DomSanitizer },
{ type: core.Renderer2 },
{ type: core.ChangeDetectorRef }
];
};
TdVirtualScrollContainerComponent.propDecorators = {
data: [{ type: core.Input, args: ['data',] }],
bottom: [{ type: core.Output }],
_rows: [{ type: core.ViewChildren, args: ['rowElement',] }],
_rowTemplate: [{ type: core.ContentChild, args: [TdVirtualScrollRowDirective,] }],
trackBy: [{ type: core.Input, args: ['trackBy',] }],
handleScroll: [{ type: core.HostListener, args: ['scroll', ['$event'],] }]
};
return TdVirtualScrollContainerComponent;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/** @type {?} */
var TD_VIRTUAL_SCROLL = [
TdVirtualScrollRowDirective,
TdVirtualScrollContainerComponent,
];
var CovalentVirtualScrollModule = /** @class */ (function () {
function CovalentVirtualScrollModule() {
}
CovalentVirtualScrollModule.decorators = [
{ type: core.NgModule, args: [{
imports: [
common.CommonModule,
],
declarations: [
TD_VIRTUAL_SCROLL,
],
exports: [
TD_VIRTUAL_SCROLL,
],
},] }
];
return CovalentVirtualScrollModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
exports.CovalentVirtualScrollModule = CovalentVirtualScrollModule;
exports.TdVirtualScrollContainerComponent = TdVirtualScrollContainerComponent;
exports.TdVirtualScrollRowDirective = TdVirtualScrollRowDirective;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=covalent-core-virtual-scroll.umd.js.map