ng-virtual-list 22.12.1 → 22.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.
@@ -1,11 +1,11 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Injectable, inject, viewChild, signal, ElementRef, DestroyRef, effect, computed, ChangeDetectionStrategy, Component, output, Input, Directive, Injector, InjectionToken, input, ViewChild, ViewContainerRef, ViewEncapsulation, NO_ERRORS_SCHEMA, NgModule } from '@angular/core';
3
- import { Subject, BehaviorSubject, tap, map, fromEvent, race, of, debounceTime, switchMap as switchMap$1, combineLatest, filter as filter$1, delay, takeUntil as takeUntil$1, startWith, from, distinctUntilChanged, take, skip } from 'rxjs';
3
+ import { Subject, BehaviorSubject, distinctUntilChanged, combineLatest, tap, map, fromEvent, race, of, debounceTime, switchMap as switchMap$1, filter as filter$1, delay, takeUntil as takeUntil$1, startWith, from, take, skip } from 'rxjs';
4
4
  import { takeUntilDestroyed, toSignal, toObservable } from '@angular/core/rxjs-interop';
5
5
  import { BehaviorSubject as BehaviorSubject$1 } from 'rxjs/internal/BehaviorSubject';
6
6
  import * as i1 from '@angular/common';
7
7
  import { CommonModule } from '@angular/common';
8
- import { switchMap, takeUntil, filter, tap as tap$1 } from 'rxjs/operators';
8
+ import { tap as tap$1, switchMap, takeUntil, filter } from 'rxjs/operators';
9
9
  import * as i4 from '@angular/cdk/scrolling';
10
10
  import { CdkScrollable, CdkScrollableModule } from '@angular/cdk/scrolling';
11
11
 
@@ -248,6 +248,7 @@ var TextDirections;
248
248
  TextDirections["LTR"] = "ltr";
249
249
  })(TextDirections || (TextDirections = {}));
250
250
 
251
+ const INVISIBLE_POSITION = -10000;
251
252
  const SERVICE_PROP_DUMMY_ID = '__service-dummy-id__';
252
253
  const SERVICE_PROP_DUMMY = '__service-dummy__';
253
254
  const SERVICE_TYPE_DUMMY = '__service-type-dummy__';
@@ -277,7 +278,7 @@ const DEFAULT_MOTION_BLUR = 0.15;
277
278
  const DEFAULT_MOTION_BLUR_ENABLED = false;
278
279
  const DEFAULT_MAX_MOTION_BLUR = 0.5;
