@fusion.dev/helix-core 0.2.0 → 0.4.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.
Files changed (56) hide show
  1. package/custom-elements.json +4 -4
  2. package/dist/controllers/aria-forward-controller/aria-forward-controller.js +0 -105
  3. package/dist/controllers/chart-pointer-controller/chart-pointer-controller.js +0 -71
  4. package/dist/controllers/command-controller/command-controller.js +0 -62
  5. package/dist/controllers/copy-controller/copy-controller.js +0 -63
  6. package/dist/controllers/disabled-cascade-controller/disabled-cascade-controller.js +0 -40
  7. package/dist/controllers/dismiss-controller/dismiss-controller.js +0 -124
  8. package/dist/controllers/drilldown-controller/drilldown-controller.js +0 -87
  9. package/dist/controllers/floating-controller/floating-controller.js +0 -152
  10. package/dist/controllers/focus-trap-controller/focus-trap-controller.js +0 -35
  11. package/dist/controllers/indicator-controller/indicator-controller.js +0 -82
  12. package/dist/controllers/keyboard-navigation-controller/keyboard-navigation-controller.js +0 -46
  13. package/dist/controllers/popover-controller/popover-controller.js +0 -72
  14. package/dist/controllers/source-controller/source-controller.js +0 -38
  15. package/dist/controllers/token-color-controller/token-color-controller.js +0 -51
  16. package/dist/controllers/virtualize-controller/virtualize-controller.js +0 -128
  17. package/dist/events/element-events.js +0 -22
  18. package/dist/events/events.js +0 -386
  19. package/dist/helix-element/helix-element.d.ts +10 -17
  20. package/dist/helix-element/helix-element.js +0 -505
  21. package/dist/helix-form-element/helix-form-element.js +0 -140
  22. package/dist/mixins/mixin-chart-source/mixin-chart-source.js +0 -77
  23. package/dist/mixins/mixin-collection/mixin-collection.js +0 -83
  24. package/dist/mixins/mixin-controller-active/mixin-controller-active.js +0 -82
  25. package/dist/mixins/mixin-controller-checked/mixin-controller-checked.js +0 -78
  26. package/dist/mixins/mixin-controller-open/mixin-controller-open.js +0 -93
  27. package/dist/mixins/mixin-controller-value/mixin-controller-value.js +0 -87
  28. package/dist/mixins/mixin-dismissible/mixin-dismissible.js +0 -38
  29. package/dist/mixins/mixin-field/mixin-field.js +0 -277
  30. package/dist/utils/anchor-element/anchor-element.js +0 -23
  31. package/dist/utils/capture-pointer/capture-pointer.js +0 -18
  32. package/dist/utils/closest-instance/closest-instance.js +0 -20
  33. package/dist/utils/create-sheet/create-sheet.js +0 -14
  34. package/dist/utils/custom-element/custom-element.js +0 -83
  35. package/dist/utils/draw-icon/draw-icon.js +0 -28
  36. package/dist/utils/draw-tooltip/draw-tooltip.js +1 -50
  37. package/dist/utils/elapsed-time/elapsed-time.js +0 -51
  38. package/dist/utils/focusable-elements/focusable-elements.js +1 -59
  39. package/dist/utils/format-numbers/format-numbers.js +0 -16
  40. package/dist/utils/host-aria/host-aria.js +0 -26
  41. package/dist/utils/inherit-disabled/inherit-disabled.js +0 -36
  42. package/dist/utils/line-path/line-path.js +0 -36
  43. package/dist/utils/on-unless-false/on-unless-false.js +0 -23
  44. package/dist/utils/read-series/read-series.js +0 -71
  45. package/dist/utils/relative-time/relative-time.js +0 -43
  46. package/dist/utils/resolve-active-item/resolve-active-item.js +0 -20
  47. package/dist/utils/restore-value/restore-value.js +0 -54
  48. package/dist/utils/scale/scale.js +0 -19
  49. package/dist/utils/scale/ticks.js +0 -36
  50. package/dist/utils/scroll-item-into-view/scroll-item-into-view.js +0 -53
  51. package/dist/utils/slot-filled/slot-filled.js +0 -23
  52. package/dist/utils/tell-disclosure/tell-disclosure.js +0 -53
  53. package/dist/utils/ticker/ticker.js +0 -22
  54. package/dist/utils/tone-marks/tone-marks.js +0 -24
  55. package/dist/utils/value-as/value-as.js +0 -56
  56. package/package.json +5 -5
