ng-virtual-list 22.12.2 → 22.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.
- package/README.md +10 -10
- package/fesm2022/ng-virtual-list.mjs +214 -71
- package/fesm2022/ng-virtual-list.mjs.map +1 -1
- package/package.json +2 -2
- package/types/ng-virtual-list.d.ts +46 -9
|
@@ -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,
|
|
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
|
|
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:
|
|
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
|
|
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
|
-
|
|
1454
|
+
_$maxDistance = new BehaviorSubject(null);
|
|
1455
|
+
$maxDistance = this._$maxDistance.asObservable();
|
|
1456
|
+
_maxDistance = null;
|
|
1420
1457
|
set maxDistance(v) {
|
|
1421
|
-
|
|
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 >
|
|
1486
|
+
if (dist > maxDistance) {
|
|
1487
|
+
this.onVirtualClickCancel.emit();
|
|
1438
1488
|
return of(true);
|
|
1439
1489
|
}
|
|
1440
1490
|
return of(false);
|
|
1441
|
-
}),
|
|
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()\"
|
|
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()\"
|
|
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,34 @@ 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
|
+
_prevPos = 0;
|
|
4074
|
+
updateTo(end) {
|
|
4075
|
+
this._endValue = end;
|
|
4076
|
+
this._diff = this._endValue - this._startValue;
|
|
4077
|
+
return this.hasAnimation();
|
|
4078
|
+
}
|
|
3989
4079
|
animate(params) {
|
|
3990
4080
|
this.stop();
|
|
3991
4081
|
const id = this.generateId();
|
|
3992
4082
|
this._currentId = id;
|
|
3993
4083
|
const { withDelta = DEFAULT_WITH_DELTA, startValue, endValue, duration = DEFAULT_ANIMATION_DURATION, getPropValue, easingFunction = easeLinear, onUpdate, onComplete, } = params;
|
|
4084
|
+
this._startValue = startValue;
|
|
4085
|
+
this._endValue = endValue;
|
|
3994
4086
|
const startTime = performance.now();
|
|
3995
|
-
let isCanceled = false,
|
|
4087
|
+
let isCanceled = false, startPosDelta = 0, delta = 0, prevTime = startTime, isFinished = false;
|
|
4088
|
+
this._prevPos = startValue;
|
|
4089
|
+
this._diff = this._endValue - this._startValue;
|
|
3996
4090
|
const step = (currentTime) => {
|
|
3997
4091
|
if (id !== this._currentId) {
|
|
3998
4092
|
isCanceled = true;
|
|
@@ -4002,34 +4096,35 @@ class Animator {
|
|
|
4002
4096
|
}
|
|
4003
4097
|
const cPos = getPropValue?.() || 0;
|
|
4004
4098
|
let startDelta = 0;
|
|
4005
|
-
if (cPos !==
|
|
4006
|
-
startDelta = cPos -
|
|
4099
|
+
if (cPos !== this._prevPos) {
|
|
4100
|
+
startDelta = cPos - this._prevPos;
|
|
4007
4101
|
startPosDelta += startDelta;
|
|
4008
4102
|
}
|
|
4009
|
-
const elapsed = currentTime - startTime, progress =
|
|
4103
|
+
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();
|
|
4010
4104
|
isFinished = progress === 1;
|
|
4011
|
-
delta = currentValue - startDelta -
|
|
4012
|
-
const
|
|
4105
|
+
delta = currentValue - startDelta - this._prevPos;
|
|
4106
|
+
const frameTimestamp = t - prevTime, actualFrameTimestamp = frameTimestamp < ANIMATOR_MIN_TIMESTAMP ? ANIMATOR_MIN_TIMESTAMP : frameTimestamp;
|
|
4013
4107
|
prevTime = t;
|
|
4014
|
-
|
|
4108
|
+
this._prevPos = currentValue;
|
|
4015
4109
|
if (onUpdate !== undefined) {
|
|
4016
4110
|
const data = {
|
|
4017
4111
|
id,
|
|
4018
4112
|
delta,
|
|
4019
4113
|
elapsed,
|
|
4020
|
-
value:
|
|
4021
|
-
timestamp,
|
|
4114
|
+
value: currentValue,
|
|
4115
|
+
timestamp: actualFrameTimestamp,
|
|
4022
4116
|
};
|
|
4023
4117
|
onUpdate(data);
|
|
4024
4118
|
}
|
|
4025
4119
|
if (isFinished) {
|
|
4120
|
+
this._animationId = -1;
|
|
4026
4121
|
if (onComplete !== undefined) {
|
|
4027
4122
|
const data = {
|
|
4028
4123
|
id,
|
|
4029
4124
|
delta,
|
|
4030
4125
|
elapsed,
|
|
4031
|
-
value:
|
|
4032
|
-
timestamp,
|
|
4126
|
+
value: currentValue,
|
|
4127
|
+
timestamp: actualFrameTimestamp,
|
|
4033
4128
|
};
|
|
4034
4129
|
onComplete(data);
|
|
4035
4130
|
}
|
|
@@ -4039,9 +4134,17 @@ class Animator {
|
|
|
4039
4134
|
}
|
|
4040
4135
|
};
|
|
4041
4136
|
this._animationId = requestAnimationFrame(step);
|
|
4137
|
+
return this._currentId;
|
|
4138
|
+
}
|
|
4139
|
+
hasAnimation(id = -1) {
|
|
4140
|
+
if ((this._currentId === id || id === -1) && this.animated) {
|
|
4141
|
+
return true;
|
|
4142
|
+
}
|
|
4143
|
+
return false;
|
|
4042
4144
|
}
|
|
4043
|
-
stop() {
|
|
4044
|
-
cancelAnimationFrame(this._animationId);
|
|
4145
|
+
stop(id = -1) {
|
|
4146
|
+
cancelAnimationFrame(id === -1 ? this._animationId : id);
|
|
4147
|
+
this._animationId = -1;
|
|
4045
4148
|
}
|
|
4046
4149
|
dispose() {
|
|
4047
4150
|
this.stop();
|
|
@@ -4498,6 +4601,7 @@ class NgScrollView extends BaseScrollView {
|
|
|
4498
4601
|
get startLayoutOffset() { return this._startLayoutOffset; }
|
|
4499
4602
|
_intersectionComponentId = null;
|
|
4500
4603
|
_isAlignmentAnimation = false;
|
|
4604
|
+
get animated() { return this._animator?.isAnimated ?? false; }
|
|
4501
4605
|
constructor() {
|
|
4502
4606
|
super();
|
|
4503
4607
|
let mouseCanceled = false, touchCanceled = false;
|
|
@@ -4689,6 +4793,7 @@ class NgScrollView extends BaseScrollView {
|
|
|
4689
4793
|
}));
|
|
4690
4794
|
})).subscribe();
|
|
4691
4795
|
}
|
|
4796
|
+
hasAnimation(id = -1) { return this._animator?.hasAnimation(id) ?? false; }
|
|
4692
4797
|
updateDirection(position, prePosition) {
|
|
4693
4798
|
const delta = (position - this._delta) - prePosition;
|
|
4694
4799
|
this._scrollDirection.add(delta > 0 ? 1 : delta < 0 ? -1 : 0);
|
|
@@ -4851,7 +4956,7 @@ class NgScrollView extends BaseScrollView {
|
|
|
4851
4956
|
moveWithAcceleration(isVertical, position, v0, v, a0, timestamp) {
|
|
4852
4957
|
if (a0 !== 0 && timestamp < MAX_VELOCITY_TIMESTAMP) {
|
|
4853
4958
|
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;
|
|
4854
|
-
this.animate(startPosition, Math.round(positionWithVelocity), aDuration, easeOutQuad, true);
|
|
4959
|
+
this.animate(startPosition, Math.round(positionWithVelocity), aDuration, easeOutQuad, false, true);
|
|
4855
4960
|
}
|
|
4856
4961
|
else {
|
|
4857
4962
|
this.alignPosition(true, true);
|
|
@@ -4864,11 +4969,17 @@ class NgScrollView extends BaseScrollView {
|
|
|
4864
4969
|
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
4970
|
return result;
|
|
4866
4971
|
}
|
|
4867
|
-
animate(startValue, endValue, duration = ANIMATION_DURATION, easingFunction = easeOutQuad, userAction = false, alignmentAtComplete = true, skipOverridedCoordinates = false) {
|
|
4972
|
+
animate(startValue, endValue, duration = ANIMATION_DURATION, easingFunction = easeOutQuad, blending = false, userAction = false, alignmentAtComplete = true, skipOverridedCoordinates = false) {
|
|
4868
4973
|
const isVertical = this.isVertical();
|
|
4869
4974
|
let position = startValue;
|
|
4870
4975
|
this._isAlignmentAnimation = !alignmentAtComplete;
|
|
4871
|
-
this.
|
|
4976
|
+
if (this.hasAnimation() && blending) {
|
|
4977
|
+
const updatable = this._animator.updateTo(endValue);
|
|
4978
|
+
if (updatable) {
|
|
4979
|
+
return this._animator.id;
|
|
4980
|
+
}
|
|
4981
|
+
}
|
|
4982
|
+
return this._animator.animate({
|
|
4872
4983
|
withDelta: this._service.dynamic && !this.isInfinity(),
|
|
4873
4984
|
startValue,
|
|
4874
4985
|
endValue,
|
|
@@ -4880,7 +4991,7 @@ class NgScrollView extends BaseScrollView {
|
|
|
4880
4991
|
if (this._isCoordinatesOverrided && !skipOverridedCoordinates) {
|
|
4881
4992
|
this._isCoordinatesOverrided = false;
|
|
4882
4993
|
const currentCoordinate = isVertical ? this._y : this._x, delta = endValue - value;
|
|
4883
|
-
this.animate(currentCoordinate, currentCoordinate + delta, duration - elapsed, easingFunction, userAction, alignmentAtComplete);
|
|
4994
|
+
this.animate(currentCoordinate, currentCoordinate + delta, duration - elapsed, easingFunction, blending, userAction, alignmentAtComplete);
|
|
4884
4995
|
return;
|
|
4885
4996
|
}
|
|
4886
4997
|
const v0 = calculateVelocity(position, value - this._delta, timestamp) ?? this.averageVelocity;
|
|
@@ -5012,7 +5123,7 @@ class NgScrollView extends BaseScrollView {
|
|
|
5012
5123
|
const cPos = (isVertical ? this.scrollTop : this.scrollLeft);
|
|
5013
5124
|
if (position !== null && position !== cPos) {
|
|
5014
5125
|
this.stopScrolling(true);
|
|
5015
|
-
this.animate(cPos, position, animated ? this.animationParams().snapToItem : 1, easeOutQuad, false, false, true);
|
|
5126
|
+
this.animate(cPos, position, animated ? this.animationParams().snapToItem : 1, easeOutQuad, false, false, false, true);
|
|
5016
5127
|
return true;
|
|
5017
5128
|
}
|
|
5018
5129
|
return false;
|
|
@@ -5098,21 +5209,18 @@ class NgScrollView extends BaseScrollView {
|
|
|
5098
5209
|
if (behavior === AUTO || behavior === SMOOTH) {
|
|
5099
5210
|
if (isVertical) {
|
|
5100
5211
|
if (prevY !== y) {
|
|
5101
|
-
this.animate(prevY, y, duration, ease, userAction);
|
|
5212
|
+
return this.animate(prevY, y, duration, ease, blending, userAction);
|
|
5102
5213
|
}
|
|
5103
5214
|
}
|
|
5104
5215
|
else {
|
|
5105
5216
|
if (prevX !== x) {
|
|
5106
|
-
this.animate(prevX, x, duration, ease, userAction);
|
|
5217
|
+
return this.animate(prevX, x, duration, ease, blending, userAction);
|
|
5107
5218
|
}
|
|
5108
5219
|
}
|
|
5109
5220
|
}
|
|
5110
5221
|
else {
|
|
5111
5222
|
if (isVertical) {
|
|
5112
5223
|
if (this._y !== y || force) {
|
|
5113
|
-
if (!blending) {
|
|
5114
|
-
this.stopScrolling(force);
|
|
5115
|
-
}
|
|
5116
5224
|
this.setY(y, snap, normalize);
|
|
5117
5225
|
this.emitScrollableEvent();
|
|
5118
5226
|
if (fireUpdate) {
|
|
@@ -5122,9 +5230,6 @@ class NgScrollView extends BaseScrollView {
|
|
|
5122
5230
|
}
|
|
5123
5231
|
else {
|
|
5124
5232
|
if (this._x !== x || force) {
|
|
5125
|
-
if (!blending) {
|
|
5126
|
-
this.stopScrolling(force);
|
|
5127
|
-
}
|
|
5128
5233
|
this.setX(x, snap, normalize);
|
|
5129
5234
|
this.emitScrollableEvent();
|
|
5130
5235
|
if (fireUpdate) {
|
|
@@ -5133,6 +5238,7 @@ class NgScrollView extends BaseScrollView {
|
|
|
5133
5238
|
}
|
|
5134
5239
|
}
|
|
5135
5240
|
}
|
|
5241
|
+
return -1;
|
|
5136
5242
|
}
|
|
5137
5243
|
emitScrollableEvent() {
|
|
5138
5244
|
if (!!this.cdkScrollable) {
|
|
@@ -5151,6 +5257,9 @@ class NgScrollView extends BaseScrollView {
|
|
|
5151
5257
|
this.stopScrolling();
|
|
5152
5258
|
this.move(this.isVertical(), offset);
|
|
5153
5259
|
}
|
|
5260
|
+
stopAnimation(id) {
|
|
5261
|
+
this._animator.stop(id);
|
|
5262
|
+
}
|
|
5154
5263
|
ngOnDestroy() {
|
|
5155
5264
|
if (this._animator) {
|
|
5156
5265
|
this._animator.dispose();
|
|
@@ -5573,6 +5682,10 @@ class NgScrollerComponent extends NgScrollView {
|
|
|
5573
5682
|
$updateScrollBar.pipe(takeUntilDestroyed(this._destroyRef), debounceTime(0), tap(() => {
|
|
5574
5683
|
this.updateScrollBarHandler(!this._isScrollbarUserAction);
|
|
5575
5684
|
})).subscribe();
|
|
5685
|
+
effect(() => {
|
|
5686
|
+
const grabbing = this.grabbing();
|
|
5687
|
+
this._service.grabbing = grabbing;
|
|
5688
|
+
});
|
|
5576
5689
|
this.actualClasses = computed(() => {
|
|
5577
5690
|
const classes = this.classes(), direction = this.direction(), filtered = this.motionBlurEnabled();
|
|
5578
5691
|
return { ...classes, [direction]: true, grabbing: this.grabbing(), filtered };
|
|
@@ -5712,7 +5825,7 @@ class NgScrollerComponent extends NgScrollView {
|
|
|
5712
5825
|
this._isScrollbarUserAction = false;
|
|
5713
5826
|
this.scrollBar?.stopScrolling();
|
|
5714
5827
|
}
|
|
5715
|
-
this.scroll({ ...params, userAction: userAction });
|
|
5828
|
+
return this.scroll({ ...params, userAction: userAction });
|
|
5716
5829
|
}
|
|
5717
5830
|
stopScrollbar() {
|
|
5718
5831
|
if (!!this.scrollBar) {
|
|
@@ -6081,14 +6194,14 @@ class NgPrerenderVirtualListItemComponent extends NgVirtualListItemComponent {
|
|
|
6081
6194
|
}
|
|
6082
6195
|
}
|
|
6083
6196
|
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()\"
|
|
6197
|
+
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
6198
|
}
|
|
6086
6199
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: NgPrerenderVirtualListItemComponent, decorators: [{
|
|
6087
6200
|
type: Component,
|
|
6088
6201
|
args: [{ selector: 'ng-prerender-virtual-list-item', host: {
|
|
6089
6202
|
'class': 'ngvl__item',
|
|
6090
6203
|
'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()\"
|
|
6204
|
+
}, 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
6205
|
}] });
|
|
6093
6206
|
|
|
6094
6207
|
/**
|
|
@@ -7146,7 +7259,7 @@ class NgVirtualListComponent {
|
|
|
7146
7259
|
},
|
|
7147
7260
|
};
|
|
7148
7261
|
/**
|
|
7149
|
-
* Animation parameters. The default value is "{ scrollToItem:
|
|
7262
|
+
* Animation parameters. The default value is "{ scrollToItem: 150, snapToItem: 150, navigateToItem: 150, navigateByKeyboard: 50 }".
|
|
7150
7263
|
*/
|
|
7151
7264
|
animationParams = input(DEFAULT_ANIMATION_PARAMS, { ...(ngDevMode ? { debugName: "animationParams" } : /* istanbul ignore next */ {}), ...this._animationParamsOptions });
|
|
7152
7265
|
_overscrollEnabledOptions = {
|
|
@@ -7640,6 +7753,7 @@ class NgVirtualListComponent {
|
|
|
7640
7753
|
_readyForShow = false;
|
|
7641
7754
|
_cached = false;
|
|
7642
7755
|
_isLoading = false;
|
|
7756
|
+
_animationId = -1;
|
|
7643
7757
|
get cachable() {
|
|
7644
7758
|
return this._prerender()?.active ?? false;
|
|
7645
7759
|
}
|
|
@@ -7654,6 +7768,7 @@ class NgVirtualListComponent {
|
|
|
7654
7768
|
NgVirtualListComponent.__nextId = NgVirtualListComponent.__nextId + 1 === Number.MAX_SAFE_INTEGER
|
|
7655
7769
|
? 0 : NgVirtualListComponent.__nextId + 1;
|
|
7656
7770
|
this._id = NgVirtualListComponent.__nextId;
|
|
7771
|
+
let readyForAnimations = false;
|
|
7657
7772
|
const _$created = new BehaviorSubject(false), $created = _$created.asObservable();
|
|
7658
7773
|
combineLatest([$created, this.$show]).pipe(takeUntilDestroyed(), filter$1(([created, shown]) => created && shown), debounceTime(1), tap(v => {
|
|
7659
7774
|
this._$initialized.next(true);
|
|
@@ -7895,6 +8010,7 @@ class NgVirtualListComponent {
|
|
|
7895
8010
|
}), tap(items => {
|
|
7896
8011
|
this._trackBox.resetCollection(items, this._actualItemSize());
|
|
7897
8012
|
}), switchMap$1(i => of((i ?? []).length > 0)), distinctUntilChanged(), tap(v => {
|
|
8013
|
+
readyForAnimations = false;
|
|
7898
8014
|
if (!v) {
|
|
7899
8015
|
this.cacheClean();
|
|
7900
8016
|
this.cleanup();
|
|
@@ -8238,12 +8354,22 @@ class NgVirtualListComponent {
|
|
|
8238
8354
|
}), debounceTime(100), tap(() => {
|
|
8239
8355
|
this._isLoading = false;
|
|
8240
8356
|
})).subscribe();
|
|
8357
|
+
let prevCacheVersion = -1, prevScrollable = false;
|
|
8358
|
+
$viewInit.pipe(takeUntilDestroyed(), filter$1(v => !!v), switchMap$1(() => {
|
|
8359
|
+
return this.$show.pipe(takeUntilDestroyed(this._destroyRef), debounceTime(Math.max(500, this.animationParams().scrollToItem)), tap(() => {
|
|
8360
|
+
if (this._readyForShow || (this.cachable && this._cached)) {
|
|
8361
|
+
readyForAnimations = true;
|
|
8362
|
+
}
|
|
8363
|
+
}));
|
|
8364
|
+
})).subscribe();
|
|
8241
8365
|
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;
|
|
8366
|
+
const { alignment, snapScrollToStart, snapScrollToEnd, bounds, items, itemConfigMap, scrollSize, itemSize, minItemSize, maxItemSize, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, enabledBufferOptimization, snapToItem, snapToItemAlign, userAction, collapsedIds, cacheVersion, itemTransform, } = params;
|
|
8367
|
+
const cacheChanged = prevCacheVersion !== cacheVersion;
|
|
8368
|
+
prevCacheVersion = cacheVersion;
|
|
8243
8369
|
const scroller = this._scrollerComponent();
|
|
8244
8370
|
let totalSize = 0;
|
|
8245
8371
|
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;
|
|
8372
|
+
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
8373
|
if (this._readyForShow || (cachable && cached)) {
|
|
8248
8374
|
const currentScrollSize = (isVertical ? scroller.scrollTop : scroller.scrollLeft);
|
|
8249
8375
|
let actualScrollSize = !this._readyForShow && snapScrollToEnd ? (isVertical ? scroller.scrollHeight : scroller.scrollWidth) :
|
|
@@ -8287,12 +8413,13 @@ class NgVirtualListComponent {
|
|
|
8287
8413
|
if (!_$created.getValue()) {
|
|
8288
8414
|
_$created.next(true);
|
|
8289
8415
|
}
|
|
8290
|
-
const delta = this._trackBox.delta, scrollPositionAfterUpdate = actualScrollSize + delta, roundedScrollPositionAfterUpdate = scrollPositionAfterUpdate, roundedMaxPositionAfterUpdate = isVertical ? scroller.
|
|
8416
|
+
const delta = this._trackBox.delta, scrollPositionAfterUpdate = actualScrollSize + delta, roundedScrollPositionAfterUpdate = scrollPositionAfterUpdate, roundedMaxPositionAfterUpdate = isVertical ? scroller.actualScrollHeight : scroller.actualScrollWidth;
|
|
8291
8417
|
if (this._isSnappingMethodAdvanced) {
|
|
8292
8418
|
this.updateRegularRenderer();
|
|
8293
8419
|
}
|
|
8294
8420
|
this.updateOffsetsByAllignment();
|
|
8295
8421
|
scroller.delta = delta;
|
|
8422
|
+
prevScrollable = scroller.scrollable;
|
|
8296
8423
|
if ((snapScrollToStart && this._trackBox.isSnappedToStart && scroller.scrollable) ||
|
|
8297
8424
|
(snapScrollToStart && currentScrollSize <= MIN_PIXELS_FOR_PREVENT_SNAPPING)) {
|
|
8298
8425
|
if (currentScrollSize !== roundedScrollPositionAfterUpdate) {
|
|
@@ -8303,10 +8430,16 @@ class NgVirtualListComponent {
|
|
|
8303
8430
|
this._trackBox.isScrollEnd;
|
|
8304
8431
|
const params = {
|
|
8305
8432
|
[isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: 0, userAction,
|
|
8306
|
-
fireUpdate: fireUpdateAtEdges, behavior: BEHAVIOR_INSTANT,
|
|
8307
|
-
blending:
|
|
8433
|
+
fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams().scrollToItem > 0 && this.scrollBehavior() !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT),
|
|
8434
|
+
blending: useAnimations && scroller.hasAnimation(this._animationId), duration: this.animationParams().scrollToItem,
|
|
8308
8435
|
};
|
|
8309
|
-
scroller?.scrollTo?.(params);
|
|
8436
|
+
const animationId = scroller?.scrollTo?.(params);
|
|
8437
|
+
if (animationId > -1) {
|
|
8438
|
+
this._animationId = animationId;
|
|
8439
|
+
}
|
|
8440
|
+
else {
|
|
8441
|
+
scroller.stopAnimation(this._animationId);
|
|
8442
|
+
}
|
|
8310
8443
|
if (emitUpdate) {
|
|
8311
8444
|
this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
|
|
8312
8445
|
}
|
|
@@ -8326,10 +8459,16 @@ class NgVirtualListComponent {
|
|
|
8326
8459
|
}
|
|
8327
8460
|
const params = {
|
|
8328
8461
|
[isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: roundedMaxPositionAfterUpdate,
|
|
8329
|
-
fireUpdate: fireUpdateAtEdges, behavior: BEHAVIOR_INSTANT, userAction: false,
|
|
8330
|
-
blending:
|
|
8462
|
+
fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams().scrollToItem > 0 && this.scrollBehavior() !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT), userAction: false,
|
|
8463
|
+
blending: useAnimations && scroller.hasAnimation(this._animationId) || cacheChanged, duration: this.animationParams().scrollToItem,
|
|
8331
8464
|
};
|
|
8332
|
-
scroller?.scrollTo?.(params);
|
|
8465
|
+
const animationId = scroller?.scrollTo?.(params);
|
|
8466
|
+
if (animationId > -1) {
|
|
8467
|
+
this._animationId = animationId;
|
|
8468
|
+
}
|
|
8469
|
+
else {
|
|
8470
|
+
scroller.stopAnimation(this._animationId);
|
|
8471
|
+
}
|
|
8333
8472
|
if (emitUpdate) {
|
|
8334
8473
|
this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
|
|
8335
8474
|
}
|
|
@@ -8342,9 +8481,13 @@ class NgVirtualListComponent {
|
|
|
8342
8481
|
if (this._readyForShow) {
|
|
8343
8482
|
this.emitScrollEvent(true, false, userAction);
|
|
8344
8483
|
}
|
|
8484
|
+
if (this._animationId > -1) {
|
|
8485
|
+
scroller.stopAnimation(this._animationId);
|
|
8486
|
+
this._animationId = -1;
|
|
8487
|
+
}
|
|
8345
8488
|
const params = {
|
|
8346
8489
|
[isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollPositionAfterUpdate, blending: true, userAction,
|
|
8347
|
-
fireUpdate, behavior: BEHAVIOR_INSTANT, duration:
|
|
8490
|
+
fireUpdate, behavior: BEHAVIOR_INSTANT, duration: 0,
|
|
8348
8491
|
};
|
|
8349
8492
|
scroller.scrollTo(params);
|
|
8350
8493
|
if (emitUpdate) {
|
|
@@ -9031,7 +9174,7 @@ class NgVirtualListComponent {
|
|
|
9031
9174
|
this._isScrollStart.set(false);
|
|
9032
9175
|
this._isScrollEnd.set(false);
|
|
9033
9176
|
this._trackBox.preventScrollSnapping(true);
|
|
9034
|
-
if (scroller) {
|
|
9177
|
+
if (!!scroller) {
|
|
9035
9178
|
scroller.stopScrolling();
|
|
9036
9179
|
}
|
|
9037
9180
|
}
|
|
@@ -9057,7 +9200,7 @@ class NgVirtualListComponent {
|
|
|
9057
9200
|
comp?.destroy();
|
|
9058
9201
|
}
|
|
9059
9202
|
}
|
|
9060
|
-
if (this._displayComponents) {
|
|
9203
|
+
if (!!this._displayComponents) {
|
|
9061
9204
|
while (this._displayComponents.length > 0) {
|
|
9062
9205
|
const comp = this._displayComponents.shift();
|
|
9063
9206
|
comp?.destroy();
|