@fusion.dev/helix-headless 0.145.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 (278) hide show
  1. package/custom-elements.json +7373 -3849
  2. package/dist/accordion/item/accordion-item.d.ts +14 -0
  3. package/dist/accordion/item/accordion-item.js +16 -6
  4. package/dist/accordion/root/accordion-root.d.ts +8 -5
  5. package/dist/announcement/root/announcement-root.d.ts +3 -2
  6. package/dist/announcement/root/announcement-root.js +3 -1
  7. package/dist/app-header/root/app-header-root.d.ts +7 -2
  8. package/dist/app-header/root/app-header-root.js +9 -1
  9. package/dist/app-header/sectioning.d.ts +3 -1
  10. package/dist/app-header/sectioning.js +3 -2
  11. package/dist/avatar/group/avatar-group.d.ts +20 -14
  12. package/dist/avatar/group/avatar-group.js +17 -19
  13. package/dist/badge/root/badge-root.d.ts +3 -1
  14. package/dist/badge/root/badge-root.js +2 -2
  15. package/dist/bar-chart/root/bar-chart-root.d.ts +18 -1
  16. package/dist/bar-chart/root/bar-chart-root.js +52 -15
  17. package/dist/bar-chart/stack.d.ts +15 -0
  18. package/dist/bar-chart/stack.js +19 -0
  19. package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +25 -0
  20. package/dist/breadcrumbs/root/breadcrumbs-root.js +50 -3
  21. package/dist/button/root/button-root.d.ts +26 -0
  22. package/dist/button/root/button-root.js +38 -18
  23. package/dist/button-group/root/button-group-root.d.ts +2 -1
  24. package/dist/button-group/root/button-group-root.js +5 -1
  25. package/dist/canvas/node/canvas-node.d.ts +4 -3
  26. package/dist/canvas/node/canvas-node.js +3 -2
  27. package/dist/canvas/root/canvas-root.js +2 -2
  28. package/dist/card/root/card-root.d.ts +24 -3
  29. package/dist/card/root/card-root.js +20 -8
  30. package/dist/carousel/root/carousel-root.d.ts +43 -4
  31. package/dist/carousel/root/carousel-root.js +40 -12
  32. package/dist/carousel/stops.d.ts +20 -0
  33. package/dist/carousel/stops.js +30 -0
  34. package/dist/chat/message/chat-message.js +5 -4
  35. package/dist/chat/naming.d.ts +5 -1
  36. package/dist/chat/naming.js +4 -2
  37. package/dist/chat/root/chat-root.d.ts +25 -3
  38. package/dist/chat/root/chat-root.js +22 -5
  39. package/dist/checkbox/root/checkbox-root.d.ts +20 -0
  40. package/dist/checkbox/root/checkbox-root.js +14 -1
  41. package/dist/checkbox-group/root/checkbox-group-root.d.ts +8 -2
  42. package/dist/checkbox-group/root/checkbox-group-root.js +12 -10
  43. package/dist/checkbox-group/select-all.d.ts +27 -0
  44. package/dist/checkbox-group/select-all.js +12 -0
  45. package/dist/code-block/highlight.d.ts +15 -0
  46. package/dist/code-block/highlight.js +4 -0
  47. package/dist/code-block/root/code-block-root.d.ts +49 -1
  48. package/dist/code-block/root/code-block-root.js +58 -3
  49. package/dist/color-input/root/color-input-root.d.ts +3 -0
  50. package/dist/color-input/root/color-input-root.js +6 -3
  51. package/dist/color-picker/root/color-picker-root.d.ts +33 -4
  52. package/dist/color-picker/root/color-picker-root.js +80 -21
  53. package/dist/color-picker/swatches.d.ts +12 -0
  54. package/dist/color-picker/swatches.js +26 -0
  55. package/dist/combobox/root/combobox-root.d.ts +43 -0
  56. package/dist/combobox/root/combobox-root.js +79 -15
  57. package/dist/command/root/command-root.d.ts +16 -1
  58. package/dist/command/root/command-root.js +22 -4
  59. package/dist/copy-button/root/copy-button-root.d.ts +5 -0
  60. package/dist/copy-button/root/copy-button-root.js +10 -3
  61. package/dist/data-table/index.d.ts +1 -1
  62. package/dist/data-table/index.js +1 -1
  63. package/dist/data-table/keys.d.ts +24 -0
  64. package/dist/data-table/keys.js +24 -0
  65. package/dist/data-table/root/data-table-root.d.ts +27 -18
  66. package/dist/data-table/root/data-table-root.js +20 -52
  67. package/dist/data-table/tree.d.ts +16 -1
  68. package/dist/data-table/tree.js +2 -3
  69. package/dist/date-input/root/date-input-root.d.ts +3 -1
  70. package/dist/date-input/root/date-input-root.js +18 -7
  71. package/dist/date-picker/root/date-picker-root.js +12 -6
  72. package/dist/dialog/description.js +15 -1
  73. package/dist/dialog/root/dialog-root.d.ts +8 -2
  74. package/dist/dialog/root/dialog-root.js +16 -1
  75. package/dist/divider/root/divider-root.d.ts +3 -0
  76. package/dist/divider/root/divider-root.js +2 -1
  77. package/dist/donut-chart/root/donut-chart-root.d.ts +31 -0
  78. package/dist/donut-chart/root/donut-chart-root.js +48 -1
  79. package/dist/drawer/reveal.d.ts +8 -0
  80. package/dist/drawer/reveal.js +1 -0
  81. package/dist/drawer/root/drawer-root.d.ts +59 -0
  82. package/dist/drawer/root/drawer-root.js +63 -4
  83. package/dist/drilldown/item/drilldown-item.js +1 -1
  84. package/dist/drilldown/root/drilldown-root.d.ts +21 -3
  85. package/dist/drilldown/root/drilldown-root.js +21 -3
  86. package/dist/element-events.generated.js +31 -5
  87. package/dist/empty/root/empty-root.d.ts +3 -1
  88. package/dist/empty/root/empty-root.js +3 -2
  89. package/dist/file-input/root/file-input-root.d.ts +69 -6
  90. package/dist/file-input/root/file-input-root.js +82 -19
  91. package/dist/file-input/screen.d.ts +2 -1
  92. package/dist/filter-input/menu/filter-menu.d.ts +2 -0
  93. package/dist/filter-input/menu/filter-menu.js +12 -4
  94. package/dist/filter-input/root/filter-input-root.d.ts +30 -6
  95. package/dist/filter-input/root/filter-input-root.js +1 -1
  96. package/dist/filter-input/suggest.d.ts +28 -3
  97. package/dist/filter-input/suggest.js +18 -8
  98. package/dist/format-date/root/format-date-root.d.ts +9 -16
  99. package/dist/format-date/root/format-date-root.js +10 -27
  100. package/dist/heatmap/root/heatmap-root.d.ts +24 -13
  101. package/dist/heatmap/root/heatmap-root.js +34 -12
  102. package/dist/icon/root/icon-root.d.ts +12 -1
  103. package/dist/icon/root/icon-root.js +21 -10
  104. package/dist/icon/settle.d.ts +7 -0
  105. package/dist/icon/settle.js +10 -0
  106. package/dist/icon-button/root/icon-button-root.d.ts +2 -0
  107. package/dist/image/root/image-root.d.ts +5 -1
  108. package/dist/image/root/image-root.js +1 -1
  109. package/dist/input/root/input-root.d.ts +12 -2
  110. package/dist/input/root/input-root.js +11 -2
  111. package/dist/kbd/root/kbd-root.d.ts +35 -1
  112. package/dist/kbd/root/kbd-root.js +23 -4
  113. package/dist/legend/root/legend-root.d.ts +55 -8
  114. package/dist/legend/root/legend-root.js +55 -13
  115. package/dist/lightbox/root/lightbox-root.d.ts +49 -6
  116. package/dist/lightbox/root/lightbox-root.js +86 -19
  117. package/dist/lightbox/zoom-controller.d.ts +59 -0
  118. package/dist/lightbox/zoom-controller.js +128 -0
  119. package/dist/lightbox/zoom.d.ts +22 -0
  120. package/dist/lightbox/zoom.js +16 -0
  121. package/dist/line-chart/root/line-chart-root.d.ts +22 -1
  122. package/dist/line-chart/root/line-chart-root.js +21 -1
  123. package/dist/list/item/list-item.d.ts +2 -0
  124. package/dist/list/item/list-item.js +11 -2
  125. package/dist/list/root/list-root.d.ts +62 -13
  126. package/dist/list/root/list-root.js +70 -13
  127. package/dist/list/selection.d.ts +37 -7
  128. package/dist/list/selection.js +16 -7
  129. package/dist/listbox/root/listbox-root.d.ts +37 -1
  130. package/dist/listbox/root/listbox-root.js +49 -3
  131. package/dist/loader/busy.d.ts +10 -0
  132. package/dist/loader/busy.js +11 -0
  133. package/dist/loader/root/loader-root.d.ts +9 -2
  134. package/dist/loader/root/loader-root.js +23 -3
  135. package/dist/megamenu/root/megamenu-root.d.ts +51 -10
  136. package/dist/megamenu/root/megamenu-root.js +76 -5
  137. package/dist/menu/item/menu-item.d.ts +51 -2
  138. package/dist/menu/item/menu-item.js +47 -23
  139. package/dist/menu/root/menu-root.d.ts +14 -0
  140. package/dist/menu/root/menu-root.js +2 -2
  141. package/dist/meter/root/meter-root.d.ts +20 -1
  142. package/dist/meter/root/meter-root.js +11 -15
  143. package/dist/navigation/root/navigation-root.d.ts +2 -1
  144. package/dist/navigation/root/navigation-root.js +2 -2
  145. package/dist/notifications/root/notifications-root.d.ts +10 -3
  146. package/dist/notifications/root/notifications-root.js +19 -7
  147. package/dist/number-input/root/number-input-root.d.ts +17 -8
  148. package/dist/number-input/root/number-input-root.js +2 -7
  149. package/dist/object-inspector/root/object-inspector-root.d.ts +75 -27
  150. package/dist/object-inspector/root/object-inspector-root.js +117 -76
  151. package/dist/object-inspector/rows.d.ts +18 -0
  152. package/dist/object-inspector/rows.js +33 -0
  153. package/dist/option/root/option-root.d.ts +5 -3
  154. package/dist/outline/root/outline-root.d.ts +18 -0
  155. package/dist/outline/root/outline-root.js +23 -5
  156. package/dist/pagination/size/pagination-size.d.ts +1 -0
  157. package/dist/pagination/size/pagination-size.js +1 -1
  158. package/dist/pin-input/code.d.ts +10 -0
  159. package/dist/pin-input/code.js +13 -0
  160. package/dist/pin-input/root/pin-input-root.d.ts +25 -1
  161. package/dist/pin-input/root/pin-input-root.js +10 -11
  162. package/dist/popover/hide-outside.d.ts +14 -0
  163. package/dist/popover/hide-outside.js +41 -0
  164. package/dist/popover/root/popover-root.d.ts +57 -7
  165. package/dist/popover/root/popover-root.js +58 -3
  166. package/dist/progress/root/progress-root.d.ts +20 -0
  167. package/dist/progress/root/progress-root.js +15 -15
  168. package/dist/qr-code/export.d.ts +26 -1
  169. package/dist/qr-code/export.js +14 -0
  170. package/dist/qr-code/root/qr-code-root.d.ts +19 -5
  171. package/dist/qr-code/root/qr-code-root.js +58 -9
  172. package/dist/quote/marks.d.ts +8 -0
  173. package/dist/quote/marks.js +5 -0
  174. package/dist/quote/root/quote-root.d.ts +14 -2
  175. package/dist/quote/root/quote-root.js +23 -1
  176. package/dist/radio/root/radio-root.d.ts +6 -2
  177. package/dist/radio/root/radio-root.js +6 -1
  178. package/dist/rating/root/rating-root.d.ts +9 -4
  179. package/dist/rating/root/rating-root.js +31 -7
  180. package/dist/rating/steps.d.ts +7 -0
  181. package/dist/rating/steps.js +9 -0
  182. package/dist/scatter-chart/fit.d.ts +15 -0
  183. package/dist/scatter-chart/fit.js +35 -0
  184. package/dist/scatter-chart/root/scatter-chart-root.d.ts +21 -1
  185. package/dist/scatter-chart/root/scatter-chart-root.js +30 -17
  186. package/dist/scroll-area/root/scroll-area-root.d.ts +22 -51
  187. package/dist/scroll-area/root/scroll-area-root.js +57 -173
  188. package/dist/scroll-area/scrollbar-controller.d.ts +111 -0
  189. package/dist/scroll-area/scrollbar-controller.js +172 -0
  190. package/dist/scroll-area/scrollbar.d.ts +27 -0
  191. package/dist/scroll-area/scrollbar.js +9 -0
  192. package/dist/select/root/select-root.d.ts +15 -0
  193. package/dist/select/root/select-root.js +18 -6
  194. package/dist/skeleton/root/skeleton-root.d.ts +3 -0
  195. package/dist/skeleton/root/skeleton-root.js +4 -2
  196. package/dist/skip-link/root/skip-link-root.js +2 -2
  197. package/dist/slider/root/slider-root.d.ts +41 -4
  198. package/dist/slider/root/slider-root.js +23 -3
  199. package/dist/sparkline/readings.d.ts +18 -0
  200. package/dist/sparkline/readings.js +19 -0
  201. package/dist/sparkline/root/sparkline-root.d.ts +78 -7
  202. package/dist/sparkline/root/sparkline-root.js +118 -23
  203. package/dist/speed-dial/root/speed-dial-root.js +2 -2
  204. package/dist/splitter/root/splitter-root.d.ts +7 -12
  205. package/dist/splitter/root/splitter-root.js +209 -204
  206. package/dist/stat/root/stat-root.d.ts +14 -5
  207. package/dist/stat/root/stat-root.js +21 -5
  208. package/dist/steps/reach.d.ts +5 -0
  209. package/dist/steps/reach.js +3 -0
  210. package/dist/steps/root/steps-root.d.ts +49 -3
  211. package/dist/steps/root/steps-root.js +44 -5
  212. package/dist/steps/step/step.d.ts +7 -0
  213. package/dist/steps/step/step.js +7 -2
  214. package/dist/switch/root/switch-root.d.ts +10 -0
  215. package/dist/table/column/table-column.d.ts +0 -10
  216. package/dist/table/column/table-column.js +3 -19
  217. package/dist/table/root/table-root.d.ts +31 -10
  218. package/dist/table/root/table-root.js +2 -13
  219. package/dist/tabs/panel/tab-panel.d.ts +16 -3
  220. package/dist/tabs/panel/tab-panel.js +34 -5
  221. package/dist/tabs/root/tabs-root.d.ts +12 -0
  222. package/dist/tabs/root/tabs-root.js +1 -1
  223. package/dist/tabs/tab/tab.d.ts +5 -0
  224. package/dist/tabs/tab/tab.js +5 -2
  225. package/dist/tag/group/tag-group.d.ts +31 -4
  226. package/dist/tag/group/tag-group.js +46 -7
  227. package/dist/tag/root/tag-root.js +9 -2
  228. package/dist/textarea/root/textarea-root.d.ts +28 -1
  229. package/dist/textarea/root/textarea-root.js +40 -1
  230. package/dist/time-input/root/time-input-root.d.ts +5 -1
  231. package/dist/time-input/root/time-input-root.js +16 -8
  232. package/dist/time-picker/root/time-picker-root.d.ts +18 -4
  233. package/dist/time-picker/root/time-picker-root.js +7 -10
  234. package/dist/time-picker/wheel-name.d.ts +9 -0
  235. package/dist/time-picker/wheel-name.js +15 -0
  236. package/dist/timeline/group/timeline-group.js +2 -2
  237. package/dist/toast/item/toast-item.d.ts +14 -1
  238. package/dist/toast/item/toast-item.js +22 -5
  239. package/dist/toast/root/toast-root.d.ts +6 -0
  240. package/dist/toast/root/toast-root.js +16 -1
  241. package/dist/toggle/group/toggle-group.d.ts +24 -3
  242. package/dist/toggle/group/toggle-group.js +34 -5
  243. package/dist/tooltip/root/tooltip-root.d.ts +13 -2
  244. package/dist/tooltip/root/tooltip-root.js +9 -1
  245. package/dist/tour/back.d.ts +10 -0
  246. package/dist/tour/back.js +8 -0
  247. package/dist/tour/root/tour-root.d.ts +30 -2
  248. package/dist/tour/root/tour-root.js +34 -8
  249. package/dist/tree/item/tree-item.d.ts +7 -3
  250. package/dist/tree/item/tree-item.js +3 -0
  251. package/dist/tree/root/tree-root.d.ts +24 -3
  252. package/dist/tree/root/tree-root.js +32 -13
  253. package/dist/tree/selection.js +2 -15
  254. package/dist/trend/root/trend-root.d.ts +43 -18
  255. package/dist/trend/root/trend-root.js +31 -6
  256. package/dist/video/media-events.d.ts +13 -18
  257. package/dist/video/media-events.js +1 -5
  258. package/dist/video/root/video-root.d.ts +18 -5
  259. package/dist/video/root/video-root.js +19 -10
  260. package/dist/video-playlist/menu/video-playlist-menu.d.ts +2 -0
  261. package/dist/video-playlist/menu/video-playlist-menu.js +2 -1
  262. package/dist/video-playlist/root/video-playlist-root.d.ts +7 -1
  263. package/dist/virtual-list/fill.d.ts +0 -8
  264. package/dist/virtual-list/fill.js +1 -17
  265. package/dist/virtual-list/plan.d.ts +49 -0
  266. package/dist/virtual-list/plan.js +16 -0
  267. package/dist/virtual-list/root/virtual-list-root.d.ts +114 -13
  268. package/dist/virtual-list/root/virtual-list-root.js +183 -40
  269. package/lint.json +1 -1
  270. package/package.json +8 -8
  271. package/types/jsx.d.ts +4577 -835
  272. package/types/vue.d.ts +926 -168
  273. package/dist/chat/relative-clock.d.ts +0 -39
  274. package/dist/chat/relative-clock.js +0 -31
  275. package/dist/data-table/root/order.d.ts +0 -141
  276. package/dist/data-table/root/order.js +0 -76
  277. package/dist/tag/selection.d.ts +0 -10
  278. package/dist/tag/selection.js +0 -12
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { AriaForwardController, countLabel, customElement, DelayController, DisabledCascadeController, HelixFilterEvent, HelixFormElement, hostAria, MixinCollection, MixinControllerValue, MixinField, rangeAdd, reportValues, requestChange, scrollItemIntoView, Typeahead, typesCharacter, } from '@fusion.dev/helix-core';
7
+ import { AriaForwardController, countLabel, customElement, DelayController, DisabledCascadeController, HelixFilterEvent, HelixFormElement, HelixLoadMoreEvent, hostAria, MixinCollection, MixinControllerValue, MixinField, rangeAdd, reportValues, requestChange, scrollItemIntoView, Typeahead, typesCharacter, } from '@fusion.dev/helix-core';
8
8
  import { magnifyingGlass } from '@fusion.dev/helix-icons';
