@fusion.dev/helix-headless 0.146.0 → 0.147.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 (239) hide show
  1. package/custom-elements.json +5266 -785
  2. package/dist/accordion/item/accordion-item.d.ts +38 -19
  3. package/dist/accordion/item/accordion-item.js +31 -9
  4. package/dist/accordion/root/accordion-root.d.ts +8 -2
  5. package/dist/accordion/root/accordion-root.js +3 -3
  6. package/dist/announcement/root/announcement-root.d.ts +13 -4
  7. package/dist/announcement/root/announcement-root.js +34 -6
  8. package/dist/area-chart/root/area-chart-root.d.ts +18 -1
  9. package/dist/area-chart/root/area-chart-root.js +11 -3
  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/root/badge-root.d.ts +57 -6
  13. package/dist/badge/root/badge-root.js +88 -5
  14. package/dist/bar-chart/root/bar-chart-root.js +11 -20
  15. package/dist/bar-chart/stack.d.ts +10 -0
  16. package/dist/bar-chart/stack.js +8 -0
  17. package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +14 -0
  18. package/dist/breadcrumbs/breadcrumb/breadcrumb.js +12 -2
  19. package/dist/breadcrumbs/root/breadcrumbs-root.js +2 -2
  20. package/dist/button/root/button-root.d.ts +24 -38
  21. package/dist/button/root/button-root.js +6 -37
  22. package/dist/button/submitter.d.ts +27 -0
  23. package/dist/button/submitter.js +25 -0
  24. package/dist/card/root/card-root.d.ts +12 -1
  25. package/dist/card/root/card-root.js +11 -4
  26. package/dist/chat/root/chat-root.d.ts +15 -1
  27. package/dist/chat/root/chat-root.js +11 -2
  28. package/dist/checkbox/root/checkbox-root.js +5 -7
  29. package/dist/checkbox-group/root/checkbox-group-root.js +4 -3
  30. package/dist/checkbox-group/select-all.d.ts +0 -6
  31. package/dist/checkbox-group/select-all.js +0 -5
  32. package/dist/code-block/root/code-block-root.d.ts +35 -14
  33. package/dist/code-block/root/code-block-root.js +17 -3
  34. package/dist/color-input/root/color-input-root.d.ts +11 -0
  35. package/dist/color-input/root/color-input-root.js +12 -5
  36. package/dist/color-picker/channels.js +1 -2
  37. package/dist/color-picker/root/color-picker-root.d.ts +32 -24
  38. package/dist/color-picker/root/color-picker-root.js +101 -51
  39. package/dist/color-picker/wheel.d.ts +17 -0
  40. package/dist/color-picker/wheel.js +6 -0
  41. package/dist/combobox/root/combobox-root.d.ts +13 -0
  42. package/dist/combobox/root/combobox-root.js +14 -1
  43. package/dist/command/root/command-root.d.ts +3 -1
  44. package/dist/command/root/command-root.js +2 -19
  45. package/dist/copy-button/root/copy-button-root.d.ts +16 -1
  46. package/dist/copy-button/root/copy-button-root.js +7 -2
  47. package/dist/data-table/keys.d.ts +0 -18
  48. package/dist/data-table/keys.js +1 -11
  49. package/dist/data-table/root/data-table-root.js +13 -7
  50. package/dist/date-input/root/date-input-root.d.ts +8 -1
  51. package/dist/date-input/root/date-input-root.js +8 -5
  52. package/dist/date-picker/root/date-picker-root.d.ts +14 -9
  53. package/dist/date-picker/root/date-picker-root.js +21 -16
  54. package/dist/description-list/item/description-list-item.d.ts +18 -4
  55. package/dist/description-list/item/description-list-item.js +8 -4
  56. package/dist/donut-chart/root/donut-chart-root.js +13 -6
  57. package/dist/donut-chart/slice-label.d.ts +35 -0
  58. package/dist/donut-chart/slice-label.js +11 -0
  59. package/dist/drawer/root/drawer-root.d.ts +4 -2
  60. package/dist/drawer/root/drawer-root.js +15 -3
  61. package/dist/drilldown/item/drilldown-item.d.ts +21 -1
  62. package/dist/drilldown/item/drilldown-item.js +39 -4
  63. package/dist/drilldown/root/drilldown-root.js +3 -2
  64. package/dist/element-events.generated.js +4 -1
  65. package/dist/empty/root/empty-root.d.ts +31 -1
  66. package/dist/empty/root/empty-root.js +26 -5
  67. package/dist/file-input/root/file-input-root.d.ts +34 -6
  68. package/dist/file-input/root/file-input-root.js +54 -19
  69. package/dist/file-input/status.d.ts +24 -0
  70. package/dist/file-input/status.js +10 -0
  71. package/dist/filter-input/chip/filter-chip.d.ts +23 -0
  72. package/dist/filter-input/chip/filter-chip.js +11 -2
  73. package/dist/filter-input/root/filter-input-root.d.ts +8 -0
  74. package/dist/filter-input/root/filter-input-root.js +17 -27
  75. package/dist/format-date/options.d.ts +3 -4
  76. package/dist/format-date/options.js +2 -2
  77. package/dist/format-date/root/format-date-root.d.ts +18 -1
  78. package/dist/format-date/root/format-date-root.js +19 -23
  79. package/dist/heatmap/root/buckets.d.ts +21 -0
  80. package/dist/heatmap/root/buckets.js +34 -0
  81. package/dist/heatmap/root/heatmap-root.d.ts +64 -3
  82. package/dist/heatmap/root/heatmap-root.js +89 -19
  83. package/dist/icon/index.d.ts +1 -1
  84. package/dist/icon/index.js +1 -1
  85. package/dist/icon/registry.d.ts +26 -1
  86. package/dist/icon/registry.js +12 -1
  87. package/dist/icon/root/icon-root.d.ts +13 -0
  88. package/dist/icon/root/icon-root.js +23 -2
  89. package/dist/icon/root/index.d.ts +1 -1
  90. package/dist/icon/root/index.js +1 -1
  91. package/dist/image/root/image-root.d.ts +9 -0
  92. package/dist/image/root/image-root.js +6 -1
  93. package/dist/input/root/input-root.d.ts +23 -2
  94. package/dist/input/root/input-root.js +12 -8
  95. package/dist/kbd/keys.d.ts +29 -0
  96. package/dist/kbd/keys.js +52 -0
  97. package/dist/kbd/root/kbd-root.d.ts +20 -3
  98. package/dist/kbd/root/kbd-root.js +24 -50
  99. package/dist/legend/hidden-series.d.ts +10 -2
  100. package/dist/legend/hidden-series.js +5 -2
  101. package/dist/legend/root/legend-root.d.ts +25 -7
  102. package/dist/legend/root/legend-root.js +22 -10
  103. package/dist/lightbox/root/lightbox-root.d.ts +50 -5
  104. package/dist/lightbox/root/lightbox-root.js +76 -8
  105. package/dist/lightbox/zoom.d.ts +2 -0
  106. package/dist/lightbox/zoom.js +5 -3
  107. package/dist/line-chart/root/line-chart-root.d.ts +16 -0
  108. package/dist/line-chart/root/line-chart-root.js +10 -2
  109. package/dist/list/root/list-root.d.ts +10 -2
  110. package/dist/list/root/list-root.js +26 -5
  111. package/dist/list/selection.d.ts +17 -0
  112. package/dist/list/selection.js +16 -0
  113. package/dist/listbox/root/listbox-root.d.ts +9 -5
  114. package/dist/listbox/root/listbox-root.js +29 -37
  115. package/dist/megamenu/hand-over.d.ts +75 -0
  116. package/dist/megamenu/hand-over.js +67 -0
  117. package/dist/megamenu/root/megamenu-root.d.ts +38 -14
  118. package/dist/megamenu/root/megamenu-root.js +36 -50
  119. package/dist/menu/item/menu-item.js +4 -4
  120. package/dist/menu/root/menu-root.d.ts +3 -0
  121. package/dist/meter/root/meter-root.d.ts +42 -0
  122. package/dist/meter/root/meter-root.js +33 -7
  123. package/dist/notifications/root/notifications-root.d.ts +10 -1
  124. package/dist/notifications/root/notifications-root.js +11 -1
  125. package/dist/number-input/grain.d.ts +28 -0
  126. package/dist/number-input/grain.js +14 -0
  127. package/dist/number-input/root/number-input-root.d.ts +17 -1
  128. package/dist/number-input/root/number-input-root.js +29 -18
  129. package/dist/object-inspector/root/object-inspector-root.d.ts +13 -6
  130. package/dist/object-inspector/root/object-inspector-root.js +18 -17
  131. package/dist/option/index.d.ts +1 -0
  132. package/dist/option/index.js +1 -0
  133. package/dist/option/separator/option-separator.d.ts +30 -0
  134. package/dist/option/separator/option-separator.js +21 -0
  135. package/dist/outline/root/outline-root.d.ts +12 -0
  136. package/dist/outline/root/outline-root.js +5 -19
  137. package/dist/pagination/size/pagination-size.d.ts +5 -0
  138. package/dist/pagination/size/pagination-size.js +4 -2
  139. package/dist/pin-input/code.d.ts +28 -1
  140. package/dist/pin-input/code.js +12 -0
  141. package/dist/pin-input/root/pin-input-root.d.ts +98 -121
  142. package/dist/pin-input/root/pin-input-root.js +157 -148
  143. package/dist/popover/hide-outside.js +2 -9
  144. package/dist/popover/root/popover-root.d.ts +7 -1
  145. package/dist/popover/root/popover-root.js +9 -1
  146. package/dist/progress/root/progress-root.d.ts +27 -0
  147. package/dist/progress/root/progress-root.js +25 -7
  148. package/dist/qr-code/export.d.ts +19 -0
  149. package/dist/qr-code/export.js +14 -0
  150. package/dist/qr-code/name.d.ts +11 -0
  151. package/dist/qr-code/name.js +7 -0
  152. package/dist/qr-code/root/qr-code-root.d.ts +17 -6
  153. package/dist/qr-code/root/qr-code-root.js +10 -12
  154. package/dist/radio/group/radio-group.d.ts +15 -0
  155. package/dist/radio/root/radio-root.js +2 -2
  156. package/dist/rating/root/rating-root.d.ts +22 -9
  157. package/dist/rating/root/rating-root.js +15 -39
  158. package/dist/scatter-chart/root/scatter-chart-root.d.ts +30 -0
  159. package/dist/scatter-chart/root/scatter-chart-root.js +34 -7
  160. package/dist/scroll-area/scrollbar.d.ts +0 -8
  161. package/dist/scroll-area/scrollbar.js +1 -1
  162. package/dist/select/align.d.ts +47 -0
  163. package/dist/select/align.js +7 -0
  164. package/dist/select/root/select-root.d.ts +59 -3
  165. package/dist/select/root/select-root.js +72 -12
  166. package/dist/slider/root/slider-root.d.ts +18 -1
  167. package/dist/slider/root/slider-root.js +22 -0
  168. package/dist/sparkline/readings.d.ts +30 -12
  169. package/dist/sparkline/readings.js +32 -15
  170. package/dist/sparkline/root/sparkline-root.d.ts +46 -3
  171. package/dist/sparkline/root/sparkline-root.js +60 -21
  172. package/dist/speed-dial/item/speed-dial-item.d.ts +1 -1
  173. package/dist/speed-dial/item/speed-dial-item.js +2 -2
  174. package/dist/speed-dial/root/speed-dial-root.d.ts +6 -0
  175. package/dist/speed-dial/root/speed-dial-root.js +9 -1
  176. package/dist/splitter/root/splitter-root.d.ts +3 -0
  177. package/dist/splitter/root/splitter-root.js +2 -0
  178. package/dist/steps/root/steps-root.d.ts +8 -1
  179. package/dist/steps/root/steps-root.js +6 -1
  180. package/dist/steps/step/step.d.ts +1 -0
  181. package/dist/steps/step/step.js +1 -1
  182. package/dist/table/column/table-column.d.ts +6 -0
  183. package/dist/table/column/table-column.js +5 -1
  184. package/dist/table/root/table-root.js +13 -6
  185. package/dist/table/row/table-row.d.ts +24 -0
  186. package/dist/table/row/table-row.js +37 -1
  187. package/dist/tabs/root/tabs-root.d.ts +5 -3
  188. package/dist/tag/group/tag-group.d.ts +16 -4
  189. package/dist/tag/group/tag-group.js +19 -7
  190. package/dist/textarea/root/textarea-root.d.ts +14 -2
  191. package/dist/textarea/root/textarea-root.js +6 -7
  192. package/dist/time-input/root/time-input-root.d.ts +5 -1
  193. package/dist/time-input/root/time-input-root.js +10 -7
  194. package/dist/time-picker/root/time-picker-root.d.ts +11 -14
  195. package/dist/time-picker/root/time-picker-root.js +15 -23
  196. package/dist/toast/item/toast-item.d.ts +3 -3
  197. package/dist/toast/item/toast-item.js +0 -1
  198. package/dist/toast/root/toast-root.d.ts +28 -4
  199. package/dist/toast/root/toast-root.js +58 -12
  200. package/dist/toast/words.d.ts +12 -0
  201. package/dist/toast/words.js +25 -0
  202. package/dist/toggle/group/toggle-group.d.ts +29 -5
  203. package/dist/toggle/group/toggle-group.js +26 -41
  204. package/dist/toggle/root/toggle-root.js +2 -4
  205. package/dist/toolbar/root/toolbar-root.d.ts +21 -5
  206. package/dist/toolbar/root/toolbar-root.js +52 -8
  207. package/dist/tooltip/root/tooltip-root.d.ts +7 -1
  208. package/dist/tooltip/root/tooltip-root.js +10 -1
  209. package/dist/tour/root/tour-root.d.ts +15 -0
  210. package/dist/tour/root/tour-root.js +20 -1
  211. package/dist/tour/stop/tour-stop.d.ts +3 -0
  212. package/dist/tour/stop/tour-stop.js +3 -3
  213. package/dist/tree/root/tree-root.js +2 -2
  214. package/dist/trend/figure.d.ts +16 -0
  215. package/dist/trend/figure.js +8 -0
  216. package/dist/trend/root/trend-root.d.ts +41 -2
  217. package/dist/trend/root/trend-root.js +29 -3
  218. package/dist/video/root/extra-controls.d.ts +12 -0
  219. package/dist/video/root/extra-controls.js +6 -2
  220. package/dist/video/root/video-root.d.ts +5 -1
  221. package/dist/video-playlist/root/video-playlist-root.d.ts +11 -1
  222. package/dist/video-playlist/root/video-playlist-root.js +3 -0
  223. package/dist/virtual-list/fill.d.ts +11 -0
  224. package/dist/virtual-list/fill.js +9 -0
  225. package/dist/virtual-list/keys.d.ts +16 -7
  226. package/dist/virtual-list/keys.js +17 -6
  227. package/dist/virtual-list/plan.d.ts +17 -1
  228. package/dist/virtual-list/plan.js +13 -2
  229. package/dist/virtual-list/root/virtual-list-root.d.ts +25 -3
  230. package/dist/virtual-list/root/virtual-list-root.js +48 -24
  231. package/lint.json +1 -1
  232. package/package.json +5 -5
  233. package/types/jsx.d.ts +2979 -738
  234. package/types/svelte.d.ts +1 -0
  235. package/types/vue.d.ts +619 -202
  236. package/dist/color-picker/swatches.d.ts +0 -12
  237. package/dist/color-picker/swatches.js +0 -26
  238. package/dist/rating/steps.d.ts +0 -7
  239. package/dist/rating/steps.js +0 -9
