@fusion.dev/helix-headless 0.144.0 → 0.146.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (319) hide show
  1. package/custom-elements.json +15195 -4240
  2. package/dist/accordion/item/accordion-item.d.ts +62 -12
  3. package/dist/accordion/item/accordion-item.js +41 -10
  4. package/dist/accordion/root/accordion-root.d.ts +14 -5
  5. package/dist/accordion/root/accordion-root.js +7 -1
  6. package/dist/announcement/root/announcement-root.d.ts +24 -3
  7. package/dist/announcement/root/announcement-root.js +39 -2
  8. package/dist/app-header/root/app-header-root.d.ts +12 -0
  9. package/dist/app-header/root/app-header-root.js +13 -1
  10. package/dist/app-header/sectioning.d.ts +9 -0
  11. package/dist/app-header/sectioning.js +27 -0
  12. package/dist/avatar/group/avatar-group.d.ts +20 -14
  13. package/dist/avatar/group/avatar-group.js +17 -19
  14. package/dist/badge/root/badge-root.d.ts +3 -1
  15. package/dist/badge/root/badge-root.js +2 -2
  16. package/dist/bar-chart/root/bar-chart-root.d.ts +18 -1
  17. package/dist/bar-chart/root/bar-chart-root.js +52 -15
  18. package/dist/bar-chart/stack.d.ts +15 -0
  19. package/dist/bar-chart/stack.js +19 -0
  20. package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +57 -1
  21. package/dist/breadcrumbs/root/breadcrumbs-root.js +73 -3
  22. package/dist/button/root/button-root.d.ts +26 -0
  23. package/dist/button/root/button-root.js +38 -18
  24. package/dist/button-group/root/button-group-root.d.ts +2 -1
  25. package/dist/button-group/root/button-group-root.js +5 -1
  26. package/dist/canvas/node/canvas-node.d.ts +4 -3
  27. package/dist/canvas/node/canvas-node.js +3 -2
  28. package/dist/canvas/root/canvas-root.d.ts +38 -3
  29. package/dist/canvas/root/canvas-root.js +123 -42
  30. package/dist/card/root/card-root.d.ts +24 -3
  31. package/dist/card/root/card-root.js +20 -8
  32. package/dist/carousel/root/carousel-root.d.ts +133 -4
  33. package/dist/carousel/root/carousel-root.js +174 -24
  34. package/dist/carousel/stops.d.ts +20 -0
  35. package/dist/carousel/stops.js +30 -0
  36. package/dist/chat/composer/chat-composer.d.ts +38 -6
  37. package/dist/chat/composer/chat-composer.js +42 -9
  38. package/dist/chat/message/chat-message.d.ts +32 -1
  39. package/dist/chat/message/chat-message.js +27 -10
  40. package/dist/chat/naming.d.ts +26 -0
  41. package/dist/chat/naming.js +14 -0
  42. package/dist/chat/root/chat-root.d.ts +58 -0
  43. package/dist/chat/root/chat-root.js +43 -3
  44. package/dist/checkbox/root/checkbox-root.d.ts +20 -0
  45. package/dist/checkbox/root/checkbox-root.js +14 -1
  46. package/dist/checkbox-group/root/checkbox-group-root.d.ts +8 -2
  47. package/dist/checkbox-group/root/checkbox-group-root.js +12 -10
  48. package/dist/checkbox-group/select-all.d.ts +27 -0
  49. package/dist/checkbox-group/select-all.js +12 -0
  50. package/dist/code-block/highlight.d.ts +15 -0
  51. package/dist/code-block/highlight.js +4 -0
  52. package/dist/code-block/root/code-block-root.d.ts +57 -2
  53. package/dist/code-block/root/code-block-root.js +63 -8
  54. package/dist/color-input/root/color-input-root.d.ts +3 -0
  55. package/dist/color-input/root/color-input-root.js +6 -3
  56. package/dist/color-picker/root/color-picker-root.d.ts +33 -4
  57. package/dist/color-picker/root/color-picker-root.js +80 -21
  58. package/dist/color-picker/swatches.d.ts +12 -0
  59. package/dist/color-picker/swatches.js +26 -0
  60. package/dist/combobox/root/combobox-root.d.ts +43 -0
  61. package/dist/combobox/root/combobox-root.js +79 -15
  62. package/dist/command/root/command-root.d.ts +16 -1
  63. package/dist/command/root/command-root.js +22 -4
  64. package/dist/copy-button/root/copy-button-root.d.ts +26 -1
  65. package/dist/copy-button/root/copy-button-root.js +12 -5
  66. package/dist/data-table/index.d.ts +1 -1
  67. package/dist/data-table/index.js +1 -1
  68. package/dist/data-table/keys.d.ts +24 -0
  69. package/dist/data-table/keys.js +24 -0
  70. package/dist/data-table/root/data-table-root.d.ts +170 -13
  71. package/dist/data-table/root/data-table-root.js +294 -52
  72. package/dist/data-table/tree.d.ts +55 -0
  73. package/dist/data-table/tree.js +54 -0
  74. package/dist/date-input/root/date-input-root.d.ts +3 -1
  75. package/dist/date-input/root/date-input-root.js +18 -7
  76. package/dist/date-picker/root/date-picker-root.js +12 -6
  77. package/dist/description-list/item/description-list-item.d.ts +17 -2
  78. package/dist/description-list/item/description-list-item.js +15 -2
  79. package/dist/description-list/root/description-list-root.d.ts +27 -1
  80. package/dist/description-list/root/description-list-root.js +26 -1
  81. package/dist/dialog/description.js +15 -1
  82. package/dist/dialog/root/dialog-root.d.ts +8 -2
  83. package/dist/dialog/root/dialog-root.js +16 -1
  84. package/dist/divider/root/divider-root.d.ts +3 -0
  85. package/dist/divider/root/divider-root.js +2 -1
  86. package/dist/donut-chart/root/donut-chart-root.d.ts +31 -0
  87. package/dist/donut-chart/root/donut-chart-root.js +48 -1
  88. package/dist/drawer/reveal.d.ts +8 -0
  89. package/dist/drawer/reveal.js +1 -0
  90. package/dist/drawer/root/drawer-root.d.ts +59 -0
  91. package/dist/drawer/root/drawer-root.js +63 -4
  92. package/dist/drilldown/item/drilldown-item.d.ts +11 -6
  93. package/dist/drilldown/item/drilldown-item.js +8 -5
  94. package/dist/drilldown/root/drilldown-root.d.ts +29 -0
  95. package/dist/drilldown/root/drilldown-root.js +28 -5
  96. package/dist/element-events.generated.js +83 -12
  97. package/dist/empty/root/empty-root.d.ts +3 -1
  98. package/dist/empty/root/empty-root.js +3 -2
  99. package/dist/file-input/root/file-input-root.d.ts +69 -6
  100. package/dist/file-input/root/file-input-root.js +82 -19
  101. package/dist/file-input/screen.d.ts +2 -1
  102. package/dist/filter-input/menu/filter-menu.d.ts +5 -0
  103. package/dist/filter-input/menu/filter-menu.js +16 -4
  104. package/dist/filter-input/root/filter-input-root.d.ts +30 -6
  105. package/dist/filter-input/root/filter-input-root.js +1 -1
  106. package/dist/filter-input/suggest.d.ts +28 -3
  107. package/dist/filter-input/suggest.js +18 -8
  108. package/dist/format-date/root/format-date-root.d.ts +9 -16
  109. package/dist/format-date/root/format-date-root.js +10 -27
  110. package/dist/heatmap/root/heatmap-root.d.ts +24 -13
  111. package/dist/heatmap/root/heatmap-root.js +34 -12
  112. package/dist/icon/root/icon-root.d.ts +12 -1
  113. package/dist/icon/root/icon-root.js +21 -10
  114. package/dist/icon/settle.d.ts +7 -0
  115. package/dist/icon/settle.js +10 -0
  116. package/dist/icon-button/root/icon-button-root.d.ts +2 -0
  117. package/dist/image/root/image-root.d.ts +5 -1
  118. package/dist/image/root/image-root.js +10 -2
  119. package/dist/input/root/input-root.d.ts +13 -3
  120. package/dist/input/root/input-root.js +12 -3
  121. package/dist/kbd/root/kbd-root.d.ts +35 -1
  122. package/dist/kbd/root/kbd-root.js +23 -4
  123. package/dist/legend/root/legend-root.d.ts +55 -8
  124. package/dist/legend/root/legend-root.js +55 -13
  125. package/dist/lightbox/root/lightbox-root.d.ts +49 -6
  126. package/dist/lightbox/root/lightbox-root.js +86 -19
  127. package/dist/lightbox/zoom-controller.d.ts +59 -0
  128. package/dist/lightbox/zoom-controller.js +128 -0
  129. package/dist/lightbox/zoom.d.ts +22 -0
  130. package/dist/lightbox/zoom.js +16 -0
  131. package/dist/line-chart/root/line-chart-root.d.ts +22 -1
  132. package/dist/line-chart/root/line-chart-root.js +21 -1
  133. package/dist/list/item/list-item.d.ts +70 -1
  134. package/dist/list/item/list-item.js +77 -6
  135. package/dist/list/numbering.d.ts +14 -0
  136. package/dist/list/numbering.js +8 -0
  137. package/dist/list/root/list-root.d.ts +155 -9
  138. package/dist/list/root/list-root.js +246 -4
  139. package/dist/list/selection.d.ts +49 -0
  140. package/dist/list/selection.js +30 -0
  141. package/dist/listbox/root/listbox-root.d.ts +37 -1
  142. package/dist/listbox/root/listbox-root.js +49 -4
  143. package/dist/loader/busy.d.ts +10 -0
  144. package/dist/loader/busy.js +11 -0
  145. package/dist/loader/root/loader-root.d.ts +9 -2
  146. package/dist/loader/root/loader-root.js +23 -3
  147. package/dist/map/root/map-root.d.ts +6 -2
  148. package/dist/map/root/map-root.js +5 -2
  149. package/dist/megamenu/root/megamenu-root.d.ts +62 -0
  150. package/dist/megamenu/root/megamenu-root.js +90 -5
  151. package/dist/menu/index.d.ts +1 -0
  152. package/dist/menu/index.js +1 -0
  153. package/dist/menu/item/menu-item.d.ts +87 -11
  154. package/dist/menu/item/menu-item.js +78 -22
  155. package/dist/menu/root/menu-root.d.ts +39 -1
  156. package/dist/menu/root/menu-root.js +65 -8
  157. package/dist/menu/section/menu-section.d.ts +55 -0
  158. package/dist/menu/section/menu-section.js +60 -0
  159. package/dist/meter/root/meter-root.d.ts +20 -1
  160. package/dist/meter/root/meter-root.js +11 -15
  161. package/dist/navigation/root/navigation-root.d.ts +18 -2
  162. package/dist/navigation/root/navigation-root.js +29 -3
  163. package/dist/notifications/root/notifications-root.d.ts +25 -0
  164. package/dist/notifications/root/notifications-root.js +33 -5
  165. package/dist/number-input/root/number-input-root.d.ts +17 -8
  166. package/dist/number-input/root/number-input-root.js +2 -7
  167. package/dist/object-inspector/root/object-inspector-root.d.ts +161 -32
  168. package/dist/object-inspector/root/object-inspector-root.js +264 -123
  169. package/dist/object-inspector/rows.d.ts +75 -0
  170. package/dist/object-inspector/rows.js +119 -0
  171. package/dist/option/root/option-root.d.ts +5 -3
  172. package/dist/outline/levels.d.ts +31 -0
  173. package/dist/outline/levels.js +23 -0
  174. package/dist/outline/root/outline-root.d.ts +86 -3
  175. package/dist/outline/root/outline-root.js +95 -12
  176. package/dist/pagination/size/pagination-size.d.ts +12 -2
  177. package/dist/pagination/size/pagination-size.js +20 -5
  178. package/dist/pin-input/code.d.ts +10 -0
  179. package/dist/pin-input/code.js +13 -0
  180. package/dist/pin-input/root/pin-input-root.d.ts +25 -1
  181. package/dist/pin-input/root/pin-input-root.js +10 -11
  182. package/dist/popover/hide-outside.d.ts +14 -0
  183. package/dist/popover/hide-outside.js +41 -0
  184. package/dist/popover/root/popover-root.d.ts +57 -7
  185. package/dist/popover/root/popover-root.js +58 -3
  186. package/dist/progress/root/progress-root.d.ts +20 -0
  187. package/dist/progress/root/progress-root.js +15 -15
  188. package/dist/qr-code/export.d.ts +26 -1
  189. package/dist/qr-code/export.js +14 -0
  190. package/dist/qr-code/root/qr-code-root.d.ts +19 -5
  191. package/dist/qr-code/root/qr-code-root.js +58 -9
  192. package/dist/quote/marks.d.ts +8 -0
  193. package/dist/quote/marks.js +5 -0
  194. package/dist/quote/root/quote-root.d.ts +14 -2
  195. package/dist/quote/root/quote-root.js +23 -1
  196. package/dist/radio/group/radio-group.d.ts +4 -10
  197. package/dist/radio/group/radio-group.js +5 -10
  198. package/dist/radio/root/radio-root.d.ts +6 -2
  199. package/dist/radio/root/radio-root.js +6 -1
  200. package/dist/rating/root/rating-root.d.ts +10 -5
  201. package/dist/rating/root/rating-root.js +32 -8
  202. package/dist/rating/steps.d.ts +7 -0
  203. package/dist/rating/steps.js +9 -0
  204. package/dist/scatter-chart/fit.d.ts +15 -0
  205. package/dist/scatter-chart/fit.js +35 -0
  206. package/dist/scatter-chart/root/scatter-chart-root.d.ts +21 -1
  207. package/dist/scatter-chart/root/scatter-chart-root.js +30 -17
  208. package/dist/scroll-area/root/scroll-area-root.d.ts +84 -0
  209. package/dist/scroll-area/root/scroll-area-root.js +106 -7
  210. package/dist/scroll-area/scrollbar-controller.d.ts +111 -0
  211. package/dist/scroll-area/scrollbar-controller.js +172 -0
  212. package/dist/scroll-area/scrollbar.d.ts +92 -0
  213. package/dist/scroll-area/scrollbar.js +33 -0
  214. package/dist/select/root/select-root.d.ts +15 -0
  215. package/dist/select/root/select-root.js +18 -6
  216. package/dist/skeleton/root/skeleton-root.d.ts +3 -0
  217. package/dist/skeleton/root/skeleton-root.js +4 -2
  218. package/dist/skip-link/root/skip-link-root.js +2 -2
  219. package/dist/slider/root/slider-root.d.ts +41 -4
  220. package/dist/slider/root/slider-root.js +23 -3
  221. package/dist/sparkline/readings.d.ts +18 -0
  222. package/dist/sparkline/readings.js +19 -0
  223. package/dist/sparkline/root/sparkline-root.d.ts +78 -7
  224. package/dist/sparkline/root/sparkline-root.js +118 -23
  225. package/dist/speed-dial/root/speed-dial-root.js +2 -2
  226. package/dist/splitter/root/splitter-root.d.ts +20 -12
  227. package/dist/splitter/root/splitter-root.js +226 -203
  228. package/dist/splitter/snap.d.ts +9 -0
  229. package/dist/splitter/snap.js +12 -0
  230. package/dist/stat/root/stat-root.d.ts +14 -5
  231. package/dist/stat/root/stat-root.js +21 -5
  232. package/dist/steps/reach.d.ts +20 -0
  233. package/dist/steps/reach.js +15 -0
  234. package/dist/steps/root/steps-root.d.ts +76 -0
  235. package/dist/steps/root/steps-root.js +93 -1
  236. package/dist/steps/step/step.d.ts +45 -2
  237. package/dist/steps/step/step.js +33 -6
  238. package/dist/switch/root/switch-root.d.ts +10 -0
  239. package/dist/table/column/table-column.d.ts +11 -10
  240. package/dist/table/column/table-column.js +8 -19
  241. package/dist/table/root/table-root.d.ts +126 -4
  242. package/dist/table/root/table-root.js +156 -6
  243. package/dist/table/row/table-row.d.ts +47 -1
  244. package/dist/table/row/table-row.js +39 -2
  245. package/dist/tabs/panel/tab-panel.d.ts +22 -5
  246. package/dist/tabs/panel/tab-panel.js +34 -6
  247. package/dist/tabs/root/tabs-root.d.ts +37 -1
  248. package/dist/tabs/root/tabs-root.js +22 -4
  249. package/dist/tabs/tab/tab.d.ts +41 -4
  250. package/dist/tabs/tab/tab.js +49 -3
  251. package/dist/tag/group/tag-group.d.ts +31 -4
  252. package/dist/tag/group/tag-group.js +46 -7
  253. package/dist/tag/root/tag-root.js +9 -2
  254. package/dist/textarea/root/textarea-root.d.ts +28 -1
  255. package/dist/textarea/root/textarea-root.js +40 -1
  256. package/dist/time-input/root/time-input-root.d.ts +5 -1
  257. package/dist/time-input/root/time-input-root.js +16 -8
  258. package/dist/time-picker/root/time-picker-root.d.ts +18 -4
  259. package/dist/time-picker/root/time-picker-root.js +7 -10
  260. package/dist/time-picker/wheel-name.d.ts +9 -0
  261. package/dist/time-picker/wheel-name.js +15 -0
  262. package/dist/timeline/group/timeline-group.d.ts +46 -0
  263. package/dist/timeline/group/timeline-group.js +37 -0
  264. package/dist/timeline/index.d.ts +1 -0
  265. package/dist/timeline/index.js +1 -0
  266. package/dist/timeline/root/timeline-root.d.ts +10 -3
  267. package/dist/toast/item/toast-item.d.ts +24 -18
  268. package/dist/toast/item/toast-item.js +36 -40
  269. package/dist/toast/root/toast-root.d.ts +6 -0
  270. package/dist/toast/root/toast-root.js +16 -1
  271. package/dist/toggle/group/toggle-group.d.ts +24 -3
  272. package/dist/toggle/group/toggle-group.js +34 -5
  273. package/dist/toolbar/root/toolbar-root.d.ts +13 -0
  274. package/dist/toolbar/root/toolbar-root.js +15 -5
  275. package/dist/tooltip/root/tooltip-root.d.ts +13 -2
  276. package/dist/tooltip/root/tooltip-root.js +9 -1
  277. package/dist/tour/back.d.ts +10 -0
  278. package/dist/tour/back.js +8 -0
  279. package/dist/tour/root/tour-root.d.ts +30 -2
  280. package/dist/tour/root/tour-root.js +34 -8
  281. package/dist/tree/item/tree-item.d.ts +61 -4
  282. package/dist/tree/item/tree-item.js +92 -20
  283. package/dist/tree/root/tree-root.d.ts +58 -0
  284. package/dist/tree/root/tree-root.js +80 -16
  285. package/dist/tree/selection.d.ts +24 -0
  286. package/dist/tree/selection.js +13 -0
  287. package/dist/trend/root/trend-root.d.ts +43 -18
  288. package/dist/trend/root/trend-root.js +31 -6
  289. package/dist/video/media-events.d.ts +44 -0
  290. package/dist/video/media-events.js +35 -0
  291. package/dist/video/root/video-root.d.ts +117 -18
  292. package/dist/video/root/video-root.js +93 -47
  293. package/dist/video-playlist/menu/video-playlist-menu.d.ts +5 -0
  294. package/dist/video-playlist/menu/video-playlist-menu.js +3 -1
  295. package/dist/video-playlist/order.d.ts +41 -0
  296. package/dist/video-playlist/order.js +34 -0
  297. package/dist/video-playlist/root/video-playlist-root.d.ts +77 -3
  298. package/dist/video-playlist/root/video-playlist-root.js +60 -16
  299. package/dist/virtual-list/controls.d.ts +4 -0
  300. package/dist/virtual-list/controls.js +30 -0
  301. package/dist/virtual-list/fill.d.ts +22 -0
  302. package/dist/virtual-list/fill.js +23 -0
  303. package/dist/virtual-list/keys.d.ts +15 -0
  304. package/dist/virtual-list/keys.js +24 -0
  305. package/dist/virtual-list/plan.d.ts +49 -0
  306. package/dist/virtual-list/plan.js +16 -0
  307. package/dist/virtual-list/root/virtual-list-root.d.ts +259 -26
  308. package/dist/virtual-list/root/virtual-list-root.js +333 -49
  309. package/lint.json +1 -1
  310. package/package.json +8 -8
  311. package/types/jsx.d.ts +8113 -1394
  312. package/types/svelte.d.ts +2 -0
  313. package/types/vue.d.ts +1678 -353
  314. package/dist/data-table/root/order.d.ts +0 -141
  315. package/dist/data-table/root/order.js +0 -76
  316. package/dist/listbox/range.d.ts +0 -17
  317. package/dist/listbox/range.js +0 -5
  318. package/dist/tag/selection.d.ts +0 -10
  319. package/dist/tag/selection.js +0 -12
