@fusion.dev/helix-headless 0.143.0 → 0.145.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 (314) hide show
  1. package/custom-elements.json +16990 -1383
  2. package/dist/accordion/item/accordion-item.d.ts +48 -12
  3. package/dist/accordion/item/accordion-item.js +26 -5
  4. package/dist/accordion/root/accordion-root.d.ts +6 -0
  5. package/dist/accordion/root/accordion-root.js +7 -1
  6. package/dist/announcement/root/announcement-root.d.ts +21 -1
  7. package/dist/announcement/root/announcement-root.js +36 -1
  8. package/dist/app-header/root/app-header-root.d.ts +7 -0
  9. package/dist/app-header/root/app-header-root.js +5 -1
  10. package/dist/app-header/sectioning.d.ts +7 -0
  11. package/dist/app-header/sectioning.js +26 -0
  12. package/dist/area-chart/root/area-chart-root.d.ts +12 -4
  13. package/dist/area-chart/root/area-chart-root.js +24 -7
  14. package/dist/avatar/root/avatar-root.d.ts +14 -0
  15. package/dist/avatar/root/avatar-root.js +23 -9
  16. package/dist/badge/root/badge-root.d.ts +11 -7
  17. package/dist/badge/root/badge-root.js +1 -1
  18. package/dist/bar-chart/root/bar-chart-root.d.ts +12 -3
  19. package/dist/bar-chart/root/bar-chart-root.js +17 -10
  20. package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +32 -1
  21. package/dist/breadcrumbs/root/breadcrumbs-root.js +25 -2
  22. package/dist/button/root/button-root.d.ts +47 -1
  23. package/dist/button/root/button-root.js +38 -4
  24. package/dist/callout/root/callout-root.d.ts +18 -1
  25. package/dist/callout/root/callout-root.js +15 -4
  26. package/dist/canvas/root/canvas-root.d.ts +38 -3
  27. package/dist/canvas/root/canvas-root.js +121 -40
  28. package/dist/card/root/card-root.d.ts +30 -1
  29. package/dist/card/root/card-root.js +38 -5
  30. package/dist/carousel/root/carousel-root.d.ts +90 -0
  31. package/dist/carousel/root/carousel-root.js +134 -12
  32. package/dist/chat/composer/chat-composer.d.ts +38 -6
  33. package/dist/chat/composer/chat-composer.js +42 -9
  34. package/dist/chat/message/chat-message.d.ts +32 -1
  35. package/dist/chat/message/chat-message.js +25 -9
  36. package/dist/chat/naming.d.ts +22 -0
  37. package/dist/chat/naming.js +12 -0
  38. package/dist/chat/relative-clock.d.ts +39 -0
  39. package/dist/chat/relative-clock.js +31 -0
  40. package/dist/chat/root/chat-root.d.ts +36 -0
  41. package/dist/chat/root/chat-root.js +24 -1
  42. package/dist/checkbox/root/checkbox-root.js +2 -0
  43. package/dist/checkbox-group/root/checkbox-group-root.d.ts +53 -3
  44. package/dist/checkbox-group/root/checkbox-group-root.js +71 -22
  45. package/dist/code-block/lines.d.ts +13 -0
  46. package/dist/code-block/lines.js +2 -0
  47. package/dist/code-block/root/code-block-root.d.ts +38 -1
  48. package/dist/code-block/root/code-block-root.js +28 -7
  49. package/dist/color-input/root/color-input-root.d.ts +34 -1
  50. package/dist/color-input/root/color-input-root.js +23 -4
  51. package/dist/color-picker/channels.d.ts +26 -0
  52. package/dist/color-picker/channels.js +84 -0
  53. package/dist/color-picker/root/color-picker-root.d.ts +81 -5
  54. package/dist/color-picker/root/color-picker-root.js +103 -10
  55. package/dist/combobox/root/combobox-root.d.ts +38 -3
  56. package/dist/combobox/root/combobox-root.js +64 -2
  57. package/dist/command/root/command-root.d.ts +30 -4
  58. package/dist/command/root/command-root.js +33 -3
  59. package/dist/copy-button/from.d.ts +22 -0
  60. package/dist/copy-button/from.js +28 -0
  61. package/dist/copy-button/root/copy-button-root.d.ts +47 -1
  62. package/dist/copy-button/root/copy-button-root.js +44 -8
  63. package/dist/data-table/root/data-table-root.d.ts +150 -2
  64. package/dist/data-table/root/data-table-root.js +303 -29
  65. package/dist/data-table/tree.d.ts +40 -0
  66. package/dist/data-table/tree.js +55 -0
  67. package/dist/date-input/root/date-input-root.d.ts +73 -4
  68. package/dist/date-input/root/date-input-root.js +93 -43
  69. package/dist/date-picker/root/date-picker-root.d.ts +145 -1
  70. package/dist/date-picker/root/date-picker-root.js +239 -48
  71. package/dist/description-list/item/description-list-item.d.ts +17 -2
  72. package/dist/description-list/item/description-list-item.js +15 -2
  73. package/dist/description-list/root/description-list-root.d.ts +27 -1
  74. package/dist/description-list/root/description-list-root.js +26 -1
  75. package/dist/dialog/description.d.ts +9 -0
  76. package/dist/dialog/description.js +14 -0
  77. package/dist/dialog/root/dialog-root.d.ts +64 -1
  78. package/dist/dialog/root/dialog-root.js +49 -23
  79. package/dist/donut-chart/root/donut-chart-root.d.ts +25 -4
  80. package/dist/donut-chart/root/donut-chart-root.js +21 -6
  81. package/dist/drawer/root/drawer-root.d.ts +63 -2
  82. package/dist/drawer/root/drawer-root.js +95 -19
  83. package/dist/drawer/swipe-start.d.ts +9 -0
  84. package/dist/drawer/swipe-start.js +12 -0
  85. package/dist/drilldown/item/drilldown-item.d.ts +11 -6
  86. package/dist/drilldown/item/drilldown-item.js +8 -5
  87. package/dist/drilldown/root/drilldown-root.d.ts +11 -0
  88. package/dist/drilldown/root/drilldown-root.js +8 -3
  89. package/dist/element-events.generated.js +61 -13
  90. package/dist/empty/root/empty-root.d.ts +1 -1
  91. package/dist/file-input/root/file-input-root.d.ts +47 -0
  92. package/dist/file-input/root/file-input-root.js +60 -22
  93. package/dist/file-input/screen.d.ts +35 -0
  94. package/dist/file-input/screen.js +49 -0
  95. package/dist/filter-input/menu/filter-menu.d.ts +3 -0
  96. package/dist/filter-input/menu/filter-menu.js +8 -4
  97. package/dist/filter-input/root/filter-input-root.d.ts +38 -4
  98. package/dist/filter-input/root/filter-input-root.js +67 -3
  99. package/dist/filter-input/suggest.d.ts +17 -0
  100. package/dist/filter-input/suggest.js +23 -0
  101. package/dist/format-date/options.d.ts +33 -0
  102. package/dist/format-date/options.js +42 -0
  103. package/dist/format-date/root/format-date-root.d.ts +51 -0
  104. package/dist/format-date/root/format-date-root.js +58 -38
  105. package/dist/heatmap/root/heatmap-root.d.ts +23 -6
  106. package/dist/heatmap/root/heatmap-root.js +24 -13
  107. package/dist/icon/index.d.ts +2 -0
  108. package/dist/icon/index.js +2 -0
  109. package/dist/icon/registry.d.ts +37 -0
  110. package/dist/icon/registry.js +83 -0
  111. package/dist/icon/root/icon-root.d.ts +30 -4
  112. package/dist/icon/root/icon-root.js +41 -6
  113. package/dist/icon/root/index.d.ts +2 -0
  114. package/dist/icon/root/index.js +2 -0
  115. package/dist/icon/set.d.ts +1 -0
  116. package/dist/icon/set.js +3 -0
  117. package/dist/image/root/image-root.d.ts +14 -0
  118. package/dist/image/root/image-root.js +23 -2
  119. package/dist/input/root/input-root.d.ts +11 -0
  120. package/dist/input/root/input-root.js +16 -1
  121. package/dist/kbd/root/kbd-root.d.ts +20 -13
  122. package/dist/kbd/root/kbd-root.js +35 -37
  123. package/dist/kbd/shortcut.d.ts +18 -0
  124. package/dist/kbd/shortcut.js +35 -0
  125. package/dist/legend/hidden-series.d.ts +8 -0
  126. package/dist/legend/hidden-series.js +13 -0
  127. package/dist/legend/root/legend-root.d.ts +56 -0
  128. package/dist/legend/root/legend-root.js +54 -5
  129. package/dist/lightbox/item/lightbox-item.d.ts +15 -0
  130. package/dist/lightbox/item/lightbox-item.js +10 -1
  131. package/dist/lightbox/root/lightbox-root.d.ts +61 -1
  132. package/dist/lightbox/root/lightbox-root.js +94 -4
  133. package/dist/line-chart/root/line-chart-root.d.ts +11 -3
  134. package/dist/line-chart/root/line-chart-root.js +19 -5
  135. package/dist/list/item/list-item.d.ts +68 -1
  136. package/dist/list/item/list-item.js +66 -4
  137. package/dist/list/numbering.d.ts +14 -0
  138. package/dist/list/numbering.js +8 -0
  139. package/dist/list/root/list-root.d.ts +106 -9
  140. package/dist/list/root/list-root.js +189 -4
  141. package/dist/list/selection.d.ts +19 -0
  142. package/dist/list/selection.js +21 -0
  143. package/dist/listbox/root/listbox-root.d.ts +74 -3
  144. package/dist/listbox/root/listbox-root.js +86 -9
  145. package/dist/loader/busy.d.ts +17 -0
  146. package/dist/loader/busy.js +24 -0
  147. package/dist/loader/root/loader-root.d.ts +37 -0
  148. package/dist/loader/root/loader-root.js +52 -3
  149. package/dist/map/root/map-root.d.ts +6 -2
  150. package/dist/map/root/map-root.js +5 -2
  151. package/dist/megamenu/root/megamenu-root.d.ts +21 -0
  152. package/dist/megamenu/root/megamenu-root.js +16 -2
  153. package/dist/menu/index.d.ts +1 -0
  154. package/dist/menu/index.js +1 -0
  155. package/dist/menu/item/menu-item.d.ts +38 -11
  156. package/dist/menu/item/menu-item.js +33 -1
  157. package/dist/menu/root/menu-root.d.ts +25 -1
  158. package/dist/menu/root/menu-root.js +63 -6
  159. package/dist/menu/section/menu-section.d.ts +55 -0
  160. package/dist/menu/section/menu-section.js +60 -0
  161. package/dist/meter/root/meter-root.d.ts +7 -0
  162. package/dist/meter/root/meter-root.js +6 -3
  163. package/dist/navigation/root/navigation-root.d.ts +16 -1
  164. package/dist/navigation/root/navigation-root.js +27 -1
  165. package/dist/notifications/feed-keys.d.ts +10 -0
  166. package/dist/notifications/feed-keys.js +14 -0
  167. package/dist/notifications/notification/notification.d.ts +17 -0
  168. package/dist/notifications/notification/notification.js +21 -2
  169. package/dist/notifications/root/notifications-root.d.ts +60 -0
  170. package/dist/notifications/root/notifications-root.js +76 -1
  171. package/dist/number-input/root/number-input-root.d.ts +47 -0
  172. package/dist/number-input/root/number-input-root.js +58 -22
  173. package/dist/object-inspector/root/object-inspector-root.d.ts +98 -16
  174. package/dist/object-inspector/root/object-inspector-root.js +180 -80
  175. package/dist/object-inspector/rows.d.ts +57 -0
  176. package/dist/object-inspector/rows.js +86 -0
  177. package/dist/option/root/option-root.d.ts +54 -5
  178. package/dist/option/root/option-root.js +34 -5
  179. package/dist/outline/levels.d.ts +31 -0
  180. package/dist/outline/levels.js +23 -0
  181. package/dist/outline/root/outline-root.d.ts +68 -3
  182. package/dist/outline/root/outline-root.js +73 -8
  183. package/dist/pagination/size/pagination-size.d.ts +11 -2
  184. package/dist/pagination/size/pagination-size.js +19 -4
  185. package/dist/pin-input/format.d.ts +7 -0
  186. package/dist/pin-input/format.js +16 -0
  187. package/dist/pin-input/root/pin-input-root.d.ts +21 -0
  188. package/dist/pin-input/root/pin-input-root.js +29 -2
  189. package/dist/popover/root/popover-root.d.ts +62 -4
  190. package/dist/popover/root/popover-root.js +53 -5
  191. package/dist/progress/root/progress-root.d.ts +7 -0
  192. package/dist/progress/root/progress-root.js +9 -3
  193. package/dist/qr-code/export.d.ts +31 -0
  194. package/dist/qr-code/export.js +10 -0
  195. package/dist/qr-code/root/qr-code-root.d.ts +26 -0
  196. package/dist/qr-code/root/qr-code-root.js +49 -2
  197. package/dist/radio/group/radio-group.d.ts +17 -0
  198. package/dist/radio/group/radio-group.js +14 -1
  199. package/dist/rating/root/rating-root.d.ts +25 -0
  200. package/dist/rating/root/rating-root.js +46 -4
  201. package/dist/scatter-chart/root/scatter-chart-root.d.ts +17 -3
  202. package/dist/scatter-chart/root/scatter-chart-root.js +25 -7
  203. package/dist/scroll-area/root/scroll-area-root.d.ts +113 -0
  204. package/dist/scroll-area/root/scroll-area-root.js +218 -3
  205. package/dist/scroll-area/scrollbar.d.ts +65 -0
  206. package/dist/scroll-area/scrollbar.js +24 -0
  207. package/dist/select/root/select-root.d.ts +24 -0
  208. package/dist/select/root/select-root.js +21 -7
  209. package/dist/skeleton/root/skeleton-root.d.ts +25 -0
  210. package/dist/skeleton/root/skeleton-root.js +17 -2
  211. package/dist/slider/root/slider-root.d.ts +39 -0
  212. package/dist/slider/root/slider-root.js +45 -9
  213. package/dist/splitter/root/splitter-root.d.ts +13 -0
  214. package/dist/splitter/root/splitter-root.js +20 -2
  215. package/dist/splitter/snap.d.ts +9 -0
  216. package/dist/splitter/snap.js +12 -0
  217. package/dist/stat/root/stat-root.d.ts +2 -0
  218. package/dist/stat/root/stat-root.js +1 -1
  219. package/dist/steps/reach.d.ts +15 -0
  220. package/dist/steps/reach.js +12 -0
  221. package/dist/steps/root/steps-root.d.ts +30 -0
  222. package/dist/steps/root/steps-root.js +53 -0
  223. package/dist/steps/step/step.d.ts +39 -2
  224. package/dist/steps/step/step.js +29 -7
  225. package/dist/switch/root/switch-root.d.ts +12 -2
  226. package/dist/switch/root/switch-root.js +6 -1
  227. package/dist/table/column/table-column.d.ts +11 -0
  228. package/dist/table/column/table-column.js +6 -1
  229. package/dist/table/root/table-root.d.ts +101 -0
  230. package/dist/table/root/table-root.js +166 -5
  231. package/dist/table/row/table-row.d.ts +47 -1
  232. package/dist/table/row/table-row.js +39 -2
  233. package/dist/tabs/panel/tab-panel.d.ts +9 -5
  234. package/dist/tabs/panel/tab-panel.js +3 -4
  235. package/dist/tabs/root/tabs-root.d.ts +25 -1
  236. package/dist/tabs/root/tabs-root.js +21 -3
  237. package/dist/tabs/tab/tab.d.ts +36 -4
  238. package/dist/tabs/tab/tab.js +46 -3
  239. package/dist/tag/group/tag-group.d.ts +107 -0
  240. package/dist/tag/group/tag-group.js +157 -0
  241. package/dist/tag/index.d.ts +1 -0
  242. package/dist/tag/index.js +1 -0
  243. package/dist/tag/root/tag-root.d.ts +60 -0
  244. package/dist/tag/root/tag-root.js +74 -18
  245. package/dist/tag/selection.d.ts +10 -0
  246. package/dist/tag/selection.js +12 -0
  247. package/dist/textarea/grow.d.ts +22 -0
  248. package/dist/textarea/grow.js +20 -0
  249. package/dist/textarea/root/textarea-root.d.ts +9 -0
  250. package/dist/textarea/root/textarea-root.js +9 -1
  251. package/dist/time-input/root/time-input-root.d.ts +44 -5
  252. package/dist/time-input/root/time-input-root.js +69 -39
  253. package/dist/time-picker/root/time-picker-root.d.ts +54 -8
  254. package/dist/time-picker/root/time-picker-root.js +121 -91
  255. package/dist/timeline/group/timeline-group.d.ts +46 -0
  256. package/dist/timeline/group/timeline-group.js +37 -0
  257. package/dist/timeline/index.d.ts +1 -0
  258. package/dist/timeline/index.js +1 -0
  259. package/dist/timeline/root/timeline-root.d.ts +10 -3
  260. package/dist/toast/hotkey.d.ts +22 -0
  261. package/dist/toast/hotkey.js +23 -0
  262. package/dist/toast/item/toast-item.d.ts +26 -18
  263. package/dist/toast/item/toast-item.js +55 -48
  264. package/dist/toast/root/toast-root.d.ts +42 -8
  265. package/dist/toast/root/toast-root.js +64 -4
  266. package/dist/toggle/group/toggle-group.d.ts +57 -15
  267. package/dist/toggle/group/toggle-group.js +69 -9
  268. package/dist/toggle/root/toggle-root.d.ts +12 -1
  269. package/dist/toggle/root/toggle-root.js +11 -3
  270. package/dist/toolbar/root/toolbar-root.d.ts +13 -0
  271. package/dist/toolbar/root/toolbar-root.js +15 -5
  272. package/dist/tooltip/focus-target.d.ts +6 -0
  273. package/dist/tooltip/focus-target.js +9 -0
  274. package/dist/tooltip/root/tooltip-root.d.ts +42 -17
  275. package/dist/tooltip/root/tooltip-root.js +50 -9
  276. package/dist/tour/naming.d.ts +30 -0
  277. package/dist/tour/naming.js +10 -0
  278. package/dist/tour/root/tour-root.d.ts +35 -0
  279. package/dist/tour/root/tour-root.js +56 -5
  280. package/dist/tour/stop/tour-stop.d.ts +53 -8
  281. package/dist/tour/stop/tour-stop.js +45 -15
  282. package/dist/tour/wait.d.ts +11 -0
  283. package/dist/tour/wait.js +19 -0
  284. package/dist/tree/item/tree-item.d.ts +54 -1
  285. package/dist/tree/item/tree-item.js +89 -20
  286. package/dist/tree/root/tree-root.d.ts +37 -0
  287. package/dist/tree/root/tree-root.js +51 -6
  288. package/dist/tree/selection.d.ts +24 -0
  289. package/dist/tree/selection.js +26 -0
  290. package/dist/trend/root/trend-root.d.ts +13 -0
  291. package/dist/trend/root/trend-root.js +14 -9
  292. package/dist/video/media-events.d.ts +49 -0
  293. package/dist/video/media-events.js +39 -0
  294. package/dist/video/root/video-root.d.ts +99 -13
  295. package/dist/video/root/video-root.js +84 -47
  296. package/dist/video-playlist/menu/video-playlist-menu.d.ts +3 -0
  297. package/dist/video-playlist/menu/video-playlist-menu.js +2 -1
  298. package/dist/video-playlist/order.d.ts +41 -0
  299. package/dist/video-playlist/order.js +34 -0
  300. package/dist/video-playlist/root/video-playlist-root.d.ts +70 -2
  301. package/dist/video-playlist/root/video-playlist-root.js +60 -16
  302. package/dist/virtual-list/controls.d.ts +4 -0
  303. package/dist/virtual-list/controls.js +30 -0
  304. package/dist/virtual-list/fill.d.ts +30 -0
  305. package/dist/virtual-list/fill.js +39 -0
  306. package/dist/virtual-list/keys.d.ts +15 -0
  307. package/dist/virtual-list/keys.js +24 -0
  308. package/dist/virtual-list/root/virtual-list-root.d.ts +155 -23
  309. package/dist/virtual-list/root/virtual-list-root.js +175 -34
  310. package/lint.json +1 -1
  311. package/package.json +5 -5
  312. package/types/jsx.d.ts +8871 -1286
  313. package/types/svelte.d.ts +3 -0
  314. package/types/vue.d.ts +1918 -269
