ng-virtual-list 22.12.3 → 22.12.8

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.
@@ -328,7 +328,7 @@ const VISIBILITY_HIDDEN = 'hidden';
328
328
  const SIZE_100_PERSENT = '100%';
329
329
  const SIZE_AUTO = 'auto';
330
330
  const UNSET$5 = 'unset';
331
- const LEFT$2 = 'left';
331
+ const LEFT$3 = 'left';
332
332
  const RIGHT$1 = 'right';
333
333
  const POSITION$1 = 'position';
334
334
  const POSITION_RELATIVE = 'relative';
@@ -1831,7 +1831,7 @@ class ScrollEvent {
1831
1831
 
1832
1832
  /**
1833
1833
  * Event emitter
1834
- * @link https://github.com/DjonnyX/ng-virtual-list/blob/main/library/src/utils/event-emitter/event-emitter.ts
1834
+ * @link https://github.com/DjonnyX/ng-virtual-list/blob/22.x/projects/ng-virtual-list/src/lib/utils/event-emitter/event-emitter.ts
1835
1835
  * @author Evgenii Alexandrovich Grebennikov
1836
1836
  * @email djonnyx@gmail.com
1837
1837
  */
@@ -2741,7 +2741,7 @@ class TrackBox extends CacheMap {
2741
2741
  * Calculates list metrics
2742
2742
  */
2743
2743
  recalculateMetrics(options) {
2744
- 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);
2744
+ 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);
2745
2745
  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)
2746
2746
  || (typeof fromItemId === 'string' && fromItemId > '-1');
2747
2747
  let leftItemsOffset = 0, rightItemsOffset = 0;
@@ -3194,6 +3194,7 @@ class TrackBox extends CacheMap {
3194
3194
  rightItemLength,
3195
3195
  rightItemsWeight,
3196
3196
  scrollSize: actualScrollSize,
3197
+ maxScrollSize: totalSize,
3197
3198
  leftSizeOfAddedItems,
3198
3199
  sizeProperty,
3199
3200
  stickyEnabled,
@@ -3208,6 +3209,7 @@ class TrackBox extends CacheMap {
3208
3209
  isUpdating,
3209
3210
  snapToItem,
3210
3211
  snapToItemAlign,
3212
+ inverted,
3211
3213
  itemTransform,
3212
3214
  };
3213
3215
  return metrics;
@@ -3259,7 +3261,7 @@ class TrackBox extends CacheMap {
3259
3261
  return false;
3260
3262
  }
3261
3263
  generateDisplayCollection(items, actualItems, itemConfigMap, metrics) {
3262
- 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 = [];
3264
+ 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 = [];
3263
3265
  if (items.length) {
3264
3266
  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;
3265
3267
  let pos = startPosition, renderItems = renderItemsLength, stickyItem, nextSticky, stickyItemIndex = -1, nexstStickyItemIndex = -1, stickyItemSize = 0, endStickyItem, nextEndSticky, endStickyItemIndex = -1, endStickyItemSize = 0;
@@ -3299,6 +3301,7 @@ class TrackBox extends CacheMap {
3299
3301
  position: pos,
3300
3302
  boundsSize,
3301
3303
  scrollSize,
3304
+ maxScrollSize,
3302
3305
  absoluteStartPosition,
3303
3306
  absoluteStartPositionPercent,
3304
3307
  absoluteEndPosition,
@@ -3329,6 +3332,7 @@ class TrackBox extends CacheMap {
3329
3332
  tabIndex: i - layoutIndexOffset,
3330
3333
  divides,
3331
3334
  opacity: 1,
3335
+ inverted,
3332
3336
  zIndex: Z_INDEX_1,
3333
3337
  };
3334
3338
  const itemData = collectionItem;
@@ -3375,6 +3379,7 @@ class TrackBox extends CacheMap {
3375
3379
  position: pos,
3376
3380
  boundsSize,
3377
3381
  scrollSize,
3382
+ maxScrollSize,
3378
3383
  absoluteStartPosition,
3379
3384
  absoluteStartPositionPercent,
3380
3385
  absoluteEndPosition,
@@ -3411,6 +3416,7 @@ class TrackBox extends CacheMap {
3411
3416
  tabIndex: i - layoutIndexOffset,
3412
3417
  divides,
3413
3418
  opacity: 1,
3419
+ inverted,
3414
3420
  zIndex: Z_INDEX_1,
3415
3421
  };
3416
3422
  const itemData = collectionItem;
@@ -3471,6 +3477,7 @@ class TrackBox extends CacheMap {
3471
3477
  position: pos,
3472
3478
  boundsSize,
3473
3479
  scrollSize,
3480
+ maxScrollSize,
3474
3481
  absoluteStartPosition,
3475
3482
  absoluteStartPositionPercent,
3476
3483
  absoluteEndPosition,
@@ -3509,6 +3516,7 @@ class TrackBox extends CacheMap {
3509
3516
  opacity: 1,
3510
3517
  zIndex: Z_INDEX_0,
3511
3518
  fullSize,
3519
+ inverted,
3512
3520
  };
3513
3521
  if (snapped) {
3514
3522
  config.zIndex = Z_INDEX_2;
@@ -3653,18 +3661,18 @@ class TrackBox extends CacheMap {
3653
3661
  let first = null, last = null;
3654
3662
  if (!!components) {
3655
3663
  for (const comp of components) {
3656
- 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;
3664
+ 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;
3657
3665
  if (isVertical && (pos >= y && pos < y + height)) {
3658
3666
  return { id, x, y, width, height, isFirst, isLast };
3659
3667
  }
3660
- else if (!isVertical && (pos >= x && pos < x + width)) {
3661
- return { id, x, y, width, height, isFirst, isLast };
3668
+ else if (!isVertical && (pos >= xx && pos < xx + width)) {
3669
+ return { id, x: xx, y, width, height, isFirst, isLast };
3662
3670
  }
3663
3671
  if (isFirst) {
3664
- first = { id, x, y, width, height, isFirst, isLast };
3672
+ first = { id, x: xx, y, width, height, isFirst, isLast };
3665
3673
  }
3666
3674
  else if (isLast) {
3667
- last = { id, x, y, width, height, isFirst, isLast };
3675
+ last = { id, x: xx, y, width, height, isFirst, isLast };
3668
3676
  }
3669
3677
  }
3670
3678
  }
@@ -4052,7 +4060,7 @@ const easeLinear = (t) => {
4052
4060
 
4053
4061
  /**
4054
4062
  * Animator
4055
- * @link https://github.com/DjonnyX/ng-virtual-list/blob/main/library/src/utils/animator/animator.ts
4063
+ * @link https://github.com/DjonnyX/ng-virtual-list/blob/22.x/projects/ng-virtual-list/src/lib/utils/animator/animator.ts
4056
4064
  * @author Evgenii Alexandrovich Grebennikov
4057
4065
  * @email djonnyx@gmail.com
4058
4066
  */
@@ -4070,10 +4078,15 @@ class Animator {
4070
4078
  _diff = 0;
4071
4079
  _startValue = 0;
4072
4080
  _endValue = 0;
4073
- updateTo(value) {
4074
- this._endValue = value;
4075
- this._diff = this._endValue - this._startValue;
4076
- return this.hasAnimation();
4081
+ _prevPos = 0;
4082
+ updateTo(end) {
4083
+ if (this.hasAnimation()) {
4084
+ this._startValue = this._prevPos;
4085
+ this._endValue = end;
4086
+ this._diff = this._endValue - this._startValue;
4087
+ return true;
4088
+ }
4089
+ return false;
4077
4090
  }
4078
4091
  animate(params) {
4079
4092
  this.stop();
@@ -4083,7 +4096,8 @@ class Animator {
4083
4096
  this._startValue = startValue;
4084
4097
  this._endValue = endValue;
4085
4098
  const startTime = performance.now();
4086
- let isCanceled = false, prevPos = startValue, startPosDelta = 0, delta = 0, prevTime = startTime, isFinished = false;
4099
+ let isCanceled = false, startPosDelta = 0, delta = 0, prevTime = startTime, isFinished = false;
4100
+ this._prevPos = startValue;
4087
4101
  this._diff = this._endValue - this._startValue;
4088
4102
  const step = (currentTime) => {
4089
4103
  if (id !== this._currentId) {
@@ -4094,34 +4108,36 @@ class Animator {
4094
4108
  }
4095
4109
  const cPos = getPropValue?.() || 0;
4096
4110
  let startDelta = 0;
4097
- if (cPos !== prevPos) {
4098
- startDelta = cPos - prevPos;
4111
+ if (cPos !== this._prevPos) {
4112
+ startDelta = cPos - this._prevPos;
4099
4113
  startPosDelta += startDelta;
4100
4114
  }
4101
- const elapsed = currentTime - startTime, progress = this._startValue === endValue ? 1 : Math.min(duration > 0 ? elapsed / duration : 0, 1), easedProgress = easingFunction(progress), val = (withDelta ? startPosDelta : 0) + this._startValue + this._diff * easedProgress, currentValue = val, t = performance.now();
4115
+ const elapsed = currentTime - startTime, progress = this._startValue === this._endValue ? 1 : Math.min(duration > 0 ? elapsed / duration : 0, 1), easedProgress = easingFunction(progress), val = (withDelta ? startPosDelta : 0) + this._startValue + this._diff * easedProgress, currentValue = val, t = performance.now();
4102
4116
  isFinished = progress === 1;
4103
- delta = currentValue - startDelta - prevPos;
4117
+ delta = currentValue - startDelta - this._prevPos;
4104
4118
  const frameTimestamp = t - prevTime, actualFrameTimestamp = frameTimestamp < ANIMATOR_MIN_TIMESTAMP ? ANIMATOR_MIN_TIMESTAMP : frameTimestamp;
4105
4119
  prevTime = t;
4106
- prevPos = currentValue;
4120
+ this._prevPos = currentValue;
4121
+ if (isFinished) {
4122
+ this._animationId = -1;
4123
+ }
4107
4124
  if (onUpdate !== undefined) {
4108
4125
  const data = {
4109
4126
  id,
4110
4127
  delta,
4111
4128
  elapsed,
4112
- value: !withDelta && isFinished ? endValue : currentValue,
4129
+ value: currentValue,
4113
4130
  timestamp: actualFrameTimestamp,
4114
4131
  };
4115
4132
  onUpdate(data);
4116
4133
  }
4117
4134
  if (isFinished) {
4118
- this._animationId = -1;
4119
4135
  if (onComplete !== undefined) {
4120
4136
  const data = {
4121
4137
  id,
4122
4138
  delta,
4123
4139
  elapsed,
4124
- value: withDelta ? currentValue : endValue,
4140
+ value: currentValue,
4125
4141
  timestamp: actualFrameTimestamp,
4126
4142
  };
4127
4143
  onComplete(data);
@@ -4152,7 +4168,7 @@ class Animator {
4152
4168
  const SCROLL_VIEW_INVERSION = new InjectionToken('ScrollViewInversion');
4153
4169
  const SCROLL_VIEW_OVERSCROLL_ENABLED = new InjectionToken('ScrollViewOverscrollEnabled');
4154
4170
  const SCROLL_VIEW_NORMALIZE_VALUE_FROM_ZERO = new InjectionToken('ScrollViewNormalizeValueFromZero');
4155
- 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;
4171
+ 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, MAX_VELOCITY_TIMESTAMP = 100, SPEED_SCALE = 15, OVERSCROLL_START_ITERATION = 2;
4156
4172
  const MAX_ITERATIONS_FOR_AVERAGE_CALCULATIONS = 5, INSTANT_VELOCITY_SCALE = 1000;
4157
4173
  const SCROLL_EVENT$1 = new Event(SCROLLER_SCROLL);
4158
4174
 
@@ -4282,6 +4298,8 @@ class BaseScrollView {
4282
4298
  isVertical;
4283
4299
  grabbing = signal(false, /* @ts-ignore */
4284
4300
  ...(ngDevMode ? [{ debugName: "grabbing" }] : /* istanbul ignore next */ []));
4301
+ langTextDir = input(TextDirections.LTR, /* @ts-ignore */
4302
+ ...(ngDevMode ? [{ debugName: "langTextDir" }] : /* istanbul ignore next */ []));
4285
4303
  _inversion = inject(SCROLL_VIEW_INVERSION);
4286
4304
  _overscrollEnabled = inject(SCROLL_VIEW_OVERSCROLL_ENABLED);
4287
4305
  _$updateScrollBar = new Subject();
@@ -4447,7 +4465,7 @@ class BaseScrollView {
4447
4465
  }
4448
4466
  }
4449
4467
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: BaseScrollView, deps: [], target: i0.ɵɵFactoryTarget.Component });
4450
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.0", type: BaseScrollView, isStandalone: true, selector: "base-scroll-view", inputs: { direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, startOffset: { classPropertyName: "startOffset", publicName: "startOffset", isSignal: true, isRequired: false, transformFunction: null }, endOffset: { classPropertyName: "endOffset", publicName: "endOffset", isSignal: true, isRequired: false, transformFunction: null }, alignmentStartOffset: { classPropertyName: "alignmentStartOffset", publicName: "alignmentStartOffset", isSignal: true, isRequired: false, transformFunction: null }, alignmentEndOffset: { classPropertyName: "alignmentEndOffset", publicName: "alignmentEndOffset", isSignal: true, isRequired: false, transformFunction: null }, isInfinity: { classPropertyName: "isInfinity", publicName: "isInfinity", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "scrollContent", first: true, predicate: ["scrollContent"], descendants: true, isSignal: true }, { propertyName: "scrollViewport", first: true, predicate: ["scrollViewport"], descendants: true, isSignal: true }], ngImport: i0, template: '', isInline: true });
4468
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.0", type: BaseScrollView, isStandalone: true, selector: "base-scroll-view", inputs: { direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, startOffset: { classPropertyName: "startOffset", publicName: "startOffset", isSignal: true, isRequired: false, transformFunction: null }, endOffset: { classPropertyName: "endOffset", publicName: "endOffset", isSignal: true, isRequired: false, transformFunction: null }, alignmentStartOffset: { classPropertyName: "alignmentStartOffset", publicName: "alignmentStartOffset", isSignal: true, isRequired: false, transformFunction: null }, alignmentEndOffset: { classPropertyName: "alignmentEndOffset", publicName: "alignmentEndOffset", isSignal: true, isRequired: false, transformFunction: null }, isInfinity: { classPropertyName: "isInfinity", publicName: "isInfinity", isSignal: true, isRequired: false, transformFunction: null }, langTextDir: { classPropertyName: "langTextDir", publicName: "langTextDir", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "scrollContent", first: true, predicate: ["scrollContent"], descendants: true, isSignal: true }, { propertyName: "scrollViewport", first: true, predicate: ["scrollViewport"], descendants: true, isSignal: true }], ngImport: i0, template: '', isInline: true });
4451
4469
  }
4452
4470
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: BaseScrollView, decorators: [{
4453
4471
  type: Component,
@@ -4455,7 +4473,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImpor
4455
4473
  selector: 'base-scroll-view',
4456
4474
  template: '',
4457
4475
  }]
4458
- }], ctorParameters: () => [], propDecorators: { scrollContent: [{ type: i0.ViewChild, args: ['scrollContent', { isSignal: true }] }], scrollViewport: [{ type: i0.ViewChild, args: ['scrollViewport', { isSignal: true }] }], direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "direction", required: false }] }], startOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "startOffset", required: false }] }], endOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "endOffset", required: false }] }], alignmentStartOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "alignmentStartOffset", required: false }] }], alignmentEndOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "alignmentEndOffset", required: false }] }], isInfinity: [{ type: i0.Input, args: [{ isSignal: true, alias: "isInfinity", required: false }] }] } });
4476
+ }], ctorParameters: () => [], propDecorators: { scrollContent: [{ type: i0.ViewChild, args: ['scrollContent', { isSignal: true }] }], scrollViewport: [{ type: i0.ViewChild, args: ['scrollViewport', { isSignal: true }] }], direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "direction", required: false }] }], startOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "startOffset", required: false }] }], endOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "endOffset", required: false }] }], alignmentStartOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "alignmentStartOffset", required: false }] }], alignmentEndOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "alignmentEndOffset", required: false }] }], isInfinity: [{ type: i0.Input, args: [{ isSignal: true, alias: "isInfinity", required: false }] }], langTextDir: [{ type: i0.Input, args: [{ isSignal: true, alias: "langTextDir", required: false }] }] } });
4459
4477
 