@@ -67,7 +67,11 @@ declare const HelixHeadlessChat_base: (new (...args: any[]) => import("@fusion.d
67
67
  * the forwarded `message-*` parts. A turn by `me` also gets each part with
68
68
  * `-mine` added, and the turn's state adds `message-meta-failed`,
69
69
  * `message-content-sending`, and `message-content-streaming`. To style each
70
- * participant differently, pass the turns as children.
70
+ * participant differently, give `author-styles` the declarations for each
71
+ * author, such as `{"ada": "--chat-message-background-color: …"}`: the message
72
+ * drawn for each of their turns takes them as its `style`, so the message's
73
+ * custom properties change for that author alone. Turns passed as children are
74
+ * styled by their `author`, such as `helix-chat-message[author="ada"]`.
71
75
  *
72
76
  * @since 0.1.0
73
77
  * @status stable
@@ -136,6 +140,16 @@ export declare class HelixHeadlessChat extends HelixHeadlessChat_base {
136
140
  static shadowRootOptions: ShadowRootInit;
137
141
  /** How tall a turn is assumed to be before it has been drawn, in pixels. */
138
142
  static readonly ESTIMATE = 72;
143
+ /**
144
+ * Declarations for the turns from `turns` by each author, keyed by `author`,
145
+ * as JSON in the attribute: `{"ada": "--chat-message-background-color: …"}`.
146
+ *
147
+ * The message drawn for each turn by that author takes them as its `style`,
148
+ * so the custom properties a message reads, its fill, text color, radius and
149
+ * padding, change for that author alone. A turn by an author with no entry
150
+ * takes none, and looks as it did. JSON that does not parse is no entries.
151
+ */
152
+ authorStyles: Record<string, string>;
139
153
  /**
140
154
  * Whether the transcript opens pinned to the bottom, when `pinned` is not
141
155
  * set.
@@ -5,7 +5,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  var HelixHeadlessChat_1;
8
- import { customElement, fillTemplate, HelixBeforePinEvent, HelixElement, HelixHistoryEvent, HelixPinEvent, hostAria, MixinCollection, onUnlessFalse, requestChange, VirtualizeController, whenHydrated, } from '@fusion.dev/helix-core';
8
+ import { customElement, fillTemplate, HelixBeforePinEvent, HelixElement, HelixHistoryEvent, HelixPinEvent, hostAria, MixinCollection, onUnlessFalse, requestChange, VirtualizeController, whenHydrated, wordsConverter, } from '@fusion.dev/helix-core';
9
9
  import { nothing } from 'lit';
10
10
  import { property, state } from 'lit/decorators.js';
11
11
  import { keyed } from 'lit/directives/keyed.js';
@@ -24,7 +24,11 @@ const SECOND_NAMES = {
24
24
  streaming: 'content: message-content-streaming',
25
25
  },
26
26
  };
27
- const secondNames = (table, key) => key !== undefined && Object.hasOwn(table, key) ? `, ${table[key]}` : '';
27
+ const ownEntry = (table, key) => (key !== undefined && Object.hasOwn(table, key) ? table[key] : undefined);
28
+ const secondNames = (table, key) => {
29
+ const names = ownEntry(table, key);
30
+ return names === undefined ? '' : `, ${names}`;
31
+ };
28
32
  const settled = (turn) => turn.state !== 'sending' && turn.state !== 'streaming';
29
33
  const newsworthy = (turn) => turn.author !== 'me' || turn.state === 'failed';
30
34
  const spoken = (message) => [...message.childNodes]
@@ -36,6 +40,7 @@ const spoken = (message) => [...message.childNodes]
36
40
  let HelixHeadlessChat = class HelixHeadlessChat extends MixinCollection(HelixElement) {
37
41
  constructor() {
38
42
  super(...arguments);
43
+ this.authorStyles = {};
39
44
  this.defaultPinned = true;
40
45
  this.history = '';
41
46
  this.historyText = 'Loading earlier messages';
@@ -434,6 +439,7 @@ let HelixHeadlessChat = class HelixHeadlessChat extends MixinCollection(HelixEle
434
439
  author=${turn.author ?? nothing}
435
440
  author-label=${turn.authorLabel ?? nothing}
436
441
  at=${turn.at ?? nothing}
442
+ style=${ownEntry(this.authorStyles, turn.author) ?? nothing}
437
443
  .turnWords=${this.words}
438
444
  state=${turn.state ?? nothing}
439
445
  >${turn.text}</${message}>
@@ -482,6 +488,9 @@ let HelixHeadlessChat = class HelixHeadlessChat extends MixinCollection(HelixEle
482
488
  </div>`;
483
489
  }
484
490
  };
491
+ __decorate([
492
+ property({ attribute: 'author-styles', converter: wordsConverter })
493
+ ], HelixHeadlessChat.prototype, "authorStyles", void 0);
485
494
  __decorate([
486
495
  property({ attribute: 'default-pinned', converter: onUnlessFalse })
487
496
  ], HelixHeadlessChat.prototype, "defaultPinned", void 0);
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { AriaForwardController, customElement, HelixFormElement, HostClickController, MixinControllerChecked, MixinField, } from '@fusion.dev/helix-core';
7
+ import { AriaForwardController, customElement, HelixFormElement, HostClickController, MixinControllerChecked, MixinField, slotFilled, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  let HelixHeadlessCheckbox = class HelixHeadlessCheckbox extends MixinControllerChecked(MixinField(HelixFormElement)) {
@@ -34,7 +34,7 @@ let HelixHeadlessCheckbox = class HelixHeadlessCheckbox extends MixinControllerC
34
34
  };
35
35
  this.handleMarkChange = (event) => {
36
36
  const slot = event.target;
37
- const filled = slot.assignedNodes().length > 0;
37
+ const filled = slotFilled(slot);
38
38
  if (slot.name === 'dash') {
39
39
  this.toggleState('has-dash', filled);
40
40
  }
@@ -74,11 +74,9 @@ let HelixHeadlessCheckbox = class HelixHeadlessCheckbox extends MixinControllerC
74
74
  }
75
75
  syncLabelPresence() {
76
76
  const slot = this.renderRoot.querySelector('[part="label"] slot');
77
- const meaningful = (node) => node.textContent?.trim() !== '' || node.nodeType === Node.ELEMENT_NODE;
78
- const filled = (slot?.assignedNodes({ flatten: true }) ?? []).some(meaningful);
79
- const hidden = this.label === '' &&
80
- Boolean(this.getAttribute('aria-label')) &&
81
- !(slot?.assignedNodes() ?? []).some(meaningful);
77
+ const filled = slotFilled(slot);
78
+ const written = (slot?.assignedNodes() ?? []).some((node) => node.nodeType === Node.ELEMENT_NODE || node.textContent?.trim() !== '');
79
+ const hidden = this.label === '' && Boolean(this.getAttribute('aria-label')) && !written;
82
80
  this.partNamed('label')?.toggleAttribute('data-hidden', hidden);
83
81
  this.toggleState('has-label', filled && !hidden);
84
82
  this.partNamed('label')?.toggleAttribute('hidden', !filled);
@@ -5,13 +5,13 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  var HelixHeadlessCheckboxGroup_1;
8
- import { commaList, customElement, DisabledCascadeController, HelixBeforeChangeEvent, HelixFormElement, hostAria, MixinField, } from '@fusion.dev/helix-core';
8
+ import { commaList, customElement, DisabledCascadeController, HelixBeforeChangeEvent, HelixFormElement, hostAria, MixinField, toggleEvery, } from '@fusion.dev/helix-core';
9
9
  import { nothing } from 'lit';
10
10
  import { property } from 'lit/decorators.js';
11
11
  import { html } from 'lit/static-html.js';
12
12
  import { HelixHeadlessCheckbox } from '../../checkbox/root/checkbox-root.js';
13
13
  import '../../checkbox/index.js';
14
- import { selectAllPress, selectAllState } from '../select-all.js';
14
+ import { selectAllState } from '../select-all.js';
15
15
  let HelixHeadlessCheckboxGroup = HelixHeadlessCheckboxGroup_1 = class HelixHeadlessCheckboxGroup extends MixinField(HelixFormElement) {
16
16
  constructor() {
17
17
  super(...arguments);
@@ -60,7 +60,8 @@ let HelixHeadlessCheckboxGroup = HelixHeadlessCheckboxGroup_1 = class HelixHeadl
60
60
  this.handleSelectAll = (event) => {
61
61
  event.preventDefault();
62
62
  event.stopPropagation();
63
- const next = selectAllPress(this.setBoxes());
63
+ const boxes = this.setBoxes();
64
+ const next = toggleEvery(boxes.filter((box) => box.checked).map((box) => box.value), boxes.filter((box) => !box.disabled).map((box) => box.value), boxes.map((box) => box.value));
64
65
  if (!this.dispatchEvent(new HelixBeforeChangeEvent({ value: next.join(',') }))) {
65
66
  return;
66
67
  }
@@ -19,9 +19,3 @@ export declare const selectAllState: (boxes: readonly SetBox[]) => {
19
19
  checked: boolean;
20
20
  indeterminate: boolean;
21
21
  };
22
- /**
23
- * The values a press on the select-all box leaves, in the set's order: every
24
- * enabled box checked, or every enabled box clear once all of them are
25
- * checked. A disabled box keeps its state either way.
26
- */
27
- export declare const selectAllPress: (boxes: readonly SetBox[]) => string[];
@@ -5,8 +5,3 @@ export const selectAllState = (boxes) => {
5
5
  const checked = counted.length > 0 && ticked === counted.length;
6
6
  return { checked, indeterminate: ticked > 0 && !checked };
7
7
  };
8
- export const selectAllPress = (boxes) => {
9
- const enabled = boxes.filter((box) => !box.disabled);
10
- const every = enabled.length > 0 && enabled.every((box) => box.checked);
11
- return boxes.filter((box) => (box.disabled ? box.checked : !every)).map((box) => box.value);
12
- };
@@ -17,14 +17,17 @@ import '../../copy-button/index.js';
17
17
  * Set `line-numbers` to number the lines in a gutter beside the code, hidden
18
18
  * from the accessibility tree and left out of a copy. Set `highlight` to a
19
19
  * function that turns the code into highlighted markup, such as one wrapping
20
- * Shiki or Prism, and the block draws what it returns; the code stays in the
21
- * slot, so the copy button and the page's own text are the code as written.
20
+ * Shiki or Prism, and the block draws what it returns; it is handed the
21
+ * block's `language`, so one function serves every block. The code stays in
22
+ * the slot, so the copy button and the page's own text are the code as
23
+ * written.
22
24
  *
23
25
  * Set `expandable` on a block whose height is capped, such as by
24
26
  * `--code-block-max-block-size`, and a button under it shows every line and
25
27
  * then fewer again, as a docs site's long example does. The button is drawn
26
- * only while the cap hides something, says whether the block is expanded, and
27
- * the block carries `:state(expanded)` while it is.
28
+ * only while the cap hides something, says whether the block is expanded with
29
+ * `aria-expanded`, names the block it opens with `aria-controls`, and the block
30
+ * carries `:state(expanded)` while it is.
28
31
  *
29
32
  * Set `diff` to show a change. Put a unified diff, the output of `git diff` or
30
33
  * `diff -u`, in the same slot, and the block draws the lines it added and
@@ -56,6 +59,7 @@ import '../../copy-button/index.js';
56
59
  * @csspart copy-button - The inner button.
57
60
  * @csspart copy-live - The copy button's live region, which speaks while the button is pending.
58
61
  * @csspart copy-mark - The clipboard icon, and the check mark that replaces it after a copy.
62
+ * @csspart copy-spinner - The ring the copy button turns while it is pending.
59
63
  * @csspart copy-text - The words on that button, trimmed to their capitals and baseline.
60
64
  * @csspart copy-tooltip - The copy button's tooltip.
61
65
  * @csspart copy-tooltip-arrow - The tooltip's arrow, which points at the copy button.
@@ -126,17 +130,26 @@ export declare class HelixHeadlessCodeBlock extends HelixElement {
126
130
  * Turns the code into highlighted markup, which the block draws in place of
127
131
  * the plain text.
128
132
  *
129
- * Called with the code as written and returning HTML, such as the output of
130
- * Shiki's `codeToHtml` or Prism's `highlight`. **The markup is drawn as
131
- * given**, so it has to escape the code it was handed, which those
132
- * highlighters do. A `<pre>` and `<code>` around the whole of it, which
133
- * Shiki writes, are taken off, so the lines sit level with the gutter's
134
- * numbers and the block keeps one tab stop. Bind the language in the function you pass. The code
135
- * stays in the slot, so the copy button copies it as written and a reader
136
- * without the script still has it. Not called on a server, which has no code
137
- * to read, nor for a diff.
133
+ * Called with the code as written and the block's `language`, and returning
134
+ * HTML, such as the output of Shiki's `codeToHtml` or Prism's `highlight`.
135
+ * One function serves every block on a page, each block saying its own
136
+ * language:
137
+ *
138
+ * ```js
139
+ * for (const block of document.querySelectorAll('helix-code-block')) {
140
+ * block.highlight = (code, lang) => codeToHtml(code, { lang, theme: 'github-light' })
141
+ * }
142
+ * ```
143
+ *
144
+ * **The markup is drawn as given**, so it has to escape the code it was
145
+ * handed, which those highlighters do. A `<pre>` and `<code>` around the
146
+ * whole of it, which Shiki writes, are taken off, so the lines sit level
147
+ * with the gutter's numbers and the block keeps one tab stop. The code stays
148
+ * in the slot, so the copy button copies it as written and a reader without
149
+ * the script still has it. Not called on a server, which has no code to
150
+ * read, nor for a diff.
138
151
  */
139
- highlight?: (code: string) => string;
152
+ highlight?: (code: string, language: string) => string;
140
153
  /**
141
154
  * The block's name, usually a file name or a language.
142
155
  *
@@ -144,6 +157,14 @@ export declare class HelixHeadlessCodeBlock extends HelixElement {
144
157
  * carries no name of its own.
145
158
  */
146
159
  label: string;
160
+ /**
161
+ * The language the code is written in, such as `ts` or `css`, handed to
162
+ * `highlight` as its second argument.
163
+ *
164
+ * Absent hands it an empty string. It draws nothing of its own: the block's
165
+ * name is `label`.
166
+ */
167
+ language: string;
147
168
  /**
148
169
  * Whether the lines are numbered in a gutter beside the code.
149
170
  *
@@ -23,6 +23,7 @@ let HelixHeadlessCodeBlock = class HelixHeadlessCodeBlock extends HelixElement {
23
23
  this.expandable = false;
24
24
  this.expandLabel = 'Show all lines';
25
25
  this.label = '';
26
+ this.language = '';
26
27
  this.lineNumbers = false;
27
28
  this.noCopy = false;
28
29
  this.parsed = { files: [], text: '' };
@@ -88,7 +89,16 @@ let HelixHeadlessCodeBlock = class HelixHeadlessCodeBlock extends HelixElement {
88
89
  return this.renderDiff(files);
89
90
  }
90
91
  const text = this.text;
91
- const highlighted = this.highlight && text !== '' ? highlightedLines(this.highlight(text)) : undefined;
92
+ let highlighted;
93
+ try {
94
+ highlighted =
95
+ this.highlight && text !== ''
96
+ ? highlightedLines(this.highlight(text, this.language))
97
+ : undefined;
98
+ }
99
+ catch (error) {
100
+ globalThis.reportError?.(error);
101
+ }
92
102
  const code = highlighted === undefined
93
103
  ? html `<code part="code"><slot @slotchange=${() => this.requestUpdate()}></slot></code>`
94
104
  : html `<code part="code">${unsafeHTML(highlighted)}</code><slot
@@ -101,7 +111,7 @@ let HelixHeadlessCodeBlock = class HelixHeadlessCodeBlock extends HelixElement {
101
111
  : nothing;
102
112
  return html `${this.renderHeader(this.label)}
103
113
  <div part="frame">
104
- <pre part="block">${gutter}${code}</pre>
114
+ <pre id="block" part="block">${gutter}${code}</pre>
105
115
  ${this.label ? nothing : this.renderCopy()}
106
116
  </div>${this.renderExpand()}`;
107
117
  }
@@ -110,6 +120,7 @@ let HelixHeadlessCodeBlock = class HelixHeadlessCodeBlock extends HelixElement {
110
120
  return nothing;
111
121
  }
112
122
  return html `<button
123
+ aria-controls="block"
113
124
  aria-expanded=${this.expanded ? 'true' : 'false'}
114
125
  part="expand"
115
126
  type="button"
@@ -132,7 +143,7 @@ let HelixHeadlessCodeBlock = class HelixHeadlessCodeBlock extends HelixElement {
132
143
  renderCopyButton(value = this.text, name = this.label) {
133
144
  return html `<${this.tag('copy-button')}
134
145
  part="copy"
135
- exportparts="button: copy-button, text: copy-text, mark: copy-mark, live: copy-live, tooltip: copy-tooltip,
146
+ exportparts="button: copy-button, text: copy-text, mark: copy-mark, live: copy-live, spinner: copy-spinner, tooltip: copy-tooltip,
136
147
  tooltip-arrow: copy-tooltip-arrow, tooltip-arrow-bottom: copy-tooltip-arrow-bottom,
137
148
  tooltip-arrow-left: copy-tooltip-arrow-left, tooltip-arrow-right: copy-tooltip-arrow-right,
138
149
  tooltip-arrow-top: copy-tooltip-arrow-top, tooltip-bottom: copy-tooltip-bottom,
@@ -214,6 +225,9 @@ __decorate([
214
225
  __decorate([
215
226
  property()
216
227
  ], HelixHeadlessCodeBlock.prototype, "label", void 0);
228
+ __decorate([
229
+ property()
230
+ ], HelixHeadlessCodeBlock.prototype, "language", void 0);
217
231
  __decorate([
218
232
  property({ attribute: 'line-numbers', reflect: true, type: Boolean })
219
233
  ], HelixHeadlessCodeBlock.prototype, "lineNumbers", void 0);
@@ -74,11 +74,14 @@ declare const HelixHeadlessColorInput_base: (new (...args: any[]) => import("@fu
74
74
  * @csspart picker-channel-marker-label - The value a mark stands at, when `marker-labels` is set.
75
75
  * @csspart picker-channel-markers - The row of marks along the track.
76
76
  * @csspart picker-channel-output - The current value, shown beside the track.
77
+ * @csspart picker-channel-tooltip - A ramp's value in a bubble, where a ramp shows one.
78
+ * @csspart picker-channel-tooltips - The layer over a ramp's track that holds its bubble.
77
79
  * @csspart picker-channels - The channel sliders beside the sample.
78
80
  * @csspart picker-controls - The row under the square.
79
81
  * @csspart picker-eyedropper - The control that samples a color from the screen.
80
82
  * @csspart picker-eyedropper-button - The button inside `picker-eyedropper`.
81
83
  * @csspart picker-eyedropper-live - The live region of the button inside `picker-eyedropper`, which says its pending label.
84
+ * @csspart picker-eyedropper-spinner - The ring the eyedropper button turns while it is pending.
82
85
  * @csspart picker-eyedropper-text - The words on the button inside `picker-eyedropper`.
83
86
  * @csspart picker-feedback - The field's message inside the open panel, under the picker, where the panel covers the one under the field.
84
87
  * @csspart picker-field - One channel's number field with its label, in `channel-fields`.
@@ -89,6 +92,7 @@ declare const HelixHeadlessColorInput_base: (new (...args: any[]) => import("@fu
89
92
  * @csspart picker-format - The control that changes the syntax the value is written in.
90
93
  * @csspart picker-format-button - The button inside `picker-format`.
91
94
  * @csspart picker-format-live - The live region of the button inside `picker-format`, which says its pending label.
95
+ * @csspart picker-format-spinner - The ring the syntax button turns while it is pending.
92
96
  * @csspart picker-format-text - The words on the button inside `picker-format`.
93
97
  * @csspart picker-grid - The saturation and brightness square.
94
98
  * @csspart picker-grid-brightness - The range input for the square's vertical axis.
@@ -99,6 +103,8 @@ declare const HelixHeadlessColorInput_base: (new (...args: any[]) => import("@fu
99
103
  * @csspart picker-swatch - One preset.
100
104
  * @csspart picker-swatches - The row of presets.
101
105
  * @csspart picker-value - The text field that holds the color. It accepts a typed or pasted color.
106
+ * @csspart picker-wheel - The hue ring round the square, with `wheel`.
107
+ * @csspart picker-wheel-hue - The range input behind the hue ring.
102
108
  * @csspart preview - The chip showing the color, inside the trigger.
103
109
  * @csspart surface - The floating panel.
104
110
  * @csspart trigger - The control that opens the panel.
@@ -196,6 +202,11 @@ export declare class HelixHeadlessColorInput extends HelixHeadlessColorInput_bas
196
202
  * where the color is the answer rather than a setting.
197
203
  */
198
204
  variant?: 'swatch';
205
+ /**
206
+ * Draws the panel's hue as a wheel around the square, in place of the hue
207
+ * ramp. See Color Picker's `wheel`.
208
+ */
209
+ wheel: boolean;
199
210
  /**
200
211
  * The last value that was a color.
201
212
  *
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { AriaForwardController, colorName, customElement, HelixFormElement, MixinControllerOpen, MixinControllerValue, MixinField, MixinPickerField, parseColor, toCss, wordsConverter, } from '@fusion.dev/helix-core';
7
+ import { AriaForwardController, colorName, customElement, HelixFormElement, localeOf, MixinControllerOpen, MixinControllerValue, MixinField, MixinPickerField, parseColor, toCss, wordsConverter, } from '@fusion.dev/helix-core';
8
8
  import { nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  import { html } from 'lit/static-html.js';
@@ -25,6 +25,7 @@ let HelixHeadlessColorInput = class HelixHeadlessColorInput extends MixinPickerF
25
25
  this.announcesInput = true;
26
26
  this.swatches = '';
27
27
  this.triggerLabel = 'Choose a color';
28
+ this.wheel = false;
28
29
  this.settled = '';
29
30
  this.handleInput = (event) => {
30
31
  event.stopPropagation();
@@ -77,7 +78,7 @@ let HelixHeadlessColorInput = class HelixHeadlessColorInput extends MixinPickerF
77
78
  if (!parsed) {
78
79
  return this.value || this.triggerLabel;
79
80
  }
80
- return `${colorName(parsed, this.colorWords, this.lang)} ${this.value}`;
81
+ return `${colorName(parsed, this.colorWords, localeOf(this))} ${this.value}`;
81
82
  }
82
83
  get painted() {
83
84
  const parsed = parseColor(this.value);
@@ -115,17 +116,20 @@ let HelixHeadlessColorInput = class HelixHeadlessColorInput extends MixinPickerF
115
116
  channel-hint: picker-channel-hint, channel-label: picker-channel-label,
116
117
  channel-marker: picker-channel-marker, channel-marker-label: picker-channel-marker-label,
117
118
  channel-markers: picker-channel-markers, channel-output: picker-channel-output,
119
+ channel-tooltip: picker-channel-tooltip, channel-tooltips: picker-channel-tooltips,
118
120
  channels: picker-channels, controls: picker-controls, eyedropper: picker-eyedropper,
119
- eyedropper-button: picker-eyedropper-button, eyedropper-live: picker-eyedropper-live, eyedropper-text: picker-eyedropper-text,
121
+ eyedropper-button: picker-eyedropper-button, eyedropper-live: picker-eyedropper-live, eyedropper-spinner: picker-eyedropper-spinner, eyedropper-text: picker-eyedropper-text,
120
122
  feedback: picker-feedback, field: picker-field, field-input: picker-field-input, field-label: picker-field-label,
121
123
  fields: picker-fields, footer: picker-footer, format: picker-format,
122
- format-button: picker-format-button, format-live: picker-format-live, format-text: picker-format-text, grid: picker-grid,
124
+ format-button: picker-format-button, format-live: picker-format-live, format-spinner: picker-format-spinner, format-text: picker-format-text, grid: picker-grid,
123
125
  grid-brightness: picker-grid-brightness, grid-handle: picker-grid-handle,
124
126
  grid-saturation: picker-grid-saturation, icon: picker-icon, sample: picker-sample,
125
- swatch: picker-swatch, swatches: picker-swatches, value: picker-value"
127
+ swatch: picker-swatch, swatches: picker-swatches, value: picker-value,
128
+ wheel: picker-wheel, wheel-hue: picker-wheel-hue"
126
129
  ?invalid=${this.resolvedFeedback !== ''}
127
130
  .feedback=${this.resolvedFeedback}
128
131
  ?alpha=${this.alpha}
132
+ ?wheel=${this.wheel}
129
133
  ?channel-fields=${this.channelFields}
130
134
  ?no-format=${this.noFormat}
131
135
  ?no-value=${this.variant !== 'swatch'}
@@ -250,6 +254,9 @@ __decorate([
250
254
  __decorate([
251
255
  property({ reflect: true })
252
256
  ], HelixHeadlessColorInput.prototype, "variant", void 0);
257
+ __decorate([
258
+ property({ reflect: true, type: Boolean })
259
+ ], HelixHeadlessColorInput.prototype, "wheel", void 0);
253
260
  HelixHeadlessColorInput = __decorate([
254
261
  customElement('helix-headless-color-input')
255
262
  ], HelixHeadlessColorInput);
@@ -1,5 +1,4 @@
1
- import { toHsl, toRgb } from '@fusion.dev/helix-core';
2
- const clamp = (value, low, high) => Math.min(high, Math.max(low, value));
1
+ import { clamp, toHsl, toRgb } from '@fusion.dev/helix-core';
3
2
  const percent = (token) => {
4
3
  if (token === undefined) {
5
4
  return 100;
@@ -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
  *