ng-virtual-list 21.12.3 → 21.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';
@@ -1818,7 +1818,7 @@ class ScrollEvent {
1818
1818
 
1819
1819
  /**
1820
1820
  * Event emitter
1821
- * @link https://github.com/DjonnyX/ng-virtual-list/blob/main/library/src/utils/event-emitter/event-emitter.ts
1821
+ * @link https://github.com/DjonnyX/ng-virtual-list/blob/21.x/projects/ng-virtual-list/src/lib/utils/event-emitter/event-emitter.ts
1822
1822
  * @author Evgenii Alexandrovich Grebennikov
1823
1823
  * @email djonnyx@gmail.com
1824
1824
  */
@@ -2728,7 +2728,7 @@ class TrackBox extends CacheMap {
2728
2728
  * Calculates list metrics
2729
2729
  */
2730
2730
  recalculateMetrics(options) {
2731
- 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);
2731
+ 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);
2732
2732
  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)
2733
2733
  || (typeof fromItemId === 'string' && fromItemId > '-1');
2734
2734
  let leftItemsOffset = 0, rightItemsOffset = 0;
@@ -3181,6 +3181,7 @@ class TrackBox extends CacheMap {
3181
3181
  rightItemLength,
3182
3182
  rightItemsWeight,
3183
3183
  scrollSize: actualScrollSize,
3184
+ maxScrollSize: totalSize,
3184
3185
  leftSizeOfAddedItems,
3185
3186
  sizeProperty,
3186
3187
  stickyEnabled,
@@ -3195,6 +3196,7 @@ class TrackBox extends CacheMap {
3195
3196
  isUpdating,
3196
3197
  snapToItem,
3197
3198
  snapToItemAlign,
3199
+ inverted,
3198
3200
  itemTransform,
3199
3201
  };
3200
3202
  return metrics;
@@ -3246,7 +3248,7 @@ class TrackBox extends CacheMap {
3246
3248
  return false;
3247
3249
  }
3248
3250
  generateDisplayCollection(items, actualItems, itemConfigMap, metrics) {
3249
- 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 = [];
3251
+ 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 = [];
3250
3252
  if (items.length) {
3251
3253
  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;
3252
3254
  let pos = startPosition, renderItems = renderItemsLength, stickyItem, nextSticky, stickyItemIndex = -1, nexstStickyItemIndex = -1, stickyItemSize = 0, endStickyItem, nextEndSticky, endStickyItemIndex = -1, endStickyItemSize = 0;
@@ -3286,6 +3288,7 @@ class TrackBox extends CacheMap {
3286
3288
  position: pos,
3287
3289
  boundsSize,
3288
3290
  scrollSize,
3291
+ maxScrollSize,
3289
3292
  absoluteStartPosition,
3290
3293
  absoluteStartPositionPercent,
3291
3294
  absoluteEndPosition,
@@ -3316,6 +3319,7 @@ class TrackBox extends CacheMap {
3316
3319
  tabIndex: i - layoutIndexOffset,
3317
3320
  divides,
3318
3321
  opacity: 1,
3322
+ inverted,
3319
3323
  zIndex: Z_INDEX_1,
3320
3324
  };
3321
3325
  const itemData = collectionItem;
@@ -3362,6 +3366,7 @@ class TrackBox extends CacheMap {
3362
3366
  position: pos,
3363
3367
  boundsSize,
3364
3368
  scrollSize,
3369
+ maxScrollSize,
3365
3370
  absoluteStartPosition,
3366
3371
  absoluteStartPositionPercent,
3367
3372
  absoluteEndPosition,
@@ -3398,6 +3403,7 @@ class TrackBox extends CacheMap {
3398
3403
  tabIndex: i - layoutIndexOffset,
3399
3404
  divides,
3400
3405
  opacity: 1,
3406
+ inverted,
3401
3407
  zIndex: Z_INDEX_1,
3402
3408
  };
3403
3409
  const itemData = collectionItem;
@@ -3458,6 +3464,7 @@ class TrackBox extends CacheMap {
3458
3464
  position: pos,
3459
3465
  boundsSize,
3460
3466
  scrollSize,
3467
+ maxScrollSize,
3461
3468
  absoluteStartPosition,
3462
3469
  absoluteStartPositionPercent,
3463
3470
  absoluteEndPosition,
@@ -3496,6 +3503,7 @@ class TrackBox extends CacheMap {
3496
3503
  opacity: 1,
3497
3504
  zIndex: Z_INDEX_0,
3498
3505
  fullSize,
3506
+ inverted,
3499
3507
  };
3500
3508
  if (snapped) {
3501
3509
  config.zIndex = Z_INDEX_2;
@@ -3640,18 +3648,18 @@ class TrackBox extends CacheMap {
3640
3648
  let first = null, last = null;
3641
3649
  if (!!components) {
3642
3650
  for (const comp of components) {
3643
- 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;
3651
+ 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;
3644
3652
  if (isVertical && (pos >= y && pos < y + height)) {
3645
3653
  return { id, x, y, width, height, isFirst, isLast };
3646
3654
  }
3647
- else if (!isVertical && (pos >= x && pos < x + width)) {
3648
- return { id, x, y, width, height, isFirst, isLast };
3655
+ else if (!isVertical && (pos >= xx && pos < xx + width)) {
3656
+ return { id, x: xx, y, width, height, isFirst, isLast };
3649
3657
  }
3650
3658
  if (isFirst) {
3651
- first = { id, x, y, width, height, isFirst, isLast };
3659
+ first = { id, x: xx, y, width, height, isFirst, isLast };
3652
3660
  }
3653
3661
  else if (isLast) {
3654
- last = { id, x, y, width, height, isFirst, isLast };
3662
+ last = { id, x: xx, y, width, height, isFirst, isLast };
3655
3663
  }
3656
3664
  }
3657
3665
  }
@@ -4039,7 +4047,7 @@ const easeLinear = (t) => {
4039
4047
 
4040
4048
  /**
4041
4049
  * Animator
4042
- * @link https://github.com/DjonnyX/ng-virtual-list/blob/main/library/src/utils/animator/animator.ts
4050
+ * @link https://github.com/DjonnyX/ng-virtual-list/blob/21.x/projects/ng-virtual-list/src/lib/utils/animator/animator.ts
4043
4051
  * @author Evgenii Alexandrovich Grebennikov
4044
4052
  * @email djonnyx@gmail.com
4045
4053
  */
@@ -4057,10 +4065,15 @@ class Animator {
4057
4065
  _diff = 0;
4058
4066
  _startValue = 0;
4059
4067
  _endValue = 0;
4060
- updateTo(value) {
4061
- this._endValue = value;
4062
- this._diff = this._endValue - this._startValue;
4063
- return this.hasAnimation();
4068
+ _prevPos = 0;
4069
+ updateTo(end) {
4070
+ if (this.hasAnimation()) {
4071
+ this._startValue = this._prevPos;
4072
+ this._endValue = end;
4073
+ this._diff = this._endValue - this._startValue;
4074
+ return true;
4075
+ }
4076
+ return false;
4064
4077
  }
4065
4078
  animate(params) {
4066
4079
  this.stop();
@@ -4070,7 +4083,8 @@ class Animator {
4070
4083
  this._startValue = startValue;
4071
4084
  this._endValue = endValue;
4072
4085
  const startTime = performance.now();
4073
- let isCanceled = false, prevPos = startValue, startPosDelta = 0, delta = 0, prevTime = startTime, isFinished = false;
4086
+ let isCanceled = false, startPosDelta = 0, delta = 0, prevTime = startTime, isFinished = false;
4087
+ this._prevPos = startValue;
4074
4088
  this._diff = this._endValue - this._startValue;
4075
4089
  const step = (currentTime) => {
4076
4090
  if (id !== this._currentId) {
@@ -4081,34 +4095,36 @@ class Animator {
4081
4095
  }
4082
4096
  const cPos = getPropValue?.() || 0;
4083
4097
  let startDelta = 0;
4084
- if (cPos !== prevPos) {
4085
- startDelta = cPos - prevPos;
4098
+ if (cPos !== this._prevPos) {
4099
+ startDelta = cPos - this._prevPos;
4086
4100
  startPosDelta += startDelta;
4087
4101
  }
4088
- 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();
4102
+ 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();
4089
4103
  isFinished = progress === 1;
4090
- delta = currentValue - startDelta - prevPos;
4104
+ delta = currentValue - startDelta - this._prevPos;
4091
4105
  const frameTimestamp = t - prevTime, actualFrameTimestamp = frameTimestamp < ANIMATOR_MIN_TIMESTAMP ? ANIMATOR_MIN_TIMESTAMP : frameTimestamp;
4092
4106
  prevTime = t;
4093
- prevPos = currentValue;
4107
+ this._prevPos = currentValue;
4108
+ if (isFinished) {
4109
+ this._animationId = -1;
4110
+ }
4094
4111
  if (onUpdate !== undefined) {
4095
4112
  const data = {
4096
4113
  id,
4097
4114
  delta,
4098
4115
  elapsed,
4099
- value: !withDelta && isFinished ? endValue : currentValue,
4116
+ value: currentValue,
4100
4117
  timestamp: actualFrameTimestamp,
4101
4118
  };
4102
4119
  onUpdate(data);
4103
4120
  }
4104
4121
  if (isFinished) {
4105
- this._animationId = -1;
4106
4122
  if (onComplete !== undefined) {
4107
4123
  const data = {
4108
4124
  id,
4109
4125
  delta,
4110
4126
  elapsed,
4111
- value: withDelta ? currentValue : endValue,
4127
+ value: currentValue,
4112
4128
  timestamp: actualFrameTimestamp,
4113
4129
  };
4114
4130
  onComplete(data);
@@ -4139,7 +4155,7 @@ class Animator {
4139
4155
  const SCROLL_VIEW_INVERSION = new InjectionToken('ScrollViewInversion');
4140
4156
  const SCROLL_VIEW_OVERSCROLL_ENABLED = new InjectionToken('ScrollViewOverscrollEnabled');
4141
4157
  const SCROLL_VIEW_NORMALIZE_VALUE_FROM_ZERO = new InjectionToken('ScrollViewNormalizeValueFromZero');
4142
- 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;
4158
+ 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;
4143
4159
  const MAX_ITERATIONS_FOR_AVERAGE_CALCULATIONS = 5, INSTANT_VELOCITY_SCALE = 1000;
4144
4160
  const SCROLL_EVENT$1 = new Event(SCROLLER_SCROLL);
4145
4161
 
@@ -4260,6 +4276,7 @@ class BaseScrollView {
4260
4276
  isInfinity = input(false, ...(ngDevMode ? [{ debugName: "isInfinity" }] : []));
4261
4277
  isVertical;
4262
4278
  grabbing = signal(false, ...(ngDevMode ? [{ debugName: "grabbing" }] : []));
4279
+ langTextDir = input(TextDirections.LTR, ...(ngDevMode ? [{ debugName: "langTextDir" }] : []));
4263
4280
  _inversion = inject(SCROLL_VIEW_INVERSION);
4264
4281
  _overscrollEnabled = inject(SCROLL_VIEW_OVERSCROLL_ENABLED);
4265
4282
  _$updateScrollBar = new Subject();
@@ -4422,7 +4439,7 @@ class BaseScrollView {
4422
4439
  }
4423
4440
  }
4424
4441
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: BaseScrollView, deps: [], target: i0.ɵɵFactoryTarget.Component });
4425
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.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 });
4442
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.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 });
4426
4443
  }
4427
4444
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: BaseScrollView, decorators: [{
4428
4445
  type: Component,
@@ -4430,7 +4447,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
4430
4447
  selector: 'base-scroll-view',
4431
4448
  template: '',
4432
4449
  }]
4433
- }], 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 }] }] } });
4450
+ }], 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 }] }] } });
4434
4451
 
