@fusion.dev/helix-headless 0.143.0 → 0.145.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 (314) hide show
  1. package/custom-elements.json +16990 -1383
  2. package/dist/accordion/item/accordion-item.d.ts +48 -12
  3. package/dist/accordion/item/accordion-item.js +26 -5
  4. package/dist/accordion/root/accordion-root.d.ts +6 -0
  5. package/dist/accordion/root/accordion-root.js +7 -1
  6. package/dist/announcement/root/announcement-root.d.ts +21 -1
  7. package/dist/announcement/root/announcement-root.js +36 -1
  8. package/dist/app-header/root/app-header-root.d.ts +7 -0
  9. package/dist/app-header/root/app-header-root.js +5 -1
  10. package/dist/app-header/sectioning.d.ts +7 -0
  11. package/dist/app-header/sectioning.js +26 -0
  12. package/dist/area-chart/root/area-chart-root.d.ts +12 -4
  13. package/dist/area-chart/root/area-chart-root.js +24 -7
  14. package/dist/avatar/root/avatar-root.d.ts +14 -0
  15. package/dist/avatar/root/avatar-root.js +23 -9
  16. package/dist/badge/root/badge-root.d.ts +11 -7
  17. package/dist/badge/root/badge-root.js +1 -1
  18. package/dist/bar-chart/root/bar-chart-root.d.ts +12 -3
  19. package/dist/bar-chart/root/bar-chart-root.js +17 -10
  20. package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +32 -1
  21. package/dist/breadcrumbs/root/breadcrumbs-root.js +25 -2
  22. package/dist/button/root/button-root.d.ts +47 -1
  23. package/dist/button/root/button-root.js +38 -4
  24. package/dist/callout/root/callout-root.d.ts +18 -1
  25. package/dist/callout/root/callout-root.js +15 -4
  26. package/dist/canvas/root/canvas-root.d.ts +38 -3
  27. package/dist/canvas/root/canvas-root.js +121 -40
  28. package/dist/card/root/card-root.d.ts +30 -1
  29. package/dist/card/root/card-root.js +38 -5
  30. package/dist/carousel/root/carousel-root.d.ts +90 -0
  31. package/dist/carousel/root/carousel-root.js +134 -12
  32. package/dist/chat/composer/chat-composer.d.ts +38 -6
  33. package/dist/chat/composer/chat-composer.js +42 -9
  34. package/dist/chat/message/chat-message.d.ts +32 -1
  35. package/dist/chat/message/chat-message.js +25 -9
  36. package/dist/chat/naming.d.ts +22 -0
  37. package/dist/chat/naming.js +12 -0
  38. package/dist/chat/relative-clock.d.ts +39 -0
  39. package/dist/chat/relative-clock.js +31 -0
  40. package/dist/chat/root/chat-root.d.ts +36 -0
  41. package/dist/chat/root/chat-root.js +24 -1
  42. package/dist/checkbox/root/checkbox-root.js +2 -0
  43. package/dist/checkbox-group/root/checkbox-group-root.d.ts +53 -3
  44. package/dist/checkbox-group/root/checkbox-group-root.js +71 -22
  45. package/dist/code-block/lines.d.ts +13 -0
  46. package/dist/code-block/lines.js +2 -0
  47. package/dist/code-block/root/code-block-root.d.ts +38 -1
  48. package/dist/code-block/root/code-block-root.js +28 -7
  49. package/dist/color-input/root/color-input-root.d.ts +34 -1
  50. package/dist/color-input/root/color-input-root.js +23 -4
  51. package/dist/color-picker/channels.d.ts +26 -0
  52. package/dist/color-picker/channels.js +84 -0
  53. package/dist/color-picker/root/color-picker-root.d.ts +81 -5
  54. package/dist/color-picker/root/color-picker-root.js +103 -10
  55. package/dist/combobox/root/combobox-root.d.ts +38 -3
  56. package/dist/combobox/root/combobox-root.js +64 -2
  57. package/dist/command/root/command-root.d.ts +30 -4
  58. package/dist/command/root/command-root.js +33 -3
  59. package/dist/copy-button/from.d.ts +22 -0
  60. package/dist/copy-button/from.js +28 -0
  61. package/dist/copy-button/root/copy-button-root.d.ts +47 -1
  62. package/dist/copy-button/root/copy-button-root.js +44 -8
  63. package/dist/data-table/root/data-table-root.d.ts +150 -2
  64. package/dist/data-table/root/data-table-root.js +303 -29
  65. package/dist/data-table/tree.d.ts +40 -0
  66. package/dist/data-table/tree.js +55 -0
  67. package/dist/date-input/root/date-input-root.d.ts +73 -4
  68. package/dist/date-input/root/date-input-root.js +93 -43
  69. package/dist/date-picker/root/date-picker-root.d.ts +145 -1
  70. package/dist/date-picker/root/date-picker-root.js +239 -48
  71. package/dist/description-list/item/description-list-item.d.ts +17 -2
  72. package/dist/description-list/item/description-list-item.js +15 -2
  73. package/dist/description-list/root/description-list-root.d.ts +27 -1
  74. package/dist/description-list/root/description-list-root.js +26 -1
  75. package/dist/dialog/description.d.ts +9 -0
  76. package/dist/dialog/description.js +14 -0
  77. package/dist/dialog/root/dialog-root.d.ts +64 -1
  78. package/dist/dialog/root/dialog-root.js +49 -23
  79. package/dist/donut-chart/root/donut-chart-root.d.ts +25 -4
  80. package/dist/donut-chart/root/donut-chart-root.js +21 -6
  81. package/dist/drawer/root/drawer-root.d.ts +63 -2
  82. package/dist/drawer/root/drawer-root.js +95 -19
  83. package/dist/drawer/swipe-start.d.ts +9 -0
  84. package/dist/drawer/swipe-start.js +12 -0
  85. package/dist/drilldown/item/drilldown-item.d.ts +11 -6
  86. package/dist/drilldown/item/drilldown-item.js +8 -5
  87. package/dist/drilldown/root/drilldown-root.d.ts +11 -0
  88. package/dist/drilldown/root/drilldown-root.js +8 -3
  89. package/dist/element-events.generated.js +61 -13
  90. package/dist/empty/root/empty-root.d.ts +1 -1
  91. package/dist/file-input/root/file-input-root.d.ts +47 -0
  92. package/dist/file-input/root/file-input-root.js +60 -22
  93. package/dist/file-input/screen.d.ts +35 -0
  94. package/dist/file-input/screen.js +49 -0
  95. package/dist/filter-input/menu/filter-menu.d.ts +3 -0
  96. package/dist/filter-input/menu/filter-menu.js +8 -4
  97. package/dist/filter-input/root/filter-input-root.d.ts +38 -4
  98. package/dist/filter-input/root/filter-input-root.js +67 -3
  99. package/dist/filter-input/suggest.d.ts +17 -0
  100. package/dist/filter-input/suggest.js +23 -0
  101. package/dist/format-date/options.d.ts +33 -0
  102. package/dist/format-date/options.js +42 -0
  103. package/dist/format-date/root/format-date-root.d.ts +51 -0
  104. package/dist/format-date/root/format-date-root.js +58 -38
  105. package/dist/heatmap/root/heatmap-root.d.ts +23 -6
  106. package/dist/heatmap/root/heatmap-root.js +24 -13
  107. package/dist/icon/index.d.ts +2 -0
  108. package/dist/icon/index.js +2 -0
  109. package/dist/icon/registry.d.ts +37 -0
  110. package/dist/icon/registry.js +83 -0
  111. package/dist/icon/root/icon-root.d.ts +30 -4
  112. package/dist/icon/root/icon-root.js +41 -6
  113. package/dist/icon/root/index.d.ts +2 -0
  114. package/dist/icon/root/index.js +2 -0
  115. package/dist/icon/set.d.ts +1 -0
  116. package/dist/icon/set.js +3 -0
  117. package/dist/image/root/image-root.d.ts +14 -0
  118. package/dist/image/root/image-root.js +23 -2
  119. package/dist/input/root/input-root.d.ts +11 -0
  120. package/dist/input/root/input-root.js +16 -1
  121. package/dist/kbd/root/kbd-root.d.ts +20 -13
  122. package/dist/kbd/root/kbd-root.js +35 -37
  123. package/dist/kbd/shortcut.d.ts +18 -0
  124. package/dist/kbd/shortcut.js +35 -0
  125. package/dist/legend/hidden-series.d.ts +8 -0
  126. package/dist/legend/hidden-series.js +13 -0
  127. package/dist/legend/root/legend-root.d.ts +56 -0
  128. package/dist/legend/root/legend-root.js +54 -5
  129. package/dist/lightbox/item/lightbox-item.d.ts +15 -0
  130. package/dist/lightbox/item/lightbox-item.js +10 -1
  131. package/dist/lightbox/root/lightbox-root.d.ts +61 -1
  132. package/dist/lightbox/root/lightbox-root.js +94 -4
  133. package/dist/line-chart/root/line-chart-root.d.ts +11 -3
  134. package/dist/line-chart/root/line-chart-root.js +19 -5
  135. package/dist/list/item/list-item.d.ts +68 -1
  136. package/dist/list/item/list-item.js +66 -4
  137. package/dist/list/numbering.d.ts +14 -0
  138. package/dist/list/numbering.js +8 -0
  139. package/dist/list/root/list-root.d.ts +106 -9
  140. package/dist/list/root/list-root.js +189 -4
  141. package/dist/list/selection.d.ts +19 -0
  142. package/dist/list/selection.js +21 -0
  143. package/dist/listbox/root/listbox-root.d.ts +74 -3
  144. package/dist/listbox/root/listbox-root.js +86 -9
  145. package/dist/loader/busy.d.ts +17 -0
  146. package/dist/loader/busy.js +24 -0
  147. package/dist/loader/root/loader-root.d.ts +37 -0
  148. package/dist/loader/root/loader-root.js +52 -3
  149. package/dist/map/root/map-root.d.ts +6 -2
  150. package/dist/map/root/map-root.js +5 -2
  151. package/dist/megamenu/root/megamenu-root.d.ts +21 -0
  152. package/dist/megamenu/root/megamenu-root.js +16 -2
  153. package/dist/menu/index.d.ts +1 -0
  154. package/dist/menu/index.js +1 -0
  155. package/dist/menu/item/menu-item.d.ts +38 -11
  156. package/dist/menu/item/menu-item.js +33 -1
  157. package/dist/menu/root/menu-root.d.ts +25 -1
  158. package/dist/menu/root/menu-root.js +63 -6
  159. package/dist/menu/section/menu-section.d.ts +55 -0
  160. package/dist/menu/section/menu-section.js +60 -0
  161. package/dist/meter/root/meter-root.d.ts +7 -0
  162. package/dist/meter/root/meter-root.js +6 -3
  163. package/dist/navigation/root/navigation-root.d.ts +16 -1
  164. package/dist/navigation/root/navigation-root.js +27 -1
  165. package/dist/notifications/feed-keys.d.ts +10 -0
  166. package/dist/notifications/feed-keys.js +14 -0
  167. package/dist/notifications/notification/notification.d.ts +17 -0
  168. package/dist/notifications/notification/notification.js +21 -2
  169. package/dist/notifications/root/notifications-root.d.ts +60 -0
  170. package/dist/notifications/root/notifications-root.js +76 -1
  171. package/dist/number-input/root/number-input-root.d.ts +47 -0
  172. package/dist/number-input/root/number-input-root.js +58 -22
  173. package/dist/object-inspector/root/object-inspector-root.d.ts +98 -16
  174. package/dist/object-inspector/root/object-inspector-root.js +180 -80
  175. package/dist/object-inspector/rows.d.ts +57 -0
  176. package/dist/object-inspector/rows.js +86 -0
  177. package/dist/option/root/option-root.d.ts +54 -5
  178. package/dist/option/root/option-root.js +34 -5
  179. package/dist/outline/levels.d.ts +31 -0
  180. package/dist/outline/levels.js +23 -0
  181. package/dist/outline/root/outline-root.d.ts +68 -3
  182. package/dist/outline/root/outline-root.js +73 -8
  183. package/dist/pagination/size/pagination-size.d.ts +11 -2
  184. package/dist/pagination/size/pagination-size.js +19 -4
  185. package/dist/pin-input/format.d.ts +7 -0
  186. package/dist/pin-input/format.js +16 -0
  187. package/dist/pin-input/root/pin-input-root.d.ts +21 -0
  188. package/dist/pin-input/root/pin-input-root.js +29 -2
  189. package/dist/popover/root/popover-root.d.ts +62 -4
  190. package/dist/popover/root/popover-root.js +53 -5
  191. package/dist/progress/root/progress-root.d.ts +7 -0
  192. package/dist/progress/root/progress-root.js +9 -3
  193. package/dist/qr-code/export.d.ts +31 -0
  194. package/dist/qr-code/export.js +10 -0
  195. package/dist/qr-code/root/qr-code-root.d.ts +26 -0
  196. package/dist/qr-code/root/qr-code-root.js +49 -2
  197. package/dist/radio/group/radio-group.d.ts +17 -0
  198. package/dist/radio/group/radio-group.js +14 -1
  199. package/dist/rating/root/rating-root.d.ts +25 -0
  200. package/dist/rating/root/rating-root.js +46 -4
  201. package/dist/scatter-chart/root/scatter-chart-root.d.ts +17 -3
  202. package/dist/scatter-chart/root/scatter-chart-root.js +25 -7
  203. package/dist/scroll-area/root/scroll-area-root.d.ts +113 -0
  204. package/dist/scroll-area/root/scroll-area-root.js +218 -3
  205. package/dist/scroll-area/scrollbar.d.ts +65 -0
  206. package/dist/scroll-area/scrollbar.js +24 -0
  207. package/dist/select/root/select-root.d.ts +24 -0
  208. package/dist/select/root/select-root.js +21 -7
  209. package/dist/skeleton/root/skeleton-root.d.ts +25 -0
  210. package/dist/skeleton/root/skeleton-root.js +17 -2
  211. package/dist/slider/root/slider-root.d.ts +39 -0
  212. package/dist/slider/root/slider-root.js +45 -9
  213. package/dist/splitter/root/splitter-root.d.ts +13 -0
  214. package/dist/splitter/root/splitter-root.js +20 -2
  215. package/dist/splitter/snap.d.ts +9 -0
  216. package/dist/splitter/snap.js +12 -0
  217. package/dist/stat/root/stat-root.d.ts +2 -0
  218. package/dist/stat/root/stat-root.js +1 -1
  219. package/dist/steps/reach.d.ts +15 -0
  220. package/dist/steps/reach.js +12 -0
  221. package/dist/steps/root/steps-root.d.ts +30 -0
  222. package/dist/steps/root/steps-root.js +53 -0
  223. package/dist/steps/step/step.d.ts +39 -2
  224. package/dist/steps/step/step.js +29 -7
  225. package/dist/switch/root/switch-root.d.ts +12 -2
  226. package/dist/switch/root/switch-root.js +6 -1
  227. package/dist/table/column/table-column.d.ts +11 -0
  228. package/dist/table/column/table-column.js +6 -1
  229. package/dist/table/root/table-root.d.ts +101 -0
  230. package/dist/table/root/table-root.js +166 -5
  231. package/dist/table/row/table-row.d.ts +47 -1
  232. package/dist/table/row/table-row.js +39 -2
  233. package/dist/tabs/panel/tab-panel.d.ts +9 -5
  234. package/dist/tabs/panel/tab-panel.js +3 -4
  235. package/dist/tabs/root/tabs-root.d.ts +25 -1
  236. package/dist/tabs/root/tabs-root.js +21 -3
  237. package/dist/tabs/tab/tab.d.ts +36 -4
  238. package/dist/tabs/tab/tab.js +46 -3
  239. package/dist/tag/group/tag-group.d.ts +107 -0
  240. package/dist/tag/group/tag-group.js +157 -0
  241. package/dist/tag/index.d.ts +1 -0
  242. package/dist/tag/index.js +1 -0
  243. package/dist/tag/root/tag-root.d.ts +60 -0
  244. package/dist/tag/root/tag-root.js +74 -18
  245. package/dist/tag/selection.d.ts +10 -0
  246. package/dist/tag/selection.js +12 -0
  247. package/dist/textarea/grow.d.ts +22 -0
  248. package/dist/textarea/grow.js +20 -0
  249. package/dist/textarea/root/textarea-root.d.ts +9 -0
  250. package/dist/textarea/root/textarea-root.js +9 -1
  251. package/dist/time-input/root/time-input-root.d.ts +44 -5
  252. package/dist/time-input/root/time-input-root.js +69 -39
  253. package/dist/time-picker/root/time-picker-root.d.ts +54 -8
  254. package/dist/time-picker/root/time-picker-root.js +121 -91
  255. package/dist/timeline/group/timeline-group.d.ts +46 -0
  256. package/dist/timeline/group/timeline-group.js +37 -0
  257. package/dist/timeline/index.d.ts +1 -0
  258. package/dist/timeline/index.js +1 -0
  259. package/dist/timeline/root/timeline-root.d.ts +10 -3
  260. package/dist/toast/hotkey.d.ts +22 -0
  261. package/dist/toast/hotkey.js +23 -0
  262. package/dist/toast/item/toast-item.d.ts +26 -18
  263. package/dist/toast/item/toast-item.js +55 -48
  264. package/dist/toast/root/toast-root.d.ts +42 -8
  265. package/dist/toast/root/toast-root.js +64 -4
  266. package/dist/toggle/group/toggle-group.d.ts +57 -15
  267. package/dist/toggle/group/toggle-group.js +69 -9
  268. package/dist/toggle/root/toggle-root.d.ts +12 -1
  269. package/dist/toggle/root/toggle-root.js +11 -3
  270. package/dist/toolbar/root/toolbar-root.d.ts +13 -0
  271. package/dist/toolbar/root/toolbar-root.js +15 -5
  272. package/dist/tooltip/focus-target.d.ts +6 -0
  273. package/dist/tooltip/focus-target.js +9 -0
  274. package/dist/tooltip/root/tooltip-root.d.ts +42 -17
  275. package/dist/tooltip/root/tooltip-root.js +50 -9
  276. package/dist/tour/naming.d.ts +30 -0
  277. package/dist/tour/naming.js +10 -0
  278. package/dist/tour/root/tour-root.d.ts +35 -0
  279. package/dist/tour/root/tour-root.js +56 -5
  280. package/dist/tour/stop/tour-stop.d.ts +53 -8
  281. package/dist/tour/stop/tour-stop.js +45 -15
  282. package/dist/tour/wait.d.ts +11 -0
  283. package/dist/tour/wait.js +19 -0
  284. package/dist/tree/item/tree-item.d.ts +54 -1
  285. package/dist/tree/item/tree-item.js +89 -20
  286. package/dist/tree/root/tree-root.d.ts +37 -0
  287. package/dist/tree/root/tree-root.js +51 -6
  288. package/dist/tree/selection.d.ts +24 -0
  289. package/dist/tree/selection.js +26 -0
  290. package/dist/trend/root/trend-root.d.ts +13 -0
  291. package/dist/trend/root/trend-root.js +14 -9
  292. package/dist/video/media-events.d.ts +49 -0
  293. package/dist/video/media-events.js +39 -0
  294. package/dist/video/root/video-root.d.ts +99 -13
  295. package/dist/video/root/video-root.js +84 -47
  296. package/dist/video-playlist/menu/video-playlist-menu.d.ts +3 -0
  297. package/dist/video-playlist/menu/video-playlist-menu.js +2 -1
  298. package/dist/video-playlist/order.d.ts +41 -0
  299. package/dist/video-playlist/order.js +34 -0
  300. package/dist/video-playlist/root/video-playlist-root.d.ts +70 -2
  301. package/dist/video-playlist/root/video-playlist-root.js +60 -16
  302. package/dist/virtual-list/controls.d.ts +4 -0
  303. package/dist/virtual-list/controls.js +30 -0
  304. package/dist/virtual-list/fill.d.ts +30 -0
  305. package/dist/virtual-list/fill.js +39 -0
  306. package/dist/virtual-list/keys.d.ts +15 -0
  307. package/dist/virtual-list/keys.js +24 -0
  308. package/dist/virtual-list/root/virtual-list-root.d.ts +155 -23
  309. package/dist/virtual-list/root/virtual-list-root.js +175 -34
  310. package/lint.json +1 -1
  311. package/package.json +5 -5
  312. package/types/jsx.d.ts +8871 -1286
  313. package/types/svelte.d.ts +3 -0
  314. package/types/vue.d.ts +1918 -269
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { AriaForwardController, customElement, fillTemplate, HelixFormElement, MixinControllerValue, MixinField, restoreValue, } from '@fusion.dev/helix-core';
7
+ import { AriaForwardController, customElement, fillTemplate, formatNumber, HelixFormElement, MixinControllerValue, MixinField, restoreValue, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  let HelixHeadlessSlider = class HelixHeadlessSlider extends MixinControllerValue(MixinField(HelixFormElement)) {
@@ -14,12 +14,14 @@ let HelixHeadlessSlider = class HelixHeadlessSlider extends MixinControllerValue
14
14
  target: () => this.partNamed('control'),
15
15
  });