@@ -1,29 +1,7 @@
1
- /**
2
- * Which events each tag actually dispatches, for the React prop audit.
3
- *
4
- * **The audit could already tell a name from a typo and not a name from a
5
- * misplacement.** `helixEventNames` is every event the library has, so
6
- * `onhelix-resize` written on an element that never fires it read as valid: the
7
- * name is real, and nothing knew that this element is not the one that sends it.
8
- * That is the likelier mistake of the two, because it happens while writing a
9
- * *correct* event name.
10
- *
11
- * **Registered rather than imported, because the direction of the tiers forbids
12
- * the other way round.** This lives in `core`, which is below the packages that
13
- * define elements and cannot name them. Each package ships a generated call
14
- * instead, so the map is filled by whoever is loaded and a consumer importing
15
- * one component is checked against that component.
16
- *
17
- * A tag nobody registered is not an error. It is a component from outside this
18
- * library, or a package built before the generator existed, and the audit says
19
- * nothing rather than guessing.
20
- */
21
1
  const declared = new Map();
22
- /** Records the events a set of tags dispatch. Called by generated code. */
23
2
  export const registerElementEvents = (entries) => {
24
3
  for (const [tag, names] of Object.entries(entries)) {
25
4
  declared.set(tag, new Set(names));
26
5
  }
27
6
  };
28
- /** The events a tag dispatches, or `undefined` if nothing registered it. */
29
7
  export const eventsForTag = (tag) => declared.get(tag);
@@ -1,29 +1,3 @@
1
- /**
2
- * Event classes, one per event a Helix component dispatches.
3
- *
4
- * A named class rather than `dispatchEvent(new CustomEvent(name, …))` for three
5
- * reasons, all of them about the type reaching a consumer:
6
- *
7
- * 1. `@event {HelixBeforeOpenEvent} helix-before-open` puts the class name in the manifest,
8
- * which is what lets the React generator emit a typed callback instead of
9
- * `(detail: unknown)`.
10
- * 2. The augmentation of `HTMLElementEventMap` below types `addEventListener`
11
- * for consumers writing plain HTML, who never see the React wrappers.
12
- * 3. The event name lives on the class as `eventName`, so a listener and a
13
- * dispatch cannot disagree about the string.
14
- */
15
- /**
16
- * Fired when an element is about to open.
17
- *
18
- * Cancelable: `preventDefault()` refuses the change, and the element stays
19
- * closed. Paired with `helix-before-close` rather than being one event carrying a
20
- * boolean, so a listener that only cares about one direction says so by which
21
- * event it listens for.
22
- *
23
- * Neither bubbles nor composed. A dialog inside a drawer inside a popover is
24
- * three overlays, and an inner one opening must not read as the outer one
25
- * opening.
26
- */
27
1
  export class HelixBeforeOpenEvent extends CustomEvent {
28
2
  static { this.eventName = 'helix-before-open'; }
29
3
  constructor() {
@@ -35,7 +9,6 @@ export class HelixBeforeOpenEvent extends CustomEvent {
35
9
  });
36
10
  }
37
11
  }
38
- /** Fired when an element is about to close. See `HelixBeforeOpenEvent`. */
39
12
  export class HelixBeforeCloseEvent extends CustomEvent {
40
13
  static { this.eventName = 'helix-before-close'; }
41
14
  constructor() {
@@ -47,24 +20,6 @@ export class HelixBeforeCloseEvent extends CustomEvent {
47
20
  });
48
21
  }
49
22
  }
50
- /**
51
- * Fired when the reader asks for the next thing in a set.
52
- *
53
- * Paired with `helix-previous` rather than being one event carrying a
54
- * direction, which is the reason `helix-before-open` gives for its own pair: a
55
- * listener that only cares about one direction says so by which event it
56
- * listens for. The detail carries the direction anyway, so a consumer who does
57
- * want one handler can have one.
58
- *
59
- * Bubbles and is composed, because the thing that answers this is usually not
60
- * the thing that asked. A video has no notion of a set: it plays one resource,
61
- * and what comes next is a playlist's business or the consumer's, so the event
62
- * has to reach a wrapper.
63
- *
64
- * Not cancelable. There is no default action to refuse: the component that
65
- * fires this does nothing on its own, and an event whose `preventDefault` means
66
- * nothing is an event that lies about what it offers.
67
- */
68
23
  export class HelixNextEvent extends CustomEvent {
69
24
  static { this.eventName = 'helix-next'; }
70
25
  constructor() {
@@ -76,7 +31,6 @@ export class HelixNextEvent extends CustomEvent {
76
31
  });
77
32
  }
78
33
  }
79
- /** Fired when the reader asks for the previous one. See `HelixNextEvent`. */
80
34
  export class HelixPreviousEvent extends CustomEvent {
81
35
  static { this.eventName = 'helix-previous'; }
82
36
  constructor() {
@@ -88,79 +42,29 @@ export class HelixPreviousEvent extends CustomEvent {
88
42
  });
89
43
  }
