@fusion.dev/helix-core 0.142.0 → 0.143.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 (47) hide show
  1. package/custom-elements.json +1475 -54
  2. package/dist/controllers/aria-forward-controller/aria-forward-controller.d.ts +55 -0
  3. package/dist/controllers/aria-forward-controller/aria-forward-controller.js +72 -16
  4. package/dist/controllers/arrival-controller/arrival-controller.d.ts +12 -0
  5. package/dist/controllers/arrival-controller/arrival-controller.js +10 -0
  6. package/dist/controllers/chart-pointer-controller/chart-pointer-controller.d.ts +10 -0
  7. package/dist/controllers/chart-pointer-controller/chart-pointer-controller.js +5 -1
  8. package/dist/controllers/copy-controller/copy-controller.js +5 -0
  9. package/dist/controllers/dismiss-controller/dismiss-controller.js +40 -3
  10. package/dist/controllers/keyboard-navigation-controller/keyboard-navigation-controller.d.ts +79 -1
  11. package/dist/controllers/keyboard-navigation-controller/keyboard-navigation-controller.js +80 -10
  12. package/dist/controllers/popover-controller/popover-controller.d.ts +11 -0
  13. package/dist/controllers/popover-controller/popover-controller.js +6 -0
  14. package/dist/controllers/source-controller/source-controller.d.ts +22 -0
  15. package/dist/controllers/source-controller/source-controller.js +27 -1
  16. package/dist/controllers/virtualize-controller/virtualize-controller.d.ts +16 -0
  17. package/dist/controllers/virtualize-controller/virtualize-controller.js +24 -2
  18. package/dist/events/events.d.ts +102 -4
  19. package/dist/events/events.js +84 -0
  20. package/dist/helix-element/react-bridge.js +6 -4
  21. package/dist/helix-form-element/helix-form-element.d.ts +131 -2
  22. package/dist/helix-form-element/helix-form-element.js +216 -6
  23. package/dist/index.d.ts +4 -3
  24. package/dist/index.js +4 -3
  25. package/dist/mixins/mixin-chart-source/mixin-chart-source.d.ts +8 -0
  26. package/dist/mixins/mixin-chart-source/mixin-chart-source.js +4 -0
  27. package/dist/mixins/mixin-collection/mixin-collection.d.ts +4 -2
  28. package/dist/mixins/mixin-collection/mixin-collection.js +8 -6
  29. package/dist/mixins/mixin-controller-open/mixin-controller-open.js +19 -3
  30. package/dist/mixins/mixin-dismissible/mixin-dismissible.js +39 -0
  31. package/dist/mixins/mixin-field/mixin-field.js +38 -8
  32. package/dist/mixins/mixin-picker-editing/mixin-picker-editing.d.ts +8 -3
  33. package/dist/mixins/mixin-picker-editing/mixin-picker-editing.js +6 -0
  34. package/dist/mixins/mixin-picker-field/mixin-picker-field.d.ts +27 -4
  35. package/dist/mixins/mixin-picker-field/mixin-picker-field.js +83 -1
  36. package/dist/utils/draw-tooltip/draw-tooltip.d.ts +3 -0
  37. package/dist/utils/draw-tooltip/draw-tooltip.js +5 -0
  38. package/dist/utils/read-series/read-series.d.ts +28 -0
  39. package/dist/utils/read-series/read-series.js +31 -4
  40. package/dist/utils/report-runtime/report-runtime.d.ts +10 -0
  41. package/dist/utils/scroll-lock/scroll-lock.d.ts +16 -0
  42. package/dist/utils/scroll-lock/scroll-lock.js +30 -0
  43. package/dist/utils/written-list/written-list.d.ts +11 -2
  44. package/dist/utils/written-list/written-list.js +3 -1
  45. package/dist/version.d.ts +1 -1
  46. package/dist/version.js +1 -1
  47. package/package.json +4 -4