@@ -1,5 +1,5 @@
1
1
  import { HelixElement } from '@fusion.dev/helix-core';
2
- import { type PropertyValues, type TemplateResult } from 'lit';
2
+ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
3
3
  declare const HelixHeadlessAccordionItem_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerOpenInterface) & typeof HelixElement;
4
4
  /**
5
5
  * @summary One collapsible section of an accordion.
@@ -18,12 +18,22 @@ declare const HelixHeadlessAccordionItem_base: (new (...args: any[]) => import("
18
18
  * out of the tab order and the accessibility tree after the styled tier's
19
19
  * `display` overrides `hidden`.
20
20
  *
21
+ * While it is open, the content part carries the content's height as
22
+ * `--accordion-content-height`, as Radix's accordion does, for a stylesheet
23
+ * that animates the section open with keyframes of its own.
24
+ *
25
+ * Set `hidden-until-found` and the browser's find in page searches a closed
26
+ * section too: a match opens it, with `helix-before-open` first, as React
27
+ * Aria's disclosure does. The content is then `hidden="until-found"` while
28
+ * closed, and not `inert`, since an inert region is never searched.
29
+ *
21
30
  * @since 0.1.0
22
31
  * @status stable
23
32
  * @aliases Collapsible, Expander, Disclosure
24
33
  * @documentation https://fusion.dev/helix/components/accordion
25
34
  *
26
35
  * @slot - The content shown when the section is open.
36
+ * @slot chevron - Replaces the open and close indicator, such as with your own icon.
27
37
  * @slot summary - The text of the button that opens and closes the section. Always shown.
28
38
  *
29
39
  * @event {HelixBeforeCloseEvent} helix-before-close - The section is about to close. Cancelable: cancel it to keep it open.
@@ -37,6 +47,8 @@ declare const HelixHeadlessAccordionItem_base: (new (...args: any[]) => import("
37
47
  * @csspart heading - The heading that holds the trigger.
38
48
  * @csspart trigger - The button that opens and closes the section, holding the summary.
39
49
  *
50
+ * @cssproperty --accordion-content-height - The height of the content, in pixels, written on the `content` part while the section is open.
51
+ *
40
52
  * @cssstate open - While the item is open.
41
53
  */