90
44
  }
91
- /**
92
- * A stop asking the tour to move.
93
- *
94
- * Composed and bubbling, because a stop is slotted into the root and the root
95
- * has to hear it across that boundary.
96
- *
97
- * **A class rather than a hand-rolled `CustomEvent`.** A dispatch is matched as
98
- * `new HelixSomethingEvent(`, so a raw `CustomEvent` is not held to being
99
- * declared and nothing carries it into the manifest: consumers can hear it and
100
- * cannot find it.
101
- */
102
45
  export class HelixTourAskEvent extends CustomEvent {
103
46
  static { this.eventName = 'helix-tour-ask'; }
104
47
  constructor(detail) {
105
48
  super(HelixTourAskEvent.eventName, {
106
49
  bubbles: true,
107
- /* Not cancelable. The name says *ask*, so refusing it looks like it should
108
- hold the tour, and honoring it here could not work: the root registers
109
- its listener in `connectedCallback` and a consumer registers later, so on
110
- a bubbling event both are on the same target and the root's runs first,
111
- reading `defaultPrevented` before the consumer has had a chance to set
112
- it. `helix-shortcut` gets this right by reading the flag on the element
113
- that dispatched, where every listener has already run.
114
-
115
- **The veto exists and is elsewhere.** Moving between stops goes through
116
- `requestChange` and announces `helix-before-activate`; leaving early
117
- dispatches `helix-before-close` and reads the flag before writing
118
- `open`. This event is the stop telling the root a button was pressed,
119
- and the decision is taken one step later. */
120
50
  cancelable: false,
121
51
  composed: true,
122
52
  detail,
123
53
  });
124
54
  }
125
55
  }
126
- /**
127
- * The eyedropper opening, and closing again.
128
- *
129
- * Two events rather than one carrying a flag, because what a consumer does with
130
- * them is not symmetrical: the surface holding the picker has to get out of the
131
- * way for the sample and come back afterwards, and those are two moments with
132
- * different work in each.
133
- *
134
- * **A class rather than a bare `Event`.** The check that holds an event to being
135
- * declared reads `new Event(` as well as `new HelixSomethingEvent(`, so a
136
- * hand-rolled one is public API a consumer can hear and cannot find.
137
- *
138
- * No detail, because there is nothing to say beyond that it happened.
139
- */
140
56
  export class HelixSampleStartEvent extends Event {
141
57
  static { this.eventName = 'helix-sample-start'; }
142
58
  constructor() {
143
59
  super(HelixSampleStartEvent.eventName, { bubbles: true, cancelable: false, composed: true });
144
60
  }
145
61
  }
146
- /** The eyedropper closing, whether or not a color was taken. */
147
62
  export class HelixSampleEndEvent extends Event {
148
63
  static { this.eventName = 'helix-sample-end'; }
149
64
  constructor() {
150
65
  super(HelixSampleEndEvent.eventName, { bubbles: true, cancelable: false, composed: true });
151
66
  }
152
67
  }
153
- /**
154
- * Fired when an element asks to be taken away.
155
- *
156
- * A request rather than a notification: the element does not remove itself,
157
- * because the consumer owns the markup it is in and removing the node under
158
- * them would put their state and the document out of step. Cancelable, so
159
- * `preventDefault()` is a refusal.
160
- *
161
- * One verb for both shapes. A tag leaving a list and an announcement closing
162
- * itself are the same act from the element's side.
163
- */
164
68
  export class HelixDismissEvent extends CustomEvent {
165
69
  static { this.eventName = 'helix-dismiss'; }
166
70
  constructor(detail) {
@@ -172,25 +76,6 @@ export class HelixDismissEvent extends CustomEvent {
172
76
  });
173
77
  }
174
78
  }
175
- /**
176
- * A set is about to make a different child current, and can be refused.
177
- *
178
- * **Not a generic `helix-change`.** `Tabs` moving to another tab, `Tree` marking
179
- * another row and `Steps` advancing are not a value changing, they are a set
180
- * choosing, and the platform's word for a committed value would say the wrong
181
- * thing. `active` names which child is current, so `activate` is the verb, and
182
- * unlike `change` the platform has no claim on it.
183
- *
184
- * **This fires before the state moves.** Inside a handler `currentTarget.active`
185
- * still holds the previous value, and `detail.value` is a proposal another
186
- * listener may refuse, so a consumer who only wants to know which child is
187
- * current listens for `helix-activate` instead. `helix-select` is not that
188
- * notification either: it fires when an item is *chosen*, not when `active` is
189
- * assigned.
190
- *
191
- * The shape is the one `MixinControllerOpen` already has, a cancelable request
192
- * and a plain notification after the state has moved.
193
- */
194
79
  export class HelixBeforeActivateEvent extends CustomEvent {
195
80
  static { this.eventName = 'helix-before-activate'; }
196
81
  constructor(detail) {
@@ -202,22 +87,6 @@ export class HelixBeforeActivateEvent extends CustomEvent {
202
87
  });
203
88
  }
