@fusion.dev/helix-core 0.142.1 → 0.144.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 (112) hide show
  1. package/custom-elements.json +10436 -3804
  2. package/dist/controllers/aria-forward-controller/aria-forward-controller.d.ts +65 -0
  3. package/dist/controllers/aria-forward-controller/aria-forward-controller.js +77 -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 +99 -0
  7. package/dist/controllers/chart-pointer-controller/chart-pointer-controller.js +107 -2
  8. package/dist/controllers/chart-pointer-controller/reading-step.d.ts +57 -0
  9. package/dist/controllers/chart-pointer-controller/reading-step.js +45 -0
  10. package/dist/controllers/copy-controller/copy-controller.d.ts +11 -6
  11. package/dist/controllers/copy-controller/copy-controller.js +16 -9
  12. package/dist/controllers/delay-controller/delay-controller.d.ts +50 -0
  13. package/dist/controllers/delay-controller/delay-controller.js +54 -0
  14. package/dist/controllers/dismiss-controller/dismiss-controller.js +40 -3
  15. package/dist/controllers/focus-scope-controller/focus-scope-controller.d.ts +56 -0
  16. package/dist/controllers/focus-scope-controller/focus-scope-controller.js +71 -0
  17. package/dist/controllers/keyboard-navigation-controller/keyboard-navigation-controller.d.ts +79 -1
  18. package/dist/controllers/keyboard-navigation-controller/keyboard-navigation-controller.js +80 -10
  19. package/dist/controllers/open-phase-controller/open-phase-controller.d.ts +49 -0
  20. package/dist/controllers/open-phase-controller/open-phase-controller.js +41 -0
  21. package/dist/controllers/popover-controller/popover-controller.d.ts +11 -0
  22. package/dist/controllers/popover-controller/popover-controller.js +6 -0
  23. package/dist/controllers/source-controller/source-controller.d.ts +38 -0
  24. package/dist/controllers/source-controller/source-controller.js +71 -2
  25. package/dist/controllers/status-controller/status-controller.d.ts +47 -0
  26. package/dist/controllers/status-controller/status-controller.js +34 -0
  27. package/dist/controllers/swipe-controller/swipe-controller.d.ts +61 -0
  28. package/dist/controllers/swipe-controller/swipe-controller.js +106 -0
  29. package/dist/controllers/virtualize-controller/virtualize-controller.d.ts +16 -0
  30. package/dist/controllers/virtualize-controller/virtualize-controller.js +24 -2
  31. package/dist/events/events.d.ts +137 -4
  32. package/dist/events/events.js +96 -0
  33. package/dist/helix-element/react-bridge.js +6 -4
  34. package/dist/helix-form-element/helix-form-element.d.ts +131 -2
  35. package/dist/helix-form-element/helix-form-element.js +216 -6
  36. package/dist/index.d.ts +30 -9
  37. package/dist/index.js +29 -8
  38. package/dist/mixins/mixin-chart-source/mixin-chart-source.d.ts +15 -2
  39. package/dist/mixins/mixin-chart-source/mixin-chart-source.js +9 -1
  40. package/dist/mixins/mixin-collection/mixin-collection.d.ts +4 -2
  41. package/dist/mixins/mixin-collection/mixin-collection.js +8 -6
  42. package/dist/mixins/mixin-controller-checked/mixin-controller-checked.d.ts +10 -0
  43. package/dist/mixins/mixin-controller-checked/mixin-controller-checked.js +9 -0
  44. package/dist/mixins/mixin-controller-open/mixin-controller-open.js +19 -3
  45. package/dist/mixins/mixin-dismissible/mixin-dismissible.d.ts +2 -0
  46. package/dist/mixins/mixin-dismissible/mixin-dismissible.js +43 -0
  47. package/dist/mixins/mixin-field/mixin-field.d.ts +2 -0
  48. package/dist/mixins/mixin-field/mixin-field.js +46 -8
  49. package/dist/mixins/mixin-picker-editing/mixin-picker-editing.d.ts +23 -8
  50. package/dist/mixins/mixin-picker-editing/mixin-picker-editing.js +25 -1
  51. package/dist/mixins/mixin-picker-field/mixin-picker-field.d.ts +29 -5
  52. package/dist/mixins/mixin-picker-field/mixin-picker-field.js +94 -1
  53. package/dist/mixins/mixin-segmented-field/mixin-segmented-field.d.ts +67 -0
  54. package/dist/mixins/mixin-segmented-field/mixin-segmented-field.js +243 -0
  55. package/dist/utils/arrow/arrow.d.ts +15 -0
  56. package/dist/utils/arrow/arrow.js +2 -0
  57. package/dist/utils/audit-name/audit-name.d.ts +28 -0
  58. package/dist/utils/audit-name/audit-name.js +95 -0
  59. package/dist/utils/calendar/calendar.d.ts +117 -0
  60. package/dist/utils/calendar/calendar.js +96 -0
  61. package/dist/utils/chord/chord.d.ts +43 -0
  62. package/dist/utils/chord/chord.js +53 -0
  63. package/dist/utils/clock/clock.d.ts +87 -0
  64. package/dist/utils/clock/clock.js +68 -0
  65. package/dist/utils/color-name/color-name.d.ts +28 -0
  66. package/dist/utils/color-name/color-name.js +150 -0
  67. package/dist/utils/count-label/count-label.d.ts +13 -0
  68. package/dist/utils/count-label/count-label.js +5 -0
  69. package/dist/utils/css-color/css-color.d.ts +12 -0
  70. package/dist/utils/css-color/css-color.js +2 -2
  71. package/dist/utils/date-segments/date-segments.d.ts +122 -0
  72. package/dist/utils/date-segments/date-segments.js +206 -0
  73. package/dist/utils/draw-dismiss/draw-dismiss.d.ts +30 -0
  74. package/dist/utils/draw-dismiss/draw-dismiss.js +16 -0
  75. package/dist/utils/draw-tooltip/draw-tooltip.d.ts +15 -18
  76. package/dist/utils/draw-tooltip/draw-tooltip.js +16 -5
  77. package/dist/utils/draw-tooltip/spoken-reading.d.ts +10 -0
  78. package/dist/utils/draw-tooltip/spoken-reading.js +10 -0
  79. package/dist/utils/follow-link/follow-link.d.ts +46 -0
  80. package/dist/utils/follow-link/follow-link.js +37 -0
  81. package/dist/utils/heading-in/heading-in.d.ts +19 -0
  82. package/dist/utils/heading-in/heading-in.js +14 -0
  83. package/dist/utils/number-format/number-format.d.ts +23 -0
  84. package/dist/utils/number-format/number-format.js +55 -0
  85. package/dist/utils/platform/platform.d.ts +23 -0
  86. package/dist/utils/platform/platform.js +11 -0
  87. package/dist/utils/read-color/read-color.d.ts +14 -0
  88. package/dist/utils/read-color/read-color.js +13 -0
  89. package/dist/utils/read-series/read-series.d.ts +34 -0
  90. package/dist/utils/read-series/read-series.js +32 -4
  91. package/dist/utils/reflect-elements/reflect-elements.d.ts +37 -0
  92. package/dist/utils/reflect-elements/reflect-elements.js +40 -0
  93. package/dist/utils/relative-time/relative-time.d.ts +13 -1
  94. package/dist/utils/relative-time/relative-time.js +7 -4
  95. package/dist/utils/report-runtime/report-runtime.d.ts +12 -0
  96. package/dist/utils/roving-stop/roving-stop.d.ts +20 -0
  97. package/dist/utils/roving-stop/roving-stop.js +3 -0
  98. package/dist/utils/scroll-lock/scroll-lock.d.ts +16 -0
  99. package/dist/utils/scroll-lock/scroll-lock.js +30 -0
  100. package/dist/utils/swipe/swipe.d.ts +63 -0
  101. package/dist/utils/swipe/swipe.js +48 -0
  102. package/dist/utils/tab-stops/tab-stops.d.ts +16 -0
  103. package/dist/utils/tab-stops/tab-stops.js +22 -0
  104. package/dist/utils/value-as/value-as.d.ts +20 -0
  105. package/dist/utils/value-as/value-as.js +16 -0
  106. package/dist/utils/write-time/write-time.d.ts +11 -1
  107. package/dist/utils/write-time/write-time.js +7 -7
  108. package/dist/utils/written-list/written-list.d.ts +29 -2
  109. package/dist/utils/written-list/written-list.js +11 -1
  110. package/dist/version.d.ts +1 -1
  111. package/dist/version.js +1 -1
  112. package/package.json +4 -4
