Svelte components for efficiently rendering large lists. Instead of rendering all your data, svelte-virtual renders only what's visible
With npm:
npm i -D svelte-virtual@next
With yarn:
yarn add -D svelte-virtual@next
With pnpm:
pnpm add -D svelte-virtual@next
Vertical List [default] (demo)
<script>
import { List } from "svelte-virtual@next";
let items = [...Array(100000).keys()];
</script>
<List itemCount={items.length} itemSize={20} height={500}>
<div slot="item" let:index let:style {style}>
{items[index]}
</div>
</List>Horizontal List (demo)
<script>
import { List } from "svelte-virtual@next";
let items = [...Array(100000).keys()];
</script>
<List itemCount={items.length} itemSize={60} height={40} layout="horizontal">
<div slot="item" let:index let:style {style}>
{items[index]}
</div>
</List>Grid (demo)
<script>
import { Grid } from "svelte-virtual@next";
let items = [...Array(100000).keys()];
</script>
<Grid itemCount={items.length} itemHeight={50} itemWidth={60} height={500}>
<div slot="item" let:index let:style {style}>
{items[index]}
</div>
</Grid>Grid [using rows and columns] (demo)
<script>
import { Grid } from "svelte-virtual@next";
let itemCount = 100000;
let columnCount = 5;
let items = Array.from({ length: itemCount }, (_, l) =>
Array.from({ length: columnCount }, (_, c) => `${l}-${c}`),
);
</script>
<Grid itemCount={itemCount * columnCount} itemHeight={50} itemWidth={65} height={500} {columnCount}>
<div slot="item" let:rowIndex let:columnIndex let:style {style}>
{items[rowIndex][columnIndex]}
</div>
</Grid>| Property | Type | Default | Required? |
|---|---|---|---|
| itemCount | number |
✓ | |
| itemSize | number |
✓ | |
| height | number | string |
"100%" |
|
| width | string |
"100%" |
|
| stickyIndices | number[] |
[] |
|
| overScan | number |
1 |
|
| marginLeft | number |
0 |
|
| marginTop | number |
0 |
|
| layout | "vertical" | "horizontal" |
"vertical" |
|
| scrollPosition | number |
0 |
|
| scrollBehavior | "auto" | "smooth" |
"auto" |
|
| getKey | (index: number) => unknown |
(index: number) => index |
| Property | Type | Default | Required? |
|---|---|---|---|
| itemCount | number |
✓ | |
| itemHeight | number |
✓ | |
| itemWidth | number |
✓ | |
| height | number |
✓ | |
| width | string |
"100%" |
|
| spacing | number |
0 |
|
| overScan | number |
1 |
|
| marginLeft | number |
0 |
|
| marginTop | number |
0 |
|
| center | boolean |
false |
|
| scrollPosition | number |
0 |
|
| scrollBehavior | "auto" | "smooth" |
"auto" |
|
| getKey | (index: number) => unknown |
(index: number) => index |
|
| columnCount | number |
undefined |
Methods (demo)
| Method | Argument | Type | Default | Required? |
|---|---|---|---|---|
| scrollToIndex | ||||
| index | number |
✓ | ||
| behavior | "auto" | "smooth" |
scrollBehavior |
||
| scrollToPosition | ||||
| position | number |
✓ | ||
| behavior | "auto" | "smooth" |
scrollBehavior |
item- Slot for each item- Props:
- Shared:
index: number- Item indexstyle: string- Item style, must be applied to the slot (look above for example)
- Only for
<Grid/>(demo):rowIndex: number- Item row indexcolumnIndex: number- Item column index
- Shared:
- Props:
placeholder(optional) - Slot for each item (when scrolling fast, replacesitemslot. if not present,itemslot is used)- Props:
- Shared:
index: number- Item indexstyle: string- Item style, must be applied to the slot (look above for example)
- Only for
<Grid/>(demo):rowIndex: number- Item row indexcolumnIndex: number- Item column index
- Shared:
- Props:
header(optional) - Slot for the elements that should appear at the top of the componentfooter(optional) - Slot for the elements that should appear at the bottom of the component