ng-virtual-list 14.3.2 → 14.4.1

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.
@@ -41,7 +41,8 @@ var SnappingMethods;
41
41
  })(SnappingMethods || (SnappingMethods = {}));
42
42
 
43
43
  const DEFAULT_ITEM_SIZE = 24;
44
- const DEFAULT_ITEMS_OFFSET = 2;
44
+ const DEFAULT_BUFFER_SIZE = 2;
45
+ const DEFAULT_MAX_BUFFER_SIZE = 100;
45
46
  const DEFAULT_LIST_SIZE = 400;
46
47
  const DEFAULT_SNAP = false;
47
48
  const DEFAULT_ENABLED_BUFFER_OPTIMIZATION = false;
@@ -210,28 +211,14 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
210
211
  }
211
212
  NgVirtualListItemComponent.__nextId = 0;
212
213
  NgVirtualListItemComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgVirtualListItemComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
213
- NgVirtualListItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: NgVirtualListItemComponent, selector: "ng-virtual-list-item", host: { classAttribute: "ngvl__item" }, usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"data\">\r\n <li #listItem part=\"item\" class=\"ngvl-item__container\" [ngClass]=\"{'snapped': data.config.snapped,\r\n 'snapped-out': data.config.snappedOut}\">\r\n <ng-container *ngIf=\"itemRenderer\">\r\n <ng-container [ngTemplateOutlet]=\"itemRenderer\"\r\n [ngTemplateOutletContext]=\"{data: data.data || {}, config: data.config}\"></ng-container>\r\n </ng-container>\r\n </li>\r\n</ng-container>", styles: [":host{display:block;position:absolute;left:0;top:0;box-sizing:border-box;overflow:hidden;will-change:scroll-position}.ngvl-item__container{margin:0;padding:0;overflow:hidden;background-color:#fff;width:inherit;height:inherit}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
214
+ NgVirtualListItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: NgVirtualListItemComponent, selector: "ng-virtual-list-item", host: { classAttribute: "ngvl__item" }, usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"data\">\r\n <li #listItem part=\"item\" class=\"ngvl-item__container\" [ngClass]=\"{'snapped': data.config.snapped,\r\n 'snapped-out': data.config.snappedOut}\">\r\n <ng-container *ngIf=\"itemRenderer\">\r\n <ng-container [ngTemplateOutlet]=\"itemRenderer\"\r\n [ngTemplateOutletContext]=\"{data: data.data || {}, config: data.config}\"></ng-container>\r\n </ng-container>\r\n </li>\r\n</ng-container>", styles: [":host{display:block;position:absolute;left:0;top:0;box-sizing:border-box;overflow:hidden}.ngvl-item__container{margin:0;padding:0;overflow:hidden;background-color:#fff;width:inherit;height:inherit}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
214
215
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgVirtualListItemComponent, decorators: [{
215
216
  type: Component,
216
217
  args: [{ selector: 'ng-virtual-list-item', host: {
217
218
  'class': 'ngvl__item',
218
- }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"data\">\r\n <li #listItem part=\"item\" class=\"ngvl-item__container\" [ngClass]=\"{'snapped': data.config.snapped,\r\n 'snapped-out': data.config.snappedOut}\">\r\n <ng-container *ngIf=\"itemRenderer\">\r\n <ng-container [ngTemplateOutlet]=\"itemRenderer\"\r\n [ngTemplateOutletContext]=\"{data: data.data || {}, config: data.config}\"></ng-container>\r\n </ng-container>\r\n </li>\r\n</ng-container>", styles: [":host{display:block;position:absolute;left:0;top:0;box-sizing:border-box;overflow:hidden;will-change:scroll-position}.ngvl-item__container{margin:0;padding:0;overflow:hidden;background-color:#fff;width:inherit;height:inherit}\n"] }]
219
+ }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"data\">\r\n <li #listItem part=\"item\" class=\"ngvl-item__container\" [ngClass]=\"{'snapped': data.config.snapped,\r\n 'snapped-out': data.config.snappedOut}\">\r\n <ng-container *ngIf=\"itemRenderer\">\r\n <ng-container [ngTemplateOutlet]=\"itemRenderer\"\r\n [ngTemplateOutletContext]=\"{data: data.data || {}, config: data.config}\"></ng-container>\r\n </ng-container>\r\n </li>\r\n</ng-container>", styles: [":host{display:block;position:absolute;left:0;top:0;box-sizing:border-box;overflow:hidden}.ngvl-item__container{margin:0;padding:0;overflow:hidden;background-color:#fff;width:inherit;height:inherit}\n"] }]
219
220
  }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }]; } });
220
221
 
221
- const HORIZONTAL_ALIASES = [Directions.HORIZONTAL, 'horizontal'], VERTICAL_ALIASES = [Directions.VERTICAL, 'vertical'];
222
- /**
223
- * Determines the axis membership of a virtual list
224
- * @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/isDirection.ts
225
- * @author Evgenii Grebennikov
226
- * @email djonnyx@gmail.com
227
- */
228
- const isDirection = (src, expected) => {
229
- if (HORIZONTAL_ALIASES.includes(expected)) {
230
- return HORIZONTAL_ALIASES.includes(src);
231
- }
232
- return VERTICAL_ALIASES.includes(src);
233
- };
234
-
235
222
  /**
236
223
  * Simple debounce function.
237
224
  * @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/debounce.ts
@@ -279,138 +266,45 @@ const toggleClassName = (el, className, removeClassName) => {
279
266
  };
280
267
 
281
268
  /**
282
- * Tracks display items by property
283
- * @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/tracker.ts
269
+ * Scroll event.
270
+ * @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/scrollEvent.ts
284
271
  * @author Evgenii Grebennikov
285
272
  * @email djonnyx@gmail.com
286
273
  */
