@fusion.dev/helix-headless 0.0.0-dev → 0.0.3

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 (210) hide show
  1. package/custom-elements.json +4513 -4483
  2. package/dist/accordion/item/accordion-item.d.ts +13 -15
  3. package/dist/accordion/item/accordion-item.js +15 -17
  4. package/dist/announcement/root/announcement-root.d.ts +7 -25
  5. package/dist/announcement/root/announcement-root.js +7 -20
  6. package/dist/app-header/root/app-header-root.d.ts +10 -17
  7. package/dist/app-header/root/app-header-root.js +9 -18
  8. package/dist/avatar/group/avatar-group.d.ts +10 -19
  9. package/dist/avatar/group/avatar-group.js +12 -17
  10. package/dist/avatar/root/avatar-root.d.ts +8 -8
  11. package/dist/avatar/root/avatar-root.js +19 -20
  12. package/dist/badge/root/badge-root.d.ts +6 -6
  13. package/dist/badge/root/badge-root.js +13 -13
  14. package/dist/bar-chart/root/bar-chart-root.d.ts +21 -29
  15. package/dist/bar-chart/root/bar-chart-root.js +42 -57
  16. package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +12 -18
  17. package/dist/breadcrumbs/breadcrumb/breadcrumb.js +13 -16
  18. package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +9 -28
  19. package/dist/breadcrumbs/root/breadcrumbs-root.js +9 -28
  20. package/dist/button/root/button-root.d.ts +84 -94
  21. package/dist/button/root/button-root.js +82 -92
  22. package/dist/callout/root/callout-root.d.ts +4 -5
  23. package/dist/carousel/root/carousel-root.d.ts +59 -71
  24. package/dist/carousel/root/carousel-root.js +73 -101
  25. package/dist/chat/composer/chat-composer.d.ts +29 -33
  26. package/dist/chat/composer/chat-composer.js +40 -44
  27. package/dist/chat/message/chat-message.d.ts +25 -25
  28. package/dist/chat/message/chat-message.js +26 -26
  29. package/dist/chat/root/chat-root.d.ts +28 -41
  30. package/dist/chat/root/chat-root.js +27 -40
  31. package/dist/checkbox/root/checkbox-root.d.ts +10 -12
  32. package/dist/checkbox/root/checkbox-root.js +29 -35
  33. package/dist/checkbox-group/root/checkbox-group-root.d.ts +32 -45
  34. package/dist/checkbox-group/root/checkbox-group-root.js +53 -79
  35. package/dist/code-block/root/code-block-root.d.ts +3 -4
  36. package/dist/code-block/root/code-block-root.js +8 -12
  37. package/dist/color-input/root/color-input-root.d.ts +36 -37
  38. package/dist/color-input/root/color-input-root.js +29 -34
  39. package/dist/color-picker/color.d.ts +7 -8
  40. package/dist/color-picker/color.js +7 -8
  41. package/dist/color-picker/root/color-picker-root.d.ts +55 -57
  42. package/dist/color-picker/root/color-picker-root.js +60 -64
  43. package/dist/combobox/root/combobox-root.d.ts +53 -58
  44. package/dist/combobox/root/combobox-root.js +85 -94
  45. package/dist/command/root/command-root.d.ts +8 -8
  46. package/dist/command/root/command-root.js +29 -33
  47. package/dist/copy-button/root/copy-button-root.d.ts +21 -24
  48. package/dist/copy-button/root/copy-button-root.js +25 -35
  49. package/dist/data-table/root/data-table-root.d.ts +77 -76
  50. package/dist/data-table/root/data-table-root.js +95 -84
  51. package/dist/data-table/root/order.d.ts +2 -2
  52. package/dist/data-table/root/order.js +1 -3
  53. package/dist/date-input/root/date-input-root.d.ts +88 -93
  54. package/dist/date-input/root/date-input-root.js +147 -158
  55. package/dist/date-picker/root/date-picker-root.d.ts +75 -83
  56. package/dist/date-picker/root/date-picker-root.js +120 -143
  57. package/dist/dialog/root/dialog-root.d.ts +41 -24
  58. package/dist/dialog/root/dialog-root.js +47 -24
  59. package/dist/divider/root/divider-root.d.ts +5 -6
  60. package/dist/divider/root/divider-root.js +4 -5
  61. package/dist/donut-chart/root/donut-chart-root.d.ts +22 -25
  62. package/dist/donut-chart/root/donut-chart-root.js +37 -51
  63. package/dist/drawer/root/drawer-root.d.ts +24 -29
  64. package/dist/drawer/root/drawer-root.js +15 -22
  65. package/dist/drilldown/item/drilldown-item.d.ts +14 -14
  66. package/dist/drilldown/item/drilldown-item.js +24 -26
  67. package/dist/drilldown/root/drilldown-root.d.ts +8 -10
  68. package/dist/drilldown/root/drilldown-root.js +6 -7
  69. package/dist/element-events.generated.js +1 -1
  70. package/dist/file-input/root/file-input-root.d.ts +20 -24
  71. package/dist/file-input/root/file-input-root.js +42 -57
  72. package/dist/format-date/root/format-date-root.js +1 -1
  73. package/dist/heatmap/root/buckets.d.ts +8 -8
  74. package/dist/heatmap/root/buckets.js +8 -8
  75. package/dist/heatmap/root/heatmap-root.d.ts +57 -63
  76. package/dist/heatmap/root/heatmap-root.js +72 -83
  77. package/dist/icon/root/icon-root.d.ts +4 -4
  78. package/dist/icon/root/icon-root.js +9 -9
  79. package/dist/icon-button/root/icon-button-root.d.ts +4 -6
  80. package/dist/icon-button/root/icon-button-root.js +4 -6
  81. package/dist/image/root/image-root.d.ts +49 -59
  82. package/dist/image/root/image-root.js +55 -65
  83. package/dist/index.d.ts +5 -5
  84. package/dist/index.js +5 -5
  85. package/dist/input/root/input-root.d.ts +61 -85
  86. package/dist/input/root/input-root.js +79 -106
  87. package/dist/kbd/root/kbd-root.d.ts +8 -7
  88. package/dist/kbd/root/kbd-root.js +71 -11
  89. package/dist/legend/root/legend-root.d.ts +1 -1
  90. package/dist/legend/root/legend-root.js +4 -5
  91. package/dist/line-chart/root/line-chart-root.d.ts +26 -30
  92. package/dist/line-chart/root/line-chart-root.js +10 -10
  93. package/dist/list/item/list-item.d.ts +14 -18
  94. package/dist/list/item/list-item.js +18 -22
  95. package/dist/list/root/list-root.d.ts +4 -4
  96. package/dist/list/root/list-root.js +3 -3
  97. package/dist/listbox/root/listbox-root.d.ts +31 -58
  98. package/dist/listbox/root/listbox-root.js +66 -109
  99. package/dist/megamenu/root/megamenu-root.d.ts +34 -35
  100. package/dist/megamenu/root/megamenu-root.js +53 -58
  101. package/dist/menu/item/menu-item.d.ts +39 -53
  102. package/dist/menu/item/menu-item.js +50 -64
  103. package/dist/menu/root/menu-root.d.ts +30 -40
  104. package/dist/menu/root/menu-root.js +49 -82
  105. package/dist/meter/root/meter-root.d.ts +49 -53
  106. package/dist/meter/root/meter-root.js +22 -27
  107. package/dist/navigation/root/navigation-root.js +11 -19
  108. package/dist/notifications/notification/notification.d.ts +16 -22
  109. package/dist/notifications/notification/notification.js +21 -27
  110. package/dist/notifications/root/notifications-root.d.ts +31 -39
  111. package/dist/notifications/root/notifications-root.js +41 -52
  112. package/dist/number-input/root/number-input-root.d.ts +31 -33
  113. package/dist/number-input/root/number-input-root.js +37 -39
  114. package/dist/option/root/option-root.d.ts +73 -74
  115. package/dist/option/root/option-root.js +62 -64
  116. package/dist/outline/root/outline-root.d.ts +38 -44
  117. package/dist/outline/root/outline-root.js +66 -82
  118. package/dist/pagination/root/pagination-root.d.ts +87 -92
  119. package/dist/pagination/root/pagination-root.js +116 -123
  120. package/dist/pagination/size/pagination-size.d.ts +31 -50
  121. package/dist/pagination/size/pagination-size.js +35 -55
  122. package/dist/pagination/summary/pagination-summary.d.ts +12 -12
  123. package/dist/pagination/summary/pagination-summary.js +18 -18
  124. package/dist/pin-input/root/pin-input-root.d.ts +53 -70
  125. package/dist/pin-input/root/pin-input-root.js +74 -94
  126. package/dist/popover/root/popover-root.d.ts +15 -20
  127. package/dist/popover/root/popover-root.js +19 -36
  128. package/dist/progress/root/progress-root.d.ts +12 -14
  129. package/dist/progress/root/progress-root.js +22 -25
  130. package/dist/qr-code/root/qr-code-root.d.ts +11 -11
  131. package/dist/qr-code/root/qr-code-root.js +12 -14
  132. package/dist/radio/group/radio-group.js +19 -26
  133. package/dist/radio/root/radio-root.d.ts +12 -13
  134. package/dist/radio/root/radio-root.js +12 -13
  135. package/dist/rating/root/rating-root.d.ts +25 -30
  136. package/dist/rating/root/rating-root.js +43 -50
  137. package/dist/scroll-area/root/scroll-area-root.d.ts +11 -14
  138. package/dist/scroll-area/root/scroll-area-root.js +39 -33
  139. package/dist/select/root/select-root.d.ts +7 -12
  140. package/dist/select/root/select-root.js +40 -55
  141. package/dist/slider/root/slider-root.d.ts +53 -60
  142. package/dist/slider/root/slider-root.js +74 -85
  143. package/dist/sparkline/root/sparkline-root.d.ts +43 -47
  144. package/dist/sparkline/root/sparkline-root.js +23 -32
  145. package/dist/speed-dial/item/speed-dial-item.d.ts +6 -6
  146. package/dist/speed-dial/item/speed-dial-item.js +9 -9
  147. package/dist/speed-dial/root/speed-dial-root.d.ts +21 -25
  148. package/dist/speed-dial/root/speed-dial-root.js +32 -40
  149. package/dist/splitter/root/splitter-root.d.ts +98 -111
  150. package/dist/splitter/root/splitter-root.js +96 -123
  151. package/dist/stat/root/stat-root.d.ts +2 -7
  152. package/dist/stat/root/stat-root.js +0 -5
  153. package/dist/steps/step/step.d.ts +19 -24
  154. package/dist/steps/step/step.js +27 -32
  155. package/dist/switch/root/switch-root.js +2 -2
  156. package/dist/table/column/table-column.d.ts +54 -60
  157. package/dist/table/column/table-column.js +95 -68
  158. package/dist/table/root/table-root.d.ts +5 -6
  159. package/dist/table/root/table-root.js +7 -10
  160. package/dist/tabs/panel/tab-panel.d.ts +21 -25
  161. package/dist/tabs/panel/tab-panel.js +25 -29
  162. package/dist/tabs/root/tabs-root.d.ts +25 -34
  163. package/dist/tabs/root/tabs-root.js +22 -28
  164. package/dist/tabs/tab/tab.d.ts +12 -12
  165. package/dist/tabs/tab/tab.js +19 -20
  166. package/dist/textarea/root/textarea-root.d.ts +36 -36
  167. package/dist/textarea/root/textarea-root.js +43 -47
  168. package/dist/time-input/root/time-input-root.d.ts +58 -68
  169. package/dist/time-input/root/time-input-root.js +62 -77
  170. package/dist/time-picker/root/time-picker-root.d.ts +73 -79
  171. package/dist/time-picker/root/time-picker-root.js +72 -84
  172. package/dist/timeline/item/timeline-item.d.ts +8 -11
  173. package/dist/timeline/item/timeline-item.js +8 -11
  174. package/dist/timeline/root/timeline-root.d.ts +5 -7
  175. package/dist/timeline/root/timeline-root.js +5 -7
  176. package/dist/toast/item/toast-item.d.ts +9 -27
  177. package/dist/toast/item/toast-item.js +19 -41
  178. package/dist/toast/root/toast-root.d.ts +10 -14
  179. package/dist/toast/root/toast-root.js +4 -5
  180. package/dist/toggle/group/toggle-group.d.ts +6 -15
  181. package/dist/toggle/group/toggle-group.js +21 -36
  182. package/dist/toggle/root/toggle-root.d.ts +26 -27
  183. package/dist/toggle/root/toggle-root.js +30 -31
  184. package/dist/toolbar/root/toolbar-root.d.ts +7 -10
  185. package/dist/toolbar/root/toolbar-root.js +10 -14
  186. package/dist/tooltip/root/tooltip-root.d.ts +52 -59
  187. package/dist/tooltip/root/tooltip-root.js +98 -93
  188. package/dist/tour/root/tour-root.d.ts +19 -23
  189. package/dist/tour/root/tour-root.js +31 -41
  190. package/dist/tour/stop/tour-stop.d.ts +14 -15
  191. package/dist/tour/stop/tour-stop.js +31 -34
  192. package/dist/tree/item/tree-item.d.ts +30 -35
  193. package/dist/tree/item/tree-item.js +43 -55
  194. package/dist/tree/root/tree-root.d.ts +7 -10
  195. package/dist/tree/root/tree-root.js +33 -42
  196. package/dist/trend/root/trend-root.d.ts +3 -5
  197. package/dist/trend/root/trend-root.js +5 -9
  198. package/dist/video/root/video-root.d.ts +100 -124
  199. package/dist/video/root/video-root.js +142 -176
  200. package/dist/video-playlist/item/video-playlist-item.d.ts +16 -16
  201. package/dist/video-playlist/item/video-playlist-item.js +24 -24
  202. package/dist/video-playlist/menu/video-playlist-menu.d.ts +5 -8
  203. package/dist/video-playlist/menu/video-playlist-menu.js +20 -29
  204. package/dist/video-playlist/root/video-playlist-root.d.ts +16 -11
  205. package/dist/video-playlist/root/video-playlist-root.js +21 -25
  206. package/dist/virtual-list/root/virtual-list-root.d.ts +8 -12
  207. package/dist/virtual-list/root/virtual-list-root.js +11 -16
  208. package/jsx.d.ts +9797 -12561
  209. package/package.json +6 -6
  210. package/vue.d.ts +2684 -3228
