@fusion.dev/helix-headless 0.144.0 → 0.146.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 (319) hide show
  1. package/custom-elements.json +15195 -4240
  2. package/dist/accordion/item/accordion-item.d.ts +62 -12
  3. package/dist/accordion/item/accordion-item.js +41 -10
  4. package/dist/accordion/root/accordion-root.d.ts +14 -5
  5. package/dist/accordion/root/accordion-root.js +7 -1
  6. package/dist/announcement/root/announcement-root.d.ts +24 -3
  7. package/dist/announcement/root/announcement-root.js +39 -2
  8. package/dist/app-header/root/app-header-root.d.ts +12 -0
  9. package/dist/app-header/root/app-header-root.js +13 -1
  10. package/dist/app-header/sectioning.d.ts +9 -0
  11. package/dist/app-header/sectioning.js +27 -0
  12. package/dist/avatar/group/avatar-group.d.ts +20 -14
  13. package/dist/avatar/group/avatar-group.js +17 -19
  14. package/dist/badge/root/badge-root.d.ts +3 -1
  15. package/dist/badge/root/badge-root.js +2 -2
  16. package/dist/bar-chart/root/bar-chart-root.d.ts +18 -1
  17. package/dist/bar-chart/root/bar-chart-root.js +52 -15
  18. package/dist/bar-chart/stack.d.ts +15 -0
  19. package/dist/bar-chart/stack.js +19 -0
  20. package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +57 -1
  21. package/dist/breadcrumbs/root/breadcrumbs-root.js +73 -3
  22. package/dist/button/root/button-root.d.ts +26 -0
  23. package/dist/button/root/button-root.js +38 -18
  24. package/dist/button-group/root/button-group-root.d.ts +2 -1
  25. package/dist/button-group/root/button-group-root.js +5 -1
  26. package/dist/canvas/node/canvas-node.d.ts +4 -3
  27. package/dist/canvas/node/canvas-node.js +3 -2
  28. package/dist/canvas/root/canvas-root.d.ts +38 -3
  29. package/dist/canvas/root/canvas-root.js +123 -42
  30. package/dist/card/root/card-root.d.ts +24 -3
  31. package/dist/card/root/card-root.js +20 -8
  32. package/dist/carousel/root/carousel-root.d.ts +133 -4
  33. package/dist/carousel/root/carousel-root.js +174 -24
  34. package/dist/carousel/stops.d.ts +20 -0
  35. package/dist/carousel/stops.js +30 -0
  36. package/dist/chat/composer/chat-composer.d.ts +38 -6
  37. package/dist/chat/composer/chat-composer.js +42 -9
  38. package/dist/chat/message/chat-message.d.ts +32 -1
  39. package/dist/chat/message/chat-message.js +27 -10
  40. package/dist/chat/naming.d.ts +26 -0
  41. package/dist/chat/naming.js +14 -0
  42. package/dist/chat/root/chat-root.d.ts +58 -0
  43. package/dist/chat/root/chat-root.js +43 -3
  44. package/dist/checkbox/root/checkbox-root.d.ts +20 -0
  45. package/dist/checkbox/root/checkbox-root.js +14 -1
  46. package/dist/checkbox-group/root/checkbox-group-root.d.ts +8 -2
  47. package/dist/checkbox-group/root/checkbox-group-root.js +12 -10
  48. package/dist/checkbox-group/select-all.d.ts +27 -0
  49. package/dist/checkbox-group/select-all.js +12 -0
  50. package/dist/code-block/highlight.d.ts +15 -0
  51. package/dist/code-block/highlight.js +4 -0
  52. package/dist/code-block/root/code-block-root.d.ts +57 -2
  53. package/dist/code-block/root/code-block-root.js +63 -8
  54. package/dist/color-input/root/color-input-root.d.ts +3 -0
  55. package/dist/color-input/root/color-input-root.js +6 -3
  56. package/dist/color-picker/root/color-picker-root.d.ts +33 -4
  57. package/dist/color-picker/root/color-picker-root.js +80 -21
  58. package/dist/color-picker/swatches.d.ts +12 -0
  59. package/dist/color-picker/swatches.js +26 -0
  60. package/dist/combobox/root/combobox-root.d.ts +43 -0
  61. package/dist/combobox/root/combobox-root.js +79 -15
  62. package/dist/command/root/command-root.d.ts +16 -1
  63. package/dist/command/root/command-root.js +22 -4
  64. package/dist/copy-button/root/copy-button-root.d.ts +26 -1
  65. package/dist/copy-button/root/copy-button-root.js +12 -5
  66. package/dist/data-table/index.d.ts +1 -1
  67. package/dist/data-table/index.js +1 -1
  68. package/dist/data-table/keys.d.ts +24 -0
  69. package/dist/data-table/keys.js +24 -0
  70. package/dist/data-table/root/data-table-root.d.ts +170 -13
  71. package/dist/data-table/root/data-table-root.js +294 -52
  72. package/dist/data-table/tree.d.ts +55 -0
  73. package/dist/data-table/tree.js +54 -0
  74. package/dist/date-input/root/date-input-root.d.ts +3 -1
  75. package/dist/date-input/root/date-input-root.js +18 -7
  76. package/dist/date-picker/root/date-picker-root.js +12 -6
  77. package/dist/description-list/item/description-list-item.d.ts +17 -2
  78. package/dist/description-list/item/description-list-item.js +15 -2
  79. package/dist/description-list/root/description-list-root.d.ts +27 -1
  80. package/dist/description-list/root/description-list-root.js +26 -1
  81. package/dist/dialog/description.js +15 -1
  82. package/dist/dialog/root/dialog-root.d.ts +8 -2
  83. package/dist/dialog/root/dialog-root.js +16 -1
  84. package/dist/divider/root/divider-root.d.ts +3 -0
  85. package/dist/divider/root/divider-root.js +2 -1
  86. package/dist/donut-chart/root/donut-chart-root.d.ts +31 -0
  87. package/dist/donut-chart/root/donut-chart-root.js +48 -1
  88. package/dist/drawer/reveal.d.ts +8 -0
  89. package/dist/drawer/reveal.js +1 -0
  90. package/dist/drawer/root/drawer-root.d.ts +59 -0
  91. package/dist/drawer/root/drawer-root.js +63 -4
  92. package/dist/drilldown/item/drilldown-item.d.ts +11 -6
  93. package/dist/drilldown/item/drilldown-item.js +8 -5
  94. package/dist/drilldown/root/drilldown-root.d.ts +29 -0
  95. package/dist/drilldown/root/drilldown-root.js +28 -5
  96. package/dist/element-events.generated.js +83 -12
  97. package/dist/empty/root/empty-root.d.ts +3 -1
  98. package/dist/empty/root/empty-root.js +3 -2
  99. package/dist/file-input/root/file-input-root.d.ts +69 -6
  100. package/dist/file-input/root/file-input-root.js +82 -19
  101. package/dist/file-input/screen.d.ts +2 -1
  102. package/dist/filter-input/menu/filter-menu.d.ts +5 -0
  103. package/dist/filter-input/menu/filter-menu.js +16 -4
  104. package/dist/filter-input/root/filter-input-root.d.ts +30 -6
  105. package/dist/filter-input/root/filter-input-root.js +1 -1
  106. package/dist/filter-input/suggest.d.ts +28 -3
  107. package/dist/filter-input/suggest.js +18 -8
  108. package/dist/format-date/root/format-date-root.d.ts +9 -16
  109. package/dist/format-date/root/format-date-root.js +10 -27
  110. package/dist/heatmap/root/heatmap-root.d.ts +24 -13
  111. package/dist/heatmap/root/heatmap-root.js +34 -12
  112. package/dist/icon/root/icon-root.d.ts +12 -1
  113. package/dist/icon/root/icon-root.js +21 -10
  114. package/dist/icon/settle.d.ts +7 -0
  115. package/dist/icon/settle.js +10 -0
  116. package/dist/icon-button/root/icon-button-root.d.ts +2 -0
  117. package/dist/image/root/image-root.d.ts +5 -1
  118. package/dist/image/root/image-root.js +10 -2
  119. package/dist/input/root/input-root.d.ts +13 -3
  120. package/dist/input/root/input-root.js +12 -3
  121. package/dist/kbd/root/kbd-root.d.ts +35 -1
  122. package/dist/kbd/root/kbd-root.js +23 -4
  123. package/dist/legend/root/legend-root.d.ts +55 -8
  124. package/dist/legend/root/legend-root.js +55 -13
  125. package/dist/lightbox/root/lightbox-root.d.ts +49 -6
  126. package/dist/lightbox/root/lightbox-root.js +86 -19
  127. package/dist/lightbox/zoom-controller.d.ts +59 -0
  128. package/dist/lightbox/zoom-controller.js +128 -0
  129. package/dist/lightbox/zoom.d.ts +22 -0
  130. package/dist/lightbox/zoom.js +16 -0
  131. package/dist/line-chart/root/line-chart-root.d.ts +22 -1
  132. package/dist/line-chart/root/line-chart-root.js +21 -1
  133. package/dist/list/item/list-item.d.ts +70 -1
  134. package/dist/list/item/list-item.js +77 -6
  135. package/dist/list/numbering.d.ts +14 -0
  136. package/dist/list/numbering.js +8 -0
  137. package/dist/list/root/list-root.d.ts +155 -9
  138. package/dist/list/root/list-root.js +246 -4
  139. package/dist/list/selection.d.ts +49 -0
  140. package/dist/list/selection.js +30 -0
  141. package/dist/listbox/root/listbox-root.d.ts +37 -1
  142. package/dist/listbox/root/listbox-root.js +49 -4
  143. package/dist/loader/busy.d.ts +10 -0
  144. package/dist/loader/busy.js +11 -0
  145. package/dist/loader/root/loader-root.d.ts +9 -2
  146. package/dist/loader/root/loader-root.js +23 -3
  147. package/dist/map/root/map-root.d.ts +6 -2
  148. package/dist/map/root/map-root.js +5 -2
  149. package/dist/megamenu/root/megamenu-root.d.ts +62 -0
  150. package/dist/megamenu/root/megamenu-root.js +90 -5
  151. package/dist/menu/index.d.ts +1 -0
  152. package/dist/menu/index.js +1 -0
  153. package/dist/menu/item/menu-item.d.ts +87 -11
  154. package/dist/menu/item/menu-item.js +78 -22
  155. package/dist/menu/root/menu-root.d.ts +39 -1
  156. package/dist/menu/root/menu-root.js +65 -8
  157. package/dist/menu/section/menu-section.d.ts +55 -0
  158. package/dist/menu/section/menu-section.js +60 -0
  159. package/dist/meter/root/meter-root.d.ts +20 -1
  160. package/dist/meter/root/meter-root.js +11 -15
  161. package/dist/navigation/root/navigation-root.d.ts +18 -2
  162. package/dist/navigation/root/navigation-root.js +29 -3
  163. package/dist/notifications/root/notifications-root.d.ts +25 -0
  164. package/dist/notifications/root/notifications-root.js +33 -5
  165. package/dist/number-input/root/number-input-root.d.ts +17 -8
  166. package/dist/number-input/root/number-input-root.js +2 -7
  167. package/dist/object-inspector/root/object-inspector-root.d.ts +161 -32
  168. package/dist/object-inspector/root/object-inspector-root.js +264 -123
  169. package/dist/object-inspector/rows.d.ts +75 -0
  170. package/dist/object-inspector/rows.js +119 -0
  171. package/dist/option/root/option-root.d.ts +5 -3
  172. package/dist/outline/levels.d.ts +31 -0
  173. package/dist/outline/levels.js +23 -0
  174. package/dist/outline/root/outline-root.d.ts +86 -3
  175. package/dist/outline/root/outline-root.js +95 -12
  176. package/dist/pagination/size/pagination-size.d.ts +12 -2
  177. package/dist/pagination/size/pagination-size.js +20 -5
  178. package/dist/pin-input/code.d.ts +10 -0
  179. package/dist/pin-input/code.js +13 -0
  180. package/dist/pin-input/root/pin-input-root.d.ts +25 -1
  181. package/dist/pin-input/root/pin-input-root.js +10 -11
  182. package/dist/popover/hide-outside.d.ts +14 -0
  183. package/dist/popover/hide-outside.js +41 -0
  184. package/dist/popover/root/popover-root.d.ts +57 -7
  185. package/dist/popover/root/popover-root.js +58 -3
  186. package/dist/progress/root/progress-root.d.ts +20 -0
  187. package/dist/progress/root/progress-root.js +15 -15
  188. package/dist/qr-code/export.d.ts +26 -1
  189. package/dist/qr-code/export.js +14 -0
  190. package/dist/qr-code/root/qr-code-root.d.ts +19 -5
  191. package/dist/qr-code/root/qr-code-root.js +58 -9
  192. package/dist/quote/marks.d.ts +8 -0
  193. package/dist/quote/marks.js +5 -0
  194. package/dist/quote/root/quote-root.d.ts +14 -2
  195. package/dist/quote/root/quote-root.js +23 -1
  196. package/dist/radio/group/radio-group.d.ts +4 -10
  197. package/dist/radio/group/radio-group.js +5 -10
  198. package/dist/radio/root/radio-root.d.ts +6 -2
  199. package/dist/radio/root/radio-root.js +6 -1
  200. package/dist/rating/root/rating-root.d.ts +10 -5
  201. package/dist/rating/root/rating-root.js +32 -8
  202. package/dist/rating/steps.d.ts +7 -0
  203. package/dist/rating/steps.js +9 -0
  204. package/dist/scatter-chart/fit.d.ts +15 -0
  205. package/dist/scatter-chart/fit.js +35 -0
  206. package/dist/scatter-chart/root/scatter-chart-root.d.ts +21 -1
  207. package/dist/scatter-chart/root/scatter-chart-root.js +30 -17
  208. package/dist/scroll-area/root/scroll-area-root.d.ts +84 -0
  209. package/dist/scroll-area/root/scroll-area-root.js +106 -7
  210. package/dist/scroll-area/scrollbar-controller.d.ts +111 -0
  211. package/dist/scroll-area/scrollbar-controller.js +172 -0
  212. package/dist/scroll-area/scrollbar.d.ts +92 -0
  213. package/dist/scroll-area/scrollbar.js +33 -0
  214. package/dist/select/root/select-root.d.ts +15 -0
  215. package/dist/select/root/select-root.js +18 -6
  216. package/dist/skeleton/root/skeleton-root.d.ts +3 -0
  217. package/dist/skeleton/root/skeleton-root.js +4 -2
  218. package/dist/skip-link/root/skip-link-root.js +2 -2
  219. package/dist/slider/root/slider-root.d.ts +41 -4
  220. package/dist/slider/root/slider-root.js +23 -3
  221. package/dist/sparkline/readings.d.ts +18 -0
  222. package/dist/sparkline/readings.js +19 -0
  223. package/dist/sparkline/root/sparkline-root.d.ts +78 -7
  224. package/dist/sparkline/root/sparkline-root.js +118 -23
  225. package/dist/speed-dial/root/speed-dial-root.js +2 -2
  226. package/dist/splitter/root/splitter-root.d.ts +20 -12
  227. package/dist/splitter/root/splitter-root.js +226 -203
  228. package/dist/splitter/snap.d.ts +9 -0
  229. package/dist/splitter/snap.js +12 -0
  230. package/dist/stat/root/stat-root.d.ts +14 -5
  231. package/dist/stat/root/stat-root.js +21 -5
  232. package/dist/steps/reach.d.ts +20 -0
  233. package/dist/steps/reach.js +15 -0
  234. package/dist/steps/root/steps-root.d.ts +76 -0
  235. package/dist/steps/root/steps-root.js +93 -1
  236. package/dist/steps/step/step.d.ts +45 -2
  237. package/dist/steps/step/step.js +33 -6
  238. package/dist/switch/root/switch-root.d.ts +10 -0
  239. package/dist/table/column/table-column.d.ts +11 -10
  240. package/dist/table/column/table-column.js +8 -19
  241. package/dist/table/root/table-root.d.ts +126 -4
  242. package/dist/table/root/table-root.js +156 -6
  243. package/dist/table/row/table-row.d.ts +47 -1
  244. package/dist/table/row/table-row.js +39 -2
  245. package/dist/tabs/panel/tab-panel.d.ts +22 -5
  246. package/dist/tabs/panel/tab-panel.js +34 -6
  247. package/dist/tabs/root/tabs-root.d.ts +37 -1
  248. package/dist/tabs/root/tabs-root.js +22 -4
  249. package/dist/tabs/tab/tab.d.ts +41 -4
  250. package/dist/tabs/tab/tab.js +49 -3
  251. package/dist/tag/group/tag-group.d.ts +31 -4
  252. package/dist/tag/group/tag-group.js +46 -7
  253. package/dist/tag/root/tag-root.js +9 -2
  254. package/dist/textarea/root/textarea-root.d.ts +28 -1
  255. package/dist/textarea/root/textarea-root.js +40 -1
  256. package/dist/time-input/root/time-input-root.d.ts +5 -1
  257. package/dist/time-input/root/time-input-root.js +16 -8
  258. package/dist/time-picker/root/time-picker-root.d.ts +18 -4
  259. package/dist/time-picker/root/time-picker-root.js +7 -10
  260. package/dist/time-picker/wheel-name.d.ts +9 -0
  261. package/dist/time-picker/wheel-name.js +15 -0
  262. package/dist/timeline/group/timeline-group.d.ts +46 -0
  263. package/dist/timeline/group/timeline-group.js +37 -0
  264. package/dist/timeline/index.d.ts +1 -0
  265. package/dist/timeline/index.js +1 -0
  266. package/dist/timeline/root/timeline-root.d.ts +10 -3
  267. package/dist/toast/item/toast-item.d.ts +24 -18
  268. package/dist/toast/item/toast-item.js +36 -40
  269. package/dist/toast/root/toast-root.d.ts +6 -0
  270. package/dist/toast/root/toast-root.js +16 -1
  271. package/dist/toggle/group/toggle-group.d.ts +24 -3
  272. package/dist/toggle/group/toggle-group.js +34 -5
  273. package/dist/toolbar/root/toolbar-root.d.ts +13 -0
  274. package/dist/toolbar/root/toolbar-root.js +15 -5
  275. package/dist/tooltip/root/tooltip-root.d.ts +13 -2
  276. package/dist/tooltip/root/tooltip-root.js +9 -1
  277. package/dist/tour/back.d.ts +10 -0
  278. package/dist/tour/back.js +8 -0
  279. package/dist/tour/root/tour-root.d.ts +30 -2
  280. package/dist/tour/root/tour-root.js +34 -8
  281. package/dist/tree/item/tree-item.d.ts +61 -4
  282. package/dist/tree/item/tree-item.js +92 -20
  283. package/dist/tree/root/tree-root.d.ts +58 -0
  284. package/dist/tree/root/tree-root.js +80 -16
  285. package/dist/tree/selection.d.ts +24 -0
  286. package/dist/tree/selection.js +13 -0
  287. package/dist/trend/root/trend-root.d.ts +43 -18
  288. package/dist/trend/root/trend-root.js +31 -6
  289. package/dist/video/media-events.d.ts +44 -0
  290. package/dist/video/media-events.js +35 -0
  291. package/dist/video/root/video-root.d.ts +117 -18
  292. package/dist/video/root/video-root.js +93 -47
  293. package/dist/video-playlist/menu/video-playlist-menu.d.ts +5 -0
  294. package/dist/video-playlist/menu/video-playlist-menu.js +3 -1
  295. package/dist/video-playlist/order.d.ts +41 -0
  296. package/dist/video-playlist/order.js +34 -0
  297. package/dist/video-playlist/root/video-playlist-root.d.ts +77 -3
  298. package/dist/video-playlist/root/video-playlist-root.js +60 -16
  299. package/dist/virtual-list/controls.d.ts +4 -0
  300. package/dist/virtual-list/controls.js +30 -0
  301. package/dist/virtual-list/fill.d.ts +22 -0
  302. package/dist/virtual-list/fill.js +23 -0
  303. package/dist/virtual-list/keys.d.ts +15 -0
  304. package/dist/virtual-list/keys.js +24 -0
  305. package/dist/virtual-list/plan.d.ts +49 -0
  306. package/dist/virtual-list/plan.js +16 -0
  307. package/dist/virtual-list/root/virtual-list-root.d.ts +259 -26
  308. package/dist/virtual-list/root/virtual-list-root.js +333 -49
  309. package/lint.json +1 -1
  310. package/package.json +8 -8
  311. package/types/jsx.d.ts +8113 -1394
  312. package/types/svelte.d.ts +2 -0
  313. package/types/vue.d.ts +1678 -353
  314. package/dist/data-table/root/order.d.ts +0 -141
  315. package/dist/data-table/root/order.js +0 -76
  316. package/dist/listbox/range.d.ts +0 -17
  317. package/dist/listbox/range.js +0 -5
  318. package/dist/tag/selection.d.ts +0 -10
  319. package/dist/tag/selection.js +0 -12