279
280
  const DEFAULT_ANIMATION_PARAMS = {
280
- scrollToItem: 50,
281
+ scrollToItem: 150,
281
282
  snapToItem: 150,
282
283
  navigateToItem: 150,
283
284
  navigateByKeyboard: NAVIGATION_BY_KEYBOARD_TIMER,
@@ -333,13 +334,15 @@ const POSITION$1 = 'position';
333
334
  const POSITION_RELATIVE = 'relative';
334
335
  const POSITION_ABSOLUTE = 'absolute';
335
336
  const TRANSLATE_3D = 'translate3d';
336
- const ZEROS_TRANSLATE_3D = `${TRANSLATE_3D}(0,0,0)`;
337
+ const INVISIBLE_TRANSLATE_3D = `${TRANSLATE_3D}(${INVISIBLE_POSITION},${INVISIBLE_POSITION},0)`;
337
338
  const HIDDEN_ZINDEX = '-1';
338
339
  const DEFAULT_ZINDEX = '0';
339
340
  const TOP_PROP_NAME = 'top';
340
341
  const LEFT_PROP_NAME = 'left';
341
342
  const X_PROP_NAME = 'x';
342
343
  const Y_PROP_NAME = 'y';
344
+ const TRANSFORMED_X_PROP_NAME = 'transformedX';
345
+ const TRANSFORMED_Y_PROP_NAME = 'transformedY';
343
346
  const WIDTH_PROP_NAME = 'width';
344
347
  const HEIGHT_PROP_NAME = 'height';
345
348
  const MARGIN_TOP = 'marginTop';
@@ -669,6 +672,31 @@ class NgVirtualListService {
669
672
  this._langTextDir = v;
670
673
  this._$langTextDir.next(v);
671
674
  }
675
+ _$grabbing = new BehaviorSubject$1(false);
676
+ $grabbing = this._$grabbing.asObservable();
677
+ get grabbing() { return this._$grabbing.getValue(); }
678
+ _grabbing = false;
679
+ set grabbing(v) {
680
+ if (this._grabbing === v) {
681
+ return;
682
+ }
683
+ this._grabbing = v;
684
+ this._$grabbing.next(v);
685
+ }
686
+ _$clickPressed = new BehaviorSubject$1(false);
687
+ $clickPressed = this._$clickPressed.asObservable();
688
+ get clickPressed() { return this._$clickPressed.getValue(); }
689
+ _clickPressed = false;
690
+ set clickPressed(v) {
691
+ if (this._clickPressed === v) {
692
+ return;
693
+ }
694
+ this._clickPressed = v;
695
+ this._$clickPressed.next(v);
696
+ }
697
+ _$isGrabbing = new BehaviorSubject$1(false);
698
+ $isGrabbing = this._$isGrabbing.asObservable();
699
+ get isGrabbing() { return this._$isGrabbing.getValue(); }
672
700
  get scrollBarSize() { return this._$scrollBarSize.getValue(); }
673
701
  _scrollBarSize = 0;
674
702
  set scrollBarSize(v) {
@@ -712,6 +740,10 @@ class NgVirtualListService {
712
740
  }
713
741
  get collapsedIds() { return this._$collapsedIds.getValue(); }
714
742
  constructor() {
743
+ const $grabbing = this.$grabbing.pipe(takeUntilDestroyed(), distinctUntilChanged()), $clickPressed = this.$clickPressed.pipe(takeUntilDestroyed(), distinctUntilChanged());
744
+ combineLatest([$grabbing, $clickPressed]).pipe(takeUntilDestroyed(), tap(([grabbing, clickPressed]) => {
745
+ this._$isGrabbing.next(grabbing && !clickPressed);
746
+ })).subscribe();
715
747
  this._$selectingMode.pipe(takeUntilDestroyed(), tap(v => {
716
748
  switch (v) {
717
749
  case SelectingModesTypes.SELECT: {
@@ -1162,7 +1194,7 @@ class BaseVirtualListItemComponent {
1162
1194
  }
1163
1195
  this._data = v;
1164
1196
  this.updatePartStr(v, this._isSelected, this._isCollapsed);
1165
- this.updateConfig(v);
1197
+ this.updateConfig(v, this._service.isGrabbing);
1166
1198
  this.updateMeasures(v);
1167
1199
  this.update();
1168
1200
  this.data.set(v);
@@ -1212,6 +1244,9 @@ class BaseVirtualListItemComponent {
1212
1244
  this._id = this._service.generateComponentId();
1213
1245
  this._listId = this._service.id;
1214
1246
  this._displayId = createDisplayId(this._listId, this._id);
1247
+ this._service.$isGrabbing.pipe(takeUntilDestroyed(), tap(v => {
1248
+ this.updateConfig(this._data, v);
1249
+ })).subscribe();
1215
1250
  effect(() => {
1216
1251
  const part = this.part();
1217
1252
  this._elementRef.nativeElement.setAttribute('part', part);
@@ -1252,9 +1287,9 @@ class BaseVirtualListItemComponent {
1252
1287
  updateMeasures(v) {
1253
1288
  this.measures.set(v?.measures ? { ...v.measures } : null);
1254
1289
  }
1255
- updateConfig(v) {
1290
+ updateConfig(v, grabbing) {
1256
1291
  this.config.set({
1257
- ...v?.config || {}, selected: this._isSelected, collapsed: this._isCollapsed, focused: this.focused(),
1292
+ ...v?.config || {}, selected: this._isSelected, collapsed: this._isCollapsed, focused: this.focused(), grabbing,
1258
1293
  });
1259
1294
  }
1260
1295
  update() {
@@ -1380,6 +1415,7 @@ class BaseVirtualListItemComponent {
1380
1415
  }
1381
1416
  const el = this._elementRef.nativeElement, styles = el.style;
1382
1417
  styles.zIndex = HIDDEN_ZINDEX;
1418
+ styles.transform = INVISIBLE_TRANSLATE_3D;
1383
1419
  if (this.regular) {
1384
1420
  if (styles.display === DISPLAY_NONE) {
1385
1421
  return;
@@ -1406,7 +1442,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImpor
1406
1442
  }]
1407
1443
  }], ctorParameters: () => [], propDecorators: { _item: [{ type: i0.ViewChild, args: ['item', { isSignal: true }] }], _container: [{ type: i0.ViewChild, args: ['container', { isSignal: true }] }] } });
1408
1444
 
1409
- const DEFAULT_MAX_DISTANCE = 40;
1410
1445
  /**
1411
1446
  * VirtualClickDirective
1412
1447
  * Maximum performance for extremely large lists.
@@ -1416,29 +1451,44 @@ const DEFAULT_MAX_DISTANCE = 40;
1416
1451
  * @email djonnyx@gmail.com
1417
1452
  */
1418
1453
  class VirtualClickDirective {
1419
- _maxDistance = DEFAULT_MAX_DISTANCE;
1454
+ _$maxDistance = new BehaviorSubject(null);
1455
+ $maxDistance = this._$maxDistance.asObservable();
1456
+ _maxDistance = null;
1420
1457
  set maxDistance(v) {
1421
- this._maxDistance = (v !== null || v !== undefined) ? Number(v) : DEFAULT_MAX_DISTANCE;
1458
+ const value = (v !== null || v !== undefined) ? Number(v) : null;
1459
+ this._maxDistance = value;
1460
+ this._$maxDistance.next(value);
1422
1461
  }
1423
1462
  onVirtualClick = output();
1463
+ onVirtualClickPress = output();
1464
+ onVirtualClickCancel = output();
1465
+ _service = inject(NgVirtualListService);
1424
1466
  _elementRef = inject(ElementRef);
1425
1467
  _destroyRef = inject(DestroyRef);
1426
1468
  constructor() {
1469
+ let maxDistance = this._maxDistance ?? DEFAULT_CLICK_DISTANCE;
1470
+ combineLatest([this._service.$clickDistance, this.$maxDistance]).pipe(takeUntilDestroyed(), tap$1(([clickDistance, distance]) => {
1471
+ maxDistance = distance === null ? clickDistance : distance;
1472
+ })).subscribe();
1427
1473
  const $pointerPressed = fromEvent(this._elementRef.nativeElement, 'pointerdown'), $pointerCancel = race([
1428
1474
  fromEvent(window, 'pointerup').pipe(takeUntilDestroyed()),
1429
1475
  fromEvent(window, 'pointerleave').pipe(takeUntilDestroyed()),
1430
1476
  ]), $pointerRelease = fromEvent(this._elementRef.nativeElement, 'pointerup', { passive: false });
1431
1477
  $pointerPressed.pipe(takeUntilDestroyed(), switchMap(e => {
1432
1478
  const x = Math.abs(e.clientX), y = Math.abs(e.clientY);
1479
+ this.onVirtualClickPress.emit(e);
1433
1480
  return $pointerRelease.pipe(takeUntilDestroyed(this._destroyRef), takeUntil(race([
1434
- $pointerCancel,
1481
+ $pointerCancel.pipe(takeUntilDestroyed(this._destroyRef), tap$1(() => {
1482
+ this.onVirtualClickCancel.emit();
1483
+ })),
1435
1484
  fromEvent(window, 'pointermove').pipe(takeUntilDestroyed(this._destroyRef), switchMap(e => {
1436
1485
  const xx = x - Math.abs(e.clientX), yy = y - Math.abs(e.clientY), dist = Math.sqrt(Math.pow(xx, 2) + Math.pow(yy, 2));
1437
- if (dist > this._maxDistance) {
1486
+ if (dist > maxDistance) {
1487
+ this.onVirtualClickCancel.emit();
1438
1488
  return of(true);
1439
1489
  }
1440
1490
  return of(false);
1441
- }), takeUntilDestroyed(this._destroyRef), filter(v => !!v)),
1491
+ }), filter(v => !!v)),
1442
1492
  ])), takeUntilDestroyed(this._destroyRef), tap$1(e => {
1443
1493
  if (e) {
1444
1494
  this.onVirtualClick.emit(e);
@@ -1447,7 +1497,7 @@ class VirtualClickDirective {
1447
1497
  })).subscribe();
1448
1498
  }
1449
1499
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: VirtualClickDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1450
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.0", type: VirtualClickDirective, isStandalone: false, selector: "[virtualClick]", inputs: { maxDistance: ["maxClickDistance", "maxDistance"] }, outputs: { onVirtualClick: "onVirtualClick" }, ngImport: i0 });
1500
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.0", type: VirtualClickDirective, isStandalone: false, selector: "[virtualClick]", inputs: { maxDistance: ["maxClickDistance", "maxDistance"] }, outputs: { onVirtualClick: "onVirtualClick", onVirtualClickPress: "onVirtualClickPress", onVirtualClickCancel: "onVirtualClickCancel" }, ngImport: i0 });
1451
1501
  }
1452
1502
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: VirtualClickDirective, decorators: [{
1453
1503
  type: Directive,
@@ -1458,7 +1508,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImpor
1458
1508
  }], ctorParameters: () => [], propDecorators: { maxDistance: [{
1459
1509
  type: Input,
1460
1510
  args: ['maxClickDistance']
1461
- }], onVirtualClick: [{ type: i0.Output, args: ["onVirtualClick"] }] } });
1511
+ }], onVirtualClick: [{ type: i0.Output, args: ["onVirtualClick"] }], onVirtualClickPress: [{ type: i0.Output, args: ["onVirtualClickPress"] }], onVirtualClickCancel: [{ type: i0.Output, args: ["onVirtualClickCancel"] }] } });
1462
1512
 
1463
1513
  /**
1464
1514
  * Virtual list component.
@@ -1489,12 +1539,12 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
1489
1539
  fromEvent(this.element, EVENT_FOCUS_IN).pipe(takeUntilDestroyed(this._destroyRef), tap(e => {
1490
1540
  this._service.focusedId = this.itemId ?? null;
1491
1541
  this.focused.set(true);
1492
- this.updateConfig(this._data);
1542
+ this.updateConfig(this._data, this._service.isGrabbing);
1493
1543
  this.updatePartStr(this._data, this._isSelected, this._isCollapsed);
1494
1544
  })).subscribe(),
1495
1545
  fromEvent(this.element, EVENT_FOCUS_OUT).pipe(takeUntilDestroyed(this._destroyRef), tap(e => {
1496
1546
  this.focused.set(false);
1497
- this.updateConfig(this._data);
1547
+ this.updateConfig(this._data, this._service.isGrabbing);
1498
1548
  this.updatePartStr(this._data, this._isSelected, this._isCollapsed);
1499
1549
  })).subscribe();
1500
1550
  $focused.pipe(takeUntilDestroyed(this._destroyRef), debounceTime(this.getNavigationTimeout()), switchMap$1(v => {
@@ -1527,7 +1577,7 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
1527
1577
  const actualIds = collapsedIds, isCollapsed = this.itemId !== undefined && actualIds && actualIds.includes(this.itemId);
1528
1578
  this._isCollapsed = isCollapsed;
1529
1579
  this.updatePartStr(this._data, this._isSelected, isCollapsed);
1530
- this.updateConfig(this._data);
1580
+ this.updateConfig(this._data, this._service.isGrabbing);
1531
1581
  this.updateMeasures(this._data);
1532
1582
  })).subscribe();
1533
1583
  }
@@ -1630,23 +1680,29 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
1630
1680
  }
1631
1681
  return Number.MIN_SAFE_INTEGER;
1632
1682
  }
1633
- updateConfig(v) {
1683
+ updateConfig(v, grabbing) {
1634
1684
  this.config.set({
1635
- ...v?.config || {}, selected: this._isSelected, collapsed: this._isCollapsed, focused: this.focused(),
1685
+ ...v?.config || {}, selected: this._isSelected, collapsed: this._isCollapsed, focused: this.focused(), grabbing,
1636
1686
  });
1637
1687
  }
1638
1688
  onClickHandler() {
1639
1689
  this._service.virtualClick(this._data);
1640
1690
  }
1691
+ onClickPressHandler() {
1692
+ this._service.clickPressed = true;
1693
+ }
1694
+ onClickCancelHandler() {
1695
+ this._service.clickPressed = false;
1696
+ }
1641
1697
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: NgVirtualListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1642
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.0", type: NgVirtualListItemComponent, isStandalone: false, selector: "ng-virtual-list-item", host: { attributes: { "role": "listitem" }, classAttribute: "ngvl__item" }, usesInheritance: true, ngImport: i0, template: "@let renderer = itemRenderer();\r\n@let class = classes();\r\n<div #item class=\"ngvl-item\" [ngClass]=\"class\" [part]=\"part()\" [attr.ngvl-index]=\"index()\" [attr.ngvl-visibility]=\"visibility\" tabindex=\"-1\">\r\n @if (_blendColor) {\r\n <div class=\"ngvl-item__blend-color\" [style.--blend-color]=\"_blendColor\"></div>\r\n }\r\n <div #container virtualClick [part]=\"fxPart()\" [maxClickDistance]=\"maxClickDistance()\" class=\"ngvl-item__container\"\r\n [ngClass]=\"class\" (onVirtualClick)=\"onClickHandler()\">\r\n @if (renderer) {\r\n <ng-container [ngTemplateOutlet]=\"renderer\" [ngTemplateOutletContext]=\"templateContext()\" />\r\n }\r\n </div>\r\n</div>", 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.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: VirtualClickDirective, selector: "[virtualClick]", inputs: ["maxClickDistance"], outputs: ["onVirtualClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1698
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.0", type: NgVirtualListItemComponent, isStandalone: false, selector: "ng-virtual-list-item", host: { attributes: { "role": "listitem" }, classAttribute: "ngvl__item" }, usesInheritance: true, ngImport: i0, template: "@let renderer = itemRenderer();\r\n@let class = classes();\r\n<div #item class=\"ngvl-item\" [ngClass]=\"class\" [part]=\"part()\" [attr.ngvl-index]=\"index()\"\r\n [attr.ngvl-visibility]=\"visibility\" tabindex=\"-1\">\r\n @if (_blendColor) {\r\n <div class=\"ngvl-item__blend-color\" [style.--blend-color]=\"_blendColor\"></div>\r\n }\r\n <div #container virtualClick [part]=\"fxPart()\" [maxClickDistance]=\"maxClickDistance()\" class=\"ngvl-item__container\"\r\n [ngClass]=\"class\" (onVirtualClick)=\"onClickHandler()\" (onVirtualClickPress)=\"onClickPressHandler()\"\r\n (onVirtualClickCancel)=\"onClickCancelHandler()\">\r\n @if (renderer) {\r\n <ng-container [ngTemplateOutlet]=\"renderer\" [ngTemplateOutletContext]=\"templateContext()\" />\r\n }\r\n </div>\r\n</div>", 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.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: VirtualClickDirective, selector: "[virtualClick]", inputs: ["maxClickDistance"], outputs: ["onVirtualClick", "onVirtualClickPress", "onVirtualClickCancel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1643
1699
  }
1644
1700
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: NgVirtualListItemComponent, decorators: [{
1645
1701
  type: Component,
1646
1702
  args: [{ selector: 'ng-virtual-list-item', host: {
1647
1703
  'class': 'ngvl__item',
1648
1704
  'role': 'listitem',
1649
- }, standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "@let renderer = itemRenderer();\r\n@let class = classes();\r\n<div #item class=\"ngvl-item\" [ngClass]=\"class\" [part]=\"part()\" [attr.ngvl-index]=\"index()\" [attr.ngvl-visibility]=\"visibility\" tabindex=\"-1\">\r\n @if (_blendColor) {\r\n <div class=\"ngvl-item__blend-color\" [style.--blend-color]=\"_blendColor\"></div>\r\n }\r\n <div #container virtualClick [part]=\"fxPart()\" [maxClickDistance]=\"maxClickDistance()\" class=\"ngvl-item__container\"\r\n [ngClass]=\"class\" (onVirtualClick)=\"onClickHandler()\">\r\n @if (renderer) {\r\n <ng-container [ngTemplateOutlet]=\"renderer\" [ngTemplateOutletContext]=\"templateContext()\" />\r\n }\r\n </div>\r\n</div>", 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"] }]
1705
+ }, standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "@let renderer = itemRenderer();\r\n@let class = classes();\r\n<div #item class=\"ngvl-item\" [ngClass]=\"class\" [part]=\"part()\" [attr.ngvl-index]=\"index()\"\r\n [attr.ngvl-visibility]=\"visibility\" tabindex=\"-1\">\r\n @if (_blendColor) {\r\n <div class=\"ngvl-item__blend-color\" [style.--blend-color]=\"_blendColor\"></div>\r\n }\r\n <div #container virtualClick [part]=\"fxPart()\" [maxClickDistance]=\"maxClickDistance()\" class=\"ngvl-item__container\"\r\n [ngClass]=\"class\" (onVirtualClick)=\"onClickHandler()\" (onVirtualClickPress)=\"onClickPressHandler()\"\r\n (onVirtualClickCancel)=\"onClickCancelHandler()\">\r\n @if (renderer) {\r\n <ng-container [ngTemplateOutlet]=\"renderer\" [ngTemplateOutletContext]=\"templateContext()\" />\r\n }\r\n </div>\r\n</div>", 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"] }]
1650
1706
  }], ctorParameters: () => [] });
1651
1707
 
1652
1708
  /**
@@ -3206,7 +3262,7 @@ class TrackBox extends CacheMap {
3206
3262
  const { width, height, normalizedItemWidth, normalizedItemHeight, dynamicSize, divides, itemsOnDisplayLength, itemsFromStartToScrollEnd, isVertical, leftLayoutOffset: layoutOffset, leftLayoutIndexOffset: layoutIndexOffset, renderItems: renderItemsLength, scrollSize, sizeProperty, stickyEnabled, stickyPos, startPosition, totalLength, startIndex, typicalItemSize, minItemSize, maxItemSize, snapToItem, snapToItemAlign, itemTransform, } = metrics, displayItems = [];
3207
3263
  if (items.length) {
3208
3264
  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;
3209
- let pos = startPosition, renderItems = renderItemsLength, stickyItem, nextSticky, stickyItemIndex = -1, stickyItemSize = 0, endStickyItem, nextEndSticky, endStickyItemIndex = -1, endStickyItemSize = 0;
3265
+ let pos = startPosition, renderItems = renderItemsLength, stickyItem, nextSticky, stickyItemIndex = -1, nexstStickyItemIndex = -1, stickyItemSize = 0, endStickyItem, nextEndSticky, endStickyItemIndex = -1, endStickyItemSize = 0;
3210
3266
  const li = layoutIndexOffset + actualItems.length - 1;
3211
3267
  if (stickyEnabled) {
3212
3268
  for (let i = Math.min(itemsFromStartToScrollEnd > 0 ? (divides > 1 ? (itemsFromStartToScrollEnd - 1) : itemsFromStartToScrollEnd) : 0, totalLength - 1); i >= 0; i--) {
@@ -3466,6 +3522,7 @@ class TrackBox extends CacheMap {
3466
3522
  item.measures.x = isVertical ? 0 : snapped ? actualSnippedPosition : pos;
3467
3523
  item.measures.y = isVertical ? snapped ? actualSnippedPosition : pos : 0;
3468
3524
  nextSticky = item;
3525
+ nexstStickyItemIndex = displayItems.length;
3469
3526
  nextSticky.config.snapped = snapped;
3470
3527
  nextSticky.measures.delta = (isVertical ? item.measures.y : item.measures.x) - scrollSize;
3471
3528
  nextSticky.config.zIndex = Z_INDEX_3;
@@ -3488,10 +3545,10 @@ class TrackBox extends CacheMap {
3488
3545
  }
3489
3546
  i++;
3490
3547
  }
3491
- const axis = isVertical ? Y_PROP_NAME : X_PROP_NAME;
3548
+ const axis = isVertical ? Y_PROP_NAME : X_PROP_NAME, transformedAxis = isVertical ? TRANSFORMED_Y_PROP_NAME : TRANSFORMED_X_PROP_NAME;
3492
3549
  if (!!nextSticky && !!stickyItem && nextSticky.measures[axis] <= actualSnippedPosition + stickyItem.measures[sizeProperty]) {
3493
3550
  if (nextSticky.measures[axis] > actualSnippedPosition) {
3494
- stickyItem.measures[axis] = nextSticky.measures[axis] - stickyItem.measures[sizeProperty];
3551
+ stickyItem.measures[axis] = stickyItem.measures[transformedAxis] = nextSticky.measures[axis] - stickyItem.measures[sizeProperty];
3495
3552
  stickyItem.config.snapped = nextSticky.config.snapped = false;
3496
3553
  stickyItem.config.snappedOut = true;
3497
3554
  stickyItem.config.sticky = 1;
@@ -3500,14 +3557,35 @@ class TrackBox extends CacheMap {
3500
3557
  else {
3501
3558
  nextSticky.config.snapped = true;
3502
3559
  nextSticky.measures.delta = (isVertical ? nextSticky.measures.y : nextSticky.measures.x) - scrollSize;
3503
- stickyItem.measures[axis] = nextSticky.measures[axis] - stickyItem.measures[sizeProperty];
3560
+ stickyItem.measures[axis] = stickyItem.measures[transformedAxis] = nextSticky.measures[axis] - stickyItem.measures[sizeProperty];
3504
3561
  stickyItem.measures.delta = (isVertical ? stickyItem.measures.y : stickyItem.measures.x) - scrollSize;
3562
+ const lastStickyItem = displayItems?.[nexstStickyItemIndex + 1];
3563
+ if (lastStickyItem?.config?.sticky === 1 && displayItems?.[nexstStickyItemIndex + 2]?.config?.sticky !== 1) {
3564
+ nextSticky.config.snapped = nextSticky.config.snappedOut = false;
3565
+ stickyItem.config.snappedOut = true;
3566
+ nextSticky.measures.delta = this._scrollStartOffset;
3567
+ if (lastStickyItem.measures[axis] <= actualSnippedPosition) {
3568
+ lastStickyItem.config.snapped = lastStickyItem.config.snappedOut = true;
3569
+ lastStickyItem.measures[axis] = lastStickyItem.measures[transformedAxis] = lastStickyItem.measures.position = actualSnippedPosition;
3570
+ lastStickyItem.measures.delta = this._scrollStartOffset;
3571
+ }
3572
+ }
3573
+ else if (lastStickyItem?.config?.sticky !== 1 && displayItems?.[nexstStickyItemIndex + 2]?.config?.sticky !== 1) {
3574
+ if (nextSticky.measures[axis] <= actualSnippedPosition) {
3575
+ nextSticky.config.snapped = nextSticky.config.snappedOut = true;
3576
+ nextSticky.measures[axis] = nextSticky.measures[transformedAxis] = nextSticky.measures.position = actualSnippedPosition;
3577
+ nextSticky.measures.delta = this._scrollStartOffset;
3578
+ }
3579
+ }
3580
+ else {
3581
+ nextSticky.config.snapped = nextSticky.config.snappedOut = false;
3582
+ }
3505
3583
  }
3506
3584
  }
3507
3585
  if (!!nextEndSticky && !!endStickyItem &&
3508
3586
  (nextEndSticky.measures[axis] >= actualEndSnippedPosition - endStickyItemSize - nextEndSticky.measures[sizeProperty])) {
3509
3587
  if (nextEndSticky.measures[axis] < actualEndSnippedPosition - nextEndSticky.measures[sizeProperty]) {
3510
- endStickyItem.measures[axis] = nextEndSticky.measures[axis] + nextEndSticky.measures[sizeProperty];
3588
+ endStickyItem.measures[axis] = endStickyItem.measures[transformedAxis] = nextEndSticky.measures[axis] + nextEndSticky.measures[sizeProperty];
3511
3589
  endStickyItem.config.snapped = nextEndSticky.config.snapped = false;
3512
3590
  endStickyItem.config.snappedOut = true;
3513
3591
  endStickyItem.config.sticky = 2;
@@ -3515,9 +3593,9 @@ class TrackBox extends CacheMap {
3515
3593
  }
3516
3594
  else {
3517
3595
  nextEndSticky.config.snapped = true;
3518
- nextEndSticky.measures[axis] = actualEndSnippedPosition - nextEndSticky.measures[sizeProperty];
3596
+ nextEndSticky.measures[axis] = nextEndSticky.measures[transformedAxis] = actualEndSnippedPosition - nextEndSticky.measures[sizeProperty];
3519
3597
  nextEndSticky.measures.delta = (isVertical ? nextEndSticky.measures.y : nextEndSticky.measures.x) - scrollSize;
3520
- endStickyItem.measures[axis] = nextEndSticky.measures[axis] + nextEndSticky.measures[sizeProperty];
3598
+ endStickyItem.measures[axis] = endStickyItem.measures[transformedAxis] = nextEndSticky.measures[axis] + nextEndSticky.measures[sizeProperty];
3521
3599
  endStickyItem.measures.delta = (isVertical ? endStickyItem.measures.y : endStickyItem.measures.x) - scrollSize;
3522
3600
  }
3523
3601
  }
@@ -3981,18 +4059,32 @@ const easeLinear = (t) => {
3981
4059
  class Animator {
3982
4060
  static _nextId = 0;
3983
4061
  _animationId = 0;
4062
+ get animated() { return this._animationId > -1; }
4063
+ get isAnimated() { return this.hasAnimation(this._currentId); }
3984
4064
  _currentId = Animator._nextId;
4065
+ get id() { return this._currentId; }
3985
4066
  generateId() {
3986
4067
  return Animator._nextId = Animator._nextId === Number.MAX_SAFE_INTEGER
3987
4068
  ? 0 : Animator._nextId + 1;
3988
4069
  }
4070
+ _diff = 0;
4071
+ _startValue = 0;
4072
+ _endValue = 0;
4073
+ updateTo(value) {
4074
+ this._endValue = value;
4075
+ this._diff = this._endValue - this._startValue;
4076
+ return this.hasAnimation();
4077
+ }
3989
4078
  animate(params) {
3990
4079
  this.stop();
3991
4080
  const id = this.generateId();
3992
4081
  this._currentId = id;
3993
4082
  const { withDelta = DEFAULT_WITH_DELTA, startValue, endValue, duration = DEFAULT_ANIMATION_DURATION, getPropValue, easingFunction = easeLinear, onUpdate, onComplete, } = params;
4083
+ this._startValue = startValue;
4084
+ this._endValue = endValue;
3994
4085
  const startTime = performance.now();
3995
- let isCanceled = false, prevPos = startValue, start = startValue, startPosDelta = 0, delta = 0, prevTime = startTime, diff = endValue - start, isFinished = false;
4086
+ let isCanceled = false, prevPos = startValue, startPosDelta = 0, delta = 0, prevTime = startTime, isFinished = false;
4087
+ this._diff = this._endValue - this._startValue;
3996
4088
  const step = (currentTime) => {
3997
4089
  if (id !== this._currentId) {
3998
4090
  isCanceled = true;
@@ -4006,10 +4098,10 @@ class Animator {
4006
4098
  startDelta = cPos - prevPos;
4007
4099
  startPosDelta += startDelta;
4008
4100
  }
4009
- 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();
4101
+ const elapsed = currentTime - startTime, progress = this._startValue === endValue ? 1 : Math.min(duration > 0 ? elapsed / duration : 0, 1), easedProgress = easingFunction(progress), val = (withDelta ? startPosDelta : 0) + this._startValue + this._diff * easedProgress, currentValue = val, t = performance.now();
4010
4102
  isFinished = progress === 1;
4011
4103
  delta = currentValue - startDelta - prevPos;
4012
- const ts = t - prevTime, timestamp = ts < ANIMATOR_MIN_TIMESTAMP ? ANIMATOR_MIN_TIMESTAMP : ts;
4104
+ const frameTimestamp = t - prevTime, actualFrameTimestamp = frameTimestamp < ANIMATOR_MIN_TIMESTAMP ? ANIMATOR_MIN_TIMESTAMP : frameTimestamp;
4013
4105
  prevTime = t;
4014
4106
  prevPos = currentValue;
4015
4107
  if (onUpdate !== undefined) {
@@ -4018,18 +4110,19 @@ class Animator {
4018
4110
  delta,
4019
4111
  elapsed,
4020
4112
  value: !withDelta && isFinished ? endValue : currentValue,
4021
- timestamp,
4113
+ timestamp: actualFrameTimestamp,
4022
4114
  };
4023
4115
  onUpdate(data);
4024
4116
  }
4025
4117
  if (isFinished) {
4118
+ this._animationId = -1;
4026
4119
  if (onComplete !== undefined) {
4027
4120
  const data = {
4028
4121
  id,
4029
4122
  delta,
4030
4123
  elapsed,
4031
4124
  value: withDelta ? currentValue : endValue,
4032
- timestamp,
4125
+ timestamp: actualFrameTimestamp,
4033
4126
  };
4034
4127
  onComplete(data);
4035
4128
  }
@@ -4039,9 +4132,17 @@ class Animator {
4039
4132
  }
4040
4133
  };
4041
4134
  this._animationId = requestAnimationFrame(step);
4135
+ return this._currentId;
4136
+ }
4137
+ hasAnimation(id = -1) {
4138
+ if ((this._currentId === id || id === -1) && this.animated) {
4139
+ return true;
4140
+ }
4141
+ return false;
4042
4142
  }
4043
- stop() {
4044
- cancelAnimationFrame(this._animationId);
4143
+ stop(id = -1) {
4144
+ cancelAnimationFrame(id === -1 ? this._animationId : id);
4145
+ this._animationId = -1;
4045
4146
  }
4046
4147
  dispose() {
4047
4148
  this.stop();
@@ -4051,7 +4152,7 @@ class Animator {
4051
4152
  const SCROLL_VIEW_INVERSION = new InjectionToken('ScrollViewInversion');
4052
4153
  const SCROLL_VIEW_OVERSCROLL_ENABLED = new InjectionToken('ScrollViewOverscrollEnabled');
4053
4154
  const SCROLL_VIEW_NORMALIZE_VALUE_FROM_ZERO = new InjectionToken('ScrollViewNormalizeValueFromZero');
4054
- const TOP$1 = 'top', LEFT$1 = 'left', INSTANT$1 = 'instant', AUTO = 'auto', SMOOTH = 'smooth', DURATION = 2000, FRICTION_FORCE = .035, MAX_DURATION = 4000, ANIMATION_DURATION = 50, MASS = .005, MAX_DIST = 12500, MAX_VELOCITY_TIMESTAMP = 100, SPEED_SCALE = 15, OVERSCROLL_START_ITERATION = 2, INTERSECTION_DISTANCE = 1;
4155
+ const TOP$1 = 'top', LEFT$1 = 'left', INSTANT$1 = 'instant', AUTO = 'auto', SMOOTH = 'smooth', DURATION = 2000, FRICTION_FORCE = .035, MAX_DURATION = 4000, ANIMATION_DURATION = 50, MASS = .005, ACCELERATION_SCALE = 40, MAX_DIST = 12500, MAX_VELOCITY_TIMESTAMP = 100, SPEED_SCALE = 15, OVERSCROLL_START_ITERATION = 2;
4055
4156
  const MAX_ITERATIONS_FOR_AVERAGE_CALCULATIONS = 5, INSTANT_VELOCITY_SCALE = 1000;
4056
4157
  const SCROLL_EVENT$1 = new Event(SCROLLER_SCROLL);
4057
4158
 
@@ -4498,6 +4599,7 @@ class NgScrollView extends BaseScrollView {
4498
4599
  get startLayoutOffset() { return this._startLayoutOffset; }
4499
4600
  _intersectionComponentId = null;
4500
4601
  _isAlignmentAnimation = false;
4602
+ get animated() { return this._animator?.isAnimated ?? false; }
4501
4603
  constructor() {
4502
4604
  super();
4503
4605
  let mouseCanceled = false, touchCanceled = false;
@@ -4689,6 +4791,7 @@ class NgScrollView extends BaseScrollView {
4689
4791
  }));
4690
4792
  })).subscribe();
4691
4793
  }
4794
+ hasAnimation(id = -1) { return this._animator?.hasAnimation(id) ?? false; }
4692
4795
  updateDirection(position, prePosition) {
4693
4796
  const delta = (position - this._delta) - prePosition;
4694
4797
  this._scrollDirection.add(delta > 0 ? 1 : delta < 0 ? -1 : 0);
@@ -4828,8 +4931,8 @@ class NgScrollView extends BaseScrollView {
4828
4931
  continue;
4829
4932
  }
4830
4933
  if (v00) {
4831
- const a0 = timestamp < MAX_VELOCITY_TIMESTAMP ? (v00[1] !== 0 ? (lastVSign * Math.abs(Math.abs(v01[0]) - Math.abs(v00[0]))) / Math.abs(v00[1]) : 0) : 0.1;
4832
- aSum = (aSum * mass) + a0;
4934
+ const a0 = timestamp < MAX_VELOCITY_TIMESTAMP ? (v00[1] !== 0 ? (lastVSign * Math.abs(Math.abs(v01[0]) - Math.abs(v00[0]))) / Math.abs(v00[1]) : 0) : .1;
4935
+ aSum = Math.abs((aSum * mass)) + Math.abs(a0);
4833
4936
  prevV0 = v01;
4834
4937
  }
4835
4938
  prevV0 = v01;
@@ -4850,8 +4953,8 @@ class NgScrollView extends BaseScrollView {
4850
4953
  }
4851
4954
  moveWithAcceleration(isVertical, position, v0, v, a0, timestamp) {
4852
4955
  if (a0 !== 0 && timestamp < MAX_VELOCITY_TIMESTAMP) {
4853
- 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) / 1000) / mass, distance = Math.abs(s) < maxDist ? s : maxDistance, positionWithVelocity = position + (this._inversion ? -1 : 1) * distance, vmax = Math.max(Math.abs(v0), Math.abs(v)), ad = Math.abs(vmax !== 0 ? Math.sqrt(vmax) : 0) * 10 / mass, aDuration = ad < maxDuration ? ad : maxDuration, startPosition = isVertical ? this.y : this.x;
4854
- this.animate(startPosition, Math.round(positionWithVelocity), aDuration, easeOutQuad, true);
4956
+ 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;
4957
+ this.animate(startPosition, Math.round(positionWithVelocity), aDuration, easeOutQuad, false, true);
4855
4958
  }
4856
4959
  else {
4857
4960
  this.alignPosition(true, true);
@@ -4864,11 +4967,17 @@ class NgScrollView extends BaseScrollView {
4864
4967
  const isVertical = this.isVertical(), 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;
4865
4968
  return result;
4866
4969
  }
4867
- animate(startValue, endValue, duration = ANIMATION_DURATION, easingFunction = easeOutQuad, userAction = false, alignmentAtComplete = true, skipOverridedCoordinates = false) {
4970
+ animate(startValue, endValue, duration = ANIMATION_DURATION, easingFunction = easeOutQuad, blending = false, userAction = false, alignmentAtComplete = true, skipOverridedCoordinates = false) {
4868
4971
  const isVertical = this.isVertical();
4869
4972
  let position = startValue;
4870
4973
  this._isAlignmentAnimation = !alignmentAtComplete;
4871
- this._animator.animate({
4974
+ if (this.hasAnimation() && blending) {
4975
+ const updatable = this._animator.updateTo(endValue);
4976
+ if (updatable) {
4977
+ return this._animator.id;
4978
+ }
4979
+ }
4980
+ return this._animator.animate({
4872
4981
  withDelta: this._service.dynamic && !this.isInfinity(),
4873
4982
  startValue,
4874
4983
  endValue,
@@ -4880,7 +4989,7 @@ class NgScrollView extends BaseScrollView {
4880
4989
  if (this._isCoordinatesOverrided && !skipOverridedCoordinates) {
4881
4990
  this._isCoordinatesOverrided = false;
4882
4991
  const currentCoordinate = isVertical ? this._y : this._x, delta = endValue - value;
4883
- this.animate(currentCoordinate, currentCoordinate + delta, duration - elapsed, easingFunction, userAction, alignmentAtComplete);
4992
+ this.animate(currentCoordinate, currentCoordinate + delta, duration - elapsed, easingFunction, blending, userAction, alignmentAtComplete);
4884
4993
  return;
4885
4994
  }
4886
4995
  const v0 = calculateVelocity(position, value - this._delta, timestamp) ?? this.averageVelocity;
@@ -5012,7 +5121,7 @@ class NgScrollView extends BaseScrollView {
5012
5121
  const cPos = (isVertical ? this.scrollTop : this.scrollLeft);
5013
5122
  if (position !== null && position !== cPos) {
5014
5123
  this.stopScrolling(true);
5015
- this.animate(cPos, position, animated ? this.animationParams().snapToItem : 1, easeOutQuad, false, false, true);
5124
+ this.animate(cPos, position, animated ? this.animationParams().snapToItem : 1, easeOutQuad, false, false, false, true);
5016
5125
  return true;
5017
5126
  }
5018
5127
  return false;
@@ -5098,21 +5207,18 @@ class NgScrollView extends BaseScrollView {
5098
5207
  if (behavior === AUTO || behavior === SMOOTH) {
5099
5208
  if (isVertical) {
5100
5209
  if (prevY !== y) {
5101
- this.animate(prevY, y, duration, ease, userAction);
5210
+ return this.animate(prevY, y, duration, ease, blending, userAction);
5102
5211
  }
5103
5212
  }
5104
5213
  else {
5105
5214
  if (prevX !== x) {
5106
- this.animate(prevX, x, duration, ease, userAction);
5215
+ return this.animate(prevX, x, duration, ease, blending, userAction);
5107
5216
  }
5108
5217
  }
5109
5218
  }
5110
5219
  else {
5111
5220
  if (isVertical) {
5112
5221
  if (this._y !== y || force) {
5113
- if (!blending) {
5114
- this.stopScrolling(force);
5115
- }
5116
5222
  this.setY(y, snap, normalize);
5117
5223
  this.emitScrollableEvent();
5118
5224
  if (fireUpdate) {
@@ -5122,9 +5228,6 @@ class NgScrollView extends BaseScrollView {
5122
5228
  }
5123
5229
  else {
5124
5230
  if (this._x !== x || force) {
5125
- if (!blending) {
5126
- this.stopScrolling(force);
5127
- }
5128
5231
  this.setX(x, snap, normalize);
5129
5232
  this.emitScrollableEvent();
5130
5233
  if (fireUpdate) {
@@ -5133,6 +5236,7 @@ class NgScrollView extends BaseScrollView {
5133
5236
  }
5134
5237
  }
5135
5238
  }
5239
+ return -1;
5136
5240
  }
5137
5241
  emitScrollableEvent() {
5138
5242
  if (!!this.cdkScrollable) {
@@ -5151,6 +5255,9 @@ class NgScrollView extends BaseScrollView {
5151
5255
  this.stopScrolling();
5152
5256
  this.move(this.isVertical(), offset);
5153
5257
  }
5258
+ stopAnimation(id) {
5259
+ this._animator.stop(id);
5260
+ }
5154
5261
  ngOnDestroy() {
5155
5262
  if (this._animator) {
5156
5263
  this._animator.dispose();
@@ -5329,13 +5436,13 @@ class NgScrollBarComponent extends NgScrollView {
5329
5436
  })).subscribe();
5330
5437
  }
5331
5438
  createDragEvent(userAction) {
5332
- const isVertical = this.isVertical(), scrollSize = isVertical ? this.scrollHeight : this.scrollWidth, scrollContent = this.scrollContent()?.nativeElement, scrollViewport = this.scrollViewport()?.nativeElement;
5439
+ const isVertical = this.isVertical(), scrollSize = isVertical ? this.scrollHeight : this.scrollWidth, scrollPosition = isVertical ? this.scrollTop : this.scrollLeft, startOffset = this.startOffset(), endOffset = this.endOffset(), scrollContent = this.scrollContent()?.nativeElement, scrollViewport = this.scrollViewport()?.nativeElement;
5333
5440
  if (!!scrollViewport && !!scrollContent) {
5334
- const contentSize = isVertical ? scrollContent.offsetHeight : scrollContent.offsetWidth, viewportSize = isVertical ? scrollViewport.offsetHeight : scrollViewport.offsetWidth;
5441
+ const contentSize = isVertical ? scrollContent.offsetHeight : scrollContent.offsetWidth, viewportSize = isVertical ? scrollViewport.offsetHeight : scrollViewport.offsetWidth, offsetSize = (scrollSize !== 0 ? (startOffset / scrollSize) : 0), positionSize = (scrollSize !== 0 ? (scrollPosition / scrollSize) : 0), maxSize = 1 - offsetSize, pos = (positionSize - offsetSize);
5335
5442
  const event = {
5336
- position: scrollSize !== 0 ? ((isVertical ? this._y : this._x) / scrollSize) : 0,
5337
- min: scrollSize !== 0 ? (this.startOffset() / scrollSize) : 0,
5338
- max: scrollSize !== 0 ? ((viewportSize - this.endOffset() - contentSize) / scrollSize) : 0,
5443
+ position: pos / maxSize,
5444
+ min: scrollSize !== 0 ? (startOffset / scrollSize) : 0,
5445
+ max: scrollSize !== 0 ? ((viewportSize - endOffset - contentSize) / scrollSize) : 0,
5339
5446
  animation: !this._isMoving,
5340
5447
  userAction,
5341
5448
  };
@@ -5573,6 +5680,10 @@ class NgScrollerComponent extends NgScrollView {
5573
5680
  $updateScrollBar.pipe(takeUntilDestroyed(this._destroyRef), debounceTime(0), tap(() => {
5574
5681
  this.updateScrollBarHandler(!this._isScrollbarUserAction);
5575
5682
  })).subscribe();
5683
+ effect(() => {
5684
+ const grabbing = this.grabbing();
5685
+ this._service.grabbing = grabbing;
5686
+ });
5576
5687
  this.actualClasses = computed(() => {
5577
5688
  const classes = this.classes(), direction = this.direction(), filtered = this.motionBlurEnabled();
5578
5689
  return { ...classes, [direction]: true, grabbing: this.grabbing(), filtered };
@@ -5712,7 +5823,7 @@ class NgScrollerComponent extends NgScrollView {
5712
5823
  this._isScrollbarUserAction = false;
5713
5824
  this.scrollBar?.stopScrolling();
5714
5825
  }
5715
- this.scroll({ ...params, userAction: userAction });
5826
+ return this.scroll({ ...params, userAction: userAction });
5716
5827
  }
5717
5828
  stopScrollbar() {
5718
5829
  if (!!this.scrollBar) {
@@ -6081,14 +6192,14 @@ class NgPrerenderVirtualListItemComponent extends NgVirtualListItemComponent {
6081
6192
  }
6082
6193
  }
6083
6194
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: NgPrerenderVirtualListItemComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
6084
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.0", type: NgPrerenderVirtualListItemComponent, isStandalone: false, selector: "ng-prerender-virtual-list-item", host: { attributes: { "role": "listitem" }, classAttribute: "ngvl__item" }, usesInheritance: true, ngImport: i0, template: "@let renderer = itemRenderer();\r\n@let class = classes();\r\n<div #item class=\"ngvl-item\" [ngClass]=\"class\" [part]=\"part()\" [attr.ngvl-index]=\"index()\" [attr.ngvl-visibility]=\"visibility\" tabindex=\"-1\">\r\n @if (_blendColor) {\r\n <div class=\"ngvl-item__blend-color\" [style.--blend-color]=\"_blendColor\"></div>\r\n }\r\n <div #container virtualClick [part]=\"fxPart()\" [maxClickDistance]=\"maxClickDistance()\" class=\"ngvl-item__container\"\r\n [ngClass]=\"class\" (onVirtualClick)=\"onClickHandler()\">\r\n @if (renderer) {\r\n <ng-container [ngTemplateOutlet]=\"renderer\" [ngTemplateOutletContext]=\"templateContext()\" />\r\n }\r\n </div>\r\n</div>", 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.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: VirtualClickDirective, selector: "[virtualClick]", inputs: ["maxClickDistance"], outputs: ["onVirtualClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
6195
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.0", type: NgPrerenderVirtualListItemComponent, isStandalone: false, selector: "ng-prerender-virtual-list-item", host: { attributes: { "role": "listitem" }, classAttribute: "ngvl__item" }, usesInheritance: true, ngImport: i0, template: "@let renderer = itemRenderer();\r\n@let class = classes();\r\n<div #item class=\"ngvl-item\" [ngClass]=\"class\" [part]=\"part()\" [attr.ngvl-index]=\"index()\"\r\n [attr.ngvl-visibility]=\"visibility\" tabindex=\"-1\">\r\n @if (_blendColor) {\r\n <div class=\"ngvl-item__blend-color\" [style.--blend-color]=\"_blendColor\"></div>\r\n }\r\n <div #container virtualClick [part]=\"fxPart()\" [maxClickDistance]=\"maxClickDistance()\" class=\"ngvl-item__container\"\r\n [ngClass]=\"class\" (onVirtualClick)=\"onClickHandler()\" (onVirtualClickPress)=\"onClickPressHandler()\"\r\n (onVirtualClickCancel)=\"onClickCancelHandler()\">\r\n @if (renderer) {\r\n <ng-container [ngTemplateOutlet]=\"renderer\" [ngTemplateOutletContext]=\"templateContext()\" />\r\n }\r\n </div>\r\n</div>", 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.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: VirtualClickDirective, selector: "[virtualClick]", inputs: ["maxClickDistance"], outputs: ["onVirtualClick", "onVirtualClickPress", "onVirtualClickCancel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
6085
6196
  }
6086
6197
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: NgPrerenderVirtualListItemComponent, decorators: [{
6087
6198
  type: Component,
6088
6199
  args: [{ selector: 'ng-prerender-virtual-list-item', host: {
6089
6200
  'class': 'ngvl__item',
6090
6201
  'role': 'listitem',
6091
- }, standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "@let renderer = itemRenderer();\r\n@let class = classes();\r\n<div #item class=\"ngvl-item\" [ngClass]=\"class\" [part]=\"part()\" [attr.ngvl-index]=\"index()\" [attr.ngvl-visibility]=\"visibility\" tabindex=\"-1\">\r\n @if (_blendColor) {\r\n <div class=\"ngvl-item__blend-color\" [style.--blend-color]=\"_blendColor\"></div>\r\n }\r\n <div #container virtualClick [part]=\"fxPart()\" [maxClickDistance]=\"maxClickDistance()\" class=\"ngvl-item__container\"\r\n [ngClass]=\"class\" (onVirtualClick)=\"onClickHandler()\">\r\n @if (renderer) {\r\n <ng-container [ngTemplateOutlet]=\"renderer\" [ngTemplateOutletContext]=\"templateContext()\" />\r\n }\r\n </div>\r\n</div>", 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"] }]
6202
+ }, standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "@let renderer = itemRenderer();\r\n@let class = classes();\r\n<div #item class=\"ngvl-item\" [ngClass]=\"class\" [part]=\"part()\" [attr.ngvl-index]=\"index()\"\r\n [attr.ngvl-visibility]=\"visibility\" tabindex=\"-1\">\r\n @if (_blendColor) {\r\n <div class=\"ngvl-item__blend-color\" [style.--blend-color]=\"_blendColor\"></div>\r\n }\r\n <div #container virtualClick [part]=\"fxPart()\" [maxClickDistance]=\"maxClickDistance()\" class=\"ngvl-item__container\"\r\n [ngClass]=\"class\" (onVirtualClick)=\"onClickHandler()\" (onVirtualClickPress)=\"onClickPressHandler()\"\r\n (onVirtualClickCancel)=\"onClickCancelHandler()\">\r\n @if (renderer) {\r\n <ng-container [ngTemplateOutlet]=\"renderer\" [ngTemplateOutletContext]=\"templateContext()\" />\r\n }\r\n </div>\r\n</div>", 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"] }]
6092
6203
  }] });
6093
6204
 
6094
6205
  /**
@@ -7146,7 +7257,7 @@ class NgVirtualListComponent {
7146
7257
  },
7147
7258
  };
7148
7259
  /**
7149
- * Animation parameters. The default value is "{ scrollToItem: 50, snapToItem: 150, navigateToItem: 150, navigateByKeyboard: 50 }".
7260
+ * Animation parameters. The default value is "{ scrollToItem: 150, snapToItem: 150, navigateToItem: 150, navigateByKeyboard: 50 }".
7150
7261
  */
7151
7262
  animationParams = input(DEFAULT_ANIMATION_PARAMS, { ...(ngDevMode ? { debugName: "animationParams" } : /* istanbul ignore next */ {}), ...this._animationParamsOptions });
7152
7263
  _overscrollEnabledOptions = {
@@ -7640,6 +7751,7 @@ class NgVirtualListComponent {
7640
7751
  _readyForShow = false;
7641
7752
  _cached = false;
7642
7753
  _isLoading = false;
7754
+ _animationId = -1;
7643
7755
  get cachable() {
7644
7756
  return this._prerender()?.active ?? false;
7645
7757
  }
@@ -7654,6 +7766,7 @@ class NgVirtualListComponent {
7654
7766
  NgVirtualListComponent.__nextId = NgVirtualListComponent.__nextId + 1 === Number.MAX_SAFE_INTEGER
7655
7767
  ? 0 : NgVirtualListComponent.__nextId + 1;
7656
7768
  this._id = NgVirtualListComponent.__nextId;
7769
+ let readyForAnimations = false;
7657
7770
  const _$created = new BehaviorSubject(false), $created = _$created.asObservable();
7658
7771
  combineLatest([$created, this.$show]).pipe(takeUntilDestroyed(), filter$1(([created, shown]) => created && shown), debounceTime(1), tap(v => {
7659
7772
  this._$initialized.next(true);
@@ -7895,6 +8008,7 @@ class NgVirtualListComponent {
7895
8008
  }), tap(items => {
7896
8009
  this._trackBox.resetCollection(items, this._actualItemSize());
7897
8010
  }), switchMap$1(i => of((i ?? []).length > 0)), distinctUntilChanged(), tap(v => {
8011
+ readyForAnimations = false;
7898
8012
  if (!v) {
7899
8013
  this.cacheClean();
7900
8014
  this.cleanup();
@@ -8238,12 +8352,22 @@ class NgVirtualListComponent {
8238
8352
  }), debounceTime(100), tap(() => {
8239
8353
  this._isLoading = false;
8240
8354
  })).subscribe();
8355
+ let prevCacheVersion = -1, prevScrollable = false;
8356
+ $viewInit.pipe(takeUntilDestroyed(), filter$1(v => !!v), switchMap$1(() => {
8357
+ return this.$show.pipe(takeUntilDestroyed(this._destroyRef), debounceTime(Math.max(500, this.animationParams().scrollToItem)), tap(() => {
8358
+ if (this._readyForShow || (this.cachable && this._cached)) {
8359
+ readyForAnimations = true;
8360
+ }
8361
+ }));
8362
+ })).subscribe();
8241
8363
  const update = (params) => {
8242
- const { alignment, snapScrollToStart, snapScrollToEnd, bounds, items, itemConfigMap, scrollSize, itemSize, minItemSize, maxItemSize, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, enabledBufferOptimization, snapToItem, snapToItemAlign, userAction, collapsedIds, itemTransform, } = params;
8364
+ const { alignment, snapScrollToStart, snapScrollToEnd, bounds, items, itemConfigMap, scrollSize, itemSize, minItemSize, maxItemSize, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, enabledBufferOptimization, snapToItem, snapToItemAlign, userAction, collapsedIds, cacheVersion, itemTransform, } = params;
8365
+ const cacheChanged = prevCacheVersion !== cacheVersion;
8366
+ prevCacheVersion = cacheVersion;
8243
8367
  const scroller = this._scrollerComponent();
8244
8368
  let totalSize = 0;
8245
8369
  if (!!scroller) {
8246
- 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;
8370
+ 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;
8247
8371
  if (this._readyForShow || (cachable && cached)) {
8248
8372
  const currentScrollSize = (isVertical ? scroller.scrollTop : scroller.scrollLeft);
8249
8373
  let actualScrollSize = !this._readyForShow && snapScrollToEnd ? (isVertical ? scroller.scrollHeight : scroller.scrollWidth) :
@@ -8287,12 +8411,13 @@ class NgVirtualListComponent {
8287
8411
  if (!_$created.getValue()) {
8288
8412
  _$created.next(true);
8289
8413
  }
8290
- const delta = this._trackBox.delta, scrollPositionAfterUpdate = actualScrollSize + delta, roundedScrollPositionAfterUpdate = scrollPositionAfterUpdate, roundedMaxPositionAfterUpdate = isVertical ? scroller.scrollHeight : scroller.scrollWidth;
8414
+ const delta = this._trackBox.delta, scrollPositionAfterUpdate = actualScrollSize + delta, roundedScrollPositionAfterUpdate = scrollPositionAfterUpdate, roundedMaxPositionAfterUpdate = isVertical ? scroller.actualScrollHeight : scroller.actualScrollWidth;
8291
8415
  if (this._isSnappingMethodAdvanced) {
8292
8416
  this.updateRegularRenderer();
8293
8417
  }
8294
8418
  this.updateOffsetsByAllignment();
8295
8419
  scroller.delta = delta;
8420
+ prevScrollable = scroller.scrollable;
8296
8421
  if ((snapScrollToStart && this._trackBox.isSnappedToStart && scroller.scrollable) ||
8297
8422
  (snapScrollToStart && currentScrollSize <= MIN_PIXELS_FOR_PREVENT_SNAPPING)) {
8298
8423
  if (currentScrollSize !== roundedScrollPositionAfterUpdate) {
@@ -8303,10 +8428,16 @@ class NgVirtualListComponent {
8303
8428
  this._trackBox.isScrollEnd;
8304
8429
  const params = {
8305
8430
  [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: 0, userAction,
8306
- fireUpdate: fireUpdateAtEdges, behavior: BEHAVIOR_INSTANT,
8307
- blending: false, duration: this.animationParams().scrollToItem,
8431
+ fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams().scrollToItem > 0 && this.scrollBehavior() !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT),
8432
+ blending: useAnimations && scroller.hasAnimation(this._animationId), duration: this.animationParams().scrollToItem,
8308
8433
  };
8309
- scroller?.scrollTo?.(params);
8434
+ const animationId = scroller?.scrollTo?.(params);
8435
+ if (animationId > -1) {
8436
+ this._animationId = animationId;
8437
+ }
8438
+ else {
8439
+ scroller.stopAnimation(this._animationId);
8440
+ }
8310
8441
  if (emitUpdate) {
8311
8442
  this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
8312
8443
  }
@@ -8326,10 +8457,16 @@ class NgVirtualListComponent {
8326
8457
  }
8327
8458
  const params = {
8328
8459
  [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: roundedMaxPositionAfterUpdate,
8329
- fireUpdate: fireUpdateAtEdges, behavior: BEHAVIOR_INSTANT, userAction: false,
8330
- blending: false, duration: this.animationParams().scrollToItem,
8460
+ fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams().scrollToItem > 0 && this.scrollBehavior() !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT), userAction: false,
8461
+ blending: useAnimations && scroller.hasAnimation(this._animationId) || cacheChanged, duration: this.animationParams().scrollToItem,
8331
8462
  };
8332
- scroller?.scrollTo?.(params);
8463
+ const animationId = scroller?.scrollTo?.(params);
8464
+ if (animationId > -1) {
8465
+ this._animationId = animationId;
8466
+ }
8467
+ else {
8468
+ scroller.stopAnimation(this._animationId);
8469
+ }
8333
8470
  if (emitUpdate) {
8334
8471
  this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
8335
8472
  }
@@ -8342,9 +8479,13 @@ class NgVirtualListComponent {
8342
8479
  if (this._readyForShow) {
8343
8480
  this.emitScrollEvent(true, false, userAction);
8344
8481
  }
8482
+ if (this._animationId > -1) {
8483
+ scroller.stopAnimation(this._animationId);
8484
+ this._animationId = -1;
8485
+ }
8345
8486
  const params = {
8346
8487
  [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollPositionAfterUpdate, blending: true, userAction,
8347
- fireUpdate, behavior: BEHAVIOR_INSTANT, duration: this.animationParams().scrollToItem,
8488
+ fireUpdate, behavior: BEHAVIOR_INSTANT, duration: 0,
8348
8489
  };
8349
8490
  scroller.scrollTo(params);
8350
8491
  if (emitUpdate) {
@@ -9031,7 +9172,7 @@ class NgVirtualListComponent {
9031
9172
  this._isScrollStart.set(false);
9032
9173
  this._isScrollEnd.set(false);
9033
9174
  this._trackBox.preventScrollSnapping(true);
9034
- if (scroller) {
9175
+ if (!!scroller) {
9035
9176
  scroller.stopScrolling();
9036
9177
  }
9037
9178
  }
@@ -9057,7 +9198,7 @@ class NgVirtualListComponent {
9057
9198
  comp?.destroy();
9058
9199
  }
9059
9200
  }
9060
- if (this._displayComponents) {
9201
+ if (!!this._displayComponents) {
9061
9202
  while (this._displayComponents.length > 0) {
9062
9203
  const comp = this._displayComponents.shift();
9063
9204
  comp?.destroy();