ng-virtual-list 14.12.2 → 14.12.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/README.md +2 -2
  2. package/esm2020/lib/components/ng-list-item/base/base-virtual-list-item-component.mjs +9 -5
  3. package/esm2020/lib/components/ng-list-item/const/index.mjs +2 -1
  4. package/esm2020/lib/components/ng-list-item/ng-virtual-list-item.component.mjs +14 -8
  5. package/esm2020/lib/components/ng-prerender-container/components/ng-prerender-list-item/ng-prerender-list-item.component.mjs +3 -3
  6. package/esm2020/lib/components/ng-scroll-view/ng-scroll-view.component.mjs +20 -14
  7. package/esm2020/lib/components/ng-scroller/ng-scroller.component.mjs +6 -2
  8. package/esm2020/lib/const/index.mjs +6 -3
  9. package/esm2020/lib/core/track-box.mjs +31 -9
  10. package/esm2020/lib/directives/virtual-click/virtual-click.directive.mjs +35 -15
  11. package/esm2020/lib/models/display-object-config.model.mjs +1 -1
  12. package/esm2020/lib/ng-virtual-list.component.mjs +43 -11
  13. package/esm2020/lib/ng-virtual-list.service.mjs +31 -2
  14. package/esm2020/lib/utils/animator/animator.mjs +39 -14
  15. package/fesm2015/ng-virtual-list.mjs +228 -77
  16. package/fesm2015/ng-virtual-list.mjs.map +1 -1
  17. package/fesm2020/ng-virtual-list.mjs +223 -73
  18. package/fesm2020/ng-virtual-list.mjs.map +1 -1
  19. package/lib/components/ng-list-item/base/base-virtual-list-item-component.d.ts +1 -1
  20. package/lib/components/ng-list-item/ng-virtual-list-item.component.d.ts +3 -1
  21. package/lib/components/ng-scroll-view/ng-scroll-view.component.d.ts +5 -2
  22. package/lib/components/ng-scroller/ng-scroller.component.d.ts +1 -1
  23. package/lib/const/index.d.ts +3 -1
  24. package/lib/directives/virtual-click/virtual-click.directive.d.ts +11 -6
  25. package/lib/models/display-object-config.model.d.ts +4 -0
  26. package/lib/ng-virtual-list.component.d.ts +2 -1
  27. package/lib/ng-virtual-list.service.d.ts +13 -0
  28. package/lib/utils/animator/animator.d.ts +11 -2
  29. package/package.json +1 -1
@@ -1,10 +1,10 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Injectable, inject, Component, ChangeDetectorRef, ElementRef, ChangeDetectionStrategy, ViewChild, EventEmitter as EventEmitter$1, Directive, Input, Output, Injector, InjectionToken, TemplateRef, ViewContainerRef, ViewEncapsulation, NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
3
- import { Subject, BehaviorSubject, takeUntil, tap, map, combineLatest, fromEvent, race, of, debounceTime, switchMap as switchMap$1, distinctUntilChanged, filter as filter$1, delay, startWith, from, take, skip } from 'rxjs';
3
+ import { Subject, BehaviorSubject, takeUntil, distinctUntilChanged, combineLatest, tap, map, fromEvent, race, of, debounceTime, switchMap as switchMap$1, filter as filter$1, delay, startWith, from, take, skip } from 'rxjs';
4
4
  import { BehaviorSubject as BehaviorSubject$1 } from 'rxjs/internal/BehaviorSubject';
5
5
  import * as i1 from '@angular/common';
6
6
  import { CommonModule } from '@angular/common';
7
- import { takeUntil as takeUntil$1, switchMap, filter, tap as tap$1 } from 'rxjs/operators';
7
+ import { takeUntil as takeUntil$1, tap as tap$1, switchMap, filter } from 'rxjs/operators';
8
8
  import * as i4 from '@angular/cdk/scrolling';
9
9
  import { CdkScrollable, CdkScrollableModule } from '@angular/cdk/scrolling';
10
10
 
@@ -251,6 +251,7 @@ var TextDirections;
251
251
  TextDirections["LTR"] = "ltr";
252
252
  })(TextDirections || (TextDirections = {}));
253
253
 
254
+ const INVISIBLE_POSITION = -10000;
254
255
  const SERVICE_PROP_DUMMY_ID = '__service-dummy-id__';
255
256
  const SERVICE_PROP_DUMMY = '__service-dummy__';
256
257
  const SERVICE_TYPE_DUMMY = '__service-type-dummy__';
@@ -280,7 +281,7 @@ const DEFAULT_MOTION_BLUR = 0.15;
280
281
  const DEFAULT_MOTION_BLUR_ENABLED = false;
281
282
  const DEFAULT_MAX_MOTION_BLUR = 0.5;