@@ -4,10 +4,12 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { customElement, HelixElement } from '@fusion.dev/helix-core';
7
+ import { customElement, HelixElement, rgbOf } from '@fusion.dev/helix-core';
8
8
  import { html, nothing, svg, } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  import { encode } from 'uqr';
11
+ import { qrSvg } from '../export.js';
12
+ const QUIET = 4;
11
13
  const isFinder = (x, y, size) => {
12
14
  const near = (a, b) => a < 8 && b < 8;
13
15
  return near(x, y) || near(size - 1 - x, y) || near(x, size - 1 - y);
@@ -104,6 +106,51 @@ let HelixHeadlessQrCode = class HelixHeadlessQrCode extends HelixElement {
104
106
  this.overflowed = '';
105
107
  }
106
108
  }
109
+ toSvg(size = 512) {
110
+ const code = this.renderRoot?.querySelector('svg[part="code"]');
111
+ const modules = code?.querySelector('[part="modules"]');
112
+ const finders = code?.querySelector('[part="finders"]');
113
+ if (!code || !modules || !finders) {
114
+ return '';
115
+ }
116
+ const ground = getComputedStyle(this).backgroundColor;
117
+ const clear = ground === '' || ground === 'transparent' || /^rgba\(.*,\s*0\)$/.test(ground);
118
+ return qrSvg({
119
+ background: clear ? '#ffffff' : rgbOf(ground),
120
+ box: Number(code.getAttribute('viewBox')?.split(' ')[2] ?? 0),
121
+ finderColor: rgbOf(getComputedStyle(finders).fill || '#000000'),
122
+ finders: finders.getAttribute('d') ?? '',
123
+ moduleColor: rgbOf(getComputedStyle(modules).fill || '#000000'),
124
+ modules: modules.getAttribute('d') ?? '',
125
+ quiet: QUIET,
126
+ }, size);
127
+ }
128
+ async toPng(size = 512) {
129
+ const markup = this.toSvg(size);
130
+ if (markup === '') {
131
+ return null;
132
+ }
133
+ const image = new Image();
134
+ image.src = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(markup)}`;
135
+ await image.decode();
136
+ const canvas = document.createElement('canvas');
137
+ canvas.width = size;
138
+ canvas.height = size;
139
+ canvas.getContext('2d')?.drawImage(image, 0, 0, size, size);
140
+ return new Promise((resolve) => canvas.toBlob(resolve, 'image/png'));
141
+ }
142
+ async download(filename = 'qr-code.png', size = 512) {
143
+ const png = await this.toPng(size);
144
+ if (!png) {
145
+ return;
146
+ }
147
+ const url = URL.createObjectURL(png);
148
+ const link = document.createElement('a');
149
+ link.href = url;
150
+ link.download = filename;
151
+ link.click();
152
+ setTimeout(() => URL.revokeObjectURL(url));
153
+ }
107
154
  renderCode() {
108
155
  if (this.value === '') {
109
156
  return nothing;
@@ -113,7 +160,7 @@ let HelixHeadlessQrCode = class HelixHeadlessQrCode extends HelixElement {
113
160
  return nothing;
114
161
  }
115
162
  const size = result.size;
116
- const quiet = 4;
163
+ const quiet = QUIET;
117
164
  const box = size + quiet * 2;
118
165
  const finders = pathFor(result.data, 'square', 'finders');
119
166
  return svg `<svg