4435
4452
  /**
4436
4453
  * ScrollingDirection
@@ -4515,6 +4532,8 @@ class NgScrollView extends BaseScrollView {
4515
4532
  _startPosition = 0;
4516
4533
  _animator = new Animator();
4517
4534
  _interactive = true;
4535
+ _horizontalAxisInvertion;
4536
+ get inverted() { return this._horizontalAxisInvertion(); }
4518
4537
  _overscrollIteration = 0;
4519
4538
  set x(v) {
4520
4539
  this.setX(v);
@@ -4570,6 +4589,10 @@ class NgScrollView extends BaseScrollView {
4570
4589
  constructor() {
4571
4590
  super();
4572
4591
  let mouseCanceled = false, touchCanceled = false;
4592
+ this._horizontalAxisInvertion = computed(() => {
4593
+ const isVertical = this.isVertical(), langTextDir = this.langTextDir();
4594
+ return !isVertical && langTextDir === TextDirections.RTL;
4595
+ }, ...(ngDevMode ? [{ debugName: "_horizontalAxisInvertion" }] : []));
4573
4596
  const $viewportBounds = toObservable(this.viewportBounds);
4574
4597
  $viewportBounds.pipe(takeUntilDestroyed(), debounceTime(0), tap(() => {
4575
4598
  this._isMoving = false;
@@ -4596,8 +4619,8 @@ class NgScrollView extends BaseScrollView {
4596
4619
  this.emitScrollableEvent();
4597
4620
  this.checkOverscroll(e);
4598
4621
  this.stopScrolling(true);
4599
- 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);
4600
- this.scroll({ [isVertical ? TOP$1 : LEFT$1]: position, behavior: INSTANT$1, userAction: true, blending: false, fireUpdate: true });
4622
+ 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);
4623
+ this.scroll({ [isVertical ? TOP$1 : LEFT$2]: position, behavior: INSTANT$1, userAction: true, blending: false, fireUpdate: true });
4601
4624
  this._$wheel.next(delta);
4602
4625
  }));
4603
4626
  })).subscribe();
@@ -4650,7 +4673,7 @@ class NgScrollView extends BaseScrollView {
4650
4673
  this._isMoving = true;
4651
4674
  this.grabbing.set(true);
4652
4675
  this._startPosition = (isVertical ? this.y : this.x);
4653
- let prevClientPosition = isVertical ? e.clientY : e.clientX, startClientPos = prevClientPosition, offsets = new Array(), velocities = new Array(), startTime = Date.now();
4676
+ let prevClientPosition = (isVertical ? e.clientY : e.clientX) * (this._horizontalAxisInvertion() ? -1 : 1), startClientPos = prevClientPosition, offsets = new Array(), velocities = new Array(), startTime = Date.now();
4654
4677
  return fromEvent(window, MOUSE_MOVE, { passive: false }).pipe(takeUntilDestroyed(this._destroyRef), takeUntil$1($mouseDragCancel), tap(e => {
4655
4678
  this.checkOverscroll(e);
4656
4679
  }), switchMap$1(e => {
@@ -4728,7 +4751,7 @@ class NgScrollView extends BaseScrollView {
4728
4751
  this._isMoving = true;
4729
4752
  this.grabbing.set(true);
4730
4753
  this._startPosition = (isVertical ? this.y : this.x);
4731
- 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();
4754
+ 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();
4732
4755
  return fromEvent(window, TOUCH_MOVE, { passive: false }).pipe(takeUntilDestroyed(this._destroyRef), takeUntil$1($touchCanceler), tap(e => {
4733
4756
  this.checkOverscroll(e);
4734
4757
  }), switchMap$1(e => {
@@ -4826,7 +4849,7 @@ class NgScrollView extends BaseScrollView {
4826
4849
  return false;
4827
4850
  }
4828
4851
  calculatePosition(isVertical, e, inversion, startClientPos, startTime, prevClientPosition, offsets, velocities) {
4829
- 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);
4852
+ 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);
4830
4853
  this.calculateAcceleration(velocities, v0, timestamp);
4831
4854
  return { position, currentPos, endTime, scrollDelta };
4832
4855
  }
@@ -4916,7 +4939,7 @@ class NgScrollView extends BaseScrollView {
4916
4939
  this._animator.stop();
4917
4940
  }
4918
4941
  move(isVertical, position, blending = false, userAction = false, fireUpdate = true) {
4919
- this.scroll({ [isVertical ? TOP$1 : LEFT$1]: position, behavior: INSTANT$1, blending, userAction, fireUpdate });
4942
+ this.scroll({ [isVertical ? TOP$1 : LEFT$2]: position, behavior: INSTANT$1, blending, userAction, fireUpdate });
4920
4943
  }
4921
4944
  moveWithAcceleration(isVertical, position, v0, v, a0, timestamp) {
4922
4945
  if (a0 !== 0 && timestamp < MAX_VELOCITY_TIMESTAMP) {
@@ -5212,7 +5235,7 @@ class NgScrollView extends BaseScrollView {
5212
5235
  }
5213
5236
  refreshCoordinate(x, y) {
5214
5237
  const scrollContent = this.scrollContent()?.nativeElement;
5215
- scrollContent.style.transform = matrix3d((this._inversion ? 1 : -1) * x + (this.isVertical() ? 0 : this._startLayoutOffset), (this._inversion ? 1 : -1) * y + (this.isVertical() ? this._startLayoutOffset : 0));
5238
+ 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));
5216
5239
  }
5217
5240
  fireScrollEvent(userAction) {
5218
5241
  this._$scroll.next(userAction);
@@ -5266,7 +5289,6 @@ class NgScrollBarComponent extends NgScrollView {
5266
5289
  thickness = input(DEFAULT_THICKNESS, ...(ngDevMode ? [{ debugName: "thickness" }] : []));
5267
5290
  scrollbarMinSize = input(0, ...(ngDevMode ? [{ debugName: "scrollbarMinSize" }] : []));
5268
5291
  prepared = input(false, ...(ngDevMode ? [{ debugName: "prepared" }] : []));
5269
- langTextDir = input(DEFAULT_LANG_TEXT_DIR, ...(ngDevMode ? [{ debugName: "langTextDir" }] : []));
5270
5292
  interactive = input(DEFAULT_SCROLLBAR_INTERACTIVE, ...(ngDevMode ? [{ debugName: "interactive" }] : []));
5271
5293
  overlapping = input(DEFAULT_OVERLAPPING_SCROLLBAR, ...(ngDevMode ? [{ debugName: "overlapping" }] : []));
5272
5294
  show = input(false, ...(ngDevMode ? [{ debugName: "show" }] : []));
@@ -5363,7 +5385,7 @@ class NgScrollBarComponent extends NgScrollView {
5363
5385
  if (!!el) {
5364
5386
  const overlapping = this.overlapping(), langTextDir = this.langTextDir();
5365
5387
  el.style[POSITION$1] = overlapping ? POSITION_ABSOLUTE : POSITION_RELATIVE;
5366
- el.style[LEFT$2] = overlapping && langTextDir === TextDirections.RTL ? '0' : UNSET$5;
5388
+ el.style[LEFT$3] = overlapping && langTextDir === TextDirections.RTL ? '0' : UNSET$5;
5367
5389
  el.style[RIGHT$1] = overlapping && langTextDir === TextDirections.LTR ? '0' : UNSET$5;
5368
5390
  el.style[WIDTH] = overlapping ? SIZE_AUTO : SIZE_100_PERSENT;
5369
5391
  }
@@ -5383,7 +5405,7 @@ class NgScrollBarComponent extends NgScrollView {
5383
5405
  })).subscribe();
5384
5406
  }
5385
5407
  createDragEvent(userAction) {
5386
- 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;
5408
+ 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;
5387
5409
  if (!!scrollViewport && !!scrollContent) {
5388
5410
  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);
5389
5411
  const event = {
@@ -5411,7 +5433,7 @@ class NgScrollBarComponent extends NgScrollView {
5411
5433
  this._scrollBarService.click(event);
5412
5434
  }
5413
5435
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: NgScrollBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5414
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.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: [
5436
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.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: [
5415
5437
  { provide: SCROLL_VIEW_INVERSION, useValue: true },
5416
5438
  { provide: SCROLL_VIEW_NORMALIZE_VALUE_FROM_ZERO, useValue: false },
5417
5439
  { provide: SCROLL_VIEW_OVERSCROLL_ENABLED, useValue: false },
@@ -5428,9 +5450,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
5428
5450
  NgScrollBarService,
5429
5451
  NgScrollBarPublicService,
5430
5452
  ], 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"] }]
5431
- }], 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 }] }] } });
5453
+ }], 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 }] }] } });
5432
5454
 
5433
- const RIGHT = 'right', DIR = 'dir';
5455
+ const LEFT$1 = 'left', RIGHT = 'right', DIR = 'dir';
5434
5456
  /**
5435
5457
  * LocaleSensitiveDirective
5436
5458
  * Maximum performance for extremely large lists.
@@ -5446,14 +5468,15 @@ class LocaleSensitiveDirective {
5446
5468
  constructor() {
5447
5469
  const $langTextDir = toObservable(this.langTextDir), $listDir = toObservable(this.listDir);
5448
5470
  combineLatest([$langTextDir, $listDir]).pipe(takeUntilDestroyed(), tap(([dir, listDir]) => {
5449
- const element = this._elementRef.nativeElement, isVertical = isDirection(listDir, ScrollerDirection$1.VERTICAL);
5450
- element.setAttribute(DIR, isVertical ? dir : TextDirections.LTR);
5451
- if (dir === TextDirections.RTL && isVertical) {
5471
+ const element = this._elementRef.nativeElement;
5472
+ element.setAttribute(DIR, dir);
5473
+ if (dir === TextDirections.RTL) {
5452
5474
  element.style.textAlign = RIGHT;
5453
5475
  element.classList.add(TextDirections.RTL);
5454
5476
  element.classList.remove(TextDirections.LTR);
5455
5477
  }
5456
5478
  else {
5479
+ element.style.textAlign = LEFT$1;
5457
5480
  element.classList.add(TextDirections.LTR);
5458
5481
  element.classList.remove(TextDirections.RTL);
5459
5482
  }
@@ -5504,7 +5527,6 @@ class NgScrollerComponent extends NgScrollView {
5504
5527
  thumbSize = signal(0, ...(ngDevMode ? [{ debugName: "thumbSize" }] : []));
5505
5528
  scrollbarShow = signal(false, ...(ngDevMode ? [{ debugName: "scrollbarShow" }] : []));
5506
5529
  preparedSignal = signal(false, ...(ngDevMode ? [{ debugName: "preparedSignal" }] : []));
5507
- langTextDir = signal(TextDirections.LTR, ...(ngDevMode ? [{ debugName: "langTextDir" }] : []));
5508
5530
  listStyles = signal({ perspectiveOrigin: 'center' }, ...(ngDevMode ? [{ debugName: "listStyles" }] : []));
5509
5531
  _scrollBox = new ScrollBox$1();
5510
5532
  get host() {
@@ -5587,10 +5609,6 @@ class NgScrollerComponent extends NgScrollView {
5587
5609
  }), debounceTime(50), tap(([, , filter, ,]) => {
5588
5610
  filter.nativeElement.setStdDeviation(0, 0);
5589
5611
  })).subscribe();
5590
- this._service.$langTextDir.pipe(tap(v => {
5591
- takeUntilDestroyed(this._destroyRef),
5592
- this.langTextDir.set(v);
5593
- })).subscribe();
5594
5612
  const $prepare = toObservable(this.preparedSignal);
5595
5613
  $prepare.pipe(takeUntilDestroyed(), filter$1(v => !!v), tap(() => {
5596
5614
  this.updateScrollBarHandler(true, false, true);
@@ -5623,9 +5641,9 @@ class NgScrollerComponent extends NgScrollView {
5623
5641
  });
5624
5642
  }
5625
5643
  recalculatePerspective() {
5626
- const isVertical = this.isVertical(), scrollSize = (isVertical ? this.scrollTop : this.scrollLeft) - this._startLayoutOffset, { width, height } = this.viewportBounds();
5644
+ 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();
5627
5645
  this.listStyles.set({
5628
- perspectiveOrigin: `${isVertical ? width * .5 : (scrollSize + width * .5)}${PX$1} ${isVertical ? (scrollSize + height * .5) : height * .5}${PX$1}`
5646
+ 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}`
5629
5647
  });
5630
5648
  }
5631
5649
  onResizeViewport() {
@@ -5638,6 +5656,7 @@ class NgScrollerComponent extends NgScrollView {
5638
5656
  this.viewportBounds.set(bounds);
5639
5657
  this.updateScrollBar();
5640
5658
  this._$resizeViewport.next(bounds);
5659
+ this.recalculatePerspective();
5641
5660
  }
5642
5661
  }
5643
5662
  onResizeContent(value = null) {
@@ -5653,6 +5672,7 @@ class NgScrollerComponent extends NgScrollView {
5653
5672
  this.contentBounds.set(bounds);
5654
5673
  this.updateScrollBar();
5655
5674
  this._$resizeContent.next(bounds);
5675
+ this.recalculatePerspective();
5656
5676
  }
5657
5677
  }
5658
5678
  updateScrollBarHandler(update = false, blending = true, fireUpdate = false) {
@@ -5820,7 +5840,7 @@ class NgScrollerComponent extends NgScrollView {
5820
5840
  { provide: SCROLL_VIEW_INVERSION, useValue: false },
5821
5841
  { provide: SCROLL_VIEW_NORMALIZE_VALUE_FROM_ZERO, useValue: true },
5822
5842
  { provide: SCROLL_VIEW_OVERSCROLL_ENABLED, useValue: true },
5823
- ], 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]" }] });
5843
+ ], 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]" }] });
5824
5844
  }
5825
5845
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: NgScrollerComponent, decorators: [{
5826
5846
  type: Component,
@@ -5828,7 +5848,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
5828
5848
  { provide: SCROLL_VIEW_INVERSION, useValue: false },
5829
5849
  { provide: SCROLL_VIEW_NORMALIZE_VALUE_FROM_ZERO, useValue: true },
5830
5850
  { provide: SCROLL_VIEW_OVERSCROLL_ENABLED, useValue: true },
5831
- ], 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"] }]
5851
+ ], 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"] }]
5832
5852
  }], ctorParameters: () => [], propDecorators: { scrollBar: [{
5833
5853
  type: ViewChild,
5834
5854
  args: ['scrollBar', { read: NgScrollBarComponent }]
@@ -5848,6 +5868,7 @@ const createItemData = (data, isVertical, bounds, boundsSize, dynamic, divides,
5848
5868
  measures: {
5849
5869
  position: 0,
5850
5870
  scrollSize: 0,
5871
+ maxScrollSize: 0,
5851
5872
  size: itemSize,
5852
5873
  row: {
5853
5874
  size: itemSize,
@@ -5907,6 +5928,7 @@ const createItemData = (data, isVertical, bounds, boundsSize, dynamic, divides,
5907
5928
  fullSize: false,
5908
5929
  layoutIndexOffset: 0,
5909
5930
  totalItems: 0,
5931
+ inverted: false,
5910
5932
  },
5911
5933
  };
5912
5934
  };
@@ -6133,7 +6155,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
6133
6155
  */