42
54
  export declare class HelixHeadlessAccordionItem extends HelixHeadlessAccordionItem_base {
@@ -51,8 +63,13 @@ export declare class HelixHeadlessAccordionItem extends HelixHeadlessAccordionIt
51
63
  * have two.
52
64
  */
53
65
  chevronPlacement?: 'auto' | 'start' | 'end' | 'none';
54
- /** The chevron, or nothing when suppressed. */
55
- private renderChevron;
66
+ /**
67
+ * The chevron, or nothing when suppressed.
68
+ *
69
+ * The drawn chevron is the `chevron` slot's fallback, so an icon of your own
70
+ * replaces it by being slotted, and a tier drawing its own overrides this.
71
+ */
72
+ protected renderChevron(): TemplateResult | typeof nothing;
56
73
  /**
57
74
  * Whether the section is disabled, so its trigger cannot be pressed or
58
75
  * reached with the arrow keys. A script can still open and close it.
@@ -64,6 +81,11 @@ export declare class HelixHeadlessAccordionItem extends HelixHeadlessAccordionIt
64
81
  * causes a hydration mismatch.
65
82
  */
66
83
  groupHeadingLevel: number | undefined;
84
+ /**
85
+ * @internal The accordion's `hidden-until-found`, written by the accordion,
86
+ * for the reason `groupHeadingLevel` is a property.
87
+ */
88
+ groupHiddenUntilFound: boolean;
67
89
  /**
68
90
  * The level of the heading around the trigger, from 1 to 6.
69
91
  *
@@ -71,6 +93,16 @@ export declare class HelixHeadlessAccordionItem extends HelixHeadlessAccordionIt
71
93
  * too.
72
94
  */
73
95
  headingLevel?: number;
96
+ /**
97
+ * Whether find in page searches the section while it is closed, and opens it
98
+ * on a match.
99
+ *
100
+ * Off by default. A closed section is then `hidden="until-found"`, which
101
+ * hides through `content-visibility`, so a stylesheet that animates the
102
+ * section closed shows an empty box for the length of that animation. The
103
+ * accordion's own `hidden-until-found` turns it on for every section.
104
+ */
105
+ hiddenUntilFound: boolean;
74
106
  /**
75
107
  * A group name. Opening an item closes the other items with the same name,
76
108
  * as `<details name>` does.
@@ -92,6 +124,15 @@ export declare class HelixHeadlessAccordionItem extends HelixHeadlessAccordionIt
92
124
  * absence. Caught by `hydration.dom.spec.ts`.
93
125
  */
94
126
  name?: string;
127
+ /** Whether find in page searches this section while it is closed. */
128
+ private get findable();
129
+ /**
130
+ * Opens the section find in page has matched in, before the match is shown.
131
+ *
132
+ * The browser removes `hidden` itself. A refusal puts it back, so the trigger
133
+ * and the region still agree.
134
+ */
135
+ private readonly handleBeforeMatch;
95
136
  /** Whether the item was open at the last update, and `undefined` before one. */
96
137
  private wasOpen;
97
138
  /**
@@ -131,6 +172,12 @@ export declare class HelixHeadlessAccordionItem extends HelixHeadlessAccordionIt
131
172
  * settle, once every item is there to compare.
132
173
  */
133
174
  protected updated(changed: PropertyValues): void;
175
+ /**
176
+ * Writes the content's height onto the content part while the section is
177
+ * open. `scrollHeight`, so a sheet that clips the box while it grows still
178
+ * reads the whole height.
179
+ */
180
+ private readonly measure;
134
181
  /**
135
182
  * Moves focus to this item's trigger.
136
183
  *
@@ -157,16 +204,19 @@ export declare class HelixHeadlessAccordionItem extends HelixHeadlessAccordionIt
157
204
  * part outranks it and the transition runs exactly as before. Measured on
158
205
  * both tiers.
159
206
  *
160
- * **Not `hidden="until-found"`**, which would be the better accordion and is
161
- * a different piece of work. It hides through `content-visibility` rather
162
- * than `display`, which an author `display` does not override, so a collapsed
163
- * section a sheet animates would open to nothing. It also needs a
164
- * `beforematch` handler to set `open`, or find-in-page reveals text while the
165
- * trigger still reports collapsed.
207
+ * **`hidden="until-found"` only where it was asked for.** It hides through
208
+ * `content-visibility` rather than `display`, which an author `display` does
209
+ * not override, so a section a sheet animates closed shows an empty box while
210
+ * it shrinks. `beforematch` sets `open`, so find in page never reveals text
211
+ * under a trigger that still reports collapsed.
166
212
  *
167
- * `inert` stays. `hidden` answers the reader who can see and `inert` answers
168
- * the one tabbing through, and wherever a sheet overrides `display`, `inert`
169
- * is the only one of the two still in force.
213
+ * `inert` stays, except under `until-found`. `hidden` answers the reader who
214
+ * can see and `inert` answers the one tabbing through, and wherever a sheet
215
+ * overrides `display`, `inert` is the only one of the two still in force.
216
+ * `content-visibility: hidden` keeps skipped content out of the tab order and
217
+ * the accessibility tree by itself, and an inert region is never searched.
218
+ * It leaves the region's own box in the tree, so a closed findable section
219
+ * drops `role="region"` and its name until it opens.
170
220
  */
171
221
  protected render(): TemplateResult;
172
222
  }
