ng-virtual-list 20.7.0 → 20.7.2
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 +24 -22
- package/fesm2022/ng-virtual-list.mjs +126 -45
- package/fesm2022/ng-virtual-list.mjs.map +1 -1
- package/index.d.ts +73 -22
- package/package.json +1 -1
- package/esm2020/lib/components/ng-virtual-list-item.component.mjs +0 -198
- package/esm2020/lib/const/index.mjs +0 -51
- package/esm2020/lib/enums/direction.mjs +0 -2
- package/esm2020/lib/enums/directions.mjs +0 -18
- package/esm2020/lib/enums/index.mjs +0 -5
- package/esm2020/lib/enums/method-for-selecting-types.mjs +0 -22
- package/esm2020/lib/enums/method-for-selecting.mjs +0 -2
- package/esm2020/lib/enums/methods-for-selecting.mjs +0 -22
- package/esm2020/lib/enums/snapping-method.mjs +0 -2
- package/esm2020/lib/enums/snapping-methods.mjs +0 -18
- package/esm2020/lib/models/base-virtual-list-item-component.mjs +0 -9
- package/esm2020/lib/models/collection.model.mjs +0 -3
- package/esm2020/lib/models/component.model.mjs +0 -2
- package/esm2020/lib/models/index.mjs +0 -2
- package/esm2020/lib/models/item.model.mjs +0 -2
- package/esm2020/lib/models/render-collection.model.mjs +0 -3
- package/esm2020/lib/models/render-item-config.model.mjs +0 -2
- package/esm2020/lib/models/render-item.model.mjs +0 -3
- package/esm2020/lib/models/scroll-direction.model.mjs +0 -2
- package/esm2020/lib/models/scroll-event.model.mjs +0 -2
- package/esm2020/lib/models/sticky-map.model.mjs +0 -2
- package/esm2020/lib/ng-virtual-list.component.mjs +0 -800
- package/esm2020/lib/ng-virtual-list.module.mjs +0 -20
- package/esm2020/lib/ng-virtual-list.service.mjs +0 -94
- package/esm2020/lib/types/id.mjs +0 -2
- package/esm2020/lib/types/index.mjs +0 -2
- package/esm2020/lib/types/rect.mjs +0 -2
- package/esm2020/lib/types/size.mjs +0 -2
- package/esm2020/lib/utils/browser.mjs +0 -3
- package/esm2020/lib/utils/buffer-interpolation.mjs +0 -27
- package/esm2020/lib/utils/cacheMap.mjs +0 -167
- package/esm2020/lib/utils/debounce.mjs +0 -31
- package/esm2020/lib/utils/disposableComponent.mjs +0 -29
- package/esm2020/lib/utils/eventEmitter.mjs +0 -106
- package/esm2020/lib/utils/index.mjs +0 -5
- package/esm2020/lib/utils/isDirection.mjs +0 -15
- package/esm2020/lib/utils/isMethodForSelecting.mjs +0 -18
- package/esm2020/lib/utils/scrollEvent.mjs +0 -42
- package/esm2020/lib/utils/snapping-method.mjs +0 -9
- package/esm2020/lib/utils/toggleClassName.mjs +0 -15
- package/esm2020/lib/utils/trackBox.mjs +0 -762
- package/esm2020/lib/utils/tracker.mjs +0 -143
- package/esm2020/ng-virtual-list.mjs +0 -5
- package/esm2020/public-api.mjs +0 -10
- package/esm2022/lib/components/ng-virtual-list-item.component.mjs +0 -190
- package/esm2022/lib/const/index.mjs +0 -51
- package/esm2022/lib/enums/direction.mjs +0 -2
- package/esm2022/lib/enums/directions.mjs +0 -18
- package/esm2022/lib/enums/index.mjs +0 -5
- package/esm2022/lib/enums/method-for-selecting-types.mjs +0 -22
- package/esm2022/lib/enums/method-for-selecting.mjs +0 -2
- package/esm2022/lib/enums/methods-for-selecting.mjs +0 -22
- package/esm2022/lib/enums/snapping-method.mjs +0 -2
- package/esm2022/lib/enums/snapping-methods.mjs +0 -18
- package/esm2022/lib/models/base-virtual-list-item-component.mjs +0 -9
- package/esm2022/lib/models/collection.model.mjs +0 -3
- package/esm2022/lib/models/component.model.mjs +0 -2
- package/esm2022/lib/models/index.mjs +0 -2
- package/esm2022/lib/models/item.model.mjs +0 -2
- package/esm2022/lib/models/render-collection.model.mjs +0 -3
- package/esm2022/lib/models/render-item-config.model.mjs +0 -2
- package/esm2022/lib/models/render-item.model.mjs +0 -3
- package/esm2022/lib/models/scroll-direction.model.mjs +0 -2
- package/esm2022/lib/models/scroll-event.model.mjs +0 -2
- package/esm2022/lib/models/sticky-map.model.mjs +0 -2
- package/esm2022/lib/ng-virtual-list.component.mjs +0 -624
- package/esm2022/lib/ng-virtual-list.module.mjs +0 -20
- package/esm2022/lib/ng-virtual-list.service.mjs +0 -89
- package/esm2022/lib/types/id.mjs +0 -2
- package/esm2022/lib/types/index.mjs +0 -2
- package/esm2022/lib/types/rect.mjs +0 -2
- package/esm2022/lib/types/size.mjs +0 -2
- package/esm2022/lib/utils/browser.mjs +0 -3
- package/esm2022/lib/utils/buffer-interpolation.mjs +0 -27
- package/esm2022/lib/utils/cacheMap.mjs +0 -168
- package/esm2022/lib/utils/debounce.mjs +0 -31
- package/esm2022/lib/utils/eventEmitter.mjs +0 -105
- package/esm2022/lib/utils/index.mjs +0 -5
- package/esm2022/lib/utils/isDirection.mjs +0 -15
- package/esm2022/lib/utils/isMethodForSelecting.mjs +0 -18
- package/esm2022/lib/utils/scrollEvent.mjs +0 -42
- package/esm2022/lib/utils/snapping-method.mjs +0 -9
- package/esm2022/lib/utils/toggleClassName.mjs +0 -15
- package/esm2022/lib/utils/trackBox.mjs +0 -768
- package/esm2022/lib/utils/tracker.mjs +0 -144
- package/esm2022/ng-virtual-list.mjs +0 -5
- package/esm2022/public-api.mjs +0 -11
- package/fesm2015/ng-virtual-list.mjs +0 -2582
- package/fesm2015/ng-virtual-list.mjs.map +0 -1
- package/fesm2020/ng-virtual-list.mjs +0 -2586
- package/fesm2020/ng-virtual-list.mjs.map +0 -1
- package/lib/components/ng-virtual-list-item.component.d.ts +0 -47
- package/lib/const/index.d.ts +0 -48
- package/lib/enums/direction.d.ts +0 -8
- package/lib/enums/directions.d.ts +0 -16
- package/lib/enums/index.d.ts +0 -8
- package/lib/enums/method-for-selecting-types.d.ts +0 -20
- package/lib/enums/method-for-selecting.d.ts +0 -8
- package/lib/enums/methods-for-selecting.d.ts +0 -20
- package/lib/enums/snapping-method.d.ts +0 -10
- package/lib/enums/snapping-methods.d.ts +0 -16
- package/lib/models/base-virtual-list-item-component.d.ts +0 -24
- package/lib/models/collection.model.d.ts +0 -9
- package/lib/models/component.model.d.ts +0 -3
- package/lib/models/index.d.ts +0 -7
- package/lib/models/item.model.d.ts +0 -14
- package/lib/models/render-collection.model.d.ts +0 -9
- package/lib/models/render-item-config.model.d.ts +0 -49
- package/lib/models/render-item.model.d.ts +0 -37
- package/lib/models/scroll-direction.model.d.ts +0 -5
- package/lib/models/scroll-event.model.d.ts +0 -50
- package/lib/models/sticky-map.model.d.ts +0 -14
- package/lib/ng-virtual-list.component.d.ts +0 -202
- package/lib/ng-virtual-list.module.d.ts +0 -9
- package/lib/ng-virtual-list.service.d.ts +0 -23
- package/lib/types/id.d.ts +0 -7
- package/lib/types/index.d.ts +0 -4
- package/lib/types/rect.d.ts +0 -17
- package/lib/types/size.d.ts +0 -16
- package/lib/utils/browser.d.ts +0 -2
- package/lib/utils/buffer-interpolation.d.ts +0 -5
- package/lib/utils/cacheMap.d.ts +0 -60
- package/lib/utils/debounce.d.ts +0 -16
- package/lib/utils/disposableComponent.d.ts +0 -15
- package/lib/utils/eventEmitter.d.ts +0 -40
- package/lib/utils/index.d.ts +0 -6
- package/lib/utils/isDirection.d.ts +0 -8
- package/lib/utils/isMethodForSelecting.d.ts +0 -8
- package/lib/utils/scrollEvent.d.ts +0 -39
- package/lib/utils/snapping-method.d.ts +0 -3
- package/lib/utils/toggleClassName.d.ts +0 -7
- package/lib/utils/trackBox.d.ts +0 -207
- package/lib/utils/tracker.d.ts +0 -49
- package/public-api.d.ts +0 -7
package/README.md
CHANGED
|
@@ -109,7 +109,7 @@ export class AppComponent {
|
|
|
109
109
|
Template:
|
|
110
110
|
```html
|
|
111
111
|
<ng-virtual-list class="list" direction="horizontal" [items]="horizontalGroupItems" [itemRenderer]="horizontalGroupItemRenderer"
|
|
112
|
-
[bufferSize]="50" [
|
|
112
|
+
[bufferSize]="50" [itemConfigMap]="horizontalGroupItemConfigMap" [itemSize]="54" [snap]="true" (onItemClick)="onItemClick($event)"></ng-virtual-list>
|
|
113
113
|
|
|
114
114
|
<ng-template #horizontalGroupItemRenderer let-data="data">
|
|
115
115
|
@if (data) {
|
|
@@ -131,7 +131,7 @@ Template:
|
|
|
131
131
|
|
|
132
132
|
Component:
|
|
133
133
|
```ts
|
|
134
|
-
import { NgVirtualListComponent, IVirtualListCollection,
|
|
134
|
+
import { NgVirtualListComponent, IVirtualListCollection, IVirtualListItemConfigMap, IRenderVirtualListItem } from 'ng-virtual-list';
|
|
135
135
|
|
|
136
136
|
const GROUP_NAMES = ['A', 'B', 'C', 'D', 'E'];
|
|
137
137
|
|
|
@@ -145,12 +145,12 @@ interface ICollectionItem {
|
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
const HORIZONTAL_GROUP_ITEMS: IVirtualListCollection<ICollectionItem> = [],
|
|
148
|
-
|
|
148
|
+
HORIZONTAL_GROUP_ITEM_CONFIG_MAP: IVirtualListItemConfigMap = {};
|
|
149
149
|
|
|
150
150
|
for (let i = 0, l = 1000000; i < l; i++) {
|
|
151
151
|
const id = i + 1, type = Math.random() > .895 ? 'group-header' : 'item';
|
|
152
152
|
HORIZONTAL_GROUP_ITEMS.push({ id, type, name: type === 'group-header' ? getGroupName() : `${i}` });
|
|
153
|
-
|
|
153
|
+
HORIZONTAL_GROUP_ITEM_CONFIG_MAP[id] = type === 'group-header' ? 1 : 0;
|
|
154
154
|
}
|
|
155
155
|
|
|
156
156
|
@Component({
|
|
@@ -161,7 +161,7 @@ for (let i = 0, l = 1000000; i < l; i++) {
|
|
|
161
161
|
})
|
|
162
162
|
export class AppComponent {
|
|
163
163
|
horizontalGroupItems = HORIZONTAL_GROUP_ITEMS;
|
|
164
|
-
|
|
164
|
+
horizontalGroupItemConfigMap = HORIZONTAL_GROUP_ITEM_CONFIG_MAP;
|
|
165
165
|
|
|
166
166
|
onItemClick(item: IRenderVirtualListItem<ICollectionItem> | undefined) {
|
|
167
167
|
if (item) {
|
|
@@ -219,7 +219,7 @@ export class AppComponent {
|
|
|
219
219
|
Template:
|
|
220
220
|
```html
|
|
221
221
|
<ng-virtual-list class="list simple" [items]="groupItems" [bufferSize]="50" [itemRenderer]="groupItemRenderer"
|
|
222
|
-
[
|
|
222
|
+
[itemConfigMap]="groupItemConfigMap" [itemSize]="40" [snap]="false"></ng-virtual-list>
|
|
223
223
|
|
|
224
224
|
<ng-template #groupItemRenderer let-data="data">
|
|
225
225
|
@if (data) {
|
|
@@ -246,7 +246,7 @@ Template:
|
|
|
246
246
|
Template (with snapping):
|
|
247
247
|
```html
|
|
248
248
|
<ng-virtual-list class="list simple" [items]="groupItems" [bufferSize]="50" [itemRenderer]="groupItemRenderer"
|
|
249
|
-
[
|
|
249
|
+
[itemConfigMap]="groupItemConfigMap" [itemSize]="40" [snap]="true"></ng-virtual-list>
|
|
250
250
|
|
|
251
251
|
<ng-template #groupItemRenderer let-data="data">
|
|
252
252
|
@if (data) {
|
|
@@ -268,10 +268,10 @@ Template (with snapping):
|
|
|
268
268
|
|
|
269
269
|
Component:
|
|
270
270
|
```ts
|
|
271
|
-
import { NgVirtualListComponent, IVirtualListCollection,
|
|
271
|
+
import { NgVirtualListComponent, IVirtualListCollection, IVirtualListItemConfigMap } from 'ng-virtual-list';
|
|
272
272
|
|
|
273
273
|
const GROUP_ITEMS: IVirtualListCollection = [],
|
|
274
|
-
|
|
274
|
+
GROUP_ITEM_CONFIG_MAP: IVirtualListItemConfigMap = {};
|
|
275
275
|
|
|
276
276
|
let groupIndex = 0;
|
|
277
277
|
for (let i = 0, l = 10000000; i < l; i++) {
|
|
@@ -280,7 +280,7 @@ for (let i = 0, l = 10000000; i < l; i++) {
|
|
|
280
280
|
groupIndex++;
|
|
281
281
|
}
|
|
282
282
|
GROUP_ITEMS.push({ id, type, name: type === 'group-header' ? `Group ${groupIndex}` : `Item: ${i}` });
|
|
283
|
-
|
|
283
|
+
GROUP_ITEM_CONFIG_MAP[id] = type === 'group-header' ? 1 : 0;
|
|
284
284
|
}
|
|
285
285
|
|
|
286
286
|
@Component({
|
|
@@ -291,7 +291,7 @@ for (let i = 0, l = 10000000; i < l; i++) {
|
|
|
291
291
|
})
|
|
292
292
|
export class AppComponent {
|
|
293
293
|
groupItems = GROUP_ITEMS;
|
|
294
|
-
|
|
294
|
+
groupItemConfigMap = GROUP_ITEM_CONFIG_MAP;
|
|
295
295
|
}
|
|
296
296
|
|
|
297
297
|
```
|
|
@@ -365,7 +365,7 @@ Virtual list with height-adjustable elements.
|
|
|
365
365
|
Template
|
|
366
366
|
```html
|
|
367
367
|
<ng-virtual-list #dynamicList class="list" [items]="groupDynamicItems" [itemRenderer]="groupItemRenderer" [bufferSize]="10"
|
|
368
|
-
[
|
|
368
|
+
[itemConfigMap]="groupDynamicItemConfigMap" [dynamicSize]="true" [snap]="true"></ng-virtual-list>
|
|
369
369
|
|
|
370
370
|
<ng-template #groupItemRenderer let-data="data">
|
|
371
371
|
@if (data) {
|
|
@@ -413,7 +413,7 @@ const generateText = () => {
|
|
|
413
413
|
};
|
|
414
414
|
|
|
415
415
|
const GROUP_DYNAMIC_ITEMS: IVirtualListCollection = [],
|
|
416
|
-
|
|
416
|
+
GROUP_DYNAMIC_ITEM_CONFIG_MAP: IVirtualListItemConfigMap = {};
|
|
417
417
|
|
|
418
418
|
let groupDynamicIndex = 0;
|
|
419
419
|
for (let i = 0, l = 100000; i < l; i++) {
|
|
@@ -422,7 +422,7 @@ for (let i = 0, l = 100000; i < l; i++) {
|
|
|
422
422
|
groupDynamicIndex++;
|
|
423
423
|
}
|
|
424
424
|
GROUP_DYNAMIC_ITEMS.push({ id, type, name: type === 'group-header' ? `Group ${groupDynamicIndex}` : `${id}. ${generateText()}` });
|
|
425
|
-
|
|
425
|
+
GROUP_DYNAMIC_ITEM_CONFIG_MAP[id] = type === 'group-header' ? 1 : 0;
|
|
426
426
|
}
|
|
427
427
|
|
|
428
428
|
@Component({
|
|
@@ -433,7 +433,7 @@ for (let i = 0, l = 100000; i < l; i++) {
|
|
|
433
433
|
})
|
|
434
434
|
export class AppComponent {
|
|
435
435
|
groupDynamicItems = GROUP_DYNAMIC_ITEMS;
|
|
436
|
-
|
|
436
|
+
groupDynamicItemConfigMap = GROUP_DYNAMIC_ITEM_CONFIG_MAP;
|
|
437
437
|
}
|
|
438
438
|
```
|
|
439
439
|
|
|
@@ -535,7 +535,9 @@ Inputs
|
|
|
535
535
|
| bufferSize | number? = 2 | Number of elements outside the scope of visibility. Default value is 2. |
|
|
536
536
|
| maxBufferSize | number? = 100 | Maximum number of elements outside the scope of visibility. Default value is 100. 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. |
|
|
537
537
|
| itemRenderer | TemplateRef | Rendering element template. |
|
|
538
|
-
|
|
|
538
|
+
| 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. |
|
|
539
|
+
| 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`. |
|
|
540
|
+
| selectByClick | boolean? = true | If `false`, the element is selected using the config.select method passed to the template; if `true`, the element is selected by clicking on it. The default value is `true`. |
|
|
539
541
|
| snap | boolean? = false | Determines whether elements will snap. Default value is "false". |
|
|
540
542
|
| snappingMethod | [SnappingMethod? = 'normal'](https://github.com/DjonnyX/ng-virtual-list/blob/20.x/projects/ng-virtual-list/src/lib/enums/snapping-method.ts) | Snapping method. 'normal' - Normal group rendering. 'advanced' - The group is rendered on a transparent background. List items below the group are not rendered. |
|
|
541
543
|
| direction | [Direction? = 'vertical'](https://github.com/DjonnyX/ng-virtual-list/blob/20.x/projects/ng-virtual-list/src/lib/enums/direction.ts) | Determines the direction in which elements are placed. Default value is "vertical". |
|
|
@@ -573,12 +575,12 @@ Methods
|
|
|
573
575
|
|
|
574
576
|
| Angular version | ng-virtual-list version | git | npm |
|
|
575
577
|
|--|--|--|--|
|
|
576
|
-
| 19.x | 19.7.
|
|
577
|
-
| 18.x | 18.7.
|
|
578
|
-
| 17.x | 17.7.
|
|
579
|
-
| 16.x | 16.7.
|
|
580
|
-
| 15.x | 15.7.
|
|
581
|
-
| 14.x | 14.7.
|
|
578
|
+
| 19.x | 19.7.3 | [19.x](https://github.com/DjonnyX/ng-virtual-list/tree/19.x) | [19.7.3](https://www.npmjs.com/package/ng-virtual-list/v/19.7.3) |
|
|
579
|
+
| 18.x | 18.7.2 | [18.x](https://github.com/DjonnyX/ng-virtual-list/tree/18.x) | [18.7.2](https://www.npmjs.com/package/ng-virtual-list/v/18.7.2) |
|
|
580
|
+
| 17.x | 17.7.2 | [17.x](https://github.com/DjonnyX/ng-virtual-list/tree/17.x) | [17.7.2](https://www.npmjs.com/package/ng-virtual-list/v/17.7.2) |
|
|
581
|
+
| 16.x | 16.7.2 | [16.x](https://github.com/DjonnyX/ng-virtual-list/tree/16.x) | [16.7.2](https://www.npmjs.com/package/ng-virtual-list/v/16.7.2) |
|
|
582
|
+
| 15.x | 15.7.2 | [15.x](https://github.com/DjonnyX/ng-virtual-list/tree/15.x) | [15.7.2](https://www.npmjs.com/package/ng-virtual-list/v/15.7.2) |
|
|
583
|
+
| 14.x | 14.7.2 | [14.x](https://github.com/DjonnyX/ng-virtual-list/tree/14.x) | [14.7.2](https://www.npmjs.com/package/ng-virtual-list/v/14.7.2) |
|
|
582
584
|
|
|
583
585
|
<br/>
|
|
584
586
|
|
|
@@ -69,6 +69,7 @@ const DEFAULT_BUFFER_SIZE = 2;
|
|
|
69
69
|
const DEFAULT_MAX_BUFFER_SIZE = 100;
|
|
70
70
|
const DEFAULT_LIST_SIZE = 400;
|
|
71
71
|
const DEFAULT_SNAP = false;
|
|
72
|
+
const DEFAULT_SELECT_BY_CLICK = true;
|
|
72
73
|
const DEFAULT_ENABLED_BUFFER_OPTIMIZATION = false;
|
|
73
74
|
const DEFAULT_DYNAMIC_SIZE = false;
|
|
74
75
|
const TRACK_BY_PROPERTY_NAME = 'id';
|
|
@@ -155,6 +156,7 @@ class NgVirtualListService {
|
|
|
155
156
|
set methodOfSelecting(v) {
|
|
156
157
|
this._$methodOfSelecting.next(v);
|
|
157
158
|
}
|
|
159
|
+
selectByClick = DEFAULT_SELECT_BY_CLICK;
|
|
158
160
|
_trackBox;
|
|
159
161
|
constructor() {
|
|
160
162
|
this._$methodOfSelecting.pipe(takeUntilDestroyed(), tap(v => {
|
|
@@ -181,25 +183,61 @@ class NgVirtualListService {
|
|
|
181
183
|
})).subscribe();
|
|
182
184
|
}
|
|
183
185
|
setSelectedIds(ids) {
|
|
184
|
-
this._$selectedIds.
|
|
186
|
+
if (JSON.stringify(this._$selectedIds.getValue()) !== JSON.stringify(ids)) {
|
|
187
|
+
this._$selectedIds.next(ids);
|
|
188
|
+
}
|
|
185
189
|
}
|
|
186
190
|
itemClick(data) {
|
|
187
191
|
this._$itemClick.next(data);
|
|
188
|
-
if (
|
|
192
|
+
if (this.selectByClick) {
|
|
193
|
+
this.select(data);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Selects a list item
|
|
198
|
+
* @param data
|
|
199
|
+
* @param selected - If the value is undefined, then the toggle method is executed, if false or true, then the selection/deselection is performed.
|
|
200
|
+
*/
|
|
201
|
+
select(data, selected = undefined) {
|
|
202
|
+
if (data && data.config.selectable) {
|
|
189
203
|
switch (this._$methodOfSelecting.getValue()) {
|
|
190
204
|
case MethodsForSelectingTypes.SELECT: {
|
|
191
205
|
const curr = this._$selectedIds.getValue();
|
|
192
|
-
|
|
206
|
+
if (selected === undefined) {
|
|
207
|
+
this._$selectedIds.next(curr !== data?.id ? data?.id : undefined);
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
this._$selectedIds.next(selected ? data?.id : undefined);
|
|
211
|
+
}
|
|
193
212
|
break;
|
|
194
213
|
}
|
|
195
214
|
case MethodsForSelectingTypes.MULTI_SELECT: {
|
|
196
215
|
const curr = [...(this._$selectedIds.getValue() || [])], index = curr.indexOf(data.id);
|
|
197
|
-
if (
|
|
198
|
-
|
|
199
|
-
|
|
216
|
+
if (selected === undefined) {
|
|
217
|
+
if (index > -1) {
|
|
218
|
+
curr.splice(index, 1);
|
|
219
|
+
this._$selectedIds.next(curr);
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
this._$selectedIds.next([...curr, data.id]);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
else if (selected) {
|
|
226
|
+
if (index > -1) {
|
|
227
|
+
this._$selectedIds.next(curr);
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
this._$selectedIds.next([...curr, data.id]);
|
|
231
|
+
}
|
|
200
232
|
}
|
|
201
233
|
else {
|
|
202
|
-
|
|
234
|
+
if (index > -1) {
|
|
235
|
+
curr.splice(index, 1);
|
|
236
|
+
this._$selectedIds.next(curr);
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
this._$selectedIds.next(curr);
|
|
240
|
+
}
|
|
203
241
|
}
|
|
204
242
|
break;
|
|
205
243
|
}
|
|
@@ -242,6 +280,7 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
|
|
|
242
280
|
_service = inject(NgVirtualListService);
|
|
243
281
|
_isSelected = false;
|
|
244
282
|
config = signal({});
|
|
283
|
+
measures = signal(undefined);
|
|
245
284
|
_part = PART_DEFAULT_ITEM;
|
|
246
285
|
get part() { return this._part; }
|
|
247
286
|
regular = false;
|
|
@@ -254,6 +293,7 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
|
|
|
254
293
|
this._data = v;
|
|
255
294
|
this.updatePartStr(v, this._isSelected);
|
|
256
295
|
this.updateConfig(v);
|
|
296
|
+
this.updateMeasures(v);
|
|
257
297
|
this.update();
|
|
258
298
|
this.data.set(v);
|
|
259
299
|
}
|
|
@@ -279,6 +319,14 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
|
|
|
279
319
|
get element() {
|
|
280
320
|
return this._elementRef.nativeElement;
|
|
281
321
|
}
|
|
322
|
+
_selectHandler = (data) =>
|
|
323
|
+
/**
|
|
324
|
+
* Selects a list item
|
|
325
|
+
* @param selected - If the value is undefined, then the toggle method is executed, if false or true, then the selection/deselection is performed.
|
|
326
|
+
*/
|
|
327
|
+
(selected = undefined) => {
|
|
328
|
+
this._service.select(data, selected);
|
|
329
|
+
};
|
|
282
330
|
constructor() {
|
|
283
331
|
super();
|
|
284
332
|
this._id = this._service.generateComponentId();
|
|
@@ -306,10 +354,14 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
|
|
|
306
354
|
}
|
|
307
355
|
this.updatePartStr(this._data, this._isSelected);
|
|
308
356
|
this.updateConfig(this._data);
|
|
357
|
+
this.updateMeasures(this._data);
|
|
309
358
|
})).subscribe();
|
|
310
359
|
}
|
|
360
|
+
updateMeasures(v) {
|
|
361
|
+
this.measures.set(v?.measures ? { ...v.measures } : undefined);
|
|
362
|
+
}
|
|
311
363
|
updateConfig(v) {
|
|
312
|
-
this.config.set({ ...v?.config || {}, selected: this._isSelected });
|
|
364
|
+
this.config.set({ ...v?.config || {}, selected: this._isSelected, select: this._selectHandler(v) });
|
|
313
365
|
}
|
|
314
366
|
update() {
|
|
315
367
|
const data = this._data, regular = this.regular, length = this._regularLength;
|
|
@@ -393,14 +445,14 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
|
|
|
393
445
|
this._service.itemClick(this._data);
|
|
394
446
|
}
|
|
395
447
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: NgVirtualListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
396
|
-
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
|
|
448
|
+
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 _measures = measures();\r\n@let renderer = itemRenderer();\r\n\r\n@if (item) {\r\n <div #listItem [part]=\"part\" class=\"ngvl-item__container\"\r\n [ngClass]=\"{'snapped': item.config.snapped, 'snapped-out': item.config.snappedOut}\" (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}\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 });
|
|
397
449
|
}
|
|
398
450
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: NgVirtualListItemComponent, decorators: [{
|
|
399
451
|
type: Component,
|
|
400
452
|
args: [{ selector: 'ng-virtual-list-item', imports: [CommonModule], host: {
|
|
401
453
|
'class': 'ngvl__item',
|
|
402
454
|
'role': 'listitem',
|
|
403
|
-
}, changeDetection: ChangeDetectionStrategy.OnPush, template: "@let item = data();\r\n@let
|
|
455
|
+
}, changeDetection: ChangeDetectionStrategy.OnPush, template: "@let item = data();\r\n@let _config = config();\r\n@let _measures = measures();\r\n@let renderer = itemRenderer();\r\n\r\n@if (item) {\r\n <div #listItem [part]=\"part\" class=\"ngvl-item__container\"\r\n [ngClass]=\"{'snapped': item.config.snapped, 'snapped-out': item.config.snappedOut}\" (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}\n"] }]
|
|
404
456
|
}], ctorParameters: () => [] });
|
|
405
457
|
|
|
406
458
|
/**
|
|
@@ -1116,8 +1168,8 @@ class TrackBox extends CacheMap {
|
|
|
1116
1168
|
/**
|
|
1117
1169
|
* Finds the position of a collection element by the given Id
|
|
1118
1170
|
*/
|
|
1119
|
-
getItemPosition(id,
|
|
1120
|
-
const opt = { fromItemId: id,
|
|
1171
|
+
getItemPosition(id, itemConfigMap, options) {
|
|
1172
|
+
const opt = { fromItemId: id, itemConfigMap, ...options };
|
|
1121
1173
|
this._defaultBufferSize = opt.bufferSize;
|
|
1122
1174
|
this._maxBufferSize = opt.maxBufferSize;
|
|
1123
1175
|
const { scrollSize, isFromItemIdFound } = this.recalculateMetrics({
|
|
@@ -1132,8 +1184,8 @@ class TrackBox extends CacheMap {
|
|
|
1132
1184
|
/**
|
|
1133
1185
|
* Updates the collection of display objects
|
|
1134
1186
|
*/
|
|
1135
|
-
updateCollection(items,
|
|
1136
|
-
const opt = {
|
|
1187
|
+
updateCollection(items, itemConfigMap, options) {
|
|
1188
|
+
const opt = { itemConfigMap, ...options }, crudDetected = this._crudDetected, deletedItemsMap = this._deletedItemsMap;
|
|
1137
1189
|
if (opt.dynamicSize) {
|
|
1138
1190
|
this.cacheElements();
|
|
1139
1191
|
}
|
|
@@ -1154,7 +1206,7 @@ class TrackBox extends CacheMap {
|
|
|
1154
1206
|
if (opt.dynamicSize) {
|
|
1155
1207
|
this.snapshot();
|
|
1156
1208
|
}
|
|
1157
|
-
const displayItems = this.generateDisplayCollection(items,
|
|
1209
|
+
const displayItems = this.generateDisplayCollection(items, itemConfigMap, { ...metrics, });
|
|
1158
1210
|
return { displayItems, totalSize: metrics.totalSize, delta: metrics.delta, crudDetected };
|
|
1159
1211
|
}
|
|
1160
1212
|
/**
|
|
@@ -1235,7 +1287,7 @@ class TrackBox extends CacheMap {
|
|
|
1235
1287
|
* Calculates list metrics
|
|
1236
1288
|
*/
|
|
1237
1289
|
recalculateMetrics(options) {
|
|
1238
|
-
const { fromItemId, bounds, collection, dynamicSize, isVertical, itemSize, bufferSize: minBufferSize, scrollSize, snap,
|
|
1290
|
+
const { fromItemId, bounds, collection, dynamicSize, isVertical, itemSize, bufferSize: minBufferSize, scrollSize, snap, itemConfigMap, enabledBufferOptimization, previousTotalSize, crudDetected, deletedItemsMap } = options;
|
|
1239
1291
|
const bufferSize = Math.max(minBufferSize, this._bufferSize), { width, height } = bounds, sizeProperty = isVertical ? HEIGHT_PROP_NAME : WIDTH_PROP_NAME, size = isVertical ? height : width, totalLength = collection.length, typicalItemSize = itemSize, w = isVertical ? width : typicalItemSize, h = isVertical ? typicalItemSize : height, map = this._map, snapshot = this._snapshot, checkOverscrollItemsLimit = Math.ceil(size / typicalItemSize), snippedPos = Math.floor(scrollSize), leftItemsWeights = [], isFromId = fromItemId !== undefined && (typeof fromItemId === 'number' && fromItemId > -1)
|
|
1240
1292
|
|| (typeof fromItemId === 'string' && fromItemId > '-1');
|
|
1241
1293
|
let leftItemsOffset = 0, rightItemsOffset = 0;
|
|
@@ -1295,21 +1347,21 @@ class TrackBox extends CacheMap {
|
|
|
1295
1347
|
totalSize += componentSize;
|
|
1296
1348
|
if (isFromId) {
|
|
1297
1349
|
if (itemById === undefined) {
|
|
1298
|
-
if (id !== fromItemId &&
|
|
1350
|
+
if (id !== fromItemId && itemConfigMap && itemConfigMap[id]?.sticky === 1) {
|
|
1299
1351
|
stickyComponentSize = componentSize;
|
|
1300
1352
|
stickyCollectionItem = collectionItem;
|
|
1301
1353
|
}
|
|
1302
1354
|
if (id === fromItemId) {
|
|
1303
1355
|
isFromItemIdFound = true;
|
|
1304
1356
|
targetDisplayItemIndex = i;
|
|
1305
|
-
if (stickyCollectionItem &&
|
|
1357
|
+
if (stickyCollectionItem && itemConfigMap) {
|
|
1306
1358
|
const { num } = this.getElementNumToEnd(i, collection, map, typicalItemSize, size, isVertical);
|
|
1307
1359
|
if (num > 0) {
|
|
1308
1360
|
isTargetInOverscroll = true;
|
|
1309
1361
|
y -= size - componentSize;
|
|
1310
1362
|
}
|
|
1311
1363
|
else {
|
|
1312
|
-
if (
|
|
1364
|
+
if (itemConfigMap && !itemConfigMap[collectionItem.id] && y >= scrollSize && y < scrollSize + stickyComponentSize) {
|
|
1313
1365
|
const snappedY = scrollSize - stickyComponentSize;
|
|
1314
1366
|
leftHiddenItemsWeight -= (snappedY - y);
|
|
1315
1367
|
y = snappedY;
|
|
@@ -1492,7 +1544,7 @@ class TrackBox extends CacheMap {
|
|
|
1492
1544
|
changes() {
|
|
1493
1545
|
this.bumpVersion();
|
|
1494
1546
|
}
|
|
1495
|
-
generateDisplayCollection(items,
|
|
1547
|
+
generateDisplayCollection(items, itemConfigMap, metrics) {
|
|
1496
1548
|
const { width, height, normalizedItemWidth, normalizedItemHeight, dynamicSize, itemsOnDisplayLength, itemsFromStartToScrollEnd, isVertical, renderItems: renderItemsLength, scrollSize, sizeProperty, snap, snippedPos, startPosition, totalLength, startIndex, typicalItemSize, } = metrics, displayItems = [];
|
|
1497
1549
|
if (items.length) {
|
|
1498
1550
|
const actualSnippedPosition = snippedPos, isSnappingMethodAdvanced = this.isSnappingMethodAdvanced, boundsSize = isVertical ? height : width, actualEndSnippedPosition = boundsSize;
|
|
@@ -1502,7 +1554,7 @@ class TrackBox extends CacheMap {
|
|
|
1502
1554
|
if (!items[i]) {
|
|
1503
1555
|
continue;
|
|
1504
1556
|
}
|
|
1505
|
-
const id = items[i].id, sticky =
|
|
1557
|
+
const id = items[i].id, sticky = itemConfigMap[id]?.sticky ?? 0, selectable = itemConfigMap[id]?.selectable ?? true, size = dynamicSize ? this.get(id)?.[sizeProperty] || typicalItemSize : typicalItemSize;
|
|
1506
1558
|
if (sticky === 1) {
|
|
1507
1559
|
const isOdd = i % 2 != 0, measures = {
|
|
1508
1560
|
x: isVertical ? 0 : actualSnippedPosition,
|
|
@@ -1514,6 +1566,7 @@ class TrackBox extends CacheMap {
|
|
|
1514
1566
|
odd: isOdd,
|
|
1515
1567
|
even: !isOdd,
|
|
1516
1568
|
isVertical,
|
|
1569
|
+
selectable,
|
|
1517
1570
|
sticky,
|
|
1518
1571
|
snap,
|
|
1519
1572
|
snapped: true,
|
|
@@ -1537,7 +1590,7 @@ class TrackBox extends CacheMap {
|
|
|
1537
1590
|
if (!items[i]) {
|
|
1538
1591
|
continue;
|
|
1539
1592
|
}
|
|
1540
|
-
const id = items[i].id, sticky =
|
|
1593
|
+
const id = items[i].id, sticky = itemConfigMap[id]?.sticky ?? 0, selectable = itemConfigMap[id]?.selectable ?? true, size = dynamicSize
|
|
1541
1594
|
? this.get(id)?.[sizeProperty] || typicalItemSize
|
|
1542
1595
|
: typicalItemSize;
|
|
1543
1596
|
if (sticky === 2) {
|
|
@@ -1551,6 +1604,7 @@ class TrackBox extends CacheMap {
|
|
|
1551
1604
|
odd: isOdd,
|
|
1552
1605
|
even: !isOdd,
|
|
1553
1606
|
isVertical,
|
|
1607
|
+
selectable,
|
|
1554
1608
|
sticky,
|
|
1555
1609
|
snap,
|
|
1556
1610
|
snapped: true,
|
|
@@ -1578,9 +1632,9 @@ class TrackBox extends CacheMap {
|
|
|
1578
1632
|
}
|
|
1579
1633
|
const id = items[i].id, size = dynamicSize ? this.get(id)?.[sizeProperty] || typicalItemSize : typicalItemSize;
|
|
1580
1634
|
if (id !== stickyItem?.id && id !== endStickyItem?.id) {
|
|
1581
|
-
const isOdd = i % 2 != 0, snapped = snap && (
|
|
1582
|
-
x: isVertical ?
|
|
1583
|
-
y: isVertical ? pos :
|
|
1635
|
+
const isOdd = i % 2 != 0, sticky = itemConfigMap[id]?.sticky ?? 0, selectable = itemConfigMap[id]?.selectable ?? true, snapped = snap && (sticky === 1 && pos <= scrollSize || sticky === 2 && pos >= scrollSize + boundsSize - size), measures = {
|
|
1636
|
+
x: isVertical ? sticky === 1 ? 0 : boundsSize - size : pos,
|
|
1637
|
+
y: isVertical ? pos : sticky === 2 ? boundsSize - size : 0,
|
|
1584
1638
|
width: isVertical ? normalizedItemWidth : size,
|
|
1585
1639
|
height: isVertical ? size : normalizedItemHeight,
|
|
1586
1640
|
delta: 0,
|
|
@@ -1588,7 +1642,8 @@ class TrackBox extends CacheMap {
|
|
|
1588
1642
|
odd: isOdd,
|
|
1589
1643
|
even: !isOdd,
|
|
1590
1644
|
isVertical,
|
|
1591
|
-
|
|
1645
|
+
selectable,
|
|
1646
|
+
sticky: sticky,
|
|
1592
1647
|
snap,
|
|
1593
1648
|
snapped: false,
|
|
1594
1649
|
snappedOut: false,
|
|
@@ -1601,7 +1656,7 @@ class TrackBox extends CacheMap {
|
|
|
1601
1656
|
}
|
|
1602
1657
|
const itemData = items[i];
|
|
1603
1658
|
const item = { index: i, id, measures, data: itemData, config };
|
|
1604
|
-
if (!nextSticky && stickyItemIndex < i &&
|
|
1659
|
+
if (!nextSticky && stickyItemIndex < i && sticky === 1 && (pos <= scrollSize + size + stickyItemSize)) {
|
|
1605
1660
|
item.measures.x = isVertical ? 0 : snapped ? actualSnippedPosition : pos;
|
|
1606
1661
|
item.measures.y = isVertical ? snapped ? actualSnippedPosition : pos : 0;
|
|
1607
1662
|
nextSticky = item;
|
|
@@ -1609,7 +1664,7 @@ class TrackBox extends CacheMap {
|
|
|
1609
1664
|
nextSticky.measures.delta = isVertical ? (item.measures.y - scrollSize) : (item.measures.x - scrollSize);
|
|
1610
1665
|
nextSticky.config.zIndex = '3';
|
|
1611
1666
|
}
|
|
1612
|
-
else if (!nextEndSticky && endStickyItemIndex > i &&
|
|
1667
|
+
else if (!nextEndSticky && endStickyItemIndex > i && sticky === 2 && (pos >= scrollSize + boundsSize - size - endStickyItemSize)) {
|
|
1613
1668
|
item.measures.x = isVertical ? 0 : snapped ? actualEndSnippedPosition - size : pos;
|
|
1614
1669
|
item.measures.y = isVertical ? snapped ? actualEndSnippedPosition - size : pos : 0;
|
|
1615
1670
|
nextEndSticky = item;
|
|
@@ -1796,6 +1851,11 @@ class NgVirtualListComponent {
|
|
|
1796
1851
|
* Sets the selected items.
|
|
1797
1852
|
*/
|
|
1798
1853
|
selectedIds = input(undefined);
|
|
1854
|
+
/**
|
|
1855
|
+
* If false, the element is selected using the config.select method passed to the template;
|
|
1856
|
+
* if true, the element is selected by clicking on it. The default value is true.
|
|
1857
|
+
*/
|
|
1858
|
+
selectByClick = input(DEFAULT_SELECT_BY_CLICK);
|
|
1799
1859
|
/**
|
|
1800
1860
|
* Determines whether elements will snap. Default value is "true".
|
|
1801
1861
|
*/
|
|
@@ -1813,10 +1873,19 @@ class NgVirtualListComponent {
|
|
|
1813
1873
|
itemRenderer = input.required();
|
|
1814
1874
|
_itemRenderer = signal(undefined);
|
|
1815
1875
|
/**
|
|
1816
|
-
*
|
|
1817
|
-
*
|
|
1876
|
+
* @deprecated
|
|
1877
|
+
* Use `itemConfigMap` instead.
|
|
1878
|
+
*/
|
|
1879
|
+
stickyMap = input();
|
|
1880
|
+
/**
|
|
1881
|
+
* Sets sticky position and selectable for the list item element. If sticky position is greater than 0, then sticky position is applied.
|
|
1882
|
+
* 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`.
|
|
1883
|
+
* selectable determines whether an element can be selected or not. Default value is `true`.
|
|
1884
|
+
* @link https://github.com/DjonnyX/ng-virtual-list/blob/20.x/projects/ng-virtual-list/src/lib/models/item-config-map.model.ts
|
|
1885
|
+
* @author Evgenii Grebennikov
|
|
1886
|
+
* @email djonnyx@gmail.com
|
|
1818
1887
|
*/
|
|
1819
|
-
|
|
1888
|
+
itemConfigMap = input({});
|
|
1820
1889
|
_itemSizeOptions = {
|
|
1821
1890
|
transform: (v) => {
|
|
1822
1891
|
if (v === undefined) {
|
|
@@ -1876,7 +1945,7 @@ class NgVirtualListComponent {
|
|
|
1876
1945
|
*/
|
|
1877
1946
|
snappingMethod = input(DEFAULT_SNAPPING_METHOD);
|
|
1878
1947
|
/**
|
|
1879
|
-
* Method for selecting list items.
|
|
1948
|
+
* Method for selecting list items. Default value is 'none'.
|
|
1880
1949
|
* 'select' - List items are selected one by one.
|
|
1881
1950
|
* 'multi-select' - Multiple selection of list items.
|
|
1882
1951
|
* 'none' - List items are not selectable.
|
|
@@ -1985,11 +2054,14 @@ class NgVirtualListComponent {
|
|
|
1985
2054
|
this._initialized = signal(false);
|
|
1986
2055
|
this.$initialized = toObservable(this._initialized);
|
|
1987
2056
|
this._trackBox.displayComponents = this._displayComponents;
|
|
1988
|
-
const $trackBy = toObservable(this.trackBy);
|
|
2057
|
+
const $trackBy = toObservable(this.trackBy), $selectByClick = toObservable(this.selectByClick);
|
|
2058
|
+
$selectByClick.pipe(takeUntilDestroyed(), tap(v => {
|
|
2059
|
+
this._service.selectByClick = v;
|
|
2060
|
+
})).subscribe();
|
|
1989
2061
|
$trackBy.pipe(takeUntilDestroyed(), tap(v => {
|
|
1990
2062
|
this._trackBox.trackingPropertyName = v;
|
|
1991
2063
|
})).subscribe();
|
|
1992
|
-
const $bounds = toObservable(this._bounds).pipe(filter(b => !!b)), $items = toObservable(this.items).pipe(map(i => !i ? [] : i)), $scrollSize = toObservable(this._scrollSize), $itemSize = toObservable(this.itemSize).pipe(map(v => v <= 0 ? DEFAULT_ITEM_SIZE : v)), $bufferSize = toObservable(this.bufferSize).pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $maxBufferSize = toObservable(this.maxBufferSize).pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $
|
|
2064
|
+
const $bounds = toObservable(this._bounds).pipe(filter(b => !!b)), $items = toObservable(this.items).pipe(map(i => !i ? [] : i)), $scrollSize = toObservable(this._scrollSize), $itemSize = toObservable(this.itemSize).pipe(map(v => v <= 0 ? DEFAULT_ITEM_SIZE : v)), $bufferSize = toObservable(this.bufferSize).pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $maxBufferSize = toObservable(this.maxBufferSize).pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $itemConfigMap = toObservable(this.itemConfigMap).pipe(map(v => !v ? {} : v)), $snap = toObservable(this.snap), $isVertical = toObservable(this.direction).pipe(map(v => this.getIsVertical(v || DEFAULT_DIRECTION))), $dynamicSize = toObservable(this.dynamicSize), $enabledBufferOptimization = toObservable(this.enabledBufferOptimization), $snappingMethod = toObservable(this.snappingMethod).pipe(map(v => this.getIsSnappingMethodAdvanced(v || DEFAULT_SNAPPING_METHOD))), $methodForSelecting = toObservable(this.methodForSelecting), $selectedIds = toObservable(this.selectedIds), $cacheVersion = toObservable(this._cacheVersion);
|
|
1993
2065
|
$isVertical.pipe(takeUntilDestroyed(), tap(v => {
|
|
1994
2066
|
this._isVertical = v;
|
|
1995
2067
|
const el = this._elementRef.nativeElement;
|
|
@@ -2028,14 +2100,14 @@ class NgVirtualListComponent {
|
|
|
2028
2100
|
$dynamicSize.pipe(takeUntilDestroyed(), tap(dynamicSize => {
|
|
2029
2101
|
this.listenCacheChangesIfNeed(dynamicSize);
|
|
2030
2102
|
})).subscribe();
|
|
2031
|
-
combineLatest([this.$initialized, $bounds, $items, $
|
|
2103
|
+
combineLatest([this.$initialized, $bounds, $items, $itemConfigMap, $scrollSize, $itemSize,
|
|
2032
2104
|
$bufferSize, $maxBufferSize, $snap, $isVertical, $dynamicSize, $enabledBufferOptimization, $cacheVersion,
|
|
2033
|
-
]).pipe(takeUntilDestroyed(), distinctUntilChanged(), filter(([initialized]) => !!initialized), switchMap(([, bounds, items,
|
|
2105
|
+
]).pipe(takeUntilDestroyed(), distinctUntilChanged(), filter(([initialized]) => !!initialized), switchMap(([, bounds, items, itemConfigMap, scrollSize, itemSize, bufferSize, maxBufferSize, snap, isVertical, dynamicSize, enabledBufferOptimization, cacheVersion,]) => {
|
|
2034
2106
|
let actualScrollSize = (this._isVertical ? this._container()?.nativeElement.scrollTop ?? 0 : this._container()?.nativeElement.scrollLeft) ?? 0;
|
|
2035
2107
|
const { width, height } = bounds, opts = {
|
|
2036
2108
|
bounds: { width, height }, dynamicSize, isVertical, itemSize,
|
|
2037
2109
|
bufferSize, maxBufferSize, scrollSize: actualScrollSize, snap, enabledBufferOptimization,
|
|
2038
|
-
}, { displayItems, totalSize } = this._trackBox.updateCollection(items,
|
|
2110
|
+
}, { displayItems, totalSize } = this._trackBox.updateCollection(items, itemConfigMap, opts);
|
|
2039
2111
|
this.resetBoundsSize(isVertical, totalSize);
|
|
2040
2112
|
this.createDisplayComponentsIfNeed(displayItems);
|
|
2041
2113
|
this.tracking();
|
|
@@ -2067,10 +2139,19 @@ class NgVirtualListComponent {
|
|
|
2067
2139
|
this._service.$itemClick.pipe(takeUntilDestroyed(), tap(v => {
|
|
2068
2140
|
this.onItemClick.emit(v);
|
|
2069
2141
|
})).subscribe();
|
|
2070
|
-
|
|
2071
|
-
|
|
2142
|
+
let isSelectedIdsFirstEmit = 0;
|
|
2143
|
+
this._service.$selectedIds.pipe(takeUntilDestroyed(), distinctUntilChanged(), tap(v => {
|
|
2144
|
+
if (this.isSingleSelecting || (this.isMultiSelecting && isSelectedIdsFirstEmit >= 2)) {
|
|
2145
|
+
const curr = this.selectedIds();
|
|
2146
|
+
if ((this.isSingleSelecting && JSON.stringify(v) !== JSON.stringify(curr)) || (isSelectedIdsFirstEmit === 2 && JSON.stringify(v) !== JSON.stringify(curr)) || isSelectedIdsFirstEmit > 2) {
|
|
2147
|
+
this.onSelect.emit(v);
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
if (isSelectedIdsFirstEmit < 3) {
|
|
2151
|
+
isSelectedIdsFirstEmit++;
|
|
2152
|
+
}
|
|
2072
2153
|
})).subscribe();
|
|
2073
|
-
$selectedIds.pipe(takeUntilDestroyed(), tap(v => {
|
|
2154
|
+
$selectedIds.pipe(takeUntilDestroyed(), distinctUntilChanged(), tap(v => {
|
|
2074
2155
|
this._service.setSelectedIds(v);
|
|
2075
2156
|
})).subscribe();
|
|
2076
2157
|
}
|
|
@@ -2200,19 +2281,19 @@ class NgVirtualListComponent {
|
|
|
2200
2281
|
if (container) {
|
|
2201
2282
|
container.nativeElement.removeEventListener(SCROLL, this._onScrollHandler);
|
|
2202
2283
|
}
|
|
2203
|
-
const { width, height } = this._bounds() || { width: DEFAULT_LIST_SIZE, height: DEFAULT_LIST_SIZE },
|
|
2284
|
+
const { width, height } = this._bounds() || { width: DEFAULT_LIST_SIZE, height: DEFAULT_LIST_SIZE }, itemConfigMap = this.itemConfigMap(), items = this.items(), isVertical = this._isVertical, delta = this._trackBox.delta, opts = {
|
|
2204
2285
|
bounds: { width, height }, collection: items, dynamicSize, isVertical: this._isVertical, itemSize,
|
|
2205
2286
|
bufferSize: this.bufferSize(), maxBufferSize: this.maxBufferSize(),
|
|
2206
2287
|
scrollSize: (isVertical ? container.nativeElement.scrollTop : container.nativeElement.scrollLeft) + delta,
|
|
2207
2288
|
snap: this.snap(), fromItemId: id, enabledBufferOptimization: this.enabledBufferOptimization(),
|
|
2208
|
-
}, scrollSize = this._trackBox.getItemPosition(id,
|
|
2289
|
+
}, scrollSize = this._trackBox.getItemPosition(id, itemConfigMap, opts), params = { [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollSize, behavior };
|
|
2209
2290
|
if (scrollSize === -1) {
|
|
2210
2291
|
container.nativeElement.addEventListener(SCROLL, this._onScrollHandler);
|
|
2211
2292
|
return;
|
|
2212
2293
|
}
|
|
2213
2294
|
this._trackBox.clearDelta();
|
|
2214
2295
|
if (container) {
|
|
2215
|
-
const { displayItems, totalSize } = this._trackBox.updateCollection(items,
|
|
2296
|
+
const { displayItems, totalSize } = this._trackBox.updateCollection(items, itemConfigMap, {
|
|
2216
2297
|
...opts, scrollSize, fromItemId: isLastIteration ? undefined : id,
|
|
2217
2298
|
}), delta = this._trackBox.delta;
|
|
2218
2299
|
this._trackBox.clearDelta();
|
|
@@ -2220,7 +2301,7 @@ class NgVirtualListComponent {
|
|
|
2220
2301
|
this.resetBoundsSize(isVertical, totalSize);
|
|
2221
2302
|
this.createDisplayComponentsIfNeed(displayItems);
|
|
2222
2303
|
this.tracking();
|
|
2223
|
-
const _scrollSize = this._trackBox.getItemPosition(id,
|
|
2304
|
+
const _scrollSize = this._trackBox.getItemPosition(id, itemConfigMap, { ...opts, scrollSize: actualScrollSize, fromItemId: id });
|
|
2224
2305
|
if (_scrollSize === -1) {
|
|
2225
2306
|
container.nativeElement.addEventListener(SCROLL, this._onScrollHandler);
|
|
2226
2307
|
return;
|
|
@@ -2334,7 +2415,7 @@ class NgVirtualListComponent {
|
|
|
2334
2415
|
}
|
|
2335
2416
|
}
|
|
2336
2417
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: NgVirtualListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2337
|
-
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 }, 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 }, stickyMap: { classPropertyName: "stickyMap", publicName: "stickyMap", 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 }, itemsOffset: { classPropertyName: "itemsOffset", publicName: "itemsOffset", 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" }, 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 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 });
|
|
2418
|
+
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 }, selectByClick: { classPropertyName: "selectByClick", publicName: "selectByClick", 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 }, stickyMap: { classPropertyName: "stickyMap", publicName: "stickyMap", isSignal: true, isRequired: false, 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 }, itemsOffset: { classPropertyName: "itemsOffset", publicName: "itemsOffset", 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" }, 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 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 });
|
|
2338
2419
|
}
|
|
2339
2420
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: NgVirtualListComponent, decorators: [{
|
|
2340
2421
|
type: Component,
|