@fusion.dev/helix-headless 0.142.1 → 0.144.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 (285) hide show
  1. package/custom-elements.json +25381 -1202
  2. package/dist/accordion/item/accordion-item.d.ts +38 -2
  3. package/dist/accordion/item/accordion-item.js +38 -6
  4. package/dist/accordion/root/accordion-root.d.ts +23 -1
  5. package/dist/accordion/root/accordion-root.js +39 -3
  6. package/dist/announcement/root/announcement-root.d.ts +11 -7
  7. package/dist/announcement/root/announcement-root.js +1 -1
  8. package/dist/app-header/root/app-header-root.d.ts +21 -0
  9. package/dist/app-header/root/app-header-root.js +31 -5
  10. package/dist/area-chart/root/area-chart-root.d.ts +12 -4
  11. package/dist/area-chart/root/area-chart-root.js +39 -11
  12. package/dist/avatar/group/avatar-group.d.ts +24 -3
  13. package/dist/avatar/group/avatar-group.js +34 -2
  14. package/dist/avatar/root/avatar-root.d.ts +17 -1
  15. package/dist/avatar/root/avatar-root.js +31 -10
  16. package/dist/badge/root/badge-root.d.ts +12 -0
  17. package/dist/badge/root/badge-root.js +1 -1
  18. package/dist/bar-chart/root/bar-chart-root.d.ts +30 -5
  19. package/dist/bar-chart/root/bar-chart-root.js +58 -21
  20. package/dist/blockquote/root/blockquote-root.d.ts +12 -7
  21. package/dist/blockquote/root/blockquote-root.js +6 -4
  22. package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +9 -3
  23. package/dist/breadcrumbs/root/breadcrumbs-root.js +9 -1
  24. package/dist/button/root/button-root.d.ts +84 -1
  25. package/dist/button/root/button-root.js +81 -3
  26. package/dist/callout/root/callout-root.d.ts +32 -6
  27. package/dist/callout/root/callout-root.js +26 -7
  28. package/dist/canvas/root/canvas-root.d.ts +1 -0
  29. package/dist/canvas/root/canvas-root.js +10 -1
  30. package/dist/card/root/card-root.d.ts +30 -1
  31. package/dist/card/root/card-root.js +38 -5
  32. package/dist/carousel/root/carousel-root.d.ts +47 -5
  33. package/dist/carousel/root/carousel-root.js +53 -21
  34. package/dist/chat/composer/chat-composer.d.ts +13 -11
  35. package/dist/chat/composer/chat-composer.js +6 -12
  36. package/dist/chat/message/chat-message.js +8 -1
  37. package/dist/chat/root/chat-root.d.ts +1 -0
  38. package/dist/chat/root/chat-root.js +2 -1
  39. package/dist/checkbox/root/checkbox-root.d.ts +7 -0
  40. package/dist/checkbox/root/checkbox-root.js +9 -3
  41. package/dist/checkbox-group/root/checkbox-group-root.d.ts +116 -33
  42. package/dist/checkbox-group/root/checkbox-group-root.js +141 -44
  43. package/dist/code/root/code-root.d.ts +1 -1
  44. package/dist/code-block/lines.d.ts +13 -0
  45. package/dist/code-block/lines.js +2 -0
  46. package/dist/code-block/root/code-block-root.d.ts +49 -0
  47. package/dist/code-block/root/code-block-root.js +44 -3
  48. package/dist/color-input/root/color-input-root.d.ts +60 -2
  49. package/dist/color-input/root/color-input-root.js +55 -7
  50. package/dist/color-picker/channels.d.ts +26 -0
  51. package/dist/color-picker/channels.js +84 -0
  52. package/dist/color-picker/root/color-picker-root.d.ts +118 -12
  53. package/dist/color-picker/root/color-picker-root.js +183 -13
  54. package/dist/combobox/root/combobox-root.d.ts +126 -3
  55. package/dist/combobox/root/combobox-root.js +224 -21
  56. package/dist/command/root/command-root.d.ts +47 -10
  57. package/dist/command/root/command-root.js +45 -4
  58. package/dist/copy-button/from.d.ts +22 -0
  59. package/dist/copy-button/from.js +28 -0
  60. package/dist/copy-button/root/copy-button-root.d.ts +48 -7
  61. package/dist/copy-button/root/copy-button-root.js +54 -8
  62. package/dist/data-table/root/data-table-root.d.ts +164 -10
  63. package/dist/data-table/root/data-table-root.js +488 -57
  64. package/dist/date-input/root/date-input-root.d.ts +123 -9
  65. package/dist/date-input/root/date-input-root.js +147 -45
  66. package/dist/date-picker/root/date-picker-root.d.ts +229 -18
  67. package/dist/date-picker/root/date-picker-root.js +342 -46
  68. package/dist/dialog/description.d.ts +9 -0
  69. package/dist/dialog/description.js +14 -0
  70. package/dist/dialog/root/dialog-root.d.ts +101 -10
  71. package/dist/dialog/root/dialog-root.js +83 -4
  72. package/dist/donut-chart/root/donut-chart-root.d.ts +61 -16
  73. package/dist/donut-chart/root/donut-chart-root.js +48 -13
  74. package/dist/drawer/root/drawer-root.d.ts +93 -7
  75. package/dist/drawer/root/drawer-root.js +126 -5
  76. package/dist/drawer/swipe-start.d.ts +9 -0
  77. package/dist/drawer/swipe-start.js +12 -0
  78. package/dist/drilldown/item/drilldown-item.d.ts +16 -13
  79. package/dist/drilldown/item/drilldown-item.js +6 -2
  80. package/dist/drilldown/root/drilldown-root.d.ts +21 -5
  81. package/dist/drilldown/root/drilldown-root.js +26 -10
  82. package/dist/element-events.generated.js +42 -13
  83. package/dist/empty/root/empty-root.d.ts +1 -1
  84. package/dist/file-input/root/file-input-root.d.ts +65 -1
  85. package/dist/file-input/root/file-input-root.js +76 -12
  86. package/dist/file-input/screen.d.ts +35 -0
  87. package/dist/file-input/screen.js +49 -0
  88. package/dist/filter-input/menu/filter-menu.d.ts +9 -0
  89. package/dist/filter-input/menu/filter-menu.js +8 -0
  90. package/dist/filter-input/root/filter-input-root.d.ts +43 -6
  91. package/dist/filter-input/root/filter-input-root.js +89 -10
  92. package/dist/filter-input/suggest.d.ts +17 -0
  93. package/dist/filter-input/suggest.js +23 -0
  94. package/dist/format-date/options.d.ts +33 -0
  95. package/dist/format-date/options.js +42 -0
  96. package/dist/format-date/root/format-date-root.d.ts +62 -3
  97. package/dist/format-date/root/format-date-root.js +78 -37
  98. package/dist/graph/root/graph-root.d.ts +24 -3
  99. package/dist/graph/root/graph-root.js +66 -12
  100. package/dist/heatmap/root/buckets.d.ts +2 -1
  101. package/dist/heatmap/root/buckets.js +5 -1
  102. package/dist/heatmap/root/heatmap-root.d.ts +47 -9
  103. package/dist/heatmap/root/heatmap-root.js +46 -18
  104. package/dist/icon/index.d.ts +2 -0
  105. package/dist/icon/index.js +2 -0
  106. package/dist/icon/registry.d.ts +37 -0
  107. package/dist/icon/registry.js +83 -0
  108. package/dist/icon/root/icon-root.d.ts +53 -6
  109. package/dist/icon/root/icon-root.js +72 -4
  110. package/dist/icon/root/index.d.ts +2 -0
  111. package/dist/icon/root/index.js +2 -0
  112. package/dist/icon/set.d.ts +1 -0
  113. package/dist/icon/set.js +3 -0
  114. package/dist/icon-button/root/icon-button-root.d.ts +1 -1
  115. package/dist/image/root/image-root.d.ts +23 -2
  116. package/dist/image/root/image-root.js +23 -4
  117. package/dist/input/root/input-root.d.ts +62 -9
  118. package/dist/input/root/input-root.js +61 -5
  119. package/dist/kbd/root/kbd-root.d.ts +26 -11
  120. package/dist/kbd/root/kbd-root.js +35 -38
  121. package/dist/kbd/shortcut.d.ts +18 -0
  122. package/dist/kbd/shortcut.js +35 -0
  123. package/dist/legend/hidden-series.d.ts +8 -0
  124. package/dist/legend/hidden-series.js +13 -0
  125. package/dist/legend/root/legend-root.d.ts +63 -0
  126. package/dist/legend/root/legend-root.js +61 -7
  127. package/dist/lightbox/item/lightbox-item.d.ts +17 -1
  128. package/dist/lightbox/item/lightbox-item.js +10 -1
  129. package/dist/lightbox/root/lightbox-root.d.ts +77 -6
  130. package/dist/lightbox/root/lightbox-root.js +116 -5
  131. package/dist/line-chart/root/line-chart-root.d.ts +29 -4
  132. package/dist/line-chart/root/line-chart-root.js +58 -17
  133. package/dist/list/item/list-item.d.ts +11 -5
  134. package/dist/list/item/list-item.js +5 -6
  135. package/dist/listbox/range.d.ts +17 -0
  136. package/dist/listbox/range.js +5 -0
  137. package/dist/listbox/root/listbox-root.d.ts +184 -4
  138. package/dist/listbox/root/listbox-root.js +229 -23
  139. package/dist/loader/busy.d.ts +17 -0
  140. package/dist/loader/busy.js +24 -0
  141. package/dist/loader/root/loader-root.d.ts +37 -0
  142. package/dist/loader/root/loader-root.js +52 -3
  143. package/dist/map/root/map-root.d.ts +19 -4
  144. package/dist/map/root/map-root.js +36 -7
  145. package/dist/megamenu/root/megamenu-root.d.ts +10 -1
  146. package/dist/megamenu/root/megamenu-root.js +10 -1
  147. package/dist/menu/item/menu-item.d.ts +41 -12
  148. package/dist/menu/item/menu-item.js +46 -3
  149. package/dist/menu/root/menu-root.d.ts +32 -2
  150. package/dist/menu/root/menu-root.js +48 -8
  151. package/dist/meter/root/meter-root.d.ts +13 -0
  152. package/dist/meter/root/meter-root.js +24 -5
  153. package/dist/navigation/root/navigation-root.d.ts +10 -2
  154. package/dist/navigation/root/navigation-root.js +13 -2
  155. package/dist/notifications/feed-keys.d.ts +10 -0
  156. package/dist/notifications/feed-keys.js +14 -0
  157. package/dist/notifications/group/notification-group.d.ts +1 -0
  158. package/dist/notifications/notification/notification.d.ts +29 -0
  159. package/dist/notifications/notification/notification.js +51 -3
  160. package/dist/notifications/root/notifications-root.d.ts +49 -0
  161. package/dist/notifications/root/notifications-root.js +76 -2
  162. package/dist/number-input/root/number-input-root.d.ts +109 -7
  163. package/dist/number-input/root/number-input-root.js +109 -21
  164. package/dist/object-inspector/root/object-inspector-root.d.ts +49 -5
  165. package/dist/object-inspector/root/object-inspector-root.js +92 -12
  166. package/dist/option/root/option-root.d.ts +58 -6
  167. package/dist/option/root/option-root.js +35 -5
  168. package/dist/outline/root/outline-root.d.ts +13 -2
  169. package/dist/outline/root/outline-root.js +4 -2
  170. package/dist/pagination/root/pagination-root.d.ts +19 -1
  171. package/dist/pagination/root/pagination-root.js +49 -9
  172. package/dist/pagination/size/pagination-size.d.ts +13 -3
  173. package/dist/pagination/size/pagination-size.js +7 -0
  174. package/dist/pin-input/format.d.ts +7 -0
  175. package/dist/pin-input/format.js +16 -0
  176. package/dist/pin-input/root/pin-input-root.d.ts +37 -0
  177. package/dist/pin-input/root/pin-input-root.js +48 -7
  178. package/dist/popover/root/popover-root.d.ts +78 -3
  179. package/dist/popover/root/popover-root.js +74 -5
  180. package/dist/progress/root/progress-root.d.ts +23 -1
  181. package/dist/progress/root/progress-root.js +40 -10
  182. package/dist/qr-code/export.d.ts +31 -0
  183. package/dist/qr-code/export.js +10 -0
  184. package/dist/qr-code/root/qr-code-root.d.ts +45 -0
  185. package/dist/qr-code/root/qr-code-root.js +78 -3
  186. package/dist/radio/group/radio-group.d.ts +64 -0
  187. package/dist/radio/group/radio-group.js +66 -12
  188. package/dist/radio/root/radio-root.d.ts +8 -5
  189. package/dist/radio/root/radio-root.js +1 -2
  190. package/dist/rating/root/rating-root.d.ts +49 -1
  191. package/dist/rating/root/rating-root.js +69 -10
  192. package/dist/scatter-chart/root/scatter-chart-root.d.ts +17 -3
  193. package/dist/scatter-chart/root/scatter-chart-root.js +40 -14
  194. package/dist/select/root/select-root.d.ts +93 -3
  195. package/dist/select/root/select-root.js +111 -13
  196. package/dist/skeleton/root/skeleton-root.d.ts +39 -3
  197. package/dist/skeleton/root/skeleton-root.js +33 -4
  198. package/dist/skip-link/root/skip-link-root.d.ts +10 -0
  199. package/dist/skip-link/root/skip-link-root.js +15 -1
  200. package/dist/slider/root/slider-root.d.ts +59 -2
  201. package/dist/slider/root/slider-root.js +82 -8
  202. package/dist/sparkline/root/sparkline-root.d.ts +9 -10
  203. package/dist/speed-dial/item/speed-dial-item.d.ts +11 -5
  204. package/dist/speed-dial/item/speed-dial-item.js +7 -2
  205. package/dist/speed-dial/root/speed-dial-root.d.ts +15 -4
  206. package/dist/speed-dial/root/speed-dial-root.js +19 -5
  207. package/dist/splitter/root/splitter-root.d.ts +28 -6
  208. package/dist/splitter/root/splitter-root.js +35 -1
  209. package/dist/stat/root/stat-root.d.ts +9 -1
  210. package/dist/stat/root/stat-root.js +15 -2
  211. package/dist/steps/root/steps-root.js +1 -1
  212. package/dist/steps/step/step.d.ts +1 -0
  213. package/dist/steps/step/step.js +1 -1
  214. package/dist/switch/root/switch-root.d.ts +14 -2
  215. package/dist/switch/root/switch-root.js +7 -1
  216. package/dist/table/cell/table-cell.d.ts +24 -4
  217. package/dist/table/cell/table-cell.js +21 -1
  218. package/dist/table/column/table-column.d.ts +32 -6
  219. package/dist/table/column/table-column.js +36 -6
  220. package/dist/table/root/table-root.d.ts +94 -3
  221. package/dist/table/root/table-root.js +128 -5
  222. package/dist/table/row/table-row.d.ts +7 -0
  223. package/dist/table/row/table-row.js +9 -1
  224. package/dist/tabs/root/tabs-root.d.ts +6 -1
  225. package/dist/tabs/root/tabs-root.js +6 -2
  226. package/dist/tag/group/tag-group.d.ts +107 -0
  227. package/dist/tag/group/tag-group.js +157 -0
  228. package/dist/tag/index.d.ts +1 -0
  229. package/dist/tag/index.js +1 -0
  230. package/dist/tag/root/tag-root.d.ts +83 -1
  231. package/dist/tag/root/tag-root.js +87 -17
  232. package/dist/tag/selection.d.ts +10 -0
  233. package/dist/tag/selection.js +12 -0
  234. package/dist/textarea/grow.d.ts +22 -0
  235. package/dist/textarea/grow.js +20 -0
  236. package/dist/textarea/root/textarea-root.d.ts +13 -0
  237. package/dist/textarea/root/textarea-root.js +10 -2
  238. package/dist/time-input/root/time-input-root.d.ts +71 -6
  239. package/dist/time-input/root/time-input-root.js +110 -44
  240. package/dist/time-picker/root/time-picker-root.d.ts +155 -26
  241. package/dist/time-picker/root/time-picker-root.js +192 -63
  242. package/dist/toast/hotkey.d.ts +22 -0
  243. package/dist/toast/hotkey.js +23 -0
  244. package/dist/toast/item/toast-item.d.ts +16 -1
  245. package/dist/toast/item/toast-item.js +41 -13
  246. package/dist/toast/root/toast-root.d.ts +105 -8
  247. package/dist/toast/root/toast-root.js +209 -4
  248. package/dist/toggle/group/toggle-group.d.ts +95 -16
  249. package/dist/toggle/group/toggle-group.js +99 -13
  250. package/dist/toggle/root/toggle-root.d.ts +26 -11
  251. package/dist/toggle/root/toggle-root.js +14 -6
  252. package/dist/toolbar/root/toolbar-root.d.ts +55 -15
  253. package/dist/toolbar/root/toolbar-root.js +99 -16
  254. package/dist/tooltip/focus-target.d.ts +6 -0
  255. package/dist/tooltip/focus-target.js +9 -0
  256. package/dist/tooltip/root/tooltip-root.d.ts +73 -15
  257. package/dist/tooltip/root/tooltip-root.js +96 -7
  258. package/dist/tour/naming.d.ts +30 -0
  259. package/dist/tour/naming.js +10 -0
  260. package/dist/tour/root/tour-root.d.ts +67 -3
  261. package/dist/tour/root/tour-root.js +105 -17
  262. package/dist/tour/stop/tour-stop.d.ts +65 -3
  263. package/dist/tour/stop/tour-stop.js +61 -11
  264. package/dist/tour/wait.d.ts +11 -0
  265. package/dist/tour/wait.js +19 -0
  266. package/dist/tree/item/tree-item.d.ts +21 -5
  267. package/dist/tree/item/tree-item.js +14 -4
  268. package/dist/tree/root/tree-root.d.ts +29 -5
  269. package/dist/tree/root/tree-root.js +64 -8
  270. package/dist/trend/root/trend-root.d.ts +36 -1
  271. package/dist/trend/root/trend-root.js +41 -15
  272. package/dist/video/root/keys.d.ts +5 -0
  273. package/dist/video/root/keys.js +13 -1
  274. package/dist/video/root/video-root.d.ts +19 -0
  275. package/dist/video/root/video-root.js +48 -4
  276. package/dist/video-playlist/menu/video-playlist-menu.d.ts +20 -2
  277. package/dist/video-playlist/menu/video-playlist-menu.js +27 -5
  278. package/dist/video-playlist/root/video-playlist-root.js +6 -3
  279. package/dist/virtual-list/root/virtual-list-root.d.ts +52 -4
  280. package/dist/virtual-list/root/virtual-list-root.js +103 -21
  281. package/lint.json +1 -1
  282. package/package.json +5 -5
  283. package/types/jsx.d.ts +9140 -1149
  284. package/types/svelte.d.ts +1 -0
  285. package/types/vue.d.ts +2089 -267