16
16
  this.announcesInput = true;
17
+ this.locale = '';
17
18
  this.markerLabels = false;
18
19
  this.markers = 0;
19
20
  this.max = 100;
20
21
  this.maximumLabel = 'maximum';
21
22
  this.min = 0;
22
23
  this.minimumLabel = 'minimum';
24
+ this.minStepsBetweenThumbs = 0;
23
25
  this.range = false;
24
26
  this.showValue = false;
25
27
  this.step = 1;
@@ -29,9 +31,10 @@ let HelixHeadlessSlider = class HelixHeadlessSlider extends MixinControllerValue
29
31
  if (this.range) {
30
32
  const [start, end] = this.bounds;
31
33
  const moved = Number(control.value);
34
+ const gap = this.gap;
32
35
  const pair = control.dataset.thumb === 'start'
33
- ? [Math.min(moved, end), end]
34
- : [start, Math.max(moved, start)];
36
+ ? [Math.min(moved, end - gap), end]
37
+ : [start, Math.max(moved, start + gap)];
35
38
  this.requestValue(pair.join(','));
36
39
  restoreValue(control, String(control.dataset.thumb === 'start' ? this.bounds[0] : this.bounds[1]));
37
40
  return;
@@ -47,7 +50,7 @@ let HelixHeadlessSlider = class HelixHeadlessSlider extends MixinControllerValue
47
50
  this.valueText = '';
48
51
  }
