@fusion.dev/helix-headless 0.146.0 → 0.148.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (288) hide show
  1. package/custom-elements.json +9287 -1084
  2. package/dist/accordion/item/accordion-item.d.ts +43 -21
  3. package/dist/accordion/item/accordion-item.js +37 -11
  4. package/dist/accordion/root/accordion-root.d.ts +8 -2
  5. package/dist/accordion/root/accordion-root.js +6 -8
  6. package/dist/announcement/root/announcement-root.d.ts +66 -6
  7. package/dist/announcement/root/announcement-root.js +144 -13
  8. package/dist/area-chart/root/area-chart-root.d.ts +18 -1
  9. package/dist/area-chart/root/area-chart-root.js +14 -7
  10. package/dist/avatar/root/avatar-root.d.ts +31 -1
  11. package/dist/avatar/root/avatar-root.js +11 -1
  12. package/dist/badge/count.d.ts +14 -0
  13. package/dist/badge/count.js +20 -0
  14. package/dist/badge/root/badge-root.d.ts +57 -6
  15. package/dist/badge/root/badge-root.js +77 -8
  16. package/dist/bar-chart/root/bar-chart-root.js +11 -20
  17. package/dist/bar-chart/stack.d.ts +10 -0
  18. package/dist/bar-chart/stack.js +8 -0
  19. package/dist/blockquote/root/blockquote-root.d.ts +66 -8
  20. package/dist/blockquote/root/blockquote-root.js +85 -8
  21. package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +14 -0
  22. package/dist/breadcrumbs/breadcrumb/breadcrumb.js +12 -2
  23. package/dist/breadcrumbs/root/breadcrumbs-root.js +2 -2
  24. package/dist/button/root/button-root.d.ts +24 -38
  25. package/dist/button/root/button-root.js +6 -37
  26. package/dist/button/submitter.d.ts +27 -0
  27. package/dist/button/submitter.js +25 -0
  28. package/dist/button-group/arrows.d.ts +14 -0
  29. package/dist/button-group/arrows.js +10 -0
  30. package/dist/button-group/root/button-group-root.d.ts +141 -3
  31. package/dist/button-group/root/button-group-root.js +142 -2
  32. package/dist/canvas/edge-pan.d.ts +61 -0
  33. package/dist/canvas/edge-pan.js +63 -0
  34. package/dist/canvas/node/canvas-node.d.ts +12 -2
  35. package/dist/canvas/node/canvas-node.js +6 -2
  36. package/dist/canvas/root/canvas-document.d.ts +10 -0
  37. package/dist/canvas/root/canvas-document.js +1 -0
  38. package/dist/canvas/root/canvas-root.d.ts +107 -5
  39. package/dist/canvas/root/canvas-root.js +140 -36
  40. package/dist/canvas/snap.d.ts +42 -0
  41. package/dist/canvas/snap.js +32 -0
  42. package/dist/card/root/card-root.d.ts +12 -1
  43. package/dist/card/root/card-root.js +11 -4
  44. package/dist/carousel/root/carousel-root.d.ts +4 -3
  45. package/dist/carousel/root/carousel-root.js +2 -6
  46. package/dist/chat/root/chat-root.d.ts +28 -4
  47. package/dist/chat/root/chat-root.js +12 -7
  48. package/dist/checkbox/root/checkbox-root.js +5 -7
  49. package/dist/checkbox-group/root/checkbox-group-root.d.ts +13 -0
  50. package/dist/checkbox-group/root/checkbox-group-root.js +16 -7
  51. package/dist/checkbox-group/select-all.d.ts +9 -4
  52. package/dist/checkbox-group/select-all.js +1 -1
  53. package/dist/code-block/root/code-block-root.d.ts +41 -18
  54. package/dist/code-block/root/code-block-root.js +21 -6
  55. package/dist/color-input/root/color-input-root.d.ts +11 -0
  56. package/dist/color-input/root/color-input-root.js +12 -5
  57. package/dist/color-picker/channels.js +1 -2
  58. package/dist/color-picker/root/color-picker-root.d.ts +32 -24
  59. package/dist/color-picker/root/color-picker-root.js +99 -55
  60. package/dist/color-picker/wheel.d.ts +28 -0
  61. package/dist/color-picker/wheel.js +15 -0
  62. package/dist/combobox/root/combobox-root.d.ts +83 -11
  63. package/dist/combobox/root/combobox-root.js +81 -18
  64. package/dist/command/root/command-root.d.ts +7 -4
  65. package/dist/command/root/command-root.js +2 -19
  66. package/dist/copy-button/root/copy-button-root.d.ts +16 -1
  67. package/dist/copy-button/root/copy-button-root.js +7 -2
  68. package/dist/data-table/keys.d.ts +0 -18
  69. package/dist/data-table/keys.js +1 -11
  70. package/dist/data-table/root/data-table-root.js +29 -50
  71. package/dist/date-input/root/date-input-root.d.ts +8 -1
  72. package/dist/date-input/root/date-input-root.js +8 -5
  73. package/dist/date-picker/root/date-picker-root.d.ts +14 -9
  74. package/dist/date-picker/root/date-picker-root.js +21 -16
  75. package/dist/description-list/item/description-list-item.d.ts +22 -4
  76. package/dist/description-list/item/description-list-item.js +14 -4
  77. package/dist/divider/root/divider-root.d.ts +45 -16
  78. package/dist/divider/root/divider-root.js +28 -4
  79. package/dist/donut-chart/root/donut-chart-root.js +13 -6
  80. package/dist/donut-chart/slice-label.d.ts +35 -0
  81. package/dist/donut-chart/slice-label.js +11 -0
  82. package/dist/drawer/root/drawer-root.d.ts +4 -2
  83. package/dist/drawer/root/drawer-root.js +15 -3
  84. package/dist/drilldown/item/drilldown-item.d.ts +21 -1
  85. package/dist/drilldown/item/drilldown-item.js +38 -4
  86. package/dist/drilldown/root/drilldown-root.js +3 -2
  87. package/dist/element-events.generated.js +5 -1
  88. package/dist/empty/root/empty-root.d.ts +46 -2
  89. package/dist/empty/root/empty-root.js +50 -5
  90. package/dist/file-input/root/file-input-root.d.ts +34 -6
  91. package/dist/file-input/root/file-input-root.js +55 -21
  92. package/dist/file-input/status.d.ts +24 -0
  93. package/dist/file-input/status.js +11 -0
  94. package/dist/filter-input/chip/filter-chip.d.ts +23 -0
  95. package/dist/filter-input/chip/filter-chip.js +10 -2
  96. package/dist/filter-input/root/filter-input-root.d.ts +8 -0
  97. package/dist/filter-input/root/filter-input-root.js +17 -27
  98. package/dist/format-date/fields.d.ts +20 -0
  99. package/dist/format-date/fields.js +14 -0
  100. package/dist/format-date/options.d.ts +5 -5
  101. package/dist/format-date/options.js +10 -39
  102. package/dist/format-date/root/format-date-root.d.ts +53 -4
  103. package/dist/format-date/root/format-date-root.js +38 -50
  104. package/dist/graph/root/graph-root.d.ts +23 -5
  105. package/dist/graph/root/graph-root.js +17 -20
  106. package/dist/heatmap/root/buckets.d.ts +21 -0
  107. package/dist/heatmap/root/buckets.js +34 -0
  108. package/dist/heatmap/root/heatmap-root.d.ts +76 -3
  109. package/dist/heatmap/root/heatmap-root.js +105 -20
  110. package/dist/icon/index.d.ts +1 -1
  111. package/dist/icon/index.js +1 -1
  112. package/dist/icon/registry.d.ts +26 -1
  113. package/dist/icon/registry.js +12 -1
  114. package/dist/icon/root/icon-root.d.ts +13 -0
  115. package/dist/icon/root/icon-root.js +23 -2
  116. package/dist/icon/root/index.d.ts +1 -1
  117. package/dist/icon/root/index.js +1 -1
  118. package/dist/image/root/image-root.d.ts +20 -0
  119. package/dist/image/root/image-root.js +6 -1
  120. package/dist/input/root/input-root.d.ts +23 -2
  121. package/dist/input/root/input-root.js +12 -8
  122. package/dist/kbd/root/kbd-root.d.ts +20 -3
  123. package/dist/kbd/root/kbd-root.js +23 -50
  124. package/dist/legend/hidden-series.d.ts +10 -2
  125. package/dist/legend/hidden-series.js +5 -2
  126. package/dist/legend/root/legend-root.d.ts +25 -7
  127. package/dist/legend/root/legend-root.js +25 -26
  128. package/dist/lightbox/root/lightbox-root.d.ts +50 -5
  129. package/dist/lightbox/root/lightbox-root.js +76 -8
  130. package/dist/lightbox/zoom.d.ts +2 -0
  131. package/dist/lightbox/zoom.js +5 -3
  132. package/dist/line-chart/root/line-chart-root.d.ts +16 -0
  133. package/dist/line-chart/root/line-chart-root.js +10 -2
  134. package/dist/list/root/list-root.d.ts +10 -2
  135. package/dist/list/root/list-root.js +31 -24
  136. package/dist/list/selection.d.ts +17 -0
  137. package/dist/list/selection.js +16 -0
  138. package/dist/listbox/root/listbox-root.d.ts +125 -26
  139. package/dist/listbox/root/listbox-root.js +156 -166
  140. package/dist/map/marker/map-marker.d.ts +2 -1
  141. package/dist/map/root/map-root.d.ts +40 -2
  142. package/dist/map/root/map-root.js +64 -23
  143. package/dist/megamenu/hand-over.d.ts +75 -0
  144. package/dist/megamenu/hand-over.js +67 -0
  145. package/dist/megamenu/root/megamenu-root.d.ts +38 -14
  146. package/dist/megamenu/root/megamenu-root.js +29 -50
  147. package/dist/menu/item/menu-item.js +4 -4
  148. package/dist/menu/root/menu-root.d.ts +5 -2
  149. package/dist/meter/root/meter-root.d.ts +42 -0
  150. package/dist/meter/root/meter-root.js +33 -7
  151. package/dist/navigation/root/navigation-root.js +5 -8
  152. package/dist/notifications/group/notification-group.d.ts +8 -1
  153. package/dist/notifications/group/notification-group.js +12 -6
  154. package/dist/notifications/notification/notification.d.ts +12 -1
  155. package/dist/notifications/notification/notification.js +3 -1
  156. package/dist/notifications/root/notifications-root.d.ts +48 -3
  157. package/dist/notifications/root/notifications-root.js +36 -6
  158. package/dist/number-input/grain.d.ts +28 -0
  159. package/dist/number-input/grain.js +14 -0
  160. package/dist/number-input/root/number-input-root.d.ts +17 -1
  161. package/dist/number-input/root/number-input-root.js +29 -18
  162. package/dist/object-inspector/root/object-inspector-root.d.ts +17 -6
  163. package/dist/object-inspector/root/object-inspector-root.js +31 -20
  164. package/dist/option/index.d.ts +1 -0
  165. package/dist/option/index.js +1 -0
  166. package/dist/option/separator/option-separator.d.ts +30 -0
  167. package/dist/option/separator/option-separator.js +21 -0
  168. package/dist/outline/root/outline-root.d.ts +12 -0
  169. package/dist/outline/root/outline-root.js +5 -19
  170. package/dist/pagination/size/pagination-size.d.ts +6 -0
  171. package/dist/pagination/size/pagination-size.js +5 -3
  172. package/dist/pin-input/code.d.ts +51 -1
  173. package/dist/pin-input/code.js +37 -0
  174. package/dist/pin-input/root/pin-input-root.d.ts +98 -121
  175. package/dist/pin-input/root/pin-input-root.js +151 -156
  176. package/dist/popover/hide-outside.js +2 -9
  177. package/dist/popover/root/popover-root.d.ts +7 -1
  178. package/dist/popover/root/popover-root.js +9 -1
  179. package/dist/progress/root/progress-root.d.ts +27 -0
  180. package/dist/progress/root/progress-root.js +25 -7
  181. package/dist/qr-code/export.d.ts +19 -0
  182. package/dist/qr-code/export.js +14 -0
  183. package/dist/qr-code/name.d.ts +11 -0
  184. package/dist/qr-code/name.js +7 -0
  185. package/dist/qr-code/root/qr-code-root.d.ts +31 -9
  186. package/dist/qr-code/root/qr-code-root.js +29 -17
  187. package/dist/radio/group/radio-group.d.ts +15 -0
  188. package/dist/radio/root/radio-root.js +2 -2
  189. package/dist/rating/root/rating-root.d.ts +22 -9
  190. package/dist/rating/root/rating-root.js +15 -39
  191. package/dist/scatter-chart/measures.d.ts +22 -0
  192. package/dist/scatter-chart/measures.js +11 -0
  193. package/dist/scatter-chart/root/scatter-chart-root.d.ts +26 -0
  194. package/dist/scatter-chart/root/scatter-chart-root.js +21 -7
  195. package/dist/scroll-area/scrollbar.d.ts +0 -8
  196. package/dist/scroll-area/scrollbar.js +1 -1
  197. package/dist/select/align.d.ts +47 -0
  198. package/dist/select/align.js +7 -0
  199. package/dist/select/root/select-root.d.ts +115 -11
  200. package/dist/select/root/select-root.js +104 -20
  201. package/dist/slider/root/slider-root.d.ts +18 -1
  202. package/dist/slider/root/slider-root.js +22 -0
  203. package/dist/sparkline/readings.d.ts +30 -12
  204. package/dist/sparkline/readings.js +32 -15
  205. package/dist/sparkline/root/sparkline-root.d.ts +46 -3
  206. package/dist/sparkline/root/sparkline-root.js +60 -21
  207. package/dist/speed-dial/group/speed-dial-group.d.ts +48 -0
  208. package/dist/speed-dial/group/speed-dial-group.js +43 -0
  209. package/dist/speed-dial/index.d.ts +1 -0
  210. package/dist/speed-dial/index.js +1 -0
  211. package/dist/speed-dial/item/speed-dial-item.d.ts +27 -2
  212. package/dist/speed-dial/item/speed-dial-item.js +43 -5
  213. package/dist/speed-dial/long-press.d.ts +50 -0
  214. package/dist/speed-dial/long-press.js +48 -0
  215. package/dist/speed-dial/root/speed-dial-root.d.ts +86 -1
  216. package/dist/speed-dial/root/speed-dial-root.js +123 -6
  217. package/dist/splitter/root/splitter-root.d.ts +9 -2
  218. package/dist/splitter/root/splitter-root.js +18 -3
  219. package/dist/steps/root/steps-root.d.ts +8 -1
  220. package/dist/steps/root/steps-root.js +6 -1
  221. package/dist/steps/step/step.d.ts +1 -0
  222. package/dist/steps/step/step.js +1 -1
  223. package/dist/table/cell/table-cell.d.ts +8 -1
  224. package/dist/table/cell/table-cell.js +6 -2
  225. package/dist/table/column/table-column.d.ts +6 -0
  226. package/dist/table/column/table-column.js +5 -1
  227. package/dist/table/grid-controller.d.ts +117 -0
  228. package/dist/table/grid-controller.js +293 -0
  229. package/dist/table/root/table-root.d.ts +47 -3
  230. package/dist/table/root/table-root.js +93 -29
  231. package/dist/table/row/table-row.d.ts +36 -0
  232. package/dist/table/row/table-row.js +52 -2
  233. package/dist/tabs/root/tabs-root.d.ts +5 -3
  234. package/dist/tag/group/tag-group.d.ts +16 -4
  235. package/dist/tag/group/tag-group.js +23 -20
  236. package/dist/textarea/root/textarea-root.d.ts +14 -2
  237. package/dist/textarea/root/textarea-root.js +6 -7
  238. package/dist/time-input/root/time-input-root.d.ts +5 -1
  239. package/dist/time-input/root/time-input-root.js +10 -7
  240. package/dist/time-picker/root/time-picker-root.d.ts +12 -14
  241. package/dist/time-picker/root/time-picker-root.js +18 -23
  242. package/dist/toast/item/toast-item.d.ts +9 -6
  243. package/dist/toast/item/toast-item.js +1 -1
  244. package/dist/toast/root/toast-root.d.ts +40 -4
  245. package/dist/toast/root/toast-root.js +68 -16
  246. package/dist/toast/words.d.ts +12 -0
  247. package/dist/toast/words.js +25 -0
  248. package/dist/toggle/group/toggle-group.d.ts +29 -5
  249. package/dist/toggle/group/toggle-group.js +26 -43
  250. package/dist/toggle/root/toggle-root.js +2 -4
  251. package/dist/toolbar/root/toolbar-root.d.ts +52 -5
  252. package/dist/toolbar/root/toolbar-root.js +88 -13
  253. package/dist/tooltip/root/tooltip-root.d.ts +7 -1
  254. package/dist/tooltip/root/tooltip-root.js +10 -2
  255. package/dist/tour/root/tour-root.d.ts +15 -0
  256. package/dist/tour/root/tour-root.js +20 -1
  257. package/dist/tour/stop/tour-stop.d.ts +3 -0
  258. package/dist/tour/stop/tour-stop.js +3 -3
  259. package/dist/tree/root/tree-root.js +2 -2
  260. package/dist/trend/figure.d.ts +16 -0
  261. package/dist/trend/figure.js +8 -0
  262. package/dist/trend/root/trend-root.d.ts +41 -2
  263. package/dist/trend/root/trend-root.js +29 -3
  264. package/dist/video/root/extra-controls.d.ts +12 -0
  265. package/dist/video/root/extra-controls.js +6 -2
  266. package/dist/video/root/video-root.d.ts +16 -1
  267. package/dist/video/root/video-root.js +15 -1
  268. package/dist/video-playlist/root/video-playlist-root.d.ts +11 -1
  269. package/dist/video-playlist/root/video-playlist-root.js +3 -0
  270. package/dist/virtual-list/fill.d.ts +11 -0
  271. package/dist/virtual-list/fill.js +9 -0
  272. package/dist/virtual-list/keys.d.ts +16 -7
  273. package/dist/virtual-list/keys.js +17 -6
  274. package/dist/virtual-list/plan.d.ts +17 -1
  275. package/dist/virtual-list/plan.js +13 -2
  276. package/dist/virtual-list/root/virtual-list-root.d.ts +25 -3
  277. package/dist/virtual-list/root/virtual-list-root.js +53 -41
  278. package/lint.json +1 -1
  279. package/package.json +5 -5
  280. package/types/jsx.d.ts +4934 -954
  281. package/types/svelte.d.ts +2 -0
  282. package/types/vue.d.ts +946 -253
  283. package/dist/color-picker/swatches.d.ts +0 -12
  284. package/dist/color-picker/swatches.js +0 -26
  285. package/dist/rating/steps.d.ts +0 -7
  286. package/dist/rating/steps.js +0 -9
  287. package/dist/tooltip/focus-target.d.ts +0 -6
  288. package/dist/tooltip/focus-target.js +0 -9
