ng-virtual-list 16.7.3 → 16.7.5

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 CHANGED
@@ -1,29 +1,60 @@
1
1
  # NgVirtualList
2
2
 
3
- Maximum performance for extremely large lists.<br/>
4
- Flexible, and actively maintained Angular library that excels with high-performance, feature-rich virtualized lists—including grouping, sticky headers, snapping, animations, single and multiple selection of elements and both scroll directions. Whether you're rendering millions of items or building interactive list components, it delivers scalability and customization.
3
+ 🚀 High-performance virtual scrolling for Angular apps. Render 100,000+ items in Angular without breaking a sweat. Smooth, customizable, and developer-friendly.
4
+
5
+ Flexible, and actively maintained Angular library that excels with high-performance, feature-rich virtualized lists—including grouping, sticky headers, snapping, animations, single and multiple selection of elements and both scroll directions. Whether you're rendering millions of items or building interactive list components, it delivers scalability and customization. Angular (14–20) compatibility.
5
6
 
6
7
  <img width="1033" height="171" alt="logo" src="https://github.com/user-attachments/assets/b559cfde-405a-4361-b71b-6715478d997d" />
7
8
 
8
- Angular version 16.X.X.
9
+ <b>Angular version 16.X.X</b>.
10
+
11
+ ![npm](https://img.shields.io/npm/v/ng-virtual-list)
12
+ ![npm downloads](https://img.shields.io/npm/dm/ng-virtual-list)
13
+ ![npm total downloads](https://img.shields.io/npm/dt/ng-virtual-list)
9
14
 
10
15
  [Live Demo](https://ng-virtual-list-chat-demo.eugene-grebennikov.pro/)
16
+ [(Code)](https://github.com/DjonnyX/ng-virtual-list-demo)
11
17
 
12
18
  [Live Examples](https://ng-virtual-list.eugene-grebennikov.pro/)
19
+ [(Code)](https://github.com/DjonnyX/ng-virtual-list-demo/tree/main/src/app)
20
+
21
+ <br/>
22
+
23
+ ## ✨ Why use ng-virtual-list?
24
+
25
+ ⚡ Blazing fast — only renders what’s visible (plus a smart buffer).<br/>
26
+ 📱 Works everywhere — smooth on desktop & mobile.<br/>
27
+ 🔀 Flexible layouts — vertical, horizontal, grouped lists, sticky headers.<br/>
28
+ 📏 Dynamic sizes — handles items of varying height/width.<br/>
29
+ 🎯 Precise control — scroll to an ID, or snap to positions.<br/>
30
+ 🔌 Angular-friendly — simple inputs/outputs, trackBy support.<br/>
13
31
 
14
32
  <br/>
15
33
 
16
- | **Pros** | **Description** |
17
- | --- | --- |
18
- | **High performance** | Only renders items visible in the viewport (plus a buffer), reducing DOM overhead and improving responsiveness—even with very large datasets |
19
- | **Grouped lists with sticky headers & snapping** | Supports grouping items, sticky headers, and optional “snap” behavior for clean section scrolling |
20
- | **Angular (14–20) compatibility** | Compatible with Angular versions 14 through 20.x, ensuring seamless integration in modern Angular projects |
21
- | **Scroll-to capabilities** | Allows programmatic navigation to specific items by ID |
22
- | **TypeScript support** | Comes with typing for safety and better integration in TypeScript projects |
34
+ ## ⚙️ Key Features
35
+
36
+ Virtualization modes
37
+ - Fixed size (fastest)
38
+ - Dynamic size (auto-measured)
39
+ - Scrolling control
40
+ - Scroll to item ID
41
+ - Smooth or instant scroll
42
+ - Custom snapping behavior
43
+ - Advanced layouts
44
+ - Grouped lists with sticky headers
45
+ - Horizontal or vertical scrolling
46
+ - Advanced layouts
47
+ - Grouped lists with sticky headers
48
+ - Horizontal or vertical scrolling
49
+ - Selecting elements
50
+ - Single selection
51
+ - Multiple selection
52
+ - Performance tuning
53
+ - bufferSize and maxBufferSize for fine-grained control
23
54
 
24
55
  <br/>
25
56
 
26
- ## When to Use It: Ideal Use Cases
57
+ ## 📱 When to Use It: Ideal Use Cases
27
58
 
28
59
  Drawing on general virtual-scroll insights and ng-virtual-list features:
29
60
 
@@ -50,27 +81,44 @@ Support for element animation
50
81
 
51
82
  <br/>
52
83
 
53
- ## Installation
84
+ ## 📦 Installation
54
85
 
55
86
  ```bash
56
87
  npm i ng-virtual-list
57
88
  ```
58
89
 
59
- ## Examples
90
+ <br/>
60
91
 
61
- ### Horizontal virtual list
92
+ ## 🚀 Quick Start
93
+ ```html
94
+ <ng-virtual-list [items]="items" [bufferSize]="5" [itemRenderer]="itemRenderer" [itemSize]="64"></ng-virtual-list>
95
+
96
+ <ng-template #itemRenderer let-data="data">
97
+ <span *ngIf="data">{{data.name}}</span>
98
+ </ng-template>
99
+ ```
100
+ ```ts
101
+ items = Array.from({ length: 100000 }, (_, i) => ({ id: i, name: `Item #${i}` }));
102
+ ```
103
+
104
+ <br/>
105
+
106
+ ## 📱 Examples
107
+
108
+ ### Horizontal virtual list (Single selection)
62
109
 
63
110
  ![preview](https://github.com/user-attachments/assets/5a16d4b3-5e66-4d53-ae90-d0eab0b246a1)
64
111
 
65
112
  Template:
66
113
  ```html
67
114
  <ng-virtual-list class="list" direction="horizontal" [items]="horizontalItems" [bufferSize]="50"
68
- [itemRenderer]="horizontalItemRenderer" [itemSize]="64" (onItemClick)="onItemClick($event)"></ng-virtual-list>
115
+ [itemRenderer]="horizontalItemRenderer" [itemSize]="64" [methodForSelecting]="'select'"
116
+ [selectedIds]="2" (onSelect)="onSelect($event)" (onItemClick)="onItemClick($event)"></ng-virtual-list>
69
117
 
70
- <ng-template #horizontalItemRenderer let-data="data">
71
- <div *ngIf="data" class="list__h-container">
72
- <span>{{data.name}}</span>
73
- </div>
118
+ <ng-template #horizontalItemRenderer let-data="data" let-config="config">
119
+ <div *ngIf="data" [ngClass]="{'list__h-container': true, 'selected': config.selected}">
120
+ <span>{{data.name}}</span>
121
+ </div>
74
122
  </ng-template>
75
123
  ```
76
124
 
@@ -82,10 +130,7 @@ interface ICollectionItem {
82
130
  name: string;
83
131
  }
84
132
 
85
- const HORIZONTAL_ITEMS: IVirtualListCollection<ICollectionItem> = [];
86
- for (let i = 0, l = 1000000; i < l; i++) {
87
- HORIZONTAL_ITEMS.push({ id: i + 1, name: `${i}` });
88
- }
133
+ const HORIZONTAL_ITEMS: IVirtualListCollection<ICollectionItem> = Array.from({ length: 100000 }, (_, i) => ({ id: i, name: `${i}` }));
89
134
 
90
135
  @Component({
91
136
  selector: 'app-root',
@@ -101,24 +146,29 @@ export class AppComponent {
101
146
  console.info(`Click: (ID: ${item.id}) Item ${item.data.name}`);
102
147
  }
103
148
  }
149
+
150
+ onSelect(data: Array<Id> | Id | undefined) {
151
+ console.info(`Select: ${JSON.stringify(data)}`);
152
+ }
104
153
  }
105
154
  ```
106
155
 
107
- ### Horizontal grouped virtual list
156
+ ### Horizontal grouped virtual list (Multiple selection)
108
157
 
109
158
  ![preview](https://github.com/user-attachments/assets/99584660-dc0b-4cd0-9439-9b051163c077)
110
159
 
111
160
  Template:
112
161
  ```html
113
162
  <ng-virtual-list class="list" direction="horizontal" [items]="horizontalGroupItems" [itemRenderer]="horizontalGroupItemRenderer"
114
- [bufferSize]="50" [itemConfigMap]="horizontalGroupItemConfigMap" [itemSize]="54" [snap]="true" (onItemClick)="onItemClick($event)"></ng-virtual-list>
163
+ [bufferSize]="50" [itemConfigMap]="horizontalGroupItemConfigMap" [itemSize]="54" [snap]="true" [methodForSelecting]="'multi-select'"
164
+ [selectedIds]="[3,2]" (onSelect)="onSelect($event)" (onItemClick)="onItemClick($event)"></ng-virtual-list>
115
165
 
116
- <ng-template #horizontalGroupItemRenderer let-data="data">
166
+ <ng-template #horizontalGroupItemRenderer let-data="data" let-config="config">
117
167
  <ng-container *ngIf="data" [ngSwitch]="data.type">
118
168
  <div *ngSwitchCase="'group-header'" class="list__h-group-container">
119
169
  <span>{{data.name}}</span>
120
170
  </div>
121
- <div *ngSwitchCase="'item'" class="list__h-container">
171
+ <div *ngSwitchCase="'item'" [ngClass]="{'list__h-container': true, 'selected': config.selected}">
122
172
  <span>{{data.name}}</span>
123
173
  </div>
124
174
  </ng-container>
@@ -164,6 +214,10 @@ export class AppComponent {
164
214
  console.info(`Click: (ID: ${item.id}) Item ${item.data.name}`);
165
215
  }
166
216
  }
217
+
218
+ onSelect(data: Array<Id> | Id | undefined) {
219
+ console.info(`Select: ${JSON.stringify(data)}`);
220
+ }
167
221
  }
168
222
  ```
169
223
 
@@ -224,7 +278,6 @@ Template:
224
278
  <span>{{data.name}}</span>
225
279
  </div>
226
280
  </ng-container>
227
- </ng-template>
228
281
  ```
229
282
 
230
283
  #### With snapping
@@ -411,7 +464,9 @@ export class AppComponent {
411
464
  }
412
465
  ```
413
466
 
414
- ## Stylization
467
+ <br/>
468
+
469
+ ## 🖼️ Stylization
415
470
 
416
471
  List items are encapsulated in shadowDOM, so to override default styles you need to use ::part access
417
472
 
@@ -493,7 +548,9 @@ Selecting even elements:
493
548
  }
494
549
  ```
495
550
 
496
- ## API
551
+ <br/>
552
+
553
+ ## 📚 API
497
554
 
498
555
  [NgVirtualListComponent](https://github.com/DjonnyX/ng-virtual-list/blob/16.x/projects/ng-virtual-list/src/lib/ng-virtual-list.component.ts)
499
556
 
@@ -508,7 +565,7 @@ Inputs
508
565
  | 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. |
509
566
  | itemRenderer | TemplateRef | Rendering element template. |
510
567
  | methodForSelecting | [MethodForSelecting](https://github.com/DjonnyX/ng-virtual-list/blob/16.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. |
511
- | itemConfigMap | [IVirtualListItemConfigMap?](https://github.com/DjonnyX/ng-virtual-list/blob/16.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`. |
568
+ | itemConfigMap | [IVirtualListItemConfigMap?](https://github.com/DjonnyX/ng-virtual-list/blob/16.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`. |
512
569
  | 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`. |
513
570
  | snap | boolean? = false | Determines whether elements will snap. Default value is "false". |
514
571
  | snappingMethod | [SnappingMethod? = 'normal'](https://github.com/DjonnyX/ng-virtual-list/blob/16.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. |
@@ -543,7 +600,15 @@ Methods
543
600
 
544
601
  <br/>
545
602
 
546
- ## License
603
+ ## 🤝 Contributing
604
+
605
+ PRs and feature requests are welcome!
606
+ Open an issue or start a discussion to shape the future of [ng-virtual-list](https://github.com/DjonnyX/ng-virtual-list/).
607
+ Try it out, star ⭐ the repo, and let us know what you’re building.
608
+
609
+ <br/>
610
+
611
+ ## 📄 License
547
612
 
548
613
  MIT License
549
614
 
@@ -565,4 +630,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
565
630
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
566
631
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
567
632
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
568
- SOFTWARE.
633
+ SOFTWARE.