@fusion.dev/helix-core 0.215.1 → 0.215.3
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.
|
@@ -215,6 +215,12 @@ export declare class VirtualizeController implements ReactiveController {
|
|
|
215
215
|
private heading;
|
|
216
216
|
/** Whether a finger is on the box. iOS keeps scrolling after it lifts. */
|
|
217
217
|
private touching;
|
|
218
|
+
/**
|
|
219
|
+
* Whether the reader uses a touch screen: the device says its pointer is
|
|
220
|
+
* coarse, or a finger has been on the box. Rows are held while the box moves
|
|
221
|
+
* on such a screen only, since a mouse wheel does not end on a row change.
|
|
222
|
+
*/
|
|
223
|
+
private touched;
|
|
218
224
|
/** The timer that ends a scroll, set again on every scroll event. */
|
|
219
225
|
private resting;
|
|
220
226
|
/**
|
|
@@ -299,8 +305,13 @@ export declare class VirtualizeController implements ReactiveController {
|
|
|
299
305
|
* scroll offset, with what is owed to it and less the drift.
|
|
300
306
|
*/
|
|
301
307
|
private offset;
|
|
302
|
-
/**
|
|
308
|
+
/**
|
|
309
|
+
* How far past the screen to draw toward the side the box is scrolling to,
|
|
310
|
+
* and on a touched screen on both sides, `BUFFER` boxes of it.
|
|
311
|
+
*/
|
|
303
312
|
private lead;
|
|
313
|
+
/** Whether the rows beyond the box are drawn on the side the box is not scrolling to. */
|
|
314
|
+
private both;
|
|
304
315
|
/**
|
|
305
316
|
* Reads the scroll offset and settles the window.
|
|
306
317
|
*
|
|
@@ -309,6 +320,16 @@ export declare class VirtualizeController implements ReactiveController {
|
|
|
309
320
|
* so requesting one per event would re-render the list for every pixel.
|
|
310
321
|
*/
|
|
311
322
|
measure(): void;
|
|
323
|
+
/**
|
|
324
|
+
* Whether the rows already drawn are kept for now: the screen is touched, the
|
|
325
|
+
* box is moving, and the rows drawn cover all of it.
|
|
326
|
+
*
|
|
327
|
+
* Not in a waterfall, where an item measured moves the items under it and
|
|
328
|
+
* the host draws them again.
|
|
329
|
+
*/
|
|
330
|
+
private holds;
|
|
331
|
+
/** The window with the rows `first` to `last`, and the spacers that stand in for the rest. */
|
|
332
|
+
private frame;
|
|
312
333
|
/** The straight line: one estimate, so offset and index convert by division. */
|
|
313
334
|
private uniform;
|
|
314
335
|
/**
|
|
@@ -3,6 +3,7 @@ import { reportRuntime } from '../../utils/report-runtime/report-runtime.js';
|
|
|
3
3
|
import { Heights } from './heights.js';
|
|
4
4
|
const UNSTABLE = 10;
|
|
5
5
|
const REST = 150;
|
|
6
|
+
const BUFFER = 2;
|
|
6
7
|
export class VirtualizeController {
|
|
7
8
|
constructor(host, options) {
|
|
8
9
|
this.watching = false;
|
|
@@ -15,6 +16,7 @@ export class VirtualizeController {
|
|
|
15
16
|
this.lastTop = 0;
|
|
16
17
|
this.heading = 0;
|
|
17
18
|
this.touching = false;
|
|
19
|
+
this.touched = typeof matchMedia === 'function' && matchMedia('(any-pointer: coarse)').matches;
|
|
18
20
|
this.uneven = false;
|
|
19
21
|
this.handleScroll = () => {
|
|
20
22
|
const box = this.options.container();
|
|
@@ -34,6 +36,7 @@ export class VirtualizeController {
|
|
|
34
36
|
};
|
|
35
37
|
this.handleTouchStart = () => {
|
|
36
38
|
this.touching = true;
|
|
39
|
+
this.touched = true;
|
|
37
40
|
};
|
|
38
41
|
this.handleTouchEnd = () => {
|
|
39
42
|
this.touching = false;
|
|
@@ -43,7 +46,13 @@ export class VirtualizeController {
|
|
|
43
46
|
};
|
|
44
47
|
this.rest = () => {
|
|
45
48
|
this.resting = undefined;
|
|
46
|
-
if (this.touching
|
|
49
|
+
if (this.touching) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (this.drift === 0) {
|
|
53
|
+
if (this.touched) {
|
|
54
|
+
this.measure();
|
|
55
|
+
}
|
|
47
56
|
return;
|
|
48
57
|
}
|
|
49
58
|
this.square();
|
|
@@ -148,8 +157,14 @@ export class VirtualizeController {
|
|
|
148
157
|
return this.scrolled(box) + this.owed - this.drift;
|
|
149
158
|
}
|
|
150
159
|
lead(box) {
|
|
160
|
+
if (this.touched) {
|
|
161
|
+
return this.span(box) * BUFFER;
|
|
162
|
+
}
|
|
151
163
|
return this.heading === 0 ? 0 : this.span(box);
|
|
152
164
|
}
|
|
165
|
+
both() {
|
|
166
|
+
return this.touched;
|
|
167
|
+
}
|
|
153
168
|
measure() {
|
|
154
169
|
this.watch();
|
|
155
170
|
const box = this.options.container();
|
|
@@ -168,10 +183,14 @@ export class VirtualizeController {
|
|
|
168
183
|
this.square();
|
|
169
184
|
next = choose();
|
|
170
185
|
}
|
|
171
|
-
|
|
186
|
+
const moved = this.last?.count !== total || this.last.estimate !== size;
|
|
187
|
+
if (moved) {
|
|
172
188
|
this.last = { count: total, estimate: size };
|
|
173
189
|
this.settling = 0;
|
|
174
190
|
}
|
|
191
|
+
if (!moved && this.holds(box, total)) {
|
|
192
|
+
next = this.frame(this.window.first, this.window.last, total, size);
|
|
193
|
+
}
|
|
175
194
|
const same = next.first === this.window.first &&
|
|
176
195
|
next.last === this.window.last &&
|
|
177
196
|
next.before === this.window.before &&
|
|
@@ -188,11 +207,38 @@ export class VirtualizeController {
|
|
|
188
207
|
this.window = next;
|
|
189
208
|
this.host.requestUpdate();
|
|
190
209
|
}
|
|
210
|
+
holds(box, total) {
|
|
211
|
+
if (!this.touched || !this.scrolling() || this.laned(total)) {
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
const { first, last, before } = this.window;
|
|
215
|
+
if (last <= first || last > total) {
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
const size = this.line();
|
|
219
|
+
const drawn = this.measuring()
|
|
220
|
+
? this.startOf(last, total) - this.startOf(first, total)
|
|
221
|
+
: (last - first) * size;
|
|
222
|
+
const top = this.scrolled(box);
|
|
223
|
+
return top >= before && top + this.span(box) <= before + drawn;
|
|
224
|
+
}
|
|
225
|
+
frame(first, last, total, size) {
|
|
226
|
+
return this.measuring()
|
|
227
|
+
? {
|
|
228
|
+
after: Math.max(0, this.startOf(total, total) - this.startOf(last, total)),
|
|
229
|
+
before: this.startOf(first, total) + this.drift,
|
|
230
|
+
first,
|
|
231
|
+
last,
|
|
232
|
+
}
|
|
233
|
+
: { after: Math.max(0, (total - last) * size), before: first * size, first, last };
|
|
234
|
+
}
|
|
191
235
|
uniform(box, total, size, overscan) {
|
|
192
236
|
const extra = Math.ceil(this.lead(box) / size);
|
|
193
237
|
const at = Math.min(Math.floor(this.offset(box) / size), total);
|
|
194
|
-
const first = Math.max(0, at - overscan - (this.heading < 0 ? extra : 0));
|
|
195
|
-
const fits = Math.ceil(this.span(box) / size) +
|
|
238
|
+
const first = Math.max(0, at - overscan - (this.heading < 0 || this.both() ? extra : 0));
|
|
239
|
+
const fits = Math.ceil(this.span(box) / size) +
|
|
240
|
+
overscan * 2 +
|
|
241
|
+
(this.both() ? extra * 2 : this.heading === 0 ? 0 : extra);
|
|
196
242
|
const last = Math.min(total, first + fits);
|
|
197
243
|
return { after: Math.max(0, (total - last) * size), before: first * size, first, last };
|
|
198
244
|
}
|
|
@@ -287,10 +333,10 @@ export class VirtualizeController {
|
|
|
287
333
|
placed(box, total, overscan) {
|
|
288
334
|
const top = this.offset(box);
|
|
289
335
|
const lead = this.lead(box);
|
|
290
|
-
const from = this.heading < 0 ? top - lead : top;
|
|
336
|
+
const from = this.heading < 0 || this.both() ? top - lead : top;
|
|
291
337
|
const more = overscan * (this.laned(total)?.lanes ?? 1);
|
|
292
338
|
const first = Math.max(0, this.indexAt(from, total) - more);
|
|
293
|
-
const bottom = top + this.span(box) + (this.heading > 0 ? lead : 0);
|
|
339
|
+
const bottom = top + this.span(box) + (this.heading > 0 || this.both() ? lead : 0);
|
|
294
340
|
let last = this.indexAt(top, total);
|
|
295
341
|
while (last < total && this.startOf(last, total) < bottom) {
|
|
296
342
|
last += 1;
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '0.215.
|
|
1
|
+
export const VERSION = '0.215.3';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusion.dev/helix-core",
|
|
3
3
|
"description": "Helix element primitives: base classes, mixins, decorators, utilities.",
|
|
4
|
-
"version": "0.215.
|
|
4
|
+
"version": "0.215.3",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ross Sheppard <ross.sheppard@fusion.dev>",
|
|
7
7
|
"repository": {
|
|
@@ -81,12 +81,12 @@
|
|
|
81
81
|
"bugs": "https://github.com/project-fusion/fusion/issues",
|
|
82
82
|
"dependencies": {
|
|
83
83
|
"@floating-ui/dom": "^1.8.0",
|
|
84
|
-
"@fusion.dev/helix-icons": "0.215.
|
|
84
|
+
"@fusion.dev/helix-icons": "0.215.3",
|
|
85
85
|
"tslib": "^2.8.1"
|
|
86
86
|
},
|
|
87
87
|
"devDependencies": {
|
|
88
|
-
"@fusion.dev/helix-cem": "0.215.
|
|
89
|
-
"@fusion.dev/helix-testing": "0.215.
|
|
88
|
+
"@fusion.dev/helix-cem": "0.215.3",
|
|
89
|
+
"@fusion.dev/helix-testing": "0.215.3",
|
|
90
90
|
"@lit-labs/ssr": "^4.1.0",
|
|
91
91
|
"lit": "^3.2.1"
|
|
92
92
|
},
|