@fusion.dev/helix-headless 0.146.0 → 0.148.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 (288) hide show
  1. package/custom-elements.json +9287 -1084
  2. package/dist/accordion/item/accordion-item.d.ts +43 -21
  3. package/dist/accordion/item/accordion-item.js +37 -11
  4. package/dist/accordion/root/accordion-root.d.ts +8 -2
  5. package/dist/accordion/root/accordion-root.js +6 -8
  6. package/dist/announcement/root/announcement-root.d.ts +66 -6
  7. package/dist/announcement/root/announcement-root.js +144 -13
  8. package/dist/area-chart/root/area-chart-root.d.ts +18 -1
  9. package/dist/area-chart/root/area-chart-root.js +14 -7
  10. package/dist/avatar/root/avatar-root.d.ts +31 -1
  11. package/dist/avatar/root/avatar-root.js +11 -1
  12. package/dist/badge/count.d.ts +14 -0
  13. package/dist/badge/count.js +20 -0
  14. package/dist/badge/root/badge-root.d.ts +57 -6
  15. package/dist/badge/root/badge-root.js +77 -8
  16. package/dist/bar-chart/root/bar-chart-root.js +11 -20
  17. package/dist/bar-chart/stack.d.ts +10 -0
  18. package/dist/bar-chart/stack.js +8 -0
  19. package/dist/blockquote/root/blockquote-root.d.ts +66 -8
  20. package/dist/blockquote/root/blockquote-root.js +85 -8
  21. package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +14 -0
  22. package/dist/breadcrumbs/breadcrumb/breadcrumb.js +12 -2
  23. package/dist/breadcrumbs/root/breadcrumbs-root.js +2 -2
  24. package/dist/button/root/button-root.d.ts +24 -38
  25. package/dist/button/root/button-root.js +6 -37
  26. package/dist/button/submitter.d.ts +27 -0
  27. package/dist/button/submitter.js +25 -0
  28. package/dist/button-group/arrows.d.ts +14 -0
  29. package/dist/button-group/arrows.js +10 -0
  30. package/dist/button-group/root/button-group-root.d.ts +141 -3
  31. package/dist/button-group/root/button-group-root.js +142 -2
  32. package/dist/canvas/edge-pan.d.ts +61 -0
  33. package/dist/canvas/edge-pan.js +63 -0
  34. package/dist/canvas/node/canvas-node.d.ts +12 -2
  35. package/dist/canvas/node/canvas-node.js +6 -2
  36. package/dist/canvas/root/canvas-document.d.ts +10 -0
  37. package/dist/canvas/root/canvas-document.js +1 -0
  38. package/dist/canvas/root/canvas-root.d.ts +107 -5
  39. package/dist/canvas/root/canvas-root.js +140 -36
  40. package/dist/canvas/snap.d.ts +42 -0
  41. package/dist/canvas/snap.js +32 -0
  42. package/dist/card/root/card-root.d.ts +12 -1
  43. package/dist/card/root/card-root.js +11 -4
  44. package/dist/carousel/root/carousel-root.d.ts +4 -3
  45. package/dist/carousel/root/carousel-root.js +2 -6
  46. package/dist/chat/root/chat-root.d.ts +28 -4
  47. package/dist/chat/root/chat-root.js +12 -7
  48. package/dist/checkbox/root/checkbox-root.js +5 -7
  49. package/dist/checkbox-group/root/checkbox-group-root.d.ts +13 -0
  50. package/dist/checkbox-group/root/checkbox-group-root.js +16 -7
  51. package/dist/checkbox-group/select-all.d.ts +9 -4
  52. package/dist/checkbox-group/select-all.js +1 -1
  53. package/dist/code-block/root/code-block-root.d.ts +41 -18
  54. package/dist/code-block/root/code-block-root.js +21 -6
  55. package/dist/color-input/root/color-input-root.d.ts +11 -0
  56. package/dist/color-input/root/color-input-root.js +12 -5
  57. package/dist/color-picker/channels.js +1 -2
  58. package/dist/color-picker/root/color-picker-root.d.ts +32 -24
  59. package/dist/color-picker/root/color-picker-root.js +99 -55
  60. package/dist/color-picker/wheel.d.ts +28 -0
  61. package/dist/color-picker/wheel.js +15 -0
  62. package/dist/combobox/root/combobox-root.d.ts +83 -11
  63. package/dist/combobox/root/combobox-root.js +81 -18
  64. package/dist/command/root/command-root.d.ts +7 -4
  65. package/dist/command/root/command-root.js +2 -19
  66. package/dist/copy-button/root/copy-button-root.d.ts +16 -1
  67. package/dist/copy-button/root/copy-button-root.js +7 -2
  68. package/dist/data-table/keys.d.ts +0 -18
  69. package/dist/data-table/keys.js +1 -11
  70. package/dist/data-table/root/data-table-root.js +29 -50
  71. package/dist/date-input/root/date-input-root.d.ts +8 -1
  72. package/dist/date-input/root/date-input-root.js +8 -5
  73. package/dist/date-picker/root/date-picker-root.d.ts +14 -9
  74. package/dist/date-picker/root/date-picker-root.js +21 -16
  75. package/dist/description-list/item/description-list-item.d.ts +22 -4
  76. package/dist/description-list/item/description-list-item.js +14 -4
  77. package/dist/divider/root/divider-root.d.ts +45 -16
  78. package/dist/divider/root/divider-root.js +28 -4
  79. package/dist/donut-chart/root/donut-chart-root.js +13 -6
  80. package/dist/donut-chart/slice-label.d.ts +35 -0
  81. package/dist/donut-chart/slice-label.js +11 -0
  82. package/dist/drawer/root/drawer-root.d.ts +4 -2
  83. package/dist/drawer/root/drawer-root.js +15 -3
  84. package/dist/drilldown/item/drilldown-item.d.ts +21 -1
  85. package/dist/drilldown/item/drilldown-item.js +38 -4
  86. package/dist/drilldown/root/drilldown-root.js +3 -2
  87. package/dist/element-events.generated.js +5 -1
  88. package/dist/empty/root/empty-root.d.ts +46 -2
  89. package/dist/empty/root/empty-root.js +50 -5
  90. package/dist/file-input/root/file-input-root.d.ts +34 -6
  91. package/dist/file-input/root/file-input-root.js +55 -21
  92. package/dist/file-input/status.d.ts +24 -0
  93. package/dist/file-input/status.js +11 -0
  94. package/dist/filter-input/chip/filter-chip.d.ts +23 -0
  95. package/dist/filter-input/chip/filter-chip.js +10 -2
  96. package/dist/filter-input/root/filter-input-root.d.ts +8 -0
  97. package/dist/filter-input/root/filter-input-root.js +17 -27
  98. package/dist/format-date/fields.d.ts +20 -0
  99. package/dist/format-date/fields.js +14 -0
  100. package/dist/format-date/options.d.ts +5 -5
  101. package/dist/format-date/options.js +10 -39
  102. package/dist/format-date/root/format-date-root.d.ts +53 -4
  103. package/dist/format-date/root/format-date-root.js +38 -50
  104. package/dist/graph/root/graph-root.d.ts +23 -5
  105. package/dist/graph/root/graph-root.js +17 -20
  106. package/dist/heatmap/root/buckets.d.ts +21 -0
  107. package/dist/heatmap/root/buckets.js +34 -0
  108. package/dist/heatmap/root/heatmap-root.d.ts +76 -3
  109. package/dist/heatmap/root/heatmap-root.js +105 -20
  110. package/dist/icon/index.d.ts +1 -1
  111. package/dist/icon/index.js +1 -1
  112. package/dist/icon/registry.d.ts +26 -1
  113. package/dist/icon/registry.js +12 -1
  114. package/dist/icon/root/icon-root.d.ts +13 -0
  115. package/dist/icon/root/icon-root.js +23 -2
  116. package/dist/icon/root/index.d.ts +1 -1
  117. package/dist/icon/root/index.js +1 -1
  118. package/dist/image/root/image-root.d.ts +20 -0
  119. package/dist/image/root/image-root.js +6 -1
  120. package/dist/input/root/input-root.d.ts +23 -2
  121. package/dist/input/root/input-root.js +12 -8
  122. package/dist/kbd/root/kbd-root.d.ts +20 -3
  123. package/dist/kbd/root/kbd-root.js +23 -50
  124. package/dist/legend/hidden-series.d.ts +10 -2
  125. package/dist/legend/hidden-series.js +5 -2
  126. package/dist/legend/root/legend-root.d.ts +25 -7
  127. package/dist/legend/root/legend-root.js +25 -26
  128. package/dist/lightbox/root/lightbox-root.d.ts +50 -5
  129. package/dist/lightbox/root/lightbox-root.js +76 -8
  130. package/dist/lightbox/zoom.d.ts +2 -0
  131. package/dist/lightbox/zoom.js +5 -3
  132. package/dist/line-chart/root/line-chart-root.d.ts +16 -0
  133. package/dist/line-chart/root/line-chart-root.js +10 -2
  134. package/dist/list/root/list-root.d.ts +10 -2
  135. package/dist/list/root/list-root.js +31 -24
  136. package/dist/list/selection.d.ts +17 -0
  137. package/dist/list/selection.js +16 -0
  138. package/dist/listbox/root/listbox-root.d.ts +125 -26
  139. package/dist/listbox/root/listbox-root.js +156 -166
  140. package/dist/map/marker/map-marker.d.ts +2 -1
  141. package/dist/map/root/map-root.d.ts +40 -2
  142. package/dist/map/root/map-root.js +64 -23
  143. package/dist/megamenu/hand-over.d.ts +75 -0
  144. package/dist/megamenu/hand-over.js +67 -0
  145. package/dist/megamenu/root/megamenu-root.d.ts +38 -14
  146. package/dist/megamenu/root/megamenu-root.js +29 -50
  147. package/dist/menu/item/menu-item.js +4 -4
  148. package/dist/menu/root/menu-root.d.ts +5 -2
  149. package/dist/meter/root/meter-root.d.ts +42 -0
  150. package/dist/meter/root/meter-root.js +33 -7
  151. package/dist/navigation/root/navigation-root.js +5 -8
  152. package/dist/notifications/group/notification-group.d.ts +8 -1
  153. package/dist/notifications/group/notification-group.js +12 -6
  154. package/dist/notifications/notification/notification.d.ts +12 -1
  155. package/dist/notifications/notification/notification.js +3 -1
  156. package/dist/notifications/root/notifications-root.d.ts +48 -3
  157. package/dist/notifications/root/notifications-root.js +36 -6
  158. package/dist/number-input/grain.d.ts +28 -0
  159. package/dist/number-input/grain.js +14 -0
  160. package/dist/number-input/root/number-input-root.d.ts +17 -1
  161. package/dist/number-input/root/number-input-root.js +29 -18
  162. package/dist/object-inspector/root/object-inspector-root.d.ts +17 -6
  163. package/dist/object-inspector/root/object-inspector-root.js +31 -20
  164. package/dist/option/index.d.ts +1 -0
  165. package/dist/option/index.js +1 -0
  166. package/dist/option/separator/option-separator.d.ts +30 -0
  167. package/dist/option/separator/option-separator.js +21 -0
  168. package/dist/outline/root/outline-root.d.ts +12 -0
  169. package/dist/outline/root/outline-root.js +5 -19
  170. package/dist/pagination/size/pagination-size.d.ts +6 -0
  171. package/dist/pagination/size/pagination-size.js +5 -3
  172. package/dist/pin-input/code.d.ts +51 -1
  173. package/dist/pin-input/code.js +37 -0
  174. package/dist/pin-input/root/pin-input-root.d.ts +98 -121
  175. package/dist/pin-input/root/pin-input-root.js +151 -156
  176. package/dist/popover/hide-outside.js +2 -9
  177. package/dist/popover/root/popover-root.d.ts +7 -1
  178. package/dist/popover/root/popover-root.js +9 -1
  179. package/dist/progress/root/progress-root.d.ts +27 -0
  180. package/dist/progress/root/progress-root.js +25 -7
  181. package/dist/qr-code/export.d.ts +19 -0
  182. package/dist/qr-code/export.js +14 -0
  183. package/dist/qr-code/name.d.ts +11 -0
  184. package/dist/qr-code/name.js +7 -0
  185. package/dist/qr-code/root/qr-code-root.d.ts +31 -9
  186. package/dist/qr-code/root/qr-code-root.js +29 -17
  187. package/dist/radio/group/radio-group.d.ts +15 -0
  188. package/dist/radio/root/radio-root.js +2 -2
  189. package/dist/rating/root/rating-root.d.ts +22 -9
  190. package/dist/rating/root/rating-root.js +15 -39
  191. package/dist/scatter-chart/measures.d.ts +22 -0
  192. package/dist/scatter-chart/measures.js +11 -0
  193. package/dist/scatter-chart/root/scatter-chart-root.d.ts +26 -0
  194. package/dist/scatter-chart/root/scatter-chart-root.js +21 -7
  195. package/dist/scroll-area/scrollbar.d.ts +0 -8
  196. package/dist/scroll-area/scrollbar.js +1 -1
  197. package/dist/select/align.d.ts +47 -0
  198. package/dist/select/align.js +7 -0
  199. package/dist/select/root/select-root.d.ts +115 -11
  200. package/dist/select/root/select-root.js +104 -20
  201. package/dist/slider/root/slider-root.d.ts +18 -1
  202. package/dist/slider/root/slider-root.js +22 -0
  203. package/dist/sparkline/readings.d.ts +30 -12
  204. package/dist/sparkline/readings.js +32 -15
  205. package/dist/sparkline/root/sparkline-root.d.ts +46 -3
  206. package/dist/sparkline/root/sparkline-root.js +60 -21
  207. package/dist/speed-dial/group/speed-dial-group.d.ts +48 -0
  208. package/dist/speed-dial/group/speed-dial-group.js +43 -0
  209. package/dist/speed-dial/index.d.ts +1 -0
  210. package/dist/speed-dial/index.js +1 -0
  211. package/dist/speed-dial/item/speed-dial-item.d.ts +27 -2
  212. package/dist/speed-dial/item/speed-dial-item.js +43 -5
  213. package/dist/speed-dial/long-press.d.ts +50 -0
  214. package/dist/speed-dial/long-press.js +48 -0
  215. package/dist/speed-dial/root/speed-dial-root.d.ts +86 -1
  216. package/dist/speed-dial/root/speed-dial-root.js +123 -6
  217. package/dist/splitter/root/splitter-root.d.ts +9 -2
  218. package/dist/splitter/root/splitter-root.js +18 -3
  219. package/dist/steps/root/steps-root.d.ts +8 -1
  220. package/dist/steps/root/steps-root.js +6 -1
  221. package/dist/steps/step/step.d.ts +1 -0
  222. package/dist/steps/step/step.js +1 -1
  223. package/dist/table/cell/table-cell.d.ts +8 -1
  224. package/dist/table/cell/table-cell.js +6 -2
  225. package/dist/table/column/table-column.d.ts +6 -0
  226. package/dist/table/column/table-column.js +5 -1
  227. package/dist/table/grid-controller.d.ts +117 -0
  228. package/dist/table/grid-controller.js +293 -0
  229. package/dist/table/root/table-root.d.ts +47 -3
  230. package/dist/table/root/table-root.js +93 -29
  231. package/dist/table/row/table-row.d.ts +36 -0
  232. package/dist/table/row/table-row.js +52 -2
  233. package/dist/tabs/root/tabs-root.d.ts +5 -3
  234. package/dist/tag/group/tag-group.d.ts +16 -4
  235. package/dist/tag/group/tag-group.js +23 -20
  236. package/dist/textarea/root/textarea-root.d.ts +14 -2
  237. package/dist/textarea/root/textarea-root.js +6 -7
  238. package/dist/time-input/root/time-input-root.d.ts +5 -1
  239. package/dist/time-input/root/time-input-root.js +10 -7
  240. package/dist/time-picker/root/time-picker-root.d.ts +12 -14
  241. package/dist/time-picker/root/time-picker-root.js +18 -23
  242. package/dist/toast/item/toast-item.d.ts +9 -6
  243. package/dist/toast/item/toast-item.js +1 -1
  244. package/dist/toast/root/toast-root.d.ts +40 -4
  245. package/dist/toast/root/toast-root.js +68 -16
  246. package/dist/toast/words.d.ts +12 -0
  247. package/dist/toast/words.js +25 -0
  248. package/dist/toggle/group/toggle-group.d.ts +29 -5
  249. package/dist/toggle/group/toggle-group.js +26 -43
  250. package/dist/toggle/root/toggle-root.js +2 -4
  251. package/dist/toolbar/root/toolbar-root.d.ts +52 -5
  252. package/dist/toolbar/root/toolbar-root.js +88 -13
  253. package/dist/tooltip/root/tooltip-root.d.ts +7 -1
  254. package/dist/tooltip/root/tooltip-root.js +10 -2
  255. package/dist/tour/root/tour-root.d.ts +15 -0
  256. package/dist/tour/root/tour-root.js +20 -1
  257. package/dist/tour/stop/tour-stop.d.ts +3 -0
  258. package/dist/tour/stop/tour-stop.js +3 -3
  259. package/dist/tree/root/tree-root.js +2 -2
  260. package/dist/trend/figure.d.ts +16 -0
  261. package/dist/trend/figure.js +8 -0
  262. package/dist/trend/root/trend-root.d.ts +41 -2
  263. package/dist/trend/root/trend-root.js +29 -3
  264. package/dist/video/root/extra-controls.d.ts +12 -0
  265. package/dist/video/root/extra-controls.js +6 -2
  266. package/dist/video/root/video-root.d.ts +16 -1
  267. package/dist/video/root/video-root.js +15 -1
  268. package/dist/video-playlist/root/video-playlist-root.d.ts +11 -1
  269. package/dist/video-playlist/root/video-playlist-root.js +3 -0
  270. package/dist/virtual-list/fill.d.ts +11 -0
  271. package/dist/virtual-list/fill.js +9 -0
  272. package/dist/virtual-list/keys.d.ts +16 -7
  273. package/dist/virtual-list/keys.js +17 -6
  274. package/dist/virtual-list/plan.d.ts +17 -1
  275. package/dist/virtual-list/plan.js +13 -2
  276. package/dist/virtual-list/root/virtual-list-root.d.ts +25 -3
  277. package/dist/virtual-list/root/virtual-list-root.js +53 -41
  278. package/lint.json +1 -1
  279. package/package.json +5 -5
  280. package/types/jsx.d.ts +4934 -954
  281. package/types/svelte.d.ts +2 -0
  282. package/types/vue.d.ts +946 -253
  283. package/dist/color-picker/swatches.d.ts +0 -12
  284. package/dist/color-picker/swatches.js +0 -26
  285. package/dist/rating/steps.d.ts +0 -7
  286. package/dist/rating/steps.js +0 -9
  287. package/dist/tooltip/focus-target.d.ts +0 -6
  288. package/dist/tooltip/focus-target.js +0 -9
