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
|
-
|
|
4
|
-
|
|
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
|
+

|
|
12
|
+

|
|
13
|
+

|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
|
|
90
|
+
<br/>
|
|
60
91
|
|
|
61
|
-
|
|
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
|

|
|
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"
|
|
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
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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
|

|
|
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"
|
|
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'"
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
##
|
|
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.
|