Data #
Async data loading with pagination, placeholders, and infinite scroll.
import { createVList, data } from "vlist";
const list = createVList({
container: "#app",
item: { height: 48, template: renderItem },
}, [data({
adapter: {
read: async ({ offset, limit }) => {
const res = await fetch(`/api/items?offset=${offset}&limit=${limit}`);
const { items, total } = await res.json();
return { items, total };
},
},
total: 1000,
})]);
Config #
| Option |
Type |
Default |
Description |
adapter |
VListAdapter<T> |
required |
Data source |
total |
number |
— |
Total item count (if known) |
autoLoad |
boolean |
true |
Auto-load initial data |
storage.chunkSize |
number |
100 |
Items per request |
storage.maxCachedItems |
number |
10000 |
Max cached items |
storage.evictionBuffer |
number |
500 |
Extra items to keep around visible range |
loading.cancelThreshold |
number |
15 |
Velocity above which loading is cancelled (px/ms) |
loading.preloadThreshold |
number |
2 |
Velocity above which preloading kicks in (px/ms) |
loading.preloadAhead |
number |
50 |
Items to preload ahead of scroll direction |
Adapter Interface #
interface VListAdapter<T> {
read(params: {
offset: number;
limit: number;
cursor: string | undefined;
signal: AbortSignal;
}): Promise<{
items: T[];
total?: number;
cursor?: string;
hasMore?: boolean;
}>;
}
Methods #
| Method |
Description |
reload() |
Reset and reload all data |
loadVisibleRange() |
Load visible items on demand |
getTotal() |
Get total item count |
setTotal(n) |
Set total item count |
Events #
| Event |
Payload |
load:start |
{ offset, limit } |
load:end |
{ items, total } |
error |
{ error, context } |
Notes #
- Velocity-aware: skips loads during fast scroll, loads on idle
- Deduplicates concurrent requests for the same range
- Supports cursor-based pagination via
cursor in adapter response
- Sets
aria-busy on root during loading