@@ -33,19 +33,12 @@ import { property, state } from 'lit/decorators.js';
33
33
  * here guesses. What this adds is the anchor, so `reportValidity` points the
34
34
  * bubble at the input rather than at the host.
35
35
  *
36
- * `pattern`, `minlength` and `maxlength` are forwarded with them. They were
37
- * promised by this paragraph and did not exist, so a consumer following the
38
- * sentence wrote an attribute on the host that reached no input and constrained
39
- * nothing: the field looked as though it were checked and was not.
36
+ * `pattern`, `minlength` and `maxlength` are forwarded with them.
40
37
  *
41
- * **`clearable` and `reveal` are the field's, not the consumer's.** The `end`
42
- * slot used to be the answer to both, which meant every consumer of
43
- * `type="search"` built the same button and every consumer of
44
- * `type="password"` either built the same toggle or shipped a field a reader
45
- * cannot check what they typed into. Neither is a slot's worth of variation:
46
- * one empties the value, the other flips the type, and both want the same
47
- * position, the same size and the same disabled behavior. The slot stays for
48
- * what actually varies, a unit or a prefix.
38
+ * **`clearable` and `reveal` are the field's, not the consumer's.** Neither is
39
+ * a slot's worth of variation: one empties the value, the other flips the type,
40
+ * and both want the same position, the same size and the same disabled
41
+ * behavior. The `end` slot stays for what actually varies, a unit or a prefix.
49
42
  *
