@fusion.dev/helix-core 0.223.1 → 0.225.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 (235) hide show
  1. package/custom-elements.json +1 -1
  2. package/dist/controllers/reorder-controller/reorder-controller.js +2 -3
  3. package/dist/events/before-activate.d.ts +3 -1
  4. package/dist/events/before-change.d.ts +2 -0
  5. package/dist/events/before-check.d.ts +31 -0
  6. package/dist/events/before-check.js +11 -0
  7. package/dist/events/before-close.d.ts +5 -1
  8. package/dist/events/before-filter.d.ts +17 -0
  9. package/dist/events/before-filter.js +11 -0
  10. package/dist/events/before-listen.d.ts +5 -1
  11. package/dist/events/before-navigate.d.ts +16 -0
  12. package/dist/events/before-navigate.js +11 -0
  13. package/dist/events/before-open.d.ts +2 -0
  14. package/dist/events/before-pin.d.ts +5 -1
  15. package/dist/events/before-reorder.d.ts +2 -0
  16. package/dist/events/before-resize.d.ts +5 -1
  17. package/dist/events/before-select.d.ts +19 -0
  18. package/dist/events/before-select.js +11 -0
  19. package/dist/events/before-sort.d.ts +19 -0
  20. package/dist/events/before-sort.js +11 -0
  21. package/dist/events/check.d.ts +15 -0
  22. package/dist/events/{caret.js → check.js} +3 -3
  23. package/dist/events/details.d.ts +11 -514
  24. package/dist/events/events.d.ts +27 -170
  25. package/dist/events/events.js +13 -165
  26. package/dist/events/expand.d.ts +2 -1
  27. package/dist/events/filter.d.ts +3 -4
  28. package/dist/events/filter.js +1 -1
  29. package/dist/events/found.d.ts +1 -1
  30. package/dist/events/names.d.ts +5 -16
  31. package/dist/events/names.js +11 -15
  32. package/dist/events/navigate.d.ts +3 -5
  33. package/dist/events/navigate.js +1 -1
  34. package/dist/events/reorder.d.ts +12 -13
  35. package/dist/events/reorder.js +1 -1
  36. package/dist/events/select.d.ts +4 -4
  37. package/dist/events/select.js +1 -1
  38. package/dist/events/sort.d.ts +3 -9
  39. package/dist/events/sort.js +1 -1
  40. package/dist/helix-element/helix-element.d.ts +31 -14
  41. package/dist/helix-element/helix-element.js +25 -3
  42. package/dist/helix-element/react-audit-off.d.ts +3 -1
  43. package/dist/helix-element/react-audit-off.js +1 -0
  44. package/dist/helix-element/react-audit.d.ts +22 -0
  45. package/dist/helix-element/react-audit.js +18 -0
  46. package/dist/helix-element/react-bridge.d.ts +34 -1
  47. package/dist/helix-element/react-bridge.js +33 -9
  48. package/dist/helix-element/react-root.d.ts +2 -0
  49. package/dist/helix-element/react-root.js +9 -0
  50. package/dist/helix-form-element/helix-form-element-base.js +12 -12
  51. package/dist/helix-form-element/helix-form-element.js +4 -3
  52. package/dist/index.d.ts +4 -2
  53. package/dist/index.js +4 -2
  54. package/dist/mixins/mixin-controller-checked/mixin-controller-checked.d.ts +3 -3
  55. package/dist/mixins/mixin-controller-checked/mixin-controller-checked.js +2 -2
  56. package/dist/mixins/mixin-field/mixin-field.js +9 -8
  57. package/dist/mixins/mixin-picker-feedback/mixin-picker-feedback.js +3 -2
  58. package/dist/mixins/mixin-picker-field/mixin-picker-field.js +4 -3
  59. package/dist/mixins/mixin-segmented-field/mixin-segmented-field.js +5 -4
  60. package/dist/mixins/mixin-selectable-item/mixin-selectable-item.d.ts +1 -1
  61. package/dist/mixins/mixin-selectable-item/mixin-selectable-item.js +2 -2
  62. package/dist/utils/audit-children/audit-children.d.ts +1 -1
  63. package/dist/utils/audit-name/audit-name.js +12 -1
  64. package/dist/utils/controls/controls.js +6 -1
  65. package/dist/utils/draw-icon/draw-icon.d.ts +1 -1
  66. package/dist/utils/follow-link/follow-link.d.ts +1 -1
  67. package/dist/utils/report-runtime/report-runtime.d.ts +5 -0
  68. package/dist/utils/tell-disclosure/tell-disclosure.d.ts +6 -3
  69. package/dist/utils/ticker/ticker.d.ts +5 -0
  70. package/dist/version.d.ts +4 -5
  71. package/dist/version.js +1 -1
  72. package/package.json +6 -6
  73. package/dist/events/action.d.ts +0 -12
  74. package/dist/events/action.js +0 -6
  75. package/dist/events/aura-fallback.d.ts +0 -12
  76. package/dist/events/aura-fallback.js +0 -11
  77. package/dist/events/band.d.ts +0 -13
  78. package/dist/events/band.js +0 -11
  79. package/dist/events/before-collapse.d.ts +0 -6
  80. package/dist/events/before-collapse.js +0 -11
  81. package/dist/events/before-edit.d.ts +0 -6
  82. package/dist/events/before-edit.js +0 -11
  83. package/dist/events/before-move.d.ts +0 -17
  84. package/dist/events/before-move.js +0 -11
  85. package/dist/events/before-panel-resize.d.ts +0 -13
  86. package/dist/events/before-panel-resize.js +0 -11
  87. package/dist/events/before-paste.d.ts +0 -13
  88. package/dist/events/before-paste.js +0 -11
  89. package/dist/events/before-reconnect.d.ts +0 -14
  90. package/dist/events/before-reconnect.js +0 -11
  91. package/dist/events/before-relabel.d.ts +0 -15
  92. package/dist/events/before-relabel.js +0 -11
  93. package/dist/events/before-split.d.ts +0 -12
  94. package/dist/events/before-split.js +0 -11
  95. package/dist/events/before-toggle.d.ts +0 -23
  96. package/dist/events/before-toggle.js +0 -11
  97. package/dist/events/canvas-edit.d.ts +0 -16
  98. package/dist/events/canvas-edit.js +0 -11
  99. package/dist/events/canvas-pan.d.ts +0 -13
  100. package/dist/events/canvas-pan.js +0 -11
  101. package/dist/events/canvas-view.d.ts +0 -14
  102. package/dist/events/canvas-view.js +0 -11
  103. package/dist/events/canvas-zoom.d.ts +0 -6
  104. package/dist/events/canvas-zoom.js +0 -11
  105. package/dist/events/caret.d.ts +0 -17
  106. package/dist/events/collapse.d.ts +0 -12
  107. package/dist/events/collapse.js +0 -11
  108. package/dist/events/connect.d.ts +0 -14
  109. package/dist/events/connect.js +0 -11
  110. package/dist/events/console.d.ts +0 -13
  111. package/dist/events/console.js +0 -11
  112. package/dist/events/create.d.ts +0 -18
  113. package/dist/events/create.js +0 -11
  114. package/dist/events/device-button.d.ts +0 -14
  115. package/dist/events/device-button.js +0 -11
  116. package/dist/events/device-key.d.ts +0 -16
  117. package/dist/events/device-key.js +0 -11
  118. package/dist/events/device-screenshot.d.ts +0 -13
  119. package/dist/events/device-screenshot.js +0 -10
  120. package/dist/events/device-scroll.d.ts +0 -14
  121. package/dist/events/device-scroll.js +0 -11
  122. package/dist/events/device-swipe.d.ts +0 -15
  123. package/dist/events/device-swipe.js +0 -11
  124. package/dist/events/device-tap.d.ts +0 -13
  125. package/dist/events/device-tap.js +0 -11
  126. package/dist/events/device-text.d.ts +0 -13
  127. package/dist/events/device-text.js +0 -11
  128. package/dist/events/device-touch.d.ts +0 -15
  129. package/dist/events/device-touch.js +0 -11
  130. package/dist/events/edit.d.ts +0 -12
  131. package/dist/events/edit.js +0 -11
  132. package/dist/events/end.d.ts +0 -9
  133. package/dist/events/end.js +0 -6
  134. package/dist/events/facet.d.ts +0 -17
  135. package/dist/events/facet.js +0 -11
  136. package/dist/events/filtered.d.ts +0 -12
  137. package/dist/events/filtered.js +0 -11
  138. package/dist/events/graph-filter.d.ts +0 -10
  139. package/dist/events/graph-filter.js +0 -11
  140. package/dist/events/graph-layout.d.ts +0 -10
  141. package/dist/events/graph-layout.js +0 -11
  142. package/dist/events/graph-pan.d.ts +0 -9
  143. package/dist/events/graph-pan.js +0 -11
  144. package/dist/events/graph-part-change.d.ts +0 -10
  145. package/dist/events/graph-part-change.js +0 -11
  146. package/dist/events/graph-ready.d.ts +0 -8
  147. package/dist/events/graph-ready.js +0 -6
  148. package/dist/events/graph-signal.d.ts +0 -11
  149. package/dist/events/graph-signal.js +0 -11
  150. package/dist/events/graph-zoom.d.ts +0 -6
  151. package/dist/events/graph-zoom.js +0 -11
  152. package/dist/events/history.d.ts +0 -16
  153. package/dist/events/history.js +0 -11
  154. package/dist/events/map-cluster.d.ts +0 -15
  155. package/dist/events/map-cluster.js +0 -11
  156. package/dist/events/map-pan.d.ts +0 -18
  157. package/dist/events/map-pan.js +0 -11
  158. package/dist/events/map-part-change.d.ts +0 -16
  159. package/dist/events/map-part-change.js +0 -11
  160. package/dist/events/map-ready.d.ts +0 -15
  161. package/dist/events/map-ready.js +0 -6
  162. package/dist/events/map-rotate.d.ts +0 -9
  163. package/dist/events/map-rotate.js +0 -11
  164. package/dist/events/map-tilt.d.ts +0 -9
  165. package/dist/events/map-tilt.js +0 -11
  166. package/dist/events/map-zoom.d.ts +0 -13
  167. package/dist/events/map-zoom.js +0 -11
  168. package/dist/events/move.d.ts +0 -11
  169. package/dist/events/move.js +0 -11
  170. package/dist/events/next.d.ts +0 -23
  171. package/dist/events/next.js +0 -11
  172. package/dist/events/panel-resize.d.ts +0 -12
  173. package/dist/events/panel-resize.js +0 -11
  174. package/dist/events/pasted.d.ts +0 -6
  175. package/dist/events/pasted.js +0 -11
  176. package/dist/events/press.d.ts +0 -19
  177. package/dist/events/press.js +0 -11
  178. package/dist/events/preview.d.ts +0 -14
  179. package/dist/events/preview.js +0 -11
  180. package/dist/events/previous.d.ts +0 -6
  181. package/dist/events/previous.js +0 -11
  182. package/dist/events/range-change.d.ts +0 -10
  183. package/dist/events/range-change.js +0 -11
  184. package/dist/events/read.d.ts +0 -19
  185. package/dist/events/read.js +0 -11
  186. package/dist/events/reconnect.d.ts +0 -6
  187. package/dist/events/reconnect.js +0 -11
  188. package/dist/events/reject.d.ts +0 -13
  189. package/dist/events/reject.js +0 -11
  190. package/dist/events/relabel.d.ts +0 -6
  191. package/dist/events/relabel.js +0 -11
  192. package/dist/events/remove.d.ts +0 -12
  193. package/dist/events/remove.js +0 -11
  194. package/dist/events/reordered.d.ts +0 -12
  195. package/dist/events/reordered.js +0 -11
  196. package/dist/events/sample-end.d.ts +0 -5
  197. package/dist/events/sample-end.js +0 -6
  198. package/dist/events/sample-start.d.ts +0 -18
  199. package/dist/events/sample-start.js +0 -6
  200. package/dist/events/scrolled.d.ts +0 -32
  201. package/dist/events/scrolled.js +0 -11
  202. package/dist/events/selected.d.ts +0 -12
  203. package/dist/events/selected.js +0 -11
  204. package/dist/events/send.d.ts +0 -18
  205. package/dist/events/send.js +0 -11
  206. package/dist/events/shortcut.d.ts +0 -13
  207. package/dist/events/shortcut.js +0 -11
  208. package/dist/events/sorted.d.ts +0 -15
  209. package/dist/events/sorted.js +0 -11
  210. package/dist/events/split.d.ts +0 -12
  211. package/dist/events/split.js +0 -11
  212. package/dist/events/stop.d.ts +0 -12
  213. package/dist/events/stop.js +0 -6
  214. package/dist/events/strands-fallback.d.ts +0 -13
  215. package/dist/events/strands-fallback.js +0 -11
  216. package/dist/events/terminal-bell.d.ts +0 -13
  217. package/dist/events/terminal-bell.js +0 -6
  218. package/dist/events/terminal-input.d.ts +0 -14
  219. package/dist/events/terminal-input.js +0 -11
  220. package/dist/events/terminal-link.d.ts +0 -15
  221. package/dist/events/terminal-link.js +0 -11
  222. package/dist/events/terminal-resize.d.ts +0 -13
  223. package/dist/events/terminal-resize.js +0 -11
  224. package/dist/events/terminal-restart.d.ts +0 -11
  225. package/dist/events/terminal-restart.js +0 -10
  226. package/dist/events/terminal-title.d.ts +0 -12
  227. package/dist/events/terminal-title.js +0 -11
  228. package/dist/events/toggle.d.ts +0 -15
  229. package/dist/events/toggle.js +0 -11
  230. package/dist/events/tour-ask.d.ts +0 -16
  231. package/dist/events/tour-ask.js +0 -11
  232. package/dist/events/tour-status.d.ts +0 -14
  233. package/dist/events/tour-status.js +0 -11
  234. package/dist/events/typing.d.ts +0 -10
  235. package/dist/events/typing.js +0 -11
