ng-virtual-list 14.12.2 → 14.12.3

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 +31 -8
  15. package/fesm2015/ng-virtual-list.mjs +219 -70
  16. package/fesm2015/ng-virtual-list.mjs.map +1 -1
  17. package/fesm2020/ng-virtual-list.mjs +214 -66
  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 +10 -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) {
@@ -1226,6 +1259,9 @@ class BaseVirtualListItemComponent extends DisposableComponent {
1226
1259
  this._id = this._service.generateComponentId();
1227
1260
  this._listId = this._service.id;
1228
1261
  this._displayId = createDisplayId(this._listId, this._id);
1262
+ this._service.$isGrabbing.pipe(takeUntil(this._$unsubscribe), tap(v => {
1263
+ this.updateConfig(this._data, v);
1264
+ })).subscribe();
1229
1265
  const $part = this.$part;
1230
1266
  $part.pipe(takeUntil(this._$unsubscribe), tap(part => {
1231
1267
  this._elementRef.nativeElement.setAttribute('part', part);
@@ -1282,7 +1318,7 @@ class BaseVirtualListItemComponent extends DisposableComponent {
1282
1318
  }
1283
1319
  this._data = v;
1284
1320
  this.updatePartStr(v, this._isSelected, this._isCollapsed);
1285
- this.updateConfig(v);
1321
+ this.updateConfig(v, this._service.isGrabbing);
1286
1322
  this.updateMeasures(v);
1287
1323
  this.update();
1288
1324
  this._$data.next(v);
@@ -1320,9 +1356,9 @@ class BaseVirtualListItemComponent extends DisposableComponent {
1320
1356
  this._$measures.next(v?.measures ? { ...v.measures } : null);
1321
1357
  this._cdr.markForCheck();
1322
1358
  }
1323
- updateConfig(v) {
1359
+ updateConfig(v, grabbing) {
1324
1360
  this._$config.next({
1325
- ...v?.config || {}, selected: this._isSelected, collapsed: this._isCollapsed, focused: this._$focused.getValue(),
1361
+ ...v?.config || {}, selected: this._isSelected, collapsed: this._isCollapsed, focused: this._$focused.getValue(), grabbing,
1326
1362
  });
1327
1363
  this._cdr.markForCheck();
1328
1364
  }
@@ -1451,6 +1487,7 @@ class BaseVirtualListItemComponent extends DisposableComponent {
1451
1487
  }
1452
1488
  const el = this._elementRef.nativeElement, styles = el.style;
1453
1489
  styles.zIndex = HIDDEN_ZINDEX;
1490
+ styles.transform = INVISIBLE_TRANSLATE_3D;
1454
1491
  if (this.regular) {
1455
1492
  if (styles.display === DISPLAY_NONE) {
1456
1493
  return;
@@ -1483,9 +1520,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
1483
1520
  args: ['container']
1484
1521
  }] } });
1485
1522
 
1486
- const DEFAULT_MAX_DISTANCE = 40;
1487
1523
  /**
1488
- * ItemClickDirective
1524
+ * VirtualClickDirective
1489
1525
  * Maximum performance for extremely large lists.
1490
1526
  * It is based on algorithms for virtualization of screen objects.
1491
1527
  * @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/directives/item-click/item-click.directive.ts
@@ -1493,26 +1529,39 @@ const DEFAULT_MAX_DISTANCE = 40;
1493
1529
  * @email djonnyx@gmail.com
1494
1530
  */
1495
1531
  class VirtualClickDirective {
1496
- constructor(_elementRef) {
1497
- this._elementRef = _elementRef;
1532
+ constructor() {
1498
1533
  this._$unsubscribe = new Subject();
1499
- this._maxDistance = DEFAULT_MAX_DISTANCE;
1534
+ this._$maxDistance = new BehaviorSubject(null);
1535
+ this.$maxDistance = this._$maxDistance.asObservable();
1536
+ this._maxDistance = null;
1500
1537
  this.onVirtualClick = new EventEmitter$1();
1538
+ this.onVirtualClickPress = new EventEmitter$1();
1539
+ this.onVirtualClickCancel = new EventEmitter$1();
1540
+ this._service = inject(NgVirtualListService);
1541
+ this._elementRef = inject(ElementRef);
1542
+ let maxDistance = this._maxDistance ?? DEFAULT_CLICK_DISTANCE;
1543
+ combineLatest([this._service.$clickDistance, this.$maxDistance]).pipe(takeUntil$1(this._$unsubscribe), tap$1(([clickDistance, distance]) => {
1544
+ maxDistance = distance === null ? clickDistance : distance;
1545
+ })).subscribe();
1501
1546
  const $pointerPressed = fromEvent(this._elementRef.nativeElement, 'pointerdown'), $pointerCancel = race([
1502
1547
  fromEvent(window, 'pointerup').pipe(takeUntil$1(this._$unsubscribe)),
1503
1548
  fromEvent(window, 'pointerleave').pipe(takeUntil$1(this._$unsubscribe)),
1504
1549
  ]), $pointerRelease = fromEvent(this._elementRef.nativeElement, 'pointerup', { passive: false });
1505
1550
  $pointerPressed.pipe(takeUntil$1(this._$unsubscribe), switchMap(e => {
1506
1551
  const x = Math.abs(e.clientX), y = Math.abs(e.clientY);
1552
+ this.onVirtualClickPress.emit(e);
1507
1553
  return $pointerRelease.pipe(takeUntil$1(this._$unsubscribe), takeUntil$1(race([
1508
- $pointerCancel,
1554
+ $pointerCancel.pipe(takeUntil$1(this._$unsubscribe), tap$1(() => {
1555
+ this.onVirtualClickCancel.emit();
1556
+ })),
1509
1557
  fromEvent(window, 'pointermove').pipe(takeUntil$1(this._$unsubscribe), switchMap(e => {
1510
1558
  const xx = x - Math.abs(e.clientX), yy = y - Math.abs(e.clientY), dist = Math.sqrt(Math.pow(xx, 2) + Math.pow(yy, 2));
1511
- if (dist > this._maxDistance) {
1559
+ if (dist > maxDistance) {
1560
+ this.onVirtualClickCancel.emit();
1512
1561
  return of(true);
1513
1562
  }
1514
1563
  return of(false);
1515
- }), takeUntil$1(this._$unsubscribe), filter(v => !!v)),
1564
+ }), filter(v => !!v)),
1516
1565
  ])), takeUntil$1(this._$unsubscribe), tap$1(e => {
1517
1566
  if (e) {
1518
1567
  this.onVirtualClick.emit(e);
@@ -1521,7 +1570,9 @@ class VirtualClickDirective {
1521
1570
  })).subscribe();
1522
1571
  }
1523
1572
  set maxDistance(v) {
1524
- this._maxDistance = (v !== null || v !== undefined) ? Number(v) : DEFAULT_MAX_DISTANCE;
1573
+ const value = (v !== null || v !== undefined) ? Number(v) : null;
1574
+ this._maxDistance = value;
1575
+ this._$maxDistance.next(value);
1525
1576
  }
1526
1577
  ngOnDestroy() {
1527
1578
  if (this._$unsubscribe) {
@@ -1530,19 +1581,23 @@ class VirtualClickDirective {
1530
1581
  }
1531
1582
  }
1532
1583
  }
1533
- VirtualClickDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: VirtualClickDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
1534
- 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 });
1584
+ VirtualClickDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: VirtualClickDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1585
+ 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 });
1535
1586
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: VirtualClickDirective, decorators: [{
1536
1587
  type: Directive,
1537
1588
  args: [{
1538
1589
  selector: '[virtualClick]',
1539
1590
  standalone: false,
1540
1591
  }]
1541
- }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { maxDistance: [{
1592
+ }], ctorParameters: function () { return []; }, propDecorators: { maxDistance: [{
1542
1593
  type: Input,
1543
1594
  args: ['maxClickDistance']
1544
1595
  }], onVirtualClick: [{
1545
1596
  type: Output
1597
+ }], onVirtualClickPress: [{
1598
+ type: Output
1599
+ }], onVirtualClickCancel: [{
1600
+ type: Output
1546
1601
  }] } });
1547
1602
 
1548
1603
  /**
@@ -1574,12 +1629,12 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
1574
1629
  fromEvent(this.element, EVENT_FOCUS_IN).pipe(takeUntil(this._$unsubscribe), tap(e => {
1575
1630
  this._service.focusedId = this.itemId ?? null;
1576
1631
  this._$focused.next(true);
1577
- this.updateConfig(this._data);
1632
+ this.updateConfig(this._data, this._service.isGrabbing);
1578
1633
  this.updatePartStr(this._data, this._isSelected, this._isCollapsed);
1579
1634
  })).subscribe(),
1580
1635
  fromEvent(this.element, EVENT_FOCUS_OUT).pipe(takeUntil(this._$unsubscribe), tap(e => {
1581
1636
  this._$focused.next(false);
1582
- this.updateConfig(this._data);
1637
+ this.updateConfig(this._data, this._service.isGrabbing);
1583
1638
  this.updatePartStr(this._data, this._isSelected, this._isCollapsed);
1584
1639
  })).subscribe();
1585
1640
  $focused.pipe(takeUntil(this._$unsubscribe), debounceTime(this.getNavigationTimeout()), switchMap$1(v => {
@@ -1612,7 +1667,7 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
1612
1667
  const actualIds = collapsedIds, isCollapsed = this.itemId !== undefined && actualIds && actualIds.includes(this.itemId);
1613
1668
  this._isCollapsed = isCollapsed;
1614
1669
  this.updatePartStr(this._data, this._isSelected, isCollapsed);
1615
- this.updateConfig(this._data);
1670
+ this.updateConfig(this._data, this._service.isGrabbing);
1616
1671
  this.updateMeasures(this._data);
1617
1672
  })).subscribe();
1618
1673
  }
@@ -1715,24 +1770,30 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
1715
1770
  }
1716
1771
  return Number.MIN_SAFE_INTEGER;
1717
1772
  }
1718
- updateConfig(v) {
1773
+ updateConfig(v, grabbing) {
1719
1774
  this._$config.next({
1720
- ...v?.config || {}, selected: this._isSelected, collapsed: this._isCollapsed, focused: this._$focused.getValue(),
1775
+ ...v?.config || {}, selected: this._isSelected, collapsed: this._isCollapsed, focused: this._$focused.getValue(), grabbing,
1721
1776
  });
1722
1777
  this._cdr.markForCheck();
1723
1778
  }
1724
1779
  onClickHandler() {
1725
1780
  this._service.virtualClick(this._data);
1726
1781
  }
1782
+ onClickPressHandler() {
1783
+ this._service.clickPressed = true;
1784
+ }
1785
+ onClickCancelHandler() {
1786
+ this._service.clickPressed = false;
1787
+ }
1727
1788
  }
1728
1789
  NgVirtualListItemComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgVirtualListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1729
- 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 });
1790
+ 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 });
1730
1791
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgVirtualListItemComponent, decorators: [{
1731
1792
  type: Component,
1732
1793
  args: [{ selector: 'ng-virtual-list-item', host: {
1733
1794
  'class': 'ngvl__item',
1734
1795
  'role': 'listitem',
1735
- }, 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"] }]
1796
+ }, 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"] }]
1736
1797
  }], ctorParameters: function () { return []; } });
1737
1798
 
1738
1799
  /**
@@ -3286,7 +3347,7 @@ class TrackBox extends CacheMap {
3286
3347
  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
3348
  if (items.length) {
3288
3349
  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;
3350
+ let pos = startPosition, renderItems = renderItemsLength, stickyItem, nextSticky, stickyItemIndex = -1, nexstStickyItemIndex = -1, stickyItemSize = 0, endStickyItem, nextEndSticky, endStickyItemIndex = -1, endStickyItemSize = 0;
3290
3351
  const li = layoutIndexOffset + actualItems.length - 1;
3291
3352
  if (stickyEnabled) {
3292
3353
  for (let i = Math.min(itemsFromStartToScrollEnd > 0 ? (divides > 1 ? (itemsFromStartToScrollEnd - 1) : itemsFromStartToScrollEnd) : 0, totalLength - 1); i >= 0; i--) {
@@ -3546,6 +3607,7 @@ class TrackBox extends CacheMap {
3546
3607
  item.measures.x = isVertical ? 0 : snapped ? actualSnippedPosition : pos;
3547
3608
  item.measures.y = isVertical ? snapped ? actualSnippedPosition : pos : 0;
3548
3609
  nextSticky = item;
3610
+ nexstStickyItemIndex = displayItems.length;
3549
3611
  nextSticky.config.snapped = snapped;
3550
3612
  nextSticky.measures.delta = (isVertical ? item.measures.y : item.measures.x) - scrollSize;
3551
3613
  nextSticky.config.zIndex = Z_INDEX_3;
@@ -3568,10 +3630,10 @@ class TrackBox extends CacheMap {
3568
3630
  }
3569
3631
  i++;
3570
3632
  }
3571
- const axis = isVertical ? Y_PROP_NAME : X_PROP_NAME;
3633
+ const axis = isVertical ? Y_PROP_NAME : X_PROP_NAME, transformedAxis = isVertical ? TRANSFORMED_Y_PROP_NAME : TRANSFORMED_X_PROP_NAME;
3572
3634
  if (!!nextSticky && !!stickyItem && nextSticky.measures[axis] <= actualSnippedPosition + stickyItem.measures[sizeProperty]) {
3573
3635
  if (nextSticky.measures[axis] > actualSnippedPosition) {
3574
- stickyItem.measures[axis] = nextSticky.measures[axis] - stickyItem.measures[sizeProperty];
3636
+ stickyItem.measures[axis] = stickyItem.measures[transformedAxis] = nextSticky.measures[axis] - stickyItem.measures[sizeProperty];
3575
3637
  stickyItem.config.snapped = nextSticky.config.snapped = false;
3576
3638
  stickyItem.config.snappedOut = true;
3577
3639
  stickyItem.config.sticky = 1;
@@ -3580,14 +3642,35 @@ class TrackBox extends CacheMap {
3580
3642
  else {
3581
3643
  nextSticky.config.snapped = true;
3582
3644
  nextSticky.measures.delta = (isVertical ? nextSticky.measures.y : nextSticky.measures.x) - scrollSize;
3583
- stickyItem.measures[axis] = nextSticky.measures[axis] - stickyItem.measures[sizeProperty];
3645
+ stickyItem.measures[axis] = stickyItem.measures[transformedAxis] = nextSticky.measures[axis] - stickyItem.measures[sizeProperty];
3584
3646
  stickyItem.measures.delta = (isVertical ? stickyItem.measures.y : stickyItem.measures.x) - scrollSize;
3647
+ const lastStickyItem = displayItems?.[nexstStickyItemIndex + 1];
3648
+ if (lastStickyItem?.config?.sticky === 1 && displayItems?.[nexstStickyItemIndex + 2]?.config?.sticky !== 1) {
3649
+ nextSticky.config.snapped = nextSticky.config.snappedOut = false;
3650
+ stickyItem.config.snappedOut = true;
3651
+ nextSticky.measures.delta = this._scrollStartOffset;
3652
+ if (lastStickyItem.measures[axis] <= actualSnippedPosition) {
3653
+ lastStickyItem.config.snapped = lastStickyItem.config.snappedOut = true;
3654
+ lastStickyItem.measures[axis] = lastStickyItem.measures[transformedAxis] = lastStickyItem.measures.position = actualSnippedPosition;
3655
+ lastStickyItem.measures.delta = this._scrollStartOffset;
3656
+ }
3657
+ }
3658
+ else if (lastStickyItem?.config?.sticky !== 1 && displayItems?.[nexstStickyItemIndex + 2]?.config?.sticky !== 1) {
3659
+ if (nextSticky.measures[axis] <= actualSnippedPosition) {
3660
+ nextSticky.config.snapped = nextSticky.config.snappedOut = true;
3661
+ nextSticky.measures[axis] = nextSticky.measures[transformedAxis] = nextSticky.measures.position = actualSnippedPosition;
3662
+ nextSticky.measures.delta = this._scrollStartOffset;
3663
+ }
3664
+ }
3665
+ else {
3666
+ nextSticky.config.snapped = nextSticky.config.snappedOut = false;
3667
+ }
3585
3668
  }
3586
3669
  }
3587
3670
  if (!!nextEndSticky && !!endStickyItem &&
3588
3671
  (nextEndSticky.measures[axis] >= actualEndSnippedPosition - endStickyItemSize - nextEndSticky.measures[sizeProperty])) {
3589
3672
  if (nextEndSticky.measures[axis] < actualEndSnippedPosition - nextEndSticky.measures[sizeProperty]) {
3590
- endStickyItem.measures[axis] = nextEndSticky.measures[axis] + nextEndSticky.measures[sizeProperty];
3673
+ endStickyItem.measures[axis] = endStickyItem.measures[transformedAxis] = nextEndSticky.measures[axis] + nextEndSticky.measures[sizeProperty];
3591
3674
  endStickyItem.config.snapped = nextEndSticky.config.snapped = false;
3592
3675
  endStickyItem.config.snappedOut = true;
3593
3676
  endStickyItem.config.sticky = 2;
@@ -3595,9 +3678,9 @@ class TrackBox extends CacheMap {
3595
3678
  }
3596
3679
  else {
3597
3680
  nextEndSticky.config.snapped = true;
3598
- nextEndSticky.measures[axis] = actualEndSnippedPosition - nextEndSticky.measures[sizeProperty];
3681
+ nextEndSticky.measures[axis] = nextEndSticky.measures[transformedAxis] = actualEndSnippedPosition - nextEndSticky.measures[sizeProperty];
3599
3682
  nextEndSticky.measures.delta = (isVertical ? nextEndSticky.measures.y : nextEndSticky.measures.x) - scrollSize;
3600
- endStickyItem.measures[axis] = nextEndSticky.measures[axis] + nextEndSticky.measures[sizeProperty];
3683
+ endStickyItem.measures[axis] = endStickyItem.measures[transformedAxis] = nextEndSticky.measures[axis] + nextEndSticky.measures[sizeProperty];
3601
3684
  endStickyItem.measures.delta = (isVertical ? endStickyItem.measures.y : endStickyItem.measures.x) - scrollSize;
3602
3685
  }
3603
3686
  }
@@ -3871,18 +3954,32 @@ class Animator {
3871
3954
  constructor() {
3872
3955
  this._animationId = 0;
3873
3956
  this._currentId = Animator._nextId;
3957
+ this._diff = 0;
3958
+ this._startValue = 0;
3959
+ this._endValue = 0;
3874
3960
  }
3961
+ get animated() { return this._animationId > -1; }
3962
+ get isAnimated() { return this.hasAnimation(this._currentId); }
3963
+ get id() { return this._currentId; }
3875
3964
  generateId() {
3876
3965
  return Animator._nextId = Animator._nextId === Number.MAX_SAFE_INTEGER
3877
3966
  ? 0 : Animator._nextId + 1;
3878
3967
  }
3968
+ updateTo(value) {
3969
+ this._endValue = value;
3970
+ this._diff = this._endValue - this._startValue;
3971
+ return this.hasAnimation();
3972
+ }
3879
3973
  animate(params) {
3880
3974
  this.stop();
3881
3975
  const id = this.generateId();
3882
3976
  this._currentId = id;
3883
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;
3884
3980
  const startTime = performance.now();
3885
- let isCanceled = false, prevPos = startValue, start = startValue, startPosDelta = 0, delta = 0, prevTime = startTime, diff = endValue - start, isFinished = false;
3981
+ let isCanceled = false, prevPos = startValue, startPosDelta = 0, delta = 0, prevTime = startTime, isFinished = false;
3982
+ this._diff = this._endValue - this._startValue;
3886
3983
  const step = (currentTime) => {
3887
3984
  if (id !== this._currentId) {
3888
3985
  isCanceled = true;
@@ -3896,10 +3993,10 @@ class Animator {
3896
3993
  startDelta = cPos - prevPos;
3897
3994
  startPosDelta += startDelta;
3898
3995
  }
3899
- 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();
3996
+ 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();
3900
3997
  isFinished = progress === 1;
3901
3998
  delta = currentValue - startDelta - prevPos;
3902
- const ts = t - prevTime, timestamp = ts < ANIMATOR_MIN_TIMESTAMP ? ANIMATOR_MIN_TIMESTAMP : ts;
3999
+ const frameTimestamp = t - prevTime, actualFrameTimestamp = frameTimestamp < ANIMATOR_MIN_TIMESTAMP ? ANIMATOR_MIN_TIMESTAMP : frameTimestamp;
3903
4000
  prevTime = t;
3904
4001
  prevPos = currentValue;
3905
4002
  if (onUpdate !== undefined) {
@@ -3908,18 +4005,19 @@ class Animator {
3908
4005
  delta,
3909
4006
  elapsed,
3910
4007
  value: !withDelta && isFinished ? endValue : currentValue,
3911
- timestamp,
4008
+ timestamp: actualFrameTimestamp,
3912
4009
  };
3913
4010
  onUpdate(data);
3914
4011
  }
3915
4012
  if (isFinished) {
4013
+ this._animationId = -1;
3916
4014
  if (onComplete !== undefined) {
3917
4015
  const data = {
3918
4016
  id,
3919
4017
  delta,
3920
4018
  elapsed,
3921
4019
  value: withDelta ? currentValue : endValue,
3922
- timestamp,
4020
+ timestamp: actualFrameTimestamp,
3923
4021
  };
3924
4022
  onComplete(data);
3925
4023
  }
@@ -3929,9 +4027,17 @@ class Animator {
3929
4027
  }
3930
4028
  };
3931
4029
  this._animationId = requestAnimationFrame(step);
4030
+ return this._currentId;
4031
+ }
4032
+ hasAnimation(id = -1) {
4033
+ if ((this._currentId === id || id === -1) && this.animated) {
4034
+ return true;
4035
+ }
4036
+ return false;
3932
4037
  }
3933
- stop() {
3934
- cancelAnimationFrame(this._animationId);
4038
+ stop(id = -1) {
4039
+ cancelAnimationFrame(id === -1 ? this._animationId : id);
4040
+ this._animationId = -1;
3935
4041
  }
3936
4042
  dispose() {
3937
4043
  this.stop();
@@ -4518,6 +4624,7 @@ class NgScrollView extends BaseScrollView {
4518
4624
  }
4519
4625
  }
4520
4626
  get startLayoutOffset() { return this._startLayoutOffset; }
4627
+ get animated() { return this._animator?.isAnimated ?? false; }
4521
4628
  ngAfterViewInit() {
4522
4629
  let mouseCanceled = false, touchCanceled = false;
4523
4630
  const $viewportBounds = this.$viewportBounds;
@@ -4708,6 +4815,7 @@ class NgScrollView extends BaseScrollView {
4708
4815
  }));
4709
4816
  })).subscribe();
4710
4817
  }
4818
+ hasAnimation(id = -1) { return this._animator?.hasAnimation(id) ?? false; }
4711
4819
  updateDirection(position, prePosition) {
4712
4820
  const delta = (position - this._delta) - prePosition;
4713
4821
  this._scrollDirection.add(delta > 0 ? 1 : delta < 0 ? -1 : 0);
@@ -4870,7 +4978,7 @@ class NgScrollView extends BaseScrollView {
4870
4978
  moveWithAcceleration(isVertical, position, v0, v, a0, timestamp) {
4871
4979
  if (a0 !== 0 && timestamp < MAX_VELOCITY_TIMESTAMP) {
4872
4980
  const dvSign = Math.sign(v), mass = this.scrollingSettings?.mass ?? MASS, duration = DURATION, maxDuration = this.scrollingSettings?.maxDuration ?? MAX_DURATION, maxDist = this.scrollingSettings?.maxDistance ?? MAX_DIST, maxDistance = dvSign * maxDist, s = (dvSign * Math.abs((a0 * Math.pow(duration, 2)) * .5) / 10000) / mass, distance = Math.abs(s) < maxDist ? s : maxDistance, positionWithVelocity = position + (this._inversion ? -1 : 1) * distance, ad = Math.abs(a0 !== 0 ? Math.sqrt(a0) : 0) * ACCELERATION_SCALE / mass, aDuration = ad < maxDuration ? ad : maxDuration, startPosition = isVertical ? this.y : this.x;
4873
- this.animate(startPosition, Math.round(positionWithVelocity), aDuration, easeOutQuad, true);
4981
+ this.animate(startPosition, Math.round(positionWithVelocity), aDuration, easeOutQuad, false, true);
4874
4982
  }
4875
4983
  else {
4876
4984
  this.alignPosition(true, true);
@@ -4883,11 +4991,17 @@ class NgScrollView extends BaseScrollView {
4883
4991
  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;
4884
4992
  return result;
4885
4993
  }
4886
- animate(startValue, endValue, duration = ANIMATION_DURATION, easingFunction = easeOutQuad, userAction = false, alignmentAtComplete = true, skipOverridedCoordinates = false) {
4994
+ animate(startValue, endValue, duration = ANIMATION_DURATION, easingFunction = easeOutQuad, blending = false, userAction = false, alignmentAtComplete = true, skipOverridedCoordinates = false) {
4887
4995
  const isVertical = this._$isVertical.getValue();
4888
4996
  let position = startValue;
4889
4997
  this._isAlignmentAnimation = !alignmentAtComplete;
4890
- this._animator.animate({
4998
+ if (this.hasAnimation() && blending) {
4999
+ const updatable = this._animator.updateTo(endValue);
5000
+ if (updatable) {
5001
+ return this._animator.id;
5002
+ }
5003
+ }
5004
+ return this._animator.animate({
4891
5005
  withDelta: this._service.dynamic && !this.isInfinity,
4892
5006
  startValue,
4893
5007
  endValue,
@@ -4899,7 +5013,7 @@ class NgScrollView extends BaseScrollView {
4899
5013
  if (this._isCoordinatesOverrided && !skipOverridedCoordinates) {
4900
5014
  this._isCoordinatesOverrided = false;
4901
5015
  const currentCoordinate = isVertical ? this._y : this._x, delta = endValue - value;
4902
- this.animate(currentCoordinate, currentCoordinate + delta, duration - elapsed, easingFunction, userAction, alignmentAtComplete);
5016
+ this.animate(currentCoordinate, currentCoordinate + delta, duration - elapsed, easingFunction, blending, userAction, alignmentAtComplete);
4903
5017
  return;
4904
5018
  }
4905
5019
  const v0 = calculateVelocity(position, value - this._delta, timestamp) ?? this.averageVelocity;
@@ -5031,7 +5145,7 @@ class NgScrollView extends BaseScrollView {
5031
5145
  const cPos = (isVertical ? this.scrollTop : this.scrollLeft);
5032
5146
  if (position !== null && position !== cPos) {
5033
5147
  this.stopScrolling(true);
5034
- this.animate(cPos, position, animated ? this.animationParams.snapToItem : 1, easeOutQuad, false, false, true);
5148
+ this.animate(cPos, position, animated ? this._$animationParams.getValue().snapToItem : 1, easeOutQuad, false, false, false, true);
5035
5149
  return true;
5036
5150
  }
5037
5151
  return false;
@@ -5117,21 +5231,18 @@ class NgScrollView extends BaseScrollView {
5117
5231
  if (behavior === AUTO || behavior === SMOOTH) {
5118
5232
  if (isVertical) {
5119
5233
  if (prevY !== y) {
5120
- this.animate(prevY, y, duration, ease, userAction);
5234
+ return this.animate(prevY, y, duration, ease, blending, userAction);
5121
5235
  }
5122
5236
  }
5123
5237
  else {
5124
5238
  if (prevX !== x) {
5125
- this.animate(prevX, x, duration, ease, userAction);
5239
+ return this.animate(prevX, x, duration, ease, blending, userAction);
5126
5240
  }
5127
5241
  }
5128
5242
  }
5129
5243
  else {
5130
5244
  if (isVertical) {
5131
5245
  if (this._y !== y || force) {
5132
- if (!blending) {
5133
- this.stopScrolling(force);
5134
- }
5135
5246
  this.setY(y, snap, normalize);
5136
5247
  this.emitScrollableEvent();
5137
5248
  if (fireUpdate) {
@@ -5141,9 +5252,6 @@ class NgScrollView extends BaseScrollView {
5141
5252
  }
5142
5253
  else {
5143
5254
  if (this._x !== x || force) {
5144
- if (!blending) {
5145
- this.stopScrolling(force);
5146
- }
5147
5255
  this.setX(x, snap, normalize);
5148
5256
  this.emitScrollableEvent();
5149
5257
  if (fireUpdate) {
@@ -5152,6 +5260,7 @@ class NgScrollView extends BaseScrollView {
5152
5260
  }
5153
5261
  }
5154
5262
  }
5263
+ return -1;
5155
5264
  }
5156
5265
  emitScrollableEvent() {
5157
5266
  if (!!this.cdkScrollable) {
@@ -5170,6 +5279,9 @@ class NgScrollView extends BaseScrollView {
5170
5279
  this.stopScrolling();
5171
5280
  this.move(this._$isVertical.getValue(), offset);
5172
5281
  }
5282
+ stopAnimation(id) {
5283
+ this._animator.stop(id);
5284
+ }
5173
5285
  ngOnDestroy() {
5174
5286
  super.ngOnDestroy();
5175
5287
  if (this._animator) {
@@ -5836,6 +5948,10 @@ class NgScrollerComponent extends NgScrollView {
5836
5948
  $updateScrollBar.pipe(takeUntil(this._$unsubscribe), debounceTime(0), tap(() => {
5837
5949
  this.updateScrollBarHandler(!this._isScrollbarUserAction);
5838
5950
  })).subscribe();
5951
+ const $grabbing = this.$grabbing;
5952
+ $grabbing.pipe(takeUntil(this._$unsubscribe), tap(v => {
5953
+ this._service.grabbing = v;
5954
+ })).subscribe();
5839
5955
  combineLatest([this.$classes, this.$direction, this.$grabbing, this.$motionBlurEnabled]).pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), debounceTime(0), tap(([classes, direction, grabbing, filtered]) => {
5840
5956
  this._$actualClasses.next({ ...classes, [direction]: true, grabbing, filtered });
5841
5957
  })).subscribe();
@@ -5973,7 +6089,7 @@ class NgScrollerComponent extends NgScrollView {
5973
6089
  this._isScrollbarUserAction = false;
5974
6090
  this.scrollBar?.stopScrolling();
5975
6091
  }
5976
- this.scroll({ ...params, userAction: userAction });
6092
+ return this.scroll({ ...params, userAction: userAction });
5977
6093
  }
5978
6094
  stopScrollbar() {
5979
6095
  if (!!this.scrollBar) {
@@ -6377,13 +6493,13 @@ class NgPrerenderVirtualListItemComponent extends NgVirtualListItemComponent {
6377
6493
  }
6378
6494
  }
6379
6495
  NgPrerenderVirtualListItemComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgPrerenderVirtualListItemComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
6380
- 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 });
6496
+ 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 });
6381
6497
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgPrerenderVirtualListItemComponent, decorators: [{
6382
6498
  type: Component,
6383
6499
  args: [{ selector: 'ng-prerender-virtual-list-item', host: {
6384
6500
  'class': 'ngvl__item',
6385
6501
  'role': 'listitem',
6386
- }, 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"] }]
6502
+ }, 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"] }]
6387
6503
  }] });
6388
6504
 
6389
6505
  /**
@@ -7912,6 +8028,7 @@ class NgVirtualListComponent extends DisposableComponent {
7912
8028
  this._readyForShow = false;
7913
8029
  this._cached = false;
7914
8030
  this._isLoading = false;
8031
+ this._animationId = -1;
7915
8032
  this._$viewInit = new BehaviorSubject(false);
7916
8033
  this.$viewInit = this._$viewInit.asObservable();
7917
8034
  this._$destroy = new Subject();
@@ -8441,7 +8558,7 @@ class NgVirtualListComponent extends DisposableComponent {
8441
8558
  ;
8442
8559
  get motionBlurEnabled() { return this._$motionBlurEnabled.getValue(); }
8443
8560
  /**
8444
- * Animation parameters. The default value is "{ scrollToItem: 50, snapToItem: 150, navigateToItem: 150, navigateByKeyboard: 50 }".
8561
+ * Animation parameters. The default value is "{ scrollToItem: 150, snapToItem: 150, navigateToItem: 150, navigateByKeyboard: 50 }".
8445
8562
  */
8446
8563
  set animationParams(v) {
8447
8564
  if (this._$animationParams.getValue() === v) {
@@ -8728,6 +8845,7 @@ class NgVirtualListComponent extends DisposableComponent {
8728
8845
  return this.dynamicSize && (this._trackBox?.isSnappedToEnd ?? false);
8729
8846
  }
8730
8847
  ngAfterViewInit() {
8848
+ let readyForAnimations = false;
8731
8849
  const _$created = new BehaviorSubject(false), $created = _$created.asObservable();
8732
8850
  combineLatest([$created, this.$show]).pipe(takeUntil(this._$unsubscribe), filter$1(([created, shown]) => created && shown), debounceTime(1), tap(v => {
8733
8851
  this._$initialized.next(true);
@@ -8920,6 +9038,7 @@ class NgVirtualListComponent extends DisposableComponent {
8920
9038
  }), tap(items => {
8921
9039
  this._trackBox.resetCollection(items, this.actualItemSize);
8922
9040
  }), switchMap$1(i => of((i ?? []).length > 0)), distinctUntilChanged(), tap(v => {
9041
+ readyForAnimations = false;
8923
9042
  if (!v) {
8924
9043
  this.cacheClean();
8925
9044
  this.cleanup();
@@ -9259,12 +9378,22 @@ class NgVirtualListComponent extends DisposableComponent {
9259
9378
  }), debounceTime(100), tap(() => {
9260
9379
  this._isLoading = false;
9261
9380
  })).subscribe();
9381
+ let prevCacheVersion = -1, prevScrollable = false;
9382
+ $viewInit.pipe(takeUntil(this._$unsubscribe), filter$1(v => !!v), switchMap$1(() => {
9383
+ return this.$show.pipe(takeUntil(this._$unsubscribe), debounceTime(Math.max(500, this._$animationParams.getValue().scrollToItem)), tap(() => {
9384
+ if (this._readyForShow || (this.cachable && this._cached)) {
9385
+ readyForAnimations = true;
9386
+ }
9387
+ }));
9388
+ })).subscribe();
9262
9389
  const update = (params) => {
9263
- const { alignment, snapScrollToStart, snapScrollToEnd, bounds, items, itemConfigMap, scrollSize, itemSize, minItemSize, maxItemSize, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, enabledBufferOptimization, snapToItem, snapToItemAlign, userAction, collapsedIds, itemTransform, } = params;
9390
+ const { alignment, snapScrollToStart, snapScrollToEnd, bounds, items, itemConfigMap, scrollSize, itemSize, minItemSize, maxItemSize, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, enabledBufferOptimization, snapToItem, snapToItemAlign, userAction, collapsedIds, cacheVersion, itemTransform, } = params;
9391
+ const cacheChanged = prevCacheVersion !== cacheVersion;
9392
+ prevCacheVersion = cacheVersion;
9264
9393
  const scroller = this._scrollerComponent;
9265
9394
  let totalSize = 0;
9266
9395
  if (!!scroller) {
9267
- 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;
9396
+ 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;
9268
9397
  if (this._readyForShow || (cachable && cached)) {
9269
9398
  const currentScrollSize = (isVertical ? scroller.scrollTop : scroller.scrollLeft);
9270
9399
  let actualScrollSize = !this._readyForShow && snapScrollToEnd ? (isVertical ? scroller.scrollHeight : scroller.scrollWidth) :
@@ -9308,12 +9437,13 @@ class NgVirtualListComponent extends DisposableComponent {
9308
9437
  if (!_$created.getValue()) {
9309
9438
  _$created.next(true);
9310
9439
  }
9311
- const delta = this._trackBox.delta, scrollPositionAfterUpdate = actualScrollSize + delta, roundedScrollPositionAfterUpdate = scrollPositionAfterUpdate, roundedMaxPositionAfterUpdate = isVertical ? scroller.scrollHeight : scroller.scrollWidth;
9440
+ const delta = this._trackBox.delta, scrollPositionAfterUpdate = actualScrollSize + delta, roundedScrollPositionAfterUpdate = scrollPositionAfterUpdate, roundedMaxPositionAfterUpdate = isVertical ? scroller.actualScrollHeight : scroller.actualScrollWidth;
9312
9441
  if (this._isSnappingMethodAdvanced) {
9313
9442
  this.updateRegularRenderer();
9314
9443
  }
9315
9444
  this.updateOffsetsByAllignment();
9316
9445
  scroller.delta = delta;
9446
+ prevScrollable = scroller.scrollable;
9317
9447
  if ((snapScrollToStart && this._trackBox.isSnappedToStart && scroller.scrollable) ||
9318
9448
  (snapScrollToStart && currentScrollSize <= MIN_PIXELS_FOR_PREVENT_SNAPPING)) {
9319
9449
  if (currentScrollSize !== roundedScrollPositionAfterUpdate) {
@@ -9324,9 +9454,16 @@ class NgVirtualListComponent extends DisposableComponent {
9324
9454
  this._trackBox.isScrollEnd;
9325
9455
  const params = {
9326
9456
  [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: 0, userAction,
9327
- fireUpdate: fireUpdateAtEdges, behavior: BEHAVIOR_INSTANT,
9328
- blending: false, duration: this.animationParams.scrollToItem,
9457
+ fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams.scrollToItem > 0 && this.scrollBehavior !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT),
9458
+ blending: useAnimations && scroller.hasAnimation(this._animationId), duration: this.animationParams.scrollToItem,
9329
9459
  };
9460
+ const animationId = scroller?.scrollTo?.(params);
9461
+ if (animationId > -1) {
9462
+ this._animationId = animationId;
9463
+ }
9464
+ else {
9465
+ scroller.stopAnimation(this._animationId);
9466
+ }
9330
9467
  scroller?.scrollTo?.(params);
9331
9468
  if (emitUpdate) {
9332
9469
  this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
@@ -9347,9 +9484,16 @@ class NgVirtualListComponent extends DisposableComponent {
9347
9484
  }
9348
9485
  const params = {
9349
9486
  [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: roundedMaxPositionAfterUpdate,
9350
- fireUpdate: fireUpdateAtEdges, behavior: BEHAVIOR_INSTANT, userAction: false,
9351
- blending: false, duration: this.animationParams.scrollToItem,
9487
+ fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams.scrollToItem > 0 && this.scrollBehavior !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT), userAction: false,
9488
+ blending: useAnimations && scroller.hasAnimation(this._animationId) || cacheChanged, duration: this.animationParams.scrollToItem,
9352
9489
  };
9490
+ const animationId = scroller?.scrollTo?.(params);
9491
+ if (animationId > -1) {
9492
+ this._animationId = animationId;
9493
+ }
9494
+ else {
9495
+ scroller.stopAnimation(this._animationId);
9496
+ }
9353
9497
  scroller?.scrollTo?.(params);
9354
9498
  if (emitUpdate) {
9355
9499
  this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
@@ -9363,9 +9507,13 @@ class NgVirtualListComponent extends DisposableComponent {
9363
9507
  if (this._readyForShow) {
9364
9508
  this.emitScrollEvent(true, false, userAction);
9365
9509
  }
9510
+ if (this._animationId > -1) {
9511
+ scroller.stopAnimation(this._animationId);
9512
+ this._animationId = -1;
9513
+ }
9366
9514
  const params = {
9367
9515
  [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollPositionAfterUpdate, blending: true, userAction,
9368
- fireUpdate, behavior: BEHAVIOR_INSTANT, duration: this.animationParams.scrollToItem,
9516
+ fireUpdate, behavior: BEHAVIOR_INSTANT, duration: 0,
9369
9517
  };
9370
9518
  scroller.scrollTo(params);
9371
9519
  if (emitUpdate) {
@@ -10080,7 +10228,7 @@ class NgVirtualListComponent extends DisposableComponent {
10080
10228
  comp?.destroy();
10081
10229
  }
10082
10230
  }
10083
- if (this._displayComponents) {
10231
+ if (!!this._displayComponents) {
10084
10232
  while (this._displayComponents.length > 0) {
10085
10233
  const comp = this._displayComponents.shift();
10086
10234
  comp?.destroy();