@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
@@ -28,6 +28,23 @@ declare const HelixHeadlessToggleGroup_base: (new (...args: any[]) => import("@f
28
28
  * `orientation="vertical"` runs the items down a column, says so to the
29
29
  * accessibility tree, and the up and down arrows move between them.
30
30
  *
31
+ * **Keyboard.** The group is one tab stop: the chosen item, or the first that
32
+ * can be chosen, as in a radio group, and in a multiple group the item focus
33
+ * was last on.
34
+ *
35
+ * | Key | What it does |
36
+ * |---|---|
37
+ * | Right, Down | Moves to the next item, from the last back to the first. In a single group, chooses it. |
38
+ * | Left, Up | Moves to the item before, from the first round to the last. In a single group, chooses it. |
39
+ * | Home, End | Moves to the first or the last item. In a single group, chooses it. |
40
+ * | Space, Enter | Chooses the focused item, or presses or releases it in a multiple group. |
41
+ *
42
+ * Left and Right swap on a right-to-left page, and a disabled item is passed
43
+ * over. A single group is a `radiogroup` of items with `role="radio"` and
44
+ * `aria-checked`. A multiple group is a `toolbar` of buttons with
45
+ * `aria-pressed`, or a `group` inside a toolbar. The group is named by
46
+ * `label` and carries `aria-orientation` under `orientation`.
47
+ *
31
48
  * @since 0.1.0
32
49
  * @status stable
33
50
  * @aliases SegmentedControl, Segmented, Navigation, Switcher
@@ -115,6 +132,11 @@ export declare class HelixHeadlessToggleGroup extends HelixHeadlessToggleGroup_b
115
132
  /** The item focus was last on, in a toolbar, which holds its tab stop. */
116
133
  private lastFocused;
117
134
  private readonly noteFocus;
135
+ /**
136
+ * The item whose value is the group's, in a single group: the exact match,
137
+ * so nothing chosen marks nothing. A multiple group has none.
138
+ */
139
+ private get chosenItem();
118
140
  /** Whether several items can be pressed at once. */
119
141
  private get multiple();
120
142
  /**
@@ -192,11 +214,6 @@ export declare class HelixHeadlessToggleGroup extends HelixHeadlessToggleGroup_b
192
214
  */
193
215
  private get groupRole();
194
216
  protected willUpdate(changed: PropertyValues): void;
195
- /**
196
- * What the form receives: the value, or under `selection-mode="multiple"`
197
- * one entry per pressed value, as a native `<select multiple>` sends.
198
- */
199
- private formValue;
200
217
  /**
201
218
  * The verdict on the answer `required` asks for.
202
219
  *
@@ -238,6 +255,13 @@ export declare class HelixHeadlessToggleGroup extends HelixHeadlessToggleGroup_b
238
255
  * in it.
239
256
  */
240
257
  protected render(): TemplateResult;
258
+ /**
259
+ * Items that arrive after the first render, which is every item on a page
260
+ * the parser is still reading. Outside an update here, so taking the
261
+ * declaration schedules one rather than warning, and the update reports the
262
+ * form, which a removed answer no longer holds.
263
+ */
264
+ private readonly handleItems;
241
265
  }
242
266
  declare global {
243
267
  interface HTMLElementTagNameMap {
@@ -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 { commaList, customElement, DisabledCascadeController, HelixFormElement, hostAria, IndicatorController, KeyboardNavigationController, MixinControllerValue, MixinField, rovingStop, toggleValue, } from '@fusion.dev/helix-core';
7
+ import { commaList, customElement, DisabledCascadeController, HelixFormElement, hostAria, IndicatorController, KeyboardNavigationController, MixinControllerValue, MixinField, reportValues, rovingStop, toggleValue, toolbarAround, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  import { HelixHeadlessToggle } from '../root/toggle-root.js';
@@ -13,15 +13,15 @@ let HelixHeadlessToggleGroup = class HelixHeadlessToggleGroup extends MixinContr
13
13
  super(...arguments);
14
14
  this.lastFocused = undefined;
15
15
  this.noteFocus = (event) => {
16
- const item = this.items.find((one) => one === event.target);
17
- if (this.multiple && item && item !== this.lastFocused) {
16
+ const item = event.target;
17
+ if (this.multiple && item !== this.lastFocused && this.items.includes(item)) {
18
18
  this.lastFocused = item;
19
19
  this.sync();
20
20
  }
21
21
  };
22
22
  this.focusable = true;
23
23
  this.indicator = new IndicatorController(this, {
24
- active: () => this.multiple ? undefined : this.items.find((item) => item.value === this.value),
24
+ active: () => this.chosenItem,
25
25
  indicator: () => this.partNamed('indicator'),
26
26
  observe: () => this.items,
27
27
  surface: () => this.partNamed('track'),
@@ -52,6 +52,12 @@ let HelixHeadlessToggleGroup = class HelixHeadlessToggleGroup extends MixinContr
52
52
  });
53
53
  };
54
54
  this.chosen = undefined;
55
+ this.handleItems = () => {
56
+ this.adopt();
57
+ this.sync();
58
+ this.indicator.place();
59
+ this.requestUpdate();
60
+ };
55
61
  }
56
62
  adopt() {
57
63
  if (this.value !== '' || this.children === undefined) {
@@ -63,7 +69,7 @@ let HelixHeadlessToggleGroup = class HelixHeadlessToggleGroup extends MixinContr
63
69
  }
64
70
  }
65
71
  sync() {
66
- const active = this.multiple ? undefined : this.items.find((item) => item.value === this.value);
72
+ const active = this.chosenItem;
67
73
  const pressed = new Set(this.values);
68
74
  const entry = this.focusable ? this.entry() : undefined;
69
75
  for (const item of this.items) {
@@ -80,9 +86,12 @@ let HelixHeadlessToggleGroup = class HelixHeadlessToggleGroup extends MixinContr
80
86
  selected: (item) => item.pressed === true,
81
87
  });
82
88
  }
83
- const active = items.find((item) => item.value === this.value);
89
+ const active = this.chosenItem;
84
90
  return active && !active.disabled ? active : items.find((item) => !item.disabled);
85
91
  }
92
+ get chosenItem() {
93
+ return this.multiple ? undefined : this.items.find((item) => item.value === this.value);
94
+ }
86
95
  get multiple() {
87
96
  return this.selectionMode === 'multiple';
88
97
  }
@@ -98,14 +107,12 @@ let HelixHeadlessToggleGroup = class HelixHeadlessToggleGroup extends MixinContr
98
107
  if (this.value === '') {
99
108
  return false;
100
109
  }
101
- if (this.multiple) {
102
- return this.children === undefined || this.values.length > 0;
103
- }
104
110
  if (this.children === undefined) {
105
111
  return true;
106
112
  }
107
- const items = this.items;
108
- return items.length === 0 || items.some((item) => item.value === this.value);
113
+ return this.multiple
114
+ ? this.values.length > 0
115
+ : this.items.length === 0 || this.chosenItem !== undefined;
109
116
  }
