ng-virtual-list 18.12.2 → 18.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 (27) hide show
  1. package/README.md +2 -2
  2. package/esm2022/lib/components/ng-list-item/base/base-virtual-list-item-component.mjs +9 -5
  3. package/esm2022/lib/components/ng-list-item/const/index.mjs +2 -1
  4. package/esm2022/lib/components/ng-list-item/ng-virtual-list-item.component.mjs +14 -8
  5. package/esm2022/lib/components/ng-prerender-container/components/ng-prerender-list-item/ng-prerender-list-item.component.mjs +3 -3
  6. package/esm2022/lib/components/ng-scroll-view/ng-scroll-view.component.mjs +20 -14
  7. package/esm2022/lib/components/ng-scroller/ng-scroller.component.mjs +6 -2
  8. package/esm2022/lib/const/index.mjs +6 -3
  9. package/esm2022/lib/core/track-box.mjs +31 -9
  10. package/esm2022/lib/directives/virtual-click/virtual-click.directive.mjs +35 -16
  11. package/esm2022/lib/models/display-object-config.model.mjs +1 -1
  12. package/esm2022/lib/ng-virtual-list.component.mjs +43 -11
  13. package/esm2022/lib/ng-virtual-list.service.mjs +31 -2
  14. package/esm2022/lib/utils/animator/animator.mjs +39 -14
  15. package/fesm2022/ng-virtual-list.mjs +222 -73
  16. package/fesm2022/ng-virtual-list.mjs.map +1 -1
  17. package/lib/components/ng-list-item/base/base-virtual-list-item-component.d.ts +1 -1
  18. package/lib/components/ng-list-item/ng-virtual-list-item.component.d.ts +3 -1
  19. package/lib/components/ng-scroll-view/ng-scroll-view.component.d.ts +5 -2
  20. package/lib/components/ng-scroller/ng-scroller.component.d.ts +1 -1
  21. package/lib/const/index.d.ts +3 -1
  22. package/lib/directives/virtual-click/virtual-click.directive.d.ts +11 -6
  23. package/lib/models/display-object-config.model.d.ts +4 -0
  24. package/lib/ng-virtual-list.component.d.ts +2 -1
  25. package/lib/ng-virtual-list.service.d.ts +13 -0
  26. package/lib/utils/animator/animator.d.ts +11 -2
  27. 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
 
@@ -247,6 +247,7 @@ var TextDirections;
247
247
  TextDirections["LTR"] = "ltr";
248
248
  })(TextDirections || (TextDirections = {}));
249
249
 
250
+ const INVISIBLE_POSITION = -10000;
250
251
  const SERVICE_PROP_DUMMY_ID = '__service-dummy-id__';
251
252
  const SERVICE_PROP_DUMMY = '__service-dummy__';
252
253
  const SERVICE_TYPE_DUMMY = '__service-type-dummy__';
@@ -276,7 +277,7 @@ const DEFAULT_MOTION_BLUR = 0.15;
276
277
  const DEFAULT_MOTION_BLUR_ENABLED = false;
277
278
  const DEFAULT_MAX_MOTION_BLUR = 0.5;
