ng-virtual-list 16.12.4 → 16.12.9

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.
Files changed (42) hide show
  1. package/esm2022/lib/components/ng-list-item/const/index.mjs +2 -1
  2. package/esm2022/lib/components/ng-prerender-container/components/ng-prerender-scroller/ng-prerender-scroller.component.mjs +1 -4
  3. package/esm2022/lib/components/ng-prerender-container/core/prerender-track-box.mjs +3 -1
  4. package/esm2022/lib/components/ng-scroll-bar/ng-scroll-bar.component.mjs +5 -15
  5. package/esm2022/lib/components/ng-scroll-view/base/base-scroll-view.component.mjs +16 -2
  6. package/esm2022/lib/components/ng-scroll-view/const/index.mjs +2 -2
  7. package/esm2022/lib/components/ng-scroll-view/ng-scroll-view.component.mjs +123 -33
  8. package/esm2022/lib/components/ng-scroller/ng-scroller.component.mjs +15 -12
  9. package/esm2022/lib/core/interfaces/metrics.mjs +1 -1
  10. package/esm2022/lib/core/interfaces/recalculate-metrics-options.mjs +1 -1
  11. package/esm2022/lib/core/track-box.mjs +16 -8
  12. package/esm2022/lib/directives/locale-sensitive/locale-sensitive.directive.mjs +6 -6
  13. package/esm2022/lib/models/render-item-config.model.mjs +1 -1
  14. package/esm2022/lib/models/render-item-measures.model.mjs +1 -1
  15. package/esm2022/lib/ng-virtual-list.component.mjs +90 -86
  16. package/esm2022/lib/utils/animator/animator.mjs +12 -6
  17. package/esm2022/lib/utils/animator/interfaces/animator-params.mjs +1 -1
  18. package/esm2022/lib/utils/animator/interfaces/animator-update-data.mjs +1 -1
  19. package/esm2022/lib/utils/animator/types/easing.mjs +1 -1
  20. package/esm2022/lib/utils/event-emitter/event-emitter.mjs +2 -2
  21. package/esm2022/lib/utils/event-emitter/interfaces/event-emitter.mjs +1 -1
  22. package/fesm2022/ng-virtual-list.mjs +279 -162
  23. package/fesm2022/ng-virtual-list.mjs.map +1 -1
  24. package/lib/components/ng-prerender-container/components/ng-prerender-scroller/ng-prerender-scroller.component.d.ts +0 -3
  25. package/lib/components/ng-scroll-bar/ng-scroll-bar.component.d.ts +1 -6
  26. package/lib/components/ng-scroll-view/base/base-scroll-view.component.d.ts +7 -1
  27. package/lib/components/ng-scroll-view/const/index.d.ts +1 -1
  28. package/lib/components/ng-scroll-view/ng-scroll-view.component.d.ts +12 -1
  29. package/lib/components/ng-scroller/ng-scroller.component.d.ts +1 -3
  30. package/lib/core/interfaces/metrics.d.ts +2 -0
  31. package/lib/core/interfaces/recalculate-metrics-options.d.ts +1 -0
  32. package/lib/directives/locale-sensitive/locale-sensitive.directive.d.ts +2 -2
  33. package/lib/models/render-item-config.model.d.ts +4 -0
  34. package/lib/models/render-item-measures.model.d.ts +4 -0
  35. package/lib/ng-virtual-list.component.d.ts +0 -1
  36. package/lib/utils/animator/animator.d.ts +1 -1
  37. package/lib/utils/animator/interfaces/animator-params.d.ts +1 -1
  38. package/lib/utils/animator/interfaces/animator-update-data.d.ts +1 -1
  39. package/lib/utils/animator/types/easing.d.ts +1 -1
  40. package/lib/utils/event-emitter/event-emitter.d.ts +1 -1
  41. package/lib/utils/event-emitter/interfaces/event-emitter.d.ts +1 -1
  42. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Injectable, inject, Component, ChangeDetectorRef, ElementRef, ChangeDetectionStrategy, ViewChild, EventEmitter as EventEmitter$1, Directive, Input, Output, Injector, InjectionToken, TemplateRef, ViewContainerRef, ViewEncapsulation, NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
3
- import { Subject, BehaviorSubject, takeUntil, distinctUntilChanged, combineLatest, tap, map, fromEvent, race, of, debounceTime, switchMap as switchMap$1, filter as filter$1, delay, startWith, from, take, skip } from 'rxjs';
3
+ import { Subject, BehaviorSubject, takeUntil, distinctUntilChanged, combineLatest, tap, map, fromEvent, race, of, debounceTime, switchMap as switchMap$1, filter as filter$1, delay, startWith, take, from, skip } from 'rxjs';
4
4
  import { BehaviorSubject as BehaviorSubject$1 } from 'rxjs/internal/BehaviorSubject';
5
5
  import * as i1 from '@angular/common';
6
6
  import { CommonModule } from '@angular/common';
@@ -327,7 +327,7 @@ const VISIBILITY_HIDDEN = 'hidden';
327
327
  const SIZE_100_PERSENT = '100%';
328
328
  const SIZE_AUTO = 'auto';
329
329
  const UNSET$5 = 'unset';
330
- const LEFT$2 = 'left';
330
+ const LEFT$3 = 'left';
331
331
  const RIGHT$1 = 'right';
332
332
  const POSITION$1 = 'position';
333
333
  const POSITION_RELATIVE = 'relative';
@@ -496,6 +496,7 @@ const DEFAULT_TEMPLATE_CONTEXT = {
496
496
  fullSize: false,
497
497
  totalItems: 0,
498
498
  grabbing: false,
499
+ inverted: false,
499
500
  },
500
501
  reseted: false,
501
502
  index: -1,
