ng-virtual-list 0.7.2 → 14.0.0

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.
Files changed (66) hide show
  1. package/README.md +44 -71
  2. package/esm2020/lib/components/ng-virtual-list-item.component.mjs +80 -0
  3. package/esm2020/lib/const/index.mjs +34 -0
  4. package/esm2020/lib/enums/direction.mjs +2 -0
  5. package/esm2020/lib/enums/directions.mjs +18 -0
  6. package/esm2020/lib/enums/index.mjs +3 -0
  7. package/esm2020/lib/models/collection.model.mjs +3 -0
  8. package/esm2020/lib/models/index.mjs +2 -0
  9. package/esm2020/lib/models/item.model.mjs +3 -0
  10. package/esm2020/lib/models/render-collection.model.mjs +3 -0
  11. package/esm2020/lib/models/render-item-config.model.mjs +2 -0
  12. package/esm2020/lib/models/render-item.model.mjs +3 -0
  13. package/esm2020/lib/models/sticky-map.model.mjs +2 -0
  14. package/esm2020/lib/ng-virtual-list.component.mjs +510 -0
  15. package/esm2020/lib/ng-virtual-list.module.mjs +20 -0
  16. package/esm2020/lib/types/id.mjs +2 -0
  17. package/esm2020/lib/types/index.mjs +2 -0
  18. package/esm2020/lib/types/rect.mjs +2 -0
  19. package/esm2020/lib/types/size.mjs +2 -0
  20. package/esm2020/lib/utils/cacheMap.mjs +52 -0
  21. package/esm2020/lib/utils/debounce.mjs +31 -0
  22. package/esm2020/lib/utils/disposableComponent.mjs +29 -0
  23. package/esm2020/lib/utils/eventEmitter.mjs +106 -0
  24. package/esm2020/lib/utils/index.mjs +8 -0
  25. package/esm2020/lib/utils/isDirection.mjs +15 -0
  26. package/esm2020/lib/utils/toggleClassName.mjs +15 -0
  27. package/esm2020/lib/utils/trackBox.mjs +352 -0
  28. package/esm2020/lib/utils/tracker.mjs +108 -0
  29. package/esm2020/ng-virtual-list.mjs +5 -0
  30. package/esm2020/public-api.mjs +8 -0
  31. package/fesm2015/ng-virtual-list.mjs +1360 -0
  32. package/fesm2015/ng-virtual-list.mjs.map +1 -0
  33. package/fesm2020/ng-virtual-list.mjs +1359 -0
  34. package/fesm2020/ng-virtual-list.mjs.map +1 -0
  35. package/index.d.ts +5 -5
  36. package/lib/components/ng-virtual-list-item.component.d.ts +28 -35
  37. package/lib/const/index.d.ts +32 -31
  38. package/lib/enums/direction.d.ts +8 -2
  39. package/lib/enums/directions.d.ts +16 -4
  40. package/lib/enums/index.d.ts +4 -4
  41. package/lib/models/collection.model.d.ts +9 -3
  42. package/lib/models/index.d.ts +4 -4
  43. package/lib/models/item.model.d.ts +14 -5
  44. package/lib/models/render-collection.model.d.ts +9 -3
  45. package/lib/models/render-item-config.model.d.ts +33 -7
  46. package/lib/models/render-item.model.d.ts +28 -10
  47. package/lib/models/sticky-map.model.d.ts +12 -6
  48. package/lib/ng-virtual-list.component.d.ts +151 -110
  49. package/lib/ng-virtual-list.module.d.ts +9 -0
  50. package/lib/types/id.d.ts +7 -1
  51. package/lib/types/index.d.ts +4 -4
  52. package/lib/types/rect.d.ts +17 -5
  53. package/lib/types/size.d.ts +16 -4
  54. package/lib/utils/cacheMap.d.ts +34 -31
  55. package/lib/utils/debounce.d.ts +16 -10
  56. package/lib/utils/disposableComponent.d.ts +15 -0
  57. package/lib/utils/eventEmitter.d.ts +40 -37
  58. package/lib/utils/index.d.ts +7 -6
  59. package/lib/utils/isDirection.d.ts +8 -2
  60. package/lib/utils/toggleClassName.d.ts +7 -1
  61. package/lib/utils/trackBox.d.ts +113 -73
  62. package/lib/utils/tracker.d.ts +38 -38
  63. package/package.json +18 -6
  64. package/public-api.d.ts +4 -3
  65. package/fesm2022/ng-virtual-list.mjs +0 -942
  66. package/fesm2022/ng-virtual-list.mjs.map +0 -1