49
52
  get reserve() {
50
- const widest = Math.max(String(this.min).length, String(this.max).length);
53
+ const widest = Math.max(this.said(this.min).length, this.said(this.max).length);
51
54
  return this.range ? widest * 2 + ' to '.length : widest;
52
55
  }
53
56
  get precision() {
@@ -141,8 +144,27 @@ let HelixHeadlessSlider = class HelixHeadlessSlider extends MixinControllerValue
141
144
  const at = Number.isFinite(parsed) ? parsed : this.min + (this.max - this.min) / 2;
142
145
  return String(this.settled(at));
143
146
  }
147
+ get gap() {
148
+ return Math.max(0, this.minStepsBetweenThumbs) * this.step;
149
+ }
150
+ get formats() {
151
+ return this.formatter !== undefined || this.formatOptions !== undefined;
152
+ }
153
+ said(at) {
154
+ const number = typeof at === 'number' ? at : Number.parseFloat(at);
155
+ if (!Number.isFinite(number)) {
156
+ return String(at);
157
+ }
158
+ if (this.formatter) {
159
+ return this.formatter(number);
160
+ }
161
+ return this.formatOptions ? formatNumber(number, this.locale, this.formatOptions) : String(at);
162
+ }
144
163
  spoken(at) {
145
- return this.valueText ? fillTemplate(this.valueText, { value: at }) : nothing;
164
+ if (this.valueText) {
165
+ return fillTemplate(this.valueText, { value: this.said(at) });
166
+ }
167
+ return this.formats ? this.said(at) : nothing;
146
168
  }
