ng-virtual-list 20.7.9 → 20.7.10
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 +7 -7
- package/fesm2022/ng-virtual-list.mjs +84 -24
- package/fesm2022/ng-virtual-list.mjs.map +1 -1
- package/index.d.ts +10 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -599,7 +599,7 @@ Inputs
|
|
|
599
599
|
| items | [IVirtualListCollection](https://github.com/DjonnyX/ng-virtual-list/blob/20.x/projects/ng-virtual-list/src/lib/models/collection.model.ts) | Collection of list items. The collection of elements must be immutable. |
|
|
600
600
|
| itemSize | number? = 24 | If direction = 'vertical', then the height of a typical element. If direction = 'horizontal', then the width of a typical element. Ignored if the dynamicSize property is true. |
|
|
601
601
|
| bufferSize | number? = 2 | Number of elements outside the scope of visibility. Default value is 2. |
|
|
602
|
-
| maxBufferSize | number? =
|
|
602
|
+
| maxBufferSize | number? = 10 | Maximum number of elements outside the scope of visibility. Default value is 10. If maxBufferSize is set to be greater than bufferSize, then adaptive buffer mode is enabled. The greater the scroll size, the more elements are allocated for rendering. |
|
|
603
603
|
| itemRenderer | TemplateRef | Rendering element template. |
|
|
604
604
|
| methodForSelecting | [MethodForSelecting](https://github.com/DjonnyX/ng-virtual-list/blob/20.x/projects/ng-virtual-list/src/lib/enums/method-for-selecting.ts) | Method for selecting list items. Default value is 'none'. 'select' - List items are selected one by one. 'multi-select' - Multiple selection of list items. 'none' - List items are not selectable. |
|
|
605
605
|
| itemConfigMap | [IVirtualListItemConfigMap?](https://github.com/DjonnyX/ng-virtual-list/blob/20.x/projects/ng-virtual-list/src/lib/models/item-config-map.model.ts) | Sets `sticky` position and `selectable` for the list item element. If `sticky` position is greater than `0`, then `sticky` position is applied. If the `sticky` value is greater than `0`, then the `sticky` position mode is enabled for the element. `1` - position start, `2` - position end. Default value is `0`. `selectable` determines whether an element can be selected or not. Default value is `true`. |
|
|
@@ -644,12 +644,12 @@ Methods
|
|
|
644
644
|
|
|
645
645
|
| Angular version | ng-virtual-list version | git | npm |
|
|
646
646
|
|--|--|--|--|
|
|
647
|
-
| 19.x | 19.7.
|
|
648
|
-
| 18.x | 18.7.
|
|
649
|
-
| 17.x | 17.7.
|
|
650
|
-
| 16.x | 16.7.
|
|
651
|
-
| 15.x | 15.7.
|
|
652
|
-
| 14.x | 14.7.
|
|
647
|
+
| 19.x | 19.7.14 | [19.x](https://github.com/DjonnyX/ng-virtual-list/tree/19.x) | [19.7.14](https://www.npmjs.com/package/ng-virtual-list/v/19.7.14) |
|
|
648
|
+
| 18.x | 18.7.10 | [18.x](https://github.com/DjonnyX/ng-virtual-list/tree/18.x) | [18.7.10](https://www.npmjs.com/package/ng-virtual-list/v/18.7.10) |
|
|
649
|
+
| 17.x | 17.7.11 | [17.x](https://github.com/DjonnyX/ng-virtual-list/tree/17.x) | [17.7.11](https://www.npmjs.com/package/ng-virtual-list/v/17.7.11) |
|
|
650
|
+
| 16.x | 16.7.9 | [16.x](https://github.com/DjonnyX/ng-virtual-list/tree/16.x) | [16.7.9](https://www.npmjs.com/package/ng-virtual-list/v/16.7.9) |
|
|
651
|
+
| 15.x | 15.7.9 | [15.x](https://github.com/DjonnyX/ng-virtual-list/tree/15.x) | [15.7.9](https://www.npmjs.com/package/ng-virtual-list/v/15.7.9) |
|
|
652
|
+
| 14.x | 14.7.9 | [14.x](https://github.com/DjonnyX/ng-virtual-list/tree/14.x) | [14.7.9](https://www.npmjs.com/package/ng-virtual-list/v/14.7.9) |
|
|
653
653
|
|
|
654
654
|
<br/>
|
|
655
655
|
|
|
@@ -66,7 +66,7 @@ var SnappingMethods;
|
|
|
66
66
|
|
|
67
67
|
const DEFAULT_ITEM_SIZE = 24;
|
|
68
68
|
const DEFAULT_BUFFER_SIZE = 2;
|
|
69
|
-
const DEFAULT_MAX_BUFFER_SIZE =
|
|
69
|
+
const DEFAULT_MAX_BUFFER_SIZE = 10;
|
|
70
70
|
const DEFAULT_LIST_SIZE = 400;
|
|
71
71
|
const DEFAULT_SNAP = false;
|
|
72
72
|
const DEFAULT_SELECT_BY_CLICK = true;
|
|
@@ -161,10 +161,14 @@ class NgVirtualListService {
|
|
|
161
161
|
set methodOfSelecting(v) {
|
|
162
162
|
this._$methodOfSelecting.next(v);
|
|
163
163
|
}
|
|
164
|
+
_$focusedId = new BehaviorSubject(null);
|
|
165
|
+
$focusedId = this._$focusedId.asObservable();
|
|
166
|
+
get focusedId() { return this._$focusedId.getValue(); }
|
|
164
167
|
selectByClick = DEFAULT_SELECT_BY_CLICK;
|
|
165
168
|
collapseByClick = DEFAULT_COLLAPSE_BY_CLICK;
|
|
166
169
|
_trackBox;
|
|
167
170
|
listElement = null;
|
|
171
|
+
collection = [];
|
|
168
172
|
constructor() {
|
|
169
173
|
this._$methodOfSelecting.pipe(takeUntilDestroyed(), tap(v => {
|
|
170
174
|
switch (v) {
|
|
@@ -208,6 +212,9 @@ class NgVirtualListService {
|
|
|
208
212
|
this.select(data);
|
|
209
213
|
}
|
|
210
214
|
}
|
|
215
|
+
update() {
|
|
216
|
+
this._trackBox?.changes();
|
|
217
|
+
}
|
|
211
218
|
/**
|
|
212
219
|
* Selects a list item
|
|
213
220
|
* @param data
|
|
@@ -299,6 +306,17 @@ class NgVirtualListService {
|
|
|
299
306
|
}
|
|
300
307
|
}
|
|
301
308
|
}
|
|
309
|
+
itemToFocus;
|
|
310
|
+
focus(element) {
|
|
311
|
+
element.focus({ preventScroll: true });
|
|
312
|
+
if (element.parentElement) {
|
|
313
|
+
const pos = parseFloat(element.parentElement?.getAttribute('position') ?? '0');
|
|
314
|
+
this.itemToFocus?.(element, pos);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
areaFocus(id) {
|
|
318
|
+
this._$focusedId.next(id);
|
|
319
|
+
}
|
|
302
320
|
initialize(trackBox) {
|
|
303
321
|
this._trackBox = trackBox;
|
|
304
322
|
}
|
|
@@ -316,7 +334,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
|
|
|
316
334
|
}]
|
|
317
335
|
}], ctorParameters: () => [] });
|
|
318
336
|
|
|
319
|
-
const ATTR_AREA_SELECTED = 'area-selected', TABINDEX = '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';
|
|
337
|
+
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';
|
|
338
|
+
const getElementByIndex = (index) => {
|
|
339
|
+
return `[${TABINDEX}="${index}"]`;
|
|
340
|
+
};
|
|
320
341
|
/**
|
|
321
342
|
* Virtual list item component
|
|
322
343
|
* @link https://github.com/DjonnyX/ng-virtual-list/blob/20.x/projects/ng-virtual-list/src/lib/components/ng-virtual-list-item.component.ts
|
|
@@ -390,7 +411,11 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
|
|
|
390
411
|
constructor() {
|
|
391
412
|
super();
|
|
392
413
|
this._id = this._service.generateComponentId();
|
|
393
|
-
|
|
414
|
+
this._elementRef.nativeElement.setAttribute('id', String(this._id));
|
|
415
|
+
const $data = toObservable(this.data), $focus = toObservable(this.focus);
|
|
416
|
+
$focus.pipe(takeUntilDestroyed(), tap(v => {
|
|
417
|
+
this._service.areaFocus(v ? this._id : this._service.focusedId === this._id ? null : this._service.focusedId);
|
|
418
|
+
})).subscribe();
|
|
394
419
|
fromEvent(this.element, EVENT_FOCUS_IN).pipe(takeUntilDestroyed(), tap(e => {
|
|
395
420
|
this.focus.set(true);
|
|
396
421
|
this.updateConfig(this._data);
|
|
@@ -473,20 +498,30 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
|
|
|
473
498
|
})).subscribe();
|
|
474
499
|
}
|
|
475
500
|
focusNext() {
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
501
|
+
if (this._service.listElement) {
|
|
502
|
+
const tabIndex = this._data?.config?.tabIndex ?? 0, length = this._service.collection?.length ?? 0;
|
|
503
|
+
let index = tabIndex;
|
|
504
|
+
while (index <= length) {
|
|
505
|
+
index++;
|
|
506
|
+
const el = this._service.listElement.querySelector(getElementByIndex(index));
|
|
507
|
+
if (el) {
|
|
508
|
+
this._service.focus(el);
|
|
509
|
+
break;
|
|
510
|
+
}
|
|
481
511
|
}
|
|
482
512
|
}
|
|
483
513
|
}
|
|
484
514
|
focusPrev() {
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
515
|
+
if (this._service.listElement) {
|
|
516
|
+
const tabIndex = this._data?.config?.tabIndex ?? 0;
|
|
517
|
+
let index = tabIndex;
|
|
518
|
+
while (index >= 0) {
|
|
519
|
+
index--;
|
|
520
|
+
const el = this._service.listElement.querySelector(getElementByIndex(index));
|
|
521
|
+
if (el) {
|
|
522
|
+
this._service.focus(el);
|
|
523
|
+
break;
|
|
524
|
+
}
|
|
490
525
|
}
|
|
491
526
|
}
|
|
492
527
|
}
|
|
@@ -505,6 +540,7 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
|
|
|
505
540
|
const styles = this._elementRef.nativeElement.style;
|
|
506
541
|
styles.zIndex = data.config.zIndex;
|
|
507
542
|
if (data.config.snapped) {
|
|
543
|
+
this._elementRef.nativeElement.setAttribute('position', data.config.sticky === 1 ? '0' : `${data.config.isVertical ? data.measures.y : data.measures.x}`);
|
|
508
544
|
styles.transform = data.config.sticky === 1 ? ZEROS_TRANSLATE_3D : `${TRANSLATE_3D}(${data.config.isVertical ? 0 : data.measures.x}${PX}, ${data.config.isVertical ? data.measures.y : 0}${PX} , 0)`;
|
|
509
545
|
;
|
|
510
546
|
if (!data.config.isSnappingMethodAdvanced) {
|
|
@@ -514,9 +550,11 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
|
|
|
514
550
|
else {
|
|
515
551
|
styles.position = POSITION_ABSOLUTE;
|
|
516
552
|
if (regular) {
|
|
553
|
+
this._elementRef.nativeElement.setAttribute('position', '0');
|
|
517
554
|
styles.transform = `${TRANSLATE_3D}(${data.config.isVertical ? 0 : data.measures.delta}${PX}, ${data.config.isVertical ? data.measures.delta : 0}${PX} , 0)`;
|
|
518
555
|
}
|
|
519
556
|
else {
|
|
557
|
+
this._elementRef.nativeElement.setAttribute('position', `${data.config.isVertical ? data.measures.y : data.measures.x}`);
|
|
520
558
|
styles.transform = `${TRANSLATE_3D}(${data.config.isVertical ? 0 : data.measures.x}${PX}, ${data.config.isVertical ? data.measures.y : 0}${PX} , 0)`;
|
|
521
559
|
}
|
|
522
560
|
}
|
|
@@ -587,14 +625,14 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
|
|
|
587
625
|
this._service.itemClick(this._data);
|
|
588
626
|
}
|
|
589
627
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: NgVirtualListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
590
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: NgVirtualListItemComponent, isStandalone: true, selector: "ng-virtual-list-item", host: { attributes: { "role": "listitem" }, classAttribute: "ngvl__item" }, usesInheritance: true, ngImport: i0, template: "@let item = data();\r\n@let _config = config();\r\n@let _part = part();\r\n@let _measures = measures();\r\n@let renderer = itemRenderer();\r\n\r\n@if (item) {\r\n <div #listItem [part]=\"_part\" [attr.index]=\"
|
|
628
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: NgVirtualListItemComponent, isStandalone: true, selector: "ng-virtual-list-item", host: { attributes: { "role": "listitem" }, classAttribute: "ngvl__item" }, usesInheritance: true, ngImport: i0, template: "@let item = data();\r\n@let _config = config();\r\n@let _part = part();\r\n@let _measures = measures();\r\n@let renderer = itemRenderer();\r\n\r\n@if (item) {\r\n <div #listItem [part]=\"_part\" [attr.ng-vl-index]=\"_config.tabIndex || -1\" tabindex=\"0\" class=\"ngvl-item__container\"\r\n [ngClass]=\"{'snapped': item.config.snapped, 'snapped-out': item.config.snappedOut, 'focus': focus()}\" (click)=\"onClickHandler()\">\r\n @if (renderer) {\r\n <ng-container [ngTemplateOutlet]=\"renderer\"\r\n [ngTemplateOutletContext]=\"{data: item.data, measures: _measures, config: _config}\" />\r\n }\r\n </div>\r\n}", 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: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
591
629
|
}
|
|
592
630
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: NgVirtualListItemComponent, decorators: [{
|
|
593
631
|
type: Component,
|
|
594
632
|
args: [{ selector: 'ng-virtual-list-item', imports: [CommonModule], host: {
|
|
595
633
|
'class': 'ngvl__item',
|
|
596
634
|
'role': 'listitem',
|
|
597
|
-
}, changeDetection: ChangeDetectionStrategy.OnPush, template: "@let item = data();\r\n@let _config = config();\r\n@let _part = part();\r\n@let _measures = measures();\r\n@let renderer = itemRenderer();\r\n\r\n@if (item) {\r\n <div #listItem [part]=\"_part\" [attr.index]=\"
|
|
635
|
+
}, changeDetection: ChangeDetectionStrategy.OnPush, template: "@let item = data();\r\n@let _config = config();\r\n@let _part = part();\r\n@let _measures = measures();\r\n@let renderer = itemRenderer();\r\n\r\n@if (item) {\r\n <div #listItem [part]=\"_part\" [attr.ng-vl-index]=\"_config.tabIndex || -1\" tabindex=\"0\" class=\"ngvl-item__container\"\r\n [ngClass]=\"{'snapped': item.config.snapped, 'snapped-out': item.config.snappedOut, 'focus': focus()}\" (click)=\"onClickHandler()\">\r\n @if (renderer) {\r\n <ng-container [ngTemplateOutlet]=\"renderer\"\r\n [ngTemplateOutletContext]=\"{data: item.data, measures: _measures, config: _config}\" />\r\n }\r\n </div>\r\n}", 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"] }]
|
|
598
636
|
}], ctorParameters: () => [] });
|
|
599
637
|
|
|
600
638
|
/**
|
|
@@ -1017,22 +1055,26 @@ class Tracker {
|
|
|
1017
1055
|
snapedComponent.instance.show();
|
|
1018
1056
|
}
|
|
1019
1057
|
}
|
|
1020
|
-
comp.instance.item = item;
|
|
1021
1058
|
if (snapedComponent) {
|
|
1022
1059
|
if (item['config']['snapped'] || item['config']['snappedOut']) {
|
|
1060
|
+
comp.instance.item = null;
|
|
1023
1061
|
comp.instance.hide();
|
|
1024
1062
|
}
|
|
1025
1063
|
else {
|
|
1064
|
+
comp.instance.item = item;
|
|
1026
1065
|
comp.instance.show();
|
|
1027
1066
|
}
|
|
1028
1067
|
}
|
|
1029
1068
|
else {
|
|
1069
|
+
comp.instance.item = item;
|
|
1030
1070
|
comp.instance.show();
|
|
1031
1071
|
}
|
|
1032
1072
|
untrackedItems.splice(indexByUntrackedItems, 1);
|
|
1033
1073
|
continue;
|
|
1034
1074
|
}
|
|
1035
1075
|
}
|
|
1076
|
+
}
|
|
1077
|
+
else {
|
|
1036
1078
|
this._trackMap.delete(itemTrackingProperty);
|
|
1037
1079
|
}
|
|
1038
1080
|
}
|
|
@@ -1041,9 +1083,8 @@ class Tracker {
|
|
|
1041
1083
|
}
|
|
1042
1084
|
}
|
|
1043
1085
|
for (let i = 0, l = newTrackItems.length; i < l; i++) {
|
|
1044
|
-
const item = newTrackItems[i], itemTrackingProperty = item[idPropName];
|
|
1045
1086
|
if (untrackedItems.length > 0) {
|
|
1046
|
-
const comp = untrackedItems.shift(), item =
|
|
1087
|
+
const comp = untrackedItems.shift(), item = newTrackItems[i], itemTrackingProperty = item[idPropName];
|
|
1047
1088
|
if (comp) {
|
|
1048
1089
|
if (snapedComponent) {
|
|
1049
1090
|
if (item['config']['snapped'] || item['config']['snappedOut']) {
|
|
@@ -1052,16 +1093,18 @@ class Tracker {
|
|
|
1052
1093
|
snapedComponent.instance.show();
|
|
1053
1094
|
}
|
|
1054
1095
|
}
|
|
1055
|
-
comp.instance.item = item;
|
|
1056
1096
|
if (snapedComponent) {
|
|
1057
1097
|
if (item['config']['snapped'] || item['config']['snappedOut']) {
|
|
1098
|
+
comp.instance.item = null;
|
|
1058
1099
|
comp.instance.hide();
|
|
1059
1100
|
}
|
|
1060
1101
|
else {
|
|
1102
|
+
comp.instance.item = item;
|
|
1061
1103
|
comp.instance.show();
|
|
1062
1104
|
}
|
|
1063
1105
|
}
|
|
1064
1106
|
else {
|
|
1107
|
+
comp.instance.item = item;
|
|
1065
1108
|
comp.instance.show();
|
|
1066
1109
|
}
|
|
1067
1110
|
if (this._trackMap) {
|
|
@@ -1073,6 +1116,7 @@ class Tracker {
|
|
|
1073
1116
|
if (untrackedItems.length) {
|
|
1074
1117
|
for (let i = 0, l = untrackedItems.length; i < l; i++) {
|
|
1075
1118
|
const comp = untrackedItems[i];
|
|
1119
|
+
comp.instance.item = null;
|
|
1076
1120
|
comp.instance.hide();
|
|
1077
1121
|
}
|
|
1078
1122
|
}
|
|
@@ -1757,7 +1801,7 @@ class TrackBox extends CacheMap {
|
|
|
1757
1801
|
snappedOut: false,
|
|
1758
1802
|
dynamic: dynamicSize,
|
|
1759
1803
|
isSnappingMethodAdvanced,
|
|
1760
|
-
tabIndex:
|
|
1804
|
+
tabIndex: items.length,
|
|
1761
1805
|
zIndex: '1',
|
|
1762
1806
|
};
|
|
1763
1807
|
const itemData = items[i];
|
|
@@ -1765,7 +1809,6 @@ class TrackBox extends CacheMap {
|
|
|
1765
1809
|
endStickyItemIndex = i;
|
|
1766
1810
|
endStickyItemSize = size;
|
|
1767
1811
|
displayItems.push(endStickyItem);
|
|
1768
|
-
count++;
|
|
1769
1812
|
break;
|
|
1770
1813
|
}
|
|
1771
1814
|
}
|
|
@@ -1801,6 +1844,7 @@ class TrackBox extends CacheMap {
|
|
|
1801
1844
|
tabIndex: count,
|
|
1802
1845
|
zIndex: '0',
|
|
1803
1846
|
};
|
|
1847
|
+
count++;
|
|
1804
1848
|
if (snapped) {
|
|
1805
1849
|
config.zIndex = '2';
|
|
1806
1850
|
}
|
|
@@ -1823,7 +1867,6 @@ class TrackBox extends CacheMap {
|
|
|
1823
1867
|
nextEndSticky.measures.delta = isVertical ? (item.measures.y - scrollSize) : (item.measures.x - scrollSize);
|
|
1824
1868
|
}
|
|
1825
1869
|
displayItems.push(item);
|
|
1826
|
-
count++;
|
|
1827
1870
|
}
|
|
1828
1871
|
renderItems -= 1;
|
|
1829
1872
|
pos += size;
|
|
@@ -2116,6 +2159,7 @@ class NgVirtualListComponent {
|
|
|
2116
2159
|
get orientation() {
|
|
2117
2160
|
return this._isVertical ? Directions.VERTICAL : Directions.HORIZONTAL;
|
|
2118
2161
|
}
|
|
2162
|
+
focusedElement = signal(undefined);
|
|
2119
2163
|
_actualItems = signal([]);
|
|
2120
2164
|
_collapsedItemIds = signal([]);
|
|
2121
2165
|
_displayComponents = [];
|
|
@@ -2178,6 +2222,14 @@ class NgVirtualListComponent {
|
|
|
2178
2222
|
this._scrollSize.set(actualScrollSize);
|
|
2179
2223
|
}
|
|
2180
2224
|
};
|
|
2225
|
+
itemToFocus = (element, position) => {
|
|
2226
|
+
const container = this._container()?.nativeElement;
|
|
2227
|
+
if (container) {
|
|
2228
|
+
const { width, height } = this._bounds(), { width: elementWidth, height: elementHeight } = element.getBoundingClientRect(), isVertical = this._isVertical, pos = isVertical ? position - (height - elementHeight) * .5 : position - (width - elementWidth) * .5;
|
|
2229
|
+
const params = { [this._isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: pos, behavior: 'instant' };
|
|
2230
|
+
container.scrollTo(params);
|
|
2231
|
+
}
|
|
2232
|
+
};
|
|
2181
2233
|
_elementRef = inject((ElementRef));
|
|
2182
2234
|
_initialized;
|
|
2183
2235
|
$initialized;
|
|
@@ -2206,9 +2258,13 @@ class NgVirtualListComponent {
|
|
|
2206
2258
|
? 0 : NgVirtualListComponent.__nextId + 1;
|
|
2207
2259
|
this._id = NgVirtualListComponent.__nextId;
|
|
2208
2260
|
this._service.initialize(this._trackBox);
|
|
2261
|
+
this._service.itemToFocus = this.itemToFocus;
|
|
2209
2262
|
this._initialized = signal(false);
|
|
2210
2263
|
this.$initialized = toObservable(this._initialized);
|
|
2211
2264
|
this._trackBox.displayComponents = this._displayComponents;
|
|
2265
|
+
this._service.$focusedId.pipe(takeUntilDestroyed(), tap(v => {
|
|
2266
|
+
this.focusedElement.set(v ?? undefined);
|
|
2267
|
+
})).subscribe();
|
|
2212
2268
|
toObservable(this._list).pipe(takeUntilDestroyed(), filter(v => !!v), tap(v => {
|
|
2213
2269
|
this._service.listElement = v.nativeElement;
|
|
2214
2270
|
})).subscribe();
|
|
@@ -2296,6 +2352,7 @@ class NgVirtualListComponent {
|
|
|
2296
2352
|
bounds: { width, height }, dynamicSize, isVertical, itemSize,
|
|
2297
2353
|
bufferSize, maxBufferSize, scrollSize: actualScrollSize, snap, enabledBufferOptimization,
|
|
2298
2354
|
}, { displayItems, totalSize } = this._trackBox.updateCollection(items, itemConfigMap, opts);
|
|
2355
|
+
this._service.collection = displayItems;
|
|
2299
2356
|
this.resetBoundsSize(isVertical, totalSize);
|
|
2300
2357
|
this.createDisplayComponentsIfNeed(displayItems);
|
|
2301
2358
|
this.tracking();
|
|
@@ -2499,6 +2556,7 @@ class NgVirtualListComponent {
|
|
|
2499
2556
|
const { displayItems, totalSize } = this._trackBox.updateCollection(items, itemConfigMap, {
|
|
2500
2557
|
...opts, scrollSize, fromItemId: isLastIteration ? undefined : id,
|
|
2501
2558
|
}), delta = this._trackBox.delta;
|
|
2559
|
+
this._service.collection = displayItems;
|
|
2502
2560
|
this._trackBox.clearDelta();
|
|
2503
2561
|
let actualScrollSize = scrollSize + delta;
|
|
2504
2562
|
this.resetBoundsSize(isVertical, totalSize);
|
|
@@ -2616,11 +2674,13 @@ class NgVirtualListComponent {
|
|
|
2616
2674
|
}
|
|
2617
2675
|
}
|
|
2618
2676
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: NgVirtualListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2619
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: NgVirtualListComponent, isStandalone: true, selector: "ng-virtual-list", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, selectedIds: { classPropertyName: "selectedIds", publicName: "selectedIds", isSignal: true, isRequired: false, transformFunction: null }, collapsedIds: { classPropertyName: "collapsedIds", publicName: "collapsedIds", isSignal: true, isRequired: false, transformFunction: null }, selectByClick: { classPropertyName: "selectByClick", publicName: "selectByClick", isSignal: true, isRequired: false, transformFunction: null }, collapseByClick: { classPropertyName: "collapseByClick", publicName: "collapseByClick", isSignal: true, isRequired: false, transformFunction: null }, snap: { classPropertyName: "snap", publicName: "snap", isSignal: true, isRequired: false, transformFunction: null }, enabledBufferOptimization: { classPropertyName: "enabledBufferOptimization", publicName: "enabledBufferOptimization", isSignal: true, isRequired: false, transformFunction: null }, itemRenderer: { classPropertyName: "itemRenderer", publicName: "itemRenderer", isSignal: true, isRequired: true, transformFunction: null }, itemConfigMap: { classPropertyName: "itemConfigMap", publicName: "itemConfigMap", isSignal: true, isRequired: false, transformFunction: null }, itemSize: { classPropertyName: "itemSize", publicName: "itemSize", isSignal: true, isRequired: false, transformFunction: null }, dynamicSize: { classPropertyName: "dynamicSize", publicName: "dynamicSize", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, bufferSize: { classPropertyName: "bufferSize", publicName: "bufferSize", isSignal: true, isRequired: false, transformFunction: null }, maxBufferSize: { classPropertyName: "maxBufferSize", publicName: "maxBufferSize", isSignal: true, isRequired: false, transformFunction: null }, snappingMethod: { classPropertyName: "snappingMethod", publicName: "snappingMethod", isSignal: true, isRequired: false, transformFunction: null }, methodForSelecting: { classPropertyName: "methodForSelecting", publicName: "methodForSelecting", isSignal: true, isRequired: false, transformFunction: null }, trackBy: { classPropertyName: "trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onScroll: "onScroll", onScrollEnd: "onScrollEnd", onViewportChange: "onViewportChange", onItemClick: "onItemClick", onSelect: "onSelect", onCollapse: "onCollapse" }, providers: [NgVirtualListService], viewQueries: [{ propertyName: "_snappedContainer", first: true, predicate: ["snapped"], descendants: true, isSignal: true }, { propertyName: "_container", first: true, predicate: ["container"], descendants: true, isSignal: true }, { propertyName: "_list", first: true, predicate: ["list"], descendants: true, isSignal: true }, { propertyName: "_listContainerRef", first: true, predicate: ["renderersContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_snapContainerRef", first: true, predicate: ["snapRendererContainer"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "@if (snap()) {\r\n <div #snapped part=\"snapped-item\" class=\"ngvl__list-snapper\">\r\n <ng-container #snapRendererContainer></ng-container>\r\n </div>\r\n}\r\n<div #container part=\"scroller\" class=\"ngvl__scroller\">\r\n <div [attr.aria-orientation]=\"orientation\" #list
|
|
2677
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: NgVirtualListComponent, isStandalone: true, selector: "ng-virtual-list", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, selectedIds: { classPropertyName: "selectedIds", publicName: "selectedIds", isSignal: true, isRequired: false, transformFunction: null }, collapsedIds: { classPropertyName: "collapsedIds", publicName: "collapsedIds", isSignal: true, isRequired: false, transformFunction: null }, selectByClick: { classPropertyName: "selectByClick", publicName: "selectByClick", isSignal: true, isRequired: false, transformFunction: null }, collapseByClick: { classPropertyName: "collapseByClick", publicName: "collapseByClick", isSignal: true, isRequired: false, transformFunction: null }, snap: { classPropertyName: "snap", publicName: "snap", isSignal: true, isRequired: false, transformFunction: null }, enabledBufferOptimization: { classPropertyName: "enabledBufferOptimization", publicName: "enabledBufferOptimization", isSignal: true, isRequired: false, transformFunction: null }, itemRenderer: { classPropertyName: "itemRenderer", publicName: "itemRenderer", isSignal: true, isRequired: true, transformFunction: null }, itemConfigMap: { classPropertyName: "itemConfigMap", publicName: "itemConfigMap", isSignal: true, isRequired: false, transformFunction: null }, itemSize: { classPropertyName: "itemSize", publicName: "itemSize", isSignal: true, isRequired: false, transformFunction: null }, dynamicSize: { classPropertyName: "dynamicSize", publicName: "dynamicSize", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, bufferSize: { classPropertyName: "bufferSize", publicName: "bufferSize", isSignal: true, isRequired: false, transformFunction: null }, maxBufferSize: { classPropertyName: "maxBufferSize", publicName: "maxBufferSize", isSignal: true, isRequired: false, transformFunction: null }, snappingMethod: { classPropertyName: "snappingMethod", publicName: "snappingMethod", isSignal: true, isRequired: false, transformFunction: null }, methodForSelecting: { classPropertyName: "methodForSelecting", publicName: "methodForSelecting", isSignal: true, isRequired: false, transformFunction: null }, trackBy: { classPropertyName: "trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onScroll: "onScroll", onScrollEnd: "onScrollEnd", onViewportChange: "onViewportChange", onItemClick: "onItemClick", onSelect: "onSelect", onCollapse: "onCollapse" }, host: { styleAttribute: "position: relative;" }, providers: [NgVirtualListService], viewQueries: [{ propertyName: "_snappedContainer", first: true, predicate: ["snapped"], descendants: true, isSignal: true }, { propertyName: "_container", first: true, predicate: ["container"], descendants: true, isSignal: true }, { propertyName: "_list", first: true, predicate: ["list"], descendants: true, isSignal: true }, { propertyName: "_listContainerRef", first: true, predicate: ["renderersContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_snapContainerRef", first: true, predicate: ["snapRendererContainer"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "@if (snap()) {\r\n <div #snapped part=\"snapped-item\" class=\"ngvl__list-snapper\">\r\n <ng-container #snapRendererContainer></ng-container>\r\n </div>\r\n}\r\n<div #container part=\"scroller\" class=\"ngvl__scroller\">\r\n <div [attr.aria-orientation]=\"orientation\" [attr.aria-activedescendant]=\"focusedElement()\" tabindex=\"0\" #list\r\n part=\"list\" 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: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
2620
2678
|
}
|
|
2621
2679
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: NgVirtualListComponent, decorators: [{
|
|
2622
2680
|
type: Component,
|
|
2623
|
-
args: [{ selector: 'ng-virtual-list', imports: [CommonModule],
|
|
2681
|
+
args: [{ selector: 'ng-virtual-list', imports: [CommonModule], host: {
|
|
2682
|
+
'style': 'position: relative;'
|
|
2683
|
+
}, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, providers: [NgVirtualListService], template: "@if (snap()) {\r\n <div #snapped part=\"snapped-item\" class=\"ngvl__list-snapper\">\r\n <ng-container #snapRendererContainer></ng-container>\r\n </div>\r\n}\r\n<div #container part=\"scroller\" class=\"ngvl__scroller\">\r\n <div [attr.aria-orientation]=\"orientation\" [attr.aria-activedescendant]=\"focusedElement()\" tabindex=\"0\" #list\r\n part=\"list\" 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"] }]
|
|
2624
2684
|
}], ctorParameters: () => [], propDecorators: { _listContainerRef: [{
|
|
2625
2685
|
type: ViewChild,
|
|
2626
2686
|
args: ['renderersContainer', { read: ViewContainerRef }]
|