282
283
  const DEFAULT_ANIMATION_PARAMS = {
283
- scrollToItem: 50,
284
+ scrollToItem: 150,
284
285
  snapToItem: 150,
285
286
  navigateToItem: 150,
286
287
  navigateByKeyboard: NAVIGATION_BY_KEYBOARD_TIMER,
@@ -336,13 +337,15 @@ const POSITION$1 = 'position';
336
337
  const POSITION_RELATIVE = 'relative';
337
338
  const POSITION_ABSOLUTE = 'absolute';
338
339
  const TRANSLATE_3D = 'translate3d';
339
- const ZEROS_TRANSLATE_3D = `${TRANSLATE_3D}(0,0,0)`;
340
+ const INVISIBLE_TRANSLATE_3D = `${TRANSLATE_3D}(${INVISIBLE_POSITION},${INVISIBLE_POSITION},0)`;
340
341
  const HIDDEN_ZINDEX = '-1';
341
342
  const DEFAULT_ZINDEX = '0';
342
343
  const TOP_PROP_NAME = 'top';
343
344
  const LEFT_PROP_NAME = 'left';
344
345
  const X_PROP_NAME = 'x';
345
346
  const Y_PROP_NAME = 'y';
347
+ const TRANSFORMED_X_PROP_NAME = 'transformedX';
348
+ const TRANSFORMED_Y_PROP_NAME = 'transformedY';
346
349
  const WIDTH_PROP_NAME = 'width';
347
350
  const HEIGHT_PROP_NAME = 'height';
348
351
  const MARGIN_TOP = 'marginTop';
@@ -496,6 +499,7 @@ const DEFAULT_TEMPLATE_CONTEXT = {
496
499
  isLast: false,
497
500
  fullSize: false,
498
501
  totalItems: 0,
502
+ grabbing: false,
499
503
  },
500
504
  reseted: false,
501
505
  index: -1,
@@ -684,6 +688,14 @@ class NgVirtualListService {
684
688
  this._$langTextDir = new BehaviorSubject$1(TextDirections.LTR);
685
689
  this.$langTextDir = this._$langTextDir.asObservable();
686
690
  this._langTextDir = TextDirections.LTR;
691
+ this._$grabbing = new BehaviorSubject$1(false);
692
+ this.$grabbing = this._$grabbing.asObservable();
693
+ this._grabbing = false;
694
+ this._$clickPressed = new BehaviorSubject$1(false);
695
+ this.$clickPressed = this._$clickPressed.asObservable();
696
+ this._clickPressed = false;
697
+ this._$isGrabbing = new BehaviorSubject$1(false);
698
+ this.$isGrabbing = this._$isGrabbing.asObservable();
687
699
  this._scrollBarSize = 0;
688
700
  this._$scrollBarSize = new BehaviorSubject$1(this._scrollBarSize);
689
701
  this.$scrollBarSize = this._$scrollBarSize.asObservable();
@@ -698,6 +710,10 @@ class NgVirtualListService {
698
710
  this._onTrackBoxChangeHandler = (v) => {
699
711
  this._$cacheVersion.next(v);
700
712
  };
713
+ const $grabbing = this.$grabbing.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged()), $clickPressed = this.$clickPressed.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged());
714
+ combineLatest([$grabbing, $clickPressed]).pipe(takeUntil(this._$unsubscribe), tap(([grabbing, clickPressed]) => {
715
+ this._$isGrabbing.next(grabbing && !clickPressed);
716
+ })).subscribe();
701
717
  this._$selectingMode.pipe(takeUntil(this._$unsubscribe), tap(v => {
702
718
  switch (v) {
703
719
  case SelectingModesTypes.SELECT: {
@@ -748,6 +764,23 @@ class NgVirtualListService {
748
764
  this._langTextDir = v;
749
765
  this._$langTextDir.next(v);
750
766
  }
767
+ get grabbing() { return this._$grabbing.getValue(); }
768
+ set grabbing(v) {
769
+ if (this._grabbing === v) {
770
+ return;
771
+ }
772
+ this._grabbing = v;
773
+ this._$grabbing.next(v);
774
+ }
775
+ get clickPressed() { return this._$clickPressed.getValue(); }
776
+ set clickPressed(v) {
777
+ if (this._clickPressed === v) {
778
+ return;
779
+ }
780
+ this._clickPressed = v;
781
+ this._$clickPressed.next(v);
782
+ }
783
+ get isGrabbing() { return this._$isGrabbing.getValue(); }
751
784
  get scrollBarSize() { return this._$scrollBarSize.getValue(); }
752
785
  set scrollBarSize(v) {
753
786
  if (this._scrollBarSize === v) {
@@ -1236,6 +1269,9 @@ class BaseVirtualListItemComponent extends DisposableComponent {
1236
1269
  this._id = this._service.generateComponentId();
1237
1270
  this._listId = this._service.id;
1238
1271
  this._displayId = createDisplayId(this._listId, this._id);
1272
+ this._service.$isGrabbing.pipe(takeUntil(this._$unsubscribe), tap(v => {
1273
+ this.updateConfig(this._data, v);
1274
+ })).subscribe();
1239
1275
  const $part = this.$part;
1240
1276
  $part.pipe(takeUntil(this._$unsubscribe), tap(part => {
1241
1277
  this._elementRef.nativeElement.setAttribute('part', part);
@@ -1296,7 +1332,7 @@ class BaseVirtualListItemComponent extends DisposableComponent {
1296
1332
  }
1297
1333
  this._data = v;
1298
1334
  this.updatePartStr(v, this._isSelected, this._isCollapsed);
1299
- this.updateConfig(v);
1335
+ this.updateConfig(v, this._service.isGrabbing);
1300
1336
  this.updateMeasures(v);
1301
1337
  this.update();
1302
1338
  this._$data.next(v);
@@ -1335,8 +1371,8 @@ class BaseVirtualListItemComponent extends DisposableComponent {
1335
1371
  this._$measures.next((v === null || v === void 0 ? void 0 : v.measures) ? Object.assign({}, v.measures) : null);
1336
1372
  this._cdr.markForCheck();
1337
1373
  }
1338
- updateConfig(v) {
1339
- this._$config.next(Object.assign(Object.assign({}, (v === null || v === void 0 ? void 0 : v.config) || {}), { selected: this._isSelected, collapsed: this._isCollapsed, focused: this._$focused.getValue() }));
1374
+ updateConfig(v, grabbing) {
1375
+ this._$config.next(Object.assign(Object.assign({}, (v === null || v === void 0 ? void 0 : v.config) || {}), { selected: this._isSelected, collapsed: this._isCollapsed, focused: this._$focused.getValue(), grabbing }));
1340
1376
  this._cdr.markForCheck();
1341
1377
  }
1342
1378
  update() {
@@ -1468,6 +1504,7 @@ class BaseVirtualListItemComponent extends DisposableComponent {
1468
1504
  }
1469
1505
  const el = this._elementRef.nativeElement, styles = el.style;
1470
1506
  styles.zIndex = HIDDEN_ZINDEX;
1507
+ styles.transform = INVISIBLE_TRANSLATE_3D;
1471
1508
  if (this.regular) {
1472
1509
  if (styles.display === DISPLAY_NONE) {
1473
1510
  return;
@@ -1500,9 +1537,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
1500
1537
  args: ['container']
1501
1538
  }] } });
1502
1539
 
1503
- const DEFAULT_MAX_DISTANCE = 40;
1504
1540
  /**
1505
- * ItemClickDirective
1541
+ * VirtualClickDirective
1506
1542
  * Maximum performance for extremely large lists.
1507
1543
  * It is based on algorithms for virtualization of screen objects.
1508
1544
  * @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/directives/item-click/item-click.directive.ts
@@ -1510,26 +1546,40 @@ const DEFAULT_MAX_DISTANCE = 40;
1510
1546
  * @email djonnyx@gmail.com
1511
1547
  */
1512
1548
  class VirtualClickDirective {
1513
- constructor(_elementRef) {
1514
- this._elementRef = _elementRef;
1549
+ constructor() {
1550
+ var _a;
1515
1551
  this._$unsubscribe = new Subject();
1516
- this._maxDistance = DEFAULT_MAX_DISTANCE;
1552
+ this._$maxDistance = new BehaviorSubject(null);
1553
+ this.$maxDistance = this._$maxDistance.asObservable();
1554
+ this._maxDistance = null;
1517
1555
  this.onVirtualClick = new EventEmitter$1();
1556
+ this.onVirtualClickPress = new EventEmitter$1();
1557
+ this.onVirtualClickCancel = new EventEmitter$1();
1558
+ this._service = inject(NgVirtualListService);
1559
+ this._elementRef = inject(ElementRef);
1560
+ let maxDistance = (_a = this._maxDistance) !== null && _a !== void 0 ? _a : DEFAULT_CLICK_DISTANCE;
1561
+ combineLatest([this._service.$clickDistance, this.$maxDistance]).pipe(takeUntil$1(this._$unsubscribe), tap$1(([clickDistance, distance]) => {
1562
+ maxDistance = distance === null ? clickDistance : distance;
1563
+ })).subscribe();
1518
1564
  const $pointerPressed = fromEvent(this._elementRef.nativeElement, 'pointerdown'), $pointerCancel = race([
1519
1565
  fromEvent(window, 'pointerup').pipe(takeUntil$1(this._$unsubscribe)),
1520
1566
  fromEvent(window, 'pointerleave').pipe(takeUntil$1(this._$unsubscribe)),
1521
1567
  ]), $pointerRelease = fromEvent(this._elementRef.nativeElement, 'pointerup', { passive: false });
1522
1568
  $pointerPressed.pipe(takeUntil$1(this._$unsubscribe), switchMap(e => {
1523
1569
  const x = Math.abs(e.clientX), y = Math.abs(e.clientY);
1570
+ this.onVirtualClickPress.emit(e);
1524
1571
  return $pointerRelease.pipe(takeUntil$1(this._$unsubscribe), takeUntil$1(race([
1525
- $pointerCancel,
1572
+ $pointerCancel.pipe(takeUntil$1(this._$unsubscribe), tap$1(() => {
1573
+ this.onVirtualClickCancel.emit();
1574
+ })),
1526
1575
  fromEvent(window, 'pointermove').pipe(takeUntil$1(this._$unsubscribe), switchMap(e => {
1527
1576
  const xx = x - Math.abs(e.clientX), yy = y - Math.abs(e.clientY), dist = Math.sqrt(Math.pow(xx, 2) + Math.pow(yy, 2));
1528
- if (dist > this._maxDistance) {
1577
+ if (dist > maxDistance) {
1578
+ this.onVirtualClickCancel.emit();
1529
1579
  return of(true);
1530
1580
  }
1531
1581
  return of(false);
1532
- }), takeUntil$1(this._$unsubscribe), filter(v => !!v)),
1582
+ }), filter(v => !!v)),
1533
1583
  ])), takeUntil$1(this._$unsubscribe), tap$1(e => {
1534
1584
  if (e) {
1535
1585
  this.onVirtualClick.emit(e);
@@ -1538,7 +1588,9 @@ class VirtualClickDirective {
1538
1588
  })).subscribe();
1539
1589
  }
1540
1590
  set maxDistance(v) {
1541
- this._maxDistance = (v !== null || v !== undefined) ? Number(v) : DEFAULT_MAX_DISTANCE;
1591
+ const value = (v !== null || v !== undefined) ? Number(v) : null;
1592
+ this._maxDistance = value;
1593
+ this._$maxDistance.next(value);
1542
1594
  }
1543
1595
  ngOnDestroy() {
1544
1596
  if (this._$unsubscribe) {
@@ -1547,19 +1599,23 @@ class VirtualClickDirective {
1547
1599
  }
1548
1600
  }
1549
1601
  }
1550
- VirtualClickDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: VirtualClickDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
1551
- VirtualClickDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: VirtualClickDirective, selector: "[virtualClick]", inputs: { maxDistance: ["maxClickDistance", "maxDistance"] }, outputs: { onVirtualClick: "onVirtualClick" }, ngImport: i0 });
1602
+ VirtualClickDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: VirtualClickDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1603
+ VirtualClickDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: VirtualClickDirective, selector: "[virtualClick]", inputs: { maxDistance: ["maxClickDistance", "maxDistance"] }, outputs: { onVirtualClick: "onVirtualClick", onVirtualClickPress: "onVirtualClickPress", onVirtualClickCancel: "onVirtualClickCancel" }, ngImport: i0 });
1552
1604
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: VirtualClickDirective, decorators: [{
1553
1605
  type: Directive,
1554
1606
  args: [{
1555
1607
  selector: '[virtualClick]',
1556
1608
  standalone: false,
1557
1609
  }]
1558
- }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { maxDistance: [{
1610
+ }], ctorParameters: function () { return []; }, propDecorators: { maxDistance: [{
1559
1611
  type: Input,
1560
1612
  args: ['maxClickDistance']
1561
1613
  }], onVirtualClick: [{
1562
1614
  type: Output
1615
+ }], onVirtualClickPress: [{
1616
+ type: Output
1617
+ }], onVirtualClickCancel: [{
1618
+ type: Output
1563
1619
  }] } });
1564
1620
 
1565
1621
  /**
@@ -1592,12 +1648,12 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
1592
1648
  var _a;
1593
1649
  this._service.focusedId = (_a = this.itemId) !== null && _a !== void 0 ? _a : null;
1594
1650
  this._$focused.next(true);
1595
- this.updateConfig(this._data);
1651
+ this.updateConfig(this._data, this._service.isGrabbing);
1596
1652
  this.updatePartStr(this._data, this._isSelected, this._isCollapsed);
1597
1653
  })).subscribe(),
1598
1654
  fromEvent(this.element, EVENT_FOCUS_OUT).pipe(takeUntil(this._$unsubscribe), tap(e => {
1599
1655
  this._$focused.next(false);
1600
- this.updateConfig(this._data);
1656
+ this.updateConfig(this._data, this._service.isGrabbing);
1601
1657
  this.updatePartStr(this._data, this._isSelected, this._isCollapsed);
1602
1658
  })).subscribe();
1603
1659
  $focused.pipe(takeUntil(this._$unsubscribe), debounceTime(this.getNavigationTimeout()), switchMap$1(v => {
@@ -1630,7 +1686,7 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
1630
1686
  const actualIds = collapsedIds, isCollapsed = this.itemId !== undefined && actualIds && actualIds.includes(this.itemId);
1631
1687
  this._isCollapsed = isCollapsed;
1632
1688
  this.updatePartStr(this._data, this._isSelected, isCollapsed);
1633
- this.updateConfig(this._data);
1689
+ this.updateConfig(this._data, this._service.isGrabbing);
1634
1690
  this.updateMeasures(this._data);
1635
1691
  })).subscribe();
1636
1692
  }
@@ -1736,22 +1792,28 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
1736
1792
  }
1737
1793
  return Number.MIN_SAFE_INTEGER;
1738
1794
  }
1739
- updateConfig(v) {
1740
- this._$config.next(Object.assign(Object.assign({}, (v === null || v === void 0 ? void 0 : v.config) || {}), { selected: this._isSelected, collapsed: this._isCollapsed, focused: this._$focused.getValue() }));
1795
+ updateConfig(v, grabbing) {
1796
+ this._$config.next(Object.assign(Object.assign({}, (v === null || v === void 0 ? void 0 : v.config) || {}), { selected: this._isSelected, collapsed: this._isCollapsed, focused: this._$focused.getValue(), grabbing }));
1741
1797
  this._cdr.markForCheck();
1742
1798
  }
1743
1799
  onClickHandler() {
1744
1800
  this._service.virtualClick(this._data);
1745
1801
  }
1802
+ onClickPressHandler() {
1803
+ this._service.clickPressed = true;
1804
+ }
1805
+ onClickCancelHandler() {
1806
+ this._service.clickPressed = false;
1807
+ }
1746
1808
  }
1747
1809
  NgVirtualListItemComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgVirtualListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1748
- NgVirtualListItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: NgVirtualListItemComponent, selector: "ng-virtual-list-item", host: { attributes: { "role": "listitem" }, classAttribute: "ngvl__item" }, usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"($data | async) as data\">\r\n <div #item class=\"ngvl-item\" [ngClass]=\"($classes | async)!\" [part]=\"($part | async)!\" [attr.ngvl-index]=\"($index | async)!\"\r\n [attr.ngvl-visibility]=\"visibility\" tabindex=\"-1\">\r\n <div *ngIf=\"_blendColor\" class=\"ngvl-item__blend-color\" [style.--blend-color]=\"_blendColor\"></div>\r\n <div #container virtualClick [part]=\"$fxPart | async\" [maxClickDistance]=\"$maxClickDistance | async\"\r\n class=\"ngvl-item__container\" [ngClass]=\"($classes | async)!\" (onVirtualClick)=\"onClickHandler()\">\r\n <ng-container [ngTemplateOutlet]=\"itemRenderer ?? null\"\r\n [ngTemplateOutletContext]=\"$templateContext | async\"></ng-container>\r\n </div>\r\n </div>\r\n</ng-container>", styles: [":host{display:block;position:absolute;left:0;top:0;box-sizing:border-box;overflow:hidden;-webkit-tap-highlight-color:transparent;-webkit-user-drag:none;-moz-user-drag:none;text-rendering:optimizeSpeed;image-rendering:auto}.ngvl-item{position:relative;margin:0;padding:0;overflow:hidden;outline:none;width:inherit;height:inherit;box-sizing:border-box}.ngvl-item__blend-color{position:absolute;left:0;top:0;width:100%;height:100%;background-color:var(--blend-color);z-index:-1}.ngvl-item__container{margin:0;padding:0;width:100%;height:100%;box-sizing:border-box}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: VirtualClickDirective, selector: "[virtualClick]", inputs: ["maxClickDistance"], outputs: ["onVirtualClick"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1810
+ NgVirtualListItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: NgVirtualListItemComponent, selector: "ng-virtual-list-item", host: { attributes: { "role": "listitem" }, classAttribute: "ngvl__item" }, usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"($data | async) as data\">\r\n <div #item class=\"ngvl-item\" [ngClass]=\"($classes | async)!\" [part]=\"($part | async)!\"\r\n [attr.ngvl-index]=\"($index | async)!\" [attr.ngvl-visibility]=\"visibility\" tabindex=\"-1\">\r\n <div *ngIf=\"_blendColor\" class=\"ngvl-item__blend-color\" [style.--blend-color]=\"_blendColor\"></div>\r\n <div #container virtualClick [part]=\"$fxPart | async\" [maxClickDistance]=\"($maxClickDistance | async)!\"\r\n class=\"ngvl-item__container\" [ngClass]=\"($classes | async)!\" (onVirtualClick)=\"onClickHandler()\"\r\n (onVirtualClickPress)=\"onClickPressHandler()\" (onVirtualClickCancel)=\"onClickCancelHandler()\">\r\n <ng-container [ngTemplateOutlet]=\"itemRenderer ?? null\"\r\n [ngTemplateOutletContext]=\"$templateContext | async\"></ng-container>\r\n </div>\r\n </div>\r\n</ng-container>", styles: [":host{display:block;position:absolute;left:0;top:0;box-sizing:border-box;overflow:hidden;-webkit-tap-highlight-color:transparent;-webkit-user-drag:none;-moz-user-drag:none;text-rendering:optimizeSpeed;image-rendering:auto}.ngvl-item{position:relative;margin:0;padding:0;overflow:hidden;outline:none;width:inherit;height:inherit;box-sizing:border-box}.ngvl-item__blend-color{position:absolute;left:0;top:0;width:100%;height:100%;background-color:var(--blend-color);z-index:-1}.ngvl-item__container{margin:0;padding:0;width:100%;height:100%;box-sizing:border-box}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: VirtualClickDirective, selector: "[virtualClick]", inputs: ["maxClickDistance"], outputs: ["onVirtualClick", "onVirtualClickPress", "onVirtualClickCancel"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1749
1811
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgVirtualListItemComponent, decorators: [{
1750
1812
  type: Component,
1751
1813
  args: [{ selector: 'ng-virtual-list-item', host: {
1752
1814
  'class': 'ngvl__item',
1753
1815
  'role': 'listitem',
1754
- }, standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"($data | async) as data\">\r\n <div #item class=\"ngvl-item\" [ngClass]=\"($classes | async)!\" [part]=\"($part | async)!\" [attr.ngvl-index]=\"($index | async)!\"\r\n [attr.ngvl-visibility]=\"visibility\" tabindex=\"-1\">\r\n <div *ngIf=\"_blendColor\" class=\"ngvl-item__blend-color\" [style.--blend-color]=\"_blendColor\"></div>\r\n <div #container virtualClick [part]=\"$fxPart | async\" [maxClickDistance]=\"$maxClickDistance | async\"\r\n class=\"ngvl-item__container\" [ngClass]=\"($classes | async)!\" (onVirtualClick)=\"onClickHandler()\">\r\n <ng-container [ngTemplateOutlet]=\"itemRenderer ?? null\"\r\n [ngTemplateOutletContext]=\"$templateContext | async\"></ng-container>\r\n </div>\r\n </div>\r\n</ng-container>", styles: [":host{display:block;position:absolute;left:0;top:0;box-sizing:border-box;overflow:hidden;-webkit-tap-highlight-color:transparent;-webkit-user-drag:none;-moz-user-drag:none;text-rendering:optimizeSpeed;image-rendering:auto}.ngvl-item{position:relative;margin:0;padding:0;overflow:hidden;outline:none;width:inherit;height:inherit;box-sizing:border-box}.ngvl-item__blend-color{position:absolute;left:0;top:0;width:100%;height:100%;background-color:var(--blend-color);z-index:-1}.ngvl-item__container{margin:0;padding:0;width:100%;height:100%;box-sizing:border-box}\n"] }]
1816
+ }, standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"($data | async) as data\">\r\n <div #item class=\"ngvl-item\" [ngClass]=\"($classes | async)!\" [part]=\"($part | async)!\"\r\n [attr.ngvl-index]=\"($index | async)!\" [attr.ngvl-visibility]=\"visibility\" tabindex=\"-1\">\r\n <div *ngIf=\"_blendColor\" class=\"ngvl-item__blend-color\" [style.--blend-color]=\"_blendColor\"></div>\r\n <div #container virtualClick [part]=\"$fxPart | async\" [maxClickDistance]=\"($maxClickDistance | async)!\"\r\n class=\"ngvl-item__container\" [ngClass]=\"($classes | async)!\" (onVirtualClick)=\"onClickHandler()\"\r\n (onVirtualClickPress)=\"onClickPressHandler()\" (onVirtualClickCancel)=\"onClickCancelHandler()\">\r\n <ng-container [ngTemplateOutlet]=\"itemRenderer ?? null\"\r\n [ngTemplateOutletContext]=\"$templateContext | async\"></ng-container>\r\n </div>\r\n </div>\r\n</ng-container>", styles: [":host{display:block;position:absolute;left:0;top:0;box-sizing:border-box;overflow:hidden;-webkit-tap-highlight-color:transparent;-webkit-user-drag:none;-moz-user-drag:none;text-rendering:optimizeSpeed;image-rendering:auto}.ngvl-item{position:relative;margin:0;padding:0;overflow:hidden;outline:none;width:inherit;height:inherit;box-sizing:border-box}.ngvl-item__blend-color{position:absolute;left:0;top:0;width:100%;height:100%;background-color:var(--blend-color);z-index:-1}.ngvl-item__container{margin:0;padding:0;width:100%;height:100%;box-sizing:border-box}\n"] }]
1755
1817
  }], ctorParameters: function () { return []; } });
1756
1818
 
1757
1819
  /**
@@ -3282,11 +3344,11 @@ class TrackBox extends CacheMap {
3282
3344
  return false;
3283
3345
  }
3284
3346
  generateDisplayCollection(items, actualItems, itemConfigMap, metrics) {
3285
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
3347
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1;
3286
3348
  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 = [];
3287
3349
  if (items.length) {
3288
3350
  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;
3289
- let pos = startPosition, renderItems = renderItemsLength, stickyItem, nextSticky, stickyItemIndex = -1, stickyItemSize = 0, endStickyItem, nextEndSticky, endStickyItemIndex = -1, endStickyItemSize = 0;
3351
+ let pos = startPosition, renderItems = renderItemsLength, stickyItem, nextSticky, stickyItemIndex = -1, nexstStickyItemIndex = -1, stickyItemSize = 0, endStickyItem, nextEndSticky, endStickyItemIndex = -1, endStickyItemSize = 0;
3290
3352
  const li = layoutIndexOffset + actualItems.length - 1;
3291
3353
  if (stickyEnabled) {
3292
3354
  for (let i = Math.min(itemsFromStartToScrollEnd > 0 ? (divides > 1 ? (itemsFromStartToScrollEnd - 1) : itemsFromStartToScrollEnd) : 0, totalLength - 1); i >= 0; i--) {
@@ -3546,6 +3608,7 @@ class TrackBox extends CacheMap {
3546
3608
  item.measures.x = isVertical ? 0 : snapped ? actualSnippedPosition : pos;
3547
3609
  item.measures.y = isVertical ? snapped ? actualSnippedPosition : pos : 0;
3548
3610
  nextSticky = item;
3611
+ nexstStickyItemIndex = displayItems.length;
3549
3612
  nextSticky.config.snapped = snapped;
3550
3613
  nextSticky.measures.delta = (isVertical ? item.measures.y : item.measures.x) - scrollSize;
3551
3614
  nextSticky.config.zIndex = Z_INDEX_3;
@@ -3568,10 +3631,10 @@ class TrackBox extends CacheMap {
3568
3631
  }
3569
3632
  i++;
3570
3633
  }
3571
- const axis = isVertical ? Y_PROP_NAME : X_PROP_NAME;
3634
+ const axis = isVertical ? Y_PROP_NAME : X_PROP_NAME, transformedAxis = isVertical ? TRANSFORMED_Y_PROP_NAME : TRANSFORMED_X_PROP_NAME;
3572
3635
  if (!!nextSticky && !!stickyItem && nextSticky.measures[axis] <= actualSnippedPosition + stickyItem.measures[sizeProperty]) {
3573
3636
  if (nextSticky.measures[axis] > actualSnippedPosition) {
3574
- stickyItem.measures[axis] = nextSticky.measures[axis] - stickyItem.measures[sizeProperty];
3637
+ stickyItem.measures[axis] = stickyItem.measures[transformedAxis] = nextSticky.measures[axis] - stickyItem.measures[sizeProperty];
3575
3638
  stickyItem.config.snapped = nextSticky.config.snapped = false;
3576
3639
  stickyItem.config.snappedOut = true;
3577
3640
  stickyItem.config.sticky = 1;
@@ -3580,14 +3643,35 @@ class TrackBox extends CacheMap {
3580
3643
  else {
3581
3644
  nextSticky.config.snapped = true;
3582
3645
  nextSticky.measures.delta = (isVertical ? nextSticky.measures.y : nextSticky.measures.x) - scrollSize;
3583
- stickyItem.measures[axis] = nextSticky.measures[axis] - stickyItem.measures[sizeProperty];
3646
+ stickyItem.measures[axis] = stickyItem.measures[transformedAxis] = nextSticky.measures[axis] - stickyItem.measures[sizeProperty];
3584
3647
  stickyItem.measures.delta = (isVertical ? stickyItem.measures.y : stickyItem.measures.x) - scrollSize;
3648
+ const lastStickyItem = displayItems === null || displayItems === void 0 ? void 0 : displayItems[nexstStickyItemIndex + 1];
3649
+ if (((_w = lastStickyItem === null || lastStickyItem === void 0 ? void 0 : lastStickyItem.config) === null || _w === void 0 ? void 0 : _w.sticky) === 1 && ((_y = (_x = displayItems === null || displayItems === void 0 ? void 0 : displayItems[nexstStickyItemIndex + 2]) === null || _x === void 0 ? void 0 : _x.config) === null || _y === void 0 ? void 0 : _y.sticky) !== 1) {
3650
+ nextSticky.config.snapped = nextSticky.config.snappedOut = false;
3651
+ stickyItem.config.snappedOut = true;
3652
+ nextSticky.measures.delta = this._scrollStartOffset;
3653
+ if (lastStickyItem.measures[axis] <= actualSnippedPosition) {
3654
+ lastStickyItem.config.snapped = lastStickyItem.config.snappedOut = true;
3655
+ lastStickyItem.measures[axis] = lastStickyItem.measures[transformedAxis] = lastStickyItem.measures.position = actualSnippedPosition;
3656
+ lastStickyItem.measures.delta = this._scrollStartOffset;
3657
+ }
3658
+ }
3659
+ else if (((_z = lastStickyItem === null || lastStickyItem === void 0 ? void 0 : lastStickyItem.config) === null || _z === void 0 ? void 0 : _z.sticky) !== 1 && ((_1 = (_0 = displayItems === null || displayItems === void 0 ? void 0 : displayItems[nexstStickyItemIndex + 2]) === null || _0 === void 0 ? void 0 : _0.config) === null || _1 === void 0 ? void 0 : _1.sticky) !== 1) {
3660
+ if (nextSticky.measures[axis] <= actualSnippedPosition) {
3661
+ nextSticky.config.snapped = nextSticky.config.snappedOut = true;
3662
+ nextSticky.measures[axis] = nextSticky.measures[transformedAxis] = nextSticky.measures.position = actualSnippedPosition;
3663
+ nextSticky.measures.delta = this._scrollStartOffset;
3664
+ }
3665
+ }
3666
+ else {
3667
+ nextSticky.config.snapped = nextSticky.config.snappedOut = false;
3668
+ }
3585
3669
  }
3586
3670
  }
3587
3671
  if (!!nextEndSticky && !!endStickyItem &&
3588
3672
  (nextEndSticky.measures[axis] >= actualEndSnippedPosition - endStickyItemSize - nextEndSticky.measures[sizeProperty])) {
3589
3673
  if (nextEndSticky.measures[axis] < actualEndSnippedPosition - nextEndSticky.measures[sizeProperty]) {
3590
- endStickyItem.measures[axis] = nextEndSticky.measures[axis] + nextEndSticky.measures[sizeProperty];
3674
+ endStickyItem.measures[axis] = endStickyItem.measures[transformedAxis] = nextEndSticky.measures[axis] + nextEndSticky.measures[sizeProperty];
3591
3675
  endStickyItem.config.snapped = nextEndSticky.config.snapped = false;
3592
3676
  endStickyItem.config.snappedOut = true;
3593
3677
  endStickyItem.config.sticky = 2;
@@ -3595,9 +3679,9 @@ class TrackBox extends CacheMap {
3595
3679
  }
3596
3680
  else {
3597
3681
  nextEndSticky.config.snapped = true;
3598
- nextEndSticky.measures[axis] = actualEndSnippedPosition - nextEndSticky.measures[sizeProperty];
3682
+ nextEndSticky.measures[axis] = nextEndSticky.measures[transformedAxis] = actualEndSnippedPosition - nextEndSticky.measures[sizeProperty];
3599
3683
  nextEndSticky.measures.delta = (isVertical ? nextEndSticky.measures.y : nextEndSticky.measures.x) - scrollSize;
3600
- endStickyItem.measures[axis] = nextEndSticky.measures[axis] + nextEndSticky.measures[sizeProperty];
3684
+ endStickyItem.measures[axis] = endStickyItem.measures[transformedAxis] = nextEndSticky.measures[axis] + nextEndSticky.measures[sizeProperty];
3601
3685
  endStickyItem.measures.delta = (isVertical ? endStickyItem.measures.y : endStickyItem.measures.x) - scrollSize;
3602
3686
  }
3603
3687
  }
@@ -3869,18 +3953,34 @@ class Animator {
3869
3953
  constructor() {
3870
3954
  this._animationId = 0;
3871
3955
  this._currentId = Animator._nextId;
3872
- }
3956
+ this._diff = 0;
3957
+ this._startValue = 0;
3958
+ this._endValue = 0;
3959
+ this._prevPos = 0;
3960
+ }
3961
+ get animated() { return this._animationId > -1; }
3962
+ get isAnimated() { return this.hasAnimation(this._currentId); }
3963
+ get id() { return this._currentId; }
3873
3964
  generateId() {
3874
3965
  return Animator._nextId = Animator._nextId === Number.MAX_SAFE_INTEGER
3875
3966
  ? 0 : Animator._nextId + 1;
3876
3967
  }
3968
+ updateTo(end) {
3969
+ this._endValue = end;
3970
+ this._diff = this._endValue - this._startValue;
3971
+ return this.hasAnimation();
3972
+ }
3877
3973
  animate(params) {
3878
3974
  this.stop();
3879
3975
  const id = this.generateId();
3880
3976
  this._currentId = id;
3881
3977
  const { withDelta = DEFAULT_WITH_DELTA, startValue, endValue, duration = DEFAULT_ANIMATION_DURATION, getPropValue, easingFunction = easeLinear, onUpdate, onComplete, } = params;
3978
+ this._startValue = startValue;
3979
+ this._endValue = endValue;
3882
3980
  const startTime = performance.now();
3883
- let isCanceled = false, prevPos = startValue, start = startValue, startPosDelta = 0, delta = 0, prevTime = startTime, diff = endValue - start, isFinished = false;
3981
+ let isCanceled = false, startPosDelta = 0, delta = 0, prevTime = startTime, isFinished = false;
3982
+ this._prevPos = startValue;
3983
+ this._diff = this._endValue - this._startValue;
3884
3984
  const step = (currentTime) => {
3885
3985
  if (id !== this._currentId) {
3886
3986
  isCanceled = true;
@@ -3890,34 +3990,35 @@ class Animator {
3890
3990
  }
3891
3991
  const cPos = (getPropValue === null || getPropValue === void 0 ? void 0 : getPropValue()) || 0;
3892
3992
  let startDelta = 0;
3893
- if (cPos !== prevPos) {
3894
- startDelta = cPos - prevPos;
3993
+ if (cPos !== this._prevPos) {
3994
+ startDelta = cPos - this._prevPos;
3895
3995
  startPosDelta += startDelta;
3896
3996
  }
3897
- const elapsed = currentTime - startTime, progress = start === endValue ? 1 : Math.min(duration > 0 ? elapsed / duration : 0, 1), easedProgress = easingFunction(progress), val = (withDelta ? startPosDelta : 0) + start + diff * easedProgress, currentValue = val, t = performance.now();
3997
+ 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();
3898
3998
  isFinished = progress === 1;
3899
- delta = currentValue - startDelta - prevPos;
3900
- const ts = t - prevTime, timestamp = ts < ANIMATOR_MIN_TIMESTAMP ? ANIMATOR_MIN_TIMESTAMP : ts;
3999
+ delta = currentValue - startDelta - this._prevPos;
4000
+ const frameTimestamp = t - prevTime, actualFrameTimestamp = frameTimestamp < ANIMATOR_MIN_TIMESTAMP ? ANIMATOR_MIN_TIMESTAMP : frameTimestamp;
3901
4001
  prevTime = t;
3902
- prevPos = currentValue;
4002
+ this._prevPos = currentValue;
3903
4003
  if (onUpdate !== undefined) {
3904
4004
  const data = {
3905
4005
  id,
3906
4006
  delta,
3907
4007
  elapsed,
3908
- value: !withDelta && isFinished ? endValue : currentValue,
3909
- timestamp,
4008
+ value: currentValue,
4009
+ timestamp: actualFrameTimestamp,
3910
4010
  };
3911
4011
  onUpdate(data);
3912
4012
  }
3913
4013
  if (isFinished) {
4014
+ this._animationId = -1;
3914
4015
  if (onComplete !== undefined) {
3915
4016
  const data = {
3916
4017
  id,
3917
4018
  delta,
3918
4019
  elapsed,
3919
- value: withDelta ? currentValue : endValue,
3920
- timestamp,
4020
+ value: currentValue,
4021
+ timestamp: actualFrameTimestamp,
3921
4022
  };
3922
4023
  onComplete(data);
3923
4024
  }
@@ -3927,9 +4028,17 @@ class Animator {
3927
4028
  }
3928
4029
  };
3929
4030
  this._animationId = requestAnimationFrame(step);
4031
+ return this._currentId;
3930
4032
  }
3931
- stop() {
3932
- cancelAnimationFrame(this._animationId);
4033
+ hasAnimation(id = -1) {
4034
+ if ((this._currentId === id || id === -1) && this.animated) {
4035
+ return true;
4036
+ }
4037
+ return false;
4038
+ }
4039
+ stop(id = -1) {
4040
+ cancelAnimationFrame(id === -1 ? this._animationId : id);
4041
+ this._animationId = -1;
3933
4042
  }
3934
4043
  dispose() {
3935
4044
  this.stop();
@@ -4518,6 +4627,7 @@ class NgScrollView extends BaseScrollView {
4518
4627
  }
4519
4628
  }
4520
4629
  get startLayoutOffset() { return this._startLayoutOffset; }
4630
+ get animated() { var _a, _b; return (_b = (_a = this._animator) === null || _a === void 0 ? void 0 : _a.isAnimated) !== null && _b !== void 0 ? _b : false; }
4521
4631
  ngAfterViewInit() {
4522
4632
  let mouseCanceled = false, touchCanceled = false;
4523
4633
  const $viewportBounds = this.$viewportBounds;
@@ -4708,6 +4818,7 @@ class NgScrollView extends BaseScrollView {
4708
4818
  }));
4709
4819
  })).subscribe();
4710
4820
  }
4821
+ hasAnimation(id = -1) { var _a, _b; return (_b = (_a = this._animator) === null || _a === void 0 ? void 0 : _a.hasAnimation(id)) !== null && _b !== void 0 ? _b : false; }
4711
4822
  updateDirection(position, prePosition) {
4712
4823
  const delta = (position - this._delta) - prePosition;
4713
4824
  this._scrollDirection.add(delta > 0 ? 1 : delta < 0 ? -1 : 0);
@@ -4874,7 +4985,7 @@ class NgScrollView extends BaseScrollView {
4874
4985
  var _a, _b, _c, _d, _e, _f;
4875
4986
  if (a0 !== 0 && timestamp < MAX_VELOCITY_TIMESTAMP) {
4876
4987
  const dvSign = Math.sign(v), mass = (_b = (_a = this.scrollingSettings) === null || _a === void 0 ? void 0 : _a.mass) !== null && _b !== void 0 ? _b : MASS, duration = DURATION, maxDuration = (_d = (_c = this.scrollingSettings) === null || _c === void 0 ? void 0 : _c.maxDuration) !== null && _d !== void 0 ? _d : MAX_DURATION, maxDist = (_f = (_e = this.scrollingSettings) === null || _e === void 0 ? void 0 : _e.maxDistance) !== null && _f !== void 0 ? _f : MAX_DIST, maxDistance = dvSign * maxDist, s = (dvSign * Math.abs((a0 * Math.pow(duration, 2)) * .5) / 10000) / mass, distance = Math.abs(s) < maxDist ? s : maxDistance, positionWithVelocity = position + (this._inversion ? -1 : 1) * distance, ad = Math.abs(a0 !== 0 ? Math.sqrt(a0) : 0) * ACCELERATION_SCALE / mass, aDuration = ad < maxDuration ? ad : maxDuration, startPosition = isVertical ? this.y : this.x;
4877
- this.animate(startPosition, Math.round(positionWithVelocity), aDuration, easeOutQuad, true);
4988
+ this.animate(startPosition, Math.round(positionWithVelocity), aDuration, easeOutQuad, false, true);
4878
4989
  }
4879
4990
  else {
4880
4991
  this.alignPosition(true, true);
@@ -4887,11 +4998,17 @@ class NgScrollView extends BaseScrollView {
4887
4998
  const isVertical = this._$isVertical.getValue(), startOffset = this._normalizeValueFromZero ? 0 : this.startOffset, scrollSize = this.scrollable ? ((isVertical ? this.scrollHeight : this.scrollWidth) - this.alignmentEndOffset) : 0, result = this.scrollable ? (value <= startOffset ? startOffset : value > scrollSize ? scrollSize : value) : startOffset;
4888
4999
  return result;
4889
5000
  }
4890
- animate(startValue, endValue, duration = ANIMATION_DURATION, easingFunction = easeOutQuad, userAction = false, alignmentAtComplete = true, skipOverridedCoordinates = false) {
5001
+ animate(startValue, endValue, duration = ANIMATION_DURATION, easingFunction = easeOutQuad, blending = false, userAction = false, alignmentAtComplete = true, skipOverridedCoordinates = false) {
4891
5002
  const isVertical = this._$isVertical.getValue();
4892
5003
  let position = startValue;
4893
5004
  this._isAlignmentAnimation = !alignmentAtComplete;
4894
- this._animator.animate({
5005
+ if (this.hasAnimation() && blending) {
5006
+ const updatable = this._animator.updateTo(endValue);
5007
+ if (updatable) {
5008
+ return this._animator.id;
5009
+ }
5010
+ }
5011
+ return this._animator.animate({
4895
5012
  withDelta: this._service.dynamic && !this.isInfinity,
4896
5013
  startValue,
4897
5014
  endValue,
@@ -4904,7 +5021,7 @@ class NgScrollView extends BaseScrollView {
4904
5021
  if (this._isCoordinatesOverrided && !skipOverridedCoordinates) {
4905
5022
  this._isCoordinatesOverrided = false;
4906
5023
  const currentCoordinate = isVertical ? this._y : this._x, delta = endValue - value;
4907
- this.animate(currentCoordinate, currentCoordinate + delta, duration - elapsed, easingFunction, userAction, alignmentAtComplete);
5024
+ this.animate(currentCoordinate, currentCoordinate + delta, duration - elapsed, easingFunction, blending, userAction, alignmentAtComplete);
4908
5025
  return;
4909
5026
  }
4910
5027
  const v0 = (_a = calculateVelocity(position, value - this._delta, timestamp)) !== null && _a !== void 0 ? _a : this.averageVelocity;
@@ -5038,7 +5155,7 @@ class NgScrollView extends BaseScrollView {
5038
5155
  const cPos = (isVertical ? this.scrollTop : this.scrollLeft);
5039
5156
  if (position !== null && position !== cPos) {
5040
5157
  this.stopScrolling(true);
5041
- this.animate(cPos, position, animated ? this.animationParams.snapToItem : 1, easeOutQuad, false, false, true);
5158
+ this.animate(cPos, position, animated ? this._$animationParams.getValue().snapToItem : 1, easeOutQuad, false, false, false, true);
5042
5159
  return true;
5043
5160
  }
5044
5161
  return false;
@@ -5125,21 +5242,18 @@ class NgScrollView extends BaseScrollView {
5125
5242
  if (behavior === AUTO || behavior === SMOOTH) {
5126
5243
  if (isVertical) {
5127
5244
  if (prevY !== y) {
5128
- this.animate(prevY, y, duration, ease, userAction);
5245
+ return this.animate(prevY, y, duration, ease, blending, userAction);
5129
5246
  }
5130
5247
  }
5131
5248
  else {
5132
5249
  if (prevX !== x) {
5133
- this.animate(prevX, x, duration, ease, userAction);
5250
+ return this.animate(prevX, x, duration, ease, blending, userAction);
5134
5251
  }
5135
5252
  }
5136
5253
  }
5137
5254
  else {
5138
5255
  if (isVertical) {
5139
5256
  if (this._y !== y || force) {
5140
- if (!blending) {
5141
- this.stopScrolling(force);
5142
- }
5143
5257
  this.setY(y, snap, normalize);
5144
5258
  this.emitScrollableEvent();
5145
5259
  if (fireUpdate) {
@@ -5149,9 +5263,6 @@ class NgScrollView extends BaseScrollView {
5149
5263
  }
5150
5264
  else {
5151
5265
  if (this._x !== x || force) {
5152
- if (!blending) {
5153
- this.stopScrolling(force);
5154
- }
5155
5266
  this.setX(x, snap, normalize);
5156
5267
  this.emitScrollableEvent();
5157
5268
  if (fireUpdate) {
@@ -5160,6 +5271,7 @@ class NgScrollView extends BaseScrollView {
5160
5271
  }
5161
5272
  }
5162
5273
  }
5274
+ return -1;
5163
5275
  }
5164
5276
  emitScrollableEvent() {
5165
5277
  var _a, _b;
@@ -5180,6 +5292,9 @@ class NgScrollView extends BaseScrollView {
5180
5292
  this.stopScrolling();
5181
5293
  this.move(this._$isVertical.getValue(), offset);
5182
5294
  }
5295
+ stopAnimation(id) {
5296
+ this._animator.stop(id);
5297
+ }
5183
5298
  ngOnDestroy() {
5184
5299
  super.ngOnDestroy();
5185
5300
  if (this._animator) {
@@ -5851,6 +5966,10 @@ class NgScrollerComponent extends NgScrollView {
5851
5966
  $updateScrollBar.pipe(takeUntil(this._$unsubscribe), debounceTime(0), tap(() => {
5852
5967
  this.updateScrollBarHandler(!this._isScrollbarUserAction);
5853
5968
  })).subscribe();
5969
+ const $grabbing = this.$grabbing;
5970
+ $grabbing.pipe(takeUntil(this._$unsubscribe), tap(v => {
5971
+ this._service.grabbing = v;
5972
+ })).subscribe();
5854
5973
  combineLatest([this.$classes, this.$direction, this.$grabbing, this.$motionBlurEnabled]).pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), debounceTime(0), tap(([classes, direction, grabbing, filtered]) => {
5855
5974
  this._$actualClasses.next(Object.assign(Object.assign({}, classes), { [direction]: true, grabbing, filtered }));
5856
5975
  })).subscribe();
@@ -5993,7 +6112,7 @@ class NgScrollerComponent extends NgScrollView {
5993
6112
  this._isScrollbarUserAction = false;
5994
6113
  (_b = this.scrollBar) === null || _b === void 0 ? void 0 : _b.stopScrolling();
5995
6114
  }
5996
- this.scroll(Object.assign(Object.assign({}, params), { userAction: userAction }));
6115
+ return this.scroll(Object.assign(Object.assign({}, params), { userAction: userAction }));
5997
6116
  }
5998
6117
  stopScrollbar() {
5999
6118
  if (!!this.scrollBar) {
@@ -6402,13 +6521,13 @@ class NgPrerenderVirtualListItemComponent extends NgVirtualListItemComponent {
6402
6521
  }
6403
6522
  }
6404
6523
  NgPrerenderVirtualListItemComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgPrerenderVirtualListItemComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
6405
- NgPrerenderVirtualListItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: NgPrerenderVirtualListItemComponent, selector: "ng-prerender-virtual-list-item", host: { attributes: { "role": "listitem" }, classAttribute: "ngvl__item" }, usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"($data | async) as data\">\r\n <div #item class=\"ngvl-item\" [ngClass]=\"($classes | async)!\" [part]=\"($part | async)!\" [attr.ngvl-index]=\"($index | async)!\"\r\n [attr.ngvl-visibility]=\"visibility\" tabindex=\"-1\">\r\n <div *ngIf=\"_blendColor\" class=\"ngvl-item__blend-color\" [style.--blend-color]=\"_blendColor\"></div>\r\n <div #container virtualClick [part]=\"$fxPart | async\" [maxClickDistance]=\"$maxClickDistance | async\"\r\n class=\"ngvl-item__container\" [ngClass]=\"($classes | async)!\" (onVirtualClick)=\"onClickHandler()\">\r\n <ng-container [ngTemplateOutlet]=\"itemRenderer ?? null\"\r\n [ngTemplateOutletContext]=\"$templateContext | async\"></ng-container>\r\n </div>\r\n </div>\r\n</ng-container>", styles: [":host{display:block;position:absolute;left:0;top:0;box-sizing:border-box;overflow:hidden;-webkit-tap-highlight-color:transparent;-webkit-user-drag:none;-moz-user-drag:none;text-rendering:optimizeSpeed;image-rendering:auto}.ngvl-item{position:relative;margin:0;padding:0;overflow:hidden;outline:none;width:inherit;height:inherit;box-sizing:border-box}.ngvl-item__blend-color{position:absolute;left:0;top:0;width:100%;height:100%;background-color:var(--blend-color);z-index:-1}.ngvl-item__container{margin:0;padding:0;width:100%;height:100%;box-sizing:border-box}\n", ":host{display:block;position:absolute!important;left:0;top:0;box-sizing:border-box;overflow:hidden;-webkit-tap-highlight-color:transparent;-webkit-user-drag:none;-moz-user-drag:none;pointer-events:none;-webkit-user-select:none;user-select:none;text-rendering:optimizeSpeed;image-rendering:pixelated}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: VirtualClickDirective, selector: "[virtualClick]", inputs: ["maxClickDistance"], outputs: ["onVirtualClick"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
6524
+ NgPrerenderVirtualListItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: NgPrerenderVirtualListItemComponent, selector: "ng-prerender-virtual-list-item", host: { attributes: { "role": "listitem" }, classAttribute: "ngvl__item" }, usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"($data | async) as data\">\r\n <div #item class=\"ngvl-item\" [ngClass]=\"($classes | async)!\" [part]=\"($part | async)!\"\r\n [attr.ngvl-index]=\"($index | async)!\" [attr.ngvl-visibility]=\"visibility\" tabindex=\"-1\">\r\n <div *ngIf=\"_blendColor\" class=\"ngvl-item__blend-color\" [style.--blend-color]=\"_blendColor\"></div>\r\n <div #container virtualClick [part]=\"$fxPart | async\" [maxClickDistance]=\"($maxClickDistance | async)!\"\r\n class=\"ngvl-item__container\" [ngClass]=\"($classes | async)!\" (onVirtualClick)=\"onClickHandler()\"\r\n (onVirtualClickPress)=\"onClickPressHandler()\" (onVirtualClickCancel)=\"onClickCancelHandler()\">\r\n <ng-container [ngTemplateOutlet]=\"itemRenderer ?? null\"\r\n [ngTemplateOutletContext]=\"$templateContext | async\"></ng-container>\r\n </div>\r\n </div>\r\n</ng-container>", styles: [":host{display:block;position:absolute;left:0;top:0;box-sizing:border-box;overflow:hidden;-webkit-tap-highlight-color:transparent;-webkit-user-drag:none;-moz-user-drag:none;text-rendering:optimizeSpeed;image-rendering:auto}.ngvl-item{position:relative;margin:0;padding:0;overflow:hidden;outline:none;width:inherit;height:inherit;box-sizing:border-box}.ngvl-item__blend-color{position:absolute;left:0;top:0;width:100%;height:100%;background-color:var(--blend-color);z-index:-1}.ngvl-item__container{margin:0;padding:0;width:100%;height:100%;box-sizing:border-box}\n", ":host{display:block;position:absolute!important;left:0;top:0;box-sizing:border-box;overflow:hidden;-webkit-tap-highlight-color:transparent;-webkit-user-drag:none;-moz-user-drag:none;pointer-events:none;-webkit-user-select:none;user-select:none;text-rendering:optimizeSpeed;image-rendering:pixelated}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: VirtualClickDirective, selector: "[virtualClick]", inputs: ["maxClickDistance"], outputs: ["onVirtualClick", "onVirtualClickPress", "onVirtualClickCancel"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
6406
6525
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgPrerenderVirtualListItemComponent, decorators: [{
6407
6526
  type: Component,
6408
6527
  args: [{ selector: 'ng-prerender-virtual-list-item', host: {
6409
6528
  'class': 'ngvl__item',
6410
6529
  'role': 'listitem',
6411
- }, standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"($data | async) as data\">\r\n <div #item class=\"ngvl-item\" [ngClass]=\"($classes | async)!\" [part]=\"($part | async)!\" [attr.ngvl-index]=\"($index | async)!\"\r\n [attr.ngvl-visibility]=\"visibility\" tabindex=\"-1\">\r\n <div *ngIf=\"_blendColor\" class=\"ngvl-item__blend-color\" [style.--blend-color]=\"_blendColor\"></div>\r\n <div #container virtualClick [part]=\"$fxPart | async\" [maxClickDistance]=\"$maxClickDistance | async\"\r\n class=\"ngvl-item__container\" [ngClass]=\"($classes | async)!\" (onVirtualClick)=\"onClickHandler()\">\r\n <ng-container [ngTemplateOutlet]=\"itemRenderer ?? null\"\r\n [ngTemplateOutletContext]=\"$templateContext | async\"></ng-container>\r\n </div>\r\n </div>\r\n</ng-container>", styles: [":host{display:block;position:absolute;left:0;top:0;box-sizing:border-box;overflow:hidden;-webkit-tap-highlight-color:transparent;-webkit-user-drag:none;-moz-user-drag:none;text-rendering:optimizeSpeed;image-rendering:auto}.ngvl-item{position:relative;margin:0;padding:0;overflow:hidden;outline:none;width:inherit;height:inherit;box-sizing:border-box}.ngvl-item__blend-color{position:absolute;left:0;top:0;width:100%;height:100%;background-color:var(--blend-color);z-index:-1}.ngvl-item__container{margin:0;padding:0;width:100%;height:100%;box-sizing:border-box}\n", ":host{display:block;position:absolute!important;left:0;top:0;box-sizing:border-box;overflow:hidden;-webkit-tap-highlight-color:transparent;-webkit-user-drag:none;-moz-user-drag:none;pointer-events:none;-webkit-user-select:none;user-select:none;text-rendering:optimizeSpeed;image-rendering:pixelated}\n"] }]
6530
+ }, standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"($data | async) as data\">\r\n <div #item class=\"ngvl-item\" [ngClass]=\"($classes | async)!\" [part]=\"($part | async)!\"\r\n [attr.ngvl-index]=\"($index | async)!\" [attr.ngvl-visibility]=\"visibility\" tabindex=\"-1\">\r\n <div *ngIf=\"_blendColor\" class=\"ngvl-item__blend-color\" [style.--blend-color]=\"_blendColor\"></div>\r\n <div #container virtualClick [part]=\"$fxPart | async\" [maxClickDistance]=\"($maxClickDistance | async)!\"\r\n class=\"ngvl-item__container\" [ngClass]=\"($classes | async)!\" (onVirtualClick)=\"onClickHandler()\"\r\n (onVirtualClickPress)=\"onClickPressHandler()\" (onVirtualClickCancel)=\"onClickCancelHandler()\">\r\n <ng-container [ngTemplateOutlet]=\"itemRenderer ?? null\"\r\n [ngTemplateOutletContext]=\"$templateContext | async\"></ng-container>\r\n </div>\r\n </div>\r\n</ng-container>", styles: [":host{display:block;position:absolute;left:0;top:0;box-sizing:border-box;overflow:hidden;-webkit-tap-highlight-color:transparent;-webkit-user-drag:none;-moz-user-drag:none;text-rendering:optimizeSpeed;image-rendering:auto}.ngvl-item{position:relative;margin:0;padding:0;overflow:hidden;outline:none;width:inherit;height:inherit;box-sizing:border-box}.ngvl-item__blend-color{position:absolute;left:0;top:0;width:100%;height:100%;background-color:var(--blend-color);z-index:-1}.ngvl-item__container{margin:0;padding:0;width:100%;height:100%;box-sizing:border-box}\n", ":host{display:block;position:absolute!important;left:0;top:0;box-sizing:border-box;overflow:hidden;-webkit-tap-highlight-color:transparent;-webkit-user-drag:none;-moz-user-drag:none;pointer-events:none;-webkit-user-select:none;user-select:none;text-rendering:optimizeSpeed;image-rendering:pixelated}\n"] }]
6412
6531
  }] });
6413
6532
 
6414
6533
  /**
@@ -7945,6 +8064,7 @@ class NgVirtualListComponent extends DisposableComponent {
7945
8064
  this._readyForShow = false;
7946
8065
  this._cached = false;
7947
8066
  this._isLoading = false;
8067
+ this._animationId = -1;
7948
8068
  this._$viewInit = new BehaviorSubject(false);
7949
8069
  this.$viewInit = this._$viewInit.asObservable();
7950
8070
  this._$destroy = new Subject();
@@ -8476,7 +8596,7 @@ class NgVirtualListComponent extends DisposableComponent {
8476
8596
  ;
8477
8597
  get motionBlurEnabled() { return this._$motionBlurEnabled.getValue(); }
8478
8598
  /**
8479
- * Animation parameters. The default value is "{ scrollToItem: 50, snapToItem: 150, navigateToItem: 150, navigateByKeyboard: 50 }".
8599
+ * Animation parameters. The default value is "{ scrollToItem: 150, snapToItem: 150, navigateToItem: 150, navigateByKeyboard: 50 }".
8480
8600
  */
8481
8601
  set animationParams(v) {
8482
8602
  if (this._$animationParams.getValue() === v) {
@@ -8766,6 +8886,7 @@ class NgVirtualListComponent extends DisposableComponent {
8766
8886
  }
8767
8887
  ngAfterViewInit() {
8768
8888
  var _a, _b;
8889
+ let readyForAnimations = false;
8769
8890
  const _$created = new BehaviorSubject(false), $created = _$created.asObservable();
8770
8891
  combineLatest([$created, this.$show]).pipe(takeUntil(this._$unsubscribe), filter$1(([created, shown]) => created && shown), debounceTime(1), tap(v => {
8771
8892
  this._$initialized.next(true);
@@ -8964,6 +9085,7 @@ class NgVirtualListComponent extends DisposableComponent {
8964
9085
  }), tap(items => {
8965
9086
  this._trackBox.resetCollection(items, this.actualItemSize);
8966
9087
  }), switchMap$1(i => of((i !== null && i !== void 0 ? i : []).length > 0)), distinctUntilChanged(), tap(v => {
9088
+ readyForAnimations = false;
8967
9089
  if (!v) {
8968
9090
  this.cacheClean();
8969
9091
  this.cleanup();
@@ -9308,13 +9430,23 @@ class NgVirtualListComponent extends DisposableComponent {
9308
9430
  }), debounceTime(100), tap(() => {
9309
9431
  this._isLoading = false;
9310
9432
  })).subscribe();
9433
+ let prevCacheVersion = -1, prevScrollable = false;
9434
+ $viewInit.pipe(takeUntil(this._$unsubscribe), filter$1(v => !!v), switchMap$1(() => {
9435
+ return this.$show.pipe(takeUntil(this._$unsubscribe), debounceTime(Math.max(500, this._$animationParams.getValue().scrollToItem)), tap(() => {
9436
+ if (this._readyForShow || (this.cachable && this._cached)) {
9437
+ readyForAnimations = true;
9438
+ }
9439
+ }));
9440
+ })).subscribe();
9311
9441
  const update = (params) => {
9312
- var _a, _b;
9313
- const { alignment, snapScrollToStart, snapScrollToEnd, bounds, items, itemConfigMap, scrollSize, itemSize, minItemSize, maxItemSize, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, enabledBufferOptimization, snapToItem, snapToItemAlign, userAction, collapsedIds, itemTransform, } = params;
9442
+ var _a, _b, _c, _d;
9443
+ const { alignment, snapScrollToStart, snapScrollToEnd, bounds, items, itemConfigMap, scrollSize, itemSize, minItemSize, maxItemSize, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, enabledBufferOptimization, snapToItem, snapToItemAlign, userAction, collapsedIds, cacheVersion, itemTransform, } = params;
9444
+ const cacheChanged = prevCacheVersion !== cacheVersion;
9445
+ prevCacheVersion = cacheVersion;
9314
9446
  const scroller = this._scrollerComponent;
9315
9447
  let totalSize = 0;
9316
9448
  if (!!scroller) {
9317
- 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;
9449
+ 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;
9318
9450
  if (this._readyForShow || (cachable && cached)) {
9319
9451
  const currentScrollSize = (isVertical ? scroller.scrollTop : scroller.scrollLeft);
9320
9452
  let actualScrollSize = !this._readyForShow && snapScrollToEnd ? (isVertical ? scroller.scrollHeight : scroller.scrollWidth) :
@@ -9358,12 +9490,13 @@ class NgVirtualListComponent extends DisposableComponent {
9358
9490
  if (!_$created.getValue()) {
9359
9491
  _$created.next(true);
9360
9492
  }
9361
- const delta = this._trackBox.delta, scrollPositionAfterUpdate = actualScrollSize + delta, roundedScrollPositionAfterUpdate = scrollPositionAfterUpdate, roundedMaxPositionAfterUpdate = isVertical ? scroller.scrollHeight : scroller.scrollWidth;
9493
+ const delta = this._trackBox.delta, scrollPositionAfterUpdate = actualScrollSize + delta, roundedScrollPositionAfterUpdate = scrollPositionAfterUpdate, roundedMaxPositionAfterUpdate = isVertical ? scroller.actualScrollHeight : scroller.actualScrollWidth;
9362
9494
  if (this._isSnappingMethodAdvanced) {
9363
9495
  this.updateRegularRenderer();
9364
9496
  }
9365
9497
  this.updateOffsetsByAllignment();
9366
9498
  scroller.delta = delta;
9499
+ prevScrollable = scroller.scrollable;
9367
9500
  if ((snapScrollToStart && this._trackBox.isSnappedToStart && scroller.scrollable) ||
9368
9501
  (snapScrollToStart && currentScrollSize <= MIN_PIXELS_FOR_PREVENT_SNAPPING)) {
9369
9502
  if (currentScrollSize !== roundedScrollPositionAfterUpdate) {
@@ -9374,10 +9507,17 @@ class NgVirtualListComponent extends DisposableComponent {
9374
9507
  this._trackBox.isScrollEnd;
9375
9508
  const params = {
9376
9509
  [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: 0, userAction,
9377
- fireUpdate: fireUpdateAtEdges, behavior: BEHAVIOR_INSTANT,
9378
- blending: false, duration: this.animationParams.scrollToItem,
9510
+ fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams.scrollToItem > 0 && this.scrollBehavior !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT),
9511
+ blending: useAnimations && scroller.hasAnimation(this._animationId), duration: this.animationParams.scrollToItem,
9379
9512
  };
9380
- (_a = scroller === null || scroller === void 0 ? void 0 : scroller.scrollTo) === null || _a === void 0 ? void 0 : _a.call(scroller, params);
9513
+ const animationId = (_a = scroller === null || scroller === void 0 ? void 0 : scroller.scrollTo) === null || _a === void 0 ? void 0 : _a.call(scroller, params);
9514
+ if (animationId > -1) {
9515
+ this._animationId = animationId;
9516
+ }
9517
+ else {
9518
+ scroller.stopAnimation(this._animationId);
9519
+ }
9520
+ (_b = scroller === null || scroller === void 0 ? void 0 : scroller.scrollTo) === null || _b === void 0 ? void 0 : _b.call(scroller, params);
9381
9521
  if (emitUpdate) {
9382
9522
  this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
9383
9523
  }
@@ -9397,10 +9537,17 @@ class NgVirtualListComponent extends DisposableComponent {
9397
9537
  }
9398
9538
  const params = {
9399
9539
  [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: roundedMaxPositionAfterUpdate,
9400
- fireUpdate: fireUpdateAtEdges, behavior: BEHAVIOR_INSTANT, userAction: false,
9401
- blending: false, duration: this.animationParams.scrollToItem,
9540
+ fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams.scrollToItem > 0 && this.scrollBehavior !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT), userAction: false,
9541
+ blending: useAnimations && scroller.hasAnimation(this._animationId) || cacheChanged, duration: this.animationParams.scrollToItem,
9402
9542
  };
9403
- (_b = scroller === null || scroller === void 0 ? void 0 : scroller.scrollTo) === null || _b === void 0 ? void 0 : _b.call(scroller, params);
9543
+ const animationId = (_c = scroller === null || scroller === void 0 ? void 0 : scroller.scrollTo) === null || _c === void 0 ? void 0 : _c.call(scroller, params);
9544
+ if (animationId > -1) {
9545
+ this._animationId = animationId;
9546
+ }
9547
+ else {
9548
+ scroller.stopAnimation(this._animationId);
9549
+ }
9550
+ (_d = scroller === null || scroller === void 0 ? void 0 : scroller.scrollTo) === null || _d === void 0 ? void 0 : _d.call(scroller, params);
9404
9551
  if (emitUpdate) {
9405
9552
  this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
9406
9553
  }
@@ -9413,9 +9560,13 @@ class NgVirtualListComponent extends DisposableComponent {
9413
9560
  if (this._readyForShow) {
9414
9561
  this.emitScrollEvent(true, false, userAction);
9415
9562
  }
9563
+ if (this._animationId > -1) {
9564
+ scroller.stopAnimation(this._animationId);
9565
+ this._animationId = -1;
9566
+ }
9416
9567
  const params = {
9417
9568
  [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollPositionAfterUpdate, blending: true, userAction,
9418
- fireUpdate, behavior: BEHAVIOR_INSTANT, duration: this.animationParams.scrollToItem,
9569
+ fireUpdate, behavior: BEHAVIOR_INSTANT, duration: 0,
9419
9570
  };
9420
9571
  scroller.scrollTo(params);
9421
9572
  if (emitUpdate) {
@@ -10141,7 +10292,7 @@ class NgVirtualListComponent extends DisposableComponent {
10141
10292
  comp === null || comp === void 0 ? void 0 : comp.destroy();
10142
10293
  }
10143
10294
  }
10144
- if (this._displayComponents) {
10295
+ if (!!this._displayComponents) {
10145
10296
  while (this._displayComponents.length > 0) {
10146
10297
  const comp = this._displayComponents.shift();
10147
10298
  comp === null || comp === void 0 ? void 0 : comp.destroy();