204
89
  }
205
- /**
206
- * A set has made a different child current.
207
- *
208
- * The notification half of `helix-before-activate`, dispatched after the state
209
- * has moved, so `currentTarget.active` is the new value and the detail is a fact
210
- * rather than a proposal.
211
- *
212
- * **Not cancelable**, for the reason every notification here is not: the
213
- * decision was taken by the event before it, and a second refusable event for
214
- * one transition is two answers to one question.
215
- *
216
- * **Prefixed, and it has to be.** `activate` unprefixed is not in any
217
- * `*EventMap` in the DOM library, checked rather than assumed, but the prefix is
218
- * what stops an event dispatched inside a shadow root and retargeted to the host
219
- * being mistaken for something the host's own contents sent.
220
- */
221
90
  export class HelixActivateEvent extends CustomEvent {
222
91
  static { this.eventName = 'helix-activate'; }
223
92
  constructor(detail) {
@@ -229,7 +98,6 @@ export class HelixActivateEvent extends CustomEvent {
229
98
  });
230
99
  }
231
100
  }
232
- /** A message is about to be pinned or unpinned, and can be refused. */
233
101
  export class HelixBeforePinEvent extends CustomEvent {
234
102
  static { this.eventName = 'helix-before-pin'; }
235
103
  constructor(detail) {
@@ -241,7 +109,6 @@ export class HelixBeforePinEvent extends CustomEvent {
241
109
  });
242
110
  }
243
111
  }
244
- /** A divider is about to move, and can be refused. */
245
112
  export class HelixBeforeResizeEvent extends CustomEvent {
246
113
  static { this.eventName = 'helix-before-resize'; }
247
114
  constructor(detail) {
@@ -253,13 +120,6 @@ export class HelixBeforeResizeEvent extends CustomEvent {
253
120
  });
254
121
  }
255
122
  }
256
- /**
257
- * The divider between a sandbox's panes is about to move, and can be refused.
258
- *
259
- * Its own verb rather than a `helix-before-resize` carrying which divider moved:
260
- * a sandbox has two, and they were told apart by a field on a detail every other
261
- * request in this file also carries.
262
- */
263
123
  export class HelixBeforeSplitEvent extends CustomEvent {
264
124
  static { this.eventName = 'helix-before-split'; }
265
125
  constructor(detail) {
@@ -271,14 +131,6 @@ export class HelixBeforeSplitEvent extends CustomEvent {
271
131
  });
272
132
  }
273
133
  }
274
- /**
275
- * A sandbox's panel is about to change height, and can be refused.
276
- *
277
- * The sibling of `helix-before-split`, and named for the divider rather than for
278
- * the axis because a reader binding one of the two is choosing which divider they
279
- * care about. `value` is pixels here and a percentage there, which is what each
280
- * property already publishes.
281
- */
282
134
  export class HelixBeforePanelResizeEvent extends CustomEvent {
283
135
  static { this.eventName = 'helix-before-panel-resize'; }
284
136
  constructor(detail) {
@@ -290,7 +142,6 @@ export class HelixBeforePanelResizeEvent extends CustomEvent {
290
142
  });
291
143
  }
292
144
  }
293
- /** A pane is about to collapse or reopen, and can be refused. */
294
145
  export class HelixBeforeCollapseEvent extends CustomEvent {
295
146
  static { this.eventName = 'helix-before-collapse'; }
296
147
  constructor(detail) {
@@ -302,7 +153,6 @@ export class HelixBeforeCollapseEvent extends CustomEvent {
302
153
  });
303
154
  }
304
155
  }
305
- /** Source is about to be edited, and can be refused. */
306
156
  export class HelixBeforeEditEvent extends CustomEvent {
307
157
  static { this.eventName = 'helix-before-edit'; }
308
158
  constructor(detail) {
@@ -314,27 +164,6 @@ export class HelixBeforeEditEvent extends CustomEvent {
314
164
  });
315
165
  }
316
166
  }