@@ -5,17 +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 HelixHeadlessMegamenu_1;
8
- import { anchorElement, customElement, deepContains, focusableElements, HelixElement, MixinControllerOpen, PopoverController, tellDisclosure, } from '@fusion.dev/helix-core';
8
+ import { anchorElement, customElement, deepContains, focusableElements, focusItemOf, HelixElement, KeyboardNavigationController, MixinControllerOpen, PopoverController, tellDisclosure, } from '@fusion.dev/helix-core';
9
9
  import { html, nothing } from 'lit';
10
10
  import { property, state } from 'lit/decorators.js';
11
- let showing;
12
- const connected = new Set();
13
- let pressed;
14
- const release = () => {
15
- setTimeout(() => {
16
- pressed = undefined;
17
- });
18
- };
11
+ import { HandOver } from '../hand-over.js';
19
12
  let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerOpen(HelixElement) {
20
13
  constructor() {
21
14
  super(...arguments);
@@ -28,13 +21,24 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
28
21
  };
29
22
  this.panel = new PopoverController(this, {
30
23
  anchor: () => this.trigger,
31
- boundary: () => [...connected],
24
+ boundary: () => [...HelixHeadlessMegamenu_1.bar.connected],
32
25
  onDismiss: () => this.close(),
33
26
  open: () => this.open,
34
27
  place: () => !this.banded,
35
28
  placement: () => 'bottom-start',
36
29
  surface: () => this.partNamed('surface'),
37
30
  });
31
+ this.keys = new KeyboardNavigationController(this, {
32
+ items: () => !this.parentElement?.shadowRoot
33
+ ? HelixHeadlessMegamenu_1.bar
34
+ .alongside(this)
35
+ .map((megamenu) => focusItemOf(megamenu.trigger))
36
+ : [],
37
+ origin: 'focus',
38
+ reserved: () => ['ArrowDown', 'ArrowUp'],
39
+ selects: () => false,
40
+ wrap: false,
41
+ });
38
42
  this.handleKeyDown = (event) => {
39
43
  if (event.key !== 'ArrowDown' || !this.open || event.defaultPrevented) {
40
44
  return;
@@ -61,14 +65,13 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
61
65
  };
62
66
  this.handlePointerDown = (event) => {
63
67
  this.pointer = event.pointerType;
64
- pressed = this;
65
- window.addEventListener('pointerup', release, { capture: true, once: true });
66
- window.addEventListener('pointercancel', release, { capture: true, once: true });
68
+ HelixHeadlessMegamenu_1.bar.press(this);
67
69
  };
68
70
  this.handlePointerEnter = (event) => {
69
71
  if (this.openOn !== 'hover' || event.pointerType !== 'mouse') {
70
72
  return;
71
73
  }
74
+ const showing = HelixHeadlessMegamenu_1.bar.showing;
72
75
  this.schedule(showing && showing !== this ? 0 : HelixHeadlessMegamenu_1.OPEN_DELAY, () => {
73
76
  this.requestOpen(true);
74
77
  });
@@ -86,6 +89,7 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
86
89
  if (!this.open || next === null || deepContains(this, next)) {
87
90
  return;
88
91
  }
92
+ const pressed = HelixHeadlessMegamenu_1.bar.pressed;
89
93
  if (pressed !== undefined && pressed !== this && deepContains(pressed, next)) {
90
94
  return;
91
95
  }
@@ -119,9 +123,9 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
119
123
  }
120
124
  this.requestOpen(false);
121
125
  };
122
- this.handedOver = false;
123
126
  }