147
169
  updated(changed) {
148
170
  super.updated(changed);
@@ -161,8 +183,8 @@ let HelixHeadlessSlider = class HelixHeadlessSlider extends MixinControllerValue
161
183
  step=${this.step}
162
184
  .value=${String(at)}
163
185
  aria-labelledby=${this.labeled ? `${this.labelId} ${which}-name` : `${which}-name`}
164
- aria-valuemin=${which === 'end' ? start : nothing}
165
- aria-valuemax=${which === 'start' ? end : nothing}
186
+ aria-valuemin=${which === 'end' ? start + this.gap : nothing}
187
+ aria-valuemax=${which === 'start' ? end - this.gap : nothing}
166
188
  aria-valuetext=${this.spoken(at)}
167
189
  aria-describedby=${this.describedBy ?? nothing}
168
190
  aria-invalid=${this.invalidity ?? nothing}
@@ -207,7 +229,9 @@ let HelixHeadlessSlider = class HelixHeadlessSlider extends MixinControllerValue
207
229
  ${this.markerValues.map((at) => html `<span
208
230
  part="marker"
209
231
  style="--slider-marker-at: ${((at - this.min) / (this.max - this.min)) * 100}%"
210
- >${this.markerLabels ? html `<span part="marker-label">${at}</span>` : nothing}</span
232
+ >${this.markerLabels
233
+ ? html `<span part="marker-label">${this.said(at)}</span>`
234
+ : nothing}</span
211
235
  >`)}
212
236
  </div>`
213
237
  : nothing}
@@ -217,13 +241,22 @@ let HelixHeadlessSlider = class HelixHeadlessSlider extends MixinControllerValue
217
241
  for=${this.range ? 'control control-end' : 'control'}
218
242
  aria-hidden="true"
219
243
  style=${`--_slider-output-reserve: ${this.reserve}ch`}
220
- >${this.range ? `${start} to ${end}` : this.value}</output
244
+ >${this.range ? `${this.said(start)} to ${this.said(end)}` : this.said(this.value)}</output
221
245
  >`
222
246
  : nothing}