317
- /**
318
- * A value is about to change, and the change can be refused.
319
- *
320
- * **The request half of every value control.** It announces the value being
321
- * *proposed*, before anything moves, so a listener calling `preventDefault()`
322
- * refuses it and the control stays where it was. That is how a consumer takes
323
- * one decision without declaring a mode, which is what 294 settled: the element
324
- * always owns and applies its state, and refusing is the way to take it over.
325
- *
326
- * **The notification is native and separate.** Once this has gone out and the
327
- * value has moved, the control announces it again under the platform's own
328
- * name, `input` while a reader is editing and `change` when they are done, so
329
- * `onChange` in React and `onchange=` in HTML both reach it and
330
- * `currentTarget.value` is correct by the time a handler reads it. This event
331
- * carries the detail because at the moment it fires the value is not on the
332
- * element yet.
333
- *
334
- * **`announcesInput` picks which native notification fires, not which name this
335
- * carries.** Granularity is the platform's own distinction, `input` against
336
- * `change`; the request is always this one event.
337
- */
338
167
  export class HelixBeforeChangeEvent extends CustomEvent {
339
168
  static { this.eventName = 'helix-before-change'; }
340
169
  constructor(detail) {
@@ -346,24 +175,6 @@ export class HelixBeforeChangeEvent extends CustomEvent {
346
175
  });
347
176
  }
348
177
  }
349
- /**
350
- * A checked state is about to change, and the change can be refused.
351
- *
352
- * **Its own event rather than a `helix-before-change` carrying a boolean.**
353
- * Through the value event the state arrives as `String(checked)`, so a consumer
354
- * receives the string `"false"`, which is truthy, and a test asserting the value
355
- * passes on that bug. A control whose state is a boolean wants an event with a
356
- * typed boolean in it.
357
- *
358
- * The notification is native, as it is for a value: the control relays `change`
359
- * from the inner input and announces `input` beside it, so `onChange` reads
360
- * `currentTarget.checked` and gets a boolean from the platform.
361
- *
362
- * It also ends a collision: Checkbox Group listened for its boxes' change and
363
- * dispatched its own under the same name from the same host, so it needed
364
- * `stopImmediatePropagation` to keep a consumer from receiving one box's boolean
365
- * alongside the whole set. Two names, two facts.
366
- */
367
178
  export class HelixBeforeToggleEvent extends CustomEvent {
368
179
  static { this.eventName = 'helix-before-toggle'; }
369
180
  constructor(detail) {
@@ -375,19 +186,6 @@ export class HelixBeforeToggleEvent extends CustomEvent {
375
186
  });
376
187
  }
377
188
  }
378
- /**
379
- * The reader asked for something the list does not hold.
380
- *
381
- * Cancelable, and announced before anything is applied, because the options are
382
- * the consumer's own light DOM and no component here writes into it. What the
383
- * control can do is say what was asked for and take the value; putting an
384
- * option in the list, or a row in a database, is the consumer's, and a consumer
385
- * who validates first refuses this and adds nothing.
386
- *
387
- * The detail carries the text as typed, not a slug of it. Trimming or lowering
388
- * it here would be this element deciding what a name means, and a consumer who
389
- * wants an identifier can make one from what they were given.
390
- */
391
189
  export class HelixCreateEvent extends CustomEvent {
392
190
  static { this.eventName = 'helix-create'; }
393
191
  constructor(detail) {
@@ -399,13 +197,6 @@ export class HelixCreateEvent extends CustomEvent {
399
197
  });
400
198
  }
401
199
  }
402
- /**
403
- * Something was copied to the clipboard.
404
- *
405
- * Not cancelable, and deliberately: it is announced after the write, because a
406
- * clipboard write is a permission the platform may refuse and there is nothing
407
- * useful to report until it has either happened or not.
408
- */
409
200
  export class HelixCopyEvent extends CustomEvent {
410
201
  static { this.eventName = 'helix-copy'; }
411
202
  constructor(detail) {
@@ -416,85 +207,28 @@ export class HelixCopyEvent extends CustomEvent {
416
207
  });
417
208
  }
418
209
  }
419
- /**
420
- * Fired when something being previewed writes to the console.
421
- *
422
- * Carries text rather than the logged values. The preview is a separate
423
- * document, so what arrives has crossed `postMessage` and been through
424
- * structured clone: a DOM node or a function does not survive that, and half a
425
- * value is worse than a string of it.
426
- */
427
210
  export class HelixConsoleEvent extends CustomEvent {
428
211
  static { this.eventName = 'helix-console'; }
429
212
  constructor(detail) {
430
213
  super(HelixConsoleEvent.eventName, {
431
214
  bubbles: true,
432
- /* Not cancelable, for the reason `helix-resize` is not: a log line the
433
- frame already wrote is a fact being relayed rather than a proposal, and
434
- nothing reads the result. */
435
215
  cancelable: false,
436
216
  composed: true,
437
217
  detail,
438
218
  });
439
219
  }
440
220
  }
