UNPKG

ng-cdk-table-virtual-scroll

Version:
88 lines 12.8 kB
import { __decorate } from "tslib"; import { Injectable } from '@angular/core'; import { distinctUntilChanged } from 'rxjs/operators'; import { BehaviorSubject, Subject } from 'rxjs'; let FixedSizeTableVirtualScrollStrategy = class FixedSizeTableVirtualScrollStrategy { constructor() { this.indexChange = new Subject(); this.stickyChange = new Subject(); this.renderedRangeStream = new BehaviorSubject({ start: 0, end: 0 }); this.scrolledIndexChange = this.indexChange.pipe(distinctUntilChanged()); this._dataLength = 0; } get dataLength() { return this._dataLength; } set dataLength(value) { this._dataLength = value; this.onDataLengthChanged(); } attach(viewport) { this.viewport = viewport; this.viewport.renderedRangeStream.subscribe(this.renderedRangeStream); this.onDataLengthChanged(); } detach() { this.indexChange.complete(); this.stickyChange.complete(); this.renderedRangeStream.complete(); } onContentScrolled() { this.updateContent(); } onDataLengthChanged() { if (this.viewport) { this.viewport.setTotalContentSize(this.dataLength * this.rowHeight + this.headerHeight + this.footerHeight); } this.updateContent(); } onContentRendered() { // no-op } onRenderedOffsetChanged() { // no-op } scrollToIndex(index, behavior) { if (!this.viewport || !this.rowHeight) { return; } this.viewport.scrollToOffset((index - 1) * this.rowHeight + this.headerHeight); } setConfig(configs) { const { rowHeight, headerHeight, footerHeight, bufferMultiplier } = configs; if (this.rowHeight === rowHeight && this.headerHeight === headerHeight && this.footerHeight === footerHeight && this.bufferMultiplier === bufferMultiplier) { return; } this.rowHeight = rowHeight; this.headerHeight = headerHeight; this.footerHeight = footerHeight; this.bufferMultiplier = bufferMultiplier; this.onDataLengthChanged(); } updateContent() { if (!this.viewport || !this.rowHeight) { return; } const scrollOffset = this.viewport.measureScrollOffset(); const amount = Math.ceil(this.viewport.getViewportSize() / this.rowHeight); const offset = Math.max(scrollOffset - this.headerHeight, 0); const buffer = Math.ceil(amount * this.bufferMultiplier); const skip = Math.round(offset / this.rowHeight); const index = Math.max(0, skip); const start = Math.max(0, index - buffer); const end = Math.min(this.dataLength, index + amount + buffer); const renderedOffset = start * this.rowHeight; this.viewport.setRenderedContentOffset(renderedOffset); this.viewport.setRenderedRange({ start, end }); this.indexChange.next(index); this.stickyChange.next(renderedOffset); } }; FixedSizeTableVirtualScrollStrategy = __decorate([ Injectable() ], FixedSizeTableVirtualScrollStrategy); export { FixedSizeTableVirtualScrollStrategy }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZml4ZWQtc2l6ZS10YWJsZS12aXJ0dWFsLXNjcm9sbC1zdHJhdGVneS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25nLWNkay10YWJsZS12aXJ0dWFsLXNjcm9sbC8iLCJzb3VyY2VzIjpbImxpYi9maXhlZC1zaXplLXRhYmxlLXZpcnR1YWwtc2Nyb2xsLXN0cmF0ZWd5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxlQUFlLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBWWhELElBQWEsbUNBQW1DLEdBQWhELE1BQWEsbUNBQW1DO0lBQWhEO1FBS1UsZ0JBQVcsR0FBRyxJQUFJLE9BQU8sRUFBVSxDQUFDO1FBQ3JDLGlCQUFZLEdBQUcsSUFBSSxPQUFPLEVBQVUsQ0FBQztRQUlyQyx3QkFBbUIsR0FBRyxJQUFJLGVBQWUsQ0FBWSxFQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBQyxDQUFDLENBQUM7UUFFekUsd0JBQW1CLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxDQUFDO1FBV25FLGdCQUFXLEdBQUcsQ0FBQyxDQUFDO0lBNEUxQixDQUFDO0lBckZDLElBQUksVUFBVTtRQUNaLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQztJQUMxQixDQUFDO0lBRUQsSUFBSSxVQUFVLENBQUMsS0FBYTtRQUMxQixJQUFJLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztRQUN6QixJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztJQUM3QixDQUFDO0lBSU0sTUFBTSxDQUFDLFFBQWtDO1FBQzlDLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxRQUFRLENBQUMsbUJBQW1C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R0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxLQUFLLEdBQUcsTUFBTSxDQUFDLENBQUM7UUFDMUMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLEtBQUssR0FBRyxNQUFNLEdBQUcsTUFBTSxDQUFDLENBQUM7UUFDL0QsTUFBTSxjQUFjLEdBQUcsS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7UUFDOUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyx3QkFBd0IsQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUN2RCxJQUFJLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBQyxDQUFDLENBQUM7UUFDN0MsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDN0IsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDekMsQ0FBQztDQUNGLENBQUE7QUFuR1ksbUNBQW1DO0lBRC9DLFVBQVUsRUFBRTtHQUNBLG1DQUFtQyxDQW1HL0M7U0FuR1ksbUNBQW1DIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBkaXN0aW5jdFVudGlsQ2hhbmdlZCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IENka1ZpcnR1YWxTY3JvbGxWaWV3cG9ydCwgVmlydHVhbFNjcm9sbFN0cmF0ZWd5IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3Njcm9sbGluZyc7XHJcbmltcG9ydCB7IExpc3RSYW5nZSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9jb2xsZWN0aW9ucyc7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFRTVlN0cmF0ZWd5Q29uZmlncyB7XHJcbiAgcm93SGVpZ2h0OiBudW1iZXI7XHJcbiAgaGVhZGVySGVpZ2h0OiBudW1iZXI7XHJcbiAgZm9vdGVySGVpZ2h0OiBudW1iZXI7XHJcbiAgYnVmZmVyTXVsdGlwbGllcjogbnVtYmVyO1xyXG59XHJcblxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBGaXhlZFNpemVUYWJsZVZpcnR1YWxTY3JvbGxTdHJhdGVneSBpbXBsZW1lbnRzIFZpcnR1YWxTY3JvbGxTdHJhdGVneSB7XHJcbiAgcHJpdmF0ZSByb3dIZWlnaHQhOiBudW1iZXI7XHJcbiAgcHJpdmF0ZSBoZWFkZXJIZWlnaHQhOiBudW1iZXI7XHJcbiAgcHJpdmF0ZSBmb290ZXJIZWlnaHQhOiBudW1iZXI7XHJcbiAgcHJpdmF0ZSBidWZmZXJNdWx0aXBsaWVyITogbnVtYmVyO1xyXG4gIHByaXZhdGUgaW5kZXhDaGFuZ2UgPSBuZXcgU3ViamVjdDxudW1iZXI+KCk7XHJcbiAgcHVibGljIHN0aWNreUNoYW5nZSA9IG5ldyBTdWJqZWN0PG51bWJlcj4oKTtcclxuXHJcbiAgcHVibGljIHZpZXdwb3J0OiBDZGtWaXJ0dWFsU2Nyb2xsVmlld3BvcnQ7XHJcblxyXG4gIHB1YmxpYyByZW5kZXJlZFJhbmdlU3RyZWFtID0gbmV3IEJlaGF2aW9yU3ViamVjdDxMaXN0UmFuZ2U+KHtzdGFydDogMCwgZW5kOiAwfSk7XHJcblxyXG4gIHB1YmxpYyBzY3JvbGxlZEluZGV4Q2hhbmdlID0gdGhpcy5pbmRleENoYW5nZS5waXBlKGRpc3RpbmN0VW50aWxDaGFuZ2VkKCkpO1xyXG5cclxuICBnZXQgZGF0YUxlbmd0aCgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMuX2RhdGFMZW5ndGg7XHJcbiAgfVxyXG5cclxuICBzZXQgZGF0YUxlbmd0aCh2YWx1ZTogbnVtYmVyKSB7XHJcbiAgICB0aGlzLl9kYXRhTGVuZ3RoID0gdmFsdWU7XHJcbiAgICB0aGlzLm9uRGF0YUxlbmd0aENoYW5nZWQoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2RhdGFMZW5ndGggPSAwO1xyXG5cclxuICBwdWJsaWMgYXR0YWNoKHZpZXdwb3J0OiBDZGtWaXJ0dWFsU2Nyb2xsVmlld3BvcnQpOiB2b2lkIHtcclxuICAgIHRoaXMudmlld3BvcnQgPSB2aWV3cG9ydDtcclxuICAgIHRoaXMudmlld3BvcnQucmVuZGVyZWRSYW5nZVN0cmVhbS5zdWJzY3JpYmUodGhpcy5yZW5kZXJlZFJhbmdlU3RyZWFtKTtcclxuICAgIHRoaXMub25EYXRhTGVuZ3RoQ2hhbmdlZCgpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGRldGFjaCgpOiB2b2lkIHtcclxuICAgIHRoaXMuaW5kZXhDaGFuZ2UuY29tcGxldGUoKTtcclxuICAgIHRoaXMuc3RpY2t5Q2hhbmdlLmNvbXBsZXRlKCk7XHJcbiAgICB0aGlzLnJlbmRlcmVkUmFuZ2VTdHJlYW0uY29tcGxldGUoKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBvbkNvbnRlbnRTY3JvbGxlZCgpOiB2b2lkIHtcclxuICAgIHRoaXMudXBkYXRlQ29udGVudCgpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG9uRGF0YUxlbmd0aENoYW5nZWQoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy52aWV3cG9ydCkge1xyXG4gICAgICB0aGlzLnZpZXdwb3J0LnNldFRvdGFsQ29udGVudFNpemUodGhpcy5kYXRhTGVuZ3RoICogdGhpcy5yb3dIZWlnaHQgKyB0aGlzLmhlYWRlckhlaWdodCArIHRoaXMuZm9vdGVySGVpZ2h0KTtcclxuICAgIH1cclxuICAgIHRoaXMudXBkYXRlQ29udGVudCgpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG9uQ29udGVudFJlbmRlcmVkKCk6IHZvaWQge1xyXG4gICAgLy8gbm8tb3BcclxuICB9XHJcblxyXG4gIHB1YmxpYyBvblJlbmRlcmVkT2Zmc2V0Q2hhbmdlZCgpOiB2b2lkIHtcclxuICAgIC8vIG5vLW9wXHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2Nyb2xsVG9JbmRleChpbmRleDogbnVtYmVyLCBiZWhhdmlvcj86IFNjcm9sbEJlaGF2aW9yKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMudmlld3BvcnQgfHwgIXRoaXMucm93SGVpZ2h0KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIHRoaXMudmlld3BvcnQuc2Nyb2xsVG9PZmZzZXQoKGluZGV4IC0gMSApICogdGhpcy5yb3dIZWlnaHQgKyB0aGlzLmhlYWRlckhlaWdodCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2V0Q29uZmlnKGNvbmZpZ3M6IFRTVlN0cmF0ZWd5Q29uZmlncykge1xyXG4gICAgY29uc3Qge3Jvd0hlaWdodCwgaGVhZGVySGVpZ2h0LCBmb290ZXJIZWlnaHQsIGJ1ZmZlck11bHRpcGxpZXJ9ID0gY29uZmlncztcclxuICAgIGlmIChcclxuICAgICAgdGhpcy5yb3dIZWlnaHQgPT09IHJvd0hlaWdodFxyXG4gICAgICAmJiB0aGlzLmhlYWRlckhlaWdodCA9PT0gaGVhZGVySGVpZ2h0XHJcbiAgICAgICYmIHRoaXMuZm9vdGVySGVpZ2h0ID09PSBmb290ZXJIZWlnaHRcclxuICAgICAgJiYgdGhpcy5idWZmZXJNdWx0aXBsaWVyID09PSBidWZmZXJNdWx0aXBsaWVyXHJcbiAgICApIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgdGhpcy5yb3dIZWlnaHQgPSByb3dIZWlnaHQ7XHJcbiAgICB0aGlzLmhlYWRlckhlaWdodCA9IGhlYWRlckhlaWdodDtcclxuICAgIHRoaXMuZm9vdGVySGVpZ2h0ID0gZm9vdGVySGVpZ2h0O1xyXG4gICAgdGhpcy5idWZmZXJNdWx0aXBsaWVyID0gYnVmZmVyTXVsdGlwbGllcjtcclxuICAgIHRoaXMub25EYXRhTGVuZ3RoQ2hhbmdlZCgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB1cGRhdGVDb250ZW50KCkge1xyXG4gICAgaWYgKCF0aGlzLnZpZXdwb3J0IHx8ICF0aGlzLnJvd0hlaWdodCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBjb25zdCBzY3JvbGxPZmZzZXQgPSB0aGlzLnZpZXdwb3J0Lm1lYXN1cmVTY3JvbGxPZmZzZXQoKTtcclxuICAgIGNvbnN0IGFtb3VudCA9IE1hdGguY2VpbCh0aGlzLnZpZXdwb3J0LmdldFZpZXdwb3J0U2l6ZSgpIC8gdGhpcy5yb3dIZWlnaHQpO1xyXG4gICAgY29uc3Qgb2Zmc2V0ID0gTWF0aC5tYXgoc2Nyb2xsT2Zmc2V0IC0gdGhpcy5oZWFkZXJIZWlnaHQsIDApO1xyXG4gICAgY29uc3QgYnVmZmVyID0gTWF0aC5jZWlsKGFtb3VudCAqIHRoaXMuYnVmZmVyTXVsdGlwbGllcik7XHJcblxyXG4gICAgY29uc3Qgc2tpcCA9IE1hdGgucm91bmQob2Zmc2V0IC8gdGhpcy5yb3dIZWlnaHQpO1xyXG4gICAgY29uc3QgaW5kZXggPSBNYXRoLm1heCgwLCBza2lwKTtcclxuICAgIGNvbnN0IHN0YXJ0ID0gTWF0aC5tYXgoMCwgaW5kZXggLSBidWZmZXIpO1xyXG4gICAgY29uc3QgZW5kID0gTWF0aC5taW4odGhpcy5kYXRhTGVuZ3RoLCBpbmRleCArIGFtb3VudCArIGJ1ZmZlcik7XHJcbiAgICBjb25zdCByZW5kZXJlZE9mZnNldCA9IHN0YXJ0ICogdGhpcy5yb3dIZWlnaHQ7XHJcbiAgICB0aGlzLnZpZXdwb3J0LnNldFJlbmRlcmVkQ29udGVudE9mZnNldChyZW5kZXJlZE9mZnNldCk7XHJcbiAgICB0aGlzLnZpZXdwb3J0LnNldFJlbmRlcmVkUmFuZ2Uoe3N0YXJ0LCBlbmR9KTtcclxuICAgIHRoaXMuaW5kZXhDaGFuZ2UubmV4dChpbmRleCk7XHJcbiAgICB0aGlzLnN0aWNreUNoYW5nZS5uZXh0KHJlbmRlcmVkT2Zmc2V0KTtcclxuICB9XHJcbn1cclxuIl19