50
43
  * Both opt in rather than following from `type`, and are booleans that default
51
44
  * to false. A Lit boolean property that defaults to *true* cannot be turned off
@@ -72,7 +65,6 @@ import { property, state } from 'lit/decorators.js';
72
65
  * @csspart feedback - What is wrong with it.
73
66
  * @csspart field - The box holding everything.
74
67
  * @csspart hint - Help under the field, while nothing is wrong.
75
- * @csspart icon - A glyph this component draws.
76
68
  * @csspart label - The question, over the field.
77
69
  * @csspart reveal - The button that shows and hides a password.
78
70
  */
@@ -96,54 +88,6 @@ let HelixHeadlessInput = class HelixHeadlessInput extends MixinControllerValue(M
96
88
  * a token like `email` or `bday` to ask for autofill, or to `off` to refuse.
97
89
  */
98
90
  this.autocomplete = '';
99
- /**
100
- * Shown while the field is empty.
101
- *
102
- * Not a label: it goes when typing starts.
103
- */
104
- this.placeholder = '';
105
- /**
106
- * Whether the field refuses input while still submitting its value.
107
- *
108
- * **`readonly`, which is the platform's spelling, and it was `read-only`
109
- * until 28 Aug 2026.** A camelCase property needs an explicit `attribute`
110
- * and the library had been answering that question two ways: thirteen
111
- * attributes kept the name HTML uses (`crossorigin`, `maxlength`,
112
- * `formnovalidate`, `dirname` and the rest) and five dash-cased a word the
113
- * platform writes as one. `readonly` was the only one on both lists, this
114
- * spelling on `Rating` and `read-only` on the eight other fields, so one
115
- * library shipped both and each was inert on the other's families.
116
- *
117
- * The cost of the dash-cased form is the one this repository keeps writing
118
- * down about attributes: nothing warns. `<helix-input readonly>` is what
119
- * anybody who has written HTML types, it parsed to no property at all, and
120
- * the field stayed editable with no error anywhere. Measured before the
121
- * rename: `readOnly` came back `false`.
122
- *
123
- * Taken now for the reason [#213](../../../../../docs/19-queue.md) gives
124
- * about the part it renamed for the same kind of reason: there is no
125
- * `helix-v` tag, so no consumer is holding the old spelling, and this is free
126
- * today and a deprecation after the first release.
127
- * `check:attribute-names` holds it from here.
128
- */
129
- this.readOnly = false;
130
- /**
131
- * What the field accepts, which decides the keyboard and the validation.
132
- *
133
- * **Not reflected**, and it was. Reflection exists so a selector can reach a
134
- * value, and no stylesheet in this repository selects on `type`: what it did
135
- * instead was write `type="text"` onto every `<helix-input>` ever rendered,
136
- * an attribute no consumer's markup had. That is precisely the fault `Button`
137
- * had with `href`, `target` and `rel`, written up in the area rules as the
138
- * reason the rule exists, and this was the last property in the library still
139
- * doing it. Audited: ten reflected attributes have no selector anywhere, and
140
- * this is the only one of them with a value that puts itself on the host.
141
- *
142
- * Nothing reads it from the attribute either. The real `<input>` inside takes
143
- * it as a property binding, which is what makes the keyboard and the
144
- * validation follow.
145
- */
146
- this.type = 'text';
147
91
  /**
148
92
  * Whether the field offers a button that empties it.
149
93
  *
@@ -158,20 +102,36 @@ let HelixHeadlessInput = class HelixHeadlessInput extends MixinControllerValue(M
158
102
  */
159
103
  this.clearLabel = 'Clear';
160
104
  /**
161
- * Whether a password field offers a toggle that shows what was typed.
105
+ * A regular expression the value has to match, as the platform reads it.
162
106
  *
163
- * Ignored on every other type. A reveal on an email field would be a button
164
- * that does nothing visible, and guarding it here rather than asking the
165
- * consumer not to means the property can be set once on a component that
166
- * changes type.
107
+ * Forwarded rather than checked here, which is the whole reason validity is
108
+ * the platform's: the browser knows what a `pattern` means, anchors it at both
109
+ * ends, and produces the message in the reader's own language.
167
110
  */
168
- this.reveal = false;
111
+ this.pattern = '';
169
112
  /**
170
- * What the reveal toggle is called.
113
+ * Shown while the field is empty.
171
114
  *
172
- * The state is `aria-pressed`, not this.
115
+ * Not a label: it goes when typing starts.
173
116
  */
174
- this.revealLabel = 'Show password';
117
+ this.placeholder = '';
118
+ /**
119
+ * Whether the field refuses input while still submitting its value.
120
+ *
121
+ * **The attribute is `readonly`, which is the platform's spelling.** A
122
+ * camelCase property needs an explicit `attribute`, and dash-casing a word
123
+ * HTML writes as one costs what an attribute always costs here: nothing
124
+ * warns. `<helix-input readonly>` is what anybody who has written HTML types;
125
+ * against `read-only` it parses to no property at all, and the field stays
126
+ * editable with no error anywhere. Measured on the dash-cased form, `readOnly`
127
+ * came back `false`.
128
+ *
129
+ * A part was renamed for
130
+ * the same kind of reason: there is no `helix-v` tag, so no consumer is
131
+ * holding the old spelling, and this is free today and a deprecation after
132
+ * the first release.
133
+ */
134
+ this.readOnly = false;
175
135
  /**
176
136
  * Whether the password is currently showing.
177
137
  *
@@ -196,8 +156,7 @@ let HelixHeadlessInput = class HelixHeadlessInput extends MixinControllerValue(M
196
156
  beside the one the mixin announces: measured in Chrome 148, one keystroke
197
157
  produced `helix-before-change`, this element's own `input`, and the inner
198
158
  control's, so `onInput` ran twice and one of the two carried the value
199
- from before the change. `handleChange` two methods down has always done
200
- this; the pair was half applied. */
159
+ from before the change. `handleChange` two methods down does the same. */
201
160
  event.stopPropagation();
202
161
  const control = event.target;
203
162
  const next = control.value;
@@ -234,18 +193,34 @@ let HelixHeadlessInput = class HelixHeadlessInput extends MixinControllerValue(M
234
193
  this.dispatchEvent(new Event('change', { bubbles: true, composed: false }));
235
194
  };
236
195
  /**
237
- * A regular expression the value has to match, as the platform reads it.
196
+ * Whether a password field offers a toggle that shows what was typed.
197
+ *
198
+ * Ignored on every other type. A reveal on an email field would be a button
199
+ * that does nothing visible, and guarding it here rather than asking the
200
+ * consumer not to means the property can be set once on a component that
201
+ * changes type.
202
+ */
203
+ this.reveal = false;
204
+ /**
205
+ * What the reveal toggle is called.
206
+ *
207
+ * The state is `aria-pressed`, not this.
208
+ */
209
+ this.revealLabel = 'Show password';
210
+ /**
211
+ * What the field accepts, which decides the keyboard and the validation.
238
212
  *
239
- * The class documentation promised `pattern` and `minlength` "and the rest"
240
- * were set on the real input, and no such properties existed: a consumer
241
- * following that sentence wrote an attribute on the host, it reached no input,
242
- * and the field constrained nothing while looking as though it did.
213
+ * **Not reflected.** Reflection exists so a selector can reach a value, and
214
+ * no stylesheet in this repository selects on `type`. Reflecting it writes
215
+ * `type="text"` onto every `<helix-input>` ever rendered, an attribute no
216
+ * consumer's markup has, which is the fault the area rules write up under
217
+ * `Button`'s `href`, `target` and `rel`.
243
218
  *
244
- * Forwarded rather than checked here, which is the whole reason validity is
245
- * the platform's: the browser knows what a `pattern` means, anchors it at both
246
- * ends, and produces the message in the reader's own language.
219
+ * Nothing reads it from the attribute either. The real `<input>` inside takes
220
+ * it as a property binding, which is what makes the keyboard and the
221
+ * validation follow.
247
222
  */
248
- this.pattern = '';
223
+ this.type = 'text';
249
224
  }