@@ -4,11 +4,13 @@ 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, customElement, drawIcon, fillTemplate, formatColor, HelixFormElement, HelixSampleEndEvent, HelixSampleStartEvent, isRtl, MixinControllerValue, parseColor, splitValues, toCss, } from '@fusion.dev/helix-core';
7
+ import { CopyController, capturePointer, colorName, customElement, drawIcon, fillTemplate, formatColor, HelixFormElement, HelixSampleEndEvent, HelixSampleStartEvent, hostAria, hueName, isRtl, MixinControllerValue, parseColor, splitValues, toCss, } 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
+ import { live } from 'lit/directives/live.js';
11
12
  import { html } from 'lit/static-html.js';
13
+ import { channelFields, writeChannel } from '../channels.js';
12
14
  import '../../button/index.js';
13
15
  import '../../button-group/index.js';
14
16
  import '../../slider/index.js';
@@ -19,19 +21,25 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
19
21
  super(...arguments);
20
22
  this.alpha = false;
21
23
  this.autocomplete = 'off';
24
+ this.blueLabel = 'Blue';
22
25
  this.brightnessLabel = 'Brightness';
26
+ this.channelFields = false;
27
+ this.colorWords = {};
23
28
  this.copiedLabel = 'Copied';
24
29
  this.copyLabel = 'Copy {value}';