4460
4478
  /**
4461
4479
  * ScrollingDirection
@@ -4548,6 +4566,8 @@ class NgScrollView extends BaseScrollView {
4548
4566
  _startPosition = 0;
4549
4567
  _animator = new Animator();
4550
4568
  _interactive = true;
4569
+ _horizontalAxisInvertion;
4570
+ get inverted() { return this._horizontalAxisInvertion(); }
4551
4571
  _overscrollIteration = 0;
4552
4572
  set x(v) {
4553
4573
  this.setX(v);
@@ -4603,6 +4623,11 @@ class NgScrollView extends BaseScrollView {
4603
4623
  constructor() {
4604
4624
  super();
4605
4625
  let mouseCanceled = false, touchCanceled = false;
4626
+ this._horizontalAxisInvertion = computed(() => {
4627
+ const isVertical = this.isVertical(), langTextDir = this.langTextDir();
4628
+ return !isVertical && langTextDir === TextDirections.RTL;
4629
+ }, /* @ts-ignore */
4630
+ ...(ngDevMode ? [{ debugName: "_horizontalAxisInvertion" }] : /* istanbul ignore next */ []));
4606
4631
  const $viewportBounds = toObservable(this.viewportBounds);
4607
4632
  $viewportBounds.pipe(takeUntilDestroyed(), debounceTime(0), tap(() => {
4608
4633
  this._isMoving = false;
@@ -4629,8 +4654,8 @@ class NgScrollView extends BaseScrollView {
4629
4654
  this.emitScrollableEvent();
4630
4655
  this.checkOverscroll(e);
4631
4656
  this.stopScrolling(true);
4632
- 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);
4633
- this.scroll({ [isVertical ? TOP$1 : LEFT$1]: position, behavior: INSTANT$1, userAction: true, blending: false, fireUpdate: true });
4657
+ 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);
4658
+ this.scroll({ [isVertical ? TOP$1 : LEFT$2]: position, behavior: INSTANT$1, userAction: true, blending: false, fireUpdate: true });
4634
4659
  this._$wheel.next(delta);
4635
4660
  }));
4636
4661
  })).subscribe();