@@ -26,10 +26,24 @@ export interface SourceHost extends ReactiveControllerHost, HTMLElement {
26
26
  * The element is watched for `childList` and `characterData` alike, because
27
27
  * renaming a series edits a text node in place rather than replacing a cell,
28
28
  * and nothing in a page has reason to know a chart is reading it.
29
+ *
30
+ * **The tree around it is watched as well, for the table that is not there
31
+ * yet.** A framework page renders a chart first and its table once the data
32
+ * loads, or re-keys the table and so replaces it under the same id. Watching
33
+ * only the element resolved on connect found nothing in the first case and
34
+ * kept a detached table in the second, and the chart drew neither until some
35
+ * unrelated property changed. So the root the id resolves in is watched for
36
+ * nodes arriving and leaving and for `id` and `role` changing, and each batch
37
+ * asks the id again. That is one lookup by id per batch, and a chart redraws
38
+ * only when the answer is a different element.
29
39
  */
30
40
  export declare class SourceController implements ReactiveController {
31
41
  private host;
32
42
  private observer;
43
+ /** Watches the tree `for` resolves in, for the table arriving, leaving or being replaced. */
44
+ private tree;
45
+ /** The element the watcher is on, or null where `for` named nothing. */
46
+ private watched;
33
47
  /** Whether a hydrating render was told there was nothing, and needs the render after. */
34
48
  private deferred;
35
49
  /**
@@ -96,4 +110,12 @@ export declare class SourceController implements ReactiveController {
96
110
  * there is no `MutationObserver`, which is the server.
97
111
  */
98
112
  watch(): void;
113
+ /**
114
+ * Watches the root `for` resolves in, so a table that arrives, leaves or is
115
+ * replaced under the same id is followed.
116
+ *
117
+ * Only while `for` names something and the host sits in a tree that can
118
+ * resolve an id, which a detached host and a server render do not.
119
+ */
120
+ private watchTree;
99
121
  }
@@ -2,6 +2,7 @@ import { elementById } from '../../utils/element-by-id/element-by-id.js';
2
2
  import { readRows, readSeries } from '../../utils/read-series/read-series.js';
3
3
  export class SourceController {
4
4
  constructor(host) {
5
+ this.watched = null;
5
6
  this.deferred = false;
6
7
  this.version = 0;
7
8
  this.host = host;
@@ -58,12 +59,20 @@ export class SourceController {
58
59
  hostDisconnected() {
59
60
  this.observer?.disconnect();
60
61
  this.observer = undefined;
62
+ this.tree?.disconnect();
63
+ this.tree = undefined;
61
64
  }
62
65
  watch() {
63
66
  this.observer?.disconnect();
67
+ this.tree?.disconnect();
64
68
  this.version += 1;
65
69
  const element = this.resolve();
66
- if (!element || typeof MutationObserver === 'undefined') {
70
+ this.watched = element;
71
+ if (typeof MutationObserver === 'undefined') {
72
+ return;
73
+ }
74
+ this.watchTree();
75
+ if (!element) {
67
76
  return;
68
77
  }
69
78
  this.observer ??= new MutationObserver(() => {
@@ -76,4 +85,21 @@ export class SourceController {
76
85
  subtree: true,
77
86
  });
78
87
  }
88
+ watchTree() {
89
+ const root = this.host.getRootNode();
90
+ if (this.host.for === '' || typeof root.getElementById !== 'function') {
91
+ return;
92
+ }
93
+ this.tree ??= new MutationObserver(() => {
94
+ if (this.resolve() !== this.watched) {
95
+ this.watch();
96
+ this.host.requestUpdate();
97
+ }
98
+ });
99
+ this.tree.observe(root, {
100
+ attributeFilter: ['id', 'role'],
101
+ childList: true,
102
+ subtree: true,
103
+ });
104
+ }
79
105
  }
@@ -198,6 +198,22 @@ export declare class VirtualizeController implements ReactiveController {
198
198
  * Call it from `willUpdate`, before the render that draws the grown set.
199
199
  */
200
200
  shift(by: number): void;
201
+ /**
202
+ * How tall item `index` is: what was measured, or the estimate.
203
+ *
204
+ * For a host that draws an item outside the window, the row holding focus
205
+ * say, and has to take that item's room out of a spacer.
206
+ */
207
+ sizeOf(index: number): number;
208
+ /**
209
+ * Scrolls the box the least distance that shows item `index` whole.
210
+ *
211
+ * For a host moving focus to an item outside the window, whose own element
212
+ * cannot be scrolled to because it is not drawn where it belongs. `inset` is
213
+ * how far into the box the items start, for a heading that sticks at its
214
+ * top and covers that much of every item scrolled under it.
215
+ */
216
+ reveal(index: number, inset?: number): void;
201
217
  /**
202
218
  * Drops every measurement, for a host that swapped its data.
203
219
  *
@@ -74,7 +74,7 @@ export class VirtualizeController {
74
74
  this.host.requestUpdate();
75
75
  }
76
76
  uniform(box, total, size, overscan) {
77
- const first = Math.max(0, Math.floor(box.scrollTop / size) - overscan);
77
+ const first = Math.max(0, Math.min(Math.floor(box.scrollTop / size), total) - overscan);
78
78
  const fits = Math.ceil(box.clientHeight / size) + overscan * 2;
79
79
  const last = Math.min(total, first + fits);
80
80
  return { after: Math.max(0, (total - last) * size), before: first * size, first, last };
@@ -146,6 +146,26 @@ export class VirtualizeController {
146
146
  };
147
147
  this.owed += room;
148
148
  }
149
+ sizeOf(index) {
150
+ return this.measuring() ? this.heights.at(index) : Math.max(1, this.options.estimate());
151
+ }
152
+ reveal(index, inset = 0) {
153
+ const box = this.options.container();
154
+ if (!box) {
155
+ return;
156
+ }
157
+ const total = Math.max(0, this.options.count());
158
+ const top = this.measuring()
159
+ ? this.heights.before(index, total)
160
+ : index * Math.max(1, this.options.estimate());
161
+ const bottom = top + this.sizeOf(index) + inset;
162
+ if (top < box.scrollTop) {
163
+ box.scrollTop = top;
164
+ }
165
+ else if (bottom > box.scrollTop + box.clientHeight) {
166
+ box.scrollTop = bottom - box.clientHeight;
167
+ }
168
+ }
149
169
  forget() {
150
170
  this.heights.forget();
151
171
  }
@@ -161,7 +181,9 @@ export class VirtualizeController {
161
181
  'the last one. That happens when the scrolling box has no height of its own: its ' +
162
182
  '`clientHeight` is then a function of the rows just drawn, so measuring moves what is ' +
163
183
  'being measured and the two never agree. Give the container a block size and an ' +
164
- 'overflow, which is what the styled tier does and what a headless consumer has to.',
184
+ 'overflow, which is what the styled tier does and what a headless consumer has to. ' +
185
+ 'It also happens when the rows report no height, such as a row drawn with ' +
186
+ '`display: contents`, which is a fault in the component that draws them.',
165
187
  tag: typeof host.localName === 'string' ? host.localName : undefined,
166
188
  });
167
189
  }
@@ -319,6 +319,13 @@ export type MapPanDetail = ViewportPanDetail;
319
319
  export type MapZoomDetail = ViewportZoomDetail;
320
320
  /** Detail carried by `helix-navigate`. */
321
321
  export interface NavigateDetail {
322
+ /**
323
+ * The page asked for, as a number, where the component pages by number.
324
+ *
325
+ * Beside `value` rather than in place of it, because a calendar pages by
326
+ * month and its `value` is a month.
327
+ */
328
+ page?: number;
322
329
  /** Where the view is moving to, in whatever the component pages by. */
323
330
  value: string;
324
331
  }
@@ -368,7 +375,7 @@ export interface FacetDetail {
368
375
  export interface ReadDetail {
369
376
  /**
370
377
  * The state being asked for, as a boolean rather than a word that reads like
371
- * one, which is `helix-toggle`'s rule and for the same reason: `"false"` is
378
+ * one, which is `helix-before-toggle`'s rule and for the same reason: `"false"` is
372
379
  * truthy and a consumer who forgets that marks everything read.
373
380
  */
374
381
  read: boolean;
@@ -472,7 +479,7 @@ export declare class HelixDismissEvent extends CustomEvent<DismissDetail> {
472
479
  *
473
480
  * A boolean is the case where it *is* lost, because `"false"` is truthy, so a
474
481
  * consumer who forgets to compare against the word gets the opposite answer and
475
- * no error. That is why checkedness has `helix-toggle` and its own boolean, and
482
+ * no error. That is why checkedness has `helix-before-toggle` and its own boolean, and
476
483
  * it is the line to hold: **stringify a value, never a fact.** A new control
477
484
  * whose state is a boolean wants an event with a typed detail, not a `String()`
478
485
  * call here.
@@ -750,11 +757,37 @@ export declare class HelixBeforePinEvent extends CustomEvent<ChangeDetail> {
750
757
  static readonly eventName = "helix-before-pin";
751
758
  constructor(detail: ChangeDetail);
752
759
  }
760
+ /**
761
+ * A transcript was pinned to the bottom, or let go of it.
762
+ *
763
+ * The notification half of `helix-before-pin`, sent once `pinned` has moved,
764
+ * so `currentTarget.pinned` is the new state and `detail.value` says it as
765
+ * `true` or `false`. Not cancelable: the decision was the request's.
766
+ */
767
+ export declare class HelixPinEvent extends CustomEvent<ChangeDetail> {
768
+ static readonly eventName = "helix-pin";
769
+ constructor(detail: ChangeDetail);
770
+ }
753
771
  /** A divider is about to move, and can be refused. */
754
772
  export declare class HelixBeforeResizeEvent extends CustomEvent<ChangeDetail> {
755
773
  static readonly eventName = "helix-before-resize";
756
774
  constructor(detail: ChangeDetail);
757
775
  }
776
+ /**
777
+ * A divider settled somewhere new.
778
+ *
779
+ * The notification half of `helix-before-resize`, sent once `position` has
780
+ * moved, with the new position. Not cancelable: the decision was the
781
+ * request's.
782
+ *
783
+ * **Past tense, because `helix-resize` was already taken** by a measurement,
784
+ * the height a sandboxed preview reports for what it drew, and one name cannot
785
+ * carry both.
786
+ */
787
+ export declare class HelixResizedEvent extends CustomEvent<ChangeDetail> {
788
+ static readonly eventName = "helix-resized";
789
+ constructor(detail: ChangeDetail);
790
+ }
758
791
  /**
759
792
  * The divider between a sandbox's panes is about to move, and can be refused.
760
793
  *
@@ -783,6 +816,17 @@ export declare class HelixBeforeCollapseEvent extends CustomEvent<ChangeDetail>
783
816
  static readonly eventName = "helix-before-collapse";
784
817
  constructor(detail: ChangeDetail);
785
818
  }
819
+ /**
820
+ * A pane shut or reopened.
821
+ *
822
+ * The notification half of `helix-before-collapse`, sent once `collapsed` has
823
+ * moved. `detail.value` is the side that is shut, or empty where both panes
824
+ * are open. Not cancelable: the decision was the request's.
825
+ */
826
+ export declare class HelixCollapseEvent extends CustomEvent<ChangeDetail> {
827
+ static readonly eventName = "helix-collapse";
828
+ constructor(detail: ChangeDetail);
829
+ }
786
830
  /** Source is about to be edited, and can be refused. */
787
831
  export declare class HelixBeforeEditEvent extends CustomEvent<ChangeDetail> {
788
832
  static readonly eventName = "helix-before-edit";
@@ -839,11 +883,11 @@ export declare class HelixBeforeToggleEvent extends CustomEvent<ToggleDetail> {
839
883
  export interface ScrolledDetail {
840
884
  /**
841
885
  * Whether the page is scrolled away from the top, as a boolean and not a word
842
- * that reads like one. Follows `helix-toggle`'s rule for the same reason.
886
+ * that reads like one. Follows `helix-before-toggle`'s rule for the same reason.
843
887
  */
844
888
  scrolled: boolean;
845
889
  }
846
- /** Detail carried by `helix-toggle`. */
890
+ /** Detail carried by `helix-before-toggle`. */
847
891
  export interface ToggleDetail {
848
892
  /** The state being asked for, as a boolean and not a word that reads like one. */
849
893
  checked: boolean;
@@ -1089,6 +1133,20 @@ export declare class HelixSortEvent extends CustomEvent<SortDetail> {
1089
1133
  static readonly eventName = "helix-sort";
1090
1134
  constructor(detail: SortDetail);
1091
1135
  }
1136
+ /**
1137
+ * The rows are in a different order.
1138
+ *
1139
+ * The notification after `helix-sort`, sent once `sort` has moved, with the
1140
+ * order now in force. Not cancelable: the decision was the request's.
1141
+ *
1142
+ * **Past tense, because the plain verb is the request.** `helix-sort` was
1143
+ * cancelable before the library had a word for its notification, and
1144
+ * consumers bind it by that name, so the notification takes the one after it.
1145
+ */
1146
+ export declare class HelixSortedEvent extends CustomEvent<SortDetail> {
1147
+ static readonly eventName = "helix-sorted";
1148
+ constructor(detail: SortDetail);
1149
+ }
1092
1150
  /**
1093
1151
  * Fired when the reader changes which values a field is filtered by.
1094
1152
  *
@@ -1116,6 +1174,17 @@ export declare class HelixFilterEvent extends CustomEvent<FilterDetail> {
1116
1174
  static readonly eventName = "helix-filter";
1117
1175
  constructor(detail: FilterDetail);
1118
1176
  }
1177
+ /**
1178
+ * A component is showing a narrower or a wider set.
1179
+ *
1180
+ * The notification after `helix-filter`, sent once the query has moved, with
1181
+ * the query now in force. Not cancelable, and past tense for the reason
1182
+ * `helix-sorted` is.
1183
+ */
1184
+ export declare class HelixFilteredEvent extends CustomEvent<FilterDetail> {
1185
+ static readonly eventName = "helix-filtered";
1186
+ constructor(detail: FilterDetail);
1187
+ }
1119
1188
  /** What a shortcut reports when its chord is pressed. */
1120
1189
  export interface ShortcutDetail {
1121
1190
  /**
@@ -1149,6 +1218,17 @@ export declare class HelixSelectEvent extends CustomEvent<SelectDetail> {
1149
1218
  static readonly eventName = "helix-select";
1150
1219
  constructor(detail: SelectDetail);
1151
1220
  }
1221
+ /**
1222
+ * A set holds a different selection.
1223
+ *
1224
+ * The notification after a `helix-select` that asked to change what is
1225
+ * selected, sent once the selection has moved, with the selection now in
1226
+ * force. Not cancelable, and past tense for the reason `helix-sorted` is.
1227
+ */
1228
+ export declare class HelixSelectedEvent extends CustomEvent<SelectDetail> {
1229
+ static readonly eventName = "helix-selected";
1230
+ constructor(detail: SelectDetail);
1231
+ }
1152
1232
  /**
1153
1233
  * Fired when the reader asks for the columns in a different order.
1154
1234
  *
@@ -1166,6 +1246,17 @@ export declare class HelixReorderEvent extends CustomEvent<ChangeDetail> {
1166
1246
  static readonly eventName = "helix-reorder";
1167
1247
  constructor(detail: ChangeDetail);
1168
1248
  }
1249
+ /**
1250
+ * The columns are in a different order.
1251
+ *
1252
+ * The notification after `helix-reorder`, sent once the order has moved, with
1253
+ * every field in the new one. Not cancelable, and past tense for the reason
1254
+ * `helix-sorted` is.
1255
+ */
1256
+ export declare class HelixReorderedEvent extends CustomEvent<ChangeDetail> {
1257
+ static readonly eventName = "helix-reordered";
1258
+ constructor(detail: ChangeDetail);
1259
+ }
1169
1260
  /**
1170
1261
  * Fired when a reader reaches the oldest turn a transcript holds, while there are
1171
1262
  * older ones to fetch.
@@ -1214,6 +1305,7 @@ declare const registry: {
1214
1305
  readonly HelixCanvasViewEvent: typeof HelixCanvasViewEvent;
1215
1306
  readonly HelixCanvasZoomEvent: typeof HelixCanvasZoomEvent;
1216
1307
  readonly HelixCaretEvent: typeof HelixCaretEvent;
1308
+ readonly HelixCollapseEvent: typeof HelixCollapseEvent;
1217
1309
  readonly HelixCompleteEvent: typeof HelixCompleteEvent;
1218
1310
  readonly HelixConnectEvent: typeof HelixConnectEvent;
1219
1311
  readonly HelixConsoleEvent: typeof HelixConsoleEvent;
@@ -1222,6 +1314,7 @@ declare const registry: {
1222
1314
  readonly HelixDismissEvent: typeof HelixDismissEvent;
1223
1315
  readonly HelixFacetEvent: typeof HelixFacetEvent;
1224
1316
  readonly HelixFilterEvent: typeof HelixFilterEvent;
1317
+ readonly HelixFilteredEvent: typeof HelixFilteredEvent;
1225
1318
  readonly HelixGraphFilterEvent: typeof HelixGraphFilterEvent;
1226
1319
  readonly HelixGraphLayoutEvent: typeof HelixGraphLayoutEvent;
1227
1320
  readonly HelixGraphPanEvent: typeof HelixGraphPanEvent;
@@ -1240,20 +1333,25 @@ declare const registry: {
1240
1333
  readonly HelixMoveEvent: typeof HelixMoveEvent;
1241
1334
  readonly HelixNavigateEvent: typeof HelixNavigateEvent;
1242
1335
  readonly HelixNextEvent: typeof HelixNextEvent;
1336
+ readonly HelixPinEvent: typeof HelixPinEvent;
1243
1337
  readonly HelixPreviousEvent: typeof HelixPreviousEvent;
1244
1338
  readonly HelixReadEvent: typeof HelixReadEvent;
1245
1339
  readonly HelixReconnectEvent: typeof HelixReconnectEvent;
1246
1340
  readonly HelixRelabelEvent: typeof HelixRelabelEvent;
1247
1341
  readonly HelixRemoveEvent: typeof HelixRemoveEvent;
1248
1342
  readonly HelixReorderEvent: typeof HelixReorderEvent;
1343
+ readonly HelixReorderedEvent: typeof HelixReorderedEvent;
1344
+ readonly HelixResizedEvent: typeof HelixResizedEvent;
1249
1345
  readonly HelixResizeEvent: typeof HelixResizeEvent;
1250
1346
  readonly HelixSampleEndEvent: typeof HelixSampleEndEvent;
1251
1347
  readonly HelixSampleStartEvent: typeof HelixSampleStartEvent;
1252
1348
  readonly HelixScrolledEvent: typeof HelixScrolledEvent;
1253
1349
  readonly HelixSelectEvent: typeof HelixSelectEvent;
1350
+ readonly HelixSelectedEvent: typeof HelixSelectedEvent;
1254
1351
  readonly HelixSendEvent: typeof HelixSendEvent;
1255
1352
  readonly HelixShortcutEvent: typeof HelixShortcutEvent;
1256
1353
  readonly HelixSortEvent: typeof HelixSortEvent;
1354
+ readonly HelixSortedEvent: typeof HelixSortedEvent;
1257
1355
  readonly HelixTourAskEvent: typeof HelixTourAskEvent;
1258
1356
  };
1259
1357
  /**
@@ -385,6 +385,17 @@ export class HelixBeforePinEvent extends CustomEvent {
385
385
  });
386
386
  }
387
387
  }
388
+ export class HelixPinEvent extends CustomEvent {
389
+ static { this.eventName = 'helix-pin'; }
390
+ constructor(detail) {
391
+ super(HelixPinEvent.eventName, {
392
+ bubbles: true,
393
+ cancelable: false,
394
+ composed: true,
395
+ detail,
396
+ });
397
+ }
398
+ }
388
399
  export class HelixBeforeResizeEvent extends CustomEvent {
389
400
  static { this.eventName = 'helix-before-resize'; }
390
401
  constructor(detail) {
@@ -396,6 +407,17 @@ export class HelixBeforeResizeEvent extends CustomEvent {
396
407
  });
397
408
  }
398
409
  }
410
+ export class HelixResizedEvent extends CustomEvent {
411
+ static { this.eventName = 'helix-resized'; }
412
+ constructor(detail) {
413
+ super(HelixResizedEvent.eventName, {
414
+ bubbles: true,
415
+ cancelable: false,
416
+ composed: true,
417
+ detail,
418
+ });
419
+ }
420
+ }
399
421
  export class HelixBeforeSplitEvent extends CustomEvent {
400
422
  static { this.eventName = 'helix-before-split'; }
401
423
  constructor(detail) {
@@ -429,6 +451,17 @@ export class HelixBeforeCollapseEvent extends CustomEvent {
429
451
  });
430
452
  }
431
453
  }
454
+ export class HelixCollapseEvent extends CustomEvent {
455
+ static { this.eventName = 'helix-collapse'; }
456
+ constructor(detail) {
457
+ super(HelixCollapseEvent.eventName, {
458
+ bubbles: true,
459
+ cancelable: false,
460
+ composed: true,
461
+ detail,
462
+ });
463
+ }
464
+ }
432
465
  export class HelixBeforeEditEvent extends CustomEvent {
433
466
  static { this.eventName = 'helix-before-edit'; }
434
467
  constructor(detail) {
@@ -582,6 +615,17 @@ export class HelixSortEvent extends CustomEvent {
582
615
  });
583
616
  }
584
617
  }
618
+ export class HelixSortedEvent extends CustomEvent {
619
+ static { this.eventName = 'helix-sorted'; }
620
+ constructor(detail) {
621
+ super(HelixSortedEvent.eventName, {
622
+ bubbles: true,
623
+ cancelable: false,
624
+ composed: true,
625
+ detail,
626
+ });
627
+ }
628
+ }
585
629
  export class HelixFacetEvent extends CustomEvent {
586
630
  static { this.eventName = 'helix-facet'; }
587
631
  constructor(detail) {
@@ -604,6 +648,17 @@ export class HelixFilterEvent extends CustomEvent {
604
648
  });
605
649
  }
606
650
  }
651
+ export class HelixFilteredEvent extends CustomEvent {
652
+ static { this.eventName = 'helix-filtered'; }
653
+ constructor(detail) {
654
+ super(HelixFilteredEvent.eventName, {
655
+ bubbles: true,
656
+ cancelable: false,
657
+ composed: true,
658
+ detail,
659
+ });
660
+ }
661
+ }
607
662
  export class HelixShortcutEvent extends CustomEvent {
608
663
  static { this.eventName = 'helix-shortcut'; }
609
664
  constructor(detail) {
@@ -626,6 +681,17 @@ export class HelixSelectEvent extends CustomEvent {
626
681
  });
627
682
  }
628
683
  }
684
+ export class HelixSelectedEvent extends CustomEvent {
685
+ static { this.eventName = 'helix-selected'; }
686
+ constructor(detail) {
687
+ super(HelixSelectedEvent.eventName, {
688
+ bubbles: true,
689
+ cancelable: false,
690
+ composed: true,
691
+ detail,
692
+ });
693
+ }
694
+ }
629
695
  export class HelixReorderEvent extends CustomEvent {
630
696
  static { this.eventName = 'helix-reorder'; }
631
697
  constructor(detail) {
@@ -637,6 +703,17 @@ export class HelixReorderEvent extends CustomEvent {
637
703
  });
638
704
  }
639
705
  }
706
+ export class HelixReorderedEvent extends CustomEvent {
707
+ static { this.eventName = 'helix-reordered'; }
708
+ constructor(detail) {
709
+ super(HelixReorderedEvent.eventName, {
710
+ bubbles: true,
711
+ cancelable: false,
712
+ composed: true,
713
+ detail,
714
+ });
715
+ }
716
+ }
640
717
  export class HelixHistoryEvent extends CustomEvent {
641
718
  static { this.eventName = 'helix-history'; }
642
719
  constructor() {
@@ -669,6 +746,7 @@ const registry = {
669
746
  HelixCanvasViewEvent,
670
747
  HelixCanvasZoomEvent,
671
748
  HelixCaretEvent,
749
+ HelixCollapseEvent,
672
750
  HelixCompleteEvent,
673
751
  HelixConnectEvent,
674
752
  HelixConsoleEvent,
@@ -677,6 +755,7 @@ const registry = {
677
755
  HelixDismissEvent,
678
756
  HelixFacetEvent,
679
757
  HelixFilterEvent,
758
+ HelixFilteredEvent,
680
759
  HelixGraphFilterEvent,
681
760
  HelixGraphLayoutEvent,
682
761
  HelixGraphPanEvent,
@@ -695,20 +774,25 @@ const registry = {
695
774
  HelixMoveEvent,
696
775
  HelixNavigateEvent,
697
776
  HelixNextEvent,
777
+ HelixPinEvent,
698
778
  HelixPreviousEvent,
699
779
  HelixReadEvent,
700
780
  HelixReconnectEvent,
701
781
  HelixRelabelEvent,
702
782
  HelixRemoveEvent,
703
783
  HelixReorderEvent,
784
+ HelixReorderedEvent,
785
+ HelixResizedEvent,
704
786
  HelixResizeEvent,
705
787
  HelixSampleEndEvent,
706
788
  HelixSampleStartEvent,
707
789
  HelixScrolledEvent,
708
790
  HelixSelectEvent,
791
+ HelixSelectedEvent,
709
792
  HelixSendEvent,
710
793
  HelixShortcutEvent,
711
794
  HelixSortEvent,
795
+ HelixSortedEvent,
712
796
  HelixTourAskEvent,
713
797
  };
714
798
  export const helixEventNames = new Set(Object.values(registry).map((event) => event.eventName));
@@ -78,16 +78,18 @@ export const reactPropFor = (event) => {
78
78
  }
79
79
  return `on${event.type.charAt(0).toUpperCase()}${event.type.slice(1)}`;
80
80
  };
81
+ const lowercasePropFor = (event) => event.type.includes('-') || REACT_WIRES.has(event.type) ? undefined : `on${event.type}`;
81
82
  export const bindReactHandler = (host, event) => {
82
83
  const props = reactPropsOf(host);
83
84
  if (props === undefined) {
84
85
  return;
85
86
  }
86
87
  auditReactProps(host, props);
87
- const key = reactPropFor(event);
88
- const handler = key === undefined ? undefined : props[key];
89
- if (typeof handler === 'function') {
90
- host.addEventListener(event.type, handler);
88
+ for (const key of [reactPropFor(event), lowercasePropFor(event)]) {
89
+ const handler = key === undefined ? undefined : props[key];
90
+ if (typeof handler === 'function') {
91
+ host.addEventListener(event.type, handler);
92
+ }
91
93
  }
92
94
  };
93
95
  export const applyReactProperties = (host) => {