278
279
  const DEFAULT_ANIMATION_PARAMS = {
279
- scrollToItem: 50,
280
+ scrollToItem: 150,
280
281
  snapToItem: 150,
281
282
  navigateToItem: 150,
282
283
  navigateByKeyboard: NAVIGATION_BY_KEYBOARD_TIMER,
@@ -332,13 +333,15 @@ const POSITION$1 = 'position';
332
333
  const POSITION_RELATIVE = 'relative';
333
334
  const POSITION_ABSOLUTE = 'absolute';
334
335
  const TRANSLATE_3D = 'translate3d';
335
- const ZEROS_TRANSLATE_3D = `${TRANSLATE_3D}(0,0,0)`;
336
+ const INVISIBLE_TRANSLATE_3D = `${TRANSLATE_3D}(${INVISIBLE_POSITION},${INVISIBLE_POSITION},0)`;
336
337
  const HIDDEN_ZINDEX = '-1';
337
338
  const DEFAULT_ZINDEX = '0';
338
339
  const TOP_PROP_NAME = 'top';
339
340
  const LEFT_PROP_NAME = 'left';
340
341
  const X_PROP_NAME = 'x';
341
342
  const Y_PROP_NAME = 'y';
343
+ const TRANSFORMED_X_PROP_NAME = 'transformedX';
344
+ const TRANSFORMED_Y_PROP_NAME = 'transformedY';
342
345
  const WIDTH_PROP_NAME = 'width';
343
346
  const HEIGHT_PROP_NAME = 'height';
344
347
  const MARGIN_TOP = 'marginTop';
@@ -492,6 +495,7 @@ const DEFAULT_TEMPLATE_CONTEXT = {
492
495
  isLast: false,
493
496
  fullSize: false,
494
497
  totalItems: 0,
498
+ grabbing: false,
495
499
  },
496
500
  reseted: false,
497
501
  index: -1,
@@ -707,6 +711,31 @@ class NgVirtualListService {
707
711
  this._langTextDir = v;
708
712
  this._$langTextDir.next(v);
709
713
  }
714
+ _$grabbing = new BehaviorSubject$1(false);
715
+ $grabbing = this._$grabbing.asObservable();
716
+ get grabbing() { return this._$grabbing.getValue(); }
717
+ _grabbing = false;
718
+ set grabbing(v) {
719
+ if (this._grabbing === v) {
720
+ return;
721
+ }
722
+ this._grabbing = v;
723
+ this._$grabbing.next(v);
724
+ }
725
+ _$clickPressed = new BehaviorSubject$1(false);
726
+ $clickPressed = this._$clickPressed.asObservable();
727
+ get clickPressed() { return this._$clickPressed.getValue(); }
728
+ _clickPressed = false;
729
+ set clickPressed(v) {
730
+ if (this._clickPressed === v) {
731
+ return;
732
+ }
733
+ this._clickPressed = v;
734
+ this._$clickPressed.next(v);
735
+ }
736
+ _$isGrabbing = new BehaviorSubject$1(false);
737
+ $isGrabbing = this._$isGrabbing.asObservable();
738
+ get isGrabbing() { return this._$isGrabbing.getValue(); }
710
739
  get scrollBarSize() { return this._$scrollBarSize.getValue(); }
711
740
  _scrollBarSize = 0;
712
741
  set scrollBarSize(v) {
@@ -750,6 +779,10 @@ class NgVirtualListService {
750
779
  }
751
780
  get collapsedIds() { return this._$collapsedIds.getValue(); }
752
781
  constructor() {
782
+ const $grabbing = this.$grabbing.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged()), $clickPressed = this.$clickPressed.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged());
783
+ combineLatest([$grabbing, $clickPressed]).pipe(takeUntil(this._$unsubscribe), tap(([grabbing, clickPressed]) => {
784
+ this._$isGrabbing.next(grabbing && !clickPressed);
785
+ })).subscribe();
753
786
  this._$selectingMode.pipe(takeUntil(this._$unsubscribe), tap(v => {
754
787
  switch (v) {
755
788
  case SelectingModesTypes.SELECT: {
@@ -1230,7 +1263,7 @@ class BaseVirtualListItemComponent extends DisposableComponent {
1230
1263
  }
1231
1264
  this._data = v;
1232
1265
  this.updatePartStr(v, this._isSelected, this._isCollapsed);
1233
- this.updateConfig(v);
1266
+ this.updateConfig(v, this._service.isGrabbing);
1234
1267
  this.updateMeasures(v);
1235
1268
  this.update();
1236
1269
  this._$data.next(v);
@@ -1282,6 +1315,9 @@ class BaseVirtualListItemComponent extends DisposableComponent {
1282
1315
  this._id = this._service.generateComponentId();
1283
1316
  this._listId = this._service.id;
1284
1317
  this._displayId = createDisplayId(this._listId, this._id);
1318
+ this._service.$isGrabbing.pipe(takeUntil(this._$unsubscribe), tap(v => {
1319
+ this.updateConfig(this._data, v);
1320
+ })).subscribe();
1285
1321
  const $part = this.$part;
1286
1322
  $part.pipe(takeUntil(this._$unsubscribe), tap(part => {
1287
1323
  this._elementRef.nativeElement.setAttribute('part', part);
@@ -1319,9 +1355,9 @@ class BaseVirtualListItemComponent extends DisposableComponent {
1319
1355
  this._$measures.next(v?.measures ? { ...v.measures } : null);
1320
1356
  this._cdr.markForCheck();
1321
1357
  }
1322
- updateConfig(v) {
1358
+ updateConfig(v, grabbing) {
1323
1359
  this._$config.next({
1324
- ...v?.config || {}, selected: this._isSelected, collapsed: this._isCollapsed, focused: this._$focused.getValue(),
1360
+ ...v?.config || {}, selected: this._isSelected, collapsed: this._isCollapsed, focused: this._$focused.getValue(), grabbing,
1325
1361
  });
1326
1362
  this._cdr.markForCheck();
1327
1363
  }
@@ -1450,6 +1486,7 @@ class BaseVirtualListItemComponent extends DisposableComponent {
1450
1486
  }
1451
1487
  const el = this._elementRef.nativeElement, styles = el.style;
1452
1488
  styles.zIndex = HIDDEN_ZINDEX;
1489
+ styles.transform = INVISIBLE_TRANSLATE_3D;
1453
1490
  if (this.regular) {
1454
1491
  if (styles.display === DISPLAY_NONE) {
1455
1492
  return;
@@ -1482,9 +1519,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
1482
1519
  args: ['container']
1483
1520
  }] } });
1484
1521
 
1485
- const DEFAULT_MAX_DISTANCE = 40;
1486
1522
  /**
1487
- * ItemClickDirective
1523
+ * VirtualClickDirective
1488
1524
  * Maximum performance for extremely large lists.
1489
1525
  * It is based on algorithms for virtualization of screen objects.
1490
1526
  * @link https://github.com/DjonnyX/ng-virtual-list/blob/18.x/projects/ng-virtual-list/src/lib/directives/item-click/item-click.directive.ts
@@ -1492,30 +1528,44 @@ const DEFAULT_MAX_DISTANCE = 40;
1492
1528
  * @email djonnyx@gmail.com
1493
1529
  */
1494
1530
  class VirtualClickDirective {
1495
- _elementRef;
1496
1531
  _$unsubscribe = new Subject();
1497
- _maxDistance = DEFAULT_MAX_DISTANCE;
1532
+ _$maxDistance = new BehaviorSubject(null);
1533
+ $maxDistance = this._$maxDistance.asObservable();
1534
+ _maxDistance = null;
1498
1535
  set maxDistance(v) {
1499
- this._maxDistance = (v !== null || v !== undefined) ? Number(v) : DEFAULT_MAX_DISTANCE;
1536
+ const value = (v !== null || v !== undefined) ? Number(v) : null;
1537
+ this._maxDistance = value;
1538
+ this._$maxDistance.next(value);
1500
1539
  }
1501
1540
  onVirtualClick = new EventEmitter$1();
1502
- constructor(_elementRef) {
1503
- this._elementRef = _elementRef;
1541
+ onVirtualClickPress = new EventEmitter$1();
1542
+ onVirtualClickCancel = new EventEmitter$1();
1543
+ _service = inject(NgVirtualListService);
1544
+ _elementRef = inject(ElementRef);
1545
+ constructor() {
1546
+ let maxDistance = this._maxDistance ?? DEFAULT_CLICK_DISTANCE;
1547
+ combineLatest([this._service.$clickDistance, this.$maxDistance]).pipe(takeUntil$1(this._$unsubscribe), tap$1(([clickDistance, distance]) => {
1548
+ maxDistance = distance === null ? clickDistance : distance;
1549
+ })).subscribe();
1504
1550
  const $pointerPressed = fromEvent(this._elementRef.nativeElement, 'pointerdown'), $pointerCancel = race([
1505
1551
  fromEvent(window, 'pointerup').pipe(takeUntil$1(this._$unsubscribe)),
1506
1552
  fromEvent(window, 'pointerleave').pipe(takeUntil$1(this._$unsubscribe)),
1507
1553
  ]), $pointerRelease = fromEvent(this._elementRef.nativeElement, 'pointerup', { passive: false });
1508
1554
  $pointerPressed.pipe(takeUntil$1(this._$unsubscribe), switchMap(e => {
1509
1555
  const x = Math.abs(e.clientX), y = Math.abs(e.clientY);
1556
+ this.onVirtualClickPress.emit(e);
1510
1557
  return $pointerRelease.pipe(takeUntil$1(this._$unsubscribe), takeUntil$1(race([
1511
- $pointerCancel,
1558
+ $pointerCancel.pipe(takeUntil$1(this._$unsubscribe), tap$1(() => {
1559
+ this.onVirtualClickCancel.emit();
1560
+ })),
1512
1561
  fromEvent(window, 'pointermove').pipe(takeUntil$1(this._$unsubscribe), switchMap(e => {
1513
1562
  const xx = x - Math.abs(e.clientX), yy = y - Math.abs(e.clientY), dist = Math.sqrt(Math.pow(xx, 2) + Math.pow(yy, 2));
1514
- if (dist > this._maxDistance) {
1563
+ if (dist > maxDistance) {
1564
+ this.onVirtualClickCancel.emit();
1515
1565
  return of(true);
1516
1566
  }
1517
1567
  return of(false);
1518
- }), takeUntil$1(this._$unsubscribe), filter(v => !!v)),
1568
+ }), filter(v => !!v)),
1519
1569
  ])), takeUntil$1(this._$unsubscribe), tap$1(e => {
1520
1570
  if (e) {
1521
1571
  this.onVirtualClick.emit(e);
@@ -1529,8 +1579,8 @@ class VirtualClickDirective {
1529
1579
  this._$unsubscribe.complete();
1530
1580
  }
1531
1581
  }
1532
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: VirtualClickDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
1533
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: VirtualClickDirective, selector: "[virtualClick]", inputs: { maxDistance: ["maxClickDistance", "maxDistance"] }, outputs: { onVirtualClick: "onVirtualClick" }, ngImport: i0 });
1582
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: VirtualClickDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1583
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: VirtualClickDirective, selector: "[virtualClick]", inputs: { maxDistance: ["maxClickDistance", "maxDistance"] }, outputs: { onVirtualClick: "onVirtualClick", onVirtualClickPress: "onVirtualClickPress", onVirtualClickCancel: "onVirtualClickCancel" }, ngImport: i0 });
1534
1584
  }
1535
1585
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: VirtualClickDirective, decorators: [{
1536
1586
  type: Directive,
@@ -1538,11 +1588,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
1538
1588
  selector: '[virtualClick]',
1539
1589
  standalone: false,
1540
1590
  }]
1541
- }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { maxDistance: [{
1591
+ }], ctorParameters: () => [], propDecorators: { maxDistance: [{
1542
1592
  type: Input,
1543
1593
  args: ['maxClickDistance']
1544
1594
  }], onVirtualClick: [{
1545
1595
  type: Output
1596
+ }], onVirtualClickPress: [{
1597
+ type: Output
1598
+ }], onVirtualClickCancel: [{
1599
+ type: Output
1546
1600
  }] } });
1547
1601
 
1548
1602
  /**
@@ -1574,12 +1628,12 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
1574
1628
  fromEvent(this.element, EVENT_FOCUS_IN).pipe(takeUntil(this._$unsubscribe), tap(e => {
1575
1629
  this._service.focusedId = this.itemId ?? null;
1576
1630
  this._$focused.next(true);
1577
- this.updateConfig(this._data);
1631
+ this.updateConfig(this._data, this._service.isGrabbing);
1578
1632
  this.updatePartStr(this._data, this._isSelected, this._isCollapsed);
1579
1633
  })).subscribe(),
1580
1634
  fromEvent(this.element, EVENT_FOCUS_OUT).pipe(takeUntil(this._$unsubscribe), tap(e => {
1581
1635
  this._$focused.next(false);
1582
- this.updateConfig(this._data);
1636
+ this.updateConfig(this._data, this._service.isGrabbing);
1583
1637
  this.updatePartStr(this._data, this._isSelected, this._isCollapsed);
1584
1638
  })).subscribe();
1585
1639
  $focused.pipe(takeUntil(this._$unsubscribe), debounceTime(this.getNavigationTimeout()), switchMap$1(v => {
@@ -1612,7 +1666,7 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
1612
1666
  const actualIds = collapsedIds, isCollapsed = this.itemId !== undefined && actualIds && actualIds.includes(this.itemId);
1613
1667
  this._isCollapsed = isCollapsed;
1614
1668
  this.updatePartStr(this._data, this._isSelected, isCollapsed);
1615
- this.updateConfig(this._data);
1669
+ this.updateConfig(this._data, this._service.isGrabbing);
1616
1670
  this.updateMeasures(this._data);
1617
1671
  })).subscribe();
1618
1672
  }
@@ -1715,24 +1769,30 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
1715
1769
  }
1716
1770
  return Number.MIN_SAFE_INTEGER;
1717
1771
  }
1718
- updateConfig(v) {
1772
+ updateConfig(v, grabbing) {
1719
1773
  this._$config.next({
1720
- ...v?.config || {}, selected: this._isSelected, collapsed: this._isCollapsed, focused: this._$focused.getValue(),
1774
+ ...v?.config || {}, selected: this._isSelected, collapsed: this._isCollapsed, focused: this._$focused.getValue(), grabbing,
1721
1775
  });
1722
1776
  this._cdr.markForCheck();
1723
1777
  }
1724
1778
  onClickHandler() {
1725
1779
  this._service.virtualClick(this._data);
1726
1780
  }
1781
+ onClickPressHandler() {
1782
+ this._service.clickPressed = true;
1783
+ }
1784
+ onClickCancelHandler() {
1785
+ this._service.clickPressed = false;
1786
+ }
1727
1787
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NgVirtualListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1728
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", 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 });
1788
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", 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 });
1729
1789
  }
1730
1790
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NgVirtualListItemComponent, decorators: [{
1731
1791
  type: Component,
1732
1792
  args: [{ selector: 'ng-virtual-list-item', host: {
1733
1793
  'class': 'ngvl__item',
1734
1794
  '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"] }]
1795
+ }, 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
1796
  }], ctorParameters: () => [] });
1737
1797
 
1738
1798
  /**
@@ -3292,7 +3352,7 @@ class TrackBox extends CacheMap {
3292
3352
  const { width, height, normalizedItemWidth, normalizedItemHeight, dynamicSize, divides, itemsOnDisplayLength, itemsFromStartToScrollEnd, isVertical, leftLayoutOffset: layoutOffset, leftLayoutIndexOffset: layoutIndexOffset, renderItems: renderItemsLength, scrollSize, sizeProperty, stickyEnabled, stickyPos, startPosition, totalLength, startIndex, typicalItemSize, minItemSize, maxItemSize, snapToItem, snapToItemAlign, itemTransform, } = metrics, displayItems = [];
3293
3353
  if (items.length) {
3294
3354
  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;
3295
- let pos = startPosition, renderItems = renderItemsLength, stickyItem, nextSticky, stickyItemIndex = -1, stickyItemSize = 0, endStickyItem, nextEndSticky, endStickyItemIndex = -1, endStickyItemSize = 0;
3355
+ let pos = startPosition, renderItems = renderItemsLength, stickyItem, nextSticky, stickyItemIndex = -1, nexstStickyItemIndex = -1, stickyItemSize = 0, endStickyItem, nextEndSticky, endStickyItemIndex = -1, endStickyItemSize = 0;
3296
3356
  const li = layoutIndexOffset + actualItems.length - 1;
3297
3357
  if (stickyEnabled) {
3298
3358
  for (let i = Math.min(itemsFromStartToScrollEnd > 0 ? (divides > 1 ? (itemsFromStartToScrollEnd - 1) : itemsFromStartToScrollEnd) : 0, totalLength - 1); i >= 0; i--) {
@@ -3552,6 +3612,7 @@ class TrackBox extends CacheMap {
3552
3612
  item.measures.x = isVertical ? 0 : snapped ? actualSnippedPosition : pos;
3553
3613
  item.measures.y = isVertical ? snapped ? actualSnippedPosition : pos : 0;
3554
3614
  nextSticky = item;
3615
+ nexstStickyItemIndex = displayItems.length;
3555
3616
  nextSticky.config.snapped = snapped;
3556
3617
  nextSticky.measures.delta = (isVertical ? item.measures.y : item.measures.x) - scrollSize;
3557
3618
  nextSticky.config.zIndex = Z_INDEX_3;
@@ -3574,10 +3635,10 @@ class TrackBox extends CacheMap {
3574
3635
  }
3575
3636
  i++;
3576
3637
  }
3577
- const axis = isVertical ? Y_PROP_NAME : X_PROP_NAME;
3638
+ const axis = isVertical ? Y_PROP_NAME : X_PROP_NAME, transformedAxis = isVertical ? TRANSFORMED_Y_PROP_NAME : TRANSFORMED_X_PROP_NAME;
3578
3639
  if (!!nextSticky && !!stickyItem && nextSticky.measures[axis] <= actualSnippedPosition + stickyItem.measures[sizeProperty]) {
3579
3640
  if (nextSticky.measures[axis] > actualSnippedPosition) {
3580
- stickyItem.measures[axis] = nextSticky.measures[axis] - stickyItem.measures[sizeProperty];
3641
+ stickyItem.measures[axis] = stickyItem.measures[transformedAxis] = nextSticky.measures[axis] - stickyItem.measures[sizeProperty];
3581
3642
  stickyItem.config.snapped = nextSticky.config.snapped = false;
3582
3643
  stickyItem.config.snappedOut = true;
3583
3644
  stickyItem.config.sticky = 1;
@@ -3586,14 +3647,35 @@ class TrackBox extends CacheMap {
3586
3647
  else {
3587
3648
  nextSticky.config.snapped = true;
3588
3649
  nextSticky.measures.delta = (isVertical ? nextSticky.measures.y : nextSticky.measures.x) - scrollSize;
3589
- stickyItem.measures[axis] = nextSticky.measures[axis] - stickyItem.measures[sizeProperty];
3650
+ stickyItem.measures[axis] = stickyItem.measures[transformedAxis] = nextSticky.measures[axis] - stickyItem.measures[sizeProperty];
3590
3651
  stickyItem.measures.delta = (isVertical ? stickyItem.measures.y : stickyItem.measures.x) - scrollSize;
3652
+ const lastStickyItem = displayItems?.[nexstStickyItemIndex + 1];
3653
+ if (lastStickyItem?.config?.sticky === 1 && displayItems?.[nexstStickyItemIndex + 2]?.config?.sticky !== 1) {
3654
+ nextSticky.config.snapped = nextSticky.config.snappedOut = false;
3655
+ stickyItem.config.snappedOut = true;
3656
+ nextSticky.measures.delta = this._scrollStartOffset;
3657
+ if (lastStickyItem.measures[axis] <= actualSnippedPosition) {
3658
+ lastStickyItem.config.snapped = lastStickyItem.config.snappedOut = true;
3659
+ lastStickyItem.measures[axis] = lastStickyItem.measures[transformedAxis] = lastStickyItem.measures.position = actualSnippedPosition;
3660
+ lastStickyItem.measures.delta = this._scrollStartOffset;
3661
+ }
3662
+ }
3663
+ else if (lastStickyItem?.config?.sticky !== 1 && displayItems?.[nexstStickyItemIndex + 2]?.config?.sticky !== 1) {
3664
+ if (nextSticky.measures[axis] <= actualSnippedPosition) {
3665
+ nextSticky.config.snapped = nextSticky.config.snappedOut = true;
3666
+ nextSticky.measures[axis] = nextSticky.measures[transformedAxis] = nextSticky.measures.position = actualSnippedPosition;
3667
+ nextSticky.measures.delta = this._scrollStartOffset;
3668
+ }
3669
+ }
3670
+ else {
3671
+ nextSticky.config.snapped = nextSticky.config.snappedOut = false;
3672
+ }
3591
3673
  }
3592
3674
  }
3593
3675
  if (!!nextEndSticky && !!endStickyItem &&
3594
3676
  (nextEndSticky.measures[axis] >= actualEndSnippedPosition - endStickyItemSize - nextEndSticky.measures[sizeProperty])) {
3595
3677
  if (nextEndSticky.measures[axis] < actualEndSnippedPosition - nextEndSticky.measures[sizeProperty]) {
3596
- endStickyItem.measures[axis] = nextEndSticky.measures[axis] + nextEndSticky.measures[sizeProperty];
3678
+ endStickyItem.measures[axis] = endStickyItem.measures[transformedAxis] = nextEndSticky.measures[axis] + nextEndSticky.measures[sizeProperty];
3597
3679
  endStickyItem.config.snapped = nextEndSticky.config.snapped = false;
3598
3680
  endStickyItem.config.snappedOut = true;
3599
3681
  endStickyItem.config.sticky = 2;
@@ -3601,9 +3683,9 @@ class TrackBox extends CacheMap {
3601
3683
  }
3602
3684
  else {
3603
3685
  nextEndSticky.config.snapped = true;
3604
- nextEndSticky.measures[axis] = actualEndSnippedPosition - nextEndSticky.measures[sizeProperty];
3686
+ nextEndSticky.measures[axis] = nextEndSticky.measures[transformedAxis] = actualEndSnippedPosition - nextEndSticky.measures[sizeProperty];
3605
3687
  nextEndSticky.measures.delta = (isVertical ? nextEndSticky.measures.y : nextEndSticky.measures.x) - scrollSize;
3606
- endStickyItem.measures[axis] = nextEndSticky.measures[axis] + nextEndSticky.measures[sizeProperty];
3688
+ endStickyItem.measures[axis] = endStickyItem.measures[transformedAxis] = nextEndSticky.measures[axis] + nextEndSticky.measures[sizeProperty];
3607
3689
  endStickyItem.measures.delta = (isVertical ? endStickyItem.measures.y : endStickyItem.measures.x) - scrollSize;
3608
3690
  }
3609
3691
  }
@@ -3879,18 +3961,34 @@ const easeLinear = (t) => {
3879
3961
  class Animator {
3880
3962
  static _nextId = 0;
3881
3963
  _animationId = 0;
3964
+ get animated() { return this._animationId > -1; }
3965
+ get isAnimated() { return this.hasAnimation(this._currentId); }
3882
3966
  _currentId = Animator._nextId;
3967
+ get id() { return this._currentId; }
3883
3968
  generateId() {
3884
3969
  return Animator._nextId = Animator._nextId === Number.MAX_SAFE_INTEGER
3885
3970
  ? 0 : Animator._nextId + 1;
3886
3971
  }
3972
+ _diff = 0;
3973
+ _startValue = 0;
3974
+ _endValue = 0;
3975
+ _prevPos = 0;
3976
+ updateTo(end) {
3977
+ this._endValue = end;
3978
+ this._diff = this._endValue - this._startValue;
3979
+ return this.hasAnimation();
3980
+ }
3887
3981
  animate(params) {
3888
3982
  this.stop();
3889
3983
  const id = this.generateId();
3890
3984
  this._currentId = id;
3891
3985
  const { withDelta = DEFAULT_WITH_DELTA, startValue, endValue, duration = DEFAULT_ANIMATION_DURATION, getPropValue, easingFunction = easeLinear, onUpdate, onComplete, } = params;
3986
+ this._startValue = startValue;
3987
+ this._endValue = endValue;
3892
3988
  const startTime = performance.now();
3893
- let isCanceled = false, prevPos = startValue, start = startValue, startPosDelta = 0, delta = 0, prevTime = startTime, diff = endValue - start, isFinished = false;
3989
+ let isCanceled = false, startPosDelta = 0, delta = 0, prevTime = startTime, isFinished = false;
3990
+ this._prevPos = startValue;
3991
+ this._diff = this._endValue - this._startValue;
3894
3992
  const step = (currentTime) => {
3895
3993
  if (id !== this._currentId) {
3896
3994
  isCanceled = true;
@@ -3900,34 +3998,35 @@ class Animator {
3900
3998
  }
3901
3999
  const cPos = getPropValue?.() || 0;
3902
4000
  let startDelta = 0;
3903
- if (cPos !== prevPos) {
3904
- startDelta = cPos - prevPos;
4001
+ if (cPos !== this._prevPos) {
4002
+ startDelta = cPos - this._prevPos;
3905
4003
  startPosDelta += startDelta;
3906
4004
  }
3907
- 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();
4005
+ 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();
3908
4006
  isFinished = progress === 1;
3909
- delta = currentValue - startDelta - prevPos;
3910
- const ts = t - prevTime, timestamp = ts < ANIMATOR_MIN_TIMESTAMP ? ANIMATOR_MIN_TIMESTAMP : ts;
4007
+ delta = currentValue - startDelta - this._prevPos;
4008
+ const frameTimestamp = t - prevTime, actualFrameTimestamp = frameTimestamp < ANIMATOR_MIN_TIMESTAMP ? ANIMATOR_MIN_TIMESTAMP : frameTimestamp;
3911
4009
  prevTime = t;
3912
- prevPos = currentValue;
4010
+ this._prevPos = currentValue;
3913
4011
  if (onUpdate !== undefined) {
3914
4012
  const data = {
3915
4013
  id,
3916
4014
  delta,
3917
4015
  elapsed,
3918
- value: !withDelta && isFinished ? endValue : currentValue,
3919
- timestamp,
4016
+ value: currentValue,
4017
+ timestamp: actualFrameTimestamp,
3920
4018
  };
3921
4019
  onUpdate(data);
3922
4020
  }
3923
4021
  if (isFinished) {
4022
+ this._animationId = -1;
3924
4023
  if (onComplete !== undefined) {
3925
4024
  const data = {
3926
4025
  id,
3927
4026
  delta,
3928
4027
  elapsed,
3929
- value: withDelta ? currentValue : endValue,
3930
- timestamp,
4028
+ value: currentValue,
4029
+ timestamp: actualFrameTimestamp,
3931
4030
  };
3932
4031
  onComplete(data);
3933
4032
  }
@@ -3937,9 +4036,17 @@ class Animator {
3937
4036
  }
3938
4037
  };
3939
4038
  this._animationId = requestAnimationFrame(step);
4039
+ return this._currentId;
4040
+ }
4041
+ hasAnimation(id = -1) {
4042
+ if ((this._currentId === id || id === -1) && this.animated) {
4043
+ return true;
4044
+ }
4045
+ return false;
3940
4046
  }
3941
- stop() {
3942
- cancelAnimationFrame(this._animationId);
4047
+ stop(id = -1) {
4048
+ cancelAnimationFrame(id === -1 ? this._animationId : id);
4049
+ this._animationId = -1;
3943
4050
  }
3944
4051
  dispose() {
3945
4052
  this.stop();
@@ -4526,6 +4633,7 @@ class NgScrollView extends BaseScrollView {
4526
4633
  get startLayoutOffset() { return this._startLayoutOffset; }
4527
4634
  _intersectionComponentId = null;
4528
4635
  _isAlignmentAnimation = false;
4636
+ get animated() { return this._animator?.isAnimated ?? false; }
4529
4637
  constructor() {
4530
4638
  super();
4531
4639
  }
@@ -4719,6 +4827,7 @@ class NgScrollView extends BaseScrollView {
4719
4827
  }));
4720
4828
  })).subscribe();
4721
4829
  }
4830
+ hasAnimation(id = -1) { return this._animator?.hasAnimation(id) ?? false; }
4722
4831
  updateDirection(position, prePosition) {
4723
4832
  const delta = (position - this._delta) - prePosition;
4724
4833
  this._scrollDirection.add(delta > 0 ? 1 : delta < 0 ? -1 : 0);
@@ -4881,7 +4990,7 @@ class NgScrollView extends BaseScrollView {
4881
4990
  moveWithAcceleration(isVertical, position, v0, v, a0, timestamp) {
4882
4991
  if (a0 !== 0 && timestamp < MAX_VELOCITY_TIMESTAMP) {
4883
4992
  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;
4884
- this.animate(startPosition, Math.round(positionWithVelocity), aDuration, easeOutQuad, true);
4993
+ this.animate(startPosition, Math.round(positionWithVelocity), aDuration, easeOutQuad, false, true);
4885
4994
  }
4886
4995
  else {
4887
4996
  this.alignPosition(true, true);
@@ -4894,11 +5003,17 @@ class NgScrollView extends BaseScrollView {
4894
5003
  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;
4895
5004
  return result;
4896
5005
  }
4897
- animate(startValue, endValue, duration = ANIMATION_DURATION, easingFunction = easeOutQuad, userAction = false, alignmentAtComplete = true, skipOverridedCoordinates = false) {
5006
+ animate(startValue, endValue, duration = ANIMATION_DURATION, easingFunction = easeOutQuad, blending = false, userAction = false, alignmentAtComplete = true, skipOverridedCoordinates = false) {
4898
5007
  const isVertical = this._$isVertical.getValue();
4899
5008
  let position = startValue;
4900
5009
  this._isAlignmentAnimation = !alignmentAtComplete;
4901
- this._animator.animate({
5010
+ if (this.hasAnimation() && blending) {
5011
+ const updatable = this._animator.updateTo(endValue);
5012
+ if (updatable) {
5013
+ return this._animator.id;
5014
+ }
5015
+ }
5016
+ return this._animator.animate({
4902
5017
  withDelta: this._service.dynamic && !this.isInfinity,
4903
5018
  startValue,
4904
5019
  endValue,
@@ -4910,7 +5025,7 @@ class NgScrollView extends BaseScrollView {
4910
5025
  if (this._isCoordinatesOverrided && !skipOverridedCoordinates) {
4911
5026
  this._isCoordinatesOverrided = false;
4912
5027
  const currentCoordinate = isVertical ? this._y : this._x, delta = endValue - value;
4913
- this.animate(currentCoordinate, currentCoordinate + delta, duration - elapsed, easingFunction, userAction, alignmentAtComplete);
5028
+ this.animate(currentCoordinate, currentCoordinate + delta, duration - elapsed, easingFunction, blending, userAction, alignmentAtComplete);
4914
5029
  return;
4915
5030
  }
4916
5031
  const v0 = calculateVelocity(position, value - this._delta, timestamp) ?? this.averageVelocity;
@@ -5042,7 +5157,7 @@ class NgScrollView extends BaseScrollView {
5042
5157
  const cPos = (isVertical ? this.scrollTop : this.scrollLeft);
5043
5158
  if (position !== null && position !== cPos) {
5044
5159
  this.stopScrolling(true);
5045
- this.animate(cPos, position, animated ? this.animationParams.snapToItem : 1, easeOutQuad, false, false, true);
5160
+ this.animate(cPos, position, animated ? this._$animationParams.getValue().snapToItem : 1, easeOutQuad, false, false, false, true);
5046
5161
  return true;
5047
5162
  }
5048
5163
  return false;
@@ -5128,21 +5243,18 @@ class NgScrollView extends BaseScrollView {
5128
5243
  if (behavior === AUTO || behavior === SMOOTH) {
5129
5244
  if (isVertical) {
5130
5245
  if (prevY !== y) {
5131
- this.animate(prevY, y, duration, ease, userAction);
5246
+ return this.animate(prevY, y, duration, ease, blending, userAction);
5132
5247
  }
5133
5248
  }
5134
5249
  else {
5135
5250
  if (prevX !== x) {
5136
- this.animate(prevX, x, duration, ease, userAction);
5251
+ return this.animate(prevX, x, duration, ease, blending, userAction);
5137
5252
  }
5138
5253
  }
5139
5254
  }
5140
5255
  else {
5141
5256
  if (isVertical) {
5142
5257
  if (this._y !== y || force) {
5143
- if (!blending) {
5144
- this.stopScrolling(force);
5145
- }
5146
5258
  this.setY(y, snap, normalize);
5147
5259
  this.emitScrollableEvent();
5148
5260
  if (fireUpdate) {
@@ -5152,9 +5264,6 @@ class NgScrollView extends BaseScrollView {
5152
5264
  }
5153
5265
  else {
5154
5266
  if (this._x !== x || force) {
5155
- if (!blending) {
5156
- this.stopScrolling(force);
5157
- }
5158
5267
  this.setX(x, snap, normalize);
5159
5268
  this.emitScrollableEvent();
5160
5269
  if (fireUpdate) {
@@ -5163,6 +5272,7 @@ class NgScrollView extends BaseScrollView {
5163
5272
  }
5164
5273
  }
5165
5274
  }
5275
+ return -1;
5166
5276
  }
5167
5277
  emitScrollableEvent() {
5168
5278
  if (!!this.cdkScrollable) {
@@ -5181,6 +5291,9 @@ class NgScrollView extends BaseScrollView {
5181
5291
  this.stopScrolling();
5182
5292
  this.move(this._$isVertical.getValue(), offset);
5183
5293
  }
5294
+ stopAnimation(id) {
5295
+ this._animator.stop(id);
5296
+ }
5184
5297
  ngOnDestroy() {
5185
5298
  super.ngOnDestroy();
5186
5299
  if (this._animator) {
@@ -5852,6 +5965,10 @@ class NgScrollerComponent extends NgScrollView {
5852
5965
  $updateScrollBar.pipe(takeUntil(this._$unsubscribe), debounceTime(0), tap(() => {
5853
5966
  this.updateScrollBarHandler(!this._isScrollbarUserAction);
5854
5967
  })).subscribe();
5968
+ const $grabbing = this.$grabbing;
5969
+ $grabbing.pipe(takeUntil(this._$unsubscribe), tap(v => {
5970
+ this._service.grabbing = v;
5971
+ })).subscribe();
5855
5972
  combineLatest([this.$classes, this.$direction, this.$grabbing, this.$motionBlurEnabled]).pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), debounceTime(0), tap(([classes, direction, grabbing, filtered]) => {
5856
5973
  this._$actualClasses.next({ ...classes, [direction]: true, grabbing, filtered });
5857
5974
  })).subscribe();
@@ -5989,7 +6106,7 @@ class NgScrollerComponent extends NgScrollView {
5989
6106
  this._isScrollbarUserAction = false;
5990
6107
  this.scrollBar?.stopScrolling();
5991
6108
  }
5992
- this.scroll({ ...params, userAction: userAction });
6109
+ return this.scroll({ ...params, userAction: userAction });
5993
6110
  }
5994
6111
  stopScrollbar() {
5995
6112
  if (!!this.scrollBar) {
@@ -6389,14 +6506,14 @@ class NgPrerenderVirtualListItemComponent extends NgVirtualListItemComponent {
6389
6506
  }
6390
6507
  }
6391
6508
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NgPrerenderVirtualListItemComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
6392
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", 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 });
6509
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", 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 });
6393
6510
  }
6394
6511
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NgPrerenderVirtualListItemComponent, decorators: [{
6395
6512
  type: Component,
6396
6513
  args: [{ selector: 'ng-prerender-virtual-list-item', host: {
6397
6514
  'class': 'ngvl__item',
6398
6515
  'role': 'listitem',
6399
- }, 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"] }]
6516
+ }, 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"] }]
6400
6517
  }] });
6401
6518
 
6402
6519
  /**
@@ -8044,7 +8161,7 @@ class NgVirtualListComponent extends DisposableComponent {
8044
8161
  return v;
8045
8162
  };
8046
8163
  /**
8047
- * Animation parameters. The default value is "{ scrollToItem: 50, snapToItem: 150, navigateToItem: 150, navigateByKeyboard: 50 }".
8164
+ * Animation parameters. The default value is "{ scrollToItem: 150, snapToItem: 150, navigateToItem: 150, navigateByKeyboard: 50 }".
8048
8165
  */
8049
8166
  set animationParams(v) {
8050
8167
  if (this._$animationParams.getValue() === v) {
@@ -8691,6 +8808,7 @@ class NgVirtualListComponent extends DisposableComponent {
8691
8808
  _readyForShow = false;
8692
8809
  _cached = false;
8693
8810
  _isLoading = false;
8811
+ _animationId = -1;
8694
8812
  get cachable() {
8695
8813
  return this._prerender?.active ?? false;
8696
8814
  }
@@ -8752,6 +8870,7 @@ class NgVirtualListComponent extends DisposableComponent {
8752
8870
  })).subscribe();
8753
8871
  }
8754
8872
  ngAfterViewInit() {
8873
+ let readyForAnimations = false;
8755
8874
  const _$created = new BehaviorSubject(false), $created = _$created.asObservable();
8756
8875
  combineLatest([$created, this.$show]).pipe(takeUntil(this._$unsubscribe), filter$1(([created, shown]) => created && shown), debounceTime(1), tap(v => {
8757
8876
  this._$initialized.next(true);
@@ -8944,6 +9063,7 @@ class NgVirtualListComponent extends DisposableComponent {
8944
9063
  }), tap(items => {
8945
9064
  this._trackBox.resetCollection(items, this.actualItemSize);
8946
9065
  }), switchMap$1(i => of((i ?? []).length > 0)), distinctUntilChanged(), tap(v => {
9066
+ readyForAnimations = false;
8947
9067
  if (!v) {
8948
9068
  this.cacheClean();
8949
9069
  this.cleanup();
@@ -9283,12 +9403,22 @@ class NgVirtualListComponent extends DisposableComponent {
9283
9403
  }), debounceTime(100), tap(() => {
9284
9404
  this._isLoading = false;
9285
9405
  })).subscribe();
9406
+ let prevCacheVersion = -1, prevScrollable = false;
9407
+ $viewInit.pipe(takeUntil(this._$unsubscribe), filter$1(v => !!v), switchMap$1(() => {
9408
+ return this.$show.pipe(takeUntil(this._$unsubscribe), debounceTime(Math.max(500, this._$animationParams.getValue().scrollToItem)), tap(() => {
9409
+ if (this._readyForShow || (this.cachable && this._cached)) {
9410
+ readyForAnimations = true;
9411
+ }
9412
+ }));
9413
+ })).subscribe();
9286
9414
  const update = (params) => {
9287
- const { alignment, snapScrollToStart, snapScrollToEnd, bounds, items, itemConfigMap, scrollSize, itemSize, minItemSize, maxItemSize, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, enabledBufferOptimization, snapToItem, snapToItemAlign, userAction, collapsedIds, itemTransform, } = params;
9415
+ const { alignment, snapScrollToStart, snapScrollToEnd, bounds, items, itemConfigMap, scrollSize, itemSize, minItemSize, maxItemSize, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, enabledBufferOptimization, snapToItem, snapToItemAlign, userAction, collapsedIds, cacheVersion, itemTransform, } = params;
9416
+ const cacheChanged = prevCacheVersion !== cacheVersion;
9417
+ prevCacheVersion = cacheVersion;
9288
9418
  const scroller = this._scrollerComponent;
9289
9419
  let totalSize = 0;
9290
9420
  if (!!scroller) {
9291
- 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;
9421
+ 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;
9292
9422
  if (this._readyForShow || (cachable && cached)) {
9293
9423
  const currentScrollSize = (isVertical ? scroller.scrollTop : scroller.scrollLeft);
9294
9424
  let actualScrollSize = !this._readyForShow && snapScrollToEnd ? (isVertical ? scroller.scrollHeight : scroller.scrollWidth) :
@@ -9332,12 +9462,13 @@ class NgVirtualListComponent extends DisposableComponent {
9332
9462
  if (!_$created.getValue()) {
9333
9463
  _$created.next(true);
9334
9464
  }
9335
- const delta = this._trackBox.delta, scrollPositionAfterUpdate = actualScrollSize + delta, roundedScrollPositionAfterUpdate = scrollPositionAfterUpdate, roundedMaxPositionAfterUpdate = isVertical ? scroller.scrollHeight : scroller.scrollWidth;
9465
+ const delta = this._trackBox.delta, scrollPositionAfterUpdate = actualScrollSize + delta, roundedScrollPositionAfterUpdate = scrollPositionAfterUpdate, roundedMaxPositionAfterUpdate = isVertical ? scroller.actualScrollHeight : scroller.actualScrollWidth;
9336
9466
  if (this._isSnappingMethodAdvanced) {
9337
9467
  this.updateRegularRenderer();
9338
9468
  }
9339
9469
  this.updateOffsetsByAllignment();
9340
9470
  scroller.delta = delta;
9471
+ prevScrollable = scroller.scrollable;
9341
9472
  if ((snapScrollToStart && this._trackBox.isSnappedToStart && scroller.scrollable) ||
9342
9473
  (snapScrollToStart && currentScrollSize <= MIN_PIXELS_FOR_PREVENT_SNAPPING)) {
9343
9474
  if (currentScrollSize !== roundedScrollPositionAfterUpdate) {
@@ -9348,9 +9479,16 @@ class NgVirtualListComponent extends DisposableComponent {
9348
9479
  this._trackBox.isScrollEnd;
9349
9480
  const params = {
9350
9481
  [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: 0, userAction,
9351
- fireUpdate: fireUpdateAtEdges, behavior: BEHAVIOR_INSTANT,
9352
- blending: false, duration: this.animationParams.scrollToItem,
9482
+ fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams.scrollToItem > 0 && this.scrollBehavior !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT),
9483
+ blending: useAnimations && scroller.hasAnimation(this._animationId), duration: this.animationParams.scrollToItem,
9353
9484
  };
9485
+ const animationId = scroller?.scrollTo?.(params);
9486
+ if (animationId > -1) {
9487
+ this._animationId = animationId;
9488
+ }
9489
+ else {
9490
+ scroller.stopAnimation(this._animationId);
9491
+ }
9354
9492
  scroller?.scrollTo?.(params);
9355
9493
  if (emitUpdate) {
9356
9494
  this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
@@ -9371,9 +9509,16 @@ class NgVirtualListComponent extends DisposableComponent {
9371
9509
  }
9372
9510
  const params = {
9373
9511
  [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: roundedMaxPositionAfterUpdate,
9374
- fireUpdate: fireUpdateAtEdges, behavior: BEHAVIOR_INSTANT, userAction: false,
9375
- blending: false, duration: this.animationParams.scrollToItem,
9512
+ fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams.scrollToItem > 0 && this.scrollBehavior !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT), userAction: false,
9513
+ blending: useAnimations && scroller.hasAnimation(this._animationId) || cacheChanged, duration: this.animationParams.scrollToItem,
9376
9514
  };
9515
+ const animationId = scroller?.scrollTo?.(params);
9516
+ if (animationId > -1) {
9517
+ this._animationId = animationId;
9518
+ }
9519
+ else {
9520
+ scroller.stopAnimation(this._animationId);
9521
+ }
9377
9522
  scroller?.scrollTo?.(params);
9378
9523
  if (emitUpdate) {
9379
9524
  this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
@@ -9387,9 +9532,13 @@ class NgVirtualListComponent extends DisposableComponent {
9387
9532
  if (this._readyForShow) {
9388
9533
  this.emitScrollEvent(true, false, userAction);
9389
9534
  }
9535
+ if (this._animationId > -1) {
9536
+ scroller.stopAnimation(this._animationId);
9537
+ this._animationId = -1;
9538
+ }
9390
9539
  const params = {
9391
9540
  [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollPositionAfterUpdate, blending: true, userAction,
9392
- fireUpdate, behavior: BEHAVIOR_INSTANT, duration: this.animationParams.scrollToItem,
9541
+ fireUpdate, behavior: BEHAVIOR_INSTANT, duration: 0,
9393
9542
  };
9394
9543
  scroller.scrollTo(params);
9395
9544
  if (emitUpdate) {
@@ -10104,7 +10253,7 @@ class NgVirtualListComponent extends DisposableComponent {
10104
10253
  comp?.destroy();
10105
10254
  }
10106
10255
  }
10107
- if (this._displayComponents) {
10256
+ if (!!this._displayComponents) {
10108
10257
  while (this._displayComponents.length > 0) {
10109
10258
  const comp = this._displayComponents.shift();
10110
10259
  comp?.destroy();