ng-virtual-list 16.7.11 → 16.7.13
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 +28 -9
- package/esm2022/lib/components/ng-virtual-list-item.component.mjs +43 -27
- package/esm2022/lib/const/index.mjs +3 -2
- package/esm2022/lib/enums/collection-mode.mjs +2 -0
- package/esm2022/lib/enums/collection-modes.mjs +18 -0
- package/esm2022/lib/enums/focus-alignments.mjs +14 -0
- package/esm2022/lib/enums/index.mjs +4 -2
- package/esm2022/lib/models/display-object-config.model.mjs +2 -0
- package/esm2022/lib/models/display-object-measures.model.mjs +2 -0
- package/esm2022/lib/models/index.mjs +1 -1
- package/esm2022/lib/ng-virtual-list.component.mjs +108 -19
- package/esm2022/lib/ng-virtual-list.service.mjs +4 -3
- package/esm2022/lib/types/focus-alignment.mjs +2 -0
- package/esm2022/lib/types/index.mjs +1 -1
- package/esm2022/lib/utils/isCollectionMode.mjs +15 -0
- package/esm2022/lib/utils/trackBox.mjs +45 -16
- package/fesm2022/ng-virtual-list.mjs +237 -59
- package/fesm2022/ng-virtual-list.mjs.map +1 -1
- package/lib/components/ng-virtual-list-item.component.d.ts +9 -39
- package/lib/const/index.d.ts +2 -1
- package/lib/enums/collection-mode.d.ts +8 -0
- package/lib/enums/collection-modes.d.ts +16 -0
- package/lib/enums/focus-alignments.d.ts +12 -0
- package/lib/enums/index.d.ts +5 -2
- package/lib/models/display-object-config.model.d.ts +35 -0
- package/lib/models/display-object-measures.model.d.ts +13 -0
- package/lib/models/index.d.ts +3 -1
- package/lib/ng-virtual-list.component.d.ts +19 -3
- package/lib/ng-virtual-list.service.d.ts +4 -4
- package/lib/types/focus-alignment.d.ts +8 -0
- package/lib/types/index.d.ts +2 -1
- package/lib/utils/isCollectionMode.d.ts +8 -0
- package/lib/utils/trackBox.d.ts +17 -9
- package/package.json +1 -1
|
@@ -1,12 +1,30 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { Injectable, Component, ChangeDetectionStrategy, EventEmitter as EventEmitter$1, ViewContainerRef, ElementRef, ViewEncapsulation, ViewChild, Output, Input, NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
|
|
3
|
-
import {
|
|
4
|
-
import { Subject, tap, BehaviorSubject as BehaviorSubject$1, fromEvent, combineLatest, filter, distinctUntilChanged,
|
|
5
|
-
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
|
|
3
|
+
import { tap as tap$1, map } from 'rxjs/operators';
|
|
4
|
+
import { Subject, tap, BehaviorSubject as BehaviorSubject$1, fromEvent, combineLatest, filter, distinctUntilChanged, map as map$1, debounceTime, switchMap, of } from 'rxjs';
|
|
6
5
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
6
|
+
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
|
|
7
7
|
import * as i2 from '@angular/common';
|
|
8
8
|
import { CommonModule } from '@angular/common';
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Action modes for collection elements.
|
|
12
|
+
* @link https://github.com/DjonnyX/ng-virtual-list/blob/16.x/projects/ng-virtual-list/src/lib/enums/collection-modes.ts
|
|
13
|
+
* @author Evgenii Grebennikov
|
|
14
|
+
* @email djonnyx@gmail.com
|
|
15
|
+
*/
|
|
16
|
+
var CollectionModes;
|
|
17
|
+
(function (CollectionModes) {
|
|
18
|
+
/**
|
|
19
|
+
* When adding elements to the beginning of the collection, the scroll remains at the current position.
|
|
20
|
+
*/
|
|
21
|
+
CollectionModes["NORMAL"] = "normal";
|
|
22
|
+
/**
|
|
23
|
+
* When adding elements to the beginning of the collection, the scroll is shifted by the sum of the sizes of the new elements.
|
|
24
|
+
*/
|
|
25
|
+
CollectionModes["LAZY"] = "lazy";
|
|
26
|
+
})(CollectionModes || (CollectionModes = {}));
|
|
27
|
+
|
|
10
28
|
/**
|
|
11
29
|
* Axis of the arrangement of virtual list elements.
|
|
12
30
|
* @link https://github.com/DjonnyX/ng-virtual-list/blob/16.x/projects/ng-virtual-list/src/lib/enums/directions.ts
|
|
@@ -65,6 +83,20 @@ var SnappingMethods;
|
|
|
65
83
|
SnappingMethods["ADVANCED"] = "advanced";
|
|
66
84
|
})(SnappingMethods || (SnappingMethods = {}));
|
|
67
85
|
|
|
86
|
+
/**
|
|
87
|
+
* Focus Alignments.
|
|
88
|
+
* @link https://github.com/DjonnyX/ng-virtual-list/blob/16.x/projects/ng-virtual-list/src/lib/enums/focus-alignments.ts
|
|
89
|
+
* @author Evgenii Grebennikov
|
|
90
|
+
* @email djonnyx@gmail.com
|
|
91
|
+
*/
|
|
92
|
+
var FocusAlignments;
|
|
93
|
+
(function (FocusAlignments) {
|
|
94
|
+
FocusAlignments["NONE"] = "none";
|
|
95
|
+
FocusAlignments["START"] = "start";
|
|
96
|
+
FocusAlignments["CENTER"] = "center";
|
|
97
|
+
FocusAlignments["END"] = "end";
|
|
98
|
+
})(FocusAlignments || (FocusAlignments = {}));
|
|
99
|
+
|
|
68
100
|
const DEFAULT_ITEM_SIZE = 24;
|
|
69
101
|
const DEFAULT_BUFFER_SIZE = 2;
|
|
70
102
|
const DEFAULT_MAX_BUFFER_SIZE = 10;
|
|
@@ -76,6 +108,7 @@ const DEFAULT_ENABLED_BUFFER_OPTIMIZATION = false;
|
|
|
76
108
|
const DEFAULT_DYNAMIC_SIZE = false;
|
|
77
109
|
const TRACK_BY_PROPERTY_NAME = 'id';
|
|
78
110
|
const DEFAULT_DIRECTION = Directions.VERTICAL;
|
|
111
|
+
const DEFAULT_COLLECTION_MODE = CollectionModes.NORMAL;
|
|
79
112
|
const DISPLAY_OBJECTS_LENGTH_MESUREMENT_ERROR = 1;
|
|
80
113
|
const MAX_SCROLL_TO_ITERATIONS = 5;
|
|
81
114
|
const DEFAULT_SNAPPING_METHOD = SnappingMethods.NORMAL;
|
|
@@ -368,11 +401,11 @@ class NgVirtualListService {
|
|
|
368
401
|
this._trackBox = trackBox;
|
|
369
402
|
}
|
|
370
403
|
itemToFocus;
|
|
371
|
-
focus(element) {
|
|
404
|
+
focus(element, align = FocusAlignments.CENTER) {
|
|
372
405
|
element.focus({ preventScroll: true });
|
|
373
406
|
if (element.parentElement) {
|
|
374
407
|
const pos = parseFloat(element.parentElement?.getAttribute('position') ?? '0');
|
|
375
|
-
this.itemToFocus?.(element, pos);
|
|
408
|
+
this.itemToFocus?.(element, pos, align);
|
|
376
409
|
}
|
|
377
410
|
}
|
|
378
411
|
areaFocus(id) {
|
|
@@ -392,7 +425,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
392
425
|
}]
|
|
393
426
|
}], ctorParameters: function () { return []; } });
|
|
394
427
|
|
|
395
|
-
const ATTR_AREA_SELECTED = 'area-selected', TABINDEX = 'ng-vl-index', KEY_SPACE = " ", KEY_ARR_LEFT = "ArrowLeft", KEY_ARR_UP = "ArrowUp", KEY_ARR_RIGHT = "ArrowRight", KEY_ARR_DOWN = "ArrowDown", EVENT_FOCUS_IN = 'focusin', EVENT_FOCUS_OUT = 'focusout', EVENT_KEY_DOWN = 'keydown';
|
|
428
|
+
const ATTR_AREA_SELECTED = 'area-selected', TABINDEX = 'ng-vl-index', POSITION = 'position', POSITION_ZERO = '0', ID = 'item-id', KEY_SPACE = " ", KEY_ARR_LEFT = "ArrowLeft", KEY_ARR_UP = "ArrowUp", KEY_ARR_RIGHT = "ArrowRight", KEY_ARR_DOWN = "ArrowDown", EVENT_FOCUS_IN = 'focusin', EVENT_FOCUS_OUT = 'focusout', EVENT_KEY_DOWN = 'keydown';
|
|
396
429
|
const getElementByIndex = (index) => {
|
|
397
430
|
return `[${TABINDEX}="${index}"]`;
|
|
398
431
|
};
|
|
@@ -406,7 +439,6 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
|
|
|
406
439
|
_cdr;
|
|
407
440
|
_elementRef;
|
|
408
441
|
_service;
|
|
409
|
-
_$unsubscribe = new Subject();
|
|
410
442
|
_id;
|
|
411
443
|
get id() {
|
|
412
444
|
return this._id;
|
|
@@ -418,12 +450,12 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
|
|
|
418
450
|
_$config = new BehaviorSubject$1({});
|
|
419
451
|
$config = this._$config.asObservable();
|
|
420
452
|
measures = new BehaviorSubject$1(undefined);
|
|
421
|
-
_$
|
|
422
|
-
$
|
|
453
|
+
_$focused = new BehaviorSubject$1(false);
|
|
454
|
+
$focused = this._$focused.asObservable();
|
|
423
455
|
_$part = new BehaviorSubject$1(PART_DEFAULT_ITEM);
|
|
424
456
|
$part = this._$part.asObservable();
|
|
425
457
|
regular = false;
|
|
426
|
-
data
|
|
458
|
+
data;
|
|
427
459
|
_$data = new BehaviorSubject$1(this.data);
|
|
428
460
|
$data = this._$data.asObservable();
|
|
429
461
|
set item(v) {
|
|
@@ -490,28 +522,35 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
|
|
|
490
522
|
}
|
|
491
523
|
this._service.collapse(data, collapsed);
|
|
492
524
|
};
|
|
525
|
+
_focusHandler = () =>
|
|
526
|
+
/**
|
|
527
|
+
* Focus a list item
|
|
528
|
+
*/
|
|
529
|
+
(align = FocusAlignments.CENTER) => {
|
|
530
|
+
this.focus(align);
|
|
531
|
+
};
|
|
493
532
|
constructor(_cdr, _elementRef, _service) {
|
|
494
533
|
super();
|
|
495
534
|
this._cdr = _cdr;
|
|
496
535
|
this._elementRef = _elementRef;
|
|
497
536
|
this._service = _service;
|
|
498
537
|
this._id = this._service.generateComponentId();
|
|
499
|
-
const $data = this.$data, $focus = this.$
|
|
538
|
+
const $data = this.$data, $focus = this.$focused;
|
|
500
539
|
this._elementRef.nativeElement.setAttribute('id', String(this._id));
|
|
501
|
-
$focus.pipe(
|
|
540
|
+
$focus.pipe(takeUntilDestroyed(), tap$1(v => {
|
|
502
541
|
this._service.areaFocus(v ? this._id : this._service.focusedId === this._id ? null : this._service.focusedId);
|
|
503
542
|
})).subscribe();
|
|
504
|
-
fromEvent(this.element, EVENT_FOCUS_IN).pipe(
|
|
505
|
-
this._$
|
|
543
|
+
fromEvent(this.element, EVENT_FOCUS_IN).pipe(takeUntilDestroyed(), tap$1(e => {
|
|
544
|
+
this._$focused.next(true);
|
|
506
545
|
this.updateConfig(this.data);
|
|
507
546
|
this.updatePartStr(this.data, this._isSelected, this._isCollapsed);
|
|
508
547
|
})).subscribe(),
|
|
509
|
-
fromEvent(this.element, EVENT_FOCUS_OUT).pipe(
|
|
510
|
-
this._$
|
|
548
|
+
fromEvent(this.element, EVENT_FOCUS_OUT).pipe(takeUntilDestroyed(), tap$1(e => {
|
|
549
|
+
this._$focused.next(false);
|
|
511
550
|
this.updateConfig(this.data);
|
|
512
551
|
this.updatePartStr(this.data, this._isSelected, this._isCollapsed);
|
|
513
552
|
})).subscribe(),
|
|
514
|
-
fromEvent(this.element, EVENT_KEY_DOWN).pipe(
|
|
553
|
+
fromEvent(this.element, EVENT_KEY_DOWN).pipe(takeUntilDestroyed(), tap$1(e => {
|
|
515
554
|
switch (e.key) {
|
|
516
555
|
case KEY_SPACE: {
|
|
517
556
|
e.stopImmediatePropagation();
|
|
@@ -554,7 +593,7 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
|
|
|
554
593
|
break;
|
|
555
594
|
}
|
|
556
595
|
})).subscribe();
|
|
557
|
-
combineLatest([$data, this._service.$methodOfSelecting, this._service.$selectedIds, this._service.$collapsedIds]).pipe(
|
|
596
|
+
combineLatest([$data, this._service.$methodOfSelecting, this._service.$selectedIds, this._service.$collapsedIds]).pipe(takeUntilDestroyed(), map(([, m, selectedIds, collapsedIds]) => ({ method: m, selectedIds, collapsedIds })), tap$1(({ method, selectedIds, collapsedIds }) => {
|
|
558
597
|
switch (method) {
|
|
559
598
|
case MethodsForSelectingTypes.SELECT: {
|
|
560
599
|
const id = selectedIds, isSelected = id === this.itemId;
|
|
@@ -610,18 +649,29 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
|
|
|
610
649
|
}
|
|
611
650
|
}
|
|
612
651
|
}
|
|
652
|
+
focus(align = FocusAlignments.CENTER) {
|
|
653
|
+
if (this._service.listElement) {
|
|
654
|
+
const tabIndex = this.data?.config?.tabIndex ?? 0;
|
|
655
|
+
let index = tabIndex;
|
|
656
|
+
const el = this._service.listElement.querySelector(getElementByIndex(index));
|
|
657
|
+
if (el) {
|
|
658
|
+
this._service.focus(el, align);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
}
|
|
613
662
|
updateMeasures(v) {
|
|
614
663
|
this.measures.next(v?.measures ? { ...v.measures } : undefined);
|
|
615
664
|
}
|
|
616
665
|
updateConfig(v) {
|
|
617
666
|
this._$config.next({
|
|
618
|
-
...v?.config || {}, selected: this._isSelected, collapsed: this._isCollapsed,
|
|
619
|
-
collapse: this._collapseHandler(v), select: this._selectHandler(v)
|
|
667
|
+
...v?.config || {}, selected: this._isSelected, collapsed: this._isCollapsed, focused: this._$focused.getValue(),
|
|
668
|
+
collapse: this._collapseHandler(v), select: this._selectHandler(v), focus: this._focusHandler(),
|
|
620
669
|
});
|
|
621
670
|
}
|
|
622
671
|
update() {
|
|
623
672
|
const data = this.data, regular = this.regular, length = this._regularLength;
|
|
624
673
|
if (data) {
|
|
674
|
+
this._elementRef.nativeElement.setAttribute(ID, `${data.id}`);
|
|
625
675
|
const styles = this._elementRef.nativeElement.style;
|
|
626
676
|
styles.zIndex = data.config.zIndex;
|
|
627
677
|
if (data.config.snapped) {
|
|
@@ -645,6 +695,9 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
|
|
|
645
695
|
styles.height = data.config.isVertical ? data.config.dynamic ? SIZE_AUTO : `${data.measures.height}${PX}` : regular ? length : SIZE_100_PERSENT;
|
|
646
696
|
styles.width = data.config.isVertical ? regular ? length : SIZE_100_PERSENT : data.config.dynamic ? SIZE_AUTO : `${data.measures.width}${PX}`;
|
|
647
697
|
}
|
|
698
|
+
else {
|
|
699
|
+
this._elementRef.nativeElement.removeAttribute(ID);
|
|
700
|
+
}
|
|
648
701
|
this._cdr.markForCheck();
|
|
649
702
|
}
|
|
650
703
|
updatePartStr(v, isSelected, isCollapsed) {
|
|
@@ -666,7 +719,7 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
|
|
|
666
719
|
if (v ? v.config.new : false) {
|
|
667
720
|
part += PART_ITEM_NEW;
|
|
668
721
|
}
|
|
669
|
-
if (this._$
|
|
722
|
+
if (this._$focused.getValue()) {
|
|
670
723
|
part += PART_ITEM_FOCUSED;
|
|
671
724
|
}
|
|
672
725
|
this._$part.next(part);
|
|
@@ -712,21 +765,15 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
|
|
|
712
765
|
onClickHandler() {
|
|
713
766
|
this._service.itemClick(this.data);
|
|
714
767
|
}
|
|
715
|
-
ngOnDestroy() {
|
|
716
|
-
if (this._$unsubscribe) {
|
|
717
|
-
this._$unsubscribe.next();
|
|
718
|
-
this._$unsubscribe.complete();
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
768
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgVirtualListItemComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: NgVirtualListService }], target: i0.ɵɵFactoryTarget.Component });
|
|
722
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NgVirtualListItemComponent, selector: "ng-virtual-list-item", host: { attributes: { "role": "listitem" }, classAttribute: "ngvl__item" }, usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"data\">\r\n <div #listItem [part]=\"$part | async\" [attr.ng-vl-index]=\"data.config.tabIndex || -1\" tabindex=\"0\" class=\"ngvl-item__container\" [ngClass]=\"{'snapped': data.config.snapped,\r\n 'snapped-out': data.config.snappedOut, 'focus': $
|
|
769
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NgVirtualListItemComponent, selector: "ng-virtual-list-item", host: { attributes: { "role": "listitem" }, classAttribute: "ngvl__item" }, usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"data\">\r\n <div #listItem [part]=\"$part | async\" [attr.ng-vl-index]=\"data.config.tabIndex || -1\" tabindex=\"0\" class=\"ngvl-item__container\" [ngClass]=\"{'snapped': data.config.snapped,\r\n 'snapped-out': data.config.snappedOut, 'focus': $focused | async}\" (click)=\"onClickHandler()\">\r\n <ng-container *ngIf=\"itemRenderer\">\r\n <ng-container [ngTemplateOutlet]=\"itemRenderer\"\r\n [ngTemplateOutletContext]=\"{data: data.data || {}, measures: measures | async, config: $config | async}\"></ng-container>\r\n </ng-container>\r\n </div>\r\n</ng-container>", styles: [":host{display:block;position:absolute;left:0;top:0;box-sizing:border-box;overflow:hidden}.ngvl-item__container{margin:0;padding:0;overflow:hidden;background-color:#fff;width:inherit;height:inherit;box-sizing:border-box}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
723
770
|
}
|
|
724
771
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgVirtualListItemComponent, decorators: [{
|
|
725
772
|
type: Component,
|
|
726
773
|
args: [{ selector: 'ng-virtual-list-item', host: {
|
|
727
774
|
'class': 'ngvl__item',
|
|
728
775
|
'role': 'listitem',
|
|
729
|
-
}, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"data\">\r\n <div #listItem [part]=\"$part | async\" [attr.ng-vl-index]=\"data.config.tabIndex || -1\" tabindex=\"0\" class=\"ngvl-item__container\" [ngClass]=\"{'snapped': data.config.snapped,\r\n 'snapped-out': data.config.snappedOut, 'focus': $
|
|
776
|
+
}, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"data\">\r\n <div #listItem [part]=\"$part | async\" [attr.ng-vl-index]=\"data.config.tabIndex || -1\" tabindex=\"0\" class=\"ngvl-item__container\" [ngClass]=\"{'snapped': data.config.snapped,\r\n 'snapped-out': data.config.snappedOut, 'focus': $focused | async}\" (click)=\"onClickHandler()\">\r\n <ng-container *ngIf=\"itemRenderer\">\r\n <ng-container [ngTemplateOutlet]=\"itemRenderer\"\r\n [ngTemplateOutletContext]=\"{data: data.data || {}, measures: measures | async, config: $config | async}\"></ng-container>\r\n </ng-container>\r\n </div>\r\n</ng-container>", styles: [":host{display:block;position:absolute;left:0;top:0;box-sizing:border-box;overflow:hidden}.ngvl-item__container{margin:0;padding:0;overflow:hidden;background-color:#fff;width:inherit;height:inherit;box-sizing:border-box}\n"] }]
|
|
730
777
|
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: NgVirtualListService }]; } });
|
|
731
778
|
|
|
732
779
|
/**
|
|
@@ -1264,7 +1311,11 @@ const bufferInterpolation = (currentBufferValue, array, value, extra) => {
|
|
|
1264
1311
|
return Math.ceil(buffer / l);
|
|
1265
1312
|
};
|
|
1266
1313
|
|
|
1267
|
-
|
|
1314
|
+
var TrackBoxEvents;
|
|
1315
|
+
(function (TrackBoxEvents) {
|
|
1316
|
+
TrackBoxEvents["CHANGE"] = "change";
|
|
1317
|
+
TrackBoxEvents["RESET"] = "reset";
|
|
1318
|
+
})(TrackBoxEvents || (TrackBoxEvents = {}));
|
|
1268
1319
|
var ItemDisplayMethods;
|
|
1269
1320
|
(function (ItemDisplayMethods) {
|
|
1270
1321
|
ItemDisplayMethods[ItemDisplayMethods["CREATE"] = 0] = "CREATE";
|
|
@@ -1272,7 +1323,7 @@ var ItemDisplayMethods;
|
|
|
1272
1323
|
ItemDisplayMethods[ItemDisplayMethods["DELETE"] = 2] = "DELETE";
|
|
1273
1324
|
ItemDisplayMethods[ItemDisplayMethods["NOT_CHANGED"] = 3] = "NOT_CHANGED";
|
|
1274
1325
|
})(ItemDisplayMethods || (ItemDisplayMethods = {}));
|
|
1275
|
-
const DEFAULT_BUFFER_EXTREMUM_THRESHOLD = 15, DEFAULT_MAX_BUFFER_SEQUENCE_LENGTH = 30, DEFAULT_RESET_BUFFER_SIZE_TIMEOUT = 10000;
|
|
1326
|
+
const DEFAULT_BUFFER_EXTREMUM_THRESHOLD = 15, DEFAULT_MAX_BUFFER_SEQUENCE_LENGTH = 30, DEFAULT_RESET_BUFFER_SIZE_TIMEOUT = 10000, IS_NEW = 'isNew';
|
|
1276
1327
|
/**
|
|
1277
1328
|
* An object that performs tracking, calculations and caching.
|
|
1278
1329
|
* @link https://github.com/DjonnyX/ng-virtual-list/blob/16.x/projects/ng-virtual-list/src/lib/utils/trackBox.ts
|
|
@@ -1309,6 +1360,13 @@ class TrackBox extends CacheMap {
|
|
|
1309
1360
|
}
|
|
1310
1361
|
this._isSnappingMethodAdvanced = v;
|
|
1311
1362
|
}
|
|
1363
|
+
_isLazy = false;
|
|
1364
|
+
set isLazy(v) {
|
|
1365
|
+
if (this._isLazy === v) {
|
|
1366
|
+
return;
|
|
1367
|
+
}
|
|
1368
|
+
this._isLazy = v;
|
|
1369
|
+
}
|
|
1312
1370
|
/**
|
|
1313
1371
|
* Set the trackBy property
|
|
1314
1372
|
*/
|
|
@@ -1341,7 +1399,7 @@ class TrackBox extends CacheMap {
|
|
|
1341
1399
|
get crudDetected() { return this._crudDetected; }
|
|
1342
1400
|
fireChangeIfNeed() {
|
|
1343
1401
|
if (this.changesDetected()) {
|
|
1344
|
-
this.dispatch(
|
|
1402
|
+
this.dispatch(TrackBoxEvents.CHANGE, this._version);
|
|
1345
1403
|
}
|
|
1346
1404
|
}
|
|
1347
1405
|
_previousTotalSize = 0;
|
|
@@ -1357,7 +1415,7 @@ class TrackBox extends CacheMap {
|
|
|
1357
1415
|
_maxBufferSize = this._defaultBufferSize;
|
|
1358
1416
|
_resetBufferSizeTimeout = DEFAULT_RESET_BUFFER_SIZE_TIMEOUT;
|
|
1359
1417
|
_resetBufferSizeTimer;
|
|
1360
|
-
|
|
1418
|
+
isReseted = true;
|
|
1361
1419
|
lifeCircle() {
|
|
1362
1420
|
this.fireChangeIfNeed();
|
|
1363
1421
|
this.lifeCircleDo();
|
|
@@ -1370,11 +1428,19 @@ class TrackBox extends CacheMap {
|
|
|
1370
1428
|
console.warn('Attention! The collection must be immutable.');
|
|
1371
1429
|
return;
|
|
1372
1430
|
}
|
|
1373
|
-
|
|
1374
|
-
|
|
1431
|
+
let reseted = this.isReseted;
|
|
1432
|
+
if (reseted) {
|
|
1433
|
+
if (!(!this._previousCollection || this._previousCollection.length === 0)) {
|
|
1434
|
+
reseted = false;
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
if (!reseted && (!currentCollection || currentCollection.length === 0)) {
|
|
1438
|
+
reseted = true;
|
|
1375
1439
|
}
|
|
1440
|
+
this.isReseted = reseted;
|
|
1441
|
+
this.dispatch(TrackBoxEvents.RESET, reseted);
|
|
1376
1442
|
this.updateCache(this._previousCollection, currentCollection, itemSize);
|
|
1377
|
-
this._previousCollection = currentCollection;
|
|
1443
|
+
this._previousCollection = [...(currentCollection || [])];
|
|
1378
1444
|
}
|
|
1379
1445
|
/**
|
|
1380
1446
|
* Update the cache of items from the list
|
|
@@ -1597,9 +1663,10 @@ class TrackBox extends CacheMap {
|
|
|
1597
1663
|
leftItemsOffset = rightItemsOffset = bufferSize;
|
|
1598
1664
|
}
|
|
1599
1665
|
let itemsFromStartToScrollEnd = -1, itemsFromDisplayEndToOffsetEnd = 0, itemsFromStartToDisplayEnd = -1, leftItemLength = 0, rightItemLength = 0, leftItemsWeight = 0, rightItemsWeight = 0, leftHiddenItemsWeight = 0, totalItemsToDisplayEndWeight = 0, leftSizeOfAddedItems = 0, leftSizeOfUpdatedItems = 0, leftSizeOfDeletedItems = 0, itemById = undefined, itemByIdPos = 0, targetDisplayItemIndex = -1, isTargetInOverscroll = false, actualScrollSize = itemByIdPos, totalSize = 0, startIndex, isFromItemIdFound = false, deltaFromStartCreation = 0;
|
|
1666
|
+
let isNew = !this.isReseted && (scrollSize === 0);
|
|
1600
1667
|
// If the list is dynamic or there are new elements in the collection, then it switches to the long algorithm.
|
|
1601
1668
|
if (dynamicSize) {
|
|
1602
|
-
let y = 0, stickyCollectionItem = undefined, stickyComponentSize = 0
|
|
1669
|
+
let y = 0, stickyCollectionItem = undefined, stickyComponentSize = 0;
|
|
1603
1670
|
for (let i = 0, l = collection.length; i < l; i++) {
|
|
1604
1671
|
const ii = i + 1, collectionItem = collection[i], id = collectionItem.id;
|
|
1605
1672
|
let componentSize = 0, componentSizeDelta = 0, itemDisplayMethod = ItemDisplayMethods.NOT_CHANGED;
|
|
@@ -1607,8 +1674,8 @@ class TrackBox extends CacheMap {
|
|
|
1607
1674
|
const bounds = map.get(id) || { width: typicalItemSize, height: typicalItemSize };
|
|
1608
1675
|
componentSize = bounds[sizeProperty];
|
|
1609
1676
|
itemDisplayMethod = bounds?.method ?? ItemDisplayMethods.UPDATE;
|
|
1610
|
-
const isItemNew = bounds
|
|
1611
|
-
if (
|
|
1677
|
+
const isItemNew = bounds?.[IS_NEW] ?? this._isLazy;
|
|
1678
|
+
if (!isItemNew && (!this._isLazy || !itemConfigMap[collection[0].id]?.sticky)) {
|
|
1612
1679
|
isNew = false;
|
|
1613
1680
|
}
|
|
1614
1681
|
switch (itemDisplayMethod) {
|
|
@@ -1745,8 +1812,15 @@ class TrackBox extends CacheMap {
|
|
|
1745
1812
|
if (map.has(id)) {
|
|
1746
1813
|
const bounds = map.get(id);
|
|
1747
1814
|
itemDisplayMethod = bounds?.method ?? ItemDisplayMethods.UPDATE;
|
|
1815
|
+
const isItemNew = bounds?.[IS_NEW] ?? this._isLazy;
|
|
1816
|
+
if (!isItemNew && (!this._isLazy || !itemConfigMap[collection[0].id]?.sticky)) {
|
|
1817
|
+
isNew = false;
|
|
1818
|
+
}
|
|
1748
1819
|
if (itemDisplayMethod === ItemDisplayMethods.CREATE) {
|
|
1749
|
-
|
|
1820
|
+
if (isNew) {
|
|
1821
|
+
deltaFromStartCreation += componentSize;
|
|
1822
|
+
}
|
|
1823
|
+
map.set(id, { ...bounds, method: ItemDisplayMethods.NOT_CHANGED, isNew });
|
|
1750
1824
|
}
|
|
1751
1825
|
}
|
|
1752
1826
|
if (deletedItemsMap.hasOwnProperty(i)) {
|
|
@@ -1758,7 +1832,9 @@ class TrackBox extends CacheMap {
|
|
|
1758
1832
|
if (y < scrollSize - componentSize) {
|
|
1759
1833
|
switch (itemDisplayMethod) {
|
|
1760
1834
|
case ItemDisplayMethods.CREATE: {
|
|
1761
|
-
|
|
1835
|
+
if (!isNew) {
|
|
1836
|
+
leftSizeOfUpdatedItems += componentSize;
|
|
1837
|
+
}
|
|
1762
1838
|
break;
|
|
1763
1839
|
}
|
|
1764
1840
|
case ItemDisplayMethods.UPDATE: {
|
|
@@ -1854,7 +1930,7 @@ class TrackBox extends CacheMap {
|
|
|
1854
1930
|
height: isVertical ? size : normalizedItemHeight,
|
|
1855
1931
|
delta: 0,
|
|
1856
1932
|
}, config = {
|
|
1857
|
-
new: cache
|
|
1933
|
+
new: cache?.[IS_NEW] === true,
|
|
1858
1934
|
odd: isOdd,
|
|
1859
1935
|
even: !isOdd,
|
|
1860
1936
|
isVertical,
|
|
@@ -1896,7 +1972,7 @@ class TrackBox extends CacheMap {
|
|
|
1896
1972
|
height: h,
|
|
1897
1973
|
delta: 0,
|
|
1898
1974
|
}, config = {
|
|
1899
|
-
new: cache
|
|
1975
|
+
new: cache?.[IS_NEW] === true,
|
|
1900
1976
|
odd: isOdd,
|
|
1901
1977
|
even: !isOdd,
|
|
1902
1978
|
isVertical,
|
|
@@ -1937,7 +2013,7 @@ class TrackBox extends CacheMap {
|
|
|
1937
2013
|
height: isVertical ? size : normalizedItemHeight,
|
|
1938
2014
|
delta: 0,
|
|
1939
2015
|
}, config = {
|
|
1940
|
-
new: cache
|
|
2016
|
+
new: cache?.[IS_NEW] === true,
|
|
1941
2017
|
odd: isOdd,
|
|
1942
2018
|
even: !isOdd,
|
|
1943
2019
|
isVertical,
|
|
@@ -2123,7 +2199,21 @@ const copyValueAsReadonly = (source) => {
|
|
|
2123
2199
|
return source;
|
|
2124
2200
|
};
|
|
2125
2201
|
|
|
2126
|
-
const
|
|
2202
|
+
const NORMAL_ALIASES = [CollectionModes.NORMAL, 'normal'], LAZY_ALIASES = [CollectionModes.LAZY, 'lazy'];
|
|
2203
|
+
/**
|
|
2204
|
+
* Determines the axis membership of a virtual list
|
|
2205
|
+
* @link https://github.com/DjonnyX/ng-virtual-list/blob/16.x/projects/ng-virtual-list/src/lib/utils/isCollectionMode.ts
|
|
2206
|
+
* @author Evgenii Grebennikov
|
|
2207
|
+
* @email djonnyx@gmail.com
|
|
2208
|
+
*/
|
|
2209
|
+
const isCollectionMode = (src, expected) => {
|
|
2210
|
+
if (LAZY_ALIASES.includes(expected)) {
|
|
2211
|
+
return LAZY_ALIASES.includes(src);
|
|
2212
|
+
}
|
|
2213
|
+
return NORMAL_ALIASES.includes(src);
|
|
2214
|
+
};
|
|
2215
|
+
|
|
2216
|
+
const ROLE_LIST = 'list', ROLE_LIST_BOX = 'listbox', ITEM_ID = 'item-id', ITEM_CONTAINER = 'ngvl-item__container';
|
|
2127
2217
|
const validateScrollIteration = (value) => {
|
|
2128
2218
|
return Number.isNaN(value) || (value < 0) ? 0 : value > MAX_SCROLL_TO_ITERATIONS ? MAX_SCROLL_TO_ITERATIONS : value;
|
|
2129
2219
|
}, validateId = (id) => {
|
|
@@ -2142,6 +2232,11 @@ const validateScrollIteration = (value) => {
|
|
|
2142
2232
|
if (!valid) {
|
|
2143
2233
|
throw Error('The "iteration" parameter must be of type `number`.');
|
|
2144
2234
|
}
|
|
2235
|
+
}, validateFocusAlignment = (align) => {
|
|
2236
|
+
const valid = validateString(align) && (align === 'none' || align === 'start' || align === 'center' || align === 'end');
|
|
2237
|
+
if (!valid) {
|
|
2238
|
+
throw Error('The "align" parameter must have the value `none`, `start`, `center` or `end`.');
|
|
2239
|
+
}
|
|
2145
2240
|
};
|
|
2146
2241
|
/**
|
|
2147
2242
|
* Virtual list component.
|
|
@@ -2541,6 +2636,29 @@ class NgVirtualListComponent {
|
|
|
2541
2636
|
}
|
|
2542
2637
|
;
|
|
2543
2638
|
get direction() { return this._$direction.getValue(); }
|
|
2639
|
+
_$collectionMode = new BehaviorSubject$1(DEFAULT_COLLECTION_MODE);
|
|
2640
|
+
$collectionMode = this._$collectionMode.asObservable();
|
|
2641
|
+
_collectionModeTransform = (v) => {
|
|
2642
|
+
const valid = validateString(v) && (v === 'normal' || v === 'lazy');
|
|
2643
|
+
if (!valid) {
|
|
2644
|
+
console.error('The "direction" parameter must have the value `normal` or `lazy`.');
|
|
2645
|
+
return DEFAULT_COLLECTION_MODE;
|
|
2646
|
+
}
|
|
2647
|
+
return v;
|
|
2648
|
+
};
|
|
2649
|
+
/**
|
|
2650
|
+
* Determines the action modes for collection elements. Default value is "normal".
|
|
2651
|
+
*/
|
|
2652
|
+
set collectionMode(v) {
|
|
2653
|
+
if (this._$collectionMode.getValue() === v) {
|
|
2654
|
+
return;
|
|
2655
|
+
}
|
|
2656
|
+
const transformedValue = this._collectionModeTransform(v);
|
|
2657
|
+
this._$collectionMode.next(transformedValue);
|
|
2658
|
+
this._cdr.markForCheck();
|
|
2659
|
+
}
|
|
2660
|
+
;
|
|
2661
|
+
get collectionMode() { return this._$collectionMode.getValue(); }
|
|
2544
2662
|
_$bufferSize = new BehaviorSubject$1(DEFAULT_BUFFER_SIZE);
|
|
2545
2663
|
$bufferSize = this._$bufferSize.asObservable();
|
|
2546
2664
|
_bufferSizeTransform = (v) => {
|
|
@@ -2664,6 +2782,7 @@ class NgVirtualListComponent {
|
|
|
2664
2782
|
;
|
|
2665
2783
|
get trackBy() { return this._$trackBy.getValue(); }
|
|
2666
2784
|
_isVertical = this.getIsVertical();
|
|
2785
|
+
_isLazy = this.getIsLazy();
|
|
2667
2786
|
get orientation() {
|
|
2668
2787
|
return this._isVertical ? Directions.VERTICAL : Directions.HORIZONTAL;
|
|
2669
2788
|
}
|
|
@@ -2739,12 +2858,33 @@ class NgVirtualListComponent {
|
|
|
2739
2858
|
this._$scrollSize.next(scrollSize);
|
|
2740
2859
|
}
|
|
2741
2860
|
};
|
|
2742
|
-
itemToFocus = (element, position) => {
|
|
2861
|
+
itemToFocus = (element, position, align = FocusAlignments.CENTER) => {
|
|
2743
2862
|
const container = this._container?.nativeElement;
|
|
2744
2863
|
if (container) {
|
|
2745
|
-
const { width, height } = this._$bounds.getValue(), { width: elementWidth, height: elementHeight } = element.getBoundingClientRect(), isVertical = this._isVertical
|
|
2746
|
-
|
|
2747
|
-
|
|
2864
|
+
const { width, height } = this._$bounds.getValue(), { width: elementWidth, height: elementHeight } = element.getBoundingClientRect(), isVertical = this._isVertical;
|
|
2865
|
+
let pos = Number.NaN;
|
|
2866
|
+
switch (align) {
|
|
2867
|
+
case FocusAlignments.START: {
|
|
2868
|
+
pos = isVertical ? position : position;
|
|
2869
|
+
break;
|
|
2870
|
+
}
|
|
2871
|
+
case FocusAlignments.CENTER: {
|
|
2872
|
+
pos = isVertical ? position - (height - elementHeight) * .5 : position - (width - elementWidth) * .5;
|
|
2873
|
+
break;
|
|
2874
|
+
}
|
|
2875
|
+
case FocusAlignments.END: {
|
|
2876
|
+
pos = isVertical ? position - (height - elementHeight) : position - (width - elementWidth);
|
|
2877
|
+
break;
|
|
2878
|
+
}
|
|
2879
|
+
case FocusAlignments.NONE:
|
|
2880
|
+
default: {
|
|
2881
|
+
break;
|
|
2882
|
+
}
|
|
2883
|
+
}
|
|
2884
|
+
if (!Number.isNaN(pos)) {
|
|
2885
|
+
const params = { [this._isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: pos, behavior: 'instant' };
|
|
2886
|
+
container.scrollTo(params);
|
|
2887
|
+
}
|
|
2748
2888
|
}
|
|
2749
2889
|
};
|
|
2750
2890
|
_$initialized = new BehaviorSubject$1(false);
|
|
@@ -2768,6 +2908,20 @@ class NgVirtualListComponent {
|
|
|
2768
2908
|
};
|
|
2769
2909
|
_$cacheVersion = new BehaviorSubject$1(-1);
|
|
2770
2910
|
get $cacheVersion() { return this._$cacheVersion.asObservable(); }
|
|
2911
|
+
_isResetedReachStart = true;
|
|
2912
|
+
_onTrackBoxResetHandler = (v) => {
|
|
2913
|
+
if (v) {
|
|
2914
|
+
this._isResetedReachStart = true;
|
|
2915
|
+
const container = this._container?.nativeElement;
|
|
2916
|
+
if (container) {
|
|
2917
|
+
const params = {
|
|
2918
|
+
[this._isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: 0,
|
|
2919
|
+
behavior: BEHAVIOR_INSTANT,
|
|
2920
|
+
};
|
|
2921
|
+
container.scrollTo(params);
|
|
2922
|
+
}
|
|
2923
|
+
}
|
|
2924
|
+
};
|
|
2771
2925
|
constructor(_cdr, _elementRef, _service) {
|
|
2772
2926
|
this._cdr = _cdr;
|
|
2773
2927
|
this._elementRef = _elementRef;
|
|
@@ -2785,12 +2939,13 @@ class NgVirtualListComponent {
|
|
|
2785
2939
|
})).subscribe();
|
|
2786
2940
|
this._trackBox.displayComponents = this._displayComponents;
|
|
2787
2941
|
const $trackBy = this.$trackBy, $selectByClick = this.$selectByClick, $collapseByClick = this.$collapseByClick, $isScrollStart = this._$isScrollStart.asObservable(), $isScrollFinished = this._$isScrollFinished.asObservable();
|
|
2788
|
-
$isScrollStart.pipe(takeUntilDestroyed(), distinctUntilChanged(),
|
|
2789
|
-
if (v) {
|
|
2942
|
+
$isScrollStart.pipe(takeUntilDestroyed(), distinctUntilChanged(), tap(v => {
|
|
2943
|
+
if (v && !this._isResetedReachStart) {
|
|
2790
2944
|
this.onScrollReachStart.emit();
|
|
2791
2945
|
}
|
|
2946
|
+
this._isResetedReachStart = false;
|
|
2792
2947
|
})).subscribe();
|
|
2793
|
-
$isScrollFinished.pipe(takeUntilDestroyed(), distinctUntilChanged(),
|
|
2948
|
+
$isScrollFinished.pipe(takeUntilDestroyed(), distinctUntilChanged(), tap(v => {
|
|
2794
2949
|
if (v) {
|
|
2795
2950
|
this.onScrollReachEnd.emit();
|
|
2796
2951
|
}
|
|
@@ -2804,7 +2959,10 @@ class NgVirtualListComponent {
|
|
|
2804
2959
|
$trackBy.pipe(takeUntilDestroyed(), tap(v => {
|
|
2805
2960
|
this._trackBox.trackingPropertyName = v;
|
|
2806
2961
|
})).subscribe();
|
|
2807
|
-
const $bounds = this._$bounds.asObservable().pipe(filter(b => !!b)), $items = this.$items.pipe(map$1(i => !i ? [] : i)), $scrollSize = this._$scrollSize.asObservable(), $itemSize = this.$itemSize.pipe(map$1(v => v <= 0 ? DEFAULT_ITEM_SIZE : v)), $bufferSize = this.$bufferSize.pipe(map$1(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $maxBufferSize = this.$maxBufferSize.pipe(map$1(v => v < 0 ? DEFAULT_MAX_BUFFER_SIZE : v)), $itemConfigMap = this.$itemConfigMap.pipe(map$1(v => !v ? {} : v)), $snap = this.$snap, $isVertical = this.$direction.pipe(map$1(v => this.getIsVertical(v || DEFAULT_DIRECTION))), $dynamicSize = this.$dynamicSize, $enabledBufferOptimization = this.$enabledBufferOptimization, $snappingMethod = this.$snappingMethod.pipe(map$1(v => this.getIsSnappingMethodAdvanced(v || DEFAULT_SNAPPING_METHOD))), $methodForSelecting = this.$methodForSelecting, $selectedIds = this.$selectedIds, $collapsedIds = this.$collapsedIds.pipe(map$1(v => Array.isArray(v) ? v : [])), $collapsedItemIds = this._$collapsedItemIds.asObservable().pipe(map$1(v => Array.isArray(v) ? v : [])), $actualItems = this._$actualItems.asObservable(), $cacheVersion = this.$cacheVersion;
|
|
2962
|
+
const $bounds = this._$bounds.asObservable().pipe(filter(b => !!b)), $items = this.$items.pipe(map$1(i => !i ? [] : i)), $scrollSize = this._$scrollSize.asObservable(), $itemSize = this.$itemSize.pipe(map$1(v => v <= 0 ? DEFAULT_ITEM_SIZE : v)), $bufferSize = this.$bufferSize.pipe(map$1(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $maxBufferSize = this.$maxBufferSize.pipe(map$1(v => v < 0 ? DEFAULT_MAX_BUFFER_SIZE : v)), $itemConfigMap = this.$itemConfigMap.pipe(map$1(v => !v ? {} : v)), $snap = this.$snap, $isVertical = this.$direction.pipe(map$1(v => this.getIsVertical(v || DEFAULT_DIRECTION))), $isLazy = this.$collectionMode.pipe(map$1(v => this.getIsLazy(v || DEFAULT_COLLECTION_MODE))), $dynamicSize = this.$dynamicSize, $enabledBufferOptimization = this.$enabledBufferOptimization, $snappingMethod = this.$snappingMethod.pipe(map$1(v => this.getIsSnappingMethodAdvanced(v || DEFAULT_SNAPPING_METHOD))), $methodForSelecting = this.$methodForSelecting, $selectedIds = this.$selectedIds, $collapsedIds = this.$collapsedIds.pipe(map$1(v => Array.isArray(v) ? v : [])), $collapsedItemIds = this._$collapsedItemIds.asObservable().pipe(map$1(v => Array.isArray(v) ? v : [])), $actualItems = this._$actualItems.asObservable(), $cacheVersion = this.$cacheVersion;
|
|
2963
|
+
$isLazy.pipe(takeUntilDestroyed(), tap(v => {
|
|
2964
|
+
this._trackBox.isLazy = v;
|
|
2965
|
+
})).subscribe();
|
|
2808
2966
|
combineLatest([$items, $itemSize, this.$initialized]).pipe(takeUntilDestroyed(), distinctUntilChanged(), filter(([, , init]) => !!init), map$1(([items, itemSize]) => ({ items, itemSize })), tap(({ items, itemSize }) => {
|
|
2809
2967
|
this._trackBox.resetCollection(items, itemSize);
|
|
2810
2968
|
})).subscribe();
|
|
@@ -2953,13 +3111,13 @@ class NgVirtualListComponent {
|
|
|
2953
3111
|
}
|
|
2954
3112
|
listenCacheChangesIfNeed(value) {
|
|
2955
3113
|
if (value) {
|
|
2956
|
-
if (!this._trackBox.hasEventListener(
|
|
2957
|
-
this._trackBox.addEventListener(
|
|
3114
|
+
if (!this._trackBox.hasEventListener(TrackBoxEvents.CHANGE, this._onTrackBoxChangeHandler)) {
|
|
3115
|
+
this._trackBox.addEventListener(TrackBoxEvents.CHANGE, this._onTrackBoxChangeHandler);
|
|
2958
3116
|
}
|
|
2959
3117
|
}
|
|
2960
3118
|
else {
|
|
2961
|
-
if (this._trackBox.hasEventListener(
|
|
2962
|
-
this._trackBox.removeEventListener(
|
|
3119
|
+
if (this._trackBox.hasEventListener(TrackBoxEvents.CHANGE, this._onTrackBoxChangeHandler)) {
|
|
3120
|
+
this._trackBox.removeEventListener(TrackBoxEvents.CHANGE, this._onTrackBoxChangeHandler);
|
|
2963
3121
|
}
|
|
2964
3122
|
}
|
|
2965
3123
|
}
|
|
@@ -2983,6 +3141,10 @@ class NgVirtualListComponent {
|
|
|
2983
3141
|
const dir = d || this.direction;
|
|
2984
3142
|
return isDirection(dir, Directions.VERTICAL);
|
|
2985
3143
|
}
|
|
3144
|
+
getIsLazy(m) {
|
|
3145
|
+
const mode = m || this.collectionMode;
|
|
3146
|
+
return isCollectionMode(mode, CollectionModes.LAZY);
|
|
3147
|
+
}
|
|
2986
3148
|
_componentsResizeObserver = new ResizeObserver(() => {
|
|
2987
3149
|
this._trackBox.changes();
|
|
2988
3150
|
});
|
|
@@ -3048,6 +3210,20 @@ class NgVirtualListComponent {
|
|
|
3048
3210
|
validateId(id);
|
|
3049
3211
|
return this._trackBox.getItemBounds(id);
|
|
3050
3212
|
}
|
|
3213
|
+
/**
|
|
3214
|
+
* Focus an list item by a given id.
|
|
3215
|
+
*/
|
|
3216
|
+
focus(id, align = FocusAlignments.NONE) {
|
|
3217
|
+
validateId(id);
|
|
3218
|
+
validateFocusAlignment(align);
|
|
3219
|
+
const el = this._list?.nativeElement.querySelector(`[${ITEM_ID}="${id}"]`);
|
|
3220
|
+
if (el) {
|
|
3221
|
+
const focusedEl = el.querySelector(`.${ITEM_CONTAINER}`);
|
|
3222
|
+
if (focusedEl) {
|
|
3223
|
+
this._service.focus(focusedEl, align);
|
|
3224
|
+
}
|
|
3225
|
+
}
|
|
3226
|
+
}
|
|
3051
3227
|
/**
|
|
3052
3228
|
* The method scrolls the list to the element with the given id and returns the value of the scrolled area.
|
|
3053
3229
|
* Behavior accepts the values "auto", "instant" and "smooth".
|
|
@@ -3209,7 +3385,7 @@ class NgVirtualListComponent {
|
|
|
3209
3385
|
}
|
|
3210
3386
|
}
|
|
3211
3387
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgVirtualListComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: NgVirtualListService }], target: i0.ɵɵFactoryTarget.Component });
|
|
3212
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NgVirtualListComponent, selector: "ng-virtual-list", inputs: { items: "items", selectedIds: "selectedIds", collapsedIds: "collapsedIds", selectByClick: "selectByClick", collapseByClick: "collapseByClick", snap: "snap", enabledBufferOptimization: "enabledBufferOptimization", itemRenderer: "itemRenderer", itemConfigMap: "itemConfigMap", itemSize: "itemSize", dynamicSize: "dynamicSize", direction: "direction", bufferSize: "bufferSize", maxBufferSize: "maxBufferSize", snappingMethod: "snappingMethod", methodForSelecting: "methodForSelecting", trackBy: "trackBy" }, outputs: { onScroll: "onScroll", onScrollEnd: "onScrollEnd", onViewportChange: "onViewportChange", onItemClick: "onItemClick", onSelect: "onSelect", onCollapse: "onCollapse", onScrollReachStart: "onScrollReachStart", onScrollReachEnd: "onScrollReachEnd" }, host: { styleAttribute: "position: relative;" }, providers: [NgVirtualListService], viewQueries: [{ propertyName: "_listContainerRef", first: true, predicate: ["renderersContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_container", first: true, predicate: ["container"], descendants: true, read: (ElementRef) }, { propertyName: "_list", first: true, predicate: ["list"], descendants: true, read: (ElementRef) }, { propertyName: "_snapContainerRef", first: true, predicate: ["snapRendererContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_snappedContainer", first: true, predicate: ["snapped"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<div *ngIf=\"snap\" #snapped part=\"snapped-item\" class=\"ngvl__list-snapper\">\r\n <ng-container #snapRendererContainer></ng-container>\r\n</div>\r\n<div #container part=\"scroller\" class=\"ngvl__scroller\">\r\n <div [attr.aria-orientation]=\"orientation\" [attr.aria-activedescendant]=\"$focusedElement | async\" #list part=\"list\"\r\n class=\"ngvl__list\">\r\n <ng-container #renderersContainer></ng-container>\r\n </div>\r\n</div>", styles: [":host{position:relative;display:block;width:400px;overflow:hidden}:host(.horizontal){height:48px}:host(.horizontal) .ngvl__list{display:inline-flex}:host(.horizontal) .ngvl__scroller{overflow:auto hidden}:host(.vertical) .ngvl__scroller{overflow:hidden auto}:host(.vertical){height:320px}.ngvl__scroller{overflow:auto;width:100%;height:100%}.ngvl__list-snapper{pointer-events:none;position:absolute;list-style:none;left:0;top:0;z-index:1}.ngvl__list{position:relative;list-style:none;padding:0;margin:0;width:100%;height:100%}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
3388
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NgVirtualListComponent, selector: "ng-virtual-list", inputs: { items: "items", selectedIds: "selectedIds", collapsedIds: "collapsedIds", selectByClick: "selectByClick", collapseByClick: "collapseByClick", snap: "snap", enabledBufferOptimization: "enabledBufferOptimization", itemRenderer: "itemRenderer", itemConfigMap: "itemConfigMap", itemSize: "itemSize", dynamicSize: "dynamicSize", direction: "direction", collectionMode: "collectionMode", bufferSize: "bufferSize", maxBufferSize: "maxBufferSize", snappingMethod: "snappingMethod", methodForSelecting: "methodForSelecting", trackBy: "trackBy" }, outputs: { onScroll: "onScroll", onScrollEnd: "onScrollEnd", onViewportChange: "onViewportChange", onItemClick: "onItemClick", onSelect: "onSelect", onCollapse: "onCollapse", onScrollReachStart: "onScrollReachStart", onScrollReachEnd: "onScrollReachEnd" }, host: { styleAttribute: "position: relative;" }, providers: [NgVirtualListService], viewQueries: [{ propertyName: "_listContainerRef", first: true, predicate: ["renderersContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_container", first: true, predicate: ["container"], descendants: true, read: (ElementRef) }, { propertyName: "_list", first: true, predicate: ["list"], descendants: true, read: (ElementRef) }, { propertyName: "_snapContainerRef", first: true, predicate: ["snapRendererContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_snappedContainer", first: true, predicate: ["snapped"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<div *ngIf=\"snap\" #snapped part=\"snapped-item\" class=\"ngvl__list-snapper\">\r\n <ng-container #snapRendererContainer></ng-container>\r\n</div>\r\n<div #container part=\"scroller\" class=\"ngvl__scroller\">\r\n <div [attr.aria-orientation]=\"orientation\" [attr.aria-activedescendant]=\"$focusedElement | async\" #list part=\"list\"\r\n class=\"ngvl__list\">\r\n <ng-container #renderersContainer></ng-container>\r\n </div>\r\n</div>", styles: [":host{position:relative;display:block;width:400px;overflow:hidden}:host(.horizontal){height:48px}:host(.horizontal) .ngvl__list{display:inline-flex}:host(.horizontal) .ngvl__scroller{overflow:auto hidden}:host(.vertical) .ngvl__scroller{overflow:hidden auto}:host(.vertical){height:320px}.ngvl__scroller{overflow:auto;width:100%;height:100%}.ngvl__list-snapper{pointer-events:none;position:absolute;list-style:none;left:0;top:0;z-index:1}.ngvl__list{position:relative;list-style:none;padding:0;margin:0;width:100%;height:100%}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
3213
3389
|
}
|
|
3214
3390
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgVirtualListComponent, decorators: [{
|
|
3215
3391
|
type: Component,
|
|
@@ -3271,6 +3447,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
3271
3447
|
type: Input
|
|
3272
3448
|
}], direction: [{
|
|
3273
3449
|
type: Input
|
|
3450
|
+
}], collectionMode: [{
|
|
3451
|
+
type: Input
|
|
3274
3452
|
}], bufferSize: [{
|
|
3275
3453
|
type: Input
|
|
3276
3454
|
}], maxBufferSize: [{
|
|
@@ -3306,5 +3484,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
3306
3484
|
* Generated bundle index. Do not edit.
|
|
3307
3485
|
*/
|
|
3308
3486
|
|
|
3309
|
-
export { Directions, MethodsForSelecting, NgVirtualListComponent, NgVirtualListItemComponent, NgVirtualListModule, ScrollEvent, SnappingMethods, debounce, toggleClassName };
|
|
3487
|
+
export { CollectionModes, Directions, FocusAlignments, MethodsForSelecting, NgVirtualListComponent, NgVirtualListItemComponent, NgVirtualListModule, ScrollEvent, SnappingMethods, debounce, toggleClassName };
|
|
3310
3488
|
//# sourceMappingURL=ng-virtual-list.mjs.map
|