25
30
  this.eyedropperLabel = 'Sample a color from the screen';
26
31
  this.formatLabel = 'Syntax: {format}. Change it.';
32
+ this.greenLabel = 'Green';
27
33
  this.hueLabel = 'Hue';
28
34
  this.invalid = false;
35
+ this.lightnessLabel = 'Lightness';
29
36
  this.noEyedropper = false;
30
37
  this.noFormat = false;
31
38
  this.noValue = false;
32
39
  this.opacityLabel = 'Opacity';
33
40
  this.presetsLabel = 'Presets';
34
41
  this.readOnly = false;
42
+ this.redLabel = 'Red';
35
43
  this.required = false;
36
44
  this.saturationLabel = 'Saturation';
37
45
  this.swatches = '';
@@ -39,6 +47,8 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
39
47
  this.valueLabel = 'Color';
40
48
  this.sampling = false;
41
49
  this.owned = false;
50
+ this.announcesInput = true;
51
+ this.unsettled = false;
42
52
  this.settled = '';
43
53
  this.handleValueInput = (event) => {
44
54
  event.stopPropagation();
@@ -57,16 +67,21 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
57
67
  if (this.readOnly) {
58
68
  return;
59
69
  }
70
+ const before = this.moved;
60
71
  this.moved = { ...this.color, ...next };
61
72
  const value = formatColor(this.moved, this.format ?? 'hex', this.alpha);
62
73
  this.owned = value !== this.value;
63
- this.requestValue(value);
74
+ if (!this.requestValue(value)) {
75
+ this.moved = before;
76
+ this.owned = false;
77
+ }
64
78
  };