@@ -23,6 +23,13 @@ declare const HelixHeadlessRadioGroup_base: (new (...args: any[]) => import("@fu
23
23
  * the value until something is chosen, and where a reset returns. The two work
24
24
  * like `checked` and `defaultChecked`.
25
25
  *
26
+ * A choice sends its events in this order: `helix-select` from the radio, then,
27
+ * a microtask later and only if nobody refused it, `helix-before-change` from
28
+ * the group, and once the value has moved, `input` and `change`. The microtask
29
+ * is what lets a listener you add to the group after it connected refuse the
30
+ * `helix-select`. A native radio sends `input` and `change` in the same task as
31
+ * the click.
32
+ *
26
33
  * @since 0.1.0
27
34
  * @status stable
28
35
  * @aliases RadioButtons, Choice group
@@ -69,6 +76,16 @@ export declare class HelixHeadlessRadioGroup extends HelixHeadlessRadioGroup_bas
69
76
  * only `horizontal` has to be named.
70
77
  */
71
78
  orientation?: 'horizontal' | 'vertical';
79
+ /**
80
+ * Whether a reader can see and focus the answer and cannot change it. A
81
+ * read-only group still submits its value.
82
+ *
83
+ * React Aria's `isReadOnly`. A press on a radio is refused. The arrow keys,
84
+ * Home and End move focus between the radios and choose nothing, so a reader
85
+ * can hear every choice, and Tab still reaches the answer. The group says
86
+ * `aria-readonly`. A script can still set `value`.
87
+ */
88
+ readOnly: boolean;
72
89
  protected readonly keys: KeyboardNavigationController;
73
90
  protected readonly cascade: DisabledCascadeController;
74
91
  /** The radios, in light-DOM order. Client only: the server has no tree. */
@@ -12,12 +12,21 @@ let HelixHeadlessRadioGroup = class HelixHeadlessRadioGroup extends MixinControl
12
12
  constructor() {
13
13
  super(...arguments);
14
14
  this.focusable = true;
15
- this.keys = new KeyboardNavigationController(this, { items: () => this.items });
15
+ this.readOnly = false;
16
+ this.keys = new KeyboardNavigationController(this, {
17
+ items: () => this.items,
18
+ origin: () => (this.readOnly ? 'focus' : 'selection'),
19
+ selects: () => !this.readOnly,
20
+ });
16
21
  this.cascade = new DisabledCascadeController(this, {
17
22
  items: () => this.items,
18
23
  });
19
24
  this.handleSelection = (event) => {
20
25
  event.stopPropagation();
26
+ if (this.readOnly) {
27
+ event.preventDefault();
28
+ return;
29
+ }
21
30
  queueMicrotask(() => {
22
31
  if (event.defaultPrevented) {
23
32
  return;
@@ -90,6 +99,7 @@ let HelixHeadlessRadioGroup = class HelixHeadlessRadioGroup extends MixinControl
90
99
  this.adopt();
91
100
  hostAria(this.internals, { label: this.label, role: 'radiogroup' });
92
101
  this.internals.ariaRequired = this.required ? 'true' : null;
102
+ this.internals.ariaReadOnly = this.readOnly ? 'true' : null;
93
103
  }
94
104
  updated(changed) {
95
105
  super.updated(changed);
@@ -111,6 +121,9 @@ __decorate([
111
121
  __decorate([
112
122
  property({ reflect: true })
113
123
  ], HelixHeadlessRadioGroup.prototype, "orientation", void 0);
124
+ __decorate([
125
+ property({ attribute: 'readonly', reflect: true, type: Boolean })
126
+ ], HelixHeadlessRadioGroup.prototype, "readOnly", void 0);
114
127
  HelixHeadlessRadioGroup = __decorate([
115
128
  customElement('helix-headless-radio-group')
116
129
  ], HelixHeadlessRadioGroup);
@@ -15,6 +15,9 @@ declare const HelixHeadlessRating_base: (new (...args: any[]) => import("@fusion
15
15
  * A read-only rating displays a score, which is the most common use. It is
16
16
  * announced as a displayed value and does not look disabled.
17
17
  *
18
+ * With `clearable`, pressing the chosen score again, or Backspace or Delete on
19
+ * the marks, takes the rating back to unrated and sends `helix-clear`.
20
+ *
18
21
  * @since 0.1.0
19
22
  * @status stable
20
23
  * @category forms
@@ -28,6 +31,7 @@ declare const HelixHeadlessRating_base: (new (...args: any[]) => import("@fusion
28
31
  *
29
32
  * @event {Event} change - The score was chosen. Sent together with `input`, because each choice commits the score.
30
33
  * @event {HelixBeforeChangeEvent} helix-before-change - The score is about to change. Cancelable: cancel it to keep the current score.
34
+ * @event {HelixClearEvent} helix-clear - The rating went back to unrated, under `clearable`. Sent after `input` and `change`.
31
35
  * @event {Event} input - The score changed.
32
36
  *
33
37
  * @csspart feedback - The message that says what is wrong.
@@ -50,6 +54,12 @@ declare const HelixHeadlessRating_base: (new (...args: any[]) => import("@fusion
50
54
  */
51
55
  export declare class HelixHeadlessRating extends HelixHeadlessRating_base {
52
56
  protected readonly announcesInput = false;
57
+ /**
58
+ * Whether a reader can take the rating back to unrated: by pressing the
59
+ * chosen score again, or with Backspace or Delete. Zag's rating group
60
+ * clears the same way.
61
+ */
62
+ clearable: boolean;
53
63
  /**
54
64
  * How many marks there are.
55
65
  */
@@ -142,6 +152,8 @@ export declare class HelixHeadlessRating extends HelixHeadlessRating_base {
142
152
  */
143
153
  valueText: string;
144
154
  protected readonly aria: AriaForwardController;
155
+ /** @internal The element a missing name is checked on: the set of stars, so the name of one star does not count as the name of the rating. */
156
+ protected get namedControl(): HTMLElement | null;
145
157
  /**
146
158
  * The shape a consumer slotted, if they slotted one.
147
159
  *
@@ -236,8 +248,17 @@ export declare class HelixHeadlessRating extends HelixHeadlessRating_base {
236
248
  * or off the element entirely, has asked for nothing.
237
249
  */
238
250
  private readonly handleDragStart;
251
+ /** The score a press began on, so releasing on the chosen one can clear it. */
252
+ private pressedOn;
253
+ /**
254
+ * Whether a drag has just chosen, so the click a browser may send after it
255
+ * does not choose again. Cleared a task later, since the click may not come.
256
+ */
257
+ private dragChose;
239
258
  private readonly handleDragMove;
240
259
  private readonly handleDragEnd;
260
+ /** Whether a press on `score` takes a clearable rating back to unrated. */
261
+ private clearsAt;
241
262
  private readonly handleDragCancel;
242
263
  /**
243
264
  * Reports the value, and whether the form may go without one.
@@ -260,6 +281,10 @@ export declare class HelixHeadlessRating extends HelixHeadlessRating_base {
260
281
  */
261
282
  private sync;
262
283
  private readonly handleOptionClick;
284
+ /** Backspace and Delete take a clearable rating back to unrated. */
285
+ private readonly handleClearKey;
286
+ /** Back to unrated, through the same cancelable request as a score, and said. */
287
+ private clear;
263
288
  private readonly handleOptionEnter;
264
289
  private readonly handleLeave;
265
290
  connectedCallback(): void;
@@ -4,13 +4,14 @@ 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, valueAsNumber as asNumber, customElement, fillTemplate, numberAsValue as fromNumber, HelixFormElement, KeyboardNavigationController, MixinControllerValue, MixinField, reportRuntime, } from '@fusion.dev/helix-core';
7
+ import { AriaForwardController, valueAsNumber as asNumber, customElement, fillTemplate, numberAsValue as fromNumber, HelixClearEvent, HelixFormElement, KeyboardNavigationController, MixinControllerValue, MixinField, reportRuntime, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property, state } from 'lit/decorators.js';
10
10
  let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue(MixinField(HelixFormElement)) {
11
11
  constructor() {
12
12
  super(...arguments);
13
13
  this.announcesInput = false;
14
+ this.clearable = false;
14
15
  this.max = 5;
15
16
  this.min = 0;
16
17
  this.optionLabel = '{score} out of {max}';
@@ -50,8 +51,11 @@ let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue
50
51
  catch {
51
52
  }
52
53
  this.dragging = event.pointerId;
54
+ this.pressedOn = score;
53
55
  this.previewing = Number.parseFloat(score);
54
56
  };
57
+ this.pressedOn = undefined;
58
+ this.dragChose = false;
55
59
  this.handleDragMove = (event) => {
56
60
  if (this.dragging !== event.pointerId) {
57
61
  return;
@@ -68,9 +72,18 @@ let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue
68
72
  this.dragging = undefined;
69
73
  this.previewing = undefined;
70
74
  const score = this.scoreAt(event.clientX);
71
- if (score !== undefined) {
72
- this.requestValue(score);
75
+ if (score === undefined) {
76
+ return;
77
+ }
78
+ this.dragChose = true;
79
+ setTimeout(() => {
80
+ this.dragChose = false;
81
+ }, 0);
82
+ if (this.clearsAt(score) && score === this.pressedOn) {
83
+ this.clear();
84
+ return;
73
85
  }
86
+ this.requestValue(score);
74
87
  };
75
88
  this.handleDragCancel = (event) => {
76
89
  if (this.dragging !== event.pointerId) {
@@ -80,8 +93,22 @@ let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue
80
93
  this.previewing = undefined;
81
94
  };
82
95
  this.handleOptionClick = (event) => {
96
+ if (this.dragChose) {
97
+ return;
98
+ }
83
99
  const option = event.currentTarget;
84
- this.requestValue(option.dataset.score ?? '');
100
+ const score = option.dataset.score ?? '';
101
+ if (this.clearsAt(score)) {
102
+ this.clear();
103
+ return;
104
+ }
105
+ this.requestValue(score);
106
+ };
107
+ this.handleClearKey = (event) => {
108
+ if (this.clearable && (event.key === 'Backspace' || event.key === 'Delete')) {
109
+ event.preventDefault();
110
+ this.clear();
111
+ }
85
112
  };
86
113
  this.handleOptionEnter = (event) => {
87
114
  if (this.isDisabled) {
@@ -95,6 +122,9 @@ let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue
95
122
  };
96
123
  this.warned = false;
97
124
  }
125
+ get namedControl() {
126
+ return this.partNamed('marks');
127
+ }
98
128
  get floor() {
99
129
  if (!Number.isFinite(this.min)) {
100
130
  return 0;
@@ -156,10 +186,18 @@ let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue
156
186
  }
157
187
  return nearest;
158
188
  }
189
+ clearsAt(score) {
190
+ return this.clearable && this.value !== '' && Number(score) === Number(this.value);
191
+ }
159
192
  sync() {
160
193
  this.internals.setFormValue(this.value === '' ? null : this.value);
161
194
  this.reportRequired(this.value === '', 'Choose a rating to continue.', 'marks');
162
195
  }
196
+ clear() {
197
+ if (this.value !== '' && !this.readOnly && !this.isDisabled && this.requestValue('')) {
198
+ this.dispatchEvent(new HelixClearEvent());
199
+ }
200
+ }
163
201
  connectedCallback() {
164
202
  super.connectedCallback();
165
203
  this.addEventListener('pointerleave', this.handleLeave);
@@ -226,6 +264,7 @@ let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue
226
264
  data-slotted=${this.markSource ? '' : nothing}
227
265
  style=${`--rating-full: ${Math.floor(showing)}; --rating-part: ${showing - Math.floor(showing)}; --rating-steps: ${this.positions.length}`}
228
266
  @pointercancel=${this.handleDragCancel}
267
+ @keydown=${this.handleClearKey}
229
268
  @pointerdown=${this.handleDragStart}
230
269
  @pointermove=${this.handleDragMove}
231
270
  @pointerup=${this.handleDragEnd}
@@ -283,6 +322,9 @@ let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue
283
322
  this.value = fromNumber(count);
284
323
  }
285
324
  };
325
+ __decorate([
326
+ property({ type: Boolean })
327
+ ], HelixHeadlessRating.prototype, "clearable", void 0);
286
328
  __decorate([
287
329
  property({ type: Number })
288
330
  ], HelixHeadlessRating.prototype, "max", void 0);
@@ -33,7 +33,14 @@ declare const HelixHeadlessScatterChart_base: typeof HelixElement & (new (...arg
33
33
  * round numbers, and the range extends to them.
34
34
  *
35
35
  * The summary gives each series' correlation coefficient and its number of
36
- * points. The table has every number, and the drawing is `aria-hidden`.
36
+ * points. The table has every number, and the drawing is hidden from screen
37
+ * readers.
38
+ *
39
+ * **The plot is read by key.** It takes focus, named by `label` or the caption.
40
+ * The left and right arrows move from row to row in the table's order, Home
41
+ * and End go to the first and the last, and the up and down arrows move among
42
+ * the series of a row. The tooltip sits on that point, the `live` part says the
43
+ * row in words, and Escape puts the tooltip away.
37
44
  *
38
45
  * Each point is a `<span>` placed by percentage over the drawing, as
39
46
  * `LineChart` places its end points, so points stay round when the drawing
@@ -52,9 +59,10 @@ declare const HelixHeadlessScatterChart_base: typeof HelixElement & (new (...arg
52
59
  * @documentation https://fusion.dev/helix/components/scatter-chart
53
60
  *
54
61
  * @csspart gridline - One line across the plot, drawn when `gridlines` is set.
62
+ * @csspart live - The readout: a polite live region that says the row the keys moved to. Hide it visually.
55
63
  * @csspart mark - The invisible point the tooltip is anchored to.
56
64
  * @csspart plane - The grid that holds the plot, both axes, and their names. It runs left to right on every page.
57
- * @csspart plot - The drawing.
65
+ * @csspart plot - The drawing, which takes focus to be read by key.
58
66
  * @csspart point - One row, as a point.
59
67
  * @csspart point-active - A point in the row under the pointer. Set alongside `point`.
60
68
  * @csspart summary - The text that says how strongly the measures relate, for people who cannot see the points.
@@ -68,6 +76,7 @@ declare const HelixHeadlessScatterChart_base: typeof HelixElement & (new (...arg
68
76
  * @csspart tooltip-arrow-top - The point while the bubble is above the reading, on its bottom edge. Set alongside `tooltip-arrow`.
69
77
  * @csspart tooltip-bottom - The bubble while it is below the reading. Set alongside `tooltip`.
70
78
  * @csspart tooltip-cell - One column's name and value inside the tooltip.
79
+ * @csspart tooltip-cell-current - The cell the up and down arrows rest on, while they rest there. Set alongside `tooltip-cell`.
71
80
  * @csspart tooltip-label - The row's own name inside the tooltip.
72
81
  * @csspart tooltip-left - The bubble while it is left of the reading. Set alongside `tooltip`.
73
82
  * @csspart tooltip-name - A column's name inside the tooltip.
@@ -149,7 +158,12 @@ export declare class HelixHeadlessScatterChart extends HelixHeadlessScatterChart
149
158
  * absent where there are fewer than three points or no spread to measure.
150
159
  */
151
160
  protected renderSummary(field: ScatterField): TemplateResult;
152
- /** The row a pointer is resting on, over the point it is nearest. */
161
+ /**
162
+ * The row a pointer is resting on, over the point it is nearest.
163
+ *
164
+ * A row reached by key has no nearest point, so the bubble sits on the
165
+ * point of the series the keys rest on, or on the row's first point.
166
+ */
153
167
  protected renderTooltip(): TemplateResult | typeof nothing;
154
168
  /**
155
169
  * The point a pointer is nearest, within reach.
@@ -116,14 +116,17 @@ let HelixHeadlessScatterChart = class HelixHeadlessScatterChart extends MixinCha
116
116
  const y = row.cells[column]?.value;
117
117
  return x === undefined || y === undefined ? [] : [[x, y, index]];
118
118
  }));
119
- const all = pairs.flat();
119
+ const shown = ups.map((column) => this.showsSeries(name(column)));
120
+ const all = pairs.filter((_, depth) => shown[depth]).flat();
120
121
  const x = nice(extent(all.length > 0 ? all.map(([one]) => one) : [0]));
121
122
  const y = nice(extent(all.length > 0 ? all.map(([, one]) => one) : [0]));
122
123
  const along = linear(x, [0, PLOT_WIDTH]);
123
124
  const up = linear(y, [PLOT_HEIGHT, 0]);
124
125
  return {
125
126
  pairs: pairs.map((series) => series.map(([one, two]) => [one, two])),
126
- points: pairs.flatMap((series, depth) => series.map(([one, two, row]) => ({ depth, row, x: along(one), y: up(two) }))),
127
+ points: pairs.flatMap((series, depth) => shown[depth]
128
+ ? series.map(([one, two, row]) => ({ depth, row, x: along(one), y: up(two) }))
129
+ : []),
127
130
  x,
128
131
  xName: name(across),
129
132
  y,
@@ -156,8 +159,17 @@ let HelixHeadlessScatterChart = class HelixHeadlessScatterChart extends MixinCha
156
159
  }
157
160
  renderPlot(field, along, up) {
158
161
  const at = this.pointer.at;
159
- return html `<div aria-hidden="true" id=${CHART_PLOT} part="plot">
162
+ return html `<div
163
+ aria-describedby=${this.named ? 'helix-chart-summary' : nothing}
164
+ aria-label=${this.named || nothing}
165
+ aria-labelledby=${this.named ? nothing : 'helix-chart-summary'}
166
+ id=${CHART_PLOT}
167
+ part="plot"
168
+ role="application"
169
+ tabindex="0"
170
+ >
160
171
  <svg part="svg"
172
+ aria-hidden="true"
161
173
  preserveAspectRatio="none"
162
174
  viewBox="0 0 ${PLOT_WIDTH} ${PLOT_HEIGHT}"
163
175
  xmlns="http://www.w3.org/2000/svg"
@@ -172,6 +184,7 @@ let HelixHeadlessScatterChart = class HelixHeadlessScatterChart extends MixinCha
172
184
  ${field.points.map((point) => {
173
185
  const index = seriesIndex(point.depth);
174
186
  return html `<span
187
+ aria-hidden="true"
175
188
  data-series=${index}
176
189
  ?data-active=${point.row === at}
177
190
  part="point${point.row === at ? ' point-active' : ''}"
@@ -189,13 +202,18 @@ let HelixHeadlessScatterChart = class HelixHeadlessScatterChart extends MixinCha
189
202
  return `${name} / ${field.xName}: ${pairs.length} ${this.pointsLabel}${strength}`;
190
203
  });
191
204
  const named = this.named ? `${this.named}. ` : '';
192
- return html `<p part="summary">${named}${clauses.join('; ')}.</p>`;
205
+ return html `<p id="helix-chart-summary" part="summary">${named}${clauses.join('; ')}.</p>`;
193
206
  }
194
207
  renderTooltip() {
195
208
  const at = this.pointer.at;
196
- const point = this.nearest;
209
+ const column = this.pointer.column;
210
+ const depth = column === undefined ? -1 : this.plottedColumns.indexOf(column) - 1;
211
+ const point = this.nearest?.row === at && !this.pointer.keyed
212
+ ? this.nearest
213
+ : (this.drawn.find((one) => one.row === at && one.depth === depth) ??
214
+ this.drawn.find((one) => one.row === at));
197
215
  if (at < 0 || !point) {
198
- return drawTooltip(this.sourceRows, -1, this.tag('tooltip'));
216
+ return drawTooltip(this.sourceRows, -1, this.tag('tooltip'), undefined, undefined, this.pointer);
199
217
  }
200
218
  return drawTooltip(this.sourceRows, at, this.tag('tooltip'), {
201
219
  dir: isRtl(this) ? 'rtl' : 'ltr',
@@ -203,7 +221,7 @@ let HelixHeadlessScatterChart = class HelixHeadlessScatterChart extends MixinCha
203
221
  placement: 'top',
204
222
  x: `${point.x}%`,
205
223
  y: `${point.y}%`,
206
- }, (cell) => this.seriesOf(cell));
224
+ }, (cell) => this.seriesOf(cell), this.pointer);
207
225
  }
208
226
  };
209
227
  __decorate([
@@ -20,6 +20,20 @@ declare const EDGES: readonly ['block-start', 'block-end', 'inline-start', 'inli
20
20
  * It has `role="region"` only when you set a `label`, because a screen reader
21
21
  * announces an unnamed region as only "region".
22
22
  *
23
+ * **`scrollbars` draws scrollbars of its own** in place of the browser's: a
24
+ * `scrollbar` part for each axis that scrolls, a `thumb` in each, and a
25
+ * `corner` where the two meet. They are for the pointer. The thumb drags, and
26
+ * a press on the track moves the thumb to the press. The viewport stays the
27
+ * tab stop and the region a screen reader reads, and the scrollbars are hidden
28
+ * from screen readers. On the headless tier your stylesheet sizes and places
29
+ * them, hides the browser's own with `scrollbar-width: none` on the viewport,
30
+ * and draws the thumb from the two custom properties written on each
31
+ * scrollbar. An axis whose `overflow` is `hidden` gets no scrollbar.
32
+ *
33
+ * The viewport's `scroll` and `scrollend` are sent again from the host, which
34
+ * is the element you hold. In React, bind them with `onScroll` and
35
+ * `onScrollEnd`.
36
+ *
23
37
  * @since 0.1.0
24
38
  * @status stable
25
39
  * @category layout
@@ -28,22 +42,69 @@ declare const EDGES: readonly ['block-start', 'block-end', 'inline-start', 'inli
28
42
  *
29
43
  * @slot - The content that scrolls.
30
44
  *
45
+ * @event {Event} scroll - The content scrolled. Sent from the host, because the viewport's own does not leave the shadow root. Does not bubble.
46
+ * @event {Event} scrollend - The content stopped scrolling. Sent from the host, as `scroll` is. Does not bubble.
47
+ *
48
+ * @csspart corner - The square where the two scrollbars meet, under `scrollbars`. Hidden unless both are drawn.
31
49
  * @csspart edges - The layer that draws the cues on the inline start and end edges.
50
+ * @csspart scrollbar - Each scrollbar, under `scrollbars`. Hidden on an axis that has none.
51
+ * @csspart scrollbar-horizontal - The scrollbar along the inline axis, alongside `scrollbar`.
52
+ * @csspart scrollbar-vertical - The scrollbar along the block axis, alongside `scrollbar`.
53
+ * @csspart scrollbar-visible - A scrollbar while it is showing, alongside `scrollbar`. Always under `auto` and `always`, and while scrolling, held, or hovered under `scroll` and `hover`.
54
+ * @csspart thumb - The thumb inside each scrollbar, which drags.
55
+ * @csspart thumb-horizontal - The thumb of the horizontal scrollbar, alongside `thumb`.
56
+ * @csspart thumb-vertical - The thumb of the vertical scrollbar, alongside `thumb`.
32
57
  * @csspart viewport - The scrolling box.
33
58
  *
59
+ * @cssproperty --scroll-area-scroll-fraction - How far along its axis the content is scrolled, from 0 at the start to 1 at the end. Written on each `scrollbar` part, so its thumb inherits it. Counted from the right on a right-to-left page.
60
+ * @cssproperty --scroll-area-thumb-fraction - The share of the track the thumb covers, from 0 to 1, which is how much of the content is in view. Written on each `scrollbar` part.
61
+ *
34
62
  * @cssstate more-block-end - While there is more to scroll to past the block end.
35
63
  * @cssstate more-block-start - While there is more to scroll back to before the block start.
36
64
  * @cssstate more-inline-end - While there is more to scroll to past the inline end.
37
65
  * @cssstate more-inline-start - While there is more to scroll back to before the inline start.
66
+ * @cssstate scrollbar-horizontal - While the horizontal scrollbar is drawn, under `scrollbars`.
67
+ * @cssstate scrollbar-vertical - While the vertical scrollbar is drawn, under `scrollbars`.
38
68
  * @cssstate scrolls - While the content is larger than the viewport, on either axis.
39
69
  */
40
70
  export declare class HelixHeadlessScrollArea extends HelixElement {
71
+ /**
72
+ * How long the scrollbars stay after the content stops moving, or the pointer
73
+ * leaves, in milliseconds. Read under `scrollbars="scroll"` and
74
+ * `scrollbars="hover"`.
75
+ */
76
+ hideDelay: number;
41
77
  /**
42
78
  * The region's name, read by screen readers.
43
79
  *
44
80
  * Without one there is no region: see the note on the class.
45
81
  */
46
82
  label: string;
83
+ /**
84
+ * Draws scrollbars of the component's own in place of the browser's, and
85
+ * says when they show.
86
+ *
87
+ * - `auto`: on each axis that has content past it.
88
+ * - `always`: on each axis that can scroll, whether or not it has anything to
89
+ * scroll, so the scrollbar is there before the content grows.
90
+ * - `scroll`: while the content is moving, and for `hide-delay` after.
91
+ * - `hover`: as `scroll`, and while the pointer is over the scroll area.
92
+ *
93
+ * Absent keeps the browser's scrollbars.
94
+ */
95
+ scrollbars?: 'always' | 'auto' | 'hover' | 'scroll';
96
+ /** What each scrollbar shows, measured, and `undefined` until it has been. */
97
+ private bars;
98
+ /** Whether the content moved, or the pointer left, within the hide delay. */
99
+ private active;
100
+ /** Whether the pointer is over the scroll area. */
101
+ private hovered;
102
+ /** Whether the pointer is over a scrollbar. */
103
+ private over;
104
+ /** The thumb being dragged, if one is. */
105
+ private drag;
106
+ /** Puts the scrollbars away once nothing has moved for the hide delay. */
107
+ private readonly hide;
47
108
  /**
48
109
  * Which edges have content past them, measured rather than guessed.
49
110
  */
@@ -76,6 +137,46 @@ export declare class HelixHeadlessScrollArea extends HelixElement {
76
137
  * costs.
77
138
  */
78
139
  private measure;
140
+ /** One axis of the box, counted from its start whichever way the line runs. */
141
+ private extent;
142
+ /**
143
+ * Reads what each scrollbar shows off the box.
144
+ *
145
+ * An axis scrolls unless its `overflow` says it cannot. An empty reading is a
146
+ * harness with no layout, where the mark `core` puts on the viewport is
147
+ * `overflow: auto` on both axes, so it counts as one that scrolls.
148
+ *
149
+ * Written only on a change, so a scroll that moves no thumb renders nothing.
150
+ */
151
+ private readBars;
152
+ /**
153
+ * Shows the scrollbars and starts the wait that puts them away again, under
154
+ * `scroll` and `hover`.
155
+ */
156
+ private wake;
157
+ /** Sends the content to `offset` along an axis, counted from its start. */
158
+ private scrollAlong;
159
+ /**
160
+ * Takes hold of a thumb, or presses the track.
161
+ *
162
+ * A press on the track sends the thumb's middle to the press first, and the
163
+ * drag carries on from there, so a press and a drag are one gesture as they
164
+ * are on the browser's own scrollbar. `preventDefault` keeps the press from
165
+ * starting a text selection, and from moving focus off the viewport.
166
+ */
167
+ private grab;
168
+ private readonly handleVerticalDown;
169
+ private readonly handleHorizontalDown;
170
+ /** Moves the content with a dragged thumb. Nothing while no thumb is held. */
171
+ private readonly handleDragMove;
172
+ private readonly handleDragEnd;
173
+ private readonly handleBarEnter;
174
+ private readonly handleBarLeave;
175
+ private readonly handleEnter;
176
+ private readonly handleLeave;
177
+ /** Measures, shows the scrollbars, and sends the event on from the host. */
178
+ private readonly handleScroll;
179
+ private readonly handleScrollEnd;
79
180
  connectedCallback(): void;
80
181
  disconnectedCallback(): void;
81
182
  protected firstUpdated(changed: PropertyValues): void;
@@ -84,6 +185,18 @@ export declare class HelixHeadlessScrollArea extends HelixElement {
84
185
  protected updated(changed: PropertyValues): void;
85
186
  private readonly handleSlotChange;
86
187
  protected render(): TemplateResult;
188
+ /**
189
+ * The scrollbars, the thumbs in them and the corner.
190
+ *
191
+ * **For the pointer, and hidden from everything else.** The viewport is
192
+ * already the tab stop and the region, and the keys scroll it, so a second
193
+ * way in would be one more stop that does the same thing. The scrollbars
194
+ * carry `aria-hidden` and take no focus, as Radix's do.
195
+ *
196
+ * Hidden on the server, which cannot measure whether there is anything to
197
+ * scroll, and until the first measurement.
198
+ */
199
+ private renderScrollbars;
87
200
  }
88
201
  declare global {
89
202
  interface HTMLElementTagNameMap {