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;
@@ -208,28 +209,14 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
208
209
  }
209
210
  NgVirtualListItemComponent.__nextId = 0;
210
211
  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 });
211
- 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 });
212
+ 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 });
212
213
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgVirtualListItemComponent, decorators: [{
213
214
  type: Component,
214
215
  args: [{ selector: 'ng-virtual-list-item', host: {
215
216
  'class': 'ngvl__item',
216
- }, 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"] }]
217
+ }, 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"] }]
217
218
  }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }]; } });
218
219
 
219
- const HORIZONTAL_ALIASES = [Directions.HORIZONTAL, 'horizontal'], VERTICAL_ALIASES = [Directions.VERTICAL, 'vertical'];
220
- /**
221
- * Determines the axis membership of a virtual list
222
- * @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/isDirection.ts
223
- * @author Evgenii Grebennikov
224
- * @email djonnyx@gmail.com
225
- */
226
- const isDirection = (src, expected) => {
227
- if (HORIZONTAL_ALIASES.includes(expected)) {
228
- return HORIZONTAL_ALIASES.includes(src);
229
- }
230
- return VERTICAL_ALIASES.includes(src);
231
- };
232
-
233
220
  /**
234
221
  * Simple debounce function.
235
222
  * @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/debounce.ts
@@ -277,137 +264,45 @@ const toggleClassName = (el, className, removeClassName) => {
277
264
  };
278
265
 
279
266
  /**
280
- * Tracks display items by property
281
- * @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/tracker.ts
267
+ * Scroll event.
268
+ * @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/scrollEvent.ts
282
269
  * @author Evgenii Grebennikov
283
270
  * @email djonnyx@gmail.com
284
271
  */