@@ -1,942 +0,0 @@
1
- import * as i0 from '@angular/core';
2
- import { signal, inject, ElementRef, ChangeDetectionStrategy, Component, viewChild, output, input, ViewContainerRef, ViewChild, ViewEncapsulation } from '@angular/core';
3
- import * as i1 from '@angular/common';
4
- import { CommonModule } from '@angular/common';
5
- import { toObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop';
6
- import { BehaviorSubject, filter, map, tap, combineLatest, distinctUntilChanged, switchMap, of } from 'rxjs';
7
-
8
- var Directions;
9
- (function (Directions) {
10
- Directions["HORIZONTAL"] = "horizontal";
11
- Directions["VERTICAL"] = "vertical";
12
- })(Directions || (Directions = {}));
13
-
14
- const DEFAULT_ITEM_SIZE = 24;
15
- const DEFAULT_ITEMS_OFFSET = 2;
16
- const DEFAULT_LIST_SIZE = 400;
17
- const DEFAULT_SNAP = false;
18
- const DEFAULT_SNAP_TO_ITEM = false;
19
- const DEFAULT_DYNAMIC_SIZE = false;
20
- const TRACK_BY_PROPERTY_NAME = 'id';
21
- const DEFAULT_DIRECTION = Directions.VERTICAL;
22
- const DISPLAY_OBJECTS_LENGTH_MESUREMENT_ERROR = 1;
23
- // presets
24
- const BEHAVIOR_INSTANT = 'instant';
25
- const BEHAVIOR_AUTO = 'auto';
26
- const VISIBILITY_VISIBLE = 'visible';
27
- const VISIBILITY_HIDDEN = 'hidden';
28
- const SIZE_100_PERSENT = '100%';
29
- const SIZE_AUTO = 'auto';
30
- const POSITION_ABSOLUTE = 'absolute';
31
- const POSITION_STICKY = 'sticky';
32
- const TRANSLATE_3D = 'translate3d';
33
- const ZEROS_TRANSLATE_3D = `${TRANSLATE_3D}(0,0,0)`;
34
- const TOP_PROP_NAME = 'top';
35
- const LEFT_PROP_NAME = 'left';
36
- const X_PROP_NAME = 'x';
37
- const Y_PROP_NAME = 'y';
38
- const WIDTH_PROP_NAME = 'width';
39
- const HEIGHT_PROP_NAME = 'height';
40
- const PX = 'px';
41
- const SCROLL = 'scroll';
42
- const SCROLL_END = 'scrollend';
43
- const CLASS_LIST_VERTICAL = 'vertical';
44
- const CLASS_LIST_HORIZONTAL = 'horizontal';
45
-
46
- /**
47
- * Virtual list item component
48
- * @homepage https://github.com/DjonnyX/ng-virtual-list/tree/main/projects/ng-virtual-list
49
- * @author Evgenii Grebennikov
50
- * @email djonnyx@gmail.com
51
- */
52
- class NgVirtualListItemComponent {
53
- static __nextId = 0;
54
- _id;
55
- get id() {
56
- return this._id;
57
- }
58
- get config() {
59
- return { ...this._data?.config || {} };
60
- }
61
- data = signal(undefined);
62
- _data = undefined;
63
- set item(v) {
64
- if (this._data === v) {
65
- return;
66
- }
67
- const data = this._data = v;
68
- if (data) {
69
- const styles = this._elementRef.nativeElement.style;
70
- styles.zIndex = data.config.sticky;
71
- if (data.config.snapped) {
72
- styles.transform = ZEROS_TRANSLATE_3D;
73
- styles.position = POSITION_STICKY;
74
- }
75
- else {
76
- styles.position = POSITION_ABSOLUTE;
77
- styles.transform = `${TRANSLATE_3D}(${data.config.isVertical ? 0 : data.measures.x}${PX}, ${data.config.isVertical ? data.measures.y : 0}${PX} , 0)`;
78
- }
79
- styles.height = data.config.isVertical ? data.config.dynamic ? SIZE_AUTO : `${data.measures.height}${PX}` : SIZE_100_PERSENT;
80
- styles.width = data.config.isVertical ? SIZE_100_PERSENT : data.config.dynamic ? SIZE_AUTO : `${data.measures.width}${PX}`;
81
- }
82
- this.data.set(v);
83
- }
84
- get itemId() {
85
- return this._data?.id;
86
- }
87
- itemRenderer = signal(undefined);
88
- set renderer(v) {
89
- this.itemRenderer.set(v);
90
- }
91
- _elementRef = inject((ElementRef));
92
- constructor() {
93
- this._id = NgVirtualListItemComponent.__nextId = NgVirtualListItemComponent.__nextId === Number.MAX_SAFE_INTEGER
94
- ? 0 : NgVirtualListItemComponent.__nextId + 1;
95
- }
96
- getBounds() {
97
- const el = this._elementRef.nativeElement, { width, height, left, top } = el.getBoundingClientRect();
98
- return { width, height, x: left, y: top };
99
- }
100
- showIfNeed() {
101
- const styles = this._elementRef.nativeElement.style;
102
- if (styles.visibility === VISIBILITY_VISIBLE) {
103
- return;
104
- }
105
- styles.visibility = VISIBILITY_VISIBLE;
106
- }
107
- hide() {
108
- const styles = this._elementRef.nativeElement.style;
109
- if (styles.visibility === VISIBILITY_HIDDEN) {
110
- return;
111
- }
112
- styles.visibility = VISIBILITY_HIDDEN;
113
- }
114
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: NgVirtualListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
115
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: NgVirtualListItemComponent, isStandalone: true, selector: "ng-virtual-list-item", host: { classAttribute: "ngvl__item" }, ngImport: i0, template: "@let item = data();\r\n@let renderer = itemRenderer();\r\n\r\n@if (item) {\r\n<li #listItem part=\"item\" class=\"ngvl-item__container\" [ngClass]=\"{snipped: item.config.snapped}\">\r\n @if (renderer) {\r\n <ng-container [ngTemplateOutlet]=\"renderer\" [ngTemplateOutletContext]=\"{data: item.data || {}, config: config}\" />\r\n }\r\n</li>\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 });
116
- }
117
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: NgVirtualListItemComponent, decorators: [{
118
- type: Component,
119
- args: [{ selector: 'ng-virtual-list-item', imports: [CommonModule], host: {
120
- 'class': 'ngvl__item',
121
- }, changeDetection: ChangeDetectionStrategy.OnPush, template: "@let item = data();\r\n@let renderer = itemRenderer();\r\n\r\n@if (item) {\r\n<li #listItem part=\"item\" class=\"ngvl-item__container\" [ngClass]=\"{snipped: item.config.snapped}\">\r\n @if (renderer) {\r\n <ng-container [ngTemplateOutlet]=\"renderer\" [ngTemplateOutletContext]=\"{data: item.data || {}, config: config}\" />\r\n }\r\n</li>\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"] }]
122
- }], ctorParameters: () => [] });
123
-
124
- const HORIZONTAL_ALIASES = [Directions.HORIZONTAL, 'horizontal'], VERTICAL_ALIASES = [Directions.VERTICAL, 'vertical'];
125
- const isDirection = (src, expected) => {
126
- if (HORIZONTAL_ALIASES.includes(expected)) {
127
- return HORIZONTAL_ALIASES.includes(src);
128
- }
129
- return VERTICAL_ALIASES.includes(src);
130
- };
131
-
132
- /**
133
- * Simple debounce function.
134
- * @homepage https://github.com/DjonnyX/ng-virtual-list/tree/main/projects/ng-virtual-list
135
- * @author Evgenii Grebennikov
136
- * @email djonnyx@gmail.com
137
- */
138
- const debounce = (cb, debounceTime = 0) => {
139
- let timeout;
140
- const dispose = () => {
141
- if (timeout !== undefined) {
142
- clearTimeout(timeout);
143
- }
144
- };
145
- const execute = (...args) => {
146
- dispose();
147
- timeout = setTimeout(() => {
148
- cb(...args);
149
- }, debounceTime);
150
- };
151
- return {
152
- execute,
153
- dispose,
154
- };
155
- };
156
-
157
- const toggleClassName = (el, className, remove = false) => {
158
- if (!el.classList.contains(className)) {
159
- el.classList.add(className);
160
- }
161
- else if (remove) {
162
- el.classList.remove(className);
163
- }
164
- };
165
-
166
- /**
167
- * Tracks display items by property
168
- * @homepage https://github.com/DjonnyX/ng-virtual-list/tree/main/projects/ng-virtual-list
169
- * @author Evgenii Grebennikov
170
- * @email djonnyx@gmail.com
171
- */
172
- class Tracker {
173
- /**
174
- * display objects dictionary of indexes by id
175
- */
176
- _displayObjectIndexMapById = {};
177
- set displayObjectIndexMapById(v) {
178
- if (this._displayObjectIndexMapById === v) {
179
- return;
180
- }
181
- this._displayObjectIndexMapById = v;
182
- }
183
- get displayObjectIndexMapById() {
184
- return this._displayObjectIndexMapById;
185
- }
186
- /**
187
- * Dictionary displayItems propertyNameId by items propertyNameId
188
- */
189
- _trackMap = {};
190
- get trackMap() {
191
- return this._trackMap;
192
- }
193
- _trackingPropertyName;
194
- constructor(trackingPropertyName) {
195
- this._trackingPropertyName = trackingPropertyName;
196
- }
197
- /**
198
- * tracking by propName
199
- */
200
- track(items, components, afterComponentSetup) {
201
- if (!items) {
202
- return;
203
- }
204
- const idPropName = this._trackingPropertyName, untrackedItems = [...components];
205
- for (let i = 0, l = items.length; i < l; i++) {
206
- const item = items[i], itemTrackingProperty = item[idPropName];
207
- if (this._trackMap) {
208
- const diId = this._trackMap[itemTrackingProperty];
209
- if (this._trackMap.hasOwnProperty(itemTrackingProperty)) {
210
- const lastIndex = this._displayObjectIndexMapById[diId], el = components[lastIndex];
211
- this._checkComponentProperty(el?.instance);
212
- const elId = el?.instance?.[itemTrackingProperty];
213
- if (el && elId === diId) {
214
- const indexByUntrackedItems = untrackedItems.findIndex(v => {
215
- this._checkComponentProperty(v.instance);
216
- return v.instance[itemTrackingProperty] === elId;
217
- });
218
- if (indexByUntrackedItems > -1) {
219
- el.instance.item = item;
220
- if (afterComponentSetup !== undefined) {
221
- afterComponentSetup(el.instance, item);
222
- }
223
- untrackedItems.splice(indexByUntrackedItems, 1);
224
- continue;
225
- }
226
- }
227
- delete this._trackMap[itemTrackingProperty];
228
- }
229
- }
230
- if (untrackedItems.length > 0) {
231
- const el = untrackedItems.shift(), item = items[i];
232
- if (el) {
233
- el.instance.item = item;
234
- if (this._trackMap) {
235
- this._checkComponentProperty(el.instance);
236
- this._trackMap[itemTrackingProperty] = el.instance[itemTrackingProperty];
237
- }
238
- if (afterComponentSetup !== undefined) {
239
- afterComponentSetup(el.instance, item);
240
- }
241
- }
242
- }
243
- }
244
- if (untrackedItems.length) {
245
- throw Error('Tracking by id caused an error.');
246
- }
247
- }
248
- untrackComponentByIdProperty(component) {
249
- if (!component) {
250
- return;
251
- }
252
- const propertyIdName = this._trackingPropertyName;
253
- this._checkComponentProperty(component);
254
- if (this._trackMap && component[propertyIdName] !== undefined) {
255
- delete this._trackMap[propertyIdName];
256
- }
257
- }
258
- _checkComponentProperty(component) {
259
- if (!component) {
260
- return;
261
- }
262
- const propertyIdName = this._trackingPropertyName;
263
- try {
264
- component[propertyIdName];
265
- }
266
- catch (err) {
267
- throw Error(`Property ${propertyIdName} does not exist.`);
268
- }
269
- }
270
- dispose() {
271
- this._trackMap = null;
272
- }
273
- }
274
-
275
- /**
276
- * Simple event emitter
277
- * @homepage https://github.com/DjonnyX/ng-virtual-list/tree/main/projects/ng-virtual-list
278
- * @author Evgenii Grebennikov
279
- * @email djonnyx@gmail.com
280
- */
281
- class EventEmitter {
282
- _listeners = {};
283
- _disposed = false;
284
- constructor() { }
285
- /**
286
- * Emits the event
287
- */
288
- dispatch(event, ...args) {
289
- const ctx = this;
290
- const listeners = this._listeners[event];
291
- if (Array.isArray(listeners)) {
292
- for (let i = 0, l = listeners.length; i < l; i++) {
293
- const listener = listeners[i];
294
- if (listener) {
295
- listener.apply(ctx, args);
296
- }
297
- }
298
- }
299
- }
300
- /**
301
- * Emits the event async
302
- */
303
- dispatchAsync(event, ...args) {
304
- queueMicrotask(() => {
305
- if (this._disposed) {
306
- return;
307
- }
308
- this.dispatch(event, ...args);
309
- });
310
- }
311
- /**
312
- * Returns true if the event listener is already subscribed.
313
- */
314
- hasEventListener(eventName, handler) {
315
- const event = eventName;
316
- if (this._listeners.hasOwnProperty(event)) {
317
- const listeners = this._listeners[event];
318
- const index = listeners.findIndex(v => v === handler);
319
- if (index > -1) {
320
- return true;
321
- }
322
- }
323
- return false;
324
- }
325
- /**
326
- * Add event listener
327
- */
328
- addEventListener(eventName, handler) {
329
- const event = eventName;
330
- if (!this._listeners.hasOwnProperty(event)) {
331
- this._listeners[event] = [];
332
- }
333
- this._listeners[event].push(handler);
334
- }
335
- /**
336
- * Remove event listener
337
- */
338
- removeEventListener(eventName, handler) {
339
- const event = eventName;
340
- if (!this._listeners.hasOwnProperty(event)) {
341
- return;
342
- }
343
- const listeners = this._listeners[event], index = listeners.findIndex(v => v === handler);
344
- if (index > -1) {
345
- listeners.splice(index, 1);
346
- if (listeners.length === 0) {
347
- delete this._listeners[event];
348
- }
349
- }
350
- }
351
- /**
352
- * Remove all listeners
353
- */
354
- removeAllListeners() {
355
- const events = Object.keys(this._listeners);
356
- while (events.length > 0) {
357
- const event = events.pop();
358
- if (event) {
359
- const listeners = this._listeners[event];
360
- if (Array.isArray(listeners)) {
361
- while (listeners.length > 0) {
362
- const listener = listeners.pop();
363
- if (listener) {
364
- this.removeEventListener(event, listener);
365
- }
366
- }
367
- }
368
- }
369
- }
370
- }
371
- dispose() {
372
- this._disposed = true;
373
- this.removeAllListeners();
374
- }
375
- }
376
-
377
- /**
378
- * Cache map.
379
- * Emits a change event on each mutation.
380
- * @homepage https://github.com/DjonnyX/ng-virtual-list/tree/main/projects/ng-virtual-list
381
- * @author Evgenii Grebennikov
382
- * @email djonnyx@gmail.com
383
- */
384
- class CacheMap extends EventEmitter {
385
- _map = new Map();
386
- _version = 0;
387
- get version() {
388
- return this._version;
389
- }
390
- constructor() {
391
- super();
392
- }
393
- bumpVersion() {
394
- this._version = this._version === Number.MAX_SAFE_INTEGER ? 0 : this._version + 1;
395
- }
396
- fireChange() {
397
- this.dispatch('change', this.version);
398
- }
399
- set(id, bounds) {
400
- if (this._map.has(id) && JSON.stringify(this._map.get(id)) === JSON.stringify(bounds)) {
401
- return this._map;
402
- }
403
- const v = this._map.set(id, bounds);
404
- this.bumpVersion();
405
- this.fireChange();
406
- return v;
407
- }
408
- has(id) {
409
- return this._map.has(id);
410
- }
411
- get(id) {
412
- return this._map.get(id);
413
- }
414
- forEach(callbackfn, thisArg) {
415
- return this._map.forEach(callbackfn, thisArg);
416
- }
417
- dispose() {
418
- super.dispose();
419
- this._map.clear();
420
- }
421
- }
422
-
423
- const TRACK_BOX_CHANGE_EVENT_NAME = 'change';
424
- /**
425
- * An object that performs tracking, calculations and caching.
426
- * @homepage https://github.com/DjonnyX/ng-virtual-list/tree/main/projects/ng-virtual-list
427
- * @author Evgenii Grebennikov
428
- * @email djonnyx@gmail.com
429
- */
430
- class TrackBox extends CacheMap {
431
- _tracker;
432
- _items;
433
- set items(v) {
434
- if (this._items === v) {
435
- return;
436
- }
437
- this._items = v;
438
- }
439
- _displayComponents;
440
- set displayComponents(v) {
441
- if (this._displayComponents === v) {
442
- return;
443
- }
444
- this._displayComponents = v;
445
- }
446
- constructor(trackingPropertyName) {
447
- super();
448
- this._tracker = new Tracker(trackingPropertyName);
449
- }
450
- set(id, bounds) {
451
- if (this._map.has(id) && JSON.stringify(this._map.get(id)) === JSON.stringify(bounds)) {
452
- return this._map;
453
- }
454
- const v = this._map.set(id, bounds);
455
- this.bumpVersion();
456
- this.fireChange();
457
- return v;
458
- }
459
- _fireChanges = (version) => {
460
- this.dispatch(TRACK_BOX_CHANGE_EVENT_NAME, version);
461
- };
462
- _debounceChanges = debounce(this._fireChanges, 0);
463
- fireChange() {
464
- this._debounceChanges.execute(this._version);
465
- }
466
- recalculateMetrics(options) {
467
- const { bounds, collection, dynamicSize, isVertical, itemSize, itemsOffset, scrollSize, snap, } = options;
468
- const { width, height } = bounds, sizeProperty = isVertical ? HEIGHT_PROP_NAME : WIDTH_PROP_NAME, size = isVertical ? height : width, weightToDisplayEnd = scrollSize + height, totalLength = collection.length, typicalItemSize = itemSize, totalSize = dynamicSize ? this.getBoundsFromCache(collection, typicalItemSize, isVertical) : totalLength * typicalItemSize, snippedPos = Math.floor(scrollSize), leftItemsWeights = [];
469
- let itemsFromStartToScrollEnd = -1, itemsFromDisplayEndToOffsetEnd = 0, itemsFromStartToDisplayEnd = -1, leftItemLength = 0, rightItemLength = 0, leftItemsWeight = 0, rightItemsWeight = 0, leftHiddenItemsWeight = 0, totalItemsToDisplayEndWeight = 0, startIndex;
470
- if (dynamicSize) {
471
- let y = 0;
472
- for (let i = 0, l = collection.length; i < l; i++) {
473
- const ii = i + 1, collectionItem = collection[i], map = this._map;
474
- let componentSize = 0;
475
- if (map.has(collectionItem.id)) {
476
- const bounds = map.get(collectionItem.id);
477
- componentSize = bounds ? bounds[sizeProperty] : typicalItemSize;
478
- }
479
- else {
480
- componentSize = typicalItemSize;
481
- }
482
- if (y < scrollSize - componentSize) {
483
- leftItemsWeights.push(componentSize);
484
- leftHiddenItemsWeight += componentSize;
485
- itemsFromStartToScrollEnd = ii;
486
- }
487
- if (y < scrollSize + size + componentSize) {
488
- itemsFromStartToDisplayEnd = ii;
489
- totalItemsToDisplayEndWeight += componentSize;
490
- itemsFromDisplayEndToOffsetEnd = itemsFromStartToDisplayEnd + itemsOffset;
491
- }
492
- else if (i < itemsFromDisplayEndToOffsetEnd) {
493
- rightItemsWeight += componentSize;
494
- }
495
- y += componentSize;
496
- }
497
- if (itemsFromStartToScrollEnd === -1) {
498
- itemsFromStartToScrollEnd = 0;
499
- }
500
- if (itemsFromStartToDisplayEnd === -1) {
501
- itemsFromStartToDisplayEnd = 0;
502
- }
503
- leftItemsWeights.splice(0, leftItemsWeights.length - itemsOffset);
504
- leftItemsWeights.forEach(v => {
505
- leftItemsWeight += v;
506
- });
507
- leftItemLength = Math.min(itemsFromStartToScrollEnd, itemsOffset);
508
- rightItemLength = itemsFromStartToDisplayEnd + itemsOffset > totalLength
509
- ? totalLength - itemsFromStartToDisplayEnd : itemsOffset;
510
- startIndex = itemsFromStartToScrollEnd - leftItemLength;
511
- }
512
- else {
513
- itemsFromStartToScrollEnd = Math.ceil(scrollSize / typicalItemSize);
514
- itemsFromStartToDisplayEnd = Math.ceil((scrollSize + size) / typicalItemSize);
515
- leftItemLength = Math.min(itemsFromStartToScrollEnd, itemsOffset);
516
- rightItemLength = itemsFromStartToDisplayEnd + itemsOffset > totalLength
517
- ? totalLength - itemsFromStartToDisplayEnd : itemsOffset;
518
- startIndex = itemsFromStartToScrollEnd - leftItemLength;
519
- leftItemsWeight = leftItemLength * typicalItemSize;
520
- rightItemsWeight = rightItemLength * typicalItemSize,
521
- leftHiddenItemsWeight = itemsFromStartToScrollEnd * typicalItemSize,
522
- totalItemsToDisplayEndWeight = itemsFromStartToDisplayEnd * typicalItemSize;
523
- }
524
- const itemsOnDisplay = totalItemsToDisplayEndWeight - leftHiddenItemsWeight, itemsOnDisplayLength = itemsFromStartToDisplayEnd - itemsFromStartToScrollEnd;
525
- const metrics = {
526
- itemsFromStartToScrollEnd,
527
- itemsFromStartToDisplayEnd,
528
- itemsOnDisplay,
529
- itemsOnDisplayLength,
530
- leftHiddenItemsWeight,
531
- leftItemLength,
532
- leftItemsWeight,
533
- rightItemLength,
534
- rightItemsWeight,
535
- snippedPos,
536
- totalItemsToDisplayEndWeight,
537
- totalSize,
538
- typicalItemSize,
539
- };
540
- return metrics;
541
- }
542
- /**
543
- * tracking by propName
544
- */
545
- track() {
546
- if (!this._items || !this._displayComponents) {
547
- return;
548
- }
549
- this._tracker.track(this._items, this._displayComponents);
550
- }
551
- setDisplayObjectIndexMapById(v) {
552
- this._tracker.displayObjectIndexMapById = v;
553
- }
554
- untrackComponentByIdProperty(component) {
555
- this._tracker.untrackComponentByIdProperty(component);
556
- }
557
- cacheElements() {
558
- if (!this._displayComponents) {
559
- return;
560
- }
561
- for (let i = 0, l = this._displayComponents.length; i < l; i++) {
562
- const component = this._displayComponents[i], itemId = component.instance.itemId;
563
- if (itemId === undefined) {
564
- continue;
565
- }
566
- const bounds = component.instance.getBounds();
567
- this.set(itemId, bounds);
568
- }
569
- }
570
- /**
571
- * Returns calculated bounds from cache
572
- */
573
- getBoundsFromCache(items, typicalItemSize, isVertical) {
574
- const sizeProperty = isVertical ? HEIGHT_PROP_NAME : WIDTH_PROP_NAME, map = this._map;
575
- let size = 0;
576
- for (let i = 0, l = items.length; i < l; i++) {
577
- const item = items[i];
578
- if (map.has(item.id)) {
579
- const bounds = map.get(item.id);
580
- size += bounds ? bounds[sizeProperty] : typicalItemSize;
581
- }
582
- else {
583
- size += typicalItemSize;
584
- }
585
- }
586
- return size;
587
- }
588
- dispose() {
589
- super.dispose();
590
- if (this._debounceChanges) {
591
- this._debounceChanges.dispose();
592
- }
593
- if (this._tracker) {
594
- this._tracker.dispose();
595
- }
596
- }
597
- }
598
-
599
- /**
600
- * Virtual list component.
601
- * Maximum performance for extremely large lists.
602
- * It is based on algorithms for virtualization of screen objects.
603
- * @homepage https://github.com/DjonnyX/ng-virtual-list/tree/main/projects/ng-virtual-list
604
- * @author Evgenii Grebennikov
605
- * @email djonnyx@gmail.com
606
- */
607
- class NgVirtualListComponent {
608
- static __nextId = 0;
609
- _id = NgVirtualListComponent.__nextId;
610
- /**
611
- * Readonly. Returns the unique identifier of the component.
612
- */
613
- get id() { return this._id; }
614
- _listContainerRef;
615
- _container = viewChild('container');
616
- _list = viewChild('list');
617
- /**
618
- * Fires when the list has been scrolled.
619
- */
620
- onScroll = output();
621
- /**
622
- * Fires when the list has completed scrolling.
623
- */
624
- onScrollEnd = output();
625
- /**
626
- * Collection of list items.
627
- */
628
- items = input.required();
629
- /**
630
- * Determines whether elements will snap. Default value is "true".
631
- */
632
- snap = input(DEFAULT_SNAP);
633
- /**
634
- * Determines whether scroll positions will be snapped to the element. Default value is "false".
635
- */
636
- snapToItem = input(DEFAULT_SNAP_TO_ITEM);
637
- /**
638
- * Rendering element template.
639
- */
640
- itemRenderer = input.required();
641
- /**
642
- * Dictionary zIndex by id of the list element. If the value is not set or equal to 0,
643
- * then a simple element is displayed, if the value is greater than 0, then the sticky position mode is enabled for the element.
644
- */
645
- stickyMap = input({});
646
- /**
647
- * If direction = 'vertical', then the height of a typical element. If direction = 'horizontal', then the width of a typical element.
648
- * Ignored if the dynamicSize property is true.
649
- */
650
- itemSize = input(DEFAULT_ITEM_SIZE);
651
- /**
652
- * If true then the items in the list can have different sizes and the itemSize property is ignored.
653
- * If false then the items in the list have a fixed size specified by the itemSize property. The default value is false.
654
- */
655
- dynamicSize = input(DEFAULT_DYNAMIC_SIZE);
656
- /**
657
- * Determines the direction in which elements are placed. Default value is "vertical".
658
- */
659
- direction = input(DEFAULT_DIRECTION);
660
- /**
661
- * Number of elements outside the scope of visibility. Default value is 2.
662
- */
663
- itemsOffset = input(DEFAULT_ITEMS_OFFSET);
664
- _isVertical = this.getIsVertical();
665
- _displayItems = signal(null);
666
- _displayComponents = [];
667
- _bounds = signal(null);
668
- _scrollSize = signal(0);
669
- _resizeObserver = null;
670
- _onResizeHandler = () => {
671
- this._bounds.set(this._container()?.nativeElement?.getBoundingClientRect() ?? null);
672
- };
673
- _onScrollHandler = (e) => {
674
- const target = e.target, scrollSize = this._isVertical ? target.scrollTop : target.scrollLeft;
675
- this._scrollSize.set(scrollSize);
676
- this.onScroll.emit(e);
677
- };
678
- _onScrollEndHandler = (e) => {
679
- const target = e.target, s = this.itemSize(), itemSize = s < 0 ? DEFAULT_ITEM_SIZE : s, snapToItem = this.snapToItem(), scrollSize = this._isVertical ? target.scrollTop : target.scrollLeft, scrollItems = Math.round(scrollSize / itemSize), actualScrollSize = snapToItem ? scrollItems * itemSize : scrollSize;
680
- if (target.scrollTop !== actualScrollSize) {
681
- const container = target, params = {
682
- [this._isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: actualScrollSize,
683
- behavior: BEHAVIOR_INSTANT
684
- };
685
- container.scroll(params);
686
- }
687
- this.onScrollEnd.emit(e);
688
- };
689
- _elementRef = inject((ElementRef));
690
- _initialized = signal(false);
691
- /**
692
- * Dictionary of element sizes by their id
693
- */
694
- _trackBox = new TrackBox(TRACK_BY_PROPERTY_NAME);
695
- _onTrackBoxChangeHandler = (v) => {
696
- this._$cacheVersion.next(v);
697
- };
698
- _$cacheVersion = new BehaviorSubject(-1);
699
- get $cacheVersion() { return this._$cacheVersion.asObservable(); }
700
- constructor() {
701
- NgVirtualListComponent.__nextId = NgVirtualListComponent.__nextId + 1 === Number.MAX_SAFE_INTEGER
702
- ? 0 : NgVirtualListComponent.__nextId + 1;
703
- this._id = NgVirtualListComponent.__nextId;
704
- this._trackBox.displayComponents = this._displayComponents;
705
- 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)), $itemsOffset = toObservable(this.itemsOffset).pipe(map(v => v < 0 ? DEFAULT_ITEMS_OFFSET : v)), $stickyMap = toObservable(this.stickyMap).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), $cacheVersion = this.$cacheVersion, $displayItems = toObservable(this._displayItems), $initialized = toObservable(this._initialized);
706
- $isVertical.pipe(takeUntilDestroyed(), tap(v => {
707
- this._isVertical = v;
708
- const el = this._elementRef.nativeElement;
709
- toggleClassName(el, v ? CLASS_LIST_VERTICAL : CLASS_LIST_HORIZONTAL, true);
710
- })).subscribe();
711
- $dynamicSize.pipe(takeUntilDestroyed(), tap(dynamicSize => {
712
- if (dynamicSize) {
713
- if (!this._trackBox.hasEventListener(TRACK_BOX_CHANGE_EVENT_NAME, this._onTrackBoxChangeHandler)) {
714
- this._trackBox.addEventListener(TRACK_BOX_CHANGE_EVENT_NAME, this._onTrackBoxChangeHandler);
715
- }
716
- }
717
- else {
718
- if (this._trackBox.hasEventListener(TRACK_BOX_CHANGE_EVENT_NAME, this._onTrackBoxChangeHandler)) {
719
- this._trackBox.removeEventListener(TRACK_BOX_CHANGE_EVENT_NAME, this._onTrackBoxChangeHandler);
720
- }
721
- }
722
- })).subscribe();
723
- $displayItems.pipe(takeUntilDestroyed(), tap((displayItems) => {
724
- this._trackBox.items = displayItems;
725
- })).subscribe();
726
- combineLatest([$initialized, $bounds, $items, $stickyMap, $scrollSize, $itemSize,
727
- $itemsOffset, $snap, $isVertical, $dynamicSize, $cacheVersion,
728
- ]).pipe(takeUntilDestroyed(), distinctUntilChanged(), filter(([initialized]) => !!initialized), switchMap(([, bounds, items, stickyMap, scrollSize, itemSize, itemsOffset, snap, isVertical, dynamicSize, cacheVersion,]) => {
729
- this._trackBox.cacheElements();
730
- const { width, height } = bounds, { itemsFromStartToScrollEnd, itemsOnDisplay, itemsOnDisplayLength, leftHiddenItemsWeight, leftItemLength, leftItemsWeight, rightItemLength, rightItemsWeight, snippedPos, totalSize, typicalItemSize, } = this._trackBox.recalculateMetrics({
731
- bounds: { width, height }, collection: items,
732
- dynamicSize, isVertical, itemSize, itemsOffset, scrollSize, snap,
733
- });
734
- // Необходима кореляция startDisplayObjectY с помощью дельты от высоты предыдущей и текущей размеченной области по версии кэша.
735
- // TrackBox может расчитать дельту!
736
- return of({
737
- items, stickyMap, width, height, isVertical, scrollSize, itemsFromStartToScrollEnd,
738
- itemsOnDisplay, itemsOnDisplayLength, leftHiddenItemsWeight, itemSize: typicalItemSize,
739
- totalSize, snap, leftItemLength, leftItemsWeight, rightItemLength, rightItemsWeight, snippedPos,
740
- dynamicSize,
741
- });
742
- }), tap(({ items, stickyMap, width, height, isVertical, scrollSize, itemsFromStartToScrollEnd, itemsOnDisplay, itemsOnDisplayLength, leftHiddenItemsWeight, leftItemLength, leftItemsWeight, rightItemLength, rightItemsWeight, snippedPos, itemSize, totalSize, snap, dynamicSize: dynamic, }) => {
743
- const displayItems = [];
744
- if (items.length) {
745
- const sizeProperty = isVertical ? HEIGHT_PROP_NAME : WIDTH_PROP_NAME, w = isVertical ? width : itemSize, h = isVertical ? itemSize : height, totalItems = items.length, startIndex = itemsFromStartToScrollEnd - leftItemLength;
746
- let pos = leftHiddenItemsWeight - leftItemsWeight, renderItems = itemsOnDisplayLength + leftItemLength + rightItemLength, stickyItem, nextSticky, stickyItemIndex = -1, stickyItemSize = 0;
747
- if (snap) {
748
- for (let i = itemsFromStartToScrollEnd - 1; i >= 0; i--) {
749
- const id = items[i].id, sticky = stickyMap[id], size = dynamic ? this._trackBox.get(id)?.[sizeProperty] || itemSize : itemSize;
750
- stickyItemSize = size;
751
- if (sticky > 0) {
752
- const measures = {
753
- x: isVertical ? 0 : snippedPos,
754
- y: isVertical ? snippedPos : 0,
755
- width: w,
756
- height: h,
757
- }, config = {
758
- isVertical,
759
- sticky,
760
- snap,
761
- snapped: true,
762
- dynamic,
763
- };
764
- const itemData = items[i];
765
- stickyItem = { id, measures, data: itemData, config };
766
- stickyItemIndex = i;
767
- displayItems.push(stickyItem);
768
- break;
769
- }
770
- }
771
- }
772
- let i = startIndex;
773
- while (renderItems > 0) {
774
- if (i >= totalItems) {
775
- break;
776
- }
777
- const id = items[i].id, size = dynamic ? this._trackBox.get(id)?.[sizeProperty] || itemSize : itemSize;
778
- if (id !== stickyItem?.id) {
779
- const snaped = snap && stickyMap[id] > 0 && pos <= scrollSize, measures = {
780
- x: isVertical ? 0 : pos,
781
- y: isVertical ? pos : 0,
782
- width: w,
783
- height: h,
784
- }, config = {
785
- isVertical,
786
- sticky: stickyMap[id],
787
- snap,
788
- snapped: false,
789
- dynamic,
790
- };
791
- const itemData = items[i];
792
- const item = { id, measures, data: itemData, config };
793
- if (!nextSticky && stickyItemIndex < i && snap && stickyMap[id] > 0 && pos <= scrollSize + size) {
794
- item.measures.x = isVertical ? 0 : snaped ? snippedPos : pos;
795
- item.measures.y = isVertical ? snaped ? snippedPos : pos : 0;
796
- nextSticky = item;
797
- }
798
- displayItems.push(item);
799
- }
800
- renderItems -= 1;
801
- pos += size;
802
- i++;
803
- }
804
- const axis = isVertical ? Y_PROP_NAME : X_PROP_NAME;
805
- if (nextSticky && stickyItem && nextSticky.measures[axis] <= scrollSize + stickyItemSize) {
806
- if (nextSticky.measures[axis] > scrollSize) {
807
- stickyItem.measures[axis] = nextSticky.measures[axis] - stickyItemSize;
808
- stickyItem.config.snapped = nextSticky.config.snapped = false;
809
- stickyItem.config.sticky = 1;
810
- }
811
- else {
812
- nextSticky.config.snapped = true;
813
- }
814
- }
815
- }
816
- this._displayItems.set(displayItems);
817
- this.resetBoundsSize(isVertical, totalSize);
818
- })).subscribe();
819
- combineLatest([$initialized, toObservable(this.itemRenderer)]).pipe(takeUntilDestroyed(), distinctUntilChanged(), filter(([initialized]) => !!initialized), tap(([, itemRenderer]) => {
820
- this.resetRenderers(itemRenderer);
821
- }));
822
- combineLatest([$initialized, $displayItems]).pipe(takeUntilDestroyed(), distinctUntilChanged(), filter(([initialized]) => !!initialized), tap(([, displayItems]) => {
823
- this.createDisplayComponentsIfNeed(displayItems);
824
- this.tracking();
825
- })).subscribe();
826
- }
827
- ngOnInit() {
828
- this._initialized.set(true);
829
- }
830
- getIsVertical(d) {
831
- const dir = d || this.direction();
832
- return isDirection(dir, Directions.VERTICAL);
833
- }
834
- createDisplayComponentsIfNeed(displayItems) {
835
- if (!displayItems || !this._listContainerRef) {
836
- this._trackBox.setDisplayObjectIndexMapById({});
837
- return;
838
- }
839
- const _listContainerRef = this._listContainerRef;
840
- while (this._displayComponents.length < displayItems.length) {
841
- if (_listContainerRef) {
842
- const comp = _listContainerRef.createComponent(NgVirtualListItemComponent);
843
- this._displayComponents.push(comp);
844
- }
845
- }
846
- const maxLength = displayItems.length;
847
- while (this._displayComponents.length > maxLength) {
848
- const comp = this._displayComponents.pop();
849
- comp?.destroy();
850
- const id = comp?.instance.item?.id;
851
- if (id !== undefined) {
852
- this._trackBox.untrackComponentByIdProperty(comp?.instance);
853
- }
854
- }
855
- this.resetRenderers();
856
- }
857
- resetRenderers(itemRenderer) {
858
- const doMap = {};
859
- for (let i = 0, l = this._displayComponents.length; i < l; i++) {
860
- const item = this._displayComponents[i];
861
- item.instance.renderer = itemRenderer || this.itemRenderer();
862
- doMap[item.instance.id] = i;
863
- }
864
- this._trackBox.setDisplayObjectIndexMapById(doMap);
865
- }
866
- /**
867
- * tracking by id
868
- */
869
- tracking() {
870
- this._trackBox.track();
871
- }
872
- resetBoundsSize(isVertical, totalSize) {
873
- const l = this._list();
874
- if (l) {
875
- l.nativeElement.style[isVertical ? HEIGHT_PROP_NAME : WIDTH_PROP_NAME] = `${totalSize}${PX}`;
876
- }
877
- }
878
- /**
879
- * The method scrolls the list to the element with the given id and returns the value of the scrolled area.
880
- * Behavior accepts the values ​​"auto", "instant" and "smooth".
881
- */
882
- scrollTo(id, behavior = BEHAVIOR_AUTO) {
883
- const items = this.items();
884
- if (!items || !items.length) {
885
- return;
886
- }
887
- const index = items.findIndex(item => item.id === id), scrollSize = index * this.itemSize(), container = this._container();
888
- if (container) {
889
- const params = { [this._isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollSize, behavior };
890
- container.nativeElement.scroll(params);
891
- }
892
- }
893
- ngAfterViewInit() {
894
- const containerEl = this._container();
895
- if (containerEl) {
896
- containerEl.nativeElement.addEventListener(SCROLL, this._onScrollHandler);
897
- containerEl.nativeElement.addEventListener(SCROLL_END, this._onScrollEndHandler);
898
- this._resizeObserver = new ResizeObserver(this._onResizeHandler);
899
- this._resizeObserver.observe(containerEl.nativeElement);
900
- this._onResizeHandler();
901
- }
902
- }
903
- ngOnDestroy() {
904
- if (this._trackBox) {
905
- this._trackBox.dispose();
906
- }
907
- const containerEl = this._container();
908
- if (containerEl) {
909
- containerEl.nativeElement.removeEventListener(SCROLL, this._onScrollHandler);
910
- containerEl.nativeElement.removeEventListener(SCROLL_END, this._onScrollEndHandler);
911
- if (this._resizeObserver) {
912
- this._resizeObserver.unobserve(containerEl.nativeElement);
913
- }
914
- }
915
- if (this._displayComponents) {
916
- while (this._displayComponents.length > 0) {
917
- const comp = this._displayComponents.pop();
918
- comp?.destroy();
919
- }
920
- }
921
- }
922
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: NgVirtualListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
923
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.2.14", type: NgVirtualListComponent, isStandalone: true, selector: "ng-virtual-list", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, snap: { classPropertyName: "snap", publicName: "snap", isSignal: true, isRequired: false, transformFunction: null }, snapToItem: { classPropertyName: "snapToItem", publicName: "snapToItem", 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 } }, outputs: { onScroll: "onScroll", onScrollEnd: "onScrollEnd" }, viewQueries: [{ 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 }], ngImport: i0, template: "<div #container part=\"scroller\" class=\"ngvl__container\">\r\n <ul #list part=\"list\" class=\"ngvl__list\">\r\n <ng-container #renderersContainer></ng-container>\r\n </ul>\r\n</div>", styles: [":host{display:block;width:400px;overflow:hidden}:host(.horizontal){height:48px}:host(.vertical){height:320px}.ngvl__container{overflow:auto;width:100%;height:100%}.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 });
924
- }
925
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: NgVirtualListComponent, decorators: [{
926
- type: Component,
927
- args: [{ selector: 'ng-virtual-list', imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, template: "<div #container part=\"scroller\" class=\"ngvl__container\">\r\n <ul #list part=\"list\" class=\"ngvl__list\">\r\n <ng-container #renderersContainer></ng-container>\r\n </ul>\r\n</div>", styles: [":host{display:block;width:400px;overflow:hidden}:host(.horizontal){height:48px}:host(.vertical){height:320px}.ngvl__container{overflow:auto;width:100%;height:100%}.ngvl__list{position:relative;list-style:none;padding:0;margin:0;width:100%;height:100%}\n"] }]
928
- }], ctorParameters: () => [], propDecorators: { _listContainerRef: [{
929
- type: ViewChild,
930
- args: ['renderersContainer', { read: ViewContainerRef }]
931
- }] } });
932
-
933
- /*
934
- * Public API Surface of ng-virtual-list
935
- */
936
-
937
- /**
938
- * Generated bundle index. Do not edit.
939
- */
940
-
941
- export { NgVirtualListComponent };
942
- //# sourceMappingURL=ng-virtual-list.mjs.map