@fusion.dev/helix-headless 0.142.1 → 0.143.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 (217) hide show
  1. package/custom-elements.json +16710 -707
  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.js +16 -5
  11. package/dist/avatar/group/avatar-group.d.ts +24 -3
  12. package/dist/avatar/group/avatar-group.js +34 -2
  13. package/dist/avatar/root/avatar-root.d.ts +3 -1
  14. package/dist/avatar/root/avatar-root.js +8 -1
  15. package/dist/badge/root/badge-root.d.ts +8 -0
  16. package/dist/bar-chart/root/bar-chart-root.d.ts +19 -3
  17. package/dist/bar-chart/root/bar-chart-root.js +43 -13
  18. package/dist/blockquote/root/blockquote-root.d.ts +12 -7
  19. package/dist/blockquote/root/blockquote-root.js +6 -4
  20. package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +9 -3
  21. package/dist/breadcrumbs/root/breadcrumbs-root.js +9 -1
  22. package/dist/button/root/button-root.d.ts +37 -0
  23. package/dist/button/root/button-root.js +44 -0
  24. package/dist/callout/root/callout-root.d.ts +14 -5
  25. package/dist/callout/root/callout-root.js +11 -3
  26. package/dist/canvas/root/canvas-root.d.ts +1 -0
  27. package/dist/canvas/root/canvas-root.js +10 -1
  28. package/dist/carousel/root/carousel-root.d.ts +47 -5
  29. package/dist/carousel/root/carousel-root.js +53 -21
  30. package/dist/chat/composer/chat-composer.d.ts +13 -11
  31. package/dist/chat/composer/chat-composer.js +6 -12
  32. package/dist/chat/message/chat-message.js +8 -1
  33. package/dist/chat/root/chat-root.d.ts +1 -0
  34. package/dist/chat/root/chat-root.js +2 -1
  35. package/dist/checkbox/root/checkbox-root.d.ts +7 -0
  36. package/dist/checkbox/root/checkbox-root.js +7 -3
  37. package/dist/checkbox-group/root/checkbox-group-root.d.ts +65 -32
  38. package/dist/checkbox-group/root/checkbox-group-root.js +85 -37
  39. package/dist/code/root/code-root.d.ts +1 -1
  40. package/dist/code-block/root/code-block-root.d.ts +19 -0
  41. package/dist/code-block/root/code-block-root.js +21 -1
  42. package/dist/color-input/root/color-input-root.d.ts +26 -1
  43. package/dist/color-input/root/color-input-root.js +32 -3
  44. package/dist/color-picker/root/color-picker-root.d.ts +37 -7
  45. package/dist/color-picker/root/color-picker-root.js +83 -6
  46. package/dist/combobox/root/combobox-root.d.ts +90 -2
  47. package/dist/combobox/root/combobox-root.js +160 -19
  48. package/dist/command/root/command-root.d.ts +17 -6
  49. package/dist/command/root/command-root.js +12 -1
  50. package/dist/copy-button/root/copy-button-root.d.ts +21 -6
  51. package/dist/copy-button/root/copy-button-root.js +11 -1
  52. package/dist/data-table/root/data-table-root.d.ts +164 -10
  53. package/dist/data-table/root/data-table-root.js +488 -57
  54. package/dist/date-input/root/date-input-root.d.ts +53 -8
  55. package/dist/date-input/root/date-input-root.js +70 -18
  56. package/dist/date-picker/root/date-picker-root.d.ts +84 -17
  57. package/dist/date-picker/root/date-picker-root.js +125 -20
  58. package/dist/dialog/root/dialog-root.d.ts +38 -10
  59. package/dist/dialog/root/dialog-root.js +55 -2
  60. package/dist/donut-chart/root/donut-chart-root.d.ts +39 -15
  61. package/dist/donut-chart/root/donut-chart-root.js +30 -10
  62. package/dist/drawer/root/drawer-root.d.ts +32 -7
  63. package/dist/drawer/root/drawer-root.js +50 -5
  64. package/dist/drilldown/item/drilldown-item.d.ts +16 -13
  65. package/dist/drilldown/item/drilldown-item.js +6 -2
  66. package/dist/drilldown/root/drilldown-root.d.ts +21 -5
  67. package/dist/drilldown/root/drilldown-root.js +26 -10
  68. package/dist/element-events.generated.js +35 -9
  69. package/dist/file-input/root/file-input-root.d.ts +18 -1
  70. package/dist/file-input/root/file-input-root.js +34 -8
  71. package/dist/filter-input/menu/filter-menu.d.ts +9 -0
  72. package/dist/filter-input/menu/filter-menu.js +8 -0
  73. package/dist/filter-input/root/filter-input-root.d.ts +5 -2
  74. package/dist/filter-input/root/filter-input-root.js +22 -7
  75. package/dist/format-date/root/format-date-root.d.ts +11 -3
  76. package/dist/format-date/root/format-date-root.js +26 -5
  77. package/dist/graph/root/graph-root.d.ts +24 -3
  78. package/dist/graph/root/graph-root.js +66 -12
  79. package/dist/heatmap/root/buckets.d.ts +2 -1
  80. package/dist/heatmap/root/buckets.js +5 -1
  81. package/dist/heatmap/root/heatmap-root.d.ts +27 -6
  82. package/dist/heatmap/root/heatmap-root.js +23 -6
  83. package/dist/icon/root/icon-root.d.ts +24 -3
  84. package/dist/icon/root/icon-root.js +34 -1
  85. package/dist/icon-button/root/icon-button-root.d.ts +1 -1
  86. package/dist/image/root/image-root.d.ts +9 -2
  87. package/dist/image/root/image-root.js +8 -2
  88. package/dist/input/root/input-root.d.ts +51 -9
  89. package/dist/input/root/input-root.js +46 -5
  90. package/dist/kbd/root/kbd-root.d.ts +12 -4
  91. package/dist/kbd/root/kbd-root.js +10 -11
  92. package/dist/legend/root/legend-root.d.ts +7 -0
  93. package/dist/legend/root/legend-root.js +7 -2
  94. package/dist/lightbox/item/lightbox-item.d.ts +2 -1
  95. package/dist/lightbox/root/lightbox-root.d.ts +16 -5
  96. package/dist/lightbox/root/lightbox-root.js +24 -3
  97. package/dist/line-chart/root/line-chart-root.d.ts +19 -2
  98. package/dist/line-chart/root/line-chart-root.js +40 -13
  99. package/dist/list/item/list-item.d.ts +11 -5
  100. package/dist/list/item/list-item.js +5 -6
  101. package/dist/listbox/root/listbox-root.d.ts +111 -2
  102. package/dist/listbox/root/listbox-root.js +144 -16
  103. package/dist/map/root/map-root.d.ts +19 -4
  104. package/dist/map/root/map-root.js +36 -7
  105. package/dist/megamenu/root/megamenu-root.d.ts +10 -1
  106. package/dist/megamenu/root/megamenu-root.js +10 -1
  107. package/dist/menu/item/menu-item.d.ts +41 -12
  108. package/dist/menu/item/menu-item.js +46 -3
  109. package/dist/menu/root/menu-root.d.ts +32 -2
  110. package/dist/menu/root/menu-root.js +48 -8
  111. package/dist/meter/root/meter-root.d.ts +6 -0
  112. package/dist/meter/root/meter-root.js +18 -2
  113. package/dist/navigation/root/navigation-root.d.ts +10 -2
  114. package/dist/navigation/root/navigation-root.js +13 -2
  115. package/dist/notifications/group/notification-group.d.ts +1 -0
  116. package/dist/notifications/notification/notification.d.ts +12 -0
  117. package/dist/notifications/notification/notification.js +31 -2
  118. package/dist/notifications/root/notifications-root.d.ts +7 -0
  119. package/dist/notifications/root/notifications-root.js +17 -2
  120. package/dist/number-input/root/number-input-root.d.ts +62 -7
  121. package/dist/number-input/root/number-input-root.js +68 -16
  122. package/dist/object-inspector/root/object-inspector-root.d.ts +48 -5
  123. package/dist/object-inspector/root/object-inspector-root.js +91 -11
  124. package/dist/option/root/option-root.d.ts +4 -1
  125. package/dist/option/root/option-root.js +1 -0
  126. package/dist/outline/root/outline-root.d.ts +13 -2
  127. package/dist/outline/root/outline-root.js +4 -2
  128. package/dist/pagination/root/pagination-root.d.ts +19 -1
  129. package/dist/pagination/root/pagination-root.js +49 -9
  130. package/dist/pagination/size/pagination-size.d.ts +13 -3
  131. package/dist/pagination/size/pagination-size.js +7 -0
  132. package/dist/pin-input/root/pin-input-root.d.ts +16 -0
  133. package/dist/pin-input/root/pin-input-root.js +19 -5
  134. package/dist/popover/root/popover-root.d.ts +19 -2
  135. package/dist/popover/root/popover-root.js +22 -1
  136. package/dist/progress/root/progress-root.d.ts +16 -1
  137. package/dist/progress/root/progress-root.js +31 -7
  138. package/dist/qr-code/root/qr-code-root.d.ts +19 -0
  139. package/dist/qr-code/root/qr-code-root.js +29 -1
  140. package/dist/radio/group/radio-group.d.ts +41 -0
  141. package/dist/radio/group/radio-group.js +50 -14
  142. package/dist/radio/root/radio-root.d.ts +8 -5
  143. package/dist/radio/root/radio-root.js +1 -2
  144. package/dist/rating/root/rating-root.d.ts +24 -1
  145. package/dist/rating/root/rating-root.js +24 -7
  146. package/dist/scatter-chart/root/scatter-chart-root.js +15 -7
  147. package/dist/select/root/select-root.d.ts +69 -3
  148. package/dist/select/root/select-root.js +92 -8
  149. package/dist/skeleton/root/skeleton-root.d.ts +14 -3
  150. package/dist/skeleton/root/skeleton-root.js +17 -3
  151. package/dist/skip-link/root/skip-link-root.d.ts +10 -0
  152. package/dist/skip-link/root/skip-link-root.js +15 -1
  153. package/dist/slider/root/slider-root.d.ts +20 -2
  154. package/dist/slider/root/slider-root.js +41 -3
  155. package/dist/sparkline/root/sparkline-root.d.ts +9 -10
  156. package/dist/speed-dial/item/speed-dial-item.d.ts +11 -5
  157. package/dist/speed-dial/item/speed-dial-item.js +7 -2
  158. package/dist/speed-dial/root/speed-dial-root.d.ts +15 -4
  159. package/dist/speed-dial/root/speed-dial-root.js +19 -5
  160. package/dist/splitter/root/splitter-root.d.ts +28 -6
  161. package/dist/splitter/root/splitter-root.js +35 -1
  162. package/dist/stat/root/stat-root.d.ts +7 -1
  163. package/dist/stat/root/stat-root.js +14 -1
  164. package/dist/steps/root/steps-root.js +1 -1
  165. package/dist/switch/root/switch-root.d.ts +2 -0
  166. package/dist/switch/root/switch-root.js +1 -0
  167. package/dist/table/cell/table-cell.d.ts +24 -4
  168. package/dist/table/cell/table-cell.js +21 -1
  169. package/dist/table/column/table-column.d.ts +32 -6
  170. package/dist/table/column/table-column.js +36 -6
  171. package/dist/table/root/table-root.d.ts +94 -3
  172. package/dist/table/root/table-root.js +128 -5
  173. package/dist/table/row/table-row.d.ts +7 -0
  174. package/dist/table/row/table-row.js +9 -1
  175. package/dist/tabs/root/tabs-root.d.ts +6 -1
  176. package/dist/tabs/root/tabs-root.js +6 -2
  177. package/dist/tag/root/tag-root.d.ts +23 -1
  178. package/dist/tag/root/tag-root.js +16 -2
  179. package/dist/textarea/root/textarea-root.d.ts +4 -0
  180. package/dist/textarea/root/textarea-root.js +1 -1
  181. package/dist/time-input/root/time-input-root.d.ts +28 -2
  182. package/dist/time-input/root/time-input-root.js +46 -10
  183. package/dist/time-picker/root/time-picker-root.d.ts +101 -18
  184. package/dist/time-picker/root/time-picker-root.js +115 -16
  185. package/dist/toast/root/toast-root.d.ts +64 -1
  186. package/dist/toast/root/toast-root.js +147 -2
  187. package/dist/toggle/group/toggle-group.d.ts +38 -1
  188. package/dist/toggle/group/toggle-group.js +34 -8
  189. package/dist/toggle/root/toggle-root.d.ts +14 -10
  190. package/dist/toggle/root/toggle-root.js +3 -3
  191. package/dist/toolbar/root/toolbar-root.d.ts +55 -15
  192. package/dist/toolbar/root/toolbar-root.js +99 -16
  193. package/dist/tooltip/root/tooltip-root.d.ts +37 -4
  194. package/dist/tooltip/root/tooltip-root.js +48 -0
  195. package/dist/tour/root/tour-root.d.ts +34 -5
  196. package/dist/tour/root/tour-root.js +51 -14
  197. package/dist/tour/stop/tour-stop.d.ts +18 -1
  198. package/dist/tour/stop/tour-stop.js +25 -5
  199. package/dist/tree/item/tree-item.d.ts +21 -5
  200. package/dist/tree/item/tree-item.js +14 -4
  201. package/dist/tree/root/tree-root.d.ts +29 -5
  202. package/dist/tree/root/tree-root.js +64 -8
  203. package/dist/trend/root/trend-root.d.ts +23 -1
  204. package/dist/trend/root/trend-root.js +28 -7
  205. package/dist/video/root/keys.d.ts +5 -0
  206. package/dist/video/root/keys.js +13 -1
  207. package/dist/video/root/video-root.d.ts +19 -0
  208. package/dist/video/root/video-root.js +48 -4
  209. package/dist/video-playlist/menu/video-playlist-menu.d.ts +20 -2
  210. package/dist/video-playlist/menu/video-playlist-menu.js +27 -5
  211. package/dist/video-playlist/root/video-playlist-root.js +6 -3
  212. package/dist/virtual-list/root/virtual-list-root.d.ts +52 -4
  213. package/dist/virtual-list/root/virtual-list-root.js +103 -21
  214. package/lint.json +1 -1
  215. package/package.json +5 -5
  216. package/types/jsx.d.ts +4348 -965
  217. package/types/vue.d.ts +972 -232