@@ -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 { closestInstance, customElement, HelixElement, MixinControllerOpen, } from '@fusion.dev/helix-core';
7
+ import { closestInstance, customElement, HelixElement, headingLevel, MixinControllerOpen, } from '@fusion.dev/helix-core';
8
8
  import { caretDown } from '@fusion.dev/helix-icons';
9
9
  import { html, nothing } from 'lit';
10
10
  import { property } from 'lit/decorators.js';
@@ -17,6 +17,15 @@ let HelixHeadlessAccordionItem = class HelixHeadlessAccordionItem extends MixinC
17
17
  super(...arguments);
18
18
  this.disabled = false;
19
19
  this.groupHeadingLevel = undefined;
20
+ this.groupHiddenUntilFound = false;
21
+ this.hiddenUntilFound = false;
22
+ this.handleBeforeMatch = (event) => {
23
+ if (this.open || this.requestOpen(true)) {
24
+ return;
25
+ }
26
+ ;
27
+ event.currentTarget.setAttribute('hidden', 'until-found');
28
+ };
20
29
  this.wasOpen = undefined;
21
30
  this.handleToggle = () => {
22
31
  if (this.disabled) {
@@ -34,14 +43,27 @@ let HelixHeadlessAccordionItem = class HelixHeadlessAccordionItem extends MixinC
34
43
  this.closePeers();
35
44
  }
36
45
  };
