ng-virtual-list 20.12.2 → 20.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 +2 -2
- package/fesm2022/ng-virtual-list.mjs +214 -71
- package/fesm2022/ng-virtual-list.mjs.map +1 -1
- package/index.d.ts +46 -9
- package/package.json +1 -1
|
@@ -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: {
|
|
@@ -1154,7 +1186,7 @@ class BaseVirtualListItemComponent {
|
|
|
1154
1186
|
}
|
|
1155
1187
|
this._data = v;
|
|
1156
1188
|
this.updatePartStr(v, this._isSelected, this._isCollapsed);
|
|
1157
|
-
this.updateConfig(v);
|
|
1189
|
+
this.updateConfig(v, this._service.isGrabbing);
|
|
1158
1190
|
this.updateMeasures(v);
|
|
1159
1191
|
this.update();
|
|
1160
1192
|
this.data.set(v);
|
|
@@ -1203,6 +1235,9 @@ class BaseVirtualListItemComponent {
|
|
|
1203
1235
|
this._id = this._service.generateComponentId();
|
|
1204
1236
|
this._listId = this._service.id;
|
|
1205
1237
|
this._displayId = createDisplayId(this._listId, this._id);
|
|
1238
|
+
this._service.$isGrabbing.pipe(takeUntilDestroyed(), tap(v => {
|
|
1239
|
+
this.updateConfig(this._data, v);
|
|
1240
|
+
})).subscribe();
|
|
1206
1241
|
effect(() => {
|
|
1207
1242
|
const part = this.part();
|
|
1208
1243
|
this._elementRef.nativeElement.setAttribute('part', part);
|
|
@@ -1240,9 +1275,9 @@ class BaseVirtualListItemComponent {
|
|
|
1240
1275
|
updateMeasures(v) {
|
|
1241
1276
|
this.measures.set(v?.measures ? { ...v.measures } : null);
|
|
1242
1277
|
}
|
|
1243
|
-
updateConfig(v) {
|
|
1278
|
+
updateConfig(v, grabbing) {
|
|
1244
1279
|
this.config.set({
|
|
1245
|
-
...v?.config || {}, selected: this._isSelected, collapsed: this._isCollapsed, focused: this.focused(),
|
|
1280
|
+
...v?.config || {}, selected: this._isSelected, collapsed: this._isCollapsed, focused: this.focused(), grabbing,
|
|
1246
1281
|
});
|
|
1247
1282
|
}
|
|
1248
1283
|
update() {
|
|
@@ -1368,6 +1403,7 @@ class BaseVirtualListItemComponent {
|
|
|
1368
1403
|
}
|
|
1369
1404
|
const el = this._elementRef.nativeElement, styles = el.style;
|
|
1370
1405
|
styles.zIndex = HIDDEN_ZINDEX;
|
|
1406
|
+
styles.transform = INVISIBLE_TRANSLATE_3D;
|
|
1371
1407
|
if (this.regular) {
|
|
1372
1408
|
if (styles.display === DISPLAY_NONE) {
|
|
1373
1409
|
return;
|
|
@@ -1394,7 +1430,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
1394
1430
|
}]
|
|
1395
1431
|
}], ctorParameters: () => [], propDecorators: { _item: [{ type: i0.ViewChild, args: ['item', { isSignal: true }] }], _container: [{ type: i0.ViewChild, args: ['container', { isSignal: true }] }] } });
|
|
1396
1432
|
|
|
1397
|
-
const DEFAULT_MAX_DISTANCE = 40;
|
|
1398
1433
|
/**
|
|
1399
1434
|
* VirtualClickDirective
|
|
1400
1435
|
* Maximum performance for extremely large lists.
|
|
@@ -1404,29 +1439,44 @@ const DEFAULT_MAX_DISTANCE = 40;
|
|
|
1404
1439
|
* @email djonnyx@gmail.com
|
|
1405
1440
|
*/
|
|
1406
1441
|
class VirtualClickDirective {
|
|
1407
|
-
|
|
1442
|
+
_$maxDistance = new BehaviorSubject(null);
|
|
1443
|
+
$maxDistance = this._$maxDistance.asObservable();
|
|
1444
|
+
_maxDistance = null;
|
|
1408
1445
|
set maxDistance(v) {
|
|
1409
|
-
|
|
1446
|
+
const value = (v !== null || v !== undefined) ? Number(v) : null;
|
|
1447
|
+
this._maxDistance = value;
|
|
1448
|
+
this._$maxDistance.next(value);
|
|
1410
1449
|
}
|
|
1411
1450
|
onVirtualClick = output();
|
|
1451
|
+
onVirtualClickPress = output();
|
|
1452
|
+
onVirtualClickCancel = output();
|
|
1453
|
+
_service = inject(NgVirtualListService);
|
|
1412
1454
|
_elementRef = inject(ElementRef);
|
|
1413
1455
|
_destroyRef = inject(DestroyRef);
|
|
1414
1456
|
constructor() {
|
|
1457
|
+
let maxDistance = this._maxDistance ?? DEFAULT_CLICK_DISTANCE;
|
|
1458
|
+
combineLatest([this._service.$clickDistance, this.$maxDistance]).pipe(takeUntilDestroyed(), tap$1(([clickDistance, distance]) => {
|
|
1459
|
+
maxDistance = distance === null ? clickDistance : distance;
|
|
1460
|
+
})).subscribe();
|
|
1415
1461
|
const $pointerPressed = fromEvent(this._elementRef.nativeElement, 'pointerdown'), $pointerCancel = race([
|
|
1416
1462
|
fromEvent(window, 'pointerup').pipe(takeUntilDestroyed()),
|
|
1417
1463
|
fromEvent(window, 'pointerleave').pipe(takeUntilDestroyed()),
|
|
1418
1464
|
]), $pointerRelease = fromEvent(this._elementRef.nativeElement, 'pointerup', { passive: false });
|
|
1419
1465
|
$pointerPressed.pipe(takeUntilDestroyed(), switchMap(e => {
|
|
1420
1466
|
const x = Math.abs(e.clientX), y = Math.abs(e.clientY);
|
|
1467
|
+
this.onVirtualClickPress.emit(e);
|
|
1421
1468
|
return $pointerRelease.pipe(takeUntilDestroyed(this._destroyRef), takeUntil(race([
|
|
1422
|
-
$pointerCancel,
|
|
1469
|
+
$pointerCancel.pipe(takeUntilDestroyed(this._destroyRef), tap$1(() => {
|
|
1470
|
+
this.onVirtualClickCancel.emit();
|
|
1471
|
+
})),
|
|
1423
1472
|
fromEvent(window, 'pointermove').pipe(takeUntilDestroyed(this._destroyRef), switchMap(e => {
|
|
1424
1473
|
const xx = x - Math.abs(e.clientX), yy = y - Math.abs(e.clientY), dist = Math.sqrt(Math.pow(xx, 2) + Math.pow(yy, 2));
|
|
1425
|
-
if (dist >
|
|
1474
|
+
if (dist > maxDistance) {
|
|
1475
|
+
this.onVirtualClickCancel.emit();
|
|
1426
1476
|
return of(true);
|
|
1427
1477
|
}
|
|
1428
1478
|
return of(false);
|
|
1429
|
-
}),
|
|
1479
|
+
}), filter(v => !!v)),
|
|
1430
1480
|
])), takeUntilDestroyed(this._destroyRef), tap$1(e => {
|
|
1431
1481
|
if (e) {
|
|
1432
1482
|
this.onVirtualClick.emit(e);
|
|
@@ -1435,7 +1485,7 @@ class VirtualClickDirective {
|
|
|
1435
1485
|
})).subscribe();
|
|
1436
1486
|
}
|
|
1437
1487
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: VirtualClickDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1438
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.19", type: VirtualClickDirective, isStandalone: false, selector: "[virtualClick]", inputs: { maxDistance: ["maxClickDistance", "maxDistance"] }, outputs: { onVirtualClick: "onVirtualClick" }, ngImport: i0 });
|
|
1488
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.19", type: VirtualClickDirective, isStandalone: false, selector: "[virtualClick]", inputs: { maxDistance: ["maxClickDistance", "maxDistance"] }, outputs: { onVirtualClick: "onVirtualClick", onVirtualClickPress: "onVirtualClickPress", onVirtualClickCancel: "onVirtualClickCancel" }, ngImport: i0 });
|
|
1439
1489
|
}
|
|
1440
1490
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: VirtualClickDirective, decorators: [{
|
|
1441
1491
|
type: Directive,
|
|
@@ -1446,7 +1496,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
1446
1496
|
}], ctorParameters: () => [], propDecorators: { maxDistance: [{
|
|
1447
1497
|
type: Input,
|
|
1448
1498
|
args: ['maxClickDistance']
|
|
1449
|
-
}], onVirtualClick: [{ type: i0.Output, args: ["onVirtualClick"] }] } });
|
|
1499
|
+
}], onVirtualClick: [{ type: i0.Output, args: ["onVirtualClick"] }], onVirtualClickPress: [{ type: i0.Output, args: ["onVirtualClickPress"] }], onVirtualClickCancel: [{ type: i0.Output, args: ["onVirtualClickCancel"] }] } });
|
|
1450
1500
|
|
|
1451
1501
|
/**
|
|
1452
1502
|
* Virtual list component.
|
|
@@ -1476,12 +1526,12 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
|
|
|
1476
1526
|
fromEvent(this.element, EVENT_FOCUS_IN).pipe(takeUntilDestroyed(this._destroyRef), tap(e => {
|
|
1477
1527
|
this._service.focusedId = this.itemId ?? null;
|
|
1478
1528
|
this.focused.set(true);
|
|
1479
|
-
this.updateConfig(this._data);
|
|
1529
|
+
this.updateConfig(this._data, this._service.isGrabbing);
|
|
1480
1530
|
this.updatePartStr(this._data, this._isSelected, this._isCollapsed);
|
|
1481
1531
|
})).subscribe(),
|
|
1482
1532
|
fromEvent(this.element, EVENT_FOCUS_OUT).pipe(takeUntilDestroyed(this._destroyRef), tap(e => {
|
|
1483
1533
|
this.focused.set(false);
|
|
1484
|
-
this.updateConfig(this._data);
|
|
1534
|
+
this.updateConfig(this._data, this._service.isGrabbing);
|
|
1485
1535
|
this.updatePartStr(this._data, this._isSelected, this._isCollapsed);
|
|
1486
1536
|
})).subscribe();
|
|
1487
1537
|
$focused.pipe(takeUntilDestroyed(this._destroyRef), debounceTime(this.getNavigationTimeout()), switchMap$1(v => {
|
|
@@ -1514,7 +1564,7 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
|
|
|
1514
1564
|
const actualIds = collapsedIds, isCollapsed = this.itemId !== undefined && actualIds && actualIds.includes(this.itemId);
|
|
1515
1565
|
this._isCollapsed = isCollapsed;
|
|
1516
1566
|
this.updatePartStr(this._data, this._isSelected, isCollapsed);
|
|
1517
|
-
this.updateConfig(this._data);
|
|
1567
|
+
this.updateConfig(this._data, this._service.isGrabbing);
|
|
1518
1568
|
this.updateMeasures(this._data);
|
|
1519
1569
|
})).subscribe();
|
|
1520
1570
|
}
|
|
@@ -1617,23 +1667,29 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
|
|
|
1617
1667
|
}
|
|
1618
1668
|
return Number.MIN_SAFE_INTEGER;
|
|
1619
1669
|
}
|
|
1620
|
-
updateConfig(v) {
|
|
1670
|
+
updateConfig(v, grabbing) {
|
|
1621
1671
|
this.config.set({
|
|
1622
|
-
...v?.config || {}, selected: this._isSelected, collapsed: this._isCollapsed, focused: this.focused(),
|
|
1672
|
+
...v?.config || {}, selected: this._isSelected, collapsed: this._isCollapsed, focused: this.focused(), grabbing,
|
|
1623
1673
|
});
|
|
1624
1674
|
}
|
|
1625
1675
|
onClickHandler() {
|
|
1626
1676
|
this._service.virtualClick(this._data);
|
|
1627
1677
|
}
|
|
1678
|
+
onClickPressHandler() {
|
|
1679
|
+
this._service.clickPressed = true;
|
|
1680
|
+
}
|
|
1681
|
+
onClickCancelHandler() {
|
|
1682
|
+
this._service.clickPressed = false;
|
|
1683
|
+
}
|
|
1628
1684
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NgVirtualListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1629
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", 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()\"
|
|
1685
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", 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 });
|
|
1630
1686
|
}
|
|
1631
1687
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NgVirtualListItemComponent, decorators: [{
|
|
1632
1688
|
type: Component,
|
|
1633
1689
|
args: [{ selector: 'ng-virtual-list-item', host: {
|
|
1634
1690
|
'class': 'ngvl__item',
|
|
1635
1691
|
'role': 'listitem',
|
|
1636
|
-
}, 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()\"
|
|
1692
|
+
}, 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"] }]
|
|
1637
1693
|
}], ctorParameters: () => [] });
|
|
1638
1694
|
|
|
1639
1695
|
/**
|
|
@@ -3193,7 +3249,7 @@ class TrackBox extends CacheMap {
|
|
|
3193
3249
|
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 = [];
|
|
3194
3250
|
if (items.length) {
|
|
3195
3251
|
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;
|
|
3196
|
-
let pos = startPosition, renderItems = renderItemsLength, stickyItem, nextSticky, stickyItemIndex = -1, stickyItemSize = 0, endStickyItem, nextEndSticky, endStickyItemIndex = -1, endStickyItemSize = 0;
|
|
3252
|
+
let pos = startPosition, renderItems = renderItemsLength, stickyItem, nextSticky, stickyItemIndex = -1, nexstStickyItemIndex = -1, stickyItemSize = 0, endStickyItem, nextEndSticky, endStickyItemIndex = -1, endStickyItemSize = 0;
|
|
3197
3253
|
const li = layoutIndexOffset + actualItems.length - 1;
|
|
3198
3254
|
if (stickyEnabled) {
|
|
3199
3255
|
for (let i = Math.min(itemsFromStartToScrollEnd > 0 ? (divides > 1 ? (itemsFromStartToScrollEnd - 1) : itemsFromStartToScrollEnd) : 0, totalLength - 1); i >= 0; i--) {
|
|
@@ -3453,6 +3509,7 @@ class TrackBox extends CacheMap {
|
|
|
3453
3509
|
item.measures.x = isVertical ? 0 : snapped ? actualSnippedPosition : pos;
|
|
3454
3510
|
item.measures.y = isVertical ? snapped ? actualSnippedPosition : pos : 0;
|
|
3455
3511
|
nextSticky = item;
|
|
3512
|
+
nexstStickyItemIndex = displayItems.length;
|
|
3456
3513
|
nextSticky.config.snapped = snapped;
|
|
3457
3514
|
nextSticky.measures.delta = (isVertical ? item.measures.y : item.measures.x) - scrollSize;
|
|
3458
3515
|
nextSticky.config.zIndex = Z_INDEX_3;
|
|
@@ -3475,10 +3532,10 @@ class TrackBox extends CacheMap {
|
|
|
3475
3532
|
}
|
|
3476
3533
|
i++;
|
|
3477
3534
|
}
|
|
3478
|
-
const axis = isVertical ? Y_PROP_NAME : X_PROP_NAME;
|
|
3535
|
+
const axis = isVertical ? Y_PROP_NAME : X_PROP_NAME, transformedAxis = isVertical ? TRANSFORMED_Y_PROP_NAME : TRANSFORMED_X_PROP_NAME;
|
|
3479
3536
|
if (!!nextSticky && !!stickyItem && nextSticky.measures[axis] <= actualSnippedPosition + stickyItem.measures[sizeProperty]) {
|
|
3480
3537
|
if (nextSticky.measures[axis] > actualSnippedPosition) {
|
|
3481
|
-
stickyItem.measures[axis] = nextSticky.measures[axis] - stickyItem.measures[sizeProperty];
|
|
3538
|
+
stickyItem.measures[axis] = stickyItem.measures[transformedAxis] = nextSticky.measures[axis] - stickyItem.measures[sizeProperty];
|
|
3482
3539
|
stickyItem.config.snapped = nextSticky.config.snapped = false;
|
|
3483
3540
|
stickyItem.config.snappedOut = true;
|
|
3484
3541
|
stickyItem.config.sticky = 1;
|
|
@@ -3487,14 +3544,35 @@ class TrackBox extends CacheMap {
|
|
|
3487
3544
|
else {
|
|
3488
3545
|
nextSticky.config.snapped = true;
|
|
3489
3546
|
nextSticky.measures.delta = (isVertical ? nextSticky.measures.y : nextSticky.measures.x) - scrollSize;
|
|
3490
|
-
stickyItem.measures[axis] = nextSticky.measures[axis] - stickyItem.measures[sizeProperty];
|
|
3547
|
+
stickyItem.measures[axis] = stickyItem.measures[transformedAxis] = nextSticky.measures[axis] - stickyItem.measures[sizeProperty];
|
|
3491
3548
|
stickyItem.measures.delta = (isVertical ? stickyItem.measures.y : stickyItem.measures.x) - scrollSize;
|
|
3549
|
+
const lastStickyItem = displayItems?.[nexstStickyItemIndex + 1];
|
|
3550
|
+
if (lastStickyItem?.config?.sticky === 1 && displayItems?.[nexstStickyItemIndex + 2]?.config?.sticky !== 1) {
|
|
3551
|
+
nextSticky.config.snapped = nextSticky.config.snappedOut = false;
|
|
3552
|
+
stickyItem.config.snappedOut = true;
|
|
3553
|
+
nextSticky.measures.delta = this._scrollStartOffset;
|
|
3554
|
+
if (lastStickyItem.measures[axis] <= actualSnippedPosition) {
|
|
3555
|
+
lastStickyItem.config.snapped = lastStickyItem.config.snappedOut = true;
|
|
3556
|
+
lastStickyItem.measures[axis] = lastStickyItem.measures[transformedAxis] = lastStickyItem.measures.position = actualSnippedPosition;
|
|
3557
|
+
lastStickyItem.measures.delta = this._scrollStartOffset;
|
|
3558
|
+
}
|
|
3559
|
+
}
|
|
3560
|
+
else if (lastStickyItem?.config?.sticky !== 1 && displayItems?.[nexstStickyItemIndex + 2]?.config?.sticky !== 1) {
|
|
3561
|
+
if (nextSticky.measures[axis] <= actualSnippedPosition) {
|
|
3562
|
+
nextSticky.config.snapped = nextSticky.config.snappedOut = true;
|
|
3563
|
+
nextSticky.measures[axis] = nextSticky.measures[transformedAxis] = nextSticky.measures.position = actualSnippedPosition;
|
|
3564
|
+
nextSticky.measures.delta = this._scrollStartOffset;
|
|
3565
|
+
}
|
|
3566
|
+
}
|
|
3567
|
+
else {
|
|
3568
|
+
nextSticky.config.snapped = nextSticky.config.snappedOut = false;
|
|
3569
|
+
}
|
|
3492
3570
|
}
|
|
3493
3571
|
}
|
|
3494
3572
|
if (!!nextEndSticky && !!endStickyItem &&
|
|
3495
3573
|
(nextEndSticky.measures[axis] >= actualEndSnippedPosition - endStickyItemSize - nextEndSticky.measures[sizeProperty])) {
|
|
3496
3574
|
if (nextEndSticky.measures[axis] < actualEndSnippedPosition - nextEndSticky.measures[sizeProperty]) {
|
|
3497
|
-
endStickyItem.measures[axis] = nextEndSticky.measures[axis] + nextEndSticky.measures[sizeProperty];
|
|
3575
|
+
endStickyItem.measures[axis] = endStickyItem.measures[transformedAxis] = nextEndSticky.measures[axis] + nextEndSticky.measures[sizeProperty];
|
|
3498
3576
|
endStickyItem.config.snapped = nextEndSticky.config.snapped = false;
|
|
3499
3577
|
endStickyItem.config.snappedOut = true;
|
|
3500
3578
|
endStickyItem.config.sticky = 2;
|
|
@@ -3502,9 +3580,9 @@ class TrackBox extends CacheMap {
|
|
|
3502
3580
|
}
|
|
3503
3581
|
else {
|
|
3504
3582
|
nextEndSticky.config.snapped = true;
|
|
3505
|
-
nextEndSticky.measures[axis] = actualEndSnippedPosition - nextEndSticky.measures[sizeProperty];
|
|
3583
|
+
nextEndSticky.measures[axis] = nextEndSticky.measures[transformedAxis] = actualEndSnippedPosition - nextEndSticky.measures[sizeProperty];
|
|
3506
3584
|
nextEndSticky.measures.delta = (isVertical ? nextEndSticky.measures.y : nextEndSticky.measures.x) - scrollSize;
|
|
3507
|
-
endStickyItem.measures[axis] = nextEndSticky.measures[axis] + nextEndSticky.measures[sizeProperty];
|
|
3585
|
+
endStickyItem.measures[axis] = endStickyItem.measures[transformedAxis] = nextEndSticky.measures[axis] + nextEndSticky.measures[sizeProperty];
|
|
3508
3586
|
endStickyItem.measures.delta = (isVertical ? endStickyItem.measures.y : endStickyItem.measures.x) - scrollSize;
|
|
3509
3587
|
}
|
|
3510
3588
|
}
|
|
@@ -3968,18 +4046,34 @@ const easeLinear = (t) => {
|
|
|
3968
4046
|
class Animator {
|
|
3969
4047
|
static _nextId = 0;
|
|
3970
4048
|
_animationId = 0;
|
|
4049
|
+
get animated() { return this._animationId > -1; }
|
|
4050
|
+
get isAnimated() { return this.hasAnimation(this._currentId); }
|
|
3971
4051
|
_currentId = Animator._nextId;
|
|
4052
|
+
get id() { return this._currentId; }
|
|
3972
4053
|
generateId() {
|
|
3973
4054
|
return Animator._nextId = Animator._nextId === Number.MAX_SAFE_INTEGER
|
|
3974
4055
|
? 0 : Animator._nextId + 1;
|
|
3975
4056
|
}
|
|
4057
|
+
_diff = 0;
|
|
4058
|
+
_startValue = 0;
|
|
4059
|
+
_endValue = 0;
|
|
4060
|
+
_prevPos = 0;
|
|
4061
|
+
updateTo(end) {
|
|
4062
|
+
this._endValue = end;
|
|
4063
|
+
this._diff = this._endValue - this._startValue;
|
|
4064
|
+
return this.hasAnimation();
|
|
4065
|
+
}
|
|
3976
4066
|
animate(params) {
|
|
3977
4067
|
this.stop();
|
|
3978
4068
|
const id = this.generateId();
|
|
3979
4069
|
this._currentId = id;
|
|
3980
4070
|
const { withDelta = DEFAULT_WITH_DELTA, startValue, endValue, duration = DEFAULT_ANIMATION_DURATION, getPropValue, easingFunction = easeLinear, onUpdate, onComplete, } = params;
|
|
4071
|
+
this._startValue = startValue;
|
|
4072
|
+
this._endValue = endValue;
|
|
3981
4073
|
const startTime = performance.now();
|
|
3982
|
-
let isCanceled = false,
|
|
4074
|
+
let isCanceled = false, startPosDelta = 0, delta = 0, prevTime = startTime, isFinished = false;
|
|
4075
|
+
this._prevPos = startValue;
|
|
4076
|
+
this._diff = this._endValue - this._startValue;
|
|
3983
4077
|
const step = (currentTime) => {
|
|
3984
4078
|
if (id !== this._currentId) {
|
|
3985
4079
|
isCanceled = true;
|
|
@@ -3989,34 +4083,35 @@ class Animator {
|
|
|
3989
4083
|
}
|
|
3990
4084
|
const cPos = getPropValue?.() || 0;
|
|
3991
4085
|
let startDelta = 0;
|
|
3992
|
-
if (cPos !==
|
|
3993
|
-
startDelta = cPos -
|
|
4086
|
+
if (cPos !== this._prevPos) {
|
|
4087
|
+
startDelta = cPos - this._prevPos;
|
|
3994
4088
|
startPosDelta += startDelta;
|
|
3995
4089
|
}
|
|
3996
|
-
const elapsed = currentTime - startTime, progress =
|
|
4090
|
+
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();
|
|
3997
4091
|
isFinished = progress === 1;
|
|
3998
|
-
delta = currentValue - startDelta -
|
|
3999
|
-
const
|
|
4092
|
+
delta = currentValue - startDelta - this._prevPos;
|
|
4093
|
+
const frameTimestamp = t - prevTime, actualFrameTimestamp = frameTimestamp < ANIMATOR_MIN_TIMESTAMP ? ANIMATOR_MIN_TIMESTAMP : frameTimestamp;
|
|
4000
4094
|
prevTime = t;
|
|
4001
|
-
|
|
4095
|
+
this._prevPos = currentValue;
|
|
4002
4096
|
if (onUpdate !== undefined) {
|
|
4003
4097
|
const data = {
|
|
4004
4098
|
id,
|
|
4005
4099
|
delta,
|
|
4006
4100
|
elapsed,
|
|
4007
|
-
value:
|
|
4008
|
-
timestamp,
|
|
4101
|
+
value: currentValue,
|
|
4102
|
+
timestamp: actualFrameTimestamp,
|
|
4009
4103
|
};
|
|
4010
4104
|
onUpdate(data);
|
|
4011
4105
|
}
|
|
4012
4106
|
if (isFinished) {
|
|
4107
|
+
this._animationId = -1;
|
|
4013
4108
|
if (onComplete !== undefined) {
|
|
4014
4109
|
const data = {
|
|
4015
4110
|
id,
|
|
4016
4111
|
delta,
|
|
4017
4112
|
elapsed,
|
|
4018
|
-
value:
|
|
4019
|
-
timestamp,
|
|
4113
|
+
value: currentValue,
|
|
4114
|
+
timestamp: actualFrameTimestamp,
|
|
4020
4115
|
};
|
|
4021
4116
|
onComplete(data);
|
|
4022
4117
|
}
|
|
@@ -4026,9 +4121,17 @@ class Animator {
|
|
|
4026
4121
|
}
|
|
4027
4122
|
};
|
|
4028
4123
|
this._animationId = requestAnimationFrame(step);
|
|
4124
|
+
return this._currentId;
|
|
4125
|
+
}
|
|
4126
|
+
hasAnimation(id = -1) {
|
|
4127
|
+
if ((this._currentId === id || id === -1) && this.animated) {
|
|
4128
|
+
return true;
|
|
4129
|
+
}
|
|
4130
|
+
return false;
|
|
4029
4131
|
}
|
|
4030
|
-
stop() {
|
|
4031
|
-
cancelAnimationFrame(this._animationId);
|
|
4132
|
+
stop(id = -1) {
|
|
4133
|
+
cancelAnimationFrame(id === -1 ? this._animationId : id);
|
|
4134
|
+
this._animationId = -1;
|
|
4032
4135
|
}
|
|
4033
4136
|
dispose() {
|
|
4034
4137
|
this.stop();
|
|
@@ -4465,6 +4568,7 @@ class NgScrollView extends BaseScrollView {
|
|
|
4465
4568
|
get startLayoutOffset() { return this._startLayoutOffset; }
|
|
4466
4569
|
_intersectionComponentId = null;
|
|
4467
4570
|
_isAlignmentAnimation = false;
|
|
4571
|
+
get animated() { return this._animator?.isAnimated ?? false; }
|
|
4468
4572
|
constructor() {
|
|
4469
4573
|
super();
|
|
4470
4574
|
let mouseCanceled = false, touchCanceled = false;
|
|
@@ -4656,6 +4760,7 @@ class NgScrollView extends BaseScrollView {
|
|
|
4656
4760
|
}));
|
|
4657
4761
|
})).subscribe();
|
|
4658
4762
|
}
|
|
4763
|
+
hasAnimation(id = -1) { return this._animator?.hasAnimation(id) ?? false; }
|
|
4659
4764
|
updateDirection(position, prePosition) {
|
|
4660
4765
|
const delta = (position - this._delta) - prePosition;
|
|
4661
4766
|
this._scrollDirection.add(delta > 0 ? 1 : delta < 0 ? -1 : 0);
|
|
@@ -4818,7 +4923,7 @@ class NgScrollView extends BaseScrollView {
|
|
|
4818
4923
|
moveWithAcceleration(isVertical, position, v0, v, a0, timestamp) {
|
|
4819
4924
|
if (a0 !== 0 && timestamp < MAX_VELOCITY_TIMESTAMP) {
|
|
4820
4925
|
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;
|
|
4821
|
-
this.animate(startPosition, Math.round(positionWithVelocity), aDuration, easeOutQuad, true);
|
|
4926
|
+
this.animate(startPosition, Math.round(positionWithVelocity), aDuration, easeOutQuad, false, true);
|
|
4822
4927
|
}
|
|
4823
4928
|
else {
|
|
4824
4929
|
this.alignPosition(true, true);
|
|
@@ -4831,11 +4936,17 @@ class NgScrollView extends BaseScrollView {
|
|
|
4831
4936
|
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;
|
|
4832
4937
|
return result;
|
|
4833
4938
|
}
|
|
4834
|
-
animate(startValue, endValue, duration = ANIMATION_DURATION, easingFunction = easeOutQuad, userAction = false, alignmentAtComplete = true, skipOverridedCoordinates = false) {
|
|
4939
|
+
animate(startValue, endValue, duration = ANIMATION_DURATION, easingFunction = easeOutQuad, blending = false, userAction = false, alignmentAtComplete = true, skipOverridedCoordinates = false) {
|
|
4835
4940
|
const isVertical = this.isVertical();
|
|
4836
4941
|
let position = startValue;
|
|
4837
4942
|
this._isAlignmentAnimation = !alignmentAtComplete;
|
|
4838
|
-
this.
|
|
4943
|
+
if (this.hasAnimation() && blending) {
|
|
4944
|
+
const updatable = this._animator.updateTo(endValue);
|
|
4945
|
+
if (updatable) {
|
|
4946
|
+
return this._animator.id;
|
|
4947
|
+
}
|
|
4948
|
+
}
|
|
4949
|
+
return this._animator.animate({
|
|
4839
4950
|
withDelta: this._service.dynamic && !this.isInfinity(),
|
|
4840
4951
|
startValue,
|
|
4841
4952
|
endValue,
|
|
@@ -4847,7 +4958,7 @@ class NgScrollView extends BaseScrollView {
|
|
|
4847
4958
|
if (this._isCoordinatesOverrided && !skipOverridedCoordinates) {
|
|
4848
4959
|
this._isCoordinatesOverrided = false;
|
|
4849
4960
|
const currentCoordinate = isVertical ? this._y : this._x, delta = endValue - value;
|
|
4850
|
-
this.animate(currentCoordinate, currentCoordinate + delta, duration - elapsed, easingFunction, userAction, alignmentAtComplete);
|
|
4961
|
+
this.animate(currentCoordinate, currentCoordinate + delta, duration - elapsed, easingFunction, blending, userAction, alignmentAtComplete);
|
|
4851
4962
|
return;
|
|
4852
4963
|
}
|
|
4853
4964
|
const v0 = calculateVelocity(position, value - this._delta, timestamp) ?? this.averageVelocity;
|
|
@@ -4979,7 +5090,7 @@ class NgScrollView extends BaseScrollView {
|
|
|
4979
5090
|
const cPos = (isVertical ? this.scrollTop : this.scrollLeft);
|
|
4980
5091
|
if (position !== null && position !== cPos) {
|
|
4981
5092
|
this.stopScrolling(true);
|
|
4982
|
-
this.animate(cPos, position, animated ? this.animationParams().snapToItem : 1, easeOutQuad, false, false, true);
|
|
5093
|
+
this.animate(cPos, position, animated ? this.animationParams().snapToItem : 1, easeOutQuad, false, false, false, true);
|
|
4983
5094
|
return true;
|
|
4984
5095
|
}
|
|
4985
5096
|
return false;
|
|
@@ -5065,21 +5176,18 @@ class NgScrollView extends BaseScrollView {
|
|
|
5065
5176
|
if (behavior === AUTO || behavior === SMOOTH) {
|
|
5066
5177
|
if (isVertical) {
|
|
5067
5178
|
if (prevY !== y) {
|
|
5068
|
-
this.animate(prevY, y, duration, ease, userAction);
|
|
5179
|
+
return this.animate(prevY, y, duration, ease, blending, userAction);
|
|
5069
5180
|
}
|
|
5070
5181
|
}
|
|
5071
5182
|
else {
|
|
5072
5183
|
if (prevX !== x) {
|
|
5073
|
-
this.animate(prevX, x, duration, ease, userAction);
|
|
5184
|
+
return this.animate(prevX, x, duration, ease, blending, userAction);
|
|
5074
5185
|
}
|
|
5075
5186
|
}
|
|
5076
5187
|
}
|
|
5077
5188
|
else {
|
|
5078
5189
|
if (isVertical) {
|
|
5079
5190
|
if (this._y !== y || force) {
|
|
5080
|
-
if (!blending) {
|
|
5081
|
-
this.stopScrolling(force);
|
|
5082
|
-
}
|
|
5083
5191
|
this.setY(y, snap, normalize);
|
|
5084
5192
|
this.emitScrollableEvent();
|
|
5085
5193
|
if (fireUpdate) {
|
|
@@ -5089,9 +5197,6 @@ class NgScrollView extends BaseScrollView {
|
|
|
5089
5197
|
}
|
|
5090
5198
|
else {
|
|
5091
5199
|
if (this._x !== x || force) {
|
|
5092
|
-
if (!blending) {
|
|
5093
|
-
this.stopScrolling(force);
|
|
5094
|
-
}
|
|
5095
5200
|
this.setX(x, snap, normalize);
|
|
5096
5201
|
this.emitScrollableEvent();
|
|
5097
5202
|
if (fireUpdate) {
|
|
@@ -5100,6 +5205,7 @@ class NgScrollView extends BaseScrollView {
|
|
|
5100
5205
|
}
|
|
5101
5206
|
}
|
|
5102
5207
|
}
|
|
5208
|
+
return -1;
|
|
5103
5209
|
}
|
|
5104
5210
|
emitScrollableEvent() {
|
|
5105
5211
|
if (!!this.cdkScrollable) {
|
|
@@ -5118,6 +5224,9 @@ class NgScrollView extends BaseScrollView {
|
|
|
5118
5224
|
this.stopScrolling();
|
|
5119
5225
|
this.move(this.isVertical(), offset);
|
|
5120
5226
|
}
|
|
5227
|
+
stopAnimation(id) {
|
|
5228
|
+
this._animator.stop(id);
|
|
5229
|
+
}
|
|
5121
5230
|
ngOnDestroy() {
|
|
5122
5231
|
if (this._animator) {
|
|
5123
5232
|
this._animator.dispose();
|
|
@@ -5496,6 +5605,10 @@ class NgScrollerComponent extends NgScrollView {
|
|
|
5496
5605
|
$updateScrollBar.pipe(takeUntilDestroyed(this._destroyRef), debounceTime(0), tap(() => {
|
|
5497
5606
|
this.updateScrollBarHandler(!this._isScrollbarUserAction);
|
|
5498
5607
|
})).subscribe();
|
|
5608
|
+
effect(() => {
|
|
5609
|
+
const grabbing = this.grabbing();
|
|
5610
|
+
this._service.grabbing = grabbing;
|
|
5611
|
+
});
|
|
5499
5612
|
this.actualClasses = computed(() => {
|
|
5500
5613
|
const classes = this.classes(), direction = this.direction(), filtered = this.motionBlurEnabled();
|
|
5501
5614
|
return { ...classes, [direction]: true, grabbing: this.grabbing(), filtered };
|
|
@@ -5633,7 +5746,7 @@ class NgScrollerComponent extends NgScrollView {
|
|
|
5633
5746
|
this._isScrollbarUserAction = false;
|
|
5634
5747
|
this.scrollBar?.stopScrolling();
|
|
5635
5748
|
}
|
|
5636
|
-
this.scroll({ ...params, userAction: userAction });
|
|
5749
|
+
return this.scroll({ ...params, userAction: userAction });
|
|
5637
5750
|
}
|
|
5638
5751
|
stopScrollbar() {
|
|
5639
5752
|
if (!!this.scrollBar) {
|
|
@@ -6002,14 +6115,14 @@ class NgPrerenderVirtualListItemComponent extends NgVirtualListItemComponent {
|
|
|
6002
6115
|
}
|
|
6003
6116
|
}
|
|
6004
6117
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NgPrerenderVirtualListItemComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
6005
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", 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()\"
|
|
6118
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", 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 });
|
|
6006
6119
|
}
|
|
6007
6120
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NgPrerenderVirtualListItemComponent, decorators: [{
|
|
6008
6121
|
type: Component,
|
|
6009
6122
|
args: [{ selector: 'ng-prerender-virtual-list-item', host: {
|
|
6010
6123
|
'class': 'ngvl__item',
|
|
6011
6124
|
'role': 'listitem',
|
|
6012
|
-
}, 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()\"
|
|
6125
|
+
}, 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"] }]
|
|
6013
6126
|
}] });
|
|
6014
6127
|
|
|
6015
6128
|
/**
|
|
@@ -7031,7 +7144,7 @@ class NgVirtualListComponent {
|
|
|
7031
7144
|
},
|
|
7032
7145
|
};
|
|
7033
7146
|
/**
|
|
7034
|
-
* Animation parameters. The default value is "{ scrollToItem:
|
|
7147
|
+
* Animation parameters. The default value is "{ scrollToItem: 150, snapToItem: 150, navigateToItem: 150, navigateByKeyboard: 50 }".
|
|
7035
7148
|
*/
|
|
7036
7149
|
animationParams = input(DEFAULT_ANIMATION_PARAMS, ...(ngDevMode ? [{ debugName: "animationParams", ...this._animationParamsOptions }] : [{ ...this._animationParamsOptions }]));
|
|
7037
7150
|
_overscrollEnabledOptions = {
|
|
@@ -7505,6 +7618,7 @@ class NgVirtualListComponent {
|
|
|
7505
7618
|
_readyForShow = false;
|
|
7506
7619
|
_cached = false;
|
|
7507
7620
|
_isLoading = false;
|
|
7621
|
+
_animationId = -1;
|
|
7508
7622
|
get cachable() {
|
|
7509
7623
|
return this._prerender()?.active ?? false;
|
|
7510
7624
|
}
|
|
@@ -7519,6 +7633,7 @@ class NgVirtualListComponent {
|
|
|
7519
7633
|
NgVirtualListComponent.__nextId = NgVirtualListComponent.__nextId + 1 === Number.MAX_SAFE_INTEGER
|
|
7520
7634
|
? 0 : NgVirtualListComponent.__nextId + 1;
|
|
7521
7635
|
this._id = NgVirtualListComponent.__nextId;
|
|
7636
|
+
let readyForAnimations = false;
|
|
7522
7637
|
const _$created = new BehaviorSubject(false), $created = _$created.asObservable();
|
|
7523
7638
|
combineLatest([$created, this.$show]).pipe(takeUntilDestroyed(), filter$1(([created, shown]) => created && shown), debounceTime(1), tap(v => {
|
|
7524
7639
|
this._$initialized.next(true);
|
|
@@ -7755,6 +7870,7 @@ class NgVirtualListComponent {
|
|
|
7755
7870
|
}), tap(items => {
|
|
7756
7871
|
this._trackBox.resetCollection(items, this._actualItemSize());
|
|
7757
7872
|
}), switchMap$1(i => of((i ?? []).length > 0)), distinctUntilChanged(), tap(v => {
|
|
7873
|
+
readyForAnimations = false;
|
|
7758
7874
|
if (!v) {
|
|
7759
7875
|
this.cacheClean();
|
|
7760
7876
|
this.cleanup();
|
|
@@ -8096,12 +8212,22 @@ class NgVirtualListComponent {
|
|
|
8096
8212
|
}), debounceTime(100), tap(() => {
|
|
8097
8213
|
this._isLoading = false;
|
|
8098
8214
|
})).subscribe();
|
|
8215
|
+
let prevCacheVersion = -1, prevScrollable = false;
|
|
8216
|
+
$viewInit.pipe(takeUntilDestroyed(), filter$1(v => !!v), switchMap$1(() => {
|
|
8217
|
+
return this.$show.pipe(takeUntilDestroyed(this._destroyRef), debounceTime(Math.max(500, this.animationParams().scrollToItem)), tap(() => {
|
|
8218
|
+
if (this._readyForShow || (this.cachable && this._cached)) {
|
|
8219
|
+
readyForAnimations = true;
|
|
8220
|
+
}
|
|
8221
|
+
}));
|
|
8222
|
+
})).subscribe();
|
|
8099
8223
|
const update = (params) => {
|
|
8100
|
-
const { alignment, snapScrollToStart, snapScrollToEnd, bounds, items, itemConfigMap, scrollSize, itemSize, minItemSize, maxItemSize, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, enabledBufferOptimization, snapToItem, snapToItemAlign, userAction, collapsedIds, itemTransform, } = params;
|
|
8224
|
+
const { alignment, snapScrollToStart, snapScrollToEnd, bounds, items, itemConfigMap, scrollSize, itemSize, minItemSize, maxItemSize, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, enabledBufferOptimization, snapToItem, snapToItemAlign, userAction, collapsedIds, cacheVersion, itemTransform, } = params;
|
|
8225
|
+
const cacheChanged = prevCacheVersion !== cacheVersion;
|
|
8226
|
+
prevCacheVersion = cacheVersion;
|
|
8101
8227
|
const scroller = this._scrollerComponent();
|
|
8102
8228
|
let totalSize = 0;
|
|
8103
8229
|
if (!!scroller) {
|
|
8104
|
-
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;
|
|
8230
|
+
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;
|
|
8105
8231
|
if (this._readyForShow || (cachable && cached)) {
|
|
8106
8232
|
const currentScrollSize = (isVertical ? scroller.scrollTop : scroller.scrollLeft);
|
|
8107
8233
|
let actualScrollSize = !this._readyForShow && snapScrollToEnd ? (isVertical ? scroller.scrollHeight : scroller.scrollWidth) :
|
|
@@ -8145,12 +8271,13 @@ class NgVirtualListComponent {
|
|
|
8145
8271
|
if (!_$created.getValue()) {
|
|
8146
8272
|
_$created.next(true);
|
|
8147
8273
|
}
|
|
8148
|
-
const delta = this._trackBox.delta, scrollPositionAfterUpdate = actualScrollSize + delta, roundedScrollPositionAfterUpdate = scrollPositionAfterUpdate, roundedMaxPositionAfterUpdate = isVertical ? scroller.
|
|
8274
|
+
const delta = this._trackBox.delta, scrollPositionAfterUpdate = actualScrollSize + delta, roundedScrollPositionAfterUpdate = scrollPositionAfterUpdate, roundedMaxPositionAfterUpdate = isVertical ? scroller.actualScrollHeight : scroller.actualScrollWidth;
|
|
8149
8275
|
if (this._isSnappingMethodAdvanced) {
|
|
8150
8276
|
this.updateRegularRenderer();
|
|
8151
8277
|
}
|
|
8152
8278
|
this.updateOffsetsByAllignment();
|
|
8153
8279
|
scroller.delta = delta;
|
|
8280
|
+
prevScrollable = scroller.scrollable;
|
|
8154
8281
|
if ((snapScrollToStart && this._trackBox.isSnappedToStart && scroller.scrollable) ||
|
|
8155
8282
|
(snapScrollToStart && currentScrollSize <= MIN_PIXELS_FOR_PREVENT_SNAPPING)) {
|
|
8156
8283
|
if (currentScrollSize !== roundedScrollPositionAfterUpdate) {
|
|
@@ -8161,10 +8288,16 @@ class NgVirtualListComponent {
|
|
|
8161
8288
|
this._trackBox.isScrollEnd;
|
|
8162
8289
|
const params = {
|
|
8163
8290
|
[isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: 0, userAction,
|
|
8164
|
-
fireUpdate: fireUpdateAtEdges, behavior: BEHAVIOR_INSTANT,
|
|
8165
|
-
blending:
|
|
8291
|
+
fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams().scrollToItem > 0 && this.scrollBehavior() !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT),
|
|
8292
|
+
blending: useAnimations && scroller.hasAnimation(this._animationId), duration: this.animationParams().scrollToItem,
|
|
8166
8293
|
};
|
|
8167
|
-
scroller?.scrollTo?.(params);
|
|
8294
|
+
const animationId = scroller?.scrollTo?.(params);
|
|
8295
|
+
if (animationId > -1) {
|
|
8296
|
+
this._animationId = animationId;
|
|
8297
|
+
}
|
|
8298
|
+
else {
|
|
8299
|
+
scroller.stopAnimation(this._animationId);
|
|
8300
|
+
}
|
|
8168
8301
|
if (emitUpdate) {
|
|
8169
8302
|
this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
|
|
8170
8303
|
}
|
|
@@ -8184,10 +8317,16 @@ class NgVirtualListComponent {
|
|
|
8184
8317
|
}
|
|
8185
8318
|
const params = {
|
|
8186
8319
|
[isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: roundedMaxPositionAfterUpdate,
|
|
8187
|
-
fireUpdate: fireUpdateAtEdges, behavior: BEHAVIOR_INSTANT, userAction: false,
|
|
8188
|
-
blending:
|
|
8320
|
+
fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams().scrollToItem > 0 && this.scrollBehavior() !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT), userAction: false,
|
|
8321
|
+
blending: useAnimations && scroller.hasAnimation(this._animationId) || cacheChanged, duration: this.animationParams().scrollToItem,
|
|
8189
8322
|
};
|
|
8190
|
-
scroller?.scrollTo?.(params);
|
|
8323
|
+
const animationId = scroller?.scrollTo?.(params);
|
|
8324
|
+
if (animationId > -1) {
|
|
8325
|
+
this._animationId = animationId;
|
|
8326
|
+
}
|
|
8327
|
+
else {
|
|
8328
|
+
scroller.stopAnimation(this._animationId);
|
|
8329
|
+
}
|
|
8191
8330
|
if (emitUpdate) {
|
|
8192
8331
|
this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
|
|
8193
8332
|
}
|
|
@@ -8200,9 +8339,13 @@ class NgVirtualListComponent {
|
|
|
8200
8339
|
if (this._readyForShow) {
|
|
8201
8340
|
this.emitScrollEvent(true, false, userAction);
|
|
8202
8341
|
}
|
|
8342
|
+
if (this._animationId > -1) {
|
|
8343
|
+
scroller.stopAnimation(this._animationId);
|
|
8344
|
+
this._animationId = -1;
|
|
8345
|
+
}
|
|
8203
8346
|
const params = {
|
|
8204
8347
|
[isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollPositionAfterUpdate, blending: true, userAction,
|
|
8205
|
-
fireUpdate, behavior: BEHAVIOR_INSTANT, duration:
|
|
8348
|
+
fireUpdate, behavior: BEHAVIOR_INSTANT, duration: 0,
|
|
8206
8349
|
};
|
|
8207
8350
|
scroller.scrollTo(params);
|
|
8208
8351
|
if (emitUpdate) {
|
|
@@ -8889,7 +9032,7 @@ class NgVirtualListComponent {
|
|
|
8889
9032
|
this._isScrollStart.set(false);
|
|
8890
9033
|
this._isScrollEnd.set(false);
|
|
8891
9034
|
this._trackBox.preventScrollSnapping(true);
|
|
8892
|
-
if (scroller) {
|
|
9035
|
+
if (!!scroller) {
|
|
8893
9036
|
scroller.stopScrolling();
|
|
8894
9037
|
}
|
|
8895
9038
|
}
|
|
@@ -8915,7 +9058,7 @@ class NgVirtualListComponent {
|
|
|
8915
9058
|
comp?.destroy();
|
|
8916
9059
|
}
|
|
8917
9060
|
}
|
|
8918
|
-
if (this._displayComponents) {
|
|
9061
|
+
if (!!this._displayComponents) {
|
|
8919
9062
|
while (this._displayComponents.length > 0) {
|
|
8920
9063
|
const comp = this._displayComponents.shift();
|
|
8921
9064
|
comp?.destroy();
|