@fusion.dev/helix-core 0.0.0-dev → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +156 -124
- package/dist/controllers/aria-forward-controller/aria-forward-controller.d.ts +2 -0
- package/dist/controllers/aria-forward-controller/aria-forward-controller.js +44 -17
- package/dist/controllers/chart-pointer-controller/chart-pointer-controller.d.ts +5 -6
- package/dist/controllers/chart-pointer-controller/chart-pointer-controller.js +5 -6
- package/dist/controllers/command-controller/command-controller.d.ts +5 -7
- package/dist/controllers/command-controller/command-controller.js +5 -7
- package/dist/controllers/copy-controller/copy-controller.d.ts +2 -4
- package/dist/controllers/copy-controller/copy-controller.js +7 -9
- package/dist/controllers/disabled-cascade-controller/disabled-cascade-controller.d.ts +10 -17
- package/dist/controllers/disabled-cascade-controller/disabled-cascade-controller.js +11 -18
- package/dist/controllers/dismiss-controller/dismiss-controller.d.ts +44 -6
- package/dist/controllers/dismiss-controller/dismiss-controller.js +77 -10
- package/dist/controllers/drilldown-controller/drilldown-controller.d.ts +3 -6
- package/dist/controllers/drilldown-controller/drilldown-controller.js +3 -6
- package/dist/controllers/floating-controller/floating-controller.d.ts +7 -8
- package/dist/controllers/floating-controller/floating-controller.js +69 -38
- package/dist/controllers/focus-trap-controller/focus-trap-controller.js +7 -10
- package/dist/controllers/indicator-controller/indicator-controller.d.ts +17 -29
- package/dist/controllers/indicator-controller/indicator-controller.js +11 -21
- package/dist/controllers/keyboard-navigation-controller/keyboard-navigation-controller.d.ts +3 -13
- package/dist/controllers/keyboard-navigation-controller/keyboard-navigation-controller.js +11 -24
- package/dist/controllers/popover-controller/popover-controller.d.ts +2 -7
- package/dist/controllers/popover-controller/popover-controller.js +3 -9
- package/dist/controllers/source-controller/source-controller.d.ts +2 -5
- package/dist/controllers/source-controller/source-controller.js +2 -5
- package/dist/controllers/token-color-controller/token-color-controller.d.ts +2 -4
- package/dist/controllers/token-color-controller/token-color-controller.js +2 -4
- package/dist/controllers/virtualize-controller/virtualize-controller.d.ts +1 -1
- package/dist/controllers/virtualize-controller/virtualize-controller.js +15 -15
- package/dist/events/element-events.js +0 -5
- package/dist/events/events.d.ts +55 -93
- package/dist/events/events.js +68 -105
- package/dist/helix-element/helix-element.d.ts +26 -27
- package/dist/helix-element/helix-element.js +83 -100
- package/dist/helix-form-element/helix-form-element.d.ts +11 -17
- package/dist/helix-form-element/helix-form-element.js +15 -21
- package/dist/mixins/mixin-chart-source/mixin-chart-source.d.ts +6 -14
- package/dist/mixins/mixin-chart-source/mixin-chart-source.js +12 -25
- package/dist/mixins/mixin-collection/mixin-collection.d.ts +1 -7
- package/dist/mixins/mixin-collection/mixin-collection.js +16 -23
- package/dist/mixins/mixin-controller-active/mixin-controller-active.d.ts +15 -16
- package/dist/mixins/mixin-controller-active/mixin-controller-active.js +28 -42
- package/dist/mixins/mixin-controller-checked/mixin-controller-checked.d.ts +15 -17
- package/dist/mixins/mixin-controller-checked/mixin-controller-checked.js +33 -45
- package/dist/mixins/mixin-controller-open/mixin-controller-open.d.ts +4 -4
- package/dist/mixins/mixin-controller-open/mixin-controller-open.js +29 -45
- package/dist/mixins/mixin-controller-value/mixin-controller-value.d.ts +10 -18
- package/dist/mixins/mixin-controller-value/mixin-controller-value.js +14 -31
- package/dist/mixins/mixin-dismissible/mixin-dismissible.d.ts +10 -15
- package/dist/mixins/mixin-dismissible/mixin-dismissible.js +10 -15
- package/dist/mixins/mixin-field/mixin-field.d.ts +10 -12
- package/dist/mixins/mixin-field/mixin-field.js +48 -64
- package/dist/utils/capture-pointer/capture-pointer.d.ts +1 -4
- package/dist/utils/capture-pointer/capture-pointer.js +1 -4
- package/dist/utils/closest-instance/closest-instance.d.ts +6 -10
- package/dist/utils/closest-instance/closest-instance.js +6 -10
- package/dist/utils/create-sheet/create-sheet.d.ts +1 -1
- package/dist/utils/create-sheet/create-sheet.js +1 -1
- package/dist/utils/custom-element/custom-element.d.ts +0 -21
- package/dist/utils/custom-element/custom-element.js +1 -1
- package/dist/utils/draw-icon/draw-icon.d.ts +3 -3
- package/dist/utils/draw-icon/draw-icon.js +3 -3
- package/dist/utils/elapsed-time/elapsed-time.js +1 -3
- package/dist/utils/focusable-elements/focusable-elements.d.ts +3 -4
- package/dist/utils/focusable-elements/focusable-elements.js +9 -11
- package/dist/utils/format-numbers/format-numbers.js +1 -4
- package/dist/utils/host-aria/host-aria.d.ts +2 -2
- package/dist/utils/host-aria/host-aria.js +2 -2
- package/dist/utils/line-path/line-path.js +1 -1
- package/dist/utils/on-unless-false/on-unless-false.d.ts +0 -5
- package/dist/utils/on-unless-false/on-unless-false.js +0 -5
- package/dist/utils/read-series/read-series.d.ts +26 -0
- package/dist/utils/read-series/read-series.js +26 -29
- package/dist/utils/relative-time/relative-time.js +5 -6
- package/dist/utils/request-change/request-change.d.ts +9 -20
- package/dist/utils/resolve-active-item/resolve-active-item.d.ts +3 -3
- package/dist/utils/resolve-active-item/resolve-active-item.js +3 -3
- package/dist/utils/restore-value/restore-value.js +1 -6
- package/dist/utils/scroll-item-into-view/scroll-item-into-view.js +4 -5
- package/dist/utils/slot-filled/slot-filled.d.ts +2 -4
- package/dist/utils/slot-filled/slot-filled.js +2 -4
- package/dist/utils/tell-disclosure/tell-disclosure.d.ts +15 -18
- package/dist/utils/tell-disclosure/tell-disclosure.js +15 -18
- package/dist/utils/tone-marks/tone-marks.d.ts +10 -16
- package/dist/utils/tone-marks/tone-marks.js +6 -10
- package/dist/utils/value-as/value-as.d.ts +0 -28
- package/dist/utils/value-as/value-as.js +5 -10
- package/package.json +6 -6
package/dist/events/events.d.ts
CHANGED
|
@@ -130,11 +130,10 @@ export interface TourAskDetail {
|
|
|
130
130
|
* Composed and bubbling, because a stop is slotted into the root and the root
|
|
131
131
|
* has to hear it across that boundary.
|
|
132
132
|
*
|
|
133
|
-
* **A class rather than
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
* which is the trap #75 is about, in its purest form.
|
|
133
|
+
* **A class rather than a hand-rolled `CustomEvent`.** A dispatch is matched as
|
|
134
|
+
* `new HelixSomethingEvent(`, so a raw `CustomEvent` is not held to being
|
|
135
|
+
* declared and nothing carries it into the manifest: consumers can hear it and
|
|
136
|
+
* cannot find it.
|
|
138
137
|
*/
|
|
139
138
|
export declare class HelixTourAskEvent extends CustomEvent<TourAskDetail> {
|
|
140
139
|
static readonly eventName = "helix-tour-ask";
|
|
@@ -148,11 +147,9 @@ export declare class HelixTourAskEvent extends CustomEvent<TourAskDetail> {
|
|
|
148
147
|
* way for the sample and come back afterwards, and those are two moments with
|
|
149
148
|
* different work in each.
|
|
150
149
|
*
|
|
151
|
-
* **A class rather than
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
* public API that a consumer could hear and could not find. The check reads
|
|
155
|
-
* `new Event(` now as well.
|
|
150
|
+
* **A class rather than a bare `Event`.** The check that holds an event to being
|
|
151
|
+
* declared reads `new Event(` as well as `new HelixSomethingEvent(`, so a
|
|
152
|
+
* hand-rolled one is public API a consumer can hear and cannot find.
|
|
156
153
|
*
|
|
157
154
|
* No detail, because there is nothing to say beyond that it happened.
|
|
158
155
|
*/
|
|
@@ -196,18 +193,10 @@ export declare class HelixDismissEvent extends CustomEvent<DismissDetail> {
|
|
|
196
193
|
* whose state is a boolean wants an event with a typed detail, not a `String()`
|
|
197
194
|
* call here.
|
|
198
195
|
*
|
|
199
|
-
* **There is no `property` field
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
* are told apart by the element rather than by a field, `composedPath()[0]`
|
|
204
|
-
* surviving the retarget that `event.target` does not.
|
|
205
|
-
*
|
|
206
|
-
* The one element that sent one verb for two facts was the sandbox root, whose
|
|
207
|
-
* split and whose panel both settled through `helix-before-resize`. They have a
|
|
208
|
-
* verb each now, `helix-before-split` and `helix-before-panel-resize`, which is
|
|
209
|
-
* 294's argument one level down: a name says what moved, and a field that repeats
|
|
210
|
-
* the name is eleven dispatch sites paying for one that needed it. See 306.
|
|
196
|
+
* **There is no `property` field.** Every verb in this file says by itself which
|
|
197
|
+
* property a request is about, and two families sharing a verb are told apart by
|
|
198
|
+
* the element rather than by a field: `composedPath()[0]` survives the retarget
|
|
199
|
+
* that `event.target` does not.
|
|
211
200
|
*/
|
|
212
201
|
export interface ChangeDetail {
|
|
213
202
|
/** The value after the change. */
|
|
@@ -216,35 +205,21 @@ export interface ChangeDetail {
|
|
|
216
205
|
/**
|
|
217
206
|
* A set is about to make a different child current, and can be refused.
|
|
218
207
|
*
|
|
219
|
-
* **
|
|
220
|
-
*
|
|
221
|
-
* platform
|
|
222
|
-
*
|
|
223
|
-
* `
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
* conclusion did not follow: that no *native* word fits is an argument against
|
|
235
|
-
* borrowing one, not an argument against having a notification at all.
|
|
236
|
-
*
|
|
237
|
-
* What the missing half cost is the thing 294 fixed for values and left here.
|
|
238
|
-
* A consumer who only wants to know which child is current now had one channel,
|
|
239
|
-
* and it fires *before* `apply`: `currentTarget.active` still holds the previous
|
|
240
|
-
* value inside the handler, and `detail.value` is a proposal another listener may
|
|
241
|
-
* refuse. Measured across the four families taking this mixin, nothing at all was
|
|
242
|
-
* announced afterwards. `Tabs` and `Tree` looked covered because `helix-select`
|
|
243
|
-
* bubbles up from a child, which fires when an item is *chosen* and not when
|
|
244
|
-
* `active` is assigned; `Steps` and `Video Playlist` had nothing.
|
|
245
|
-
*
|
|
246
|
-
* So the shape is the one `MixinControllerOpen` already has, a cancelable
|
|
247
|
-
* request and a plain notification after the state has moved. See #325.
|
|
208
|
+
* **Not a generic `helix-change`.** `Tabs` moving to another tab, `Tree` marking
|
|
209
|
+
* another row and `Steps` advancing are not a value changing, they are a set
|
|
210
|
+
* choosing, and the platform's word for a committed value would say the wrong
|
|
211
|
+
* thing. `active` names which child is current, so `activate` is the verb, and
|
|
212
|
+
* unlike `change` the platform has no claim on it.
|
|
213
|
+
*
|
|
214
|
+
* **This fires before the state moves.** Inside a handler `currentTarget.active`
|
|
215
|
+
* still holds the previous value, and `detail.value` is a proposal another
|
|
216
|
+
* listener may refuse, so a consumer who only wants to know which child is
|
|
217
|
+
* current listens for `helix-activate` instead. `helix-select` is not that
|
|
218
|
+
* notification either: it fires when an item is *chosen*, not when `active` is
|
|
219
|
+
* assigned.
|
|
220
|
+
*
|
|
221
|
+
* The shape is the one `MixinControllerOpen` already has, a cancelable request
|
|
222
|
+
* and a plain notification after the state has moved.
|
|
248
223
|
*/
|
|
249
224
|
export declare class HelixBeforeActivateEvent extends CustomEvent<ChangeDetail> {
|
|
250
225
|
static readonly eventName = "helix-before-activate";
|
|
@@ -264,8 +239,7 @@ export declare class HelixBeforeActivateEvent extends CustomEvent<ChangeDetail>
|
|
|
264
239
|
* **Prefixed, and it has to be.** `activate` unprefixed is not in any
|
|
265
240
|
* `*EventMap` in the DOM library, checked rather than assumed, but the prefix is
|
|
266
241
|
* what stops an event dispatched inside a shadow root and retargeted to the host
|
|
267
|
-
* being mistaken for something the host's own contents sent.
|
|
268
|
-
* argument `helix-select` and `helix-resize` are excused under.
|
|
242
|
+
* being mistaken for something the host's own contents sent.
|
|
269
243
|
*/
|
|
270
244
|
export declare class HelixActivateEvent extends CustomEvent<ChangeDetail> {
|
|
271
245
|
static readonly eventName = "helix-activate";
|
|
@@ -286,7 +260,7 @@ export declare class HelixBeforeResizeEvent extends CustomEvent<ChangeDetail> {
|
|
|
286
260
|
*
|
|
287
261
|
* Its own verb rather than a `helix-before-resize` carrying which divider moved:
|
|
288
262
|
* a sandbox has two, and they were told apart by a field on a detail every other
|
|
289
|
-
* request in this file also carries.
|
|
263
|
+
* request in this file also carries.
|
|
290
264
|
*/
|
|
291
265
|
export declare class HelixBeforeSplitEvent extends CustomEvent<ChangeDetail> {
|
|
292
266
|
static readonly eventName = "helix-before-split";
|
|
@@ -331,13 +305,9 @@ export declare class HelixBeforeEditEvent extends CustomEvent<ChangeDetail> {
|
|
|
331
305
|
* carries the detail because at the moment it fires the value is not on the
|
|
332
306
|
* element yet.
|
|
333
307
|
*
|
|
334
|
-
*
|
|
335
|
-
*
|
|
336
|
-
*
|
|
337
|
-
* "the reader is done" wired a request to `onhelix-change` and got one per
|
|
338
|
-
* character. Granularity is now what the platform already says it is, `input`
|
|
339
|
-
* against `change`, and `announcesInput` picks which native one fires rather
|
|
340
|
-
* than which name this carries. See 294.
|
|
308
|
+
* **`announcesInput` picks which native notification fires, not which name this
|
|
309
|
+
* carries.** Granularity is the platform's own distinction, `input` against
|
|
310
|
+
* `change`; the request is always this one event.
|
|
341
311
|
*/
|
|
342
312
|
export declare class HelixBeforeChangeEvent extends CustomEvent<ChangeDetail> {
|
|
343
313
|
static readonly eventName = "helix-before-change";
|
|
@@ -346,22 +316,20 @@ export declare class HelixBeforeChangeEvent extends CustomEvent<ChangeDetail> {
|
|
|
346
316
|
/**
|
|
347
317
|
* A checked state is about to change, and the change can be refused.
|
|
348
318
|
*
|
|
349
|
-
* **Its own event rather than a `helix-before-change` carrying a boolean
|
|
350
|
-
* the
|
|
351
|
-
*
|
|
352
|
-
*
|
|
353
|
-
*
|
|
354
|
-
* have passed on that bug. A control whose state is a boolean wants an event
|
|
355
|
-
* with a typed boolean in it.
|
|
319
|
+
* **Its own event rather than a `helix-before-change` carrying a boolean.**
|
|
320
|
+
* Through the value event the state arrives as `String(checked)`, so a consumer
|
|
321
|
+
* receives the string `"false"`, which is truthy, and a test asserting the value
|
|
322
|
+
* passes on that bug. A control whose state is a boolean wants an event with a
|
|
323
|
+
* typed boolean in it.
|
|
356
324
|
*
|
|
357
325
|
* The notification is native, as it is for a value: the control relays `change`
|
|
358
326
|
* from the inner input and announces `input` beside it, so `onChange` reads
|
|
359
327
|
* `currentTarget.checked` and gets a boolean from the platform.
|
|
360
328
|
*
|
|
361
|
-
* It also ends a collision
|
|
362
|
-
* dispatched its own under the same name from the same host, so it
|
|
363
|
-
* `stopImmediatePropagation` to keep a consumer from receiving one box's
|
|
364
|
-
*
|
|
329
|
+
* It also ends a collision: Checkbox Group listened for its boxes' change and
|
|
330
|
+
* dispatched its own under the same name from the same host, so it needed
|
|
331
|
+
* `stopImmediatePropagation` to keep a consumer from receiving one box's boolean
|
|
332
|
+
* alongside the whole set. Two names, two facts.
|
|
365
333
|
*/
|
|
366
334
|
export declare class HelixBeforeToggleEvent extends CustomEvent<ToggleDetail> {
|
|
367
335
|
static readonly eventName = "helix-before-toggle";
|
|
@@ -464,15 +432,14 @@ export declare class HelixResizeEvent extends CustomEvent<ResizeDetail> {
|
|
|
464
432
|
* Fired when a header crosses the threshold between resting at the top of the
|
|
465
433
|
* page and floating over it.
|
|
466
434
|
*
|
|
467
|
-
* **
|
|
468
|
-
*
|
|
469
|
-
*
|
|
470
|
-
*
|
|
471
|
-
*
|
|
472
|
-
* state, which is deliberately not in the DOM and therefore not something a
|
|
435
|
+
* **The threshold lives in a custom state, and is announced rather than
|
|
436
|
+
* reflected.** A `data-scrolled` on the host is an attribute nobody rendered: a
|
|
437
|
+
* server sends the element without it and the element adds it on upgrade, so a
|
|
438
|
+
* framework hydrating the page finds markup that no longer matches what it sent.
|
|
439
|
+
* A custom state is deliberately not in the DOM and therefore not something a
|
|
473
440
|
* hydration pass can disagree with.
|
|
474
441
|
*
|
|
475
|
-
* That closes the observability
|
|
442
|
+
* That closes the observability an attribute would accidentally provide. A
|
|
476
443
|
* `MutationObserver` can watch an attribute and there is no equivalent for
|
|
477
444
|
* `ElementInternals.states`, so a component holding a boolean nothing can read
|
|
478
445
|
* is a component with a private opinion its consumers demonstrably need: the
|
|
@@ -611,8 +578,8 @@ export declare class HelixReadEvent extends CustomEvent<ReadDetail> {
|
|
|
611
578
|
*
|
|
612
579
|
* Cancelable, and refusing it leaves the order alone, which is what makes a
|
|
613
580
|
* server-side sort expressible: the consumer refuses the local reorder, fetches,
|
|
614
|
-
* and hands back a new set.
|
|
615
|
-
*
|
|
581
|
+
* and hands back a new set. This is the element reporting that a heading was
|
|
582
|
+
* clicked, before it acts on it.
|
|
616
583
|
*
|
|
617
584
|
* Not `helix-change`: nothing about the data changed, only the order it is read
|
|
618
585
|
* in, and a consumer listening for changes to a value should not hear a sort.
|
|
@@ -669,18 +636,13 @@ export declare class HelixSelectEvent extends CustomEvent<SelectDetail> {
|
|
|
669
636
|
/**
|
|
670
637
|
* Every event this file publishes, and the one place a new one is added.
|
|
671
638
|
*
|
|
672
|
-
* The map below is derived from this rather than written beside it
|
|
673
|
-
*
|
|
674
|
-
*
|
|
675
|
-
*
|
|
676
|
-
*
|
|
677
|
-
*
|
|
678
|
-
*
|
|
679
|
-
*
|
|
680
|
-
* Derived, a class that is in here is typed and a class that is not is absent
|
|
681
|
-
* from both halves at once, so the two cannot disagree. `check:events` fails
|
|
682
|
-
* the build on an exported event class left out of this object, which is the
|
|
683
|
-
* only step left that can be forgotten.
|
|
639
|
+
* The map below is derived from this rather than written beside it, so a class
|
|
640
|
+
* that is in here is typed and one that is not is absent from both halves at
|
|
641
|
+
* once. Kept by hand the two drifted, and nothing failed when they did: a
|
|
642
|
+
* consumer writing `addEventListener('helix-navigate', …)` got `Event` and had
|
|
643
|
+
* to reach into `detail` through a cast. The build fails on an exported event
|
|
644
|
+
* class left out of this object, which is the only step left that can be
|
|
645
|
+
* forgotten.
|
|
684
646
|
*/
|
|
685
647
|
declare const registry: {
|
|
686
648
|
readonly HelixActivateEvent: typeof HelixActivateEvent;
|
package/dist/events/events.js
CHANGED
|
@@ -94,35 +94,29 @@ export class HelixPreviousEvent extends CustomEvent {
|
|
|
94
94
|
* Composed and bubbling, because a stop is slotted into the root and the root
|
|
95
95
|
* has to hear it across that boundary.
|
|
96
96
|
*
|
|
97
|
-
* **A class rather than
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
* which is the trap #75 is about, in its purest form.
|
|
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.
|
|
102
101
|
*/
|
|
103
102
|
export class HelixTourAskEvent extends CustomEvent {
|
|
104
103
|
static { this.eventName = 'helix-tour-ask'; }
|
|
105
104
|
constructor(detail) {
|
|
106
105
|
super(HelixTourAskEvent.eventName, {
|
|
107
106
|
bubbles: true,
|
|
108
|
-
/* Not cancelable
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
target and the root's runs first: it would read `defaultPrevented`
|
|
116
|
-
before the consumer had a chance to set it. `helix-shortcut` gets this
|
|
117
|
-
right by reading the flag on the element that dispatched, where every
|
|
118
|
-
listener has already run.
|
|
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.
|
|
119
114
|
|
|
120
|
-
**The veto exists and is elsewhere
|
|
121
|
-
downgrade rather than a gap. Moving between stops goes through
|
|
115
|
+
**The veto exists and is elsewhere.** Moving between stops goes through
|
|
122
116
|
`requestChange` and announces `helix-before-activate`; leaving early
|
|
123
117
|
dispatches `helix-before-close` and reads the flag before writing
|
|
124
|
-
`open`.
|
|
125
|
-
|
|
118
|
+
`open`. This event is the stop telling the root a button was pressed,
|
|
119
|
+
and the decision is taken one step later. */
|
|
126
120
|
cancelable: false,
|
|
127
121
|
composed: true,
|
|
128
122
|
detail,
|
|
@@ -137,11 +131,9 @@ export class HelixTourAskEvent extends CustomEvent {
|
|
|
137
131
|
* way for the sample and come back afterwards, and those are two moments with
|
|
138
132
|
* different work in each.
|
|
139
133
|
*
|
|
140
|
-
* **A class rather than
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
* public API that a consumer could hear and could not find. The check reads
|
|
144
|
-
* `new Event(` now as well.
|
|
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.
|
|
145
137
|
*
|
|
146
138
|
* No detail, because there is nothing to say beyond that it happened.
|
|
147
139
|
*/
|
|
@@ -183,35 +175,21 @@ export class HelixDismissEvent extends CustomEvent {
|
|
|
183
175
|
/**
|
|
184
176
|
* A set is about to make a different child current, and can be refused.
|
|
185
177
|
*
|
|
186
|
-
* **
|
|
187
|
-
*
|
|
188
|
-
* platform
|
|
189
|
-
*
|
|
190
|
-
* `
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
* conclusion did not follow: that no *native* word fits is an argument against
|
|
202
|
-
* borrowing one, not an argument against having a notification at all.
|
|
203
|
-
*
|
|
204
|
-
* What the missing half cost is the thing 294 fixed for values and left here.
|
|
205
|
-
* A consumer who only wants to know which child is current now had one channel,
|
|
206
|
-
* and it fires *before* `apply`: `currentTarget.active` still holds the previous
|
|
207
|
-
* value inside the handler, and `detail.value` is a proposal another listener may
|
|
208
|
-
* refuse. Measured across the four families taking this mixin, nothing at all was
|
|
209
|
-
* announced afterwards. `Tabs` and `Tree` looked covered because `helix-select`
|
|
210
|
-
* bubbles up from a child, which fires when an item is *chosen* and not when
|
|
211
|
-
* `active` is assigned; `Steps` and `Video Playlist` had nothing.
|
|
212
|
-
*
|
|
213
|
-
* So the shape is the one `MixinControllerOpen` already has, a cancelable
|
|
214
|
-
* request and a plain notification after the state has moved. See #325.
|
|
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.
|
|
215
193
|
*/
|
|
216
194
|
export class HelixBeforeActivateEvent extends CustomEvent {
|
|
217
195
|
static { this.eventName = 'helix-before-activate'; }
|
|
@@ -238,8 +216,7 @@ export class HelixBeforeActivateEvent extends CustomEvent {
|
|
|
238
216
|
* **Prefixed, and it has to be.** `activate` unprefixed is not in any
|
|
239
217
|
* `*EventMap` in the DOM library, checked rather than assumed, but the prefix is
|
|
240
218
|
* what stops an event dispatched inside a shadow root and retargeted to the host
|
|
241
|
-
* being mistaken for something the host's own contents sent.
|
|
242
|
-
* argument `helix-select` and `helix-resize` are excused under.
|
|
219
|
+
* being mistaken for something the host's own contents sent.
|
|
243
220
|
*/
|
|
244
221
|
export class HelixActivateEvent extends CustomEvent {
|
|
245
222
|
static { this.eventName = 'helix-activate'; }
|
|
@@ -281,7 +258,7 @@ export class HelixBeforeResizeEvent extends CustomEvent {
|
|
|
281
258
|
*
|
|
282
259
|
* Its own verb rather than a `helix-before-resize` carrying which divider moved:
|
|
283
260
|
* a sandbox has two, and they were told apart by a field on a detail every other
|
|
284
|
-
* request in this file also carries.
|
|
261
|
+
* request in this file also carries.
|
|
285
262
|
*/
|
|
286
263
|
export class HelixBeforeSplitEvent extends CustomEvent {
|
|
287
264
|
static { this.eventName = 'helix-before-split'; }
|
|
@@ -354,13 +331,9 @@ export class HelixBeforeEditEvent extends CustomEvent {
|
|
|
354
331
|
* carries the detail because at the moment it fires the value is not on the
|
|
355
332
|
* element yet.
|
|
356
333
|
*
|
|
357
|
-
*
|
|
358
|
-
*
|
|
359
|
-
*
|
|
360
|
-
* "the reader is done" wired a request to `onhelix-change` and got one per
|
|
361
|
-
* character. Granularity is now what the platform already says it is, `input`
|
|
362
|
-
* against `change`, and `announcesInput` picks which native one fires rather
|
|
363
|
-
* than which name this carries. See 294.
|
|
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.
|
|
364
337
|
*/
|
|
365
338
|
export class HelixBeforeChangeEvent extends CustomEvent {
|
|
366
339
|
static { this.eventName = 'helix-before-change'; }
|
|
@@ -376,22 +349,20 @@ export class HelixBeforeChangeEvent extends CustomEvent {
|
|
|
376
349
|
/**
|
|
377
350
|
* A checked state is about to change, and the change can be refused.
|
|
378
351
|
*
|
|
379
|
-
* **Its own event rather than a `helix-before-change` carrying a boolean
|
|
380
|
-
* the
|
|
381
|
-
*
|
|
382
|
-
*
|
|
383
|
-
*
|
|
384
|
-
* have passed on that bug. A control whose state is a boolean wants an event
|
|
385
|
-
* with a typed boolean in it.
|
|
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.
|
|
386
357
|
*
|
|
387
358
|
* The notification is native, as it is for a value: the control relays `change`
|
|
388
359
|
* from the inner input and announces `input` beside it, so `onChange` reads
|
|
389
360
|
* `currentTarget.checked` and gets a boolean from the platform.
|
|
390
361
|
*
|
|
391
|
-
* It also ends a collision
|
|
392
|
-
* dispatched its own under the same name from the same host, so it
|
|
393
|
-
* `stopImmediatePropagation` to keep a consumer from receiving one box's
|
|
394
|
-
*
|
|
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.
|
|
395
366
|
*/
|
|
396
367
|
export class HelixBeforeToggleEvent extends CustomEvent {
|
|
397
368
|
static { this.eventName = 'helix-before-toggle'; }
|
|
@@ -459,9 +430,8 @@ export class HelixConsoleEvent extends CustomEvent {
|
|
|
459
430
|
super(HelixConsoleEvent.eventName, {
|
|
460
431
|
bubbles: true,
|
|
461
432
|
/* Not cancelable, for the reason `helix-resize` is not: a log line the
|
|
462
|
-
frame already wrote is a fact being relayed
|
|
463
|
-
|
|
464
|
-
read the result. */
|
|
433
|
+
frame already wrote is a fact being relayed rather than a proposal, and
|
|
434
|
+
nothing reads the result. */
|
|
465
435
|
cancelable: false,
|
|
466
436
|
composed: true,
|
|
467
437
|
detail,
|
|
@@ -487,12 +457,11 @@ export class HelixResizeEvent extends CustomEvent {
|
|
|
487
457
|
constructor(detail) {
|
|
488
458
|
super(HelixResizeEvent.eventName, {
|
|
489
459
|
bubbles: true,
|
|
490
|
-
/* Not cancelable
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
they had stopped something. */
|
|
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. */
|
|
496
465
|
cancelable: false,
|
|
497
466
|
composed: true,
|
|
498
467
|
detail,
|
|
@@ -503,15 +472,14 @@ export class HelixResizeEvent extends CustomEvent {
|
|
|
503
472
|
* Fired when a header crosses the threshold between resting at the top of the
|
|
504
473
|
* page and floating over it.
|
|
505
474
|
*
|
|
506
|
-
* **
|
|
507
|
-
*
|
|
508
|
-
*
|
|
509
|
-
*
|
|
510
|
-
*
|
|
511
|
-
* state, which is deliberately not in the DOM and therefore not something a
|
|
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
|
|
512
480
|
* hydration pass can disagree with.
|
|
513
481
|
*
|
|
514
|
-
* That closes the observability
|
|
482
|
+
* That closes the observability an attribute would accidentally provide. A
|
|
515
483
|
* `MutationObserver` can watch an attribute and there is no equivalent for
|
|
516
484
|
* `ElementInternals.states`, so a component holding a boolean nothing can read
|
|
517
485
|
* is a component with a private opinion its consumers demonstrably need: the
|
|
@@ -666,8 +634,8 @@ export class HelixReadEvent extends CustomEvent {
|
|
|
666
634
|
*
|
|
667
635
|
* Cancelable, and refusing it leaves the order alone, which is what makes a
|
|
668
636
|
* server-side sort expressible: the consumer refuses the local reorder, fetches,
|
|
669
|
-
* and hands back a new set.
|
|
670
|
-
*
|
|
637
|
+
* and hands back a new set. This is the element reporting that a heading was
|
|
638
|
+
* clicked, before it acts on it.
|
|
671
639
|
*
|
|
672
640
|
* Not `helix-change`: nothing about the data changed, only the order it is read
|
|
673
641
|
* in, and a consumer listening for changes to a value should not hear a sort.
|
|
@@ -742,18 +710,13 @@ export class HelixSelectEvent extends CustomEvent {
|
|
|
742
710
|
/**
|
|
743
711
|
* Every event this file publishes, and the one place a new one is added.
|
|
744
712
|
*
|
|
745
|
-
* The map below is derived from this rather than written beside it
|
|
746
|
-
*
|
|
747
|
-
*
|
|
748
|
-
*
|
|
749
|
-
*
|
|
750
|
-
*
|
|
751
|
-
*
|
|
752
|
-
*
|
|
753
|
-
* Derived, a class that is in here is typed and a class that is not is absent
|
|
754
|
-
* from both halves at once, so the two cannot disagree. `check:events` fails
|
|
755
|
-
* the build on an exported event class left out of this object, which is the
|
|
756
|
-
* only step left that can be forgotten.
|
|
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.
|
|
757
720
|
*/
|
|
758
721
|
const registry = {
|
|
759
722
|
HelixActivateEvent,
|
|
@@ -26,13 +26,11 @@ export declare class HelixElement extends LitElement {
|
|
|
26
26
|
* `helix-pagination-size` composes `helix-select`. One template says
|
|
27
27
|
* `${this.tag('select')}` and each tier answers with its own name.
|
|
28
28
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* tier to test it against. Thirty-nine specs had to be moved back to
|
|
35
|
-
* `helix/styled` for exactly that reason.
|
|
29
|
+
* **The public tag may not be the composed one, in either tier.** Using it
|
|
30
|
+
* costs three things: the name means two different things depending on what a
|
|
31
|
+
* consumer imported, the headless tier composes an element it does not ship,
|
|
32
|
+
* and the composition cannot be tested there at all, because there is no
|
|
33
|
+
* `helix-select` on that tier to test it against.
|
|
36
34
|
*
|
|
37
35
|
* **A prefix rather than an override per composition**, which was the first
|
|
38
36
|
* plan and does not compile. An override re-renders the fragment from the
|
|
@@ -76,25 +74,27 @@ export declare class HelixElement extends LitElement {
|
|
|
76
74
|
* fact to a stylesheet through `:state()` and leaves the markup alone, so the
|
|
77
75
|
* server's output and the client's agree by construction.
|
|
78
76
|
*
|
|
79
|
-
* `SETTLED` carries the long version of that argument
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
* showcase: a `default-checked` switch, a `default-checked` checkbox and a
|
|
83
|
-
* `default-open` accordion item, each writing its own resolved state onto
|
|
84
|
-
* itself before React reached the node.
|
|
77
|
+
* `SETTLED` carries the long version of that argument; `checked`, `open`,
|
|
78
|
+
* `invalid` and `has-label` are recorded the same way, each of them a state a
|
|
79
|
+
* `default-*` attribute resolves before React reaches the node.
|
|
85
80
|
*
|
|
86
|
-
* **
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
* fact is kept somewhere React reconciles.
|
|
81
|
+
* **Deferring the definitions is not a fix and could not be.** Importing them
|
|
82
|
+
* from an effect so the upgrades fall the other side of hydration works only
|
|
83
|
+
* while hydration is one pass: anything that splits it, a streamed segment or
|
|
84
|
+
* a suspended boundary, puts an upgrade back inside the window. Timing cannot
|
|
85
|
+
* be the guarantee when the fact is kept somewhere React reconciles.
|
|
92
86
|
*
|
|
93
87
|
* Feature-tested rather than assumed, the way `hostAria` tests element
|
|
94
88
|
* references. An engine without `CustomStateSet` records nothing and keeps
|
|
95
|
-
* whatever the resting rule draws, which is the safe direction to fail
|
|
96
|
-
*
|
|
97
|
-
*
|
|
89
|
+
* whatever the resting rule draws, which is the safe direction to fail.
|
|
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
|
|
97
|
+
* fails to render rather than rendering without whatever the state draws.
|
|
98
98
|
*/
|
|
99
99
|
protected toggleState(name: string, on: boolean): void;
|
|
100
100
|
/**
|
|
@@ -116,8 +116,7 @@ export declare class HelixElement extends LitElement {
|
|
|
116
116
|
*
|
|
117
117
|
* Separate from `updateComplete`, which resolves in the microtask checkpoint
|
|
118
118
|
* the suppression is still active in. That is the distinction `readyToMove`
|
|
119
|
-
* in `@fusion.dev/helix-testing`
|
|
120
|
-
* were misread as a token fault for days.
|
|
119
|
+
* in `@fusion.dev/helix-testing` is written around.
|
|
121
120
|
*
|
|
122
121
|
* It never resolves where `requestAnimationFrame` never fires, which is a
|
|
123
122
|
* server, a hidden tab, and happy-dom. Callers that must not hang race it
|
|
@@ -193,9 +192,9 @@ export declare class HelixElement extends LitElement {
|
|
|
193
192
|
* suppressing transitions.
|
|
194
193
|
*
|
|
195
194
|
* A frame later, not now: see `SETTLED` for why `firstUpdated` itself is too
|
|
196
|
-
* early. SSR never calls this, which is correct, because the
|
|
197
|
-
*
|
|
198
|
-
*
|
|
195
|
+
* early. SSR never calls this, which is correct, because the state describes
|
|
196
|
+
* something that happened in a browser and the server has no frame to wait
|
|
197
|
+
* for.
|
|
199
198
|
*/
|
|
200
199
|
protected firstUpdated(changed: PropertyValues): void;
|
|
201
200
|
}
|