124
127
  static { HelixHeadlessMegamenu_1 = this; }
128
+ static { this.bar = new HandOver((megamenu, to) => megamenu.motion(to)); }
125
129
  get banded() {
126
130
  return this.variant === 'band' || this.narrow;
127
131
  }
@@ -191,7 +195,7 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
191
195
  connectedCallback() {
192
196
  super.connectedCallback();
193
197
  this.watchWidth();
194
- connected.add(this);
198
+ HelixHeadlessMegamenu_1.bar.add(this);
195
199
  window.addEventListener('scroll', this.handleScroll, { capture: true, passive: true });
196
200
  this.addEventListener('pointerdown', this.handlePointerDown);
197
201
  this.addEventListener('click', this.handleContentClick);
@@ -211,11 +215,8 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
211
215
  this.removeEventListener('pointerleave', this.handlePointerLeave);
212
216
  this.removeEventListener('focusout', this.handleFocusOut);
213
217
  this.removeEventListener('keydown', this.handleKeyDown);
214
- connected.delete(this);
218
+ HelixHeadlessMegamenu_1.bar.remove(this);
215
219
  this.stop();
216
- if (showing === this) {
217
- showing = undefined;
218
- }
219
220
  }
220
221
  willUpdate(changed) {
221
222
  super.willUpdate(changed);
@@ -223,37 +224,10 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
223
224
  return;
224
225
  }