@@ -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 { CopyController, capturePointer, customElement, drawIcon, fillTemplate, formatColor, HelixFormElement, HelixSampleEndEvent, HelixSampleStartEvent, isRtl, MixinControllerValue, parseColor, splitValues, toCss, } from '@fusion.dev/helix-core';
7
+ import { CopyController, capturePointer, customElement, drawIcon, fillTemplate, formatColor, HelixFormElement, HelixSampleEndEvent, HelixSampleStartEvent, hostAria, 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';
@@ -39,6 +39,8 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
39
39
  this.valueLabel = 'Color';
40
40
  this.sampling = false;
41
41
  this.owned = false;
42
+ this.announcesInput = true;
43
+ this.unsettled = false;
42
44
  this.settled = '';
43
45
  this.handleValueInput = (event) => {
44
46
  event.stopPropagation();
@@ -57,16 +59,21 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
57
59
  if (this.readOnly) {
58
60
  return;
59
61
  }
62
+ const before = this.moved;
60
63
  this.moved = { ...this.color, ...next };
61
64
  const value = formatColor(this.moved, this.format ?? 'hex', this.alpha);
62
65
  this.owned = value !== this.value;
63
- this.requestValue(value);
66
+ if (!this.requestValue(value)) {
67
+ this.moved = before;
68
+ this.owned = false;
69
+ }
64
70
  };
65
71
  this.copier = new CopyController(this);
66
72
  this.handleSwatch = (preset) => {
67
73
  const parsed = parseColor(preset);
68
74
  if (parsed) {
69
75
  this.move(parsed);
76
+ this.settle();
70
77
  }
71
78
  };
72
79
  this.handleFormat = () => {
@@ -76,6 +83,7 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
76
83
  this.format = FORMATS[(FORMATS.indexOf(this.format ?? 'hex') + 1) % FORMATS.length] ?? 'hex';
77
84
  if (this.value !== '') {
78
85
  this.move({});
86
+ this.settle();
79
87
  }
80
88
  };
81
89
  this.handleEyeDropper = async () => {
@@ -92,6 +100,7 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
92
100
  const parsed = parseColor(sRGBHex);
93
101
  if (parsed) {
94
102
  this.move({ ...parsed, alpha: this.color.alpha });
103
+ this.settle();
95
104
  }
96
105
  }
97
106
  catch {
@@ -99,7 +108,14 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
99
108
  this.dispatchEvent(new HelixSampleEndEvent());
100
109
  };
101
110
  this.handleGridPointer = (event) => {
111
+ if (this.isDisabled) {
112
+ return;
113
+ }
102
114
  const grid = event.currentTarget;
115
+ if (event.type === 'pointerup' || event.type === 'pointercancel') {
116
+ this.settle();
117
+ return;
118
+ }
103
119
  if (event.type === 'pointerdown') {
104
120
  capturePointer(grid, event.pointerId);
105
121
  this.partNamed('grid-saturation')?.focus();
@@ -117,10 +133,39 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
117
133
  const down = Math.min(1, Math.max(0, (event.clientY - box.top) / box.height));
118
134
  this.move({ brightness: Math.round((1 - down) * 100), saturation: Math.round(across * 100) });
119
135
  };
136
+ this.handleAreaKeydown = (event) => {
137
+ if (this.isDisabled || this.readOnly) {
138
+ return;
139
+ }
140
+ const color = this.color;
141
+ const along = isRtl(this) ? -1 : 1;
142
+ const clamp = (at) => Math.min(100, Math.max(0, at));
143
+ const moves = {
144
+ ArrowDown: { brightness: clamp(color.brightness - 1) },
145
+ ArrowLeft: { saturation: clamp(color.saturation - along) },
146
+ ArrowRight: { saturation: clamp(color.saturation + along) },
147
+ ArrowUp: { brightness: clamp(color.brightness + 1) },
148
+ PageDown: { brightness: clamp(color.brightness - 10) },
149
+ PageUp: { brightness: clamp(color.brightness + 10) },
150
+ };
151
+ const next = moves[event.key];
152
+ if (!next) {
153
+ return;
154
+ }
155
+ event.preventDefault();
156
+ this.move(next);
157
+ this.settle();
158
+ };
120
159
  this.keepChannelRequest = (event) => {
121
160
  event.stopPropagation();
122
161
  };
123
162
  }
163
+ settle() {
164
+ if (this.unsettled) {
165
+ this.unsettled = false;
166
+ this.announceChange();
167
+ }
168
+ }
124
169
  get color() {
125
170
  return this.moved ?? parseColor(this.value) ?? parseColor(this.settled) ?? START;
126
171
  }
@@ -134,7 +179,12 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
134
179
  if (this.readOnly) {
135
180
  return false;
136
181
  }
137
- return super.requestValue(next);
182
+ const before = this.value;
183
+ const taken = super.requestValue(next);
184
+ if (taken && this.value !== before) {
185
+ this.unsettled = true;
186
+ }
187
+ return taken;
138
188
  }