250
225
  /**
251
226
  * The type the real input is given, which is not always the type asked for.
@@ -275,7 +250,7 @@ let HelixHeadlessInput = class HelixHeadlessInput extends MixinControllerValue(M
275
250
  * the boundary. An insert-at-cursor toolbar, a format button, a mask that
276
251
  * repositions the caret after rewriting the value, all of them need this and
277
252
  * none of them could be written. Textarea gained the same surface for the same
278
- * reason. See 295.
253
+ * reason.
279
254
  *
280
255
  * Zero before there is a control, which is where an empty field's caret would
281
256
  * be anyway.
@@ -396,12 +371,10 @@ let HelixHeadlessInput = class HelixHeadlessInput extends MixinControllerValue(M
396
371
  />
397
372
  <slot name="end"></slot>
398
373
  <!-- In the tab order, unlike the browser's own search clear, which is not
399
- reachable by keyboard at all. That is defensible for a native control
400
- a reader can empty with select-all and Delete, and less so for one
401
- whose only affordance is an icon: a control that exists on screen and
402
- cannot be reached is one a keyboard reader is told about and cannot
403
- use. It only exists while there is a value, so the extra stop appears
404
- exactly when there is something to do with it. -->
374
+ reachable by keyboard at all: a control whose only affordance is an
375
+ icon and that cannot be reached is one a keyboard reader is told
376
+ about and cannot use. It only exists while there is a value, so the
377
+ extra stop appears exactly when there is something to do with it. -->
405
378
  ${this.showsClear
406
379
  ? html `<button
407
380
  part="clear"
@@ -433,6 +406,21 @@ let HelixHeadlessInput = class HelixHeadlessInput extends MixinControllerValue(M
433
406
  __decorate([
434
407
  property()
435
408
  ], HelixHeadlessInput.prototype, "autocomplete", void 0);
409
+ __decorate([
410
+ property({ type: Boolean })
411
+ ], HelixHeadlessInput.prototype, "clearable", void 0);
412
+ __decorate([
413
+ property({ attribute: 'clear-label' })
414
+ ], HelixHeadlessInput.prototype, "clearLabel", void 0);
415
+ __decorate([
416
+ property({ attribute: 'maxlength', type: Number })
417
+ ], HelixHeadlessInput.prototype, "maxLength", void 0);
418
+ __decorate([
419
+ property({ attribute: 'minlength', type: Number })
420
+ ], HelixHeadlessInput.prototype, "minLength", void 0);
421
+ __decorate([
422
+ property()
423
+ ], HelixHeadlessInput.prototype, "pattern", void 0);
436
424
  __decorate([
437
425
  property()
438
426
  ], HelixHeadlessInput.prototype, "placeholder", void 0);
@@ -440,32 +428,17 @@ __decorate([
440
428
  property({ attribute: 'readonly', reflect: true, type: Boolean })
441
429
  ], HelixHeadlessInput.prototype, "readOnly", void 0);
442
430
  __decorate([
443
- property()
444
- ], HelixHeadlessInput.prototype, "type", void 0);
445
- __decorate([
446
- property({ type: Boolean })
447
- ], HelixHeadlessInput.prototype, "clearable", void 0);
448
- __decorate([
449
- property({ attribute: 'clear-label' })
450
- ], HelixHeadlessInput.prototype, "clearLabel", void 0);
431
+ state()
432
+ ], HelixHeadlessInput.prototype, "revealed", void 0);
451
433
  __decorate([
452
434
  property({ type: Boolean })
453
435
  ], HelixHeadlessInput.prototype, "reveal", void 0);
454
436
  __decorate([
455
437
  property({ attribute: 'reveal-label' })
456
438
  ], HelixHeadlessInput.prototype, "revealLabel", void 0);
457
- __decorate([
458
- state()
459
- ], HelixHeadlessInput.prototype, "revealed", void 0);
460
439
  __decorate([
461
440
  property()
462
- ], HelixHeadlessInput.prototype, "pattern", void 0);
463
- __decorate([
464
- property({ attribute: 'minlength', type: Number })
465
- ], HelixHeadlessInput.prototype, "minLength", void 0);
466
- __decorate([
467
- property({ attribute: 'maxlength', type: Number })
468
- ], HelixHeadlessInput.prototype, "maxLength", void 0);
441
+ ], HelixHeadlessInput.prototype, "type", void 0);
469
442
  HelixHeadlessInput = __decorate([
470
443
  customElement('helix-headless-input')
471
444
  ], HelixHeadlessInput);
@@ -29,13 +29,6 @@ import { type TemplateResult } from 'lit';
29
29
  * the control does.
30
30
  * - `document` listens on the document, for a chord that works from anywhere.
31
31
  *
32
- * *Corrected 25 Aug 2026: this said `scope`, `self` and `global` until then,
33
- * naming a property that has never existed under that name. The rename is
34
- * explained on the property itself, twenty lines below, and this paragraph
35
- * above it went on teaching the old one. A reader who trusted the class doc
36
- * wrote an attribute that binds nothing, which is also what an unset `within`
37
- * does, so nothing about the mistake looked like one.*
38
- *
39
32
  * **A hidden `kbd` is a dead shortcut, and that is the point rather than a
40
33
  * trap.** Binding here ties the key to its own advertisement, so a hint that is
41
34
  * not rendered is a shortcut that is not offered. A chord that must outlive its
@@ -87,6 +80,14 @@ export declare class HelixHeadlessKbd extends HelixElement {
87
80
  private listen;
88
81
  private deafen;
89
82
  private readonly handleKeydown;
83
+ /**
84
+ * Whether this chord is one bare character, and so indistinguishable from
85
+ * typing.
86
+ *
87
+ * A single part means no modifier, and one code point means a character
88
+ * rather than a name: `/` and `?` are printable, `escape` and `enter` are not.
89
+ */
90
+ private get printable();
90
91
  /** Whether a press is this chord, modifiers and all. */
