ng-virtual-list 14.0.2 → 14.0.4

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.
@@ -552,10 +552,10 @@ class TrackBox extends CacheMap {
552
552
  const displayItems = this.generateDisplayCollection(items, stickyMap, metrics);
553
553
  return { displayItems, totalSize: metrics.totalSize, delta: metrics.delta };
554
554
  }
555
- getElementNumToEnd(i, collection, map, typicalItemSize, size, isVertical) {
555
+ getElementNumToEnd(i, collection, map, typicalItemSize, size, isVertical, indexOffset = 0) {
556
556
  const sizeProperty = isVertical ? HEIGHT_PROP_NAME : WIDTH_PROP_NAME;
557
557
  let offset = 0, num = 0;
558
- for (let j = collection.length - 1; j >= i; j--) {
558
+ for (let j = collection.length - indexOffset - 1; j >= i; j--) {
559
559
  const item = collection[j];
560
560
  let itemSize = 0;
561
561
  if (map.has(item.id)) {
@@ -578,13 +578,13 @@ class TrackBox extends CacheMap {
578
578
  */
579
579
  recalculateMetrics(options) {
580
580
  const { fromItemId, bounds, collection, dynamicSize, isVertical, itemSize, itemsOffset, scrollSize, snap, stickyMap } = options;
581
- 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, snippedPos = Math.floor(scrollSize), leftItemsWeights = [], isFromId = fromItemId !== undefined && (typeof fromItemId === 'number' && fromItemId > -1)
581
+ 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, checkOverscrollItemsLimit = Math.ceil(size / typicalItemSize), snippedPos = Math.floor(scrollSize), leftItemsWeights = [], isFromId = fromItemId !== undefined && (typeof fromItemId === 'number' && fromItemId > -1)
582
582
  || (typeof fromItemId === 'string' && fromItemId > '-1');
583
- let itemsFromStartToScrollEnd = -1, itemsFromDisplayEndToOffsetEnd = 0, itemsFromStartToDisplayEnd = -1, leftItemLength = 0, rightItemLength = 0, leftItemsWeight = 0, rightItemsWeight = 0, leftHiddenItemsWeight = 0, totalItemsToDisplayEndWeight = 0, itemById = undefined, itemByIdPos = 0, lastDisplayItemId = undefined, actualScrollSize = itemByIdPos, totalSize = 0, startIndex;
583
+ let itemsFromStartToScrollEnd = -1, itemsFromDisplayEndToOffsetEnd = 0, itemsFromStartToDisplayEnd = -1, leftItemLength = 0, rightItemLength = 0, leftItemsWeight = 0, rightItemsWeight = 0, leftHiddenItemsWeight = 0, totalItemsToDisplayEndWeight = 0, itemById = undefined, itemByIdPos = 0, targetDisplayItemIndex = -1, isTargetInOverscroll = false, actualScrollSize = itemByIdPos, totalSize = 0, startIndex;
584
584
  if (dynamicSize) {
585
585
  let y = 0, stickyCollectionItem = undefined, stickyComponentSize = 0;
586
586
  for (let i = 0, l = collection.length; i < l; i++) {
587
- const ii = i + 1, collectionItem = collection[i], map = this._map;
587
+ const ii = i + 1, collectionItem = collection[i];
588
588
  let componentSize = 0;
589
589
  if (map.has(collectionItem.id)) {
590
590
  const bounds = map.get(collectionItem.id);
@@ -601,9 +601,11 @@ class TrackBox extends CacheMap {
601
601
  stickyCollectionItem = collectionItem;
602
602
  }
603
603
  if (collectionItem.id === fromItemId) {
604
+ targetDisplayItemIndex = i;
604
605
  if (stickyCollectionItem && stickyMap && stickyMap[stickyCollectionItem.id] > 0) {
605
606
  const { num } = this.getElementNumToEnd(i, collection, map, typicalItemSize, size, isVertical);
606
607
  if (num > 0) {
608
+ isTargetInOverscroll = true;
607
609
  y -= size - componentSize;
608
610
  }
609
611
  else {
@@ -627,12 +629,10 @@ class TrackBox extends CacheMap {
627
629
  itemsFromStartToScrollEnd = ii;
628
630
  }
629
631
  if (isFromId) {
630
- if (!lastDisplayItemId) {
631
- if (itemById === undefined || y < itemByIdPos + size + componentSize) {
632
- itemsFromStartToDisplayEnd = ii;
633
- totalItemsToDisplayEndWeight += componentSize;
634
- itemsFromDisplayEndToOffsetEnd = itemsFromStartToDisplayEnd + itemsOffset;
635
- }
632
+ if (itemById === undefined || y < itemByIdPos + size + componentSize) {
633
+ itemsFromStartToDisplayEnd = ii;
634
+ totalItemsToDisplayEndWeight += componentSize;
635
+ itemsFromDisplayEndToOffsetEnd = itemsFromStartToDisplayEnd + itemsOffset;
636
636
  }
637
637
  }
638
638
  else if (y < scrollSize + size + componentSize) {
@@ -645,10 +645,16 @@ class TrackBox extends CacheMap {
645
645
  }
646
646
  y += componentSize;
647
647
  }
648
- if (itemsFromStartToScrollEnd === -1) {
648
+ if (isTargetInOverscroll) {
649
+ const { num } = this.getElementNumToEnd(collection.length - (checkOverscrollItemsLimit < 0 ? 0 : collection.length - checkOverscrollItemsLimit), collection, map, typicalItemSize, size, isVertical, collection.length - (collection.length - (targetDisplayItemIndex + 1)));
650
+ if (num > 0) {
651
+ itemsFromStartToScrollEnd -= num;
652
+ }
653
+ }
654
+ if (itemsFromStartToScrollEnd <= -1) {
649
655
  itemsFromStartToScrollEnd = 0;
650
656
  }
651
- if (itemsFromStartToDisplayEnd === -1) {
657
+ if (itemsFromStartToDisplayEnd <= -1) {
652
658
  itemsFromStartToDisplayEnd = 0;
653
659
  }
654
660
  actualScrollSize = isFromId ? itemByIdPos : scrollSize;
@@ -879,6 +885,38 @@ class TrackBox extends CacheMap {
879
885
  }
880
886
  }
881
887
 
888
+ class ScrollEvent {
889
+ constructor(direction, container, list, delta, isVertical) {
890
+ this._direction = 1;
891
+ this._scrollSize = 0;
892
+ this._scrollWeight = 0;
893
+ this._isVertical = true;
894
+ this._listSize = 0;
895
+ this._size = 0;
896
+ this._isStart = true;
897
+ this._isEnd = false;
898
+ this._delta = 0;
899
+ this._direction = direction;
900
+ this._isVertical = isVertical;
901
+ this._scrollSize = isVertical ? container.scrollTop : container.scrollLeft;
902
+ this._scrollWeight = isVertical ? container.scrollHeight : container.scrollWidth;
903
+ this._listSize = isVertical ? list.offsetHeight : list.offsetWidth;
904
+ this._size = isVertical ? container.offsetHeight : container.offsetWidth;
905
+ this._isEnd = (this._scrollSize + this._size) === this._scrollWeight;
906
+ this._delta = delta;
907
+ this._isStart = this._scrollSize === 0;
908
+ }
909
+ get direction() { return this._direction; }
910
+ get scrollSize() { return this._scrollSize; }
911
+ get scrollWeight() { return this._scrollWeight; }
912
+ get isVertical() { return this._isVertical; }
913
+ get listSize() { return this._listSize; }
914
+ get size() { return this._size; }
915
+ get isStart() { return this._isStart; }
916
+ get isEnd() { return this._isEnd; }
917
+ get delta() { return this._delta; }
918
+ }
919
+
882
920
  /**
883
921
  * Base disposable component
884
922
  * @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/disposableComponent.ts
@@ -961,10 +999,11 @@ class NgVirtualListComponent extends DisposableComponent {
961
999
  this._$bounds.next(this._container?.nativeElement?.getBoundingClientRect() ?? null);
962
1000
  };
963
1001
  this._onScrollHandler = (e) => {
1002
+ this.clearScrollToRepeatExecutionTimeout();
964
1003
  const container = this._container?.nativeElement;
965
1004
  if (container) {
966
1005
  const dynamicSize = this.dynamicSize, delta = this._trackBox.delta, scrollSize = (this._isVertical ? container.scrollTop : container.scrollLeft), previouseScrollSize = this._$scrollSize.getValue();
967
- let actualScrollSize = scrollSize;
1006
+ let actualScrollSize = scrollSize, isImmediateScroll = false;
968
1007
  this._trackBox.deltaDirection = previouseScrollSize > scrollSize ? -1 : 1;
969
1008
  if (dynamicSize && delta !== 0) {
970
1009
  actualScrollSize = scrollSize + delta;
@@ -974,12 +1013,19 @@ class NgVirtualListComponent extends DisposableComponent {
974
1013
  };
975
1014
  const container = this._container;
976
1015
  if (container) {
977
- this.scrollImmediately(container, params);
1016
+ isImmediateScroll = true;
1017
+ this.scrollImmediately(container, params, () => {
1018
+ const event = new ScrollEvent(this._trackBox.scrollDirection, container.nativeElement, this._list.nativeElement, delta, this._isVertical);
1019
+ this.onScroll.emit(event);
1020
+ });
978
1021
  this._trackBox.clearDelta();
979
1022
  }
980
1023
  }
981
1024
  this._$scrollSize.next(actualScrollSize);
982
- this.onScroll.emit({ scrollSize: actualScrollSize, direction: this._trackBox.scrollDirection });
1025
+ if (!isImmediateScroll) {
1026
+ const event = new ScrollEvent(this._trackBox.scrollDirection, container, this._list.nativeElement, delta, this._isVertical);
1027
+ this.onScroll.emit(event);
1028
+ }
983
1029
  }
984
1030
  };
985
1031
  this._scrollImmediatelyHandler = undefined;
@@ -990,6 +1036,7 @@ class NgVirtualListComponent extends DisposableComponent {
990
1036
  this._trackBox.clearDeltaDirection();
991
1037
  const itemSize = this.itemSize, snapToItem = this.snapToItem, dynamicSize = this.dynamicSize, delta = this._trackBox.delta, scrollSize = (this._isVertical ? container.nativeElement.scrollTop : container.nativeElement.scrollLeft);
992
1038
  let actualScrollSize = scrollSize;
1039
+ const event = new ScrollEvent(this._trackBox.scrollDirection, container.nativeElement, this._list.nativeElement, delta, this._isVertical);
993
1040
  if (dynamicSize && delta !== 0) {
994
1041
  actualScrollSize = scrollSize + delta;
995
1042
  if (scrollSize !== actualScrollSize) {
@@ -1014,7 +1061,7 @@ class NgVirtualListComponent extends DisposableComponent {
1014
1061
  }
1015
1062
  }
1016
1063
  this._$scrollSize.next(actualScrollSize);
1017
- this.onScroll.emit({ scrollSize: actualScrollSize, direction: this._trackBox.scrollDirection });
1064
+ this.onScrollEnd.emit(event);
1018
1065
  }
1019
1066
  };
1020
1067
  this._$initialized = new BehaviorSubject(false);
@@ -1176,13 +1223,16 @@ class NgVirtualListComponent extends DisposableComponent {
1176
1223
  }
1177
1224
  ;
1178
1225
  get itemsOffset() { return this._$itemsOffset.getValue(); }
1179
- scrollImmediately(container, params) {
1226
+ scrollImmediately(container, params, cb) {
1180
1227
  this.clearScrollImmediately();
1181
1228
  container.nativeElement.removeEventListener(SCROLL_END, this._onScrollEndHandler);
1182
1229
  const handler = () => {
1183
1230
  if (container) {
1184
1231
  container.nativeElement.removeEventListener(SCROLL_END, handler);
1185
1232
  container.nativeElement.scroll(params);
1233
+ if (cb !== undefined) {
1234
+ cb();
1235
+ }
1186
1236
  container.nativeElement.addEventListener(SCROLL_END, this._onScrollEndHandler);
1187
1237
  }
1188
1238
  };
@@ -1312,7 +1362,8 @@ class NgVirtualListComponent extends DisposableComponent {
1312
1362
  }
1313
1363
  else {
1314
1364
  this._$scrollSize.next(scrollSize);
1315
- this.onScroll.emit({ scrollSize, direction: this._trackBox.scrollDirection });
1365
+ const event = new ScrollEvent(this._trackBox.scrollDirection, container.nativeElement, this._list.nativeElement, this._trackBox.delta, this._isVertical);
1366
+ this.onScroll.emit(event);
1316
1367
  container.nativeElement.addEventListener(SCROLL, this._onScrollHandler);
1317
1368
  container.nativeElement.addEventListener(SCROLL_END, this._onScrollEndHandler);
1318
1369
  }