ng-virtual-list 22.12.0 → 22.12.2

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/README.md CHANGED
@@ -612,11 +612,7 @@ Inputs
612
612
  | itemSize | number \| 'viewport' = 24 | If direction = 'vertical', then the height of a typical element. If direction = 'horizontal', then the width of a typical element. If the dynamicSize property is true, the items in the list can have different sizes, and you must specify the itemSize property to adjust the sizes of the items in the unallocated area. If the value is 'viewport', the sizes of elements are automatically resized to fit the viewport size. |
613
613
  | itemTransform | [ItemTransform](https://github.com/DjonnyX/ng-virtual-list/blob/22.x/projects/ng-virtual-list/src/lib/types/item-transform.ts) \| null = null | Custom transformation of element's position, rotation, scale, opacity and zIndex. The default value is `null`. |
614
614
  | itemRenderer | TemplateRef | Rendering element template. |
615
- | itemConfigMap | [IVirtualListItemConfigMap?](https://github.com/DjonnyX/ng-virtual-list/blob/22.x/projects/ng-virtual-list/src/lib/models/item-config-map.model.ts) | Sets `sticky` position, `fullSize`, `collapsable` and `selectable` for the list item element. If `sticky` position is greater than `0`, then `sticky` position is applied.
616
- If the `sticky` value is greater than `0`, then the `sticky` position mode is enabled for the element. `1` - position start, `2` - position end. Default value is `0`.
617
- `selectable` determines whether an element can be selected or not. Default value is `true`.
618
- `collapsable` determines whether an element with a `sticky` property greater than zero can collapse and collapse elements in front that do not have a `sticky` property.
619
- `fullSize` determines the size of an element when rendering lists with cell divisions. If sticky is 1 or 2, fullSize automatically becomes true. The default value is false. |
615
+ | itemConfigMap | [IVirtualListItemConfigMap?](https://github.com/DjonnyX/ng-virtual-list/blob/22.x/projects/ng-virtual-list/src/lib/models/item-config-map.model.ts) | Sets `sticky` position, `fullSize`, `collapsable` and `selectable` for the list item element. If `sticky` position is greater than `0`, then `sticky` position is applied. If the `sticky` value is greater than `0`, then the `sticky` position mode is enabled for the element. `1` - position start, `2` - position end. Default value is `0`. `selectable` determines whether an element can be selected or not. Default value is `true`. `collapsable` determines whether an element with a `sticky` property greater than zero can collapse and collapse elements in front that do not have a `sticky` property. `fullSize` determines the size of an element when rendering lists with cell divisions. If sticky is 1 or 2, fullSize automatically becomes true. The default value is false. |
620
616
  | langTextDir | [TextDirection? = 'ltr'](https://github.com/DjonnyX/ng-virtual-list/blob/22.x/projects/ng-virtual-list/src/lib/enums/text-direction.ts) | A string indicating the direction of text for the locale. Can be either "ltr" (left-to-right) or "rtl" (right-to-left). |
621
617
  | loading | boolean? = false | If `true`, the scrollBar goes into loading state. The default value is `false`. |
622
618
  | maxBufferSize | number? = 10 | Maximum number of elements outside the scope of visibility. Default value is 10. If maxBufferSize is set to be greater than bufferSize, then adaptive buffer mode is enabled. The greater the scroll size, the more elements are allocated for rendering. |
@@ -730,25 +726,20 @@ import { NgVirtualListModule, VirtualClickModule } from 'ng-virtual-list';
730
726
  </ng-template>
731
727
  ```
732
728
 
729
+ <br/>
730
+
733
731
  ## 📦 Previous versions
734
732
 
735
733
  | Angular version | ng-virtual-list version | git | npm |
736
734
  |--|--|--|--|
737
- | 21.x | 21.12.0 | [20.x](https://github.com/DjonnyX/ng-virtual-list/tree/21.x) | [21.12.0](https://www.npmjs.com/package/ng-virtual-list/v/21.12.0) |
738
- | 20.x | 20.12.0 | [20.x](https://github.com/DjonnyX/ng-virtual-list/tree/20.x) | [20.12.0](https://www.npmjs.com/package/ng-virtual-list/v/20.12.0) |
739
- | 19.x | 19.12.0 | [19.x](https://github.com/DjonnyX/ng-virtual-list/tree/19.x) | [19.12.0](https://www.npmjs.com/package/ng-virtual-list/v/19.12.0) |
740
- | 18.x | 18.12.0 | [18.x](https://github.com/DjonnyX/ng-virtual-list/tree/18.x) | [18.12.0](https://www.npmjs.com/package/ng-virtual-list/v/18.12.0) |
741
- | 17.x | 17.12.0 | [17.x](https://github.com/DjonnyX/ng-virtual-list/tree/17.x) | [17.12.0](https://www.npmjs.com/package/ng-virtual-list/v/17.12.0) |
742
- | 16.x | 16.12.0 | [16.x](https://github.com/DjonnyX/ng-virtual-list/tree/16.x) | [16.12.0](https://www.npmjs.com/package/ng-virtual-list/v/16.12.0) |
743
- | 15.x | 15.12.0 | [15.x](https://github.com/DjonnyX/ng-virtual-list/tree/15.x) | [15.12.0](https://www.npmjs.com/package/ng-virtual-list/v/15.12.0) |
744
- | 14.x | 14.12.0 | [14.x](https://github.com/DjonnyX/ng-virtual-list/tree/14.x) | [14.12.0](https://www.npmjs.com/package/ng-virtual-list/v/14.12.0) |
745
- <br/>
746
-
747
- ## 🤝 Contributing
748
-
749
- PRs and feature requests are welcome!
750
- Open an issue or start a discussion to shape the future of [ng-virtual-list](https://github.com/DjonnyX/ng-virtual-list/).
751
- Try it out, star ⭐ the repo, and let us know what you’re building.
735
+ | 21.x | 21.12.2 | [20.x](https://github.com/DjonnyX/ng-virtual-list/tree/21.x) | [21.12.2](https://www.npmjs.com/package/ng-virtual-list/v/21.12.2) |
736
+ | 20.x | 20.12.2 | [20.x](https://github.com/DjonnyX/ng-virtual-list/tree/20.x) | [20.12.2](https://www.npmjs.com/package/ng-virtual-list/v/20.12.2) |
737
+ | 19.x | 19.12.2 | [19.x](https://github.com/DjonnyX/ng-virtual-list/tree/19.x) | [19.12.2](https://www.npmjs.com/package/ng-virtual-list/v/19.12.2) |
738
+ | 18.x | 18.12.2 | [18.x](https://github.com/DjonnyX/ng-virtual-list/tree/18.x) | [18.12.2](https://www.npmjs.com/package/ng-virtual-list/v/18.12.2) |
739
+ | 17.x | 17.12.2 | [17.x](https://github.com/DjonnyX/ng-virtual-list/tree/17.x) | [17.12.2](https://www.npmjs.com/package/ng-virtual-list/v/17.12.2) |
740
+ | 16.x | 16.12.2 | [16.x](https://github.com/DjonnyX/ng-virtual-list/tree/16.x) | [16.12.2](https://www.npmjs.com/package/ng-virtual-list/v/16.12.2) |
741
+ | 15.x | 15.12.2 | [15.x](https://github.com/DjonnyX/ng-virtual-list/tree/15.x) | [15.12.2](https://www.npmjs.com/package/ng-virtual-list/v/15.12.2) |
742
+ | 14.x | 14.12.2 | [14.x](https://github.com/DjonnyX/ng-virtual-list/tree/14.x) | [14.12.2](https://www.npmjs.com/package/ng-virtual-list/v/14.12.2) |
752
743
 
753
744
  <br/>
754
745
 
@@ -1775,7 +1775,7 @@ class ScrollEvent {
1775
1775
 
1776
1776
  /**
1777
1777
  * Event emitter
1778
- * @link https://github.com/DjonnyX/data-channel-router/blob/main/library/src/utils/event-emitter/event-emitter.ts
1778
+ * @link https://github.com/DjonnyX/ng-virtual-list/blob/main/library/src/utils/event-emitter/event-emitter.ts
1779
1779
  * @author Evgenii Alexandrovich Grebennikov
1780
1780
  * @email djonnyx@gmail.com
1781
1781
  */
@@ -2078,7 +2078,7 @@ class Tracker {
2078
2078
  }
2079
2079
  const untrackedItems = [...components], newTrackItems = [], untrackedComponentsByTypeMap = {}, isDown = direction === 0 || direction === 1, snapped = !!snappedComponents ? [...snappedComponents] : [];
2080
2080
  let isRegularSnapped = false;
2081
- const serviceIdProp = getServiceIdProp(trackBy);
2081
+ const serviceIdProp = getServiceIdProp(trackBy), snappedItems = new Array();
2082
2082
  for (let i = isDown ? 0 : items.length - 1, l = isDown ? items.length : 0; isDown ? i < l : i >= l; isDown ? i++ : i--) {
2083
2083
  const item = items[i], isDummy = item?.data?.[SERVICE_PROP_DUMMY] && (item?.data?.[SERVICE_PROP_DUMMY] === SERVICE_PROP_DUMMY_ENABLED);
2084
2084
  if (isDummy) {
@@ -2101,6 +2101,7 @@ class Tracker {
2101
2101
  isRegularSnapped = true;
2102
2102
  snappedComponent.instance.item = item;
2103
2103
  snappedComponent.instance.show();
2104
+ snappedItems.push(snappedComponent);
2104
2105
  }
2105
2106
  }
2106
2107
  }
@@ -2166,6 +2167,7 @@ class Tracker {
2166
2167
  if (!!snappedComponent) {
2167
2168
  snappedComponent.instance.item = item;
2168
2169
  snappedComponent.instance.show();
2170
+ snappedItems.push(snappedComponent);
2169
2171
  }
2170
2172
  }
2171
2173
  }
@@ -2196,13 +2198,14 @@ class Tracker {
2196
2198
  comp.instance.hide();
2197
2199
  }
2198
2200
  }
2199
- if (!isRegularSnapped) {
2200
- for (let i = 0, l = snapped.length; i < l; i++) {
2201
- const snappedComponent = snapped[i];
2202
- if (!!snappedComponent) {
2203
- snappedComponent.instance.item = null;
2204
- snappedComponent.instance.hide();
2205
- }
2201
+ for (let i = 0, l = snapped.length; i < l; i++) {
2202
+ const snappedComponent = snapped[i];
2203
+ if (snappedItems.indexOf(snappedComponent) > -1) {
2204
+ continue;
2205
+ }
2206
+ if (!!snappedComponent) {
2207
+ snappedComponent.instance.item = null;
2208
+ snappedComponent.instance.hide();
2206
2209
  }
2207
2210
  }
2208
2211
  }
@@ -2682,7 +2685,7 @@ class TrackBox extends CacheMap {
2682
2685
  * Calculates list metrics
2683
2686
  */
2684
2687
  recalculateMetrics(options) {
2685
- const { fromItemId, bounds, collection, dynamicSize, isVertical, itemSize, minItemSize, maxItemSize, bufferSize: minBufferSize, scrollSize, stickyEnabled, itemConfigMap, enabledBufferOptimization, previousTotalSize, snapToItem, snapToItemAlign, deletedItemsMap, itemTransform } = options, roundedScrollSize = Math.round(scrollSize);
2688
+ const { alignment, fromItemId, bounds, collection, dynamicSize, isVertical, itemSize, minItemSize, maxItemSize, bufferSize: minBufferSize, scrollSize, stickyEnabled, itemConfigMap, enabledBufferOptimization, previousTotalSize, snapToItem, snapToItemAlign, deletedItemsMap, itemTransform } = options, roundedScrollSize = Math.round(scrollSize);
2686
2689
  const trackBy = this._trackingPropertyName, 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, divides = this._divides, stickyPos = Math.floor(scrollSize) + this._scrollStartOffset, leftItemsOrRowsWeights = [], isFromId = fromItemId !== undefined && (typeof fromItemId === 'number' && fromItemId > -1)
2687
2690
  || (typeof fromItemId === 'string' && fromItemId > '-1');
2688
2691
  let leftItemsOffset = 0, rightItemsOffset = 0;
@@ -2822,15 +2825,17 @@ class TrackBox extends CacheMap {
2822
2825
  }
2823
2826
  if (id == fromItemId) {
2824
2827
  isFromItemIdFound = true;
2825
- const { num, offset } = this.getElementNumToEnd(i, collection, map, typicalItemSize, size, isVertical), leftViewportSize = size - offset;
2826
- if (leftViewportSize > 0) {
2827
- const { num: num1, offset: offset1 } = this.getElementNumToEnd(i + num, collection, map, typicalItemSize, size, isVertical, 0, true), deltaNum = (num1 - num), deltaOffset = (offset1 - offset);
2828
- totalItemsToDisplayEndWeight += offset;
2829
- itemsFromStartToScrollEnd -= deltaNum;
2830
- rightItemsWeight = rightItemLength = 0;
2831
- leftHiddenItemsWeight -= deltaOffset;
2832
- leftItemsOrRowsWeights.splice(leftItemsOrRowsWeights.length - deltaNum, deltaNum);
2833
- y -= deltaOffset;
2828
+ if (alignment !== Alignments.CENTER) {
2829
+ const { num, offset } = this.getElementNumToEnd(i, collection, map, typicalItemSize, size, isVertical), leftViewportSize = size - offset;
2830
+ if (leftViewportSize > 0) {
2831
+ const { num: num1, offset: offset1 } = this.getElementNumToEnd(i + num, collection, map, typicalItemSize, size, isVertical, 0, true), deltaNum = (num1 - num), deltaOffset = (offset1 - offset);
2832
+ totalItemsToDisplayEndWeight += offset;
2833
+ itemsFromStartToScrollEnd -= deltaNum;
2834
+ rightItemsWeight = rightItemLength = 0;
2835
+ leftHiddenItemsWeight -= deltaOffset;
2836
+ leftItemsOrRowsWeights.splice(leftItemsOrRowsWeights.length - deltaNum, deltaNum);
2837
+ y -= deltaOffset;
2838
+ }
2834
2839
  }
2835
2840
  itemById = collectionItem;
2836
2841
  itemByIdPos = y;
@@ -3017,7 +3022,7 @@ class TrackBox extends CacheMap {
3017
3022
  rightItemsWeight = Math.floor(rightItemLength * dividedTypicalItemSize / typicalItemSize) * typicalItemSize;
3018
3023
  leftHiddenItemsWeight = Math.floor(itemsFromStartToScrollEnd * dividedTypicalItemSize / typicalItemSize) * typicalItemSize;
3019
3024
  totalItemsToDisplayEndWeight = Math.floor(itemsFromStartToDisplayEnd * dividedTypicalItemSize / typicalItemSize) * typicalItemSize;
3020
- totalSize = (totalLength * dividedTypicalItemSize) + this._scrollStartOffset + this._scrollEndOffset;
3025
+ totalSize = (Math.ceil(totalLength / divides) * divides * dividedTypicalItemSize) + this._scrollStartOffset + this._scrollEndOffset;
3021
3026
  const k = totalSize !== 0 ? previousTotalSize / totalSize : 0;
3022
3027
  if (isFromId) {
3023
3028
  const index = collection.findIndex(item => item[trackBy] == fromItemId);
@@ -3393,7 +3398,7 @@ class TrackBox extends CacheMap {
3393
3398
  }
3394
3399
  if (!isDummy) {
3395
3400
  if ((isSnappingMethodAdvanced || id !== stickyItem?.id) && id !== endStickyItem?.id) {
3396
- const isOdd = (items.length - layoutIndexOffset + i) % 2 != 0, sticky = itemConfigMap[id]?.sticky ?? 0, fullSize = itemConfigMap[id]?.fullSize ?? false, selectable = itemConfigMap[id]?.selectable ?? true, collapsable = itemConfigMap[id]?.collapsable ?? false, snapped = stickyEnabled && (sticky === 1 && (pos <= scrollSize + this._scrollStartOffset) || sticky === 2 && (pos >= scrollSize + boundsSize - size)), absoluteStartPosition = pos - scrollSize, ratio = size !== 0 ? boundsSize / size : 0, absoluteStartPositionPercent = -(boundsSize !== 0 ? absoluteStartPosition / boundsSize : 0) * ratio, absoluteEndPosition = boundsSize - (absoluteStartPositionPercent + size), absoluteEndPositionPercent = (absoluteStartPositionPercent + (boundsSize !== 0 ? (absoluteEndPosition + size) / boundsSize : 0) * ratio), x = isVertical ? divSize * ((sticky || fullSize) ? 0 : ci) : pos, y = isVertical ? pos : divSize * ((sticky || fullSize) ? 0 : ci), measures = {
3401
+ const isOdd = (items.length - layoutIndexOffset + i) % 2 != 0, sticky = itemConfigMap[id]?.sticky ?? 0, fullSize = itemConfigMap[id]?.fullSize ?? false, selectable = itemConfigMap[id]?.selectable ?? true, collapsable = itemConfigMap[id]?.collapsable ?? false, snapped = stickyEnabled && ((sticky === 1 && (pos <= scrollSize + this._scrollStartOffset)) || (sticky === 2 && (pos >= scrollSize + boundsSize - size))), absoluteStartPosition = pos - scrollSize, ratio = size !== 0 ? boundsSize / size : 0, absoluteStartPositionPercent = -(boundsSize !== 0 ? absoluteStartPosition / boundsSize : 0) * ratio, absoluteEndPosition = boundsSize - (absoluteStartPositionPercent + size), absoluteEndPositionPercent = (absoluteStartPositionPercent + (boundsSize !== 0 ? (absoluteEndPosition + size) / boundsSize : 0) * ratio), x = isVertical ? divSize * ((sticky || fullSize) ? 0 : ci) : pos, y = isVertical ? pos : divSize * ((sticky || fullSize) ? 0 : ci), measures = {
3397
3402
  x,
3398
3403
  y,
3399
3404
  transformedX: x,
@@ -3421,7 +3426,7 @@ class TrackBox extends CacheMap {
3421
3426
  maxWidth: maxItemSize,
3422
3427
  maxHeight: maxItemSize,
3423
3428
  scrollDirection,
3424
- delta: sticky === 1 ? actualSnippedPosition : sticky === 2 ? actualEndSnippedPosition - deltaOffet - size : 0,
3429
+ delta: sticky === 1 ? actualSnippedPosition : (sticky === 2 ? (actualEndSnippedPosition - deltaOffet - size) : 0),
3425
3430
  }, config = {
3426
3431
  isFirst: i === layoutIndexOffset,
3427
3432
  isLast: i === li,
@@ -3431,7 +3436,7 @@ class TrackBox extends CacheMap {
3431
3436
  isVertical,
3432
3437
  collapsable,
3433
3438
  selectable,
3434
- sticky: sticky,
3439
+ sticky,
3435
3440
  snap: stickyEnabled,
3436
3441
  snapped: false,
3437
3442
  snappedOut: false,
@@ -3484,9 +3489,9 @@ class TrackBox extends CacheMap {
3484
3489
  i++;
3485
3490
  }
3486
3491
  const axis = isVertical ? Y_PROP_NAME : X_PROP_NAME;
3487
- if (!!nextSticky && !!stickyItem && nextSticky.measures[axis] <= actualSnippedPosition + stickyItemSize) {
3488
- if (nextSticky.measures[axis] > scrollSize - stickyItemSize) {
3489
- stickyItem.measures[axis] = nextSticky.measures[axis] - stickyItemSize;
3492
+ if (!!nextSticky && !!stickyItem && nextSticky.measures[axis] <= actualSnippedPosition + stickyItem.measures[sizeProperty]) {
3493
+ if (nextSticky.measures[axis] > actualSnippedPosition) {
3494
+ stickyItem.measures[axis] = nextSticky.measures[axis] - stickyItem.measures[sizeProperty];
3490
3495
  stickyItem.config.snapped = nextSticky.config.snapped = false;
3491
3496
  stickyItem.config.snappedOut = true;
3492
3497
  stickyItem.config.sticky = 1;
@@ -3495,7 +3500,8 @@ class TrackBox extends CacheMap {
3495
3500
  else {
3496
3501
  nextSticky.config.snapped = true;
3497
3502
  nextSticky.measures.delta = (isVertical ? nextSticky.measures.y : nextSticky.measures.x) - scrollSize;
3498
- stickyItem.measures[axis] = stickyItem.measures[axis] + stickyItem.measures[sizeProperty];
3503
+ stickyItem.measures[axis] = nextSticky.measures[axis] - stickyItem.measures[sizeProperty];
3504
+ stickyItem.measures.delta = (isVertical ? stickyItem.measures.y : stickyItem.measures.x) - scrollSize;
3499
3505
  }
3500
3506
  }
3501
3507
  if (!!nextEndSticky && !!endStickyItem &&
@@ -3512,6 +3518,7 @@ class TrackBox extends CacheMap {
3512
3518
  nextEndSticky.measures[axis] = actualEndSnippedPosition - nextEndSticky.measures[sizeProperty];
3513
3519
  nextEndSticky.measures.delta = (isVertical ? nextEndSticky.measures.y : nextEndSticky.measures.x) - scrollSize;
3514
3520
  endStickyItem.measures[axis] = nextEndSticky.measures[axis] + nextEndSticky.measures[sizeProperty];
3521
+ endStickyItem.measures.delta = (isVertical ? endStickyItem.measures.y : endStickyItem.measures.x) - scrollSize;
3515
3522
  }
3516
3523
  }
3517
3524
  if (itemTransform !== null) {
@@ -3967,7 +3974,7 @@ const easeLinear = (t) => {
3967
3974
 
3968
3975
  /**
3969
3976
  * Animator
3970
- * @link https://github.com/DjonnyX/data-channel-router/blob/main/library/src/utils/animator/animator.ts
3977
+ * @link https://github.com/DjonnyX/ng-virtual-list/blob/main/library/src/utils/animator/animator.ts
3971
3978
  * @author Evgenii Alexandrovich Grebennikov
3972
3979
  * @email djonnyx@gmail.com
3973
3980
  */
@@ -4044,7 +4051,7 @@ class Animator {
4044
4051
  const SCROLL_VIEW_INVERSION = new InjectionToken('ScrollViewInversion');
4045
4052
  const SCROLL_VIEW_OVERSCROLL_ENABLED = new InjectionToken('ScrollViewOverscrollEnabled');
4046
4053
  const SCROLL_VIEW_NORMALIZE_VALUE_FROM_ZERO = new InjectionToken('ScrollViewNormalizeValueFromZero');
4047
- const TOP$1 = 'top', LEFT$1 = 'left', INSTANT$1 = 'instant', AUTO = 'auto', SMOOTH = 'smooth', DURATION = 2000, FRICTION_FORCE = .035, MAX_DURATION = 4000, ANIMATION_DURATION = 50, MASS = .005, MAX_DIST = 12500, MAX_VELOCITY_TIMESTAMP = 100, SPEED_SCALE = 15, OVERSCROLL_START_ITERATION = 2, INTERSECTION_DISTANCE = 1;
4054
+ const TOP$1 = 'top', LEFT$1 = 'left', INSTANT$1 = 'instant', AUTO = 'auto', SMOOTH = 'smooth', DURATION = 2000, FRICTION_FORCE = .035, MAX_DURATION = 4000, ANIMATION_DURATION = 50, MASS = .005, ACCELERATION_SCALE = 40, MAX_DIST = 12500, MAX_VELOCITY_TIMESTAMP = 100, SPEED_SCALE = 15, OVERSCROLL_START_ITERATION = 2;
4048
4055
  const MAX_ITERATIONS_FOR_AVERAGE_CALCULATIONS = 5, INSTANT_VELOCITY_SCALE = 1000;
4049
4056
  const SCROLL_EVENT$1 = new Event(SCROLLER_SCROLL);
4050
4057
 
@@ -4821,8 +4828,8 @@ class NgScrollView extends BaseScrollView {
4821
4828
  continue;
4822
4829
  }
4823
4830
  if (v00) {
4824
- const a0 = timestamp < MAX_VELOCITY_TIMESTAMP ? (v00[1] !== 0 ? (lastVSign * Math.abs(Math.abs(v01[0]) - Math.abs(v00[0]))) / Math.abs(v00[1]) : 0) : 0.1;
4825
- aSum = (aSum * mass) + a0;
4831
+ const a0 = timestamp < MAX_VELOCITY_TIMESTAMP ? (v00[1] !== 0 ? (lastVSign * Math.abs(Math.abs(v01[0]) - Math.abs(v00[0]))) / Math.abs(v00[1]) : 0) : .1;
4832
+ aSum = Math.abs((aSum * mass)) + Math.abs(a0);
4826
4833
  prevV0 = v01;
4827
4834
  }
4828
4835
  prevV0 = v01;
@@ -4843,7 +4850,7 @@ class NgScrollView extends BaseScrollView {
4843
4850
  }
4844
4851
  moveWithAcceleration(isVertical, position, v0, v, a0, timestamp) {
4845
4852
  if (a0 !== 0 && timestamp < MAX_VELOCITY_TIMESTAMP) {
4846
- const dvSign = Math.sign(v), mass = this.scrollingSettings()?.mass ?? MASS, duration = DURATION, maxDuration = this.scrollingSettings()?.maxDuration ?? MAX_DURATION, maxDist = this.scrollingSettings()?.maxDistance ?? MAX_DIST, maxDistance = dvSign * maxDist, s = (dvSign * Math.abs((a0 * Math.pow(duration, 2)) * .5) / 1000) / mass, distance = Math.abs(s) < maxDist ? s : maxDistance, positionWithVelocity = position + (this._inversion ? -1 : 1) * distance, vmax = Math.max(Math.abs(v0), Math.abs(v)), ad = Math.abs(vmax !== 0 ? Math.sqrt(vmax) : 0) * 10 / mass, aDuration = ad < maxDuration ? ad : maxDuration, startPosition = isVertical ? this.y : this.x;
4853
+ const dvSign = Math.sign(v), mass = this.scrollingSettings()?.mass ?? MASS, duration = DURATION, maxDuration = this.scrollingSettings()?.maxDuration ?? MAX_DURATION, maxDist = this.scrollingSettings()?.maxDistance ?? MAX_DIST, maxDistance = dvSign * maxDist, s = (dvSign * Math.abs((a0 * Math.pow(duration, 2)) * .5) / 10000) / mass, distance = Math.abs(s) < maxDist ? s : maxDistance, positionWithVelocity = position + (this._inversion ? -1 : 1) * distance, ad = Math.abs(a0 !== 0 ? Math.sqrt(a0) : 0) * ACCELERATION_SCALE / mass, aDuration = ad < maxDuration ? ad : maxDuration, startPosition = isVertical ? this.y : this.x;
4847
4854
  this.animate(startPosition, Math.round(positionWithVelocity), aDuration, easeOutQuad, true);
4848
4855
  }
4849
4856
  else {
@@ -4859,7 +4866,7 @@ class NgScrollView extends BaseScrollView {
4859
4866
  }
4860
4867
  animate(startValue, endValue, duration = ANIMATION_DURATION, easingFunction = easeOutQuad, userAction = false, alignmentAtComplete = true, skipOverridedCoordinates = false) {
4861
4868
  const isVertical = this.isVertical();
4862
- let iteration = 0, position = startValue;
4869
+ let position = startValue;
4863
4870
  this._isAlignmentAnimation = !alignmentAtComplete;
4864
4871
  this._animator.animate({
4865
4872
  withDelta: this._service.dynamic && !this.isInfinity(),
@@ -4876,17 +4883,16 @@ class NgScrollView extends BaseScrollView {
4876
4883
  this.animate(currentCoordinate, currentCoordinate + delta, duration - elapsed, easingFunction, userAction, alignmentAtComplete);
4877
4884
  return;
4878
4885
  }
4879
- const v0 = calculateVelocity(position, value, timestamp) ?? this.averageVelocity;
4886
+ const v0 = calculateVelocity(position, value - this._delta, timestamp) ?? this.averageVelocity;
4880
4887
  position = value;
4881
4888
  if (alignmentAtComplete && !this._isAlignmentAnimation && !skipOverridedCoordinates) {
4882
- if (iteration < MAX_ITERATIONS_FOR_AVERAGE_CALCULATIONS || !this.snapIfNecessary(v0)) {
4889
+ if (!this.snapIfNecessary(v0)) {
4883
4890
  this.move(isVertical, value, false, userAction);
4884
4891
  }
4885
4892
  }
4886
4893
  else {
4887
4894
  this.move(isVertical, value, false, userAction);
4888
4895
  }
4889
- iteration++;
4890
4896
  this._service.update(true);
4891
4897
  }, onComplete: ({ value, timestamp }) => {
4892
4898
  this._isAlignmentAnimation = false;
@@ -4938,10 +4944,9 @@ class NgScrollView extends BaseScrollView {
4938
4944
  return size;
4939
4945
  }
4940
4946
  alignPosition(animated = true, force = false) {
4941
- if (!this.snapToItem() || this._isAlignmentAnimation) {
4947
+ if (!this.snapToItem() || (this._isAlignmentAnimation && !force)) {
4942
4948
  return false;
4943
4949
  }
4944
- this.stopScrolling(true);
4945
4950
  const scrollDirection = this._scrollDirection.get() || (force ? 1 : 0);
4946
4951
  if (scrollDirection === 0) {
4947
4952
  return false;
@@ -5324,13 +5329,13 @@ class NgScrollBarComponent extends NgScrollView {
5324
5329
  })).subscribe();
5325
5330
  }
5326
5331
  createDragEvent(userAction) {
5327
- const isVertical = this.isVertical(), scrollSize = isVertical ? this.scrollHeight : this.scrollWidth, scrollContent = this.scrollContent()?.nativeElement, scrollViewport = this.scrollViewport()?.nativeElement;
5332
+ const isVertical = this.isVertical(), scrollSize = isVertical ? this.scrollHeight : this.scrollWidth, scrollPosition = isVertical ? this.scrollTop : this.scrollLeft, startOffset = this.startOffset(), endOffset = this.endOffset(), scrollContent = this.scrollContent()?.nativeElement, scrollViewport = this.scrollViewport()?.nativeElement;
5328
5333
  if (!!scrollViewport && !!scrollContent) {
5329
- const contentSize = isVertical ? scrollContent.offsetHeight : scrollContent.offsetWidth, viewportSize = isVertical ? scrollViewport.offsetHeight : scrollViewport.offsetWidth;
5334
+ const contentSize = isVertical ? scrollContent.offsetHeight : scrollContent.offsetWidth, viewportSize = isVertical ? scrollViewport.offsetHeight : scrollViewport.offsetWidth, offsetSize = (scrollSize !== 0 ? (startOffset / scrollSize) : 0), positionSize = (scrollSize !== 0 ? (scrollPosition / scrollSize) : 0), maxSize = 1 - offsetSize, pos = (positionSize - offsetSize);
5330
5335
  const event = {
5331
- position: scrollSize !== 0 ? ((isVertical ? this._y : this._x) / scrollSize) : 0,
5332
- min: scrollSize !== 0 ? (this.startOffset() / scrollSize) : 0,
5333
- max: scrollSize !== 0 ? ((viewportSize - this.endOffset() - contentSize) / scrollSize) : 0,
5336
+ position: pos / maxSize,
5337
+ min: scrollSize !== 0 ? (startOffset / scrollSize) : 0,
5338
+ max: scrollSize !== 0 ? ((viewportSize - endOffset - contentSize) / scrollSize) : 0,
5334
5339
  animation: !this._isMoving,
5335
5340
  userAction,
5336
5341
  };
@@ -8234,7 +8239,7 @@ class NgVirtualListComponent {
8234
8239
  this._isLoading = false;
8235
8240
  })).subscribe();
8236
8241
  const update = (params) => {
8237
- const { alignment, precalculatedScrollStartOffset, precalculatedScrollEndOffset, trackBy, isInfinity, snapScrollToStart, snapScrollToEnd, bounds, listBounds, scrollEndOffset, items, itemConfigMap, scrollSize, itemSize, minItemSize, maxItemSize, divides, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, enabledBufferOptimization, snapToItem, snapToItemAlign, cacheVersion, userAction, collapsedIds, itemTransform, } = params;
8242
+ const { alignment, snapScrollToStart, snapScrollToEnd, bounds, items, itemConfigMap, scrollSize, itemSize, minItemSize, maxItemSize, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, enabledBufferOptimization, snapToItem, snapToItemAlign, userAction, collapsedIds, itemTransform, } = params;
8238
8243
  const scroller = this._scrollerComponent();
8239
8244
  let totalSize = 0;
8240
8245
  if (!!scroller) {
@@ -8244,7 +8249,7 @@ class NgVirtualListComponent {
8244
8249
  let actualScrollSize = !this._readyForShow && snapScrollToEnd ? (isVertical ? scroller.scrollHeight : scroller.scrollWidth) :
8245
8250
  (isVertical ? scroller.scrollTop : scroller.scrollLeft), leftLayoutOffset = 0, displayItems;
8246
8251
  const { width, height } = bounds, viewportSize = (isVertical ? height : width), opts = {
8247
- bounds: { width, height }, dynamicSize, isVertical, itemSize, minItemSize, maxItemSize, bufferSize, maxBufferSize,
8252
+ alignment, bounds: { width, height }, dynamicSize, isVertical, itemSize, minItemSize, maxItemSize, bufferSize, maxBufferSize,
8248
8253
  scrollSize: actualScrollSize, stickyEnabled, enabledBufferOptimization, snapToItem, snapToItemAlign, itemTransform,
8249
8254
  };
8250
8255
  if (snapScrollToEnd && !this._readyForShow) {
@@ -8252,12 +8257,24 @@ class NgVirtualListComponent {
8252
8257
  displayItems = calculatedDisplayItems;
8253
8258
  totalSize = calculatedTotalSize1;
8254
8259
  leftLayoutOffset = leftLayoutOffset1;
8260
+ if (!!itemTransform && dynamicSize && this._trackBox.delta !== 0) {
8261
+ const { displayItems: calculatedDisplayItems, totalSize: calculatedTotalSize1, leftLayoutOffset: leftLayoutOffset1 } = this._trackBox.updateCollection(items, itemConfigMap, { ...opts, scrollSize: actualScrollSize + this._trackBox.delta });
8262
+ displayItems = calculatedDisplayItems;
8263
+ totalSize = calculatedTotalSize1;
8264
+ leftLayoutOffset = leftLayoutOffset1;
8265
+ }
8255
8266
  }
8256
8267
  else {
8257
8268
  const { displayItems: calculatedDisplayItems, totalSize: calculatedTotalSize, leftLayoutOffset: leftLayoutOffset1 } = this._trackBox.updateCollection(items, itemConfigMap, opts);
8258
8269
  displayItems = calculatedDisplayItems;
8259
8270
  totalSize = calculatedTotalSize;
8260
8271
  leftLayoutOffset = leftLayoutOffset1;
8272
+ if (!!itemTransform && dynamicSize && this._trackBox.delta !== 0) {
8273
+ const { displayItems: calculatedDisplayItems, totalSize: calculatedTotalSize, leftLayoutOffset: leftLayoutOffset1 } = this._trackBox.updateCollection(items, itemConfigMap, { ...opts, scrollSize: actualScrollSize + this._trackBox.delta });
8274
+ displayItems = calculatedDisplayItems;
8275
+ totalSize = calculatedTotalSize;
8276
+ leftLayoutOffset = leftLayoutOffset1;
8277
+ }
8261
8278
  }
8262
8279
  scroller.totalSize = totalSize;
8263
8280
  scroller.startLayoutOffset = leftLayoutOffset;
@@ -8274,23 +8291,7 @@ class NgVirtualListComponent {
8274
8291
  if (this._isSnappingMethodAdvanced) {
8275
8292
  this.updateRegularRenderer();
8276
8293
  }
8277
- switch (alignment) {
8278
- case Alignments.NONE: {
8279
- this._actualScrollStartOffset.set(precalculatedScrollStartOffset);
8280
- this._actualScrollEndOffset.set(precalculatedScrollEndOffset);
8281
- break;
8282
- }
8283
- case Alignments.CENTER: {
8284
- const firstItemId = items.length > 0 ? (items[0]?.[trackBy] ?? null) : null, endItemId = items.length > 0 ? (items?.[items.length - 1]?.[trackBy] ?? null) : null, alignmentStartOffset = viewportSize * .5 - (firstItemId !== null ? (isVertical ? (this._service.getItemBounds(firstItemId)?.height ?? 0) :
8285
- (this._service.getItemBounds(firstItemId)?.width ?? 0)) : 0) * (isInfinity ? 0 : .5), alignmentEndOffset = viewportSize * .5 - (endItemId !== null ? (isVertical ? (this._service.getItemBounds(endItemId)?.height ?? 0) :
8286
- (this._service.getItemBounds(endItemId)?.width ?? 0)) : 0) * (isInfinity ? 0 : .5);
8287
- this._alignmentScrollStartOffset.set(alignmentStartOffset);
8288
- this._alignmentScrollEndOffset.set(alignmentEndOffset);
8289
- this._actualScrollStartOffset.set(precalculatedScrollStartOffset + alignmentStartOffset);
8290
- this._actualScrollEndOffset.set(precalculatedScrollEndOffset + alignmentEndOffset);
8291
- break;
8292
- }
8293
- }
8294
+ this.updateOffsetsByAllignment();
8294
8295
  scroller.delta = delta;
8295
8296
  if ((snapScrollToStart && this._trackBox.isSnappedToStart && scroller.scrollable) ||
8296
8297
  (snapScrollToStart && currentScrollSize <= MIN_PIXELS_FOR_PREVENT_SNAPPING)) {
@@ -8469,6 +8470,7 @@ class NgVirtualListComponent {
8469
8470
  const dynamicSize = this.dynamicSize(), itemSize = this._actualItemSize(), minItemSize = this._actualMinItemSize(), maxItemSize = this._actualMaxItemSize(), snapScrollToEnd = this.snapScrollToEnd();
8470
8471
  if (dynamicSize) {
8471
8472
  const { width, height } = this._bounds() || { width: DEFAULT_LIST_SIZE, height: DEFAULT_LIST_SIZE }, itemConfigMap = this.itemConfigMap(), isVertical = this._isVertical, currentScrollSize = isVertical ? scrollerComponent.scrollTop : scrollerComponent.scrollLeft, opts = {
8473
+ alignment: this.actualAlignment(),
8472
8474
  bounds: { width, height }, collection: items, dynamicSize, isVertical: this._isVertical, itemSize, minItemSize, maxItemSize,
8473
8475
  bufferSize: this.bufferSize(), maxBufferSize: this.maxBufferSize(), itemTransform: this.itemTransform(),
8474
8476
  scrollSize: (isVertical ? scrollerComponent.scrollTop : scrollerComponent.scrollLeft),
@@ -8494,21 +8496,8 @@ class NgVirtualListComponent {
8494
8496
  this.createDisplayComponentsIfNeed(displayItems);
8495
8497
  this.tracking();
8496
8498
  this.snappingHandler();
8499
+ this.updateOffsetsByAllignment();
8497
8500
  scrollSize = this._trackBox.getItemPosition(id, itemConfigMap, { ...opts, scrollSize: actualScrollSize, fromItemId: id });
8498
- if (this._isInfinity()) {
8499
- if (this.snapToItem()) {
8500
- const itemBounds = this._trackBox.getItemBounds(id);
8501
- if (!!itemBounds) {
8502
- const itemSize = isVertical ? itemBounds.height : itemBounds.width;
8503
- switch (this.snapToItemAlign()) {
8504
- case SnapToItemAligns.CENTER: {
8505
- scrollSize += itemSize * .5;
8506
- break;
8507
- }
8508
- }
8509
- }
8510
- }
8511
- }
8512
8501
  if (scrollSize === -1) {
8513
8502
  return of([finished, { id, blending, iteration: nextIteration, cb }]).pipe(delay(0));
8514
8503
  }
@@ -8533,11 +8522,11 @@ class NgVirtualListComponent {
8533
8522
  else {
8534
8523
  const index = items.findIndex(item => item[trackBy] === id);
8535
8524
  if (index > -1) {
8536
- const isVertical = this._isVertical, itemSize = this._actualItemSize();
8525
+ const isVertical = this._isVertical, itemSize = this._actualItemSize(), isInfinity = this._isInfinity(), snapToItem = this.snapToItem(), snapToItemAlign = this.snapToItemAlign();
8537
8526
  let scrollSize = index * itemSize;
8538
- if (this._isInfinity()) {
8539
- if (this.snapToItem()) {
8540
- switch (this.snapToItemAlign()) {
8527
+ if (isInfinity) {
8528
+ if (snapToItem) {
8529
+ switch (snapToItemAlign) {
8541
8530
  case SnapToItemAligns.CENTER: {
8542
8531
  scrollSize += itemSize * .5;
8543
8532
  break;
@@ -8546,11 +8535,12 @@ class NgVirtualListComponent {
8546
8535
  }
8547
8536
  }
8548
8537
  const { width, height } = this._bounds() || { width: DEFAULT_LIST_SIZE, height: DEFAULT_LIST_SIZE }, itemConfigMap = this.itemConfigMap(), items = this._actualItems(), opts = {
8538
+ alignment: this._actualAlignment(),
8549
8539
  bounds: { width, height }, collection: items, dynamicSize, isVertical: this._isVertical, itemSize, minItemSize, maxItemSize,
8550
8540
  bufferSize: this.bufferSize(), maxBufferSize: this.maxBufferSize(), itemTransform: this.itemTransform(),
8551
8541
  scrollSize: (isVertical ? scrollerComponent.scrollTop : scrollerComponent.scrollLeft),
8552
- snapToItem: this.snapToItem(), snapToItemAlign: this.snapToItemAlign(),
8553
- stickyEnabled: this.stickyEnabled(), fromItemId: id, enabledBufferOptimization: this.enabledBufferOptimization(),
8542
+ snapToItem, snapToItemAlign, stickyEnabled: this.stickyEnabled(), fromItemId: id,
8543
+ enabledBufferOptimization: this.enabledBufferOptimization(),
8554
8544
  };
8555
8545
  this._trackBox.clearDelta();
8556
8546
  const viewportSize = (isVertical ? height : width), { displayItems, totalSize, leftLayoutOffset } = this._trackBox.updateCollection(items, itemConfigMap, {
@@ -8565,6 +8555,7 @@ class NgVirtualListComponent {
8565
8555
  this.createDisplayComponentsIfNeed(displayItems);
8566
8556
  this.tracking();
8567
8557
  this.snappingHandler();
8558
+ this.updateOffsetsByAllignment();
8568
8559
  this._$preventScrollSnapping.next(true);
8569
8560
  const params = {
8570
8561
  [this._isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollSize, fireUpdate: false,
@@ -8591,7 +8582,7 @@ class NgVirtualListComponent {
8591
8582
  this.emitScrollEvent(true, false, true);
8592
8583
  const scrollParams = params;
8593
8584
  scrollParams?.cb?.();
8594
- }), delay(100), tap(([finished]) => {
8585
+ }), delay(0), tap(([finished]) => {
8595
8586
  if (finished) {
8596
8587
  this._scrollerComponent()?.snapIfNeed();
8597
8588
  }
@@ -8632,6 +8623,14 @@ class NgVirtualListComponent {
8632
8623
  }
8633
8624
  }));
8634
8625
  })).subscribe();
8626
+ combineLatest([$itemConfigMap, $dynamicSize, $divides]).pipe(takeUntilDestroyed(), filter$1(([itemConfigMap, dynamicSize, divides]) => !!itemConfigMap && !dynamicSize && divides > 1), tap(([itemConfigMap]) => {
8627
+ for (const id in itemConfigMap) {
8628
+ const metaData = itemConfigMap[id];
8629
+ if (metaData?.fullSize || metaData?.sticky === 1 || metaData?.sticky === 2) {
8630
+ throw Error('The accelerated rendering algorithm `[dynamicSize]="false"` cannot correctly handle non-uniform lists (the itemConfigMap specifies full-size elements). For correct rendering, specify `[dynamicSize]="true"`.');
8631
+ }
8632
+ }
8633
+ })).subscribe();
8635
8634
  combineLatest([$collapsingMode, $items, $itemConfigMap, $trackBy]).pipe(takeUntilDestroyed(), tap(([collapsingMode, items, itemConfigMap, trackBy]) => {
8636
8635
  const isAccordion = isCollapseMode(collapsingMode, CollapsingModes.ACCORDION);
8637
8636
  if (isAccordion) {
@@ -8835,6 +8834,26 @@ class NgVirtualListComponent {
8835
8834
  this._trackBox.setDisplayObjectIndexMapById(doMap);
8836
8835
  }
8837
8836
  }
8837
+ updateOffsetsByAllignment() {
8838
+ const alignment = this._actualAlignment(), items = this._actualItems(), trackBy = this.trackBy(), isInfinity = this._isInfinity(), isVertical = this._isVertical, { width, height } = this._bounds() || { width: DEFAULT_LIST_SIZE, height: DEFAULT_LIST_SIZE }, viewportSize = isVertical ? height : width, precalculatedScrollStartOffset = this._precalculatedScrollStartOffset(), precalculatedScrollEndOffset = this._precalculatedScrollEndOffset();
8839
+ switch (alignment) {
8840
+ case Alignments.NONE: {
8841
+ this._actualScrollStartOffset.set(precalculatedScrollStartOffset);
8842
+ this._actualScrollEndOffset.set(precalculatedScrollEndOffset);
8843
+ break;
8844
+ }
8845
+ case Alignments.CENTER: {
8846
+ const firstItemId = items.length > 0 ? (items[0]?.[trackBy] ?? null) : null, endItemId = items.length > 0 ? (items?.[items.length - 1]?.[trackBy] ?? null) : null, alignmentStartOffset = viewportSize * .5 - (firstItemId !== null ? (isVertical ? (this._service.getItemBounds(firstItemId)?.height ?? 0) :
8847
+ (this._service.getItemBounds(firstItemId)?.width ?? 0)) : 0) * (isInfinity ? 0 : .5), alignmentEndOffset = viewportSize * .5 - (endItemId !== null ? (isVertical ? (this._service.getItemBounds(endItemId)?.height ?? 0) :
8848
+ (this._service.getItemBounds(endItemId)?.width ?? 0)) : 0) * (isInfinity ? 0 : .5);
8849
+ this._alignmentScrollStartOffset.set(alignmentStartOffset);
8850
+ this._alignmentScrollEndOffset.set(alignmentEndOffset);
8851
+ this._actualScrollStartOffset.set(precalculatedScrollStartOffset + alignmentStartOffset);
8852
+ this._actualScrollEndOffset.set(precalculatedScrollEndOffset + alignmentEndOffset);
8853
+ break;
8854
+ }
8855
+ }
8856
+ }
8838
8857
  updateRegularRenderer() {
8839
8858
  this._resizeSnappedComponentHandler();
8840
8859
  }