6134
6156
  class NgPrerenderScrollerComponent extends BaseScrollView {
6135
6157
  scrollBar;
6136
- langTextDir = signal(TextDirections.LTR, ...(ngDevMode ? [{ debugName: "langTextDir" }] : []));
6137
6158
  scrollbarEnabled = input(DEFAULT_SCROLLBAR_ENABLED, ...(ngDevMode ? [{ debugName: "scrollbarEnabled" }] : []));
6138
6159
  classes = input({}, ...(ngDevMode ? [{ debugName: "classes" }] : []));
6139
6160
  actualClasses;
@@ -7547,19 +7568,22 @@ class NgVirtualListComponent {
7547
7568
  }
7548
7569
  const scroller = this._scrollerComponent();
7549
7570
  if (!!scroller) {
7550
- const { width, height } = this._bounds(), { width: elementWidth, height: elementHeight } = element.getBoundingClientRect(), isVertical = this._isVertical, viewportSize = isVertical ? height : width, elementSize = isVertical ? elementHeight : elementWidth;
7571
+ 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;
7551
7572
  let pos = Number.NaN;
7552
7573
  switch (align) {
7553
7574
  case FocusAlignments.START: {
7554
- pos = position + scroller.startLayoutOffset;
7575
+ const p = position + scroller.startLayoutOffset;
7576
+ pos = scroller.inverted ? (maxPosition - p) : p;
7555
7577
  break;
7556
7578
  }
7557
7579
  case FocusAlignments.CENTER: {
7558
- pos = position - (viewportSize - elementSize) * .5 + scroller.startLayoutOffset;
7580
+ const p = position - (viewportSize - elementSize) * .5 + scroller.startLayoutOffset;
7581
+ pos = scroller.inverted ? (maxPosition - p) : p;
7559
7582
  break;
7560
7583
  }
7561
7584
  case FocusAlignments.END: {
7562
- pos = position - (viewportSize - elementSize) + scroller.startLayoutOffset;
7585
+ const p = position - (viewportSize - elementSize) + scroller.startLayoutOffset;
7586
+ pos = scroller.inverted ? (maxPosition - p) : p;
7563
7587
  break;
7564
7588
  }
7565
7589
  case FocusAlignments.NONE:
@@ -7664,10 +7688,9 @@ class NgVirtualListComponent {
7664
7688
  this.onSnapItem.emit(id);
7665
7689
  })).subscribe();
7666
7690
  this._service.$tick.pipe(takeUntilDestroyed(), tap(() => {
7667
- this._scrollerComponent()?.tick();
7668
- })).subscribe();
7669
- this._service.$tick.pipe(takeUntilDestroyed(), filter$1(() => this.dynamicSize() === true), tap(() => {
7670
- this.checkBoundsOfElements();
7691
+ if (this.dynamicSize() === true) {
7692
+ this.checkBoundsOfElements();
7693
+ }
7671
7694
  this._scrollerComponent()?.tick();
7672
7695
  })).subscribe();
7673
7696
  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));