110
117
  connectedCallback() {
111
118
  super.connectedCallback();
@@ -132,29 +139,22 @@ let HelixHeadlessToggleGroup = class HelixHeadlessToggleGroup extends MixinContr
132
139
  if (!this.multiple) {
133
140
  return 'radiogroup';
134
141
  }
135
- return this.parentElement?.closest('[role="toolbar"], helix-toolbar, helix-headless-toolbar')
136
- ? 'group'
137
- : 'toolbar';
142
+ return toolbarAround(this) ? 'group' : 'toolbar';
138
143
  }
139
144
  willUpdate(changed) {
140
145
  super.willUpdate(changed);
141
146
  this.adopt();
142
147
  hostAria(this.internals, { label: this.label, role: this.groupRole });
143
148
  this.internals.ariaOrientation = this.orientation ?? null;
144
- this.internals.setFormValue(this.formValue());
145
- }
146
- formValue() {
147
149
  if (!this.answered) {
148
- return null;
150
+ this.internals.setFormValue(null);
149
151
  }
150
- if (!this.multiple || this.name === '') {
151
- return this.value;
152
+ else if (this.multiple) {
153
+ reportValues(this.internals, this.name, this.values, { state: 'entries' });
152
154
  }
153
- const data = new FormData();
154
- for (const value of this.values) {
155
- data.append(this.name, value);
155
+ else {
156
+ this.internals.setFormValue(this.value);
156
157
  }
157
- return data;
158
158
  }
159
159
  validate() {
160
160
  this.reportRequired(!this.answered, 'Choose one to continue.', 'track');
@@ -176,29 +176,12 @@ let HelixHeadlessToggleGroup = class HelixHeadlessToggleGroup extends MixinContr
176
176
  super.formStateRestoreCallback(state);
177
177
  return;
178
178
  }
179
- this.values = state.getAll(this.name).filter((one) => typeof one === 'string');
179
+ this.values = state.getAll(this.name);
180
180
  }
181
181
  render() {
182
182
  const inside = this.labelPlacement === 'start';
183
183
  const label = this.renderGroupLabel();
184
- return html `${inside ? nothing : label}
185
- <div part="row">
186
- <slot name="start"></slot>
187
- <div part="track">
188
- ${inside ? label : nothing}
189
- <div part="indicator" aria-hidden="true"></div>
190
- <slot
191
- @slotchange=${() => {
192
- this.adopt();
193
- this.sync();
194
- this.indicator.place();
195
- this.requestUpdate();
196
- }}
197
- ></slot>
198
- </div>
199
- <slot name="end"></slot>
200
- </div>
201
- ${this.renderHint()}${this.renderFeedback()}`;
184
+ return html `${inside ? nothing : label}<div part="row"><slot name="start"></slot><div part="track">${inside ? label : nothing}<div part="indicator" aria-hidden="true"></div><slot @slotchange=${this.handleItems}></slot></div><slot name="end"></slot></div>${this.renderHint()}${this.renderFeedback()}`;
202
185
  }
203
186
  };
