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.
- package/LICENSE +21 -0
- package/README.md +26 -0
- package/esm2020/lib/models/scroll-event.model.mjs +1 -1
- package/esm2020/lib/ng-virtual-list.component.mjs +23 -9
- package/esm2020/lib/utils/index.mjs +3 -3
- package/esm2020/lib/utils/scrollEvent.mjs +32 -0
- package/esm2020/lib/utils/trackBox.mjs +20 -14
- package/fesm2015/ng-virtual-list.mjs +70 -19
- package/fesm2015/ng-virtual-list.mjs.map +1 -1
- package/fesm2020/ng-virtual-list.mjs +70 -19
- package/fesm2020/ng-virtual-list.mjs.map +1 -1
- package/lib/models/scroll-event.model.d.ts +4 -0
- package/lib/ng-virtual-list.component.d.ts +2 -2
- package/lib/utils/index.d.ts +2 -2
- package/lib/utils/scrollEvent.d.ts +22 -0
- package/package.json +1 -1
|
@@ -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,
|
|
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]
|
|
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 (
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
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 (
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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
|
}
|