46
+ this.measure = () => {
47
+ const content = this.partNamed('content');
48
+ const inner = this.partNamed('content-inner');
49
+ if (!content || !inner || !this.open) {
50
+ return;
51
+ }
52
+ content.style.setProperty('--accordion-content-height', `${inner.scrollHeight}px`);
53
+ };
37
54
  }
38
55
  renderChevron() {
39
56
  if (this.chevronPlacement === 'none') {
40
57
  return nothing;
41
58
  }
42
- return html `<svg part="chevron" fill="currentColor" viewBox=${caretDown.viewBox} aria-hidden="true">
43
- ${unsafeSVG(caretDown.content)}
44
- </svg>`;
59
+ return html `<slot name="chevron" aria-hidden="true"
60
+ ><svg part="chevron" fill="currentColor" viewBox=${caretDown.viewBox} aria-hidden="true">
61
+ ${unsafeSVG(caretDown.content)}
62
+ </svg></slot
63
+ >`;
64
+ }
65
+ get findable() {
66
+ return this.hiddenUntilFound || this.groupHiddenUntilFound;
45
67
  }
46
68
  get accordion() {
47
69
  return closestInstance(this, HelixHeadlessAccordion);
@@ -75,13 +97,15 @@ let HelixHeadlessAccordionItem = class HelixHeadlessAccordionItem extends MixinC
75
97
  this.closePeers();
76
98
  }
77
99
  this.wasOpen = this.open;
100
+ this.measure();
78
101
  }
79
102
  focusTrigger() {
80
103
  this.renderRoot.querySelector(`#${TRIGGER_ID}`)?.focus();
81
104
  }