65
79
  this.copier = new CopyController(this);
66
80
  this.handleSwatch = (preset) => {
67
81
  const parsed = parseColor(preset);
68
82
  if (parsed) {
69
83
  this.move(parsed);
84
+ this.settle();
70
85
  }
71
86
  };
72
87
  this.handleFormat = () => {
@@ -76,6 +91,7 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
76
91
  this.format = FORMATS[(FORMATS.indexOf(this.format ?? 'hex') + 1) % FORMATS.length] ?? 'hex';
77
92
  if (this.value !== '') {
78
93
  this.move({});
94
+ this.settle();
79
95
  }
80
96
  };
81
97
  this.handleEyeDropper = async () => {
@@ -92,6 +108,7 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
92
108
  const parsed = parseColor(sRGBHex);
93
109
  if (parsed) {
94
110
  this.move({ ...parsed, alpha: this.color.alpha });
111
+ this.settle();
95
112
  }
96
113
  }
97
114
  catch {
@@ -99,7 +116,14 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
99
116
  this.dispatchEvent(new HelixSampleEndEvent());
100
117
  };
101
118
  this.handleGridPointer = (event) => {
119
+ if (this.isDisabled) {
120
+ return;
121
+ }
102
122
  const grid = event.currentTarget;
123
+ if (event.type === 'pointerup' || event.type === 'pointercancel') {
124
+ this.settle();
125
+ return;
126
+ }
103
127
  if (event.type === 'pointerdown') {
104
128
  capturePointer(grid, event.pointerId);
105
129
  this.partNamed('grid-saturation')?.focus();
@@ -117,10 +141,51 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
117
141
  const down = Math.min(1, Math.max(0, (event.clientY - box.top) / box.height));
118
142
  this.move({ brightness: Math.round((1 - down) * 100), saturation: Math.round(across * 100) });
119
143
  };
144
+ this.handleAreaKeydown = (event) => {
145
+ if (this.isDisabled || this.readOnly) {
146
+ return;
147
+ }
148
+ const color = this.color;
149
+ const along = isRtl(this) ? -1 : 1;
150
+ const clamp = (at) => Math.min(100, Math.max(0, at));
151
+ const moves = {
152
+ ArrowDown: { brightness: clamp(color.brightness - 1) },
153
+ ArrowLeft: { saturation: clamp(color.saturation - along) },
154
+ ArrowRight: { saturation: clamp(color.saturation + along) },
155
+ ArrowUp: { brightness: clamp(color.brightness + 1) },
156
+ PageDown: { brightness: clamp(color.brightness - 10) },
157
+ PageUp: { brightness: clamp(color.brightness + 10) },
158
+ };
159
+ const next = moves[event.key];
160
+ if (!next) {
161
+ return;
162
+ }
163
+ event.preventDefault();
164
+ this.move(next);
165
+ this.settle();
166
+ };
167
+ this.handleField = (channel, event) => {
168
+ event.stopPropagation();
169
+ const typed = event.target.value;
170
+ if (typed.trim() === '') {
171
+ return;
172
+ }
173
+ const format = this.format ?? 'hex';
174
+ const written = writeChannel(channelFields(this.value, this.color, format, this.alpha), format, this.alpha, channel, Number(typed));
175
+ if (written !== null) {
176
+ this.takeWritten(written);
177
+ }
178
+ };
120
179
  this.keepChannelRequest = (event) => {
121
180
  event.stopPropagation();
122
181
  };
123
182
  }