285
- class Tracker {
286
- constructor(trackingPropertyName) {
287
- /**
288
- * display objects dictionary of indexes by id
289
- */
290
- this._displayObjectIndexMapById = {};
291
- /**
292
- * Dictionary displayItems propertyNameId by items propertyNameId
293
- */
294
- this._trackMap = {};
295
- this._trackingPropertyName = trackingPropertyName;
296
- }
297
- set displayObjectIndexMapById(v) {
298
- if (this._displayObjectIndexMapById === v) {
299
- return;
300
- }
301
- this._displayObjectIndexMapById = v;
302
- }
303
- get displayObjectIndexMapById() {
304
- return this._displayObjectIndexMapById;
305
- }
306
- get trackMap() {
307
- return this._trackMap;
308
- }
309
- set trackingPropertyName(v) {
310
- this._trackingPropertyName = v;
311
- }
312
- /**
313
- * tracking by propName
314
- */
315
- track(items, components, snapedComponent, direction) {
316
- if (!items) {
317
- return;
318
- }
319
- const idPropName = this._trackingPropertyName, untrackedItems = [...components], isDown = direction === 0 || direction === 1;
320
- let isRegularSnapped = false;
321
- for (let i = isDown ? 0 : items.length - 1, l = isDown ? items.length : 0; isDown ? i < l : i >= l; isDown ? i++ : i--) {
322
- const item = items[i], itemTrackingProperty = item[idPropName];
323
- if (this._trackMap) {
324
- if (this._trackMap.hasOwnProperty(itemTrackingProperty)) {
325
- const diId = this._trackMap[itemTrackingProperty], compIndex = this._displayObjectIndexMapById[diId], comp = components[compIndex];
326
- const compId = comp?.instance?.id;
327
- if (comp !== undefined && compId === diId) {
328
- const indexByUntrackedItems = untrackedItems.findIndex(v => {
329
- return v.instance.id === compId;
330
- });
331
- if (indexByUntrackedItems > -1) {
332
- if (snapedComponent) {
333
- if (item['config']['snapped'] || item['config']['snappedOut']) {
334
- isRegularSnapped = true;
335
- snapedComponent.instance.item = item;
336
- snapedComponent.instance.show();
337
- }
338
- }
339
- comp.instance.item = item;
340
- if (snapedComponent) {
341
- if (item['config']['snapped'] || item['config']['snappedOut']) {
342
- comp.instance.hide();
343
- }
344
- else {
345
- comp.instance.show();
346
- }
347
- }
348
- else {
349
- comp.instance.show();
350
- }
351
- untrackedItems.splice(indexByUntrackedItems, 1);
352
- continue;
353
- }
354
- }
355
- delete this._trackMap[itemTrackingProperty];
356
- }
357
- }
358
- if (untrackedItems.length > 0) {
359
- const comp = untrackedItems.shift(), item = items[i];
360
- if (comp) {
361
- if (snapedComponent) {
362
- if (item['config']['snapped'] || item['config']['snappedOut']) {
363
- isRegularSnapped = true;
364
- snapedComponent.instance.item = item;
365
- snapedComponent.instance.show();
366
- }
367
- }
368
- comp.instance.item = item;
369
- if (snapedComponent) {
370
- if (item['config']['snapped'] || item['config']['snappedOut']) {
371
- comp.instance.hide();
372
- }
373
- else {
374
- comp.instance.show();
375
- }
376
- }
377
- else {
378
- comp.instance.show();
379
- }
380
- if (this._trackMap) {
381
- this._trackMap[itemTrackingProperty] = comp.instance.id;
382
- }
383
- }
384
- }
385
- }
386
- if (untrackedItems.length) {
387
- for (let i = 0, l = untrackedItems.length; i < l; i++) {
388
- const comp = untrackedItems[i];
389
- comp.instance.hide();
390
- }
391
- }
392
- if (!isRegularSnapped) {
393
- if (snapedComponent) {
394
- snapedComponent.instance.item = null;
395
- snapedComponent.instance.hide();
396
- }
397
- }
398
- }
399
- untrackComponentByIdProperty(component) {
400
- if (!component) {
401
- return;
402
- }
403
- const propertyIdName = this._trackingPropertyName;
404
- if (this._trackMap && component[propertyIdName] !== undefined) {
405
- delete this._trackMap[propertyIdName];
406
- }
407
- }
408
- dispose() {
409
- this._trackMap = null;
272
+ class ScrollEvent {
273
+ constructor(params) {
274
+ this._direction = 1;
275
+ this._scrollSize = 0;
276
+ this._scrollWeight = 0;
277
+ this._isVertical = true;
278
+ this._listSize = 0;
279
+ this._size = 0;
280
+ this._isStart = true;
281
+ this._isEnd = false;
282
+ this._delta = 0;
283
+ this._scrollDelta = 0;
284
+ const { direction, isVertical, container, list, delta, scrollDelta } = params;
285
+ this._direction = direction;
286
+ this._isVertical = isVertical;
287
+ this._scrollSize = isVertical ? container.scrollTop : container.scrollLeft;
288
+ this._scrollWeight = isVertical ? container.scrollHeight : container.scrollWidth;
289
+ this._listSize = isVertical ? list.offsetHeight : list.offsetWidth;
290
+ this._size = isVertical ? container.offsetHeight : container.offsetWidth;
291
+ this._isEnd = (this._scrollSize + this._size) === this._scrollWeight;
292
+ this._delta = delta;
293
+ this._scrollDelta = scrollDelta;
294
+ this._isStart = this._scrollSize === 0;
410
295
  }
296
+ get direction() { return this._direction; }
297
+ get scrollSize() { return this._scrollSize; }
298
+ get scrollWeight() { return this._scrollWeight; }
299
+ get isVertical() { return this._isVertical; }
300
+ get listSize() { return this._listSize; }
301
+ get size() { return this._size; }
302
+ get isStart() { return this._isStart; }
303
+ get isEnd() { return this._isEnd; }
304
+ get delta() { return this._delta; }
305
+ get scrollDelta() { return this._scrollDelta; }
411
306
  }
412
307
 
413
308
  /**
@@ -681,6 +576,167 @@ class CacheMap extends EventEmitter {
681
576
  }
682
577
  }
683
578
 
579
+ /**
580
+ * Tracks display items by property
581
+ * @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/tracker.ts
582
+ * @author Evgenii Grebennikov
583
+ * @email djonnyx@gmail.com
584
+ */
585
+ class Tracker {
586
+ constructor(trackingPropertyName) {
587
+ /**
588
+ * display objects dictionary of indexes by id
589
+ */
590
+ this._displayObjectIndexMapById = {};
591
+ /**
592
+ * Dictionary displayItems propertyNameId by items propertyNameId
593
+ */
594
+ this._trackMap = {};
595
+ this._trackingPropertyName = trackingPropertyName;
596
+ }
597
+ set displayObjectIndexMapById(v) {
598
+ if (this._displayObjectIndexMapById === v) {
599
+ return;
600
+ }
601
+ this._displayObjectIndexMapById = v;
602
+ }
603
+ get displayObjectIndexMapById() {
604
+ return this._displayObjectIndexMapById;
605
+ }
606
+ get trackMap() {
607
+ return this._trackMap;
608
+ }
609
+ set trackingPropertyName(v) {
610
+ this._trackingPropertyName = v;
611
+ }
612
+ /**
613
+ * tracking by propName
614
+ */
615
+ track(items, components, snapedComponent, direction) {
616
+ if (!items) {
617
+ return;
618
+ }
619
+ const idPropName = this._trackingPropertyName, untrackedItems = [...components], isDown = direction === 0 || direction === 1;
620
+ let isRegularSnapped = false;
621
+ for (let i = isDown ? 0 : items.length - 1, l = isDown ? items.length : 0; isDown ? i < l : i >= l; isDown ? i++ : i--) {
622
+ const item = items[i], itemTrackingProperty = item[idPropName];
623
+ if (this._trackMap) {
624
+ if (this._trackMap.hasOwnProperty(itemTrackingProperty)) {
625
+ const diId = this._trackMap[itemTrackingProperty], compIndex = this._displayObjectIndexMapById[diId], comp = components[compIndex];
626
+ const compId = comp?.instance?.id;
627
+ if (comp !== undefined && compId === diId) {
628
+ const indexByUntrackedItems = untrackedItems.findIndex(v => {
629
+ return v.instance.id === compId;
630
+ });
631
+ if (indexByUntrackedItems > -1) {
632
+ if (snapedComponent) {
633
+ if (item['config']['snapped'] || item['config']['snappedOut']) {
634
+ isRegularSnapped = true;
635
+ snapedComponent.instance.item = item;
636
+ snapedComponent.instance.show();
637
+ }
638
+ }
639
+ comp.instance.item = item;
640
+ if (snapedComponent) {
641
+ if (item['config']['snapped'] || item['config']['snappedOut']) {
642
+ comp.instance.hide();
643
+ }
644
+ else {
645
+ comp.instance.show();
646
+ }
647
+ }
648
+ else {
649
+ comp.instance.show();
650
+ }
651
+ untrackedItems.splice(indexByUntrackedItems, 1);
652
+ continue;
653
+ }
654
+ }
655
+ delete this._trackMap[itemTrackingProperty];
656
+ }
657
+ }
658
+ if (untrackedItems.length > 0) {
659
+ const comp = untrackedItems.shift(), item = items[i];
660
+ if (comp) {
661
+ if (snapedComponent) {
662
+ if (item['config']['snapped'] || item['config']['snappedOut']) {
663
+ isRegularSnapped = true;
664
+ snapedComponent.instance.item = item;
665
+ snapedComponent.instance.show();
666
+ }
667
+ }
668
+ comp.instance.item = item;
669
+ if (snapedComponent) {
670
+ if (item['config']['snapped'] || item['config']['snappedOut']) {
671
+ comp.instance.hide();
672
+ }
673
+ else {
674
+ comp.instance.show();
675
+ }
676
+ }
677
+ else {
678
+ comp.instance.show();
679
+ }
680
+ if (this._trackMap) {
681
+ this._trackMap[itemTrackingProperty] = comp.instance.id;
682
+ }
683
+ }
684
+ }
685
+ }
686
+ if (untrackedItems.length) {
687
+ for (let i = 0, l = untrackedItems.length; i < l; i++) {
688
+ const comp = untrackedItems[i];
689
+ comp.instance.hide();
690
+ }
691
+ }
692
+ if (!isRegularSnapped) {
693
+ if (snapedComponent) {
694
+ snapedComponent.instance.item = null;
695
+ snapedComponent.instance.hide();
696
+ }
697
+ }
698
+ }
699
+ untrackComponentByIdProperty(component) {
700
+ if (!component) {
701
+ return;
702
+ }
703
+ const propertyIdName = this._trackingPropertyName;
704
+ if (this._trackMap && component[propertyIdName] !== undefined) {
705
+ delete this._trackMap[propertyIdName];
706
+ }
707
+ }
708
+ dispose() {
709
+ this._trackMap = null;
710
+ }
711
+ }
712
+
713
+ const DEFAULT_EXTRA = {
714
+ extremumThreshold: 2,
715
+ bufferSize: 10,
716
+ };
717
+ const bufferInterpolation = (currentBufferValue, array, value, extra) => {
718
+ const { extremumThreshold = DEFAULT_EXTRA.extremumThreshold, bufferSize = DEFAULT_EXTRA.bufferSize, } = extra ?? DEFAULT_EXTRA;
719
+ if (currentBufferValue < value) {
720
+ let i = 0;
721
+ while (i < extremumThreshold) {
722
+ array.push(value);
723
+ i++;
724
+ }
725
+ }
726
+ else {
727
+ array.push(value);
728
+ }
729
+ while (array.length >= bufferSize) {
730
+ array.shift();
731
+ }
732
+ const l = array.length;
733
+ let buffer = 0;
734
+ for (let i = 0; i < l; i++) {
735
+ buffer += array[i];
736
+ }
737
+ return Math.ceil(buffer / l);
738
+ };
739
+
684
740
  const TRACK_BOX_CHANGE_EVENT_NAME = 'change';
685
741
  var ItemDisplayMethods;
686
742
  (function (ItemDisplayMethods) {
@@ -689,6 +745,7 @@ var ItemDisplayMethods;
689
745
  ItemDisplayMethods[ItemDisplayMethods["DELETE"] = 2] = "DELETE";
690
746
  ItemDisplayMethods[ItemDisplayMethods["NOT_CHANGED"] = 3] = "NOT_CHANGED";
691
747
  })(ItemDisplayMethods || (ItemDisplayMethods = {}));
748
+ const DEFAULT_BUFFER_EXTREMUM_THRESHOLD = 15, DEFAULT_MAX_BUFFER_SEQUENCE_LENGTH = 30, DEFAULT_RESET_BUFFER_SIZE_TIMEOUT = 10000;
692
749
  /**
693
750
  * An object that performs tracking, calculations and caching.
694
751
  * @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/trackBox.ts
@@ -699,11 +756,22 @@ class TrackBox extends CacheMap {
699
756
  constructor(trackingPropertyName) {
700
757
  super();
701
758
  this._isSnappingMethodAdvanced = false;
759
+ this._trackingPropertyName = TRACK_BY_PROPERTY_NAME;
702
760
  this._deletedItemsMap = {};
703
761
  this._crudDetected = false;
704
762
  this._previousTotalSize = 0;
705
763
  this._scrollDelta = 0;
706
- this._tracker = new Tracker(trackingPropertyName);
764
+ this.isAdaptiveBuffer = true;
765
+ this._bufferSequenceExtraThreshold = DEFAULT_BUFFER_EXTREMUM_THRESHOLD;
766
+ this._maxBufferSequenceLength = DEFAULT_MAX_BUFFER_SEQUENCE_LENGTH;
767
+ this._bufferSizeSequence = [];
768
+ this._bufferSize = 0;
769
+ this._defaultBufferSize = 0;
770
+ this._maxBufferSize = this._defaultBufferSize;
771
+ this._resetBufferSizeTimeout = DEFAULT_RESET_BUFFER_SIZE_TIMEOUT;
772
+ this._previousScrollSize = 0;
773
+ this._trackingPropertyName = trackingPropertyName;
774
+ this.initialize();
707
775
  }
708
776
  set items(v) {
709
777
  if (this._items === v) {
@@ -733,7 +801,10 @@ class TrackBox extends CacheMap {
733
801
  * Set the trackBy property
734
802
  */
735
803
  set trackingPropertyName(v) {
736
- this._tracker.trackingPropertyName = v;
804
+ this._trackingPropertyName = this._tracker.trackingPropertyName = v;
805
+ }
806
+ initialize() {
807
+ this._tracker = new Tracker(this._trackingPropertyName);
737
808
  }
738
809
  set(id, bounds) {
739
810
  if (this._map.has(id)) {
@@ -753,6 +824,7 @@ class TrackBox extends CacheMap {
753
824
  }
754
825
  }
755
826
  get scrollDelta() { return this._scrollDelta; }
827
+ get bufferSize() { return this._bufferSize; }
756
828
  lifeCircle() {
757
829
  this.fireChangeIfNeed();
758
830
  this.lifeCircleDo();
@@ -846,6 +918,8 @@ class TrackBox extends CacheMap {
846
918
  */
847
919
  getItemPosition(id, stickyMap, options) {
848
920
  const opt = { fromItemId: id, stickyMap, ...options };
921
+ this._defaultBufferSize = opt.bufferSize;
922
+ this._maxBufferSize = opt.maxBufferSize;
849
923
  const { scrollSize, isFromItemIdFound } = this.recalculateMetrics({
850
924
  ...opt,
851
925
  dynamicSize: this._crudDetected || opt.dynamicSize,
@@ -863,6 +937,8 @@ class TrackBox extends CacheMap {
863
937
  if (opt.dynamicSize) {
864
938
  this.cacheElements();
865
939
  }
940
+ this._defaultBufferSize = opt.bufferSize;
941
+ this._maxBufferSize = opt.maxBufferSize;
866
942
  const metrics = this.recalculateMetrics({
867
943
  ...opt,
868
944
  collection: items,
@@ -871,6 +947,7 @@ class TrackBox extends CacheMap {
871
947
  deletedItemsMap,
872
948
  });
873
949
  this._delta += metrics.delta;
950
+ this.updateAdaptiveBufferParams(metrics, items.length);
874
951
  this._previousTotalSize = metrics.totalSize;
875
952
  this._deletedItemsMap = {};
876
953
  this._crudDetected = false;
@@ -886,6 +963,26 @@ class TrackBox extends CacheMap {
886
963
  getNearestItem(scrollSize, items, itemSize, isVertical) {
887
964
  return this.getElementFromStart(scrollSize, items, this._map, itemSize, isVertical);
888
965
  }
966
+ updateAdaptiveBufferParams(metrics, totalItemsLength) {
967
+ this.disposeClearBufferSizeTimer();
968
+ const scrollSize = metrics.scrollSize + this._delta, delta = Math.abs(this._previousScrollSize - scrollSize);
969
+ this._previousScrollSize = scrollSize;
970
+ 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;
971
+ this._bufferSize = bufferInterpolation(this._bufferSize, this._bufferSizeSequence, bufferValue, {
972
+ extremumThreshold: this._bufferSequenceExtraThreshold,
973
+ bufferSize: this._maxBufferSequenceLength,
974
+ });
975
+ this.startResetBufferSizeTimer();
976
+ }
977
+ startResetBufferSizeTimer() {
978
+ this._resetBufferSizeTimer = setTimeout(() => {
979
+ this._bufferSize = this._defaultBufferSize;
980
+ this._bufferSizeSequence = [];
981
+ }, this._resetBufferSizeTimeout);
982
+ }
983
+ disposeClearBufferSizeTimer() {
984
+ clearTimeout(this._resetBufferSizeTimer);
985
+ }
889
986
  /**
890
987
  * Calculates the position of an element based on the given scrollSize
891
988
  */
@@ -937,30 +1034,30 @@ class TrackBox extends CacheMap {
937
1034
  * Calculates list metrics
938
1035
  */
939
1036
  recalculateMetrics(options) {
940
- const { fromItemId, bounds, collection, dynamicSize, isVertical, itemSize, itemsOffset, scrollSize, snap, stickyMap, enabledBufferOptimization, previousTotalSize, crudDetected, deletedItemsMap } = options;
941
- 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)
1037
+ const { fromItemId, bounds, collection, dynamicSize, isVertical, itemSize, bufferSize: minBufferSize, scrollSize, snap, stickyMap, enabledBufferOptimization, previousTotalSize, crudDetected, deletedItemsMap } = options;
1038
+ 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)
942
1039
  || (typeof fromItemId === 'string' && fromItemId > '-1');
943
1040
  let leftItemsOffset = 0, rightItemsOffset = 0;
944
1041
  if (enabledBufferOptimization) {
945
1042
  switch (this.scrollDirection) {
946
1043
  case 1: {
947
1044
  leftItemsOffset = 0;
948
- rightItemsOffset = itemsOffset;
1045
+ rightItemsOffset = bufferSize;
949
1046
  break;
950
1047
  }
951
1048
  case -1: {
952
- leftItemsOffset = itemsOffset;
1049
+ leftItemsOffset = bufferSize;
953
1050
  rightItemsOffset = 0;
954
1051
  break;
955
1052
  }
956
1053
  case 0:
957
1054
  default: {
958
- leftItemsOffset = rightItemsOffset = itemsOffset;
1055
+ leftItemsOffset = rightItemsOffset = bufferSize;
959
1056
  }
960
1057
  }
961
1058
  }
962
1059
  else {
963
- leftItemsOffset = rightItemsOffset = itemsOffset;
1060
+ leftItemsOffset = rightItemsOffset = bufferSize;
964
1061
  }
965
1062
  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;
966
1063
  // If the list is dynamic or there are new elements in the collection, then it switches to the long algorithm.
@@ -1135,9 +1232,9 @@ class TrackBox extends CacheMap {
1135
1232
  }
1136
1233
  itemsFromStartToScrollEnd = Math.floor(scrollSize / typicalItemSize);
1137
1234
  itemsFromStartToDisplayEnd = Math.ceil((scrollSize + size) / typicalItemSize);
1138
- leftItemLength = Math.min(itemsFromStartToScrollEnd, itemsOffset);
1139
- rightItemLength = itemsFromStartToDisplayEnd + itemsOffset > totalLength
1140
- ? totalLength - itemsFromStartToDisplayEnd : itemsOffset;
1235
+ leftItemLength = Math.min(itemsFromStartToScrollEnd, bufferSize);
1236
+ rightItemLength = itemsFromStartToDisplayEnd + bufferSize > totalLength
1237
+ ? totalLength - itemsFromStartToDisplayEnd : bufferSize;
1141
1238
  leftItemsWeight = leftItemLength * typicalItemSize;
1142
1239
  rightItemsWeight = rightItemLength * typicalItemSize;
1143
1240
  leftHiddenItemsWeight = itemsFromStartToScrollEnd * typicalItemSize;
@@ -1234,6 +1331,9 @@ class TrackBox extends CacheMap {
1234
1331
  if (snap) {
1235
1332
  const startIndex = itemsFromStartToScrollEnd + itemsOnDisplayLength - 1;
1236
1333
  for (let i = Math.min(startIndex, totalLength > 0 ? totalLength - 1 : 0), l = totalLength; i < l; i++) {
1334
+ if (!items[i]) {
1335
+ continue;
1336
+ }
1237
1337
  const id = items[i].id, sticky = stickyMap[id], size = dynamicSize
1238
1338
  ? this.get(id)?.[sizeProperty] || typicalItemSize
1239
1339
  : typicalItemSize;
@@ -1268,6 +1368,9 @@ class TrackBox extends CacheMap {
1268
1368
  if (i >= totalLength) {
1269
1369
  break;
1270
1370
  }
1371
+ if (!items[i]) {
1372
+ continue;
1373
+ }
1271
1374
  const id = items[i].id, size = dynamicSize ? this.get(id)?.[sizeProperty] || typicalItemSize : typicalItemSize;
1272
1375
  if (id !== stickyItem?.id && id !== endStickyItem?.id) {
1273
1376
  const snapped = snap && (stickyMap[id] === 1 && pos <= scrollSize || stickyMap[id] === 2 && pos >= scrollSize + boundsSize - size), measures = {
@@ -1379,54 +1482,13 @@ class TrackBox extends CacheMap {
1379
1482
  }
1380
1483
  dispose() {
1381
1484
  super.dispose();
1485
+ this.disposeClearBufferSizeTimer();
1382
1486
  if (this._tracker) {
1383
1487
  this._tracker.dispose();
1384
1488
  }
1385
1489
  }
1386
1490
  }
1387
1491
 
1388
- /**
1389
- * Scroll event.
1390
- * @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/scrollEvent.ts
1391
- * @author Evgenii Grebennikov
1392
- * @email djonnyx@gmail.com
1393
- */
1394
- class ScrollEvent {
1395
- constructor(params) {
1396
- this._direction = 1;
1397
- this._scrollSize = 0;
1398
- this._scrollWeight = 0;
1399
- this._isVertical = true;
1400
- this._listSize = 0;
1401
- this._size = 0;
1402
- this._isStart = true;
1403
- this._isEnd = false;
1404
- this._delta = 0;
1405
- this._scrollDelta = 0;
1406
- const { direction, isVertical, container, list, delta, scrollDelta } = params;
1407
- this._direction = direction;
1408
- this._isVertical = isVertical;
1409
- this._scrollSize = isVertical ? container.scrollTop : container.scrollLeft;
1410
- this._scrollWeight = isVertical ? container.scrollHeight : container.scrollWidth;
1411
- this._listSize = isVertical ? list.offsetHeight : list.offsetWidth;
1412
- this._size = isVertical ? container.offsetHeight : container.offsetWidth;
1413
- this._isEnd = (this._scrollSize + this._size) === this._scrollWeight;
1414
- this._delta = delta;
1415
- this._scrollDelta = scrollDelta;
1416
- this._isStart = this._scrollSize === 0;
1417
- }
1418
- get direction() { return this._direction; }
1419
- get scrollSize() { return this._scrollSize; }
1420
- get scrollWeight() { return this._scrollWeight; }
1421
- get isVertical() { return this._isVertical; }
1422
- get listSize() { return this._listSize; }
1423
- get size() { return this._size; }
1424
- get isStart() { return this._isStart; }
1425
- get isEnd() { return this._isEnd; }
1426
- get delta() { return this._delta; }
1427
- get scrollDelta() { return this._scrollDelta; }
1428
- }
1429
-
1430
1492
  /**
1431
1493
  * Base disposable component
1432
1494
  * @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/disposableComponent.ts
@@ -1464,6 +1526,20 @@ const isSnappingMethodDefault = (method) => {
1464
1526
  const IS_FIREFOX = navigator.userAgent.toLowerCase().includes('firefox');
1465
1527
  const FIREFOX_SCROLLBAR_OVERLAP_SIZE = 12;
1466
1528
 
1529
+ const HORIZONTAL_ALIASES = [Directions.HORIZONTAL, 'horizontal'], VERTICAL_ALIASES = [Directions.VERTICAL, 'vertical'];
1530
+ /**
1531
+ * Determines the axis membership of a virtual list
1532
+ * @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/isDirection.ts
1533
+ * @author Evgenii Grebennikov
1534
+ * @email djonnyx@gmail.com
1535
+ */
1536
+ const isDirection = (src, expected) => {
1537
+ if (HORIZONTAL_ALIASES.includes(expected)) {
1538
+ return HORIZONTAL_ALIASES.includes(src);
1539
+ }
1540
+ return VERTICAL_ALIASES.includes(src);
1541
+ };
1542
+
1467
1543
  /**
1468
1544
  * Virtual list component.
1469
1545
  * Maximum performance for extremely large lists.
@@ -1514,8 +1590,17 @@ class NgVirtualListComponent extends DisposableComponent {
1514
1590
  this.$dynamicSize = this._$dynamicSize.asObservable();
1515
1591
  this._$direction = new BehaviorSubject(DEFAULT_DIRECTION);
1516
1592
  this.$direction = this._$direction.asObservable();
1517
- this._$itemsOffset = new BehaviorSubject(DEFAULT_ITEMS_OFFSET);
1518
- this.$itemsOffset = this._$itemsOffset.asObservable();
1593
+ this._$bufferSize = new BehaviorSubject(DEFAULT_BUFFER_SIZE);
1594
+ this.$bufferSize = this._$bufferSize.asObservable();
1595
+ this._maxBufferSizeTransform = (v) => {
1596
+ const bufferSize = this._$bufferSize.getValue();
1597
+ if (v === undefined || v <= bufferSize) {
1598
+ return bufferSize;
1599
+ }
1600
+ return v;
1601
+ };
1602
+ this._$maxBufferSize = new BehaviorSubject(DEFAULT_MAX_BUFFER_SIZE);
1603
+ this.$maxBufferSize = this._$maxBufferSize.asObservable();
1519
1604
  this._$trackBy = new BehaviorSubject(TRACK_BY_PROPERTY_NAME);
1520
1605
  this.$trackBy = this._$trackBy.asObservable();
1521
1606
  this._isVertical = this.getIsVertical();
@@ -1635,7 +1720,7 @@ class NgVirtualListComponent extends DisposableComponent {
1635
1720
  $trackBy.pipe(takeUntil(this._$unsubscribe), tap(v => {
1636
1721
  this._trackBox.trackingPropertyName = v;
1637
1722
  })).subscribe();
1638
- 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;
1723
+ 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;
1639
1724
  $isVertical.pipe(takeUntil(this._$unsubscribe), tap(v => {
1640
1725
  this._isVertical = v;
1641
1726
  const el = this._elementRef.nativeElement;
@@ -1648,12 +1733,12 @@ class NgVirtualListComponent extends DisposableComponent {
1648
1733
  this.listenCacheChangesIfNeed(dynamicSize);
1649
1734
  })).subscribe();
1650
1735
  combineLatest([this.$initialized, $bounds, $items, $stickyMap, $scrollSize, $itemSize,
1651
- $itemsOffset, $snap, $isVertical, $dynamicSize, $enabledBufferOptimization, $cacheVersion,
1652
- ]).pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), filter(([initialized]) => !!initialized), switchMap(([, bounds, items, stickyMap, scrollSize, itemSize, itemsOffset, snap, isVertical, dynamicSize, enabledBufferOptimization, cacheVersion,]) => {
1736
+ $bufferSize, $maxBufferSize, $snap, $isVertical, $dynamicSize, $enabledBufferOptimization, $cacheVersion,
1737
+ ]).pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), filter(([initialized]) => !!initialized), switchMap(([, bounds, items, stickyMap, scrollSize, itemSize, bufferSize, maxBufferSize, snap, isVertical, dynamicSize, enabledBufferOptimization, cacheVersion,]) => {
1653
1738
  let actualScrollSize = (this._isVertical ? this._container?.nativeElement.scrollTop ?? 0 : this._container?.nativeElement.scrollLeft) ?? 0;
1654
1739
  const { width, height } = bounds, opts = {
1655
1740
  bounds: { width, height }, dynamicSize, isVertical, itemSize,
1656
- itemsOffset, scrollSize: actualScrollSize, snap, enabledBufferOptimization,
1741
+ bufferSize, maxBufferSize, scrollSize: actualScrollSize, snap, enabledBufferOptimization,
1657
1742
  }, { displayItems, totalSize } = this._trackBox.updateCollection(items, stickyMap, opts);
1658
1743
  this.resetBoundsSize(isVertical, totalSize);
1659
1744
  this.createDisplayComponentsIfNeed(displayItems);
@@ -1676,7 +1761,10 @@ class NgVirtualListComponent extends DisposableComponent {
1676
1761
  }
1677
1762
  return of(displayItems);
1678
1763
  })).subscribe();
1679
- this.setupRenderer();
1764
+ const $itemRenderer = this.$itemRenderer;
1765
+ $itemRenderer.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), filter(v => !!v), tap(v => {
1766
+ this._$renderer.next(v);
1767
+ })).subscribe();
1680
1768
  }
1681
1769
  /**
1682
1770
  * Readonly. Returns the unique identifier of the component.
@@ -1786,16 +1874,37 @@ class NgVirtualListComponent extends DisposableComponent {
1786
1874
  ;
1787
1875
  get direction() { return this._$direction.getValue(); }
1788
1876
  /**
1789
- * Number of elements outside the scope of visibility. Default value is 2.
1877
+ * @deprecated "itemOffset" parameter is deprecated. Use "bufferSize" and "maxBufferSize".
1790
1878
  */
1791
1879
  set itemsOffset(v) {
1792
- if (this._$itemsOffset.getValue() === v) {
1880
+ throw Error('"itemOffset" parameter is deprecated. Use "bufferSize" and "maxBufferSize".');
1881
+ }
1882
+ ;
1883
+ /**
1884
+ * Number of elements outside the scope of visibility. Default value is 2.
1885
+ */
1886
+ set bufferSize(v) {
1887
+ if (this._$bufferSize.getValue() === v) {
1793
1888
  return;
1794
1889
  }
1795
- this._$itemsOffset.next(v);
1890
+ this._$bufferSize.next(v);
1796
1891
  }
1797
1892
  ;
1798
- get itemsOffset() { return this._$itemsOffset.getValue(); }
1893
+ get bufferSize() { return this._$bufferSize.getValue(); }
1894
+ /**
1895
+ * Maximum number of elements outside the scope of visibility. Default value is 100.
1896
+ * If maxBufferSize is set to be greater than bufferSize, then adaptive buffer mode is enabled.
1897
+ * The greater the scroll size, the more elements are allocated for rendering.
1898
+ */
1899
+ set maxBufferSize(v) {
1900
+ const val = this._maxBufferSizeTransform(v);
1901
+ if (this._$maxBufferSize.getValue() === val) {
1902
+ return;
1903
+ }
1904
+ this._$maxBufferSize.next(val);
1905
+ }
1906
+ ;
1907
+ get maxBufferSize() { return this._$maxBufferSize.getValue(); }
1799
1908
  /**
1800
1909
  * The name of the property by which tracking is performed
1801
1910
  */
@@ -1822,12 +1931,6 @@ class NgVirtualListComponent extends DisposableComponent {
1822
1931
  get snappingMethod() { return this._$snappingMethod.getValue(); }
1823
1932
  get isSnappingMethodAdvanced() { return this._isSnappingMethodAdvanced; }
1824
1933
  get $cacheVersion() { return this._$cacheVersion.asObservable(); }
1825
- setupRenderer() {
1826
- const $itemRenderer = this.$itemRenderer;
1827
- $itemRenderer.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), filter(v => !!v), tap(v => {
1828
- this._$renderer.next(v);
1829
- })).subscribe();
1830
- }
1831
1934
  /** @internal */
1832
1935
  ngOnInit() {
1833
1936
  this.onInit();
@@ -1940,7 +2043,7 @@ class NgVirtualListComponent extends DisposableComponent {
1940
2043
  }
1941
2044
  const { width, height } = this._$bounds.getValue() || { width: 0, height: 0 }, stickyMap = this.stickyMap, items = this.items, isVertical = this._isVertical, delta = this._trackBox.delta, opts = {
1942
2045
  bounds: { width, height }, collection: items, dynamicSize, isVertical: this._isVertical, itemSize,
1943
- itemsOffset: this.itemsOffset, scrollSize: (isVertical ? container.nativeElement.scrollTop : container.nativeElement.scrollLeft) + delta,
2046
+ bufferSize: this.bufferSize, maxBufferSize: this.maxBufferSize, scrollSize: (isVertical ? container.nativeElement.scrollTop : container.nativeElement.scrollLeft) + delta,
1944
2047
  snap: this.snap, fromItemId: id, enabledBufferOptimization: this.enabledBufferOptimization,
1945
2048
  }, scrollSize = this._trackBox.getItemPosition(id, stickyMap, opts), params = { [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollSize, behavior };
1946
2049
  if (scrollSize === -1) {
@@ -2048,7 +2151,7 @@ class NgVirtualListComponent extends DisposableComponent {
2048
2151
  }
2049
2152
  NgVirtualListComponent.__nextId = 0;
2050
2153
  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 });
2051
- 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 });
2154
+ 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 });
2052
2155
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgVirtualListComponent, decorators: [{
2053
2156
  type: Component,
2054
2157
  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"] }]
@@ -2089,6 +2192,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
2089
2192
  type: Input
2090
2193
  }], itemsOffset: [{
2091
2194
  type: Input
2195
+ }], bufferSize: [{
2196
+ type: Input
2197
+ }], maxBufferSize: [{
2198
+ type: Input
2092
2199
  }], trackBy: [{
2093
2200
  type: Input
2094
2201
  }], snappingMethod: [{
@@ -2118,5 +2225,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
2118
2225
  * Generated bundle index. Do not edit.
2119
2226
  */
2120
2227
 
2121
- export { BaseVirtualListItemComponent, Directions, NgVirtualListComponent, NgVirtualListItemComponent, NgVirtualListModule, SnappingMethods };
2228
+ export { Directions, NgVirtualListComponent, NgVirtualListItemComponent, NgVirtualListModule, SnappingMethods };
2122
2229
  //# sourceMappingURL=ng-virtual-list.mjs.map