441
- /**
442
- * Fired when something reports how much room its content actually needs.
443
- *
444
- * **A measurement crossing a boundary the measurer is on the far side of.** A
445
- * sandboxed preview is its own document: nothing outside it can read the height
446
- * of what it drew, because the frame is opaque and a box sized from the outside
447
- * only ever reports the box. So the document measures itself and says so, and
448
- * this is what it says it with.
449
- *
450
- * A number rather than a box, because the width is the container's to decide and
451
- * only the block size follows the content. A consumer that wants to act on it
452
- * clamps it: what arrives is what was drawn, which for an empty example is
453
- * nearly nothing and for a long one is more than a page.
454
- */
455
221
  export class HelixResizeEvent extends CustomEvent {
456
222
  static { this.eventName = 'helix-resize'; }
457
223
  constructor(detail) {
458
224
  super(HelixResizeEvent.eventName, {
459
225
  bubbles: true,
460
- /* Not cancelable. A measurement is not a proposal: the content is that
461
- tall whether or not anybody wants it to be, and neither dispatcher,
462
- `Heatmap` nor `Sandbox.Preview`, reads the result. Accepting
463
- `preventDefault()` and ignoring it is worse than refusing the call, a
464
- consumer having every reason to believe they had stopped something. */
465
226
  cancelable: false,
466
227
  composed: true,
467
228
  detail,
468
229
  });
469
230
  }
470
231
  }
471
- /**
472
- * Fired when a header crosses the threshold between resting at the top of the
473
- * page and floating over it.
474
- *
475
- * **The threshold lives in a custom state, and is announced rather than
476
- * reflected.** A `data-scrolled` on the host is an attribute nobody rendered: a
477
- * server sends the element without it and the element adds it on upgrade, so a
478
- * framework hydrating the page finds markup that no longer matches what it sent.
479
- * A custom state is deliberately not in the DOM and therefore not something a
480
- * hydration pass can disagree with.
481
- *
482
- * That closes the observability an attribute would accidentally provide. A
483
- * `MutationObserver` can watch an attribute and there is no equivalent for
484
- * `ElementInternals.states`, so a component holding a boolean nothing can read
485
- * is a component with a private opinion its consumers demonstrably need: the
486
- * bar's own backdrop is drawn by the page around it, and the page has to know
487
- * when to light it.
488
- *
489
- * Not cancelable. It reports where the page is rather than asking permission to
490
- * be there, and refusing it would leave the state and the announcement
491
- * disagreeing.
492
- *
493
- * The hysteresis stays inside the header, which is the point of announcing at
494
- * all: a consumer listening to `scroll` itself would be a second opinion on
495
- * when the page counts as scrolled, and the two would part company at the eight
496
- * pixels of travel this waits for.
497
- */
498
232
  export class HelixScrolledEvent extends CustomEvent {
499
233
  static { this.eventName = 'helix-scrolled'; }
500
234
  constructor(detail) {
@@ -506,18 +240,6 @@ export class HelixScrolledEvent extends CustomEvent {
506
240
  });
507
241
  }
508
242
  }
509
- /**
510
- * Fired when the cursor moves in a text editor.
511
- *
512
- * Not cancelable, unlike everything else here. The others announce something
513
- * about to happen and a listener can refuse it; this one reports where the
514
- * caret already is, and there is nothing left to refuse.
515
- *
516
- * It fires on every keystroke and every arrow press, which is why the status
517
- * bar reads it from the DOM rather than through a framework's state: routing a
518
- * caret position through React would re-render the workbench on every cursor
519
- * move.
520
- */
521
243
  export class HelixCaretEvent extends CustomEvent {
522
244
  static { this.eventName = 'helix-caret'; }
523
245
  constructor(detail) {
@@ -529,14 +251,6 @@ export class HelixCaretEvent extends CustomEvent {
529
251
  });
530
252
  }
531
253
  }
532
- /**
533
- * Fired when a component moves the view it is showing, rather than its value.
534
- *
535
- * A calendar paging to another month is not choosing a date, and the two have
536
- * to be separable: a consumer driving the view needs to hear that it moved
537
- * without being told the answer changed. `helix-change` belongs to the value,
538
- * and giving it both jobs would make either one unusable on its own.
539
- */
540
254
  export class HelixNavigateEvent extends CustomEvent {
541
255
  static { this.eventName = 'helix-navigate'; }
542
256
  constructor(detail) {
@@ -548,27 +262,6 @@ export class HelixNavigateEvent extends CustomEvent {
548
262
  });
549
263
  }
550
264
  }