91
92
  private matches_;
92
93
  protected render(): TemplateResult;
@@ -7,15 +7,41 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  import { customElement, HelixElement, HelixShortcutEvent } from '@fusion.dev/helix-core';
8
8
  import { html } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
+ /**
11
+ * Whether a node is something a reader types into.
12
+ *
13
+ * The input types are the ones that take text. A checkbox and a range are
14
+ * `<input>` and are not typing, so a chord still reaches them.
15
+ */
16
+ const typing = (node) => {
17
+ if (node instanceof HTMLTextAreaElement) {
18
+ return true;
19
+ }
20
+ if (node instanceof HTMLElement && node.isContentEditable) {
21
+ return true;
22
+ }
23
+ return node instanceof HTMLInputElement && !UNTYPED.has(node.type);
24
+ };
25
+ /** `<input>` types that hold no text, so a bare chord is not competing with one. */
26
+ const UNTYPED = new Set([
27
+ 'button',
28
+ 'checkbox',
29
+ 'color',
30
+ 'file',
31
+ 'hidden',
32
+ 'image',
33
+ 'radio',
34
+ 'range',
35
+ 'reset',
36
+ 'submit',
37
+ ]);
10
38
  /**
11
39
  * How each name in a chord is drawn, per platform.
12
40
  *
13
41
  * Apple keyboards label their modifiers with glyphs and print no separator
14
42
  * between them, so `⌘K` is the whole of it. Everywhere else the words are the
15
- * label and the plus is part of the convention rather than prose. That is the
16
- * one separator this component is willing to supply: the class docstring says
17
- * a separator between keys is prose because it is "then" in a sequence and
18
- * "plus" in a simultaneous press, and `keys` is only ever the second of those.
43
+ * label and the plus is part of the convention rather than prose, which is why
44
+ * it is the one separator this component supplies.
19
45
  */