@@ -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 { customElement, HelixElement, hostAria, reportRuntime, whenHydrated, } from '@fusion.dev/helix-core';
7
+ import { customElement, fillTemplate, HelixElement, hostAria, whenHydrated, } from '@fusion.dev/helix-core';
8
8
  import { html } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  export const FOLDS_UP_TO = 12;
@@ -12,17 +12,15 @@ let HelixHeadlessAvatarGroup = class HelixHeadlessAvatarGroup extends HelixEleme
12
12
  constructor() {
13
13
  super(...arguments);
14
14
  this.label = '';
15
- this.overflowLabel = '{count} more';
15
+ this.overflowLabel = '{count} more: {names}';
16
16
  this.folded = new WeakSet();
17
- this.warned = false;
18
17
  }
19
18
  get avatars() {
20
19
  return this.knownChildren.filter((child) => child instanceof HTMLElement);
21
20
  }
22
21
  get overflow() {
23
22
  const limit = this.max ?? 0;
24
- const limited = limit > 0 && limit <= FOLDS_UP_TO;
25
- return limited ? Math.max(this.avatars.length - limit, 0) : 0;
23
+ return limit > 0 ? Math.max(this.avatars.length - limit, 0) : 0;
26
24
  }
27
25
  willUpdate(changed) {
28
26
  super.willUpdate(changed);
@@ -35,23 +33,11 @@ let HelixHeadlessAvatarGroup = class HelixHeadlessAvatarGroup extends HelixEleme
35
33
  updated(changed) {
36
34
  super.updated(changed);
37
35
  this.fold();
38
- const limit = this.max ?? 0;
39
- if (limit > FOLDS_UP_TO && this.avatars.length > limit && !this.warned) {
40
- this.warned = true;
41
- reportRuntime({
42
- kind: 'max-past-fold',
43
- message: `<${this.localName}> has max="${this.max}", past the ${FOLDS_UP_TO} the fold is written for, ` +
44
- 'so every avatar is shown and none are counted. Lower `max`, or hand the group the ' +
45
- 'avatars you want shown.',
46
- tag: this.localName,
47
- });
48
- }
49
36
  }
50
37
  fold() {
51
38
  const limit = this.max ?? 0;
52
- const limited = limit > 0 && limit <= FOLDS_UP_TO;
53
39
  for (const [index, avatar] of this.avatars.entries()) {
54
- const past = limited && index >= limit;
40
+ const past = limit > 0 && index >= limit;
55
41
  if (past && !avatar.hidden) {
56
42
  this.folded.add(avatar);
57
43
  whenHydrated(avatar, () => {
@@ -66,6 +52,15 @@ let HelixHeadlessAvatarGroup = class HelixHeadlessAvatarGroup extends HelixEleme
66
52
  }
67
53
  }
68
54
  }
55
+ foldedNames() {
56
+ const limit = this.max ?? 0;
57
+ return this.avatars
58
+ .slice(limit)
59
+ .map((avatar) => avatar.name ||
60
+ avatar.getAttribute('aria-label') ||
61
+ '')
62
+ .filter(Boolean);
63
+ }
69
64
  render() {
70
65
  const past = this.overflow;
71
66
  return html `<slot @slotchange=${() => this.requestUpdate()}></slot>
@@ -73,7 +68,10 @@ let HelixHeadlessAvatarGroup = class HelixHeadlessAvatarGroup extends HelixEleme
73
68
  ? html `<span
74
69
  part="overflow"
75
70
  role="img"
76
- aria-label=${this.overflowLabel.replace('{count}', String(past))}
71
+ aria-label=${fillTemplate(this.overflowLabel, {
72
+ count: String(past),
73
+ names: this.foldedNames().join(', '),
74
+ }).replace(/[\s:,]+$/, '')}
77
75
  >+${past}</span
78
76
  >`
79
77
  : ''}`;
@@ -44,7 +44,9 @@ export declare class HelixHeadlessBadge extends HelixElement {
44
44
  /**
45
45
  * The badge's name, read by screen readers.
46
46
  *
47
- * Required for a dot, which has no text to read.
47
+ * Required for a dot, which has no text to read. `{count}` is replaced with
48
+ * what the badge shows, so `label="{count} unread"` reads "8 unread" and
49
+ * stays current as `value` changes, with no label of yours to keep in step.
48
50
  */
49
51
  label: string;
50
52
  /**
@@ -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 { customElement, HelixElement } from '@fusion.dev/helix-core';
7
+ import { customElement, fillTemplate, HelixElement } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  let HelixHeadlessBadge = class HelixHeadlessBadge extends HelixElement {
@@ -36,7 +36,7 @@ let HelixHeadlessBadge = class HelixHeadlessBadge extends HelixElement {
36
36
  data-blank=${blank ? '' : nothing}
37
37
  data-single=${text.length <= 1 ? '' : nothing}
38
38
  role="status"
39
- aria-label=${announced ? this.label || text : nothing}
39
+ aria-label=${announced ? fillTemplate(this.label, { count: text }) || text : nothing}
40
40
  >${blank ? html `<span aria-hidden="true">${text}</span>` : text}</span
41
41
  >`;
42
42
  }
@@ -176,6 +176,17 @@ export declare class HelixHeadlessBarChart extends HelixHeadlessBarChart_base {
176
176
  * of any scale question the picture raises.
177
177
  */
178
178
  secondary?: string;
179
+ /**
180
+ * Stacks a category's columns into one, each series standing on the ones
181
+ * before it, so the column's height is the category's total.
182
+ *
183
+ * Absent stands them side by side, as it always did. A negative reading
184
+ * hangs below zero on the negatives before it, so neither direction hides
185
+ * the other. The scale fits the stacks. A series
186
+ * in `lines` is still a line, measured on its own reading; columns on the
187
+ * second scale stack among themselves.
188
+ */
189
+ stacked: boolean;
179
190
  /** The series names on the second scale, lowercased and trimmed. */
180
191
  private get scaled();
181
192
  /** The series names drawn as a line, lowercased and trimmed for matching. */
@@ -204,7 +215,8 @@ export declare class HelixHeadlessBarChart extends HelixHeadlessBarChart_base {
204
215
  *
205
216
  * The highest, because which category leads is the question a bar chart is
206
217
  * read for, and the table beside it has every other number. The reading is
207
- * written the way the table writes it, such as `$128k` for `128000`.
218
+ * written the way the table writes it, such as `$128k` for `128000`. A
219
+ * series a legend hid is not drawn and is not said.
208
220
  */
209
221
  protected renderSummary(series: Series[]): TemplateResult;
210
222
  /**
@@ -214,6 +226,11 @@ export declare class HelixHeadlessBarChart extends HelixHeadlessBarChart_base {
214
226
  * and a screen reader hearing both hears the same numbers twice.
215
227
  */
216
228
  protected renderPlot(series: Series[], categories: string[], y: (value: number) => number, domain: [number, number], floor: number, z?: (value: number) => number): TemplateResult;
229
+ /**
230
+ * One category's columns stacked into one, each on the ones before it on
231
+ * its own scale, through the pure `stackSpans`.
232
+ */
233
+ private renderStack;
217
234
  /**
218
235
  * The numbers along one scale, drawn only where there are two of them.
219
236
  *
@@ -7,11 +7,13 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  import { byRow, CHART_PLOT, customElement, drawTooltip, extent, formatNumbers, HelixElement, linear, linePath, MixinChartSource, PLOT_HEIGHT, PLOT_WIDTH, seriesIndex, seriesNames, ticks, unbroken, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing, svg } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
+ import { stackEnds, stackSpans } from '../stack.js';
10
11
  import '../../tooltip/index.js';
11
12
  let HelixHeadlessBarChart = class HelixHeadlessBarChart extends MixinChartSource(HelixElement) {
12
13
  constructor() {
13
14
  super(...arguments);
14
15
  this.highestLabel = 'Highest';
16
+ this.stacked = false;
15
17
  }
16
18
  get scaled() {
17
19
  return new Set(seriesNames(this.secondary));
@@ -39,8 +41,22 @@ let HelixHeadlessBarChart = class HelixHeadlessBarChart extends MixinChartSource
39
41
  const own = (one) => scaled.has(one.name.trim().toLowerCase());
40
42
  const shown = series.filter((one) => this.showsSeries(one.name));
41
43
  const values = shown.flatMap((one) => one.points.map((point) => point.value));
44
+ const lined = this.lined;
45
+ const readingsOf = (group) => {
46
+ if (!this.stacked) {
47
+ return group.flatMap((one) => one.points.map((point) => point.value));
48
+ }
49
+ const columns = group.filter((one) => !lined.has(one.name.trim().toLowerCase()));
50
+ const slots = columns.map((one) => byRow(one, categories.length));
51
+ return [
52
+ ...group
53
+ .filter((one) => lined.has(one.name.trim().toLowerCase()))
54
+ .flatMap((one) => one.points.map((point) => point.value)),
55
+ ...stackEnds(categories.map((_, at) => slots.map((one) => one[at]?.value))),
56
+ ];
57
+ };
42
58
  const on = (which) => {
43
- const found = shown.filter(which).flatMap((one) => one.points.map((point) => point.value));
59
+ const found = readingsOf(shown.filter(which));
44
60
  return found.length > 0 ? found : values.length > 0 ? values : [0];
45
61
  };
46
62
  const [low, high] = extent(scaled.size === 0 ? on(() => true) : on((one) => !own(one)));
@@ -66,7 +82,7 @@ let HelixHeadlessBarChart = class HelixHeadlessBarChart extends MixinChartSource
66
82
  const columns = this.plottedColumns;
67
83
  const highest = series.flatMap((one, depth) => {
68
84
  const top = one.points.reduce((best, point) => (best === undefined || point.value > best.value ? point : best), undefined);
69
- if (top === undefined) {
85
+ if (top === undefined || !this.showsSeries(one.name)) {
70
86
  return [];
71
87
  }
72
88
  const text = rows[top.at]?.cells[columns[depth] ?? -1]?.text ?? String(top.value);
@@ -85,13 +101,15 @@ let HelixHeadlessBarChart = class HelixHeadlessBarChart extends MixinChartSource
85
101
  const columns = series
86
102
  .map((one, index) => ({ one, slots: byRow(one, categories.length), tone: index }))
87
103
  .filter(({ one }) => !lined.has(one.name.trim().toLowerCase()) && this.showsSeries(one.name));
88
- const stride = (slot * 0.72) / Math.max(columns.length, 1);
89
- const gap = columns.length > 1 ? stride * 0.08 : 0;
104
+ const abreast = this.stacked ? 1 : columns.length;
105
+ const stride = (slot * 0.72) / Math.max(abreast, 1);
106
+ const gap = abreast > 1 ? stride * 0.08 : 0;
90
107
  const thickness = stride - gap;
91
- const bar = (value, index, depth, tone, scale) => {
108
+ const bar = (value, index, depth, tone, scale, from) => {
92
109
  const at = scale(value);
93
- const along = Math.min(floor, at);
94
- const size = Math.abs(floor - at);
110
+ const base = from === undefined ? floor : scale(from);
111
+ const along = Math.min(base, at);
112
+ const size = Math.abs(base - at);
95
113
  const across = index * slot + slot * 0.14 + depth * stride + gap / 2;
96
114
  return sideways
97
115
  ? svg `<rect
@@ -151,12 +169,14 @@ let HelixHeadlessBarChart = class HelixHeadlessBarChart extends MixinChartSource
151
169
  data-active=${this.pointer.at === index ? '' : nothing}
152
170
  part="group${this.pointer.at === index ? ' group-active' : ''}"
153
171
  >
154
- ${columns.map(({ slots, one, tone }, depth) => {
155
- const point = slots[index];
156
- return point === undefined
157
- ? nothing
158
- : bar(point.value, index, depth, tone, against(one));
159
- })}
172
+ ${this.stacked
173
+ ? this.renderStack(columns, index, against, bar)
174
+ : columns.map(({ slots, one, tone }, depth) => {
175
+ const point = slots[index];
176
+ return point === undefined
177
+ ? nothing
178
+ : bar(point.value, index, depth, tone, against(one));
179
+ })}
160
180
  </g>`)}
161
181
  ${series.map((one) => lined.has(one.name.trim().toLowerCase()) && this.showsSeries(one.name)
162
182
  ? this.renderLine(one, series.indexOf(one), slot, against(one), sideways)
@@ -165,6 +185,17 @@ let HelixHeadlessBarChart = class HelixHeadlessBarChart extends MixinChartSource
165
185
  ${this.renderTooltip()}
166
186
  </div>`;
167
187
  }
188
+ renderStack(columns, index, against, bar) {
189
+ const scales = [...new Set(columns.map(({ one }) => against(one)))];
190
+ return scales.flatMap((scale) => {
191
+ const mine = columns.filter(({ one }) => against(one) === scale);
192
+ const spans = stackSpans(mine.map(({ slots }) => slots[index]?.value));
193
+ return mine.flatMap(({ tone }, place) => {
194
+ const span = spans[place];
195
+ return span === undefined ? [] : [bar(span[1], index, 0, tone, scale, span[0])];
196
+ });
197
+ });
198
+ }
168
199
  renderAxis(scale, domain, which, sideways, widest, tint) {
169
200
  const sizing = sideways ? undefined : `--bar-chart-axis: ${widest}ch`;
170
201
  return html `<div
@@ -234,10 +265,13 @@ let HelixHeadlessBarChart = class HelixHeadlessBarChart extends MixinChartSource
234
265
  return drawTooltip(this.sourceRows, at, this.tag('tooltip'), undefined, undefined, this.pointer);
235
266
  }
236
267
  const shown = series.filter((one) => this.showsSeries(one.name));
237
- const values = shown
268
+ const reached = shown
238
269
  .map((one) => byRow(one, this.readings)[at]?.value)
239
270
  .filter((one) => one !== undefined);
240
- const all = shown.flatMap((one) => one.points.map((point) => point.value));
271
+ const values = this.stacked ? stackEnds([reached]) : reached;
272
+ const all = this.stacked
273
+ ? stackEnds(Array.from({ length: this.readings }, (_, row) => shown.map((one) => byRow(one, this.readings)[row]?.value)))
274
+ : shown.flatMap((one) => one.points.map((point) => point.value));
241
275
  const [low, high] = extent(all.length > 0 ? all : [0]);
242
276
  const domain = [Math.min(0, low), Math.max(0, high)];
243
277
  const sideways = this.orientation === 'horizontal';
@@ -268,6 +302,9 @@ __decorate([
268
302
  __decorate([
269
303
  property({ reflect: true })
270
304
  ], HelixHeadlessBarChart.prototype, "secondary", void 0);
305
+ __decorate([
306
+ property({ reflect: true, type: Boolean })
307
+ ], HelixHeadlessBarChart.prototype, "stacked", void 0);
271
308
  HelixHeadlessBarChart = __decorate([
272
309
  customElement('helix-headless-bar-chart')
273
310
  ], HelixHeadlessBarChart);
@@ -0,0 +1,15 @@
1
+ /** Where a column starts and ends along the measure, in the data's own units. */
2
+ export type Span = readonly [from: number, to: number];
3
+ /**
4
+ * Each column's span in one category, in the order given: a positive reading
5
+ * stacks up from zero on the positives before it, and a negative one down
6
+ * from zero on the negatives before it, so neither hides the other. A blank
7
+ * has no span.
8
+ */
9
+ export declare const stackSpans: (values: readonly (number | undefined)[]) => (Span | undefined)[];
10
+ /**
11
+ * Every end a stack reaches across the categories, which is what its scale
12
+ * has to hold: the top of each stack of positives and the foot of each stack
13
+ * of negatives. `categories` holds each category's readings, one per column.
14
+ */
15
+ export declare const stackEnds: (categories: readonly (readonly (number | undefined)[])[]) => number[];
@@ -0,0 +1,19 @@
1
+ export const stackSpans = (values) => {
2
+ let up = 0;
3
+ let down = 0;
4
+ return values.map((value) => {
5
+ if (value === undefined) {
6
+ return undefined;
7
+ }
8
+ const from = value >= 0 ? up : down;
9
+ const to = from + value;
10
+ if (value >= 0) {
11
+ up = to;
12
+ }
13
+ else {
14
+ down = to;
15
+ }
16
+ return [from, to];
17
+ });
18
+ };
19
+ export const stackEnds = (categories) => categories.flatMap((values) => stackSpans(values).flatMap((span) => (span === undefined ? [] : [span[1]])));
@@ -1,5 +1,17 @@
1
1
  import { HelixElement } from '@fusion.dev/helix-core';
2
- import { type PropertyValues, type TemplateResult } from 'lit';
2
+ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
3
+ import '../breadcrumb/breadcrumb.js';
4
+ /** One step of a trail written as data, for `items`. */
5
+ export interface BreadcrumbItem {
6
+ /** The URL the step links to. The last step is the current page and takes none. */
7
+ href?: string;
8
+ /** The step's words. */
9
+ label: string;
10
+ /** The link's `rel`. */
11
+ rel?: string;
12
+ /** Where the link opens. */
13
+ target?: string;
14
+ }
3
15
  /**
4
16
  * @summary Shows the path to the current page.
5
17
  *
@@ -19,6 +31,16 @@ import { type PropertyValues, type TemplateResult } from 'lit';
19
31
  * The trail does not measure itself, and you write its overflow in markup: put
20
32
  * the crumb that holds the folded items where the gap should appear.
21
33
  *
34
+ * A trail built from data, such as a router's matched routes, takes `items`: an
35
+ * array of `{ label, href }`, drawn as crumbs in order, the last one as the
36
+ * current page. Slotted crumbs follow them. Use one way or the other in a trail.
37
+ *
38
+ * With `max-items`, a trail drawn from `items` that is longer folds its middle
39
+ * into one crumb: the first crumb, a button, then the last `max-items` less one.
40
+ * The button is named by `expand-label` and shows the whole trail, moving focus
41
+ * to the first crumb it brought back. A new `items` folds again. Slotted crumbs
42
+ * do not fold; write the folded crumb where the gap should be.
43
+ *
22
44
  * @since 0.1.0
23
45
  * @status stable
24
46
  * @category navigation
@@ -28,15 +50,49 @@ import { type PropertyValues, type TemplateResult } from 'lit';
28
50
  * @slot - The trail's items, in order from the root to the current page. Put
29
51
  * the crumb that holds the folded items where the gap should appear.
30
52
  *
53
+ * @csspart crumb - Each crumb drawn from `items`.
54
+ * @csspart crumb-collapsed - The crumb that holds the folded middle of a trail longer than `max-items`.
55
+ * @csspart crumb-current - The crumb drawn from `items` for the current page.
56
+ * @csspart crumb-link - The link, or the current page's words, of a crumb drawn from `items`.
57
+ * @csspart crumb-separator - The separator before a crumb drawn from `items`.
58
+ * @csspart crumb-separator-mark - The chevron before a crumb drawn from `items`.
59
+ * @csspart expand - The button in the folded crumb that shows the whole trail.
31
60
  * @csspart list - The ordered list.
32
61
  */
33
62
  export declare class HelixHeadlessBreadcrumbs extends HelixElement {
63
+ /**
64
+ * The name of the button that shows a folded trail's hidden crumbs. `{count}`
65
+ * is replaced by how many it shows. Translate it with the page.
66
+ */
67
+ expandLabel: string;
68
+ /**
69
+ * The trail as data, drawn as crumbs before any you slot. The last item is the
70
+ * current page.
71
+ *
72
+ * React Aria's `items`. A property only: a trail is built by script, and an
73
+ * attribute would put the whole path into the markup twice.
74
+ */
75
+ items: BreadcrumbItem[];
34
76
  /**
35
77
  * The landmark's name, read by screen readers. An `aria-label` on the host
36
78
  * wins over it.
37
79
  */
38
80
  label: string;
81
+ /**
82
+ * The most crumbs a trail drawn from `items` shows before it folds its middle
83
+ * into one, counting the first and the last. Unset, it never folds. At least
84
+ * 2, so the first crumb and the current page always show.
85
+ */
86
+ maxItems?: number;
87
+ /** Whether a reader has asked to see the whole of a folded trail. */
88
+ private expanded;
89
+ /** Shows the whole trail and moves focus to the first crumb it brought back. */
90
+ private readonly expand;
39
91
  protected willUpdate(changed: PropertyValues): void;
92
+ /** How many crumbs drawn from `items` are folded away, or 0. */
93
+ private get folded();
94
+ /** The crumbs `items` describes, each a crumb of this tier. */
95
+ protected renderItems(): TemplateResult | typeof nothing;
40
96
  protected render(): TemplateResult;
41
97
  }
42
98
  declare global {
@@ -5,26 +5,96 @@ 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
  import { customElement, HelixElement, hostAria } from '@fusion.dev/helix-core';
8
- import { html } from 'lit';
9
- import { property } from 'lit/decorators.js';
8
+ import { nothing } from 'lit';
9
+ import { property, state } from 'lit/decorators.js';
10
+ import { repeat } from 'lit/directives/repeat.js';
11
+ import { html } from 'lit/static-html.js';
12
+ import '../breadcrumb/breadcrumb.js';
10
13
  let HelixHeadlessBreadcrumbs = class HelixHeadlessBreadcrumbs extends HelixElement {
11
14
  constructor() {
12
15
  super(...arguments);
16
+ this.expandLabel = 'Show {count} more';
17
+ this.items = [];
13
18
  this.label = 'Breadcrumb';
19
+ this.expanded = false;
20
+ this.expand = () => {
21
+ this.expanded = true;
22
+ this.updateComplete.then(() => {
23
+ const crumb = this.renderRoot.querySelectorAll('[part~="crumb"]')[1];
24
+ crumb?.shadowRoot?.querySelector('a, [part="link"]')?.focus();
25
+ });
26
+ };
14
27
  }
15
28
  willUpdate(changed) {
16
29
  super.willUpdate(changed);
17
30
  hostAria(this.internals, { label: this.label, role: 'navigation' });
31
+ if (changed.has('items') && changed.get('items') !== undefined) {
32
+ this.expanded = false;
33
+ }
34
+ }
35
+ get folded() {
36
+ const most = this.maxItems ?? 0;
37
+ const count = this.items.length;
38
+ return !this.expanded && most >= 2 && count > most ? count - most : 0;
39
+ }
40
+ renderItems() {
41
+ if (this.items.length === 0) {
42
+ return nothing;
43
+ }
44
+ const crumb = this.tag('breadcrumb');
45
+ const last = this.items.length - 1;
46
+ const folded = this.folded;
47
+ const shown = this.items
48
+ .map((item, index) => ({ index, item }))
49
+ .filter(({ index }) => folded === 0 || index === 0 || index > folded);
50
+ const fold = folded === 0
51
+ ? nothing
52
+ : html `<${crumb}
53
+ part="crumb crumb-collapsed"
54
+ exportparts="link: crumb-link, separator: crumb-separator, separator-mark: crumb-separator-mark"
55
+ ><button
56
+ part="expand"
57
+ type="button"
58
+ aria-label=${this.expandLabel.replace('{count}', String(folded))}
59
+ @click=${this.expand}
60
+ >
61
+ …
62
+ </button></${crumb}
63
+ >`;
64
+ const first = shown.slice(0, 1);
65
+ const rest = shown.slice(1);
66
+ const draw = ({ index, item }) => html `<${crumb}
67
+ part="crumb${index === last ? ' crumb-current' : ''}"
68
+ exportparts="link: crumb-link, separator: crumb-separator, separator-mark: crumb-separator-mark"
69
+ href=${index === last ? nothing : (item.href ?? nothing)}
70
+ rel=${item.rel ?? nothing}
71
+ target=${item.target ?? nothing}
72
+ ?current=${index === last}
73
+ >${item.label}</${crumb}
74
+ >`;
75
+ return html `${repeat(first, ({ index }) => index, draw)}${fold}${repeat(rest, ({ index }) => index, draw)}`;
18
76
  }
19
77
  render() {
20
78
  return html `<ol part="list" role="list">
21
- <slot></slot>
79
+ ${this.renderItems()}<slot></slot>
22
80
  </ol>`;
23
81
  }
24
82
  };
83
+ __decorate([
84
+ property({ attribute: 'expand-label' })
85
+ ], HelixHeadlessBreadcrumbs.prototype, "expandLabel", void 0);
86
+ __decorate([
87
+ property({ attribute: false })
88
+ ], HelixHeadlessBreadcrumbs.prototype, "items", void 0);
25
89
  __decorate([
26
90
  property()
27
91
  ], HelixHeadlessBreadcrumbs.prototype, "label", void 0);
92
+ __decorate([
93
+ property({ attribute: 'max-items', type: Number })
94
+ ], HelixHeadlessBreadcrumbs.prototype, "maxItems", void 0);
95
+ __decorate([
96
+ state()
97
+ ], HelixHeadlessBreadcrumbs.prototype, "expanded", void 0);
28
98
  HelixHeadlessBreadcrumbs = __decorate([
29
99
  customElement('helix-headless-breadcrumbs')
30
100
  ], HelixHeadlessBreadcrumbs);
@@ -32,6 +32,15 @@ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
32
32
  * Set `pending` while the action a press started is still running. The button
33
33
  * keeps focus and refuses presses, and a reader on it hears `pending-label`.
34
34
  *
35
+ * Every press that acts sends `helix-press` with what pressed it in
36
+ * `detail.pointerType`: `mouse`, `pen`, `touch`, `keyboard`, or `virtual` for
37
+ * a screen reader's press or a script's `click()`, as React Aria's `onPress`
38
+ * does. It is sent once the press has done its own work, before `click`
39
+ * reaches listeners on the element, and never for a disabled or pending
40
+ * button.
41
+ *
42
+ * **Keyboard.** Enter and Space press the button, as on a native one.
43
+ *
35
44
  * @since 0.1.0
36
45
  * @status stable
37
46
  * @category actions
@@ -41,6 +50,8 @@ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
41
50
  * @slot end - Content after the label.
42
51
  * @slot start - Content before the label, usually an icon.
43
52
  *
53
+ * @event {HelixPressEvent} helix-press - Fired when a press acts, with `detail.pointerType` saying what pressed the button.
54
+ *
44
55
  * @csspart button - The inner control.
45
56
  * @csspart live - The live region that says `pending-label` when the button becomes pending under focus. It is rendered from the first time the button is pending, and the styled button clips it out of view.
46
57
  * @csspart text - The button's words, which the styled button trims to their capitals and baseline so the letters sit at the middle in any font.
@@ -214,7 +225,22 @@ export declare class HelixHeadlessButton extends HelixFormElement {
214
225
  protected renderLive(): TemplateResult | typeof nothing;
215
226
  /** Moves focus to the inner control, so the host is never the focus target. */
216
227
  static shadowRootOptions: ShadowRootInit;
228
+ /** What the control saw before a click that the click may not carry. */
229
+ private recent;
230
+ /**
231
+ * @internal Records what starts a press, a pointer's kind or Enter or Space,
232
+ * for `helix-press`. Bound on the inner control by this render and by any
233
+ * subclass that draws its own.
234
+ */
235
+ protected readonly notePress: (event: Event) => void;
236
+ /**
237
+ * @internal Sends `helix-press` for a click that acted, with what pressed it,
238
+ * and forgets what started it.
239
+ */
240
+ protected announcePress(click: Event): void;
217
241
  private readonly handleClick;
242
+ /** What a press does: sends the command, and submits or resets the form. */
243
+ private act;
218
244
  /**
219
245
  * What activating the button does to its form.
220
246
  */
@@ -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, drawStatus, elementById, HelixFallbackCommandEvent, HelixFormElement, StatusController, supportsInvokers, } from '@fusion.dev/helix-core';
7
+ import { AriaForwardController, customElement, defaultButton, drawStatus, elementById, HelixFallbackCommandEvent, HelixFormElement, HelixPressEvent, pressType, StatusController, submitsOnEnter, supportsInvokers, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  let HelixHeadlessButton = class HelixHeadlessButton extends HelixFormElement {
@@ -27,27 +27,23 @@ let HelixHeadlessButton = class HelixHeadlessButton extends HelixFormElement {
27
27
  this.pending = false;
28
28
  this.pendingLabel = 'Loading';
29
29
  this.status = new StatusController(this);
30
+ this.recent = {};
31
+ this.notePress = (event) => {
32
+ if (event.type === 'pointerdown') {
33
+ this.recent = { pointer: event.pointerType };
34
+ }
35
+ else if (event.key === 'Enter' || event.key === ' ') {
36
+ this.recent = { key: true };
37
+ }
38
+ };
30
39
  this.handleClick = (event) => {
31
40
  if (this.pending) {
32
41
  event.preventDefault();
33
42
  event.stopImmediatePropagation();
34
43
  return;
35
44
  }
36
- this.linkCommand();
37
- this.sendCommand();
38
- if (this.type === 'button') {
39
- return;
40
- }
41
- const { form } = this;
42
- if (!form) {
43
- return;
44
- }
45
- if (this.type === 'submit') {
46
- this.submit(form);
47
- }
48
- else {
49
- form.reset();
50
- }
45
+ this.act();
46
+ this.announcePress(event);
51
47
  };
52
48
  this.type = 'button';
53
49
  this.value = '';
@@ -57,8 +53,8 @@ let HelixHeadlessButton = class HelixHeadlessButton extends HelixFormElement {
57
53
  if (event.key !== 'Enter' ||
58
54
  event.defaultPrevented ||
59
55
  !form ||
60
- !HelixFormElement.submitsOnEnter(event.composedPath()[0], form) ||
61
- HelixFormElement.defaultButton(form) !== this) {
56
+ !submitsOnEnter(event.composedPath()[0], form) ||
57
+ defaultButton(form) !== this) {
62
58
  return;
63
59
  }
64
60
  event.preventDefault();
@@ -84,6 +80,28 @@ let HelixHeadlessButton = class HelixHeadlessButton extends HelixFormElement {
84
80
  ...HelixFormElement.shadowRootOptions,
85
81
  delegatesFocus: true,
86
82
  }; }
83
+ announcePress(click) {
84
+ const pointerType = pressType(click, this.recent);
85
+ this.recent = {};
86
+ this.dispatchEvent(new HelixPressEvent({ pointerType }));
87
+ }
88
+ act() {
89
+ this.linkCommand();
90
+ this.sendCommand();
91
+ if (this.type === 'button') {
92
+ return;
93
+ }
94
+ const { form } = this;
95
+ if (!form) {
96
+ return;
97
+ }
98
+ if (this.type === 'submit') {
99
+ this.submit(form);
100
+ }
101
+ else {
102
+ form.reset();
103
+ }
104
+ }
87
105
  submit(form) {
88
106
  const undo = [];
89
107
  const override = (attribute, value) => {
@@ -201,6 +219,8 @@ let HelixHeadlessButton = class HelixHeadlessButton extends HelixFormElement {
201
219
  tabindex=${stop}
202
220
  ?disabled=${this.isDisabled}
203
221
  @click=${this.handleClick}
222
+ @keydown=${this.notePress}
223
+ @pointerdown=${this.notePress}
204
224
  >
205
225
  ${label}
206
226
  </button>${this.renderLive()}`;