@@ -8043,7 +8066,12 @@ class NgVirtualListComponent {
8043
8066
  const scrollbarEnabled = this.scrollbarEnabled(), spreadingMode = this.spreadingMode();
8044
8067
  return isSpreadingMode(spreadingMode, SpreadingModes.INFINITY) ? false : scrollbarEnabled;
8045
8068
  }, ...(ngDevMode ? [{ debugName: "_actualScrollbarEnabled" }] : []));
8046
- 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;
8069
+ 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;
8070
+ combineLatest([$isVertical, $langTextDir, $itemTransform]).pipe(takeUntilDestroyed(), debounceTime(0), tap(([isVertical, langTextDir, itemTransform]) => {
8071
+ if (langTextDir === TextDirections.RTL && !isVertical && itemTransform) {
8072
+ throw Error('Currently, converting right-to-left items in horizontal lists is not possible.');
8073
+ }
8074
+ })).subscribe();
8047
8075
  $snapToItem.pipe(takeUntilDestroyed(), tap(v => {
8048
8076
  this._service.snapToItem = v;
8049
8077
  })).subscribe();
@@ -8104,6 +8132,9 @@ class NgVirtualListComponent {
8104
8132
  actualItems.push(item);
8105
8133
  }
8106
8134
  const normalizedCollection = normalizeCollection(actualItems, itemConfigMap, trackBy, divides);