223
247
  </div>
224
248
  ${this.renderHint()}${this.renderFeedback()}`;
225
249
  }
226
250
  };
251
+ __decorate([
252
+ property({ attribute: 'format-options', type: Object })
253
+ ], HelixHeadlessSlider.prototype, "formatOptions", void 0);
254
+ __decorate([
255
+ property({ attribute: false })
256
+ ], HelixHeadlessSlider.prototype, "formatter", void 0);
257
+ __decorate([
258
+ property()
259
+ ], HelixHeadlessSlider.prototype, "locale", void 0);
227
260
  __decorate([
228
261
  property({ attribute: 'marker-labels', reflect: true, type: Boolean })
229
262
  ], HelixHeadlessSlider.prototype, "markerLabels", void 0);
@@ -242,6 +275,9 @@ __decorate([
242
275
  __decorate([
243
276
  property({ attribute: 'minimum-label' })
244
277
  ], HelixHeadlessSlider.prototype, "minimumLabel", void 0);
278
+ __decorate([
279
+ property({ attribute: 'min-steps-between-thumbs', type: Number })
280
+ ], HelixHeadlessSlider.prototype, "minStepsBetweenThumbs", void 0);
245
281
  __decorate([
246
282
  property({ reflect: true })
247
283
  ], HelixHeadlessSlider.prototype, "orientation", void 0);
@@ -179,6 +179,17 @@ export declare class HelixHeadlessSplitter extends HelixElement {
179
179
  */
180
180
  get position(): number;
181
181
  set position(next: number);
182
+ /**
183
+ * Where a dragged divider snaps, comma separated, as Web Awesome's split
184
+ * panel does: a bare number is a percentage and a length such as `240px` is
185
+ * measured along the splitter, so `snap="25, 50, 75"` or `snap="240px, 50"`.
186
+ * The arrow keys move by `step` and do not snap.
187
+ */
188
+ snap: string;
189
+ /**
190
+ * How close a drag has to come to a snap point to land on it, in pixels.
191
+ */
192
+ snapThreshold: number;
182
193
  /**
183
194
  * How far one arrow key press moves the divider, as a percentage.
184
195
  */
@@ -434,6 +445,8 @@ export declare class HelixHeadlessSplitter extends HelixElement {
434
445
  private settle;
435
446
  private readonly handlePointerDown;
436
447
  private readonly handlePointerMove;
448
+ /** Where a drag at `position` lands once `snap` has had its say. */
449
+ private snapped;
437
450
  private readonly handlePointerUp;
438
451
  /**
439
452
  * The keys a separator answers.
@@ -5,9 +5,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  var HelixHeadlessSplitter_1;
8
- import { AriaForwardController, capturePointer, closestInstance, customElement, HelixBeforeCollapseEvent, HelixBeforeResizeEvent, HelixCollapseEvent, HelixElement, HelixResizedEvent, inlineStep, isRtl, requestChange, } from '@fusion.dev/helix-core';
8
+ import { AriaForwardController, capturePointer, closestInstance, commaList, customElement, HelixBeforeCollapseEvent, HelixBeforeResizeEvent, HelixCollapseEvent, HelixElement, HelixResizedEvent, inlineStep, isRtl, requestChange, } from '@fusion.dev/helix-core';
9
9
  import { html, nothing } from 'lit';
10
10
  import { property, state } from 'lit/decorators.js';
11
+ import { snapTo } from '../snap.js';
11
12
  const STACK_BELOW = 512;
12
13
  let HelixHeadlessSplitter = HelixHeadlessSplitter_1 = class HelixHeadlessSplitter extends HelixElement {
13
14
  constructor() {
@@ -23,6 +24,8 @@ let HelixHeadlessSplitter = HelixHeadlessSplitter_1 = class HelixHeadlessSplitte
23
24
  });
24
25
  this.max = 100;
25
26
  this.min = 0;
27
+ this.snap = '';
28
+ this.snapThreshold = 12;
26
29
  this.step = 2;
27
30
  this.positionState = undefined;
28
31
  this.collapsedState = undefined;
@@ -57,7 +60,7 @@ let HelixHeadlessSplitter = HelixHeadlessSplitter_1 = class HelixHeadlessSplitte
57
60
  const along = this.vertical ? event.clientY : event.clientX;
58
61
  const raw = ((along - origin.start) / origin.length) * 100;
59
62
  const rtl = !this.vertical && isRtl(this);
60
- this.move(rtl ? 100 - raw : raw);
63
+ this.move(this.snapped(rtl ? 100 - raw : raw, origin.length));
61
64
  };
62
65
  this.handlePointerUp = (event) => {
63
66
  if (!this.origin) {
@@ -345,6 +348,15 @@ let HelixHeadlessSplitter = HelixHeadlessSplitter_1 = class HelixHeadlessSplitte
345
348
  });
346
349
  }
347
350
  }
351
+ snapped(position, length) {
352
+ if (this.snap === '' || length <= 0) {
353
+ return position;
354
+ }
355
+ const points = commaList(this.snap)
356
+ .map((point) => this.toPercent(point, Number.NaN))
357
+ .filter((point) => Number.isFinite(point));
358
+ return snapTo(position, points, (this.snapThreshold / length) * 100);
359
+ }
348
360
  travel(key) {
349
361
  if (!this.vertical) {
350
362
  return inlineStep(this, key);
@@ -541,6 +553,12 @@ __decorate([
541
553
  __decorate([
542
554
  property({ type: Number })
543
555
  ], HelixHeadlessSplitter.prototype, "position", null);
556
+ __decorate([
557
+ property()
558
+ ], HelixHeadlessSplitter.prototype, "snap", void 0);
559
+ __decorate([
560
+ property({ attribute: 'snap-threshold', type: Number })
561
+ ], HelixHeadlessSplitter.prototype, "snapThreshold", void 0);
544
562
  __decorate([
545
563
  property({ type: Number })
546
564
  ], HelixHeadlessSplitter.prototype, "step", void 0);
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Where a dragged divider lands: on the nearest snap point within `threshold`,
3
+ * or where the pointer is.
4
+ *
5
+ * Every number is a percentage of the splitter's box, so the caller turns a
6
+ * point written as a length, and the threshold, into one first. Ties go to the
7
+ * point written first.
8
+ */
9
+ export declare const snapTo: (position: number, points: readonly number[], threshold: number) => number;
@@ -0,0 +1,12 @@
1
+ export const snapTo = (position, points, threshold) => {
2
+ let best;
3
+ let distance = Number.POSITIVE_INFINITY;
4
+ for (const point of points) {
5
+ const away = Math.abs(point - position);
6
+ if (away <= threshold && away < distance) {
7
+ best = point;
8
+ distance = away;
9
+ }
10
+ }
11
+ return best ?? position;
12
+ };
@@ -21,6 +21,8 @@ import { type PropertyValues, type TemplateResult } from 'lit';
21
21
  * @slot - The value.
22
22
  * @slot label - What the value measures.
23
23
  * @slot unit - The unit, shown beside the value.
24
+ *
25
+ * @csspart value - The slot the value is written in. A slot draws no box, so it takes the inherited properties, such as color and font, and passes them to the value.
24
26
  */
25
27
  export declare class HelixHeadlessStat extends HelixElement {
26
28
  /**
@@ -23,7 +23,7 @@ let HelixHeadlessStat = class HelixHeadlessStat extends HelixElement {
23
23
  }
24
24
  render() {
25
25
  return html `<slot name="label"></slot>