@@ -261,6 +261,34 @@ export declare class HelixCanvasEditEvent extends CustomEvent<{
261
261
  name: string;
262
262
  });
263
263
  }
264
+ /** Why a file field did not take a file. */
265
+ export type Refusal = 'count' | 'invalid' | 'size' | 'type';
266
+ /** One file a file field did not take, and why. */
267
+ export interface RefusedFile {
268
+ /** The file. */
269
+ readonly file: File;
270
+ /** What the field's `validate` said about it, where it was the one refusing. */
271
+ readonly message?: string;
272
+ /** Why it was not taken. */
273
+ readonly reason: Refusal;
274
+ }
275
+ /** The files a file field refused. */
276
+ export interface RejectDetail {
277
+ /** Each refused file with its reason, in the order they arrived. */
278
+ files: RefusedFile[];
279
+ }
280
+ /**
281
+ * Files arrived at a file field and some were refused: by `accept`, by
282
+ * `max-file-size`, by `max-files`, or by the field's own `validate`.
283
+ *
284
+ * A notification and not a request, because the files are already left out;
285
+ * the event is how a page tells the reader why. Bubbles and is composed, so a
286
+ * form around the field hears it.
287
+ */
288
+ export declare class HelixRejectEvent extends CustomEvent<RejectDetail> {
289
+ static readonly eventName = "helix-reject";
290
+ constructor(detail: RejectDetail);
291
+ }
264
292
  /** What a reader asked to take off the board. */