139
189
  firstUpdated(changed) {
140
190
  super.firstUpdated(changed);
@@ -149,6 +199,10 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
149
199
  this.internals.setValidity({ valueMissing: true }, this.valueMissingMessage || 'Choose a color.', this.partNamed('grid') ?? undefined);
150
200
  return;
151
201
  }
202
+ if (this.value !== '' && parseColor(this.value) === null) {
203
+ 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);
204
+ return;
205
+ }
152
206
  this.internals.setValidity({});
153
207
  }
154
208
  updated(changed) {
@@ -183,7 +237,10 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
183
237
  .value=${String(value)}
184
238
  ?disabled=${this.isDisabled}
185
239
  @input=${(event) => this.takeChannel(channel, event)}
186
- @change=${(event) => this.takeChannel(channel, event)}
240
+ @change=${(event) => {
241
+ this.takeChannel(channel, event);
242
+ this.settle();
243
+ }}
187
244
  @helix-before-change=${this.keepChannelRequest}
188
245
  ></${this.tag('slider')}>`;
189
246
  }
@@ -211,6 +268,8 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
211
268
  willUpdate(changed) {
212
269
  super.willUpdate(changed);
213
270
  this.internals.ariaInvalid = this.invalid ? 'true' : null;
271
+ const outside = [...(this.internals.labels ?? [])];
272
+ hostAria(this.internals, { labelledBy: outside, role: outside.length > 0 ? 'group' : '' });
214
273
  if (!this.hydrating) {
215
274
  this.sampling = 'EyeDropper' in globalThis;
216
275
  }
@@ -221,7 +280,7 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
221
280
  ? html `<${this.tag('button')}
222
281
  part="eyedropper"
223
282
  exportparts="button: eyedropper-button, text: eyedropper-text"
224
- aria-label=${this.eyedropperLabel}
283
+ label=${this.eyedropperLabel}
225
284
  ?disabled=${this.isDisabled}
226
285
  @click=${this.handleEyeDropper}
227
286
  >
@@ -233,7 +292,7 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
233
292
  : html `<${this.tag('button')}
234
293
  part="format"
235
294
  exportparts="button: format-button, text: format-text"
236
- aria-label=${fillTemplate(this.formatLabel, { format: this.format ?? 'hex' })}
295
+ label=${fillTemplate(this.formatLabel, { format: this.format ?? 'hex' })}
237
296
  ?disabled=${this.isDisabled}
238
297
  @click=${this.handleFormat}
239
298
  >
@@ -244,11 +303,16 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
244
303
  render() {
245
304
  const color = this.color;
246
305
  const painted = toCss(color);
306
+ const both = `${this.saturationLabel} ${color.saturation}%, ${this.brightnessLabel} ${color.brightness}%`;
307
+ const reversed = `${this.brightnessLabel} ${color.brightness}%, ${this.saturationLabel} ${color.saturation}%`;
247
308
  return html `<div
248
309
  part="grid"
249
310
  style="--color-picker-hue: ${color.hue}; --color-picker-saturation: ${color.saturation}%; --color-picker-brightness: ${color.brightness}%"
250
311
  @pointerdown=${this.handleGridPointer}
251
312
  @pointermove=${this.handleGridPointer}
313
+ @pointerup=${this.handleGridPointer}
314
+ @pointercancel=${this.handleGridPointer}
315
+ @keydown=${this.handleAreaKeydown}
252
316
  >
253
317
  <input
254
318
  part="grid-saturation"
@@ -256,21 +320,27 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
256
320
  min="0"
257
321
  max="100"
258
322
  aria-label=${this.saturationLabel}
323
+ aria-valuetext=${both}
259
324
  aria-invalid=${this.invalid ? 'true' : nothing}
260
325
  .value=${String(color.saturation)}
261
326
  ?disabled=${this.isDisabled}
262
327
  @input=${(event) => this.takeArea('saturation', event)}
328
+ @change=${() => this.settle()}
263
329
  />
330
+ ${''}
264
331
  <input
265
332
  part="grid-brightness"
266
333
  type="range"
267
334
  min="0"
268
335
  max="100"
336
+ tabindex="-1"
269
337
  aria-label=${this.brightnessLabel}
338
+ aria-valuetext=${reversed}
270
339
  aria-invalid=${this.invalid ? 'true' : nothing}
271
340
  .value=${String(color.brightness)}
272
341
  ?disabled=${this.isDisabled}
273
342
  @input=${(event) => this.takeArea('brightness', event)}
343
+ @change=${() => this.settle()}
274
344
  />
275
345
  </div>
276
346
 
@@ -309,6 +379,10 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
309
379
  ?disabled=${this.isDisabled}
310
380
  ?readonly=${this.readOnly}
311
381
  @input=${this.handleValueInput}
382
+ @change=${(event) => {
383
+ event.stopPropagation();
384
+ this.settle();
385
+ }}
312
386
  />`}
313
387
  ${this.tools ? html `${this.renderTools()}` : nothing}
314
388
  </div>
@@ -337,6 +411,9 @@ __decorate([
337
411
  __decorate([
338
412
  property()
339
413
  ], HelixHeadlessColorPicker.prototype, "autocomplete", void 0);
414
+ __decorate([
415
+ property({ attribute: 'bad-input-message' })
416
+ ], HelixHeadlessColorPicker.prototype, "badInputMessage", void 0);
340
417
  __decorate([
341
418
  property({ attribute: 'brightness-label' })
342
419
  ], HelixHeadlessColorPicker.prototype, "brightnessLabel", void 0);
@@ -18,6 +18,10 @@ 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. Space, Home, End and letters edit the text, and Enter in
23
+ * a closed field is left to the form. Emptying the field and leaving it clears
24
+ * a single choice; Escape puts the chosen words back.
21
25
  *
22
26
  * With `multiple`, each chosen option is a tag in the field with its own remove
23
27
  * control. The panel stays open and the filter clears after each choice, so the
@@ -36,7 +40,10 @@ declare const HelixHeadlessCombobox_base: (new (...args: any[]) => import("@fusi
36
40
  *
37
41
  * @slot - The options.
38
42
  * @slot end - After the text, for a unit or a clear button.
43
+ * @slot feedback - The message that says what is wrong, for content richer than a string. It shows while there is a message.
44
+ * @slot hint - The hint, for content richer than plain text.
39
45
  * @slot indicator - Replaces the caret that shows the field opens a list.
46
+ * @slot label - The label, for content richer than plain text.
40
47
  * @slot start - Before the text, for an icon.
41
48
  *
42
49
  * @event {Event} change - Fired after the value changes.
@@ -46,10 +53,11 @@ declare const HelixHeadlessCombobox_base: (new (...args: any[]) => import("@fusi
46
53
  * @event {HelixCreateEvent} helix-create - Fired when the user adds a value that is not in the list. Cancelable.
47
54
  * @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
55
  * @event {Event} input - Fired after the value changes.
49
- * @event {Event} toggle - Fired when the panel opens or closes, with `newState` and `oldState`.
56
+ * @event {ToggleEvent} toggle - Fired when the panel opens or closes, with `newState` and `oldState`.
50
57
  *
51
58
  * @csspart control - The text field itself.
52
59
  * @csspart create - The row offering to add what was typed.
60
+ * @csspart create-active - The create row while the keyboard is on it. Set alongside `create`.
53
61
  * @csspart feedback - The message that explains what is wrong with the value.
54
62
  * @csspart field - The box around the text and its marks.
55
63
  * @csspart hint - Help text under the field, shown while there is no error.
@@ -96,7 +104,8 @@ export declare class HelixHeadlessCombobox extends HelixHeadlessCombobox_base {
96
104
  * The row appears while what is typed matches no option's words exactly, so
97
105
  * it is offered next to near misses too: a reader typing "Ruby on Rails" with
98
106
  * "Ruby" in the list wants the one they are typing, not the one they are
99
- * halfway through.
107
+ * halfway through. The arrow keys reach it after the last option, and Enter
108
+ * on it adds what was typed.
100
109
  */
101
110
  creatable: boolean;
102
111
  /**
@@ -146,6 +155,17 @@ export declare class HelixHeadlessCombobox extends HelixHeadlessCombobox_base {
146
155
  * Text shown while nothing has been chosen.
147
156
  */
148
157
  placeholder: string;
158
+ /**
159
+ * Whether the choice is locked. A read-only combobox still submits its value.
160
+ *
161
+ * The field can be read and focused, the list does not open, and the tags of
162
+ * a `multiple` combobox cannot be dismissed.
163
+ */
164
+ readOnly: boolean;
165
+ /** Requests a new value. While `readOnly` is set, nothing changes. */
166
+ requestValue(next: string): boolean;
167
+ /** Requests the list open or closed. While `readOnly` is set, it does not open. */
168
+ requestOpen(next: boolean): boolean;
149
169
  /**
150
170
  * The name of the control that removes one chosen option, with `{name}`
151
171
  * filled in.
@@ -180,6 +200,23 @@ export declare class HelixHeadlessCombobox extends HelixHeadlessCombobox_base {
180
200
  * what the reader is offered.
181
201
  */
182
202
  private suggestion;
203
+ /**
204
+ * Whether the reader has typed since the list opened, which decides what the
205
+ * field shows: their text while they type, and the chosen words otherwise.
206
+ */
207
+ private editing;
208
+ /** Whether the keyboard is on the create row rather than on an option. */
209
+ private onCreate;
210
+ /**
211
+ * Whether the reader emptied the field, so leaving it clears the choice.
212
+ *
213
+ * Escape takes it back, being a reader putting things as they were.
214
+ */
215
+ private emptied;
216
+ /** Where the highlight goes when an arrow opens the list. */
217
+ private opening;
218
+ /** Hears an option's words change, which no slot reports. See `Select`. */
219
+ private watcher;
183
220
  /**
184
221
  * Which option is chosen, as an index, or `-1` where none is.
185
222
  *
@@ -268,6 +305,25 @@ export declare class HelixHeadlessCombobox extends HelixHeadlessCombobox_base {
268
305
  */
269
306
  private drop;
270
307
  private close;
308
+ /**
309
+ * Clears a single choice whose words the reader deleted, as they leave.
310
+ *
311
+ * Measured before this: emptying the field and pressing Tab put the old
312
+ * choice back, so a combobox that was not required could not be emptied
313
+ * once answered.
314
+ */
315
+ private commitEmptied;
316
+ /** The options the arrows can reach. */
317
+ private get reachable();
318
+ /**
319
+ * Moves between the options and the create row, which sits after the last
320
+ * option, and returns whether the key was taken.
321
+ *
322
+ * The row is outside the list, so the list's own keys never reach it. While
323
+ * it is showing, a Down past the last option lands on it and an Up from the
324
+ * first one does, and either arrow from it goes back into the list.
325
+ */
326
+ private moveAroundCreate;
271
327
  private readonly handleInput;
272
328
  /**
273
329
  * The words of the first option the typing begins, or nothing.
@@ -286,6 +342,18 @@ export declare class HelixHeadlessCombobox extends HelixHeadlessCombobox_base {
286
342
  * the panel rather than about the options in it.
287
343
  */
288
344
  private readonly handleKeydown;
345
+ /**
346
+ * Enter in a closed field submits the form, as it does in a native text
347
+ * field.
348
+ *
349
+ * The field is in a shadow root and has no form owner, so the platform never
350
+ * runs implicit submission for it. On `keypress`, which a prevented
351
+ * `keydown` suppresses, so an Enter that chose an option or created one
352
+ * submits nothing.
353
+ */
354
+ private readonly handleKeypress;
355
+ /** @internal A single line of text counts against implicit submission. */
356
+ protected get blocksImplicitSubmission(): boolean;
289
357
  /**
290
358
  * Tells the input which option is highlighted.
291
359
  *
@@ -350,8 +418,19 @@ export declare class HelixHeadlessCombobox extends HelixHeadlessCombobox_base {
350
418
  * component: a form that received "jav" got the filter, not an option.
351
419
  */
352
420
  private sync;
421
+ connectedCallback(): void;
422
+ disconnectedCallback(): void;
423
+ protected willUpdate(changed: PropertyValues): void;
353
424
  protected firstUpdated(changed: PropertyValues): void;
354
425
  protected updated(changed: PropertyValues): void;
426
+ /**
427
+ * What the field shows: the typed text while the reader types, and the
428
+ * chosen words otherwise, open or closed.
429
+ *
430
+ * Measured before this: opening the list emptied the field, so a reader
431
+ * arrowing in to check the choice lost sight of it.
432
+ */
433
+ private get fieldText();
355
434
  /**
356
435
  * The list the field filters, behind a seam the styled tier can move.
357
436
  *
@@ -385,6 +464,15 @@ export declare class HelixHeadlessCombobox extends HelixHeadlessCombobox_base {
385
464
  * cannot change.
386
465
  */
387
466
  protected renderIndicator(): TemplateResult;
467
+ /**
468
+ * The row offering to add what was typed, after the list.
469
+ *
470
+ * Written out twice rather than bound through `part=${…}`: a part is read
471
+ * from the template as a literal, so a bound one is a `::part(create)` the
472
+ * checks cannot pair with its `@csspart`. The keyboard arriving swaps the
473
+ * element, and `linkActive` runs after the render that swaps it.
474
+ */
475
+ private renderCreate;
388
476
  protected render(): TemplateResult;
389
477
  }
390
478
  declare global {