551
- /**
552
- * Fired when a control that fills up has filled.
553
- *
554
- * The moment a code entry exists for: a six-character field is worth submitting
555
- * the instant the sixth character lands, and a consumer watching `helix-change`
556
- * has to know the length and compare it on every keystroke to find that moment
557
- * themselves.
558
- *
559
- * Separate from `helix-change` rather than a flag on it, because they are
560
- * answered by different code: one keeps a value in step and the other decides
561
- * whether to send a form. A listener that only cares about the second says so by
562
- * which event it listens for.
563
- *
564
- * `complete` is free as a verb. React's synthetic system claims `change`,
565
- * `input`, `submit`, `reset`, `copy`, `paste`, `scroll`, `drag`, `focus` and
566
- * `blur`, measured, and this is none of them.
567
- *
568
- * Not cancelable. It reports that something already happened, which is the same
569
- * reason `helix-caret` is not: there is nothing left to refuse once the last
570
- * character is in the box.
571
- */
572
265
  export class HelixCompleteEvent extends CustomEvent {
573
266
  static { this.eventName = 'helix-complete'; }
574
267
  constructor(detail) {
@@ -580,19 +273,6 @@ export class HelixCompleteEvent extends CustomEvent {
580
273
  });
581
274
  }
582
275
  }
583
- /**
584
- * Fired when the reader offers something they wrote.
585
- *
586
- * **Cancelable, and the composer clears only when nobody refused.** Sending is a
587
- * round trip: a composer that empties itself and then hears the request failed
588
- * has thrown away the only copy of what the reader typed, and a reader who has
589
- * just written three paragraphs is exactly who cannot afford that. Refusing
590
- * leaves the text where it is.
591
- *
592
- * Not `helix-create`, which is the combobox's event for a value a list does not
593
- * hold, and not `helix-change`, because nothing about a value changed: the
594
- * reader finished something and handed it over.
595
- */
596
276
  export class HelixSendEvent extends CustomEvent {
597
277
  static { this.eventName = 'helix-send'; }
598
278
  constructor(detail) {
@@ -604,20 +284,6 @@ export class HelixSendEvent extends CustomEvent {
604
284
  });
605
285
  }
606
286
  }
607
- /**
608
- * Fired when something a user comes back to is marked read, or unread.
609
- *
610
- * **Read state is reported rather than owned.** Marking a notification read is
611
- * usually a round trip, and a component that flips the state itself and then
612
- * hears the request failed has already told the reader something untrue. So this
613
- * is cancelable, and refusing it leaves the item alone; a component left
614
- * uncontrolled applies it once nobody has refused, which is the same contract
615
- * every other axis in the library uses.
616
- *
617
- * Bubbles and is composed, so a feed hears its own items: one handler on the
618
- * list serves every notification in it, which is what a consumer syncing to a
619
- * server actually wants.
620
- */
621
287
  export class HelixReadEvent extends CustomEvent {
622
288
  static { this.eventName = 'helix-read'; }
623
289
  constructor(detail) {
@@ -629,18 +295,6 @@ export class HelixReadEvent extends CustomEvent {
629
295
  });
630
296
  }
631
297
  }
632
- /**
633
- * Fired when the reader asks for a different order.
634
- *
635
- * Cancelable, and refusing it leaves the order alone, which is what makes a
636
- * server-side sort expressible: the consumer refuses the local reorder, fetches,
637
- * and hands back a new set. This is the element reporting that a heading was
638
- * clicked, before it acts on it.
639
- *
640
- * Not `helix-change`: nothing about the data changed, only the order it is read
641
- * in, and a consumer listening for changes to a value should not hear a sort.
642
- * That is the same distinction `helix-filter` is drawn on.
643
- */
644
298
  export class HelixSortEvent extends CustomEvent {
645
299
  static { this.eventName = 'helix-sort'; }
646
300
  constructor(detail) {
@@ -652,13 +306,6 @@ export class HelixSortEvent extends CustomEvent {
652
306
  });
653
307
  }
654
308
  }
655
- /**
656
- * Fired when a component narrows what it is showing.
657
- *
658
- * Filtering hides rather than removes, so nothing about the value changes and
659
- * `helix-change` would be a lie. What a consumer wants to know is that the list
660
- * in front of the reader is no longer the whole list.
661
- */
662
309
  export class HelixFilterEvent extends CustomEvent {
663
310
  static { this.eventName = 'helix-filter'; }
664
311
  constructor(detail) {
@@ -670,14 +317,6 @@ export class HelixFilterEvent extends CustomEvent {
670
317
  });
671
318
  }
672
319
  }
673
- /**
674
- * Fired when a shortcut's chord is pressed.
675
- *
676
- * Cancelable, and the key event is only consumed where this is not refused: a
677
- * consumer that decides the moment is wrong, a dialog is over the control or
678
- * the reader is mid-composition, calls `preventDefault()` and the keystroke
679
- * goes on to whatever would have had it.
680
- */
681
320
  export class HelixShortcutEvent extends CustomEvent {
682
321
  static { this.eventName = 'helix-shortcut'; }
683
322
  constructor(detail) {
@@ -689,13 +328,6 @@ export class HelixShortcutEvent extends CustomEvent {
689
328
  });
690
329
  }