265
293
  export interface RemoveDetail {
266
294
  /** The cards, by name. */
@@ -319,6 +347,13 @@ export type MapPanDetail = ViewportPanDetail;
319
347
  export type MapZoomDetail = ViewportZoomDetail;
320
348
  /** Detail carried by `helix-navigate`. */
321
349
  export interface NavigateDetail {
350
+ /**
351
+ * The page asked for, as a number, where the component pages by number.
352
+ *
353
+ * Beside `value` rather than in place of it, because a calendar pages by
354
+ * month and its `value` is a month.
355
+ */
356
+ page?: number;
322
357
  /** Where the view is moving to, in whatever the component pages by. */
323
358
  value: string;
324
359
  }
@@ -368,7 +403,7 @@ export interface FacetDetail {
368
403
  export interface ReadDetail {
369
404
  /**
370
405
  * 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
406
+ * one, which is `helix-before-toggle`'s rule and for the same reason: `"false"` is
372
407
  * truthy and a consumer who forgets that marks everything read.
373
408
  */
374
409
  read: boolean;
@@ -472,7 +507,7 @@ export declare class HelixDismissEvent extends CustomEvent<DismissDetail> {
472
507
  *
473
508
  * A boolean is the case where it *is* lost, because `"false"` is truthy, so a
474
509
  * 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
510
+ * no error. That is why checkedness has `helix-before-toggle` and its own boolean, and
476
511
  * it is the line to hold: **stringify a value, never a fact.** A new control
477
512
  * whose state is a boolean wants an event with a typed detail, not a `String()`
478
513
  * call here.
@@ -750,11 +785,37 @@ export declare class HelixBeforePinEvent extends CustomEvent<ChangeDetail> {
750
785
  static readonly eventName = "helix-before-pin";
751
786
  constructor(detail: ChangeDetail);
752
787
  }
788
+ /**
789
+ * A transcript was pinned to the bottom, or let go of it.
790
+ *
791
+ * The notification half of `helix-before-pin`, sent once `pinned` has moved,
792
+ * so `currentTarget.pinned` is the new state and `detail.value` says it as
793
+ * `true` or `false`. Not cancelable: the decision was the request's.
794
+ */
795
+ export declare class HelixPinEvent extends CustomEvent<ChangeDetail> {
796
+ static readonly eventName = "helix-pin";
797
+ constructor(detail: ChangeDetail);
798
+ }
753
799
  /** A divider is about to move, and can be refused. */
754
800
  export declare class HelixBeforeResizeEvent extends CustomEvent<ChangeDetail> {
755
801
  static readonly eventName = "helix-before-resize";
756
802
  constructor(detail: ChangeDetail);
757
803
  }
804
+ /**
805
+ * A divider settled somewhere new.
806
+ *
807
+ * The notification half of `helix-before-resize`, sent once `position` has
808
+ * moved, with the new position. Not cancelable: the decision was the
809
+ * request's.
810
+ *
811
+ * **Past tense, because `helix-resize` was already taken** by a measurement,
812
+ * the height a sandboxed preview reports for what it drew, and one name cannot
813
+ * carry both.
814
+ */
815
+ export declare class HelixResizedEvent extends CustomEvent<ChangeDetail> {
816
+ static readonly eventName = "helix-resized";
817
+ constructor(detail: ChangeDetail);
818
+ }
758
819
  /**
759
820
  * The divider between a sandbox's panes is about to move, and can be refused.
760
821
  *
@@ -783,6 +844,17 @@ export declare class HelixBeforeCollapseEvent extends CustomEvent<ChangeDetail>
783
844
  static readonly eventName = "helix-before-collapse";
784
845
  constructor(detail: ChangeDetail);
785
846
  }
847
+ /**
848
+ * A pane shut or reopened.
849
+ *
850
+ * The notification half of `helix-before-collapse`, sent once `collapsed` has
851
+ * moved. `detail.value` is the side that is shut, or empty where both panes
852
+ * are open. Not cancelable: the decision was the request's.
853
+ */
854
+ export declare class HelixCollapseEvent extends CustomEvent<ChangeDetail> {
855
+ static readonly eventName = "helix-collapse";
856
+ constructor(detail: ChangeDetail);
857
+ }
786
858
  /** Source is about to be edited, and can be refused. */
787
859
  export declare class HelixBeforeEditEvent extends CustomEvent<ChangeDetail> {
788
860
  static readonly eventName = "helix-before-edit";
@@ -839,11 +911,11 @@ export declare class HelixBeforeToggleEvent extends CustomEvent<ToggleDetail> {
839
911
  export interface ScrolledDetail {
840
912
  /**
841
913
  * 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.
914
+ * that reads like one. Follows `helix-before-toggle`'s rule for the same reason.
843
915
  */
844
916
  scrolled: boolean;
845
917
  }
846
- /** Detail carried by `helix-toggle`. */
918
+ /** Detail carried by `helix-before-toggle`. */
847
919
  export interface ToggleDetail {
848
920
  /** The state being asked for, as a boolean and not a word that reads like one. */
849
921
  checked: boolean;
@@ -993,6 +1065,12 @@ export interface SelectDetail {
993
1065
  * A flag says it outright.
994
1066
  */
995
1067
  alternate?: boolean;
1068
+ /**
1069
+ * The link of a row that is a link, which the browser follows once the event
1070
+ * is done unless it is canceled. A client-side router cancels it and follows
1071
+ * the link itself.
1072
+ */
1073
+ href?: string;
996
1074
  /** Value of the item the reader chose. */
997
1075
  value: string;
998
1076
  }
@@ -1089,6 +1167,20 @@ export declare class HelixSortEvent extends CustomEvent<SortDetail> {
1089
1167
  static readonly eventName = "helix-sort";
1090
1168
  constructor(detail: SortDetail);
1091
1169
  }
1170
+ /**
1171
+ * The rows are in a different order.
1172
+ *
1173
+ * The notification after `helix-sort`, sent once `sort` has moved, with the
1174
+ * order now in force. Not cancelable: the decision was the request's.
1175
+ *
1176
+ * **Past tense, because the plain verb is the request.** `helix-sort` was
1177
+ * cancelable before the library had a word for its notification, and
1178
+ * consumers bind it by that name, so the notification takes the one after it.
1179
+ */
1180
+ export declare class HelixSortedEvent extends CustomEvent<SortDetail> {
1181
+ static readonly eventName = "helix-sorted";
1182
+ constructor(detail: SortDetail);
1183
+ }
1092
1184
  /**
1093
1185
  * Fired when the reader changes which values a field is filtered by.
1094
1186
  *
@@ -1116,6 +1208,17 @@ export declare class HelixFilterEvent extends CustomEvent<FilterDetail> {
1116
1208
  static readonly eventName = "helix-filter";
1117
1209
  constructor(detail: FilterDetail);
1118
1210
  }
1211
+ /**
1212
+ * A component is showing a narrower or a wider set.
1213
+ *
1214
+ * The notification after `helix-filter`, sent once the query has moved, with
1215
+ * the query now in force. Not cancelable, and past tense for the reason
1216
+ * `helix-sorted` is.
1217
+ */
1218
+ export declare class HelixFilteredEvent extends CustomEvent<FilterDetail> {
1219
+ static readonly eventName = "helix-filtered";
1220
+ constructor(detail: FilterDetail);
1221
+ }
1119
1222
  /** What a shortcut reports when its chord is pressed. */
1120
1223
  export interface ShortcutDetail {
1121
1224
  /**
@@ -1149,6 +1252,17 @@ export declare class HelixSelectEvent extends CustomEvent<SelectDetail> {
1149
1252
  static readonly eventName = "helix-select";
1150
1253
  constructor(detail: SelectDetail);
1151
1254
  }
1255
+ /**
1256
+ * A set holds a different selection.
1257
+ *
1258
+ * The notification after a `helix-select` that asked to change what is
1259
+ * selected, sent once the selection has moved, with the selection now in
1260
+ * force. Not cancelable, and past tense for the reason `helix-sorted` is.
1261
+ */
1262
+ export declare class HelixSelectedEvent extends CustomEvent<SelectDetail> {
1263
+ static readonly eventName = "helix-selected";
1264
+ constructor(detail: SelectDetail);
1265
+ }
1152
1266
  /**
1153
1267
  * Fired when the reader asks for the columns in a different order.
1154
1268
  *
@@ -1166,6 +1280,17 @@ export declare class HelixReorderEvent extends CustomEvent<ChangeDetail> {
1166
1280
  static readonly eventName = "helix-reorder";
1167
1281
  constructor(detail: ChangeDetail);
1168
1282
  }
1283
+ /**
1284
+ * The columns are in a different order.
1285
+ *
1286
+ * The notification after `helix-reorder`, sent once the order has moved, with
1287
+ * every field in the new one. Not cancelable, and past tense for the reason
1288
+ * `helix-sorted` is.
1289
+ */
1290
+ export declare class HelixReorderedEvent extends CustomEvent<ChangeDetail> {
1291
+ static readonly eventName = "helix-reordered";
1292
+ constructor(detail: ChangeDetail);
1293
+ }
1169
1294
  /**
1170
1295
  * Fired when a reader reaches the oldest turn a transcript holds, while there are
1171
1296
  * older ones to fetch.
@@ -1214,6 +1339,7 @@ declare const registry: {
1214
1339
  readonly HelixCanvasViewEvent: typeof HelixCanvasViewEvent;
1215
1340
  readonly HelixCanvasZoomEvent: typeof HelixCanvasZoomEvent;
1216
1341
  readonly HelixCaretEvent: typeof HelixCaretEvent;
1342
+ readonly HelixCollapseEvent: typeof HelixCollapseEvent;
1217
1343
  readonly HelixCompleteEvent: typeof HelixCompleteEvent;
1218
1344
  readonly HelixConnectEvent: typeof HelixConnectEvent;
1219
1345
  readonly HelixConsoleEvent: typeof HelixConsoleEvent;
@@ -1222,6 +1348,7 @@ declare const registry: {
1222
1348
  readonly HelixDismissEvent: typeof HelixDismissEvent;
1223
1349
  readonly HelixFacetEvent: typeof HelixFacetEvent;
1224
1350
  readonly HelixFilterEvent: typeof HelixFilterEvent;
1351
+ readonly HelixFilteredEvent: typeof HelixFilteredEvent;
1225
1352
  readonly HelixGraphFilterEvent: typeof HelixGraphFilterEvent;
1226
1353
  readonly HelixGraphLayoutEvent: typeof HelixGraphLayoutEvent;
1227
1354
  readonly HelixGraphPanEvent: typeof HelixGraphPanEvent;
@@ -1240,20 +1367,26 @@ declare const registry: {
1240
1367
  readonly HelixMoveEvent: typeof HelixMoveEvent;
1241
1368
  readonly HelixNavigateEvent: typeof HelixNavigateEvent;
1242
1369
  readonly HelixNextEvent: typeof HelixNextEvent;
1370
+ readonly HelixPinEvent: typeof HelixPinEvent;
1243
1371
  readonly HelixPreviousEvent: typeof HelixPreviousEvent;
1244
1372
  readonly HelixReadEvent: typeof HelixReadEvent;
1245
1373
  readonly HelixReconnectEvent: typeof HelixReconnectEvent;
1374
+ readonly HelixRejectEvent: typeof HelixRejectEvent;
1246
1375
  readonly HelixRelabelEvent: typeof HelixRelabelEvent;
1247
1376
  readonly HelixRemoveEvent: typeof HelixRemoveEvent;
1248
1377
  readonly HelixReorderEvent: typeof HelixReorderEvent;
1378
+ readonly HelixReorderedEvent: typeof HelixReorderedEvent;
1379
+ readonly HelixResizedEvent: typeof HelixResizedEvent;
1249
1380
  readonly HelixResizeEvent: typeof HelixResizeEvent;
1250
1381
  readonly HelixSampleEndEvent: typeof HelixSampleEndEvent;
1251
1382
  readonly HelixSampleStartEvent: typeof HelixSampleStartEvent;
1252
1383
  readonly HelixScrolledEvent: typeof HelixScrolledEvent;
1253
1384
  readonly HelixSelectEvent: typeof HelixSelectEvent;
1385
+ readonly HelixSelectedEvent: typeof HelixSelectedEvent;
1254
1386
  readonly HelixSendEvent: typeof HelixSendEvent;
1255
1387
  readonly HelixShortcutEvent: typeof HelixShortcutEvent;
1256
1388
  readonly HelixSortEvent: typeof HelixSortEvent;
1389
+ readonly HelixSortedEvent: typeof HelixSortedEvent;
1257
1390
  readonly HelixTourAskEvent: typeof HelixTourAskEvent;
1258
1391
  };
1259
1392
  /**
@@ -152,6 +152,17 @@ export class HelixCanvasEditEvent extends CustomEvent {
152
152
  });
153
153
  }
154
154
  }
155
+ export class HelixRejectEvent extends CustomEvent {
156
+ static { this.eventName = 'helix-reject'; }
157
+ constructor(detail) {
158
+ super(HelixRejectEvent.eventName, {
159
+ bubbles: true,
160
+ cancelable: false,
161
+ composed: true,
162
+ detail,
163
+ });
164
+ }
165
+ }
155
166
  export class HelixRemoveEvent extends CustomEvent {
156
167
  static { this.eventName = 'helix-remove'; }
157
168
  constructor(detail) {
@@ -385,6 +396,17 @@ export class HelixBeforePinEvent extends CustomEvent {
385
396
  });
386
397
  }
387
398
  }
399
+ export class HelixPinEvent extends CustomEvent {
400
+ static { this.eventName = 'helix-pin'; }
401
+ constructor(detail) {
402
+ super(HelixPinEvent.eventName, {
403
+ bubbles: true,
404
+ cancelable: false,
405
+ composed: true,
406
+ detail,
407
+ });
408
+ }
409
+ }
388
410
  export class HelixBeforeResizeEvent extends CustomEvent {
389
411
  static { this.eventName = 'helix-before-resize'; }
390
412
  constructor(detail) {
@@ -396,6 +418,17 @@ export class HelixBeforeResizeEvent extends CustomEvent {
396
418
  });
397
419
  }
398
420
  }
421
+ export class HelixResizedEvent extends CustomEvent {
422
+ static { this.eventName = 'helix-resized'; }
423
+ constructor(detail) {
424
+ super(HelixResizedEvent.eventName, {
425
+ bubbles: true,
426
+ cancelable: false,
427
+ composed: true,
428
+ detail,
429
+ });
430
+ }
431
+ }
399
432
  export class HelixBeforeSplitEvent extends CustomEvent {
400
433
  static { this.eventName = 'helix-before-split'; }
401
434
  constructor(detail) {
@@ -429,6 +462,17 @@ export class HelixBeforeCollapseEvent extends CustomEvent {
429
462
  });
430
463
  }
431
464
  }
465
+ export class HelixCollapseEvent extends CustomEvent {
466
+ static { this.eventName = 'helix-collapse'; }
467
+ constructor(detail) {
468
+ super(HelixCollapseEvent.eventName, {
469
+ bubbles: true,
470
+ cancelable: false,
471
+ composed: true,
472
+ detail,
473
+ });
474
+ }
475
+ }
432
476
  export class HelixBeforeEditEvent extends CustomEvent {
433
477
  static { this.eventName = 'helix-before-edit'; }
434
478
  constructor(detail) {
@@ -582,6 +626,17 @@ export class HelixSortEvent extends CustomEvent {
582
626
  });
583
627
  }
584
628
  }
629
+ export class HelixSortedEvent extends CustomEvent {
630
+ static { this.eventName = 'helix-sorted'; }
631
+ constructor(detail) {
632
+ super(HelixSortedEvent.eventName, {
633
+ bubbles: true,
634
+ cancelable: false,
635
+ composed: true,
636
+ detail,
637
+ });
638
+ }
639
+ }
585
640
  export class HelixFacetEvent extends CustomEvent {
586
641
  static { this.eventName = 'helix-facet'; }
587
642
  constructor(detail) {
@@ -604,6 +659,17 @@ export class HelixFilterEvent extends CustomEvent {
604
659
  });
605
660
  }
606
661
  }
662
+ export class HelixFilteredEvent extends CustomEvent {
663
+ static { this.eventName = 'helix-filtered'; }
664
+ constructor(detail) {
665
+ super(HelixFilteredEvent.eventName, {
666
+ bubbles: true,
667
+ cancelable: false,
668
+ composed: true,
669
+ detail,
670
+ });
671
+ }
672
+ }
607
673
  export class HelixShortcutEvent extends CustomEvent {
608
674
  static { this.eventName = 'helix-shortcut'; }
609
675
  constructor(detail) {
@@ -626,6 +692,17 @@ export class HelixSelectEvent extends CustomEvent {
626
692
  });
627
693
  }
628
694
  }
695
+ export class HelixSelectedEvent extends CustomEvent {
696
+ static { this.eventName = 'helix-selected'; }
697
+ constructor(detail) {
698
+ super(HelixSelectedEvent.eventName, {
699
+ bubbles: true,
700
+ cancelable: false,
701
+ composed: true,
702
+ detail,
703
+ });
704
+ }
705
+ }
629
706
  export class HelixReorderEvent extends CustomEvent {
630
707
  static { this.eventName = 'helix-reorder'; }
631
708
  constructor(detail) {
@@ -637,6 +714,17 @@ export class HelixReorderEvent extends CustomEvent {
637
714
  });
638
715
  }
639
716
  }
717
+ export class HelixReorderedEvent extends CustomEvent {
718
+ static { this.eventName = 'helix-reordered'; }
719
+ constructor(detail) {
720
+ super(HelixReorderedEvent.eventName, {
721
+ bubbles: true,
722
+ cancelable: false,
723
+ composed: true,
724
+ detail,
725
+ });
726
+ }
727
+ }
640
728
  export class HelixHistoryEvent extends CustomEvent {
641
729
  static { this.eventName = 'helix-history'; }
642
730
  constructor() {
@@ -669,6 +757,7 @@ const registry = {
669
757
  HelixCanvasViewEvent,
670
758
  HelixCanvasZoomEvent,
671
759
  HelixCaretEvent,
760
+ HelixCollapseEvent,
672
761
  HelixCompleteEvent,
673
762
  HelixConnectEvent,
674
763
  HelixConsoleEvent,
@@ -677,6 +766,7 @@ const registry = {
677
766
  HelixDismissEvent,
678
767
  HelixFacetEvent,
679
768
  HelixFilterEvent,
769
+ HelixFilteredEvent,
680
770
  HelixGraphFilterEvent,
681
771
  HelixGraphLayoutEvent,
682
772
  HelixGraphPanEvent,
@@ -695,20 +785,26 @@ const registry = {
695
785
  HelixMoveEvent,
696
786
  HelixNavigateEvent,
697
787
  HelixNextEvent,
788
+ HelixPinEvent,
698
789
  HelixPreviousEvent,
699
790
  HelixReadEvent,
700
791
  HelixReconnectEvent,
792
+ HelixRejectEvent,
701
793
  HelixRelabelEvent,
702
794
  HelixRemoveEvent,
703
795
  HelixReorderEvent,
796
+ HelixReorderedEvent,
797
+ HelixResizedEvent,
704
798
  HelixResizeEvent,
705
799
  HelixSampleEndEvent,
706
800
  HelixSampleStartEvent,
707
801
  HelixScrolledEvent,
708
802
  HelixSelectEvent,
803
+ HelixSelectedEvent,
709
804
  HelixSendEvent,
710
805
  HelixShortcutEvent,
711
806
  HelixSortEvent,
807
+ HelixSortedEvent,
712
808
  HelixTourAskEvent,
713
809
  };
714
810
  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) => {
@@ -11,8 +11,17 @@ import { HelixElement } from '../helix-element/helix-element.js';
11
11
  * `internals` comes from `HelixElement`, which attaches it for every component.
12
12
  * `attachInternals()` throws on a second call, so only one class attaches it.
13
13
  *
14
- * The class carries only what every form participant needs. `value`, validity,
15
- * and the reset and restore callbacks are added with the first input component.
14
+ * The class carries only what every form participant needs. `value` and the
15
+ * reset and restore callbacks are added with the first input component.
16
+ *
17
+ * **The validity API is the platform's, read through `internals`**, so
18
+ * `checkValidity()`, `reportValidity()` and `setCustomValidity()` work on the
19
+ * host as they do on a native control. A custom message is laid over whatever
20
+ * the control itself reports, which is why `setValidity` is wrapped below.
21
+ *
22
+ * **Focus goes to the control's first tab stop**, for `focus()` and for a
23
+ * press on a `<label>` that names the host. A host is not focusable itself, so
24
+ * without this a label press focused nothing on half the controls.
16
25
  *
17
26
  * @since 0.1.0
18
27
  * @status experimental
@@ -109,6 +118,16 @@ export declare class HelixFormElement extends HelixElement {
109
118
  * middle of removing.
110
119
  */
111
120
  formDisabledCallback(disabled: boolean): void;
121
+ /**
122
+ * Whether an ancestor `<fieldset disabled>` holds the control, outside its
123
+ * first `<legend>`, read from the tree.
124
+ *
125
+ * For the one case the callback cannot report: a control disabled itself and
126
+ * by a fieldset, whose own `disabled` is then removed. The effective state does
127
+ * not change, so the platform does not call, and the fieldset's hold has to
128
+ * be read.
129
+ */
130
+ private get heldByFieldset();
112
131
  /**
113
132
  * Called by the browser when the form is reset. It does nothing here, and
114
133
  * every override calls it.
@@ -158,6 +177,116 @@ export declare class HelixFormElement extends HelixElement {
158
177
  * Here rather than on each control.
159
178
  */
160
179
  name: string;
180
+ constructor();
181
+ /** The platform's own `setValidity`, which the wrapper above calls. */
182
+ private readonly reportValidityTo;
183
+ /** What the control last reported, before any custom error is laid over it. */
184
+ private reported;
185
+ /** The message `setCustomValidity` was given. */
186
+ private customValidity;
187
+ /** The `validityFeedback` the platform was last told about. */
188
+ private appliedFeedback;
189
+ /**
190
+ * @internal A message that marks the control invalid, from a layer above this
191
+ * one. `MixinField` answers with `feedback`, so a field showing what is wrong
192
+ * does not submit.
193
+ */
194
+ protected get validityFeedback(): string;
195
+ /**
196
+ * Hands the platform the control's own verdict with any custom error on top,
197
+ * anchored where focus can go.
198
+ */
199
+ private applyValidity;
200
+ /**
201
+ * Where the browser points its bubble: the anchor a control gave if focus
202
+ * can go there, and its first tab stop otherwise.
203
+ *
204
+ * A group anchors on a part that holds its members and cannot take focus,
205
+ * and the platform then refuses the submission, logs that the control is
206
+ * not focusable, and leaves the reader on the submit button.
207
+ */
208
+ protected validationAnchor(anchor?: HTMLElement): HTMLElement | undefined;
209
+ /**
210
+ * Whether the control meets its constraints, and why not.
211
+ *
212
+ * @reference https://developer.mozilla.org/docs/Web/API/ElementInternals/validity ElementInternals.validity
213
+ */
214
+ get validity(): ValidityState;
215
+ /** The message the browser would show for the control, or an empty string. */
216
+ get validationMessage(): string;
217
+ /** Whether the control is checked when its form is submitted. */
218
+ get willValidate(): boolean;
219
+ /**
220
+ * Returns whether the control is valid, and fires `invalid` on it when it is
221
+ * not.
222
+ */
223
+ checkValidity(): boolean;
224
+ /**
225
+ * Returns whether the control is valid, and when it is not, fires `invalid`
226
+ * and shows the browser's message at the control.
227
+ */
228
+ reportValidity(): boolean;
229
+ /**
230
+ * Marks the control invalid with `message`, or clears that with an empty
231
+ * string, as on a native control. The form does not submit while it is set.
232
+ */
233
+ setCustomValidity(message: string): void;
234
+ /**
235
+ * The element focus goes to: the control's first tab stop, or `null` where
236
+ * there is none.
237
+ *
238
+ * Read through shadow roots and slots, so a group lands on the member that
239
+ * holds its tab stop, which is the chosen radio in a radio group.
240
+ */
241
+ protected get focusTarget(): HTMLElement | null;
242
+ /** Moves focus to the control, as focusing a native control does. */
243
+ focus(options?: FocusOptions): void;
244
+ /**
245
+ * Focuses the control when its `<label>` is pressed.
246
+ *
247
+ * The label sends the host a click of the browser's own after trying to
248
+ * focus it, and a host that is not focusable takes nothing from that try.
249
+ * Only a click that starts at the host and that the browser sent: one from
250
+ * inside has landed where it meant to, and `click()` from a script does not
251
+ * focus a native control either.
252
+ */
253
+ private readonly focusFromLabel;
254
+ /**
255
+ * Re-anchors the verdict as the form checks it, because the control's
256
+ * members may have rendered since it last reported, and the anchor read then
257
+ * was the best there was.
258
+ */
259
+ private readonly refreshAnchor;
260
+ connectedCallback(): void;
261
+ disconnectedCallback(): void;
262
+ /**
263
+ * @internal Whether this control is a field that counts against implicit
264
+ * submission: a single line of text, as `<input type="text">` is.
265
+ */
266
+ protected get blocksImplicitSubmission(): boolean;
267
+ /** @internal Whether this control submits its form, for finding the form's default button. */
268
+ protected get submitsForm(): boolean;
269
+ /** @internal Activates the control as its form's default button. */
270
+ protected activate(): void;
271
+ /**
272
+ * Submits the form the way pressing Enter in a native text field does.
273
+ *
274
+ * The control's own input is in a shadow root and has no form owner, so the
275
+ * platform never runs implicit submission for it. This runs it: the form's
276
+ * default button is activated, the first submit button in it, a Helix one
277
+ * included. With none, the form is submitted when it holds no more than one
278
+ * field that counts against implicit submission, and nothing happens
279
+ * otherwise.
280
+ *
281
+ * @reference https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#implicit-submission implicit submission
282
+ */
283
+ protected submitImplicitly(): void;
284
+ /** The form's default button, the first submit button in it, native or Helix. */
285
+ protected static defaultButton(form: HTMLFormElement): Element | undefined;
286
+ /** Whether `target` is a native field of `form` that Enter submits it from. */
287
+ protected static submitsOnEnter(target: EventTarget | undefined, form: HTMLFormElement): boolean;
288
+ /** Whether `element` is a submit button, native or Helix. */
289
+ protected static submits(element: Element): boolean;
161
290
  /**
162
291
  * The form the control belongs to, or `null`.
163
292
  *