@@ -1,9 +1,9 @@
1
- import { type Color, type ColorFormat, type ColorWords, HelixFormElement } from '@fusion.dev/helix-core';
1
+ import { type Color, type ColorFormat, type ColorWords, HelixFormElement, KeyboardNavigationController } from '@fusion.dev/helix-core';
2
2
  import { type PropertyValues, type TemplateResult } from 'lit';
3
3
  import '../../button/index.js';
4
4
  import '../../button-group/index.js';
5
5
  import '../../slider/index.js';
6
- declare const HelixHeadlessColorPicker_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerValueInterface) & typeof HelixFormElement;
6
+ declare const HelixHeadlessColorPicker_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinPickerFeedbackInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerValueInterface) & typeof HelixFormElement;
7
7
  /**
8
8
  * @summary A color picker made of a square and two ramps.
9
9
  *
@@ -62,11 +62,14 @@ declare const HelixHeadlessColorPicker_base: (new (...args: any[]) => import("@f
62
62
  * @csspart channel-marker-label - The value a mark stands at, when `marker-labels` is set.
63
63
  * @csspart channel-markers - The row of marks along the track.
64
64
  * @csspart channel-output - The current value, shown beside the track.
65
+ * @csspart channel-tooltip - A ramp's value in a bubble, where a ramp shows one.
66
+ * @csspart channel-tooltips - The layer over a ramp's track that holds its bubble.
65
67
  * @csspart channels - The ramps beside the sample.
66
68
  * @csspart controls - The row under the square.
67
69
  * @csspart eyedropper - The control that samples a color from the screen.
68
70
  * @csspart eyedropper-button - The button inside `eyedropper`.
69
71
  * @csspart eyedropper-live - The live region of the button inside `eyedropper`, which says its pending label.
72
+ * @csspart eyedropper-spinner - The ring the eyedropper button turns while it is pending.
70
73
  * @csspart eyedropper-text - The words on the button inside `eyedropper`, trimmed to their capitals and baseline.
71
74
  * @csspart feedback - The message under the picker, while `feedback` is set.
72
75
  * @csspart field - One channel's number field with its label, in `channel-fields`.
@@ -77,6 +80,7 @@ declare const HelixHeadlessColorPicker_base: (new (...args: any[]) => import("@f
77
80
  * @csspart format - The control that changes the syntax the value is written in.
78
81
  * @csspart format-button - The button inside `format`.
79
82
  * @csspart format-live - The live region of the button inside `format`, which says its pending label.
83
+ * @csspart format-spinner - The ring the syntax button turns while it is pending.
80
84
  * @csspart format-text - The words on the button inside `format`, trimmed to their capitals and baseline.
81
85
  * @csspart grid - The saturation and brightness square. Draw the mark that shows
82
86
  * where the color sits with `::part(grid)::after` in your stylesheet. The
@@ -88,11 +92,15 @@ declare const HelixHeadlessColorPicker_base: (new (...args: any[]) => import("@f
88
92
  * @csspart swatch - One preset, an option in the `swatches` listbox.
89
93
  * @csspart swatches - The row of presets, a listbox.
90
94
  * @csspart value - The text field that holds the color. It accepts a typed or pasted color.
95
+ * @csspart wheel - The hue ring round the square, with `wheel`. Draw the ring and its mark from `--color-picker-hue`.
96
+ * @csspart wheel-hue - The range input behind the ring, which a reader turns with the keys.
91
97
  *
92
98
  * @cssproperty --color-picker-brightness - The chosen brightness, 0 to 100, as a percentage.
93
99
  * @cssproperty --color-picker-hue - The chosen hue, 0 to 360, unitless.
94
100
  * @cssproperty --color-picker-saturation - The chosen saturation, 0 to 100, as a percentage.
95
101
  * @cssproperty --color-picker-swatch - The color a chip shows: the current color on the sample, and the preset's color on each preset.
102
+ *
103
+ * @cssstate invalid - While `invalid` is set or `feedback` says what is wrong.
96
104
  */
