vlist 3.0.0 → 3.1.0-next.2
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 +59 -53
- package/README.md +59 -53
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/constants.d.ts +0 -16
- package/dist/core/adapter.d.ts +3 -3
- package/dist/core/create.d.ts +10 -5
- package/dist/core/fold.d.ts +3 -3
- package/dist/core/logical.d.ts +93 -0
- package/dist/core/runway.d.ts +20 -106
- package/dist/core/state.d.ts +2 -2
- package/dist/core/switching.d.ts +15 -0
- package/dist/core/types.d.ts +6 -2
- package/dist/index.js +1 -1
- package/dist/internals.js +1 -1
- package/dist/plugins/carousel/input.d.ts +16 -0
- package/dist/plugins/carousel/plugin.d.ts +2 -3
- package/dist/size.json +1 -1
- package/dist/synthetic/driver.d.ts +26 -0
- package/dist/synthetic/handler.d.ts +4 -4
- package/dist/synthetic-driver.js +1 -0
- package/dist/synthetic.d.ts +7 -0
- package/dist/synthetic.js +1 -1
- package/dist/types.d.ts +22 -3
- package/dist/version.json +1 -0
- package/package.json +3 -2
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.0.
|
|
5
|
+
**v3.1.0-next.2** (prerelease on the npm `next` tag) — `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; carousels honour `"synthetic"`; `vlist/synthetic` is deprecated. See the [changelog](https://github.com/floor/vlist/blob/next/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 tiny adapters for Vue, Svelte, Solid, React
|
|
14
|
-
- **10.
|
|
14
|
+
- **10.3 KB gzipped** — composable plugins with perfect tree-shaking
|
|
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
|
|
@@ -46,20 +46,19 @@ npm install vlist@2 # the 2.x line, still maintained
|
|
|
46
46
|
npm install vlist vlist-vue # or vlist-svelte / vlist-solidjs / vlist-react
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
Adapters
|
|
49
|
+
Adapters forward `scroll` unchanged, so `scroll.mode` works through them too (adapters `3.1.0-next.2` and later):
|
|
50
50
|
|
|
51
51
|
```ts
|
|
52
52
|
import { useVList } from "vlist-react";
|
|
53
|
-
import { createVList } from "vlist/synthetic";
|
|
54
53
|
|
|
55
54
|
useVList({
|
|
56
|
-
factory: createVList,
|
|
57
55
|
items,
|
|
58
56
|
item: { height: 48, template: item => String(item.id) },
|
|
57
|
+
scroll: { mode: "synthetic" }, // "auto" by default
|
|
59
58
|
});
|
|
60
59
|
```
|
|
61
60
|
|
|
62
|
-
The
|
|
61
|
+
The mode is structural configuration: changing it requires recreating the list.
|
|
63
62
|
|
|
64
63
|
## Quick Start
|
|
65
64
|
|
|
@@ -108,47 +107,54 @@ const list = createVList({
|
|
|
108
107
|
|
|
109
108
|
## Scroll input
|
|
110
109
|
|
|
111
|
-
|
|
110
|
+
`scroll.mode` chooses who owns scroll input, on the one `vlist` entry. Plugins come from `vlist` in every mode.
|
|
112
111
|
|
|
113
|
-
|
|
|
112
|
+
| `scroll.mode` | Input | Use |
|
|
114
113
|
|---|---|---|
|
|
115
|
-
| `
|
|
116
|
-
| `
|
|
117
|
-
| `
|
|
114
|
+
| `"auto"` (default) | Native; past the browser's element size limit (16,000,000 px of content) the list hands itself to synthetic input in place, and takes native input back below 12,000,000 px | Every list: nothing to choose, however large it grows |
|
|
115
|
+
| `"native"` | Always native | Browser scrolling only; past the limit the last rows are out of reach, and `content:size:overflow` says so |
|
|
116
|
+
| `"synthetic"` | vlist owns wheel, touch and keys from the start | Application-owned touch motion |
|
|
118
117
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
Select synthetic input by importing its factory; there is no `scroll.mode` option. Plugins still come from `vlist`.
|
|
118
|
+
Native input keeps browser scrollbars, native touch momentum, boundary handoff and native assistive-technology scrolling. The synthetic driver is a separate file, `synthetic-driver.js`, downloaded the first time a list needs it; until it arrives the list scrolls natively. Each handoff emits `scroll:mode`.
|
|
122
119
|
|
|
123
120
|
```typescript
|
|
124
|
-
import { createVList } from 'vlist
|
|
125
|
-
import { scrollbar } from 'vlist'
|
|
121
|
+
import { createVList } from 'vlist'
|
|
126
122
|
import 'vlist/styles'
|
|
127
123
|
|
|
128
124
|
const list = createVList({
|
|
129
125
|
container: '#my-list',
|
|
130
126
|
items: Array.from({ length: 1000 }, (_, id) => ({ id, name: `Row ${id}` })),
|
|
131
127
|
item: { height: 48, template: item => `<div>${item.name}</div>` },
|
|
132
|
-
},
|
|
128
|
+
scroll: { mode: 'synthetic' },
|
|
129
|
+
})
|
|
133
130
|
```
|
|
134
131
|
|
|
135
|
-
|
|
132
|
+
| Entry | Use |
|
|
133
|
+
|---|---|
|
|
134
|
+
| `vlist` | Every list; input chosen by `scroll.mode` |
|
|
135
|
+
| `vlist/synthetic` | Deprecated: `scroll: { mode: "synthetic" }`. Kept through 3.x; it bundles the driver instead of loading it |
|
|
136
|
+
| `vlist/native` | Deprecated alias of `vlist` |
|
|
137
|
+
|
|
138
|
+
### Synthetic input
|
|
139
|
+
|
|
140
|
+
A synthetic list draws its own scrollbar, since the browser draws none for content the size of its viewport: the `scrollbar()` plugin's, loaded with the driver. `scroll.scrollbar` options configure it, `"none"` skips it, and a list with `scrollbar()` keeps that one. `scroll.scrollbar: "native"` asks for the browser's scrollbar, so `mode: "synthetic"` rejects it.
|
|
141
|
+
|
|
142
|
+
`page()` scrolls the document natively in every mode. Its content must fit the 16,777,216 px document element limit; creation throws above that limit when the size is known, and later growth warns once. A deferred custom renderer whose size is first committed during rendering also warns once. Use viewport scrolling (`"auto"` or `"synthetic"`) for larger lists.
|
|
136
143
|
|
|
137
|
-
`carousel()`
|
|
144
|
+
`carousel()` runs on its own wrap runway with `"auto"` and `"native"`, and on the synthetic handler with `"synthetic"`: folds preserve touch motion and smooth snapping across whole laps. The first carousel on a page starts on its runway and switches in place once the driver loads and the carousel is idle. `page()` and carousel remain incompatible.
|
|
138
145
|
|
|
139
146
|
Synthetic input limitations:
|
|
140
147
|
|
|
141
|
-
- Horizontal RTL lists throw at creation
|
|
142
|
-
- Same-axis touch stops at either boundary with no parent handoff, including gestures starting inside an edge-pinned list. Use
|
|
143
|
-
- There is no native main-axis scrollbar. Add `scrollbar()` for an accessible custom scrollbar. The synthetic entry rejects the `"native"` and `"none"` scrollbar strings.
|
|
148
|
+
- Horizontal RTL lists throw at creation, in every mode. Vertical lists and tables support `dir="rtl"`, including cross-axis wheel movement, aligned table headers and keyboard column navigation.
|
|
149
|
+
- Same-axis touch stops at either boundary with no parent handoff, including gestures starting inside an edge-pinned list. Use `"native"` when boundary gestures must scroll the parent page.
|
|
144
150
|
- Inertia initializes its frame clock on the first frame after release, adding up to one frame of release latency.
|
|
145
151
|
- Wheel input at an edge is left to the page when it cannot move the list. Native cross-axis scrolling remains available.
|
|
146
152
|
|
|
147
|
-
Measurement corrections from autosize preserve ongoing synthetic motion. Existing plugin conflicts still apply. See the [scroll input contract](https://vlist.io/docs/rfcs/RFC-014-Scroll-Input-Model).
|
|
153
|
+
Measurement corrections from autosize preserve ongoing synthetic motion. Existing plugin conflicts still apply. See the [scroll input contract](https://vlist.io/docs/rfcs/RFC-014-Scroll-Input-Model) and [RFC-015](https://vlist.io/docs/rfcs/RFC-015-Overflow-Handoff).
|
|
148
154
|
|
|
149
155
|
### Sortable gestures
|
|
150
156
|
|
|
151
|
-
`sortable()` works
|
|
157
|
+
`sortable()` works in every scroll mode. Mouse and trackpad dragging still starts after `dragThreshold` (5 px by default). Touch and pen without a handle use `touchDelay`, a 350 ms long press; moving at least `dragThreshold` pixels in any direction before it completes yields to scrolling. This delay separates a deliberate hold from a quick flick. With `handle`, dragging starts at the threshold without waiting; touches elsewhere scroll.
|
|
152
158
|
|
|
153
159
|
```typescript
|
|
154
160
|
sortable({ touchDelay: 350, dragThreshold: 5 })
|
|
@@ -161,46 +167,46 @@ The touch-only `.vlist-item--touch-sort` class suppresses selection and callouts
|
|
|
161
167
|
|
|
162
168
|
## Migrating to 3.0
|
|
163
169
|
|
|
164
|
-
|
|
170
|
+
3.0 scrolls natively by default, as 2.x did. Since 3.1, `scroll.mode` chooses the input on the one `vlist` entry, and its default, `"auto"`, hands huge lists to synthetic input by itself. `vlist/synthetic` and `vlist/native` are deprecated aliases; `vlist/native` its `NativeScrollConfig` and `NativeCreateVListConfig` types alias the standard `ScrollConfig` and `CreateVListConfig`.
|
|
165
171
|
|
|
166
172
|
| 2.x option or API | 3.0 replacement |
|
|
167
173
|
|---|---|
|
|
168
|
-
| `scroll.mode`
|
|
169
|
-
| `scroll.runway`
|
|
170
|
-
| `scroll.scrollbar: "native"` or `"none"` | Retained
|
|
174
|
+
| `scroll.mode` | Since 3.1: `"auto"` (default), `"native"` or `"synthetic"`. The 2.x `"bounded"` is refused. |
|
|
175
|
+
| `scroll.runway` | Remove it. Huge lists need nothing: the default `scroll.mode`, `"auto"`, hands them to synthetic input. |
|
|
176
|
+
| `scroll.scrollbar: "native"` or `"none"` | Retained. `"native"` needs native input; a synthetic list draws its own scrollbar, which `"none"` skips. |
|
|
171
177
|
| `PluginContext.setScrollFns`, `disableDefaultScroll` | Use `ctx.scroll.setSource` to supply an external position source and commit callback. |
|
|
172
178
|
| Flat `PluginContext` members (`registerMethod`, `forceRender`, `sizeCache`, `scrollTo`, …) | Grouped by capability: `ctx.hooks.method`, `ctx.render.force`, `ctx.sizes.cache`, `ctx.scroll.to`, `ctx.items.all`. `pool`, `config`, `emitter`, `template` and `getState()` stay at the top level. |
|
|
173
|
-
| `scale()` and `ScalePluginConfig` | Remove them;
|
|
179
|
+
| `scale()` and `ScalePluginConfig` | Remove them; the default `scroll.mode` covers the full logical range. Config no longer installs a scale stub. |
|
|
174
180
|
|
|
175
|
-
|
|
181
|
+
`scroll.runway` and the bounded mode throw a migration error before creating DOM. `vlist/config` wires only what the config asks for: `selection`, the custom scrollbar, `snapshots` and `a11y` are each opt-in, so an adapter list matches a core list built from the same options. It keeps the scrollbar options convenience and its top-level `scrollbar: "none"`; pass `scrollbar: true` for the overlay scrollbar earlier versions added to every list. `baseOffset` stays private engine state; plugins use `ctx.scroll.getRenderOrigin()`. Custom wrap providers supply their handler factory as the second argument of `ctx.scroll.setWrap` (named `setBoundedWrap` in 3.0.0, still accepted).
|
|
176
182
|
|
|
177
183
|
## Plugins
|
|
178
184
|
|
|
179
185
|
| Entry / export | Minified | Gzipped |
|
|
180
186
|
|---|---:|---:|
|
|
181
|
-
| **Base (`vlist`)** | 27.
|
|
182
|
-
| `vlist/synthetic` |
|
|
183
|
-
| `vlist/native` (alias) | 27.
|
|
184
|
-
| `a11y()` |
|
|
185
|
-
| `selection()` | 36.
|
|
186
|
-
| `data()` |
|
|
187
|
-
| `scrollbar()` | 35.
|
|
188
|
-
| `sortable()` |
|
|
189
|
-
| `groups()` | 43.
|
|
190
|
-
| `page()` | 29.
|
|
191
|
-
| `snapshots()` | 30.
|
|
192
|
-
| `transition()` |
|
|
193
|
-
| `autosize()` | 30.
|
|
194
|
-
| `grid()` | 34.
|
|
195
|
-
| `table()` | 45.
|
|
196
|
-
| `masonry()` | 39.
|
|
197
|
-
| `tree()` | 43.
|
|
198
|
-
| `search()` | 36.
|
|
199
|
-
| `carousel()` |
|
|
200
|
-
| `vlist/synthetic` + `carousel()` |
|
|
201
|
-
| `vlist/synthetic` + `sortable()` |
|
|
202
|
-
|
|
203
|
-
Sizes are tree-shaken totals from `bun run size`, not additive plugin costs. Plugin rows include the native default factory plus that plugin. The base is **10,
|
|
187
|
+
| **Base (`vlist`)** | 27.3 KB | 10.3 KB |
|
|
188
|
+
| `vlist/synthetic` (deprecated) | 34.2 KB | 12.9 KB |
|
|
189
|
+
| `vlist/native` (alias) | 27.3 KB | 10.3 KB |
|
|
190
|
+
| `a11y()` | 31.2 KB | 11.7 KB |
|
|
191
|
+
| `selection()` | 36.9 KB | 13.2 KB |
|
|
192
|
+
| `data()` | 41.0 KB | 15.1 KB |
|
|
193
|
+
| `scrollbar()` | 35.5 KB | 13.2 KB |
|
|
194
|
+
| `sortable()` | 39.2 KB | 13.9 KB |
|
|
195
|
+
| `groups()` | 43.4 KB | 15.7 KB |
|
|
196
|
+
| `page()` | 29.9 KB | 11.2 KB |
|
|
197
|
+
| `snapshots()` | 30.6 KB | 11.4 KB |
|
|
198
|
+
| `transition()` | 34.1 KB | 12.3 KB |
|
|
199
|
+
| `autosize()` | 30.6 KB | 11.5 KB |
|
|
200
|
+
| `grid()` | 34.8 KB | 12.9 KB |
|
|
201
|
+
| `table()` | 45.8 KB | 16.2 KB |
|
|
202
|
+
| `masonry()` | 39.4 KB | 14.7 KB |
|
|
203
|
+
| `tree()` | 43.6 KB | 15.7 KB |
|
|
204
|
+
| `search()` | 36.9 KB | 13.6 KB |
|
|
205
|
+
| `carousel()` | 43.1 KB | 15.7 KB |
|
|
206
|
+
| `vlist/synthetic` + `carousel()` | 49.2 KB | 18.0 KB |
|
|
207
|
+
| `vlist/synthetic` + `sortable()` | 46.1 KB | 16.5 KB |
|
|
208
|
+
|
|
209
|
+
Sizes are tree-shaken totals from `bun run size`, not additive plugin costs. Plugin rows include the native default factory plus that plugin. The base is **10,541 bytes gzipped**, within the 10.3 KB budget (10,547 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,183 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.
|
|
204
210
|
|
|
205
211
|
## Examples
|
|
206
212
|
|
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.0.
|
|
5
|
+
**v3.1.0-next.2** (prerelease on the npm `next` tag) — `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; carousels honour `"synthetic"`; `vlist/synthetic` is deprecated. See the [changelog](https://github.com/floor/vlist/blob/next/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, tiny adapters for Vue, Svelte, Solid, React
|
|
14
|
-
- **10.
|
|
14
|
+
- **10.3 KB gzipped** — composable plugins with perfect tree-shaking
|
|
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
|
|
|
@@ -55,47 +55,54 @@ const list = createVList({ container: '#app', items, item: { height: 200, templa
|
|
|
55
55
|
|
|
56
56
|
## Scroll input
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
`scroll.mode` chooses who owns scroll input, on the one `vlist` entry. Plugins come from `vlist` in every mode.
|
|
59
59
|
|
|
60
|
-
|
|
|
60
|
+
| `scroll.mode` | Input | Use |
|
|
61
61
|
|---|---|---|
|
|
62
|
-
| `
|
|
63
|
-
| `
|
|
64
|
-
| `
|
|
62
|
+
| `"auto"` (default) | Native; past the browser's element size limit (16,000,000 px of content) the list hands itself to synthetic input in place, and takes native input back below 12,000,000 px | Every list: nothing to choose, however large it grows |
|
|
63
|
+
| `"native"` | Always native | Browser scrolling only; past the limit the last rows are out of reach, and `content:size:overflow` says so |
|
|
64
|
+
| `"synthetic"` | vlist owns wheel, touch and keys from the start | Application-owned touch motion |
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
Select synthetic input by importing its factory; there is no `scroll.mode` option. Plugins still come from `vlist`.
|
|
66
|
+
Native input keeps browser scrollbars, native touch momentum, boundary handoff and native assistive-technology scrolling. The synthetic driver is a separate file, `synthetic-driver.js`, downloaded the first time a list needs it; until it arrives the list scrolls natively. Each handoff emits `scroll:mode`.
|
|
69
67
|
|
|
70
68
|
```typescript
|
|
71
|
-
import { createVList } from 'vlist
|
|
72
|
-
import { scrollbar } from 'vlist'
|
|
69
|
+
import { createVList } from 'vlist'
|
|
73
70
|
import 'vlist/styles'
|
|
74
71
|
|
|
75
72
|
const list = createVList({
|
|
76
73
|
container: '#my-list',
|
|
77
74
|
items: Array.from({ length: 1000 }, (_, id) => ({ id, name: `Row ${id}` })),
|
|
78
75
|
item: { height: 48, template: item => `<div>${item.name}</div>` },
|
|
79
|
-
},
|
|
76
|
+
scroll: { mode: 'synthetic' },
|
|
77
|
+
})
|
|
80
78
|
```
|
|
81
79
|
|
|
82
|
-
|
|
80
|
+
| Entry | Use |
|
|
81
|
+
|---|---|
|
|
82
|
+
| `vlist` | Every list; input chosen by `scroll.mode` |
|
|
83
|
+
| `vlist/synthetic` | Deprecated: `scroll: { mode: "synthetic" }`. Kept through 3.x; it bundles the driver instead of loading it |
|
|
84
|
+
| `vlist/native` | Deprecated alias of `vlist` |
|
|
85
|
+
|
|
86
|
+
### Synthetic input
|
|
87
|
+
|
|
88
|
+
A synthetic list draws its own scrollbar, since the browser draws none for content the size of its viewport: the `scrollbar()` plugin's, loaded with the driver. `scroll.scrollbar` options configure it, `"none"` skips it, and a list with `scrollbar()` keeps that one. `scroll.scrollbar: "native"` asks for the browser's scrollbar, so `mode: "synthetic"` rejects it.
|
|
89
|
+
|
|
90
|
+
`page()` scrolls the document natively in every mode. Its content must fit the 16,777,216 px document element limit; creation throws above that limit when the size is known, and later growth warns once. A deferred custom renderer whose size is first committed during rendering also warns once. Use viewport scrolling (`"auto"` or `"synthetic"`) for larger lists.
|
|
83
91
|
|
|
84
|
-
`carousel()`
|
|
92
|
+
`carousel()` runs on its own wrap runway with `"auto"` and `"native"`, and on the synthetic handler with `"synthetic"`: folds preserve touch motion and smooth snapping across whole laps. The first carousel on a page starts on its runway and switches in place once the driver loads and the carousel is idle. `page()` and carousel remain incompatible.
|
|
85
93
|
|
|
86
94
|
Synthetic input limitations:
|
|
87
95
|
|
|
88
|
-
- Horizontal RTL lists throw at creation
|
|
89
|
-
- Same-axis touch stops at either boundary with no parent handoff, including gestures starting inside an edge-pinned list. Use
|
|
90
|
-
- There is no native main-axis scrollbar. Add `scrollbar()` for an accessible custom scrollbar. The synthetic entry rejects the `"native"` and `"none"` scrollbar strings.
|
|
96
|
+
- Horizontal RTL lists throw at creation, in every mode. Vertical lists and tables support `dir="rtl"`, including cross-axis wheel movement, aligned table headers and keyboard column navigation.
|
|
97
|
+
- Same-axis touch stops at either boundary with no parent handoff, including gestures starting inside an edge-pinned list. Use `"native"` when boundary gestures must scroll the parent page.
|
|
91
98
|
- Inertia initializes its frame clock on the first frame after release, adding up to one frame of release latency.
|
|
92
99
|
- Wheel input at an edge is left to the page when it cannot move the list. Native cross-axis scrolling remains available.
|
|
93
100
|
|
|
94
|
-
Measurement corrections from autosize preserve ongoing synthetic motion. Existing plugin conflicts still apply. See the [scroll input contract](https://vlist.io/docs/rfcs/RFC-014-Scroll-Input-Model).
|
|
101
|
+
Measurement corrections from autosize preserve ongoing synthetic motion. Existing plugin conflicts still apply. See the [scroll input contract](https://vlist.io/docs/rfcs/RFC-014-Scroll-Input-Model) and [RFC-015](https://vlist.io/docs/rfcs/RFC-015-Overflow-Handoff).
|
|
95
102
|
|
|
96
103
|
### Sortable gestures
|
|
97
104
|
|
|
98
|
-
`sortable()` works
|
|
105
|
+
`sortable()` works in every scroll mode. Mouse and trackpad dragging still starts after `dragThreshold` (5 px by default). Touch and pen without a handle use `touchDelay`, a 350 ms long press; moving at least `dragThreshold` pixels in any direction before it completes yields to scrolling. This delay separates a deliberate hold from a quick flick. With `handle`, dragging starts at the threshold without waiting; touches elsewhere scroll.
|
|
99
106
|
|
|
100
107
|
```typescript
|
|
101
108
|
sortable({ touchDelay: 350, dragThreshold: 5 })
|
|
@@ -108,45 +115,45 @@ The touch-only `.vlist-item--touch-sort` class suppresses selection and callouts
|
|
|
108
115
|
|
|
109
116
|
## Migrating to 3.0
|
|
110
117
|
|
|
111
|
-
|
|
118
|
+
3.0 scrolls natively by default, as 2.x did. Since 3.1, `scroll.mode` chooses the input on the one `vlist` entry, and its default, `"auto"`, hands huge lists to synthetic input by itself. `vlist/synthetic` and `vlist/native` are deprecated aliases; `vlist/native` its `NativeScrollConfig` and `NativeCreateVListConfig` types alias the standard `ScrollConfig` and `CreateVListConfig`.
|
|
112
119
|
|
|
113
120
|
| 2.x option or API | 3.0 replacement |
|
|
114
121
|
|---|---|
|
|
115
|
-
| `scroll.mode`
|
|
116
|
-
| `scroll.runway`
|
|
117
|
-
| `scroll.scrollbar: "native"` or `"none"` | Retained
|
|
122
|
+
| `scroll.mode` | Since 3.1: `"auto"` (default), `"native"` or `"synthetic"`. The 2.x `"bounded"` is refused. |
|
|
123
|
+
| `scroll.runway` | Remove it. Huge lists need nothing: the default `scroll.mode`, `"auto"`, hands them to synthetic input. |
|
|
124
|
+
| `scroll.scrollbar: "native"` or `"none"` | Retained. `"native"` needs native input; a synthetic list draws its own scrollbar, which `"none"` skips. |
|
|
118
125
|
| `PluginContext.setScrollFns`, `disableDefaultScroll` | Use `setScrollSource` to supply an external position source and commit callback. |
|
|
119
|
-
| `scale()` and `ScalePluginConfig` | Remove them;
|
|
126
|
+
| `scale()` and `ScalePluginConfig` | Remove them; the default `scroll.mode` covers the full logical range. Config no longer installs a scale stub. |
|
|
120
127
|
|
|
121
|
-
|
|
128
|
+
`scroll.runway` and the bounded mode throw a migration error before creating DOM. `vlist/config` wires only what the config asks for: `selection`, the custom scrollbar, `snapshots` and `a11y` are each opt-in, so an adapter list matches a core list built from the same options. It keeps the scrollbar options convenience and its top-level `scrollbar: "none"`; pass `scrollbar: true` for the overlay scrollbar earlier versions added to every list. `baseOffset` stays private engine state; plugins use `ctx.scroll.getRenderOrigin()`. Custom wrap providers supply their handler factory as the second argument of `ctx.scroll.setWrap` (named `setBoundedWrap` in 3.0.0, still accepted).
|
|
122
129
|
|
|
123
130
|
## Plugins
|
|
124
131
|
|
|
125
132
|
| Entry / export | Minified | Gzipped |
|
|
126
133
|
|---|---:|---:|
|
|
127
|
-
| **Base (`vlist`)** | 27.
|
|
128
|
-
| `vlist/synthetic` |
|
|
129
|
-
| `vlist/native` (alias) | 27.
|
|
130
|
-
| `a11y()` |
|
|
131
|
-
| `selection()` | 36.
|
|
132
|
-
| `data()` |
|
|
133
|
-
| `scrollbar()` | 35.
|
|
134
|
-
| `sortable()` |
|
|
135
|
-
| `groups()` | 43.
|
|
136
|
-
| `page()` | 29.
|
|
137
|
-
| `snapshots()` | 30.
|
|
138
|
-
| `transition()` |
|
|
139
|
-
| `autosize()` | 30.
|
|
140
|
-
| `grid()` | 34.
|
|
141
|
-
| `table()` | 45.
|
|
142
|
-
| `masonry()` | 39.
|
|
143
|
-
| `tree()` | 43.
|
|
144
|
-
| `search()` | 36.
|
|
145
|
-
| `carousel()` |
|
|
146
|
-
| `vlist/synthetic` + `carousel()` |
|
|
147
|
-
| `vlist/synthetic` + `sortable()` |
|
|
148
|
-
|
|
149
|
-
Sizes are tree-shaken totals from `bun run size`, not additive plugin costs. Plugin rows include the native default factory plus that plugin. The base is **10,
|
|
134
|
+
| **Base (`vlist`)** | 27.3 KB | 10.3 KB |
|
|
135
|
+
| `vlist/synthetic` (deprecated) | 34.2 KB | 12.9 KB |
|
|
136
|
+
| `vlist/native` (alias) | 27.3 KB | 10.3 KB |
|
|
137
|
+
| `a11y()` | 31.2 KB | 11.7 KB |
|
|
138
|
+
| `selection()` | 36.9 KB | 13.2 KB |
|
|
139
|
+
| `data()` | 41.0 KB | 15.1 KB |
|
|
140
|
+
| `scrollbar()` | 35.5 KB | 13.2 KB |
|
|
141
|
+
| `sortable()` | 39.2 KB | 13.9 KB |
|
|
142
|
+
| `groups()` | 43.4 KB | 15.7 KB |
|
|
143
|
+
| `page()` | 29.9 KB | 11.2 KB |
|
|
144
|
+
| `snapshots()` | 30.6 KB | 11.4 KB |
|
|
145
|
+
| `transition()` | 34.1 KB | 12.3 KB |
|
|
146
|
+
| `autosize()` | 30.6 KB | 11.5 KB |
|
|
147
|
+
| `grid()` | 34.8 KB | 12.9 KB |
|
|
148
|
+
| `table()` | 45.8 KB | 16.2 KB |
|
|
149
|
+
| `masonry()` | 39.4 KB | 14.7 KB |
|
|
150
|
+
| `tree()` | 43.6 KB | 15.7 KB |
|
|
151
|
+
| `search()` | 36.9 KB | 13.6 KB |
|
|
152
|
+
| `carousel()` | 43.1 KB | 15.7 KB |
|
|
153
|
+
| `vlist/synthetic` + `carousel()` | 49.2 KB | 18.0 KB |
|
|
154
|
+
| `vlist/synthetic` + `sortable()` | 46.1 KB | 16.5 KB |
|
|
155
|
+
|
|
156
|
+
Sizes are tree-shaken totals from `bun run size`, not additive plugin costs. Plugin rows include the native default factory plus that plugin. The base is **10,541 bytes gzipped**, within the 10.3 KB budget (10,547 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,183 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.
|
|
150
157
|
|
|
151
158
|
## Framework Adapters
|
|
152
159
|
|
|
@@ -157,20 +164,19 @@ Sizes are tree-shaken totals from `bun run size`, not additive plugin costs. Plu
|
|
|
157
164
|
| SolidJS | [`vlist-solidjs`](https://github.com/floor/vlist-solidjs) | 0.5 KB |
|
|
158
165
|
| React | [`vlist-react`](https://github.com/floor/vlist-react) | 0.6 KB |
|
|
159
166
|
|
|
160
|
-
Adapters
|
|
167
|
+
Adapters forward `scroll` unchanged, so `scroll.mode` works through them too (adapters `3.1.0-next.2` and later):
|
|
161
168
|
|
|
162
169
|
```ts
|
|
163
170
|
import { useVList } from "vlist-react";
|
|
164
|
-
import { createVList } from "vlist/synthetic";
|
|
165
171
|
|
|
166
172
|
useVList({
|
|
167
|
-
factory: createVList,
|
|
168
173
|
items,
|
|
169
174
|
item: { height: 48, template: item => String(item.id) },
|
|
175
|
+
scroll: { mode: "synthetic" }, // "auto" by default
|
|
170
176
|
});
|
|
171
177
|
```
|
|
172
178
|
|
|
173
|
-
The
|
|
179
|
+
The mode is structural configuration: changing it requires recreating the list.
|
|
174
180
|
|
|
175
181
|
## Docs & Examples
|
|
176
182
|
|
package/dist/config.d.ts
CHANGED
|
@@ -41,7 +41,7 @@ export type VListFactory<T extends VListItem = VListItem> = typeof createVList<T
|
|
|
41
41
|
* translated into plugins by {@link resolvePlugins}.
|
|
42
42
|
*/
|
|
43
43
|
export interface VListConfig<T extends VListItem = VListItem> extends Omit<CreateVListConfig<T>, "container" | "scroll"> {
|
|
44
|
-
/** Scroll options;
|
|
44
|
+
/** Scroll options; `scroll.mode` chooses native, synthetic or auto input. */
|
|
45
45
|
scroll?: ScrollConfig;
|
|
46
46
|
/** List factory; defaults to core createVList. Fixed for this instance. */
|
|
47
47
|
factory?: VListFactory<T>;
|