82
105
  render() {
83
106
  const open = this.open;
84
- const level = Math.min(6, Math.max(1, this.headingLevel ?? this.groupHeadingLevel ?? 3));
107
+ const landmark = open || !this.findable;
108
+ const level = headingLevel(this.headingLevel ?? this.groupHeadingLevel);
85
109
  return html `
86
110
  <div part="container">
87
111
  <div part="heading" role="heading" aria-level=${level}>
@@ -101,14 +125,15 @@ let HelixHeadlessAccordionItem = class HelixHeadlessAccordionItem extends MixinC
101
125
  </div>
102
126
  <div
103
127
  id=${CONTENT_ID}
104
- aria-labelledby=${TRIGGER_ID}
128
+ aria-labelledby=${landmark ? TRIGGER_ID : nothing}
105
129
  part="content"
106
- ?hidden=${!open}
107
- ?inert=${!open}
108
- role="region"
130
+ hidden=${open ? nothing : this.findable ? 'until-found' : ''}
131
+ ?inert=${!open && !this.findable}
132
+ role=${landmark ? 'region' : nothing}
133
+ @beforematch=${this.handleBeforeMatch}
109
134
  >
110
135
  <div part="content-inner">
111
- <slot></slot>
136
+ <slot @slotchange=${this.measure}></slot>
112
137
  </div>
113
138
  </div>
114
139
  </div>
@@ -124,9 +149,15 @@ __decorate([
124
149
  __decorate([
125
150
  property({ attribute: false })
126
151
  ], HelixHeadlessAccordionItem.prototype, "groupHeadingLevel", void 0);
152
+ __decorate([
153
+ property({ attribute: false })
154
+ ], HelixHeadlessAccordionItem.prototype, "groupHiddenUntilFound", void 0);
127
155
  __decorate([
128
156
  property({ attribute: 'heading-level', type: Number })
129
157
  ], HelixHeadlessAccordionItem.prototype, "headingLevel", void 0);
158
+ __decorate([
159
+ property({ attribute: 'hidden-until-found', type: Boolean })
160
+ ], HelixHeadlessAccordionItem.prototype, "hiddenUntilFound", void 0);
130
161
  __decorate([
131
162
  property({ reflect: true })
132
163
  ], HelixHeadlessAccordionItem.prototype, "name", void 0);
@@ -17,12 +17,15 @@ import { HelixHeadlessAccordionItem } from '../item/accordion-item.js';
17
17
  * matched with `instanceof HelixHeadlessAccordionItem`, so the headless tier
18
18
  * does not depend on the styled tier's tag names.
19
19
  *
20
- * The keyboard listener belongs to the controller and is attached on connect,
21
- * so it does not run on the server.
20
+ * Keys, on a trigger: Up and Down Arrow move to the previous and the next
21
+ * trigger, and so do Left and Right, wrapping at the ends; Home and End go to
22
+ * the first and the last. Enter and Space open and close the section. Disabled
23
+ * sections are passed over.
22
24
  *
23
- * Each trigger sits inside a heading, level 3 unless `heading-level` says
24
- * otherwise, so the sections are in a screen reader's list of headings. Set the
25
- * level that fits the page's outline.
25
+ * Each trigger is a button with `aria-expanded` and `aria-controls`, inside a
26
+ * heading, level 3 unless `heading-level` says otherwise, so the sections are
27
+ * in a screen reader's list of headings. An open section is a region named by
28
+ * its trigger. Set the level that fits the page's outline.
26
29
  *
27
30
  * @since 0.1.0
28
31
  * @status stable
@@ -39,6 +42,12 @@ export declare class HelixHeadlessAccordion extends HelixElement {
39
42
  * Unset is 3. An item's own `heading-level` wins over this.
40
43
  */
41
44
  headingLevel?: number;
45
+ /**
46
+ * Whether find in page searches every closed section, and opens the one it
47
+ * matches in. Each item's own `hidden-until-found` turns it on for that item
48
+ * alone.
49
+ */
50
+ hiddenUntilFound: boolean;
42
51
  /**
43
52
  * How many sections may be open at once.
44
53
  *
@@ -18,6 +18,7 @@ const navigable = (item) => ({
18
18
  let HelixHeadlessAccordion = class HelixHeadlessAccordion extends HelixElement {
19
19
  constructor() {
20
20
  super(...arguments);
21
+ this.hiddenUntilFound = false;
21
22
  this.keys = new KeyboardNavigationController(this, {
22
23
  items: () => this.items.map(navigable),
23
24
  origin: 'focus',
@@ -32,6 +33,7 @@ let HelixHeadlessAccordion = class HelixHeadlessAccordion extends HelixElement {
32
33
  for (const item of items) {
33
34
  whenHydrated(item, () => {
34
35
  item.groupHeadingLevel = this.headingLevel;
36
+ item.groupHiddenUntilFound = this.hiddenUntilFound;
35
37
  });
36
38
  }
37
39
  if (this.mode === undefined) {
@@ -56,7 +58,8 @@ let HelixHeadlessAccordion = class HelixHeadlessAccordion extends HelixElement {
56
58
  }
57
59
  updated(changed) {
58
60
  super.updated(changed);
59
- if (this.hasUpdated && (changed.has('mode') || changed.has('headingLevel'))) {
61
+ if (this.hasUpdated &&
62
+ (changed.has('mode') || changed.has('headingLevel') || changed.has('hiddenUntilFound'))) {
60
63
  this.settle();
61
64
  }
62
65
  }
@@ -67,6 +70,9 @@ let HelixHeadlessAccordion = class HelixHeadlessAccordion extends HelixElement {
67
70
  __decorate([
68
71
  property({ attribute: 'heading-level', type: Number })
69
72
  ], HelixHeadlessAccordion.prototype, "headingLevel", void 0);
73
+ __decorate([
74
+ property({ attribute: 'hidden-until-found', type: Boolean })
75
+ ], HelixHeadlessAccordion.prototype, "hiddenUntilFound", void 0);
70
76
  __decorate([
71
77
  property({ reflect: true })
72
78
  ], HelixHeadlessAccordion.prototype, "mode", void 0);
@@ -16,8 +16,9 @@ declare const HelixHeadlessAnnouncement_base: (new (...args: any[]) => import("@
16
16
  *
17
17
  * The live region is its own part. When the announcement appears after the page
18
18
  * has loaded, the message is written into the region one frame later, so screen
19
- * readers read it reliably, and the region is emptied seven seconds later, so
20
- * the message is not in the page twice. When the announcement is in the served
19
+ * readers read it reliably, and the region is emptied seven seconds later.
20
+ * While the region holds the copy, the message itself is hidden from screen
21
+ * readers, so it is in the page once. When the announcement is in the served
21
22
  * HTML, the region stays empty and nothing is read out.
22
23
  *
23
24
  * The dismiss button fires `helix-dismiss`, and the announcement stays in the
@@ -28,6 +29,11 @@ declare const HelixHeadlessAnnouncement_base: (new (...args: any[]) => import("@
28
29
  * announcement beside it, move focus yourself, for example to the page's main
29
30
  * heading.
30
31
  *
32
+ * Set `duration` to dismiss it after a time. The clock stops while the pointer
33
+ * or focus is on the announcement, and continues from what was left, so a
34
+ * reader partway through is not cut off. When the time runs out it sends
35
+ * `helix-dismiss`, as the button does.
36
+ *
31
37
  * @since 0.1.0
32
38
  * @status stable
33
39
  * @category feedback
@@ -38,7 +44,7 @@ declare const HelixHeadlessAnnouncement_base: (new (...args: any[]) => import("@
38
44
  * @slot actions - Actions for the message, usually a link or a button.
39
45
  * @slot icon - Replaces the icon inside the dismiss button.
40
46
  *
41
- * @event {HelixDismissEvent} helix-dismiss - The dismiss button was pressed. The announcement does not remove itself, so remove it in response. Cancelable.
47
+ * @event {HelixDismissEvent} helix-dismiss - The dismiss button was pressed, or `duration` ran out. The announcement does not remove itself, so remove it in response. Cancelable.
42
48
  *
43
49
  * @csspart actions - The region after the message that holds the actions.
44
50
  * @csspart content - The region that holds the message.
@@ -47,6 +53,14 @@ declare const HelixHeadlessAnnouncement_base: (new (...args: any[]) => import("@
47
53
  * @csspart live - A copy of the message in a live region, read by screen readers when the announcement appears after the page has loaded, and emptied seven seconds later. Visually hidden in the styled tier.
48
54
  */
49
55
  export declare class HelixHeadlessAnnouncement extends HelixHeadlessAnnouncement_base {
56
+ /**
57
+ * How long the announcement stays, in milliseconds, before it sends
58
+ * `helix-dismiss`. When it is not set, it stays until it is dismissed.
59
+ *
60
+ * Read once when the announcement is first rendered, as `Toast` reads its
61
+ * own. The clock stops while the pointer or focus is on the announcement.
62
+ */
63
+ duration?: number;
50
64
  /**
51
65
  * The band's color.
52
66
  *
@@ -71,6 +85,13 @@ export declare class HelixHeadlessAnnouncement extends HelixHeadlessAnnouncement
71
85
  */
72
86
  tone?: 'accent' | 'danger' | 'info' | 'neutral' | 'primary' | 'success' | 'warning';
73
87
  protected readonly arrival: ArrivalController;
88
+ /** The time `duration` gives it, held while a reader is on it. */
89
+ private readonly countdown;
90
+ private readonly handleHold;
91
+ private readonly handleRelease;
92
+ connectedCallback(): void;
93
+ disconnectedCallback(): void;
94
+ protected firstUpdated(changed: PropertyValues): void;
74
95
  protected updated(changed: PropertyValues): void;
75
96
  /**
76
97
  * Says on the `actions` region whether anything is in it.
@@ -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 { ArrivalController, customElement, HelixElement, MixinDismissible, markRegion, slottedWords, } from '@fusion.dev/helix-core';
7
+ import { ArrivalController, CountdownController, customElement, HelixElement, MixinDismissible, markRegion, slottedWords, } from '@fusion.dev/helix-core';
8
8
  import { x } from '@fusion.dev/helix-icons';
9
9
  import { html, nothing } from 'lit';
10
10
  import { property } from 'lit/decorators.js';
@@ -16,6 +16,38 @@ let HelixHeadlessAnnouncement = class HelixHeadlessAnnouncement extends MixinDis
16
16
  arriving: () => !this.serverRendered && document.readyState === 'complete',
17
17
  text: () => slottedWords(this, ['']),
18
18
  });
19
+ this.countdown = new CountdownController(this, {
20
+ done: () => {
21
+ this.dismiss();
22
+ },
23
+ });
24
+ this.handleHold = () => {
25
+ this.countdown.hold();
26
+ };
27
+ this.handleRelease = () => {
28
+ this.countdown.release();
29
+ };
30
+ }
31
+ connectedCallback() {
32
+ super.connectedCallback();
33
+ this.addEventListener('mouseenter', this.handleHold);
34
+ this.addEventListener('mouseleave', this.handleRelease);
35
+ this.addEventListener('focusin', this.handleHold);
36
+ this.addEventListener('focusout', this.handleRelease);
37
+ if (this.hasUpdated) {
38
+ this.countdown.resume();
39
+ }
40
+ }
41
+ disconnectedCallback() {
42
+ super.disconnectedCallback();
43
+ this.removeEventListener('mouseenter', this.handleHold);
44
+ this.removeEventListener('mouseleave', this.handleRelease);
45
+ this.removeEventListener('focusin', this.handleHold);
46
+ this.removeEventListener('focusout', this.handleRelease);
47
+ }
48
+ firstUpdated(changed) {
49
+ super.firstUpdated(changed);
50
+ this.countdown.start(this.duration);
19
51
  }
20
52
  updated(changed) {
21
53
  super.updated(changed);
@@ -32,7 +64,9 @@ let HelixHeadlessAnnouncement = class HelixHeadlessAnnouncement extends MixinDis
32
64
  </slot>`;
33
65
  }
