@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
@@ -4,27 +4,48 @@ 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, markRegion } from '@fusion.dev/helix-core';
7
+ import { customElement, HelixElement, markRegion, toolbarAround, toolbarAxis, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  let HelixHeadlessDivider = class HelixHeadlessDivider extends HelixElement {
11
11
  constructor() {
12
12
  super(...arguments);
13
13
  this.announced = false;
14
+ this.decorative = false;
15
+ }
16
+ get drawn() {
17
+ const toolbar = this.orientation || this.hydrating ? null : toolbarAround(this);
18
+ if (toolbar) {
19
+ return toolbarAxis(toolbar) === 'vertical' ? 'horizontal' : 'vertical';
20
+ }
21
+ return this.orientation ?? 'horizontal';
22
+ }
23
+ connectedCallback() {
24
+ super.connectedCallback();
25
+ this.requestUpdate();
14
26
  }
15
27
  markEmpty() {
16
28
  markRegion(this.renderRoot, 'content', ['']);
17
29
  }
30
+ willUpdate(changed) {
31
+ super.willUpdate(changed);
32
+ this.toggleState('vertical', this.drawn === 'vertical');
33
+ }
34
+ firstUpdated(changed) {
35
+ super.firstUpdated(changed);
36
+ this.finishHydration();
37
+ }
18
38
  updated(changed) {
19
39
  super.updated(changed);
20
40
  this.markEmpty();
21
41
  }
22
42
  render() {
43
+ const separator = this.announced || !this.decorative;
23
44
  return html `<div
24
45
  part="line"
25
- role=${this.announced ? 'separator' : 'presentation'}
26
- aria-labelledby=${this.announced ? 'content' : nothing}
27
- aria-orientation=${this.announced ? (this.orientation ?? 'horizontal') : nothing}
46
+ role=${separator ? 'separator' : 'presentation'}
47
+ aria-labelledby=${separator ? 'content' : nothing}
48
+ aria-orientation=${separator ? this.drawn : nothing}
28
49
  ></div>
29
50
  <span id="content" part="content"><slot @slotchange=${() => this.markEmpty()}></slot></span>
30
51
  <div part="line" role="presentation"></div>`;
@@ -33,6 +54,9 @@ let HelixHeadlessDivider = class HelixHeadlessDivider extends HelixElement {
33
54
  __decorate([
34
55
  property({ reflect: true, type: Boolean })
35
56
  ], HelixHeadlessDivider.prototype, "announced", void 0);
57
+ __decorate([
58
+ property({ reflect: true, type: Boolean })
59
+ ], HelixHeadlessDivider.prototype, "decorative", void 0);
36
60
  __decorate([
37
61
  property({ reflect: true })
38
62
  ], HelixHeadlessDivider.prototype, "orientation", void 0);
@@ -8,6 +8,7 @@ import { CHART_PLOT, customElement, drawTooltip, HelixElement, MixinChartSource,
8
8
  import { html, nothing, svg } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  import '../../tooltip/index.js';
11
+ import { sliceLabelAt } from '../slice-label.js';
11
12
  const PERCENTS = new Map();
12
13
  const percentIn = (locale) => {
13
14
  let found = PERCENTS.get(locale);
@@ -124,16 +125,22 @@ let HelixHeadlessDonutChart = class HelixHeadlessDonutChart extends MixinChartSo
124
125
  }
125
126
  renderSliceLabels(shares) {
126
127
  const half = this.sweep === 'half';
127
- const top = half ? CENTER - EDGE : 0;
128
- const tall = half ? EDGE + this.thickness / 2 : PLOT_HEIGHT;
128
+ const ring = {
129
+ center: CENTER,
130
+ origin: this.origin,
131
+ radius: this.radius,
132
+ span: this.span,
133
+ tall: half ? EDGE + this.thickness / 2 : PLOT_HEIGHT,
134
+ top: half ? CENTER - EDGE : 0,
135
+ width: PLOT_WIDTH,
136
+ };
129
137
  const format = percentIn(this.locale);
130
138
  return html `${shares.map((share, index) => {
131
- if (share.fraction < 0.05) {
139
+ const place = sliceLabelAt(share, ring);
140
+ if (!place) {
132
141
  return nothing;
133
142
  }
134
- const angle = (share.start + share.fraction / 2) * 2 * Math.PI * this.span + this.origin;
135
- const x = ((CENTER + Math.cos(angle) * this.radius) / PLOT_WIDTH) * 100;
136
- const y = ((CENTER + Math.sin(angle) * this.radius - top) / tall) * 100;
143
+ const { x, y } = place;
137
144
  return html `<span
138
145
  aria-hidden="true"
139
146
  data-series=${seriesIndex(index)}
@@ -0,0 +1,35 @@
1
+ /** A slice's place on the ring, as shares of the whole from 0 to 1. */
2
+ export interface SliceShare {
3
+ /** How much of the ring the slice takes. */
4
+ fraction: number;
5
+ /** Where the slice starts, as the share of the ring before it. */
6
+ start: number;
7
+ }
8
+ /** The ring a slice label is placed on, in the drawing's own units. */
9
+ export interface RingGeometry {
10
+ /** The center, on both axes. */
11
+ center: number;
12
+ /** Where the ring's turn starts, in radians: a quarter turn back is twelve o'clock. */
13
+ origin: number;
14
+ /** The radius of the band's middle, where a label sits. */
15
+ radius: number;
16
+ /** How much of a turn the ring takes: 1 for a ring, a half for an arc. */
17
+ span: number;
18
+ /** How tall the box the labels are placed in is. */
19
+ tall: number;
20
+ /** Where the top of that box is. */
21
+ top: number;
22
+ /** How wide the drawing is. */
23
+ width: number;
24
+ }
25
+ /** The smallest share that takes a label: a twentieth of the ring. */
26
+ export declare const SMALLEST_LABELED = 0.05;
27
+ /**
28
+ * Where a slice's label goes, as percentages of the box from the left and the
29
+ * top: the middle of its band at its mid-angle. Nothing for a slice under a
30
+ * twentieth, whose label would not fit on it.
31
+ */
32
+ export declare const sliceLabelAt: (share: SliceShare, ring: RingGeometry) => {
33
+ x: number;
34
+ y: number;
35
+ } | undefined;
@@ -0,0 +1,11 @@
1
+ export const SMALLEST_LABELED = 0.05;
2
+ export const sliceLabelAt = (share, ring) => {
3
+ if (share.fraction < SMALLEST_LABELED) {
4
+ return undefined;
5
+ }
6
+ const angle = (share.start + share.fraction / 2) * 2 * Math.PI * ring.span + ring.origin;
7
+ return {
8
+ x: ((ring.center + Math.cos(angle) * ring.radius) / ring.width) * 100,
9
+ y: ((ring.center + Math.sin(angle) * ring.radius - ring.top) / ring.tall) * 100,
10
+ };
11
+ };
@@ -1,4 +1,4 @@
1
- import { AriaForwardController, CommandController, HelixElement, OpenPhaseController, SwipeController } from '@fusion.dev/helix-core';
1
+ import { AriaForwardController, CommandController, FocusScopeController, HelixElement, OpenPhaseController, SwipeController } from '@fusion.dev/helix-core';
2
2
  import { type PropertyValues, type TemplateResult } from 'lit';
3
3
  declare const HelixHeadlessDrawer_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerOpenInterface) & typeof HelixElement;
4
4
  /**
@@ -11,7 +11,8 @@ declare const HelixHeadlessDrawer_base: (new (...args: any[]) => import("@fusion
11
11
  *
12
12
  * The drawer is modal by default, which means four things:
13
13
  *
14
- * - focus is trapped inside
14
+ * - focus is trapped inside: `Tab` from the last control goes to the first,
15
+ * and `Shift+Tab` from the first to the last, as in `Dialog`
15
16
  * - Escape and a press outside close it
16
17
  * - the page behind is covered
17
18
  * - the page behind does not scroll
@@ -233,6 +234,7 @@ export declare class HelixHeadlessDrawer extends HelixHeadlessDrawer_base {
233
234
  * key is read here, and comes through the same request.
234
235
  */
235
236
  private readonly handleKeydown;
237
+ protected readonly scope: FocusScopeController;
236
238
  /** The panel, which is a real `<dialog>`. */
237
239
  private get panel();
238
240
  /**
@@ -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, CommandController, customElement, drawDismiss, drawDismissGlyph, edgeOffset, HelixElement, headingsIn, isRtl, lockScroll, MixinControllerOpen, OpenPhaseController, onUnlessFalse, parseSnapPoints, reflectElements, SwipeController, settleSwipe, snapTravel, swipeAxis, swipeEdge, towardEdge, unlockScroll, } from '@fusion.dev/helix-core';
7
+ import { AriaForwardController, CommandController, customElement, drawDismiss, drawDismissGlyph, edgeOffset, FocusScopeController, HelixElement, headingsIn, isRtl, lockScroll, MixinControllerOpen, nearest, OpenPhaseController, onUnlessFalse, parseSnapPoints, reflectElements, SwipeController, settleSwipe, snapTravel, swipeAxis, swipeEdge, towardEdge, unlockScroll, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  import { beyondWindow } from '../reveal.js';
@@ -64,6 +64,16 @@ let HelixHeadlessDrawer = class HelixHeadlessDrawer extends MixinControllerOpen(
64
64
  event.preventDefault();
65
65
  this.requestOpen(false);
66
66
  };
67
+ this.scope = new FocusScopeController(this, {
68
+ contain: () => this.open && this.modal,
69
+ contents: () => [
70
+ ...['header', '', 'footer'].flatMap((name) => this.renderRoot
71
+ ?.querySelector(name ? `slot[name="${name}"]` : 'slot:not([name])')
72
+ ?.assignedElements({ flatten: true }) ?? []),
73
+ ...[...(this.panel?.children ?? [])].filter((one) => one.localName === 'button'),
74
+ ],
75
+ surface: () => this.panel,
76
+ });
67
77
  this.handleCancel = (event) => {
68
78
  event.preventDefault();
69
79
  this.requestOpen(false);
@@ -153,8 +163,10 @@ let HelixHeadlessDrawer = class HelixHeadlessDrawer extends MixinControllerOpen(
153
163
  return;
154
164
  }
155
165
  const points = parseSnapPoints(this.snapPoints);
156
- const nearest = points.reduce((best, one) => Math.abs(one - point) < Math.abs(best - point) ? one : best);
157
- this.restAt(nearest);
166
+ const at = nearest(points, point);
167
+ if (at !== undefined) {
168
+ this.restAt(at);
169
+ }
158
170
  }
159
171
  show() {
160
172
  this.requestOpen(true);
@@ -13,6 +13,8 @@ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
13
13
  * - On the page that is showing, it renders its row.
14
14
  * - When its own page is showing, it renders only that page's rows. Its row
15
15
  * belongs to the page above.
16
+ * - When a page further down its own is showing, it renders its page's slot
17
+ * alone, so the rows below reach the page.
16
18
  * - Otherwise it renders nothing. The rows stay in the light DOM untouched, so
17
19
  * there is no state to keep.
18
20
  *
@@ -23,6 +25,10 @@ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
23
25
  * `aria-haspopup`, the same way `Menu` marks a row with a submenu. The server
24
26
  * render leaves both out, because the server cannot see the children.
25
27
  *
28
+ * The row is named by its label alone. Words in `description`, a line under
29
+ * the label, and in `end` describe it instead, through `aria-describedby`, as
30
+ * `Menu.Item` does: a reader hears "Theme", then "Dark".
31
+ *
26
32
  * @since 0.1.0
27
33
  * @status stable
28
34
  * @aliases Panel item, Drill row
@@ -30,7 +36,8 @@ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
30
36
  *
31
37
  * @slot - The row's label.
32
38
  * @slot chevron - Replaces the caret of a row that opens a page, such as with your own icon.
33
- * @slot end - Content after the label, usually an icon or a count.
39
+ * @slot description - A line under the label that describes the row. It describes the row to a screen reader and is not part of its name.
40
+ * @slot end - Content after the label, such as the setting a page holds or a count. It describes the row and is not part of its name.
34
41
  * @slot page - The rows of the page this row opens.
35
42
  * @slot start - Content before the label, usually an icon.
36
43
  *
@@ -71,6 +78,11 @@ export declare class HelixHeadlessDrilldownItem extends HelixElement {
71
78
  * event handler is why it is kept off the typings.
72
79
  */
73
80
  onPage: boolean;
81
+ /**
82
+ * @internal Whether the page showing is below this row's own, deeper than one
83
+ * level. Written by the stack.
84
+ */
85
+ onPath: boolean;
74
86
  /**
75
87
  * @internal Whether this row's own page is the one showing. Written by the
76
88
  * stack.
@@ -89,6 +101,10 @@ export declare class HelixHeadlessDrilldownItem extends HelixElement {
89
101
  * render would open with no caret on the row that leads to it.
90
102
  */
91
103
  private page;
104
+ /** Whether anything is slotted under the label, read the way `page` is. */
105
+ private description;
106
+ /** Whether anything is slotted after the label, read the way `page` is. */
107
+ private end;
92
108
  /**
93
109
  * Reads the children before each render, where they can be known.
94
110
  *
@@ -109,6 +125,10 @@ export declare class HelixHeadlessDrilldownItem extends HelixElement {
109
125
  * the same note.
110
126
  */
111
127
  private readonly readPage;
128
+ /** Re-reads whether the line under the label or the words after it are filled. */
129
+ private readonly readWords;
130
+ /** What describes the row: the line under its label and the words after it. */
131
+ private get describedBy();
112
132
  /** Moves focus onto the row itself. */
113
133
  focusItem(): void;
114
134
  /**
@@ -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, deepActiveElement, HelixElement, HelixSelectEvent, } from '@fusion.dev/helix-core';
7
+ import { customElement, deepActiveElement, HelixElement, HelixSelectEvent, slotFilled, slotNamed, } from '@fusion.dev/helix-core';
8
8
  import { caretRight } from '@fusion.dev/helix-icons';
9
9
  import { html, nothing } from 'lit';
10
10
  import { property, state } from 'lit/decorators.js';
@@ -16,24 +16,40 @@ let HelixHeadlessDrilldownItem = class HelixHeadlessDrilldownItem extends HelixE
16
16
  this.focusable = false;
17
17
  this.isDrilldownItem = true;
18
18
  this.onPage = true;
19
+ this.onPath = false;
19
20
  this.showingPage = false;
20
21
  this.value = '';
21
22
  this.page = false;
23
+ this.description = false;
24
+ this.end = false;
22
25
  this.readPage = () => {
23
26
  const slot = this.renderRoot.querySelector('slot[name="page"]');
24
27
  this.page = (slot?.assignedElements().length ?? 0) > 0;
25
28
  };
29
+ this.readWords = () => {
30
+ this.description = slotFilled(slotNamed(this.renderRoot, 'description'));
31
+ this.end = slotFilled(slotNamed(this.renderRoot, 'end'));
32
+ };
26
33
  }
27
34
  willUpdate(changed) {
28
35
  super.willUpdate(changed);
29
36
  if (this.childrenKnown) {
30
- this.page = this.knownChildren.some((child) => child.slot === 'page');
37
+ const named = (name) => this.knownChildren.some((child) => child.slot === name);
38
+ this.page = named('page');
39
+ this.description = named('description');
40
+ this.end = named('end');
31
41
  }
32
42
  }
33
43
  firstUpdated(changed) {
34
44
  super.firstUpdated(changed);
35
45
  this.finishHydration();
36
46
  }
47
+ get describedBy() {
48
+ const ids = [this.description ? 'description' : '', this.end ? 'end' : '']
49
+ .filter((id) => id !== '')
50
+ .join(' ');
51
+ return ids === '' ? nothing : ids;
52
+ }
37
53
  focusItem() {
38
54
  this.partNamed('item')?.focus();
39
55
  }
@@ -58,7 +74,7 @@ let HelixHeadlessDrilldownItem = class HelixHeadlessDrilldownItem extends HelixE
58
74
  >`;
59
75
  }
60
76
  render() {
61
- if (this.showingPage) {
77
+ if (this.showingPage || this.onPath) {
62
78
  return html `<slot name="page" @slotchange=${this.readPage}></slot>`;
63
79
  }
64
80
  if (!this.onPage) {
@@ -68,14 +84,23 @@ let HelixHeadlessDrilldownItem = class HelixHeadlessDrilldownItem extends HelixE
68
84
  part="item"
69
85
  type="button"
70
86
  role="menuitem"
87
+ aria-describedby=${this.describedBy}
71
88
  aria-disabled=${this.disabled ? 'true' : nothing}
72
89
  aria-haspopup=${this.page ? 'menu' : nothing}
73
90
  tabindex=${this.focusable ? '0' : '-1'}
91
+ ?data-described=${this.description}
74
92
  @click=${() => this.select()}
75
93
  >
76
94
  <slot name="start"></slot>
77
95
  <span part="label"><slot></slot></span>
78
- <slot name="end"></slot>
96
+ <slot
97
+ id="description"
98
+ name="description"
99
+ aria-hidden="true"
100
+ ?data-empty=${!this.description}
101
+ @slotchange=${this.readWords}
102
+ ></slot>
103
+ <slot id="end" name="end" aria-hidden="true" @slotchange=${this.readWords}></slot>
79
104
  ${this.page ? this.renderMark() : nothing}
80
105
  </button>
81
106
  <div hidden><slot name="page" @slotchange=${this.readPage}></slot></div>`;
@@ -90,6 +115,9 @@ __decorate([
90
115
  __decorate([
91
116
  property({ attribute: false })
92
117
  ], HelixHeadlessDrilldownItem.prototype, "onPage", void 0);
118
+ __decorate([
119
+ property({ attribute: false })
120
+ ], HelixHeadlessDrilldownItem.prototype, "onPath", void 0);
93
121
  __decorate([
94
122
  property({ attribute: false })
95
123
  ], HelixHeadlessDrilldownItem.prototype, "showingPage", void 0);
@@ -99,6 +127,12 @@ __decorate([
99
127
  __decorate([
100
128
  state()
101
129
  ], HelixHeadlessDrilldownItem.prototype, "page", void 0);
130
+ __decorate([
131
+ state()
132
+ ], HelixHeadlessDrilldownItem.prototype, "description", void 0);
133
+ __decorate([
134
+ state()
135
+ ], HelixHeadlessDrilldownItem.prototype, "end", void 0);
102
136
  HelixHeadlessDrilldownItem = __decorate([
103
137
  customElement('helix-headless-drilldown-item')
104
138
  ], HelixHeadlessDrilldownItem);
@@ -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, DrilldownController, HelixElement, inlineStep, KeyboardNavigationController, keyClaimed, MixinCollection, slottedWords, typeaheadBy, } from '@fusion.dev/helix-core';
7
+ import { AriaForwardController, customElement, DrilldownController, HelixElement, inlineStep, KeyboardNavigationController, keyClaimed, MixinCollection, slottedWords, typeaheadByWords, } from '@fusion.dev/helix-core';
8
8
  import { caretLeft } from '@fusion.dev/helix-icons';
9
9
  import { html, nothing } from 'lit';
10
10
  import { property, state } from 'lit/decorators.js';
@@ -38,7 +38,7 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
38
38
  })),
39
39
  reserved: () => ['ArrowLeft', 'ArrowRight'],
40
40
  selects: () => false,
41
- typeahead: typeaheadBy((item) => item.words),
41
+ typeahead: typeaheadByWords(),
42
42
  });
43
43
  this.handleFocusIn = (event) => {
44
44
  const item = this.drilldown.rows.find((row) => row.contains(event.target));
@@ -162,6 +162,7 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
162
162
  mark(item, page, onPage) {
163
163
  item.onPage = onPage;
164
164
  item.showingPage = item === page;
165
+ item.onPath = page !== null && item !== page && item.contains(page);
165
166
  for (const child of item.children) {
166
167
  if (child instanceof HelixHeadlessDrilldownItem && child.slot === 'page') {
167
168
  this.mark(child, page, item === page);
@@ -5,6 +5,7 @@ registerElementEvents({
5
5
  'helix-headless-app-header': ['helix-scrolled'],
6
6
  'helix-headless-avatar': ['error', 'load'],
7
7
  'helix-headless-button': ['helix-press'],
8
+ 'helix-headless-button-group': ['change', 'helix-before-change'],
8
9
  'helix-headless-callout': ['helix-dismiss'],
9
10
  'helix-headless-canvas': [
10
11
  'helix-before-move',
@@ -115,7 +116,7 @@ registerElementEvents({
115
116
  'helix-graph-signal',
116
117
  'helix-graph-zoom',
117
118
  ],
118
- 'helix-headless-heatmap': ['helix-resize'],
119
+ 'helix-headless-heatmap': ['change', 'helix-before-change', 'helix-resize'],
119
120
  'helix-headless-icon': ['error', 'load'],
120
121
  'helix-headless-icon-button': ['helix-press'],
121
122
  'helix-headless-image': ['error', 'load'],
@@ -166,6 +167,7 @@ registerElementEvents({
166
167
  'helix-headless-megamenu': ['helix-before-close', 'helix-before-open', 'toggle'],
167
168
  'helix-headless-menu': ['helix-before-close', 'helix-before-open', 'helix-select', 'toggle'],
168
169
  'helix-headless-menu-item': ['helix-before-toggle', 'helix-select'],
170
+ 'helix-headless-meter': ['helix-band'],
169
171
  'helix-headless-notification': ['helix-dismiss', 'helix-read'],
170
172
  'helix-headless-notification-group': ['helix-before-close', 'helix-before-open', 'toggle'],
171
173
  'helix-headless-notifications': ['helix-dismiss', 'helix-load-more', 'helix-read'],
@@ -186,6 +188,7 @@ registerElementEvents({
186
188
  'helix-headless-pagination-size': ['change', 'helix-before-change', 'input'],
187
189
  'helix-headless-pin-input': ['change', 'helix-before-change', 'helix-complete', 'input'],
188
190
  'helix-headless-popover': ['helix-before-close', 'helix-before-open', 'toggle'],
191
+ 'helix-headless-progress': ['helix-complete'],
189
192
  'helix-headless-qr-code': ['error'],
190
193
  'helix-headless-radio': ['helix-select'],
191
194
  'helix-headless-radio-group': ['change', 'helix-before-change', 'helix-select', 'input'],
@@ -220,6 +223,7 @@ registerElementEvents({
220
223
  'helix-before-resize',
221
224
  'helix-collapse',
222
225
  'helix-resized',
226
+ 'input',
223
227
  ],
224
228
  'helix-headless-step': ['helix-select'],
225
229
  'helix-headless-steps': ['helix-activate', 'helix-before-activate', 'helix-select'],
@@ -1,5 +1,5 @@
1
1
  import { ArrivalController, HelixElement } from '@fusion.dev/helix-core';
2
- import { type TemplateResult } from 'lit';
2
+ import { type PropertyValues, type TemplateResult } from 'lit';
3
3
  /**
4
4
  * @summary A message that a region has nothing in it, and the next step to take.
5
5
  *
@@ -19,6 +19,18 @@ import { type TemplateResult } from 'lit';
19
19
  * `empty-state-actions` element: assign your own heading and actions to the
20
20
  * slots.
21
21
  *
22
+ * **Or give the heading as words.** `heading` draws them in a `heading` part
23
+ * that is a heading at `heading-level`, 3 where it is not set, so a page
24
+ * rendering from data or on a server gets a heading a reader finds in the
25
+ * outline without writing the element. A heading slotted in replaces it.
26
+ *
27
+ * **Whatever is slotted into `heading` is read as a heading.** An element that
28
+ * is no heading, such as a `<span>` or a `<p>`, is set inside the `heading`
29
+ * part at `heading-level`, so a screen reader still finds it in the outline.
30
+ * A heading element, or an element holding one, keeps its own level. A server
31
+ * cannot see the slotted element, so a served `<span>` becomes a heading once
32
+ * the script runs.
33
+ *
22
34
  * @since 0.1.0
23
35
  * @status stable
24
36
  * @category feedback
@@ -27,12 +39,27 @@ import { type TemplateResult } from 'lit';
27
39
  *
28
40
  * @slot - The message: why the region is empty, and what to do about it.
29
41
  * @slot actions - The action that would put something in the region.
30
- * @slot heading - The heading, which names what is missing. Slot a heading element, such as an `<h3>`, so a reader can find it in the page's outline.
42
+ * @slot heading - The heading, which names what is missing. A heading element, such as an `<h3>`, keeps its level; any other element is read as a heading at `heading-level`. Replaces the one `heading` draws.
31
43
  * @slot icon - An icon above the heading.
32
44
  *
45
+ * @csspart heading - The heading at `heading-level`: the one `heading` draws while nothing is slotted into `heading`, or the one around a slotted element that is no heading.
33
46
  * @csspart live - A copy of the heading and the message, in a live region that screen readers announce when the view appears. Visually hidden in the styled tier.
34
47
  */
35
48
  export declare class HelixHeadlessEmpty extends HelixElement {
49
+ /**
50
+ * The heading as words, such as "No results", drawn as a heading when
51
+ * nothing is slotted into `heading`.
52
+ *
53
+ * Absent draws none, and the `heading` slot is the only heading.
54
+ */
55
+ heading: string;
56
+ /**
57
+ * The level of the heading `heading` draws, from 1 to 6.
58
+ *
59
+ * Absent is 3, the level of a heading inside a page's section. Set it to fit
60
+ * the outline the empty view sits in. A slotted heading keeps its own.
61
+ */
62
+ headingLevel?: number;
36
63
  /**
37
64
  * Whether the state is announced when it appears.
38
65
  *
@@ -41,7 +68,24 @@ export declare class HelixHeadlessEmpty extends HelixElement {
41
68
  * has nothing to announce because nothing changed.
42
69
  */
43
70
  noAnnounce: boolean;
71
+ /**
72
+ * Whether the `heading` slot holds elements and none of them is or holds a
73
+ * heading, read from the children before each render.
74
+ */
75
+ private looseHeading;
76
+ protected willUpdate(changed: PropertyValues): void;
77
+ protected firstUpdated(changed: PropertyValues): void;
44
78
  protected readonly arrival: ArrivalController;
79
+ /**
80
+ * The `heading` slot, with the heading `heading` draws as its fallback, so
81
+ * one slotted in replaces it; no fallback while `heading` holds no words.
82
+ *
83
+ * A method, so a tier above can draw its own, as the slot lets a page.
84
+ *
85
+ * @param hidden Whether the live copy holds the heading's words, which
86
+ * hides them from readers until it empties.
87
+ */
88
+ protected renderHeading(hidden: boolean): TemplateResult;
45
89
  protected render(): TemplateResult;
46
90
  }
47
91
  declare global {
@@ -4,30 +4,75 @@ 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 { ArrivalController, customElement, HelixElement, slottedWords, } from '@fusion.dev/helix-core';
7
+ import { ArrivalController, customElement, HelixElement, headingIn, headingLevel, slottedWords, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  let HelixHeadlessEmpty = class HelixHeadlessEmpty extends HelixElement {
11
11
  constructor() {
12
12
  super(...arguments);
13
+ this.heading = '';
13
14
  this.noAnnounce = false;
15
+ this.looseHeading = false;
14
16
  this.arrival = new ArrivalController(this, {
15
17
  arriving: () => !this.serverRendered && document.readyState === 'complete',
16
- text: () => slottedWords(this, ['heading', '']),
18
+ text: () => [slottedWords(this, ['heading']) || this.heading.trim(), slottedWords(this, [''])]
19
+ .filter(Boolean)
20
+ .join(' '),
17
21
  });
18
22
  }
23
+ willUpdate(changed) {
24
+ super.willUpdate(changed);
25
+ if (this.childrenKnown) {
26
+ const slotted = this.knownChildren.filter((child) => child.slot === 'heading');
27
+ this.looseHeading = slotted.length > 0 && headingIn(slotted) === null;
28
+ }
29
+ }
30
+ firstUpdated(changed) {
31
+ super.firstUpdated(changed);
32
+ this.finishHydration();
33
+ }
34
+ renderHeading(hidden) {
35
+ const level = headingLevel(this.headingLevel);
36
+ const slot = html `<slot
37
+ aria-hidden=${hidden && !this.looseHeading ? 'true' : nothing}
38
+ name="heading"
39
+ @slotchange=${() => {
40
+ this.arrival.say();
41
+ this.requestUpdate();
42
+ }}
43
+ >${this.heading.trim()
44
+ ? html `<div aria-level=${level} part="heading" role="heading">
45
+ ${this.heading}
46
+ </div>`
47
+ : nothing}</slot
48
+ >`;
49
+ return this.looseHeading
50
+ ? html `<div
51
+ aria-hidden=${hidden ? 'true' : nothing}
52
+ aria-level=${level}
53
+ part="heading"
54
+ role="heading"
55
+ >${slot}</div>`
56
+ : slot;
57
+ }
19
58
  render() {
20
59
  const say = () => this.arrival.say();
21
- const copied = this.arrival.said !== '' && !this.noAnnounce ? 'true' : nothing;
60
+ const held = this.arrival.said !== '' && !this.noAnnounce;
22
61
  return html `<slot name="icon"></slot>
23
- <slot aria-hidden=${copied} name="heading" @slotchange=${say}></slot>
24
- <slot aria-hidden=${copied} @slotchange=${say}></slot>
62
+ ${this.renderHeading(held)}
63
+ <slot aria-hidden=${held ? 'true' : nothing} @slotchange=${say}></slot>
25
64
  <slot name="actions"></slot>
26
65
  ${this.noAnnounce
27
66
  ? nothing
28
67
  : html `<span part="live" role="status">${this.arrival.said}</span>`}`;
29
68
  }
30
69
  };
70
+ __decorate([
71
+ property()
72
+ ], HelixHeadlessEmpty.prototype, "heading", void 0);
73
+ __decorate([
74
+ property({ attribute: 'heading-level', type: Number })
75
+ ], HelixHeadlessEmpty.prototype, "headingLevel", void 0);
31
76
  __decorate([
32
77
  property({ attribute: 'no-announce', reflect: true, type: Boolean })
33
78
  ], HelixHeadlessEmpty.prototype, "noAnnounce", void 0);