20
46
  const APPLE = {
21
47
  alt: '⌥',
@@ -86,13 +112,6 @@ const onApple = () => typeof navigator !== 'undefined' && /mac|iphone|ipad|ipod/
86
112
  * the control does.
87
113
  * - `document` listens on the document, for a chord that works from anywhere.
88
114
  *
89
- * *Corrected 25 Aug 2026: this said `scope`, `self` and `global` until then,
90
- * naming a property that has never existed under that name. The rename is
91
- * explained on the property itself, twenty lines below, and this paragraph
92
- * above it went on teaching the old one. A reader who trusted the class doc
93
- * wrote an attribute that binds nothing, which is also what an unset `within`
94
- * does, so nothing about the mistake looked like one.*
95
- *
96
115
  * **A hidden `kbd` is a dead shortcut, and that is the point rather than a
97
116
  * trap.** Binding here ties the key to its own advertisement, so a hint that is
98
117
  * not rendered is a shortcut that is not offered. A chord that must outlive its
@@ -133,6 +152,33 @@ let HelixHeadlessKbd = class HelixHeadlessKbd extends HelixElement {
133
152
  if (press.isComposing) {
134
153
  return;
135
154
  }
155
+ /* Neither is a bare character typed into a field, which is the same fault
156
+ the IME guard above already refuses: the reader meant the key to reach
157
+ what they are writing in.
158
+
159
+ Only a bare printable chord. `mod+k` is a shortcut a reader expects to
160
+ work from inside a search field, and `escape` is how they leave it, so a
161
+ guard over every chord would break the two conventions this is for. It is
162
+ `/` and `?` that are ambiguous, being both the most conventional
163
+ shortcuts on the web and characters somebody types.
164
+
165
+ `composedPath()[0]` rather than `target`, which retargets to the host at
166
+ document level and would need a list of every tag name that holds a field.
167
+ The path's first entry is the real one, through open shadow roots and
168
+ through `delegatesFocus`.
169
+
170
+ **`document` only, because `control` has already answered the question.**
171
+ That binding listens on `this.parentElement`, so it fires only with focus
172
+ inside the control the badge sits in, and the guard would make a bare
173
+ printable chord unreachable there by construction: the two are mutually
174
+ exclusive. `.examples/events.html` is exactly that shape, a `keys="/"`
175
+ slotted into a `helix-input` telling the reader to put the cursor in the
176
+ field and press slash, and it would have shipped to the docs site doing
177
+ nothing. What is ambiguous is `/` competing with every field on the page,
178
+ which is the `document` case and the only one this refuses. */
179
+ if (this.within === 'document' && this.printable && typing(press.composedPath()[0])) {
180
+ return;
181
+ }
136
182
  if (!this.matches_(press)) {
137
183
  return;
138
184
  }
@@ -188,6 +234,20 @@ let HelixHeadlessKbd = class HelixHeadlessKbd extends HelixElement {
188
234
  this.listening?.removeEventListener('keydown', this.handleKeydown);
189
235
  this.listening = undefined;
190
236
  }
237
+ /**
238
+ * Whether this chord is one bare character, and so indistinguishable from
239
+ * typing.
240
+ *
241
+ * A single part means no modifier, and one code point means a character
242
+ * rather than a name: `/` and `?` are printable, `escape` and `enter` are not.
243
+ */
244
+ get printable() {
245
+ const parts = this.keys
246
+ .split('+')
247
+ .map((part) => part.trim())
248
+ .filter((part) => part !== '');
249
+ return parts.length === 1 && [...(parts[0] ?? '')].length === 1;
250
+ }
191
251
  /** Whether a press is this chord, modifiers and all. */
192
252
  matches_(press) {
193
253
  const parts = this.keys
@@ -26,7 +26,7 @@ import { type PropertyValues, type TemplateResult } from 'lit';
26
26
  * tell it.
27
27
  *
28
28
  * **Not hidden from a screen reader, though the mapping it draws is a color
29
- * one.** The argument for hiding it is real: the colours mean nothing to a
29
+ * one.** The argument for hiding it is real: the colors mean nothing to a
30
30
  * reader who cannot see them, and the names are already in the table. It stays
31
31
  * because the cost of being wrong runs one way. A duplicated list of three
32
32
  * words is noise; a consumer who took the table out of the accessibility tree
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  import { customElement, HelixElement, SourceController } from '@fusion.dev/helix-core';
8
8
  import { html } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
- /** How many colours the series palette has, and so where it starts over. */
10
+ /** How many colors the series palette has, and so where it starts over. */
11
11
  const PALETTE = 24;
12
12
  /**
13
13
  * @summary The names a chart draws, each beside the color it is drawn in.
@@ -35,7 +35,7 @@ const PALETTE = 24;
35
35
  * tell it.
36
36
  *
37
37
  * **Not hidden from a screen reader, though the mapping it draws is a color
38
- * one.** The argument for hiding it is real: the colours mean nothing to a
38
+ * one.** The argument for hiding it is real: the colors mean nothing to a
39
39
  * reader who cannot see them, and the names are already in the table. It stays
40
40
  * because the cost of being wrong runs one way. A duplicated list of three
41
41
  * words is noise; a consumer who took the table out of the accessibility tree
@@ -66,9 +66,8 @@ let HelixHeadlessLegend = class HelixHeadlessLegend extends HelixElement {
66
66
  * `Tooltip.for` does, so it does not reflect and nothing styles on it.
67
67
  */
68
68
  this.for = '';
69
- /* One controller rather than the resolve-and-watch each chart had written
70
- out for itself. Three copies had already drifted into two names for the
71
- same lookup. */
69
+ /* One controller rather than the resolve-and-watch each chart would write
70
+ out for itself, which drifts into two names for the same lookup. */
72
71
  this.source = new SourceController(this);
73
72
  }
74
73
  willUpdate(changed) {
@@ -67,22 +67,19 @@ export declare class HelixHeadlessLineChart extends HelixHeadlessLineChart_base
67
67
  /**
68
68
  * How the line gets from one reading to the next.
69
69
  *
70
- * **`smooth` is the resting curve.** *Changed 21 Aug 2026, reversing the
71
- * argument this comment used to make.* Joining the readings claims nothing in
72
- * between, which is true and is why `straight` still exists: a straight
73
- * segment asserts nothing about the values between two readings, and a curve
74
- * invents them. What settles it the other way is that the invention is
75
- * bounded. The interpolation is monotone cubic, so it never leaves the band
70
+ * **`smooth` is the resting curve.** A curve invents the values between two
71
+ * readings, which is why `straight` still exists, but the invention is
72
+ * bounded: the interpolation is monotone cubic, so it never leaves the band
76
73
  * the data sets and never introduces a peak or a trough the series does not
77
- * have, and within that bound the smoothed line is the easier one to follow
78
- * across a long series. `straight` becomes the deliberate claim.
74
+ * have. Within that bound the smoothed line is the easier one to follow
75
+ * across a long series, and `straight` becomes the deliberate claim.
79
76
  *
80
- * **Still absent rather than defaulted on the property**, because a
81
- * reflecting property with a default writes its attribute onto every host
82
- * anybody renders, including the ones nobody configured.
77
+ * **Absent rather than defaulted on the property**, because a reflecting
78
+ * property with a default writes its attribute onto every host anybody
79
+ * renders, including the ones nobody configured.
83
80
  * `line-chart-root.ssr.spec.ts` asserts the host carries only what the
84
- * consumer wrote, and caught that the first time. The default therefore lives
85
- * where the path is built, as `curve ?? 'smooth'`.
81
+ * consumer wrote. The default therefore lives where the path is built, as
82
+ * `curve ?? 'smooth'`.
86
83
  *
87
84
  * `step` claims the opposite of both, that a reading holds until the next.
88
85
  */
@@ -101,12 +98,11 @@ export declare class HelixHeadlessLineChart extends HelixHeadlessLineChart_base
101
98
  * through each reading, which is what lets a point be traced down to its
102
99
  * label across a wide chart. `both` draws both.
103
100
  *
104
- * **A bare `gridlines` means `value`**, and so does anything unrecognised.
105
- * Written out, the attribute a consumer reaches for first should be the grid
106
- * they meant, and a typo should fall back to the useful half rather than to
107
- * nothing at all: an unrecognised value that draws no rules is
108
- * indistinguishable from the attribute being absent, which is the one thing
109
- * a reader cannot debug.
101
+ * **A bare `gridlines` means `value`**, and so does anything unrecognized.
102
+ * The attribute a consumer reaches for first should be the grid they meant,
103
+ * and a typo should fall back to the useful half rather than to nothing at
104
+ * all: an unrecognized value that draws no rules is indistinguishable from
105
+ * the attribute being absent, which is the one thing a reader cannot debug.
110
106
  *
111
107
  * Furniture rather than data, so the rules are inside the `aria-hidden` plot
112
108
  * and reach no reader through the table.
@@ -116,17 +112,6 @@ export declare class HelixHeadlessLineChart extends HelixHeadlessLineChart_base
116
112
  protected get rulesValue(): boolean;
117
113
  /** Whether each reading is ruled, which only two values ask for. */
118
114
  protected get rulesCategory(): boolean;
119
- /**
120
- * Whether zero is forced into the range.
121
- *
122
- * Absent measures from the data's own extent, which is what a line is for.
123
- * Set it where the distance from nothing is the point rather than the shape,
124
- * and accept that a series which never approaches zero becomes a flat rule
125
- * near the top of the box.
126
- */
127
- zero: boolean;
128
- /** The domain every series is drawn against, which the tooltip also needs. */
129
- private range;
130
115
  /**
131
116
  * The shape of the mark on each series' last reading.
132
117
  *
@@ -151,6 +136,17 @@ export declare class HelixHeadlessLineChart extends HelixHeadlessLineChart_base
151
136
  * layers; a single `mask-image` would only ever cut the last one.
152
137
  */
153
138
  terminus?: 'none' | 'ring' | 'square' | 'triangle';
139
+ /** The domain every series is drawn against, which the tooltip also needs. */
140
+ private range;
141
+ /**
142
+ * Whether zero is forced into the range.
143
+ *
144
+ * Absent measures from the data's own extent, which is what a line is for.
145
+ * Set it where the distance from nothing is the point rather than the shape,
146
+ * and accept that a series which never approaches zero becomes a flat rule
147
+ * near the top of the box.
148
+ */
149
+ zero: boolean;
154
150
  /**
155
151
  * Where each series ends, as percentages of the drawing's own box.
156
152
  *
@@ -135,12 +135,12 @@ let HelixHeadlessLineChart = class HelixHeadlessLineChart extends MixinChartSour
135
135
  /* **A reading sits in the middle of its own slot, not at the edge of the
136
136
  box**, which is what makes the names underneath line up with it.
137
137
  *
138
- * Spanning 0 to 100 is the obvious version and is what this did first. The
139
- * labels are a grid of equal columns, the same row the bar chart uses, so
140
- * each name is centered in its share of the width while the readings sat at
141
- * the gridlines between those shares: measured, the first name centered at a
142
- * twelfth of the width with its point at zero. Every label was off by half
143
- * a slot and the error grew toward the middle.
138
+ * Spanning 0 to 100 is the obvious version and is wrong. The labels are a
139
+ * grid of equal columns, the same row the bar chart uses, so each name is
140
+ * centered in its share of the width while the readings sit at the
141
+ * gridlines between those shares: measured, the first name centered at a
142
+ * twelfth of the width with its point at zero. Every label is off by half
143
+ * a slot and the error grows toward the middle.
144
144
  *
145
145
  * Insetting by half a slot also means a line chart and a bar chart drawn
146
146
  * from the same table stack, which is the arrangement anybody comparing a
@@ -208,7 +208,7 @@ let HelixHeadlessLineChart = class HelixHeadlessLineChart extends MixinChartSour
208
208
  /* Through each reading rather than between them. A rule on the boundary
209
209
  divides two catchments, which is a fact about the pointer; a rule on the
210
210
  reading is the line a reader traces down to the label, which is what a
211
- category grid is for. The readings sit at slot centres, so the two are
211
+ category grid is for. The readings sit at slot centers, so the two are
212
212
  half a slot apart and only one of them lands under a point. */
213
213
  const down = this.rulesCategory
214
214
  ? Array.from({ length: count }, (_, index) => svg `<line part="gridline" x1=${x(index)} x2=${x(index)} y1="0" y2=${HEIGHT} />`)
@@ -353,12 +353,12 @@ __decorate([
353
353
  __decorate([
354
354
  property()
355
355
  ], HelixHeadlessLineChart.prototype, "gridlines", void 0);
356
- __decorate([
357
- property({ reflect: true, type: Boolean })
358
- ], HelixHeadlessLineChart.prototype, "zero", void 0);
359
356
  __decorate([
360
357
  property({ reflect: true })
361
358
  ], HelixHeadlessLineChart.prototype, "terminus", void 0);
359
+ __decorate([
360
+ property({ reflect: true, type: Boolean })
361
+ ], HelixHeadlessLineChart.prototype, "zero", void 0);
362
362
  HelixHeadlessLineChart = __decorate([
363
363
  customElement('helix-headless-line-chart')
364
364
  ], HelixHeadlessLineChart);