183
+ settle() {
184
+ if (this.unsettled) {
185
+ this.unsettled = false;
186
+ this.announceChange();
187
+ }
188
+ }
124
189
  get color() {
125
190
  return this.moved ?? parseColor(this.value) ?? parseColor(this.settled) ?? START;
126
191
  }
@@ -134,7 +199,12 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
134
199
  if (this.readOnly) {
135
200
  return false;
136
201
  }
137
- return super.requestValue(next);
202
+ const before = this.value;
203
+ const taken = super.requestValue(next);
204
+ if (taken && this.value !== before) {
205
+ this.unsettled = true;
206
+ }
207
+ return taken;
138
208
  }
139
209
  firstUpdated(changed) {
140
210
  super.firstUpdated(changed);
@@ -149,6 +219,10 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
149
219
  this.internals.setValidity({ valueMissing: true }, this.valueMissingMessage || 'Choose a color.', this.partNamed('grid') ?? undefined);
150
220
  return;
151
221
  }
222
+ if (this.value !== '' && parseColor(this.value) === null) {
223
+ this.internals.setValidity({ badInput: true }, this.badInputMessage || 'Enter a color, like #ff0000, rgb(255 0 0) or hsl(0 100% 50%).', this.partNamed('value') ?? this.partNamed('grid') ?? undefined);
224
+ return;
225
+ }
152
226
  this.internals.setValidity({});
153
227
  }