225
226
  if (this.open) {
226
- const previous = showing && showing !== this ? showing : undefined;
227
- const forward = previous !== undefined &&
228
- (previous.compareDocumentPosition(this) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0;
229
- this.motion(previous ? (forward ? 'from-end' : 'from-start') : undefined);
230
- this.from = previous?.size;
231
- HelixHeadlessMegamenu_1.settle(this, previous);
232
- if (previous) {
233
- previous.motion(forward ? 'to-start' : 'to-end');
234
- previous.handedOver = true;
235
- if (!previous.requestOpen(false)) {
236
- previous.handedOver = false;
237
- previous.motion(undefined);
238
- }
239
- }
240
- showing = this;
227
+ this.from = HelixHeadlessMegamenu_1.bar.open(this)?.size;
241
228
  return;
242
229
  }
243
- if (showing === this) {
244
- showing = undefined;
245
- }
246
- if (!this.handedOver) {
247
- HelixHeadlessMegamenu_1.settle();
248
- }
249
- this.handedOver = false;
250
- }
251
- static settle(...moving) {
252
- for (const megamenu of connected) {
253
- if (!moving.includes(megamenu)) {
254
- megamenu.motion(undefined);
255
- }
256
- }
230
+ HelixHeadlessMegamenu_1.bar.close(this);
257
231
  }
258
232
  measure() {
259
233
  const surface = this.partNamed('surface');
@@ -301,8 +275,13 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
301
275
  </button>
302
276
  </slot>`;
303
277
  }
278
+ renderIndicator() {
279
+ return this.open
280
+ ? html `<slot name="indicator" part="indicator" aria-hidden="true"></slot>`
281
+ : nothing;
282
+ }
304
283
  render() {
305
- return html `${this.renderTrigger()}
284
+ return html `${this.renderTrigger()}${this.renderIndicator()}
306
285
  <div
307
286
  part="surface"
308
287
  id="panel"
@@ -311,7 +290,7 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
311
290
  role="group"
312
291
  ?hidden=${!this.open}
313
292
  >
314
- <slot></slot>
293
+ <slot part="columns"></slot>
315
294
  </div>`;
316
295
  }
317
296
  };
@@ -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 { ariaChord, customElement, deepActiveElement, HelixBeforeToggleEvent, HelixElement, HelixSelectEvent, onApple, requestChange, } from '@fusion.dev/helix-core';
7
+ import { ariaChord, customElement, deepActiveElement, HelixBeforeToggleEvent, HelixElement, HelixSelectEvent, onApple, requestChange, slotFilled, } from '@fusion.dev/helix-core';
8
8
  import { caretRight, check } from '@fusion.dev/helix-icons';