34
66
  render() {
35
- return html `<div part="content"><slot @slotchange=${() => this.arrival.say()}></slot></div>
67
+ return html `<div aria-hidden=${this.arrival.said === '' ? nothing : 'true'} part="content"
68
+ ><slot @slotchange=${() => this.arrival.say()}></slot
69
+ ></div>
36
70
  <span part="live" role="status">${this.arrival.said}</span>
37
71
  <div part="actions"><slot name="actions" @slotchange=${() => this.markEmpty()}></slot></div>
38
72
  ${this.dismissible
@@ -47,6 +81,9 @@ let HelixHeadlessAnnouncement = class HelixHeadlessAnnouncement extends MixinDis
47
81
  : nothing}`;
48
82
  }
49
83
  };
84
+ __decorate([
85
+ property({ type: Number })
86
+ ], HelixHeadlessAnnouncement.prototype, "duration", void 0);
50
87
  __decorate([
51
88
  property({ reflect: true })
52
89
  ], HelixHeadlessAnnouncement.prototype, "tone", void 0);
@@ -19,6 +19,15 @@ import { type PropertyValues, type TemplateResult } from 'lit';
19
19
  * The page is the window unless `scroller` names the element that scrolls, for
20
20
  * an app shell whose content scrolls inside a container.
21
21
  *
22
+ * The host is the page's `banner` landmark. Placed inside `main`, `article`,
23
+ * `aside`, `nav` or `section`, it is a plain box instead, as a native
24
+ * `<header>` is there, so a header inside a card or a pane does not add a
25
+ * second banner. The ancestors are read as the accessibility tree reads them,
26
+ * through the slots that take the header in, so one slotted into a component
27
+ * that draws a `<nav>`, such as `Navigation`, is not a banner either. A server
28
+ * cannot see the ancestors, so it serves the banner and the browser corrects
29
+ * it when the element connects.
30
+ *
22
31
  * @since 0.1.0
23
32
  * @status stable
24
33
  * @category navigation
@@ -64,6 +73,7 @@ export declare class HelixHeadlessAppHeader extends HelixElement {
64
73
  * scrolls a container instead of the window. Unset is the window.
65
74
  */
66
75
  scroller?: string;
76
+ private landmark;
67
77
  private scrolled;
68
78
  /** What scroll is listened to now, so a change of `scroller` moves it. */
69
79
  private source;
@@ -98,6 +108,8 @@ export declare class HelixHeadlessAppHeader extends HelixElement {
98
108
  private readonly handleScroll;
99
109
  protected willUpdate(changed: PropertyValues): void;
100
110
  connectedCallback(): void;
111
+ /** Whether this header is the page's banner, read from where it sits. */
112
+ private readLandmark;
101
113
  disconnectedCallback(): void;
102
114
  protected updated(changed: PropertyValues): void;
103
115
  protected render(): TemplateResult;
@@ -7,9 +7,11 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  import { customElement, elementById, HelixElement, HelixScrolledEvent, hostAria, } from '@fusion.dev/helix-core';
8
8
  import { html } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
+ import { inSectioningContent } from '../sectioning.js';
10
11
  let HelixHeadlessAppHeader = class HelixHeadlessAppHeader extends HelixElement {
11
12
  constructor() {
12
13
  super(...arguments);
14
+ this.landmark = 'banner';
13
15
  this.scrolled = false;
14
16
  this.handleScroll = () => {
15
17
  const source = this.source ?? window;
@@ -41,12 +43,22 @@ let HelixHeadlessAppHeader = class HelixHeadlessAppHeader extends HelixElement {
41
43
  }
42
44
  willUpdate(changed) {
43
45
  super.willUpdate(changed);
44
- hostAria(this.internals, { role: 'banner' });
46
+ hostAria(this.internals, { role: this.landmark });
45
47
  }
46
48
  connectedCallback() {
47
49
  super.connectedCallback();
50
+ this.readLandmark();
51
+ setTimeout(() => {
52
+ if (this.isConnected) {
53
+ this.readLandmark();
54
+ }
55
+ });
48
56
  this.listen();
49
57
  }
58
+ readLandmark() {
59
+ this.landmark = inSectioningContent(this) ? '' : 'banner';
60
+ hostAria(this.internals, { role: this.landmark });
61
+ }
50
62
  disconnectedCallback() {
51
63
  super.disconnectedCallback();
52
64
  this.source?.removeEventListener('scroll', this.handleScroll);
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Whether an element sits inside sectioning content, read across shadow
3
+ * boundaries as the accessibility tree reads it: through the slot an element
4
+ * is assigned to, so a header slotted into a component that draws a `<nav>`
5
+ * around its slot, as `Navigation` does, is inside that `<nav>`.
6
+ *
7
+ * Client only: a server has no ancestors to read.
8
+ */
9
+ export declare const inSectioningContent: (element: Element) => boolean;
@@ -0,0 +1,27 @@
1
+ const SECTIONING = [
2
+ 'article',
3
+ 'aside',
4
+ 'main',
5
+ 'nav',
6
+ 'section',
7
+ '[role="article"]',
8
+ '[role="complementary"]',
9
+ '[role="main"]',
10
+ '[role="navigation"]',
11
+ '[role="region"]',
12
+ ].join(', ');
13
+ export const inSectioningContent = (element) => {
14
+ let node = above(element);
15
+ while (node) {
16
+ if (node.matches(SECTIONING)) {
17
+ return true;
18
+ }
19
+ node = above(node);
20
+ }
21
+ return false;
22
+ };
23
+ const above = (element) => element.assignedSlot ?? element.parentElement ?? hostOf(element);
24
+ const hostOf = (element) => {
25
+ const root = element.getRootNode();
26
+ return root instanceof ShadowRoot ? root.host : null;
27
+ };
@@ -1,13 +1,13 @@
1
1
  import { HelixElement } from '@fusion.dev/helix-core';
2
2
  import { type PropertyValues, type TemplateResult } from 'lit';
3
3
  /**
4
- * The largest `max` a stylesheet can hide past.
4
+ * The largest `max` a stylesheet folds a server's markup at.
5
5
  *
6
- * The fold is `:host([max="N"]) ::slotted(:nth-child(n + N+1))`, one selector
6
+ * The rule is `:host([max="N"]) ::slotted(:nth-child(n + N+1))`, one selector
7
7
  * per value, because `An+B` takes a literal and no custom property can be read
8
- * into it. So the range is finite, and it is written down beside the count that
9
- * has to agree with it: a count that folds and a stylesheet that does not would
10
- * put a "+5" beside five avatars that are still on screen.
8
+ * into it. So the range a stylesheet covers is finite. The group folds any
9
+ * `max` itself once it runs, with the platform's `hidden`; past this one, a
10
+ * server's markup shows every avatar until the page hydrates.
11
11
  */
12
12
  export declare const FOLDS_UP_TO = 12;
13
13
  /**
@@ -21,9 +21,10 @@ export declare const FOLDS_UP_TO = 12;
21
21
  * hidden.
22
22
  *
23
23
  * Avatars past `max` stay in the DOM and are hidden. The group writes `hidden`
24
- * on each of them, so they are hidden on the headless tier as well, and the
25
- * count is read out as `overflow-label`, such as "3 more", so a screen reader
26
- * hears that there are more people than the ones it can reach.
24
+ * on each of them, so they are hidden on the headless tier as well, and at any
25
+ * `max`. The count is read out as `overflow-label`, such as "3 more: Grace
26
+ * Hopper, Alan Turing, Barbara Liskov", so a screen reader hears who is there
27
+ * past the ones it can reach.
27
28
  *
28
29
  * @since 0.1.0
29
30
  * @status stable
@@ -59,10 +60,11 @@ export declare class HelixHeadlessAvatarGroup extends HelixElement {
59
60
  */
60
61
  max?: number;
61
62
  /**
62
- * What a screen reader is told the count is, with `{count}` for the number.
63
+ * What a screen reader is told the count is, with `{count}` for the number
64
+ * and `{names}` for the people it stands for, by each avatar's `name`.
63
65
  *
64
66
  * The count shows "+3", which reads as "plus three" and says nothing about
65
- * what was counted.
67
+ * what was counted, nor who.
66
68
  */
67
69
  overflowLabel: string;
68
70
  /** The avatars this group hid, so it unhides only those. */
@@ -78,8 +80,6 @@ export declare class HelixHeadlessAvatarGroup extends HelixElement {
78
80
  * the attribute that hides the whole group.
79
81
  */
80
82
  get overflow(): number;
81
- /** Said once per element, because a re-render is not a second mistake. */
82
- private warned;
83
83
  protected willUpdate(changed: PropertyValues): void;
84
84
  protected firstUpdated(changed: PropertyValues): void;
85
85
  protected updated(changed: PropertyValues): void;
@@ -89,10 +89,16 @@ export declare class HelixHeadlessAvatarGroup extends HelixElement {
89
89
  * **State in markup, so the headless tier folds too.** The fold was a styled
90
90
  * rule alone, and on the headless tier every avatar was drawn beside a "+3".
91
91
  * The styled rule stays, because it is what folds a server's markup before
92
- * this runs. Written through `whenHydrated`, so an avatar's hydrating render
93
- * is the server's, and undone only on the avatars this group hid.
92
+ * this runs, up to `FOLDS_UP_TO`, and this folds at any `max`. Written
93
+ * through `whenHydrated`, so an avatar's hydrating render is the server's,
94
+ * and undone only on the avatars this group hid.
94
95
  */
95
96
  private fold;
97
+ /**
98
+ * The names of the people past `max`, by each avatar's `name`, then its
99
+ * `aria-label`, in the order they are read.
100
+ */
101
+ private foldedNames;
96
102
  protected render(): TemplateResult;
97
103
  }
98
104
  declare global {