@fusion.dev/helix-headless 0.142.0 → 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,18 +4,27 @@ 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
+ var HelixHeadlessCheckboxGroup_1;
7
8
  import { customElement, DisabledCascadeController, HelixBeforeChangeEvent, HelixFormElement, hostAria, MixinField, } from '@fusion.dev/helix-core';
8
9
  import { html } from 'lit';
9
10
  import { property } from 'lit/decorators.js';
10
11
  import { HelixHeadlessCheckbox } from '../../checkbox/root/checkbox-root.js';
11
- let HelixHeadlessCheckboxGroup = class HelixHeadlessCheckboxGroup extends MixinField(HelixFormElement) {
12
+ let HelixHeadlessCheckboxGroup = HelixHeadlessCheckboxGroup_1 = class HelixHeadlessCheckboxGroup extends MixinField(HelixFormElement) {
12
13
  constructor() {
13
14
  super(...arguments);
14
- this.value = '';
15
+ this.declared = '';
16
+ this.pending = false;
17
+ this.watched = new Set();
18
+ this.member = {
19
+ hostUpdated: () => {
20
+ if (this.isConnected && this.value !== this.judged) {
21
+ this.requestUpdate();
22
+ }
23
+ },
24
+ };
15
25
  this.cascade = new DisabledCascadeController(this, {
16
26
  items: () => this.boxes,
17
27
  });
18
- this.seeded = false;
19
28
  this.handleToggle = (event) => {
20
29
  const target = event.target;
21
30
  const changed = this.boxes.find((box) => box === target);
@@ -32,6 +41,7 @@ let HelixHeadlessCheckboxGroup = class HelixHeadlessCheckboxGroup extends MixinF
32
41
  .map((box) => box.value)
33
42
  .join(',');
34
43
  if (!this.dispatchEvent(new HelixBeforeChangeEvent({ value: next }))) {
44
+ event.preventDefault();
35
45
  return;
36
46
  }
37
47
  this.value = next;
@@ -39,30 +49,68 @@ let HelixHeadlessCheckboxGroup = class HelixHeadlessCheckboxGroup extends MixinF
39
49
  this.announceChange();
40
50
  };
41
51
  this.handleMemberNative = (event) => {
42
- if (event.target !== this) {
52
+ if (event.target instanceof HelixHeadlessCheckbox && this.holds(event.target)) {
43
53
  event.stopImmediatePropagation();
44
54
  }
45
55
  };
46
56
  }
57
+ get value() {
58
+ if (this.pending || !this.hasUpdated || !this.childrenKnown) {
59
+ return this.declared;
60
+ }
61
+ const boxes = this.boxes;
62
+ return boxes.length === 0
63
+ ? this.declared
64
+ : boxes
65
+ .filter((box) => box.checked)
66
+ .map((box) => box.value)
67
+ .join(',');
68
+ }
69
+ set value(next) {
70
+ const previous = this.declared;
71
+ this.declared = next;
72
+ this.pending = true;
73
+ this.requestUpdate('value', previous);
74
+ }
47
75
  get boxes() {
48
- return [...this.children].filter((child) => child instanceof HelixHeadlessCheckbox);
76
+ return [...this.querySelectorAll('*')].filter((element) => element instanceof HelixHeadlessCheckbox && this.holds(element));
77
+ }
78
+ holds(box) {
79
+ let parent = box.parentElement;
80
+ while (parent && parent !== this) {
81
+ if (parent instanceof HelixHeadlessCheckboxGroup_1) {
82
+ return false;
83
+ }
84
+ parent = parent.parentElement;
85
+ }
86
+ return parent === this;
49
87
  }
50
88
  sync() {
51
- const wanted = new Set(this.value
52
- .split(',')
53
- .map((entry) => entry.trim())
54
- .filter(Boolean));
55
- for (const box of this.boxes) {
89
+ const boxes = this.boxes;
90
+ for (const box of boxes) {
56
91
  if (this.name !== '' && box.name === '') {
57
92
  box.name = this.name;
58
93
  }
59
- box.checked = wanted.has(box.value);
94
+ if (!this.watched.has(box)) {
95
+ box.addController(this.member);
96
+ this.watched.add(box);
97
+ }
60
98
  }
61
- }
62
- seed() {
63
- const checked = this.boxes.filter((box) => box.checked).map((box) => box.value);
64
- if (checked.length > 0) {
65
- this.value = checked.join(',');
99
+ for (const box of this.watched) {
100
+ if (!boxes.includes(box)) {
101
+ this.unwatch(box);
102
+ }
103
+ }
104
+ if (!this.pending || boxes.length === 0) {
105
+ return;
106
+ }
107
+ this.pending = false;
108
+ const wanted = new Set(this.declared
109
+ .split(',')
110
+ .map((entry) => entry.trim())
111
+ .filter(Boolean));
112
+ for (const box of boxes) {
113
+ box.checked = wanted.has(box.value);
66
114
  }
67
115
  }
68
116
  connectedCallback() {
@@ -70,45 +118,45 @@ let HelixHeadlessCheckboxGroup = class HelixHeadlessCheckboxGroup extends MixinF
70
118
  this.addEventListener('helix-before-toggle', this.handleToggle);
71
119
  this.addEventListener('change', this.handleMemberNative);
72
120
  this.addEventListener('input', this.handleMemberNative);
121
+ this.observer = new MutationObserver(() => this.requestUpdate());
122
+ this.observer.observe(this, { childList: true, subtree: true });
73
123
  }
74
124
  disconnectedCallback() {
75
125
  super.disconnectedCallback();
76
126
  this.removeEventListener('helix-before-toggle', this.handleToggle);
77
127
  this.removeEventListener('change', this.handleMemberNative);
78
128
  this.removeEventListener('input', this.handleMemberNative);
129
+ this.observer?.disconnect();
130
+ this.observer = undefined;
131
+ for (const box of this.watched) {
132
+ this.unwatch(box);
133
+ }
134
+ }
135
+ unwatch(box) {
136
+ box.removeController(this.member);
137
+ this.watched.delete(box);
79
138
  }
80
139
  willUpdate(changed) {
81
140
  super.willUpdate(changed);
82
141
  hostAria(this.internals, { label: this.label, role: 'group' });
83
142
  this.internals.ariaRequired = this.required ? 'true' : null;
84
- if (!this.seeded && this.childrenKnown) {
85
- this.seeded = true;
86
- if (this.value === '') {
87
- this.seed();
88
- }
89
- }
90
- }
91
- firstUpdated(changed) {
92
- super.firstUpdated(changed);
93
- if (!this.seeded && this.children !== undefined) {
94
- this.seeded = true;
95
- if (this.value === '') {
96
- this.seed();
97
- }
98
- }
99
143
  }
100
144
  formResetCallback() {
101
145
  super.formResetCallback();
102
- this.value = this.getAttribute('value') ?? '';
103
- this.seeded = false;
146
+ const declared = this.getAttribute('value');
147
+ if (declared !== null) {
148
+ this.value = declared;
149
+ }
150
+ this.requestUpdate();
104
151
  }
105
152
  validate() {
106
- this.reportRequired(this.value === '', 'Choose at least one to continue.', 'items');
153
+ this.judged = this.value;
154
+ this.reportRequired(this.judged === '', 'Choose at least one to continue.', 'items');
107
155
  }
108
156
  updated(changed) {
109
157
  super.updated(changed);
110
- this.validate();
111
158
  this.sync();
159
+ this.validate();
112
160
  this.linkHost();
113
161
  }
114
162
  render() {
@@ -122,8 +170,8 @@ let HelixHeadlessCheckboxGroup = class HelixHeadlessCheckboxGroup extends MixinF
122
170
  };
123
171
  __decorate([
124
172
  property()
125
- ], HelixHeadlessCheckboxGroup.prototype, "value", void 0);
126
- HelixHeadlessCheckboxGroup = __decorate([
173
+ ], HelixHeadlessCheckboxGroup.prototype, "value", null);
174
+ HelixHeadlessCheckboxGroup = HelixHeadlessCheckboxGroup_1 = __decorate([
127
175
  customElement('helix-headless-checkbox-group')
128
176
  ], HelixHeadlessCheckboxGroup);
129
177
  export { HelixHeadlessCheckboxGroup };
@@ -15,7 +15,7 @@ import { type TemplateResult } from 'lit';
15
15
  * @since 0.1.0
16
16
  * @status stable
17
17
  * @category typography
18
- * @aliases Inline code, Kbd
18
+ * @aliases Inline code
19
19
  * @documentation https://fusion.dev/helix/components/code
20
20
  *
21
21
  * @slot - The code.
@@ -69,6 +69,14 @@ import '../../copy-button/index.js';
69
69
  * @csspart text - In a diff, a line's code.
70
70
  */
71
71
  export declare class HelixHeadlessCodeBlock extends HelixElement {
72
+ /**
73
+ * The copy button's name and tooltip text after a copy.
74
+ */
75
+ copiedLabel: string;
76
+ /**
77
+ * The copy button's name and tooltip text before a copy.
78
+ */
79
+ copyLabel: string;
72
80
  /**
73
81
  * Whether the content is a unified diff, drawn as the lines it changed.
74
82
  *
@@ -133,6 +141,17 @@ export declare class HelixHeadlessCodeBlock extends HelixElement {
133
141
  * server sent, which rendered it empty.
134
142
  */
135
143
  private get text();
144
+ /**
145
+ * Watches the code for edits that change no slot assignment.
146
+ *
147
+ * A framework updating one string child writes the text node's data in
148
+ * place, which React does, and that fires no `slotchange`. The block showed
149
+ * the new code while its button copied the old, and a diff edited that way
150
+ * was not redrawn.
151
+ */
152
+ private observer;
153
+ connectedCallback(): void;
154
+ disconnectedCallback(): void;
136
155
  protected firstUpdated(changed: PropertyValues): void;
137
156
  protected render(): TemplateResult;
138
157
  /**
@@ -13,6 +13,8 @@ import { pairLines, parsePatch } from '../patch.js';
13
13
  let HelixHeadlessCodeBlock = class HelixHeadlessCodeBlock extends HelixElement {
14
14
  constructor() {
15
15
  super(...arguments);
16
+ this.copiedLabel = 'Copied';
17
+ this.copyLabel = 'Copy code';
16
18
  this.diff = false;
17
19
  this.label = '';
18
20
  this.noCopy = false;
@@ -38,6 +40,17 @@ let HelixHeadlessCodeBlock = class HelixHeadlessCodeBlock extends HelixElement {
38
40
  .map((node) => node.textContent ?? '')
39
41
  .join('');
40
42
  }
43
+ connectedCallback() {
44
+ super.connectedCallback();
45
+ if (typeof MutationObserver !== 'undefined') {
46
+ this.observer ??= new MutationObserver(() => this.requestUpdate());
47
+ this.observer.observe(this, { characterData: true, childList: true, subtree: true });
48
+ }
49
+ }
50
+ disconnectedCallback() {
51
+ super.disconnectedCallback();
52
+ this.observer?.disconnect();
53
+ }
41
54
  firstUpdated(changed) {
42
55
  super.firstUpdated(changed);
43
56
  this.finishHydration();
@@ -69,7 +82,8 @@ let HelixHeadlessCodeBlock = class HelixHeadlessCodeBlock extends HelixElement {
69
82
  tooltip-arrow-left: copy-tooltip-arrow-left, tooltip-arrow-right: copy-tooltip-arrow-right,
70
83
  tooltip-arrow-top: copy-tooltip-arrow-top, tooltip-bottom: copy-tooltip-bottom,
71
84
  tooltip-left: copy-tooltip-left, tooltip-right: copy-tooltip-right, tooltip-top: copy-tooltip-top"
72
- label="Copy code"
85
+ copied-label=${this.copiedLabel}
86
+ label=${this.copyLabel}
73
87
  .value=${value}
74
88
  ></${this.tag('copy-button')}>`;
75
89
  }
@@ -121,6 +135,12 @@ let HelixHeadlessCodeBlock = class HelixHeadlessCodeBlock extends HelixElement {
121
135
  })}<slot hidden @slotchange=${() => this.requestUpdate()}></slot>`;
122
136
  }
123
137
  };
138
+ __decorate([
139
+ property({ attribute: 'copied-label' })
140
+ ], HelixHeadlessCodeBlock.prototype, "copiedLabel", void 0);
141
+ __decorate([
142
+ property({ attribute: 'copy-label' })
143
+ ], HelixHeadlessCodeBlock.prototype, "copyLabel", void 0);
124
144
  __decorate([
125
145
  property({ reflect: true, type: Boolean })
126
146
  ], HelixHeadlessCodeBlock.prototype, "diff", void 0);
@@ -23,6 +23,11 @@ declare const HelixHeadlessColorInput_base: (new (...args: any[]) => import("@fu
23
23
  * not survive a round trip through a formatter. Date Input does the same with
24
24
  * dates.
25
25
  *
26
+ * Typing sends `input` on each keystroke and `change` when you leave the
27
+ * field, as a text field does, so the message about a color it cannot read
28
+ * waits until you are done. Dragging in the panel sends `input` as the color
29
+ * moves and `change` when it settles.
30
+ *
26
31
  * The component sets `--color-input-swatch`, so do not set it yourself. It
27
32
  * holds the resolved color, so the styled tier can paint the swatch without
28
33
  * parsing the value.
@@ -44,7 +49,7 @@ declare const HelixHeadlessColorInput_base: (new (...args: any[]) => import("@fu
44
49
  * @event {HelixBeforeCloseEvent} helix-before-close - The panel is about to close. Cancelable: cancel it to keep it open.
45
50
  * @event {HelixBeforeOpenEvent} helix-before-open - The panel is about to open. Cancelable: cancel it to keep it closed.
46
51
  * @event {Event} input - Fired as the value changes.
47
- * @event {Event} toggle - The panel opened or closed. The event carries `newState` and `oldState`.
52
+ * @event {ToggleEvent} toggle - The panel opened or closed. The event carries `newState` and `oldState`.
48
53
  *
49
54
  * @csspart control - The text input that holds the value. Absent in the `swatch` variant.
50
55
  * @csspart feedback - The message that says what is wrong with the value.
@@ -125,6 +130,19 @@ export declare class HelixHeadlessColorInput extends HelixHeadlessColorInput_bas
125
130
  * The text the field shows before a color is entered.
126
131
  */
127
132
  placeholder: string;
133
+ /**
134
+ * Whether the color is locked. A read-only field still submits its value.
135
+ *
136
+ * The field can be read and copied from, and the panel does not open, as on
137
+ * Date Input and Time Input.
138
+ */
139
+ readOnly: boolean;
140
+ /** Typed, so a keystroke is announced as `input` alone. See `announcesInput`. */
141
+ protected readonly announcesInput = true;
142
+ /** Requests a new value. While `readOnly` is set, nothing changes. */
143
+ requestValue(next: string): boolean;
144
+ /** Requests the panel open or closed. While `readOnly` is set, it does not open. */
145
+ requestOpen(next: boolean): boolean;
128
146
  /**
129
147
  * Colors offered under the picker, as a comma-separated list.
130
148
  */
@@ -193,6 +211,13 @@ export declare class HelixHeadlessColorInput extends HelixHeadlessColorInput_bas
193
211
  * not mean.
194
212
  */
195
213
  private readonly handlePickerChange;
214
+ /**
215
+ * The picker's `change`, said under this element's name.
216
+ *
217
+ * The picker sends it when a drag, a key or a preset settles the color, so
218
+ * this field does too, and a drag is one `change` rather than one a frame.
219
+ */
220
+ private readonly handlePickerSettled;
196
221
  /**
197
222
  * The picker is about to take the pointer over, so the panel gets out of the
198
223
  * way and comes back after.
@@ -19,6 +19,8 @@ let HelixHeadlessColorInput = class HelixHeadlessColorInput extends MixinPickerF
19
19
  this.autocomplete = 'off';
20
20
  this.noFormat = false;
21
21
  this.placeholder = '#000000';
22
+ this.readOnly = false;
23
+ this.announcesInput = true;
22
24
  this.swatches = '';
23
25
  this.triggerLabel = 'Choose a color';
24
26
  this.settled = '';
@@ -32,9 +34,17 @@ let HelixHeadlessColorInput = class HelixHeadlessColorInput extends MixinPickerF
32
34
  if (event.composedPath()[0] !== event.currentTarget) {
33
35
  return;
34
36
  }
35
- this.requestValue(event.detail.value);
37
+ if (!this.requestValue(event.detail.value)) {
38
+ event.preventDefault();
39
+ }
36
40
  this.restore();
37
41
  };
42
+ this.handlePickerSettled = (event) => {
43
+ event.stopPropagation();
44
+ if (event.composedPath()[0] === event.currentTarget) {
45
+ this.announceChange();
46
+ }
47
+ };
38
48
  this.handleSampleStart = () => {
39
49
  this.requestOpen(false);
40
50
  };
@@ -42,6 +52,18 @@ let HelixHeadlessColorInput = class HelixHeadlessColorInput extends MixinPickerF
42
52
  this.requestOpen(true);
43
53
  };
44
54
  }
55
+ requestValue(next) {
56
+ if (this.readOnly) {
57
+ return false;
58
+ }
59
+ return super.requestValue(next);
60
+ }
61
+ requestOpen(next) {
62
+ if (next && this.readOnly) {
63
+ return false;
64
+ }
65
+ return super.requestOpen(next);
66
+ }
45
67
  get anchor() {
46
68
  return this.control ?? this.partNamed('trigger');
47
69
  }
@@ -99,7 +121,7 @@ let HelixHeadlessColorInput = class HelixHeadlessColorInput extends MixinPickerF
99
121
  swatches=${this.swatches || nothing}
100
122
  ?disabled=${this.isDisabled}
101
123
  @helix-before-change=${this.handlePickerChange}
102
- @change=${this.stopInner}
124
+ @change=${this.handlePickerSettled}
103
125
  @input=${this.stopInner}
104
126
  @helix-sample-start=${this.handleSampleStart}
105
127
  @helix-sample-end=${this.handleSampleEnd}
@@ -130,8 +152,11 @@ let HelixHeadlessColorInput = class HelixHeadlessColorInput extends MixinPickerF
130
152
  aria-describedby=${this.describedBy ?? nothing}
131
153
  aria-invalid=${this.invalidity ?? nothing}
132
154
  ?disabled=${this.isDisabled}
155
+ ?readonly=${this.readOnly}
133
156
  ?required=${this.required}
157
+ @change=${this.handleCommit}
134
158
  @input=${this.handleInput}
159
+ @keypress=${this.handleKeypress}
135
160
  />`}
136
161
  <slot name="end"></slot>
137
162
  <button
@@ -139,6 +164,7 @@ let HelixHeadlessColorInput = class HelixHeadlessColorInput extends MixinPickerF
139
164
  id=${this.variant === 'swatch' ? 'control' : nothing}
140
165
  type="button"
141
166
  aria-controls="surface"
167
+ aria-disabled=${this.readOnly ? 'true' : nothing}
142
168
  aria-expanded=${this.open ? 'true' : 'false'}
143
169
  aria-haspopup="dialog"
144
170
  aria-label=${this.variant === 'swatch' ? nothing : this.triggerLabel}
@@ -148,7 +174,7 @@ let HelixHeadlessColorInput = class HelixHeadlessColorInput extends MixinPickerF
148
174
  : 'swatch-value'
149
175
  : nothing}
150
176
  ?disabled=${this.isDisabled}
151
- @click=${() => this.toggleOpen()}
177
+ @click=${this.handleTriggerClick}
152
178
  >
153
179
  <span
154
180
  part="preview"
@@ -190,6 +216,9 @@ __decorate([
190
216
  __decorate([
191
217
  property()
192
218
  ], HelixHeadlessColorInput.prototype, "placeholder", void 0);
219
+ __decorate([
220
+ property({ attribute: 'readonly', reflect: true, type: Boolean })
221
+ ], HelixHeadlessColorInput.prototype, "readOnly", void 0);
193
222
  __decorate([
194
223
  property()
195
224
  ], HelixHeadlessColorInput.prototype, "swatches", void 0);
@@ -21,6 +21,12 @@ declare const HelixHeadlessColorPicker_base: (new (...args: any[]) => import("@f
21
21
  * hue or saturation, so a model read back from the value would turn red into
22
22
  * gray after you drag to the bottom of the square and back.
23
23
  *
24
+ * The square is one tab stop. In it, the up and down arrows move brightness
25
+ * and the left and right arrows move saturation, and PageUp and PageDown move
26
+ * brightness by ten. The picker sends `input` as the color moves and `change`
27
+ * when a drag, a key, a typed value or a preset settles it, as
28
+ * `<input type="color">` does.
29
+ *
24
30
  * @since 0.1.0
25
31
  * @status stable
26
32
  * @category forms
@@ -89,6 +95,10 @@ export declare class HelixHeadlessColorPicker extends HelixHeadlessColorPicker_b
89
95
  * ramps. A consumer who wants autofill can still ask.
90
96
  */
91
97
  autocomplete: string;
98
+ /**
99
+ * The message shown when the value is text that is not a color.
100
+ */
101
+ badInputMessage?: string;
92
102
  /**
93
103
  * What the square's vertical ramp is called.
94
104
  *
@@ -210,13 +220,11 @@ export declare class HelixHeadlessColorPicker extends HelixHeadlessColorPicker_b
210
220
  * would give one control two of each. What is left is the validity call and
211
221
  * the anchor the browser points its bubble at.
212
222
  *
213
- * **Emptiness is the only fault reported, and bad input deliberately is
214
- * not.** The value row is typed into a character at a time and every
215
- * keystroke reaches `requestValue`, so `#0`, `#00` and `#00f` would each be a
216
- * reported fault on the way to `#00ff00`. Date Picker and Time Picker can
217
- * report bad input because their value moves only on a commit. Color Input
218
- * reports it for this family instead, once, against the field the reader
219
- * typed into.
223
+ * **Text that is not a color is bad input**, so a form does not submit
224
+ * `#00` from a half-typed value. The picker draws no message of its own, so
225
+ * reporting it as each keystroke arrives shows nothing until the form asks;
226
+ * Color Input shows its own message against the field the reader typed
227
+ * into.
220
228
  */
221
229
  required: boolean;
222
230
  /**
@@ -268,6 +276,18 @@ export declare class HelixHeadlessColorPicker extends HelixHeadlessColorPicker_b
268
276
  * which reads back as hue 0 and saturation 0, and the next drag starts gray.
269
277
  */
270
278
  private owned;
279
+ /** Dragged and keyed, so a move is announced as `input` alone. See `announcesInput`. */
280
+ protected readonly announcesInput = true;
281
+ /** Whether the value has moved since `change` was last sent. */
282
+ private unsettled;
283
+ /**
284
+ * Sends `change` for a value that has settled, where it moved.
285
+ *
286
+ * Measured before this: a six-step drag sent six `change` events, so a
287
+ * consumer saving on `change`, as they would for `<input type="color">`,
288
+ * saved on every frame.
289
+ */
290
+ private settle;
271
291
  /** The current color: the last one moved to, the value, or the start color. */
272
292
  get color(): Color;
273
293
  /**
@@ -365,6 +385,16 @@ export declare class HelixHeadlessColorPicker extends HelixHeadlessColorPicker_b
365
385
  * `required`.
366
386
  */
367
387
  private sync;
388
+ /**
389
+ * Moves the square from the keyboard, both axes from either of its inputs.
390
+ *
391
+ * The square is two native ranges, and a native range maps every arrow to
392
+ * its own one axis: on the saturation input, ArrowUp moved the handle
393
+ * sideways. Here the vertical keys move brightness and the horizontal keys
394
+ * move saturation, turned on a right-to-left page as the pointer is, which is
395
+ * what React Aria's ColorArea does.
396
+ */
397
+ private readonly handleAreaKeydown;
368
398
  /**
369
399
  * Reports "required and empty", or clears it.
370
400
  *