@@ -1921,7 +1922,7 @@ class ScrollEvent {
1921
1922
 
1922
1923
  /**
1923
1924
  * Event emitter
1924
- * @link https://github.com/DjonnyX/ng-virtual-list/blob/main/library/src/utils/event-emitter/event-emitter.ts
1925
+ * @link https://github.com/DjonnyX/ng-virtual-list/blob/16.x/library/src/utils/event-emitter/event-emitter.ts
1925
1926
  * @author Evgenii Alexandrovich Grebennikov
1926
1927
  * @email djonnyx@gmail.com
1927
1928
  */
@@ -2831,7 +2832,7 @@ class TrackBox extends CacheMap {
2831
2832
  * Calculates list metrics
2832
2833
  */
2833
2834
  recalculateMetrics(options) {
2834
- 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);
2835
+ const { alignment, fromItemId, bounds, collection, dynamicSize, isVertical, itemSize, minItemSize, maxItemSize, bufferSize: minBufferSize, scrollSize, stickyEnabled, itemConfigMap, enabledBufferOptimization, previousTotalSize, snapToItem, snapToItemAlign, deletedItemsMap, inverted, itemTransform } = options, roundedScrollSize = Math.round(scrollSize);
2835
2836
  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)
2836
2837
  || (typeof fromItemId === 'string' && fromItemId > '-1');
2837
2838
  let leftItemsOffset = 0, rightItemsOffset = 0;
@@ -3284,6 +3285,7 @@ class TrackBox extends CacheMap {
3284
3285
  rightItemLength,
3285
3286
  rightItemsWeight,
3286
3287
  scrollSize: actualScrollSize,
3288
+ maxScrollSize: totalSize,
3287
3289
  leftSizeOfAddedItems,
3288
3290
  sizeProperty,
3289
3291
  stickyEnabled,
@@ -3298,6 +3300,7 @@ class TrackBox extends CacheMap {
3298
3300
  isUpdating,
3299
3301
  snapToItem,
3300
3302
  snapToItemAlign,
3303
+ inverted,
3301
3304
  itemTransform,
3302
3305
  };
3303
3306
  return metrics;
@@ -3349,7 +3352,7 @@ class TrackBox extends CacheMap {
3349
3352
  return false;
3350
3353
  }
3351
3354
  generateDisplayCollection(items, actualItems, itemConfigMap, metrics) {
3352
- const { width, height, normalizedItemWidth, normalizedItemHeight, dynamicSize, divides, itemsOnDisplayLength, itemsFromStartToScrollEnd, isVertical, leftLayoutOffset: layoutOffset, leftLayoutIndexOffset: layoutIndexOffset, renderItems: renderItemsLength, scrollSize, sizeProperty, stickyEnabled, stickyPos, startPosition, totalLength, startIndex, typicalItemSize, minItemSize, maxItemSize, snapToItem, snapToItemAlign, itemTransform, } = metrics, displayItems = [];
3355
+ const { width, height, normalizedItemWidth, normalizedItemHeight, dynamicSize, divides, itemsOnDisplayLength, itemsFromStartToScrollEnd, isVertical, leftLayoutOffset: layoutOffset, leftLayoutIndexOffset: layoutIndexOffset, renderItems: renderItemsLength, scrollSize, maxScrollSize, sizeProperty, stickyEnabled, stickyPos, startPosition, totalLength, startIndex, typicalItemSize, minItemSize, maxItemSize, snapToItem, snapToItemAlign, inverted, itemTransform, } = metrics, displayItems = [];
3353
3356
  if (items.length) {
3354
3357
  const trackBy = this._trackingPropertyName, actualSnippedPosition = stickyPos, isSnappingMethodAdvanced = this._isSnappingMethodAdvanced, deltaOffet = (isSnappingMethodAdvanced ? scrollSize : 0), scrollDirection = this._scrollDirection, boundsSize = isVertical ? height : width, actualEndSnippedPosition = scrollSize + boundsSize - this._scrollEndOffset;
3355
3358
  let pos = startPosition, renderItems = renderItemsLength, stickyItem, nextSticky, stickyItemIndex = -1, nexstStickyItemIndex = -1, stickyItemSize = 0, endStickyItem, nextEndSticky, endStickyItemIndex = -1, endStickyItemSize = 0;
@@ -3389,6 +3392,7 @@ class TrackBox extends CacheMap {
3389
3392
  position: pos,
3390
3393
  boundsSize,
3391
3394
  scrollSize,
3395
+ maxScrollSize,
3392
3396
  absoluteStartPosition,
3393
3397
  absoluteStartPositionPercent,
3394
3398
  absoluteEndPosition,
@@ -3419,6 +3423,7 @@ class TrackBox extends CacheMap {
3419
3423
  tabIndex: i - layoutIndexOffset,
3420
3424
  divides,
3421
3425
  opacity: 1,
3426
+ inverted,
3422
3427
  zIndex: Z_INDEX_1,
3423
3428
  };
3424
3429
  const itemData = collectionItem;
@@ -3465,6 +3470,7 @@ class TrackBox extends CacheMap {
3465
3470
  position: pos,
3466
3471
  boundsSize,
3467
3472
  scrollSize,
3473
+ maxScrollSize,
3468
3474
  absoluteStartPosition,
3469
3475
  absoluteStartPositionPercent,
3470
3476
  absoluteEndPosition,
@@ -3501,6 +3507,7 @@ class TrackBox extends CacheMap {
3501
3507
  tabIndex: i - layoutIndexOffset,
3502
3508
  divides,
3503
3509
  opacity: 1,
3510
+ inverted,
3504
3511
  zIndex: Z_INDEX_1,
3505
3512
  };
3506
3513
  const itemData = collectionItem;
@@ -3561,6 +3568,7 @@ class TrackBox extends CacheMap {
3561
3568
  position: pos,
3562
3569
  boundsSize,
3563
3570
  scrollSize,
3571
+ maxScrollSize,
3564
3572
  absoluteStartPosition,
3565
3573
  absoluteStartPositionPercent,
3566
3574
  absoluteEndPosition,
@@ -3599,6 +3607,7 @@ class TrackBox extends CacheMap {
3599
3607
  opacity: 1,
3600
3608
  zIndex: Z_INDEX_0,
3601
3609
  fullSize,
3610
+ inverted,
3602
3611
  };
3603
3612
  if (snapped) {
3604
3613
  config.zIndex = Z_INDEX_2;
@@ -3743,18 +3752,18 @@ class TrackBox extends CacheMap {
3743
3752
  let first = null, last = null;
3744
3753
  if (!!components) {
3745
3754
  for (const comp of components) {
3746
- const id = comp.instance.itemId ?? null, isVertical = comp.instance.item?.config?.isVertical, x = comp.instance.item?.measures?.x ?? 0, y = comp.instance.item?.measures?.y ?? 0, isFirst = comp.instance.item?.config?.isFirst ?? false, isLast = comp.instance.item?.config?.isLast ?? false, { width, height } = comp.instance.getBounds(), pos = position;
3755
+ const id = comp.instance.itemId ?? null, isVertical = comp.instance.item?.config?.isVertical, inverted = comp.instance.item?.config.inverted ?? false, maxScrollSize = comp.instance.item?.measures.maxScrollSize ?? 0, { width, height } = comp.instance.getBounds(), x = comp.instance.item?.measures?.x ?? 0, xx = inverted ? (maxScrollSize - x) - width : x, y = comp.instance.item?.measures?.y ?? 0, isFirst = comp.instance.item?.config?.isFirst ?? false, isLast = comp.instance.item?.config?.isLast ?? false, pos = position;
3747
3756
  if (isVertical && (pos >= y && pos < y + height)) {
3748
3757
  return { id, x, y, width, height, isFirst, isLast };
3749
3758
  }
3750
- else if (!isVertical && (pos >= x && pos < x + width)) {
3751
- return { id, x, y, width, height, isFirst, isLast };
3759
+ else if (!isVertical && (pos >= xx && pos < xx + width)) {
3760
+ return { id, x: xx, y, width, height, isFirst, isLast };
3752
3761
  }
3753
3762
  if (isFirst) {
3754
- first = { id, x, y, width, height, isFirst, isLast };
3763
+ first = { id, x: xx, y, width, height, isFirst, isLast };
3755
3764
  }
3756
3765
  else if (isLast) {
3757
- last = { id, x, y, width, height, isFirst, isLast };
3766
+ last = { id, x: xx, y, width, height, isFirst, isLast };
3758
3767
  }
3759
3768
  }
3760
3769
  }
@@ -3954,7 +3963,7 @@ const easeLinear = (t) => {
3954
3963
 
3955
3964
  /**
3956
3965
  * Animator
3957
- * @link https://github.com/DjonnyX/ng-virtual-list/blob/main/library/src/utils/animator/animator.ts
3966
+ * @link https://github.com/DjonnyX/ng-virtual-list/blob/16.x/library/src/utils/animator/animator.ts
3958
3967
  * @author Evgenii Alexandrovich Grebennikov
3959
3968
  * @email djonnyx@gmail.com
3960
3969
  */
@@ -3974,9 +3983,13 @@ class Animator {
3974
3983
  _endValue = 0;
3975
3984
  _prevPos = 0;
3976
3985
  updateTo(end) {
3977
- this._endValue = end;
3978
- this._diff = this._endValue - this._startValue;
3979
- return this.hasAnimation();
3986
+ if (this.hasAnimation()) {
3987
+ this._startValue = this._prevPos;
3988
+ this._endValue = end;
3989
+ this._diff = this._endValue - this._startValue;
3990
+ return true;
3991
+ }
3992
+ return false;
3980
3993
  }
3981
3994
  animate(params) {
3982
3995
  this.stop();
@@ -4008,6 +4021,9 @@ class Animator {
4008
4021
  const frameTimestamp = t - prevTime, actualFrameTimestamp = frameTimestamp < ANIMATOR_MIN_TIMESTAMP ? ANIMATOR_MIN_TIMESTAMP : frameTimestamp;
4009
4022
  prevTime = t;
4010
4023
  this._prevPos = currentValue;
4024
+ if (isFinished) {
4025
+ this._animationId = -1;
4026
+ }
4011
4027
  if (onUpdate !== undefined) {
4012
4028
  const data = {
4013
4029
  id,
@@ -4019,7 +4035,6 @@ class Animator {
4019
4035
  onUpdate(data);
4020
4036
  }
4021
4037
  if (isFinished) {
4022
- this._animationId = -1;
4023
4038
  if (onComplete !== undefined) {
4024
4039
  const data = {
4025
4040
  id,
@@ -4056,7 +4071,7 @@ class Animator {
4056
4071
  const SCROLL_VIEW_INVERSION = new InjectionToken('ScrollViewInversion');
4057
4072
  const SCROLL_VIEW_OVERSCROLL_ENABLED = new InjectionToken('ScrollViewOverscrollEnabled');
4058
4073
  const SCROLL_VIEW_NORMALIZE_VALUE_FROM_ZERO = new InjectionToken('ScrollViewNormalizeValueFromZero');
4059
- 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;
4074
+ const TOP$1 = 'top', LEFT$2 = '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, MIN_DELTA = 0.1, MAX_VELOCITY_TIMESTAMP = 100, MAX_VELOCITIES_LENGTH = 10, MIN_ACCELERATION = 0.001, SPEED_SCALE = 15, OVERSCROLL_START_ITERATION = 2;
4060
4075
  const MAX_ITERATIONS_FOR_AVERAGE_CALCULATIONS = 5, INSTANT_VELOCITY_SCALE = 1000;
4061
4076
  const SCROLL_EVENT$1 = new Event(SCROLLER_SCROLL);
4062
4077
 
@@ -4221,6 +4236,17 @@ class BaseScrollView extends DisposableComponent {
4221
4236
  $isVertical = this._$isVertical.asObservable();
4222
4237
  _$grabbing = new BehaviorSubject(false);
4223
4238
  $grabbing = this._$grabbing.asObservable();
4239
+ get grabbing() {
4240
+ return this._$grabbing.getValue();
4241
+ }
4242
+ _$langTextDir = new BehaviorSubject(DEFAULT_LANG_TEXT_DIR);
4243
+ $langTextDir = this._$langTextDir.asObservable();
4244
+ set langTextDir(v) {
4245
+ if (this._$langTextDir.getValue() !== v) {
4246
+ this._$langTextDir.next(v);
4247
+ }
4248
+ }
4249
+ get langTextDir() { return this._$langTextDir.getValue(); }
4224
4250
  _inversion = inject(SCROLL_VIEW_INVERSION);
4225
4251
  _overscrollEnabled = inject(SCROLL_VIEW_OVERSCROLL_ENABLED);
4226
4252
  _$updateScrollBar = new Subject();
@@ -4386,7 +4412,7 @@ class BaseScrollView extends DisposableComponent {
4386
4412
  }
4387
4413
  }
4388
4414
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BaseScrollView, deps: [], target: i0.ɵɵFactoryTarget.Component });
4389
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: BaseScrollView, selector: "base-scroll-view", inputs: { direction: "direction", startOffset: "startOffset", endOffset: "endOffset", alignmentStartOffset: "alignmentStartOffset", alignmentEndOffset: "alignmentEndOffset", isInfinity: "isInfinity" }, viewQueries: [{ propertyName: "scrollContent", first: true, predicate: ["scrollContent"], descendants: true }, { propertyName: "scrollViewport", first: true, predicate: ["scrollViewport"], descendants: true }], usesInheritance: true, ngImport: i0, template: '', isInline: true });
4415
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: BaseScrollView, selector: "base-scroll-view", inputs: { direction: "direction", startOffset: "startOffset", endOffset: "endOffset", alignmentStartOffset: "alignmentStartOffset", alignmentEndOffset: "alignmentEndOffset", isInfinity: "isInfinity", langTextDir: "langTextDir" }, viewQueries: [{ propertyName: "scrollContent", first: true, predicate: ["scrollContent"], descendants: true }, { propertyName: "scrollViewport", first: true, predicate: ["scrollViewport"], descendants: true }], usesInheritance: true, ngImport: i0, template: '', isInline: true });
4390
4416
  }
4391
4417
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BaseScrollView, decorators: [{
4392
4418
  type: Component,
@@ -4412,6 +4438,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
4412
4438
  type: Input
4413
4439
  }], isInfinity: [{
4414
4440
  type: Input
4441
+ }], langTextDir: [{
4442
+ type: Input
4415
4443
  }] } });
4416
4444
 
4417
4445
  /**
@@ -4579,10 +4607,34 @@ class NgScrollView extends BaseScrollView {
4579
4607
  get averageVelocity() { return this._$averageVelocity.getValue(); }
4580
4608
  _measureVelocityTimestamp = Date.now();
4581
4609
  _measureVelocityLastPosition = this._$isVertical.getValue() ? this._y : this._x;
4582
- _startPosition = 0;
4610
+ _startPositionX = 0;
4611
+ _startPositionY = 0;
4612
+ set startPosition(v) {
4613
+ const isVertical = this._$isVertical.getValue(), c = isVertical ? this._startPositionY : this._startPositionX;
4614
+ if (v !== c) {
4615
+ if (isVertical) {
4616
+ this._startPositionY = v;
4617
+ }
4618
+ else {
4619
+ this._startPositionX = v;
4620
+ }
4621
+ }
4622
+ }
4623
+ get startPosition() {
4624
+ if (this._$isVertical.getValue()) {
4625
+ return this._startPositionY;
4626
+ }
4627
+ return this._startPositionX;
4628
+ }
4583
4629
  _animator = new Animator();
4630
+ _$horizontalAxisInvertion = new BehaviorSubject(false);
4631
+ $horizontalAxisInvertion = this._$horizontalAxisInvertion.asObservable();
4632
+ get horizontalAxisInvertion() { return this._$horizontalAxisInvertion.getValue(); }
4633
+ get inverted() { return this._$horizontalAxisInvertion.getValue(); }
4584
4634
  _interactive = true;
4585
4635
  _overscrollIteration = 0;
4636
+ _overscrollStartIteration = 0;
4637
+ _overscrollApplied = false;
4586
4638
  set x(v) {
4587
4639
  this.setX(v);
4588
4640
  }
@@ -4622,7 +4674,7 @@ class NgScrollView extends BaseScrollView {
4622
4674
  _delta = 0;
4623
4675
  set delta(v) {
4624
4676
  this._delta = v;
4625
- this._startPosition += v;
4677
+ this.startPosition += v;
4626
4678
  }
4627
4679
  set startLayoutOffset(v) {
4628
4680
  if (this._startLayoutOffset !== v) {
@@ -4631,6 +4683,8 @@ class NgScrollView extends BaseScrollView {
4631
4683
  }
4632
4684
  }
4633
4685
  get startLayoutOffset() { return this._startLayoutOffset; }
4686
+ _scrollDirectionValueX = 0;
4687
+ _scrollDirectionValueY = 0;
4634
4688
  _intersectionComponentId = null;
4635
4689
  _isAlignmentAnimation = false;
4636
4690
  get animated() { return this._animator?.isAnimated ?? false; }
@@ -4639,6 +4693,9 @@ class NgScrollView extends BaseScrollView {
4639
4693
  }
4640
4694
  ngAfterViewInit() {
4641
4695
  let mouseCanceled = false, touchCanceled = false;
4696
+ combineLatest([this.$isVertical, this.$langTextDir]).pipe(takeUntil(this._$unsubscribe), tap(([isVertical, langTextDir]) => {
4697
+ this._$horizontalAxisInvertion.next(!isVertical && langTextDir === TextDirections.RTL);
4698
+ })).subscribe();
4642
4699
  const $viewportBounds = this.$viewportBounds;
4643
4700
  $viewportBounds.pipe(takeUntil(this._$unsubscribe), debounceTime(0), tap(() => {
4644
4701
  this._isMoving = false;
@@ -4654,19 +4711,25 @@ class NgScrollView extends BaseScrollView {
4654
4711
  this._$scrollEnd.next(false);
4655
4712
  })).subscribe();
4656
4713
  const $wheel = this.$wheel;
4657
- $wheel.pipe(takeUntil(this._$unsubscribe), switchMap$1(v => of(this.averageVelocity)), debounceTime(100), tap(v => {
4714
+ $wheel.pipe(takeUntil(this._$unsubscribe), tap(() => {
4715
+ this._$grabbing.next(true);
4716
+ }), switchMap$1(v => of(this.averageVelocity)), debounceTime(100), tap(v => {
4717
+ this._$grabbing.next(false);
4658
4718
  this.snapWithInitialForceIfNecessary(v);
4719
+ this._overscrollIteration = this._overscrollStartIteration = 0;
4720
+ this._overscrollApplied = false;
4659
4721
  this._scrollDirection.clear();
4722
+ this._scrollDirectionValueX = this._scrollDirectionValueY = 0;
4660
4723
  })).subscribe();
4661
4724
  const $viewport = of(this.scrollViewport).pipe(takeUntil(this._$unsubscribe), filter$1(v => !!v), map(v => v.nativeElement)), $content = of(this.scrollContent).pipe(takeUntil(this._$unsubscribe), filter$1(v => !!v), map(v => v.nativeElement)), $wheelEmitter = this._inversion ? $viewport : $content;
4662
4725
  $wheelEmitter.pipe(takeUntil(this._$unsubscribe), switchMap$1(content => {
4663
4726
  return fromEvent(content, WHEEL, { passive: false }).pipe(filter$1(() => this._interactive), takeUntil(this._$unsubscribe), tap(e => {
4664
4727
  const isVertical = this._$isVertical.getValue();
4665
4728
  this.emitScrollableEvent();
4666
- this.checkOverscroll(e);
4729
+ this.checkOverscroll(e, true);
4667
4730
  this.stopScrolling(true);
4668
- const scrollSize = isVertical ? this.scrollHeight : this.scrollWidth, startPos = isVertical ? this._y : this._x, delta = isVertical ? e.deltaY : e.deltaX, dp = (startPos + delta), position = this.isInfinity ? dp : (dp < 0 ? 0 : dp > scrollSize ? scrollSize : dp);
4669
- this.scroll({ [isVertical ? TOP$1 : LEFT$1]: position, behavior: INSTANT$1, userAction: true, blending: false, fireUpdate: true });
4731
+ const scrollSize = isVertical ? this.scrollHeight : this.scrollWidth, startPos = isVertical ? this._y : this._x, delta = isVertical ? e.deltaY : (e.deltaX * (this.horizontalAxisInvertion ? -1 : 1)), dp = (startPos + delta), position = this.isInfinity ? dp : (dp < 0 ? 0 : dp > scrollSize ? scrollSize : dp);
4732
+ this.scroll({ [isVertical ? TOP$1 : LEFT$2]: position, behavior: INSTANT$1, userAction: true, blending: false, fireUpdate: true });
4670
4733
  this._$wheel.next(delta);
4671
4734
  }));
4672
4735
  })).subscribe();
@@ -4706,7 +4769,10 @@ class NgScrollView extends BaseScrollView {
4706
4769
  $content.pipe(takeUntil(this._$unsubscribe), switchMap$1(content => {
4707
4770
  return fromEvent(content, MOUSE_DOWN, { passive: false }).pipe(takeUntil(this._$unsubscribe), filter$1(v => this._interactive), switchMap$1(e => {
4708
4771
  mouseCanceled = false;
4772
+ this._overscrollStartIteration = 0;
4773
+ this._overscrollApplied = false;
4709
4774
  this._scrollDirection.clear();
4775
+ this._scrollDirectionValueX = this._scrollDirectionValueY = 0;
4710
4776
  this.cancelOverscroll();
4711
4777
  this.onDragStart();
4712
4778
  this.stopScrolling(true);
@@ -4718,23 +4784,34 @@ class NgScrollView extends BaseScrollView {
4718
4784
  const inversion = this._inversion, isVertical = this._$isVertical.getValue();
4719
4785
  this._isMoving = true;
4720
4786
  this._$grabbing.next(true);
4721
- this._startPosition = (isVertical ? this.y : this.x);
4722
- let prevClientPosition = isVertical ? e.clientY : e.clientX, startClientPos = prevClientPosition, offsets = new Array(), velocities = new Array(), startTime = Date.now();
4787
+ this._startPositionX = this.x;
4788
+ this._startPositionY = this.y;
4789
+ let prevClientPositionX = (e.clientX) * (this.horizontalAxisInvertion ? -1 : 1), prevClientPositionY = e.clientY, startClientPosX = prevClientPositionX, startClientPosY = prevClientPositionY, offsetsX = new Array(), offsetsY = new Array(), velocitiesX = new Array(), velocitiesY = new Array(), startTime = Date.now();
4723
4790
  return fromEvent(window, MOUSE_MOVE, { passive: false }).pipe(takeUntil(this._$unsubscribe), takeUntil($mouseDragCancel), tap(e => {
4724
4791
  this.checkOverscroll(e);
4725
4792
  }), switchMap$1(e => {
4726
- const { position, currentPos, endTime, scrollDelta } = this.calculatePosition(isVertical, e, inversion, startClientPos, startTime, prevClientPosition, offsets, velocities);
4727
- prevClientPosition = currentPos;
4793
+ const { position: positionX, currentPos: currentPosX, endTime, scrollDelta: scrollDeltaX } = this.calculatePosition(false, true, this.horizontalAxisInvertion, e, inversion, startClientPosX, startTime, prevClientPositionX, offsetsX, velocitiesX), { position: positionY, currentPos: currentPosY, scrollDelta: scrollDeltaY } = this.calculatePosition(true, true, false, e, inversion, startClientPosY, startTime, prevClientPositionY, offsetsY, velocitiesY), position = isVertical ? positionY : positionX;
4794
+ prevClientPositionX = currentPosX;
4795
+ prevClientPositionY = currentPosY;
4796
+ this._scrollDirectionValueX += Math.abs(scrollDeltaX);
4797
+ this._scrollDirectionValueY += Math.abs(scrollDeltaY);
4728
4798
  this.move(isVertical, position, true, true, true);
4729
- const offset = Math.abs(position) - Math.abs(isVertical ? this._y : this._x), scrollSize = isVertical ? this.scrollHeight : this.scrollWidth, viewportSize = isVertical ? this._$viewportBounds.getValue().height : this._$viewportBounds.getValue().width;
4730
- if (position >= (scrollSize - viewportSize * .5) || position <= 0) {
4731
- startClientPos -= offset;
4799
+ if (this.isInfinity) {
4800
+ const offset = Math.abs(position) - Math.abs(isVertical ? this._y : this._x), scrollSize = isVertical ? this.scrollHeight : this.scrollWidth, viewportSize = isVertical ? this._$viewportBounds.getValue().height : this._$viewportBounds.getValue().width;
4801
+ if (position >= (scrollSize - viewportSize * .5) || position <= 0) {
4802
+ if (isVertical) {
4803
+ startClientPosY -= offset;
4804
+ }
4805
+ else {
4806
+ startClientPosX -= offset;
4807
+ }
4808
+ }
4732
4809
  }
4733
4810
  startTime = endTime;
4734
4811
  return race([fromEvent(window, MOUSE_UP, { passive: false }), fromEvent(content, MOUSE_UP, { passive: false })]).pipe(takeUntil(this._$unsubscribe), takeUntil($mouseDragCancel), tap(e => {
4735
4812
  mouseCanceled = true;
4736
4813
  this.cancelOverscroll();
4737
- const endTime = Date.now(), timestamp = endTime - startTime, { v0 } = this.calculateVelocity(offsets, scrollDelta, timestamp), { a0 } = this.calculateAcceleration(velocities, v0, timestamp);
4814
+ const endTime = Date.now(), timestamp = endTime - startTime, { v0 } = this.calculateVelocity(isVertical ? offsetsY : offsetsX, isVertical ? scrollDeltaY : scrollDeltaX, timestamp), { a0 } = this.calculateAcceleration(isVertical ? velocitiesY : velocitiesX, v0, timestamp);
4738
4815
  this._isMoving = false;
4739
4816
  this._$grabbing.next(false);
4740
4817
  if (!this.snapIfNecessary(v0, false) && this.scrollBehavior !== BEHAVIOR_INSTANT) {
@@ -4784,7 +4861,10 @@ class NgScrollView extends BaseScrollView {
4784
4861
  $content.pipe(takeUntil(this._$unsubscribe), switchMap$1(content => {
4785
4862
  return fromEvent(content, TOUCH_START, { passive: false }).pipe(takeUntil(this._$unsubscribe), filter$1(() => this._interactive), switchMap$1(e => {
4786
4863
  touchCanceled = false;
4864
+ this._overscrollStartIteration = 0;
4865
+ this._overscrollApplied = false;
4787
4866
  this._scrollDirection.clear();
4867
+ this._scrollDirectionValueX = this._scrollDirectionValueY = 0;
4788
4868
  this.cancelOverscroll();
4789
4869
  this.onDragStart();
4790
4870
  this.stopScrolling(true);
@@ -4796,23 +4876,34 @@ class NgScrollView extends BaseScrollView {
4796
4876
  const inversion = this._inversion, isVertical = this._$isVertical.getValue();
4797
4877
  this._isMoving = true;
4798
4878
  this._$grabbing.next(true);
4799
- this._startPosition = (isVertical ? this.y : this.x);
4800
- let prevClientPosition = isVertical ? e.touches[e.touches.length - 1].clientY : e.touches[e.touches.length - 1].clientX, startClientPos = prevClientPosition, offsets = new Array(), velocities = new Array(), startTime = Date.now();
4879
+ this._startPositionX = this.x;
4880
+ this._startPositionY = this.y;
4881
+ let prevClientPositionX = (e.touches[e.touches.length - 1].clientX) * (this.horizontalAxisInvertion ? -1 : 1), prevClientPositionY = e.touches[e.touches.length - 1].clientY, startClientPosX = prevClientPositionX, startClientPosY = prevClientPositionY, offsetsX = new Array(), offsetsY = new Array(), velocitiesX = new Array(), velocitiesY = new Array(), startTime = Date.now();
4801
4882
  return fromEvent(window, TOUCH_MOVE, { passive: false }).pipe(takeUntil(this._$unsubscribe), takeUntil($touchCanceler), tap(e => {
4802
4883
  this.checkOverscroll(e);
4803
4884
  }), switchMap$1(e => {
4804
- const { position, currentPos, endTime, scrollDelta } = this.calculatePosition(isVertical, e, inversion, startClientPos, startTime, prevClientPosition, offsets, velocities);
4805
- prevClientPosition = currentPos;
4885
+ const { position: positionX, currentPos: currentPosX, endTime, scrollDelta: scrollDeltaX } = this.calculatePosition(false, true, this.horizontalAxisInvertion, e, inversion, startClientPosX, startTime, prevClientPositionX, offsetsX, velocitiesX), { position: positionY, currentPos: currentPosY, scrollDelta: scrollDeltaY } = this.calculatePosition(true, true, false, e, inversion, startClientPosY, startTime, prevClientPositionY, offsetsY, velocitiesY), position = isVertical ? positionY : positionX;
4886
+ prevClientPositionX = currentPosX;
4887
+ prevClientPositionY = currentPosY;
4888
+ this._scrollDirectionValueX += Math.abs(scrollDeltaX);
4889
+ this._scrollDirectionValueY += Math.abs(scrollDeltaY);
4806
4890
  this.move(isVertical, position, true, true, true);
4807
- const offset = Math.abs(position) - Math.abs(isVertical ? this._y : this._x), scrollSize = isVertical ? this.scrollHeight : this.scrollWidth, viewportSize = isVertical ? this._$viewportBounds.getValue().height : this._$viewportBounds.getValue().width;
4808
- if (position >= (scrollSize - viewportSize * .5) || position <= 0) {
4809
- startClientPos -= offset;
4891
+ if (this.isInfinity) {
4892
+ const offset = Math.abs(position) - Math.abs(isVertical ? this._y : this._x), scrollSize = isVertical ? this.scrollHeight : this.scrollWidth, viewportSize = isVertical ? this._$viewportBounds.getValue().height : this._$viewportBounds.getValue().width;
4893
+ if (position >= (scrollSize - viewportSize * .5) || position <= 0) {
4894
+ if (isVertical) {
4895
+ startClientPosY -= offset;
4896
+ }
4897
+ else {
4898
+ startClientPosX -= offset;
4899
+ }
4900
+ }
4810
4901
  }
4811
4902
  startTime = endTime;
4812
4903
  return race([fromEvent(window, TOUCH_END, { passive: false }), fromEvent(content, TOUCH_END, { passive: false })]).pipe(takeUntil(this._$unsubscribe), takeUntil($touchCanceler), tap(e => {
4813
4904
  touchCanceled = true;
4814
4905
  this.cancelOverscroll();
4815
- const endTime = Date.now(), timestamp = endTime - startTime, { v0 } = this.calculateVelocity(offsets, scrollDelta, timestamp), { a0 } = this.calculateAcceleration(velocities, v0, timestamp);
4906
+ const endTime = Date.now(), timestamp = endTime - startTime, { v0 } = this.calculateVelocity(isVertical ? offsetsY : offsetsX, isVertical ? scrollDeltaY : scrollDeltaX, timestamp), { a0 } = this.calculateAcceleration(isVertical ? velocitiesY : velocitiesX, v0, timestamp);
4816
4907
  this._isMoving = false;
4817
4908
  this._$grabbing.next(false);
4818
4909
  if (!this.snapIfNecessary(v0, false) && this.scrollBehavior !== BEHAVIOR_INSTANT) {
@@ -4894,8 +4985,11 @@ class NgScrollView extends BaseScrollView {
4894
4985
  }
4895
4986
  return false;
4896
4987
  }
4897
- calculatePosition(isVertical, e, inversion, startClientPos, startTime, prevClientPosition, offsets, velocities) {
4898
- const currentPos = isVertical ? e.touches?.[e.touches?.length - 1]?.clientY || e.clientY : e.touches?.[e.touches?.length - 1]?.clientX || e.clientX, scrollSize = isVertical ? this.scrollHeight : this.scrollWidth, delta = (inversion ? -1 : 1) * (startClientPos - currentPos), dp = this._startPosition + delta, position = this.isInfinity ? dp : dp < 0 ? 0 : dp > scrollSize ? scrollSize : dp, endTime = Date.now(), timestamp = endTime - startTime, scrollDelta = prevClientPosition === 0 ? 0 : prevClientPosition - currentPos, { v0 } = this.calculateVelocity(offsets, scrollDelta, timestamp);
4988
+ calculatePosition(isVertical, enabled, axisInversion, e, inversion, startClientPos, startTime, prevClientPosition, offsets, velocities) {
4989
+ if (!enabled) {
4990
+ return { position: isVertical ? this._y : this._x, currentPos: null, endTime: Date.now(), scrollDelta: 0 };
4991
+ }
4992
+ const currentPos = (isVertical ? e.touches?.[e.touches?.length - 1]?.clientY || e.clientY : e.touches?.[e.touches?.length - 1]?.clientX || e.clientX) * (axisInversion ? -1 : 1), scrollSize = isVertical ? this.scrollHeight : this.scrollWidth, delta = (inversion ? -1 : 1) * (startClientPos - currentPos), dp = (isVertical ? this._startPositionY : this._startPositionX) + delta, position = this.isInfinity ? dp : dp < 0 ? 0 : dp > scrollSize ? scrollSize : dp, endTime = Date.now(), timestamp = endTime - startTime, scrollDelta = (prevClientPosition === 0 || prevClientPosition === null) ? 0 : prevClientPosition - currentPos, { v0 } = this.calculateVelocity(offsets, scrollDelta, timestamp);
4899
4993
  this.calculateAcceleration(velocities, v0, timestamp);
4900
4994
  return { position, currentPos, endTime, scrollDelta };
4901
4995
  }
@@ -4924,7 +5018,7 @@ class NgScrollView extends BaseScrollView {
4924
5018
  }
4925
5019
  }
4926
5020
  }
4927
- checkOverscroll(e) {
5021
+ checkOverscroll(e, wheel = false) {
4928
5022
  if (!this._overscrollEnabled || !this.overscrollEnabled) {
4929
5023
  if (e.cancelable) {
4930
5024
  e.stopImmediatePropagation();
@@ -4934,14 +5028,35 @@ class NgScrollView extends BaseScrollView {
4934
5028
  }
4935
5029
  if (this._overscrollEnabled) {
4936
5030
  if (this._$isVertical.getValue()) {
4937
- this.checkOverscrollByAxis(e, this._y, this.scrollHeight);
5031
+ if (this._overscrollStartIteration < OVERSCROLL_START_ITERATION) {
5032
+ this._overscrollStartIteration++;
5033
+ this.checkOverscrollByAxis(e, this._y, this.scrollHeight);
5034
+ }
5035
+ else {
5036
+ if (wheel || this._overscrollApplied || this._scrollDirectionValueY > this._scrollDirectionValueX) {
5037
+ this._overscrollApplied = true;
5038
+ this.checkOverscrollByAxis(e, this._y, this.scrollHeight);
5039
+ }
5040
+ }
4938
5041
  }
4939
5042
  else {
4940
- this.checkOverscrollByAxis(e, this._x, this.scrollWidth);
5043
+ if (this._overscrollStartIteration < OVERSCROLL_START_ITERATION) {
5044
+ this._overscrollStartIteration++;
5045
+ this.checkOverscrollByAxis(e, this._x, this.scrollWidth);
5046
+ }
5047
+ else {
5048
+ if (wheel || this._overscrollApplied || this._scrollDirectionValueX > this._scrollDirectionValueY) {
5049
+ this._overscrollApplied = true;
5050
+ this.checkOverscrollByAxis(e, this._x, this.scrollWidth);
5051
+ }
5052
+ }
4941
5053
  }
4942
5054
  }
4943
5055
  }
4944
5056
  calculateVelocity(offsets, delta, timestamp, indexOffset = 10) {
5057
+ if (offsets.length > MAX_VELOCITIES_LENGTH) {
5058
+ offsets.shift();
5059
+ }
4945
5060
  offsets.push([delta, timestamp < ANIMATOR_MIN_TIMESTAMP ? ANIMATOR_MIN_TIMESTAMP : timestamp]);
4946
5061
  const len = offsets.length, startIndex = len > indexOffset ? len - indexOffset : 0, lastVSign = calculateDirection(offsets), speedScale = this.scrollingSettings?.speedScale ?? SPEED_SCALE;
4947
5062
  let vSum = 0;
@@ -4957,7 +5072,10 @@ class NgScrollView extends BaseScrollView {
4957
5072
  return { v0 };
4958
5073
  }
4959
5074
  calculateAcceleration(velocities, delta, timestamp, indexOffset = 10) {
4960
- velocities.push([delta, timestamp < ANIMATOR_MIN_TIMESTAMP ? ANIMATOR_MIN_TIMESTAMP : timestamp]);
5075
+ if (velocities.length > MAX_VELOCITIES_LENGTH) {
5076
+ velocities.shift();
5077
+ }
5078
+ velocities.push([Math.abs(delta) < MIN_DELTA ? 0 : delta, timestamp < ANIMATOR_MIN_TIMESTAMP ? ANIMATOR_MIN_TIMESTAMP : timestamp]);
4961
5079
  const len = velocities.length, startIndex = len > indexOffset ? len - indexOffset : 0;
4962
5080
  let aSum = 0, prevV0, iteration = 0, lastVSign = calculateDirection(velocities);
4963
5081
  const mass = this.scrollingSettings?.mass ?? MASS;
@@ -4975,7 +5093,7 @@ class NgScrollView extends BaseScrollView {
4975
5093
  iteration++;
4976
5094
  }
4977
5095
  const a0 = aSum * (this.scrollingSettings?.frictionalForce ?? FRICTION_FORCE);
4978
- return { a0 };
5096
+ return { a0: Math.abs(a0) < MIN_ACCELERATION ? 0 : a0 };
4979
5097
  }
4980
5098
  stopScrolling(force = false) {
4981
5099
  if (this._isAlignmentAnimation && !force) {
@@ -4985,7 +5103,7 @@ class NgScrollView extends BaseScrollView {
4985
5103
  this._animator.stop();
4986
5104
  }
4987
5105
  move(isVertical, position, blending = false, userAction = false, fireUpdate = true) {
4988
- this.scroll({ [isVertical ? TOP$1 : LEFT$1]: position, behavior: INSTANT$1, blending, userAction, fireUpdate });
5106
+ this.scroll({ [isVertical ? TOP$1 : LEFT$2]: position, behavior: INSTANT$1, blending, userAction, fireUpdate });
4989
5107
  }
4990
5108
  moveWithAcceleration(isVertical, position, v0, v, a0, timestamp) {
4991
5109
  if (a0 !== 0 && timestamp < MAX_VELOCITY_TIMESTAMP) {
@@ -5281,7 +5399,7 @@ class NgScrollView extends BaseScrollView {
5281
5399
  }
5282
5400
  refreshCoordinate(x, y) {
5283
5401
  const scrollContent = this.scrollContent?.nativeElement;
5284
- scrollContent.style.transform = matrix3d((this._inversion ? 1 : -1) * x + (this._$isVertical.getValue() ? 0 : this._startLayoutOffset), (this._inversion ? 1 : -1) * y + (this._$isVertical.getValue() ? this._startLayoutOffset : 0));
5402
+ scrollContent.style.transform = matrix3d((this._inversion ? 1 : -1) * x * (this.horizontalAxisInvertion ? -1 : 1) + (this._$isVertical.getValue() ? 0 : this._startLayoutOffset), (this._inversion ? 1 : -1) * y + (this._$isVertical.getValue() ? this._startLayoutOffset : 0));
5285
5403
  }
5286
5404
  fireScrollEvent(userAction) {
5287
5405
  this._$scroll.next(userAction);
@@ -5390,7 +5508,7 @@ class NgScrollBarComponent extends NgScrollView {
5390
5508
  this._$scrollbarMinSize.next(v);
5391
5509
  }
5392
5510
  }
5393
- get scrollbarMinSize() { return this._$endOffset.getValue(); }
5511
+ get scrollbarMinSize() { return this._$scrollbarMinSize.getValue(); }
5394
5512
  _$prepared = new BehaviorSubject(false);
5395
5513
  $prepared = this._$prepared.asObservable();
5396
5514
  set prepared(v) {
@@ -5399,14 +5517,6 @@ class NgScrollBarComponent extends NgScrollView {
5399
5517
  }
5400
5518
  }
5401
5519
  get prepared() { return this._$prepared.getValue(); }
5402
- _$langTextDir = new BehaviorSubject(DEFAULT_LANG_TEXT_DIR);
5403
- $langTextDir = this._$langTextDir.asObservable();
5404
- set langTextDir(v) {
5405
- if (this._$langTextDir.getValue() !== v) {
5406
- this._$langTextDir.next(v);
5407
- }
5408
- }
5409
- get langTextDir() { return this._$langTextDir.getValue(); }
5410
5520
  _$interactive = new BehaviorSubject(DEFAULT_SCROLLBAR_INTERACTIVE);
5411
5521
  $interactive = this._$interactive.asObservable();
5412
5522
  set interactive(v) {
@@ -5549,7 +5659,7 @@ class NgScrollBarComponent extends NgScrollView {
5549
5659
  const el = this._elementRef.nativeElement;
5550
5660
  if (!!el) {
5551
5661
  el.style[POSITION$1] = overlapping ? POSITION_ABSOLUTE : POSITION_RELATIVE;
5552
- el.style[LEFT$2] = overlapping && langTextDir === TextDirections.RTL ? '0' : UNSET$5;
5662
+ el.style[LEFT$3] = overlapping && langTextDir === TextDirections.RTL ? '0' : UNSET$5;
5553
5663
  el.style[RIGHT$1] = overlapping && langTextDir === TextDirections.LTR ? '0' : UNSET$5;
5554
5664
  el.style[WIDTH] = overlapping ? SIZE_AUTO : SIZE_100_PERSENT;
5555
5665
  }
@@ -5573,7 +5683,7 @@ class NgScrollBarComponent extends NgScrollView {
5573
5683
  })).subscribe();
5574
5684
  }
5575
5685
  createDragEvent(userAction) {
5576
- const isVertical = this._$isVertical.getValue(), 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;
5686
+ const isVertical = this._$isVertical.getValue(), scrollSize = isVertical ? this.scrollHeight : this.scrollWidth, scrollPosition = isVertical ? this.y : this.x, startOffset = this.startOffset, endOffset = this.endOffset, scrollContent = this.scrollContent?.nativeElement, scrollViewport = this.scrollViewport?.nativeElement;
5577
5687
  if (!!scrollViewport && !!scrollContent) {
5578
5688
  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);
5579
5689
  const event = {
@@ -5601,7 +5711,7 @@ class NgScrollBarComponent extends NgScrollView {
5601
5711
  this._scrollBarService.click(event);
5602
5712
  }
5603
5713
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgScrollBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5604
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NgScrollBarComponent, selector: "ng-scroll-bar", inputs: { loading: "loading", thumbGradientPositions: "thumbGradientPositions", size: "size", thickness: "thickness", scrollbarMinSize: "scrollbarMinSize", prepared: "prepared", langTextDir: "langTextDir", interactive: "interactive", overlapping: "overlapping", show: "show", params: "params", renderer: "renderer" }, outputs: { onDrag: "onDrag", onDragEnd: "onDragEnd" }, providers: [
5714
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NgScrollBarComponent, selector: "ng-scroll-bar", inputs: { loading: "loading", thumbGradientPositions: "thumbGradientPositions", size: "size", thickness: "thickness", scrollbarMinSize: "scrollbarMinSize", prepared: "prepared", interactive: "interactive", overlapping: "overlapping", show: "show", params: "params", renderer: "renderer" }, outputs: { onDrag: "onDrag", onDragEnd: "onDragEnd" }, providers: [
5605
5715
  { provide: SCROLL_VIEW_INVERSION, useValue: true },
5606
5716
  { provide: SCROLL_VIEW_NORMALIZE_VALUE_FROM_ZERO, useValue: false },
5607
5717
  { provide: SCROLL_VIEW_OVERSCROLL_ENABLED, useValue: false },
@@ -5637,8 +5747,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
5637
5747
  type: Input
5638
5748
  }], prepared: [{
5639
5749
  type: Input
5640
- }], langTextDir: [{
5641
- type: Input
5642
5750
  }], interactive: [{
5643
5751
  type: Input
5644
5752
  }], overlapping: [{
@@ -5651,7 +5759,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
5651
5759
  type: Input
5652
5760
  }] } });
5653
5761
 
5654
- const RIGHT = 'right', DIR = 'dir';
5762
+ const LEFT$1 = 'left', RIGHT = 'right', DIR = 'dir';
5655
5763
  /**
5656
5764
  * LocaleSensitiveDirective
5657
5765
  * Maximum performance for extremely large lists.
@@ -5679,14 +5787,15 @@ class LocaleSensitiveDirective {
5679
5787
  this._elementRef = _elementRef;
5680
5788
  const $langTextDir = this.$langTextDir, $listDir = this.$listDir;
5681
5789
  combineLatest([$langTextDir, $listDir]).pipe(takeUntil(this._$unsubscribe), tap(([dir, listDir]) => {
5682
- const element = this._elementRef.nativeElement, isVertical = isDirection(listDir, ScrollerDirection$1.VERTICAL);
5683
- element.setAttribute(DIR, isVertical ? dir : TextDirections.LTR);
5684
- if (dir === TextDirections.RTL && isVertical) {
5790
+ const element = this._elementRef.nativeElement;
5791
+ element.setAttribute(DIR, dir);
5792
+ if (dir === TextDirections.RTL) {
5685
5793
  element.style.textAlign = RIGHT;
5686
5794
  element.classList.add(TextDirections.RTL);
5687
5795
  element.classList.remove(TextDirections.LTR);
5688
5796
  }
5689
5797
  else {
5798
+ element.style.textAlign = LEFT$1;
5690
5799
  element.classList.add(TextDirections.LTR);
5691
5800
  element.classList.remove(TextDirections.RTL);
5692
5801
  }
@@ -5857,8 +5966,6 @@ class NgScrollerComponent extends NgScrollView {
5857
5966
  $show = this._$show.asObservable();
5858
5967
  _$preparedSignal = new BehaviorSubject(false);
5859
5968
  $preparedSignal = this._$preparedSignal.asObservable();
5860
- _$langTextDir = new BehaviorSubject(TextDirections.LTR);
5861
- $langTextDir = this._$langTextDir.asObservable();
5862
5969
  _$listStyles = new BehaviorSubject({ perspectiveOrigin: 'center' });
5863
5970
  $listStyles = this._$listStyles.asObservable();
5864
5971
  _scrollBox = new ScrollBox$1();
@@ -5933,6 +6040,13 @@ class NgScrollerComponent extends NgScrollView {
5933
6040
  }
5934
6041
  ngAfterViewInit() {
5935
6042
  super.ngAfterViewInit();
6043
+ this.$resizeViewport.pipe(takeUntil(this._$unsubscribe), debounceTime(0), tap(() => {
6044
+ this.snapIfNeed();
6045
+ }), switchMap$1(() => {
6046
+ return this.$scroll.pipe(takeUntil(this._$unsubscribe), take(1), tap(() => {
6047
+ this.snapIfNeed();
6048
+ }));
6049
+ })).subscribe();
5936
6050
  const $filter = of(this.filter), $motionBlur = this.$motionBlur, $maxMotionBlur = this.$maxMotionBlur, $motionBlurEnabled = this.$motionBlurEnabled, $isVertical = this.$isVertical;
5937
6051
  const $scrollbarScroll = this.$scrollbarScroll;
5938
6052
  $scrollbarScroll.pipe(takeUntil(this._$unsubscribe), debounceTime(50), tap(() => {
@@ -5946,9 +6060,6 @@ class NgScrollerComponent extends NgScrollView {
5946
6060
  }), debounceTime(50), tap(([, , filter, ,]) => {
5947
6061
  filter.nativeElement.setStdDeviation(0, 0);
5948
6062
  })).subscribe();
5949
- this._service.$langTextDir.pipe(takeUntil(this._$unsubscribe), debounceTime(0), tap(v => {
5950
- this._$langTextDir.next(v);
5951
- })).subscribe();
5952
6063
  const $prepare = this.$preparedSignal;
5953
6064
  $prepare.pipe(takeUntil(this._$unsubscribe), filter$1(v => !!v), tap(() => {
5954
6065
  this.updateScrollBarHandler(true, false, true);
@@ -5988,9 +6099,9 @@ class NgScrollerComponent extends NgScrollView {
5988
6099
  this._$viewInitialized.next(true);
5989
6100
  }
5990
6101
  recalculatePerspective() {
5991
- const isVertical = this._$isVertical.getValue(), scrollSize = (isVertical ? this.scrollTop : this.scrollLeft) - this._startLayoutOffset, { width, height } = this._$viewportBounds.getValue();
6102
+ const isVertical = this._$isVertical.getValue(), inverted = this.horizontalAxisInvertion, scrollSize = (isVertical ? this.scrollTop : this.scrollLeft) - this._startLayoutOffset, maxScrollSize = isVertical ? this.scrollHeight : this.scrollWidth, { width, height } = this._$viewportBounds.getValue();
5992
6103
  this._$listStyles.next({
5993
- perspectiveOrigin: `${isVertical ? width * .5 : (scrollSize + width * .5)}${PX$1} ${isVertical ? (scrollSize + height * .5) : height * .5}${PX$1}`
6104
+ perspectiveOrigin: `${isVertical ? width * .5 : (inverted ? ((maxScrollSize - scrollSize) + width * .5 - this.startOffset) : (scrollSize + width * .5))}${PX$1} ${isVertical ? (inverted ? ((maxScrollSize - scrollSize) + height * .5) : (scrollSize + height * .5)) : height * .5}${PX$1}`
5994
6105
  });
5995
6106
  }
5996
6107
  onResizeViewport() {
@@ -6003,6 +6114,7 @@ class NgScrollerComponent extends NgScrollView {
6003
6114
  this._$viewportBounds.next(bounds);
6004
6115
  this.updateScrollBar();
6005
6116
  this._$resizeViewport.next(bounds);
6117
+ this.recalculatePerspective();
6006
6118
  }
6007
6119
  }
6008
6120
  onResizeContent(value = null) {
@@ -6018,6 +6130,7 @@ class NgScrollerComponent extends NgScrollView {
6018
6130
  this._$contentBounds.next(bounds);
6019
6131
  this.updateScrollBar();
6020
6132
  this._$resizeContent.next(bounds);
6133
+ this.recalculatePerspective();
6021
6134
  }
6022
6135
  }
6023
6136
  updateScrollBarHandler(update = false, blending = true, fireUpdate = false) {
@@ -6182,7 +6295,7 @@ class NgScrollerComponent extends NgScrollView {
6182
6295
  { provide: SCROLL_VIEW_INVERSION, useValue: false },
6183
6296
  { provide: SCROLL_VIEW_NORMALIZE_VALUE_FROM_ZERO, useValue: true },
6184
6297
  { provide: SCROLL_VIEW_OVERSCROLL_ENABLED, useValue: true },
6185
- ], viewQueries: [{ propertyName: "scrollBar", first: true, predicate: ["scrollBar"], descendants: true, read: NgScrollBarComponent }, { propertyName: "filter", first: true, predicate: ["filter"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div localeSensitive [langTextDir]=\"($langTextDir | async)!\" [listDir]=\"($direction | async)!\" class=\"ngvl__container\"\r\n [ngClass]=\"($containerClasses | async)!\">\r\n <svg part=\"viewport\" width=\"100%\" height=\"100%\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n <filter [id]=\"_filterId\">\r\n <feGaussianBlur #filter></feGaussianBlur>\r\n </filter>\r\n <foreignObject xmlns=\"http://www.w3.org/1999/xhtml\" width=\"100%\" height=\"100%\" class=\"ngvl__viewport\">\r\n <div class=\"ngvl__scroller-wrapper\" [class.filtered]=\"($motionBlurEnabled | async)!\" [style.filter]=\"($motionBlurEnabled | async)! ? _filter : 'unset'\">\r\n <div cdkScrollable #scrollViewport part=\"scroller\" class=\"ngvl__scroller\">\r\n <div #scrollContent [attr.aria-orientation]=\"($direction | async)!\"\r\n [attr.aria-activedescendant]=\"$focusedElement | async\" tabindex=\"0\" part=\"list\" class=\"ngvl__list\"\r\n [ngClass]=\"($actualClasses | async)!\" [ngStyle]=\"($listStyles | async)!\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n </div>\r\n </foreignObject>\r\n </svg>\r\n <ng-container *ngIf=\"($scrollbarEnabled | async)!\">\r\n <ng-scroll-bar #scrollBar [direction]=\"($direction | async)!\" [size]=\"($actualThumbSize | async)!\" [renderer]=\"($scrollbarThumbRenderer | async)!\"\r\n [thickness]=\"($scrollbarThickness | async)!\" [params]=\"($scrollbarThumbParams | async)!\" [loading]=\"($loading | async)!\" [overlapping]=\"($overlappingScrollbar | async)!\"\r\n [thumbGradientPositions]=\"($thumbColorPositions | async)!\" [prepared]=\"($preparedSignal | async)!\" [interactive]=\"($scrollbarInteractive | async)!\"\r\n [show]=\"($show | async)!\" [startOffset]=\"($startOffset | async)!\" [langTextDir]=\"($langTextDir | async)!\"\r\n [endOffset]=\"($endOffset | async)!\" [overscrollEnabled]=\"($overscrollEnabled | async)!\" [scrollBehavior]=\"($scrollBehavior | async)!\"\r\n [scrollbarMinSize]=\"($scrollbarMinSize | async)!\" (onDrag)=\"onScrollBarDragHandler($event)\"\r\n (onDragEnd)=\"onScrollBarDragEndHandler($event)\"></ng-scroll-bar>\r\n </ng-container>\r\n</div>", styles: [":host{position:relative;overflow:hidden;-webkit-user-select:none;user-select:none}.ngvl__container{position:relative;overflow:hidden;display:grid;width:100%;height:100%;cursor:grab}.ngvl__container.overlapping{position:relative;display:block}.ngvl__container.grabbing{cursor:grabbing}.ngvl__container.horizontal{transition:grid-template-rows .1s ease-out}.ngvl__container.horizontal:not(.overlapping){grid-template-rows:1fr 0}.ngvl__container.horizontal.scrollable.enabled:not(.overlapping){grid-template-rows:1fr auto}.ngvl__container.horizontal .ngvl__list{display:inline-flex}.ngvl__container.horizontal .ngvl__scroller-wrapper.filtered,.ngvl__container.horizontal .ngvl__scroller{overflow:unset}.ngvl__container.vertical{transition:grid-template-columns .1s ease-out}.ngvl__container.vertical:not(.overlapping){grid-template-columns:1fr 0}.ngvl__container.vertical.scrollable.enabled:not(.overlapping){grid-template-columns:1fr auto}.ngvl__container.vertical .ngvl__scroller-wrapper.filtered,.ngvl__container.vertical .ngvl__scroller{overflow:unset}.ngvl__container .ngvl__scroller-wrapper,.ngvl__container .ngvl__scroller{display:block;position:relative;overflow:hidden;width:100%;height:100%}.ngvl__container .ngvl__list{position:absolute;list-style:none;padding:0;margin:0;width:100%;height:100%;opacity:0}.ngvl__container .ngvl__list.prepared{opacity:1}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: NgScrollBarComponent, selector: "ng-scroll-bar", inputs: ["loading", "thumbGradientPositions", "size", "thickness", "scrollbarMinSize", "prepared", "langTextDir", "interactive", "overlapping", "show", "params", "renderer"], outputs: ["onDrag", "onDragEnd"] }, { kind: "directive", type: LocaleSensitiveDirective, selector: "[localeSensitive]", inputs: ["langTextDir", "listDir"] }, { kind: "directive", type: i4.CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }] });
6298
+ ], viewQueries: [{ propertyName: "scrollBar", first: true, predicate: ["scrollBar"], descendants: true, read: NgScrollBarComponent }, { propertyName: "filter", first: true, predicate: ["filter"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div localeSensitive [langTextDir]=\"($langTextDir | async)!\" [listDir]=\"($direction | async)!\" class=\"ngvl__container\"\r\n [ngClass]=\"($containerClasses | async)!\">\r\n <svg part=\"viewport\" width=\"100%\" height=\"100%\" xmlns=\"http://www.w3.org/2000/svg\"\r\n xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n <filter [id]=\"_filterId\">\r\n <feGaussianBlur #filter></feGaussianBlur>\r\n </filter>\r\n <foreignObject xmlns=\"http://www.w3.org/1999/xhtml\" width=\"100%\" height=\"100%\" class=\"ngvl__viewport\">\r\n <div class=\"ngvl__scroller-wrapper\" [class.filtered]=\"($motionBlurEnabled | async)!\"\r\n [style.filter]=\"($motionBlurEnabled | async)! ? _filter : 'unset'\">\r\n <div cdkScrollable #scrollViewport part=\"scroller\" class=\"ngvl__scroller\">\r\n <div #scrollContent [attr.aria-orientation]=\"($direction | async)!\"\r\n [attr.aria-activedescendant]=\"$focusedElement | async\" tabindex=\"0\" part=\"list\"\r\n class=\"ngvl__list\" [ngClass]=\"($actualClasses | async)!\" [ngStyle]=\"($listStyles | async)!\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n </div>\r\n </foreignObject>\r\n </svg>\r\n <ng-container *ngIf=\"($scrollbarEnabled | async)!\">\r\n <ng-scroll-bar #scrollBar [direction]=\"($direction | async)!\" [size]=\"($actualThumbSize | async)!\"\r\n [langTextDir]=\"($langTextDir | async)!\" [renderer]=\"($scrollbarThumbRenderer | async)!\"\r\n [thickness]=\"($scrollbarThickness | async)!\" [params]=\"($scrollbarThumbParams | async)!\"\r\n [loading]=\"($loading | async)!\" [overlapping]=\"($overlappingScrollbar | async)!\"\r\n [thumbGradientPositions]=\"($thumbColorPositions | async)!\" [prepared]=\"($preparedSignal | async)!\"\r\n [interactive]=\"($scrollbarInteractive | async)!\" [show]=\"($show | async)!\"\r\n [startOffset]=\"($startOffset | async)!\" [langTextDir]=\"($langTextDir | async)!\"\r\n [endOffset]=\"($endOffset | async)!\" [overscrollEnabled]=\"($overscrollEnabled | async)!\"\r\n [scrollBehavior]=\"($scrollBehavior | async)!\" [scrollbarMinSize]=\"($scrollbarMinSize | async)!\"\r\n (onDrag)=\"onScrollBarDragHandler($event)\" (onDragEnd)=\"onScrollBarDragEndHandler($event)\"></ng-scroll-bar>\r\n </ng-container>\r\n</div>", styles: [":host{position:relative;overflow:hidden;-webkit-user-select:none;user-select:none}.ngvl__container{position:relative;overflow:hidden;display:grid;width:100%;height:100%;cursor:grab}.ngvl__container.overlapping{position:relative;display:block}.ngvl__container.grabbing{cursor:grabbing}.ngvl__container.horizontal{transition:grid-template-rows .1s ease-out}.ngvl__container.horizontal:not(.overlapping){grid-template-rows:1fr 0}.ngvl__container.horizontal.scrollable.enabled:not(.overlapping){grid-template-rows:1fr auto}.ngvl__container.horizontal .ngvl__list{display:inline-flex}.ngvl__container.horizontal .ngvl__scroller-wrapper.filtered,.ngvl__container.horizontal .ngvl__scroller{overflow:unset}.ngvl__container.vertical{transition:grid-template-columns .1s ease-out}.ngvl__container.vertical:not(.overlapping){grid-template-columns:1fr 0}.ngvl__container.vertical.scrollable.enabled:not(.overlapping){grid-template-columns:1fr auto}.ngvl__container.vertical .ngvl__scroller-wrapper.filtered,.ngvl__container.vertical .ngvl__scroller{overflow:unset}.ngvl__container .ngvl__scroller-wrapper,.ngvl__container .ngvl__scroller{display:block;position:relative;overflow:hidden;width:100%;height:100%}.ngvl__container .ngvl__list{position:absolute;list-style:none;padding:0;margin:0;width:100%;height:100%;opacity:0}.ngvl__container .ngvl__list.prepared{opacity:1}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: NgScrollBarComponent, selector: "ng-scroll-bar", inputs: ["loading", "thumbGradientPositions", "size", "thickness", "scrollbarMinSize", "prepared", "interactive", "overlapping", "show", "params", "renderer"], outputs: ["onDrag", "onDragEnd"] }, { kind: "directive", type: LocaleSensitiveDirective, selector: "[localeSensitive]", inputs: ["langTextDir", "listDir"] }, { kind: "directive", type: i4.CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }] });
6186
6299
  }
6187
6300
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgScrollerComponent, decorators: [{
6188
6301
  type: Component,
@@ -6190,7 +6303,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
6190
6303
  { provide: SCROLL_VIEW_INVERSION, useValue: false },
6191
6304
  { provide: SCROLL_VIEW_NORMALIZE_VALUE_FROM_ZERO, useValue: true },
6192
6305
  { provide: SCROLL_VIEW_OVERSCROLL_ENABLED, useValue: true },
6193
- ], standalone: false, template: "<div localeSensitive [langTextDir]=\"($langTextDir | async)!\" [listDir]=\"($direction | async)!\" class=\"ngvl__container\"\r\n [ngClass]=\"($containerClasses | async)!\">\r\n <svg part=\"viewport\" width=\"100%\" height=\"100%\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n <filter [id]=\"_filterId\">\r\n <feGaussianBlur #filter></feGaussianBlur>\r\n </filter>\r\n <foreignObject xmlns=\"http://www.w3.org/1999/xhtml\" width=\"100%\" height=\"100%\" class=\"ngvl__viewport\">\r\n <div class=\"ngvl__scroller-wrapper\" [class.filtered]=\"($motionBlurEnabled | async)!\" [style.filter]=\"($motionBlurEnabled | async)! ? _filter : 'unset'\">\r\n <div cdkScrollable #scrollViewport part=\"scroller\" class=\"ngvl__scroller\">\r\n <div #scrollContent [attr.aria-orientation]=\"($direction | async)!\"\r\n [attr.aria-activedescendant]=\"$focusedElement | async\" tabindex=\"0\" part=\"list\" class=\"ngvl__list\"\r\n [ngClass]=\"($actualClasses | async)!\" [ngStyle]=\"($listStyles | async)!\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n </div>\r\n </foreignObject>\r\n </svg>\r\n <ng-container *ngIf=\"($scrollbarEnabled | async)!\">\r\n <ng-scroll-bar #scrollBar [direction]=\"($direction | async)!\" [size]=\"($actualThumbSize | async)!\" [renderer]=\"($scrollbarThumbRenderer | async)!\"\r\n [thickness]=\"($scrollbarThickness | async)!\" [params]=\"($scrollbarThumbParams | async)!\" [loading]=\"($loading | async)!\" [overlapping]=\"($overlappingScrollbar | async)!\"\r\n [thumbGradientPositions]=\"($thumbColorPositions | async)!\" [prepared]=\"($preparedSignal | async)!\" [interactive]=\"($scrollbarInteractive | async)!\"\r\n [show]=\"($show | async)!\" [startOffset]=\"($startOffset | async)!\" [langTextDir]=\"($langTextDir | async)!\"\r\n [endOffset]=\"($endOffset | async)!\" [overscrollEnabled]=\"($overscrollEnabled | async)!\" [scrollBehavior]=\"($scrollBehavior | async)!\"\r\n [scrollbarMinSize]=\"($scrollbarMinSize | async)!\" (onDrag)=\"onScrollBarDragHandler($event)\"\r\n (onDragEnd)=\"onScrollBarDragEndHandler($event)\"></ng-scroll-bar>\r\n </ng-container>\r\n</div>", styles: [":host{position:relative;overflow:hidden;-webkit-user-select:none;user-select:none}.ngvl__container{position:relative;overflow:hidden;display:grid;width:100%;height:100%;cursor:grab}.ngvl__container.overlapping{position:relative;display:block}.ngvl__container.grabbing{cursor:grabbing}.ngvl__container.horizontal{transition:grid-template-rows .1s ease-out}.ngvl__container.horizontal:not(.overlapping){grid-template-rows:1fr 0}.ngvl__container.horizontal.scrollable.enabled:not(.overlapping){grid-template-rows:1fr auto}.ngvl__container.horizontal .ngvl__list{display:inline-flex}.ngvl__container.horizontal .ngvl__scroller-wrapper.filtered,.ngvl__container.horizontal .ngvl__scroller{overflow:unset}.ngvl__container.vertical{transition:grid-template-columns .1s ease-out}.ngvl__container.vertical:not(.overlapping){grid-template-columns:1fr 0}.ngvl__container.vertical.scrollable.enabled:not(.overlapping){grid-template-columns:1fr auto}.ngvl__container.vertical .ngvl__scroller-wrapper.filtered,.ngvl__container.vertical .ngvl__scroller{overflow:unset}.ngvl__container .ngvl__scroller-wrapper,.ngvl__container .ngvl__scroller{display:block;position:relative;overflow:hidden;width:100%;height:100%}.ngvl__container .ngvl__list{position:absolute;list-style:none;padding:0;margin:0;width:100%;height:100%;opacity:0}.ngvl__container .ngvl__list.prepared{opacity:1}\n"] }]
6306
+ ], standalone: false, template: "<div localeSensitive [langTextDir]=\"($langTextDir | async)!\" [listDir]=\"($direction | async)!\" class=\"ngvl__container\"\r\n [ngClass]=\"($containerClasses | async)!\">\r\n <svg part=\"viewport\" width=\"100%\" height=\"100%\" xmlns=\"http://www.w3.org/2000/svg\"\r\n xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n <filter [id]=\"_filterId\">\r\n <feGaussianBlur #filter></feGaussianBlur>\r\n </filter>\r\n <foreignObject xmlns=\"http://www.w3.org/1999/xhtml\" width=\"100%\" height=\"100%\" class=\"ngvl__viewport\">\r\n <div class=\"ngvl__scroller-wrapper\" [class.filtered]=\"($motionBlurEnabled | async)!\"\r\n [style.filter]=\"($motionBlurEnabled | async)! ? _filter : 'unset'\">\r\n <div cdkScrollable #scrollViewport part=\"scroller\" class=\"ngvl__scroller\">\r\n <div #scrollContent [attr.aria-orientation]=\"($direction | async)!\"\r\n [attr.aria-activedescendant]=\"$focusedElement | async\" tabindex=\"0\" part=\"list\"\r\n class=\"ngvl__list\" [ngClass]=\"($actualClasses | async)!\" [ngStyle]=\"($listStyles | async)!\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n </div>\r\n </foreignObject>\r\n </svg>\r\n <ng-container *ngIf=\"($scrollbarEnabled | async)!\">\r\n <ng-scroll-bar #scrollBar [direction]=\"($direction | async)!\" [size]=\"($actualThumbSize | async)!\"\r\n [langTextDir]=\"($langTextDir | async)!\" [renderer]=\"($scrollbarThumbRenderer | async)!\"\r\n [thickness]=\"($scrollbarThickness | async)!\" [params]=\"($scrollbarThumbParams | async)!\"\r\n [loading]=\"($loading | async)!\" [overlapping]=\"($overlappingScrollbar | async)!\"\r\n [thumbGradientPositions]=\"($thumbColorPositions | async)!\" [prepared]=\"($preparedSignal | async)!\"\r\n [interactive]=\"($scrollbarInteractive | async)!\" [show]=\"($show | async)!\"\r\n [startOffset]=\"($startOffset | async)!\" [langTextDir]=\"($langTextDir | async)!\"\r\n [endOffset]=\"($endOffset | async)!\" [overscrollEnabled]=\"($overscrollEnabled | async)!\"\r\n [scrollBehavior]=\"($scrollBehavior | async)!\" [scrollbarMinSize]=\"($scrollbarMinSize | async)!\"\r\n (onDrag)=\"onScrollBarDragHandler($event)\" (onDragEnd)=\"onScrollBarDragEndHandler($event)\"></ng-scroll-bar>\r\n </ng-container>\r\n</div>", styles: [":host{position:relative;overflow:hidden;-webkit-user-select:none;user-select:none}.ngvl__container{position:relative;overflow:hidden;display:grid;width:100%;height:100%;cursor:grab}.ngvl__container.overlapping{position:relative;display:block}.ngvl__container.grabbing{cursor:grabbing}.ngvl__container.horizontal{transition:grid-template-rows .1s ease-out}.ngvl__container.horizontal:not(.overlapping){grid-template-rows:1fr 0}.ngvl__container.horizontal.scrollable.enabled:not(.overlapping){grid-template-rows:1fr auto}.ngvl__container.horizontal .ngvl__list{display:inline-flex}.ngvl__container.horizontal .ngvl__scroller-wrapper.filtered,.ngvl__container.horizontal .ngvl__scroller{overflow:unset}.ngvl__container.vertical{transition:grid-template-columns .1s ease-out}.ngvl__container.vertical:not(.overlapping){grid-template-columns:1fr 0}.ngvl__container.vertical.scrollable.enabled:not(.overlapping){grid-template-columns:1fr auto}.ngvl__container.vertical .ngvl__scroller-wrapper.filtered,.ngvl__container.vertical .ngvl__scroller{overflow:unset}.ngvl__container .ngvl__scroller-wrapper,.ngvl__container .ngvl__scroller{display:block;position:relative;overflow:hidden;width:100%;height:100%}.ngvl__container .ngvl__list{position:absolute;list-style:none;padding:0;margin:0;width:100%;height:100%;opacity:0}.ngvl__container .ngvl__list.prepared{opacity:1}\n"] }]
6194
6307
  }], ctorParameters: function () { return []; }, propDecorators: { scrollBar: [{
6195
6308
  type: ViewChild,
6196
6309
  args: ['scrollBar', { read: NgScrollBarComponent }]
@@ -6243,6 +6356,7 @@ const createItemData = (data, isVertical, bounds, boundsSize, dynamic, divides,
6243
6356
  measures: {
6244
6357
  position: 0,
6245
6358
  scrollSize: 0,
6359
+ maxScrollSize: 0,
6246
6360
  size: itemSize,
6247
6361
  row: {
6248
6362
  size: itemSize,
@@ -6302,6 +6416,7 @@ const createItemData = (data, isVertical, bounds, boundsSize, dynamic, divides,
6302
6416
  fullSize: false,
6303
6417
  layoutIndexOffset: 0,
6304
6418
  totalItems: 0,
6419
+ inverted: false,
6305
6420
  },
6306
6421
  };
6307
6422
  };
@@ -6526,8 +6641,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
6526
6641
  */
6527
6642
  class NgPrerenderScrollerComponent extends BaseScrollView {
6528
6643
  scrollBar;
6529
- _$langTextDir = new BehaviorSubject(TextDirections.LTR);
6530
- $langTextDir = this._$langTextDir.asObservable();
6531
6644
  _$scrollbarEnabled = new BehaviorSubject(DEFAULT_SCROLLBAR_ENABLED);
6532
6645
  $scrollbarEnabled = this._$scrollbarEnabled.asObservable();
6533
6646
  set scrollbarEnabled(v) {
@@ -7311,16 +7424,6 @@ class NgVirtualListComponent extends DisposableComponent {
7311
7424
  }
7312
7425
  ;
7313
7426
  get scrollbarThumbParams() { return this._$scrollbarThumbParams.getValue(); }
7314
- _loading = {
7315
- transform: (v) => {
7316
- const valid = validateBoolean(v);
7317
- if (!valid) {
7318
- console.error('The "loading" parameter must be of type `boolean`.');
7319
- return false;
7320
- }
7321
- return v;
7322
- },
7323
- };
7324
7427
  _$loading = new BehaviorSubject(false);
7325
7428
  $loading = this._$loading.asObservable();
7326
7429
  _loadingTransform = (v) => {
@@ -8074,9 +8177,9 @@ class NgVirtualListComponent extends DisposableComponent {
8074
8177
  const valid = validateFloat(v);
8075
8178
  if (!valid) {
8076
8179
  console.error('The "motionBlur" parameter must be of type `number`.');
8077
- return DEFAULT_DIVIDES;
8180
+ return DEFAULT_MOTION_BLUR;
8078
8181
  }
8079
- return v <= 0 ? DEFAULT_DIVIDES : v;
8182
+ return v <= 0 ? DEFAULT_MOTION_BLUR : v;
8080
8183
  };
8081
8184
  /**
8082
8185
  * Motion blur effect. The default value is `0.15`.
@@ -8742,19 +8845,22 @@ class NgVirtualListComponent extends DisposableComponent {
8742
8845
  }
8743
8846
  const scroller = this._scrollerComponent;
8744
8847
  if (!!scroller) {
8745
- const { width, height } = this._$bounds.getValue(), { width: elementWidth, height: elementHeight } = element.getBoundingClientRect(), isVertical = this._isVertical, viewportSize = isVertical ? height : width, elementSize = isVertical ? elementHeight : elementWidth;
8848
+ const { width, height } = this._$bounds.getValue(), { width: elementWidth, height: elementHeight } = element.getBoundingClientRect(), isVertical = this._isVertical, viewportSize = isVertical ? height : width, maxPosition = isVertical ? scroller.scrollHeight : scroller.scrollWidth, elementSize = isVertical ? elementHeight : elementWidth;
8746
8849
  let pos = Number.NaN;
8747
8850
  switch (align) {
8748
8851
  case FocusAlignments.START: {
8749
- pos = position + scroller.startLayoutOffset;
8852
+ const p = position + scroller.startLayoutOffset;
8853
+ pos = scroller.inverted ? (maxPosition - p) : p;
8750
8854
  break;
8751
8855
  }
8752
8856
  case FocusAlignments.CENTER: {
8753
- pos = position - (viewportSize - elementSize) * .5 + scroller.startLayoutOffset;
8857
+ const p = position - (viewportSize - elementSize) * .5 + scroller.startLayoutOffset;
8858
+ pos = scroller.inverted ? (maxPosition - p) : p;
8754
8859
  break;
8755
8860
  }
8756
8861
  case FocusAlignments.END: {
8757
- pos = position - (viewportSize - elementSize) + scroller.startLayoutOffset;
8862
+ const p = position - (viewportSize - elementSize) + scroller.startLayoutOffset;
8863
+ pos = scroller.inverted ? (maxPosition - p) : p;
8758
8864
  break;
8759
8865
  }
8760
8866
  case FocusAlignments.NONE:
@@ -8766,7 +8872,7 @@ class NgVirtualListComponent extends DisposableComponent {
8766
8872
  this._trackBox.preventScrollSnapping(true);
8767
8873
  const params = {
8768
8874
  [this._isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: pos, behavior, snap: false, normalize: true,
8769
- fireUpdate: false, blending: false, userAction: false,
8875
+ fireUpdate: true, blending: false, userAction: false,
8770
8876
  duration: this.snapToItem ? Math.max(this.animationParams.scrollToItem, this.animationParams.navigateToItem) : this.animationParams.navigateToItem,
8771
8877
  };
8772
8878
  scroller.scrollTo(params);
@@ -8862,10 +8968,9 @@ class NgVirtualListComponent extends DisposableComponent {
8862
8968
  this.onSnapItem.emit(id);
8863
8969
  })).subscribe();
8864
8970
  this._service.$tick.pipe(takeUntil(this._$unsubscribe), tap(() => {
8865
- this._scrollerComponent?.tick();
8866
- })).subscribe();
8867
- this._service.$tick.pipe(takeUntil(this._$unsubscribe), filter$1(() => this.dynamicSize === true), tap(() => {
8868
- this.checkBoundsOfElements();
8971
+ if (this.dynamicSize === true) {
8972
+ this.checkBoundsOfElements();
8973
+ }
8869
8974
  this._scrollerComponent?.tick();
8870
8975
  })).subscribe();
8871
8976
  }
@@ -9238,7 +9343,12 @@ class NgVirtualListComponent extends DisposableComponent {
9238
9343
  combineLatest([this.$scrollbarEnabled, this.$isInfinity]).pipe(takeUntil(this._$unsubscribe), debounceTime(0), tap(([scrollbarEnabled, isInfinity]) => {
9239
9344
  this._$actualScrollbarEnabled.next(isInfinity ? false : scrollbarEnabled);
9240
9345
  })).subscribe();
9241
- const $alignment = this.$actualAlignment, $precalculatedScrollStartOffset = this._$precalculatedScrollStartOffset.asObservable(), $precalculatedScrollEndOffset = this._$precalculatedScrollEndOffset.asObservable(), $listBounds = this._$listBounds.asObservable().pipe(filter$1(b => !!b)), $scrollSize = this._$scrollSize.asObservable(), $bufferSize = this.$bufferSize.pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $maxBufferSize = this.$maxBufferSize.pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $snapToItem = this.$snapToItem, $snapToItemAlign = this.$snapToItemAlign, $stickyEnabled = this.$stickyEnabled, $isLazy = this.$collectionMode.pipe(map(v => this.getIsLazy(v || DEFAULT_COLLECTION_MODE))), $enabledBufferOptimization = this.$enabledBufferOptimization, $snappingMethod = this.$snappingMethod.pipe(map(v => this.getIsSnappingMethodAdvanced(v || DEFAULT_SNAPPING_METHOD))), $collapsingMode = this.$collapsingMode, $selectingMode = this.$selectingMode, $selectedIds = this.$selectedIds, $collapsedIds = this.$collapsedIds.pipe(distinctUntilChanged(), map(v => Array.isArray(v) ? v : [])), $collapsedItemIds = this._$collapsedItemIds.asObservable().pipe(distinctUntilChanged(), map(v => Array.isArray(v) ? v : [])), $itemTransform = this.$itemTransform, $screenReaderMessage = this.$screenReaderMessage, $displayItems = this._service.$displayItems, $cacheVersion = this._service.$cacheVersion;
9346
+ const $alignment = this.$actualAlignment, $precalculatedScrollStartOffset = this._$precalculatedScrollStartOffset.asObservable(), $precalculatedScrollEndOffset = this._$precalculatedScrollEndOffset.asObservable(), $listBounds = this._$listBounds.asObservable().pipe(filter$1(b => !!b)), $scrollSize = this._$scrollSize.asObservable(), $bufferSize = this.$bufferSize.pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $maxBufferSize = this.$maxBufferSize.pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $snapToItem = this.$snapToItem, $snapToItemAlign = this.$snapToItemAlign, $stickyEnabled = this.$stickyEnabled, $isLazy = this.$collectionMode.pipe(map(v => this.getIsLazy(v || DEFAULT_COLLECTION_MODE))), $enabledBufferOptimization = this.$enabledBufferOptimization, $snappingMethod = this.$snappingMethod.pipe(map(v => this.getIsSnappingMethodAdvanced(v || DEFAULT_SNAPPING_METHOD))), $collapsingMode = this.$collapsingMode, $selectingMode = this.$selectingMode, $selectedIds = this.$selectedIds, $collapsedIds = this.$collapsedIds.pipe(distinctUntilChanged(), map(v => Array.isArray(v) ? v : [])), $collapsedItemIds = this._$collapsedItemIds.asObservable().pipe(distinctUntilChanged(), map(v => Array.isArray(v) ? v : [])), $langTextDir = this.$langTextDir, $itemTransform = this.$itemTransform, $screenReaderMessage = this.$screenReaderMessage, $displayItems = this._service.$displayItems, $cacheVersion = this._service.$cacheVersion;
9347
+ combineLatest([$isVertical, $langTextDir, $itemTransform]).pipe(takeUntil(this._$unsubscribe), debounceTime(0), tap(([isVertical, langTextDir, itemTransform]) => {
9348
+ if (langTextDir === TextDirections.RTL && !isVertical && itemTransform) {
9349
+ throw Error('Currently, converting right-to-left items in horizontal lists is not possible.');
9350
+ }
9351
+ })).subscribe();
9242
9352
  $snapToItem.pipe(takeUntil(this._$unsubscribe), tap(v => {
9243
9353
  this._service.snapToItem = v;
9244
9354
  })).subscribe();
@@ -9299,6 +9409,9 @@ class NgVirtualListComponent extends DisposableComponent {
9299
9409
  actualItems.push(item);
9300
9410
  }
9301
9411
  const normalizedCollection = normalizeCollection(actualItems, itemConfigMap, trackBy, divides);
9412
+ if (this._scrollerComponent?.inverted) {
9413
+ normalizedCollection.reverse();
9414
+ }
9302
9415
  this._$actualItems.next(normalizedCollection);
9303
9416
  })).subscribe();
9304
9417
  $isVertical.pipe(takeUntil(this._$unsubscribe), tap(v => {
@@ -9420,20 +9533,21 @@ class NgVirtualListComponent extends DisposableComponent {
9420
9533
  if (!!scroller) {
9421
9534
  const isInfinity = this.isInfinity, collapsable = collapsedIds.length > 0, cachable = this.cachable, cached = this._cached, waitingCache = cachable && !cached, emitUpdate = !this._readyForShow || waitingCache || collapsable || isChunkLoading, fireUpdate = !this._readyForShow || this._$scrollingTo.getValue(), fireUpdateAtEdges = fireUpdate || !isInfinity, useAnimations = !isInfinity && readyForAnimations && prevScrollable;
9422
9535
  if (this._readyForShow || (cachable && cached)) {
9423
- const currentScrollSize = (isVertical ? scroller.scrollTop : scroller.scrollLeft);
9424
- let actualScrollSize = !this._readyForShow && snapScrollToEnd ? (isVertical ? scroller.scrollHeight : scroller.scrollWidth) :
9536
+ const inverted = scroller.inverted, currentScrollSize = (isVertical ? scroller.scrollTop : scroller.scrollLeft), maxScrollSize = (isVertical ? scroller.scrollHeight : scroller.scrollWidth);
9537
+ let actualScrollSize = !this._readyForShow && snapScrollToEnd ? maxScrollSize :
9425
9538
  (isVertical ? scroller.scrollTop : scroller.scrollLeft), leftLayoutOffset = 0, displayItems;
9426
- const { width, height } = bounds, viewportSize = (isVertical ? height : width), opts = {
9539
+ const { width, height } = bounds, opts = {
9427
9540
  alignment, bounds: { width, height }, dynamicSize, isVertical, itemSize, minItemSize, maxItemSize, bufferSize, maxBufferSize,
9428
- scrollSize: actualScrollSize, stickyEnabled, enabledBufferOptimization, snapToItem, snapToItemAlign, itemTransform,
9541
+ scrollSize: inverted ? maxScrollSize - actualScrollSize : actualScrollSize, stickyEnabled, enabledBufferOptimization,
9542
+ snapToItem, snapToItemAlign, inverted, itemTransform,
9429
9543
  };
9430
9544
  if (snapScrollToEnd && !this._readyForShow) {
9431
- const { displayItems: calculatedDisplayItems, totalSize: calculatedTotalSize1, leftLayoutOffset: leftLayoutOffset1 } = this._trackBox.updateCollection(items, itemConfigMap, { ...opts, scrollSize: actualScrollSize });
9545
+ const { displayItems: calculatedDisplayItems, totalSize: calculatedTotalSize1, leftLayoutOffset: leftLayoutOffset1 } = this._trackBox.updateCollection(items, itemConfigMap, { ...opts, scrollSize: inverted ? maxScrollSize - actualScrollSize : actualScrollSize });
9432
9546
  displayItems = calculatedDisplayItems;
9433
9547
  totalSize = calculatedTotalSize1;
9434
9548
  leftLayoutOffset = leftLayoutOffset1;
9435
9549
  if (!!itemTransform && dynamicSize && this._trackBox.delta !== 0) {
9436
- const { displayItems: calculatedDisplayItems, totalSize: calculatedTotalSize1, leftLayoutOffset: leftLayoutOffset1 } = this._trackBox.updateCollection(items, itemConfigMap, { ...opts, scrollSize: actualScrollSize + this._trackBox.delta });
9550
+ const { displayItems: calculatedDisplayItems, totalSize: calculatedTotalSize1, leftLayoutOffset: leftLayoutOffset1 } = this._trackBox.updateCollection(items, itemConfigMap, { ...opts, scrollSize: inverted ? (maxScrollSize - actualScrollSize + this._trackBox.delta) : (actualScrollSize + this._trackBox.delta) });
9437
9551
  displayItems = calculatedDisplayItems;
9438
9552
  totalSize = calculatedTotalSize1;
9439
9553
  leftLayoutOffset = leftLayoutOffset1;
@@ -9445,7 +9559,7 @@ class NgVirtualListComponent extends DisposableComponent {
9445
9559
  totalSize = calculatedTotalSize;
9446
9560
  leftLayoutOffset = leftLayoutOffset1;
9447
9561
  if (!!itemTransform && dynamicSize && this._trackBox.delta !== 0) {
9448
- const { displayItems: calculatedDisplayItems, totalSize: calculatedTotalSize, leftLayoutOffset: leftLayoutOffset1 } = this._trackBox.updateCollection(items, itemConfigMap, { ...opts, scrollSize: actualScrollSize + this._trackBox.delta });
9562
+ const { displayItems: calculatedDisplayItems, totalSize: calculatedTotalSize, leftLayoutOffset: leftLayoutOffset1 } = this._trackBox.updateCollection(items, itemConfigMap, { ...opts, scrollSize: inverted ? (maxScrollSize - actualScrollSize + this._trackBox.delta) : (actualScrollSize + this._trackBox.delta) });
9449
9563
  displayItems = calculatedDisplayItems;
9450
9564
  totalSize = calculatedTotalSize;
9451
9565
  leftLayoutOffset = leftLayoutOffset1;
@@ -9469,18 +9583,49 @@ class NgVirtualListComponent extends DisposableComponent {
9469
9583
  this.updateOffsetsByAllignment();
9470
9584
  scroller.delta = delta;
9471
9585
  prevScrollable = scroller.scrollable;
9472
- if ((snapScrollToStart && this._trackBox.isSnappedToStart && scroller.scrollable) ||
9473
- (snapScrollToStart && currentScrollSize <= MIN_PIXELS_FOR_PREVENT_SNAPPING)) {
9474
- if (currentScrollSize !== roundedScrollPositionAfterUpdate) {
9586
+ if (!scroller.grabbing) {
9587
+ if ((snapScrollToStart && this._trackBox.isSnappedToStart && scroller.scrollable) ||
9588
+ (snapScrollToStart && currentScrollSize <= MIN_PIXELS_FOR_PREVENT_SNAPPING)) {
9589
+ if (currentScrollSize !== roundedScrollPositionAfterUpdate) {
9590
+ this._trackBox.clearDelta();
9591
+ if (this._readyForShow) {
9592
+ this.emitScrollEvent(true, false, userAction);
9593
+ }
9594
+ this._trackBox.isScrollEnd;
9595
+ const params = {
9596
+ [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: 0, userAction,
9597
+ fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams.scrollToItem > 0 && this.scrollBehavior !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT),
9598
+ blending: useAnimations && scroller.hasAnimation(this._animationId), duration: this.animationParams.scrollToItem,
9599
+ };
9600
+ const animationId = scroller?.scrollTo?.(params);
9601
+ if (animationId > -1) {
9602
+ this._animationId = animationId;
9603
+ }
9604
+ else {
9605
+ scroller.stopAnimation(this._animationId);
9606
+ }
9607
+ scroller?.scrollTo?.(params);
9608
+ if (emitUpdate) {
9609
+ this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
9610
+ }
9611
+ }
9612
+ return;
9613
+ }
9614
+ if ((snapScrollToEnd && this._trackBox.isSnappedToEnd) || (snapScrollToEnd && !scroller.scrollable) ||
9615
+ (scrollPositionAfterUpdate + MIN_PIXELS_FOR_PREVENT_SNAPPING >= roundedMaxPositionAfterUpdate) ||
9616
+ (roundedScrollPositionAfterUpdate >= scrollPositionAfterUpdate + MIN_PIXELS_FOR_PREVENT_SNAPPING)) {
9475
9617
  this._trackBox.clearDelta();
9618
+ if (!this._trackBox.isSnappedToEnd) {
9619
+ this._trackBox.isScrollEnd = true;
9620
+ this._trackBox.isScrollStart = false;
9621
+ }
9476
9622
  if (this._readyForShow) {
9477
- this.emitScrollEvent(true, false, userAction);
9623
+ this.emitScrollEvent(true, false, false);
9478
9624
  }
9479
- this._trackBox.isScrollEnd;
9480
9625
  const params = {
9481
- [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: 0, userAction,
9482
- fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams.scrollToItem > 0 && this.scrollBehavior !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT),
9483
- blending: useAnimations && scroller.hasAnimation(this._animationId), duration: this.animationParams.scrollToItem,
9626
+ [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: roundedMaxPositionAfterUpdate,
9627
+ fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams.scrollToItem > 0 && this.scrollBehavior !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT), userAction: false,
9628
+ blending: useAnimations && scroller.hasAnimation(this._animationId) || cacheChanged, duration: this.animationParams.scrollToItem,
9484
9629
  };
9485
9630
  const animationId = scroller?.scrollTo?.(params);
9486
9631
  if (animationId > -1) {
@@ -9493,37 +9638,8 @@ class NgVirtualListComponent extends DisposableComponent {
9493
9638
  if (emitUpdate) {
9494
9639
  this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
9495
9640
  }
9641
+ return;
9496
9642
  }
9497
- return;
9498
- }
9499
- if ((snapScrollToEnd && this._trackBox.isSnappedToEnd) || (snapScrollToEnd && !scroller.scrollable) ||
9500
- (scrollPositionAfterUpdate + MIN_PIXELS_FOR_PREVENT_SNAPPING >= roundedMaxPositionAfterUpdate) ||
9501
- (roundedScrollPositionAfterUpdate >= scrollPositionAfterUpdate + MIN_PIXELS_FOR_PREVENT_SNAPPING)) {
9502
- this._trackBox.clearDelta();
9503
- if (!this._trackBox.isSnappedToEnd) {
9504
- this._trackBox.isScrollEnd = true;
9505
- this._trackBox.isScrollStart = false;
9506
- }
9507
- if (this._readyForShow) {
9508
- this.emitScrollEvent(true, false, false);
9509
- }
9510
- const params = {
9511
- [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: roundedMaxPositionAfterUpdate,
9512
- fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams.scrollToItem > 0 && this.scrollBehavior !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT), userAction: false,
9513
- blending: useAnimations && scroller.hasAnimation(this._animationId) || cacheChanged, duration: this.animationParams.scrollToItem,
9514
- };
9515
- const animationId = scroller?.scrollTo?.(params);
9516
- if (animationId > -1) {
9517
- this._animationId = animationId;
9518
- }
9519
- else {
9520
- scroller.stopAnimation(this._animationId);
9521
- }
9522
- scroller?.scrollTo?.(params);
9523
- if (emitUpdate) {
9524
- this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
9525
- }
9526
- return;
9527
9643
  }
9528
9644
  if (scrollSize !== scrollPositionAfterUpdate &&
9529
9645
  ((scrollPositionAfterUpdate >= 0 && scrollPositionAfterUpdate < roundedMaxPositionAfterUpdate) ||
@@ -9663,23 +9779,23 @@ class NgVirtualListComponent extends DisposableComponent {
9663
9779
  if (!!items && items.length) {
9664
9780
  const dynamicSize = this.dynamicSize, itemSize = this.actualItemSize, minItemSize = this.actualMinItemSize, maxItemSize = this.actualMaxItemSize, snapScrollToEnd = this.snapScrollToEnd;
9665
9781
  if (dynamicSize) {
9666
- const { width, height } = this._$bounds.getValue() || { width: DEFAULT_LIST_SIZE, height: DEFAULT_LIST_SIZE }, itemConfigMap = this.itemConfigMap, isVertical = this._isVertical, currentScrollSize = isVertical ? scrollerComponent.scrollTop : scrollerComponent.scrollLeft, opts = {
9667
- alignment: this._$actualAlignment.getValue(),
9782
+ const { width, height } = this._$bounds.getValue() || { width: DEFAULT_LIST_SIZE, height: DEFAULT_LIST_SIZE }, itemConfigMap = this.itemConfigMap, isVertical = this._isVertical, inverted = scrollerComponent.inverted, maxScrollSize = isVertical ? scrollerComponent.scrollHeight : scrollerComponent.scrollWidth, currentScrollSize = isVertical ? scrollerComponent.scrollTop : scrollerComponent.scrollLeft, opts = {
9783
+ alignment: this.actualAlignment, inverted,
9668
9784
  bounds: { width, height }, collection: items, dynamicSize, isVertical: this._isVertical, itemSize, minItemSize, maxItemSize,
9669
9785
  bufferSize: this.bufferSize, maxBufferSize: this.maxBufferSize, itemTransform: this.itemTransform,
9670
- scrollSize: (isVertical ? scrollerComponent.scrollTop : scrollerComponent.scrollLeft),
9786
+ scrollSize: (inverted ? (maxScrollSize - currentScrollSize) : currentScrollSize),
9671
9787
  snapToItem: this.snapToItem, snapToItemAlign: this.snapToItemAlign,
9672
9788
  stickyEnabled: this.stickyEnabled, fromItemId: id, enabledBufferOptimization: this.enabledBufferOptimization,
9673
9789
  };
9674
9790
  let scrollSize = snapScrollToEnd && this._trackBox.isSnappedToEnd ?
9675
- (isVertical ? scrollerComponent.scrollHeight : scrollerComponent.scrollWidth) :
9791
+ maxScrollSize :
9676
9792
  this._trackBox.getItemPosition(id, itemConfigMap, opts);
9677
9793
  if (scrollSize === -1) {
9678
9794
  return of([finished, { id, blending, iteration: nextIteration, cb }]).pipe(delay(0));
9679
9795
  }
9680
9796
  this._trackBox.clearDelta();
9681
9797
  const viewportSize = (isVertical ? height : width), { displayItems, totalSize, leftLayoutOffset } = this._trackBox.updateCollection(items, itemConfigMap, {
9682
- ...opts, scrollSize, fromItemId: isLastIteration ? undefined : id,
9798
+ ...opts, scrollSize: (inverted ? (maxScrollSize - scrollSize) : scrollSize), fromItemId: isLastIteration ? undefined : id,
9683
9799
  }), delta1 = this._trackBox.delta;
9684
9800
  const normalizedTotalSize = totalSize < viewportSize ? viewportSize : totalSize;
9685
9801
  scrollerComponent.startLayoutOffset = leftLayoutOffset;
@@ -9691,7 +9807,7 @@ class NgVirtualListComponent extends DisposableComponent {
9691
9807
  this.tracking();
9692
9808
  this.snappingHandler();
9693
9809
  this.updateOffsetsByAllignment();
9694
- scrollSize = this._trackBox.getItemPosition(id, itemConfigMap, { ...opts, scrollSize: actualScrollSize, fromItemId: id });
9810
+ scrollSize = this._trackBox.getItemPosition(id, itemConfigMap, { ...opts, scrollSize: (inverted ? (maxScrollSize - actualScrollSize) : actualScrollSize), fromItemId: id });
9695
9811
  if (scrollSize === -1) {
9696
9812
  return of([finished, { id, blending, iteration: nextIteration, cb }]).pipe(delay(0));
9697
9813
  }
@@ -9716,11 +9832,11 @@ class NgVirtualListComponent extends DisposableComponent {
9716
9832
  else {
9717
9833
  const index = items.findIndex(item => item[trackBy] === id);
9718
9834
  if (index > -1) {
9719
- const isVertical = this._isVertical, itemSize = this.actualItemSize;
9835
+ const isVertical = this._isVertical, itemSize = this.actualItemSize, isInfinity = this.isInfinity, snapToItem = this.snapToItem, snapToItemAlign = this.snapToItemAlign;
9720
9836
  let scrollSize = index * itemSize;
9721
- if (this.isInfinity) {
9722
- if (this.snapToItem) {
9723
- switch (this.snapToItemAlign) {
9837
+ if (isInfinity) {
9838
+ if (snapToItem) {
9839
+ switch (snapToItemAlign) {
9724
9840
  case SnapToItemAligns.CENTER: {
9725
9841
  scrollSize += itemSize * .5;
9726
9842
  break;
@@ -9728,17 +9844,18 @@ class NgVirtualListComponent extends DisposableComponent {
9728
9844
  }
9729
9845
  }
9730
9846
  }
9731
- const { width, height } = this._$bounds.getValue() || { width: DEFAULT_LIST_SIZE, height: DEFAULT_LIST_SIZE }, itemConfigMap = this.itemConfigMap, items = this._$actualItems.getValue(), opts = {
9732
- alignment: this._$actualAlignment.getValue(),
9847
+ const { width, height } = this._$bounds.getValue() || { width: DEFAULT_LIST_SIZE, height: DEFAULT_LIST_SIZE }, itemConfigMap = this.itemConfigMap, items = this._$actualItems.getValue(), inverted = scrollerComponent.inverted, maxScrollSize = (isVertical ? scrollerComponent.scrollHeight : scrollerComponent.scrollWidth), actualScrollSize = (isVertical ? scrollerComponent.scrollTop : scrollerComponent.scrollLeft), opts = {
9848
+ alignment: this.actualAlignment, inverted,
9733
9849
  bounds: { width, height }, collection: items, dynamicSize, isVertical: this._isVertical, itemSize, minItemSize, maxItemSize,
9734
9850
  bufferSize: this.bufferSize, maxBufferSize: this.maxBufferSize, itemTransform: this.itemTransform,
9735
- scrollSize: (isVertical ? scrollerComponent.scrollTop : scrollerComponent.scrollLeft),
9736
- snapToItem: this.snapToItem, snapToItemAlign: this.snapToItemAlign,
9737
- stickyEnabled: this.stickyEnabled, fromItemId: id, enabledBufferOptimization: this.enabledBufferOptimization,
9851
+ scrollSize: (inverted ? (maxScrollSize - actualScrollSize) : actualScrollSize),
9852
+ snapToItem, snapToItemAlign, stickyEnabled: this.stickyEnabled, fromItemId: id,
9853
+ enabledBufferOptimization: this.enabledBufferOptimization,
9738
9854
  };
9739
9855
  this._trackBox.clearDelta();
9740
9856
  const viewportSize = (isVertical ? height : width), { displayItems, totalSize, leftLayoutOffset } = this._trackBox.updateCollection(items, itemConfigMap, {
9741
- ...opts, scrollSize, fromItemId: isLastIteration ? undefined : id,
9857
+ ...opts, scrollSize: (inverted ? (maxScrollSize - scrollSize) : scrollSize),
9858
+ fromItemId: isLastIteration ? undefined : id,
9742
9859
  });
9743
9860
  const actualTotalSize = this.isInfinity ? (totalSize + viewportSize) : totalSize;
9744
9861
  const normalizedTotalSize = actualTotalSize < viewportSize ? viewportSize : actualTotalSize;
@@ -10261,13 +10378,13 @@ class NgVirtualListComponent extends DisposableComponent {
10261
10378
  }
10262
10379
  }
10263
10380
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgVirtualListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10264
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NgVirtualListComponent, selector: "ng-virtual-list", inputs: { scrollbarThickness: "scrollbarThickness", scrollbarMinSize: "scrollbarMinSize", scrollbarThumbRenderer: "scrollbarThumbRenderer", scrollbarThumbParams: "scrollbarThumbParams", loading: "loading", waitForPreparation: "waitForPreparation", clickDistance: "clickDistance", items: "items", selectedIds: "selectedIds", defaultItemValue: "defaultItemValue", collapsedIds: "collapsedIds", selectByClick: "selectByClick", collapseByClick: "collapseByClick", snap: "snap", stickyEnabled: "stickyEnabled", snapToEndTransitionInstantOffset: "snapToEndTransitionInstantOffset", scrollStartOffset: "scrollStartOffset", scrollEndOffset: "scrollEndOffset", snapScrollToStart: "snapScrollToStart", snapScrollToEnd: "snapScrollToEnd", snapScrollToBottom: "snapScrollToBottom", scrollbarEnabled: "scrollbarEnabled", scrollbarInteractive: "scrollbarInteractive", overlappingScrollbar: "overlappingScrollbar", scrollBehavior: "scrollBehavior", scrollingSettings: "scrollingSettings", itemTransform: "itemTransform", snapToItem: "snapToItem", snapToItemAlign: "snapToItemAlign", snappingDistance: "snappingDistance", scrollingOneByOne: "scrollingOneByOne", alignment: "alignment", zIndexWhenSelecting: "zIndexWhenSelecting", spreadingMode: "spreadingMode", divides: "divides", motionBlur: "motionBlur", maxMotionBlur: "maxMotionBlur", motionBlurEnabled: "motionBlurEnabled", animationParams: "animationParams", overscrollEnabled: "overscrollEnabled", enabledBufferOptimization: "enabledBufferOptimization", itemRenderer: "itemRenderer", itemConfigMap: "itemConfigMap", itemSize: "itemSize", minItemSize: "minItemSize", maxItemSize: "maxItemSize", dynamicSize: "dynamicSize", direction: "direction", collectionMode: "collectionMode", bufferSize: "bufferSize", maxBufferSize: "maxBufferSize", snappingMethod: "snappingMethod", collapsingMode: "collapsingMode", methodForSelecting: "methodForSelecting", selectingMode: "selectingMode", trackBy: "trackBy", screenReaderMessage: "screenReaderMessage", langTextDir: "langTextDir" }, outputs: { onScroll: "onScroll", onScrollEnd: "onScrollEnd", onViewportChange: "onViewportChange", onSnapItem: "onSnapItem", onItemClick: "onItemClick", onSelect: "onSelect", onCollapse: "onCollapse", onScrollReachStart: "onScrollReachStart", onScrollReachEnd: "onScrollReachEnd" }, host: { styleAttribute: "position: relative;" }, providers: [NgVirtualListService, NgVirtualListPublicService], viewQueries: [{ propertyName: "_prerender", first: true, predicate: ["prerender"], descendants: true, read: NgPrerenderContainer }, { propertyName: "_listContainerRef", first: true, predicate: ["renderersContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_snapContainerRef", first: true, predicate: ["snapRendererContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_scrollerComponent", first: true, predicate: ["scroller"], descendants: true, read: NgScrollerComponent }], usesInheritance: true, ngImport: i0, template: "<div aria-live=\"polite\" aria-atomic=\"true\" class=\"ngvl__screen-reader\">\r\n {{ $screenReaderFormattedMessage | async }}\r\n</div>\r\n\r\n<ng-prerender-container #prerender [bounds]=\"($bounds | async)!\" [direction]=\"($direction | async)!\"\r\n [dynamic]=\"($dynamicSize | async)!\" [divides]=\"($divides | async)!\" [isVertical]=\"($isVertical | async)!\"\r\n [itemSize]=\"($actualItemSize | async)!\" [trackBy]=\"($trackBy | async)!\" [itemRenderer]=\"($itemRenderer | async)!\"\r\n [startOffset]=\"($startOffset | async)!\" [endOffset]=\"($endOffset | async)!\"\r\n [scrollbarEnabled]=\"(scroller.$scrollbarShow | async)!\"\r\n [enabled]=\"($prerenderEnabled | async)!\"></ng-prerender-container>\r\n\r\n<ng-container *ngIf=\"($stickyEnabled | async)!\">\r\n <div localeSensitive [langTextDir]=\"($langTextDir | async)!\" #snappedContainer class=\"ngvl__snapped-container\"\r\n [ngClass]=\"($classes | async)\">\r\n <div #snapped part=\"snapped-item\" class=\"ngvl__list-snapper\">\r\n <ng-container #snapRendererContainer></ng-container>\r\n </div>\r\n </div>\r\n</ng-container>\r\n\r\n<ng-scroller #scroller class=\"ngvl__list-scroller\" [classes]=\"($classes | async)!\"\r\n [startOffset]=\"($startOffset | async)!\" [endOffset]=\"($endOffset | async)!\"\r\n [alignmentStartOffset]=\"($alignmentScrollStartOffset | async)!\"\r\n [alignmentEndOffset]=\"($alignmentScrollEndOffset | async)!\" [direction]=\"($direction | async)!\"\r\n [scrollbarThumbRenderer]=\"($scrollbarThumbRenderer | async)!\" [isInfinity]=\"($isInfinity | async)!\"\r\n [scrollbarThickness]=\"($scrollbarThickness | async)!\" [scrollbarThumbParams]=\"($scrollbarThumbParams | async)!\"\r\n [animationParams]=\"($animationParams | async)!\" [focusedElement]=\"($focusedElement | async)!\"\r\n [loading]=\"($loading | async)!\" [overscrollEnabled]=\"($overscrollEnabled | async)!\"\r\n [snappingDistance]=\"($snappingDistance | async)!\" [overlappingScrollbar]=\"($overlappingScrollbar | async)!\"\r\n [scrollbarEnabled]=\"($actualScrollbarEnabled | async)!\" [scrollbarInteractive]=\"($scrollbarInteractive | async)!\"\r\n [snapToItem]=\"($snapToItem | async)!\" [snapToItemAlign]=\"($snapToItemAlign | async)!\"\r\n [scrollbarMinSize]=\"($scrollbarMinSize | async)!\" [scrollBehavior]=\"($scrollBehavior | async)!\"\r\n [scrollingSettings]=\"($scrollingSettings | async)!\" [scrollingOneByOne]=\"($scrollingOneByOne | async)!\"\r\n [motionBlur]=\"($motionBlur | async)!\" [maxMotionBlur]=\"($maxMotionBlur | async)!\"\r\n [motionBlurEnabled]=\"($motionBlurEnabled | async)!\">\r\n <ng-container #renderersContainer></ng-container>\r\n</ng-scroller>", styles: [":host{position:relative;display:block;width:400px;overflow:hidden}:host(.horizontal){height:48px}:host(.vertical){height:320px}.ngvl__snapped-container{position:relative;width:100%;opacity:0}.ngvl__snapped-container.prepared{opacity:1}.ngvl__list-snapper{-webkit-tap-highlight-color:transparent;position:absolute;list-style:none;left:0;top:0;z-index:1}.ngvl__list-scroller{-webkit-tap-highlight-color:transparent;position:absolute;left:0;top:0;width:100%;height:100%;z-index:0}.ngvl__screen-reader{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: NgScrollerComponent, selector: "ng-scroller", inputs: ["scrollbarEnabled", "scrollbarInteractive", "focusedElement", "overlappingScrollbar", "content", "loading", "classes", "scrollbarMinSize", "scrollbarThickness", "scrollbarThumbRenderer", "scrollbarThumbParams", "motionBlur", "maxMotionBlur", "motionBlurEnabled"], outputs: ["onScrollbarVisible"] }, { kind: "component", type: NgPrerenderContainer, selector: "ng-prerender-container", inputs: ["enabled", "direction", "isVertical", "scrollbarEnabled", "startOffset", "endOffset", "bounds", "dynamic", "itemSize", "trackBy", "divides"] }, { kind: "directive", type: LocaleSensitiveDirective, selector: "[localeSensitive]", inputs: ["langTextDir", "listDir"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
10381
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NgVirtualListComponent, selector: "ng-virtual-list", inputs: { scrollbarThickness: "scrollbarThickness", scrollbarMinSize: "scrollbarMinSize", scrollbarThumbRenderer: "scrollbarThumbRenderer", scrollbarThumbParams: "scrollbarThumbParams", loading: "loading", waitForPreparation: "waitForPreparation", clickDistance: "clickDistance", items: "items", selectedIds: "selectedIds", defaultItemValue: "defaultItemValue", collapsedIds: "collapsedIds", selectByClick: "selectByClick", collapseByClick: "collapseByClick", snap: "snap", stickyEnabled: "stickyEnabled", snapToEndTransitionInstantOffset: "snapToEndTransitionInstantOffset", scrollStartOffset: "scrollStartOffset", scrollEndOffset: "scrollEndOffset", snapScrollToStart: "snapScrollToStart", snapScrollToEnd: "snapScrollToEnd", snapScrollToBottom: "snapScrollToBottom", scrollbarEnabled: "scrollbarEnabled", scrollbarInteractive: "scrollbarInteractive", overlappingScrollbar: "overlappingScrollbar", scrollBehavior: "scrollBehavior", scrollingSettings: "scrollingSettings", itemTransform: "itemTransform", snapToItem: "snapToItem", snapToItemAlign: "snapToItemAlign", snappingDistance: "snappingDistance", scrollingOneByOne: "scrollingOneByOne", alignment: "alignment", zIndexWhenSelecting: "zIndexWhenSelecting", spreadingMode: "spreadingMode", divides: "divides", motionBlur: "motionBlur", maxMotionBlur: "maxMotionBlur", motionBlurEnabled: "motionBlurEnabled", animationParams: "animationParams", overscrollEnabled: "overscrollEnabled", enabledBufferOptimization: "enabledBufferOptimization", itemRenderer: "itemRenderer", itemConfigMap: "itemConfigMap", itemSize: "itemSize", minItemSize: "minItemSize", maxItemSize: "maxItemSize", dynamicSize: "dynamicSize", direction: "direction", collectionMode: "collectionMode", bufferSize: "bufferSize", maxBufferSize: "maxBufferSize", snappingMethod: "snappingMethod", collapsingMode: "collapsingMode", methodForSelecting: "methodForSelecting", selectingMode: "selectingMode", trackBy: "trackBy", screenReaderMessage: "screenReaderMessage", langTextDir: "langTextDir" }, outputs: { onScroll: "onScroll", onScrollEnd: "onScrollEnd", onViewportChange: "onViewportChange", onSnapItem: "onSnapItem", onItemClick: "onItemClick", onSelect: "onSelect", onCollapse: "onCollapse", onScrollReachStart: "onScrollReachStart", onScrollReachEnd: "onScrollReachEnd" }, host: { styleAttribute: "position: relative;" }, providers: [NgVirtualListService, NgVirtualListPublicService], viewQueries: [{ propertyName: "_prerender", first: true, predicate: ["prerender"], descendants: true, read: NgPrerenderContainer }, { propertyName: "_listContainerRef", first: true, predicate: ["renderersContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_snapContainerRef", first: true, predicate: ["snapRendererContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_scrollerComponent", first: true, predicate: ["scroller"], descendants: true, read: NgScrollerComponent }], usesInheritance: true, ngImport: i0, template: "<div aria-live=\"polite\" aria-atomic=\"true\" class=\"ngvl__screen-reader\">\r\n {{ $screenReaderFormattedMessage | async }}\r\n</div>\r\n\r\n<ng-prerender-container #prerender [bounds]=\"($bounds | async)!\" [direction]=\"($direction | async)!\"\r\n [dynamic]=\"($dynamicSize | async)!\" [divides]=\"($divides | async)!\" [isVertical]=\"($isVertical | async)!\"\r\n [itemSize]=\"($actualItemSize | async)!\" [trackBy]=\"($trackBy | async)!\" [itemRenderer]=\"($itemRenderer | async)!\"\r\n [startOffset]=\"($startOffset | async)!\" [endOffset]=\"($endOffset | async)!\"\r\n [scrollbarEnabled]=\"(scroller.$scrollbarShow | async)!\"\r\n [enabled]=\"($prerenderEnabled | async)!\"></ng-prerender-container>\r\n\r\n<ng-container *ngIf=\"($stickyEnabled | async)!\">\r\n <div localeSensitive [langTextDir]=\"($langTextDir | async)!\" #snappedContainer class=\"ngvl__snapped-container\"\r\n [ngClass]=\"($classes | async)\">\r\n <div #snapped part=\"snapped-item\" class=\"ngvl__list-snapper\">\r\n <ng-container #snapRendererContainer></ng-container>\r\n </div>\r\n </div>\r\n</ng-container>\r\n\r\n<ng-scroller #scroller class=\"ngvl__list-scroller\" [classes]=\"($classes | async)!\"\r\n [langTextDir]=\"($langTextDir | async)!\" [startOffset]=\"($startOffset | async)!\" [endOffset]=\"($endOffset | async)!\"\r\n [alignmentStartOffset]=\"($alignmentScrollStartOffset | async)!\"\r\n [alignmentEndOffset]=\"($alignmentScrollEndOffset | async)!\" [direction]=\"($direction | async)!\"\r\n [scrollbarThumbRenderer]=\"($scrollbarThumbRenderer | async)!\" [isInfinity]=\"($isInfinity | async)!\"\r\n [scrollbarThickness]=\"($scrollbarThickness | async)!\" [scrollbarThumbParams]=\"($scrollbarThumbParams | async)!\"\r\n [animationParams]=\"($animationParams | async)!\" [focusedElement]=\"($focusedElement | async)!\"\r\n [loading]=\"($loading | async)!\" [overscrollEnabled]=\"($overscrollEnabled | async)!\"\r\n [snappingDistance]=\"($snappingDistance | async)!\" [overlappingScrollbar]=\"($overlappingScrollbar | async)!\"\r\n [scrollbarEnabled]=\"($actualScrollbarEnabled | async)!\" [scrollbarInteractive]=\"($scrollbarInteractive | async)!\"\r\n [snapToItem]=\"($snapToItem | async)!\" [snapToItemAlign]=\"($snapToItemAlign | async)!\"\r\n [scrollbarMinSize]=\"($scrollbarMinSize | async)!\" [scrollBehavior]=\"($scrollBehavior | async)!\"\r\n [scrollingSettings]=\"($scrollingSettings | async)!\" [scrollingOneByOne]=\"($scrollingOneByOne | async)!\"\r\n [motionBlur]=\"($motionBlur | async)!\" [maxMotionBlur]=\"($maxMotionBlur | async)!\"\r\n [motionBlurEnabled]=\"($motionBlurEnabled | async)!\">\r\n <ng-container #renderersContainer></ng-container>\r\n</ng-scroller>", styles: [":host{position:relative;display:block;width:400px;overflow:hidden}:host(.horizontal){height:48px}:host(.vertical){height:320px}.ngvl__snapped-container{position:relative;width:100%;opacity:0}.ngvl__snapped-container.prepared{opacity:1}.ngvl__list-snapper{-webkit-tap-highlight-color:transparent;position:absolute;list-style:none;left:0;top:0;z-index:1}.ngvl__list-scroller{-webkit-tap-highlight-color:transparent;position:absolute;left:0;top:0;width:100%;height:100%;z-index:0}.ngvl__screen-reader{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: NgScrollerComponent, selector: "ng-scroller", inputs: ["scrollbarEnabled", "scrollbarInteractive", "focusedElement", "overlappingScrollbar", "content", "loading", "classes", "scrollbarMinSize", "scrollbarThickness", "scrollbarThumbRenderer", "scrollbarThumbParams", "motionBlur", "maxMotionBlur", "motionBlurEnabled"], outputs: ["onScrollbarVisible"] }, { kind: "component", type: NgPrerenderContainer, selector: "ng-prerender-container", inputs: ["enabled", "direction", "isVertical", "scrollbarEnabled", "startOffset", "endOffset", "bounds", "dynamic", "itemSize", "trackBy", "divides"] }, { kind: "directive", type: LocaleSensitiveDirective, selector: "[localeSensitive]", inputs: ["langTextDir", "listDir"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
10265
10382
  }
10266
10383
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgVirtualListComponent, decorators: [{
10267
10384
  type: Component,
10268
10385
  args: [{ selector: 'ng-virtual-list', host: {
10269
10386
  'style': 'position: relative;'
10270
- }, standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, providers: [NgVirtualListService, NgVirtualListPublicService], template: "<div aria-live=\"polite\" aria-atomic=\"true\" class=\"ngvl__screen-reader\">\r\n {{ $screenReaderFormattedMessage | async }}\r\n</div>\r\n\r\n<ng-prerender-container #prerender [bounds]=\"($bounds | async)!\" [direction]=\"($direction | async)!\"\r\n [dynamic]=\"($dynamicSize | async)!\" [divides]=\"($divides | async)!\" [isVertical]=\"($isVertical | async)!\"\r\n [itemSize]=\"($actualItemSize | async)!\" [trackBy]=\"($trackBy | async)!\" [itemRenderer]=\"($itemRenderer | async)!\"\r\n [startOffset]=\"($startOffset | async)!\" [endOffset]=\"($endOffset | async)!\"\r\n [scrollbarEnabled]=\"(scroller.$scrollbarShow | async)!\"\r\n [enabled]=\"($prerenderEnabled | async)!\"></ng-prerender-container>\r\n\r\n<ng-container *ngIf=\"($stickyEnabled | async)!\">\r\n <div localeSensitive [langTextDir]=\"($langTextDir | async)!\" #snappedContainer class=\"ngvl__snapped-container\"\r\n [ngClass]=\"($classes | async)\">\r\n <div #snapped part=\"snapped-item\" class=\"ngvl__list-snapper\">\r\n <ng-container #snapRendererContainer></ng-container>\r\n </div>\r\n </div>\r\n</ng-container>\r\n\r\n<ng-scroller #scroller class=\"ngvl__list-scroller\" [classes]=\"($classes | async)!\"\r\n [startOffset]=\"($startOffset | async)!\" [endOffset]=\"($endOffset | async)!\"\r\n [alignmentStartOffset]=\"($alignmentScrollStartOffset | async)!\"\r\n [alignmentEndOffset]=\"($alignmentScrollEndOffset | async)!\" [direction]=\"($direction | async)!\"\r\n [scrollbarThumbRenderer]=\"($scrollbarThumbRenderer | async)!\" [isInfinity]=\"($isInfinity | async)!\"\r\n [scrollbarThickness]=\"($scrollbarThickness | async)!\" [scrollbarThumbParams]=\"($scrollbarThumbParams | async)!\"\r\n [animationParams]=\"($animationParams | async)!\" [focusedElement]=\"($focusedElement | async)!\"\r\n [loading]=\"($loading | async)!\" [overscrollEnabled]=\"($overscrollEnabled | async)!\"\r\n [snappingDistance]=\"($snappingDistance | async)!\" [overlappingScrollbar]=\"($overlappingScrollbar | async)!\"\r\n [scrollbarEnabled]=\"($actualScrollbarEnabled | async)!\" [scrollbarInteractive]=\"($scrollbarInteractive | async)!\"\r\n [snapToItem]=\"($snapToItem | async)!\" [snapToItemAlign]=\"($snapToItemAlign | async)!\"\r\n [scrollbarMinSize]=\"($scrollbarMinSize | async)!\" [scrollBehavior]=\"($scrollBehavior | async)!\"\r\n [scrollingSettings]=\"($scrollingSettings | async)!\" [scrollingOneByOne]=\"($scrollingOneByOne | async)!\"\r\n [motionBlur]=\"($motionBlur | async)!\" [maxMotionBlur]=\"($maxMotionBlur | async)!\"\r\n [motionBlurEnabled]=\"($motionBlurEnabled | async)!\">\r\n <ng-container #renderersContainer></ng-container>\r\n</ng-scroller>", styles: [":host{position:relative;display:block;width:400px;overflow:hidden}:host(.horizontal){height:48px}:host(.vertical){height:320px}.ngvl__snapped-container{position:relative;width:100%;opacity:0}.ngvl__snapped-container.prepared{opacity:1}.ngvl__list-snapper{-webkit-tap-highlight-color:transparent;position:absolute;list-style:none;left:0;top:0;z-index:1}.ngvl__list-scroller{-webkit-tap-highlight-color:transparent;position:absolute;left:0;top:0;width:100%;height:100%;z-index:0}.ngvl__screen-reader{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] }]
10387
+ }, standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, providers: [NgVirtualListService, NgVirtualListPublicService], template: "<div aria-live=\"polite\" aria-atomic=\"true\" class=\"ngvl__screen-reader\">\r\n {{ $screenReaderFormattedMessage | async }}\r\n</div>\r\n\r\n<ng-prerender-container #prerender [bounds]=\"($bounds | async)!\" [direction]=\"($direction | async)!\"\r\n [dynamic]=\"($dynamicSize | async)!\" [divides]=\"($divides | async)!\" [isVertical]=\"($isVertical | async)!\"\r\n [itemSize]=\"($actualItemSize | async)!\" [trackBy]=\"($trackBy | async)!\" [itemRenderer]=\"($itemRenderer | async)!\"\r\n [startOffset]=\"($startOffset | async)!\" [endOffset]=\"($endOffset | async)!\"\r\n [scrollbarEnabled]=\"(scroller.$scrollbarShow | async)!\"\r\n [enabled]=\"($prerenderEnabled | async)!\"></ng-prerender-container>\r\n\r\n<ng-container *ngIf=\"($stickyEnabled | async)!\">\r\n <div localeSensitive [langTextDir]=\"($langTextDir | async)!\" #snappedContainer class=\"ngvl__snapped-container\"\r\n [ngClass]=\"($classes | async)\">\r\n <div #snapped part=\"snapped-item\" class=\"ngvl__list-snapper\">\r\n <ng-container #snapRendererContainer></ng-container>\r\n </div>\r\n </div>\r\n</ng-container>\r\n\r\n<ng-scroller #scroller class=\"ngvl__list-scroller\" [classes]=\"($classes | async)!\"\r\n [langTextDir]=\"($langTextDir | async)!\" [startOffset]=\"($startOffset | async)!\" [endOffset]=\"($endOffset | async)!\"\r\n [alignmentStartOffset]=\"($alignmentScrollStartOffset | async)!\"\r\n [alignmentEndOffset]=\"($alignmentScrollEndOffset | async)!\" [direction]=\"($direction | async)!\"\r\n [scrollbarThumbRenderer]=\"($scrollbarThumbRenderer | async)!\" [isInfinity]=\"($isInfinity | async)!\"\r\n [scrollbarThickness]=\"($scrollbarThickness | async)!\" [scrollbarThumbParams]=\"($scrollbarThumbParams | async)!\"\r\n [animationParams]=\"($animationParams | async)!\" [focusedElement]=\"($focusedElement | async)!\"\r\n [loading]=\"($loading | async)!\" [overscrollEnabled]=\"($overscrollEnabled | async)!\"\r\n [snappingDistance]=\"($snappingDistance | async)!\" [overlappingScrollbar]=\"($overlappingScrollbar | async)!\"\r\n [scrollbarEnabled]=\"($actualScrollbarEnabled | async)!\" [scrollbarInteractive]=\"($scrollbarInteractive | async)!\"\r\n [snapToItem]=\"($snapToItem | async)!\" [snapToItemAlign]=\"($snapToItemAlign | async)!\"\r\n [scrollbarMinSize]=\"($scrollbarMinSize | async)!\" [scrollBehavior]=\"($scrollBehavior | async)!\"\r\n [scrollingSettings]=\"($scrollingSettings | async)!\" [scrollingOneByOne]=\"($scrollingOneByOne | async)!\"\r\n [motionBlur]=\"($motionBlur | async)!\" [maxMotionBlur]=\"($maxMotionBlur | async)!\"\r\n [motionBlurEnabled]=\"($motionBlurEnabled | async)!\">\r\n <ng-container #renderersContainer></ng-container>\r\n</ng-scroller>", styles: [":host{position:relative;display:block;width:400px;overflow:hidden}:host(.horizontal){height:48px}:host(.vertical){height:320px}.ngvl__snapped-container{position:relative;width:100%;opacity:0}.ngvl__snapped-container.prepared{opacity:1}.ngvl__list-snapper{-webkit-tap-highlight-color:transparent;position:absolute;list-style:none;left:0;top:0;z-index:1}.ngvl__list-scroller{-webkit-tap-highlight-color:transparent;position:absolute;left:0;top:0;width:100%;height:100%;z-index:0}.ngvl__screen-reader{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] }]
10271
10388
  }], ctorParameters: function () { return []; }, propDecorators: { _prerender: [{
10272
10389
  type: ViewChild,
10273
10390
  args: ['prerender', { read: NgPrerenderContainer }]