97
105
  export declare class HelixHeadlessColorPicker extends HelixHeadlessColorPicker_base {
98
106
  /**
@@ -165,15 +173,6 @@ export declare class HelixHeadlessColorPicker extends HelixHeadlessColorPicker_b
165
173
  * What the eyedropper is called.
166
174
  */
167
175
  eyedropperLabel: string;
168
- /**
169
- * A message under the picker, such as what is wrong with the color.
170
- *
171
- * While set, the picker is invalid and does not submit, as a field's
172
- * `feedback` is, and the square and the value text are described by it.
173
- * Color Input shows its own message here, so a reader in the open panel
174
- * still sees it.
175
- */
176
- feedback: string;
177
176
  /**
178
177
  * The syntax the value is written in: `hex`, `rgb`, or `hsl`.
179
178
  *
@@ -193,16 +192,6 @@ export declare class HelixHeadlessColorPicker extends HelixHeadlessColorPicker_b
193
192
  * What the hue channel is called.
194
193
  */
195
194
  hueLabel: string;
196
- /**
197
- * Whether the current selection fails validation.
198
- *
199
- * A flag rather than a message, the split Date Picker also draws. A flat
200
- * picker has no room of its own for a sentence: the field that wraps one owns
201
- * the label, the hint and the feedback, and a second message inside the panel
202
- * would be the same error said twice. What is left for the picker is the one
203
- * thing the field cannot draw from outside, the mark on the answer itself.
204
- */
205
- invalid: boolean;
206
195
  /**
207
196
  * What the lightness channel's field is called, in `channel-fields` with
208
197
  * hsl.
@@ -319,6 +308,16 @@ export declare class HelixHeadlessColorPicker extends HelixHeadlessColorPicker_b
319
308
  * speaks it. Absent is the control's own sentence, in English.
320
309
  */
321
310
  valueMissingMessage?: string;
311
+ /**
312
+ * Draws the hue as a wheel around the square, in place of the hue ramp, as
313
+ * React Aria's ColorWheel sits round its ColorArea.
314
+ *
315
+ * The ring is one stop, a slider a reader turns with the arrow keys, Home
316
+ * and End, the same way round in either writing direction, and a press or a
317
+ * drag on it takes the hue in that direction. Off, the picker keeps its
318
+ * ramp.
319
+ */
320
+ wheel: boolean;
322
321
  /**
323
322
  * The color the reader has moved to, or nothing while they have moved none.
324
323
  *
@@ -412,8 +411,14 @@ export declare class HelixHeadlessColorPicker extends HelixHeadlessColorPicker_b
412
411
  /**
413
412
  * The arrows, Home and End in the presets: focus moves, and nothing is
414
413
  * chosen until Enter, Space or a press, as in React Aria's swatch picker.
414
+ *
415
+ * Core's roving set, as Legend's toggles are: the arrows follow the line of
416
+ * text, so the row reverses in a right-to-left page, Up and Down are the
417
+ * previous and the next since the row wraps onto lines, and focus stops at
418
+ * the ends, since a row of colors is no ring. A press from anywhere else in
419
+ * the picker is not the row's to move.
415
420
  */
416
- private readonly handleSwatchKeydown;
421
+ protected readonly swatchKeys: KeyboardNavigationController;
417
422
  /** Walks the format on, and rewrites the value in it. */
418
423
  private readonly handleFormat;
419
424
  /**
@@ -436,6 +441,11 @@ export declare class HelixHeadlessColorPicker extends HelixHeadlessColorPicker_b
436
441
  * reaches a corner, and without it the handle stops wherever the pointer left.
437
442
  */
438
443
  private readonly handleGridPointer;
444
+ /**
445
+ * A press or a drag on the hue wheel: the hue in that direction from its
446
+ * center. A press in the square inside it is the square's.
447
+ */
448
+ private readonly handleWheelPointer;
439
449
  protected firstUpdated(changed: import('lit').PropertyValues): void;
440
450
  /**
441
451
  * Reports the color to the form.
@@ -470,8 +480,6 @@ export declare class HelixHeadlessColorPicker extends HelixHeadlessColorPicker_b
470
480
  * what React Aria's ColorArea does.
471
481
  */
472
482
  private readonly handleAreaKeydown;
473
- /** @internal `feedback` marks the picker invalid, as a field's does. */
474
- protected get validityFeedback(): string;
475
483
  /**
476
484
  * Reports "required and empty", or clears it.
477
485
  *
@@ -4,20 +4,20 @@ 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 { CopyController, capturePointer, colorName, customElement, drawIcon, fillTemplate, formatColor, HelixFormElement, HelixSampleEndEvent, HelixSampleStartEvent, hostAria, hueName, inlineStep, isRtl, MixinControllerValue, parseColor, rovingStop, splitValues, toCss, wordsConverter, } from '@fusion.dev/helix-core';
7
+ import { CopyController, capturePointer, clamp, colorName, customElement, drawIcon, fillTemplate, focusItemOf, formatColor, formatNumber, HelixFormElement, HelixSampleEndEvent, HelixSampleStartEvent, hostAria, hueName, isRtl, KeyboardNavigationController, localeOf, MixinControllerValue, MixinPickerFeedback, parseColor, rovingStop, splitValues, toCss, wordsConverter, } from '@fusion.dev/helix-core';
8
8
  import { eyedropper } from '@fusion.dev/helix-icons';
9
9
  import { nothing } from 'lit';
10
10
  import { property, state } from 'lit/decorators.js';
11
11
  import { live } from 'lit/directives/live.js';
12
12
  import { html } from 'lit/static-html.js';
13
13
  import { channelFields, writeChannel } from '../channels.js';
14
- import { swatchMove } from '../swatches.js';
14
+ import { areaAt, hueAt } from '../wheel.js';
15
15
  import '../../button/index.js';
16
16
  import '../../button-group/index.js';
17
17
  import '../../slider/index.js';
18
18
  const FORMATS = ['hex', 'rgb', 'hsl'];
19
19
  const START = { alpha: 100, brightness: 100, hue: 0, saturation: 100 };
20
- let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinControllerValue(HelixFormElement) {
20
+ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinPickerFeedback(MixinControllerValue(HelixFormElement)) {
21
21
  constructor() {
22
22
  super(...arguments);
23
23
  this.alpha = false;
@@ -29,11 +29,9 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
29
29
  this.copiedLabel = 'Copied';
30
30
  this.copyLabel = 'Copy {value}';
31
31
  this.eyedropperLabel = 'Sample a color from the screen';
32
- this.feedback = '';
33
32
  this.formatLabel = 'Syntax: {format}. Change it.';
34
33
  this.greenLabel = 'Green';
35
34
  this.hueLabel = 'Hue';
36
- this.invalid = false;
37
35
  this.lightnessLabel = 'Lightness';
38
36
  this.noEyedropper = false;
39
37
  this.noFormat = false;
@@ -47,6 +45,7 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
47
45
  this.swatches = '';
48
46
  this.toolsLabel = 'Color tools';
49
47
  this.valueLabel = 'Color';
48
+ this.wheel = false;
50
49
  this.sampling = false;
51
50
  this.owned = false;
52
51
  this.announcesInput = true;
@@ -96,19 +95,21 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
96
95
  }
97
96
  this.settle();
98
97
  };
99
- this.handleSwatchKeydown = (event) => {
100
- const row = [
101
- ...(this.renderRoot.querySelectorAll('[part="swatches"] [part="swatch"]') ?? []),
102
- ];
103
- const at = row.indexOf(event.target);
104
- const next = swatchMove(event.key, inlineStep(this, event.key), at, row.length);
105
- if (at < 0 || next === null) {
106
- return;
107
- }
108
- event.preventDefault();
109
- this.swatchAt = next;
110
- row[next]?.focus();
111
- };
98
+ this.swatchKeys = new KeyboardNavigationController(this, {
99
+ items: () => [
100
+ ...(this.renderRoot?.querySelectorAll('[part="swatches"] [part="swatch"]') ??
101
+ []),
102
+ ].map((swatch, index) => focusItemOf(swatch, {
103
+ focus: () => {
104
+ this.swatchAt = index;
105
+ swatch.focus();
106
+ },
107
+ owns: (node) => node === swatch,
108
+ })),
109
+ origin: 'focus',
110
+ selects: () => false,
111
+ wrap: false,
112
+ });
112
113
  this.handleFormat = () => {
113
114
  if (this.readOnly) {
114
115
  return;
@@ -161,10 +162,32 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
161
162
  if (box.width === 0 || box.height === 0) {
162
163
  return;
163
164
  }
164
- const fromLeft = Math.min(1, Math.max(0, (event.clientX - box.left) / box.width));
165
- const across = isRtl(grid) ? 1 - fromLeft : fromLeft;
166
- const down = Math.min(1, Math.max(0, (event.clientY - box.top) / box.height));
167
- this.move({ brightness: Math.round((1 - down) * 100), saturation: Math.round(across * 100) });
165
+ this.move(areaAt(event.clientX, event.clientY, box, isRtl(grid)));
166
+ };
167
+ this.handleWheelPointer = (event) => {
168
+ const wheel = event.currentTarget;
169
+ const grid = this.partNamed('grid');
170
+ if (this.isDisabled || (grid && event.composedPath().includes(grid))) {
171
+ return;
172
+ }
173
+ if (event.type === 'pointerup' || event.type === 'pointercancel') {
174
+ if (wheel.hasPointerCapture(event.pointerId)) {
175
+ this.settle();
176
+ }
177
+ return;
178
+ }
179
+ if (event.type === 'pointerdown') {
180
+ capturePointer(wheel, event.pointerId);
181
+ this.partNamed('wheel-hue')?.focus();
182
+ }
183
+ else if (!wheel.hasPointerCapture(event.pointerId)) {
184
+ return;
185
+ }
186
+ event.preventDefault();
187
+ const box = wheel.getBoundingClientRect();
188
+ if (box.width > 0 && box.height > 0) {
189
+ this.move({ hue: hueAt(event.clientX, event.clientY, box) });
190
+ }
168
191
  };
169
192
  this.handleAreaKeydown = (event) => {
170
193
  if (this.isDisabled || this.readOnly) {
@@ -172,14 +195,14 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
172
195
  }
173
196
  const color = this.color;
174
197
  const along = isRtl(this) ? -1 : 1;
175
- const clamp = (at) => Math.min(100, Math.max(0, at));
198
+ const held = (at) => clamp(at, 0, 100);
176
199
  const moves = {
177
- ArrowDown: { brightness: clamp(color.brightness - 1) },
178
- ArrowLeft: { saturation: clamp(color.saturation - along) },
179
- ArrowRight: { saturation: clamp(color.saturation + along) },
180
- ArrowUp: { brightness: clamp(color.brightness + 1) },
181
- PageDown: { brightness: clamp(color.brightness - 10) },
182
- PageUp: { brightness: clamp(color.brightness + 10) },
200
+ ArrowDown: { brightness: held(color.brightness - 1) },
201
+ ArrowLeft: { saturation: held(color.saturation - along) },
202
+ ArrowRight: { saturation: held(color.saturation + along) },
203
+ ArrowUp: { brightness: held(color.brightness + 1) },
204
+ PageDown: { brightness: held(color.brightness - 10) },
205
+ PageUp: { brightness: held(color.brightness + 10) },
183
206
  };
184
207
  const next = moves[event.key];
185
208
  if (!next) {
@@ -239,9 +262,6 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
239
262
  this.internals.setFormValue(this.value === '' ? null : this.value);
240
263
  this.reportRequired();
241
264
  }
242
- get validityFeedback() {
243
- return this.feedback;
244
- }
245
265
  reportRequired() {
246
266
  if (this.required && this.value === '') {
247
267
  this.internals.setValidity({ valueMissing: true }, this.valueMissingMessage || 'Choose a color.', this.partNamed('grid') ?? undefined);
@@ -325,9 +345,10 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
325
345
  part="channel"
326
346
  exportparts="control: channel-control, feedback: channel-feedback, field: channel-field,
327
347
  hint: channel-hint, label: channel-label, marker: channel-marker,
328
- marker-label: channel-marker-label, markers: channel-markers, output: channel-output"
348
+ marker-label: channel-marker-label, markers: channel-markers, output: channel-output,
349
+ tooltip: channel-tooltip, tooltips: channel-tooltips"
329
350
  data-channel=${channel}
330
- aria-invalid=${this.invalid ? 'true' : nothing}
351
+ aria-invalid=${this.marked ? 'true' : nothing}
331
352
  label=${label}
332
353
  max=${max}
333
354
  min="0"
@@ -365,7 +386,6 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
365
386
  }
366
387
  willUpdate(changed) {
367
388
  super.willUpdate(changed);
368
- this.internals.ariaInvalid = this.invalid ? 'true' : null;
369
389
  const outside = [...(this.internals.labels ?? [])];
370
390
  hostAria(this.internals, { labelledBy: outside, role: outside.length > 0 ? 'group' : '' });
371
391
  if (!this.hydrating) {
@@ -377,7 +397,7 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
377
397
  ${this.sampling && !this.noEyedropper
378
398
  ? html `<${this.tag('button')}
379
399
  part="eyedropper"
380
- exportparts="button: eyedropper-button, live: eyedropper-live, text: eyedropper-text"
400
+ exportparts="button: eyedropper-button, live: eyedropper-live, spinner: eyedropper-spinner, text: eyedropper-text"
381
401
  label=${this.eyedropperLabel}
382
402
  ?disabled=${this.isDisabled}
383
403
  @click=${this.handleEyeDropper}
@@ -389,7 +409,7 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
389
409
  ? nothing
390
410
  : html `<${this.tag('button')}
391
411
  part="format"
392
- exportparts="button: format-button, live: format-live, text: format-text"
412
+ exportparts="button: format-button, live: format-live, spinner: format-spinner, text: format-text"
393
413
  label=${fillTemplate(this.formatLabel, { format: this.format ?? 'hex' })}
394
414
  ?disabled=${this.isDisabled}
395
415
  @click=${this.handleFormat}
@@ -411,7 +431,6 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
411
431
  role="listbox"
412
432
  aria-label=${this.presetsLabel}
413
433
  aria-orientation="horizontal"
414
- @keydown=${this.handleSwatchKeydown}
415
434
  >
416
435
  ${presets.map((preset, index) => {
417
436
  const parsed = parseColor(preset);
@@ -420,7 +439,7 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
420
439
  type="button"
421
440
  role="option"
422
441
  tabindex=${index === stop ? '0' : '-1'}
423
- aria-label=${parsed ? colorName(parsed, this.colorWords, this.lang) : preset}
442
+ aria-label=${parsed ? colorName(parsed, this.colorWords, localeOf(this)) : preset}
424
443
  aria-selected=${chosen[index] ? 'true' : 'false'}
425
444
  style="--color-picker-swatch: ${preset}"
426
445
  ?disabled=${this.isDisabled}
@@ -435,13 +454,13 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
435
454
  render() {
436
455
  const color = this.color;
437
456
  const painted = toCss(color);
438
- const named = colorName(color, this.colorWords, this.lang);
457
+ const named = colorName(color, this.colorWords, localeOf(this));
439
458
  const both = `${this.saturationLabel} ${color.saturation}%, ${this.brightnessLabel} ${color.brightness}%, ${named}`;
440
459
  const reversed = `${this.brightnessLabel} ${color.brightness}%, ${this.saturationLabel} ${color.saturation}%, ${named}`;
441
- const hue = hueName({ alpha: 100, brightness: 100, hue: color.hue, saturation: 100 }, this.colorWords, this.lang);
460
+ const hue = hueName({ alpha: 100, brightness: 100, hue: color.hue, saturation: 100 }, this.colorWords, localeOf(this));
442
461
  const owner = this.getAttribute('aria-label')?.trim();
443
462
  const axisName = (channel) => (owner ? `${owner}, ${channel}` : channel);
444
- return html `<div
463
+ const area = html `<div
445
464
  part="grid"
446
465
  style="--color-picker-hue: ${color.hue}; --color-picker-saturation: ${color.saturation}%; --color-picker-brightness: ${color.brightness}%"
447
466
  @pointerdown=${this.handleGridPointer}
@@ -458,7 +477,7 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
458
477
  aria-label=${axisName(this.saturationLabel)}
459
478
  aria-describedby=${this.feedback === '' ? nothing : 'feedback'}
460
479
  aria-valuetext=${both}
461
- aria-invalid=${this.invalid ? 'true' : nothing}
480
+ aria-invalid=${this.marked ? 'true' : nothing}
462
481
  .value=${String(color.saturation)}
463
482
  ?disabled=${this.isDisabled}
464
483
  @input=${(event) => this.takeArea('saturation', event)}
@@ -474,13 +493,41 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
474
493
  aria-label=${axisName(this.brightnessLabel)}
475
494
  aria-describedby=${this.feedback === '' ? nothing : 'feedback'}
476
495
  aria-valuetext=${reversed}
477
- aria-invalid=${this.invalid ? 'true' : nothing}
496
+ aria-invalid=${this.marked ? 'true' : nothing}
478
497
  .value=${String(color.brightness)}
479
498
  ?disabled=${this.isDisabled}
480
499
  @input=${(event) => this.takeArea('brightness', event)}
481
500
  @change=${() => this.settle()}
482
501
  />
483
- </div>
502
+ </div>`;
503
+ return html `${this.wheel
504
+ ? html `<div
505
+ part="wheel"
506
+ style="--color-picker-hue: ${color.hue}"
507
+ @pointerdown=${this.handleWheelPointer}
508
+ @pointermove=${this.handleWheelPointer}
509
+ @pointerup=${this.handleWheelPointer}
510
+ @pointercancel=${this.handleWheelPointer}
511
+ >
512
+ ${''}
513
+ <input
514
+ part="wheel-hue"
515
+ type="range"
516
+ min="0"
517
+ max="360"
518
+ dir="ltr"
519
+ aria-label=${axisName(this.hueLabel)}
520
+ aria-describedby=${this.feedback === '' ? nothing : 'feedback'}
521
+ aria-valuetext=${`${color.hue}, ${hue}`}
522
+ aria-invalid=${this.marked ? 'true' : nothing}
523
+ .value=${String(color.hue)}
524
+ ?disabled=${this.isDisabled}
525
+ @input=${(event) => this.takeArea('hue', event)}
526
+ @change=${() => this.settle()}
527
+ />
528
+ ${area}
529
+ </div>`
530
+ : area}
484
531
 
485
532
  <div part="controls" style="--color-picker-hue: ${color.hue}; --color-picker-swatch: ${painted}">
486
533
  <button
@@ -494,9 +541,9 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
494
541
  @click=${() => this.copier.copy(this.value)}
495
542
  ></button>
496
543
  <div part="channels">
497
- ${this.renderChannel('hue', this.hueLabel, 360, color.hue, `{value}, ${hue}`)}
544
+ ${this.wheel ? nothing : this.renderChannel('hue', this.hueLabel, 360, color.hue, `{value}, ${hue}`)}
498
545
  ${this.alpha
499
- ? this.renderChannel('alpha', this.opacityLabel, 100, color.alpha, new Intl.NumberFormat(this.lang || undefined, { style: 'percent' }).format(color.alpha / 100))
546
+ ? this.renderChannel('alpha', this.opacityLabel, 100, color.alpha, formatNumber(color.alpha / 100, localeOf(this), { style: 'percent' }))
500
547
  : nothing}
501
548
  </div>
502
549
  </div>
@@ -514,7 +561,7 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
514
561
  type="text"
515
562
  aria-label=${this.valueLabel}
516
563
  aria-describedby=${this.feedback === '' ? nothing : 'feedback'}
517
- aria-invalid=${this.invalid ? 'true' : nothing}
564
+ aria-invalid=${this.marked ? 'true' : nothing}
518
565
  autocomplete=${this.autocomplete || nothing}
519
566
  spellcheck="false"
520
567
  .value=${this.value}
@@ -530,7 +577,7 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
530
577
  </div>
531
578
 
532
579
  ${this.presets.length === 0 ? nothing : this.renderSwatches(painted)}
533
- ${this.feedback === '' ? nothing : html `<p part="feedback" id="feedback">${this.feedback}</p>`}`;
580
+ ${this.renderPickerFeedback()}`;
534
581
  }
535
582
  };
536
583
  __decorate([
@@ -563,9 +610,6 @@ __decorate([
563
610
  __decorate([
564
611
  property({ attribute: 'eyedropper-label' })
565
612
  ], HelixHeadlessColorPicker.prototype, "eyedropperLabel", void 0);
566
- __decorate([
567
- property()
568
- ], HelixHeadlessColorPicker.prototype, "feedback", void 0);
569
613
  __decorate([
570
614
  property({ reflect: true })
571
615
  ], HelixHeadlessColorPicker.prototype, "format", void 0);
@@ -578,9 +622,6 @@ __decorate([
578
622
  __decorate([
579
623
  property({ attribute: 'hue-label' })
580
624
  ], HelixHeadlessColorPicker.prototype, "hueLabel", void 0);
581
- __decorate([
582
- property({ reflect: true, type: Boolean })
583
- ], HelixHeadlessColorPicker.prototype, "invalid", void 0);
584
625
  __decorate([
585
626
  property({ attribute: 'lightness-label' })
586
627
  ], HelixHeadlessColorPicker.prototype, "lightnessLabel", void 0);
@@ -623,6 +664,9 @@ __decorate([
623
664
  __decorate([
624
665
  property({ attribute: 'value-missing-message' })
625
666
  ], HelixHeadlessColorPicker.prototype, "valueMissingMessage", void 0);
667
+ __decorate([
668
+ property({ reflect: true, type: Boolean })
669
+ ], HelixHeadlessColorPicker.prototype, "wheel", void 0);
626
670
  __decorate([
627
671
  state()
628
672
  ], HelixHeadlessColorPicker.prototype, "moved", void 0);
@@ -0,0 +1,28 @@
1
+ /** A box on the screen, as `getBoundingClientRect` gives one. */
2
+ export interface WheelBox {
3
+ height: number;
4
+ left: number;
5
+ top: number;
6
+ width: number;
7
+ }
8
+ /**
9
+ * The hue at a point on a hue wheel: degrees clockwise from the top, 0 to
10
+ * 359, the way React Aria's ColorWheel and every paint program lay hue out.
11
+ *
12
+ * Measured from the box's center, so a press anywhere in the wheel answers,
13
+ * not only one on the ring: the ring is the target a reader aims at, and a
14
+ * press a little inside it still means the hue in that direction. Clockwise
15
+ * whatever the writing direction, since a circle has no line of text.
16
+ */
17
+ export declare const hueAt: (x: number, y: number, box: WheelBox) => number;
18
+ /**
19
+ * The saturation and brightness at a point in the color square, 0 to 100:
20
+ * brightness falls downward, and saturation runs along the line, the way the
21
+ * two ramps under the square do, being native ranges. On a right-to-left page
22
+ * (`rtl`) it grows toward the left. A point outside the square is held to its
23
+ * edge.
24
+ */
25
+ export declare const areaAt: (x: number, y: number, box: WheelBox, rtl: boolean) => {
26
+ brightness: number;
27
+ saturation: number;
28
+ };
@@ -0,0 +1,15 @@
1
+ import { clamp } from '@fusion.dev/helix-core';
2
+ export const hueAt = (x, y, box) => {
3
+ const across = x - (box.left + box.width / 2);
4
+ const down = y - (box.top + box.height / 2);
5
+ const degrees = Math.round((Math.atan2(across, -down) * 180) / Math.PI);
6
+ return (degrees + 360) % 360;
7
+ };
8
+ export const areaAt = (x, y, box, rtl) => {
9
+ const fromLeft = clamp((x - box.left) / box.width, 0, 1);
10
+ const down = clamp((y - box.top) / box.height, 0, 1);
11
+ return {
12
+ brightness: Math.round((1 - down) * 100),
13
+ saturation: Math.round((rtl ? 1 - fromLeft : fromLeft) * 100),
14
+ };
15
+ };