26
- <slot></slot>
26
+ <slot part="value"></slot>
27
27
  <slot name="unit"></slot>`;
28
28
  }
29
29
  };
@@ -0,0 +1,15 @@
1
+ /** What linear mode reads of a step. */
2
+ export interface ReachableStep {
3
+ /** Whether the stage is finished. */
4
+ complete: boolean;
5
+ /** Whether a reader may pass the stage without finishing it. */
6
+ optional: boolean;
7
+ }
8
+ /**
9
+ * Whether a reader on step `from` may go to step `to`, in a linear sequence.
10
+ *
11
+ * Back is always allowed, as Ark UI's linear steps allow it. Forward is allowed
12
+ * only where every stage from the one the reader is on up to the target is
13
+ * complete or optional, so no stage is passed unfinished.
14
+ */
15
+ export declare const canReach: (steps: readonly ReachableStep[], from: number, to: number) => boolean;
@@ -0,0 +1,12 @@
1
+ export const canReach = (steps, from, to) => {
2
+ if (to <= from) {
3
+ return true;
4
+ }
5
+ for (let at = Math.max(from, 0); at < to; at += 1) {
6
+ const step = steps[at];
7
+ if (step && !step.complete && !step.optional) {
8
+ return false;
9
+ }
10
+ }
11
+ return true;
12
+ };
@@ -13,6 +13,13 @@ declare const HelixHeadlessSteps_base: (new (...args: any[]) => import("@fusion.
13
13
  * sequence is correct in the server's markup, where the root cannot count its
14
14
  * slotted children.
15
15
  *
16
+ * `linear` keeps a reader from passing a stage they have not finished, as Ark
17
+ * UI's linear steps do: a stage ahead is out of reach, and its button disabled,
18
+ * until every stage before it is `complete` or `optional`. Going back is always
19
+ * allowed. To check a stage before a reader leaves it, cancel
20
+ * `helix-before-activate` while it is not valid. `next()` and `previous()` move
21
+ * one stage either way, under the same rules, for your own buttons.
22
+ *
16
23
  * @since 0.1.0
17
24
  * @status stable
18
25
  * @category navigation
@@ -33,6 +40,11 @@ export declare class HelixHeadlessSteps extends HelixHeadlessSteps_base {
33
40
  * needs a name of its own rather than borrowing the heading above it.
34
41
  */
35
42
  label: string;
43
+ /**
44
+ * Whether a reader has to finish each stage, or pass an `optional` one,
45
+ * before going on to the next.
46
+ */
47
+ linear: boolean;
36
48
  /**
37
49
  * Which way the steps run.
38
50
  *
@@ -62,6 +74,24 @@ export declare class HelixHeadlessSteps extends HelixHeadlessSteps_base {
62
74
  variant?: 'numeric';
63
75
  /** The steps, in the order the consumer wrote them. */
64
76
  private get steps();
77
+ /** The index of the stage the reader is on, or `-1`. */
78
+ private get at();
79
+ /**
80
+ * Moves to the next stage that can be gone to, as Ark UI's `goToNextStep`
81
+ * does. Returns whether it moved: not past the last stage, not into a stage
82
+ * `linear` holds out of reach, and not where a listener refused.
83
+ */
84
+ next(): boolean;
85
+ /** Moves to the stage before, as Ark UI's `goToPrevStep` does. Returns whether it moved. */
86
+ previous(): boolean;
87
+ /** Moves `delta` stages, skipping disabled ones. */
88
+ private step;
89
+ /** Whether the stage at `index` can be gone to from where the reader is. */
90
+ private reachable;
91
+ /** Marks the stages a linear sequence holds out of reach. Client only. */
92
+ private lock;
93
+ /** Watches what decides a stage's reach: which is current, which are done. */
94
+ private watcher;
65
95
  /**
66
96
  * Puts `active` on whichever step owns it.
67
97
  *
@@ -7,23 +7,62 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  import { customElement, HelixElement, hostAria, MixinControllerActive, whenHydrated, } from '@fusion.dev/helix-core';
8
8
  import { html } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
+ import { canReach } from '../reach.js';
10
11
  let HelixHeadlessSteps = class HelixHeadlessSteps extends MixinControllerActive(HelixElement) {
11
12
  constructor() {
12
13
  super(...arguments);
13
14
  this.label = 'Steps';
15
+ this.linear = false;
14
16
  this.handleSelection = (event) => {
15
17
  if (event.defaultPrevented || !this.steps.includes(event.target)) {
16
18
  return;
17
19
  }
20
+ if (!this.reachable(this.steps.indexOf(event.target))) {
21
+ return;
22
+ }
18
23
  this.requestActive(event.detail.value);
19
24
  };
20
25
  this.handleSlotChange = () => {
21
26
  this.sync();
27
+ this.lock();
22
28
  };
23
29
  }
24
30
  get steps() {
25
31
  return [...this.querySelectorAll(':scope > *')].filter((one) => 'current' in one);
26
32
  }
33
+ get at() {
34
+ return this.steps.findIndex((step) => step.current);
35
+ }
36
+ next() {
37
+ return this.step(1);
38
+ }
39
+ previous() {
40
+ return this.step(-1);
41
+ }
42
+ step(delta) {
43
+ const steps = this.steps;
44
+ let index = this.at + delta;
45
+ while (steps[index]?.disabled) {
46
+ index += delta;
47
+ }
48
+ const target = steps[index];
49
+ if (!target || !this.reachable(index)) {
50
+ return false;
51
+ }
52
+ return this.requestActive(target.value);
53
+ }
54
+ reachable(index) {
55
+ return !this.linear || canReach(this.steps, this.at, index);
56
+ }
57
+ lock() {
58
+ const steps = this.steps;
59
+ steps.forEach((step, index) => {
60
+ const locked = !this.reachable(index);
61
+ whenHydrated(step, () => {
62
+ step.locked = locked;
63
+ });
64
+ });
65
+ }
27
66
  sync() {
28
67
  if (this.active === '') {
29
68
  return;
@@ -40,10 +79,18 @@ let HelixHeadlessSteps = class HelixHeadlessSteps extends MixinControllerActive(
40
79
  connectedCallback() {
41
80
  super.connectedCallback();
42
81
  this.addEventListener('helix-select', this.handleSelection);
82
+ this.watcher = new MutationObserver(() => this.lock());
83
+ this.watcher.observe(this, {
84
+ attributeFilter: ['complete', 'current', 'optional'],
85
+ attributes: true,
86
+ subtree: true,
87
+ });
43
88
  }
44
89
  disconnectedCallback() {
45
90
  super.disconnectedCallback();
46
91
  this.removeEventListener('helix-select', this.handleSelection);
92
+ this.watcher?.disconnect();
93
+ this.watcher = undefined;
47
94
  }
48
95
  willUpdate(changed) {
49
96
  super.willUpdate(changed);
@@ -54,6 +101,9 @@ let HelixHeadlessSteps = class HelixHeadlessSteps extends MixinControllerActive(
54
101
  if (changed.has('active')) {
55
102
  this.sync();
56
103
  }
104
+ if (changed.has('linear') || changed.has('active')) {
105
+ this.lock();
106
+ }
57
107
  }
58
108
  render() {
59
109
  return html `<slot @slotchange=${this.handleSlotChange}></slot>`;
@@ -62,6 +112,9 @@ let HelixHeadlessSteps = class HelixHeadlessSteps extends MixinControllerActive(
62
112
  __decorate([
63
113
  property()
64
114
  ], HelixHeadlessSteps.prototype, "label", void 0);
115
+ __decorate([
116
+ property({ reflect: true, type: Boolean })
117
+ ], HelixHeadlessSteps.prototype, "linear", void 0);
65
118
  __decorate([
66
119
  property({ reflect: true })
67
120
  ], HelixHeadlessSteps.prototype, "orientation", void 0);
@@ -1,5 +1,5 @@
1
1
  import { HelixElement } from '@fusion.dev/helix-core';
2
- import type { PropertyValues, TemplateResult } from 'lit';
2
+ import { type PropertyValues, type TemplateResult } from 'lit';
3
3
  import '../../button/index.js';
4
4
  /**
5
5
  * @summary One stage in a sequence.
@@ -21,6 +21,12 @@ import '../../button/index.js';
21
21
  * and `::after` from properties the list sets, so the step renders no extra
22
22
  * element for them.
23
23
  *
24
+ * A finished stage says so in words: the name's button is described by
25
+ * `complete-label`, "Complete" unless you translate it, and a stage that
26
+ * becomes complete while the page is open says it once in a polite live
27
+ * region. The current stage's button carries `aria-current="step"`, and only
28
+ * the button, so the state is said once, on the control.
29
+ *
24
30
  * @since 0.1.0
25
31
  * @status stable
26
32
  * @aliases Stage
@@ -38,15 +44,23 @@ import '../../button/index.js';
38
44
  * @csspart description - The line under the name.
39
45
  * @csspart label - The step's name, which is a control.
40
46
  * @csspart label-button - The button inside the label.
47
+ * @csspart label-live - The live region inside that button, rendered only from the first time the button is pending.
41
48
  * @csspart label-text - The words on that button, trimmed to their capitals and baseline.
49
+ * @csspart live - The live region that says a stage was completed, rendered from the first time one is.
42
50
  * @csspart mark - The glyph inside the marker: a tick, a dot, or an empty ring.
43
51
  * @csspart marker - The shape carrying the number or the check.
52
+ * @csspart state - The words that describe a finished stage's button. Hidden.
44
53
  */
45
54
  export declare class HelixHeadlessStep extends HelixElement {
46
55
  /**
47
56
  * Whether this stage is finished.
48
57
  */
49
58
  complete: boolean;
59
+ /**
60
+ * The words that tell a screen reader the stage is finished. Translate it
61
+ * with the page.
62
+ */
63
+ completeLabel: string;
50
64
  /**
51
65
  * Whether this is the current stage.
52
66
  */
@@ -55,11 +69,27 @@ export declare class HelixHeadlessStep extends HelixElement {
55
69
  * Whether the stage is disabled, so the user cannot go to it.
56
70
  */
57
71
  disabled: boolean;
72
+ /**
73
+ * @internal Set by a linear sequence: whether the stage is out of reach
74
+ * until the ones before it are finished. A property, because the sequence
75
+ * writes it after the step upgrades.
76
+ */
77
+ locked: boolean;
78
+ /**
79
+ * Whether a reader may pass the stage without finishing it, in a sequence
80
+ * with `linear`. Ark UI's skippable step.
81
+ */
82
+ optional: boolean;
58
83
  /**
59
84
  * The value the step sends in `helix-select`.
60
85
  */
61
86
  value: string;
62
- /** Fires `helix-select` for the step, unless the step is `disabled`. */
87
+ /** Says a stage was finished, from the first time one is. */
88
+ private readonly status;
89
+ /**
90
+ * Fires `helix-select` for the step, unless the step is `disabled` or a
91
+ * linear sequence has it out of reach.
92
+ */
63
93
  select(): void;
64
94
  /**
65
95
  * The mark this stage's state calls for.
@@ -84,6 +114,13 @@ export declare class HelixHeadlessStep extends HelixElement {
84
114
  */
85
115
  protected renderMarker(): TemplateResult;
86
116
  protected willUpdate(changed: PropertyValues): void;
117
+ /**
118
+ * Says a stage that was finished while the page is open, with its name.
119
+ *
120
+ * Only a change after the first update, so a sequence served with its done
121
+ * stages says nothing when it arrives.
122
+ */
123
+ protected updated(changed: PropertyValues): void;
87
124
  /**
88
125
  * The step's own label, which is a control because a step can be gone to, behind a seam the styled tier can move.
89
126
  *
@@ -4,8 +4,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { customElement, HelixElement, HelixSelectEvent, hostAria } from '@fusion.dev/helix-core';
7
+ import { customElement, drawStatus, HelixElement, HelixSelectEvent, hostAria, StatusController, } from '@fusion.dev/helix-core';
8
8
  import { check, circle, record } from '@fusion.dev/helix-icons';
9
+ import { nothing } from 'lit';
9
10
  import { property } from 'lit/decorators.js';
10
11
  import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
11
12
  import { html } from 'lit/static-html.js';
@@ -14,12 +15,16 @@ let HelixHeadlessStep = class HelixHeadlessStep extends HelixElement {
14
15
  constructor() {
15
16
  super(...arguments);
16
17
  this.complete = false;
18
+ this.completeLabel = 'Complete';
17
19
  this.current = false;
18
20
  this.disabled = false;
21
+ this.locked = false;
22
+ this.optional = false;
19
23
  this.value = '';
24
+ this.status = new StatusController(this);
20
25
  }
21
26
  select() {
22
- if (this.disabled) {
27
+ if (this.disabled || this.locked) {
23
28
  return;
24
29
  }
25
30
  this.dispatchEvent(new HelixSelectEvent({ value: this.value }));
@@ -35,18 +40,26 @@ let HelixHeadlessStep = class HelixHeadlessStep extends HelixElement {
35
40
  willUpdate(changed) {
36
41
  super.willUpdate(changed);
37
42
  hostAria(this.internals, { role: 'listitem' });
38
- this.internals.ariaCurrent = this.current ? 'step' : null;
43
+ }
44
+ updated(changed) {
45
+ super.updated(changed);
46
+ if (changed.get('complete') === false && this.complete) {
47
+ const name = (this.textContent ?? '').replace(/\s+/g, ' ').trim();
48
+ this.status.say(name === '' ? this.completeLabel : `${name}, ${this.completeLabel}`);
49
+ }
39
50
  }
40
51
  renderLabel() {
41
52
  return html `<${this.tag('button')}