@@ -4683,7 +4708,7 @@ class NgScrollView extends BaseScrollView {
4683
4708
  this._isMoving = true;
4684
4709
  this.grabbing.set(true);
4685
4710
  this._startPosition = (isVertical ? this.y : this.x);
4686
- let prevClientPosition = isVertical ? e.clientY : e.clientX, startClientPos = prevClientPosition, offsets = new Array(), velocities = new Array(), startTime = Date.now();
4711
+ let prevClientPosition = (isVertical ? e.clientY : e.clientX) * (this._horizontalAxisInvertion() ? -1 : 1), startClientPos = prevClientPosition, offsets = new Array(), velocities = new Array(), startTime = Date.now();
4687
4712
  return fromEvent(window, MOUSE_MOVE, { passive: false }).pipe(takeUntilDestroyed(this._destroyRef), takeUntil$1($mouseDragCancel), tap(e => {
4688
4713
  this.checkOverscroll(e);
4689
4714
  }), switchMap$1(e => {
@@ -4761,7 +4786,7 @@ class NgScrollView extends BaseScrollView {
4761
4786
  this._isMoving = true;
4762
4787
  this.grabbing.set(true);
4763
4788
  this._startPosition = (isVertical ? this.y : this.x);
4764
- 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();
4789
+ let prevClientPosition = (isVertical ? e.touches[e.touches.length - 1].clientY : e.touches[e.touches.length - 1].clientX) * (this._horizontalAxisInvertion() ? -1 : 1), startClientPos = prevClientPosition, offsets = new Array(), velocities = new Array(), startTime = Date.now();
4765
4790
  return fromEvent(window, TOUCH_MOVE, { passive: false }).pipe(takeUntilDestroyed(this._destroyRef), takeUntil$1($touchCanceler), tap(e => {
4766
4791
  this.checkOverscroll(e);
4767
4792
  }), switchMap$1(e => {
@@ -4859,7 +4884,7 @@ class NgScrollView extends BaseScrollView {
4859
4884
  return false;
4860
4885
  }
4861
4886
  calculatePosition(isVertical, e, inversion, startClientPos, startTime, prevClientPosition, offsets, velocities) {
4862
- 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);
4887
+ const currentPos = (isVertical ? e.touches?.[e.touches?.length - 1]?.clientY || e.clientY : e.touches?.[e.touches?.length - 1]?.clientX || e.clientX) * (this._horizontalAxisInvertion() ? -1 : 1), 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);
4863
4888
  this.calculateAcceleration(velocities, v0, timestamp);
4864
4889
  return { position, currentPos, endTime, scrollDelta };
4865
4890
  }
@@ -4949,7 +4974,7 @@ class NgScrollView extends BaseScrollView {
4949
4974
  this._animator.stop();
4950
4975
  }
4951
4976
  move(isVertical, position, blending = false, userAction = false, fireUpdate = true) {
4952
- this.scroll({ [isVertical ? TOP$1 : LEFT$1]: position, behavior: INSTANT$1, blending, userAction, fireUpdate });
4977
+ this.scroll({ [isVertical ? TOP$1 : LEFT$2]: position, behavior: INSTANT$1, blending, userAction, fireUpdate });
4953
4978
  }
4954
4979
  moveWithAcceleration(isVertical, position, v0, v, a0, timestamp) {
4955
4980
  if (a0 !== 0 && timestamp < MAX_VELOCITY_TIMESTAMP) {
@@ -5245,7 +5270,7 @@ class NgScrollView extends BaseScrollView {
5245
5270
  }
5246
5271
  refreshCoordinate(x, y) {
5247
5272
  const scrollContent = this.scrollContent()?.nativeElement;
5248
- scrollContent.style.transform = matrix3d((this._inversion ? 1 : -1) * x + (this.isVertical() ? 0 : this._startLayoutOffset), (this._inversion ? 1 : -1) * y + (this.isVertical() ? this._startLayoutOffset : 0));
5273
+ scrollContent.style.transform = matrix3d((this._inversion ? 1 : -1) * x * (this._horizontalAxisInvertion() ? -1 : 1) + (this.isVertical() ? 0 : this._startLayoutOffset), (this._inversion ? 1 : -1) * y + (this.isVertical() ? this._startLayoutOffset : 0));
5249
5274
  }
5250
5275
  fireScrollEvent(userAction) {
5251
5276
  this._$scroll.next(userAction);
@@ -5306,8 +5331,6 @@ class NgScrollBarComponent extends NgScrollView {
5306
5331
  ...(ngDevMode ? [{ debugName: "scrollbarMinSize" }] : /* istanbul ignore next */ []));
5307
5332
  prepared = input(false, /* @ts-ignore */
5308
5333
  ...(ngDevMode ? [{ debugName: "prepared" }] : /* istanbul ignore next */ []));
5309
- langTextDir = input(DEFAULT_LANG_TEXT_DIR, /* @ts-ignore */
5310
- ...(ngDevMode ? [{ debugName: "langTextDir" }] : /* istanbul ignore next */ []));
5311
5334
  interactive = input(DEFAULT_SCROLLBAR_INTERACTIVE, /* @ts-ignore */
5312
5335
  ...(ngDevMode ? [{ debugName: "interactive" }] : /* istanbul ignore next */ []));
5313
5336
  overlapping = input(DEFAULT_OVERLAPPING_SCROLLBAR, /* @ts-ignore */
@@ -5416,7 +5439,7 @@ class NgScrollBarComponent extends NgScrollView {
5416
5439
  if (!!el) {
5417
5440
  const overlapping = this.overlapping(), langTextDir = this.langTextDir();
5418
5441
  el.style[POSITION$1] = overlapping ? POSITION_ABSOLUTE : POSITION_RELATIVE;
5419
- el.style[LEFT$2] = overlapping && langTextDir === TextDirections.RTL ? '0' : UNSET$5;
5442
+ el.style[LEFT$3] = overlapping && langTextDir === TextDirections.RTL ? '0' : UNSET$5;
5420
5443
  el.style[RIGHT$1] = overlapping && langTextDir === TextDirections.LTR ? '0' : UNSET$5;
5421
5444
  el.style[WIDTH] = overlapping ? SIZE_AUTO : SIZE_100_PERSENT;
5422
5445
  }
@@ -5436,7 +5459,7 @@ class NgScrollBarComponent extends NgScrollView {
5436
5459
  })).subscribe();
5437
5460
  }
5438
5461
  createDragEvent(userAction) {
5439
- const isVertical = this.isVertical(), scrollSize = isVertical ? this.scrollHeight : this.scrollWidth, scrollPosition = isVertical ? this.scrollTop : this.scrollLeft, startOffset = this.startOffset(), endOffset = this.endOffset(), scrollContent = this.scrollContent()?.nativeElement, scrollViewport = this.scrollViewport()?.nativeElement;
5462
+ const isVertical = this.isVertical(), 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;
5440
5463
  if (!!scrollViewport && !!scrollContent) {
5441
5464
  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);
5442
5465
  const event = {
@@ -5464,7 +5487,7 @@ class NgScrollBarComponent extends NgScrollView {
5464
5487
  this._scrollBarService.click(event);
5465
5488
  }
5466
5489
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: NgScrollBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5467
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.0", type: NgScrollBarComponent, isStandalone: false, selector: "ng-scroll-bar", inputs: { loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, thumbGradientPositions: { classPropertyName: "thumbGradientPositions", publicName: "thumbGradientPositions", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, thickness: { classPropertyName: "thickness", publicName: "thickness", isSignal: true, isRequired: false, transformFunction: null }, scrollbarMinSize: { classPropertyName: "scrollbarMinSize", publicName: "scrollbarMinSize", isSignal: true, isRequired: false, transformFunction: null }, prepared: { classPropertyName: "prepared", publicName: "prepared", isSignal: true, isRequired: false, transformFunction: null }, langTextDir: { classPropertyName: "langTextDir", publicName: "langTextDir", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, overlapping: { classPropertyName: "overlapping", publicName: "overlapping", isSignal: true, isRequired: false, transformFunction: null }, show: { classPropertyName: "show", publicName: "show", isSignal: true, isRequired: false, transformFunction: null }, params: { classPropertyName: "params", publicName: "params", isSignal: true, isRequired: false, transformFunction: null }, renderer: { classPropertyName: "renderer", publicName: "renderer", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onDrag: "onDrag", onDragEnd: "onDragEnd" }, providers: [
5490
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.0", type: NgScrollBarComponent, isStandalone: false, selector: "ng-scroll-bar", inputs: { loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, thumbGradientPositions: { classPropertyName: "thumbGradientPositions", publicName: "thumbGradientPositions", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, thickness: { classPropertyName: "thickness", publicName: "thickness", isSignal: true, isRequired: false, transformFunction: null }, scrollbarMinSize: { classPropertyName: "scrollbarMinSize", publicName: "scrollbarMinSize", isSignal: true, isRequired: false, transformFunction: null }, prepared: { classPropertyName: "prepared", publicName: "prepared", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, overlapping: { classPropertyName: "overlapping", publicName: "overlapping", isSignal: true, isRequired: false, transformFunction: null }, show: { classPropertyName: "show", publicName: "show", isSignal: true, isRequired: false, transformFunction: null }, params: { classPropertyName: "params", publicName: "params", isSignal: true, isRequired: false, transformFunction: null }, renderer: { classPropertyName: "renderer", publicName: "renderer", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onDrag: "onDrag", onDragEnd: "onDragEnd" }, providers: [
5468
5491
  { provide: SCROLL_VIEW_INVERSION, useValue: true },
5469
5492
  { provide: SCROLL_VIEW_NORMALIZE_VALUE_FROM_ZERO, useValue: false },
5470
5493
  { provide: SCROLL_VIEW_OVERSCROLL_ENABLED, useValue: false },
@@ -5481,9 +5504,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImpor
5481
5504
  NgScrollBarService,
5482
5505
  NgScrollBarPublicService,
5483
5506
  ], standalone: false, template: "@let grab = grabbing();\r\n<div #scrollViewport class=\"track\" part=\"scrollbar-track\" [ngStyle]=\"styles()\" [ngClass]=\"{grabbing: grab}\">\r\n <div #scrollContent class=\"thumb\" part=\"scrollbar-thumb\" [class.horizontal]=\"!isVertical()\"\r\n (pointerdown)=\"click($event)\">\r\n <ng-container [ngTemplateOutlet]=\"thumbRenderer()\" [ngTemplateOutletContext]=\"templateContext()\" />\r\n </div>\r\n</div>\r\n\r\n<ng-template #defaultRenderer let-api=\"api\" let-width=\"width\" let-height=\"height\" let-fillPositions=\"fillPositions\"\r\n let-params=\"params\">\r\n <div class=\"shape\" part=\"scrollbar-thumb__shape\" [style.width.px]=\"width\" [style.height.px]=\"height\"></div>\r\n</ng-template>", styles: [":host{position:relative;overflow:hidden;-webkit-user-select:none;user-select:none;width:100%;height:100%}.track{position:relative;overflow:hidden;width:100%;height:100%;cursor:grab}.track.grabbing{cursor:grabbing}.track .thumb{display:block;position:absolute;list-style:none;padding:0;margin:0;overflow:hidden}.track .thumb.prepared{overflow:hidden}.track .thumb.horizontal{top:0}.track .thumb .shape{box-sizing:border-box;pointer-events:none;background-color:#818181;border-radius:0;overflow:hidden}.track.grabbing .thumb{cursor:grabbing}\n"] }]
5484
- }], ctorParameters: () => [], propDecorators: { _defaultRenderer: [{ type: i0.ViewChild, args: ['defaultRenderer', { isSignal: true }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], onDrag: [{ type: i0.Output, args: ["onDrag"] }], onDragEnd: [{ type: i0.Output, args: ["onDragEnd"] }], thumbGradientPositions: [{ type: i0.Input, args: [{ isSignal: true, alias: "thumbGradientPositions", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], thickness: [{ type: i0.Input, args: [{ isSignal: true, alias: "thickness", required: false }] }], scrollbarMinSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollbarMinSize", required: false }] }], prepared: [{ type: i0.Input, args: [{ isSignal: true, alias: "prepared", required: false }] }], langTextDir: [{ type: i0.Input, args: [{ isSignal: true, alias: "langTextDir", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], overlapping: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlapping", required: false }] }], show: [{ type: i0.Input, args: [{ isSignal: true, alias: "show", required: false }] }], params: [{ type: i0.Input, args: [{ isSignal: true, alias: "params", required: false }] }], renderer: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderer", required: false }] }] } });
5507
+ }], ctorParameters: () => [], propDecorators: { _defaultRenderer: [{ type: i0.ViewChild, args: ['defaultRenderer', { isSignal: true }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], onDrag: [{ type: i0.Output, args: ["onDrag"] }], onDragEnd: [{ type: i0.Output, args: ["onDragEnd"] }], thumbGradientPositions: [{ type: i0.Input, args: [{ isSignal: true, alias: "thumbGradientPositions", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], thickness: [{ type: i0.Input, args: [{ isSignal: true, alias: "thickness", required: false }] }], scrollbarMinSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollbarMinSize", required: false }] }], prepared: [{ type: i0.Input, args: [{ isSignal: true, alias: "prepared", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], overlapping: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlapping", required: false }] }], show: [{ type: i0.Input, args: [{ isSignal: true, alias: "show", required: false }] }], params: [{ type: i0.Input, args: [{ isSignal: true, alias: "params", required: false }] }], renderer: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderer", required: false }] }] } });
5485
5508
 
5486
- const RIGHT = 'right', DIR = 'dir';
5509
+ const LEFT$1 = 'left', RIGHT = 'right', DIR = 'dir';
5487
5510
  /**
5488
5511
  * LocaleSensitiveDirective
5489
5512
  * Maximum performance for extremely large lists.
@@ -5501,14 +5524,15 @@ class LocaleSensitiveDirective {
5501
5524
  constructor() {
5502
5525
  const $langTextDir = toObservable(this.langTextDir), $listDir = toObservable(this.listDir);
5503
5526
  combineLatest([$langTextDir, $listDir]).pipe(takeUntilDestroyed(), tap(([dir, listDir]) => {
5504
- const element = this._elementRef.nativeElement, isVertical = isDirection(listDir, ScrollerDirection$1.VERTICAL);
5505
- element.setAttribute(DIR, isVertical ? dir : TextDirections.LTR);
5506
- if (dir === TextDirections.RTL && isVertical) {
5527
+ const element = this._elementRef.nativeElement;
5528
+ element.setAttribute(DIR, dir);
5529
+ if (dir === TextDirections.RTL) {
5507
5530
  element.style.textAlign = RIGHT;
5508
5531
  element.classList.add(TextDirections.RTL);
5509
5532
  element.classList.remove(TextDirections.LTR);
5510
5533
  }
5511
5534
  else {
5535
+ element.style.textAlign = LEFT$1;
5512
5536
  element.classList.add(TextDirections.LTR);
5513
5537
  element.classList.remove(TextDirections.RTL);
5514
5538
  }
@@ -5578,8 +5602,6 @@ class NgScrollerComponent extends NgScrollView {
5578
5602
  ...(ngDevMode ? [{ debugName: "scrollbarShow" }] : /* istanbul ignore next */ []));
5579
5603
  preparedSignal = signal(false, /* @ts-ignore */
5580
5604
  ...(ngDevMode ? [{ debugName: "preparedSignal" }] : /* istanbul ignore next */ []));
5581
- langTextDir = signal(TextDirections.LTR, /* @ts-ignore */
5582
- ...(ngDevMode ? [{ debugName: "langTextDir" }] : /* istanbul ignore next */ []));
5583
5605
  listStyles = signal({ perspectiveOrigin: 'center' }, /* @ts-ignore */
5584
5606
  ...(ngDevMode ? [{ debugName: "listStyles" }] : /* istanbul ignore next */ []));
5585
5607
  _scrollBox = new ScrollBox$1();
@@ -5664,10 +5686,6 @@ class NgScrollerComponent extends NgScrollView {
5664
5686
  }), debounceTime(50), tap(([, , filter, ,]) => {
5665
5687
  filter.nativeElement.setStdDeviation(0, 0);
5666
5688
  })).subscribe();
5667
- this._service.$langTextDir.pipe(tap(v => {
5668
- takeUntilDestroyed(this._destroyRef),
5669
- this.langTextDir.set(v);
5670
- })).subscribe();
5671
5689
  const $prepare = toObservable(this.preparedSignal);
5672
5690
  $prepare.pipe(takeUntilDestroyed(), filter$1(v => !!v), tap(() => {
5673
5691
  this.updateScrollBarHandler(true, false, true);
@@ -5702,9 +5720,9 @@ class NgScrollerComponent extends NgScrollView {
5702
5720
  });
5703
5721
  }
5704
5722
  recalculatePerspective() {
5705
- const isVertical = this.isVertical(), scrollSize = (isVertical ? this.scrollTop : this.scrollLeft) - this._startLayoutOffset, { width, height } = this.viewportBounds();
5723
+ const isVertical = this.isVertical(), inverted = this._horizontalAxisInvertion(), scrollSize = (isVertical ? this.scrollTop : this.scrollLeft) - this._startLayoutOffset, maxScrollSize = isVertical ? this.scrollHeight : this.scrollWidth, { width, height } = this.viewportBounds();
5706
5724
  this.listStyles.set({
5707
- perspectiveOrigin: `${isVertical ? width * .5 : (scrollSize + width * .5)}${PX$1} ${isVertical ? (scrollSize + height * .5) : height * .5}${PX$1}`
5725
+ 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}`
5708
5726
  });
5709
5727
  }
5710
5728
  onResizeViewport() {
@@ -5717,6 +5735,7 @@ class NgScrollerComponent extends NgScrollView {
5717
5735
  this.viewportBounds.set(bounds);
5718
5736
  this.updateScrollBar();
5719
5737
  this._$resizeViewport.next(bounds);
5738
+ this.recalculatePerspective();
5720
5739
  }
5721
5740
  }
5722
5741
  onResizeContent(value = null) {
@@ -5732,6 +5751,7 @@ class NgScrollerComponent extends NgScrollView {
5732
5751
  this.contentBounds.set(bounds);
5733
5752
  this.updateScrollBar();
5734
5753
  this._$resizeContent.next(bounds);
5754
+ this.recalculatePerspective();
5735
5755
  }
5736
5756
  }
5737
5757
  updateScrollBarHandler(update = false, blending = true, fireUpdate = false) {
@@ -5899,7 +5919,7 @@ class NgScrollerComponent extends NgScrollView {
5899
5919
  { provide: SCROLL_VIEW_INVERSION, useValue: false },
5900
5920
  { provide: SCROLL_VIEW_NORMALIZE_VALUE_FROM_ZERO, useValue: true },
5901
5921
  { provide: SCROLL_VIEW_OVERSCROLL_ENABLED, useValue: true },
5902
- ], viewQueries: [{ propertyName: "filter", first: true, predicate: ["filter"], descendants: true, isSignal: true }, { propertyName: "scrollBar", first: true, predicate: ["scrollBar"], descendants: true, read: NgScrollBarComponent }], usesInheritance: true, ngImport: i0, template: "@let filtered = motionBlurEnabled();\r\n<div localeSensitive [langTextDir]=\"langTextDir()\" [listDir]=\"direction()\" class=\"ngvl__container\"\r\n [ngClass]=\"containerClasses()\">\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]=\"filtered\" [style.filter]=\"filtered ? _filter : 'unset'\">\r\n <div cdkScrollable #scrollViewport part=\"scroller\" class=\"ngvl__scroller\">\r\n <div #scrollContent [attr.aria-orientation]=\"direction()\"\r\n [attr.aria-activedescendant]=\"focusedElement()\" tabindex=\"0\" part=\"list\" class=\"ngvl__list\"\r\n [ngClass]=\"actualClasses()\" [ngStyle]=\"listStyles()\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n </div>\r\n </foreignObject>\r\n </svg>\r\n @if (scrollbarEnabled()) {\r\n @let prepared = preparedSignal();\r\n <ng-scroll-bar #scrollBar [direction]=\"direction()\" [size]=\"thumbSize()\" [renderer]=\"scrollbarThumbRenderer()\"\r\n [thickness]=\"scrollbarThickness()\" [params]=\"scrollbarThumbParams()\" [loading]=\"loading()\" [overlapping]=\"overlappingScrollbar()\"\r\n [thumbGradientPositions]=\"thumbGradientPositions()\" [prepared]=\"prepared\" [interactive]=\"scrollbarInteractive()\"\r\n [show]=\"scrollbarShow() && scrollbarEnabled() && prepared\" [startOffset]=\"startOffset()\" [langTextDir]=\"langTextDir()\"\r\n [endOffset]=\"endOffset()\" [overscrollEnabled]=\"overscrollEnabled()\" [scrollBehavior]=\"scrollBehavior()\"\r\n [scrollbarMinSize]=\"scrollbarMinSize()\" (onDrag)=\"onScrollBarDragHandler($event)\"\r\n (onDragEnd)=\"onScrollBarDragEndHandler($event)\"></ng-scroll-bar>\r\n }\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:not(.overlapping){grid-template-rows:1fr 0}.ngvl__container.horizontal{transition:grid-template-rows .1s ease-out}.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:not(.overlapping){grid-template-columns:1fr 0}.ngvl__container.vertical{transition:grid-template-columns .1s ease-out}.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.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]" }] });
5922
+ ], viewQueries: [{ propertyName: "filter", first: true, predicate: ["filter"], descendants: true, isSignal: true }, { propertyName: "scrollBar", first: true, predicate: ["scrollBar"], descendants: true, read: NgScrollBarComponent }], usesInheritance: true, ngImport: i0, template: "@let filtered = motionBlurEnabled();\r\n<div localeSensitive [langTextDir]=\"langTextDir()\" [listDir]=\"direction()\" class=\"ngvl__container\"\r\n [ngClass]=\"containerClasses()\">\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]=\"filtered\" [style.filter]=\"filtered ? _filter : 'unset'\">\r\n <div cdkScrollable #scrollViewport part=\"scroller\" class=\"ngvl__scroller\">\r\n <div #scrollContent [attr.aria-orientation]=\"direction()\"\r\n [attr.aria-activedescendant]=\"focusedElement()\" tabindex=\"0\" part=\"list\" class=\"ngvl__list\"\r\n [ngClass]=\"actualClasses()\" [ngStyle]=\"listStyles()\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n </div>\r\n </foreignObject>\r\n </svg>\r\n @if (scrollbarEnabled()) {\r\n @let prepared = preparedSignal();\r\n <ng-scroll-bar #scrollBar [direction]=\"direction()\" [langTextDir]=\"langTextDir()\" [size]=\"thumbSize()\" [renderer]=\"scrollbarThumbRenderer()\"\r\n [thickness]=\"scrollbarThickness()\" [params]=\"scrollbarThumbParams()\" [loading]=\"loading()\" [overlapping]=\"overlappingScrollbar()\"\r\n [thumbGradientPositions]=\"thumbGradientPositions()\" [prepared]=\"prepared\" [interactive]=\"scrollbarInteractive()\"\r\n [show]=\"scrollbarShow() && scrollbarEnabled() && prepared\" [startOffset]=\"startOffset()\" [langTextDir]=\"langTextDir()\"\r\n [endOffset]=\"endOffset()\" [overscrollEnabled]=\"overscrollEnabled()\" [scrollBehavior]=\"scrollBehavior()\"\r\n [scrollbarMinSize]=\"scrollbarMinSize()\" (onDrag)=\"onScrollBarDragHandler($event)\"\r\n (onDragEnd)=\"onScrollBarDragEndHandler($event)\"></ng-scroll-bar>\r\n }\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:not(.overlapping){grid-template-rows:1fr 0}.ngvl__container.horizontal{transition:grid-template-rows .1s ease-out}.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:not(.overlapping){grid-template-columns:1fr 0}.ngvl__container.vertical{transition:grid-template-columns .1s ease-out}.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.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]" }] });
5903
5923
  }
5904
5924
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: NgScrollerComponent, decorators: [{
5905
5925
  type: Component,
@@ -5907,7 +5927,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImpor
5907
5927
  { provide: SCROLL_VIEW_INVERSION, useValue: false },
5908
5928
  { provide: SCROLL_VIEW_NORMALIZE_VALUE_FROM_ZERO, useValue: true },
5909
5929
  { provide: SCROLL_VIEW_OVERSCROLL_ENABLED, useValue: true },
5910
- ], standalone: false, template: "@let filtered = motionBlurEnabled();\r\n<div localeSensitive [langTextDir]=\"langTextDir()\" [listDir]=\"direction()\" class=\"ngvl__container\"\r\n [ngClass]=\"containerClasses()\">\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]=\"filtered\" [style.filter]=\"filtered ? _filter : 'unset'\">\r\n <div cdkScrollable #scrollViewport part=\"scroller\" class=\"ngvl__scroller\">\r\n <div #scrollContent [attr.aria-orientation]=\"direction()\"\r\n [attr.aria-activedescendant]=\"focusedElement()\" tabindex=\"0\" part=\"list\" class=\"ngvl__list\"\r\n [ngClass]=\"actualClasses()\" [ngStyle]=\"listStyles()\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n </div>\r\n </foreignObject>\r\n </svg>\r\n @if (scrollbarEnabled()) {\r\n @let prepared = preparedSignal();\r\n <ng-scroll-bar #scrollBar [direction]=\"direction()\" [size]=\"thumbSize()\" [renderer]=\"scrollbarThumbRenderer()\"\r\n [thickness]=\"scrollbarThickness()\" [params]=\"scrollbarThumbParams()\" [loading]=\"loading()\" [overlapping]=\"overlappingScrollbar()\"\r\n [thumbGradientPositions]=\"thumbGradientPositions()\" [prepared]=\"prepared\" [interactive]=\"scrollbarInteractive()\"\r\n [show]=\"scrollbarShow() && scrollbarEnabled() && prepared\" [startOffset]=\"startOffset()\" [langTextDir]=\"langTextDir()\"\r\n [endOffset]=\"endOffset()\" [overscrollEnabled]=\"overscrollEnabled()\" [scrollBehavior]=\"scrollBehavior()\"\r\n [scrollbarMinSize]=\"scrollbarMinSize()\" (onDrag)=\"onScrollBarDragHandler($event)\"\r\n (onDragEnd)=\"onScrollBarDragEndHandler($event)\"></ng-scroll-bar>\r\n }\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:not(.overlapping){grid-template-rows:1fr 0}.ngvl__container.horizontal{transition:grid-template-rows .1s ease-out}.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:not(.overlapping){grid-template-columns:1fr 0}.ngvl__container.vertical{transition:grid-template-columns .1s ease-out}.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"] }]
5930
+ ], standalone: false, template: "@let filtered = motionBlurEnabled();\r\n<div localeSensitive [langTextDir]=\"langTextDir()\" [listDir]=\"direction()\" class=\"ngvl__container\"\r\n [ngClass]=\"containerClasses()\">\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]=\"filtered\" [style.filter]=\"filtered ? _filter : 'unset'\">\r\n <div cdkScrollable #scrollViewport part=\"scroller\" class=\"ngvl__scroller\">\r\n <div #scrollContent [attr.aria-orientation]=\"direction()\"\r\n [attr.aria-activedescendant]=\"focusedElement()\" tabindex=\"0\" part=\"list\" class=\"ngvl__list\"\r\n [ngClass]=\"actualClasses()\" [ngStyle]=\"listStyles()\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n </div>\r\n </foreignObject>\r\n </svg>\r\n @if (scrollbarEnabled()) {\r\n @let prepared = preparedSignal();\r\n <ng-scroll-bar #scrollBar [direction]=\"direction()\" [langTextDir]=\"langTextDir()\" [size]=\"thumbSize()\" [renderer]=\"scrollbarThumbRenderer()\"\r\n [thickness]=\"scrollbarThickness()\" [params]=\"scrollbarThumbParams()\" [loading]=\"loading()\" [overlapping]=\"overlappingScrollbar()\"\r\n [thumbGradientPositions]=\"thumbGradientPositions()\" [prepared]=\"prepared\" [interactive]=\"scrollbarInteractive()\"\r\n [show]=\"scrollbarShow() && scrollbarEnabled() && prepared\" [startOffset]=\"startOffset()\" [langTextDir]=\"langTextDir()\"\r\n [endOffset]=\"endOffset()\" [overscrollEnabled]=\"overscrollEnabled()\" [scrollBehavior]=\"scrollBehavior()\"\r\n [scrollbarMinSize]=\"scrollbarMinSize()\" (onDrag)=\"onScrollBarDragHandler($event)\"\r\n (onDragEnd)=\"onScrollBarDragEndHandler($event)\"></ng-scroll-bar>\r\n }\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:not(.overlapping){grid-template-rows:1fr 0}.ngvl__container.horizontal{transition:grid-template-rows .1s ease-out}.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:not(.overlapping){grid-template-columns:1fr 0}.ngvl__container.vertical{transition:grid-template-columns .1s ease-out}.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"] }]
5911
5931
  }], ctorParameters: () => [], propDecorators: { scrollBar: [{
5912
5932
  type: ViewChild,
5913
5933
  args: ['scrollBar', { read: NgScrollBarComponent }]
@@ -5927,6 +5947,7 @@ const createItemData = (data, isVertical, bounds, boundsSize, dynamic, divides,
5927
5947
  measures: {
5928
5948
  position: 0,
5929
5949
  scrollSize: 0,
5950
+ maxScrollSize: 0,
5930
5951
  size: itemSize,
5931
5952
  row: {
5932
5953
  size: itemSize,
@@ -5986,6 +6007,7 @@ const createItemData = (data, isVertical, bounds, boundsSize, dynamic, divides,
5986
6007
  fullSize: false,
5987
6008
  layoutIndexOffset: 0,
5988
6009
  totalItems: 0,
6010
+ inverted: false,
5989
6011
  },
5990
6012
  };
5991
6013
  };
@@ -6212,8 +6234,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImpor
6212
6234
  */
6213
6235
  class NgPrerenderScrollerComponent extends BaseScrollView {
6214
6236
  scrollBar;
6215
- langTextDir = signal(TextDirections.LTR, /* @ts-ignore */
6216
- ...(ngDevMode ? [{ debugName: "langTextDir" }] : /* istanbul ignore next */ []));
6217
6237
  scrollbarEnabled = input(DEFAULT_SCROLLBAR_ENABLED, /* @ts-ignore */
6218
6238
  ...(ngDevMode ? [{ debugName: "scrollbarEnabled" }] : /* istanbul ignore next */ []));
6219
6239
  classes = input({}, /* @ts-ignore */
@@ -7684,19 +7704,22 @@ class NgVirtualListComponent {
7684
7704
  }
7685
7705
  const scroller = this._scrollerComponent();
7686
7706
  if (!!scroller) {
7687
- const { width, height } = this._bounds(), { width: elementWidth, height: elementHeight } = element.getBoundingClientRect(), isVertical = this._isVertical, viewportSize = isVertical ? height : width, elementSize = isVertical ? elementHeight : elementWidth;
7707
+ const { width, height } = this._bounds(), { width: elementWidth, height: elementHeight } = element.getBoundingClientRect(), isVertical = this._isVertical, viewportSize = isVertical ? height : width, maxPosition = isVertical ? scroller.scrollHeight : scroller.scrollWidth, elementSize = isVertical ? elementHeight : elementWidth;
7688
7708
  let pos = Number.NaN;
7689
7709
  switch (align) {
7690
7710
  case FocusAlignments.START: {
7691
- pos = position + scroller.startLayoutOffset;
7711
+ const p = position + scroller.startLayoutOffset;
7712
+ pos = scroller.inverted ? (maxPosition - p) : p;
7692
7713
  break;
7693
7714
  }
7694
7715
  case FocusAlignments.CENTER: {
7695
- pos = position - (viewportSize - elementSize) * .5 + scroller.startLayoutOffset;
7716
+ const p = position - (viewportSize - elementSize) * .5 + scroller.startLayoutOffset;
7717
+ pos = scroller.inverted ? (maxPosition - p) : p;
7696
7718
  break;
7697
7719
  }
7698
7720
  case FocusAlignments.END: {
7699
- pos = position - (viewportSize - elementSize) + scroller.startLayoutOffset;
7721
+ const p = position - (viewportSize - elementSize) + scroller.startLayoutOffset;
7722
+ pos = scroller.inverted ? (maxPosition - p) : p;
7700
7723
  break;
7701
7724
  }
7702
7725
  case FocusAlignments.NONE:
@@ -7802,10 +7825,9 @@ class NgVirtualListComponent {
7802
7825
  this.onSnapItem.emit(id);
7803
7826
  })).subscribe();
7804
7827
  this._service.$tick.pipe(takeUntilDestroyed(), tap(() => {
7805
- this._scrollerComponent()?.tick();
7806
- })).subscribe();
7807
- this._service.$tick.pipe(takeUntilDestroyed(), filter$1(() => this.dynamicSize() === true), tap(() => {
7808
- this.checkBoundsOfElements();
7828
+ if (this.dynamicSize() === true) {
7829
+ this.checkBoundsOfElements();
7830
+ }
7809
7831
  this._scrollerComponent()?.tick();
7810
7832
  })).subscribe();
7811
7833
  const $scrollerComponent = toObservable(this._scrollerComponent), $resizeViewport = $scrollerComponent.pipe(takeUntilDestroyed(), filter$1(v => !!v), switchMap$1(scroller => scroller.$resizeViewport)), $resizeContent = $scrollerComponent.pipe(takeUntilDestroyed(), filter$1(v => !!v), switchMap$1(scroller => scroller.$resizeContent));
@@ -8187,7 +8209,12 @@ class NgVirtualListComponent {
8187
8209
  return isSpreadingMode(spreadingMode, SpreadingModes.INFINITY) ? false : scrollbarEnabled;
8188
8210
  }, /* @ts-ignore */
8189
8211
  ...(ngDevMode ? [{ debugName: "_actualScrollbarEnabled" }] : /* istanbul ignore next */ []));
8190
- const $alignment = toObservable(this._actualAlignment), $precalculatedScrollStartOffset = toObservable(this._precalculatedScrollStartOffset), $precalculatedScrollEndOffset = toObservable(this._precalculatedScrollEndOffset), $listBounds = toObservable(this._listBounds).pipe(filter$1(b => !!b)), $scrollSize = this._$scrollSize.asObservable(), $bufferSize = toObservable(this.bufferSize).pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $maxBufferSize = toObservable(this.maxBufferSize).pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $snapToItem = toObservable(this.snapToItem), $snapToItemAlign = toObservable(this.snapToItemAlign), $stickyEnabled = toObservable(this.stickyEnabled), $isLazy = toObservable(this.collectionMode).pipe(map(v => this.getIsLazy(v || DEFAULT_COLLECTION_MODE))), $enabledBufferOptimization = toObservable(this.enabledBufferOptimization), $snappingMethod = toObservable(this.snappingMethod).pipe(map(v => this.getIsSnappingMethodAdvanced(v || DEFAULT_SNAPPING_METHOD))), $collapsingMode = toObservable(this.collapsingMode), $selectingMode = toObservable(this.selectingMode), $selectedIds = toObservable(this.selectedIds), $collapsedIds = toObservable(this.collapsedIds).pipe(distinctUntilChanged(), map(v => Array.isArray(v) ? v : [])), $collapsedItemIds = toObservable(this._collapsedItemIds).pipe(distinctUntilChanged(), map(v => Array.isArray(v) ? v : [])), $itemTransform = toObservable(this.itemTransform), $screenReaderMessage = toObservable(this.screenReaderMessage), $displayItems = this._service.$displayItems, $cacheVersion = this._service.$cacheVersion;
8212
+ const $alignment = toObservable(this._actualAlignment), $precalculatedScrollStartOffset = toObservable(this._precalculatedScrollStartOffset), $precalculatedScrollEndOffset = toObservable(this._precalculatedScrollEndOffset), $listBounds = toObservable(this._listBounds).pipe(filter$1(b => !!b)), $scrollSize = this._$scrollSize.asObservable(), $bufferSize = toObservable(this.bufferSize).pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $maxBufferSize = toObservable(this.maxBufferSize).pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $snapToItem = toObservable(this.snapToItem), $snapToItemAlign = toObservable(this.snapToItemAlign), $stickyEnabled = toObservable(this.stickyEnabled), $isLazy = toObservable(this.collectionMode).pipe(map(v => this.getIsLazy(v || DEFAULT_COLLECTION_MODE))), $enabledBufferOptimization = toObservable(this.enabledBufferOptimization), $snappingMethod = toObservable(this.snappingMethod).pipe(map(v => this.getIsSnappingMethodAdvanced(v || DEFAULT_SNAPPING_METHOD))), $collapsingMode = toObservable(this.collapsingMode), $selectingMode = toObservable(this.selectingMode), $selectedIds = toObservable(this.selectedIds), $collapsedIds = toObservable(this.collapsedIds).pipe(distinctUntilChanged(), map(v => Array.isArray(v) ? v : [])), $collapsedItemIds = toObservable(this._collapsedItemIds).pipe(distinctUntilChanged(), map(v => Array.isArray(v) ? v : [])), $langTextDir = toObservable(this.langTextDir), $itemTransform = toObservable(this.itemTransform), $screenReaderMessage = toObservable(this.screenReaderMessage), $displayItems = this._service.$displayItems, $cacheVersion = this._service.$cacheVersion;
8213
+ combineLatest([$isVertical, $langTextDir, $itemTransform]).pipe(takeUntilDestroyed(), debounceTime(0), tap(([isVertical, langTextDir, itemTransform]) => {
8214
+ if (langTextDir === TextDirections.RTL && !isVertical && itemTransform) {
8215
+ throw Error('Currently, converting right-to-left items in horizontal lists is not possible.');
8216
+ }
8217
+ })).subscribe();
8191
8218
  $snapToItem.pipe(takeUntilDestroyed(), tap(v => {
8192
8219
  this._service.snapToItem = v;
8193
8220
  })).subscribe();
@@ -8248,6 +8275,9 @@ class NgVirtualListComponent {
8248
8275
  actualItems.push(item);
8249
8276
  }
8250
8277
  const normalizedCollection = normalizeCollection(actualItems, itemConfigMap, trackBy, divides);
8278
+ if (this._scrollerComponent()?.inverted) {
8279
+ normalizedCollection.reverse();
8280
+ }
8251
8281
  this._actualItems.set(normalizedCollection);
8252
8282
  })).subscribe();
8253
8283
  $isVertical.pipe(takeUntilDestroyed(), tap(v => {
@@ -8369,20 +8399,21 @@ class NgVirtualListComponent {
8369
8399
  if (!!scroller) {
8370
8400
  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;
8371
8401
  if (this._readyForShow || (cachable && cached)) {
8372
- const currentScrollSize = (isVertical ? scroller.scrollTop : scroller.scrollLeft);
8373
- let actualScrollSize = !this._readyForShow && snapScrollToEnd ? (isVertical ? scroller.scrollHeight : scroller.scrollWidth) :
8402
+ const inverted = scroller.inverted, currentScrollSize = (isVertical ? scroller.scrollTop : scroller.scrollLeft), maxScrollSize = (isVertical ? scroller.scrollHeight : scroller.scrollWidth);
8403
+ let actualScrollSize = !this._readyForShow && snapScrollToEnd ? maxScrollSize :
8374
8404
  (isVertical ? scroller.scrollTop : scroller.scrollLeft), leftLayoutOffset = 0, displayItems;
8375
- const { width, height } = bounds, viewportSize = (isVertical ? height : width), opts = {
8405
+ const { width, height } = bounds, opts = {
8376
8406
  alignment, bounds: { width, height }, dynamicSize, isVertical, itemSize, minItemSize, maxItemSize, bufferSize, maxBufferSize,
8377
- scrollSize: actualScrollSize, stickyEnabled, enabledBufferOptimization, snapToItem, snapToItemAlign, itemTransform,
8407
+ scrollSize: inverted ? maxScrollSize - actualScrollSize : actualScrollSize, stickyEnabled, enabledBufferOptimization,
8408
+ snapToItem, snapToItemAlign, inverted, itemTransform,
8378
8409
  };
8379
8410
  if (snapScrollToEnd && !this._readyForShow) {
8380
- const { displayItems: calculatedDisplayItems, totalSize: calculatedTotalSize1, leftLayoutOffset: leftLayoutOffset1 } = this._trackBox.updateCollection(items, itemConfigMap, { ...opts, scrollSize: actualScrollSize });
8411
+ const { displayItems: calculatedDisplayItems, totalSize: calculatedTotalSize1, leftLayoutOffset: leftLayoutOffset1 } = this._trackBox.updateCollection(items, itemConfigMap, { ...opts, scrollSize: inverted ? maxScrollSize - actualScrollSize : actualScrollSize });
8381
8412
  displayItems = calculatedDisplayItems;
8382
8413
  totalSize = calculatedTotalSize1;
8383
8414
  leftLayoutOffset = leftLayoutOffset1;
8384
8415
  if (!!itemTransform && dynamicSize && this._trackBox.delta !== 0) {
8385
- const { displayItems: calculatedDisplayItems, totalSize: calculatedTotalSize1, leftLayoutOffset: leftLayoutOffset1 } = this._trackBox.updateCollection(items, itemConfigMap, { ...opts, scrollSize: actualScrollSize + this._trackBox.delta });
8416
+ const { displayItems: calculatedDisplayItems, totalSize: calculatedTotalSize1, leftLayoutOffset: leftLayoutOffset1 } = this._trackBox.updateCollection(items, itemConfigMap, { ...opts, scrollSize: inverted ? (maxScrollSize - actualScrollSize + this._trackBox.delta) : (actualScrollSize + this._trackBox.delta) });
8386
8417
  displayItems = calculatedDisplayItems;
8387
8418
  totalSize = calculatedTotalSize1;
8388
8419
  leftLayoutOffset = leftLayoutOffset1;
@@ -8394,7 +8425,7 @@ class NgVirtualListComponent {
8394
8425
  totalSize = calculatedTotalSize;
8395
8426
  leftLayoutOffset = leftLayoutOffset1;
8396
8427
  if (!!itemTransform && dynamicSize && this._trackBox.delta !== 0) {
8397
- const { displayItems: calculatedDisplayItems, totalSize: calculatedTotalSize, leftLayoutOffset: leftLayoutOffset1 } = this._trackBox.updateCollection(items, itemConfigMap, { ...opts, scrollSize: actualScrollSize + this._trackBox.delta });
8428
+ const { displayItems: calculatedDisplayItems, totalSize: calculatedTotalSize, leftLayoutOffset: leftLayoutOffset1 } = this._trackBox.updateCollection(items, itemConfigMap, { ...opts, scrollSize: inverted ? (maxScrollSize - actualScrollSize + this._trackBox.delta) : (actualScrollSize + this._trackBox.delta) });
8398
8429
  displayItems = calculatedDisplayItems;
8399
8430
  totalSize = calculatedTotalSize;
8400
8431
  leftLayoutOffset = leftLayoutOffset1;
@@ -8418,18 +8449,48 @@ class NgVirtualListComponent {
8418
8449
  this.updateOffsetsByAllignment();
8419
8450
  scroller.delta = delta;
8420
8451
  prevScrollable = scroller.scrollable;
8421
- if ((snapScrollToStart && this._trackBox.isSnappedToStart && scroller.scrollable) ||
8422
- (snapScrollToStart && currentScrollSize <= MIN_PIXELS_FOR_PREVENT_SNAPPING)) {
8423
- if (currentScrollSize !== roundedScrollPositionAfterUpdate) {
8452
+ if (!scroller.grabbing()) {
8453
+ if ((snapScrollToStart && this._trackBox.isSnappedToStart && scroller.scrollable) ||
8454
+ (snapScrollToStart && currentScrollSize <= MIN_PIXELS_FOR_PREVENT_SNAPPING)) {
8455
+ if (currentScrollSize !== roundedScrollPositionAfterUpdate) {
8456
+ this._trackBox.clearDelta();
8457
+ if (this._readyForShow) {
8458
+ this.emitScrollEvent(true, false, userAction);
8459
+ }
8460
+ this._trackBox.isScrollEnd;
8461
+ const params = {
8462
+ [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: 0, userAction,
8463
+ fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams().scrollToItem > 0 && this.scrollBehavior() !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT),
8464
+ blending: useAnimations && scroller.hasAnimation(this._animationId), duration: this.animationParams().scrollToItem,
8465
+ };
8466
+ const animationId = scroller?.scrollTo?.(params);
8467
+ if (animationId > -1) {
8468
+ this._animationId = animationId;
8469
+ }
8470
+ else {
8471
+ scroller.stopAnimation(this._animationId);
8472
+ }
8473
+ if (emitUpdate) {
8474
+ this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
8475
+ }
8476
+ }
8477
+ return;
8478
+ }
8479
+ if ((snapScrollToEnd && this._trackBox.isSnappedToEnd) || (snapScrollToEnd && !scroller.scrollable) ||
8480
+ (scrollPositionAfterUpdate + MIN_PIXELS_FOR_PREVENT_SNAPPING >= roundedMaxPositionAfterUpdate) ||
8481
+ (roundedScrollPositionAfterUpdate >= scrollPositionAfterUpdate + MIN_PIXELS_FOR_PREVENT_SNAPPING)) {
8424
8482
  this._trackBox.clearDelta();
8483
+ if (!this._trackBox.isSnappedToEnd) {
8484
+ this._trackBox.isScrollEnd = true;
8485
+ this._trackBox.isScrollStart = false;
8486
+ }
8425
8487
  if (this._readyForShow) {
8426
- this.emitScrollEvent(true, false, userAction);
8488
+ this.emitScrollEvent(true, false, false);
8427
8489
  }
8428
- this._trackBox.isScrollEnd;
8429
8490
  const params = {
8430
- [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: 0, userAction,
8431
- fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams().scrollToItem > 0 && this.scrollBehavior() !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT),
8432
- blending: useAnimations && scroller.hasAnimation(this._animationId), duration: this.animationParams().scrollToItem,
8491
+ [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: roundedMaxPositionAfterUpdate,
8492
+ fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams().scrollToItem > 0 && this.scrollBehavior() !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT), userAction: false,
8493
+ blending: useAnimations && scroller.hasAnimation(this._animationId) || cacheChanged, duration: this.animationParams().scrollToItem,
8433
8494
  };
8434
8495
  const animationId = scroller?.scrollTo?.(params);
8435
8496
  if (animationId > -1) {
@@ -8441,36 +8502,8 @@ class NgVirtualListComponent {
8441
8502
  if (emitUpdate) {
8442
8503
  this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
8443
8504
  }
8505
+ return;
8444
8506
  }
8445
- return;
8446
- }
8447
- if ((snapScrollToEnd && this._trackBox.isSnappedToEnd) || (snapScrollToEnd && !scroller.scrollable) ||
8448
- (scrollPositionAfterUpdate + MIN_PIXELS_FOR_PREVENT_SNAPPING >= roundedMaxPositionAfterUpdate) ||
8449
- (roundedScrollPositionAfterUpdate >= scrollPositionAfterUpdate + MIN_PIXELS_FOR_PREVENT_SNAPPING)) {
8450
- this._trackBox.clearDelta();
8451
- if (!this._trackBox.isSnappedToEnd) {
8452
- this._trackBox.isScrollEnd = true;
8453
- this._trackBox.isScrollStart = false;
8454
- }
8455
- if (this._readyForShow) {
8456
- this.emitScrollEvent(true, false, false);
8457
- }
8458
- const params = {
8459
- [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: roundedMaxPositionAfterUpdate,
8460
- fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams().scrollToItem > 0 && this.scrollBehavior() !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT), userAction: false,
8461
- blending: useAnimations && scroller.hasAnimation(this._animationId) || cacheChanged, duration: this.animationParams().scrollToItem,
8462
- };
8463
- const animationId = scroller?.scrollTo?.(params);
8464
- if (animationId > -1) {
8465
- this._animationId = animationId;
8466
- }
8467
- else {
8468
- scroller.stopAnimation(this._animationId);
8469
- }
8470
- if (emitUpdate) {
8471
- this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
8472
- }
8473
- return;
8474
8507
  }
8475
8508
  if (scrollSize !== scrollPositionAfterUpdate &&
8476
8509
  ((scrollPositionAfterUpdate >= 0 && scrollPositionAfterUpdate < roundedMaxPositionAfterUpdate) ||
@@ -8502,11 +8535,11 @@ class NgVirtualListComponent {
8502
8535
  let prevItems = [];
8503
8536
  const debouncedUpdate = debounce(update, 0, MAX_NUMBERS_OF_SKIPS_FOR_QUALITY_OPTIMIZATION_LVL1);
8504
8537
  $viewInit.pipe(takeUntilDestroyed(), filter$1(v => !!v), switchMap$1(() => {
8505
- return combineLatest([$trackBy, $isInfinity, $snapScrollToStart, $snapScrollToEnd, $bounds, $listBounds, $scrollEndOffset, $actualItems, $itemConfigMap, $scrollSize,
8538
+ return combineLatest([$trackBy, $isInfinity, $snapScrollToStart, $snapScrollToEnd, $bounds, $listBounds, $actualItems, $itemConfigMap, $scrollSize,
8506
8539
  $actualItemSize, $actualMinItemSize, $actualMaxItemSize, $collapsedItemIds, $bufferSize, $maxBufferSize, $stickyEnabled, $isVertical,
8507
8540
  $dynamicSize, $divides, $snapToItem, $snapToItemAlign, $enabledBufferOptimization, $itemTransform, $alignment,
8508
8541
  $precalculatedScrollStartOffset, $precalculatedScrollEndOffset, $cacheVersion, this.$fireUpdate,
8509
- ]).pipe(takeUntilDestroyed(this._destroyRef), tap(([trackBy, isInfinity, snapScrollToStart, snapScrollToEnd, bounds, listBounds, scrollEndOffset, items, itemConfigMap, scrollSize, itemSize, minItemSize, maxItemSize, collapsedIds, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, divides, snapToItem, snapToItemAlign, enabledBufferOptimization, itemTransform, alignment, precalculatedScrollStartOffset, precalculatedScrollEndOffset, cacheVersion,]) => {
8542
+ ]).pipe(takeUntilDestroyed(this._destroyRef), tap(([trackBy, isInfinity, snapScrollToStart, snapScrollToEnd, bounds, listBounds, items, itemConfigMap, scrollSize, itemSize, minItemSize, maxItemSize, collapsedIds, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, divides, snapToItem, snapToItemAlign, enabledBufferOptimization, itemTransform, alignment, precalculatedScrollStartOffset, precalculatedScrollEndOffset, cacheVersion,]) => {
8510
8543
  let itemsChanged = false;
8511
8544
  if (prevItems !== items) {
8512
8545
  itemsChanged = true;
@@ -8517,7 +8550,7 @@ class NgVirtualListComponent {
8517
8550
  if (enabledOptimization) {
8518
8551
  if (useDebouncedUpdate) {
8519
8552
  debouncedUpdate.execute({
8520
- trackBy, isInfinity, snapScrollToStart, snapScrollToEnd, bounds, listBounds, scrollEndOffset, items, itemConfigMap, scrollSize, itemSize, minItemSize,
8553
+ trackBy, isInfinity, snapScrollToStart, snapScrollToEnd, bounds, listBounds, items, itemConfigMap, scrollSize, itemSize, minItemSize,
8521
8554
  maxItemSize, collapsedIds, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, divides, enabledBufferOptimization, itemTransform,
8522
8555
  snapToItem, snapToItemAlign, alignment, precalculatedScrollStartOffset, precalculatedScrollEndOffset, cacheVersion, userAction: hasUserAction,
8523
8556
  });
@@ -8527,7 +8560,7 @@ class NgVirtualListComponent {
8527
8560
  }
8528
8561
  if (!isScrolling) {
8529
8562
  update({
8530
- trackBy, isInfinity, snapScrollToStart, snapScrollToEnd, bounds, listBounds, scrollEndOffset, items, itemConfigMap, scrollSize, itemSize, minItemSize,
8563
+ trackBy, isInfinity, snapScrollToStart, snapScrollToEnd, bounds, listBounds, items, itemConfigMap, scrollSize, itemSize, minItemSize,
8531
8564
  maxItemSize, collapsedIds, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, divides, enabledBufferOptimization, itemTransform,
8532
8565
  snapToItem, snapToItemAlign, alignment, precalculatedScrollStartOffset, precalculatedScrollEndOffset, cacheVersion, userAction: hasUserAction,
8533
8566
  });
@@ -8610,23 +8643,23 @@ class NgVirtualListComponent {
8610
8643
  if (!!items && items.length) {
8611
8644
  const dynamicSize = this.dynamicSize(), itemSize = this._actualItemSize(), minItemSize = this._actualMinItemSize(), maxItemSize = this._actualMaxItemSize(), snapScrollToEnd = this.snapScrollToEnd();
8612
8645
  if (dynamicSize) {
8613
- const { width, height } = this._bounds() || { width: DEFAULT_LIST_SIZE, height: DEFAULT_LIST_SIZE }, itemConfigMap = this.itemConfigMap(), isVertical = this._isVertical, currentScrollSize = isVertical ? scrollerComponent.scrollTop : scrollerComponent.scrollLeft, opts = {
8614
- alignment: this.actualAlignment(),
8646
+ const { width, height } = this._bounds() || { 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 = {
8647
+ alignment: this.actualAlignment(), inverted,
8615
8648
  bounds: { width, height }, collection: items, dynamicSize, isVertical: this._isVertical, itemSize, minItemSize, maxItemSize,
8616
8649
  bufferSize: this.bufferSize(), maxBufferSize: this.maxBufferSize(), itemTransform: this.itemTransform(),
8617
- scrollSize: (isVertical ? scrollerComponent.scrollTop : scrollerComponent.scrollLeft),
8650
+ scrollSize: (inverted ? (maxScrollSize - currentScrollSize) : currentScrollSize),
8618
8651
  snapToItem: this.snapToItem(), snapToItemAlign: this.snapToItemAlign(),
8619
8652
  stickyEnabled: this.stickyEnabled(), fromItemId: id, enabledBufferOptimization: this.enabledBufferOptimization(),
8620
8653
  };
8621
8654
  let scrollSize = snapScrollToEnd && this._trackBox.isSnappedToEnd ?
8622
- (isVertical ? scrollerComponent.scrollHeight : scrollerComponent.scrollWidth) :
8655
+ maxScrollSize :
8623
8656
  this._trackBox.getItemPosition(id, itemConfigMap, opts);
8624
8657
  if (scrollSize === -1) {
8625
8658
  return of([finished, { id, blending, iteration: nextIteration, cb }]).pipe(delay(0));
8626
8659
  }
8627
8660
  this._trackBox.clearDelta();
8628
8661
  const viewportSize = (isVertical ? height : width), { displayItems, totalSize, leftLayoutOffset } = this._trackBox.updateCollection(items, itemConfigMap, {
8629
- ...opts, scrollSize, fromItemId: isLastIteration ? undefined : id,
8662
+ ...opts, scrollSize: (inverted ? (maxScrollSize - scrollSize) : scrollSize), fromItemId: isLastIteration ? undefined : id,
8630
8663
  }), delta1 = this._trackBox.delta;
8631
8664
  const normalizedTotalSize = totalSize < viewportSize ? viewportSize : totalSize;
8632
8665
  scrollerComponent.startLayoutOffset = leftLayoutOffset;
@@ -8638,7 +8671,7 @@ class NgVirtualListComponent {
8638
8671
  this.tracking();
8639
8672
  this.snappingHandler();
8640
8673
  this.updateOffsetsByAllignment();
8641
- scrollSize = this._trackBox.getItemPosition(id, itemConfigMap, { ...opts, scrollSize: actualScrollSize, fromItemId: id });
8674
+ scrollSize = this._trackBox.getItemPosition(id, itemConfigMap, { ...opts, scrollSize: (inverted ? (maxScrollSize - actualScrollSize) : actualScrollSize), fromItemId: id });
8642
8675
  if (scrollSize === -1) {
8643
8676
  return of([finished, { id, blending, iteration: nextIteration, cb }]).pipe(delay(0));
8644
8677
  }
@@ -8675,17 +8708,18 @@ class NgVirtualListComponent {
8675
8708
  }
8676
8709
  }
8677
8710
  }
8678
- const { width, height } = this._bounds() || { width: DEFAULT_LIST_SIZE, height: DEFAULT_LIST_SIZE }, itemConfigMap = this.itemConfigMap(), items = this._actualItems(), opts = {
8679
- alignment: this._actualAlignment(),
8711
+ const { width, height } = this._bounds() || { width: DEFAULT_LIST_SIZE, height: DEFAULT_LIST_SIZE }, itemConfigMap = this.itemConfigMap(), items = this._actualItems(), inverted = scrollerComponent.inverted, maxScrollSize = (isVertical ? scrollerComponent.scrollHeight : scrollerComponent.scrollWidth), actualScrollSize = (isVertical ? scrollerComponent.scrollTop : scrollerComponent.scrollLeft), opts = {
8712
+ alignment: this._actualAlignment(), inverted,
8680
8713
  bounds: { width, height }, collection: items, dynamicSize, isVertical: this._isVertical, itemSize, minItemSize, maxItemSize,
8681
8714
  bufferSize: this.bufferSize(), maxBufferSize: this.maxBufferSize(), itemTransform: this.itemTransform(),
8682
- scrollSize: (isVertical ? scrollerComponent.scrollTop : scrollerComponent.scrollLeft),
8715
+ scrollSize: (inverted ? (maxScrollSize - actualScrollSize) : actualScrollSize),
8683
8716
  snapToItem, snapToItemAlign, stickyEnabled: this.stickyEnabled(), fromItemId: id,
8684
8717
  enabledBufferOptimization: this.enabledBufferOptimization(),
8685
8718
  };
8686
8719
  this._trackBox.clearDelta();
8687
8720
  const viewportSize = (isVertical ? height : width), { displayItems, totalSize, leftLayoutOffset } = this._trackBox.updateCollection(items, itemConfigMap, {
8688
- ...opts, scrollSize, fromItemId: isLastIteration ? undefined : id,
8721
+ ...opts, scrollSize: (inverted ? (maxScrollSize - scrollSize) : scrollSize),
8722
+ fromItemId: isLastIteration ? undefined : id,
8689
8723
  });
8690
8724
  const actualTotalSize = this._isInfinity() ? (totalSize + viewportSize) : totalSize;
8691
8725
  const normalizedTotalSize = actualTotalSize < viewportSize ? viewportSize : actualTotalSize;
@@ -9206,13 +9240,13 @@ class NgVirtualListComponent {
9206
9240
  }
9207
9241
  }
9208
9242
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: NgVirtualListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9209
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.0", type: NgVirtualListComponent, isStandalone: false, selector: "ng-virtual-list", inputs: { scrollbarThickness: { classPropertyName: "scrollbarThickness", publicName: "scrollbarThickness", isSignal: true, isRequired: false, transformFunction: null }, scrollbarMinSize: { classPropertyName: "scrollbarMinSize", publicName: "scrollbarMinSize", isSignal: true, isRequired: false, transformFunction: null }, scrollbarThumbRenderer: { classPropertyName: "scrollbarThumbRenderer", publicName: "scrollbarThumbRenderer", isSignal: true, isRequired: false, transformFunction: null }, scrollbarThumbParams: { classPropertyName: "scrollbarThumbParams", publicName: "scrollbarThumbParams", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, waitForPreparation: { classPropertyName: "waitForPreparation", publicName: "waitForPreparation", isSignal: true, isRequired: false, transformFunction: null }, clickDistance: { classPropertyName: "clickDistance", publicName: "clickDistance", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, defaultItemValue: { classPropertyName: "defaultItemValue", publicName: "defaultItemValue", isSignal: true, isRequired: false, transformFunction: null }, selectedIds: { classPropertyName: "selectedIds", publicName: "selectedIds", isSignal: true, isRequired: false, transformFunction: null }, collapsedIds: { classPropertyName: "collapsedIds", publicName: "collapsedIds", isSignal: true, isRequired: false, transformFunction: null }, selectByClick: { classPropertyName: "selectByClick", publicName: "selectByClick", isSignal: true, isRequired: false, transformFunction: null }, collapseByClick: { classPropertyName: "collapseByClick", publicName: "collapseByClick", isSignal: true, isRequired: false, transformFunction: null }, snap: { classPropertyName: "snap", publicName: "snap", isSignal: true, isRequired: false, transformFunction: null }, stickyEnabled: { classPropertyName: "stickyEnabled", publicName: "stickyEnabled", isSignal: true, isRequired: false, transformFunction: null }, snapToEndTransitionInstantOffset: { classPropertyName: "snapToEndTransitionInstantOffset", publicName: "snapToEndTransitionInstantOffset", isSignal: true, isRequired: false, transformFunction: null }, scrollStartOffset: { classPropertyName: "scrollStartOffset", publicName: "scrollStartOffset", isSignal: true, isRequired: false, transformFunction: null }, scrollEndOffset: { classPropertyName: "scrollEndOffset", publicName: "scrollEndOffset", isSignal: true, isRequired: false, transformFunction: null }, snapScrollToStart: { classPropertyName: "snapScrollToStart", publicName: "snapScrollToStart", isSignal: true, isRequired: false, transformFunction: null }, snapScrollToEnd: { classPropertyName: "snapScrollToEnd", publicName: "snapScrollToEnd", isSignal: true, isRequired: false, transformFunction: null }, snapScrollToBottom: { classPropertyName: "snapScrollToBottom", publicName: "snapScrollToBottom", isSignal: true, isRequired: false, transformFunction: null }, scrollbarEnabled: { classPropertyName: "scrollbarEnabled", publicName: "scrollbarEnabled", isSignal: true, isRequired: false, transformFunction: null }, scrollbarInteractive: { classPropertyName: "scrollbarInteractive", publicName: "scrollbarInteractive", isSignal: true, isRequired: false, transformFunction: null }, overlappingScrollbar: { classPropertyName: "overlappingScrollbar", publicName: "overlappingScrollbar", isSignal: true, isRequired: false, transformFunction: null }, scrollBehavior: { classPropertyName: "scrollBehavior", publicName: "scrollBehavior", isSignal: true, isRequired: false, transformFunction: null }, scrollingSettings: { classPropertyName: "scrollingSettings", publicName: "scrollingSettings", isSignal: true, isRequired: false, transformFunction: null }, itemTransform: { classPropertyName: "itemTransform", publicName: "itemTransform", isSignal: true, isRequired: false, transformFunction: null }, snapToItem: { classPropertyName: "snapToItem", publicName: "snapToItem", isSignal: true, isRequired: false, transformFunction: null }, snapToItemAlign: { classPropertyName: "snapToItemAlign", publicName: "snapToItemAlign", isSignal: true, isRequired: false, transformFunction: null }, snappingDistance: { classPropertyName: "snappingDistance", publicName: "snappingDistance", isSignal: true, isRequired: false, transformFunction: null }, scrollingOneByOne: { classPropertyName: "scrollingOneByOne", publicName: "scrollingOneByOne", isSignal: true, isRequired: false, transformFunction: null }, alignment: { classPropertyName: "alignment", publicName: "alignment", isSignal: true, isRequired: false, transformFunction: null }, zIndexWhenSelecting: { classPropertyName: "zIndexWhenSelecting", publicName: "zIndexWhenSelecting", isSignal: true, isRequired: false, transformFunction: null }, spreadingMode: { classPropertyName: "spreadingMode", publicName: "spreadingMode", isSignal: true, isRequired: false, transformFunction: null }, divides: { classPropertyName: "divides", publicName: "divides", isSignal: true, isRequired: false, transformFunction: null }, motionBlur: { classPropertyName: "motionBlur", publicName: "motionBlur", isSignal: true, isRequired: false, transformFunction: null }, maxMotionBlur: { classPropertyName: "maxMotionBlur", publicName: "maxMotionBlur", isSignal: true, isRequired: false, transformFunction: null }, motionBlurEnabled: { classPropertyName: "motionBlurEnabled", publicName: "motionBlurEnabled", isSignal: true, isRequired: false, transformFunction: null }, animationParams: { classPropertyName: "animationParams", publicName: "animationParams", isSignal: true, isRequired: false, transformFunction: null }, overscrollEnabled: { classPropertyName: "overscrollEnabled", publicName: "overscrollEnabled", isSignal: true, isRequired: false, transformFunction: null }, enabledBufferOptimization: { classPropertyName: "enabledBufferOptimization", publicName: "enabledBufferOptimization", isSignal: true, isRequired: false, transformFunction: null }, itemRenderer: { classPropertyName: "itemRenderer", publicName: "itemRenderer", isSignal: true, isRequired: true, transformFunction: null }, itemConfigMap: { classPropertyName: "itemConfigMap", publicName: "itemConfigMap", isSignal: true, isRequired: false, transformFunction: null }, itemSize: { classPropertyName: "itemSize", publicName: "itemSize", isSignal: true, isRequired: false, transformFunction: null }, minItemSize: { classPropertyName: "minItemSize", publicName: "minItemSize", isSignal: true, isRequired: false, transformFunction: null }, maxItemSize: { classPropertyName: "maxItemSize", publicName: "maxItemSize", isSignal: true, isRequired: false, transformFunction: null }, dynamicSize: { classPropertyName: "dynamicSize", publicName: "dynamicSize", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, collectionMode: { classPropertyName: "collectionMode", publicName: "collectionMode", isSignal: true, isRequired: false, transformFunction: null }, bufferSize: { classPropertyName: "bufferSize", publicName: "bufferSize", isSignal: true, isRequired: false, transformFunction: null }, maxBufferSize: { classPropertyName: "maxBufferSize", publicName: "maxBufferSize", isSignal: true, isRequired: false, transformFunction: null }, snappingMethod: { classPropertyName: "snappingMethod", publicName: "snappingMethod", isSignal: true, isRequired: false, transformFunction: null }, collapsingMode: { classPropertyName: "collapsingMode", publicName: "collapsingMode", isSignal: true, isRequired: false, transformFunction: null }, methodForSelecting: { classPropertyName: "methodForSelecting", publicName: "methodForSelecting", isSignal: true, isRequired: false, transformFunction: null }, selectingMode: { classPropertyName: "selectingMode", publicName: "selectingMode", isSignal: true, isRequired: false, transformFunction: null }, trackBy: { classPropertyName: "trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null }, screenReaderMessage: { classPropertyName: "screenReaderMessage", publicName: "screenReaderMessage", isSignal: true, isRequired: false, transformFunction: null }, langTextDir: { classPropertyName: "langTextDir", publicName: "langTextDir", isSignal: true, isRequired: false, transformFunction: null } }, 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, isSignal: true }, { propertyName: "_scrollerComponent", first: true, predicate: ["scroller"], descendants: true, isSignal: true }, { propertyName: "_listContainerRef", first: true, predicate: ["renderersContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_snapContainerRef", first: true, predicate: ["snapRendererContainer"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "@let scrollStartOffset = _actualScrollStartOffset();\r\n@let scrollEndOffset = _actualScrollEndOffset();\r\n@let alignmentScrollStartOffset = _alignmentScrollStartOffset();\r\n@let alignmentScrollEndOffset = _alignmentScrollEndOffset();\r\n\r\n<div aria-live=\"polite\" aria-atomic=\"true\" class=\"ngvl__screen-reader\">\r\n {{ screenReaderFormattedMessage() }}\r\n</div>\r\n\r\n<ng-prerender-container #prerender [bounds]=\"bounds()!\" [direction]=\"direction()\" [dynamic]=\"dynamicSize()\"\r\n [divides]=\"divides()\" [isVertical]=\"isVertical\" [itemSize]=\"actualItemSize()\" [trackBy]=\"trackBy()\"\r\n [itemRenderer]=\"itemRenderer()\" [startOffset]=\"scrollStartOffset\" [endOffset]=\"scrollEndOffset\"\r\n [scrollbarEnabled]=\"scroller.scrollbarShow()\" [enabled]=\"dynamicSize() && snapScrollToEnd()\" />\r\n\r\n@if (stickyEnabled()) {\r\n <div localeSensitive [langTextDir]=\"langTextDir()\" #snappedContainer class=\"ngvl__snapped-container\"\r\n [ngClass]=\"classes()\">\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}\r\n\r\n<ng-scroller #scroller class=\"ngvl__list-scroller\" [classes]=\"classes()\" [startOffset]=\"scrollStartOffset\"\r\n [endOffset]=\"scrollEndOffset\" [alignmentStartOffset]=\"alignmentScrollStartOffset\" [alignmentEndOffset]=\"alignmentScrollEndOffset\"\r\n [direction]=\"direction()\" [scrollbarThumbRenderer]=\"scrollbarThumbRenderer()\" [isInfinity]=\"_isInfinity()\"\r\n [scrollbarThickness]=\"scrollbarThickness()\" [scrollbarThumbParams]=\"scrollbarThumbParams()\"\r\n [animationParams]=\"animationParams()\" [focusedElement]=\"focusedElement()\" [loading]=\"loading()\"\r\n [overscrollEnabled]=\"overscrollEnabled()\" [snappingDistance]=\"snappingDistance()\" [overlappingScrollbar]=\"overlappingScrollbar()\"\r\n [scrollbarEnabled]=\"_actualScrollbarEnabled()\" [scrollbarInteractive]=\"scrollbarInteractive()\" [snapToItem]=\"snapToItem()\"\r\n [snapToItemAlign]=\"snapToItemAlign()\" [scrollbarMinSize]=\"scrollbarMinSize()\" [scrollBehavior]=\"scrollBehavior()\"\r\n [scrollingSettings]=\"scrollingSettings()\" [scrollingOneByOne]=\"scrollingOneByOne()\" [motionBlur]=\"motionBlur()\"\r\n [maxMotionBlur]=\"maxMotionBlur()\" [motionBlurEnabled]=\"motionBlurEnabled()\">\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: "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", "itemRenderer"] }, { kind: "directive", type: LocaleSensitiveDirective, selector: "[localeSensitive]", inputs: ["langTextDir", "listDir"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
9243
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.0", type: NgVirtualListComponent, isStandalone: false, selector: "ng-virtual-list", inputs: { scrollbarThickness: { classPropertyName: "scrollbarThickness", publicName: "scrollbarThickness", isSignal: true, isRequired: false, transformFunction: null }, scrollbarMinSize: { classPropertyName: "scrollbarMinSize", publicName: "scrollbarMinSize", isSignal: true, isRequired: false, transformFunction: null }, scrollbarThumbRenderer: { classPropertyName: "scrollbarThumbRenderer", publicName: "scrollbarThumbRenderer", isSignal: true, isRequired: false, transformFunction: null }, scrollbarThumbParams: { classPropertyName: "scrollbarThumbParams", publicName: "scrollbarThumbParams", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, waitForPreparation: { classPropertyName: "waitForPreparation", publicName: "waitForPreparation", isSignal: true, isRequired: false, transformFunction: null }, clickDistance: { classPropertyName: "clickDistance", publicName: "clickDistance", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, defaultItemValue: { classPropertyName: "defaultItemValue", publicName: "defaultItemValue", isSignal: true, isRequired: false, transformFunction: null }, selectedIds: { classPropertyName: "selectedIds", publicName: "selectedIds", isSignal: true, isRequired: false, transformFunction: null }, collapsedIds: { classPropertyName: "collapsedIds", publicName: "collapsedIds", isSignal: true, isRequired: false, transformFunction: null }, selectByClick: { classPropertyName: "selectByClick", publicName: "selectByClick", isSignal: true, isRequired: false, transformFunction: null }, collapseByClick: { classPropertyName: "collapseByClick", publicName: "collapseByClick", isSignal: true, isRequired: false, transformFunction: null }, snap: { classPropertyName: "snap", publicName: "snap", isSignal: true, isRequired: false, transformFunction: null }, stickyEnabled: { classPropertyName: "stickyEnabled", publicName: "stickyEnabled", isSignal: true, isRequired: false, transformFunction: null }, snapToEndTransitionInstantOffset: { classPropertyName: "snapToEndTransitionInstantOffset", publicName: "snapToEndTransitionInstantOffset", isSignal: true, isRequired: false, transformFunction: null }, scrollStartOffset: { classPropertyName: "scrollStartOffset", publicName: "scrollStartOffset", isSignal: true, isRequired: false, transformFunction: null }, scrollEndOffset: { classPropertyName: "scrollEndOffset", publicName: "scrollEndOffset", isSignal: true, isRequired: false, transformFunction: null }, snapScrollToStart: { classPropertyName: "snapScrollToStart", publicName: "snapScrollToStart", isSignal: true, isRequired: false, transformFunction: null }, snapScrollToEnd: { classPropertyName: "snapScrollToEnd", publicName: "snapScrollToEnd", isSignal: true, isRequired: false, transformFunction: null }, snapScrollToBottom: { classPropertyName: "snapScrollToBottom", publicName: "snapScrollToBottom", isSignal: true, isRequired: false, transformFunction: null }, scrollbarEnabled: { classPropertyName: "scrollbarEnabled", publicName: "scrollbarEnabled", isSignal: true, isRequired: false, transformFunction: null }, scrollbarInteractive: { classPropertyName: "scrollbarInteractive", publicName: "scrollbarInteractive", isSignal: true, isRequired: false, transformFunction: null }, overlappingScrollbar: { classPropertyName: "overlappingScrollbar", publicName: "overlappingScrollbar", isSignal: true, isRequired: false, transformFunction: null }, scrollBehavior: { classPropertyName: "scrollBehavior", publicName: "scrollBehavior", isSignal: true, isRequired: false, transformFunction: null }, scrollingSettings: { classPropertyName: "scrollingSettings", publicName: "scrollingSettings", isSignal: true, isRequired: false, transformFunction: null }, itemTransform: { classPropertyName: "itemTransform", publicName: "itemTransform", isSignal: true, isRequired: false, transformFunction: null }, snapToItem: { classPropertyName: "snapToItem", publicName: "snapToItem", isSignal: true, isRequired: false, transformFunction: null }, snapToItemAlign: { classPropertyName: "snapToItemAlign", publicName: "snapToItemAlign", isSignal: true, isRequired: false, transformFunction: null }, snappingDistance: { classPropertyName: "snappingDistance", publicName: "snappingDistance", isSignal: true, isRequired: false, transformFunction: null }, scrollingOneByOne: { classPropertyName: "scrollingOneByOne", publicName: "scrollingOneByOne", isSignal: true, isRequired: false, transformFunction: null }, alignment: { classPropertyName: "alignment", publicName: "alignment", isSignal: true, isRequired: false, transformFunction: null }, zIndexWhenSelecting: { classPropertyName: "zIndexWhenSelecting", publicName: "zIndexWhenSelecting", isSignal: true, isRequired: false, transformFunction: null }, spreadingMode: { classPropertyName: "spreadingMode", publicName: "spreadingMode", isSignal: true, isRequired: false, transformFunction: null }, divides: { classPropertyName: "divides", publicName: "divides", isSignal: true, isRequired: false, transformFunction: null }, motionBlur: { classPropertyName: "motionBlur", publicName: "motionBlur", isSignal: true, isRequired: false, transformFunction: null }, maxMotionBlur: { classPropertyName: "maxMotionBlur", publicName: "maxMotionBlur", isSignal: true, isRequired: false, transformFunction: null }, motionBlurEnabled: { classPropertyName: "motionBlurEnabled", publicName: "motionBlurEnabled", isSignal: true, isRequired: false, transformFunction: null }, animationParams: { classPropertyName: "animationParams", publicName: "animationParams", isSignal: true, isRequired: false, transformFunction: null }, overscrollEnabled: { classPropertyName: "overscrollEnabled", publicName: "overscrollEnabled", isSignal: true, isRequired: false, transformFunction: null }, enabledBufferOptimization: { classPropertyName: "enabledBufferOptimization", publicName: "enabledBufferOptimization", isSignal: true, isRequired: false, transformFunction: null }, itemRenderer: { classPropertyName: "itemRenderer", publicName: "itemRenderer", isSignal: true, isRequired: true, transformFunction: null }, itemConfigMap: { classPropertyName: "itemConfigMap", publicName: "itemConfigMap", isSignal: true, isRequired: false, transformFunction: null }, itemSize: { classPropertyName: "itemSize", publicName: "itemSize", isSignal: true, isRequired: false, transformFunction: null }, minItemSize: { classPropertyName: "minItemSize", publicName: "minItemSize", isSignal: true, isRequired: false, transformFunction: null }, maxItemSize: { classPropertyName: "maxItemSize", publicName: "maxItemSize", isSignal: true, isRequired: false, transformFunction: null }, dynamicSize: { classPropertyName: "dynamicSize", publicName: "dynamicSize", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, collectionMode: { classPropertyName: "collectionMode", publicName: "collectionMode", isSignal: true, isRequired: false, transformFunction: null }, bufferSize: { classPropertyName: "bufferSize", publicName: "bufferSize", isSignal: true, isRequired: false, transformFunction: null }, maxBufferSize: { classPropertyName: "maxBufferSize", publicName: "maxBufferSize", isSignal: true, isRequired: false, transformFunction: null }, snappingMethod: { classPropertyName: "snappingMethod", publicName: "snappingMethod", isSignal: true, isRequired: false, transformFunction: null }, collapsingMode: { classPropertyName: "collapsingMode", publicName: "collapsingMode", isSignal: true, isRequired: false, transformFunction: null }, methodForSelecting: { classPropertyName: "methodForSelecting", publicName: "methodForSelecting", isSignal: true, isRequired: false, transformFunction: null }, selectingMode: { classPropertyName: "selectingMode", publicName: "selectingMode", isSignal: true, isRequired: false, transformFunction: null }, trackBy: { classPropertyName: "trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null }, screenReaderMessage: { classPropertyName: "screenReaderMessage", publicName: "screenReaderMessage", isSignal: true, isRequired: false, transformFunction: null }, langTextDir: { classPropertyName: "langTextDir", publicName: "langTextDir", isSignal: true, isRequired: false, transformFunction: null } }, 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, isSignal: true }, { propertyName: "_scrollerComponent", first: true, predicate: ["scroller"], descendants: true, isSignal: true }, { propertyName: "_listContainerRef", first: true, predicate: ["renderersContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_snapContainerRef", first: true, predicate: ["snapRendererContainer"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "@let scrollStartOffset = _actualScrollStartOffset();\r\n@let scrollEndOffset = _actualScrollEndOffset();\r\n@let alignmentScrollStartOffset = _alignmentScrollStartOffset();\r\n@let alignmentScrollEndOffset = _alignmentScrollEndOffset();\r\n@let textDir = langTextDir();\r\n\r\n<div aria-live=\"polite\" aria-atomic=\"true\" class=\"ngvl__screen-reader\">\r\n {{ screenReaderFormattedMessage() }}\r\n</div>\r\n\r\n<ng-prerender-container #prerender [bounds]=\"bounds()!\" [direction]=\"direction()\" [dynamic]=\"dynamicSize()\"\r\n [divides]=\"divides()\" [isVertical]=\"isVertical\" [itemSize]=\"actualItemSize()\" [trackBy]=\"trackBy()\"\r\n [itemRenderer]=\"itemRenderer()\" [startOffset]=\"scrollStartOffset\" [endOffset]=\"scrollEndOffset\"\r\n [scrollbarEnabled]=\"scroller.scrollbarShow()\" [enabled]=\"dynamicSize() && snapScrollToEnd()\" />\r\n\r\n@if (stickyEnabled()) {\r\n <div localeSensitive [langTextDir]=\"textDir\" #snappedContainer class=\"ngvl__snapped-container\"\r\n [ngClass]=\"classes()\">\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}\r\n\r\n<ng-scroller #scroller class=\"ngvl__list-scroller\" [langTextDir]=\"textDir\" [classes]=\"classes()\" [startOffset]=\"scrollStartOffset\"\r\n [endOffset]=\"scrollEndOffset\" [alignmentStartOffset]=\"alignmentScrollStartOffset\" [alignmentEndOffset]=\"alignmentScrollEndOffset\"\r\n [direction]=\"direction()\" [scrollbarThumbRenderer]=\"scrollbarThumbRenderer()\" [isInfinity]=\"_isInfinity()\"\r\n [scrollbarThickness]=\"scrollbarThickness()\" [scrollbarThumbParams]=\"scrollbarThumbParams()\"\r\n [animationParams]=\"animationParams()\" [focusedElement]=\"focusedElement()\" [loading]=\"loading()\"\r\n [overscrollEnabled]=\"overscrollEnabled()\" [snappingDistance]=\"snappingDistance()\" [overlappingScrollbar]=\"overlappingScrollbar()\"\r\n [scrollbarEnabled]=\"_actualScrollbarEnabled()\" [scrollbarInteractive]=\"scrollbarInteractive()\" [snapToItem]=\"snapToItem()\"\r\n [snapToItemAlign]=\"snapToItemAlign()\" [scrollbarMinSize]=\"scrollbarMinSize()\" [scrollBehavior]=\"scrollBehavior()\"\r\n [scrollingSettings]=\"scrollingSettings()\" [scrollingOneByOne]=\"scrollingOneByOne()\" [motionBlur]=\"motionBlur()\"\r\n [maxMotionBlur]=\"maxMotionBlur()\" [motionBlurEnabled]=\"motionBlurEnabled()\">\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: "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", "itemRenderer"] }, { kind: "directive", type: LocaleSensitiveDirective, selector: "[localeSensitive]", inputs: ["langTextDir", "listDir"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
9210
9244
  }
9211
9245
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: NgVirtualListComponent, decorators: [{
9212
9246
  type: Component,
9213
9247
  args: [{ selector: 'ng-virtual-list', host: {
9214
9248
  'style': 'position: relative;'
9215
- }, standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, providers: [NgVirtualListService, NgVirtualListPublicService], template: "@let scrollStartOffset = _actualScrollStartOffset();\r\n@let scrollEndOffset = _actualScrollEndOffset();\r\n@let alignmentScrollStartOffset = _alignmentScrollStartOffset();\r\n@let alignmentScrollEndOffset = _alignmentScrollEndOffset();\r\n\r\n<div aria-live=\"polite\" aria-atomic=\"true\" class=\"ngvl__screen-reader\">\r\n {{ screenReaderFormattedMessage() }}\r\n</div>\r\n\r\n<ng-prerender-container #prerender [bounds]=\"bounds()!\" [direction]=\"direction()\" [dynamic]=\"dynamicSize()\"\r\n [divides]=\"divides()\" [isVertical]=\"isVertical\" [itemSize]=\"actualItemSize()\" [trackBy]=\"trackBy()\"\r\n [itemRenderer]=\"itemRenderer()\" [startOffset]=\"scrollStartOffset\" [endOffset]=\"scrollEndOffset\"\r\n [scrollbarEnabled]=\"scroller.scrollbarShow()\" [enabled]=\"dynamicSize() && snapScrollToEnd()\" />\r\n\r\n@if (stickyEnabled()) {\r\n <div localeSensitive [langTextDir]=\"langTextDir()\" #snappedContainer class=\"ngvl__snapped-container\"\r\n [ngClass]=\"classes()\">\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}\r\n\r\n<ng-scroller #scroller class=\"ngvl__list-scroller\" [classes]=\"classes()\" [startOffset]=\"scrollStartOffset\"\r\n [endOffset]=\"scrollEndOffset\" [alignmentStartOffset]=\"alignmentScrollStartOffset\" [alignmentEndOffset]=\"alignmentScrollEndOffset\"\r\n [direction]=\"direction()\" [scrollbarThumbRenderer]=\"scrollbarThumbRenderer()\" [isInfinity]=\"_isInfinity()\"\r\n [scrollbarThickness]=\"scrollbarThickness()\" [scrollbarThumbParams]=\"scrollbarThumbParams()\"\r\n [animationParams]=\"animationParams()\" [focusedElement]=\"focusedElement()\" [loading]=\"loading()\"\r\n [overscrollEnabled]=\"overscrollEnabled()\" [snappingDistance]=\"snappingDistance()\" [overlappingScrollbar]=\"overlappingScrollbar()\"\r\n [scrollbarEnabled]=\"_actualScrollbarEnabled()\" [scrollbarInteractive]=\"scrollbarInteractive()\" [snapToItem]=\"snapToItem()\"\r\n [snapToItemAlign]=\"snapToItemAlign()\" [scrollbarMinSize]=\"scrollbarMinSize()\" [scrollBehavior]=\"scrollBehavior()\"\r\n [scrollingSettings]=\"scrollingSettings()\" [scrollingOneByOne]=\"scrollingOneByOne()\" [motionBlur]=\"motionBlur()\"\r\n [maxMotionBlur]=\"maxMotionBlur()\" [motionBlurEnabled]=\"motionBlurEnabled()\">\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"] }]
9249
+ }, standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, providers: [NgVirtualListService, NgVirtualListPublicService], template: "@let scrollStartOffset = _actualScrollStartOffset();\r\n@let scrollEndOffset = _actualScrollEndOffset();\r\n@let alignmentScrollStartOffset = _alignmentScrollStartOffset();\r\n@let alignmentScrollEndOffset = _alignmentScrollEndOffset();\r\n@let textDir = langTextDir();\r\n\r\n<div aria-live=\"polite\" aria-atomic=\"true\" class=\"ngvl__screen-reader\">\r\n {{ screenReaderFormattedMessage() }}\r\n</div>\r\n\r\n<ng-prerender-container #prerender [bounds]=\"bounds()!\" [direction]=\"direction()\" [dynamic]=\"dynamicSize()\"\r\n [divides]=\"divides()\" [isVertical]=\"isVertical\" [itemSize]=\"actualItemSize()\" [trackBy]=\"trackBy()\"\r\n [itemRenderer]=\"itemRenderer()\" [startOffset]=\"scrollStartOffset\" [endOffset]=\"scrollEndOffset\"\r\n [scrollbarEnabled]=\"scroller.scrollbarShow()\" [enabled]=\"dynamicSize() && snapScrollToEnd()\" />\r\n\r\n@if (stickyEnabled()) {\r\n <div localeSensitive [langTextDir]=\"textDir\" #snappedContainer class=\"ngvl__snapped-container\"\r\n [ngClass]=\"classes()\">\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}\r\n\r\n<ng-scroller #scroller class=\"ngvl__list-scroller\" [langTextDir]=\"textDir\" [classes]=\"classes()\" [startOffset]=\"scrollStartOffset\"\r\n [endOffset]=\"scrollEndOffset\" [alignmentStartOffset]=\"alignmentScrollStartOffset\" [alignmentEndOffset]=\"alignmentScrollEndOffset\"\r\n [direction]=\"direction()\" [scrollbarThumbRenderer]=\"scrollbarThumbRenderer()\" [isInfinity]=\"_isInfinity()\"\r\n [scrollbarThickness]=\"scrollbarThickness()\" [scrollbarThumbParams]=\"scrollbarThumbParams()\"\r\n [animationParams]=\"animationParams()\" [focusedElement]=\"focusedElement()\" [loading]=\"loading()\"\r\n [overscrollEnabled]=\"overscrollEnabled()\" [snappingDistance]=\"snappingDistance()\" [overlappingScrollbar]=\"overlappingScrollbar()\"\r\n [scrollbarEnabled]=\"_actualScrollbarEnabled()\" [scrollbarInteractive]=\"scrollbarInteractive()\" [snapToItem]=\"snapToItem()\"\r\n [snapToItemAlign]=\"snapToItemAlign()\" [scrollbarMinSize]=\"scrollbarMinSize()\" [scrollBehavior]=\"scrollBehavior()\"\r\n [scrollingSettings]=\"scrollingSettings()\" [scrollingOneByOne]=\"scrollingOneByOne()\" [motionBlur]=\"motionBlur()\"\r\n [maxMotionBlur]=\"maxMotionBlur()\" [motionBlurEnabled]=\"motionBlurEnabled()\">\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"] }]
9216
9250
  }], ctorParameters: () => [], propDecorators: { _prerender: [{ type: i0.ViewChild, args: ['prerender', { isSignal: true }] }], _listContainerRef: [{
9217
9251
  type: ViewChild,
9218
9252
  args: ['renderersContainer', { read: ViewContainerRef }]