8135
+ if (this._scrollerComponent()?.inverted) {
8136
+ normalizedCollection.reverse();
8137
+ }
8107
8138
  this._actualItems.set(normalizedCollection);
8108
8139
  })).subscribe();
8109
8140
  $isVertical.pipe(takeUntilDestroyed(), tap(v => {
@@ -8225,20 +8256,21 @@ class NgVirtualListComponent {
8225
8256
  if (!!scroller) {
8226
8257
  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;
8227
8258
  if (this._readyForShow || (cachable && cached)) {
8228
- const currentScrollSize = (isVertical ? scroller.scrollTop : scroller.scrollLeft);
8229
- let actualScrollSize = !this._readyForShow && snapScrollToEnd ? (isVertical ? scroller.scrollHeight : scroller.scrollWidth) :
8259
+ const inverted = scroller.inverted, currentScrollSize = (isVertical ? scroller.scrollTop : scroller.scrollLeft), maxScrollSize = (isVertical ? scroller.scrollHeight : scroller.scrollWidth);
8260
+ let actualScrollSize = !this._readyForShow && snapScrollToEnd ? maxScrollSize :
8230
8261
  (isVertical ? scroller.scrollTop : scroller.scrollLeft), leftLayoutOffset = 0, displayItems;
8231
- const { width, height } = bounds, viewportSize = (isVertical ? height : width), opts = {
8262
+ const { width, height } = bounds, opts = {
8232
8263
  alignment, bounds: { width, height }, dynamicSize, isVertical, itemSize, minItemSize, maxItemSize, bufferSize, maxBufferSize,
8233
- scrollSize: actualScrollSize, stickyEnabled, enabledBufferOptimization, snapToItem, snapToItemAlign, itemTransform,
8264
+ scrollSize: inverted ? maxScrollSize - actualScrollSize : actualScrollSize, stickyEnabled, enabledBufferOptimization,
8265
+ snapToItem, snapToItemAlign, inverted, itemTransform,
8234
8266
  };
8235
8267
  if (snapScrollToEnd && !this._readyForShow) {
8236
- const { displayItems: calculatedDisplayItems, totalSize: calculatedTotalSize1, leftLayoutOffset: leftLayoutOffset1 } = this._trackBox.updateCollection(items, itemConfigMap, { ...opts, scrollSize: actualScrollSize });
8268
+ const { displayItems: calculatedDisplayItems, totalSize: calculatedTotalSize1, leftLayoutOffset: leftLayoutOffset1 } = this._trackBox.updateCollection(items, itemConfigMap, { ...opts, scrollSize: inverted ? maxScrollSize - actualScrollSize : actualScrollSize });
8237
8269
  displayItems = calculatedDisplayItems;
8238
8270
  totalSize = calculatedTotalSize1;
8239
8271
  leftLayoutOffset = leftLayoutOffset1;
8240
8272
  if (!!itemTransform && dynamicSize && this._trackBox.delta !== 0) {
8241
- const { displayItems: calculatedDisplayItems, totalSize: calculatedTotalSize1, leftLayoutOffset: leftLayoutOffset1 } = this._trackBox.updateCollection(items, itemConfigMap, { ...opts, scrollSize: actualScrollSize + this._trackBox.delta });
8273
+ const { displayItems: calculatedDisplayItems, totalSize: calculatedTotalSize1, leftLayoutOffset: leftLayoutOffset1 } = this._trackBox.updateCollection(items, itemConfigMap, { ...opts, scrollSize: inverted ? (maxScrollSize - actualScrollSize + this._trackBox.delta) : (actualScrollSize + this._trackBox.delta) });
8242
8274
  displayItems = calculatedDisplayItems;
8243
8275
  totalSize = calculatedTotalSize1;
8244
8276
  leftLayoutOffset = leftLayoutOffset1;
@@ -8250,7 +8282,7 @@ class NgVirtualListComponent {
8250
8282
  totalSize = calculatedTotalSize;
8251
8283
  leftLayoutOffset = leftLayoutOffset1;
8252
8284
  if (!!itemTransform && dynamicSize && this._trackBox.delta !== 0) {
8253
- const { displayItems: calculatedDisplayItems, totalSize: calculatedTotalSize, leftLayoutOffset: leftLayoutOffset1 } = this._trackBox.updateCollection(items, itemConfigMap, { ...opts, scrollSize: actualScrollSize + this._trackBox.delta });
8285
+ const { displayItems: calculatedDisplayItems, totalSize: calculatedTotalSize, leftLayoutOffset: leftLayoutOffset1 } = this._trackBox.updateCollection(items, itemConfigMap, { ...opts, scrollSize: inverted ? (maxScrollSize - actualScrollSize + this._trackBox.delta) : (actualScrollSize + this._trackBox.delta) });
8254
8286
  displayItems = calculatedDisplayItems;
8255
8287
  totalSize = calculatedTotalSize;
8256
8288
  leftLayoutOffset = leftLayoutOffset1;
@@ -8274,18 +8306,48 @@ class NgVirtualListComponent {
8274
8306
  this.updateOffsetsByAllignment();
8275
8307
  scroller.delta = delta;
8276
8308
  prevScrollable = scroller.scrollable;
8277
- if ((snapScrollToStart && this._trackBox.isSnappedToStart && scroller.scrollable) ||
8278
- (snapScrollToStart && currentScrollSize <= MIN_PIXELS_FOR_PREVENT_SNAPPING)) {
8279
- if (currentScrollSize !== roundedScrollPositionAfterUpdate) {
8309
+ if (!scroller.grabbing()) {
8310
+ if ((snapScrollToStart && this._trackBox.isSnappedToStart && scroller.scrollable) ||
8311
+ (snapScrollToStart && currentScrollSize <= MIN_PIXELS_FOR_PREVENT_SNAPPING)) {
8312
+ if (currentScrollSize !== roundedScrollPositionAfterUpdate) {
8313
+ this._trackBox.clearDelta();
8314
+ if (this._readyForShow) {
8315
+ this.emitScrollEvent(true, false, userAction);
8316
+ }
8317
+ this._trackBox.isScrollEnd;
8318
+ const params = {
8319
+ [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: 0, userAction,
8320
+ fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams().scrollToItem > 0 && this.scrollBehavior() !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT),
8321
+ blending: useAnimations && scroller.hasAnimation(this._animationId), duration: this.animationParams().scrollToItem,
8322
+ };
8323
+ const animationId = scroller?.scrollTo?.(params);
8324
+ if (animationId > -1) {
8325
+ this._animationId = animationId;
8326
+ }
8327
+ else {
8328
+ scroller.stopAnimation(this._animationId);
8329
+ }
8330
+ if (emitUpdate) {
8331
+ this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
8332
+ }
8333
+ }
8334
+ return;
8335
+ }
8336
+ if ((snapScrollToEnd && this._trackBox.isSnappedToEnd) || (snapScrollToEnd && !scroller.scrollable) ||
8337
+ (scrollPositionAfterUpdate + MIN_PIXELS_FOR_PREVENT_SNAPPING >= roundedMaxPositionAfterUpdate) ||
8338
+ (roundedScrollPositionAfterUpdate >= scrollPositionAfterUpdate + MIN_PIXELS_FOR_PREVENT_SNAPPING)) {
8280
8339
  this._trackBox.clearDelta();
8340
+ if (!this._trackBox.isSnappedToEnd) {
8341
+ this._trackBox.isScrollEnd = true;
8342
+ this._trackBox.isScrollStart = false;
8343
+ }
8281
8344
  if (this._readyForShow) {
8282
- this.emitScrollEvent(true, false, userAction);
8345
+ this.emitScrollEvent(true, false, false);
8283
8346
  }
8284
- this._trackBox.isScrollEnd;
8285
8347
  const params = {
8286
- [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: 0, userAction,
8287
- fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams().scrollToItem > 0 && this.scrollBehavior() !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT),
8288
- blending: useAnimations && scroller.hasAnimation(this._animationId), duration: this.animationParams().scrollToItem,
8348
+ [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: roundedMaxPositionAfterUpdate,
8349
+ fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams().scrollToItem > 0 && this.scrollBehavior() !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT), userAction: false,
8350
+ blending: useAnimations && scroller.hasAnimation(this._animationId) || cacheChanged, duration: this.animationParams().scrollToItem,
8289
8351
  };
8290
8352
  const animationId = scroller?.scrollTo?.(params);
8291
8353
  if (animationId > -1) {
@@ -8297,36 +8359,8 @@ class NgVirtualListComponent {
8297
8359
  if (emitUpdate) {
8298
8360
  this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
8299
8361
  }
8362
+ return;
8300
8363
  }
8301
- return;
8302
- }
8303
- if ((snapScrollToEnd && this._trackBox.isSnappedToEnd) || (snapScrollToEnd && !scroller.scrollable) ||
8304
- (scrollPositionAfterUpdate + MIN_PIXELS_FOR_PREVENT_SNAPPING >= roundedMaxPositionAfterUpdate) ||
8305
- (roundedScrollPositionAfterUpdate >= scrollPositionAfterUpdate + MIN_PIXELS_FOR_PREVENT_SNAPPING)) {
8306
- this._trackBox.clearDelta();
8307
- if (!this._trackBox.isSnappedToEnd) {
8308
- this._trackBox.isScrollEnd = true;
8309
- this._trackBox.isScrollStart = false;
8310
- }
8311
- if (this._readyForShow) {
8312
- this.emitScrollEvent(true, false, false);
8313
- }
8314
- const params = {
8315
- [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: roundedMaxPositionAfterUpdate,
8316
- fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams().scrollToItem > 0 && this.scrollBehavior() !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT), userAction: false,
8317
- blending: useAnimations && scroller.hasAnimation(this._animationId) || cacheChanged, duration: this.animationParams().scrollToItem,
8318
- };
8319
- const animationId = scroller?.scrollTo?.(params);
8320
- if (animationId > -1) {
8321
- this._animationId = animationId;
8322
- }
8323
- else {
8324
- scroller.stopAnimation(this._animationId);
8325
- }
8326
- if (emitUpdate) {
8327
- this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
8328
- }
8329
- return;
8330
8364
  }
8331
8365
  if (scrollSize !== scrollPositionAfterUpdate &&
8332
8366
  ((scrollPositionAfterUpdate >= 0 && scrollPositionAfterUpdate < roundedMaxPositionAfterUpdate) ||
@@ -8358,11 +8392,11 @@ class NgVirtualListComponent {
8358
8392
  let prevItems = [];
8359
8393
  const debouncedUpdate = debounce(update, 0, MAX_NUMBERS_OF_SKIPS_FOR_QUALITY_OPTIMIZATION_LVL1);
8360
8394
  $viewInit.pipe(takeUntilDestroyed(), filter$1(v => !!v), switchMap$1(() => {
8361
- return combineLatest([$trackBy, $isInfinity, $snapScrollToStart, $snapScrollToEnd, $bounds, $listBounds, $scrollEndOffset, $actualItems, $itemConfigMap, $scrollSize,
8395
+ return combineLatest([$trackBy, $isInfinity, $snapScrollToStart, $snapScrollToEnd, $bounds, $listBounds, $actualItems, $itemConfigMap, $scrollSize,
8362
8396
  $actualItemSize, $actualMinItemSize, $actualMaxItemSize, $collapsedItemIds, $bufferSize, $maxBufferSize, $stickyEnabled, $isVertical,
8363
8397
  $dynamicSize, $divides, $snapToItem, $snapToItemAlign, $enabledBufferOptimization, $itemTransform, $alignment,
8364
8398
  $precalculatedScrollStartOffset, $precalculatedScrollEndOffset, $cacheVersion, this.$fireUpdate,
8365
- ]).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,]) => {
8399
+ ]).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,]) => {
8366
8400
  let itemsChanged = false;
8367
8401
  if (prevItems !== items) {
8368
8402
  itemsChanged = true;
@@ -8373,7 +8407,7 @@ class NgVirtualListComponent {
8373
8407
  if (enabledOptimization) {
8374
8408
  if (useDebouncedUpdate) {
8375
8409
  debouncedUpdate.execute({
8376
- trackBy, isInfinity, snapScrollToStart, snapScrollToEnd, bounds, listBounds, scrollEndOffset, items, itemConfigMap, scrollSize, itemSize, minItemSize,
8410
+ trackBy, isInfinity, snapScrollToStart, snapScrollToEnd, bounds, listBounds, items, itemConfigMap, scrollSize, itemSize, minItemSize,
8377
8411
  maxItemSize, collapsedIds, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, divides, enabledBufferOptimization, itemTransform,
8378
8412
  snapToItem, snapToItemAlign, alignment, precalculatedScrollStartOffset, precalculatedScrollEndOffset, cacheVersion, userAction: hasUserAction,
8379
8413
  });
@@ -8383,7 +8417,7 @@ class NgVirtualListComponent {
8383
8417
  }
8384
8418
  if (!isScrolling) {
8385
8419
  update({
8386
- trackBy, isInfinity, snapScrollToStart, snapScrollToEnd, bounds, listBounds, scrollEndOffset, items, itemConfigMap, scrollSize, itemSize, minItemSize,
8420
+ trackBy, isInfinity, snapScrollToStart, snapScrollToEnd, bounds, listBounds, items, itemConfigMap, scrollSize, itemSize, minItemSize,
8387
8421
  maxItemSize, collapsedIds, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, divides, enabledBufferOptimization, itemTransform,
8388
8422
  snapToItem, snapToItemAlign, alignment, precalculatedScrollStartOffset, precalculatedScrollEndOffset, cacheVersion, userAction: hasUserAction,
8389
8423
  });
@@ -8466,23 +8500,23 @@ class NgVirtualListComponent {
8466
8500
  if (!!items && items.length) {
8467
8501
  const dynamicSize = this.dynamicSize(), itemSize = this._actualItemSize(), minItemSize = this._actualMinItemSize(), maxItemSize = this._actualMaxItemSize(), snapScrollToEnd = this.snapScrollToEnd();
8468
8502
  if (dynamicSize) {
8469
- 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 = {
8470
- alignment: this.actualAlignment(),
8503
+ 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 = {
8504
+ alignment: this.actualAlignment(), inverted,
8471
8505
  bounds: { width, height }, collection: items, dynamicSize, isVertical: this._isVertical, itemSize, minItemSize, maxItemSize,
8472
8506
  bufferSize: this.bufferSize(), maxBufferSize: this.maxBufferSize(), itemTransform: this.itemTransform(),
8473
- scrollSize: (isVertical ? scrollerComponent.scrollTop : scrollerComponent.scrollLeft),
8507
+ scrollSize: (inverted ? (maxScrollSize - currentScrollSize) : currentScrollSize),
8474
8508
  snapToItem: this.snapToItem(), snapToItemAlign: this.snapToItemAlign(),
8475
8509
  stickyEnabled: this.stickyEnabled(), fromItemId: id, enabledBufferOptimization: this.enabledBufferOptimization(),
8476
8510
  };
8477
8511
  let scrollSize = snapScrollToEnd && this._trackBox.isSnappedToEnd ?
8478
- (isVertical ? scrollerComponent.scrollHeight : scrollerComponent.scrollWidth) :
8512
+ maxScrollSize :
8479
8513
  this._trackBox.getItemPosition(id, itemConfigMap, opts);
8480
8514
  if (scrollSize === -1) {
8481
8515
  return of([finished, { id, blending, iteration: nextIteration, cb }]).pipe(delay(0));
8482
8516
  }
8483
8517
  this._trackBox.clearDelta();
8484
8518
  const viewportSize = (isVertical ? height : width), { displayItems, totalSize, leftLayoutOffset } = this._trackBox.updateCollection(items, itemConfigMap, {
8485
- ...opts, scrollSize, fromItemId: isLastIteration ? undefined : id,
8519
+ ...opts, scrollSize: (inverted ? (maxScrollSize - scrollSize) : scrollSize), fromItemId: isLastIteration ? undefined : id,
8486
8520
  }), delta1 = this._trackBox.delta;
8487
8521
  const normalizedTotalSize = totalSize < viewportSize ? viewportSize : totalSize;
8488
8522
  scrollerComponent.startLayoutOffset = leftLayoutOffset;
@@ -8494,7 +8528,7 @@ class NgVirtualListComponent {
8494
8528
  this.tracking();
8495
8529
  this.snappingHandler();
8496
8530
  this.updateOffsetsByAllignment();
8497
- scrollSize = this._trackBox.getItemPosition(id, itemConfigMap, { ...opts, scrollSize: actualScrollSize, fromItemId: id });
8531
+ scrollSize = this._trackBox.getItemPosition(id, itemConfigMap, { ...opts, scrollSize: (inverted ? (maxScrollSize - actualScrollSize) : actualScrollSize), fromItemId: id });
8498
8532
  if (scrollSize === -1) {
8499
8533
  return of([finished, { id, blending, iteration: nextIteration, cb }]).pipe(delay(0));
8500
8534
  }
@@ -8531,17 +8565,18 @@ class NgVirtualListComponent {
8531
8565
  }
8532
8566
  }
8533
8567
  }
8534
- const { width, height } = this._bounds() || { width: DEFAULT_LIST_SIZE, height: DEFAULT_LIST_SIZE }, itemConfigMap = this.itemConfigMap(), items = this._actualItems(), opts = {
8535
- alignment: this._actualAlignment(),
8568
+ 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 = {
8569
+ alignment: this._actualAlignment(), inverted,
8536
8570
  bounds: { width, height }, collection: items, dynamicSize, isVertical: this._isVertical, itemSize, minItemSize, maxItemSize,
8537
8571
  bufferSize: this.bufferSize(), maxBufferSize: this.maxBufferSize(), itemTransform: this.itemTransform(),
8538
- scrollSize: (isVertical ? scrollerComponent.scrollTop : scrollerComponent.scrollLeft),
8572
+ scrollSize: (inverted ? (maxScrollSize - actualScrollSize) : actualScrollSize),
8539
8573
  snapToItem, snapToItemAlign, stickyEnabled: this.stickyEnabled(), fromItemId: id,
8540
8574
  enabledBufferOptimization: this.enabledBufferOptimization(),
8541
8575
  };
8542
8576
  this._trackBox.clearDelta();
8543
8577
  const viewportSize = (isVertical ? height : width), { displayItems, totalSize, leftLayoutOffset } = this._trackBox.updateCollection(items, itemConfigMap, {
8544
- ...opts, scrollSize, fromItemId: isLastIteration ? undefined : id,
8578
+ ...opts, scrollSize: (inverted ? (maxScrollSize - scrollSize) : scrollSize),
8579
+ fromItemId: isLastIteration ? undefined : id,
8545
8580
  });
8546
8581
  const actualTotalSize = this._isInfinity() ? (totalSize + viewportSize) : totalSize;
8547
8582
  const normalizedTotalSize = actualTotalSize < viewportSize ? viewportSize : actualTotalSize;
@@ -9062,13 +9097,13 @@ class NgVirtualListComponent {
9062
9097
  }
9063
9098
  }
9064
9099
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: NgVirtualListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9065
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.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 });
9100
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.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 });
9066
9101
  }
9067
9102
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: NgVirtualListComponent, decorators: [{
9068
9103
  type: Component,
9069
9104
  args: [{ selector: 'ng-virtual-list', host: {
9070
9105
  'style': 'position: relative;'
9071
- }, 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"] }]
9106
+ }, 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"] }]
9072
9107
  }], ctorParameters: () => [], propDecorators: { _prerender: [{ type: i0.ViewChild, args: ['prerender', { isSignal: true }] }], _listContainerRef: [{
9073
9108
  type: ViewChild,
9074
9109
  args: ['renderersContainer', { read: ViewContainerRef }]