vlist 3.1.8 → 3.3.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.
- package/README.github.md +46 -32
- package/README.md +39 -32
- package/dist/config.js +1 -1
- package/dist/core/types.d.ts +13 -0
- package/dist/index.js +1 -1
- package/dist/plugins/carousel/plugin.d.ts +3 -0
- package/dist/plugins/masonry/plugin.d.ts +1 -1
- package/dist/plugins/table/plugin.d.ts +1 -1
- package/dist/plugins/table/types.d.ts +16 -1
- package/dist/size.json +1 -1
- package/dist/synthetic.js +1 -1
- package/dist/version.json +1 -1
- package/package.json +1 -1
package/README.github.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The virtual list library for every framework. Ultra efficient, batteries-included, and accessible with composable plugins.
|
|
4
4
|
|
|
5
|
-
**v3.
|
|
5
|
+
**v3.3.0** — `scroll.mode` on the one `vlist` entry: the default, `"auto"`, scrolls natively and hands a list past the browser's size limit to synthetic input, which draws its own scrollbar. Vue, Svelte, Solid and React entries in the package itself (`vlist/vue`, `vlist/svelte`, `vlist/solid`, `vlist/react`), feature-first and tree-shaken like the vanilla builder; the separate adapter packages are deprecated. See the [changelog](https://github.com/floor/vlist/blob/main/CHANGELOG.md).
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/vlist)
|
|
8
8
|
[](https://bundlephobia.com/package/vlist)
|
|
@@ -11,7 +11,7 @@ The virtual list library for every framework. Ultra efficient, batteries-include
|
|
|
11
11
|
|
|
12
12
|
- **Accessible** — `a11y()` or a selection mode adds WAI-ARIA, 2D keyboard navigation, focus recovery, screen-reader DOM ordering
|
|
13
13
|
- **Zero dependencies** — framework-agnostic core, with Vue, Svelte, Solid and React entries in the same package
|
|
14
|
-
- **10.
|
|
14
|
+
- **10.5 KB gzipped** — composable plugins with perfect tree-shaking (Bundlephobia's badge measures the root entry with every plugin at once)
|
|
15
15
|
- **Constant memory** — ~0.1 MB overhead at any scale, from 10K to 1M+ items
|
|
16
16
|
- **Tree, grid, masonry, carousel, table, groups, data, selection, search, sortable, transition** — all opt-in
|
|
17
17
|
- **Axis-neutral** — vertical and horizontal scrolling through a single code path, all plugins work in both orientations
|
|
@@ -264,36 +264,36 @@ The touch-only `.vlist-item--touch-sort` class suppresses selection and callouts
|
|
|
264
264
|
|
|
265
265
|
| Entry / export | Minified | Gzipped |
|
|
266
266
|
|---|---:|---:|
|
|
267
|
-
| **Base (`vlist`)** | 27.
|
|
268
|
-
| `vlist/synthetic` (deprecated) | 34.
|
|
269
|
-
| `vlist/native` (alias) | 27.
|
|
270
|
-
| `a11y()` | 32.
|
|
271
|
-
| `selection()` |
|
|
272
|
-
| `data()` | 41.
|
|
273
|
-
| `scrollbar()` |
|
|
274
|
-
| `sortable()` | 39.
|
|
275
|
-
| `groups()` |
|
|
276
|
-
| `page()` |
|
|
277
|
-
| `snapshots()` |
|
|
278
|
-
| `transition()` | 34.
|
|
279
|
-
| `autosize()` |
|
|
280
|
-
| `grid()` |
|
|
281
|
-
| `table()` |
|
|
282
|
-
| `masonry()` |
|
|
283
|
-
| `tree()` | 43.
|
|
284
|
-
| `search()` |
|
|
285
|
-
| `carousel()` | 43.
|
|
286
|
-
| `vlist/synthetic` + `carousel()` |
|
|
287
|
-
| `vlist/synthetic` + `sortable()` | 46.
|
|
288
|
-
| `vlist/vue` `useVList` |
|
|
289
|
-
| `vlist/svelte` `vlist` |
|
|
290
|
-
| `vlist/solid` `createVList` |
|
|
291
|
-
| `vlist/react` `useVList` |
|
|
292
|
-
| `vlist/react` + `grid()` | 35.
|
|
293
|
-
|
|
294
|
-
Sizes are tree-shaken totals from `bun run size`, not additive plugin costs. Plugin rows include the native default factory plus that plugin; framework rows add the entry, with the framework itself external. The base is **10,
|
|
295
|
-
|
|
296
|
-
Bundlephobia's badge measures the package's root entry, which re-exports every plugin, minified and gzipped as one bundle. With a tree-shaking bundler, an app that imports named exports from `vlist` bundles the base (**10.
|
|
267
|
+
| **Base (`vlist`)** | 27.9 KB | 10.5 KB |
|
|
268
|
+
| `vlist/synthetic` (deprecated) | 34.8 KB | 13.1 KB |
|
|
269
|
+
| `vlist/native` (alias) | 27.9 KB | 10.5 KB |
|
|
270
|
+
| `a11y()` | 32.9 KB | 12.4 KB |
|
|
271
|
+
| `selection()` | 38.4 KB | 13.8 KB |
|
|
272
|
+
| `data()` | 41.5 KB | 15.3 KB |
|
|
273
|
+
| `scrollbar()` | 36.1 KB | 13.4 KB |
|
|
274
|
+
| `sortable()` | 39.8 KB | 14.1 KB |
|
|
275
|
+
| `groups()` | 44.2 KB | 15.9 KB |
|
|
276
|
+
| `page()` | 30.4 KB | 11.4 KB |
|
|
277
|
+
| `snapshots()` | 31.2 KB | 11.6 KB |
|
|
278
|
+
| `transition()` | 34.6 KB | 12.5 KB |
|
|
279
|
+
| `autosize()` | 32.3 KB | 12.1 KB |
|
|
280
|
+
| `grid()` | 35.4 KB | 13.1 KB |
|
|
281
|
+
| `table()` | 47.0 KB | 16.6 KB |
|
|
282
|
+
| `masonry()` | 40.1 KB | 14.9 KB |
|
|
283
|
+
| `tree()` | 43.7 KB | 15.8 KB |
|
|
284
|
+
| `search()` | 37.5 KB | 13.8 KB |
|
|
285
|
+
| `carousel()` | 43.9 KB | 16.0 KB |
|
|
286
|
+
| `vlist/synthetic` + `carousel()` | 50.0 KB | 18.3 KB |
|
|
287
|
+
| `vlist/synthetic` + `sortable()` | 46.7 KB | 16.7 KB |
|
|
288
|
+
| `vlist/vue` `useVList` | 28.3 KB | 10.7 KB |
|
|
289
|
+
| `vlist/svelte` `vlist` | 28.1 KB | 10.6 KB |
|
|
290
|
+
| `vlist/solid` `createVList` | 28.2 KB | 10.6 KB |
|
|
291
|
+
| `vlist/react` `useVList` | 28.3 KB | 10.7 KB |
|
|
292
|
+
| `vlist/react` + `grid()` | 35.8 KB | 13.3 KB |
|
|
293
|
+
|
|
294
|
+
Sizes are tree-shaken totals from `bun run size`, not additive plugin costs. Plugin rows include the native default factory plus that plugin; framework rows add the entry, with the framework itself external. The base is **10,735 bytes gzipped**, within the 10.59 KB budget (10,844 bytes). `bun run size` fails if a scenario fails to build, an unused plugin leaks into a bundle, or any published size exceeds its gzip budget. Synthetic input is **13,402 bytes** before plugins; with `scroll.mode`, a `vlist` list downloads the driver and its scrollbar as `synthetic-driver.js` (6.2 KB gzipped) only when it goes synthetic. The alias row measures the same source factory; the distributed alias re-exports it without duplicating the implementation.
|
|
295
|
+
|
|
296
|
+
Bundlephobia's badge measures the package's root entry, which re-exports every plugin, minified and gzipped as one bundle. With a tree-shaking bundler, an app that imports named exports from `vlist` bundles the base (**10.5 KB gzipped**) and the features it uses; the table's rows are each a combined size, not amounts to add up.
|
|
297
297
|
|
|
298
298
|
## Examples
|
|
299
299
|
|
|
@@ -336,6 +336,17 @@ cell, which sorts the column when it is sortable: give the control `tabindex`, o
|
|
|
336
336
|
Enter and Space emit `column:sort` on a sortable header and never `column:click`, so an action a
|
|
337
337
|
keyboard user must reach should be a `button` supplied in the header label.
|
|
338
338
|
|
|
339
|
+
Table rows use configured heights and are not automatically measured, so
|
|
340
|
+
`autosize()` cannot be combined with `table()`;
|
|
341
|
+
the `vlist/config` route wires `autosize()` when only an estimate is given (`item.estimatedHeight`)
|
|
342
|
+
and throws at creation. Give the table a fixed `rowHeight` and the config a fixed `item.height` instead.
|
|
343
|
+
|
|
344
|
+
`estimatedRowHeight` is deprecated in 3.3.0 and will be removed in 4.0 (#345).
|
|
345
|
+
It remains accepted but does not size or measure rows; non-production builds warn
|
|
346
|
+
once per `table()` call. Use a numeric `rowHeight` for fixed rows or a `rowHeight`
|
|
347
|
+
function for variable row sizes. For heights that change after creation, the
|
|
348
|
+
`remeasureItem(index)` API in 3.3.0 works with a `rowHeight` function (#347).
|
|
349
|
+
|
|
339
350
|
### Grid Layout
|
|
340
351
|
|
|
341
352
|
```typescript
|
|
@@ -528,6 +539,7 @@ const list = createVList(config, [plugin1(), plugin2()])
|
|
|
528
539
|
| `list.removeItems(ids)` | Batch remove (simultaneous animations) |
|
|
529
540
|
| `list.getItemAt(index)` | Get item at index |
|
|
530
541
|
| `list.getIndexById(id)` | Get index by item ID |
|
|
542
|
+
| `list.remeasureItem(index)` | Ask the size source to re-read one item after its content changed; returns `false` when the size model cannot address it |
|
|
531
543
|
|
|
532
544
|
### Navigation
|
|
533
545
|
|
|
@@ -608,6 +620,8 @@ list.remeasure(12); // Re-measure one item after its content changes.
|
|
|
608
620
|
list.remeasure(); // Invalidate all sizes and measure items as they render.
|
|
609
621
|
```
|
|
610
622
|
|
|
623
|
+
A measured item size cannot be combined with `masonry()`: masonry places items from the size cache it is handed at layout time, so an `autosize()` measurement never reaches the placements. The `vlist/config` route wires `autosize()` when only an estimate is given (`item.estimatedHeight`) and throws at creation; give the items a fixed `item.height` instead. The same holds for `carousel()`, whose slide steps are built from the size read at setup.
|
|
624
|
+
|
|
611
625
|
Full configuration reference → **[vlist.io](https://vlist.io)**
|
|
612
626
|
|
|
613
627
|
## Base Configuration
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The virtual list library for every framework. Ultra efficient, batteries-included, and accessible with composable plugins.
|
|
4
4
|
|
|
5
|
-
**v3.
|
|
5
|
+
**v3.3.0** — `scroll.mode` on the one `vlist` entry: the default, `"auto"`, scrolls natively and hands a list past the browser's size limit to synthetic input, which draws its own scrollbar. Vue, Svelte, Solid and React entries in the package itself (`vlist/vue`, `vlist/svelte`, `vlist/solid`, `vlist/react`), feature-first and tree-shaken like the vanilla builder; the separate adapter packages are deprecated. See the [changelog](https://github.com/floor/vlist/blob/main/CHANGELOG.md).
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/vlist)
|
|
8
8
|
[](https://bundlephobia.com/package/vlist)
|
|
@@ -11,7 +11,7 @@ The virtual list library for every framework. Ultra efficient, batteries-include
|
|
|
11
11
|
|
|
12
12
|
- **Accessible** — `a11y()` or a selection mode adds WAI-ARIA, 2D keyboard navigation, focus recovery, screen-reader DOM ordering
|
|
13
13
|
- **Zero dependencies** — framework-agnostic core, with Vue, Svelte, Solid and React entries in the same package
|
|
14
|
-
- **10.
|
|
14
|
+
- **10.5 KB gzipped** — composable plugins with perfect tree-shaking (Bundlephobia's badge measures the root entry with every plugin at once)
|
|
15
15
|
- **Constant memory** — ~0.1 MB overhead at any scale, from 10K to 1M+ items
|
|
16
16
|
- **Axis-neutral** — vertical and horizontal scrolling through a single code path, all plugins work in both orientations
|
|
17
17
|
|
|
@@ -131,36 +131,43 @@ The touch-only `.vlist-item--touch-sort` class suppresses selection and callouts
|
|
|
131
131
|
|
|
132
132
|
| Entry / export | Minified | Gzipped |
|
|
133
133
|
|---|---:|---:|
|
|
134
|
-
| **Base (`vlist`)** | 27.
|
|
135
|
-
| `vlist/synthetic` (deprecated) | 34.
|
|
136
|
-
| `vlist/native` (alias) | 27.
|
|
137
|
-
| `a11y()` | 32.
|
|
138
|
-
| `selection()` |
|
|
139
|
-
| `data()` | 41.
|
|
140
|
-
| `scrollbar()` |
|
|
141
|
-
| `sortable()` | 39.
|
|
142
|
-
| `groups()` |
|
|
143
|
-
| `page()` |
|
|
144
|
-
| `snapshots()` |
|
|
145
|
-
| `transition()` | 34.
|
|
146
|
-
| `autosize()` |
|
|
147
|
-
| `grid()` |
|
|
148
|
-
| `table()` |
|
|
149
|
-
| `masonry()` |
|
|
150
|
-
| `tree()` | 43.
|
|
151
|
-
| `search()` |
|
|
152
|
-
| `carousel()` | 43.
|
|
153
|
-
| `vlist/synthetic` + `carousel()` |
|
|
154
|
-
| `vlist/synthetic` + `sortable()` | 46.
|
|
155
|
-
| `vlist/vue` `useVList` |
|
|
156
|
-
| `vlist/svelte` `vlist` |
|
|
157
|
-
| `vlist/solid` `createVList` |
|
|
158
|
-
| `vlist/react` `useVList` |
|
|
159
|
-
| `vlist/react` + `grid()` | 35.
|
|
160
|
-
|
|
161
|
-
Sizes are tree-shaken totals from `bun run size`, not additive plugin costs. Plugin rows include the native default factory plus that plugin; framework rows add the entry, with the framework itself external. The base is **10,
|
|
162
|
-
|
|
163
|
-
Bundlephobia's badge measures the package's root entry, which re-exports every plugin, minified and gzipped as one bundle. With a tree-shaking bundler, an app that imports named exports from `vlist` bundles the base (**10.
|
|
134
|
+
| **Base (`vlist`)** | 27.9 KB | 10.5 KB |
|
|
135
|
+
| `vlist/synthetic` (deprecated) | 34.8 KB | 13.1 KB |
|
|
136
|
+
| `vlist/native` (alias) | 27.9 KB | 10.5 KB |
|
|
137
|
+
| `a11y()` | 32.9 KB | 12.4 KB |
|
|
138
|
+
| `selection()` | 38.4 KB | 13.8 KB |
|
|
139
|
+
| `data()` | 41.5 KB | 15.3 KB |
|
|
140
|
+
| `scrollbar()` | 36.1 KB | 13.4 KB |
|
|
141
|
+
| `sortable()` | 39.8 KB | 14.1 KB |
|
|
142
|
+
| `groups()` | 44.2 KB | 15.9 KB |
|
|
143
|
+
| `page()` | 30.4 KB | 11.4 KB |
|
|
144
|
+
| `snapshots()` | 31.2 KB | 11.6 KB |
|
|
145
|
+
| `transition()` | 34.6 KB | 12.5 KB |
|
|
146
|
+
| `autosize()` | 32.3 KB | 12.1 KB |
|
|
147
|
+
| `grid()` | 35.4 KB | 13.1 KB |
|
|
148
|
+
| `table()` | 47.0 KB | 16.6 KB |
|
|
149
|
+
| `masonry()` | 40.1 KB | 14.9 KB |
|
|
150
|
+
| `tree()` | 43.7 KB | 15.8 KB |
|
|
151
|
+
| `search()` | 37.5 KB | 13.8 KB |
|
|
152
|
+
| `carousel()` | 43.9 KB | 16.0 KB |
|
|
153
|
+
| `vlist/synthetic` + `carousel()` | 50.0 KB | 18.3 KB |
|
|
154
|
+
| `vlist/synthetic` + `sortable()` | 46.7 KB | 16.7 KB |
|
|
155
|
+
| `vlist/vue` `useVList` | 28.3 KB | 10.7 KB |
|
|
156
|
+
| `vlist/svelte` `vlist` | 28.1 KB | 10.6 KB |
|
|
157
|
+
| `vlist/solid` `createVList` | 28.2 KB | 10.6 KB |
|
|
158
|
+
| `vlist/react` `useVList` | 28.3 KB | 10.7 KB |
|
|
159
|
+
| `vlist/react` + `grid()` | 35.8 KB | 13.3 KB |
|
|
160
|
+
|
|
161
|
+
Sizes are tree-shaken totals from `bun run size`, not additive plugin costs. Plugin rows include the native default factory plus that plugin; framework rows add the entry, with the framework itself external. The base is **10,735 bytes gzipped**, within the 10.59 KB budget (10,844 bytes). `bun run size` fails if a scenario fails to build, an unused plugin leaks into a bundle, or any published size exceeds its gzip budget. Synthetic input is **13,402 bytes** before plugins; with `scroll.mode`, a `vlist` list downloads the driver and its scrollbar as `synthetic-driver.js` (6.2 KB gzipped) only when it goes synthetic. The alias row measures the same source factory; the distributed alias re-exports it without duplicating the implementation.
|
|
162
|
+
|
|
163
|
+
Bundlephobia's badge measures the package's root entry, which re-exports every plugin, minified and gzipped as one bundle. With a tree-shaking bundler, an app that imports named exports from `vlist` bundles the base (**10.5 KB gzipped**) and the features it uses; the table's rows are each a combined size, not amounts to add up.
|
|
164
|
+
|
|
165
|
+
`table()`'s `estimatedRowHeight` is deprecated in 3.3.0 and will be removed in 4.0
|
|
166
|
+
(#345). It remains accepted but does not size or measure rows; non-production
|
|
167
|
+
builds warn once per `table()` call. Use `rowHeight` for fixed rows or a `rowHeight`
|
|
168
|
+
function with the `remeasureItem(index)` API in 3.3.0 for heights that
|
|
169
|
+
change after creation (#347). Table rows are not automatically measured and
|
|
170
|
+
`table()` remains incompatible with `autosize()`.
|
|
164
171
|
|
|
165
172
|
## Frameworks
|
|
166
173
|
|
package/dist/config.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createVList as
|
|
1
|
+
import{createVList as C,page as c,autosize as T,data as L,grid as V,masonry as x,groups as b,selection as w,a11y as p,scrollbar as u,snapshots as M}from"./index.js";function z(e){let t=[];if(typeof window<"u"&&e.scroll?.element===window)t.push(c());let s=e.item,o=e.orientation==="horizontal",g=o?s.width!=null:s.height!=null,f=o?s.estimatedWidth!=null:s.estimatedHeight!=null;if(!g&&f){if(e.layout==="grid")throw Error('[vlist] config: layout: "grid" needs a fixed item size. An estimate wires autosize(), which grid() cannot combine with: grid indexes its size cache by row, autosize measures items. Use item.height (item.width when horizontal).');let n=e.plugins??[];if(!n.some((i)=>i.name==="autosize")){let i=n.find((a)=>a.name!=="autosize"&&a.conflicts?.includes("autosize"))?.name,y=e.layout==="masonry"&&!n.some((a)=>a.name==="masonry"),l=i??(y?"masonry":void 0),d=o?"item.estimatedWidth":"item.estimatedHeight",m=o?"item.width":"item.height";if(l==="table"){if(o)throw Error("[vlist] table: cannot be used with horizontal orientation");throw Error("[vlist] config: item.estimatedHeight cannot be combined with table(): an estimated item size asks for measured rows, and table() gives every row a fixed height. Give the table a fixed rowHeight and drop the estimate. Use item.height.")}if(l==="masonry")throw Error(`[vlist] config: ${d} cannot be combined with `+(i==="masonry"?"masonry()":'layout: "masonry"')+`: an estimated item size asks for measured items, and masonry() lays every item out from the size cache it is handed. Give the items a fixed ${m} and drop the estimate.`);if(l==="carousel")throw Error(`[vlist] config: ${d} cannot be combined with carousel(): an estimated item size asks for measured slides, and carousel() builds its slide steps from the item size it is given. Give the slides a fixed ${m} and drop the estimate.`)}t.push(T())}if(e.adapter)t.push(L({adapter:e.adapter,...e.loading&&{loading:e.loading}}));if(e.layout==="grid"){if(!e.grid)throw Error('[vlist] config: layout: "grid" requires a `grid` option, e.g. { columns: 3 }');t.push(V(e.grid))}if(e.layout==="masonry"){if(!e.masonry)throw Error('[vlist] config: layout: "masonry" requires a `masonry` option, e.g. { columns: 3 }');t.push(x(e.masonry))}if(e.groups)t.push(b(e.groups));if(e.selection)t.push(w(e.selection));if(e.a11y)t.push(e.a11y===!0?p():p(e.a11y));let r=e.scroll?.scrollbar??e.scrollbar;if(r===!0)t.push(u({}));else if(r&&typeof r==="object")t.push(u(r));if(e.snapshots)t.push(M());if(e.plugins&&e.plugins.length>0){let n=new Set(e.plugins.map((i)=>i.name));return[...t.filter((i)=>!n.has(i.name)),...e.plugins]}return t}function I(e){let{factory:t,...s}=e;return(t??C)(s,z(e))}export{I as createVListFromConfig,z as resolvePlugins};
|
package/dist/core/types.d.ts
CHANGED
|
@@ -255,6 +255,19 @@ export interface VList<T extends VListItem = VListItem> {
|
|
|
255
255
|
appendItems(items: T[]): void;
|
|
256
256
|
prependItems(items: T[]): void;
|
|
257
257
|
updateItem(id: string | number, updates: Partial<T>): void;
|
|
258
|
+
/**
|
|
259
|
+
* Ask whichever per-item size source owns the list to re-read item `index`,
|
|
260
|
+
* then make the list observe the result: content size, scroll anchor and any
|
|
261
|
+
* plugin state derived from offsets. The item data is not written, so a
|
|
262
|
+
* mounted row keeps its DOM — and a focused control inside it.
|
|
263
|
+
*
|
|
264
|
+
* @param index Data index, in `[0, total)`. Never throws for an index.
|
|
265
|
+
* @returns `true` when a size source was asked (the size may be unchanged),
|
|
266
|
+
* `false` when the index is not an integer or out of range, the layout's
|
|
267
|
+
* size model cannot address one data item (`grid()`, `masonry()`,
|
|
268
|
+
* `carousel()`), or the item spec is fixed.
|
|
269
|
+
*/
|
|
270
|
+
remeasureItem(index: number): boolean;
|
|
258
271
|
insertItem(item: T, index?: number): void;
|
|
259
272
|
removeItem(id: string | number): void;
|
|
260
273
|
removeItems(ids: ReadonlyArray<string | number>): number;
|