ng-virtual-list 18.7.12 → 18.7.13

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.
@@ -1,11 +1,29 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Injectable, inject, ChangeDetectorRef, signal, ElementRef, Component, ChangeDetectionStrategy, viewChild, output, input, ViewContainerRef, ViewEncapsulation, ViewChild, NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
3
- import { Subject, tap, fromEvent, combineLatest, map, filter, distinctUntilChanged, skip, switchMap, of } from 'rxjs';
3
+ import { Subject, tap, fromEvent, combineLatest, map, filter, distinctUntilChanged, switchMap, of } from 'rxjs';
4
4
  import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
5
5
  import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
6
6
  import * as i1 from '@angular/common';
7
7
  import { CommonModule } from '@angular/common';
8
8
 
9
+ /**
10
+ * Action modes for collection elements.
11
+ * @link https://github.com/DjonnyX/ng-virtual-list/blob/18.x/projects/ng-virtual-list/src/lib/enums/collection-modes.ts
12
+ * @author Evgenii Grebennikov
13
+ * @email djonnyx@gmail.com
14
+ */
15
+ var CollectionModes;
16
+ (function (CollectionModes) {
17
+ /**
18
+ * When adding elements to the beginning of the collection, the scroll remains at the current position.
19
+ */
20
+ CollectionModes["NORMAL"] = "normal";
21
+ /**
22
+ * When adding elements to the beginning of the collection, the scroll is shifted by the sum of the sizes of the new elements.
23
+ */
24
+ CollectionModes["LAZY"] = "lazy";
25
+ })(CollectionModes || (CollectionModes = {}));
26
+
9
27
  /**
10
28
  * Axis of the arrangement of virtual list elements.
11
29
  * @link https://github.com/DjonnyX/ng-virtual-list/blob/18.x/projects/ng-virtual-list/src/lib/enums/directions.ts
@@ -75,6 +93,7 @@ const DEFAULT_ENABLED_BUFFER_OPTIMIZATION = false;
75
93
  const DEFAULT_DYNAMIC_SIZE = false;
76
94
  const TRACK_BY_PROPERTY_NAME = 'id';
77
95
  const DEFAULT_DIRECTION = Directions.VERTICAL;
96
+ const DEFAULT_COLLECTION_MODE = CollectionModes.NORMAL;
78
97
  const DISPLAY_OBJECTS_LENGTH_MESUREMENT_ERROR = 1;
79
98
  const MAX_SCROLL_TO_ITERATIONS = 5;
80
99
  const DEFAULT_SNAPPING_METHOD = SnappingMethods.NORMAL;
@@ -1244,7 +1263,11 @@ const bufferInterpolation = (currentBufferValue, array, value, extra) => {
1244
1263
  return Math.ceil(buffer / l);
1245
1264
  };
1246
1265
 
1247
- const TRACK_BOX_CHANGE_EVENT_NAME = 'change';
1266
+ var TrackBoxEvents;
1267
+ (function (TrackBoxEvents) {
1268
+ TrackBoxEvents["CHANGE"] = "change";
1269
+ TrackBoxEvents["RESET"] = "reset";
1270
+ })(TrackBoxEvents || (TrackBoxEvents = {}));
1248
1271
  var ItemDisplayMethods;
1249
1272
  (function (ItemDisplayMethods) {
1250
1273
  ItemDisplayMethods[ItemDisplayMethods["CREATE"] = 0] = "CREATE";
@@ -1252,7 +1275,7 @@ var ItemDisplayMethods;
1252
1275
  ItemDisplayMethods[ItemDisplayMethods["DELETE"] = 2] = "DELETE";
1253
1276
  ItemDisplayMethods[ItemDisplayMethods["NOT_CHANGED"] = 3] = "NOT_CHANGED";
1254
1277
  })(ItemDisplayMethods || (ItemDisplayMethods = {}));
1255
- const DEFAULT_BUFFER_EXTREMUM_THRESHOLD = 15, DEFAULT_MAX_BUFFER_SEQUENCE_LENGTH = 30, DEFAULT_RESET_BUFFER_SIZE_TIMEOUT = 10000;
1278
+ const DEFAULT_BUFFER_EXTREMUM_THRESHOLD = 15, DEFAULT_MAX_BUFFER_SEQUENCE_LENGTH = 30, DEFAULT_RESET_BUFFER_SIZE_TIMEOUT = 10000, IS_NEW = 'isNew';
1256
1279
  /**
1257
1280
  * An object that performs tracking, calculations and caching.
1258
1281
  * @link https://github.com/DjonnyX/ng-virtual-list/blob/18.x/projects/ng-virtual-list/src/lib/utils/trackBox.ts
@@ -1289,6 +1312,13 @@ class TrackBox extends CacheMap {
1289
1312
  }
1290
1313
  this._isSnappingMethodAdvanced = v;
1291
1314
  }
1315
+ _isLazy = false;
1316
+ set isLazy(v) {
1317
+ if (this._isLazy === v) {
1318
+ return;
1319
+ }
1320
+ this._isLazy = v;
1321
+ }
1292
1322
  /**
1293
1323
  * Set the trackBy property
1294
1324
  */
