ng-virtual-list 16.3.1 → 16.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -42,7 +42,8 @@ var SnappingMethods;
42
42
  })(SnappingMethods || (SnappingMethods = {}));
43
43
 
44
44
  const DEFAULT_ITEM_SIZE = 24;
45
- const DEFAULT_ITEMS_OFFSET = 2;
45
+ const DEFAULT_BUFFER_SIZE = 2;
46
+ const DEFAULT_MAX_BUFFER_SIZE = 100;
46
47
  const DEFAULT_LIST_SIZE = 400;
47
48
  const DEFAULT_SNAP = false;
48
49
  const DEFAULT_ENABLED_BUFFER_OPTIMIZATION = false;
@@ -688,6 +689,33 @@ class CacheMap extends EventEmitter {
688
689
  }
689
690
  }
690
691
 
692
+ const DEFAULT_EXTRA = {
693
+ extremumThreshold: 2,
694
+ bufferSize: 10,
695
+ };
696
+ const bufferInterpolation = (currentBufferValue, array, value, extra) => {
697
+ const { extremumThreshold = DEFAULT_EXTRA.extremumThreshold, bufferSize = DEFAULT_EXTRA.bufferSize, } = extra ?? DEFAULT_EXTRA;
698
+ if (currentBufferValue < value) {
699
+ let i = 0;
700
+ while (i < extremumThreshold) {
701
+ array.push(value);
702
+ i++;
703
+ }
704
+ }
705
+ else {
706
+ array.push(value);
707
+ }
708
+ while (array.length >= bufferSize) {
709
+ array.shift();
710
+ }
711
+ const l = array.length;
712
+ let buffer = 0;
713
+ for (let i = 0; i < l; i++) {
714
+ buffer += array[i];
715
+ }
716
+ return Math.ceil(buffer / l);
717
+ };
718
+
691
719
  const TRACK_BOX_CHANGE_EVENT_NAME = 'change';
692
720
  var ItemDisplayMethods;
693
721
  (function (ItemDisplayMethods) {
@@ -696,6 +724,7 @@ var ItemDisplayMethods;
696
724
  ItemDisplayMethods[ItemDisplayMethods["DELETE"] = 2] = "DELETE";
697
725
  ItemDisplayMethods[ItemDisplayMethods["NOT_CHANGED"] = 3] = "NOT_CHANGED";
698
726
  })(ItemDisplayMethods || (ItemDisplayMethods = {}));
727
+ const DEFAULT_BUFFER_EXTREMUM_THRESHOLD = 15, DEFAULT_MAX_BUFFER_SEQUENCE_LENGTH = 30, DEFAULT_RESET_BUFFER_SIZE_TIMEOUT = 10000;
699
728
  /**
700
729
  * An object that performs tracking, calculations and caching.
701
730
  * @link https://github.com/DjonnyX/ng-virtual-list/blob/16.x/projects/ng-virtual-list/src/lib/utils/trackBox.ts
@@ -765,6 +794,16 @@ class TrackBox extends CacheMap {
765
794
  _previousTotalSize = 0;
766
795
  _scrollDelta = 0;
767
796
  get scrollDelta() { return this._scrollDelta; }
797
+ isAdaptiveBuffer = true;
798
+ _bufferSequenceExtraThreshold = DEFAULT_BUFFER_EXTREMUM_THRESHOLD;
799
+ _maxBufferSequenceLength = DEFAULT_MAX_BUFFER_SEQUENCE_LENGTH;
800
+ _bufferSizeSequence = [];
801
+ _bufferSize = 0;
802
+ get bufferSize() { return this._bufferSize; }
803
+ _defaultBufferSize = 0;
804
+ _maxBufferSize = this._defaultBufferSize;
805
+ _resetBufferSizeTimeout = DEFAULT_RESET_BUFFER_SIZE_TIMEOUT;
806
+ _resetBufferSizeTimer;
768
807
  lifeCircle() {
769
808
  this.fireChangeIfNeed();
770
809
  this.lifeCircleDo();
@@ -858,14 +897,16 @@ class TrackBox extends CacheMap {
858
897
  */