42
53
  part="label"
43
- exportparts="button: label-button, text: label-text"
54
+ exportparts="button: label-button, live: label-live, text: label-text"
44
55
  emphasis="ghost"
45
- ?disabled=${this.disabled}
56
+ aria-current=${this.current ? 'step' : nothing}
57
+ aria-describedby=${this.complete ? 'state' : nothing}
58
+ ?disabled=${this.disabled || this.locked}
46
59
  @click=${this.select}
47
60
  >
48
61
  <slot></slot>
49
- </${this.tag('button')}>`;
62
+ </${this.tag('button')}><span id="state" part="state" hidden>${this.complete ? this.completeLabel : ''}</span>`;
50
63
  }
51
64
  render() {
52
65
  return html `<span part="marker" aria-hidden="true">
@@ -56,18 +69,27 @@ let HelixHeadlessStep = class HelixHeadlessStep extends HelixElement {
56
69
  ${this.renderLabel()}
57
70
  <span part="description"><slot name="description"></slot></span>
58
71
  </span>
59
- <div part="content"><slot name="content"></slot></div>`;
72
+ <div part="content"><slot name="content"></slot></div>${drawStatus(this.status)}`;
60
73
  }
61
74
  };
62
75
  __decorate([
63
76
  property({ reflect: true, type: Boolean })
64
77
  ], HelixHeadlessStep.prototype, "complete", void 0);
78
+ __decorate([
79
+ property({ attribute: 'complete-label' })
80
+ ], HelixHeadlessStep.prototype, "completeLabel", void 0);
65
81
  __decorate([
66
82
  property({ reflect: true, type: Boolean })
67
83
  ], HelixHeadlessStep.prototype, "current", void 0);
68
84
  __decorate([
69
85
  property({ reflect: true, type: Boolean })
70
86
  ], HelixHeadlessStep.prototype, "disabled", void 0);
87
+ __decorate([
88
+ property({ attribute: false })
89
+ ], HelixHeadlessStep.prototype, "locked", void 0);
90
+ __decorate([
91
+ property({ reflect: true, type: Boolean })
92
+ ], HelixHeadlessStep.prototype, "optional", void 0);
71
93
  __decorate([
72
94
  property()
73
95
  ], HelixHeadlessStep.prototype, "value", void 0);
@@ -1,5 +1,5 @@
1
1
  import { AriaForwardController, HelixFormElement, HostClickController } from '@fusion.dev/helix-core';
2
- import { type PropertyValues, type TemplateResult } from 'lit';
2
+ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
3
3
  declare const HelixHeadlessSwitch_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerCheckedInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinFieldInterface) & typeof HelixFormElement;
4
4
  /**
5
5
  * @summary A control that turns something on or off.
@@ -40,7 +40,9 @@ declare const HelixHeadlessSwitch_base: (new (...args: any[]) => import("@fusion
40
40
  * @csspart track - The track. Draw the thumb on the track itself, with
41
41
  * `::part(track)::after` in your stylesheet. This tier ships no CSS, so it
42
42
  * renders no separate thumb element, which would be an empty child that costs
43
- * your layout as much as any other child. `ListItem` measured that cost.
43
+ * your layout as much as any other child. `ListItem` measured that cost. A
44
+ * subclass that draws one returns it from `renderThumb`, as the styled switch
45
+ * does.
44
46
  *
45
47
  * @cssstate checked - While it is on.
46
48
  * @cssstate invalid - The control has an error to show, from the browser's validation or from your `feedback`.
@@ -70,6 +72,14 @@ export declare class HelixHeadlessSwitch extends HelixHeadlessSwitch_base {
70
72
  * rendered, which React reports on hydration and does not patch up.
71
73
  */
72
74
  private markEmpty;
75
+ /**
76
+ * The thumb, drawn inside the track after the input: nothing on this tier.
77
+ *
78
+ * A seam for a tier that draws the thumb as an element, so it can be a part
79
+ * and hold icons. An element here would be an empty child on every page that
80
+ * loads only this tier, which is the cost the `track` part notes.
81
+ */
82
+ protected renderThumb(): TemplateResult | typeof nothing;
73
83
  protected render(): TemplateResult;
74
84
  }
75
85
  declare global {
@@ -43,6 +43,9 @@ let HelixHeadlessSwitch = class HelixHeadlessSwitch extends MixinControllerCheck
43
43
  markEmpty() {
44
44
  markRegion(this.renderRoot, 'label', ['']);
45
45
  }
46
+ renderThumb() {
47
+ return nothing;
48
+ }
46
49
  render() {
47
50
  return html `<label part="field">
48
51
  <span part="track">
@@ -55,9 +58,11 @@ let HelixHeadlessSwitch = class HelixHeadlessSwitch extends MixinControllerCheck
55
58
  ?required=${this.required}
56
59
  aria-describedby=${this.describedBy ?? nothing}
57
60
  aria-invalid=${this.invalidity ?? nothing}
61
+ aria-readonly=${this.readOnly ? 'true' : nothing}
58
62
  @change=${this.handleChange}
63
+ @click=${this.holdReadOnly}
59
64
  @input=${this.stopInner}
60
- />
65
+ />${this.renderThumb()}
61
66
  </span>
62
67
  <span part="label"><slot>${this.label}</slot></span>
63
68
  </label>