@fusion.dev/helix-core 0.5.0 → 0.6.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/custom-elements.json
CHANGED
|
@@ -2033,7 +2033,18 @@
|
|
|
2033
2033
|
},
|
|
2034
2034
|
{
|
|
2035
2035
|
"kind": "method",
|
|
2036
|
-
"name": "
|
|
2036
|
+
"name": "measuring",
|
|
2037
|
+
"privacy": "private",
|
|
2038
|
+
"return": {
|
|
2039
|
+
"type": {
|
|
2040
|
+
"text": "boolean"
|
|
2041
|
+
}
|
|
2042
|
+
},
|
|
2043
|
+
"description": "Whether this pass places by measurement: offered, and wanted."
|
|
2044
|
+
},
|
|
2045
|
+
{
|
|
2046
|
+
"kind": "method",
|
|
2047
|
+
"name": "placed",
|
|
2037
2048
|
"privacy": "private",
|
|
2038
2049
|
"return": {
|
|
2039
2050
|
"type": {
|
|
@@ -3902,6 +3913,14 @@
|
|
|
3902
3913
|
"module": "./controllers/token-color-controller/token-color-controller.js"
|
|
3903
3914
|
}
|
|
3904
3915
|
},
|
|
3916
|
+
{
|
|
3917
|
+
"kind": "js",
|
|
3918
|
+
"name": "Rendered",
|
|
3919
|
+
"declaration": {
|
|
3920
|
+
"name": "Rendered",
|
|
3921
|
+
"module": "./controllers/virtualize-controller/virtualize-controller.js"
|
|
3922
|
+
}
|
|
3923
|
+
},
|
|
3905
3924
|
{
|
|
3906
3925
|
"kind": "js",
|
|
3907
3926
|
"name": "VirtualizeController",
|
|
@@ -22,11 +22,35 @@ export interface VirtualizeOptions {
|
|
|
22
22
|
* came to; a host that returns nothing gets every item at `estimate`, which
|
|
23
23
|
* is right whenever the rows really are uniform and is cheaper.
|
|
24
24
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
25
|
+
* **Each row carries its own index rather than being counted off from
|
|
26
|
+
* `window.first`.** A host is free to place its rows whenever it likes, and
|
|
27
|
+
* `hostUpdated` runs *before* `updated`, so a host that appends there has the
|
|
28
|
+
* previous window's rows in the tree when this is asked. Counting positionally
|
|
29
|
+
* would then record the heights of the right elements against the wrong
|
|
30
|
+
* items, and be silently wrong exactly when the window moved.
|
|
28
31
|
*/
|
|
29
|
-
rows?: () => Iterable<
|
|
32
|
+
rows?: () => Iterable<Rendered>;
|
|
33
|
+
/**
|
|
34
|
+
* Whether to place by measurement on this pass, for a host that can be told.
|
|
35
|
+
*
|
|
36
|
+
* **Separate from `rows` because the two answer different questions**: `rows`
|
|
37
|
+
* says a host is able to report what it drew, and this says it wants the
|
|
38
|
+
* measured placement today. A host with a `measured` attribute needs to
|
|
39
|
+
* change its mind at runtime, and a controller is constructed once.
|
|
40
|
+
*
|
|
41
|
+
* True by default, so a host that supplies `rows` and nothing else measures.
|
|
42
|
+
* The uniform path is kept for the case it is better at: it converts offset
|
|
43
|
+
* to index by division, where the measured one builds prefix sums across the
|
|
44
|
+
* whole set the first time it is asked.
|
|
45
|
+
*/
|
|
46
|
+
measured?: () => boolean;
|
|
47
|
+
}
|
|
48
|
+
/** A row that has been drawn, and which item of the set it drew. */
|
|
49
|
+
export interface Rendered {
|
|
50
|
+
/** The element, measured along the scroll axis. */
|
|
51
|
+
element: HTMLElement;
|
|
52
|
+
/** Which item it is, in the whole set rather than in the window. */
|
|
53
|
+
index: number;
|
|
30
54
|
}
|
|
31
55
|
/** Which slice is rendered, and how much empty space stands in for the rest. */
|
|
32
56
|
export interface Window {
|
|
@@ -130,6 +154,8 @@ export declare class VirtualizeController implements ReactiveController {
|
|
|
130
154
|
measure(): void;
|
|
131
155
|
/** The straight line: one estimate, so offset and index convert by division. */
|
|
132
156
|
private uniform;
|
|
157
|
+
/** Whether this pass places by measurement: offered, and wanted. */
|
|
158
|
+
private measuring;
|
|
133
159
|
/**
|
|
134
160
|
* The measured version, which asks where each item starts rather than dividing.
|
|
135
161
|
*
|
|
@@ -137,7 +163,7 @@ export declare class VirtualizeController implements ReactiveController {
|
|
|
137
163
|
* because it stops at the bottom of the viewport: it is bounded by what fits
|
|
138
164
|
* on screen plus the overscan, whatever the set's length.
|
|
139
165
|
*/
|
|
140
|
-
private
|
|
166
|
+
private placed;
|
|
141
167
|
/**
|
|
142
168
|
* Measures what was just drawn, and holds the reader still if it moved.
|
|
143
169
|
*
|
|
@@ -47,8 +47,8 @@ export class VirtualizeController {
|
|
|
47
47
|
return;
|
|
48
48
|
}
|
|
49
49
|
const overscan = this.options.overscan ?? 4;
|
|
50
|
-
const next = this.
|
|
51
|
-
? this.
|
|
50
|
+
const next = this.measuring()
|
|
51
|
+
? this.placed(box, total, overscan)
|
|
52
52
|
: this.uniform(box, total, size, overscan);
|
|
53
53
|
if (this.last?.count !== total || this.last.estimate !== size) {
|
|
54
54
|
this.last = { count: total, estimate: size };
|
|
@@ -76,7 +76,10 @@ export class VirtualizeController {
|
|
|
76
76
|
const last = Math.min(total, first + fits);
|
|
77
77
|
return { after: Math.max(0, (total - last) * size), before: first * size, first, last };
|
|
78
78
|
}
|
|
79
|
-
|
|
79
|
+
measuring() {
|
|
80
|
+
return this.options.rows !== undefined && (this.options.measured?.() ?? true);
|
|
81
|
+
}
|
|
82
|
+
placed(box, total, overscan) {
|
|
80
83
|
const first = Math.max(0, this.heights.indexAt(box.scrollTop, total) - overscan);
|
|
81
84
|
const bottom = box.scrollTop + box.clientHeight;
|
|
82
85
|
let last = this.heights.indexAt(box.scrollTop, total);
|
|
@@ -92,6 +95,9 @@ export class VirtualizeController {
|
|
|
92
95
|
};
|
|
93
96
|
}
|
|
94
97
|
hostUpdated() {
|
|
98
|
+
if (!this.measuring()) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
95
101
|
const rows = this.options.rows?.();
|
|
96
102
|
if (!rows) {
|
|
97
103
|
return;
|
|
@@ -99,12 +105,10 @@ export class VirtualizeController {
|
|
|
99
105
|
const total = Math.max(0, this.options.count());
|
|
100
106
|
const was = this.heights.before(this.window.first, total);
|
|
101
107
|
let news = false;
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
if (this.heights.record(index, row.getBoundingClientRect().height)) {
|
|
108
|
+
for (const { element, index } of rows) {
|
|
109
|
+
if (this.heights.record(index, element.getBoundingClientRect().height)) {
|
|
105
110
|
news = true;
|
|
106
111
|
}
|
|
107
|
-
index += 1;
|
|
108
112
|
}
|
|
109
113
|
if (!news) {
|
|
110
114
|
return;
|
package/dist/index.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export { KeyboardNavigationController, type KeyboardNavigationOptions, type Navi
|
|
|
12
12
|
export { PopoverController, type PopoverOptions, } from './controllers/popover-controller/popover-controller.js';
|
|
13
13
|
export { SourceController, type SourceHost, } from './controllers/source-controller/source-controller.js';
|
|
14
14
|
export { type TokenColor, TokenColorController, } from './controllers/token-color-controller/token-color-controller.js';
|
|
15
|
-
export { VirtualizeController, type VirtualizeOptions, type Window as VirtualizeWindow, } from './controllers/virtualize-controller/virtualize-controller.js';
|
|
15
|
+
export { type Rendered, VirtualizeController, type VirtualizeOptions, type Window as VirtualizeWindow, } from './controllers/virtualize-controller/virtualize-controller.js';
|
|
16
16
|
export { eventsForTag, registerElementEvents } from './events/element-events.js';
|
|
17
17
|
export { type CaretDetail, type ChangeDetail, type CompleteDetail, type ConsoleDetail, type CopyDetail, type CreateDetail, type DismissDetail, type FilterDetail, HelixActivateEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePinEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCaretEvent, HelixCompleteEvent, HelixConsoleEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixFilterEvent, HelixNavigateEvent, HelixNextEvent, HelixPreviousEvent, HelixReadEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixTourAskEvent, type NavigateDetail, type OpenDetail, type ReadDetail, type ResizeDetail, type ScrolledDetail, type SelectDetail, type SendDetail, type ShortcutDetail, type SkipDetail, type SortDetail, type ToggleDetail, } from './events/events.js';
|
|
18
18
|
export { HelixElement } from './helix-element/helix-element.js';
|
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.
|
|
4
|
+
"version": "0.6.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ross Sheppard <ross.sheppard@fusion.dev>",
|
|
7
7
|
"repository": {
|
|
@@ -34,12 +34,12 @@
|
|
|
34
34
|
"bugs": "https://github.com/project-fusion/fusion/issues",
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@floating-ui/dom": "^1.8.0",
|
|
37
|
-
"@fusion.dev/helix-icons": "0.
|
|
37
|
+
"@fusion.dev/helix-icons": "0.6.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@custom-elements-manifest/analyzer": "^0.11.0",
|
|
41
|
-
"@fusion.dev/helix-cem": "0.
|
|
42
|
-
"@fusion.dev/helix-testing": "0.
|
|
41
|
+
"@fusion.dev/helix-cem": "0.6.0",
|
|
42
|
+
"@fusion.dev/helix-testing": "0.6.0",
|
|
43
43
|
"lit": "^3.2.1"
|
|
44
44
|
},
|
|
45
45
|
"homepage": "https://fusion.dev",
|