859
898
  getItemPosition(id, stickyMap, options) {
860
899
  const opt = { fromItemId: id, stickyMap, ...options };
861
- const { scrollSize } = this.recalculateMetrics({
900
+ this._defaultBufferSize = opt.bufferSize;
901
+ this._maxBufferSize = opt.maxBufferSize;
902
+ const { scrollSize, isFromItemIdFound } = this.recalculateMetrics({
862
903
  ...opt,
863
904
  dynamicSize: this._crudDetected || opt.dynamicSize,
864
905
  previousTotalSize: this._previousTotalSize,
865
906
  crudDetected: this._crudDetected,
866
907
  deletedItemsMap: this._deletedItemsMap,
867
908
  });
868
- return scrollSize;
909
+ return isFromItemIdFound ? scrollSize : -1;
869
910
  }
870
911
  /**
871
912
  * Updates the collection of display objects
@@ -875,6 +916,8 @@ class TrackBox extends CacheMap {
875
916
  if (opt.dynamicSize) {
876
917
  this.cacheElements();
877
918
  }
919
+ this._defaultBufferSize = opt.bufferSize;
920
+ this._maxBufferSize = opt.maxBufferSize;
878
921
  const metrics = this.recalculateMetrics({
879
922
  ...opt,
880
923
  collection: items,
@@ -883,6 +926,7 @@ class TrackBox extends CacheMap {
883
926
  deletedItemsMap,
884
927
  });
885
928
  this._delta += metrics.delta;
929
+ this.updateAdaptiveBufferParams(metrics, items.length);
886
930
  this._previousTotalSize = metrics.totalSize;
887
931
  this._deletedItemsMap = {};
888
932
  this._crudDetected = false;
@@ -898,6 +942,27 @@ class TrackBox extends CacheMap {
898
942
  getNearestItem(scrollSize, items, itemSize, isVertical) {
899
943
  return this.getElementFromStart(scrollSize, items, this._map, itemSize, isVertical);
900
944
  }
945
+ _previousScrollSize = 0;
946
+ updateAdaptiveBufferParams(metrics, totalItemsLength) {
947
+ this.disposeClearBufferSizeTimer();
948
+ const scrollSize = metrics.scrollSize + this._delta, delta = Math.abs(this._previousScrollSize - scrollSize);
949
+ this._previousScrollSize = scrollSize;
950
+ const bufferRawSize = Math.min(Math.floor(delta / metrics.typicalItemSize) * 5, totalItemsLength), minBufferSize = bufferRawSize < this._defaultBufferSize ? this._defaultBufferSize : bufferRawSize, bufferValue = minBufferSize > this._maxBufferSize ? this._maxBufferSize : minBufferSize;
951
+ this._bufferSize = bufferInterpolation(this._bufferSize, this._bufferSizeSequence, bufferValue, {
952
+ extremumThreshold: this._bufferSequenceExtraThreshold,
953
+ bufferSize: this._maxBufferSequenceLength,
954
+ });
955
+ this.startResetBufferSizeTimer();
956
+ }
957
+ startResetBufferSizeTimer() {
958
+ this._resetBufferSizeTimer = setTimeout(() => {
959
+ this._bufferSize = this._defaultBufferSize;
960
+ this._bufferSizeSequence = [];
961
+ }, this._resetBufferSizeTimeout);
962
+ }
963
+ disposeClearBufferSizeTimer() {
964
+ clearTimeout(this._resetBufferSizeTimer);
965
+ }
901
966
  /**
902
967
  * Calculates the position of an element based on the given scrollSize
903
968
  */
@@ -949,32 +1014,32 @@ class TrackBox extends CacheMap {
949
1014
  * Calculates list metrics
950
1015
  */
951
1016
  recalculateMetrics(options) {
952
- const { fromItemId, bounds, collection, dynamicSize, isVertical, itemSize, itemsOffset, scrollSize, snap, stickyMap, enabledBufferOptimization, previousTotalSize, crudDetected, deletedItemsMap } = options;
953
- const { width, height } = bounds, sizeProperty = isVertical ? HEIGHT_PROP_NAME : WIDTH_PROP_NAME, size = isVertical ? height : width, totalLength = collection.length, typicalItemSize = itemSize, w = isVertical ? width : typicalItemSize, h = isVertical ? typicalItemSize : height, map = this._map, snapshot = this._snapshot, checkOverscrollItemsLimit = Math.ceil(size / typicalItemSize), snippedPos = Math.floor(scrollSize), leftItemsWeights = [], isFromId = fromItemId !== undefined && (typeof fromItemId === 'number' && fromItemId > -1)
1017
+ const { fromItemId, bounds, collection, dynamicSize, isVertical, itemSize, bufferSize: minBufferSize, scrollSize, snap, stickyMap, enabledBufferOptimization, previousTotalSize, crudDetected, deletedItemsMap } = options;
1018
+ const bufferSize = Math.max(minBufferSize, this._bufferSize), { width, height } = bounds, sizeProperty = isVertical ? HEIGHT_PROP_NAME : WIDTH_PROP_NAME, size = isVertical ? height : width, totalLength = collection.length, typicalItemSize = itemSize, w = isVertical ? width : typicalItemSize, h = isVertical ? typicalItemSize : height, map = this._map, snapshot = this._snapshot, checkOverscrollItemsLimit = Math.ceil(size / typicalItemSize), snippedPos = Math.floor(scrollSize), leftItemsWeights = [], isFromId = fromItemId !== undefined && (typeof fromItemId === 'number' && fromItemId > -1)
954
1019
  || (typeof fromItemId === 'string' && fromItemId > '-1');
955
1020
  let leftItemsOffset = 0, rightItemsOffset = 0;
956
1021
  if (enabledBufferOptimization) {
957
1022
  switch (this.scrollDirection) {
958
1023
  case 1: {
959
1024
  leftItemsOffset = 0;
960
- rightItemsOffset = itemsOffset;
1025
+ rightItemsOffset = bufferSize;
961
1026
  break;
962
1027
  }
963
1028
  case -1: {
964
- leftItemsOffset = itemsOffset;
1029
+ leftItemsOffset = bufferSize;
965
1030
  rightItemsOffset = 0;
966
1031
  break;
967
1032
  }
968
1033
  case 0:
969
1034
  default: {
970
- leftItemsOffset = rightItemsOffset = itemsOffset;
1035
+ leftItemsOffset = rightItemsOffset = bufferSize;
971
1036
  }
972
1037
  }
973
1038
  }
974
1039
  else {
975
- leftItemsOffset = rightItemsOffset = itemsOffset;
1040
+ leftItemsOffset = rightItemsOffset = bufferSize;
976
1041
  }
977
- let itemsFromStartToScrollEnd = -1, itemsFromDisplayEndToOffsetEnd = 0, itemsFromStartToDisplayEnd = -1, leftItemLength = 0, rightItemLength = 0, leftItemsWeight = 0, rightItemsWeight = 0, leftHiddenItemsWeight = 0, totalItemsToDisplayEndWeight = 0, leftSizeOfAddedItems = 0, leftSizeOfUpdatedItems = 0, leftSizeOfDeletedItems = 0, itemById = undefined, itemByIdPos = 0, targetDisplayItemIndex = -1, isTargetInOverscroll = false, actualScrollSize = itemByIdPos, totalSize = 0, startIndex;
1042
+ let itemsFromStartToScrollEnd = -1, itemsFromDisplayEndToOffsetEnd = 0, itemsFromStartToDisplayEnd = -1, leftItemLength = 0, rightItemLength = 0, leftItemsWeight = 0, rightItemsWeight = 0, leftHiddenItemsWeight = 0, totalItemsToDisplayEndWeight = 0, leftSizeOfAddedItems = 0, leftSizeOfUpdatedItems = 0, leftSizeOfDeletedItems = 0, itemById = undefined, itemByIdPos = 0, targetDisplayItemIndex = -1, isTargetInOverscroll = false, actualScrollSize = itemByIdPos, totalSize = 0, startIndex, isFromItemIdFound = false;
978
1043
  // If the list is dynamic or there are new elements in the collection, then it switches to the long algorithm.
979
1044
  if (dynamicSize) {
980
1045
  let y = 0, stickyCollectionItem = undefined, stickyComponentSize = 0;
@@ -1014,6 +1079,7 @@ class TrackBox extends CacheMap {
1014
1079
  stickyCollectionItem = collectionItem;
1015
1080
  }
1016
1081
  if (id === fromItemId) {
1082
+ isFromItemIdFound = true;
1017
1083
  targetDisplayItemIndex = i;
1018
1084
  if (stickyCollectionItem && stickyMap) {
1019
1085
  const { num } = this.getElementNumToEnd(i, collection, map, typicalItemSize, size, isVertical);
@@ -1146,9 +1212,9 @@ class TrackBox extends CacheMap {
1146
1212
  }
1147
1213
  itemsFromStartToScrollEnd = Math.floor(scrollSize / typicalItemSize);
1148
1214
  itemsFromStartToDisplayEnd = Math.ceil((scrollSize + size) / typicalItemSize);
1149
- leftItemLength = Math.min(itemsFromStartToScrollEnd, itemsOffset);
1150
- rightItemLength = itemsFromStartToDisplayEnd + itemsOffset > totalLength
1151
- ? totalLength - itemsFromStartToDisplayEnd : itemsOffset;
1215
+ leftItemLength = Math.min(itemsFromStartToScrollEnd, bufferSize);
1216
+ rightItemLength = itemsFromStartToDisplayEnd + bufferSize > totalLength
1217
+ ? totalLength - itemsFromStartToDisplayEnd : bufferSize;
1152
1218
  leftItemsWeight = leftItemLength * typicalItemSize;
1153
1219
  rightItemsWeight = rightItemLength * typicalItemSize;
1154
1220
  leftHiddenItemsWeight = itemsFromStartToScrollEnd * typicalItemSize;
@@ -1189,6 +1255,7 @@ class TrackBox extends CacheMap {
1189
1255
  totalLength,
1190
1256
  totalSize,
1191
1257
  typicalItemSize,
1258
+ isFromItemIdFound,
1192
1259
  };
1193
1260
  return metrics;
1194
1261
  }
@@ -1389,6 +1456,7 @@ class TrackBox extends CacheMap {
1389
1456
  }
1390
1457
  dispose() {
1391
1458
  super.dispose();
1459
+ this.disposeClearBufferSizeTimer();
1392
1460
  if (this._tracker) {
1393
1461
  this._tracker.dispose();
1394
1462
  }
@@ -1609,19 +1677,49 @@ class NgVirtualListComponent {
1609
1677
  }
1610
1678
  ;
1611
1679
  get direction() { return this._$direction.getValue(); }
1612
- _$itemsOffset = new BehaviorSubject(DEFAULT_ITEMS_OFFSET);
1613
- $itemsOffset = this._$itemsOffset.asObservable();
1614
1680
  /**
1615
- * Number of elements outside the scope of visibility. Default value is 2.
1681
+ * @deprecated "itemOffset" parameter is deprecated. Use "bufferSize" and "maxBufferSize".
1616
1682
  */
1617
1683
  set itemsOffset(v) {
1618
- if (this._$itemsOffset.getValue() === v) {
1684
+ throw Error('"itemOffset" parameter is deprecated. Use "bufferSize" and "maxBufferSize".');
1685
+ }
1686
+ ;
1687
+ _$bufferSize = new BehaviorSubject(DEFAULT_BUFFER_SIZE);
1688
+ $bufferSize = this._$bufferSize.asObservable();
1689
+ /**
1690
+ * Number of elements outside the scope of visibility. Default value is 2.
1691
+ */
1692
+ set bufferSize(v) {
1693
+ if (this._$bufferSize.getValue() === v) {
1619
1694
  return;
1620
1695
  }
1621
- this._$itemsOffset.next(v);
1696
+ this._$bufferSize.next(v);
1622
1697
  }
1623
1698
  ;
1624
- get itemsOffset() { return this._$itemsOffset.getValue(); }
1699
+ get bufferSize() { return this._$bufferSize.getValue(); }
1700
+ _maxBufferSizeTransform = (v) => {
1701
+ const bufferSize = this._$bufferSize.getValue();
1702
+ if (v === undefined || v <= bufferSize) {
1703
+ return bufferSize;
1704
+ }
1705
+ return v;
1706
+ };
1707
+ _$maxBufferSize = new BehaviorSubject(DEFAULT_MAX_BUFFER_SIZE);
1708
+ $maxBufferSize = this._$maxBufferSize.asObservable();
1709
+ /**
1710
+ * Maximum number of elements outside the scope of visibility. Default value is 100.
1711
+ * If maxBufferSize is set to be greater than bufferSize, then adaptive buffer mode is enabled.
1712
+ * The greater the scroll size, the more elements are allocated for rendering.
1713
+ */
1714
+ set maxBufferSize(v) {
1715
+ const val = this._maxBufferSizeTransform(v);
1716
+ if (this._$maxBufferSize.getValue() === val) {
1717
+ return;
1718
+ }
1719
+ this._$maxBufferSize.next(val);
1720
+ }
1721
+ ;
1722
+ get maxBufferSize() { return this._$maxBufferSize.getValue(); }
1625
1723
  _$trackBy = new BehaviorSubject(TRACK_BY_PROPERTY_NAME);
1626
1724
  $trackBy = this._$trackBy.asObservable();
1627
1725
  /**
@@ -1743,7 +1841,7 @@ class NgVirtualListComponent {
1743
1841
  $trackBy.pipe(takeUntilDestroyed(), tap(v => {
1744
1842
  this._trackBox.trackingPropertyName = v;
1745
1843
  })).subscribe();
1746
- const $bounds = this._$bounds.asObservable().pipe(filter(b => !!b)), $items = this.$items.pipe(map(i => !i ? [] : i)), $scrollSize = this._$scrollSize.asObservable(), $itemSize = this.$itemSize.pipe(map(v => v <= 0 ? DEFAULT_ITEM_SIZE : v)), $itemsOffset = this.$itemsOffset.pipe(map(v => v < 0 ? DEFAULT_ITEMS_OFFSET : v)), $stickyMap = this.$stickyMap.pipe(map(v => !v ? {} : v)), $snap = this.$snap, $isVertical = this.$direction.pipe(map(v => this.getIsVertical(v || DEFAULT_DIRECTION))), $dynamicSize = this.$dynamicSize, $enabledBufferOptimization = this.$enabledBufferOptimization, $snappingMethod = this.$snappingMethod.pipe(map(v => this.getIsSnappingMethodAdvanced(v || DEFAULT_SNAPPING_METHOD))), $cacheVersion = this.$cacheVersion;
1844
+ const $bounds = this._$bounds.asObservable().pipe(filter(b => !!b)), $items = this.$items.pipe(map(i => !i ? [] : i)), $scrollSize = this._$scrollSize.asObservable(), $itemSize = this.$itemSize.pipe(map(v => v <= 0 ? DEFAULT_ITEM_SIZE : v)), $bufferSize = this.$bufferSize.pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $maxBufferSize = this.$maxBufferSize.pipe(map(v => v < 0 ? DEFAULT_MAX_BUFFER_SIZE : v)), $stickyMap = this.$stickyMap.pipe(map(v => !v ? {} : v)), $snap = this.$snap, $isVertical = this.$direction.pipe(map(v => this.getIsVertical(v || DEFAULT_DIRECTION))), $dynamicSize = this.$dynamicSize, $enabledBufferOptimization = this.$enabledBufferOptimization, $snappingMethod = this.$snappingMethod.pipe(map(v => this.getIsSnappingMethodAdvanced(v || DEFAULT_SNAPPING_METHOD))), $cacheVersion = this.$cacheVersion;
1747
1845
  $isVertical.pipe(takeUntilDestroyed(), tap(v => {
1748
1846
  this._isVertical = v;
1749
1847
  const el = this._elementRef.nativeElement;
@@ -1756,12 +1854,12 @@ class NgVirtualListComponent {
1756
1854
  this.listenCacheChangesIfNeed(dynamicSize);
1757
1855
  })).subscribe();
1758
1856
  combineLatest([this.$initialized, $bounds, $items, $stickyMap, $scrollSize, $itemSize,
1759
- $itemsOffset, $snap, $isVertical, $dynamicSize, $enabledBufferOptimization, $cacheVersion,
1760
- ]).pipe(takeUntilDestroyed(), distinctUntilChanged(), filter(([initialized]) => !!initialized), switchMap(([, bounds, items, stickyMap, scrollSize, itemSize, itemsOffset, snap, isVertical, dynamicSize, enabledBufferOptimization, cacheVersion,]) => {
1857
+ $bufferSize, $maxBufferSize, $snap, $isVertical, $dynamicSize, $enabledBufferOptimization, $cacheVersion,
1858
+ ]).pipe(takeUntilDestroyed(), distinctUntilChanged(), filter(([initialized]) => !!initialized), switchMap(([, bounds, items, stickyMap, scrollSize, itemSize, bufferSize, maxBufferSize, snap, isVertical, dynamicSize, enabledBufferOptimization, cacheVersion,]) => {
1761
1859
  let actualScrollSize = (this._isVertical ? this._container?.nativeElement.scrollTop ?? 0 : this._container?.nativeElement.scrollLeft) ?? 0;
1762
1860
  const { width, height } = bounds, opts = {
1763
1861
  bounds: { width, height }, dynamicSize, isVertical, itemSize,
1764
- itemsOffset, scrollSize: actualScrollSize, snap, enabledBufferOptimization,
1862
+ bufferSize, maxBufferSize, scrollSize: actualScrollSize, snap, enabledBufferOptimization,
1765
1863
  }, { displayItems, totalSize } = this._trackBox.updateCollection(items, stickyMap, opts);
1766
1864
  this.resetBoundsSize(isVertical, totalSize);
1767
1865
  this.createDisplayComponentsIfNeed(displayItems);
@@ -1908,9 +2006,13 @@ class NgVirtualListComponent {
1908
2006
  }
1909
2007
  const { width, height } = this._$bounds.getValue() || { width: 0, height: 0 }, stickyMap = this.stickyMap, items = this.items, isVertical = this._isVertical, delta = this._trackBox.delta, opts = {
1910
2008
  bounds: { width, height }, collection: items, dynamicSize, isVertical: this._isVertical, itemSize,
1911
- itemsOffset: this.itemsOffset, scrollSize: (isVertical ? container.nativeElement.scrollTop : container.nativeElement.scrollLeft) + delta,
2009
+ bufferSize: this.bufferSize, maxBufferSize: this.maxBufferSize, scrollSize: (isVertical ? container.nativeElement.scrollTop : container.nativeElement.scrollLeft) + delta,
1912
2010
  snap: this.snap, fromItemId: id, enabledBufferOptimization: this.enabledBufferOptimization,
1913
2011
  }, scrollSize = this._trackBox.getItemPosition(id, stickyMap, opts), params = { [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollSize, behavior };
2012
+ if (scrollSize === -1) {
2013
+ container.nativeElement.addEventListener(SCROLL, this._onScrollHandler);
2014
+ return;
2015
+ }
1914
2016
  this._trackBox.clearDelta();
1915
2017
  if (container) {
1916
2018
  const { displayItems, totalSize } = this._trackBox.updateCollection(items, stickyMap, {
@@ -1922,6 +2024,10 @@ class NgVirtualListComponent {
1922
2024
  this.createDisplayComponentsIfNeed(displayItems);
1923
2025
  this.tracking();
1924
2026
  const _scrollSize = this._trackBox.getItemPosition(id, stickyMap, { ...opts, scrollSize: actualScrollSize, fromItemId: id });
2027
+ if (_scrollSize === -1) {
2028
+ container.nativeElement.addEventListener(SCROLL, this._onScrollHandler);
2029
+ return;
2030
+ }
1925
2031
  const notChanged = actualScrollSize === _scrollSize;
1926
2032
  if (!notChanged || iteration < MAX_SCROLL_TO_ITERATIONS) {
1927
2033
  this.clearScrollToRepeatExecutionTimeout();
@@ -1938,9 +2044,12 @@ class NgVirtualListComponent {
1938
2044
  this._$scrollSize.next(scrollSize);
1939
2045
  }
1940
2046
  else {
1941
- const index = items.findIndex(item => item.id === id), scrollSize = index * this.itemSize;
1942
- const params = { [this._isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollSize, behavior };
1943
- container.nativeElement.scrollTo(params);
2047
+ const index = items.findIndex(item => item.id === id);
2048
+ if (index > -1) {
2049
+ const scrollSize = index * this.itemSize;
2050
+ const params = { [this._isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollSize, behavior };
2051
+ container.nativeElement.scrollTo(params);
2052
+ }
1944
2053
  }
1945
2054
  }
1946
2055
  }
@@ -2028,7 +2137,7 @@ class NgVirtualListComponent {
2028
2137
  }
2029
2138
  }
2030
2139
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgVirtualListComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
2031
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NgVirtualListComponent, selector: "ng-virtual-list", inputs: { items: "items", snap: "snap", enabledBufferOptimization: "enabledBufferOptimization", itemRenderer: "itemRenderer", stickyMap: "stickyMap", itemSize: "itemSize", dynamicSize: "dynamicSize", direction: "direction", itemsOffset: "itemsOffset", trackBy: "trackBy", snappingMethod: "snappingMethod" }, outputs: { onScroll: "onScroll", onScrollEnd: "onScrollEnd" }, viewQueries: [{ propertyName: "_listContainerRef", first: true, predicate: ["renderersContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_container", first: true, predicate: ["container"], descendants: true, read: (ElementRef) }, { propertyName: "_list", first: true, predicate: ["list"], descendants: true, read: (ElementRef) }, { propertyName: "_snapContainerRef", first: true, predicate: ["snapRendererContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_snappedContainer", first: true, predicate: ["snapped"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<div *ngIf=\"snap\" #snapped part=\"snapped-item\" class=\"ngvl__list-snapper\">\r\n <ng-container #snapRendererContainer></ng-container>\r\n</div>\r\n<div #container part=\"scroller\" class=\"ngvl__scroller\">\r\n <ul #list part=\"list\" class=\"ngvl__list\">\r\n <ng-container #renderersContainer></ng-container>\r\n </ul>\r\n</div>", styles: [":host{position:relative;display:block;width:400px;overflow:hidden}:host(.horizontal){height:48px}:host(.horizontal) .ngvl__list{display:inline-flex}:host(.horizontal) .ngvl__scroller{overflow:auto hidden}:host(.vertical) .ngvl__scroller{overflow:hidden auto}:host(.vertical){height:320px}.ngvl__scroller{overflow:auto;width:100%;height:100%}.ngvl__list-snapper{pointer-events:none;position:absolute;list-style:none;left:0;top:0;z-index:1}.ngvl__list{position:relative;list-style:none;padding:0;margin:0;width:100%;height:100%}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
2140
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NgVirtualListComponent, selector: "ng-virtual-list", inputs: { items: "items", snap: "snap", enabledBufferOptimization: "enabledBufferOptimization", itemRenderer: "itemRenderer", stickyMap: "stickyMap", itemSize: "itemSize", dynamicSize: "dynamicSize", direction: "direction", itemsOffset: "itemsOffset", bufferSize: "bufferSize", maxBufferSize: "maxBufferSize", trackBy: "trackBy", snappingMethod: "snappingMethod" }, outputs: { onScroll: "onScroll", onScrollEnd: "onScrollEnd" }, viewQueries: [{ propertyName: "_listContainerRef", first: true, predicate: ["renderersContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_container", first: true, predicate: ["container"], descendants: true, read: (ElementRef) }, { propertyName: "_list", first: true, predicate: ["list"], descendants: true, read: (ElementRef) }, { propertyName: "_snapContainerRef", first: true, predicate: ["snapRendererContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_snappedContainer", first: true, predicate: ["snapped"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<div *ngIf=\"snap\" #snapped part=\"snapped-item\" class=\"ngvl__list-snapper\">\r\n <ng-container #snapRendererContainer></ng-container>\r\n</div>\r\n<div #container part=\"scroller\" class=\"ngvl__scroller\">\r\n <ul #list part=\"list\" class=\"ngvl__list\">\r\n <ng-container #renderersContainer></ng-container>\r\n </ul>\r\n</div>", styles: [":host{position:relative;display:block;width:400px;overflow:hidden}:host(.horizontal){height:48px}:host(.horizontal) .ngvl__list{display:inline-flex}:host(.horizontal) .ngvl__scroller{overflow:auto hidden}:host(.vertical) .ngvl__scroller{overflow:hidden auto}:host(.vertical){height:320px}.ngvl__scroller{overflow:auto;width:100%;height:100%}.ngvl__list-snapper{pointer-events:none;position:absolute;list-style:none;left:0;top:0;z-index:1}.ngvl__list{position:relative;list-style:none;padding:0;margin:0;width:100%;height:100%}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
2032
2141
  }
2033
2142
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgVirtualListComponent, decorators: [{
2034
2143
  type: Component,
@@ -2070,6 +2179,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
2070
2179
  type: Input
2071
2180
  }], itemsOffset: [{
2072
2181
  type: Input
2182
+ }], bufferSize: [{
2183
+ type: Input
2184
+ }], maxBufferSize: [{
2185
+ type: Input
2073
2186
  }], trackBy: [{
2074
2187
  type: Input
2075
2188
  }], snappingMethod: [{