154
228
  updated(changed) {
@@ -169,7 +243,56 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
169
243
  focus(options) {
170
244
  this.partNamed('grid-saturation')?.focus(options);
171
245
  }
172
- renderChannel(channel, label, max, value) {
246
+ channelWord(channel) {
247
+ return {
248
+ alpha: this.opacityLabel,
249
+ blue: this.blueLabel,
250
+ green: this.greenLabel,
251
+ hue: this.hueLabel,
252
+ lightness: this.lightnessLabel,
253
+ red: this.redLabel,
254
+ saturation: this.saturationLabel,
255
+ }[channel];
256
+ }
257
+ takeWritten(next) {
258
+ const parsed = parseColor(next);
259
+ if (this.readOnly || parsed === null) {
260
+ return;
261
+ }
262
+ const before = this.moved;
263
+ const hueless = parsed.saturation === 0 || parsed.brightness === 0;
264
+ this.moved = hueless ? { ...parsed, hue: this.color.hue } : parsed;
265
+ this.owned = next !== this.value;
266
+ if (!this.requestValue(next)) {
267
+ this.moved = before;
268
+ this.owned = false;
269
+ }
270
+ }
271
+ renderFields(color) {
272
+ return html `<div part="fields">
273
+ ${channelFields(this.value, color, this.format ?? 'hex', this.alpha).map((field) => html `<label part="field">
274
+ <span part="field-label">${this.channelWord(field.channel)}</span>
275
+ <input
276
+ part="field-input"
277
+ type="number"
278
+ inputmode="numeric"
279
+ min=${field.min}
280
+ max=${field.max}
281
+ step="1"
282
+ .value=${live(String(field.value))}
283
+ ?disabled=${this.isDisabled}
284
+ ?readonly=${this.readOnly}
285
+ @input=${(event) => this.handleField(field.channel, event)}
286
+ @change=${(event) => {
287
+ event.stopPropagation();
288
+ this.settle();
289
+ this.requestUpdate();
290
+ }}
291
+ />
292
+ </label>`)}
293
+ </div>`;
294
+ }
295
+ renderChannel(channel, label, max, value, spoken = '') {
173
296
  return html `<${this.tag('slider')}
174
297
  part="channel"
175
298
  exportparts="control: channel-control, feedback: channel-feedback, field: channel-field,
@@ -180,10 +303,14 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
180
303
  label=${label}
181
304
  max=${max}
182
305
  min="0"
306
+ value-text=${spoken || nothing}
183
307
  .value=${String(value)}
184
308
  ?disabled=${this.isDisabled}
185
309
  @input=${(event) => this.takeChannel(channel, event)}
186
- @change=${(event) => this.takeChannel(channel, event)}
310
+ @change=${(event) => {
311
+ this.takeChannel(channel, event);
312
+ this.settle();
313
+ }}
187
314
  @helix-before-change=${this.keepChannelRequest}
188
315
  ></${this.tag('slider')}>`;
189
316
  }
@@ -211,6 +338,8 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
211
338
  willUpdate(changed) {
212
339
  super.willUpdate(changed);
213
340
  this.internals.ariaInvalid = this.invalid ? 'true' : null;
341
+ const outside = [...(this.internals.labels ?? [])];
342
+ hostAria(this.internals, { labelledBy: outside, role: outside.length > 0 ? 'group' : '' });
214
343
  if (!this.hydrating) {
215
344
  this.sampling = 'EyeDropper' in globalThis;
216
345
  }
@@ -220,8 +349,8 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
220
349
  ${this.sampling && !this.noEyedropper
221
350
  ? html `<${this.tag('button')}
222
351
  part="eyedropper"
223
- exportparts="button: eyedropper-button, text: eyedropper-text"
224
- aria-label=${this.eyedropperLabel}
352
+ exportparts="button: eyedropper-button, live: eyedropper-live, text: eyedropper-text"
353
+ label=${this.eyedropperLabel}
225
354
  ?disabled=${this.isDisabled}
226
355
  @click=${this.handleEyeDropper}
227
356
  >
@@ -232,8 +361,8 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
232
361
  ? nothing
233
362
  : html `<${this.tag('button')}
234
363
  part="format"
235
- exportparts="button: format-button, text: format-text"
236
- aria-label=${fillTemplate(this.formatLabel, { format: this.format ?? 'hex' })}
364
+ exportparts="button: format-button, live: format-live, text: format-text"
365
+ label=${fillTemplate(this.formatLabel, { format: this.format ?? 'hex' })}
237
366
  ?disabled=${this.isDisabled}
238
367
  @click=${this.handleFormat}
239
368
  >
@@ -244,33 +373,48 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
244
373
  render() {
245
374
  const color = this.color;
246
375
  const painted = toCss(color);
376
+ const named = colorName(color, this.colorWords, this.lang);
377
+ const both = `${this.saturationLabel} ${color.saturation}%, ${this.brightnessLabel} ${color.brightness}%, ${named}`;
378
+ const reversed = `${this.brightnessLabel} ${color.brightness}%, ${this.saturationLabel} ${color.saturation}%, ${named}`;
379
+ const hue = hueName({ alpha: 100, brightness: 100, hue: color.hue, saturation: 100 }, this.colorWords, this.lang);
380
+ const owner = this.getAttribute('aria-label')?.trim();
381
+ const axisName = (channel) => (owner ? `${owner}, ${channel}` : channel);
247
382
  return html `<div
248
383
  part="grid"
249
384
  style="--color-picker-hue: ${color.hue}; --color-picker-saturation: ${color.saturation}%; --color-picker-brightness: ${color.brightness}%"
250
385
  @pointerdown=${this.handleGridPointer}
251
386
  @pointermove=${this.handleGridPointer}
387
+ @pointerup=${this.handleGridPointer}
388
+ @pointercancel=${this.handleGridPointer}
389
+ @keydown=${this.handleAreaKeydown}
252
390
  >
253
391
  <input
254
392
  part="grid-saturation"
255
393
  type="range"
256
394
  min="0"
257
395
  max="100"
258
- aria-label=${this.saturationLabel}
396
+ aria-label=${axisName(this.saturationLabel)}
397
+ aria-valuetext=${both}
259
398
  aria-invalid=${this.invalid ? 'true' : nothing}
260
399
  .value=${String(color.saturation)}
261
400
  ?disabled=${this.isDisabled}
262
401
  @input=${(event) => this.takeArea('saturation', event)}
402
+ @change=${() => this.settle()}
263
403
  />
404
+ ${''}
264
405
  <input
265
406
  part="grid-brightness"
266
407
  type="range"
267
408
  min="0"
268
409
  max="100"
269
- aria-label=${this.brightnessLabel}
410
+ tabindex="-1"
411
+ aria-label=${axisName(this.brightnessLabel)}
412
+ aria-valuetext=${reversed}
270
413
  aria-invalid=${this.invalid ? 'true' : nothing}
271
414
  .value=${String(color.brightness)}
272
415
  ?disabled=${this.isDisabled}
273
416
  @input=${(event) => this.takeArea('brightness', event)}
417
+ @change=${() => this.settle()}
274
418
  />
275
419
  </div>
276
420
 
@@ -286,10 +430,11 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
286
430
  @click=${() => this.copier.copy(this.value)}
287
431
  ></button>
288
432
  <div part="channels">
289
- ${this.renderChannel('hue', this.hueLabel, 360, color.hue)}
433
+ ${this.renderChannel('hue', this.hueLabel, 360, color.hue, `{value}, ${hue}`)}
290
434
  ${this.alpha ? this.renderChannel('alpha', this.opacityLabel, 100, color.alpha) : nothing}
291
435
  </div>
292
436
  </div>
437
+ ${this.channelFields ? this.renderFields(color) : nothing}
293
438
 
294
439
  <!-- The syntax and the presets share a row, because neither fills one.
295
440
  Above them the ramps get the whole width, which is what they need:
@@ -309,6 +454,10 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
309
454
  ?disabled=${this.isDisabled}
310
455
  ?readonly=${this.readOnly}
311
456
  @input=${this.handleValueInput}
457
+ @change=${(event) => {
458
+ event.stopPropagation();
459
+ this.settle();
460
+ }}
312
461
  />`}
313
462
  ${this.tools ? html `${this.renderTools()}` : nothing}
314
463
  </div>
@@ -321,7 +470,7 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
321
470
  return html `<button
322
471
  part="swatch"
323
472
  type="button"
324
- aria-label=${preset}
473
+ aria-label=${parsed ? colorName(parsed, this.colorWords, this.lang) : preset}
325
474
  aria-pressed=${parsed !== null && toCss(parsed) === painted ? 'true' : 'false'}
326
475
  style="--color-picker-swatch: ${preset}"
327
476
  ?disabled=${this.isDisabled}
@@ -337,9 +486,21 @@ __decorate([
337
486
  __decorate([
338
487
  property()
339
488
  ], HelixHeadlessColorPicker.prototype, "autocomplete", void 0);
489
+ __decorate([
490
+ property({ attribute: 'bad-input-message' })
491
+ ], HelixHeadlessColorPicker.prototype, "badInputMessage", void 0);
492
+ __decorate([
493
+ property({ attribute: 'blue-label' })
494
+ ], HelixHeadlessColorPicker.prototype, "blueLabel", void 0);
340
495
  __decorate([
341
496
  property({ attribute: 'brightness-label' })
342
497
  ], HelixHeadlessColorPicker.prototype, "brightnessLabel", void 0);
498
+ __decorate([
499
+ property({ attribute: 'channel-fields', type: Boolean })
500
+ ], HelixHeadlessColorPicker.prototype, "channelFields", void 0);
501
+ __decorate([
502
+ property({ attribute: 'color-words', type: Object })
503
+ ], HelixHeadlessColorPicker.prototype, "colorWords", void 0);
343
504
  __decorate([
344
505
  property({ attribute: 'copied-label' })
345
506
  ], HelixHeadlessColorPicker.prototype, "copiedLabel", void 0);
@@ -355,12 +516,18 @@ __decorate([
355
516
  __decorate([
356
517
  property({ attribute: 'format-label' })
357
518
  ], HelixHeadlessColorPicker.prototype, "formatLabel", void 0);
519
+ __decorate([
520
+ property({ attribute: 'green-label' })
521
+ ], HelixHeadlessColorPicker.prototype, "greenLabel", void 0);
358
522
  __decorate([
359
523
  property({ attribute: 'hue-label' })
360
524
  ], HelixHeadlessColorPicker.prototype, "hueLabel", void 0);
361
525
  __decorate([
362
526
  property({ reflect: true, type: Boolean })
363
527
  ], HelixHeadlessColorPicker.prototype, "invalid", void 0);
528
+ __decorate([
529
+ property({ attribute: 'lightness-label' })
530
+ ], HelixHeadlessColorPicker.prototype, "lightnessLabel", void 0);
364
531
  __decorate([
365
532
  property({ attribute: 'no-eyedropper', type: Boolean })
366
533
  ], HelixHeadlessColorPicker.prototype, "noEyedropper", void 0);
@@ -379,6 +546,9 @@ __decorate([
379
546
  __decorate([
380
547
  property({ attribute: 'readonly', reflect: true, type: Boolean })
381
548
  ], HelixHeadlessColorPicker.prototype, "readOnly", void 0);
549
+ __decorate([
550
+ property({ attribute: 'red-label' })
551
+ ], HelixHeadlessColorPicker.prototype, "redLabel", void 0);
382
552
  __decorate([
383
553
  property({ reflect: true, type: Boolean })
384
554
  ], HelixHeadlessColorPicker.prototype, "required", void 0);
@@ -18,6 +18,12 @@ declare const HelixHeadlessCombobox_base: (new (...args: any[]) => import("@fusi
18
18
  *
19
19
  * Focus stays in the text field. The arrow keys move through the list with the
20
20
  * listbox's public `navigate` method. `role="combobox"` is on the input itself.
21
+ * ArrowDown and ArrowUp open the list on the chosen option, and Enter chooses
22
+ * the highlighted one. As typing narrows the list, a screen reader hears how
23
+ * many options are left, such as "3 results". Space, Home, End and letters edit the text, and Enter in
24
+ * a closed field is left to the form. Emptying the field and leaving it clears
25
+ * a single choice; Escape puts the chosen words back, and a second Escape on
26
+ * the closed field clears the choice.
21
27
  *
22
28
  * With `multiple`, each chosen option is a tag in the field with its own remove
23
29
  * control. The panel stays open and the filter clears after each choice, so the
@@ -35,8 +41,13 @@ declare const HelixHeadlessCombobox_base: (new (...args: any[]) => import("@fusi
35
41
  * @documentation https://fusion.dev/helix/components/combobox
36
42
  *
37
43
  * @slot - The options.
44
+ * @slot empty - What the list shows when typing hides every option, for content richer than `empty-text`.
38
45
  * @slot end - After the text, for a unit or a clear button.
46
+ * @slot feedback - The message that says what is wrong, for content richer than a string. It shows while there is a message.
47
+ * @slot hint - The hint, for content richer than plain text.
39
48
  * @slot indicator - Replaces the caret that shows the field opens a list.
49
+ * @slot label - The label, for content richer than plain text.
50
+ * @slot loading - What the list shows while the options load, for content richer than `loading-text`.
40
51
  * @slot start - Before the text, for an icon.
41
52
  *
42
53
  * @event {Event} change - Fired after the value changes.
@@ -46,10 +57,11 @@ declare const HelixHeadlessCombobox_base: (new (...args: any[]) => import("@fusi
46
57
  * @event {HelixCreateEvent} helix-create - Fired when the user adds a value that is not in the list. Cancelable.
47
58
  * @event {HelixFilterEvent} helix-filter - Fired as the user types, with the text the list is filtered by. Cancelable: cancel it to leave the list unfiltered and do the filtering yourself.
48
59
  * @event {Event} input - Fired after the value changes.
49
- * @event {Event} toggle - Fired when the panel opens or closes, with `newState` and `oldState`.
60
+ * @event {ToggleEvent} toggle - Fired when the panel opens or closes, with `newState` and `oldState`.
50
61
  *
51
62
  * @csspart control - The text field itself.
52
63
  * @csspart create - The row offering to add what was typed.
64
+ * @csspart create-active - The create row while the keyboard is on it. Set alongside `create`.
53
65
  * @csspart feedback - The message that explains what is wrong with the value.
54
66
  * @csspart field - The box around the text and its marks.
55
67
  * @csspart hint - Help text under the field, shown while there is no error.
@@ -63,16 +75,18 @@ declare const HelixHeadlessCombobox_base: (new (...args: any[]) => import("@fusi
63
75
  * @csspart listbox-hint - Help under the list.
64
76
  * @csspart listbox-items - The element that holds the options.
65
77
  * @csspart listbox-label - The label above the list.
66
- * @csspart listbox-live - The inner list's `live` part, the region screen readers announce its empty and loading messages from.
78
+ * @csspart listbox-live - The inner list's `live` part, the region screen readers announce its empty and loading messages, and how many options typing left, from.
67
79
  * @csspart listbox-loading - Shown while the options are loading.
68
80
  * @csspart listbox-search - The region holding the field that narrows the list.
69
81
  * @csspart listbox-search-field - The filter field inside that region.
70
82
  * @csspart rest - The count of choices held beyond `max-tags`. A `<button>` with `expandable`, a `<span>` without it.
71
83
  * @csspart surface - The floating panel.
72
84
  * @csspart tag - One chosen option.
85
+ * @csspart tag-cell - The tag's grid cell, which a tag draws only inside a tag group.
73
86
  * @csspart tag-dismiss - The remove button, when `dismissible`.
74
87
  * @csspart tag-dismiss-mark - The glyph on the dismiss control, where none is slotted.
75
88
  * @csspart tag-label - The label, trimmed to its capitals and baseline.
89
+ * @csspart tag-link - The tag's link around its label, which a tag draws only with `href`.
76
90
  * @csspart tag-start - The category before the label.
77
91
  * @csspart tags - The row of chosen options, when `multiple` is set.
78
92
  *
@@ -81,6 +95,17 @@ declare const HelixHeadlessCombobox_base: (new (...args: any[]) => import("@fusi
81
95
  */
82
96
  export declare class HelixHeadlessCombobox extends HelixHeadlessCombobox_base {
83
97
  protected readonly aria: AriaForwardController;
98
+ /**
99
+ * Whether text that names no option is taken as the value, as React Aria's
100
+ * `allowsCustomValue`.
101
+ *
102
+ * For a field where the list is a help and not the whole of the answer, a
103
+ * city or a job title. What was typed becomes the value when the reader
104
+ * leaves the field or presses Enter with nothing highlighted, and text that
105
+ * names an option takes that option. Unlike `creatable`, no event asks
106
+ * first and no option is expected to be added: the value is the text.
107
+ */
108
+ allowsCustomValue: boolean;
84
109
  /**
85
110
  * What the browser may autofill in the text field, as a platform token.
86
111
  *
@@ -96,7 +121,8 @@ export declare class HelixHeadlessCombobox extends HelixHeadlessCombobox_base {
96
121
  * The row appears while what is typed matches no option's words exactly, so
97
122
  * it is offered next to near misses too: a reader typing "Ruby on Rails" with
98
123
  * "Ruby" in the list wants the one they are typing, not the one they are
99
- * halfway through.
124
+ * halfway through. The arrow keys reach it after the last option, and Enter
125
+ * on it adds what was typed.
100
126
  */
101
127
  creatable: boolean;
102
128
  /**
@@ -146,6 +172,17 @@ export declare class HelixHeadlessCombobox extends HelixHeadlessCombobox_base {
146
172
  * Text shown while nothing has been chosen.
147
173
  */
148
174
  placeholder: string;
175
+ /**
176
+ * Whether the choice is locked. A read-only combobox still submits its value.
177
+ *
178
+ * The field can be read and focused, the list does not open, and the tags of
179
+ * a `multiple` combobox cannot be dismissed.
180
+ */
181
+ readOnly: boolean;
182
+ /** Requests a new value. While `readOnly` is set, nothing changes. */
183
+ requestValue(next: string): boolean;
184
+ /** Requests the list open or closed. While `readOnly` is set, it does not open. */
185
+ requestOpen(next: boolean): boolean;
149
186
  /**
150
187
  * The name of the control that removes one chosen option, with `{name}`
151
188
  * filled in.
@@ -154,6 +191,17 @@ export declare class HelixHeadlessCombobox extends HelixHeadlessCombobox_base {
154
191
  * removes rather than as "Remove" said once per chosen option.
155
192
  */
156
193
  removeLabel: string;
194
+ /**
195
+ * What a screen reader hears when typing leaves one option. `{count}` is
196
+ * the count.
197
+ */
198
+ resultLabel: string;
199
+ /**
200
+ * What a screen reader hears when typing leaves any other number of
201
+ * options. `{count}` is the count, and `Intl.PluralRules` picks between the
202
+ * two.
203
+ */
204
+ resultsLabel: string;
157
205
  /**
158
206
  * Whether the field completes the word as the user types.
159
207
  *
@@ -180,6 +228,23 @@ export declare class HelixHeadlessCombobox extends HelixHeadlessCombobox_base {
180
228
  * what the reader is offered.
181
229
  */
182
230
  private suggestion;
231
+ /**
232
+ * Whether the reader has typed since the list opened, which decides what the
233
+ * field shows: their text while they type, and the chosen words otherwise.
234
+ */
235
+ private editing;
236
+ /** Whether the keyboard is on the create row rather than on an option. */
237
+ private onCreate;
238
+ /**
239
+ * Whether the reader emptied the field, so leaving it clears the choice.
240
+ *
241
+ * Escape takes it back, being a reader putting things as they were.
242
+ */
243
+ private emptied;
244
+ /** Where the highlight goes when an arrow opens the list. */
245
+ private opening;
246
+ /** Hears an option's words change, which no slot reports. See `Select`. */
247
+ private watcher;
183
248
  /**
184
249
  * Which option is chosen, as an index, or `-1` where none is.
185
250
  *
@@ -268,6 +333,30 @@ export declare class HelixHeadlessCombobox extends HelixHeadlessCombobox_base {
268
333
  */
269
334
  private drop;
270
335
  private close;
336
+ /**
337
+ * Clears a single choice whose words the reader deleted, as they leave.
338
+ *
339
+ * Measured before this: emptying the field and pressing Tab put the old
340
+ * choice back, so a combobox that was not required could not be emptied
341
+ * once answered.
342
+ */
343
+ private commitEmptied;
344
+ /**
345
+ * Takes what was typed as the answer, where `allows-custom-value` asks: the
346
+ * option its words name, or the text itself. Returns whether it took any.
347
+ */
348
+ private commitTyped;
349
+ /** The options the arrows can reach. */
350
+ private get reachable();
351
+ /**
352
+ * Moves between the options and the create row, which sits after the last
353
+ * option, and returns whether the key was taken.
354
+ *
355
+ * The row is outside the list, so the list's own keys never reach it. While
356
+ * it is showing, a Down past the last option lands on it and an Up from the
357
+ * first one does, and either arrow from it goes back into the list.
358
+ */
359
+ private moveAroundCreate;
271
360
  private readonly handleInput;
272
361
  /**
273
362
  * The words of the first option the typing begins, or nothing.
@@ -286,6 +375,18 @@ export declare class HelixHeadlessCombobox extends HelixHeadlessCombobox_base {
286
375
  * the panel rather than about the options in it.
287
376
  */
288
377
  private readonly handleKeydown;
378
+ /**
379
+ * Enter in a closed field submits the form, as it does in a native text
380
+ * field.
381
+ *
382
+ * The field is in a shadow root and has no form owner, so the platform never
383
+ * runs implicit submission for it. On `keypress`, which a prevented
384
+ * `keydown` suppresses, so an Enter that chose an option or created one
385
+ * submits nothing.
386
+ */
387
+ private readonly handleKeypress;
388
+ /** @internal A single line of text counts against implicit submission. */
389
+ protected get blocksImplicitSubmission(): boolean;
289
390
  /**
290
391
  * Tells the input which option is highlighted.
291
392
  *
@@ -350,8 +451,21 @@ export declare class HelixHeadlessCombobox extends HelixHeadlessCombobox_base {
350
451
  * component: a form that received "jav" got the filter, not an option.
351
452
  */
352
453
  private sync;
454
+ /** A link option, once followed, closes the panel as a choice does. */
455
+ private readonly handleLinkFollowed;
456
+ connectedCallback(): void;
457
+ disconnectedCallback(): void;
458
+ protected willUpdate(changed: PropertyValues): void;
353
459
  protected firstUpdated(changed: PropertyValues): void;
354
460
  protected updated(changed: PropertyValues): void;
461
+ /**
462
+ * What the field shows: the typed text while the reader types, and the
463
+ * chosen words otherwise, open or closed.
464
+ *
465
+ * Measured before this: opening the list emptied the field, so a reader
466
+ * arrowing in to check the choice lost sight of it.
467
+ */
468
+ private get fieldText();
355
469
  /**
356
470
  * The list the field filters, behind a seam the styled tier can move.
357
471
  *
@@ -385,6 +499,15 @@ export declare class HelixHeadlessCombobox extends HelixHeadlessCombobox_base {
385
499
  * cannot change.
386
500
  */
387
501
  protected renderIndicator(): TemplateResult;
502
+ /**
503
+ * The row offering to add what was typed, after the list.
504
+ *
505
+ * Written out twice rather than bound through `part=${…}`: a part is read
506
+ * from the template as a literal, so a bound one is a `::part(create)` the
507
+ * checks cannot pair with its `@csspart`. The keyboard arriving swaps the
508
+ * element, and `linkActive` runs after the render that swaps it.
509
+ */
510
+ private renderCreate;
388
511
  protected render(): TemplateResult;
389
512
  }
390
513
  declare global {