@fusion.dev/helix-core 0.160.0 → 0.162.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 +162 -5
- package/dist/controllers/virtualize-controller/virtualize-controller.d.ts +22 -0
- package/dist/controllers/virtualize-controller/virtualize-controller.js +22 -5
- package/dist/events/details.d.ts +16 -0
- package/dist/events/events.d.ts +4 -2
- package/dist/events/events.js +3 -1
- package/dist/events/names.js +1 -1
- package/dist/events/strands-fallback.d.ts +13 -0
- package/dist/events/strands-fallback.js +11 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/mixins/mixin-controller-active/mixin-controller-active.d.ts +6 -2
- package/dist/mixins/mixin-controller-active/mixin-controller-active.js +2 -2
- package/dist/utils/draws-in-software/draws-in-software.d.ts +48 -0
- package/dist/utils/draws-in-software/draws-in-software.js +14 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -4
package/custom-elements.json
CHANGED
|
@@ -5977,6 +5977,25 @@
|
|
|
5977
5977
|
},
|
|
5978
5978
|
"description": "Whether the reader is scrolling: a finger is on the box, the box moved\nwithin the last 150 milliseconds, or it has moved and its `scroll` event\nhas not arrived yet.\n\nFor a host that holds its own reader: a write to the scroll offset while\nthis is true ends a fling on iOS, and a reader position noted before the\nlast move is out of date."
|
|
5979
5979
|
},
|
|
5980
|
+
{
|
|
5981
|
+
"kind": "method",
|
|
5982
|
+
"name": "noteClamp",
|
|
5983
|
+
"privacy": "private",
|
|
5984
|
+
"return": {
|
|
5985
|
+
"type": {
|
|
5986
|
+
"text": "number"
|
|
5987
|
+
}
|
|
5988
|
+
},
|
|
5989
|
+
"parameters": [
|
|
5990
|
+
{
|
|
5991
|
+
"name": "box",
|
|
5992
|
+
"type": {
|
|
5993
|
+
"text": "HTMLElement"
|
|
5994
|
+
}
|
|
5995
|
+
}
|
|
5996
|
+
],
|
|
5997
|
+
"description": "Takes the offset as the box's own where the box moved it up only because\nthe set below it got shorter, which the browser does to keep the offset\ninside the content, and answers where it was before.\n\n**Not a reader scrolling.** Rows at the end of the set measured shorter\nthan their estimates shrink the content, and the box pulls its offset back\nto the new bottom before any `scroll` event arrives. Read as a scroll, the\ndifference went into the spacer as drift and was then paid a second time:\nin Chromium, End on 2,000 rows of one to five lines left the window 292\npixels above the last item, which stayed drawn below the box as the row\nholding focus."
|
|
5998
|
+
},
|
|
5980
5999
|
{
|
|
5981
6000
|
"kind": "field",
|
|
5982
6001
|
"name": "rest",
|
|
@@ -6091,6 +6110,17 @@
|
|
|
6091
6110
|
},
|
|
6092
6111
|
"description": "How tall one item is on the straight line: the drawn rows' height once\nread, and `estimate` until then.\n\n**An estimate that is wrong on the straight line leaves the end of the\nset out of reach.** Rows of 21 pixels placed at 32 fill two thirds of the\nroom they are counted for, so the window stops short of the bottom of the\nbox and the spacer after it holds the rest: in Chromium, `scrollToIndex`\non the last of 5,000 such rows scrolled to the end and drew nothing there.\nReading the drawn rows once corrects the slope, and it is still a line."
|
|
6093
6112
|
},
|
|
6113
|
+
{
|
|
6114
|
+
"kind": "method",
|
|
6115
|
+
"name": "gap",
|
|
6116
|
+
"privacy": "private",
|
|
6117
|
+
"return": {
|
|
6118
|
+
"type": {
|
|
6119
|
+
"text": "number"
|
|
6120
|
+
}
|
|
6121
|
+
},
|
|
6122
|
+
"description": "The space the host draws between two items, which each item counts."
|
|
6123
|
+
},
|
|
6094
6124
|
{
|
|
6095
6125
|
"kind": "method",
|
|
6096
6126
|
"name": "sampleRows",
|
|
@@ -8107,6 +8137,14 @@
|
|
|
8107
8137
|
"module": "./details.js"
|
|
8108
8138
|
}
|
|
8109
8139
|
},
|
|
8140
|
+
{
|
|
8141
|
+
"kind": "js",
|
|
8142
|
+
"name": "StrandsFallbackDetail",
|
|
8143
|
+
"declaration": {
|
|
8144
|
+
"name": "StrandsFallbackDetail",
|
|
8145
|
+
"module": "./details.js"
|
|
8146
|
+
}
|
|
8147
|
+
},
|
|
8110
8148
|
{
|
|
8111
8149
|
"kind": "js",
|
|
8112
8150
|
"name": "ToggleDetail",
|
|
@@ -8851,6 +8889,14 @@
|
|
|
8851
8889
|
"module": "src/events/events.ts"
|
|
8852
8890
|
}
|
|
8853
8891
|
},
|
|
8892
|
+
{
|
|
8893
|
+
"kind": "js",
|
|
8894
|
+
"name": "HelixStrandsFallbackEvent",
|
|
8895
|
+
"declaration": {
|
|
8896
|
+
"name": "HelixStrandsFallbackEvent",
|
|
8897
|
+
"module": "src/events/events.ts"
|
|
8898
|
+
}
|
|
8899
|
+
},
|
|
8854
8900
|
{
|
|
8855
8901
|
"kind": "js",
|
|
8856
8902
|
"name": "HelixToggleEvent",
|
|
@@ -9731,7 +9777,7 @@
|
|
|
9731
9777
|
"type": {
|
|
9732
9778
|
"text": "ReadonlySet<string>"
|
|
9733
9779
|
},
|
|
9734
|
-
"default": "new Set( ( 'action activate aura-fallback band before-activate before-change before-close ' + 'before-collapse before-edit before-move before-open before-panel-resize before-pin ' + 'before-reconnect before-relabel before-reorder before-resize before-split before-toggle ' + 'canvas-edit canvas-pan canvas-view canvas-zoom caret clear collapse complete ' + 'connect console copy copy-error create dismiss edit end expand facet filter ' + 'filtered graph-filter graph-layout graph-pan graph-part-change graph-ready ' + 'graph-signal graph-zoom history load load-more map-cluster map-pan map-part-change ' + 'map-ready map-rotate map-tilt map-zoom move navigate next panel-resize pin press ' + 'preview previous range-change read reading-change reading-press reconnect reject ' + 'relabel remove reorder ' + 'reordered resize resized sample-end sample-start scrolled select selected send ' + 'shortcut sort sorted split toggle tour-ask tour-status typing' ) .split(' ') .map((name) => `helix-${name}`), )",
|
|
9780
|
+
"default": "new Set( ( 'action activate aura-fallback band before-activate before-change before-close ' + 'before-collapse before-edit before-move before-open before-panel-resize before-pin ' + 'before-reconnect before-relabel before-reorder before-resize before-split before-toggle ' + 'canvas-edit canvas-pan canvas-view canvas-zoom caret clear collapse complete ' + 'connect console copy copy-error create dismiss edit end expand facet filter ' + 'filtered graph-filter graph-layout graph-pan graph-part-change graph-ready ' + 'graph-signal graph-zoom history load load-more map-cluster map-pan map-part-change ' + 'map-ready map-rotate map-tilt map-zoom move navigate next panel-resize pin press ' + 'preview previous range-change read reading-change reading-press reconnect reject ' + 'relabel remove reorder ' + 'reordered resize resized sample-end sample-start scrolled select selected send ' + 'shortcut sort sorted split strands-fallback toggle tour-ask tour-status typing' ) .split(' ') .map((name) => `helix-${name}`), )",
|
|
9735
9781
|
"description": "Every name this library dispatches.\n\nExported so a runtime check can ask whether a name is one of ours without\nkeeping a second list of them. `HelixElement` uses it to tell a consumer that\nthe handler prop they wrote is attached to nothing.\n\n**Written as strings, in a module of its own, and not read off the\nclasses in `registry`.** Every element carries this set through its React\nprop audit, and a set read off the classes kept every class alive in every\nbundle: a Badge shipped all eighty of them. As strings, a family ships the\nclasses it dispatches and no others. `events.pure.spec.ts` holds this list to\nthe classes, so a class added without its name here fails.\n\n**Without the shared `helix-`, and separated by spaces.** Every element carries this\nlist, and as quoted strings each paid its quotes, its comma and the prefix."
|
|
9736
9782
|
}
|
|
9737
9783
|
],
|
|
@@ -10848,6 +10894,44 @@
|
|
|
10848
10894
|
}
|
|
10849
10895
|
]
|
|
10850
10896
|
},
|
|
10897
|
+
{
|
|
10898
|
+
"kind": "javascript-module",
|
|
10899
|
+
"path": "src/events/strands-fallback.ts",
|
|
10900
|
+
"declarations": [
|
|
10901
|
+
{
|
|
10902
|
+
"kind": "class",
|
|
10903
|
+
"description": "A strands element stopped drawing its ribbon and shows its gradient, and\nsays why.\n\nSent each time it falls back, from the element, which then matches\n`:state(fallback)` until it draws again. Not cancelable: there is nothing\nleft to refuse.",
|
|
10904
|
+
"name": "HelixStrandsFallbackEvent",
|
|
10905
|
+
"members": [
|
|
10906
|
+
{
|
|
10907
|
+
"kind": "field",
|
|
10908
|
+
"name": "eventName",
|
|
10909
|
+
"type": {
|
|
10910
|
+
"text": "string"
|
|
10911
|
+
},
|
|
10912
|
+
"static": true,
|
|
10913
|
+
"readonly": true,
|
|
10914
|
+
"default": "'helix-strands-fallback'"
|
|
10915
|
+
}
|
|
10916
|
+
],
|
|
10917
|
+
"superclass": {
|
|
10918
|
+
"name": "CustomEvent",
|
|
10919
|
+
"module": "src/events/strands-fallback.ts"
|
|
10920
|
+
},
|
|
10921
|
+
"helix": {}
|
|
10922
|
+
}
|
|
10923
|
+
],
|
|
10924
|
+
"exports": [
|
|
10925
|
+
{
|
|
10926
|
+
"kind": "js",
|
|
10927
|
+
"name": "HelixStrandsFallbackEvent",
|
|
10928
|
+
"declaration": {
|
|
10929
|
+
"name": "HelixStrandsFallbackEvent",
|
|
10930
|
+
"module": "src/events/strands-fallback.ts"
|
|
10931
|
+
}
|
|
10932
|
+
}
|
|
10933
|
+
]
|
|
10934
|
+
},
|
|
10851
10935
|
{
|
|
10852
10936
|
"kind": "javascript-module",
|
|
10853
10937
|
"path": "src/events/toggle.ts",
|
|
@@ -13857,6 +13941,14 @@
|
|
|
13857
13941
|
"module": "./events/events.js"
|
|
13858
13942
|
}
|
|
13859
13943
|
},
|
|
13944
|
+
{
|
|
13945
|
+
"kind": "js",
|
|
13946
|
+
"name": "HelixStrandsFallbackEvent",
|
|
13947
|
+
"declaration": {
|
|
13948
|
+
"name": "HelixStrandsFallbackEvent",
|
|
13949
|
+
"module": "./events/events.js"
|
|
13950
|
+
}
|
|
13951
|
+
},
|
|
13860
13952
|
{
|
|
13861
13953
|
"kind": "js",
|
|
13862
13954
|
"name": "HelixToggleEvent",
|
|
@@ -14113,6 +14205,14 @@
|
|
|
14113
14205
|
"module": "./events/events.js"
|
|
14114
14206
|
}
|
|
14115
14207
|
},
|
|
14208
|
+
{
|
|
14209
|
+
"kind": "js",
|
|
14210
|
+
"name": "StrandsFallbackDetail",
|
|
14211
|
+
"declaration": {
|
|
14212
|
+
"name": "StrandsFallbackDetail",
|
|
14213
|
+
"module": "./events/events.js"
|
|
14214
|
+
}
|
|
14215
|
+
},
|
|
14116
14216
|
{
|
|
14117
14217
|
"kind": "js",
|
|
14118
14218
|
"name": "ToggleDetail",
|
|
@@ -15265,6 +15365,14 @@
|
|
|
15265
15365
|
"module": "./utils/draw-value-axis/draw-value-axis.js"
|
|
15266
15366
|
}
|
|
15267
15367
|
},
|
|
15368
|
+
{
|
|
15369
|
+
"kind": "js",
|
|
15370
|
+
"name": "drawsInSoftware",
|
|
15371
|
+
"declaration": {
|
|
15372
|
+
"name": "drawsInSoftware",
|
|
15373
|
+
"module": "./utils/draws-in-software/draws-in-software.js"
|
|
15374
|
+
}
|
|
15375
|
+
},
|
|
15268
15376
|
{
|
|
15269
15377
|
"kind": "js",
|
|
15270
15378
|
"name": "elapsedTime",
|
|
@@ -18483,9 +18591,16 @@
|
|
|
18483
18591
|
"type": {
|
|
18484
18592
|
"text": "string"
|
|
18485
18593
|
}
|
|
18594
|
+
},
|
|
18595
|
+
{
|
|
18596
|
+
"name": "cause",
|
|
18597
|
+
"optional": true,
|
|
18598
|
+
"type": {
|
|
18599
|
+
"text": "string"
|
|
18600
|
+
}
|
|
18486
18601
|
}
|
|
18487
18602
|
],
|
|
18488
|
-
"description": "Requests a new current item, and returns whether the change was applied."
|
|
18603
|
+
"description": "Requests a new current item, and returns whether the change was applied.\n`cause` says why, where the family names its causes, and reaches\n`helix-before-activate` as `detail.cause`."
|
|
18489
18604
|
},
|
|
18490
18605
|
{
|
|
18491
18606
|
"kind": "method",
|
|
@@ -18557,9 +18672,16 @@
|
|
|
18557
18672
|
"type": {
|
|
18558
18673
|
"text": "string"
|
|
18559
18674
|
}
|
|
18675
|
+
},
|
|
18676
|
+
{
|
|
18677
|
+
"name": "cause",
|
|
18678
|
+
"optional": true,
|
|
18679
|
+
"type": {
|
|
18680
|
+
"text": "string"
|
|
18681
|
+
}
|
|
18560
18682
|
}
|
|
18561
18683
|
],
|
|
18562
|
-
"description": "Requests a new current item, and returns whether the change was applied.\n\nAnnounces before it acts, so `preventDefault()` on the `helix-before-activate` is\na refusal and nothing moves. Unlike a native control, nothing has moved\nby the time this runs, so refusing is simply not writing: there is\nnothing to put back. Nobody refusing means the set updates itself,\nwhether or not a consumer declared `active`, a declared property being a\nseed and a correction."
|
|
18684
|
+
"description": "Requests a new current item, and returns whether the change was applied.\n\nAnnounces before it acts, so `preventDefault()` on the `helix-before-activate` is\na refusal and nothing moves. Unlike a native control, nothing has moved\nby the time this runs, so refusing is simply not writing: there is\nnothing to put back. Nobody refusing means the set updates itself,\nwhether or not a consumer declared `active`, a declared property being a\nseed and a correction. `cause` says why, where the family names its\ncauses, and reaches the event as `detail.cause`."
|
|
18563
18685
|
},
|
|
18564
18686
|
{
|
|
18565
18687
|
"kind": "method",
|
|
@@ -26940,6 +27062,41 @@
|
|
|
26940
27062
|
}
|
|
26941
27063
|
]
|
|
26942
27064
|
},
|
|
27065
|
+
{
|
|
27066
|
+
"kind": "javascript-module",
|
|
27067
|
+
"path": "src/utils/draws-in-software/draws-in-software.ts",
|
|
27068
|
+
"declarations": [
|
|
27069
|
+
{
|
|
27070
|
+
"kind": "function",
|
|
27071
|
+
"name": "drawsInSoftware",
|
|
27072
|
+
"return": {
|
|
27073
|
+
"type": {
|
|
27074
|
+
"text": ""
|
|
27075
|
+
}
|
|
27076
|
+
},
|
|
27077
|
+
"parameters": [
|
|
27078
|
+
{
|
|
27079
|
+
"name": "attributes",
|
|
27080
|
+
"type": {
|
|
27081
|
+
"text": "WebGLContextAttributes"
|
|
27082
|
+
},
|
|
27083
|
+
"description": "What the caller's drawing context asks for."
|
|
27084
|
+
}
|
|
27085
|
+
],
|
|
27086
|
+
"description": "Whether WebGL here is drawn on the CPU, asked before one is drawn into.\n\nShared by the elements that draw a decorative field with WebGL, `Aura` and\n`Strands`, which take their gradient on a software renderer rather than pay\nfor a shader nobody can see at speed.\n\n**The shader costs what a GPU makes it cheap to ask for.** Measured on Aura,\n15 Sep 2026: on Metal the browser shares the compiled program and each aura\nafter the first draws its opening frame in about 2ms, while under SwiftShader\nnothing is shared and each one compiles the pipeline again for about 450ms.\nOn a page of 720 pixel auras the worst frame gap went 568ms to 50ms with one\naura, 1626ms to 34ms with three and 3200ms to 42ms with six once this check\nwas in place, and a page of three or six ran at 13 frames a second before and\nat the display's own rate after.\n\n**The unmasked name is the only one that answers.** `gl.RENDERER` is masked\nto `WebKit WebGL` on Chromium, the same string on SwiftShader and on Metal,\nand `WEBGL_debug_renderer_info` is what lifts the mask.\n\n**An unreadable renderer draws**, which is the safe direction and not the\ntidy one. The extension is optional and is withheld deliberately: Firefox's\n`privacy.resistFingerprinting` and Safari's equivalent both drop it, and a\nbrowser may drop it at any time, since a GPU name is a fingerprinting\nsurface. Treating \"we cannot tell\" as software would take the shader away\nfrom every reader on a machine that hides its hardware, which is a real GPU\nfar more often than not.\n\n**A probe context of its own, and given straight back.** Asking the caller's\nown canvas would spend it, and the probe has to release what it took or a\npage of fields runs the browser into its cap of about sixteen contexts. One\npixel by one, and released through `WEBGL_lose_context`.\n\n**The same attributes the real context asks for**, because they are part of\nthe question: `powerPreference` can select a different adapter, so a probe\nasking for a high-performance context would name a GPU the drawing one is\nnever given.\n\n**Asked per context rather than once for the page.** The answer is not fixed:\na GPU process that crashes takes the page down to SwiftShader for the rest of\nits life, and a field rebuilding after that should get the current answer. It\ncosts a context creation and two calls, about 2ms, once per context."
|
|
27087
|
+
}
|
|
27088
|
+
],
|
|
27089
|
+
"exports": [
|
|
27090
|
+
{
|
|
27091
|
+
"kind": "js",
|
|
27092
|
+
"name": "drawsInSoftware",
|
|
27093
|
+
"declaration": {
|
|
27094
|
+
"name": "drawsInSoftware",
|
|
27095
|
+
"module": "src/utils/draws-in-software/draws-in-software.ts"
|
|
27096
|
+
}
|
|
27097
|
+
}
|
|
27098
|
+
]
|
|
27099
|
+
},
|
|
26943
27100
|
{
|
|
26944
27101
|
"kind": "javascript-module",
|
|
26945
27102
|
"path": "src/utils/elapsed-time/elapsed-time.ts",
|
|
@@ -32859,7 +33016,7 @@
|
|
|
32859
33016
|
"type": {
|
|
32860
33017
|
"text": "string"
|
|
32861
33018
|
},
|
|
32862
|
-
"default": "'0.
|
|
33019
|
+
"default": "'0.162.0'",
|
|
32863
33020
|
"description": "The version of the package this file ships in.\n\n**Written by `fusion/scripts/version.mjs`** wherever it writes the package's\n`package.json`, and stamped back into the repository beside it after a\nrelease, so the two never disagree; a spec beside this holds them to it.\nNothing else in the running code knows which release it is."
|
|
32864
33021
|
}
|
|
32865
33022
|
],
|
|
@@ -33419,6 +33576,6 @@
|
|
|
33419
33576
|
],
|
|
33420
33577
|
"helix": {
|
|
33421
33578
|
"package": "@fusion.dev/helix-core",
|
|
33422
|
-
"version": "0.
|
|
33579
|
+
"version": "0.162.0"
|
|
33423
33580
|
}
|
|
33424
33581
|
}
|
|
@@ -7,6 +7,12 @@ export interface VirtualizeOptions {
|
|
|
7
7
|
count: () => number;
|
|
8
8
|
/** How tall one item is along the scroll axis, in pixels. */
|
|
9
9
|
estimate: () => number;
|
|
10
|
+
/**
|
|
11
|
+
* The space between two items along the scroll axis, in pixels, which the
|
|
12
|
+
* host draws, such as a flex or grid `gap`. Each item counts it as part of
|
|
13
|
+
* its own size. Zero by default.
|
|
14
|
+
*/
|
|
15
|
+
gap?: () => number;
|
|
10
16
|
/**
|
|
11
17
|
* Rows kept either side of what fits, so a scroll reveals something drawn
|
|
12
18
|
* rather than something blank. Four by default.
|
|
@@ -213,6 +219,20 @@ export declare class VirtualizeController implements ReactiveController {
|
|
|
213
219
|
* last move is out of date.
|
|
214
220
|
*/
|
|
215
221
|
scrolling(): boolean;
|
|
222
|
+
/**
|
|
223
|
+
* Takes the offset as the box's own where the box moved it up only because
|
|
224
|
+
* the set below it got shorter, which the browser does to keep the offset
|
|
225
|
+
* inside the content, and answers where it was before.
|
|
226
|
+
*
|
|
227
|
+
* **Not a reader scrolling.** Rows at the end of the set measured shorter
|
|
228
|
+
* than their estimates shrink the content, and the box pulls its offset back
|
|
229
|
+
* to the new bottom before any `scroll` event arrives. Read as a scroll, the
|
|
230
|
+
* difference went into the spacer as drift and was then paid a second time:
|
|
231
|
+
* in Chromium, End on 2,000 rows of one to five lines left the window 292
|
|
232
|
+
* pixels above the last item, which stayed drawn below the box as the row
|
|
233
|
+
* holding focus.
|
|
234
|
+
*/
|
|
235
|
+
private noteClamp;
|
|
216
236
|
/** Squares the spacer and the scroll offset once the box is still. */
|
|
217
237
|
private readonly rest;
|
|
218
238
|
/**
|
|
@@ -264,6 +284,8 @@ export declare class VirtualizeController implements ReactiveController {
|
|
|
264
284
|
* Reading the drawn rows once corrects the slope, and it is still a line.
|
|
265
285
|
*/
|
|
266
286
|
private line;
|
|
287
|
+
/** The space the host draws between two items, which each item counts. */
|
|
288
|
+
private gap;
|
|
267
289
|
/**
|
|
268
290
|
* Reads the drawn rows' height once for the straight line, for a host that
|
|
269
291
|
* offers `rows` and does not measure.
|
|
@@ -17,7 +17,11 @@ export class VirtualizeController {
|
|
|
17
17
|
this.touching = false;
|
|
18
18
|
this.uneven = false;
|
|
19
19
|
this.handleScroll = () => {
|
|
20
|
-
const
|
|
20
|
+
const box = this.options.container();
|
|
21
|
+
if (box) {
|
|
22
|
+
this.noteClamp(box);
|
|
23
|
+
}
|
|
24
|
+
const top = box?.scrollTop ?? 0;
|
|
21
25
|
if (top !== this.lastTop) {
|
|
22
26
|
this.heading = top > this.lastTop ? 1 : -1;
|
|
23
27
|
this.lastTop = top;
|
|
@@ -95,6 +99,15 @@ export class VirtualizeController {
|
|
|
95
99
|
this.resting !== undefined ||
|
|
96
100
|
(this.options.container()?.scrollTop ?? this.lastTop) !== this.lastTop);
|
|
97
101
|
}
|
|
102
|
+
noteClamp(box) {
|
|
103
|
+
const was = this.lastTop;
|
|
104
|
+
if (!this.touching &&
|
|
105
|
+
box.scrollTop < was &&
|
|
106
|
+
box.scrollTop >= box.scrollHeight - box.clientHeight - 1) {
|
|
107
|
+
this.lastTop = box.scrollTop;
|
|
108
|
+
}
|
|
109
|
+
return was;
|
|
110
|
+
}
|
|
98
111
|
square() {
|
|
99
112
|
const box = this.options.container();
|
|
100
113
|
if (this.drift > 0 && box) {
|
|
@@ -161,7 +174,10 @@ export class VirtualizeController {
|
|
|
161
174
|
}
|
|
162
175
|
line() {
|
|
163
176
|
const estimate = Math.max(1, this.options.estimate());
|
|
164
|
-
return this.sample?.estimate === estimate ? this.sample.size : estimate;
|
|
177
|
+
return this.sample?.estimate === estimate ? this.sample.size : estimate + this.gap();
|
|
178
|
+
}
|
|
179
|
+
gap() {
|
|
180
|
+
return Math.max(0, this.options.gap?.() ?? 0);
|
|
165
181
|
}
|
|
166
182
|
sampleRows() {
|
|
167
183
|
const estimate = Math.max(1, this.options.estimate());
|
|
@@ -176,7 +192,7 @@ export class VirtualizeController {
|
|
|
176
192
|
const uneven = Math.max(...seen) - Math.min(...seen) > 1;
|
|
177
193
|
if (this.sample?.estimate !== estimate) {
|
|
178
194
|
const was = this.line();
|
|
179
|
-
const size = Math.max(1, seen.reduce((sum, height) => sum + height, 0) / seen.length);
|
|
195
|
+
const size = Math.max(1, seen.reduce((sum, height) => sum + height, 0) / seen.length) + this.gap();
|
|
180
196
|
this.sample = { estimate, size };
|
|
181
197
|
if (Math.abs(size - was) >= 0.5) {
|
|
182
198
|
const box = this.options.container();
|
|
@@ -291,12 +307,13 @@ export class VirtualizeController {
|
|
|
291
307
|
}
|
|
292
308
|
const total = Math.max(0, this.options.count());
|
|
293
309
|
const box = this.options.container();
|
|
310
|
+
const from = box ? this.noteClamp(box) : this.lastTop;
|
|
294
311
|
const top = box ? this.offset(box) : 0;
|
|
295
312
|
const anchor = this.target ?? this.heights.indexAt(top, total);
|
|
296
313
|
const was = this.heights.before(anchor, total);
|
|
297
314
|
let news = false;
|
|
298
315
|
for (const { element, index } of rows) {
|
|
299
|
-
if (this.heights.record(index, element.getBoundingClientRect().height)) {
|
|
316
|
+
if (this.heights.record(index, element.getBoundingClientRect().height + this.gap())) {
|
|
300
317
|
news = true;
|
|
301
318
|
}
|
|
302
319
|
}
|
|
@@ -310,7 +327,7 @@ export class VirtualizeController {
|
|
|
310
327
|
this.drift -= moved;
|
|
311
328
|
}
|
|
312
329
|
else {
|
|
313
|
-
box.scrollTop
|
|
330
|
+
box.scrollTop = from + moved;
|
|
314
331
|
this.lastTop = box.scrollTop;
|
|
315
332
|
}
|
|
316
333
|
}
|
package/dist/events/details.d.ts
CHANGED
|
@@ -258,6 +258,12 @@ export interface TourAskDetail {
|
|
|
258
258
|
* that `event.target` does not.
|
|
259
259
|
*/
|
|
260
260
|
export interface ChangeDetail {
|
|
261
|
+
/**
|
|
262
|
+
* Why the change was asked for, where a family names its causes. Video
|
|
263
|
+
* Playlist sends `ended`, `next`, `press`, `previous`, and `removed` on
|
|
264
|
+
* `helix-before-activate`.
|
|
265
|
+
*/
|
|
266
|
+
cause?: string;
|
|
261
267
|
/** The value after the change. */
|
|
262
268
|
value: string;
|
|
263
269
|
}
|
|
@@ -435,6 +441,16 @@ export interface AuraFallbackDetail {
|
|
|
435
441
|
*/
|
|
436
442
|
reason: 'lost' | 'software' | 'unavailable';
|
|
437
443
|
}
|
|
444
|
+
/** Detail carried by `helix-strands-fallback`. */
|
|
445
|
+
export interface StrandsFallbackDetail {
|
|
446
|
+
/**
|
|
447
|
+
* Why the gradient shows: `software` for a renderer that draws on the CPU,
|
|
448
|
+
* `unavailable` for no WebGL or a program the browser refused, and `lost`
|
|
449
|
+
* for a context the browser took back, on a GPU reset or past its limit of
|
|
450
|
+
* about sixteen.
|
|
451
|
+
*/
|
|
452
|
+
reason: 'lost' | 'software' | 'unavailable';
|
|
453
|
+
}
|
|
438
454
|
/** Detail carried by `helix-range-change`. */
|
|
439
455
|
export interface RangeDetail {
|
|
440
456
|
/** The index of the first item on screen. */
|
package/dist/events/events.d.ts
CHANGED
|
@@ -114,13 +114,14 @@ import { HelixShortcutEvent } from './shortcut.js';
|
|
|
114
114
|
import { HelixSortEvent } from './sort.js';
|
|
115
115
|
import { HelixSortedEvent } from './sorted.js';
|
|
116
116
|
import { HelixSplitEvent } from './split.js';
|
|
117
|
+
import { HelixStrandsFallbackEvent } from './strands-fallback.js';
|
|
117
118
|
import { HelixToggleEvent } from './toggle.js';
|
|
118
119
|
import { HelixTourAskEvent } from './tour-ask.js';
|
|
119
120
|
import { HelixTourStatusEvent } from './tour-status.js';
|
|
120
121
|
import { HelixTypingEvent } from './typing.js';
|
|
121
|
-
export type { ActivateDetail, AuraFallbackDetail, BandDetail, CanvasView, CaretDetail, ChangeDetail, CompleteDetail, ConnectDetail, ConsoleDetail, CopyDetail, CreateDetail, DismissDetail, FacetDetail, FilterDetail, GraphFilterDetail, GraphLayoutDetail, GraphPartChangeDetail, GraphSignalDetail, MapClusterDetail, MapPanDetail, MapPartChangeDetail, MapRotateDetail, MapTiltDetail, MapZoomDetail, MoveDetail, NavigateDetail, OpenDetail, PressDetail, PressPointerType, RangeDetail, ReadDetail, ReadingDetail, ReconnectDetail, Refusal, RefusedFile, RejectDetail, RelabelDetail, RemoveDetail, ReorderDetail, ResizeDetail, ScrolledDetail, SelectDetail, SendDetail, ShortcutDetail, SkipDetail, SortDetail, ToggleDetail, TourAskDetail, TourStatusDetail, TypingDetail, ViewportPanDetail, ViewportZoomDetail, } from './details.js';
|
|
122
|
+
export type { ActivateDetail, AuraFallbackDetail, BandDetail, CanvasView, CaretDetail, ChangeDetail, CompleteDetail, ConnectDetail, ConsoleDetail, CopyDetail, CreateDetail, DismissDetail, FacetDetail, FilterDetail, GraphFilterDetail, GraphLayoutDetail, GraphPartChangeDetail, GraphSignalDetail, MapClusterDetail, MapPanDetail, MapPartChangeDetail, MapRotateDetail, MapTiltDetail, MapZoomDetail, MoveDetail, NavigateDetail, OpenDetail, PressDetail, PressPointerType, RangeDetail, ReadDetail, ReadingDetail, ReconnectDetail, Refusal, RefusedFile, RejectDetail, RelabelDetail, RemoveDetail, ReorderDetail, ResizeDetail, ScrolledDetail, SelectDetail, SendDetail, ShortcutDetail, SkipDetail, SortDetail, StrandsFallbackDetail, ToggleDetail, TourAskDetail, TourStatusDetail, TypingDetail, ViewportPanDetail, ViewportZoomDetail, } from './details.js';
|
|
122
123
|
export { helixEventNames } from './names.js';
|
|
123
|
-
export { HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPinEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, };
|
|
124
|
+
export { HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPinEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixStrandsFallbackEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, };
|
|
124
125
|
/**
|
|
125
126
|
* Every event class, and the one place a new one is registered: a class in a
|
|
126
127
|
* module of its own, imported above, and named here and in `names.ts`.
|
|
@@ -220,6 +221,7 @@ declare const registry: {
|
|
|
220
221
|
readonly HelixSortEvent: typeof HelixSortEvent;
|
|
221
222
|
readonly HelixSortedEvent: typeof HelixSortedEvent;
|
|
222
223
|
readonly HelixSplitEvent: typeof HelixSplitEvent;
|
|
224
|
+
readonly HelixStrandsFallbackEvent: typeof HelixStrandsFallbackEvent;
|
|
223
225
|
readonly HelixToggleEvent: typeof HelixToggleEvent;
|
|
224
226
|
readonly HelixTourAskEvent: typeof HelixTourAskEvent;
|
|
225
227
|
readonly HelixTourStatusEvent: typeof HelixTourStatusEvent;
|
package/dist/events/events.js
CHANGED
|
@@ -84,12 +84,13 @@ import { HelixShortcutEvent } from './shortcut.js';
|
|
|
84
84
|
import { HelixSortEvent } from './sort.js';
|
|
85
85
|
import { HelixSortedEvent } from './sorted.js';
|
|
86
86
|
import { HelixSplitEvent } from './split.js';
|
|
87
|
+
import { HelixStrandsFallbackEvent } from './strands-fallback.js';
|
|
87
88
|
import { HelixToggleEvent } from './toggle.js';
|
|
88
89
|
import { HelixTourAskEvent } from './tour-ask.js';
|
|
89
90
|
import { HelixTourStatusEvent } from './tour-status.js';
|
|
90
91
|
import { HelixTypingEvent } from './typing.js';
|
|
91
92
|
export { helixEventNames } from './names.js';
|
|
92
|
-
export { HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPinEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, };
|
|
93
|
+
export { HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPinEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixStrandsFallbackEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, };
|
|
93
94
|
const registry = {
|
|
94
95
|
HelixActionEvent,
|
|
95
96
|
HelixActivateEvent,
|
|
@@ -177,6 +178,7 @@ const registry = {
|
|
|
177
178
|
HelixSortEvent,
|
|
178
179
|
HelixSortedEvent,
|
|
179
180
|
HelixSplitEvent,
|
|
181
|
+
HelixStrandsFallbackEvent,
|
|
180
182
|
HelixToggleEvent,
|
|
181
183
|
HelixTourAskEvent,
|
|
182
184
|
HelixTourStatusEvent,
|
package/dist/events/names.js
CHANGED
|
@@ -9,6 +9,6 @@ export const helixEventNames = new Set(('action activate aura-fallback band befo
|
|
|
9
9
|
'preview previous range-change read reading-change reading-press reconnect reject ' +
|
|
10
10
|
'relabel remove reorder ' +
|
|
11
11
|
'reordered resize resized sample-end sample-start scrolled select selected send ' +
|
|
12
|
-
'shortcut sort sorted split toggle tour-ask tour-status typing')
|
|
12
|
+
'shortcut sort sorted split strands-fallback toggle tour-ask tour-status typing')
|
|
13
13
|
.split(' ')
|
|
14
14
|
.map((name) => `helix-${name}`));
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { StrandsFallbackDetail } from './details.js';
|
|
2
|
+
/**
|
|
3
|
+
* A strands element stopped drawing its ribbon and shows its gradient, and
|
|
4
|
+
* says why.
|
|
5
|
+
*
|
|
6
|
+
* Sent each time it falls back, from the element, which then matches
|
|
7
|
+
* `:state(fallback)` until it draws again. Not cancelable: there is nothing
|
|
8
|
+
* left to refuse.
|
|
9
|
+
*/
|
|
10
|
+
export declare class HelixStrandsFallbackEvent extends CustomEvent<StrandsFallbackDetail> {
|
|
11
|
+
static readonly eventName = "helix-strands-fallback";
|
|
12
|
+
constructor(detail: StrandsFallbackDetail);
|
|
13
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export class HelixStrandsFallbackEvent extends CustomEvent {
|
|
2
|
+
static { this.eventName = 'helix-strands-fallback'; }
|
|
3
|
+
constructor(detail) {
|
|
4
|
+
super(HelixStrandsFallbackEvent.eventName, {
|
|
5
|
+
bubbles: true,
|
|
6
|
+
cancelable: false,
|
|
7
|
+
composed: true,
|
|
8
|
+
detail,
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -33,7 +33,7 @@ export { SwipeController, type SwipeOptions, } from './controllers/swipe-control
|
|
|
33
33
|
export { type TokenColor, TokenColorController, } from './controllers/token-color-controller/token-color-controller.js';
|
|
34
34
|
export { type Rendered, VirtualizeController, type VirtualizeOptions, type Window as VirtualizeWindow, } from './controllers/virtualize-controller/virtualize-controller.js';
|
|
35
35
|
export { eventsForTag, registerElementEvents } from './events/element-events.js';
|
|
36
|
-
export { type ActivateDetail, type AuraFallbackDetail, type BandDetail, type CanvasView, type CaretDetail, type ChangeDetail, type CompleteDetail, type ConnectDetail, type ConsoleDetail, type CopyDetail, type CreateDetail, type DismissDetail, type FacetDetail, type FilterDetail, type GraphFilterDetail, type GraphLayoutDetail, type GraphPartChangeDetail, type GraphSignalDetail, HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPinEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, type MapClusterDetail, type MapPanDetail, type MapPartChangeDetail, type MapRotateDetail, type MapTiltDetail, type MapZoomDetail, type MoveDetail, type NavigateDetail, type OpenDetail, type PressDetail, type PressPointerType, type RangeDetail, type ReadDetail, type ReadingDetail, type ReconnectDetail, type Refusal, type RefusedFile, type RejectDetail, type RelabelDetail, type RemoveDetail, type ReorderDetail, type ResizeDetail, type ScrolledDetail, type SelectDetail, type SendDetail, type ShortcutDetail, type SkipDetail, type SortDetail, type ToggleDetail, type TourStatusDetail, type TypingDetail, type ViewportPanDetail, type ViewportZoomDetail, } from './events/events.js';
|
|
36
|
+
export { type ActivateDetail, type AuraFallbackDetail, type BandDetail, type CanvasView, type CaretDetail, type ChangeDetail, type CompleteDetail, type ConnectDetail, type ConsoleDetail, type CopyDetail, type CreateDetail, type DismissDetail, type FacetDetail, type FilterDetail, type GraphFilterDetail, type GraphLayoutDetail, type GraphPartChangeDetail, type GraphSignalDetail, HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPinEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixStrandsFallbackEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, type MapClusterDetail, type MapPanDetail, type MapPartChangeDetail, type MapRotateDetail, type MapTiltDetail, type MapZoomDetail, type MoveDetail, type NavigateDetail, type OpenDetail, type PressDetail, type PressPointerType, type RangeDetail, type ReadDetail, type ReadingDetail, type ReconnectDetail, type Refusal, type RefusedFile, type RejectDetail, type RelabelDetail, type RemoveDetail, type ReorderDetail, type ResizeDetail, type ScrolledDetail, type SelectDetail, type SendDetail, type ShortcutDetail, type SkipDetail, type SortDetail, type StrandsFallbackDetail, type ToggleDetail, type TourStatusDetail, type TypingDetail, type ViewportPanDetail, type ViewportZoomDetail, } from './events/events.js';
|
|
37
37
|
export { HelixElement, whenHydrated } from './helix-element/helix-element.js';
|
|
38
38
|
export { HelixFormElement } from './helix-form-element/helix-form-element.js';
|
|
39
39
|
export { MixinChartSource, type MixinChartSourceInterface, PALETTE, PLOT_HEIGHT, PLOT_WIDTH, POSITION_LABEL, seriesIndex, seriesNames, } from './mixins/mixin-chart-source/mixin-chart-source.js';
|
|
@@ -77,6 +77,7 @@ export { type DrawDismissOptions, drawDismiss, drawDismissGlyph, } from './utils
|
|
|
77
77
|
export { type DrawIconOptions, drawIcon } from './utils/draw-icon/draw-icon.js';
|
|
78
78
|
export { CHART_PLOT, drawTooltip, type ReadingCursor } from './utils/draw-tooltip/draw-tooltip.js';
|
|
79
79
|
export { drawValueAxis } from './utils/draw-value-axis/draw-value-axis.js';
|
|
80
|
+
export { drawsInSoftware } from './utils/draws-in-software/draws-in-software.js';
|
|
80
81
|
export { elapsedTime } from './utils/elapsed-time/elapsed-time.js';
|
|
81
82
|
export { type ElementByIdOptions, elementById, searchableById, } from './utils/element-by-id/element-by-id.js';
|
|
82
83
|
export { exportParts } from './utils/export-parts/export-parts.js';
|
package/dist/index.js
CHANGED
|
@@ -33,7 +33,7 @@ export { SwipeController, } from './controllers/swipe-controller/swipe-controlle
|
|
|
33
33
|
export { TokenColorController, } from './controllers/token-color-controller/token-color-controller.js';
|
|
34
34
|
export { VirtualizeController, } from './controllers/virtualize-controller/virtualize-controller.js';
|
|
35
35
|
export { eventsForTag, registerElementEvents } from './events/element-events.js';
|
|
36
|
-
export { HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPinEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, } from './events/events.js';
|
|
36
|
+
export { HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPinEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixStrandsFallbackEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, } from './events/events.js';
|
|
37
37
|
export { HelixElement, whenHydrated } from './helix-element/helix-element.js';
|
|
38
38
|
export { HelixFormElement } from './helix-form-element/helix-form-element.js';
|
|
39
39
|
export { MixinChartSource, PALETTE, PLOT_HEIGHT, PLOT_WIDTH, POSITION_LABEL, seriesIndex, seriesNames, } from './mixins/mixin-chart-source/mixin-chart-source.js';
|
|
@@ -77,6 +77,7 @@ export { drawDismiss, drawDismissGlyph, } from './utils/draw-dismiss/draw-dismis
|
|
|
77
77
|
export { drawIcon } from './utils/draw-icon/draw-icon.js';
|
|
78
78
|
export { CHART_PLOT, drawTooltip } from './utils/draw-tooltip/draw-tooltip.js';
|
|
79
79
|
export { drawValueAxis } from './utils/draw-value-axis/draw-value-axis.js';
|
|
80
|
+
export { drawsInSoftware } from './utils/draws-in-software/draws-in-software.js';
|
|
80
81
|
export { elapsedTime } from './utils/elapsed-time/elapsed-time.js';
|
|
81
82
|
export { elementById, searchableById, } from './utils/element-by-id/element-by-id.js';
|
|
82
83
|
export { exportParts } from './utils/export-parts/export-parts.js';
|
|
@@ -21,8 +21,12 @@ export declare class MixinControllerActiveInterface {
|
|
|
21
21
|
* is written.
|
|
22
22
|
*/
|
|
23
23
|
defaultActive: string;
|
|
24
|
-
/**
|
|
25
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Requests a new current item, and returns whether the change was applied.
|
|
26
|
+
* `cause` says why, where the family names its causes, and reaches
|
|
27
|
+
* `helix-before-activate` as `detail.cause`.
|
|
28
|
+
*/
|
|
29
|
+
requestActive(next: string, cause?: string): boolean;
|
|
26
30
|
/**
|
|
27
31
|
* Which item is current, given what there is to choose from.
|
|
28
32
|
*
|
|
@@ -23,7 +23,7 @@ export const MixinControllerActive = (Base) => {
|
|
|
23
23
|
this.activeState = next;
|
|
24
24
|
this.requestUpdate('active', previous);
|
|
25
25
|
}
|
|
26
|
-
requestActive(next) {
|
|
26
|
+
requestActive(next, cause) {
|
|
27
27
|
if (next === this.active) {
|
|
28
28
|
return true;
|
|
29
29
|
}
|
|
@@ -34,7 +34,7 @@ export const MixinControllerActive = (Base) => {
|
|
|
34
34
|
this.activeState = value;
|
|
35
35
|
this.requestUpdate('active', previous);
|
|
36
36
|
},
|
|
37
|
-
event: (value) => new HelixBeforeActivateEvent({ value }),
|
|
37
|
+
event: (value) => new HelixBeforeActivateEvent(cause === undefined ? { value } : { cause, value }),
|
|
38
38
|
host: this,
|
|
39
39
|
next,
|
|
40
40
|
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether WebGL here is drawn on the CPU, asked before one is drawn into.
|
|
3
|
+
*
|
|
4
|
+
* Shared by the elements that draw a decorative field with WebGL, `Aura` and
|
|
5
|
+
* `Strands`, which take their gradient on a software renderer rather than pay
|
|
6
|
+
* for a shader nobody can see at speed.
|
|
7
|
+
*
|
|
8
|
+
* **The shader costs what a GPU makes it cheap to ask for.** Measured on Aura,
|
|
9
|
+
* 15 Sep 2026: on Metal the browser shares the compiled program and each aura
|
|
10
|
+
* after the first draws its opening frame in about 2ms, while under SwiftShader
|
|
11
|
+
* nothing is shared and each one compiles the pipeline again for about 450ms.
|
|
12
|
+
* On a page of 720 pixel auras the worst frame gap went 568ms to 50ms with one
|
|
13
|
+
* aura, 1626ms to 34ms with three and 3200ms to 42ms with six once this check
|
|
14
|
+
* was in place, and a page of three or six ran at 13 frames a second before and
|
|
15
|
+
* at the display's own rate after.
|
|
16
|
+
*
|
|
17
|
+
* **The unmasked name is the only one that answers.** `gl.RENDERER` is masked
|
|
18
|
+
* to `WebKit WebGL` on Chromium, the same string on SwiftShader and on Metal,
|
|
19
|
+
* and `WEBGL_debug_renderer_info` is what lifts the mask.
|
|
20
|
+
*
|
|
21
|
+
* **An unreadable renderer draws**, which is the safe direction and not the
|
|
22
|
+
* tidy one. The extension is optional and is withheld deliberately: Firefox's
|
|
23
|
+
* `privacy.resistFingerprinting` and Safari's equivalent both drop it, and a
|
|
24
|
+
* browser may drop it at any time, since a GPU name is a fingerprinting
|
|
25
|
+
* surface. Treating "we cannot tell" as software would take the shader away
|
|
26
|
+
* from every reader on a machine that hides its hardware, which is a real GPU
|
|
27
|
+
* far more often than not.
|
|
28
|
+
*
|
|
29
|
+
* **A probe context of its own, and given straight back.** Asking the caller's
|
|
30
|
+
* own canvas would spend it, and the probe has to release what it took or a
|
|
31
|
+
* page of fields runs the browser into its cap of about sixteen contexts. One
|
|
32
|
+
* pixel by one, and released through `WEBGL_lose_context`.
|
|
33
|
+
*
|
|
34
|
+
* **The same attributes the real context asks for**, because they are part of
|
|
35
|
+
* the question: `powerPreference` can select a different adapter, so a probe
|
|
36
|
+
* asking for a high-performance context would name a GPU the drawing one is
|
|
37
|
+
* never given.
|
|
38
|
+
*
|
|
39
|
+
* **Asked per context rather than once for the page.** The answer is not fixed:
|
|
40
|
+
* a GPU process that crashes takes the page down to SwiftShader for the rest of
|
|
41
|
+
* its life, and a field rebuilding after that should get the current answer. It
|
|
42
|
+
* costs a context creation and two calls, about 2ms, once per context.
|
|
43
|
+
*
|
|
44
|
+
* @param attributes What the caller's drawing context asks for.
|
|
45
|
+
* @returns `true` only when the renderer names itself as one that draws on the
|
|
46
|
+
* CPU. No WebGL at all, or a name it cannot read, answers `false`.
|
|
47
|
+
*/
|
|
48
|
+
export declare function drawsInSoftware(attributes: WebGLContextAttributes): boolean;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const SOFTWARE_RENDERER = /swiftshader|llvmpipe|softpipe|software rasterizer|basic render/i;
|
|
2
|
+
export function drawsInSoftware(attributes) {
|
|
3
|
+
const probe = document.createElement('canvas');
|
|
4
|
+
probe.width = 1;
|
|
5
|
+
probe.height = 1;
|
|
6
|
+
const gl = probe.getContext('webgl2', attributes);
|
|
7
|
+
if (!gl) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
const debug = gl.getExtension('WEBGL_debug_renderer_info');
|
|
11
|
+
const name = debug ? gl.getParameter(debug.UNMASKED_RENDERER_WEBGL) : null;
|
|
12
|
+
gl.getExtension('WEBGL_lose_context')?.loseContext();
|
|
13
|
+
return typeof name === 'string' && SOFTWARE_RENDERER.test(name);
|
|
14
|
+
}
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '0.
|
|
1
|
+
export const VERSION = '0.162.0';
|
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.162.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ross Sheppard <ross.sheppard@fusion.dev>",
|
|
7
7
|
"repository": {
|
|
@@ -56,11 +56,11 @@
|
|
|
56
56
|
"bugs": "https://github.com/project-fusion/fusion/issues",
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"@floating-ui/dom": "^1.8.0",
|
|
59
|
-
"@fusion.dev/helix-icons": "0.
|
|
59
|
+
"@fusion.dev/helix-icons": "0.162.0"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
|
-
"@fusion.dev/helix-cem": "0.
|
|
63
|
-
"@fusion.dev/helix-testing": "0.
|
|
62
|
+
"@fusion.dev/helix-cem": "0.162.0",
|
|
63
|
+
"@fusion.dev/helix-testing": "0.162.0",
|
|
64
64
|
"@lit-labs/ssr": "^4.1.0",
|
|
65
65
|
"lit": "^3.2.1"
|
|
66
66
|
},
|