9
9
  import { html, nothing } from 'lit';
10
10
  import { property, state } from 'lit/decorators.js';
@@ -33,15 +33,15 @@ let HelixHeadlessMenuItem = class HelixHeadlessMenuItem extends HelixElement {
33
33
  this.description = false;
34
34
  this.readStart = () => {
35
35
  const slot = this.renderRoot.querySelector('slot[name="start"]');
36
- this.start = (slot?.assignedNodes().length ?? 0) > 0;
36
+ this.start = slotFilled(slot);
37
37
  };
38
38
  this.readEnd = () => {
39
39
  const slot = this.renderRoot.querySelector('slot[name="end"]');
40
- this.end = (slot?.assignedNodes().length ?? 0) > 0;
40
+ this.end = slotFilled(slot);
41
41
  };
42
42
  this.readDescription = () => {
43
43
  const slot = this.renderRoot.querySelector('slot[name="description"]');
44
- this.description = (slot?.assignedNodes().length ?? 0) > 0;
44
+ this.description = slotFilled(slot);
45
45
  };
46
46
  this.readSubmenu = () => {
47
47
  const slot = this.renderRoot.querySelector('slot[name="submenu"]');
@@ -25,8 +25,8 @@ declare const HelixHeadlessMenu_base: (new (...args: any[]) => import("@fusion.d
25
25
  * onto your element after it upgrades causes a hydration mismatch.
26
26
  *
27
27
  * Group rows under a heading with `Menu.Section`, which is a `group` named by
28
- * its heading. Between runs of rows, a `<helix-divider announced>` is a
29
- * separator a screen reader announces.
28
+ * its heading. Between runs of rows, a `<helix-divider>` is a separator a
29
+ * screen reader announces.
30
30
  *
31
31
  * Keys: Enter, Space or Down Arrow on the trigger opens the menu on its first
32
32
  * row, and Up Arrow on its last. In the menu, Up and Down Arrow move between
@@ -71,6 +71,9 @@ declare const HelixHeadlessMenu_base: (new (...args: any[]) => import("@fusion.d
71
71
  * @csspart surface - The floating panel the menu is drawn on.
72
72
  * @csspart title - The name of the submenu that is showing.
73
73
  *
74
+ * @cssproperty --floating-anchor-inline-size - The trigger's width, written on the panel while it is open, as in `min-inline-size: var(--floating-anchor-inline-size)`. Read it; a value set here is written over.
75
+ * @cssproperty --floating-available-block-size - The room between the panel and the edge of the screen it opens toward, written on the panel while it is open. Read it; a value set here is written over.
76
+ *
74
77
  * @cssstate drilled - A submenu's page is showing, so content that is not a row can hide with the top page.
75
78
  * @cssstate mark - A row on the current page has a checkbox or a link, so every row keeps the trailing column.
76
79
  * @cssstate open - While the menu is open.
@@ -16,6 +16,15 @@ export type MeterBand = 'fair' | 'good' | 'poor';
16
16
  * band. `optimum` sets the preferred band. The band next to it is fair, and the
17
17
  * band two away is poor.
18
18
  *
19
+ * The band is a custom state on the meter, `good`, `fair` or `poor`, beside
20
+ * `over` and `under` for a value past an end, so a page styles the meter
21
+ * around the fill as well as the fill.
22
+ *
23
+ * **`live` says the reading when it moves into another band**, such as "92%,
24
+ * Poor", in a polite region, for a meter whose value changes while a reader is
25
+ * on the page: a disk filling or a battery draining. The band's word comes from
26
+ * `band-labels`.
27
+ *
19
28
  * @since 0.1.0
20
29
  * @status stable
21
30
  * @category feedback
@@ -24,6 +33,8 @@ export type MeterBand = 'fair' | 'good' | 'poor';
24
33
  *
25
34
  * @slot label - A visible label. Its words name the meter in place of `label`.
26
35
  *
36
+ * @event {HelixBandEvent} helix-band - Fired when the reading moves into another band, with the band it is in now, or `''` where it is in none. Not sent on the first render, since a meter that arrives in a band has not moved.
37
+ *
27
38
  * @csspart groove - The unfilled circle, in `ring` and `arc`.
28
39
  * @csspart indicator - The part of the track the value fills.
29
40
  * @csspart indicator-fair - The fill while the reading is in a band next to the good band. Set alongside `indicator`.
@@ -31,6 +42,7 @@ export type MeterBand = 'fair' | 'good' | 'poor';
31
42
  * @csspart indicator-over - The fill while the value is above `max`. Set alongside `indicator`.
32
43
  * @csspart indicator-poor - The fill while the reading is two bands from the good band. Set alongside `indicator`.
33
44
  * @csspart indicator-under - The fill while the value is below `min`. Set alongside `indicator`.
45
+ * @csspart live - A polite region that says the reading as it moves into another band, under `live`, rendered from the first time it does. Hide it visually.
34
46
  * @csspart tick - A mark at `low` or at `high`.
35
47
  * @csspart track - The whole range, or the drawing in `ring` and `arc`.
36
48
  * @csspart value - The reading as text, shown when `show-value` is set.
@@ -39,6 +51,12 @@ export type MeterBand = 'fair' | 'good' | 'poor';
39
51
  * @cssproperty --meter-at - Where a bound sits on a linear track, as a percentage.
40
52
  * @cssproperty --meter-fraction - The value as a fraction of the range, 0 to 1.
41
53
  * @cssproperty --meter-sweep - How much of the circle the arc covers, as a path length.
54
+ *
55
+ * @cssstate fair - The reading is in a band next to the good band.
56
+ * @cssstate good - The reading is in the good band.
57
+ * @cssstate over - The value is above `max`.
58
+ * @cssstate poor - The reading is two bands from the good band.
59
+ * @cssstate under - The value is below `min`.
42
60
  */
43
61
  export declare class HelixHeadlessMeter extends HelixElement {
44
62
  /**
@@ -71,6 +89,13 @@ export declare class HelixHeadlessMeter extends HelixElement {
71
89
  * no reader.
72
90
  */
73
91
  band?: MeterBand;
92
+ /**
93
+ * The words each band is said with under `live`, by its name, written as
94
+ * JSON in the attribute: `band-labels='{"poor":"Almost full"}'`.
95
+ *
96
+ * A band left out keeps its default: "Good", "Fair" or "Poor".
97
+ */
98
+ bandLabels: Partial<Record<MeterBand, string>>;
74
99
  /**
75
100
  * `Intl.NumberFormat` options the reading is written with, as React Aria's
76
101
  * Meter and ProgressBar take them: a unit, a currency, or a number of
@@ -99,6 +124,15 @@ export declare class HelixHeadlessMeter extends HelixElement {
99
124
  * shows, so the name and the label cannot disagree.
100
125
  */
101
126
  label: string;
127
+ /**
128
+ * Says the reading in a polite `live` region each time it moves into
129
+ * another band, with the band's word, such as "92%, Poor".
130
+ *
131
+ * For a meter whose value changes while it is on screen. Off by default,
132
+ * because a meter that reads a fixed level has nothing new to say. A meter
133
+ * with no bands says nothing.
134
+ */
135
+ live: boolean;
102
136
  /**
103
137
  * The locale the percentage is written in, such as `fr` for `72 %`.
104
138
  *
@@ -171,6 +205,13 @@ export declare class HelixHeadlessMeter extends HelixElement {
171
205
  * fair summary of a task and a poor one of a quantity.
172
206
  */
173
207
  valueText: string;
208
+ /** The region `live` speaks in, rendered from the first time it does. */
209
+ private readonly status;
210
+ /**
211
+ * The band at the last update, so a move into another one is heard once:
212
+ * an empty string for none, and undefined before the first update.
213
+ */
214
+ private lastBand;
174
215
  /** The range, clamped so `max` is never at or below `min`. */
175
216
  private get span();
176
217
  /** The reading, pulled into the range. */
@@ -221,6 +262,7 @@ export declare class HelixHeadlessMeter extends HelixElement {
221
262
  */
222
263
  private get text();
223
264
  protected willUpdate(changed: PropertyValues): void;
265
+ protected updated(changed: PropertyValues): void;
224
266
  /**
225
267
  * The same reading, drawn round.
226
268
  *
@@ -4,20 +4,23 @@ 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, formatNumber, HelixElement, hostAria, slottedWords, } from '@fusion.dev/helix-core';
7
+ import { customElement, drawStatus, HelixBandEvent, HelixElement, hostAria, readingText, StatusController, slottedWords, wordsConverter, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing, svg } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
- const WHOLE_PERCENT = { maximumFractionDigits: 0, style: 'percent' };
10
+ const BAND_WORDS = { fair: 'Fair', good: 'Good', poor: 'Poor' };
11
11
  let HelixHeadlessMeter = class HelixHeadlessMeter extends HelixElement {
12
12
  constructor() {
13
13
  super(...arguments);
14
+ this.bandLabels = {};
14
15
  this.label = 'Meter';
16
+ this.live = false;
15
17
  this.locale = '';
16
18
  this.max = 100;
17
19
  this.min = 0;
18
20
  this.showValue = false;
19
21
  this.value = 0;
20
22
  this.valueText = '';
23
+ this.status = new StatusController(this);
21
24
  this.renamed = () => {
22
25
  this.requestUpdate();
23
26
  };
@@ -69,11 +72,8 @@ let HelixHeadlessMeter = class HelixHeadlessMeter extends HelixElement {
69
72
  return distance === 0 ? 'good' : distance === 1 ? 'fair' : 'poor';
70
73
  }
71
74
  get text() {
72
- const options = this.formatOptions;
73
75
  return (this.valueText ||
74
- (options && options.style !== 'percent'
75
- ? formatNumber(Number.isFinite(this.value) ? this.value : this.span.min, this.locale, options)
76
- : formatNumber(this.ratio, this.locale, options ?? WHOLE_PERCENT)));
76
+ readingText(Number.isFinite(this.value) ? this.value : this.span.min, this.ratio, this.locale, this.formatOptions));
77
77
  }
78
78
  willUpdate(changed) {
79
79
  super.willUpdate(changed);
@@ -84,6 +84,26 @@ let HelixHeadlessMeter = class HelixHeadlessMeter extends HelixElement {
84
84
  this.internals.ariaValueNow = String(this.reading);
85
85
  this.internals.ariaValueText =
86
86
  this.valueText || this.formatOptions !== undefined || this.beyond ? this.text : null;
87
+ const band = this.computedBand;
88
+ const beyond = this.beyond;
89
+ this.toggleState('fair', band === 'fair');
90
+ this.toggleState('good', band === 'good');
91
+ this.toggleState('poor', band === 'poor');
92
+ this.toggleState('over', beyond === 'over');
93
+ this.toggleState('under', beyond === 'under');
94
+ }
95
+ updated(changed) {
96
+ super.updated(changed);
97
+ const band = this.computedBand;
98
+ const moved = this.lastBand !== undefined && (band ?? '') !== this.lastBand;
99
+ this.lastBand = band ?? '';
100
+ if (!moved) {
101
+ return;
102
+ }
103
+ this.dispatchEvent(new HelixBandEvent({ band: band ?? '' }));
104
+ if (band && this.live) {
105
+ this.status.say(`${this.text}, ${this.bandLabels[band] ?? BAND_WORDS[band]}`);
106
+ }
87
107
  }
88
108
  renderRound() {
89
109
  const bounds = this.thresholds;
@@ -131,12 +151,15 @@ let HelixHeadlessMeter = class HelixHeadlessMeter extends HelixElement {
131
151
  style="--meter-fraction: ${this.fraction}"
132
152
  ></div>
133
153
  </div>`}
134
- ${this.showValue ? html `<span part="value">${this.text}</span>` : nothing}`;
154
+ ${this.showValue ? html `<span part="value">${this.text}</span>` : nothing}${drawStatus(this.status)}`;
135
155
  }
136
156
  };
137
157
  __decorate([
138
158
  property()
139
159
  ], HelixHeadlessMeter.prototype, "band", void 0);
160
+ __decorate([
161
+ property({ attribute: 'band-labels', converter: wordsConverter })
162
+ ], HelixHeadlessMeter.prototype, "bandLabels", void 0);
140
163
  __decorate([
141
164
  property({ attribute: 'format-options', type: Object })
142
165
  ], HelixHeadlessMeter.prototype, "formatOptions", void 0);
@@ -146,6 +169,9 @@ __decorate([
146
169
  __decorate([
147
170
  property()
148
171
  ], HelixHeadlessMeter.prototype, "label", void 0);
172
+ __decorate([
173
+ property({ type: Boolean })
174
+ ], HelixHeadlessMeter.prototype, "live", void 0);
149
175
  __decorate([
150
176
  property()
151
177
  ], HelixHeadlessMeter.prototype, "locale", void 0);
@@ -4,23 +4,20 @@ 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, focusableElements, HelixElement, IndicatorController, KeyboardNavigationController, } from '@fusion.dev/helix-core';
7
+ import { AriaForwardController, customElement, focusableElements, focusItemOf, HelixElement, IndicatorController, KeyboardNavigationController, } from '@fusion.dev/helix-core';
8
8
  import { html } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  const FOCUSABLE = 'a[href], button, input, select, textarea, [tabindex]:not([tabindex="-1"])';
11
11
  const navigable = (item) => {
12
12
  const control = () => item.navigationControl ??
13
13
  (item.matches(FOCUSABLE) ? item : focusableElements(item)[0]);
14
- return {
15
- contains: (node) => {
14
+ return focusItemOf(item, {
15
+ focus: () => control()?.focus(),
16
+ owns: (node) => {
16
17
  const target = control();
17
18
  return target !== undefined && node !== null && (node === target || target.contains(node));
18
19
  },
19
- disabled: false,
20
- focusItem: () => control()?.focus(),
21
- select: () => { },
22
- selected: false,
23
- };
20
+ });
24
21
  };
25
22
  let HelixHeadlessNavigation = class HelixHeadlessNavigation extends HelixElement {
26
23
  constructor() {
@@ -1,4 +1,4 @@
1
- import { HelixElement } from '@fusion.dev/helix-core';
1
+ import { ChildrenController, HelixElement } from '@fusion.dev/helix-core';
2
2
  import { type PropertyValues, type TemplateResult } from 'lit';
3
3
  import type { HelixHeadlessNotification } from '../notification/notification.js';
4
4
  declare const HelixHeadlessNotificationGroup_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerOpenInterface) & typeof HelixElement;
@@ -134,6 +134,13 @@ export declare class HelixHeadlessNotificationGroup extends HelixHeadlessNotific
134
134
  * is anything behind it. The one row is the evidence.
135
135
  */
136
136
  private assign;
137
+ /**
138
+ * Hears a row arrive after the render. The slot is assigned by hand, so a
139
+ * new row is in no slot and sends no `slotchange` to say it came. The feed
140
+ * the group is in is asked to update as well, since it counts the group's
141
+ * rows and does not watch inside the group.
142
+ */
143
+ protected readonly childWatch: ChildrenController;
137
144
  private readonly handleToggle;
138
145
  protected render(): TemplateResult;
139
146
  }
@@ -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, MixinControllerOpen } from '@fusion.dev/helix-core';
7
+ import { assignSlots, ChildrenController, customElement, HelixElement, hostAria, MixinControllerOpen, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  const TRIGGER_ID = 'trigger';
@@ -16,6 +16,10 @@ let HelixHeadlessNotificationGroup = class HelixHeadlessNotificationGroup extend
16
16
  this.collapsible = false;
17
17
  this.label = '';
18
18
  this.isNotificationGroup = true;
19
+ this.childWatch = new ChildrenController(this, () => {
20
+ this.requestUpdate();
21
+ this.parentElement?.requestUpdate?.();
22
+ });
19
23
  this.handleToggle = () => {
20
24
  this.toggleOpen();
21
25
  };
@@ -58,11 +62,13 @@ let HelixHeadlessNotificationGroup = class HelixHeadlessNotificationGroup extend
58
62
  }
59
63
  return;
60
64
  }
61
- slot.assign(...showing);
62
- const action = this.renderRoot?.querySelector?.('slot[name="actions"]');
63
- action?.assign?.(...[...this.children].filter((child) => child.getAttribute('slot') === 'actions'));
64
- const label = this.renderRoot?.querySelector?.('slot[name="label"]');
65
- label?.assign?.(...[...this.children].filter((child) => child.getAttribute('slot') === 'label'));
65
+ assignSlots(this.renderRoot, this.children, (child) => {
66
+ const row = child;
67
+ if (showing.includes(row)) {
68
+ return '';
69
+ }
70
+ return items.includes(row) || !child.hasAttribute('slot') ? 'folded' : undefined;
71
+ });
66
72
  }
67
73
  render() {
68
74
  const counted = this.counted;
@@ -53,6 +53,16 @@ declare const HelixHeadlessNotification_base: (new (...args: any[]) => import("@
53
53
  * @csspart label - What happened, on the first line.
54
54
  * @csspart media - The leading slot's box.
55
55
  * @csspart time - When it happened, formatted for people to read.
56
+ * @csspart time-day - Format Date's `day`, forwarded for a time drawn as fields. An elapsed time draws none.
57
+ * @csspart time-day-period - Format Date's `day-period`, forwarded for a time drawn as fields. An elapsed time draws none.
58
+ * @csspart time-era - Format Date's `era`, forwarded for a time drawn as fields. An elapsed time draws none.
59
+ * @csspart time-hour - Format Date's `hour`, forwarded for a time drawn as fields. An elapsed time draws none.
60
+ * @csspart time-minute - Format Date's `minute`, forwarded for a time drawn as fields. An elapsed time draws none.
61
+ * @csspart time-month - Format Date's `month`, forwarded for a time drawn as fields. An elapsed time draws none.
62
+ * @csspart time-second - Format Date's `second`, forwarded for a time drawn as fields. An elapsed time draws none.
63
+ * @csspart time-time-zone-name - Format Date's `time-zone-name`, forwarded for a time drawn as fields. An elapsed time draws none.
64
+ * @csspart time-weekday - Format Date's `weekday`, forwarded for a time drawn as fields. An elapsed time draws none.
65
+ * @csspart time-year - Format Date's `year`, forwarded for a time drawn as fields. An elapsed time draws none.
56
66
  * @csspart trailing - The column holding the time and the controls.
57
67
  *
58
68
  * @cssstate actions - While the actions slot holds something, so the words above make room for it.
@@ -210,7 +220,8 @@ export declare class HelixHeadlessNotification extends HelixHeadlessNotification
210
220
  * already named for its role: the child publishes `time`, the role here is
211
221
  * `time`, and naming both would leave `::part(time)` matching two elements.
212
222
  * What a consumer wants to reach is the `<time>`, so that is what the name
213
- * reaches.
223
+ * reaches. Format Date's field parts go on under `time-`, as every composed
224
+ * child's do, though an elapsed time draws no fields.
214
225
  */
215
226
  private renderTime;
216
227
  protected render(): TemplateResult;
@@ -103,7 +103,9 @@ let HelixHeadlessNotification = class HelixHeadlessNotification extends MixinDis
103
103
  renderTime() {
104
104
  const stamp = this.tag('format-date');
105
105
  return html `<${stamp}
106
- exportparts="time"
106
+ exportparts="time, day: time-day, day-period: time-day-period, era: time-era, hour: time-hour,
107
+ minute: time-minute, month: time-month, second: time-second,
108
+ time-zone-name: time-time-zone-name, weekday: time-weekday, year: time-year"
107
109
  elapsed
108
110
  date=${this.at}
109
111
  locale=${this.locale}
@@ -1,5 +1,5 @@
1
- import { HelixElement } from '@fusion.dev/helix-core';
2
- import { type PropertyValues, type TemplateResult } from 'lit';
1
+ import { ChildrenController, HelixElement } from '@fusion.dev/helix-core';
2
+ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
3
3
  import type { HelixHeadlessNotificationGroup } from '../group/notification-group.js';
4
4
  import type { HelixHeadlessNotification } from '../notification/notification.js';
5
5
  declare const HelixHeadlessNotifications_base: (new (...args: any[]) => import("@fusion.dev/helix-core").CollectionElement) & typeof HelixElement;
@@ -35,6 +35,11 @@ declare const HelixHeadlessNotifications_base: (new (...args: any[]) => import("
35
35
  * nothing more. While the feed is loading the button stays, so focus stays on
36
36
  * it, and it is `aria-disabled` and sends nothing.
37
37
  *
38
+ * **`load-error` says a page could not be fetched**, such as "Could not load
39
+ * notifications": it shows under the rows there are, in the `error` part, in
40
+ * place of the empty and loading lines, and a screen reader hears it. Clear it
41
+ * when you ask again.
42
+ *
38
43
  * @since 0.1.0
39
44
  * @status stable
40
45
  * @category feedback
@@ -42,22 +47,29 @@ declare const HelixHeadlessNotifications_base: (new (...args: any[]) => import("
42
47
  * @documentation https://fusion.dev/helix/components/notifications
43
48
  *
44
49
  * @slot - The notifications.
50
+ * @slot empty - Replaces the words of `empty-text` in the `empty` part, such as a picture and a line of your own. The live region still says `empty-text`.
51
+ * @slot error - Replaces the words of `load-error` in the `error` part, such as a line with a retry button. The live region still says `load-error`.
45
52
  * @slot footer - Below the list, for a link to everything.
46
53
  * @slot header - Above the list, for a title and the mark-all control.
54
+ * @slot loading - Replaces the words of `loading-text` in the `loading` part, such as a loader. The live region still says `loading-text`.
47
55
  *
48
56
  * @event {HelixDismissEvent} helix-dismiss - Fired when the user dismisses a row. The row dispatches it, and you can listen for it on the feed. Cancelable: cancel it to keep the row.
49
57
  * @event {HelixLoadMoreEvent} helix-load-more - Fired when a reader presses the `load-more` button, asking for the next page of the feed.
50
58
  * @event {HelixReadEvent} helix-read - Fired by an item when it is marked read or unread, and by the feed when everything is marked read. Cancelable.
51
59
  *
52
60
  * @csspart empty - Shown when there is nothing in the feed.
61
+ * @csspart error - Shown while `load-error` is set, under any rows there are, in place of the empty and loading lines.
53
62
  * @csspart footer - The region below the list.
54
63
  * @csspart header - The region above the list.
55
64
  * @csspart list - The list itself.
56
- * @csspart live - A copy of the empty and loading messages, in a live region that screen readers announce when they change. Visually hidden in the styled tier.
65
+ * @csspart live - A copy of the empty, loading and error messages, in a live region that screen readers announce when they change. Visually hidden in the styled tier.
57
66
  * @csspart loading - Shown while the feed is loading.
58
67
  * @csspart mark-all - The control that marks everything read.
59
68
  * @csspart more - The button after the list that asks for more, while `load-more` is set. It is `aria-disabled` while the feed is loading.
60
69
  *
70
+ * @cssstate empty - While the feed holds no notification and is not loading, and `load-error` is not set. Never on the server, which cannot count the rows.
71
+ * @cssstate error - While `load-error` is set.
72
+ * @cssstate loading - While `loading` is set.
61
73
  * @cssstate media - While a notification in the list holds something in its media slot, so every row keeps that column.
62
74
  */
63
75
  export declare class HelixHeadlessNotifications extends HelixHeadlessNotifications_base {
@@ -75,6 +87,15 @@ export declare class HelixHeadlessNotifications extends HelixHeadlessNotificatio
75
87
  * The feed's name, read by screen readers.
76
88
  */
77
89
  label: string;
90
+ /**
91
+ * What the feed says when a page of it could not be loaded, such as after a
92
+ * request to a server fails. Empty, null or no attribute is no error, so
93
+ * removing the attribute clears it.
94
+ *
95
+ * Set, it shows under the rows there are, in place of `empty-text` and
96
+ * `loading-text`, and a screen reader hears it. Clear it when you ask again.
97
+ */
98
+ loadError: string | null;
78
99
  /**
79
100
  * Whether to draw a button after the list that asks for the next page, by
80
101
  * sending `helix-load-more`. Take it off once there is nothing more.
@@ -182,6 +203,13 @@ export declare class HelixHeadlessNotifications extends HelixHeadlessNotificatio
182
203
  markEveryoneRead(): number;
183
204
  /** Items arrive from the light DOM, which changes no property here. */
184
205
  private readonly handleSlotChange;
206
+ /**
207
+ * Hears a row arrive after the render. The list slot is assigned by hand, so
208
+ * a new row is in no slot and sends no `slotchange`: without this it was
209
+ * drawn nowhere and an emptied feed kept saying it was empty. A row added to
210
+ * a group is the group's to hear, and the group asks the feed to count again.
211
+ */
212
+ protected readonly childWatch: ChildrenController;
185
213
  /**
186
214
  * An item's own read event, heard on the way past, so the count follows.
187
215
  *
@@ -220,6 +248,23 @@ export declare class HelixHeadlessNotifications extends HelixHeadlessNotificatio
220
248
  connectedCallback(): void;
221
249
  disconnectedCallback(): void;
222
250
  protected willUpdate(changed: PropertyValues): void;
251
+ /**
252
+ * The error, the empty or the loading line, each around a slot of the same
253
+ * name whose fallback is the words, so a page can put its own in. The error
254
+ * shows under the rows there are, since a page that failed is news even to
255
+ * a feed that holds some.
256
+ */
257
+ protected renderStatus(hasContent: boolean): TemplateResult | typeof nothing;
258
+ /**
259
+ * The error before the shared words, which it wins over.
260
+ *
261
+ * **One region whose words change**, as the shared one is. The error was a
262
+ * second template, so setting it put a new region in the tree with its
263
+ * words already in it, which a reader may not hear.
264
+ */
265
+ protected renderLive(hasContent: boolean): TemplateResult;
266
+ /** Whether `load-error` holds words, which a removed attribute does not. */
267
+ private get failed();
223
268
  /**
224
269
  * Says whether anything in the feed has media, so every item can hold the
225
270
  * column open whether or not it has one of its own.