@@ -1321,7 +1351,7 @@ class TrackBox extends CacheMap {
1321
1351
  get crudDetected() { return this._crudDetected; }
1322
1352
  fireChangeIfNeed() {
1323
1353
  if (this.changesDetected()) {
1324
- this.dispatch(TRACK_BOX_CHANGE_EVENT_NAME, this._version);
1354
+ this.dispatch(TrackBoxEvents.CHANGE, this._version);
1325
1355
  }
1326
1356
  }
1327
1357
  _previousTotalSize = 0;
@@ -1337,7 +1367,7 @@ class TrackBox extends CacheMap {
1337
1367
  _maxBufferSize = this._defaultBufferSize;
1338
1368
  _resetBufferSizeTimeout = DEFAULT_RESET_BUFFER_SIZE_TIMEOUT;
1339
1369
  _resetBufferSizeTimer;
1340
- isInit = true;
1370
+ isReseted = true;
1341
1371
  lifeCircle() {
1342
1372
  this.fireChangeIfNeed();
1343
1373
  this.lifeCircleDo();
@@ -1350,11 +1380,19 @@ class TrackBox extends CacheMap {
1350
1380
  console.warn('Attention! The collection must be immutable.');
1351
1381
  return;
1352
1382
  }
1353
- if (this.isInit && !(!this._previousCollection || this._previousCollection.length === 0)) {
1354
- this.isInit = false;
1383
+ let reseted = this.isReseted;
1384
+ if (reseted) {
1385
+ if (!(!this._previousCollection || this._previousCollection.length === 0)) {
1386
+ reseted = false;
1387
+ }
1388
+ }
1389
+ if (!reseted && (!currentCollection || currentCollection.length === 0)) {
1390
+ reseted = true;
1355
1391
  }
1392
+ this.isReseted = reseted;
1393
+ this.dispatch(TrackBoxEvents.RESET, reseted);
1356
1394
  this.updateCache(this._previousCollection, currentCollection, itemSize);
1357
- this._previousCollection = currentCollection;
1395
+ this._previousCollection = [...(currentCollection || [])];
1358
1396
  }
1359
1397
  /**
1360
1398
  * Update the cache of items from the list
@@ -1577,9 +1615,10 @@ class TrackBox extends CacheMap {
1577
1615
  leftItemsOffset = rightItemsOffset = bufferSize;
1578
1616
  }
1579
1617
  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, deltaFromStartCreation = 0;
1618
+ let isNew = !this.isReseted && (scrollSize === 0);
1580
1619
  // If the list is dynamic or there are new elements in the collection, then it switches to the long algorithm.
1581
1620
  if (dynamicSize) {
1582
- let y = 0, stickyCollectionItem = undefined, stickyComponentSize = 0, isNew = true;
1621
+ let y = 0, stickyCollectionItem = undefined, stickyComponentSize = 0;
1583
1622
  for (let i = 0, l = collection.length; i < l; i++) {
1584
1623
  const ii = i + 1, collectionItem = collection[i], id = collectionItem.id;
1585
1624
  let componentSize = 0, componentSizeDelta = 0, itemDisplayMethod = ItemDisplayMethods.NOT_CHANGED;
@@ -1587,8 +1626,8 @@ class TrackBox extends CacheMap {
1587
1626
  const bounds = map.get(id) || { width: typicalItemSize, height: typicalItemSize };
1588
1627
  componentSize = bounds[sizeProperty];
1589
1628
  itemDisplayMethod = bounds?.method ?? ItemDisplayMethods.UPDATE;
1590
- const isItemNew = bounds.isNew ?? true;
1591
- if (isNew && (this.isInit || (!isItemNew && i > 0))) {
1629
+ const isItemNew = bounds?.[IS_NEW] ?? this._isLazy;
1630
+ if (!isItemNew && (!this._isLazy || !itemConfigMap[collection[0].id]?.sticky)) {
1592
1631
  isNew = false;
1593
1632
  }
1594
1633
  switch (itemDisplayMethod) {
@@ -1725,8 +1764,15 @@ class TrackBox extends CacheMap {
1725
1764
  if (map.has(id)) {
1726
1765
  const bounds = map.get(id);
1727
1766
  itemDisplayMethod = bounds?.method ?? ItemDisplayMethods.UPDATE;
1767
+ const isItemNew = bounds?.[IS_NEW] ?? this._isLazy;
1768
+ if (!isItemNew && (!this._isLazy || !itemConfigMap[collection[0].id]?.sticky)) {
1769
+ isNew = false;
1770
+ }
1728
1771
  if (itemDisplayMethod === ItemDisplayMethods.CREATE) {
1729
- map.set(id, { ...bounds, method: ItemDisplayMethods.NOT_CHANGED });
1772
+ if (isNew) {
1773
+ deltaFromStartCreation += componentSize;
1774
+ }
1775
+ map.set(id, { ...bounds, method: ItemDisplayMethods.NOT_CHANGED, isNew });
1730
1776
  }
1731
1777
  }
1732
1778
  if (deletedItemsMap.hasOwnProperty(i)) {
@@ -1738,7 +1784,9 @@ class TrackBox extends CacheMap {
1738
1784
  if (y < scrollSize - componentSize) {
1739
1785
  switch (itemDisplayMethod) {
1740
1786
  case ItemDisplayMethods.CREATE: {
1741
- leftSizeOfUpdatedItems += componentSize;
1787
+ if (!isNew) {
1788
+ leftSizeOfUpdatedItems += componentSize;
1789
+ }
1742
1790
  break;
1743
1791
  }
1744
1792
  case ItemDisplayMethods.UPDATE: {
@@ -1834,7 +1882,7 @@ class TrackBox extends CacheMap {
1834
1882
  height: isVertical ? size : normalizedItemHeight,
1835
1883
  delta: 0,
1836
1884
  }, config = {
1837
- new: cache.isNew === true,
1885
+ new: cache?.[IS_NEW] === true,
1838
1886
  odd: isOdd,
1839
1887
  even: !isOdd,
1840
1888
  isVertical,
@@ -1876,7 +1924,7 @@ class TrackBox extends CacheMap {
1876
1924
  height: h,
1877
1925
  delta: 0,
1878
1926
  }, config = {
1879
- new: cache.isNew === true,
1927
+ new: cache?.[IS_NEW] === true,
1880
1928
  odd: isOdd,
1881
1929
  even: !isOdd,
1882
1930
  isVertical,
@@ -1917,7 +1965,7 @@ class TrackBox extends CacheMap {
1917
1965
  height: isVertical ? size : normalizedItemHeight,
1918
1966
  delta: 0,
1919
1967
  }, config = {
1920
- new: cache.isNew === true,
1968
+ new: cache?.[IS_NEW] === true,
1921
1969
  odd: isOdd,
1922
1970
  even: !isOdd,
1923
1971
  isVertical,
@@ -2103,6 +2151,20 @@ const copyValueAsReadonly = (source) => {
2103
2151
  return source;
2104
2152
  };
2105
2153
 
2154
+ const NORMAL_ALIASES = [CollectionModes.NORMAL, 'normal'], LAZY_ALIASES = [CollectionModes.LAZY, 'lazy'];
2155
+ /**
2156
+ * Determines the axis membership of a virtual list
2157
+ * @link https://github.com/DjonnyX/ng-virtual-list/blob/18.x/projects/ng-virtual-list/src/lib/utils/isCollectionMode.ts
2158
+ * @author Evgenii Grebennikov
2159
+ * @email djonnyx@gmail.com
2160
+ */
2161
+ const isCollectionMode = (src, expected) => {
2162
+ if (LAZY_ALIASES.includes(expected)) {
2163
+ return LAZY_ALIASES.includes(src);
2164
+ }
2165
+ return NORMAL_ALIASES.includes(src);
2166
+ };
2167
+
2106
2168
  const ROLE_LIST = 'list', ROLE_LIST_BOX = 'listbox';
2107
2169
  const validateScrollIteration = (value) => {
2108
2170
  return Number.isNaN(value) || (value < 0) ? 0 : value > MAX_SCROLL_TO_ITERATIONS ? MAX_SCROLL_TO_ITERATIONS : value;
@@ -2411,6 +2473,20 @@ class NgVirtualListComponent {
2411
2473
  * Determines the direction in which elements are placed. Default value is "vertical".
2412
2474
  */
2413
2475
  direction = input(DEFAULT_DIRECTION, { ...this._directionOptions });
2476
+ _collectionModeOptions = {
2477
+ transform: (v) => {
2478
+ const valid = validateString(v) && (v === 'normal' || v === 'lazy');
2479
+ if (!valid) {
2480
+ console.error('The "direction" parameter must have the value `normal` or `lazy`.');
2481
+ return DEFAULT_COLLECTION_MODE;
2482
+ }
2483
+ return v;
2484
+ },
2485
+ };
2486
+ /**
2487
+ * Determines the action modes for collection elements. Default value is "normal".
2488
+ */
2489
+ collectionMode = input(DEFAULT_COLLECTION_MODE, { ...this._collectionModeOptions });
2414
2490
  _bufferSizeOptions = {
2415
2491
  transform: (v) => {
2416
2492
  const valid = validateInt(v);
@@ -2501,6 +2577,7 @@ class NgVirtualListComponent {
2501
2577
  get isMultiSelecting() { return this._isMultiSelecting; }
2502
2578
  _isSnappingMethodAdvanced = this.getIsSnappingMethodAdvanced();
2503
2579
  get isSnappingMethodAdvanced() { return this._isSnappingMethodAdvanced; }
2580
+ _isLazy = this.getIsLazy();
2504
2581
  _isVertical = this.getIsVertical();
2505
2582
  get orientation() {
2506
2583
  return this._isVertical ? Directions.VERTICAL : Directions.HORIZONTAL;
@@ -2597,10 +2674,25 @@ class NgVirtualListComponent {
2597
2674
  this._cacheVersion.set(v);
2598
2675
  };
2599
2676
  _cacheVersion = signal(-1);
2677
+ _isResetedReachStart = true;
2678
+ _onTrackBoxResetHandler = (v) => {
2679
+ if (v) {
2680
+ this._isResetedReachStart = true;
2681
+ const container = this._container()?.nativeElement;
2682
+ if (container) {
2683
+ const params = {
2684
+ [this._isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: 0,
2685
+ behavior: BEHAVIOR_INSTANT,
2686
+ };
2687
+ container.scrollTo(params);
2688
+ }
2689
+ }
2690
+ };
2600
2691
  constructor() {
2601
2692
  NgVirtualListComponent.__nextId = NgVirtualListComponent.__nextId + 1 === Number.MAX_SAFE_INTEGER
2602
2693
  ? 0 : NgVirtualListComponent.__nextId + 1;
2603
2694
  this._id = NgVirtualListComponent.__nextId;
2695
+ this._trackBox.addEventListener(TrackBoxEvents.RESET, this._onTrackBoxResetHandler);
2604
2696
  this._service.initialize(this._trackBox);
2605
2697
  this._service.itemToFocus = this.itemToFocus;
2606
2698
  this._initialized = signal(false);
@@ -2613,12 +2705,13 @@ class NgVirtualListComponent {
2613
2705
  this._service.listElement = v.nativeElement;
2614
2706
  })).subscribe();
2615
2707
  const $trackBy = toObservable(this.trackBy), $selectByClick = toObservable(this.selectByClick), $collapseByClick = toObservable(this.collapseByClick), $isScrollStart = toObservable(this._isScrollStart), $isScrollFinished = toObservable(this._isScrollFinished);
2616
- $isScrollStart.pipe(takeUntilDestroyed(), distinctUntilChanged(), skip(1), tap(v => {
2617
- if (v) {
2708
+ $isScrollStart.pipe(takeUntilDestroyed(), distinctUntilChanged(), tap(v => {
2709
+ if (v && !this._isResetedReachStart) {
2618
2710
  this.onScrollReachStart.emit();
2619
2711
  }
2712
+ this._isResetedReachStart = false;
2620
2713
  })).subscribe();
2621
- $isScrollFinished.pipe(takeUntilDestroyed(), distinctUntilChanged(), skip(1), tap(v => {
2714
+ $isScrollFinished.pipe(takeUntilDestroyed(), distinctUntilChanged(), tap(v => {
2622
2715
  if (v) {
2623
2716
  this.onScrollReachEnd.emit();
2624
2717
  }
@@ -2632,7 +2725,10 @@ class NgVirtualListComponent {
2632
2725
  $trackBy.pipe(takeUntilDestroyed(), tap(v => {
2633
2726
  this._trackBox.trackingPropertyName = v;
2634
2727
  })).subscribe();
2635
- const $bounds = toObservable(this._bounds).pipe(filter(b => !!b)), $items = toObservable(this.items).pipe(map(i => !i ? [] : i)), $scrollSize = toObservable(this._scrollSize), $itemSize = toObservable(this.itemSize).pipe(map(v => v <= 0 ? DEFAULT_ITEM_SIZE : v)), $bufferSize = toObservable(this.bufferSize).pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $maxBufferSize = toObservable(this.maxBufferSize).pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $itemConfigMap = toObservable(this.itemConfigMap).pipe(map(v => !v ? {} : v)), $snap = toObservable(this.snap), $isVertical = toObservable(this.direction).pipe(map(v => this.getIsVertical(v || DEFAULT_DIRECTION))), $dynamicSize = toObservable(this.dynamicSize), $enabledBufferOptimization = toObservable(this.enabledBufferOptimization), $snappingMethod = toObservable(this.snappingMethod).pipe(map(v => this.getIsSnappingMethodAdvanced(v || DEFAULT_SNAPPING_METHOD))), $methodForSelecting = toObservable(this.methodForSelecting), $selectedIds = toObservable(this.selectedIds), $collapsedIds = toObservable(this.collapsedIds).pipe(map(v => Array.isArray(v) ? v : [])), $collapsedItemIds = toObservable(this._collapsedItemIds).pipe(map(v => Array.isArray(v) ? v : [])), $actualItems = toObservable(this._actualItems), $cacheVersion = toObservable(this._cacheVersion);
2728
+ const $bounds = toObservable(this._bounds).pipe(filter(b => !!b)), $items = toObservable(this.items).pipe(map(i => !i ? [] : i)), $scrollSize = toObservable(this._scrollSize), $itemSize = toObservable(this.itemSize).pipe(map(v => v <= 0 ? DEFAULT_ITEM_SIZE : v)), $bufferSize = toObservable(this.bufferSize).pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $maxBufferSize = toObservable(this.maxBufferSize).pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $itemConfigMap = toObservable(this.itemConfigMap).pipe(map(v => !v ? {} : v)), $snap = toObservable(this.snap), $isVertical = toObservable(this.direction).pipe(map(v => this.getIsVertical(v || DEFAULT_DIRECTION))), $isLazy = toObservable(this.collectionMode).pipe(map(v => this.getIsLazy(v || DEFAULT_COLLECTION_MODE))), $dynamicSize = toObservable(this.dynamicSize), $enabledBufferOptimization = toObservable(this.enabledBufferOptimization), $snappingMethod = toObservable(this.snappingMethod).pipe(map(v => this.getIsSnappingMethodAdvanced(v || DEFAULT_SNAPPING_METHOD))), $methodForSelecting = toObservable(this.methodForSelecting), $selectedIds = toObservable(this.selectedIds), $collapsedIds = toObservable(this.collapsedIds).pipe(map(v => Array.isArray(v) ? v : [])), $collapsedItemIds = toObservable(this._collapsedItemIds).pipe(map(v => Array.isArray(v) ? v : [])), $actualItems = toObservable(this._actualItems), $cacheVersion = toObservable(this._cacheVersion);
2729
+ $isLazy.pipe(takeUntilDestroyed(), tap(v => {
2730
+ this._trackBox.isLazy = v;
2731
+ })).subscribe();
2636
2732
  combineLatest([$items, $itemSize]).pipe(takeUntilDestroyed(), map(([items, itemSize]) => ({ items, itemSize })), tap(({ items, itemSize }) => {
2637
2733
  this._trackBox.resetCollection(items, itemSize);
2638
2734
  })).subscribe();
@@ -2710,9 +2806,11 @@ class NgVirtualListComponent {
2710
2806
  this.resetBoundsSize(isVertical, totalSize);
2711
2807
  this.createDisplayComponentsIfNeed(displayItems);
2712
2808
  this.tracking();
2713
- const scrollLength = (this._isVertical ? this._container()?.nativeElement.scrollHeight ?? 0 : this._container()?.nativeElement.scrollWidth) ?? 0, actualScrollLength = scrollLength === 0 ? 0 : scrollLength - (this._isVertical ? height : width), scrollPosition = actualScrollSize + this._trackBox.delta;
2714
- this._isScrollStart.set(scrollPosition === 0);
2715
- this._isScrollFinished.set(scrollPosition === actualScrollLength);
2809
+ const scrollLength = (this._isVertical ? this._container()?.nativeElement.scrollHeight ?? 0 : this._container()?.nativeElement.scrollWidth) ?? 0, actualScrollLength = scrollLength === 0 ? 0 : Math.round(scrollLength - (this._isVertical ? height : width)), scrollPosition = actualScrollSize + this._trackBox.delta;
2810
+ if (actualScrollLength > 0) {
2811
+ this._isScrollStart.set(scrollPosition === 0);
2812
+ this._isScrollFinished.set(scrollPosition === actualScrollLength);
2813
+ }
2716
2814
  if (this._isSnappingMethodAdvanced) {
2717
2815
  this.updateRegularRenderer();
2718
2816
  }
@@ -2781,13 +2879,13 @@ class NgVirtualListComponent {
2781
2879
  }
2782
2880
  listenCacheChangesIfNeed(value) {
2783
2881
  if (value) {
2784
- if (!this._trackBox.hasEventListener(TRACK_BOX_CHANGE_EVENT_NAME, this._onTrackBoxChangeHandler)) {
2785
- this._trackBox.addEventListener(TRACK_BOX_CHANGE_EVENT_NAME, this._onTrackBoxChangeHandler);
2882
+ if (!this._trackBox.hasEventListener(TrackBoxEvents.CHANGE, this._onTrackBoxChangeHandler)) {
2883
+ this._trackBox.addEventListener(TrackBoxEvents.CHANGE, this._onTrackBoxChangeHandler);
2786
2884
  }
2787
2885
  }
2788
2886
  else {
2789
- if (this._trackBox.hasEventListener(TRACK_BOX_CHANGE_EVENT_NAME, this._onTrackBoxChangeHandler)) {
2790
- this._trackBox.removeEventListener(TRACK_BOX_CHANGE_EVENT_NAME, this._onTrackBoxChangeHandler);
2887
+ if (this._trackBox.hasEventListener(TrackBoxEvents.CHANGE, this._onTrackBoxChangeHandler)) {
2888
+ this._trackBox.removeEventListener(TrackBoxEvents.CHANGE, this._onTrackBoxChangeHandler);
2791
2889
  }
2792
2890
  }
2793
2891
  }
@@ -2811,6 +2909,10 @@ class NgVirtualListComponent {
2811
2909
  const dir = d || this.direction();
2812
2910
  return isDirection(dir, Directions.VERTICAL);
2813
2911
  }
2912
+ getIsLazy(m) {
2913
+ const mode = m || this.collectionMode();
2914
+ return isCollectionMode(mode, CollectionModes.LAZY);
2915
+ }
2814
2916
  createDisplayComponentsIfNeed(displayItems) {
2815
2917
  if (!displayItems || !this._listContainerRef) {
2816
2918
  this._trackBox.setDisplayObjectIndexMapById({});
@@ -3037,7 +3139,7 @@ class NgVirtualListComponent {
3037
3139
  }
3038
3140
  }
3039
3141
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NgVirtualListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3040
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: NgVirtualListComponent, selector: "ng-virtual-list", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, selectedIds: { classPropertyName: "selectedIds", publicName: "selectedIds", isSignal: true, isRequired: false, transformFunction: null }, collapsedIds: { classPropertyName: "collapsedIds", publicName: "collapsedIds", isSignal: true, isRequired: false, transformFunction: null }, selectByClick: { classPropertyName: "selectByClick", publicName: "selectByClick", isSignal: true, isRequired: false, transformFunction: null }, collapseByClick: { classPropertyName: "collapseByClick", publicName: "collapseByClick", isSignal: true, isRequired: false, transformFunction: null }, snap: { classPropertyName: "snap", publicName: "snap", isSignal: true, isRequired: false, transformFunction: null }, enabledBufferOptimization: { classPropertyName: "enabledBufferOptimization", publicName: "enabledBufferOptimization", isSignal: true, isRequired: false, transformFunction: null }, itemRenderer: { classPropertyName: "itemRenderer", publicName: "itemRenderer", isSignal: true, isRequired: true, transformFunction: null }, itemConfigMap: { classPropertyName: "itemConfigMap", publicName: "itemConfigMap", isSignal: true, isRequired: false, transformFunction: null }, itemSize: { classPropertyName: "itemSize", publicName: "itemSize", isSignal: true, isRequired: false, transformFunction: null }, dynamicSize: { classPropertyName: "dynamicSize", publicName: "dynamicSize", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, bufferSize: { classPropertyName: "bufferSize", publicName: "bufferSize", isSignal: true, isRequired: false, transformFunction: null }, maxBufferSize: { classPropertyName: "maxBufferSize", publicName: "maxBufferSize", isSignal: true, isRequired: false, transformFunction: null }, snappingMethod: { classPropertyName: "snappingMethod", publicName: "snappingMethod", isSignal: true, isRequired: false, transformFunction: null }, methodForSelecting: { classPropertyName: "methodForSelecting", publicName: "methodForSelecting", isSignal: true, isRequired: false, transformFunction: null }, trackBy: { classPropertyName: "trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onScroll: "onScroll", onScrollEnd: "onScrollEnd", onViewportChange: "onViewportChange", onItemClick: "onItemClick", onSelect: "onSelect", onCollapse: "onCollapse", onScrollReachStart: "onScrollReachStart", onScrollReachEnd: "onScrollReachEnd" }, host: { styleAttribute: "position: relative;" }, providers: [NgVirtualListService], viewQueries: [{ propertyName: "_snappedContainer", first: true, predicate: ["snapped"], descendants: true, isSignal: true }, { propertyName: "_container", first: true, predicate: ["container"], descendants: true, isSignal: true }, { propertyName: "_list", first: true, predicate: ["list"], descendants: true, isSignal: true }, { propertyName: "_listContainerRef", first: true, predicate: ["renderersContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_snapContainerRef", first: true, predicate: ["snapRendererContainer"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "@if (snap()) {\r\n <div #snapped part=\"snapped-item\" class=\"ngvl__list-snapper\">\r\n <ng-container #snapRendererContainer></ng-container>\r\n </div>\r\n}\r\n<div #container part=\"scroller\" class=\"ngvl__scroller\">\r\n <div [attr.aria-orientation]=\"orientation\" [attr.aria-activedescendant]=\"focusedElement()\" #list part=\"list\" class=\"ngvl__list\">\r\n <ng-container #renderersContainer></ng-container>\r\n </div>\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"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
3142
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: NgVirtualListComponent, selector: "ng-virtual-list", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, selectedIds: { classPropertyName: "selectedIds", publicName: "selectedIds", isSignal: true, isRequired: false, transformFunction: null }, collapsedIds: { classPropertyName: "collapsedIds", publicName: "collapsedIds", isSignal: true, isRequired: false, transformFunction: null }, selectByClick: { classPropertyName: "selectByClick", publicName: "selectByClick", isSignal: true, isRequired: false, transformFunction: null }, collapseByClick: { classPropertyName: "collapseByClick", publicName: "collapseByClick", isSignal: true, isRequired: false, transformFunction: null }, snap: { classPropertyName: "snap", publicName: "snap", isSignal: true, isRequired: false, transformFunction: null }, enabledBufferOptimization: { classPropertyName: "enabledBufferOptimization", publicName: "enabledBufferOptimization", isSignal: true, isRequired: false, transformFunction: null }, itemRenderer: { classPropertyName: "itemRenderer", publicName: "itemRenderer", isSignal: true, isRequired: true, transformFunction: null }, itemConfigMap: { classPropertyName: "itemConfigMap", publicName: "itemConfigMap", isSignal: true, isRequired: false, transformFunction: null }, itemSize: { classPropertyName: "itemSize", publicName: "itemSize", isSignal: true, isRequired: false, transformFunction: null }, dynamicSize: { classPropertyName: "dynamicSize", publicName: "dynamicSize", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, collectionMode: { classPropertyName: "collectionMode", publicName: "collectionMode", isSignal: true, isRequired: false, transformFunction: null }, bufferSize: { classPropertyName: "bufferSize", publicName: "bufferSize", isSignal: true, isRequired: false, transformFunction: null }, maxBufferSize: { classPropertyName: "maxBufferSize", publicName: "maxBufferSize", isSignal: true, isRequired: false, transformFunction: null }, snappingMethod: { classPropertyName: "snappingMethod", publicName: "snappingMethod", isSignal: true, isRequired: false, transformFunction: null }, methodForSelecting: { classPropertyName: "methodForSelecting", publicName: "methodForSelecting", isSignal: true, isRequired: false, transformFunction: null }, trackBy: { classPropertyName: "trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onScroll: "onScroll", onScrollEnd: "onScrollEnd", onViewportChange: "onViewportChange", onItemClick: "onItemClick", onSelect: "onSelect", onCollapse: "onCollapse", onScrollReachStart: "onScrollReachStart", onScrollReachEnd: "onScrollReachEnd" }, host: { styleAttribute: "position: relative;" }, providers: [NgVirtualListService], viewQueries: [{ propertyName: "_snappedContainer", first: true, predicate: ["snapped"], descendants: true, isSignal: true }, { propertyName: "_container", first: true, predicate: ["container"], descendants: true, isSignal: true }, { propertyName: "_list", first: true, predicate: ["list"], descendants: true, isSignal: true }, { propertyName: "_listContainerRef", first: true, predicate: ["renderersContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_snapContainerRef", first: true, predicate: ["snapRendererContainer"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "@if (snap()) {\r\n <div #snapped part=\"snapped-item\" class=\"ngvl__list-snapper\">\r\n <ng-container #snapRendererContainer></ng-container>\r\n </div>\r\n}\r\n<div #container part=\"scroller\" class=\"ngvl__scroller\">\r\n <div [attr.aria-orientation]=\"orientation\" [attr.aria-activedescendant]=\"focusedElement()\" #list part=\"list\" class=\"ngvl__list\">\r\n <ng-container #renderersContainer></ng-container>\r\n </div>\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"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
3041
3143
  }
3042
3144
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NgVirtualListComponent, decorators: [{
3043
3145
  type: Component,
@@ -3075,5 +3177,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
3075
3177
  * Generated bundle index. Do not edit.
3076
3178
  */
3077
3179
 
3078
- export { Directions, MethodsForSelecting, NgVirtualListComponent, NgVirtualListItemComponent, NgVirtualListModule, ScrollEvent, SnappingMethods, debounce, toggleClassName };
3180
+ export { CollectionModes, Directions, MethodsForSelecting, NgVirtualListComponent, NgVirtualListItemComponent, NgVirtualListModule, ScrollEvent, SnappingMethods, debounce, toggleClassName };
3079
3181
  //# sourceMappingURL=ng-virtual-list.mjs.map