691
330
  }
692
- /**
693
- * Fired when the reader selects an item in a set.
694
- *
695
- * Bubbles and is composed, because this is how a set coordinates: a tree, a
696
- * tab list and a toggle group all learn which of their children was chosen by
697
- * hearing it arrive.
698
- */
699
331
  export class HelixSelectEvent extends CustomEvent {
700
332
  static { this.eventName = 'helix-select'; }
701
333
  constructor(detail) {
@@ -707,17 +339,6 @@ export class HelixSelectEvent extends CustomEvent {
707
339
  });
708
340
  }
709
341
  }
710
- /**
711
- * Every event this file publishes, and the one place a new one is added.
712
- *
713
- * The map below is derived from this rather than written beside it, so a class
714
- * that is in here is typed and one that is not is absent from both halves at
715
- * once. Kept by hand the two drifted, and nothing failed when they did: a
716
- * consumer writing `addEventListener('helix-navigate', …)` got `Event` and had
717
- * to reach into `detail` through a cast. The build fails on an exported event
718
- * class left out of this object, which is the only step left that can be
719
- * forgotten.
720
- */
721
342
  const registry = {
722
343
  HelixActivateEvent,
723
344
  HelixBeforeActivateEvent,
@@ -752,11 +373,4 @@ const registry = {
752
373
  HelixSortEvent,
753
374
  HelixTourAskEvent,
754
375
  };
755
- /**
756
- * Every name this library dispatches.
757
- *
758
- * Exported so a runtime check can ask whether a name is one of ours without
759
- * keeping a second list of them. `HelixElement` uses it to tell a consumer that
760
- * the handler prop they wrote is attached to nothing.
761
- */
762
376
  export const helixEventNames = new Set(Object.values(registry).map((event) => event.eventName));
@@ -88,31 +88,24 @@ export declare class HelixElement extends LitElement {
88
88
  * references. An engine without `CustomStateSet` records nothing and keeps
89
89
  * whatever the resting rule draws, which is the safe direction to fail.
90
90
  *
91
- * **Lit's server shim is no longer one of them**, and this said it was.
92
- * `@lit-labs/ssr-dom-shim@1.6.0` sets `this.states = new Set()` in its
93
- * `ElementInternals` constructor, so the guard passes on the server and a
94
- * custom state is recorded where nothing reads it, which is harmless. The
95
- * engines the test is for are browsers: Safari below 17.4 and Firefox below
96
- * 126. There the write is a `TypeError`, so a component that bypasses this
91
+ * **The engines the test is for are browsers**: Safari below 17.4 and Firefox
92
+ * below 126, where the write is a `TypeError`, so a component bypassing this
97
93
  * fails to render rather than rendering without whatever the state draws.
94
+ * Lit's server shim sets `states`, so the guard passes there and records a
95
+ * state nothing reads, which is harmless.
98
96
  */
99
97
  protected toggleState(name: string, on: boolean): void;
100
98
  /**
101
99
  * Resolves a frame after the first update, when transitions are switched on.
102
100
  *
103
- * **Named `whenSettled` because `settled` was taken four times over.** Image
104
- * and Splitter each have a private `settle`, and both color controls carry a
105
- * `settled` of their own, all of them older than this and none of them about
106
- * transitions. A base class takes the name every subclass then cannot use, so
107
- * it takes the one nobody wanted.
101
+ * **Named `whenSettled` because `settled` is taken four times over**, by
102
+ * Image, Splitter and both color controls, none of them about transitions. A
103
+ * base class takes the name every subclass then cannot use.
108
104
  *
109
105
  * **The state it reports cannot be watched, which is why this exists.** A
110
- * `MutationObserver` could see `[data-settled]` arrive and there is no
111
- * equivalent for `ElementInternals.states`: a custom state is deliberately not
112
- * in the DOM, which is the whole reason it replaced the attribute. Anything
113
- * that used to wait on the attribute waits on this instead, and gets a better
114
- * signal for it, an awaited promise being what the callers wanted rather than
115
- * a mutation they had to interpret.
106
+ * custom state is deliberately not in the DOM, so there is no
107
+ * `MutationObserver` equivalent for `ElementInternals.states`. Await this
108
+ * instead.
116
109
  *
117
110
  * Separate from `updateComplete`, which resolves in the microtask checkpoint
118
111
  * the suppression is still active in. That is the distinction `readyToMove`