ng-virtual-list 21.12.2 → 21.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/package.json +1 -1
- 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: {
|
|
@@ -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: "21.2.0", ngImpor
|
|
|
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: "21.2.0", ngImport: i0, type: VirtualClickDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1438
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.0", 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: "21.2.0", 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: "21.2.0", ngImport: i0, type: VirtualClickDirective, decorators: [{
|
|
1441
1491
|
type: Directive,
|
|
@@ -1446,7 +1496,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
|
|
|
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: "21.2.0", ngImport: i0, type: NgVirtualListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1629
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.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()\"
|
|
1685
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.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 });
|
|
1630
1686
|
}
|
|
1631
1687
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", 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: "21.2.0", ngImport: i0, type: NgPrerenderVirtualListItemComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
6005
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.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()\"
|
|
6118
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.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 });
|
|
6006
6119
|
}
|
|
6007
6120
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", 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
|
/**
|
|
@@ -7029,7 +7142,7 @@ class NgVirtualListComponent {
|
|
|
7029
7142
|
},
|
|
7030
7143
|
};
|
|
7031
7144
|
/**
|
|
7032
|
-
* Animation parameters. The default value is "{ scrollToItem:
|
|
7145
|
+
* Animation parameters. The default value is "{ scrollToItem: 150, snapToItem: 150, navigateToItem: 150, navigateByKeyboard: 50 }".
|
|
7033
7146
|
*/
|
|
7034
7147
|
animationParams = input(DEFAULT_ANIMATION_PARAMS, { ...(ngDevMode ? { debugName: "animationParams" } : {}), ...this._animationParamsOptions });
|
|
7035
7148
|
_overscrollEnabledOptions = {
|
|
@@ -7503,6 +7616,7 @@ class NgVirtualListComponent {
|
|
|
7503
7616
|
_readyForShow = false;
|
|
7504
7617
|
_cached = false;
|
|
7505
7618
|
_isLoading = false;
|
|
7619
|
+
_animationId = -1;
|
|
7506
7620
|
get cachable() {
|
|
7507
7621
|
return this._prerender()?.active ?? false;
|
|
7508
7622
|
}
|
|
@@ -7517,6 +7631,7 @@ class NgVirtualListComponent {
|
|
|
7517
7631
|
NgVirtualListComponent.__nextId = NgVirtualListComponent.__nextId + 1 === Number.MAX_SAFE_INTEGER
|
|
7518
7632
|
? 0 : NgVirtualListComponent.__nextId + 1;
|
|
7519
7633
|
this._id = NgVirtualListComponent.__nextId;
|
|
7634
|
+
let readyForAnimations = false;
|
|
7520
7635
|
const _$created = new BehaviorSubject(false), $created = _$created.asObservable();
|
|
7521
7636
|
combineLatest([$created, this.$show]).pipe(takeUntilDestroyed(), filter$1(([created, shown]) => created && shown), debounceTime(1), tap(v => {
|
|
7522
7637
|
this._$initialized.next(true);
|
|
@@ -7753,6 +7868,7 @@ class NgVirtualListComponent {
|
|
|
7753
7868
|
}), tap(items => {
|
|
7754
7869
|
this._trackBox.resetCollection(items, this._actualItemSize());
|
|
7755
7870
|
}), switchMap$1(i => of((i ?? []).length > 0)), distinctUntilChanged(), tap(v => {
|
|
7871
|
+
readyForAnimations = false;
|
|
7756
7872
|
if (!v) {
|
|
7757
7873
|
this.cacheClean();
|
|
7758
7874
|
this.cleanup();
|
|
@@ -8094,12 +8210,22 @@ class NgVirtualListComponent {
|
|
|
8094
8210
|
}), debounceTime(100), tap(() => {
|
|
8095
8211
|
this._isLoading = false;
|
|
8096
8212
|
})).subscribe();
|
|
8213
|
+
let prevCacheVersion = -1, prevScrollable = false;
|
|
8214
|
+
$viewInit.pipe(takeUntilDestroyed(), filter$1(v => !!v), switchMap$1(() => {
|
|
8215
|
+
return this.$show.pipe(takeUntilDestroyed(this._destroyRef), debounceTime(Math.max(500, this.animationParams().scrollToItem)), tap(() => {
|
|
8216
|
+
if (this._readyForShow || (this.cachable && this._cached)) {
|
|
8217
|
+
readyForAnimations = true;
|
|
8218
|
+
}
|
|
8219
|
+
}));
|
|
8220
|
+
})).subscribe();
|
|
8097
8221
|
const update = (params) => {
|
|
8098
|
-
const { alignment, snapScrollToStart, snapScrollToEnd, bounds, items, itemConfigMap, scrollSize, itemSize, minItemSize, maxItemSize, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, enabledBufferOptimization, snapToItem, snapToItemAlign, userAction, collapsedIds, itemTransform, } = params;
|
|
8222
|
+
const { alignment, snapScrollToStart, snapScrollToEnd, bounds, items, itemConfigMap, scrollSize, itemSize, minItemSize, maxItemSize, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, enabledBufferOptimization, snapToItem, snapToItemAlign, userAction, collapsedIds, cacheVersion, itemTransform, } = params;
|
|
8223
|
+
const cacheChanged = prevCacheVersion !== cacheVersion;
|
|
8224
|
+
prevCacheVersion = cacheVersion;
|
|
8099
8225
|
const scroller = this._scrollerComponent();
|
|
8100
8226
|
let totalSize = 0;
|
|
8101
8227
|
if (!!scroller) {
|
|
8102
|
-
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;
|
|
8228
|
+
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;
|
|
8103
8229
|
if (this._readyForShow || (cachable && cached)) {
|
|
8104
8230
|
const currentScrollSize = (isVertical ? scroller.scrollTop : scroller.scrollLeft);
|
|
8105
8231
|
let actualScrollSize = !this._readyForShow && snapScrollToEnd ? (isVertical ? scroller.scrollHeight : scroller.scrollWidth) :
|
|
@@ -8143,12 +8269,13 @@ class NgVirtualListComponent {
|
|
|
8143
8269
|
if (!_$created.getValue()) {
|
|
8144
8270
|
_$created.next(true);
|
|
8145
8271
|
}
|
|
8146
|
-
const delta = this._trackBox.delta, scrollPositionAfterUpdate = actualScrollSize + delta, roundedScrollPositionAfterUpdate = scrollPositionAfterUpdate, roundedMaxPositionAfterUpdate = isVertical ? scroller.
|
|
8272
|
+
const delta = this._trackBox.delta, scrollPositionAfterUpdate = actualScrollSize + delta, roundedScrollPositionAfterUpdate = scrollPositionAfterUpdate, roundedMaxPositionAfterUpdate = isVertical ? scroller.actualScrollHeight : scroller.actualScrollWidth;
|
|
8147
8273
|
if (this._isSnappingMethodAdvanced) {
|
|
8148
8274
|
this.updateRegularRenderer();
|
|
8149
8275
|
}
|
|
8150
8276
|
this.updateOffsetsByAllignment();
|
|
8151
8277
|
scroller.delta = delta;
|
|
8278
|
+
prevScrollable = scroller.scrollable;
|
|
8152
8279
|
if ((snapScrollToStart && this._trackBox.isSnappedToStart && scroller.scrollable) ||
|
|
8153
8280
|
(snapScrollToStart && currentScrollSize <= MIN_PIXELS_FOR_PREVENT_SNAPPING)) {
|
|
8154
8281
|
if (currentScrollSize !== roundedScrollPositionAfterUpdate) {
|
|
@@ -8159,10 +8286,16 @@ class NgVirtualListComponent {
|
|
|
8159
8286
|
this._trackBox.isScrollEnd;
|
|
8160
8287
|
const params = {
|
|
8161
8288
|
[isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: 0, userAction,
|
|
8162
|
-
fireUpdate: fireUpdateAtEdges, behavior: BEHAVIOR_INSTANT,
|
|
8163
|
-
blending:
|
|
8289
|
+
fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams().scrollToItem > 0 && this.scrollBehavior() !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT),
|
|
8290
|
+
blending: useAnimations && scroller.hasAnimation(this._animationId), duration: this.animationParams().scrollToItem,
|
|
8164
8291
|
};
|
|
8165
|
-
scroller?.scrollTo?.(params);
|
|
8292
|
+
const animationId = scroller?.scrollTo?.(params);
|
|
8293
|
+
if (animationId > -1) {
|
|
8294
|
+
this._animationId = animationId;
|
|
8295
|
+
}
|
|
8296
|
+
else {
|
|
8297
|
+
scroller.stopAnimation(this._animationId);
|
|
8298
|
+
}
|
|
8166
8299
|
if (emitUpdate) {
|
|
8167
8300
|
this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
|
|
8168
8301
|
}
|
|
@@ -8182,10 +8315,16 @@ class NgVirtualListComponent {
|
|
|
8182
8315
|
}
|
|
8183
8316
|
const params = {
|
|
8184
8317
|
[isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: roundedMaxPositionAfterUpdate,
|
|
8185
|
-
fireUpdate: fireUpdateAtEdges, behavior: BEHAVIOR_INSTANT, userAction: false,
|
|
8186
|
-
blending:
|
|
8318
|
+
fireUpdate: fireUpdateAtEdges, behavior: !useAnimations ? BEHAVIOR_INSTANT : ((this.animationParams().scrollToItem > 0 && this.scrollBehavior() !== BEHAVIOR_INSTANT) ? BEHAVIOR_AUTO : BEHAVIOR_INSTANT), userAction: false,
|
|
8319
|
+
blending: useAnimations && scroller.hasAnimation(this._animationId) || cacheChanged, duration: this.animationParams().scrollToItem,
|
|
8187
8320
|
};
|
|
8188
|
-
scroller?.scrollTo?.(params);
|
|
8321
|
+
const animationId = scroller?.scrollTo?.(params);
|
|
8322
|
+
if (animationId > -1) {
|
|
8323
|
+
this._animationId = animationId;
|
|
8324
|
+
}
|
|
8325
|
+
else {
|
|
8326
|
+
scroller.stopAnimation(this._animationId);
|
|
8327
|
+
}
|
|
8189
8328
|
if (emitUpdate) {
|
|
8190
8329
|
this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
|
|
8191
8330
|
}
|
|
@@ -8198,9 +8337,13 @@ class NgVirtualListComponent {
|
|
|
8198
8337
|
if (this._readyForShow) {
|
|
8199
8338
|
this.emitScrollEvent(true, false, userAction);
|
|
8200
8339
|
}
|
|
8340
|
+
if (this._animationId > -1) {
|
|
8341
|
+
scroller.stopAnimation(this._animationId);
|
|
8342
|
+
this._animationId = -1;
|
|
8343
|
+
}
|
|
8201
8344
|
const params = {
|
|
8202
8345
|
[isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollPositionAfterUpdate, blending: true, userAction,
|
|
8203
|
-
fireUpdate, behavior: BEHAVIOR_INSTANT, duration:
|
|
8346
|
+
fireUpdate, behavior: BEHAVIOR_INSTANT, duration: 0,
|
|
8204
8347
|
};
|
|
8205
8348
|
scroller.scrollTo(params);
|
|
8206
8349
|
if (emitUpdate) {
|
|
@@ -8887,7 +9030,7 @@ class NgVirtualListComponent {
|
|
|
8887
9030
|
this._isScrollStart.set(false);
|
|
8888
9031
|
this._isScrollEnd.set(false);
|
|
8889
9032
|
this._trackBox.preventScrollSnapping(true);
|
|
8890
|
-
if (scroller) {
|
|
9033
|
+
if (!!scroller) {
|
|
8891
9034
|
scroller.stopScrolling();
|
|
8892
9035
|
}
|
|
8893
9036
|
}
|
|
@@ -8913,7 +9056,7 @@ class NgVirtualListComponent {
|
|
|
8913
9056
|
comp?.destroy();
|
|
8914
9057
|
}
|
|
8915
9058
|
}
|
|
8916
|
-
if (this._displayComponents) {
|
|
9059
|
+
if (!!this._displayComponents) {
|
|
8917
9060
|
while (this._displayComponents.length > 0) {
|
|
8918
9061
|
const comp = this._displayComponents.shift();
|
|
8919
9062
|
comp?.destroy();
|