9
9
  import { html, nothing } from 'lit';
10
10
  import { property, state } from 'lit/decorators.js';
@@ -70,6 +70,7 @@ let HelixHeadlessListbox = class HelixHeadlessListbox extends MixinCollection(Mi
70
70
  this.filterable = false;
71
71
  this.filterDelay = 0;
72
72
  this.filterLabel = 'Filter';
73
+ this.loadError = '';
73
74
  this.manual = false;
74
75
  this.multiple = false;
75
76
  this.resultLabel = '{count} result';
@@ -192,6 +193,18 @@ let HelixHeadlessListbox = class HelixHeadlessListbox extends MixinCollection(Mi
192
193
  this.takeFilter(control);
193
194
  };
194
195
  this.filtering = new DelayController(this, { renders: false });
196
+ this.askedAt = -1;
197
+ this.handleScroll = (event) => {
198
+ const items = event.currentTarget;
199
+ const count = this.options.length;
200
+ if (this.loading || count === this.askedAt || items.clientHeight === 0) {
201
+ return;
202
+ }
203
+ if (items.scrollHeight - items.scrollTop - items.clientHeight <= items.clientHeight) {
204
+ this.askedAt = count;
205
+ this.dispatchEvent(new HelixLoadMoreEvent());
206
+ }
207
+ };
195
208
  this.handleFilterKeydown = (event) => {
196
209
  if (event.key === 'Enter' || FIELD_MOVES.has(event.key)) {
197
210
  this.flushFilter();
@@ -471,6 +484,8 @@ let HelixHeadlessListbox = class HelixHeadlessListbox extends MixinCollection(Mi
471
484
  }
472
485
  this.toggleState('empty', !this.showsOptions);
473
486
  this.toggleState('loading', this.loading);
487
+ this.toggleState('error', this.loadError !== '');
488
+ this.toggleState('no-results', this.noResults);
474
489
  }
475
490
  seedDeclared() {
476
491
  if (this.owned || this.defaultValue !== '' || this.hasAttribute('default-value')) {
@@ -545,13 +560,37 @@ let HelixHeadlessListbox = class HelixHeadlessListbox extends MixinCollection(Mi
545
560
  : true;
546
561
  }
547
562
  renderStatus(hasContent) {
563
+ if (this.loadError !== '') {
564
+ return html `<p part="error"><slot name="error">${this.loadError}</slot></p>`;
565
+ }
548
566
  if (!this.loading && hasContent) {
549
567
  return nothing;
550
568
  }
551
- return this.loading
552
- ? html `<p part="loading"><slot name="loading">${this.loadingText}</slot></p>`
569
+ if (this.loading) {
570
+ return html `<p part="loading"><slot name="loading">${this.loadingText}</slot></p>`;
571
+ }
572
+ const given = this.noResultsText !== undefined ||
573
+ this.querySelector?.(':scope > [slot="no-results"]') != null;
574
+ return this.noResults && given
575
+ ? html `<p part="empty"><slot name="no-results">${this.noResultsText ?? this.emptyText}</slot></p>`
553
576
  : html `<p part="empty"><slot name="empty">${this.emptyText}</slot></p>`;
554
577
  }
578
+ get noResults() {
579
+ return (this.counted &&
580
+ !this.loading &&
581
+ this.filter !== '' &&
582
+ this.options.length > 0 &&
583
+ !this.hasMatches);
584
+ }
585
+ renderLive(hasContent) {
586
+ if (this.loadError !== '') {
587
+ return html `<span part="live" role="status">${this.loadError}</span>`;
588
+ }
589
+ if (this.noResults && this.noResultsText !== undefined) {
590
+ return html `<span part="live" role="status">${this.noResultsText}</span>`;
591
+ }
592
+ return super.renderLive(hasContent);
593
+ }
555
594
  render() {
556
595
  const shown = this.showsOptions;
557
596
  return html `${this.renderGroupLabel()}
@@ -588,6 +627,7 @@ let HelixHeadlessListbox = class HelixHeadlessListbox extends MixinCollection(Mi
588
627
  aria-required=${this.required ? 'true' : nothing}
589
628
  ${''}
590
629
  tabindex=${this.filterable ? nothing : this.isDisabled ? -1 : 0}
630
+ @scroll=${this.handleScroll}
591
631
  >
592
632
  <slot @slotchange=${() => this.place()}></slot>
593
633
  ${this.renderStatus(shown)}
@@ -616,12 +656,18 @@ __decorate([
616
656
  __decorate([
617
657
  property({ attribute: 'filter-label' })
618
658
  ], HelixHeadlessListbox.prototype, "filterLabel", void 0);
659
+ __decorate([
660
+ property({ attribute: 'load-error' })
661
+ ], HelixHeadlessListbox.prototype, "loadError", void 0);
619
662
  __decorate([
620
663
  property({ type: Boolean })
621
664
  ], HelixHeadlessListbox.prototype, "manual", void 0);
622
665
  __decorate([
623
666
  property({ reflect: true, type: Boolean })
624
667
  ], HelixHeadlessListbox.prototype, "multiple", void 0);
668
+ __decorate([
669
+ property({ attribute: 'no-results-text' })
670
+ ], HelixHeadlessListbox.prototype, "noResultsText", void 0);
625
671
  __decorate([
626
672
  property({ attribute: 'result-label' })
627
673
  ], HelixHeadlessListbox.prototype, "resultLabel", void 0);
@@ -15,3 +15,13 @@
15
15
  export declare const claimBusy: (region: Element) => void;
16
16
  /** Takes a claim back, and the attribute with the last one. */
17
17
  export declare const releaseBusy: (region: Element) => void;
18
+ /**
19
+ * Calls `found` with the region `find` answers once it is in `root`, and
20
+ * returns the call that stops waiting.
21
+ *
22
+ * For a loader whose region is not on the page yet: a framework often draws
23
+ * the loader before the list it stands for, and a region looked up once, a
24
+ * frame after connecting, was never marked. Watches for children and ids being
25
+ * written, and stops at the first answer.
26
+ */
27
+ export declare const awaitRegion: (root: Node, find: () => Element | null, found: (region: Element) => void) => (() => void);
@@ -22,3 +22,14 @@ export const releaseBusy = (region) => {
22
22
  CLAIMS.set(region, held - 1);
23
23
  }
24
24
  };
25
+ export const awaitRegion = (root, find, found) => {
26
+ const observer = new MutationObserver(() => {
27
+ const region = find();
28
+ if (region) {
29
+ observer.disconnect();
30
+ found(region);
31
+ }
32
+ });
33
+ observer.observe(root, { attributeFilter: ['id'], childList: true, subtree: true });
34
+ return () => observer.disconnect();
35
+ };
@@ -22,11 +22,12 @@ import { type PropertyValues, type TemplateResult } from 'lit';
22
22
  * **`for` names the region being loaded**, and the loader sets
23
23
  * `aria-busy="true"` on it for as long as the loader is on the page, so a
24
24
  * screen reader waits for the region rather than reading it half filled. Two
25
- * loaders in one region hold it busy until the last one leaves.
25
+ * loaders in one region hold it busy until the last one leaves. A region drawn
26
+ * after the loader is marked when it arrives.
26
27
  *
27
28
  * **`delay` keeps a quick load from flashing a loader.** The loader stays
28
29
  * hidden, and silent, for that many milliseconds, and appears only if the work
29
- * is still going.
30
+ * is still going. While it waits it carries `:state(waiting)`.
30
31
  *
31
32
  * @since 0.1.0
32
33
  * @status stable
@@ -40,6 +41,8 @@ import { type PropertyValues, type TemplateResult } from 'lit';
40
41
  * @csspart mark - The region that holds the slotted content at the center.
41
42
  * @csspart svg - The rotating circle pair.
42
43
  * @csspart track - The full circle behind the indicator.
44
+ *
45
+ * @cssstate waiting - The loader is waiting out its `delay`, hidden and silent.
43
46
  */
44
47
  export declare class HelixHeadlessLoader extends HelixElement {
45
48
  /**
@@ -67,6 +70,10 @@ export declare class HelixHeadlessLoader extends HelixElement {
67
70
  private readonly due;
68
71
  /** The region this loader marked busy, so it is the one released. */
69
72
  private region;
73
+ /** Stops waiting for a region `for` names that is not on the page yet. */
74
+ private stopAwaiting;
75
+ /** Whether `for` has named an element while the loader was on the page. */
76
+ private found;
70
77
  /** Whether the loader is still waiting out its `delay`. */
71
78
  private get waiting();
72
79
  connectedCallback(): void;
@@ -4,10 +4,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { customElement, DelayController, elementById, HelixElement, hostAria, } from '@fusion.dev/helix-core';
7
+ import { customElement, DelayController, elementById, HelixElement, hostAria, reportRuntime, } from '@fusion.dev/helix-core';
8
8
  import { html } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
- import { claimBusy, releaseBusy } from '../busy.js';
10
+ import { awaitRegion, claimBusy, releaseBusy } from '../busy.js';
11
11
  let HelixHeadlessLoader = class HelixHeadlessLoader extends HelixElement {
12
12
  constructor() {
13
13
  super(...arguments);
@@ -16,6 +16,7 @@ let HelixHeadlessLoader = class HelixHeadlessLoader extends HelixElement {
16
16
  this.label = 'Loading';
17
17
  this.due = new DelayController(this);
18
18
  this.region = null;
19
+ this.found = false;
19
20
  }
20
21
  get waiting() {
21
22
  return this.delay > 0 && !this.due.elapsed;
@@ -29,10 +30,26 @@ let HelixHeadlessLoader = class HelixHeadlessLoader extends HelixElement {
29
30
  }
30
31
  disconnectedCallback() {
31
32
  super.disconnectedCallback();
33
+ if (this.stopAwaiting && !this.found) {
34
+ reportRuntime({
35
+ kind: 'missing-target',
36
+ message: `<${this.localName} for="${this.for}"> named no element in its tree while it was on ` +
37
+ 'the page, so no region was marked busy. Give the region that id.',
38
+ tag: this.localName,
39
+ });
40
+ }
41
+ this.stopAwaiting?.();
42
+ this.stopAwaiting = undefined;
32
43
  this.release();
33
44
  }
34
45
  mark() {
35
- const region = this.isConnected && this.for !== '' ? elementById(this, this.for) : null;
46
+ this.stopAwaiting?.();
47
+ this.stopAwaiting = undefined;
48
+ const named = this.isConnected && this.for !== '';
49
+ const region = named ? elementById(this, this.for) : null;
50
+ if (named && !region) {
51
+ this.stopAwaiting = awaitRegion(this.getRootNode(), () => elementById(this, this.for), () => this.mark());
52
+ }
36
53
  if (region === this.region) {
37
54
  return;
38
55
  }
@@ -40,6 +57,7 @@ let HelixHeadlessLoader = class HelixHeadlessLoader extends HelixElement {
40
57
  if (region) {
41
58
  claimBusy(region);
42
59
  this.region = region;
60
+ this.found = true;
43
61
  }
44
62
  }
45
63
  release() {
@@ -51,6 +69,7 @@ let HelixHeadlessLoader = class HelixHeadlessLoader extends HelixElement {
51
69
  updated(changed) {
52
70
  super.updated(changed);
53
71
  if (changed.has('for') && changed.get('for') !== undefined) {
72
+ this.found = false;
54
73
  this.mark();
55
74
  }
56
75
  }
@@ -59,6 +78,7 @@ let HelixHeadlessLoader = class HelixHeadlessLoader extends HelixElement {
59
78
  hostAria(this.internals, { label: this.label, role: 'progressbar' });
60
79
  this.internals.ariaBusy = 'true';
61
80
  this.internals.ariaHidden = this.waiting ? 'true' : null;
81
+ this.toggleState('waiting', this.waiting);
62
82
  }
63
83
  render() {
64
84
  return html `<svg part="svg" viewBox="0 0 24 24" aria-hidden="true" ?hidden=${this.waiting}>
@@ -21,11 +21,27 @@ declare const HelixHeadlessMegamenu_base: (new (...args: any[]) => import("@fusi
21
21
  * along the row and see each section.
22
22
  *
23
23
  * When one panel opens in place of another, each says which way the reader
24
- * moved, as Radix's `data-motion` does: the one opening is
25
- * `:state(from-start)` or `:state(from-end)`, by where the one closing sits in
26
- * the bar, and the one closing is `:state(to-start)` or `:state(to-end)`. A
27
- * stylesheet slides them on that. Put megamenus in a `Navigation` with
28
- * `arrows` and the arrow keys move between their triggers.
24
+ * moved, as Radix's `data-motion` does. Moving toward the end of the bar, the
25
+ * one opening is `:state(from-end)` and the one closing is `:state(to-start)`;
26
+ * moving back, they are `:state(from-start)` and `:state(to-end)`. A
27
+ * stylesheet slides them on that. Start and end follow the reading direction,
28
+ * so on a right-to-left page the end is on the left. A panel that opens or
29
+ * closes on its own carries none of the four. A press on another megamenu's
30
+ * trigger hands over the same way as hovering it.
31
+ *
32
+ * While a panel is open its surface carries its own size, as
33
+ * `--megamenu-surface-inline-size` and `--megamenu-surface-block-size`, and a
34
+ * panel that took over from another also carries that one's size, as
35
+ * `--megamenu-from-inline-size` and `--megamenu-from-block-size`. Radix's
36
+ * navigation menu publishes the same pair from its shared viewport, so a
37
+ * stylesheet can grow or shrink one panel into the next.
38
+ *
39
+ * Put megamenus in a `Navigation` with `arrows` and the arrow keys move
40
+ * between their triggers. Down Arrow on the trigger of an open panel moves
41
+ * focus to the panel's first link, Escape closes the panel and returns focus
42
+ * to its trigger, and Tab moves through the panel's links and closes it on the
43
+ * way out. The trigger says `aria-expanded`, and the panel is a group named by
44
+ * `label`.
29
45
  *
30
46
  * @since 0.1.0
31
47
  * @status stable
@@ -43,14 +59,18 @@ declare const HelixHeadlessMegamenu_base: (new (...args: any[]) => import("@fusi
43
59
  * @csspart surface - The floating panel that opens.
44
60
  * @csspart trigger - The default trigger button, shown when the `trigger` slot is empty.
45
61
  *
62
+ * @cssproperty --megamenu-from-block-size - The height of the panel this one took over from, written on the surface while it is open.
63
+ * @cssproperty --megamenu-from-inline-size - The width of the panel this one took over from, written on the surface while it is open.
64
+ * @cssproperty --megamenu-surface-block-size - The panel's own height, written on the surface while it is open.
65
+ * @cssproperty --megamenu-surface-inline-size - The panel's own width, written on the surface while it is open.
46
66
  * @cssproperty --megamenu-top - Where the panel starts, measured from the bar above it.
47
67
  *
48
- * @cssstate from-end - The panel opened in place of one later in the bar, so it can enter from that side.
49
- * @cssstate from-start - The panel opened in place of one earlier in the bar.
68
+ * @cssstate from-end - The panel opened in place of one earlier in the bar, so it can enter from the end side.
69
+ * @cssstate from-start - The panel opened in place of one later in the bar, so it can enter from the start side.
50
70
  * @cssstate narrow - The page is narrower than `band-below`, so the panel is shown as a band whatever its variant.
51
71
  * @cssstate open - The panel is open, and the trigger is shown as current.
52
- * @cssstate to-end - The panel closed because one later in the bar opened, so it can leave toward it.
53
- * @cssstate to-start - The panel closed because one earlier in the bar opened.
72
+ * @cssstate to-end - The panel closed because one earlier in the bar opened, so it can leave toward the end.
73
+ * @cssstate to-start - The panel closed because one later in the bar opened, so it can leave toward the start.
54
74
  */
55
75
  export declare class HelixHeadlessMegamenu extends HelixHeadlessMegamenu_base {
56
76
  /**
@@ -135,6 +155,11 @@ export declare class HelixHeadlessMegamenu extends HelixHeadlessMegamenu_base {
135
155
  * the consumer slotted, or the button drawn in its place.
136
156
  */
137
157
  get navigationControl(): HTMLElement;
158
+ /**
159
+ * Down Arrow on the trigger of an open panel moves focus to the panel's first
160
+ * link or control, as Radix's navigation menu does.
161
+ */
162
+ private readonly handleKeyDown;
138
163
  /** Shuts it and puts the reader back where they were. */
139
164
  private close;
140
165
  /**
@@ -257,9 +282,25 @@ export declare class HelixHeadlessMegamenu extends HelixHeadlessMegamenu_base {
257
282
  * overruled.
258
283
  */
259
284
  protected willUpdate(changed: PropertyValues): void;
285
+ /**
286
+ * Clears the direction of every panel but the two in a hand-over, so only
287
+ * the latest move is ever described.
288
+ */
289
+ private static settle;
290
+ /** Whether the panel is closing because another one opened in its place. */
291
+ private handedOver;
292
+ /** The panel's size the last time it was open, in pixels. */
293
+ private size;
294
+ /** The size of the panel this one took over from, if it took over. */
295
+ private from;
296
+ /**
297
+ * Writes the panel's size onto its surface, and the size of the panel it
298
+ * took over from, for a stylesheet that grows one into the next.
299
+ */
300
+ private measure;
260
301
  /**
261
302
  * Says which way the reader moved when one panel took over from another.
262
- * Nothing clears all four, for a panel opened on its own.
303
+ * Nothing clears all four, for a panel opened or closed on its own.
263
304
  */
264
305
  private motion;
265
306
  protected updated(changed: PropertyValues): void;
@@ -5,10 +5,17 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  var HelixHeadlessMegamenu_1;
8
- import { anchorElement, customElement, deepContains, HelixElement, MixinControllerOpen, PopoverController, tellDisclosure, } from '@fusion.dev/helix-core';
8
+ import { anchorElement, customElement, deepContains, focusableElements, HelixElement, MixinControllerOpen, PopoverController, tellDisclosure, } from '@fusion.dev/helix-core';
9
9
  import { html, nothing } from 'lit';
10
10
  import { property, state } from 'lit/decorators.js';
11
11
  let showing;
12
+ const connected = new Set();
13
+ let pressed;
14
+ const release = () => {
15
+ setTimeout(() => {
16
+ pressed = undefined;
17
+ });
18
+ };
12
19
  let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerOpen(HelixElement) {
13
20
  constructor() {
14
21
  super(...arguments);
@@ -21,13 +28,27 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
21
28
  };
22
29
  this.panel = new PopoverController(this, {
23
30
  anchor: () => this.trigger,
24
- boundary: () => this,
31
+ boundary: () => [...connected],
25
32
  onDismiss: () => this.close(),
26
33
  open: () => this.open,
27
34
  place: () => !this.banded,
28
35
  placement: () => 'bottom-start',
29
36
  surface: () => this.partNamed('surface'),
30
37
  });
38
+ this.handleKeyDown = (event) => {
39
+ if (event.key !== 'ArrowDown' || !this.open || event.defaultPrevented) {
40
+ return;
41
+ }
42
+ const trigger = this.trigger;
43
+ if (!event.composedPath().includes(trigger)) {
44
+ return;
45
+ }
46
+ const first = focusableElements(this).find((element) => element !== trigger && !element.closest('[slot="trigger"]'));
47
+ if (first) {
48
+ event.preventDefault();
49
+ first.focus();
50
+ }
51
+ };
31
52
  this.handleScroll = () => {
32
53
  if (!this.open || !this.banded) {
33
54
  return;
@@ -40,6 +61,9 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
40
61
  };
41
62
  this.handlePointerDown = (event) => {
42
63
  this.pointer = event.pointerType;
64
+ pressed = this;
65
+ window.addEventListener('pointerup', release, { capture: true, once: true });
66
+ window.addEventListener('pointercancel', release, { capture: true, once: true });
43
67
  };
44
68
  this.handlePointerEnter = (event) => {
45
69
  if (this.openOn !== 'hover' || event.pointerType !== 'mouse') {
@@ -62,6 +86,9 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
62
86
  if (!this.open || next === null || deepContains(this, next)) {
63
87
  return;
64
88
  }
89
+ if (pressed !== undefined && pressed !== this && deepContains(pressed, next)) {
90
+ return;
91
+ }
65
92
  this.requestOpen(false);
66
93
  };
67
94
  this.handleTriggerClick = (event) => {
@@ -72,6 +99,10 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
72
99
  }
73
100
  if (event.detail === 0 || (this.pointer !== undefined && this.pointer !== 'mouse')) {
74
101
  this.requestOpen(!this.open);
102
+ return;
103
+ }
104
+ if (!this.open) {
105
+ this.requestOpen(true);
75
106
  }
76
107
  };
77
108
  this.handleContentClick = (event) => {
@@ -88,6 +119,7 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
88
119
  }
89
120
  this.requestOpen(false);
90
121
  };
122
+ this.handedOver = false;
91
123
  }
92
124
  static { HelixHeadlessMegamenu_1 = this; }
93
125
  get banded() {
@@ -159,12 +191,14 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
159
191
  connectedCallback() {
160
192
  super.connectedCallback();
161
193
  this.watchWidth();
194
+ connected.add(this);
162
195
  window.addEventListener('scroll', this.handleScroll, { capture: true, passive: true });
163
196
  this.addEventListener('pointerdown', this.handlePointerDown);
164
197
  this.addEventListener('click', this.handleContentClick);
165
198
  this.addEventListener('pointerenter', this.handlePointerEnter);
166
199
  this.addEventListener('pointerleave', this.handlePointerLeave);
167
200
  this.addEventListener('focusout', this.handleFocusOut);
201
+ this.addEventListener('keydown', this.handleKeyDown);
168
202
  }
169
203
  disconnectedCallback() {
170
204
  super.disconnectedCallback();
@@ -176,6 +210,8 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
176
210
  this.removeEventListener('pointerenter', this.handlePointerEnter);
177
211
  this.removeEventListener('pointerleave', this.handlePointerLeave);
178
212
  this.removeEventListener('focusout', this.handleFocusOut);
213
+ this.removeEventListener('keydown', this.handleKeyDown);
214
+ connected.delete(this);
179
215
  this.stop();
180
216
  if (showing === this) {
181
217
  showing = undefined;
@@ -191,15 +227,49 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
191
227
  const forward = previous !== undefined &&
192
228
  (previous.compareDocumentPosition(this) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0;
193
229
  this.motion(previous ? (forward ? 'from-end' : 'from-start') : undefined);
230
+ this.from = previous?.size;
231
+ HelixHeadlessMegamenu_1.settle(this, previous);
194
232
  if (previous) {
195
- previous.motion(forward ? 'to-end' : 'to-start');
196
- previous.requestOpen(false);
233
+ previous.motion(forward ? 'to-start' : 'to-end');
234
+ previous.handedOver = true;
235
+ if (!previous.requestOpen(false)) {
236
+ previous.handedOver = false;
237
+ previous.motion(undefined);
238
+ }
197
239
  }
198
240
  showing = this;
241
+ return;
199
242
  }
200
- else if (showing === this) {
243
+ if (showing === this) {
201
244
  showing = undefined;
202
245
  }
246
+ if (!this.handedOver) {
247
+ HelixHeadlessMegamenu_1.settle();
248
+ }
249
+ this.handedOver = false;
250
+ }
251
+ static settle(...moving) {
252
+ for (const megamenu of connected) {
253
+ if (!moving.includes(megamenu)) {
254
+ megamenu.motion(undefined);
255
+ }
256
+ }
257
+ }
258
+ measure() {
259
+ const surface = this.partNamed('surface');
260
+ if (!surface) {
261
+ return;
262
+ }
263
+ surface.style.removeProperty('--megamenu-from-inline-size');
264
+ surface.style.removeProperty('--megamenu-from-block-size');
265
+ const box = surface.getBoundingClientRect();
266
+ this.size = { block: Math.round(box.height), inline: Math.round(box.width) };
267
+ surface.style.setProperty('--megamenu-surface-inline-size', `${this.size.inline}px`);
268
+ surface.style.setProperty('--megamenu-surface-block-size', `${this.size.block}px`);
269
+ if (this.from) {
270
+ surface.style.setProperty('--megamenu-from-inline-size', `${this.from.inline}px`);
271
+ surface.style.setProperty('--megamenu-from-block-size', `${this.from.block}px`);
272
+ }
203
273
  }
204
274
  motion(to) {
205
275
  this.toggleState('from-end', to === 'from-end');
@@ -216,6 +286,7 @@ let HelixHeadlessMegamenu = class HelixHeadlessMegamenu extends MixinControllerO
216
286
  this.tellTrigger();
217
287
  if (this.open) {
218
288
  this.band();
289
+ this.measure();
219
290
  }
220
291
  }
221
292
  renderTrigger() {
@@ -29,13 +29,25 @@ import '../../kbd/index.js';
29
29
  * nothing: the shortcut is the page's to bind. Other trailing words, such as a
30
30
  * count, go in the `end` slot.
31
31
  *
32
+ * The row is named by its label alone. Words in `description`, a line under the
33
+ * label, and in `end` describe it instead, through `aria-describedby`, as
34
+ * React Aria's menu item does with its description: a reader hears "Copy",
35
+ * then "Copies the selection".
36
+ *
37
+ * The check mark and the caret are the fallbacks of the `check` and `chevron`
38
+ * slots, so a mark of your own replaces either by being slotted. Neither is
39
+ * read as part of the row's name.
40
+ *
32
41
  * @since 0.1.0
33
42
  * @status stable
34
43
  * @aliases Menu option, Menu row
35
44
  * @documentation https://fusion.dev/helix/components/menu
36
45
  *
37
46
  * @slot - The label.
38
- * @slot end - Words after the label, such as a count or a detail, beside any `shortcut`.
47
+ * @slot check - Replaces the check mark of a checked row, such as with your own icon.
48
+ * @slot chevron - Replaces the caret of a row that opens a submenu.
49
+ * @slot description - A line under the label that describes the row. It describes the row to a screen reader and is not part of its name.
50
+ * @slot end - Words after the label, such as a count or a detail, beside any `shortcut`. They describe the row and are not part of its name.
39
51
  * @slot start - Content before the label, such as an icon.
40
52
  * @slot submenu - The rows of a submenu that this row opens.
41
53
  *
@@ -48,6 +60,8 @@ import '../../kbd/index.js';
48
60
  * when it opens a submenu. A row never shows both, so they share one column.
49
61
  * @csspart shortcut - The key drawn for `shortcut`.
50
62
  * @csspart shortcut-kbd - The key inside it.
63
+ * @csspart shortcut-key - One key of the shortcut's chord, such as `Ctrl`.
64
+ * @csspart shortcut-separator - The `+` between two keys of the shortcut, where the platform writes one.
51
65
  * @csspart start - The leading column that holds the `start` slot. It is always rendered.
52
66
  *
53
67
  * @cssstate checked - The row is checked.
@@ -201,6 +215,8 @@ export declare class HelixHeadlessMenuItem extends HelixElement {
201
215
  private start;
202
216
  /** Whether anything is slotted after the label, read the way `start` is. */
203
217
  private end;
218
+ /** Whether anything is slotted under the label, read the way `start` is. */
219
+ private description;
204
220
  /**
205
221
  * Both answers, from the children, before each render.
206
222
  *
@@ -223,13 +239,25 @@ export declare class HelixHeadlessMenuItem extends HelixElement {
223
239
  private readonly readStart;
224
240
  /** Re-reads whether anything is after the label, as `readStart` does before it. */
225
241
  private readonly readEnd;
242
+ /** Re-reads whether anything is under the label, as `readStart` does before it. */
243
+ private readonly readDescription;
244
+ /**
245
+ * The line under the label. The slot is hidden from the row's name and named
246
+ * by the row's `aria-describedby`, which reads it all the same: a description
247
+ * is read from what it points at, hidden or not. No box of its own, so a row
248
+ * with no description lays out as it did; `data-empty` says which it is.
249
+ */
250
+ protected renderDescription(): TemplateResult;
251
+ /** What describes the row: the line under its label and the words after it. */
252
+ private get describedBy();
226
253
  /**
227
254
  * The trailing column: the shortcut's key, then whatever is slotted in `end`.
228
255
  * Drawn by `Kbd`, interpolated so each tier draws its own.
229
256
  *
230
257
  * The key is hidden from the accessibility tree, since the row's
231
258
  * `aria-keyshortcuts` says it in words a screen reader reads as keys: inside
232
- * the row its glyphs became part of the row's name.
259
+ * the row its glyphs became part of the row's name. The `end` words are
260
+ * hidden from the name too, and describe the row instead.
233
261
  */
234
262
  protected renderEnd(): TemplateResult;
235
263
  /**
@@ -311,6 +339,27 @@ export declare class HelixHeadlessMenuItem extends HelixElement {
311
339
  * both announces and navigates.
312
340
  */
313
341
  private readonly handleKeydown;
342
+ /**
343
+ * The trailing mark: the caret of a row that opens a page, or the tick of a
344
+ * checked one, each the fallback of a slot a mark of your own replaces.
345
+ *
346
+ * One trailing column, and a row is never both: a way into a page has nothing
347
+ * to tick, and a choice opens nothing. The tick sits after the label rather
348
+ * than before it, so the labels start at the edge of the row and the marks
349
+ * line up down the side they are read from.
350
+ *
351
+ * `data-mirror` is what tells the two apart. They share a part name because
352
+ * they share a column, and only one of them is directional: a caret has to
353
+ * mirror in a right-to-left document and a tick must not, which Unicode's own
354
+ * mirroring list agrees on. The attribute is on an element in this shadow
355
+ * root rather than on the host, so it is the divider's `data-empty` and not a
356
+ * hydration hazard.
357
+ *
358
+ * Nothing to mark, so nothing is drawn. The column this would have sat in is
359
+ * reserved by the menu when some row on the page needs one, so the labels
360
+ * still line up without every row carrying an empty box to line them up with.
361
+ */
362
+ protected renderMark(submenu: boolean): TemplateResult | typeof nothing;
314
363
  protected render(): TemplateResult | typeof nothing;
315
364
  }
316
365
  declare global {