204
187
  __decorate([
@@ -31,14 +31,12 @@ let HelixHeadlessToggle = class HelixHeadlessToggle extends MixinSelectableItem(
31
31
  part="item"
32
32
  type="button"
33
33
  role=${this.pressed === undefined ? 'radio' : nothing}
34
- aria-checked=${this.pressed === undefined ? (this.selected ? 'true' : 'false') : nothing}
34
+ aria-checked=${this.pressed === undefined ? String(this.selected) : nothing}
35
35
  aria-pressed=${this.pressed === undefined ? nothing : String(this.pressed)}
36
36
  ?disabled=${this.disabled}
37
37
  tabindex=${(this.focusable ?? this.selected) || !this.childrenKnown ? '0' : '-1'}
38
38
  @click=${() => this.select()}
39
- >
40
- <slot></slot>
41
- </button>`;
39
+ ><slot></slot></button>`;
42
40
  }
43
41
  };
44
42
  __decorate([
@@ -12,6 +12,10 @@ import { type PropertyValues, type TemplateResult } from 'lit';
12
12
  * focus counts as a control, including your own elements. A child that takes no
13
13
  * focus, such as a divider, is skipped. A menu is reached at its trigger.
14
14
  *
15
+ * A Divider in the toolbar is a separator across the toolbar's axis, as React
16
+ * Aria's is: vertical in a horizontal toolbar and horizontal in a vertical
17
+ * one, without an `orientation` of its own.
18
+ *
15
19
  * Controls inside a plain wrapper, such as a `Button Group`, are each a stop
16
20
  * of the toolbar's own, as React Aria's toolbar flattens a group: the arrows
17
21
  * walk through the group's buttons and on past it, and the group takes no tab
@@ -20,11 +24,42 @@ import { type PropertyValues, type TemplateResult } from 'lit';
20
24
  * The arrows wrap from the last control to the first. Set `stop-at-ends` to
21
25
  * keep them at the ends, as Radix's `loop` set to false does.
22
26
  *
23
- * A nested composite, such as a toggle group, is one stop on the toolbar's
24
- * axis: the toolbar's arrows move past it, and the arrows across the toolbar
25
- * move inside it. A composite with a `focusable` property, as Toggle Group
26
- * has, gives up its own tab stop while the toolbar's is elsewhere, so Tab
27
- * stops once in the toolbar. A composite without one keeps its own tab stop.
27
+ * **Keyboard.** Tab enters the toolbar on the control that last had focus, the
28
+ * first control at the start, and the next Tab leaves it.
29
+ *
30
+ * | Key | What it does |
31
+ * |---|---|
32
+ * | Right | Moves to the next control in a horizontal toolbar, from the last back to the first. |
33
+ * | Left | Moves to the control before in a horizontal toolbar, from the first round to the last. |
34
+ * | Down, Up | The same in a vertical toolbar. |
35
+ * | Home, End | Moves to the first or the last control. |
36
+ *
37
+ * Left and Right swap on a right-to-left page, where the first control is on
38
+ * the right. The arrows across the toolbar's axis are left to the control that
39
+ * has focus, so a radio-style toggle group or a select answers them itself.
40
+ * The toolbar is `role="toolbar"` with `aria-orientation`, named by `label`.
41
+ *
42
+ * The stop moves through a control's own `focusable` property where it has
43
+ * one, as Button, Select and Toggle Group do. A control without one has
44
+ * `tabindex` written on the element that takes focus: a native element
45
+ * itself, or the control inside a custom element's open shadow root, so the
46
+ * host keeps the markup you rendered. Only a custom element whose shadow root
47
+ * is closed takes it on the host.
48
+ *
49
+ * A toggle group of pressed buttons, `selection-mode="multiple"`, is walked
50
+ * through the same way, each toggle a stop on the toolbar's axis, as React
51
+ * Aria's toolbar walks its toggle buttons. Another nested composite, such as a
52
+ * radio-style toggle group, is one stop on the toolbar's axis: the toolbar's
53
+ * arrows move past it, and the arrows across the toolbar move inside it. A
54
+ * composite with a `focusable` property, as Toggle Group has, gives up its own
55
+ * tab stop while the toolbar's is elsewhere, so Tab stops once in the
56
+ * toolbar. A composite without one keeps its own tab stop.
57
+ *
58
+ * A toolbar inside another toolbar, a Helix one or the page's own
59
+ * `role="toolbar"`, is a `group` of the outer one, as React Aria's is: the
60
+ * outer toolbar's arrows walk through its controls and on past them, and it
61
+ * takes no keys and no tab stop of its own. A server renders it as a toolbar,
62
+ * having no parent to read, until it upgrades.
28
63
  *
29
64
  * @since 0.1.0
30
65
  * @status stable
@@ -35,6 +70,10 @@ import { type PropertyValues, type TemplateResult } from 'lit';
35
70
  * @slot - The toolbar's controls.
36
71
  *
37
72
  * @csspart toolbar - The toolbar container.
73
+ *
74
+ * @cssstate horizontal - The controls run along a row, which is the default.
75
+ * @cssstate nested - The toolbar is a group inside another toolbar, which owns the keys and the tab stop.
76
+ * @cssstate vertical - The controls run down a column, under `orientation="vertical"`.
38
77
  */
39
78
  export declare class HelixHeadlessToolbar extends HelixElement {
40
79
  /**
@@ -123,6 +162,13 @@ export declare class HelixHeadlessToolbar extends HelixElement {
123
162
  * the stop hands it to the first one left.
124
163
  */
125
164
  private readonly restoreTabStop;
165
+ /**
166
+ * Whether this toolbar sits inside another, which then owns the keys and the
167
+ * tab stop: a toolbar inside a toolbar held the reader's arrows inside it.
168
+ * Read when it renders and when it connects, there being no parent on a
169
+ * server.
170
+ */
171
+ private get nested();
126
172
  /**
127
173
  * The orientation in force.
128
174
  *
@@ -143,6 +189,7 @@ export declare class HelixHeadlessToolbar extends HelixElement {
143
189
  connectedCallback(): void;
144
190
  disconnectedCallback(): void;
145
191
  protected firstUpdated(changed: PropertyValues): void;
192
+ protected willUpdate(changed: PropertyValues): void;
146
193
  protected render(): TemplateResult;
147
194
  }
148
195
  declare global {
@@ -4,13 +4,15 @@ 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, HelixElement, inlineStep, keyClaimed, } from '@fusion.dev/helix-core';
8
- import { html } from 'lit';
7
+ var HelixHeadlessToolbar_1;
8
+ import { AriaForwardController, closestInstance, customElement, HelixElement, inlineStep, keyClaimed, toolbarAround, } from '@fusion.dev/helix-core';
9
+ import { html, nothing } from 'lit';
9
10
  import { property } from 'lit/decorators.js';
10
11
  const KEYS = new Set(['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End']);
11
12
  const ownsTabStop = (node) => 'focusable' in node;
12
13
  const NATIVE = 'a[href], button, input, select, textarea, [tabindex], [contenteditable=""], [contenteditable="true"]';
13
14
  const TABBABLE = NATIVE.replace('[tabindex]', '[tabindex]:not([tabindex="-1"])');
15
+ const innerStops = new WeakMap();
14
16
  const takesFocus = (node) => {
15
17
  if (!(node instanceof HTMLElement) ||
16
18
  node.hasAttribute('disabled') ||
@@ -20,9 +22,29 @@ const takesFocus = (node) => {
20
22
  return (node.matches(NATIVE) ||
21
23
  ownsTabStop(node) ||
22
24
  node.shadowRoot?.delegatesFocus === true ||
23
- node.shadowRoot?.querySelector(TABBABLE) != null);
25
+ node.shadowRoot?.querySelector(TABBABLE) != null ||
26
+ innerStops.get(node)?.isConnected === true);
24
27
  };
25
- let HelixHeadlessToolbar = class HelixHeadlessToolbar extends HelixElement {
28
+ const stopOf = (node) => {
29
+ if (node.hasAttribute('tabindex')) {
30
+ return node;
31
+ }
32
+ const held = innerStops.get(node);
33
+ if (held?.isConnected && held.getRootNode() === node.shadowRoot) {
34
+ return held;
35
+ }
36
+ const inner = node.localName.includes('-')
37
+ ? node.shadowRoot?.querySelector(TABBABLE)
38
+ : null;
39
+ if (!inner) {
40
+ return node;
41
+ }
42
+ innerStops.set(node, inner);
43
+ return inner;
44
+ };
45
+ const flattens = (node) => ownsTabStop(node) &&
46
+ node.selectionMode === 'multiple';
47
+ let HelixHeadlessToolbar = HelixHeadlessToolbar_1 = class HelixHeadlessToolbar extends HelixElement {
26
48
  constructor() {
27
49
  super(...arguments);
28
50
  this.label = 'Toolbar';
@@ -33,28 +55,40 @@ let HelixHeadlessToolbar = class HelixHeadlessToolbar extends HelixElement {
33
55
  this.wroteForeign = false;
34
56
  this.stopAtEnds = false;
35
57
  this.handleFocusIn = (event) => {
58
+ if (this.nested) {
59
+ return;
60
+ }
36
61
  const control = this.origin(event);
37
62
  if (control) {
38
63
  this.setTabStop(control);
39
64
  }
40
65
  };
41
66
  this.restoreTabStop = () => {
67
+ if (this.nested) {
68
+ return;
69
+ }
42
70
  const controls = this.controls;
43
71
  const held = controls.some((control) => {
72
+ if (control.group) {
73
+ return control.group.focusable;
74
+ }
44
75
  const composite = control.stops.length !== 1;
45
76
  const element = composite ? control.child : control.stops[0];
46
77
  if (ownsTabStop(element)) {
47
78
  return element.focusable;
48
79
  }
49
- return composite || element.tabIndex === 0;
80
+ return composite || stopOf(element).tabIndex === 0;
50
81
  });
51
82
  if (controls.length > 0 && !held) {
52
83
  this.setTabStop(controls[0], false);
53
84
  }
54
85
  };
55
86
  this.handleCompositeKeydown = (event) => {
87
+ if (this.nested) {
88
+ return;
89
+ }
56
90
  const control = this.origin(event);
57
- if (!control || control.stops.length === 1) {
91
+ if (!control || (control.stops.length === 1 && !control.group)) {
58
92
  return;
59
93
  }
60
94
  this.handleKeydown(event);
@@ -63,7 +97,7 @@ let HelixHeadlessToolbar = class HelixHeadlessToolbar extends HelixElement {
63
97
  }
64
98
  };
65
99
  this.handleKeydown = (event) => {
66
- if (!KEYS.has(event.key) || keyClaimed(event)) {
100
+ if (this.nested || !KEYS.has(event.key) || keyClaimed(event)) {
67
101
  return;
68
102
  }
69
103
  const along = inlineStep(this, event.key);
@@ -101,8 +135,9 @@ let HelixHeadlessToolbar = class HelixHeadlessToolbar extends HelixElement {
101
135
  if (element && 'focusItem' in element && typeof element.focusItem === 'function') {
102
136
  element.focusItem();
103
137
  }
104
- else {
105
- element?.focus();
138
+ else if (element) {
139
+ ;
140
+ (ownsTabStop(element) ? element : stopOf(element)).focus();
106
141
  }
107
142
  };
108
143
  }
@@ -115,7 +150,14 @@ let HelixHeadlessToolbar = class HelixHeadlessToolbar extends HelixElement {
115
150
  continue;
116
151
  }
117
152
  if (takesFocus(child)) {
118
- controls.push({ child, stops: this.inside(child) });
153
+ const stops = this.inside(child);
154
+ if (stops.length > 1 && flattens(child)) {
155
+ for (const stop of stops) {
156
+ controls.push({ child: stop, group: child, stops: [stop] });
157
+ }
158
+ continue;
159
+ }
160
+ controls.push({ child, stops });
119
161
  continue;
120
162
  }
121
163
  for (const stop of this.within(child)) {
@@ -151,6 +193,10 @@ let HelixHeadlessToolbar = class HelixHeadlessToolbar extends HelixElement {
151
193
  this.wroteForeign = true;
152
194
  }
153
195
  for (const control of this.controls) {
196
+ if (control.group) {
197
+ control.group.focusable = control.group === active?.group;
198
+ continue;
199
+ }
154
200
  if (control.stops.length !== 1) {
155
201
  if (ownsTabStop(control.child)) {
156
202
  control.child.focusable = control.child === active?.child;
@@ -163,20 +209,31 @@ let HelixHeadlessToolbar = class HelixHeadlessToolbar extends HelixElement {
163
209
  element.focusable = stop;
164
210
  }
165
211
  else if (foreign || this.wroteForeign) {
166
- element.tabIndex = stop ? 0 : -1;
212
+ stopOf(element).tabIndex = stop ? 0 : -1;
167
213
  }
168
214
  }
169
215
  }
170
216
  async claimTabStop() {
217
+ if (this.nested) {
218
+ return;
219
+ }
171
220
  const pending = [...new Set([...this.children].map((child) => child.localName))].filter((name) => name.includes('-'));
172
221
  await Promise.all(pending.map((name) => customElements.whenDefined(name)));
173
222
  this.setTabStop(this.controls[0], false);
174
223
  }
224
+ get nested() {
225
+ const parent = this.parentElement;
226
+ if (!parent) {
227
+ return false;
228
+ }
229
+ return closestInstance(parent, HelixHeadlessToolbar_1) !== null || toolbarAround(this) !== null;
230
+ }
175
231
  get axis() {
176
232
  return this.orientation ?? 'horizontal';
177
233
  }
178
234
  connectedCallback() {
179
235
  super.connectedCallback();
236
+ this.requestUpdate();
180
237
  this.addEventListener('keydown', this.handleCompositeKeydown, true);
181
238
  this.addEventListener('keydown', this.handleKeydown);
182
239
  this.addEventListener('focusin', this.handleFocusIn);
@@ -199,8 +256,26 @@ let HelixHeadlessToolbar = class HelixHeadlessToolbar extends HelixElement {
199
256
  super.firstUpdated(changed);
200
257
  void this.claimTabStop();
201
258
  }
259
+ willUpdate(changed) {
260
+ super.willUpdate(changed);
261
+ this.toggleState('nested', this.nested);
262
+ this.toggleState('horizontal', this.axis === 'horizontal');
263
+ this.toggleState('vertical', this.axis === 'vertical');
264
+ if (this.hasUpdated && changed.has('orientation')) {
265
+ for (const child of this.children) {
266
+ ;
267
+ child.requestUpdate?.();
268
+ }
269
+ }
270
+ }
202
271
  render() {
203
- return html `<div part="toolbar" role="toolbar" aria-label=${this.label} aria-orientation=${this.axis}>
272
+ const nested = this.nested;
273
+ return html `<div
274
+ part="toolbar"
275
+ role=${nested ? 'group' : 'toolbar'}
276
+ aria-label=${this.label}
277
+ aria-orientation=${nested ? nothing : this.axis}
278
+ >
204
279
  <slot @slotchange=${() => this.claimTabStop()}></slot>
205
280
  </div>`;
206
281
  }
@@ -214,7 +289,7 @@ __decorate([
214
289
  __decorate([
215
290
  property({ attribute: 'stop-at-ends', type: Boolean })
216
291
  ], HelixHeadlessToolbar.prototype, "stopAtEnds", void 0);
217
- HelixHeadlessToolbar = __decorate([
292
+ HelixHeadlessToolbar = HelixHeadlessToolbar_1 = __decorate([
218
293
  customElement('helix-headless-toolbar')
219
294
  ], HelixHeadlessToolbar);
220
295
  export { HelixHeadlessToolbar };
@@ -1,4 +1,4 @@
1
- import { HelixElement, type Placement } from '@fusion.dev/helix-core';
1
+ import { HelixElement, OpenPhaseController, type Placement } from '@fusion.dev/helix-core';
2
2
  import { type PropertyValues, type TemplateResult } from 'lit';
3
3
  declare const HelixHeadlessTooltip_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerOpenInterface) & typeof HelixElement;
4
4
  /**
@@ -27,6 +27,9 @@ declare const HelixHeadlessTooltip_base: (new (...args: any[]) => import("@fusio
27
27
  * `aria-describedby` pointing at the tooltip yourself to have the link in the
28
28
  * server's markup. Where the browser has no element references, write it
29
29
  * yourself; the tooltip warns once on first open if nothing links the two.
30
+ * In the `for` form the tooltip itself is out of the accessibility tree while
31
+ * its bubble is down, so a reader walking the page meets its words once, as
32
+ * the trigger's description.
30
33
  *
31
34
  * The tooltip shows on hover and on focus. It hides on pointer leave, on blur,
32
35
  * on Escape, and when the trigger is activated. The pointer can move from the
@@ -65,6 +68,8 @@ declare const HelixHeadlessTooltip_base: (new (...args: any[]) => import("@fusio
65
68
  * @csspart tooltip-right - Added to `tooltip` while the bubble is right of its trigger.
66
69
  * @csspart tooltip-top - Added to `tooltip` while the bubble is above its trigger.
67
70
  *
71
+ * @cssstate entering - From the moment the bubble shows until its entrance has finished.
72
+ * @cssstate exiting - From the moment the bubble hides until its exit has finished.
68
73
  * @cssstate open - While the tooltip shows.
69
74
  * @cssstate placed-bottom - While the bubble sits below its trigger.
70
75
  * @cssstate placed-left - While the bubble sits to the left of its trigger.
@@ -236,6 +241,7 @@ export declare class HelixHeadlessTooltip extends HelixHeadlessTooltip_base {
236
241
  * it must stay inside, and a component often has one and not the other.
237
242
  */
238
243
  private get enclosure();
244
+ protected readonly phases: OpenPhaseController;
239
245
  private get bubble();
240
246
  /**
241
247
  * Whether there is anything to show.
@@ -4,10 +4,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { anchorElement, arrowReach, customElement, elementById, HelixElement, hostAria, linkDescription, MixinControllerOpen, onUnlessFalse, PopoverController, reportRuntime, sideOf, unlinkDescription, } from '@fusion.dev/helix-core';
7
+ import { anchorElement, arrowReach, customElement, elementById, focusTarget, HelixElement, hostAria, linkDescription, MixinControllerOpen, OpenPhaseController, onUnlessFalse, PopoverController, reportRuntime, sideOf, unlinkDescription, } from '@fusion.dev/helix-core';
8
8
  import { html } from 'lit';
9
9
  import { property, state } from 'lit/decorators.js';
10
- import { focusTarget } from '../focus-target.js';
11
10
  const GENERIC = new Set(['div', 'p', 'section', 'span']);
12
11
  const WARMTH = Symbol.for('fusion.helix.tooltip.warmth');
13
12
  const warmth = () => {
@@ -51,6 +50,14 @@ let HelixHeadlessTooltip = class HelixHeadlessTooltip extends MixinControllerOpe
51
50
  surface: () => this.partNamed('tooltip'),
52
51
  within: () => this.enclosure,
53
52
  });
53
+ this.phases = new OpenPhaseController(this, {
54
+ mark: {
55
+ entering: (on) => this.toggleState('entering', on),
56
+ exiting: (on) => this.toggleState('exiting', on),
57
+ },
58
+ open: () => this.open,
59
+ surface: () => this.partNamed('tooltip'),
60
+ });
54
61
  this.handleContentChange = () => {
55
62
  this.requestUpdate();
56
63
  };
@@ -335,6 +342,7 @@ let HelixHeadlessTooltip = class HelixHeadlessTooltip extends MixinControllerOpe
335
342
  describedBy: this.hasContent ? [bubble] : [],
336
343
  label: this.describedText,
337
344
  });
345
+ this.internals.ariaHidden = this.for !== '' && !this.open ? 'true' : null;
338
346
  }
339
347
  render() {
340
348
  const side = this.side;
@@ -40,6 +40,12 @@ declare const HelixHeadlessTour_base: (new (...args: any[]) => import("@fusion.d
40
40
  * you have moved it somewhere else on the page. A stop does not trap focus, so
41
41
  * you can still `Tab` out to the element it describes.
42
42
  *
43
+ * **The arrow keys move between stops** while focus is in one: the arrow that
44
+ * points the way the line runs goes on, and the other goes back, so on a
45
+ * right-to-left page `ArrowLeft` goes on. Neither finishes the tour at the last
46
+ * stop, and a text field in a stop keeps its own arrows. `Escape` skips the
47
+ * tour.
48
+ *
43
49
  * @since 0.1.0
44
50
  * @status stable
45
51
  * @category overlays
@@ -159,6 +165,15 @@ export declare class HelixHeadlessTour extends HelixHeadlessTour_base {
159
165
  private finish;
160
166
  private move;
161
167
  private readonly handleAsk;
168
+ /**
169
+ * The arrow along the line, from inside a stop: on, or back.
170
+ *
171
+ * A move and never a finish, so a reader walking the stops with the arrows
172
+ * cannot end the tour by going one too far; that is Next on the last stop.
173
+ */
174
+ private readonly handleArrows;
175
+ /** Whether `back()` would move, there being a stop that shows before this one. */
176
+ private get canGoBack();
162
177
  private readonly handleKeydown;
163
178
  private readonly handleViewport;
164
179
  connectedCallback(): void;