@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
@@ -0,0 +1,16 @@
1
+ const clamp = (value, low, high) => Math.min(Math.max(value, low), high) || 0;
2
+ export const clampScale = (scale, max) => clamp(scale, 1, Math.max(max, 1));
3
+ export const clampPan = (pan, scale, width, height) => {
4
+ const x = ((scale - 1) * width) / 2;
5
+ const y = ((scale - 1) * height) / 2;
6
+ return { x: clamp(pan.x, -x, x), y: clamp(pan.y, -y, y) };
7
+ };
8
+ export const zoomAt = (at, from, to, pan) => ({
9
+ x: at.x - ((at.x - pan.x) * to) / from,
10
+ y: at.y - ((at.y - pan.y) * to) / from,
11
+ });
12
+ export const spread = (a, b) => Math.hypot(a.x - b.x, a.y - b.y);
13
+ export const between = (a, b) => ({
14
+ x: (a.x + b.x) / 2,
15
+ y: (a.y + b.y) / 2,
16
+ });
@@ -49,6 +49,8 @@ declare const HelixHeadlessLineChart_base: typeof HelixElement & (new (...args:
49
49
  * @csspart line - The line for one series.
50
50
  * @csspart live - The readout: a polite live region that says the reading the keys moved to. Hide it visually.
51
51
  * @csspart mark - The invisible point the tooltip is anchored to.
52
+ * @csspart marker - The mark on one reading, under `markers`, and on a reading with a blank on either side. Placed with `inset-inline-start` and `inset-block-start`, and carries its series color as `--chart-series`.
53
+ * @csspart marker-lone - A `marker` on a reading with a blank on either side, which no line reaches. Set alongside `marker`.
52
54
  * @csspart plot - The drawing, which takes focus to be read by key.
53
55
  * @csspart summary - The chart's name and each series' latest reading, written as a sentence for screen readers. Hide it visually.
54
56
  * @csspart svg - The drawing surface the lines and areas sit on.
@@ -138,6 +140,15 @@ export declare class HelixHeadlessLineChart extends HelixHeadlessLineChart_base
138
140
  protected get rulesValue(): boolean;
139
141
  /** Whether each reading is ruled, which only two values ask for. */
140
142
  protected get rulesCategory(): boolean;
143
+ /**
144
+ * Draws a mark on every reading, the `marker` part, so a reader sees where
145
+ * the readings are, as well as the line between them.
146
+ *
147
+ * Absent draws none, except on a reading with a blank on either side: it
148
+ * has no line to be part of, so it takes a mark, the `marker` part with
149
+ * `marker-lone` beside it, or it would not be drawn at all.
150
+ */
151
+ markers: boolean;
141
152
  /**
142
153
  * The shape of the mark on each series' last reading.
143
154
  *
@@ -200,7 +211,8 @@ export declare class HelixHeadlessLineChart extends HelixHeadlessLineChart_base
200
211
  * The latest, because where a series ended is the question a line over time
201
212
  * is asked first, which is what `AreaChart` gives too. Each series' own last
202
213
  * reading, so a series with a blank in the last row still says where it was.
203
- * Written the way the table writes it, such as `$128k` for `128000`.
214
+ * Written the way the table writes it, such as `$128k` for `128000`. A
215
+ * series a legend hid is not drawn and is not said.
204
216
  */
205
217
  protected renderSummary(series: Series[]): TemplateResult;
206
218
  /**
@@ -255,6 +267,15 @@ export declare class HelixHeadlessLineChart extends HelixHeadlessLineChart_base
255
267
  x: number;
256
268
  y: number;
257
269
  }>): TemplateResult | typeof nothing;
270
+ /**
271
+ * The marks on the readings: every one under `markers`, and otherwise only
272
+ * a reading no line reaches, which has a blank on either side.
273
+ *
274
+ * Elements beside the drawing, as the termini are, so a mark is round in a
275
+ * drawing `preserveAspectRatio="none"` stretches. Placed from the inline
276
+ * start, as the drawing is mirrored.
277
+ */
278
+ protected renderMarkers(series: Series[], x: (value: number) => number, y: (value: number) => number): TemplateResult | typeof nothing;
258
279
  /**
259
280
  * One series, its wash first so the line is drawn over its own fill.
260
281
  *
@@ -12,6 +12,7 @@ let HelixHeadlessLineChart = class HelixHeadlessLineChart extends MixinChartSour
12
12
  constructor() {
13
13
  super(...arguments);
14
14
  this.area = false;
15
+ this.markers = false;
15
16
  this.zero = false;
16
17
  }
17
18
  get rulesValue() {
@@ -62,7 +63,7 @@ let HelixHeadlessLineChart = class HelixHeadlessLineChart extends MixinChartSour
62
63
  const columns = this.plottedColumns;
63
64
  const latest = series.flatMap((one, depth) => {
64
65
  const last = one.points.at(-1);
65
- if (last === undefined) {
66
+ if (last === undefined || !this.showsSeries(one.name)) {
66
67
  return [];
67
68
  }
68
69
  const text = rows[last.at]?.cells[columns[depth] ?? -1]?.text ?? String(last.value);
@@ -109,6 +110,7 @@ let HelixHeadlessLineChart = class HelixHeadlessLineChart extends MixinChartSour
109
110
  ${series.map((one, depth) => this.renderSeries(one, depth, x, y))}
110
111
  </svg>
111
112
  ${this.renderTermini(ends)}
113
+ ${this.renderMarkers(series, x, y)}
112
114
  ${this.renderTooltip()}
113
115
  </div>`;
114
116
  }
@@ -149,6 +151,21 @@ let HelixHeadlessLineChart = class HelixHeadlessLineChart extends MixinChartSour
149
151
  style=${`--chart-series: var(--chart-series-${end.index}); --chart-terminus-x: ${end.x}%; --chart-terminus-y: ${end.y}%`}
150
152
  ></span>`)}`;
151
153
  }
154
+ renderMarkers(series, x, y) {
155
+ const marks = series.flatMap((one, depth) => this.showsSeries(one.name)
156
+ ? unbroken(one).flatMap((run) => run.length > 1 && !this.markers
157
+ ? []
158
+ : run.map((point) => ({ depth, lone: run.length === 1, point })))
159
+ : []);
160
+ if (marks.length === 0) {
161
+ return nothing;
162
+ }
163
+ return html `${marks.map(({ depth, lone, point }) => html `<span
164
+ aria-hidden="true"
165
+ part="marker${lone ? ' marker-lone' : ''}"
166
+ style=${`--chart-series: var(--chart-series-${seriesIndex(depth)}); inset-inline-start: ${(x(point.at) / PLOT_WIDTH) * 100}%; inset-block-start: ${(y(point.value) / PLOT_HEIGHT) * 100}%`}
167
+ ></span>`)}`;
168
+ }
152
169
  renderSeries(one, depth, x, y) {
153
170
  if (!this.showsSeries(one.name)) {
154
171
  return html `${nothing}`;
@@ -221,6 +238,9 @@ __decorate([
221
238
  __decorate([
222
239
  property()
223
240
  ], HelixHeadlessLineChart.prototype, "gridlines", void 0);
241
+ __decorate([
242
+ property({ reflect: true, type: Boolean })
243
+ ], HelixHeadlessLineChart.prototype, "markers", void 0);
224
244
  __decorate([
225
245
  property({ reflect: true })
226
246
  ], HelixHeadlessLineChart.prototype, "terminus", void 0);
@@ -109,6 +109,8 @@ export declare class HelixHeadlessListItem extends HelixElement {
109
109
  value: string;
110
110
  /** The row's words, or none where the children are not known yet. */
111
111
  get words(): string;
112
+ /** Whether something is slotted into `description`, or false where the children are not known yet. */
113
+ private get described();
112
114
  /** Whether a list with `selection-mode` holds this row, which makes it a row of a grid. */
113
115
  private get grouped();
114
116
  /** @internal The cell a list with `selection-mode` moves focus to. */
@@ -20,6 +20,9 @@ let HelixHeadlessListItem = class HelixHeadlessListItem extends HelixElement {
20
20
  get words() {
21
21
  return this.childrenKnown ? slottedWords(this, ['']) : '';
22
22
  }
23
+ get described() {
24
+ return this.childrenKnown && this.knownChildren.some((child) => child.slot === 'description');
25
+ }
23
26
  get grouped() {
24
27
  return this.focusable !== undefined;
25
28
  }
@@ -54,20 +57,26 @@ let HelixHeadlessListItem = class HelixHeadlessListItem extends HelixElement {
54
57
  }
55
58
  render() {
56
59
  const content = html `${this.renderRail()}<slot name="start"></slot>
57
- <slot></slot>
58
- <slot name="description"></slot>`;
60
+ <slot id="label"></slot>
61
+ <slot name="description" id="description"></slot>`;
59
62
  const role = this.grouped ? 'gridcell' : nothing;
60
63
  const tabindex = this.grouped ? (this.focusable ? '0' : '-1') : nothing;
64
+ const labelledby = this.grouped && this.words !== '' ? 'label' : nothing;
65
+ const describedby = this.grouped && this.described ? 'description' : nothing;
61
66
  return this.href === ''
62
67
  ? html `<div
63
68
  part="row${this.current === undefined ? '' : ' row-current'}"
64
69
  role=${role}
65
70
  tabindex=${tabindex}
71
+ aria-labelledby=${labelledby}
72
+ aria-describedby=${describedby}
66
73
  >${content}<slot name="end"></slot></div>`
67
74
  : html `<div
68
75
  part="row${this.current === undefined ? '' : ' row-current'}"
69
76
  role=${role}
70
77
  tabindex=${tabindex}
78
+ aria-labelledby=${labelledby}
79
+ aria-describedby=${describedby}
71
80
  ><a
72
81
  part="link"
73
82
  href=${this.href}
@@ -1,7 +1,7 @@
1
1
  import { HelixElement, KeyboardNavigationController } from '@fusion.dev/helix-core';
2
2
  import { type PropertyValues, type TemplateResult } from 'lit';
3
3
  import { HelixHeadlessListItem } from '../item/list-item.js';
4
- import { type ListSelectionMode } from '../selection.js';
4
+ import { type ListSelectionBehavior, type ListSelectionMode } from '../selection.js';
5
5
  /**
6
6
  * @summary A set of rows, announced as a list.
7
7
  *
@@ -10,15 +10,33 @@ import { type ListSelectionMode } from '../selection.js';
10
10
  * announces each one's position, such as "1 of 7".
11
11
  *
12
12
  * **`selection-mode` makes the list interactive**, in the way of a grid list:
13
- * a grid of rows that is one tab stop. Up and Down move between rows, Home
14
- * and End go to the first and the last, and a typed letter goes to the next
15
- * row starting with it. Left and Right move between the row and the controls
16
- * in its `end` slot. `single` selects one row at a time and `multiple` any
17
- * number, with Space or a press, and `value` holds the selected rows' values,
13
+ * a grid of rows that is one tab stop. `single` selects one row at a time and
14
+ * `multiple` any number, and `value` holds the selected rows' values,
18
15
  * separated by commas. A change asks with `helix-before-change` and tells
19
- * with `change`. Enter acts on the row: it follows the row's link, or sends
20
- * `helix-action` from the row. `none` selects nothing, so a press acts too. A
21
- * `disabled` row is passed over.
16
+ * with `change`. `none` selects nothing, so a press acts on the row. A
17
+ * `disabled` row is passed over. Each row is named by its label and described
18
+ * by its description, so the words of the controls in `end` are not read as
19
+ * part of its name.
20
+ *
21
+ * `selection-behavior` says what a press does to the rows already selected.
22
+ * `toggle`, the default, adds or takes out the row. `replace` selects the row
23
+ * alone, as a file list does, and the arrow keys carry the selection with
24
+ * them. Control or Command with a press then adds or takes out one row.
25
+ *
26
+ * | Key | What it does |
27
+ * |---|---|
28
+ * | Down, Up | Moves to the next or the previous row. Under `replace`, selects it. |
29
+ * | Home, End | Moves to the first or the last row. Under `replace`, selects it. |
30
+ * | A letter or a word | Moves to the next row whose words start with what you typed. |
31
+ * | Left, Right | Moves between the row and the controls in its `end` slot. |
32
+ * | Space | Selects the row, or lets it go. |
33
+ * | Shift with Down, Up, Home, End or Space | Selects every row from the last one pressed, in `multiple`. |
34
+ * | Control or Command with Down, Up, Home or End | Moves without selecting, under `replace`. |
35
+ * | Control or Command with A | Selects every row, in `multiple`. |
36
+ * | Enter | Acts on the row: follows its link, or sends `helix-action` from it. |
37
+ *
38
+ * A press with Shift selects every row from the last one pressed, and a press
39
+ * with Control or Command adds or takes out one row under `replace`.
22
40
  *
23
41
  * **Leave `selection-mode` unset for a list a reader reads**, and set it for
24
42
  * one a reader chooses from or acts on. The rows of an interactive list are
@@ -80,6 +98,12 @@ export declare class HelixHeadlessList extends HelixElement {
80
98
  * its last row, as `<ol reversed>` does.
81
99
  */
82
100
  reversed: boolean;
101
+ /**
102
+ * What a press does to the rows already selected, in a list that selects:
103
+ * `toggle` adds or takes out the row, and `replace` selects it alone and
104
+ * lets the arrow keys carry the selection.
105
+ */
106
+ selectionBehavior: ListSelectionBehavior;
83
107
  /**
84
108
  * Makes the list interactive: `single` selects one row, `multiple` any
85
109
  * number, and `none` moves and acts without selecting. Unset is a list a
@@ -112,6 +136,13 @@ export declare class HelixHeadlessList extends HelixElement {
112
136
  value: string;
113
137
  /** The row the reader was last on, which keeps the tab stop. */
114
138
  private last;
139
+ /** The value of the row a Shift range runs from: the last row pressed. */
140
+ private anchor;
141
+ /**
142
+ * Shift and Control or Command on the key that is moving focus, read when
143
+ * focus arrives on a row and cleared once the key has been answered.
144
+ */
145
+ private moving;
115
146
  /**
116
147
  * Up, Down, Home, End and typed letters, moving focus and choosing nothing,
117
148
  * from the focused row and without wrapping. Left and Right are the row's.
@@ -136,15 +167,33 @@ export declare class HelixHeadlessList extends HelixElement {
136
167
  /** The row a press or a key came from, read off the event's path. */
137
168
  private rowOf;
138
169
  /**
139
- * Selects the row, or lets it go, asking first. `helix-before-change`
140
- * carries the `value` the press would leave, and `change` follows once it
141
- * has moved.
170
+ * Selects what a press or a key leaves, asking first. `helix-before-change`
171
+ * carries the `value` it would leave, and `change` follows once it has moved.
142
172
  */
143
- protected press(row: HelixHeadlessListItem): void;
173
+ private choose;
174
+ /** What `choiceValue` needs of this list for a row. */
175
+ private choice;
176
+ /**
177
+ * Selects the row, or lets it go, by `selection-behavior`: Shift takes in
178
+ * the rows from the last one pressed, and Control or Command toggles one row
179
+ * under `replace`. The row is where the next range runs from.
180
+ */
181
+ protected press(row: HelixHeadlessListItem, extend?: boolean, toggle?: boolean): void;
182
+ /**
183
+ * A key moved focus onto the row: under `replace` it is selected alone, and
184
+ * with Shift the rows from the anchor are taken in, from `from` where
185
+ * nothing was pressed yet.
186
+ */
187
+ private arrive;
144
188
  /** Acts on the row: follows its link, or says it was acted on. */
145
189
  protected act(row: HelixHeadlessListItem): void;
146
190
  /** Left and Right inside a row: the cell, then each control in `end`, and back. */
147
191
  private moveInRow;
192
+ /**
193
+ * Notes the modifiers of a key before the keyboard controller moves focus
194
+ * with it, which happens first, in the same dispatch.
195
+ */
196
+ private readonly handleKeyCapture;
148
197
  private readonly handleKeydown;
149
198
  private readonly handleClick;
150
199
  private readonly handleFocusin;
@@ -4,46 +4,57 @@ 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, HelixActionEvent, HelixBeforeChangeEvent, HelixElement, hostAria, inlineStep, KeyboardNavigationController, requestChange, rovingStop, whenHydrated, } from '@fusion.dev/helix-core';
7
+ import { commaList, customElement, HelixActionEvent, HelixBeforeChangeEvent, HelixElement, hostAria, inlineStep, KeyboardNavigationController, requestChange, rovingStop, typeaheadBy, whenHydrated, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  import { HelixHeadlessListItem } from '../item/list-item.js';
11
11
  import { numbering } from '../numbering.js';
12
- import { pressedValue, rowStop } from '../selection.js';
12
+ import { choiceValue, rowStop, } from '../selection.js';
13
13
  const PRESSABLE = 'a[href], button, input, label, select, textarea, [tabindex]';
14
14
  let HelixHeadlessList = class HelixHeadlessList extends HelixElement {
15
15
  constructor() {
16
16
  super(...arguments);
17
17
  this.label = '';
18
18
  this.reversed = false;
19
+ this.selectionBehavior = 'toggle';
19
20
  this.value = '';
20
21
  this.keys = new KeyboardNavigationController(this, {
21
22
  items: () => this.reachable.map((row) => this.navigable(row)),
22
23
  origin: 'focus',
23
24
  reserved: () => ['ArrowLeft', 'ArrowRight'],
24
25
  selects: () => false,
25
- typeahead: (item) => item.words,
26
+ typeahead: typeaheadBy((item) => item.words),
26
27
  wrap: false,
27
28
  });
29
+ this.handleKeyCapture = (event) => {
30
+ this.moving = { extend: event.shiftKey, toggle: event.ctrlKey || event.metaKey };
31
+ };
28
32
  this.handleKeydown = (event) => {
33
+ this.moving = undefined;
29
34
  const row = this.interactive ? this.rowOf(event) : undefined;
30
- if (!row || row.disabled || event.altKey || event.ctrlKey || event.metaKey) {
35
+ if (!row || row.disabled || event.altKey) {
31
36
  return;
32
37
  }
33
- if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
38
+ const toggle = event.ctrlKey || event.metaKey;
39
+ if (!toggle && (event.key === 'ArrowLeft' || event.key === 'ArrowRight')) {
34
40
  this.moveInRow(row, event);
35
41
  return;
36
42
  }
37
43
  if (event.composedPath()[0] !== row.cell) {
38
44
  return;
39
45
  }
40
- if (event.key === 'Enter') {
46
+ if (toggle && event.key.toLowerCase() === 'a' && this.selectionMode === 'multiple') {
47
+ event.preventDefault();
48
+ const every = this.reachable.map((one) => this.valueFor(one)).join(', ');
49
+ this.choose(every === this.value ? null : every);
50
+ }
51
+ else if (event.key === 'Enter' && !toggle) {
41
52
  event.preventDefault();
42
53
  this.act(row);
43
54
  }
44
- else if (event.key === ' ') {
55
+ else if (event.key === ' ' && !event.defaultPrevented) {
45
56
  event.preventDefault();
46
- this.press(row);
57
+ this.press(row, event.shiftKey, toggle);
47
58
  }
48
59
  };
49
60
  this.handleClick = (event) => {
@@ -62,13 +73,17 @@ let HelixHeadlessList = class HelixHeadlessList extends HelixElement {
62
73
  this.act(row);
63
74
  }
64
75
  else {
65
- this.press(row);
76
+ this.press(row, event.shiftKey, event.ctrlKey || event.metaKey);
66
77
  }
67
78
  };
68
79
  this.handleFocusin = (event) => {
69
80
  const row = this.interactive ? this.rowOf(event) : undefined;
70
81
  if (row && row !== this.last) {
82
+ const from = this.last;
71
83
  this.last = row;
84
+ if (event.composedPath()[0] === row.cell) {
85
+ this.arrive(row, from);
86
+ }
72
87
  this.sync();
73
88
  }
74
89
  };
@@ -121,9 +136,8 @@ let HelixHeadlessList = class HelixHeadlessList extends HelixElement {
121
136
  .composedPath()
122
137
  .find((node) => node instanceof HelixHeadlessListItem && node.parentElement === this);
123
138
  }
124
- press(row) {
125
- const mode = this.selectionMode;
126
- if (mode === undefined || mode === 'none' || row.disabled) {
139
+ choose(next) {
140
+ if (next === null) {
127
141
  return;
128
142
  }
129
143
  requestChange({
@@ -133,9 +147,47 @@ let HelixHeadlessList = class HelixHeadlessList extends HelixElement {
133
147
  },
134
148
  event: (value) => new HelixBeforeChangeEvent({ value }),
135
149
  host: this,
136
- next: pressedValue(mode, this.value, this.valueFor(row)),
150
+ next,
137
151
  });
138
152
  }
153
+ choice(row, extend, toggle, arrived) {
154
+ return {
155
+ anchor: this.anchor,
156
+ arrived,
157
+ behavior: this.selectionBehavior,
158
+ extend,
159
+ mode: this.selectionMode ?? 'none',
160
+ pressed: this.valueFor(row),
161
+ shown: this.reachable.map((one) => this.valueFor(one)),
162
+ toggle,
163
+ value: this.value,
164
+ };
165
+ }
166
+ press(row, extend = false, toggle = false) {
167
+ const mode = this.selectionMode;
168
+ if (mode === undefined || mode === 'none' || row.disabled) {
169
+ return;
170
+ }
171
+ const next = choiceValue(this.choice(row, extend, toggle, false));
172
+ if (!extend) {
173
+ this.anchor = this.valueFor(row);
174
+ }
175
+ this.choose(next);
176
+ }
177
+ arrive(row, from) {
178
+ const moving = this.moving;
179
+ if (!moving || this.selectionMode === undefined || this.selectionMode === 'none') {
180
+ return;
181
+ }
182
+ if (moving.extend && this.anchor === undefined && from) {
183
+ this.anchor = this.valueFor(from);
184
+ }
185
+ const next = choiceValue(this.choice(row, moving.extend, moving.toggle, true));
186
+ if (!moving.extend && next !== null) {
187
+ this.anchor = this.valueFor(row);
188
+ }
189
+ this.choose(next);
190
+ }
139
191
  act(row) {
140
192
  if (row.disabled) {
141
193
  return;
@@ -160,12 +212,14 @@ let HelixHeadlessList = class HelixHeadlessList extends HelixElement {
160
212
  }
161
213
  connectedCallback() {
162
214
  super.connectedCallback();
215
+ this.addEventListener('keydown', this.handleKeyCapture, true);
163
216
  this.addEventListener('keydown', this.handleKeydown);
164
217
  this.addEventListener('click', this.handleClick);
165
218
  this.addEventListener('focusin', this.handleFocusin);
166
219
  }
167
220
  disconnectedCallback() {
168
221
  super.disconnectedCallback();
222
+ this.removeEventListener('keydown', this.handleKeyCapture, true);
169
223
  this.removeEventListener('keydown', this.handleKeydown);
170
224
  this.removeEventListener('click', this.handleClick);
171
225
  this.removeEventListener('focusin', this.handleFocusin);
@@ -202,6 +256,9 @@ __decorate([
202
256
  __decorate([
203
257
  property({ type: Boolean })
204
258
  ], HelixHeadlessList.prototype, "reversed", void 0);
259
+ __decorate([
260
+ property({ attribute: 'selection-behavior' })
261
+ ], HelixHeadlessList.prototype, "selectionBehavior", void 0);
205
262
  __decorate([
206
263
  property({ attribute: 'selection-mode' })
207
264
  ], HelixHeadlessList.prototype, "selectionMode", void 0);
@@ -1,13 +1,43 @@
1
- /** How many rows a reader can select in an interactive list. */
2
- export type ListSelectionMode = 'multiple' | 'none' | 'single';
1
+ import { type SelectionMode } from '@fusion.dev/helix-core';
2
+ /** How many rows a reader can select in an interactive list: core's `SelectionMode`. */
3
+ export type ListSelectionMode = SelectionMode;
3
4
  /**
4
- * The `value` a press on the row carrying `pressed` leaves.
5
+ * What a press does to the rows already selected: `toggle` adds or takes out
6
+ * the row, and `replace` selects it alone, as a file list does.
7
+ */
8
+ export type ListSelectionBehavior = 'replace' | 'toggle';
9
+ /** A press on a row, or a key arriving on one, and what the list held then. */
10
+ export interface ListChoice {
11
+ /** The list's `selection-mode`. */
12
+ mode: ListSelectionMode;
13
+ /** The list's `selection-behavior`. */
14
+ behavior: ListSelectionBehavior;
15
+ /** The list's `value`, before the press. */
16
+ value: string;
17
+ /** The value of the row pressed or arrived on. */
18
+ pressed: string;
19
+ /** The values of the rows a reader can reach, in order. */
20
+ shown: readonly string[];
21
+ /** The value of the row a range runs from, where there is one. */
22
+ anchor?: string | undefined;
23
+ /** Whether Shift was held, which takes in the rows from the anchor. */
24
+ extend?: boolean;
25
+ /** Whether Control or Command was held, which toggles under `replace` and moves without choosing. */
26
+ toggle?: boolean;
27
+ /** Whether a key moved focus onto the row, where a press is false. */
28
+ arrived?: boolean;
29
+ }
30
+ /**
31
+ * The `value` a press or an arrival leaves, or `null` where it changes nothing.
5
32
  *
6
- * `single` selects that row alone, or none where it was the one selected.
7
- * `multiple` adds it, or takes it out. `none` selects nothing and leaves the
8
- * value as it was. Tag Group answers the same question for its tags.
33
+ * - With Shift, in a list that selects many, every row from the anchor to this
34
+ * one is added, as Data Table and Listbox add a range.
35
+ * - Under `replace`, the row is selected alone, by a press or by a key moving
36
+ * onto it. Control or Command toggles it under a press, and moves without
37
+ * choosing under a key.
38
+ * - Under `toggle`, a press adds or takes out the row, and a key only moves.
9
39
  */
10
- export declare const pressedValue: (mode: ListSelectionMode, value: string, pressed: string) => string;
40
+ export declare const choiceValue: ({ anchor, arrived, behavior, extend, mode, pressed, shown, toggle, value, }: ListChoice) => string | null;
11
41
  /**
12
42
  * Where Left or Right goes inside a row: `at` is the row's place among its
13
43
  * `count` stops, the cell first and its controls after it, and `step` is the
@@ -1,13 +1,22 @@
1
- import { commaList, toggleValue } from '@fusion.dev/helix-core';
2
- export const pressedValue = (mode, value, pressed) => {
1
+ import { commaList, pressedValue, rangeAdd } from '@fusion.dev/helix-core';
2
+ export const choiceValue = ({ anchor, arrived = false, behavior, extend = false, mode, pressed, shown, toggle = false, value, }) => {
3
+ if (mode === 'none') {
4
+ return null;
5
+ }
3
6
  const now = commaList(value);
4
- if (mode === 'single') {
5
- return now.includes(pressed) ? '' : pressed;
7
+ if (extend && mode === 'multiple') {
8
+ const from = anchor === undefined ? -1 : shown.indexOf(anchor);
9
+ const range = rangeAdd(now, shown, from, shown.indexOf(pressed));
10
+ return range ? range.join(', ') : null;
11
+ }
12
+ if (behavior === 'replace' && !toggle) {
13
+ return now.length === 1 && now[0] === pressed ? null : pressed;
6
14
  }
7
- if (mode === 'multiple') {
8
- return toggleValue(now, pressed).join(', ');
15
+ if (arrived) {
16
+ return null;
9
17
  }
10
- return value;
18
+ const next = pressedValue(mode, value, pressed);
19
+ return next === value ? null : next;
11
20
  };
12
21
  export const rowStop = (count, at, step) => {
13
22
  if (count <= 1) {
@@ -44,18 +44,22 @@ declare const HelixHeadlessListbox_base: (new (...args: any[]) => import("@fusio
44
44
  *
45
45
  * @slot - The options, and any groups of them.
46
46
  * @slot empty - What the list shows when it has no options to show, for content richer than `empty-text`.
47
+ * @slot error - What the list shows while `load-error` is set, for content richer than its text.
47
48
  * @slot feedback - The message that says what is wrong, for content richer than a string. It shows while there is a message.
48
49
  * @slot filter-icon - The icon in the filter field. Defaults to a magnifying glass.
49
50
  * @slot hint - The hint, for content richer than plain text.
50
51
  * @slot label - The label, for content richer than plain text.
51
52
  * @slot loading - What the list shows while its options load, for content richer than `loading-text`.
53
+ * @slot no-results - What the list shows when a filter hides every option, for content richer than `no-results-text`.
52
54
  *
53
55
  * @event {Event} change - Fired after the value changes.
54
56
  * @event {HelixBeforeChangeEvent} helix-before-change - Fired when the value is about to change, and cancelable.
55
57
  * @event {HelixFilterEvent} helix-filter - Fired before the list is filtered, and cancelable.
58
+ * @event {HelixLoadMoreEvent} helix-load-more - Fired once the list is scrolled within a screen of its end, once for each number of options, and not while `loading` is set. Add the next page of options and set `loading` while you fetch it.
56
59
  * @event {Event} input - Fired after the value changes.
57
60
  *
58
- * @csspart empty - The text shown when the filter hides every option.
61
+ * @csspart empty - The text shown when the list has no options to show, or the filter hides every one. `:state(no-results)` is set for the second.
62
+ * @csspart error - The text shown while `load-error` is set.
59
63
  * @csspart feedback - The message that says what is wrong with the value.
60
64
  * @csspart filter-icon - The icon beside the filter field.
61
65
  * @csspart filter-mark - The default icon beside the filter field, shown when none is slotted.
@@ -68,8 +72,10 @@ declare const HelixHeadlessListbox_base: (new (...args: any[]) => import("@fusio
68
72
  * @csspart search-field - The filter field.
69
73
  *
70
74
  * @cssstate empty - The list has no options to show: none were given, or the filter hid every one.
75
+ * @cssstate error - While `load-error` is set.
71
76
  * @cssstate invalid - The control has an error to show, from the browser's validation or from your `feedback`.
72
77
  * @cssstate loading - While `loading` is set.
78
+ * @cssstate no-results - A filter hid every option of a list that has some.
73
79
  */
74
80
  export declare class HelixHeadlessListbox extends HelixHeadlessListbox_base {
75
81
  protected readonly aria: AriaForwardController;
@@ -130,6 +136,14 @@ export declare class HelixHeadlessListbox extends HelixHeadlessListbox_base {
130
136
  * Placeholder text for the filter field.
131
137
  */
132
138
  filterLabel: string;
139
+ /**
140
+ * What the list says when its options could not be loaded, such as after a
141
+ * request to a server fails. Empty is no error.
142
+ *
143
+ * Set, it shows under any options there are, in place of `empty-text` and
144
+ * `loading-text`, and a screen reader hears it. Clear it when you ask again.
145
+ */
146
+ loadError: string;
133
147
  /**
134
148
  * Stops the arrow keys from choosing each option they move to. Enter, Space
135
149
  * or a click chooses the highlighted option.
@@ -143,6 +157,13 @@ export declare class HelixHeadlessListbox extends HelixHeadlessListbox_base {
143
157
  * Whether more than one option can be chosen.
144
158
  */
145
159
  multiple: boolean;
160
+ /**
161
+ * The text shown when a filter hides every option of a list that has some.
162
+ *
163
+ * Absent, the list says `empty-text` in both cases. Set it to tell "nothing
164
+ * matches what you typed" from "there is nothing here".
165
+ */
166
+ noResultsText?: string;
146
167
  /**
147
168
  * What a screen reader hears when a filter leaves one option. `{count}` is
148
169
  * the count.
@@ -430,6 +451,14 @@ export declare class HelixHeadlessListbox extends HelixHeadlessListbox_base {
430
451
  private takeFilter;
431
452
  /** Filters at once on a filter still waiting out `filterDelay`. */
432
453
  private flushFilter;
454
+ /** The number of options the list last asked for more at. */
455
+ private askedAt;
456
+ /**
457
+ * Asks for more once the reader is within a screen of the end, React Aria's
458
+ * `onLoadMore`: once for each number of options, so a scroll that goes on
459
+ * asks again only after the next page arrived, and never while loading.
460
+ */
461
+ private readonly handleScroll;
433
462
  /** Requests a new filter, and returns whether the request went through. */
434
463
  requestFilter(next: string): boolean;
435
464
  /**
@@ -485,6 +514,13 @@ export declare class HelixHeadlessListbox extends HelixHeadlessListbox_base {
485
514
  * the live region still says it.
486
515
  */
487
516
  protected renderStatus(hasContent: boolean): TemplateResult | typeof nothing;
517
+ /**
518
+ * Whether a filter hid every option of a list that has some, which is a
519
+ * different thing to say from a list that has none.
520
+ */
521
+ private get noResults();
522
+ /** The error, or what a filter that hid everything says, before the shared words. */
523
+ protected renderLive(hasContent: boolean): TemplateResult;
488
524
  protected render(): TemplateResult;
489
525
  }
490
526
  declare global {