@@ -13,7 +13,7 @@ export declare class MixinControllerCheckedInterface {
13
13
  *
14
14
  * Reading gives the real state. Writing always applies, and is a seed and a
15
15
  * correction rather than a claim of ownership: a consumer who wants the
16
- * decision refuses the `helix-before-toggle`.
16
+ * decision refuses the `helix-before-check`.
17
17
  */
18
18
  checked: boolean;
19
19
  /**
@@ -36,7 +36,7 @@ export declare class MixinControllerCheckedInterface {
36
36
  * Requests a change to `checked`, and returns whether it was applied.
37
37
  *
38
38
  * Announces before it acts: a listener calling `preventDefault()` on the
39
- * `helix-before-toggle` refuses the change, and nothing moves.
39
+ * `helix-before-check` refuses the change, and nothing moves.
40
40
  */
41
41
  requestChecked(next: boolean): boolean;
42
42
  /** Requests the opposite of the current state. */
@@ -57,7 +57,7 @@ export declare class MixinControllerCheckedInterface {
57
57
  * `checked` is a seed and a correction rather than a claim: the element applies
58
58
  * its own changes from wherever markup started it, `defaultChecked` is what a
59
59
  * reset returns to, and a consumer takes the decision by refusing the
60
- * `helix-before-toggle`.
60
+ * `helix-before-check`.
61
61
  *
62
62
  * Records `:state(checked)` whenever the element is checked. Styled tiers
63
63
  * select on that rather than on `[checked]`, which is absent until somebody
@@ -1,6 +1,6 @@
1
1
  import { __decorate } from "tslib";
2
2
  import { property } from 'lit/decorators.js';
3
- import { HelixBeforeToggleEvent } from '../../events/events.js';
3
+ import { HelixBeforeCheckEvent } from '../../events/events.js';
4
4
  import { requestChange } from '../../utils/request-change/request-change.js';
5
5
  export const MixinControllerChecked = (Base) => {
6
6
  class CheckedElement extends Base {
@@ -37,7 +37,7 @@ export const MixinControllerChecked = (Base) => {
37
37
  this.checkedState = checked;
38
38
  this.requestUpdate('checked', previous);
39
39
  },
40
- event: (checked) => new HelixBeforeToggleEvent({ checked }),
40
+ event: (checked) => new HelixBeforeCheckEvent({ checked }),
41
41
  host: this,
42
42
  next,
43
43
  });
@@ -2,6 +2,7 @@ import { __decorate } from "tslib";
2
2
  import { html, nothing } from 'lit';
3
3
  import { property, state } from 'lit/decorators.js';
4
4
  import { auditField } from '@fusion.dev/helix-core/audits/name';
5
+ import { internalsOf } from '../../helix-element/helix-element.js';
5
6
  import { hostAria } from '../../utils/host-aria/host-aria.js';
6
7
  const HINT_ID = 'helix-hint';
7
8
  const FEEDBACK_ID = 'helix-feedback';
@@ -55,10 +56,10 @@ export const MixinField = (Base) => {
55
56
  if (this.feedback !== '') {
56
57
  return this.feedback;
57
58
  }
58
- if (!this.validates || !this.touched || this.internals.validity.valid) {
59
+ if (!this.validates || !this.touched || internalsOf(this).validity.valid) {
59
60
  return '';
60
61
  }
61
- return this.internals.validationMessage;
62
+ return internalsOf(this).validationMessage;
62
63
  }
63
64
  get describedBy() {
64
65
  if (this.resolvedFeedback !== '') {
@@ -113,7 +114,7 @@ export const MixinField = (Base) => {
113
114
  }
114
115
  linkHost() {
115
116
  const label = this.partNamed('label');
116
- hostAria(this.internals, {
117
+ hostAria(internalsOf(this), {
117
118
  describedBy: [HINT_ID, FEEDBACK_ID]
118
119
  .map((id) => this.renderRoot.querySelector(`#${id}`))
119
120
  .filter((node) => node !== null),
@@ -129,28 +130,28 @@ export const MixinField = (Base) => {
129
130
  }
130
131
  reportRequired(empty, message, anchor) {
131
132
  if (this.required && empty) {
132
- this.internals.setValidity({ valueMissing: true }, this.valueMissingMessage || message, this.partNamed(anchor) ?? undefined);
133
+ internalsOf(this).setValidity({ valueMissing: true }, this.valueMissingMessage || message, this.partNamed(anchor) ?? undefined);
133
134
  }
134
135
  else {
135
- this.internals.setValidity({});
136
+ internalsOf(this).setValidity({});
136
137
  }
137
138
  this.refreshFeedback();
138
139
  }
139
140
  copyValidity(control) {
140
141
  if (!control.willValidate) {
141
- this.internals.setValidity({});
142
+ internalsOf(this).setValidity({});
142
143
  return;
143
144
  }
144
145
  const message = control.validity.valueMissing && this.valueMissingMessage
145
146
  ? this.valueMissingMessage
146
147
  : control.validationMessage;
147
- this.internals.setValidity(control.validity, message, control);
148
+ internalsOf(this).setValidity(control.validity, message, control);
148
149
  }
149
150
  willUpdate(changed) {
150
151
  super.willUpdate(changed);
151
152
  this.shownFeedback = this.resolvedFeedback;
152
153
  this.toggleState('invalid', this.shownFeedback !== '');
153
- this.internals.ariaInvalid =
154
+ internalsOf(this).ariaInvalid =
154
155
  this.shownFeedback !== '' ? 'true' : this.validates ? 'false' : null;
155
156
  }
156
157
  formResetCallback() {
@@ -1,6 +1,7 @@
1
1
  import { __decorate } from "tslib";
2
2
  import { html, nothing } from 'lit';
3
3
  import { property, state } from 'lit/decorators.js';
4
+ import { internalsOf } from '../../helix-element/helix-element.js';
4
5
  import { hostAria } from '../../utils/host-aria/host-aria.js';
5
6
  export const MixinPickerFeedback = (Base) => {
6
7
  class PickerFeedbackElement extends Base {
@@ -41,13 +42,13 @@ export const MixinPickerFeedback = (Base) => {
41
42
  }
42
43
  willUpdate(changed) {
43
44
  super.willUpdate(changed);
44
- this.internals.ariaInvalid = this.marked ? 'true' : 'false';
45
+ internalsOf(this).ariaInvalid = this.marked ? 'true' : 'false';
45
46
  this.toggleState('invalid', this.marked);
46
47
  }
47
48
  updated(changed) {
48
49
  super.updated(changed);
49
50
  const line = this.partNamed('feedback');
50
- hostAria(this.internals, { describedBy: line ? [line] : [] });
51
+ hostAria(internalsOf(this), { describedBy: line ? [line] : [] });
51
52
  }
52
53
  renderPickerFeedback() {
53
54
  return this.feedback === ''
@@ -1,6 +1,7 @@
1
1
  import { __decorate } from "tslib";
2
2
  import { property } from 'lit/decorators.js';
3
3
  import { PopoverController } from '../../controllers/popover-controller/popover-controller.js';
4
+ import { internalsOf } from '../../helix-element/helix-element.js';
4
5
  import { submitImplicitly } from '../../utils/implicit-submit/implicit-submit.js';
5
6
  import { reportValues } from '../../utils/report-values/report-values.js';
6
7
  import { tabStops } from '../../utils/tab-stops/tab-stops.js';
@@ -125,10 +126,10 @@ export const MixinPickerField = (Base) => {
125
126
  sync() {
126
127
  const answers = this.answers;
127
128
  if (answers === undefined) {
128
- this.internals.setFormValue(this.value);
129
+ internalsOf(this).setFormValue(this.value);
129
130
  }
130
131
  else {
131
- reportValues(this.internals, this.name, answers);
132
+ reportValues(internalsOf(this), this.name, answers);
132
133
  }
133
134
  const control = this.control;
134
135
  if (!control) {
@@ -139,7 +140,7 @@ export const MixinPickerField = (Base) => {
139
140
  this.copyValidity(control);
140
141
  }
141
142
  else {
142
- this.internals.setValidity(fault[0], fault[1], control);
143
+ internalsOf(this).setValidity(fault[0], fault[1], control);
143
144
  }
144
145
  this.refreshFeedback();
145
146
  }
@@ -1,6 +1,7 @@
1
1
  import { __decorate } from "tslib";
2
2
  import { html, nothing } from 'lit';
3
3
  import { property, state } from 'lit/decorators.js';
4
+ import { internalsOf } from '../../helix-element/helix-element.js';
4
5
  import { isPartial, isTwelveHourLayout, segmentKey, segmentLayout, segmentName, segmentRange, segmentsOf, segmentsValue, segmentText, segmentValueText, shownValue, } from '../../utils/date-segments/date-segments.js';
5
6
  import { inlineStep } from '../../utils/inline-step/inline-step.js';
6
7
  import { latinDigits } from '../../utils/number-format/number-format.js';
@@ -279,18 +280,18 @@ export const MixinSegmentedField = (Base) => {
279
280
  this.parts.some((one) => Object.values(one).some((part) => part !== undefined)));
280
281
  const fault = verdictFlags(this.validate());
281
282
  if (partial) {
282
- this.internals.setValidity({ badInput: true }, this.badInputMessage ||
283
+ internalsOf(this).setValidity({ badInput: true }, this.badInputMessage ||
283
284
  formatWords(this, 'incompleteMessage', { kind: this.segmentedKind }), anchor);
284
285
  }
285
286
  else if (this.required && this.value === '') {
286
- this.internals.setValidity({ valueMissing: true }, this.valueMissingMessage ||
287
+ internalsOf(this).setValidity({ valueMissing: true }, this.valueMissingMessage ||
287
288
  formatWords(this, 'emptyMessage', { kind: this.segmentedKind }), anchor);
288
289
  }
289
290
  else if (fault !== null) {
290
- this.internals.setValidity(fault[0], fault[1], anchor);
291
+ internalsOf(this).setValidity(fault[0], fault[1], anchor);
291
292
  }
292
293
  else {
293
- this.internals.setValidity({});
294
+ internalsOf(this).setValidity({});
294
295
  }
295
296
  this.refreshFeedback();
296
297
  }
@@ -21,7 +21,7 @@ export declare class MixinSelectableItemInterface {
21
21
  */
22
22
  protected itemPart: string;
23
23
  /**
24
- * Selects the item and fires `helix-select`. Returns `false` if the item is
24
+ * Selects the item and fires `helix-before-select`. Returns `false` if the item is
25
25
  * disabled or a listener cancels the event.
26
26
  *
27
27
  * `MixinDismissible.dismiss` next door has the same shape and for the same
@@ -1,6 +1,6 @@
1
1
  import { __decorate } from "tslib";
2
2
  import { property } from 'lit/decorators.js';
3
- import { HelixSelectEvent } from '../../events/events.js';
3
+ import { HelixBeforeSelectEvent } from '../../events/events.js';
4
4
  export const MixinSelectableItem = (Base) => {
5
5
  class SelectableItem extends Base {
6
6
  constructor() {
@@ -17,7 +17,7 @@ export const MixinSelectableItem = (Base) => {
17
17
  if (this.disabled) {
18
18
  return false;
19
19
  }
20
- const event = new HelixSelectEvent({ value: this.value });
20
+ const event = new HelixBeforeSelectEvent({ value: this.value });
21
21
  this.dispatchEvent(event);
22
22
  return !event.defaultPrevented;
23
23
  }
@@ -5,7 +5,7 @@
5
5
  * **An app that imports its families with `import()` registers them after
6
6
  * the page has loaded**, each as its chunk arrives, so a container can be
7
7
  * defined and painted while the chunk holding its children is still in
8
- * flight. Measured in the Hartley desktop app on October 14, 2026: Command was
8
+ * flight. Measured in a desktop app on October 14, 2026: Command was
9
9
  * defined 90 ms before Option, and its families arrived over 230 ms.
10
10
  */
11
11
  export declare const QUIET = 500;
@@ -54,7 +54,10 @@ const FIXES = new Map([
54
54
  ['button', 'Give it words, a `label`, or an `aria-label`.'],
55
55
  ['button-group', 'Give it a `label`, or an `aria-label` that says what the buttons are for.'],
56
56
  ['canvas', 'Give it a `label` that says what the board holds, such as "Release plan".'],
57
+ ['carousel', 'Give it a `label` that says what the slides show, such as "Featured products".'],
58
+ ['chat', 'Give it a `label` that names the conversation, such as "Support".'],
57
59
  ['dialog', 'Give it a `label`, or a heading in the `header` slot.'],
60
+ ['drilldown', 'Give it a `label` that says what the pages hold, such as "Settings".'],
58
61
  [
59
62
  'field',
60
63
  'Give it a `label`, an `aria-label`, words in its label, or a `<label for>` that names it.',
@@ -62,14 +65,18 @@ const FIXES = new Map([
62
65
  ['graph', 'Give it a `label` that says what the notes are, such as "Research notes".'],
63
66
  ['lightbox', 'Give it a `label`, such as "Project photos".'],
64
67
  ['list', 'Give it a `label`, or an `aria-label` that says what the rows are.'],
68
+ ['log', 'Give it a `label` that says what the log holds, such as "Build output".'],
65
69
  ['map', 'Give it a `label` that says what the map shows, such as "Stores in Edinburgh".'],
70
+ ['meter', 'Give it a `label`, or words in its `label` slot, that say what it measures.'],
66
71
  ['popover', 'Give it a `label`, or a heading in the panel.'],
67
72
  ['row', 'Give the row words in its default slot, or a label on the icon it holds.'],
68
73
  ['sandbox', 'Give each source pane a `label` or a `name`, which its file tab shows.'],
74
+ ['steps', 'Give it a `label` that says what the steps lead to, such as "Checkout".'],
69
75
  [
70
76
  'table',
71
77
  'Give it a `label`, or put a heading in its `heading` slot, that says what the rows are.',
72
78
  ],
79
+ ['tabs', 'Give it a `label`, or an `aria-labelledby` that names the heading above it.'],
73
80
  [
74
81
  'time-picker',
75
82
  'Give it a `label`, a label in the `label` slot, or an `aria-label` that says what the time is for.',
@@ -78,6 +85,7 @@ const FIXES = new Map([
78
85
  'toggle',
79
86
  'Give it words in its default slot, an `aria-label`, or a label on the icon it holds.',
80
87
  ],
88
+ ['toolbar', 'Give it a `label` that says what its controls act on, such as "Formatting".'],
81
89
  ['tour', 'Give it a `label`, such as "Getting started".'],
82
90
  ['tree', 'Give it a `label` that says what it holds, such as "Files".'],
83
91
  ['video', 'Give it a `label` that says what the video shows, such as "Product tour".'],
@@ -113,12 +121,15 @@ export const auditName = (host, control, fix, also, shown) => {
113
121
  return;
114
122
  }
115
123
  const placeholder = [host, inner].some((one) => one?.getAttribute('placeholder')?.trim());
124
+ const fallback = host.fallbackLabel;
116
125
  const sentence = FIXES.get(fix) ?? fix;
117
126
  reportRuntime({
118
127
  kind: 'missing-name',
119
128
  message: placeholder
120
129
  ? `<${host.localName}> is named only by its placeholder, which is gone once a person types. ${sentence}`
121
- : `<${host.localName}> has no accessible name, so a screen reader announces it by its role alone. ${sentence}`,
130
+ : typeof fallback === 'string' && fallback.trim() !== ''
131
+ ? `<${host.localName}> has no accessible name of its own, only its built-in "${fallback}", which says nothing about this one. ${sentence}`
132
+ : `<${host.localName}> has no accessible name, so a screen reader announces it by its role alone. ${sentence}`,
122
133
  tag: host.localName,
123
134
  });
124
135
  });
@@ -1,4 +1,6 @@
1
+ import { ariaChord } from '../chord/chord.js';
1
2
  import { nameText } from '../name-text/name-text.js';
3
+ import { onApple } from '../platform/platform.js';
2
4
  const KEY = Symbol.for('fusion.helix.controls');
3
5
  const globals = globalThis;
4
6
  if (globals[KEY] === undefined) {
@@ -90,7 +92,10 @@ export const controlReachable = (element) => {
90
92
  : true;
91
93
  };
92
94
  const keysOf = (entry) => {
93
- const written = [entry.element.getAttribute('aria-keyshortcuts'), entry.keys?.()]
95
+ const registered = [...registry.shortcuts]
96
+ .filter((shortcut) => shortcut.target === entry.element)
97
+ .map((shortcut) => ariaChord(shortcut.keys(), onApple()));
98
+ const written = [entry.element.getAttribute('aria-keyshortcuts'), entry.keys?.(), ...registered]
94
99
  .filter((list) => typeof list === 'string')
95
100
  .flatMap((list) => list.split(/\s+/))
96
101
  .filter((one) => one !== '')
@@ -30,7 +30,7 @@ export interface DrawIconOptions {
30
30
  * the thing static analysis has to read.
31
31
  *
32
32
  * `data-glyph` rather than a class, because the sizing lives in
33
- * `helix/styled/src/shared/glyph/glyph.css` and a component's own `--icon-size`
33
+ * the shared glyph stylesheet and a component's own `--icon-size`
34
34
  * declarations have to keep working untouched: the variable was read by
35
35
  * `helix-icon`, and now it is read by the rule that sheet carries. Without it
36
36
  * every one of those declarations would go quietly dead and every mark in six
@@ -37,7 +37,7 @@ export declare const followLink: (document: Document, link: LinkTarget, modifier
37
37
  * Runs `then` once a link option has been followed, for an owner whose panel
38
38
  * closes when a choice is made: Select and Combobox close on the listbox's
39
39
  * change, and a link changes nothing, so they hear the option's own
40
- * `helix-select` instead.
40
+ * `helix-before-select` instead.
41
41
  *
42
42
  * After every listener has had the event, so a page that cancels it, to route
43
43
  * there itself, keeps the panel as it was, the way the option keeps the
@@ -71,6 +71,11 @@ export type RuntimeKind =
71
71
  | 'not-a-plot'
72
72
  /** The browser refused picture in picture. */
73
73
  | 'picture-in-picture-refused'
74
+ /**
75
+ * React has a root on the page and no element found the props it holds, so React's handlers
76
+ * and object properties never arrive. Development builds only.
77
+ */
78
+ | 'react-props-missing'
74
79
  /** A Grid's `min` is no length it can write, so the grid lays out by its column count. */
75
80
  | 'refused-length'
76
81
  /** A React handler prop is a removed callback, which never ran from JSX. Development builds only. */
@@ -10,9 +10,12 @@
10
10
  * consumer's markup after upgrading is one whose output a React consumer's
11
11
  * hydration disagrees with.
12
12
  *
13
- * **Measured 28 Aug 2026 against React 19.2.8.** Four
14
- * families were server-rendered as React emits them and hydrated with the
15
- * element definitions loaded either side of `hydrateRoot`:
13
+ * **Measured against React 19.3.1 on October 25, 2026**, with an element that
14
+ * writes `aria-expanded` onto its child as it connects, server-rendered and
15
+ * hydrated with its definition loaded either side of `hydrateRoot`: a
16
+ * mismatch in both orders, and the same state written as a property clean in
17
+ * both. The families were first measured on 28 Aug 2026, on 19.2.8, as React
18
+ * emits them and while two of them still wrote the attribute:
16
19
  *
17
20
  * ```
18
21
  * case writes to trigger hydration mismatch
@@ -6,6 +6,11 @@
6
6
  * how loaded the runner is, and a loaded runner eats 400ms. One did, on a green
7
7
  * branch, and blocked a merge that had nothing wrong with it. A bigger margin is
8
8
  * the same bug at a lower rate. A spec passes its own `now` and `setTimer`.
9
+ *
10
+ * Bun 1.1.43, which this workspace pinned when this was written, has
11
+ * `jest.useFakeTimers()` without `jest.advanceTimersByTime`, so there was
12
+ * nothing to advance a faked timer with. Bun 1.4.3 has it, and the clock stays
13
+ * a value anyway: it costs nothing and needs no global faked.
9
14
  */
10
15
  export interface Clock {
11
16
  clearTimer: (timer: ReturnType<typeof setTimeout>) => void;
package/dist/version.d.ts CHANGED
@@ -1,9 +1,8 @@
1
1
  /**
2
2
  * The version of the package this file ships in.
3
3
  *
4
- * **Written by `fusion/scripts/version.mjs`** wherever it writes the package's
5
- * `package.json`, and stamped back into the repository beside it after a
6
- * release, so the two never disagree; a spec beside this holds them to it.
7
- * Nothing else in the running code knows which release it is.
4
+ * **The release writes this value** each time it writes the package's
5
+ * `package.json`, so the two always agree. Nothing else in the running code
6
+ * knows which release it is.
8
7
  */
9
- export declare const VERSION = "0.223.1";
8
+ export declare const VERSION = "0.225.0";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = '0.223.1';
1
+ export const VERSION = '0.225.0';
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@fusion.dev/helix-core",
3
3
  "description": "Helix element primitives: base classes, mixins, decorators, utilities.",
4
- "version": "0.223.1",
4
+ "version": "0.225.0",
5
5
  "license": "MIT",
6
- "author": "Ross Sheppard <ross.sheppard@fusion.dev>",
6
+ "author": "Fusion Development Group",
7
7
  "repository": {
8
8
  "directory": "helix/core",
9
9
  "type": "git",
@@ -81,12 +81,12 @@
81
81
  "bugs": "https://github.com/project-fusion/fusion/issues",
82
82
  "dependencies": {
83
83
  "@floating-ui/dom": "^1.8.0",
84
- "@fusion.dev/helix-icons": "0.223.1",
84
+ "@fusion.dev/helix-icons": "0.225.0",
85
85
  "tslib": "^2.8.1"
86
86
  },
87
87
  "devDependencies": {
88
- "@fusion.dev/helix-cem": "0.223.1",
89
- "@fusion.dev/helix-testing": "0.223.1",
88
+ "@fusion.dev/helix-cem": "0.225.0",
89
+ "@fusion.dev/helix-testing": "0.225.0",
90
90
  "@lit-labs/ssr": "^4.1.0",
91
91
  "lit": "^3.2.1"
92
92
  },
@@ -139,6 +139,6 @@
139
139
  "lit": "^3.2.1"
140
140
  },
141
141
  "publishConfig": {
142
- "access": "restricted"
142
+ "access": "public"
143
143
  }
144
144
  }
@@ -1,12 +0,0 @@
1
- /**
2
- * A reader acted on a row: Enter on a list row, or a press in a list that
3
- * selects nothing. Sent from the row, so `target` is the row acted on.
4
- *
5
- * Carries nothing, because the row is the whole of the answer. Not cancelable:
6
- * a row with a link follows it and sends nothing, so there is no default left
7
- * to refuse.
8
- */
9
- export declare class HelixActionEvent extends Event {
10
- static readonly eventName = "helix-action";
11
- constructor();
12
- }
@@ -1,6 +0,0 @@
1
- export class HelixActionEvent extends Event {
2
- static { this.eventName = 'helix-action'; }
3
- constructor() {
4
- super(HelixActionEvent.eventName, { bubbles: true, cancelable: false, composed: true });
5
- }
6
- }
@@ -1,12 +0,0 @@
1
- import type { AuraFallbackDetail } from './details.js';
2
- /**
3
- * An aura stopped drawing its shader and shows its gradient, and says why.
4
- *
5
- * Sent each time it falls back, from the aura, which then matches
6
- * `:state(fallback)` until it draws again. Not cancelable: there is nothing
7
- * left to refuse.
8
- */
9
- export declare class HelixAuraFallbackEvent extends CustomEvent<AuraFallbackDetail> {
10
- static readonly eventName = "helix-aura-fallback";
11
- constructor(detail: AuraFallbackDetail);
12
- }
@@ -1,11 +0,0 @@
1
- export class HelixAuraFallbackEvent extends CustomEvent {
2
- static { this.eventName = 'helix-aura-fallback'; }
3
- constructor(detail) {
4
- super(HelixAuraFallbackEvent.eventName, {
5
- bubbles: true,
6
- cancelable: false,
7
- composed: true,
8
- detail,
9
- });
10
- }
11
- }
@@ -1,13 +0,0 @@
1
- import type { BandDetail } from './details.js';
2
- /**
3
- * A reading moved into another band: a meter whose value crossed `low`,
4
- * `high` or `optimum` into `good`, `fair` or `poor`.
5
- *
6
- * Sent once for each crossing, not on every value, so a listener can say the
7
- * change aloud or recolor something else on the page. Not cancelable, since
8
- * the reading has already moved. Bubbles and is composed.
9
- */
10
- export declare class HelixBandEvent extends CustomEvent<BandDetail> {
11
- static readonly eventName = "helix-band";
12
- constructor(detail: BandDetail);
13
- }
@@ -1,11 +0,0 @@
1
- export class HelixBandEvent extends CustomEvent {
2
- static { this.eventName = 'helix-band'; }
3
- constructor(detail) {
4
- super(HelixBandEvent.eventName, {
5
- bubbles: true,
6
- cancelable: false,
7
- composed: true,
8
- detail,
9
- });
10
- }
11
- }
@@ -1,6 +0,0 @@
1
- import type { ChangeDetail } from './details.js';
2
- /** A pane is about to collapse or reopen, and can be refused. */
3
- export declare class HelixBeforeCollapseEvent extends CustomEvent<ChangeDetail> {
4
- static readonly eventName = "helix-before-collapse";
5
- constructor(detail: ChangeDetail);
6
- }
@@ -1,11 +0,0 @@
1
- export class HelixBeforeCollapseEvent extends CustomEvent {
2
- static { this.eventName = 'helix-before-collapse'; }
3
- constructor(detail) {
4
- super(HelixBeforeCollapseEvent.eventName, {
5
- bubbles: true,
6
- cancelable: true,
7
- composed: true,
8
- detail,
9
- });
10
- }
11
- }
@@ -1,6 +0,0 @@
1
- import type { ChangeDetail } from './details.js';
2
- /** Source is about to be edited, and can be refused. */
3
- export declare class HelixBeforeEditEvent extends CustomEvent<ChangeDetail> {
4
- static readonly eventName = "helix-before-edit";
5
- constructor(detail: ChangeDetail);
6
- }
@@ -1,11 +0,0 @@
1
- export class HelixBeforeEditEvent extends CustomEvent {
2
- static { this.eventName = 'helix-before-edit'; }
3
- constructor(detail) {
4
- super(HelixBeforeEditEvent.eventName, {
5
- bubbles: true,
6
- cancelable: true,
7
- composed: true,
8
- detail,
9
- });
10
- }
11
- }
@@ -1,17 +0,0 @@
1
- import type { MoveDetail } from './details.js';
2
- /**
3
- * Cards are about to move, and can be refused.
4
- *
5
- * **This is the controlled half, the way `helix-before-open` is for a
6
- * dialog.** A board moves its own cards by default, writing `x` and `y` onto
7
- * each one the way an input writes its own value. A consumer who keeps the
8
- * positions in their own state calls `preventDefault()` here, writes what the
9
- * detail says into that state, and renders the cards where it puts them.
10
- *
11
- * Sent for every step of a drag, so a controlled board follows the pointer
12
- * rather than jumping on the drop.
13
- */
14
- export declare class HelixBeforeMoveEvent extends CustomEvent<MoveDetail> {
15
- static readonly eventName = "helix-before-move";
16
- constructor(detail: MoveDetail);
17
- }
@@ -1,11 +0,0 @@
1
- export class HelixBeforeMoveEvent extends CustomEvent {
2
- static { this.eventName = 'helix-before-move'; }
3
- constructor(detail) {
4
- super(HelixBeforeMoveEvent.eventName, {
5
- bubbles: true,
6
- cancelable: true,
7
- composed: true,
8
- detail,
9
- });
10
- }
11
- }
@@ -1,13 +0,0 @@
1
- import type { ChangeDetail } from './details.js';
2
- /**
3
- * A sandbox's panel is about to change height, and can be refused.
4
- *
5
- * The sibling of `helix-before-split`, and named for the divider rather than for
6
- * the axis because a reader binding one of the two is choosing which divider they
7
- * care about. `value` is pixels here and a percentage there, which is what each
8
- * property already publishes.
9
- */
10
- export declare class HelixBeforePanelResizeEvent extends CustomEvent<ChangeDetail> {
11
- static readonly eventName = "helix-before-panel-resize";
12
- constructor(detail: ChangeDetail);
13
- }
@@ -1,11 +0,0 @@
1
- export class HelixBeforePanelResizeEvent extends CustomEvent {
2
- static { this.eventName = 'helix-before-panel-resize'; }
3
- constructor(detail) {
4
- super(HelixBeforePanelResizeEvent.eventName, {
5
- bubbles: true,
6
- cancelable: true,
7
- composed: true,
8
- detail,
9
- });
10
- }
11
- }
@@ -1,13 +0,0 @@
1
- import type { PasteDetail } from './details.js';
2
- /**
3
- * Cards are about to be pasted onto a board, and can be refused.
4
- *
5
- * The board adds the cards and connections in the detail by default, as
6
- * `helix-canvas-node` and `helix-canvas-edge` elements. A page that renders
7
- * its cards from its own state calls `preventDefault()` here and adds the
8
- * detail's document to that state, through `fromJsonCanvas`.
9
- */
10
- export declare class HelixBeforePasteEvent extends CustomEvent<PasteDetail> {
11
- static readonly eventName = "helix-before-paste";
12
- constructor(detail: PasteDetail);
13
- }
@@ -1,11 +0,0 @@
1
- export class HelixBeforePasteEvent extends CustomEvent {
2
- static { this.eventName = 'helix-before-paste'; }
3
- constructor(detail) {
4
- super(HelixBeforePasteEvent.eventName, {
5
- bubbles: true,
6
- cancelable: true,
7
- composed: true,
8
- detail,
9
- });
10
- }
11
- }