287
- class Tracker {
288
- constructor(trackingPropertyName) {
289
- /**
290
- * display objects dictionary of indexes by id
291
- */
292
- this._displayObjectIndexMapById = {};
293
- /**
294
- * Dictionary displayItems propertyNameId by items propertyNameId
295
- */
296
- this._trackMap = {};
297
- this._trackingPropertyName = trackingPropertyName;
298
- }
299
- set displayObjectIndexMapById(v) {
300
- if (this._displayObjectIndexMapById === v) {
301
- return;
302
- }
303
- this._displayObjectIndexMapById = v;
304
- }
305
- get displayObjectIndexMapById() {
306
- return this._displayObjectIndexMapById;
307
- }
308
- get trackMap() {
309
- return this._trackMap;
310
- }
311
- set trackingPropertyName(v) {
312
- this._trackingPropertyName = v;
313
- }
314
- /**
315
- * tracking by propName
316
- */
317
- track(items, components, snapedComponent, direction) {
318
- var _a;
319
- if (!items) {
320
- return;
321
- }
322
- const idPropName = this._trackingPropertyName, untrackedItems = [...components], isDown = direction === 0 || direction === 1;
323
- let isRegularSnapped = false;
324
- for (let i = isDown ? 0 : items.length - 1, l = isDown ? items.length : 0; isDown ? i < l : i >= l; isDown ? i++ : i--) {
325
- const item = items[i], itemTrackingProperty = item[idPropName];
326
- if (this._trackMap) {
327
- if (this._trackMap.hasOwnProperty(itemTrackingProperty)) {
328
- const diId = this._trackMap[itemTrackingProperty], compIndex = this._displayObjectIndexMapById[diId], comp = components[compIndex];
329
- const compId = (_a = comp === null || comp === void 0 ? void 0 : comp.instance) === null || _a === void 0 ? void 0 : _a.id;
330
- if (comp !== undefined && compId === diId) {
331
- const indexByUntrackedItems = untrackedItems.findIndex(v => {
332
- return v.instance.id === compId;
333
- });
334
- if (indexByUntrackedItems > -1) {
335
- if (snapedComponent) {
336
- if (item['config']['snapped'] || item['config']['snappedOut']) {
337
- isRegularSnapped = true;
338
- snapedComponent.instance.item = item;
339
- snapedComponent.instance.show();
340
- }
341
- }
342
- comp.instance.item = item;
343
- if (snapedComponent) {
344
- if (item['config']['snapped'] || item['config']['snappedOut']) {
345
- comp.instance.hide();
346
- }
347
- else {
348
- comp.instance.show();
349
- }
350
- }
351
- else {
352
- comp.instance.show();
353
- }
354
- untrackedItems.splice(indexByUntrackedItems, 1);
355
- continue;
356
- }
357
- }
358
- delete this._trackMap[itemTrackingProperty];
359
- }
360
- }
361
- if (untrackedItems.length > 0) {
362
- const comp = untrackedItems.shift(), item = items[i];
363
- if (comp) {
364
- if (snapedComponent) {
365
- if (item['config']['snapped'] || item['config']['snappedOut']) {
366
- isRegularSnapped = true;
367
- snapedComponent.instance.item = item;
368
- snapedComponent.instance.show();
369
- }
370
- }
371
- comp.instance.item = item;
372
- if (snapedComponent) {
373
- if (item['config']['snapped'] || item['config']['snappedOut']) {
374
- comp.instance.hide();
375
- }
376
- else {
377
- comp.instance.show();
378
- }
379
- }
380
- else {
381
- comp.instance.show();
382
- }
383
- if (this._trackMap) {
384
- this._trackMap[itemTrackingProperty] = comp.instance.id;
385
- }
386
- }
387
- }
388
- }
389
- if (untrackedItems.length) {
390
- for (let i = 0, l = untrackedItems.length; i < l; i++) {
391
- const comp = untrackedItems[i];
392
- comp.instance.hide();
393
- }
394
- }
395
- if (!isRegularSnapped) {
396
- if (snapedComponent) {
397
- snapedComponent.instance.item = null;
398
- snapedComponent.instance.hide();
399
- }
400
- }
401
- }
402
- untrackComponentByIdProperty(component) {
403
- if (!component) {
404
- return;
405
- }
406
- const propertyIdName = this._trackingPropertyName;
407
- if (this._trackMap && component[propertyIdName] !== undefined) {
408
- delete this._trackMap[propertyIdName];
409
- }
410
- }
411
- dispose() {
412
- this._trackMap = null;
274
+ class ScrollEvent {
275
+ constructor(params) {
276
+ this._direction = 1;
277
+ this._scrollSize = 0;
278
+ this._scrollWeight = 0;
279
+ this._isVertical = true;
280
+ this._listSize = 0;
281
+ this._size = 0;
282
+ this._isStart = true;
283
+ this._isEnd = false;
284
+ this._delta = 0;
285
+ this._scrollDelta = 0;
286
+ const { direction, isVertical, container, list, delta, scrollDelta } = params;
287
+ this._direction = direction;
288
+ this._isVertical = isVertical;
289
+ this._scrollSize = isVertical ? container.scrollTop : container.scrollLeft;
290
+ this._scrollWeight = isVertical ? container.scrollHeight : container.scrollWidth;
291
+ this._listSize = isVertical ? list.offsetHeight : list.offsetWidth;
292
+ this._size = isVertical ? container.offsetHeight : container.offsetWidth;
293
+ this._isEnd = (this._scrollSize + this._size) === this._scrollWeight;
294
+ this._delta = delta;
295
+ this._scrollDelta = scrollDelta;
296
+ this._isStart = this._scrollSize === 0;
413
297
  }
298
+ get direction() { return this._direction; }
299
+ get scrollSize() { return this._scrollSize; }
300
+ get scrollWeight() { return this._scrollWeight; }
301
+ get isVertical() { return this._isVertical; }
302
+ get listSize() { return this._listSize; }
303
+ get size() { return this._size; }
304
+ get isStart() { return this._isStart; }
305
+ get isEnd() { return this._isEnd; }
306
+ get delta() { return this._delta; }
307
+ get scrollDelta() { return this._scrollDelta; }
414
308
  }
415
309
 
416
310
  /**
@@ -684,6 +578,168 @@ class CacheMap extends EventEmitter {
684
578
  }
685
579
  }
686
580
 
581
+ /**
582
+ * Tracks display items by property
583
+ * @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/tracker.ts
584
+ * @author Evgenii Grebennikov
585
+ * @email djonnyx@gmail.com
586
+ */
587
+ class Tracker {
588
+ constructor(trackingPropertyName) {
589
+ /**
590
+ * display objects dictionary of indexes by id
591
+ */
592
+ this._displayObjectIndexMapById = {};
593
+ /**
594
+ * Dictionary displayItems propertyNameId by items propertyNameId
595
+ */
596
+ this._trackMap = {};
597
+ this._trackingPropertyName = trackingPropertyName;
598
+ }
599
+ set displayObjectIndexMapById(v) {
600
+ if (this._displayObjectIndexMapById === v) {
601
+ return;
602
+ }
603
+ this._displayObjectIndexMapById = v;
604
+ }
605
+ get displayObjectIndexMapById() {
606
+ return this._displayObjectIndexMapById;
607
+ }
608
+ get trackMap() {
609
+ return this._trackMap;
610
+ }
611
+ set trackingPropertyName(v) {
612
+ this._trackingPropertyName = v;
613
+ }
614
+ /**
615
+ * tracking by propName
616
+ */
617
+ track(items, components, snapedComponent, direction) {
618
+ var _a;
619
+ if (!items) {
620
+ return;
621
+ }
622
+ const idPropName = this._trackingPropertyName, untrackedItems = [...components], isDown = direction === 0 || direction === 1;
623
+ let isRegularSnapped = false;
624
+ for (let i = isDown ? 0 : items.length - 1, l = isDown ? items.length : 0; isDown ? i < l : i >= l; isDown ? i++ : i--) {
625
+ const item = items[i], itemTrackingProperty = item[idPropName];
626
+ if (this._trackMap) {
627
+ if (this._trackMap.hasOwnProperty(itemTrackingProperty)) {
628
+ const diId = this._trackMap[itemTrackingProperty], compIndex = this._displayObjectIndexMapById[diId], comp = components[compIndex];
629
+ const compId = (_a = comp === null || comp === void 0 ? void 0 : comp.instance) === null || _a === void 0 ? void 0 : _a.id;
630
+ if (comp !== undefined && compId === diId) {
631
+ const indexByUntrackedItems = untrackedItems.findIndex(v => {
632
+ return v.instance.id === compId;
633
+ });
634
+ if (indexByUntrackedItems > -1) {
635
+ if (snapedComponent) {
636
+ if (item['config']['snapped'] || item['config']['snappedOut']) {
637
+ isRegularSnapped = true;
638
+ snapedComponent.instance.item = item;
639
+ snapedComponent.instance.show();
640
+ }
641
+ }
642
+ comp.instance.item = item;
643
+ if (snapedComponent) {
644
+ if (item['config']['snapped'] || item['config']['snappedOut']) {
645
+ comp.instance.hide();
646
+ }
647
+ else {
648
+ comp.instance.show();
649
+ }
650
+ }
651
+ else {
652
+ comp.instance.show();
653
+ }
654
+ untrackedItems.splice(indexByUntrackedItems, 1);
655
+ continue;
656
+ }
657
+ }
658
+ delete this._trackMap[itemTrackingProperty];
659
+ }
660
+ }
661
+ if (untrackedItems.length > 0) {
662
+ const comp = untrackedItems.shift(), item = items[i];
663
+ if (comp) {
664
+ if (snapedComponent) {
665
+ if (item['config']['snapped'] || item['config']['snappedOut']) {
666
+ isRegularSnapped = true;
667
+ snapedComponent.instance.item = item;
668
+ snapedComponent.instance.show();
669
+ }
670
+ }
671
+ comp.instance.item = item;
672
+ if (snapedComponent) {
673
+ if (item['config']['snapped'] || item['config']['snappedOut']) {
674
+ comp.instance.hide();
675
+ }
676
+ else {
677
+ comp.instance.show();
678
+ }
679
+ }
680
+ else {
681
+ comp.instance.show();
682
+ }
683
+ if (this._trackMap) {
684
+ this._trackMap[itemTrackingProperty] = comp.instance.id;
685
+ }
686
+ }
687
+ }
688
+ }
689
+ if (untrackedItems.length) {
690
+ for (let i = 0, l = untrackedItems.length; i < l; i++) {
691
+ const comp = untrackedItems[i];
692
+ comp.instance.hide();
693
+ }
694
+ }
695
+ if (!isRegularSnapped) {
696
+ if (snapedComponent) {
697
+ snapedComponent.instance.item = null;
698
+ snapedComponent.instance.hide();
699
+ }
700
+ }
701
+ }
702
+ untrackComponentByIdProperty(component) {
703
+ if (!component) {
704
+ return;
705
+ }
706
+ const propertyIdName = this._trackingPropertyName;
707
+ if (this._trackMap && component[propertyIdName] !== undefined) {
708
+ delete this._trackMap[propertyIdName];
709
+ }
710
+ }
711
+ dispose() {
712
+ this._trackMap = null;
713
+ }
714
+ }
715
+
716
+ const DEFAULT_EXTRA = {
717
+ extremumThreshold: 2,
718
+ bufferSize: 10,
719
+ };
720
+ const bufferInterpolation = (currentBufferValue, array, value, extra) => {
721
+ const { extremumThreshold = DEFAULT_EXTRA.extremumThreshold, bufferSize = DEFAULT_EXTRA.bufferSize, } = extra !== null && extra !== void 0 ? extra : DEFAULT_EXTRA;
722
+ if (currentBufferValue < value) {
723
+ let i = 0;
724
+ while (i < extremumThreshold) {
725
+ array.push(value);
726
+ i++;
727
+ }
728
+ }
729
+ else {
730
+ array.push(value);
731
+ }
732
+ while (array.length >= bufferSize) {
733
+ array.shift();
734
+ }
735
+ const l = array.length;
736
+ let buffer = 0;
737
+ for (let i = 0; i < l; i++) {
738
+ buffer += array[i];
739
+ }
740
+ return Math.ceil(buffer / l);
741
+ };
742
+
687
743
  const TRACK_BOX_CHANGE_EVENT_NAME = 'change';
688
744
  var ItemDisplayMethods;
689
745
  (function (ItemDisplayMethods) {
@@ -692,6 +748,7 @@ var ItemDisplayMethods;
692
748
  ItemDisplayMethods[ItemDisplayMethods["DELETE"] = 2] = "DELETE";
693
749
  ItemDisplayMethods[ItemDisplayMethods["NOT_CHANGED"] = 3] = "NOT_CHANGED";
694
750
  })(ItemDisplayMethods || (ItemDisplayMethods = {}));
751
+ const DEFAULT_BUFFER_EXTREMUM_THRESHOLD = 15, DEFAULT_MAX_BUFFER_SEQUENCE_LENGTH = 30, DEFAULT_RESET_BUFFER_SIZE_TIMEOUT = 10000;
695
752
  /**
696
753
  * An object that performs tracking, calculations and caching.
697
754
  * @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/trackBox.ts
@@ -702,11 +759,22 @@ class TrackBox extends CacheMap {
702
759
  constructor(trackingPropertyName) {
703
760
  super();
704
761
  this._isSnappingMethodAdvanced = false;
762
+ this._trackingPropertyName = TRACK_BY_PROPERTY_NAME;
705
763
  this._deletedItemsMap = {};
706
764
  this._crudDetected = false;
707
765
  this._previousTotalSize = 0;
708
766
  this._scrollDelta = 0;
709
- this._tracker = new Tracker(trackingPropertyName);
767
+ this.isAdaptiveBuffer = true;
768
+ this._bufferSequenceExtraThreshold = DEFAULT_BUFFER_EXTREMUM_THRESHOLD;
769
+ this._maxBufferSequenceLength = DEFAULT_MAX_BUFFER_SEQUENCE_LENGTH;
770
+ this._bufferSizeSequence = [];
771
+ this._bufferSize = 0;
772
+ this._defaultBufferSize = 0;
773
+ this._maxBufferSize = this._defaultBufferSize;
774
+ this._resetBufferSizeTimeout = DEFAULT_RESET_BUFFER_SIZE_TIMEOUT;
775
+ this._previousScrollSize = 0;
776
+ this._trackingPropertyName = trackingPropertyName;
777
+ this.initialize();
710
778
  }
711
779
  set items(v) {
712
780
  if (this._items === v) {
@@ -736,7 +804,10 @@ class TrackBox extends CacheMap {
736
804
  * Set the trackBy property
737
805
  */
738
806
  set trackingPropertyName(v) {
739
- this._tracker.trackingPropertyName = v;
807
+ this._trackingPropertyName = this._tracker.trackingPropertyName = v;
808
+ }
809
+ initialize() {
810
+ this._tracker = new Tracker(this._trackingPropertyName);
740
811
  }
741
812
  set(id, bounds) {
742
813
  if (this._map.has(id)) {
@@ -756,6 +827,7 @@ class TrackBox extends CacheMap {
756
827
  }
757
828
  }
758
829
  get scrollDelta() { return this._scrollDelta; }
830
+ get bufferSize() { return this._bufferSize; }
759
831
  lifeCircle() {
760
832
  this.fireChangeIfNeed();
761
833
  this.lifeCircleDo();
@@ -849,6 +921,8 @@ class TrackBox extends CacheMap {
849
921
  */
850
922
  getItemPosition(id, stickyMap, options) {
851
923
  const opt = Object.assign({ fromItemId: id, stickyMap }, options);
924
+ this._defaultBufferSize = opt.bufferSize;
925
+ this._maxBufferSize = opt.maxBufferSize;
852
926
  const { scrollSize, isFromItemIdFound } = this.recalculateMetrics(Object.assign(Object.assign({}, opt), { dynamicSize: this._crudDetected || opt.dynamicSize, previousTotalSize: this._previousTotalSize, crudDetected: this._crudDetected, deletedItemsMap: this._deletedItemsMap }));
853
927
  return isFromItemIdFound ? scrollSize : -1;
854
928
  }
@@ -860,8 +934,11 @@ class TrackBox extends CacheMap {
860
934
  if (opt.dynamicSize) {
861
935
  this.cacheElements();
862
936
  }
937
+ this._defaultBufferSize = opt.bufferSize;
938
+ this._maxBufferSize = opt.maxBufferSize;
863
939
  const metrics = this.recalculateMetrics(Object.assign(Object.assign({}, opt), { collection: items, previousTotalSize: this._previousTotalSize, crudDetected: this._crudDetected, deletedItemsMap }));
864
940
  this._delta += metrics.delta;
941
+ this.updateAdaptiveBufferParams(metrics, items.length);
865
942
  this._previousTotalSize = metrics.totalSize;
866
943
  this._deletedItemsMap = {};
867
944
  this._crudDetected = false;
@@ -877,6 +954,26 @@ class TrackBox extends CacheMap {
877
954
  getNearestItem(scrollSize, items, itemSize, isVertical) {
878
955
  return this.getElementFromStart(scrollSize, items, this._map, itemSize, isVertical);
879
956
  }
957
+ updateAdaptiveBufferParams(metrics, totalItemsLength) {
958
+ this.disposeClearBufferSizeTimer();
959
+ const scrollSize = metrics.scrollSize + this._delta, delta = Math.abs(this._previousScrollSize - scrollSize);
960
+ this._previousScrollSize = scrollSize;
961
+ 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;
962
+ this._bufferSize = bufferInterpolation(this._bufferSize, this._bufferSizeSequence, bufferValue, {
963
+ extremumThreshold: this._bufferSequenceExtraThreshold,
964
+ bufferSize: this._maxBufferSequenceLength,
965
+ });
966
+ this.startResetBufferSizeTimer();
967
+ }
968
+ startResetBufferSizeTimer() {
969
+ this._resetBufferSizeTimer = setTimeout(() => {
970
+ this._bufferSize = this._defaultBufferSize;
971
+ this._bufferSizeSequence = [];
972
+ }, this._resetBufferSizeTimeout);
973
+ }
974
+ disposeClearBufferSizeTimer() {
975
+ clearTimeout(this._resetBufferSizeTimer);
976
+ }
880
977
  /**
881
978
  * Calculates the position of an element based on the given scrollSize
882
979
  */
@@ -929,30 +1026,30 @@ class TrackBox extends CacheMap {
929
1026
  */
930
1027
  recalculateMetrics(options) {
931
1028
  var _a, _b, _c, _d;
932
- const { fromItemId, bounds, collection, dynamicSize, isVertical, itemSize, itemsOffset, scrollSize, snap, stickyMap, enabledBufferOptimization, previousTotalSize, crudDetected, deletedItemsMap } = options;
933
- 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)
1029
+ const { fromItemId, bounds, collection, dynamicSize, isVertical, itemSize, bufferSize: minBufferSize, scrollSize, snap, stickyMap, enabledBufferOptimization, previousTotalSize, crudDetected, deletedItemsMap } = options;
1030
+ 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)
934
1031
  || (typeof fromItemId === 'string' && fromItemId > '-1');
935
1032
  let leftItemsOffset = 0, rightItemsOffset = 0;
936
1033
  if (enabledBufferOptimization) {
937
1034
  switch (this.scrollDirection) {
938
1035
  case 1: {
939
1036
  leftItemsOffset = 0;
940
- rightItemsOffset = itemsOffset;
1037
+ rightItemsOffset = bufferSize;
941
1038
  break;
942
1039
  }
943
1040
  case -1: {
944
- leftItemsOffset = itemsOffset;
1041
+ leftItemsOffset = bufferSize;
945
1042
  rightItemsOffset = 0;
946
1043
  break;
947
1044
  }
948
1045
  case 0:
949
1046
  default: {
950
- leftItemsOffset = rightItemsOffset = itemsOffset;
1047
+ leftItemsOffset = rightItemsOffset = bufferSize;
951
1048
  }
952
1049
  }
953
1050
  }
954
1051
  else {
955
- leftItemsOffset = rightItemsOffset = itemsOffset;
1052
+ leftItemsOffset = rightItemsOffset = bufferSize;
956
1053
  }
957
1054
  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;
958
1055
  // If the list is dynamic or there are new elements in the collection, then it switches to the long algorithm.
@@ -1127,9 +1224,9 @@ class TrackBox extends CacheMap {
1127
1224
  }
1128
1225
  itemsFromStartToScrollEnd = Math.floor(scrollSize / typicalItemSize);
1129
1226
  itemsFromStartToDisplayEnd = Math.ceil((scrollSize + size) / typicalItemSize);
1130
- leftItemLength = Math.min(itemsFromStartToScrollEnd, itemsOffset);
1131
- rightItemLength = itemsFromStartToDisplayEnd + itemsOffset > totalLength
1132
- ? totalLength - itemsFromStartToDisplayEnd : itemsOffset;
1227
+ leftItemLength = Math.min(itemsFromStartToScrollEnd, bufferSize);
1228
+ rightItemLength = itemsFromStartToDisplayEnd + bufferSize > totalLength
1229
+ ? totalLength - itemsFromStartToDisplayEnd : bufferSize;
1133
1230
  leftItemsWeight = leftItemLength * typicalItemSize;
1134
1231
  rightItemsWeight = rightItemLength * typicalItemSize;
1135
1232
  leftHiddenItemsWeight = itemsFromStartToScrollEnd * typicalItemSize;
@@ -1227,6 +1324,9 @@ class TrackBox extends CacheMap {
1227
1324
  if (snap) {
1228
1325
  const startIndex = itemsFromStartToScrollEnd + itemsOnDisplayLength - 1;
1229
1326
  for (let i = Math.min(startIndex, totalLength > 0 ? totalLength - 1 : 0), l = totalLength; i < l; i++) {
1327
+ if (!items[i]) {
1328
+ continue;
1329
+ }
1230
1330
  const id = items[i].id, sticky = stickyMap[id], size = dynamicSize
1231
1331
  ? ((_b = this.get(id)) === null || _b === void 0 ? void 0 : _b[sizeProperty]) || typicalItemSize
1232
1332
  : typicalItemSize;
@@ -1261,6 +1361,9 @@ class TrackBox extends CacheMap {
1261
1361
  if (i >= totalLength) {
1262
1362
  break;
1263
1363
  }
1364
+ if (!items[i]) {
1365
+ continue;
1366
+ }
1264
1367
  const id = items[i].id, size = dynamicSize ? ((_c = this.get(id)) === null || _c === void 0 ? void 0 : _c[sizeProperty]) || typicalItemSize : typicalItemSize;
1265
1368
  if (id !== (stickyItem === null || stickyItem === void 0 ? void 0 : stickyItem.id) && id !== (endStickyItem === null || endStickyItem === void 0 ? void 0 : endStickyItem.id)) {
1266
1369
  const snapped = snap && (stickyMap[id] === 1 && pos <= scrollSize || stickyMap[id] === 2 && pos >= scrollSize + boundsSize - size), measures = {
@@ -1372,54 +1475,13 @@ class TrackBox extends CacheMap {
1372
1475
  }
1373
1476
  dispose() {
1374
1477
  super.dispose();
1478
+ this.disposeClearBufferSizeTimer();
1375
1479
  if (this._tracker) {
1376
1480
  this._tracker.dispose();
1377
1481
  }
1378
1482
  }
1379
1483
  }
1380
1484
 
1381
- /**
1382
- * Scroll event.
1383
- * @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/scrollEvent.ts
1384
- * @author Evgenii Grebennikov
1385
- * @email djonnyx@gmail.com
1386
- */
1387
- class ScrollEvent {
1388
- constructor(params) {
1389
- this._direction = 1;
1390
- this._scrollSize = 0;
1391
- this._scrollWeight = 0;
1392
- this._isVertical = true;
1393
- this._listSize = 0;
1394
- this._size = 0;
1395
- this._isStart = true;
1396
- this._isEnd = false;
1397
- this._delta = 0;
1398
- this._scrollDelta = 0;
1399
- const { direction, isVertical, container, list, delta, scrollDelta } = params;
1400
- this._direction = direction;
1401
- this._isVertical = isVertical;
1402
- this._scrollSize = isVertical ? container.scrollTop : container.scrollLeft;
1403
- this._scrollWeight = isVertical ? container.scrollHeight : container.scrollWidth;
1404
- this._listSize = isVertical ? list.offsetHeight : list.offsetWidth;
1405
- this._size = isVertical ? container.offsetHeight : container.offsetWidth;
1406
- this._isEnd = (this._scrollSize + this._size) === this._scrollWeight;
1407
- this._delta = delta;
1408
- this._scrollDelta = scrollDelta;
1409
- this._isStart = this._scrollSize === 0;
1410
- }
1411
- get direction() { return this._direction; }
1412
- get scrollSize() { return this._scrollSize; }
1413
- get scrollWeight() { return this._scrollWeight; }
1414
- get isVertical() { return this._isVertical; }
1415
- get listSize() { return this._listSize; }
1416
- get size() { return this._size; }
1417
- get isStart() { return this._isStart; }
1418
- get isEnd() { return this._isEnd; }
1419
- get delta() { return this._delta; }
1420
- get scrollDelta() { return this._scrollDelta; }
1421
- }
1422
-
1423
1485
  /**
1424
1486
  * Base disposable component
1425
1487
  * @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/disposableComponent.ts
@@ -1457,6 +1519,20 @@ const isSnappingMethodDefault = (method) => {
1457
1519
  const IS_FIREFOX = navigator.userAgent.toLowerCase().includes('firefox');
1458
1520
  const FIREFOX_SCROLLBAR_OVERLAP_SIZE = 12;
1459
1521
 
1522
+ const HORIZONTAL_ALIASES = [Directions.HORIZONTAL, 'horizontal'], VERTICAL_ALIASES = [Directions.VERTICAL, 'vertical'];
1523
+ /**
1524
+ * Determines the axis membership of a virtual list
1525
+ * @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/isDirection.ts
1526
+ * @author Evgenii Grebennikov
1527
+ * @email djonnyx@gmail.com
1528
+ */
1529
+ const isDirection = (src, expected) => {
1530
+ if (HORIZONTAL_ALIASES.includes(expected)) {
1531
+ return HORIZONTAL_ALIASES.includes(src);
1532
+ }
1533
+ return VERTICAL_ALIASES.includes(src);
1534
+ };
1535
+
1460
1536
  /**
1461
1537
  * Virtual list component.
1462
1538
  * Maximum performance for extremely large lists.
@@ -1507,8 +1583,17 @@ class NgVirtualListComponent extends DisposableComponent {
1507
1583
  this.$dynamicSize = this._$dynamicSize.asObservable();
1508
1584
  this._$direction = new BehaviorSubject(DEFAULT_DIRECTION);
1509
1585
  this.$direction = this._$direction.asObservable();
1510
- this._$itemsOffset = new BehaviorSubject(DEFAULT_ITEMS_OFFSET);
1511
- this.$itemsOffset = this._$itemsOffset.asObservable();
1586
+ this._$bufferSize = new BehaviorSubject(DEFAULT_BUFFER_SIZE);
1587
+ this.$bufferSize = this._$bufferSize.asObservable();
1588
+ this._maxBufferSizeTransform = (v) => {
1589
+ const bufferSize = this._$bufferSize.getValue();
1590
+ if (v === undefined || v <= bufferSize) {
1591
+ return bufferSize;
1592
+ }
1593
+ return v;
1594
+ };
1595
+ this._$maxBufferSize = new BehaviorSubject(DEFAULT_MAX_BUFFER_SIZE);
1596
+ this.$maxBufferSize = this._$maxBufferSize.asObservable();
1512
1597
  this._$trackBy = new BehaviorSubject(TRACK_BY_PROPERTY_NAME);
1513
1598
  this.$trackBy = this._$trackBy.asObservable();
1514
1599
  this._isVertical = this.getIsVertical();
@@ -1631,7 +1716,7 @@ class NgVirtualListComponent extends DisposableComponent {
1631
1716
  $trackBy.pipe(takeUntil(this._$unsubscribe), tap(v => {
1632
1717
  this._trackBox.trackingPropertyName = v;
1633
1718
  })).subscribe();
1634
- 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;
1719
+ 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;
1635
1720
  $isVertical.pipe(takeUntil(this._$unsubscribe), tap(v => {
1636
1721
  this._isVertical = v;
1637
1722
  const el = this._elementRef.nativeElement;
@@ -1644,13 +1729,13 @@ class NgVirtualListComponent extends DisposableComponent {
1644
1729
  this.listenCacheChangesIfNeed(dynamicSize);
1645
1730
  })).subscribe();
1646
1731
  combineLatest([this.$initialized, $bounds, $items, $stickyMap, $scrollSize, $itemSize,
1647
- $itemsOffset, $snap, $isVertical, $dynamicSize, $enabledBufferOptimization, $cacheVersion,
1648
- ]).pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), filter(([initialized]) => !!initialized), switchMap(([, bounds, items, stickyMap, scrollSize, itemSize, itemsOffset, snap, isVertical, dynamicSize, enabledBufferOptimization, cacheVersion,]) => {
1732
+ $bufferSize, $maxBufferSize, $snap, $isVertical, $dynamicSize, $enabledBufferOptimization, $cacheVersion,
1733
+ ]).pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), filter(([initialized]) => !!initialized), switchMap(([, bounds, items, stickyMap, scrollSize, itemSize, bufferSize, maxBufferSize, snap, isVertical, dynamicSize, enabledBufferOptimization, cacheVersion,]) => {
1649
1734
  var _a, _b, _c, _d;
1650
1735
  let actualScrollSize = (_d = (this._isVertical ? (_b = (_a = this._container) === null || _a === void 0 ? void 0 : _a.nativeElement.scrollTop) !== null && _b !== void 0 ? _b : 0 : (_c = this._container) === null || _c === void 0 ? void 0 : _c.nativeElement.scrollLeft)) !== null && _d !== void 0 ? _d : 0;
1651
1736
  const { width, height } = bounds, opts = {
1652
1737
  bounds: { width, height }, dynamicSize, isVertical, itemSize,
1653
- itemsOffset, scrollSize: actualScrollSize, snap, enabledBufferOptimization,
1738
+ bufferSize, maxBufferSize, scrollSize: actualScrollSize, snap, enabledBufferOptimization,
1654
1739
  }, { displayItems, totalSize } = this._trackBox.updateCollection(items, stickyMap, opts);
1655
1740
  this.resetBoundsSize(isVertical, totalSize);
1656
1741
  this.createDisplayComponentsIfNeed(displayItems);
@@ -1673,7 +1758,10 @@ class NgVirtualListComponent extends DisposableComponent {
1673
1758
  }
1674
1759
  return of(displayItems);
1675
1760
  })).subscribe();
1676
- this.setupRenderer();
1761
+ const $itemRenderer = this.$itemRenderer;
1762
+ $itemRenderer.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), filter(v => !!v), tap(v => {
1763
+ this._$renderer.next(v);
1764
+ })).subscribe();
1677
1765
  }
1678
1766
  /**
1679
1767
  * Readonly. Returns the unique identifier of the component.
@@ -1783,16 +1871,37 @@ class NgVirtualListComponent extends DisposableComponent {
1783
1871
  ;
1784
1872
  get direction() { return this._$direction.getValue(); }
1785
1873
  /**
1786
- * Number of elements outside the scope of visibility. Default value is 2.
1874
+ * @deprecated "itemOffset" parameter is deprecated. Use "bufferSize" and "maxBufferSize".
1787
1875
  */
1788
1876
  set itemsOffset(v) {
1789
- if (this._$itemsOffset.getValue() === v) {
1877
+ throw Error('"itemOffset" parameter is deprecated. Use "bufferSize" and "maxBufferSize".');
1878
+ }
1879
+ ;
1880
+ /**
1881
+ * Number of elements outside the scope of visibility. Default value is 2.
1882
+ */
1883
+ set bufferSize(v) {
1884
+ if (this._$bufferSize.getValue() === v) {
1790
1885
  return;
1791
1886
  }
1792
- this._$itemsOffset.next(v);
1887
+ this._$bufferSize.next(v);
1793
1888
  }
1794
1889
  ;
1795
- get itemsOffset() { return this._$itemsOffset.getValue(); }
1890
+ get bufferSize() { return this._$bufferSize.getValue(); }
1891
+ /**
1892
+ * Maximum number of elements outside the scope of visibility. Default value is 100.
1893
+ * If maxBufferSize is set to be greater than bufferSize, then adaptive buffer mode is enabled.
1894
+ * The greater the scroll size, the more elements are allocated for rendering.
1895
+ */
1896
+ set maxBufferSize(v) {
1897
+ const val = this._maxBufferSizeTransform(v);
1898
+ if (this._$maxBufferSize.getValue() === val) {
1899
+ return;
1900
+ }
1901
+ this._$maxBufferSize.next(val);
1902
+ }
1903
+ ;
1904
+ get maxBufferSize() { return this._$maxBufferSize.getValue(); }
1796
1905
  /**
1797
1906
  * The name of the property by which tracking is performed
1798
1907
  */
@@ -1819,12 +1928,6 @@ class NgVirtualListComponent extends DisposableComponent {
1819
1928
  get snappingMethod() { return this._$snappingMethod.getValue(); }
1820
1929
  get isSnappingMethodAdvanced() { return this._isSnappingMethodAdvanced; }
1821
1930
  get $cacheVersion() { return this._$cacheVersion.asObservable(); }
1822
- setupRenderer() {
1823
- const $itemRenderer = this.$itemRenderer;
1824
- $itemRenderer.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), filter(v => !!v), tap(v => {
1825
- this._$renderer.next(v);
1826
- })).subscribe();
1827
- }
1828
1931
  /** @internal */
1829
1932
  ngOnInit() {
1830
1933
  this.onInit();
@@ -1937,7 +2040,7 @@ class NgVirtualListComponent extends DisposableComponent {
1937
2040
  }
1938
2041
  const { width, height } = this._$bounds.getValue() || { width: 0, height: 0 }, stickyMap = this.stickyMap, items = this.items, isVertical = this._isVertical, delta = this._trackBox.delta, opts = {
1939
2042
  bounds: { width, height }, collection: items, dynamicSize, isVertical: this._isVertical, itemSize,
1940
- itemsOffset: this.itemsOffset, scrollSize: (isVertical ? container.nativeElement.scrollTop : container.nativeElement.scrollLeft) + delta,
2043
+ bufferSize: this.bufferSize, maxBufferSize: this.maxBufferSize, scrollSize: (isVertical ? container.nativeElement.scrollTop : container.nativeElement.scrollLeft) + delta,
1941
2044
  snap: this.snap, fromItemId: id, enabledBufferOptimization: this.enabledBufferOptimization,
1942
2045
  }, scrollSize = this._trackBox.getItemPosition(id, stickyMap, opts), params = { [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollSize, behavior };
1943
2046
  if (scrollSize === -1) {
@@ -2043,7 +2146,7 @@ class NgVirtualListComponent extends DisposableComponent {
2043
2146
  }
2044
2147
  NgVirtualListComponent.__nextId = 0;
2045
2148
  NgVirtualListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgVirtualListComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
2046
- NgVirtualListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", 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 }], usesInheritance: true, 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 });
2149
+ NgVirtualListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", 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 }], usesInheritance: true, 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 });
2047
2150
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgVirtualListComponent, decorators: [{
2048
2151
  type: Component,
2049
2152
  args: [{ selector: 'ng-virtual-list', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, 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"] }]
@@ -2084,6 +2187,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
2084
2187
  type: Input
2085
2188
  }], itemsOffset: [{
2086
2189
  type: Input
2190
+ }], bufferSize: [{
2191
+ type: Input
2192
+ }], maxBufferSize: [{
2193
+ type: Input
2087
2194
  }], trackBy: [{
2088
2195
  type: Input
2089
2196
  }], snappingMethod: [{
@@ -2113,5 +2220,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
2113
2220
  * Generated bundle index. Do not edit.
2114
2221
  */
2115
2222
 
2116
- export { BaseVirtualListItemComponent, Directions, NgVirtualListComponent, NgVirtualListItemComponent, NgVirtualListModule, SnappingMethods };
2223
+ export { Directions, NgVirtualListComponent, NgVirtualListItemComponent, NgVirtualListModule, SnappingMethods };
2117
2224
  //# sourceMappingURL=ng-virtual-list.mjs.map