@fusion.dev/helix-headless 0.148.0 → 0.149.1

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 (240) hide show
  1. package/custom-elements.json +6966 -1798
  2. package/dist/announcement/root/announcement-root.d.ts +5 -0
  3. package/dist/announcement/root/announcement-root.js +5 -2
  4. package/dist/area-chart/root/area-chart-root.d.ts +11 -0
  5. package/dist/area-chart/root/area-chart-root.js +20 -7
  6. package/dist/avatar/group/avatar-group.d.ts +10 -2
  7. package/dist/avatar/group/avatar-group.js +10 -5
  8. package/dist/badge/count.d.ts +6 -1
  9. package/dist/badge/count.js +3 -3
  10. package/dist/badge/root/badge-root.d.ts +6 -2
  11. package/dist/badge/root/badge-root.js +3 -3
  12. package/dist/bar-chart/root/bar-chart-root.d.ts +13 -1
  13. package/dist/bar-chart/root/bar-chart-root.js +17 -4
  14. package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +8 -1
  15. package/dist/breadcrumbs/root/breadcrumbs-root.js +5 -2
  16. package/dist/button/root/button-root.d.ts +10 -1
  17. package/dist/button/root/button-root.js +3 -2
  18. package/dist/button-group/root/button-group-root.d.ts +3 -0
  19. package/dist/button-group/root/button-group-root.js +2 -2
  20. package/dist/callout/root/callout-root.d.ts +16 -2
  21. package/dist/callout/root/callout-root.js +16 -4
  22. package/dist/canvas/describe.d.ts +10 -0
  23. package/dist/canvas/describe.js +9 -0
  24. package/dist/canvas/neighbor.d.ts +17 -0
  25. package/dist/canvas/neighbor.js +1 -0
  26. package/dist/canvas/node/canvas-node.js +3 -2
  27. package/dist/canvas/root/canvas-root.d.ts +65 -8
  28. package/dist/canvas/root/canvas-root.js +115 -49
  29. package/dist/carousel/root/carousel-root.d.ts +5 -0
  30. package/dist/carousel/root/carousel-root.js +16 -5
  31. package/dist/chat/composer/chat-composer.d.ts +5 -0
  32. package/dist/chat/composer/chat-composer.js +4 -1
  33. package/dist/chat/message/chat-message.d.ts +9 -5
  34. package/dist/chat/message/chat-message.js +8 -4
  35. package/dist/chat/naming.js +2 -2
  36. package/dist/chat/root/chat-root.d.ts +27 -1
  37. package/dist/chat/root/chat-root.js +37 -9
  38. package/dist/checkbox/root/checkbox-root.d.ts +11 -0
  39. package/dist/checkbox/root/checkbox-root.js +8 -2
  40. package/dist/checkbox-group/root/checkbox-group-root.d.ts +11 -0
  41. package/dist/checkbox-group/root/checkbox-group-root.js +11 -3
  42. package/dist/code-block/root/code-block-root.d.ts +12 -2
  43. package/dist/code-block/root/code-block-root.js +12 -2
  44. package/dist/color-input/root/color-input-root.d.ts +13 -0
  45. package/dist/color-input/root/color-input-root.js +18 -5
  46. package/dist/color-picker/root/color-picker-root.d.ts +19 -3
  47. package/dist/color-picker/root/color-picker-root.js +47 -13
  48. package/dist/combobox/root/combobox-root.d.ts +36 -7
  49. package/dist/combobox/root/combobox-root.js +37 -12
  50. package/dist/command/root/command-root.d.ts +15 -6
  51. package/dist/command/root/command-root.js +9 -4
  52. package/dist/copy-button/root/copy-button-root.d.ts +5 -0
  53. package/dist/copy-button/root/copy-button-root.js +7 -2
  54. package/dist/data-table/root/data-table-root.d.ts +171 -29
  55. package/dist/data-table/root/data-table-root.js +268 -118
  56. package/dist/date-input/root/date-input-root.d.ts +32 -9
  57. package/dist/date-input/root/date-input-root.js +66 -44
  58. package/dist/date-picker/root/date-picker-root.d.ts +38 -15
  59. package/dist/date-picker/root/date-picker-root.js +52 -33
  60. package/dist/dialog/root/dialog-root.d.ts +12 -1
  61. package/dist/dialog/root/dialog-root.js +11 -4
  62. package/dist/donut-chart/root/donut-chart-root.d.ts +5 -0
  63. package/dist/donut-chart/root/donut-chart-root.js +8 -5
  64. package/dist/drawer/root/drawer-root.d.ts +12 -1
  65. package/dist/drawer/root/drawer-root.js +9 -2
  66. package/dist/drilldown/root/drilldown-root.d.ts +5 -0
  67. package/dist/drilldown/root/drilldown-root.js +4 -1
  68. package/dist/element-events.generated.js +25 -3
  69. package/dist/file-input/root/file-input-root.d.ts +18 -3
  70. package/dist/file-input/root/file-input-root.js +34 -17
  71. package/dist/filter-input/chip/filter-chip.d.ts +13 -0
  72. package/dist/filter-input/chip/filter-chip.js +6 -1
  73. package/dist/filter-input/menu/filter-menu.d.ts +5 -0
  74. package/dist/filter-input/menu/filter-menu.js +3 -1
  75. package/dist/filter-input/root/filter-input-root.d.ts +20 -3
  76. package/dist/filter-input/root/filter-input-root.js +8 -4
  77. package/dist/format-date/root/format-date-root.d.ts +20 -2
  78. package/dist/format-date/root/format-date-root.js +5 -2
  79. package/dist/graph/root/graph-model.d.ts +11 -0
  80. package/dist/graph/root/graph-model.js +4 -0
  81. package/dist/graph/root/graph-root.d.ts +78 -9
  82. package/dist/graph/root/graph-root.js +124 -27
  83. package/dist/heatmap/root/heatmap-root.d.ts +25 -4
  84. package/dist/heatmap/root/heatmap-root.js +27 -7
  85. package/dist/icon-button/root/icon-button-root.d.ts +5 -0
  86. package/dist/icon-button/root/icon-button-root.js +1 -0
  87. package/dist/input/root/input-root.d.ts +5 -0
  88. package/dist/input/root/input-root.js +4 -1
  89. package/dist/lightbox/root/lightbox-root.d.ts +14 -4
  90. package/dist/lightbox/root/lightbox-root.js +25 -7
  91. package/dist/line-chart/root/line-chart-root.d.ts +5 -0
  92. package/dist/line-chart/root/line-chart-root.js +4 -2
  93. package/dist/list/item/list-item.d.ts +32 -0
  94. package/dist/list/item/list-item.js +34 -7
  95. package/dist/list/root/list-root.d.ts +87 -0
  96. package/dist/list/root/list-root.js +112 -2
  97. package/dist/listbox/reorder/index.d.ts +1 -0
  98. package/dist/listbox/reorder/index.js +4 -0
  99. package/dist/listbox/reorder/listbox-reorder.d.ts +83 -0
  100. package/dist/listbox/reorder/listbox-reorder.js +151 -0
  101. package/dist/listbox/root/listbox-root.d.ts +68 -11
  102. package/dist/listbox/root/listbox-root.js +41 -9
  103. package/dist/loader/root/loader-root.d.ts +5 -0
  104. package/dist/loader/root/loader-root.js +3 -1
  105. package/dist/map/area/map-area.d.ts +5 -0
  106. package/dist/map/area/map-area.js +3 -1
  107. package/dist/map/buildings/map-buildings.d.ts +5 -0
  108. package/dist/map/buildings/map-buildings.js +3 -1
  109. package/dist/map/contours/map-contours.d.ts +5 -0
  110. package/dist/map/contours/map-contours.js +3 -1
  111. package/dist/map/landcover/map-landcover.d.ts +5 -0
  112. package/dist/map/landcover/map-landcover.js +3 -1
  113. package/dist/map/marker/map-marker.d.ts +16 -1
  114. package/dist/map/marker/map-marker.js +13 -5
  115. package/dist/map/points/map-points.d.ts +5 -0
  116. package/dist/map/points/map-points.js +6 -4
  117. package/dist/map/position/map-position.d.ts +5 -0
  118. package/dist/map/position/map-position.js +3 -1
  119. package/dist/map/raster/map-raster.d.ts +5 -0
  120. package/dist/map/raster/map-raster.js +3 -1
  121. package/dist/map/root/map-root.d.ts +33 -14
  122. package/dist/map/root/map-root.js +59 -22
  123. package/dist/map/route/map-route.d.ts +5 -0
  124. package/dist/map/route/map-route.js +3 -1
  125. package/dist/map/terrain/map-terrain.d.ts +5 -0
  126. package/dist/map/terrain/map-terrain.js +3 -1
  127. package/dist/menu/root/menu-root.d.ts +5 -0
  128. package/dist/menu/root/menu-root.js +3 -1
  129. package/dist/meter/root/meter-root.d.ts +16 -3
  130. package/dist/meter/root/meter-root.js +12 -5
  131. package/dist/navigation/root/navigation-root.d.ts +5 -0
  132. package/dist/navigation/root/navigation-root.js +3 -1
  133. package/dist/notifications/notification/notification.d.ts +5 -0
  134. package/dist/notifications/notification/notification.js +3 -1
  135. package/dist/notifications/root/notifications-root.d.ts +8 -0
  136. package/dist/notifications/root/notifications-root.js +10 -2
  137. package/dist/number-input/root/number-input-root.d.ts +21 -8
  138. package/dist/number-input/root/number-input-root.js +26 -11
  139. package/dist/object-inspector/root/object-inspector-root.d.ts +51 -12
  140. package/dist/object-inspector/root/object-inspector-root.js +21 -20
  141. package/dist/outline/root/outline-root.d.ts +5 -0
  142. package/dist/outline/root/outline-root.js +3 -1
  143. package/dist/pagination/root/pagination-root.d.ts +7 -1
  144. package/dist/pagination/root/pagination-root.js +16 -7
  145. package/dist/pagination/size/pagination-size.d.ts +7 -3
  146. package/dist/pagination/size/pagination-size.js +4 -2
  147. package/dist/pagination/summary/pagination-summary.d.ts +8 -6
  148. package/dist/pagination/summary/pagination-summary.js +4 -9
  149. package/dist/pin-input/code.d.ts +6 -6
  150. package/dist/pin-input/code.js +1 -5
  151. package/dist/pin-input/root/pin-input-root.d.ts +9 -3
  152. package/dist/pin-input/root/pin-input-root.js +6 -2
  153. package/dist/popover/root/popover-root.d.ts +12 -2
  154. package/dist/popover/root/popover-root.js +10 -4
  155. package/dist/progress/root/progress-root.d.ts +7 -2
  156. package/dist/progress/root/progress-root.js +5 -2
  157. package/dist/qr-code/name.d.ts +3 -2
  158. package/dist/qr-code/name.js +2 -2
  159. package/dist/qr-code/root/qr-code-root.d.ts +12 -2
  160. package/dist/qr-code/root/qr-code-root.js +9 -2
  161. package/dist/radio/group/radio-group.d.ts +11 -0
  162. package/dist/radio/group/radio-group.js +8 -2
  163. package/dist/rating/root/rating-root.d.ts +12 -1
  164. package/dist/rating/root/rating-root.js +10 -3
  165. package/dist/scatter-chart/root/scatter-chart-root.d.ts +20 -2
  166. package/dist/scatter-chart/root/scatter-chart-root.js +20 -5
  167. package/dist/select/root/select-root.d.ts +11 -0
  168. package/dist/select/root/select-root.js +13 -3
  169. package/dist/skip-link/root/skip-link-root.d.ts +5 -0
  170. package/dist/skip-link/root/skip-link-root.js +3 -1
  171. package/dist/slider/root/slider-root.d.ts +7 -2
  172. package/dist/slider/root/slider-root.js +11 -5
  173. package/dist/sparkline/readings.d.ts +15 -5
  174. package/dist/sparkline/readings.js +3 -3
  175. package/dist/sparkline/root/sparkline-root.d.ts +9 -4
  176. package/dist/sparkline/root/sparkline-root.js +9 -3
  177. package/dist/speed-dial/root/speed-dial-root.d.ts +5 -0
  178. package/dist/speed-dial/root/speed-dial-root.js +4 -1
  179. package/dist/splitter/root/splitter-root.d.ts +6 -1
  180. package/dist/splitter/root/splitter-root.js +9 -4
  181. package/dist/steps/root/steps-root.d.ts +9 -2
  182. package/dist/steps/root/steps-root.js +6 -3
  183. package/dist/steps/step/step.d.ts +12 -0
  184. package/dist/steps/step/step.js +11 -2
  185. package/dist/switch/root/switch-root.d.ts +11 -0
  186. package/dist/switch/root/switch-root.js +8 -2
  187. package/dist/table/column/table-column.d.ts +11 -4
  188. package/dist/table/column/table-column.js +15 -10
  189. package/dist/table/grid-controller.d.ts +8 -3
  190. package/dist/table/grid-controller.js +17 -11
  191. package/dist/table/root/table-root.d.ts +107 -5
  192. package/dist/table/root/table-root.js +122 -20
  193. package/dist/table/row/table-row.d.ts +42 -0
  194. package/dist/table/row/table-row.js +40 -1
  195. package/dist/tabs/root/tabs-root.d.ts +5 -0
  196. package/dist/tabs/root/tabs-root.js +3 -1
  197. package/dist/tag/group/tag-group.d.ts +5 -0
  198. package/dist/tag/group/tag-group.js +3 -1
  199. package/dist/tag/root/tag-root.d.ts +14 -1
  200. package/dist/tag/root/tag-root.js +11 -8
  201. package/dist/textarea/root/textarea-root.d.ts +5 -0
  202. package/dist/textarea/root/textarea-root.js +3 -1
  203. package/dist/time-input/root/time-input-root.d.ts +14 -7
  204. package/dist/time-input/root/time-input-root.js +43 -32
  205. package/dist/time-picker/root/time-picker-root.d.ts +15 -7
  206. package/dist/time-picker/root/time-picker-root.js +25 -12
  207. package/dist/toast/item/toast-item.d.ts +7 -0
  208. package/dist/toast/item/toast-item.js +1 -0
  209. package/dist/toast/root/toast-root.d.ts +9 -1
  210. package/dist/toast/root/toast-root.js +5 -4
  211. package/dist/toolbar/root/toolbar-root.d.ts +5 -0
  212. package/dist/toolbar/root/toolbar-root.js +5 -2
  213. package/dist/tooltip/root/tooltip-root.d.ts +27 -17
  214. package/dist/tour/root/tour-root.d.ts +8 -2
  215. package/dist/tour/root/tour-root.js +4 -2
  216. package/dist/tour/stop/tour-stop.d.ts +5 -0
  217. package/dist/tour/stop/tour-stop.js +6 -1
  218. package/dist/tree/grip.d.ts +5 -0
  219. package/dist/tree/grip.js +1 -0
  220. package/dist/tree/item/tree-item.d.ts +24 -0
  221. package/dist/tree/item/tree-item.js +27 -5
  222. package/dist/tree/root/tree-root.d.ts +66 -1
  223. package/dist/tree/root/tree-root.js +77 -5
  224. package/dist/trend/root/trend-root.d.ts +20 -4
  225. package/dist/trend/root/trend-root.js +20 -5
  226. package/dist/video/root/video-root.d.ts +12 -3
  227. package/dist/video/root/video-root.js +41 -14
  228. package/dist/video-playlist/menu/video-playlist-menu.d.ts +5 -0
  229. package/dist/video-playlist/menu/video-playlist-menu.js +3 -1
  230. package/dist/video-playlist/root/video-playlist-root.d.ts +5 -0
  231. package/dist/video-playlist/root/video-playlist-root.js +3 -1
  232. package/dist/virtual-list/root/virtual-list-root.d.ts +19 -3
  233. package/dist/virtual-list/root/virtual-list-root.js +5 -2
  234. package/lint.json +1 -1
  235. package/package.json +9 -8
  236. package/types/jsx.d.ts +4014 -1862
  237. package/types/vue.d.ts +1266 -624
  238. package/types/words.d.ts +3280 -0
  239. package/dist/toast/hotkey.d.ts +0 -22
  240. package/dist/toast/hotkey.js +0 -23
@@ -4,17 +4,20 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { customElement, fillTemplate, formatNumbers, HelixElement, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, MixinControllerActive, MixinViewport, scrollItemIntoView, scrollRoom, Typeahead, VirtualizeController, } from '@fusion.dev/helix-core';
7
+ import { auditName, customElement, formatWords, HelixElement, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, MixinControllerActive, MixinViewport, scrollItemIntoView, scrollRoom, Typeahead, VirtualizeController, words, wordsLocale, } from '@fusion.dev/helix-core';
8
8
  import { list, magnifyingGlass } from '@fusion.dev/helix-icons';
9
9
  import { html, nothing } from 'lit';
10
10
  import { property, state } from 'lit/decorators.js';
11
11
  import { repeat } from 'lit/directives/repeat.js';
12
12
  import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
13
- import { adjacencyOf, entriesOf, groupsOf, nameOf, sortedOf, within, withoutGroups, } from './graph-model.js';
13
+ import { adjacencyOf, cursorAfter, entriesOf, groupsOf, nameOf, sortedOf, within, withoutGroups, } from './graph-model.js';
14
14
  let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinControllerActive(HelixElement)) {
15
15
  constructor() {
16
16
  super(...arguments);
17
- this.countLabel = '{count} notes';
17
+ this.activateHintLabel = 'Press the graph to use it';
18
+ this.controlsLabel = 'Graph controls';
19
+ this.countLabel = '{count, plural, one {# note} other {# notes}}';
20
+ this.fallbackLabel = 'Graph';
18
21
  this.hiddenGroups = [];
19
22
  this.label = '';
20
23
  this.legend = false;
@@ -23,11 +26,20 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
23
26
  this.linkedFromLabel = 'Linked from {note}';
24
27
  this.links = [];
25
28
  this.linksToLabel = 'Links to {note}';
29
+ this.movedDownLabel = 'Moved down';
30
+ this.movedLeftLabel = 'Moved left';
31
+ this.movedRightLabel = 'Moved right';
32
+ this.movedUpLabel = 'Moved up';
26
33
  this.nodes = [];
27
34
  this.noPanel = false;
28
35
  this.notesLabel = 'Notes';
29
36
  this.searchLabel = 'Find a note';
30
37
  this.selectedLabel = 'Selected';
38
+ this.twoFingerHintLabel = 'Use two fingers to move the graph';
39
+ this.usingLabel = 'Using the graph. Press Escape to scroll the page again.';
40
+ this.wheelHintLabel = 'Use {key} and scroll to zoom the graph';
41
+ this.zoomedInLabel = 'Zoomed in';
42
+ this.zoomedOutLabel = 'Zoomed out';
31
43
  this.query = '';
32
44
  this.cursor = 0;
33
45
  this.panelOpen = false;
@@ -37,6 +49,7 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
37
49
  this.groups = [];
38
50
  this.whole = false;
39
51
  this.said = '';
52
+ this.countAsked = false;
40
53
  this.virtualize = new VirtualizeController(this, {
41
54
  container: () => this.partNamed('list'),
42
55
  count: () => this.entries.length,
@@ -99,6 +112,7 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
99
112
  this.query = event.target.value;
100
113
  };
101
114
  }
115
+ static { this.words = 'helix-graph'; }
102
116
  get shown() {
103
117
  return this.kept;
104
118
  }
@@ -121,6 +135,28 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
121
135
  signal(from, to, options = {}) {
122
136
  this.dispatchEvent(new HelixGraphSignalEvent({ from, to, tone: options.tone }));
123
137
  }
138
+ moved() {
139
+ const asked = this.asked;
140
+ this.asked = undefined;
141
+ const words = {
142
+ down: this.movedDownLabel,
143
+ in: this.zoomedInLabel,
144
+ left: this.movedLeftLabel,
145
+ out: this.zoomedOutLabel,
146
+ right: this.movedRightLabel,
147
+ up: this.movedUpLabel,
148
+ };
149
+ if (asked !== undefined) {
150
+ this.say(words[asked] ?? '');
151
+ }
152
+ }
153
+ say(words) {
154
+ this.said = words !== '' && words === this.said ? `${words}\u00a0` : words;
155
+ }
156
+ firstUpdated(changed) {
157
+ super.firstUpdated(changed);
158
+ auditName(this, () => null, 'Give it a `label` that says what the notes are, such as "Research notes".', () => this.label !== '');
159
+ }
124
160
  willUpdate(changed) {
125
161
  super.willUpdate(changed);
126
162
  this.toggleState('fullscreen', this.filled);
@@ -132,7 +168,7 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
132
168
  this.adjacency = adjacencyOf(this.links);
133
169
  }
134
170
  if (changed.has('nodes')) {
135
- this.sorted = sortedOf(this.nodes, this.closest?.('[lang]')?.getAttribute('lang') ?? '');
171
+ this.sorted = sortedOf(this.nodes, wordsLocale(this));
136
172
  }
137
173
  if (changed.has('nodes')) {
138
174
  this.groups = groupsOf(this.nodes);
@@ -146,12 +182,26 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
146
182
  this.toggleState('local', local !== undefined);
147
183
  }
148
184
  if (['nodes', 'links', 'active', 'depth', 'hiddenGroups', 'query'].some((name) => changed.has(name))) {
185
+ const was = this.entries[this.cursor]?.node.id;
149
186
  this.entries = entriesOf(this.sorted, this.adjacency, this.active, this.query, this.kept);
150
187
  this.toggleState('empty', this.entries.length === 0);
151
- this.cursor = 0;
152
188
  const list = this.partNamed('list');
153
- if (list) {
154
- list.scrollTop = 0;
189
+ if (['active', 'depth', 'hiddenGroups', 'query'].some((name) => changed.has(name)) ||
190
+ !this.hasUpdated) {
191
+ this.cursor = 0;
192
+ if (list) {
193
+ list.scrollTop = 0;
194
+ }
195
+ }
196
+ else {
197
+ this.cursor = cursorAfter(this.entries, was, this.cursor);
198
+ if (list && this.shadowRoot?.activeElement === list) {
199
+ void this.updateComplete.then(() => this.revealCursor());
200
+ }
201
+ }
202
+ if ((changed.has('query') && changed.get('query') !== undefined) || this.countAsked) {
203
+ this.countAsked = false;
204
+ this.say(this.countText());
155
205
  }
156
206
  }
157
207
  }
@@ -164,36 +214,23 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
164
214
  else if (changed.has('active') || changed.has('depth') || changed.has('hiddenGroups')) {
165
215
  this.dispatchEvent(new HelixGraphPartChangeEvent({ kind: 'focus' }));
166
216
  }
167
- if (changed.has('query') && changed.get('query') !== undefined) {
168
- this.said = this.countText();
169
- }
170
217
  }
171
218
  panEvent(detail) {
219
+ this.asked = this.sideOf(detail.to);
172
220
  return new HelixGraphPanEvent(detail);
173
221
  }
174
222
  zoomEvent(detail) {
223
+ this.asked = detail.by > 0 ? 'in' : detail.by < 0 ? 'out' : undefined;
175
224
  return new HelixGraphZoomEvent(detail);
176
225
  }
177
226
  get restingControls() {
178
227
  return 'zoom fullscreen';
179
228
  }
180
- get restingControlsLabel() {
181
- return 'Graph controls';
182
- }
183
229
  gesturesChanged() {
184
230
  this.dispatchEvent(new HelixGraphPartChangeEvent({ kind: 'gestures' }));
185
231
  }
186
- get restingGestureLabels() {
187
- return {
188
- activate: 'Press the graph to use it',
189
- twoFinger: 'Use two fingers to move the graph',
190
- using: 'Using the graph. Press Escape to scroll the page again.',
191
- wheel: 'Use {key} and scroll to zoom the graph',
192
- };
193
- }
194
232
  countText() {
195
- const lang = this.closest?.('[lang]')?.getAttribute('lang') ?? '';
196
- return fillTemplate(this.countLabel, { count: formatNumbers(lang)(this.entries.length) });
233
+ return formatWords(this, 'countLabel', { count: this.entries.length });
197
234
  }
198
235
  relationText(entry) {
199
236
  const selected = this.nodes.find((node) => node.id === this.active);
@@ -202,11 +239,11 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
202
239
  case 'selected':
203
240
  return this.selectedLabel;
204
241
  case 'to':
205
- return fillTemplate(this.linkedFromLabel, { note });
242
+ return formatWords(this, 'linkedFromLabel', { note });
206
243
  case 'from':
207
- return fillTemplate(this.linksToLabel, { note });
244
+ return formatWords(this, 'linksToLabel', { note });
208
245
  case 'both':
209
- return fillTemplate(this.linkedBothLabel, { note });
246
+ return formatWords(this, 'linkedBothLabel', { note });
210
247
  default:
211
248
  return '';
212
249
  }
@@ -217,6 +254,7 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
217
254
  : [...this.hiddenGroups, name];
218
255
  if (this.dispatchEvent(new HelixGraphFilterEvent({ hidden }))) {
219
256
  this.hiddenGroups = hidden;
257
+ this.countAsked = true;
220
258
  }
221
259
  }
222
260
  renderLegend() {
@@ -370,7 +408,7 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
370
408
  return html `<div
371
409
  part="region"
372
410
  role="group"
373
- aria-label=${this.label || this.getAttribute?.('aria-label') || 'Graph'}
411
+ aria-label=${this.label || this.getAttribute?.('aria-label') || this.fallbackLabel}
374
412
  tabindex="0"
375
413
  @focusin=${this.idle.stir}
376
414
  @keydown=${this.handleKeydown}
@@ -433,11 +471,24 @@ let HelixHeadlessGraph = class HelixHeadlessGraph extends MixinViewport(MixinCon
433
471
  }
434
472
  };
435
473
  __decorate([
474
+ words,
475
+ property({ attribute: 'activate-hint-label' })
476
+ ], HelixHeadlessGraph.prototype, "activateHintLabel", void 0);
477
+ __decorate([
478
+ words,
479
+ property({ attribute: 'controls-label' })
480
+ ], HelixHeadlessGraph.prototype, "controlsLabel", void 0);
481
+ __decorate([
482
+ words,
436
483
  property({ attribute: 'count-label' })
437
484
  ], HelixHeadlessGraph.prototype, "countLabel", void 0);
438
485
  __decorate([
439
486
  property({ type: Number })
440
487
  ], HelixHeadlessGraph.prototype, "depth", void 0);
488
+ __decorate([
489
+ words,
490
+ property({ attribute: 'fallback-label' })
491
+ ], HelixHeadlessGraph.prototype, "fallbackLabel", void 0);
441
492
  __decorate([
442
493
  property({ attribute: false })
443
494
  ], HelixHeadlessGraph.prototype, "hiddenGroups", void 0);
@@ -448,20 +499,40 @@ __decorate([
448
499
  property({ type: Boolean })
449
500
  ], HelixHeadlessGraph.prototype, "legend", void 0);
450
501
  __decorate([
502
+ words,
451
503
  property({ attribute: 'legend-label' })
452
504
  ], HelixHeadlessGraph.prototype, "legendLabel", void 0);
453
505
  __decorate([
506
+ words,
454
507
  property({ attribute: 'linked-both-label' })
455
508
  ], HelixHeadlessGraph.prototype, "linkedBothLabel", void 0);
456
509
  __decorate([
510
+ words,
457
511
  property({ attribute: 'linked-from-label' })
458
512
  ], HelixHeadlessGraph.prototype, "linkedFromLabel", void 0);
459
513
  __decorate([
460
514
  property({ attribute: false })
461
515
  ], HelixHeadlessGraph.prototype, "links", void 0);
462
516
  __decorate([
517
+ words,
463
518
  property({ attribute: 'links-to-label' })
464
519
  ], HelixHeadlessGraph.prototype, "linksToLabel", void 0);
520
+ __decorate([
521
+ words,
522
+ property({ attribute: 'moved-down-label' })
523
+ ], HelixHeadlessGraph.prototype, "movedDownLabel", void 0);
524
+ __decorate([
525
+ words,
526
+ property({ attribute: 'moved-left-label' })
527
+ ], HelixHeadlessGraph.prototype, "movedLeftLabel", void 0);
528
+ __decorate([
529
+ words,
530
+ property({ attribute: 'moved-right-label' })
531
+ ], HelixHeadlessGraph.prototype, "movedRightLabel", void 0);
532
+ __decorate([
533
+ words,
534
+ property({ attribute: 'moved-up-label' })
535
+ ], HelixHeadlessGraph.prototype, "movedUpLabel", void 0);
465
536
  __decorate([
466
537
  property({ attribute: false })
467
538
  ], HelixHeadlessGraph.prototype, "nodes", void 0);
@@ -469,14 +540,37 @@ __decorate([
469
540
  property({ attribute: 'no-panel', reflect: true, type: Boolean })
470
541
  ], HelixHeadlessGraph.prototype, "noPanel", void 0);
471
542
  __decorate([
543
+ words,
472
544
  property({ attribute: 'notes-label' })
473
545
  ], HelixHeadlessGraph.prototype, "notesLabel", void 0);
474
546
  __decorate([
547
+ words,
475
548
  property({ attribute: 'search-label' })
476
549
  ], HelixHeadlessGraph.prototype, "searchLabel", void 0);
477
550
  __decorate([
551
+ words,
478
552
  property({ attribute: 'selected-label' })
479
553
  ], HelixHeadlessGraph.prototype, "selectedLabel", void 0);
554
+ __decorate([
555
+ words,
556
+ property({ attribute: 'two-finger-hint-label' })
557
+ ], HelixHeadlessGraph.prototype, "twoFingerHintLabel", void 0);
558
+ __decorate([
559
+ words,
560
+ property({ attribute: 'using-label' })
561
+ ], HelixHeadlessGraph.prototype, "usingLabel", void 0);
562
+ __decorate([
563
+ words,
564
+ property({ attribute: 'wheel-hint-label' })
565
+ ], HelixHeadlessGraph.prototype, "wheelHintLabel", void 0);
566
+ __decorate([
567
+ words,
568
+ property({ attribute: 'zoomed-in-label' })
569
+ ], HelixHeadlessGraph.prototype, "zoomedInLabel", void 0);
570
+ __decorate([
571
+ words,
572
+ property({ attribute: 'zoomed-out-label' })
573
+ ], HelixHeadlessGraph.prototype, "zoomedOutLabel", void 0);
480
574
  __decorate([
481
575
  state()
482
576
  ], HelixHeadlessGraph.prototype, "query", void 0);
@@ -486,6 +580,9 @@ __decorate([
486
580
  __decorate([
487
581
  state()
488
582
  ], HelixHeadlessGraph.prototype, "panelOpen", void 0);
583
+ __decorate([
584
+ state()
585
+ ], HelixHeadlessGraph.prototype, "said", void 0);
489
586
  HelixHeadlessGraph = __decorate([
490
587
  customElement('helix-headless-graph')
491
588
  ], HelixHeadlessGraph);
@@ -110,7 +110,13 @@ declare const HelixHeadlessHeatmap_base: typeof HelixElement & (new (...args: an
110
110
  */
111
111
  export declare class HelixHeadlessHeatmap extends HelixHeadlessHeatmap_base {
112
112
  /**
113
- * The word the `overview` puts before the busiest reading.
113
+ * The key this family's words are registered under, its styled tag:
114
+ * `registerWords('de', { 'helix-heatmap': { emptyText: 'Keine Werte' } })`.
115
+ */
116
+ static words: string;
117
+ /**
118
+ * The name the `overview` gives the busiest reading, `{busiestLabel}` in
119
+ * `overview-label`.
114
120
  */
115
121
  busiestLabel: string;
116
122
  /**
@@ -145,6 +151,13 @@ export declare class HelixHeadlessHeatmap extends HelixHeadlessHeatmap_base {
145
151
  * container that cannot get narrow.
146
152
  */
147
153
  minCell: number;
154
+ /**
155
+ * The `overview`'s sentence. `{busiestLabel}` and `{totalLabel}` are
156
+ * `busiest-label` and `total-label`, `{busiest}` the busiest reading's name
157
+ * and its reading as the table writes it, and `{total}` the total of the
158
+ * readings drawn, written in the locale.
159
+ */
160
+ overviewLabel: string;
148
161
  /**
149
162
  * How many rows the strip has.
150
163
  *
@@ -162,8 +175,10 @@ export declare class HelixHeadlessHeatmap extends HelixHeadlessHeatmap_base {
162
175
  */
163
176
  selectedLabel: string;
164
177
  /**
165
- * What the `selection` part says after the selection changes, with `{count}` for
166
- * how many cells are selected.
178
+ * What the `selection` part says after the selection changes. `{count}` is
179
+ * how many cells are selected, written in the locale, and a language that
180
+ * needs plural forms writes them: `{count, plural, one {# wybrany} few
181
+ * {# wybrane} many {# wybranych} other {# wybranego}}`.
167
182
  */
168
183
  selectionLabel: string;
169
184
  /**
@@ -172,6 +187,11 @@ export declare class HelixHeadlessHeatmap extends HelixHeadlessHeatmap_base {
172
187
  * Absent selects nothing, and a press or Space does what it did.
173
188
  */
174
189
  selectionMode?: 'multiple' | 'single';
190
+ /**
191
+ * The strip's name where the chart has none: no `aria-label`, `label`, or
192
+ * table caption.
193
+ */
194
+ stripLabel: string;
175
195
  /**
176
196
  * Lower bounds for the tone buckets, in the order the tones are given.
177
197
  *
@@ -195,7 +215,8 @@ export declare class HelixHeadlessHeatmap extends HelixHeadlessHeatmap_base {
195
215
  */
196
216
  tones: string;
197
217
  /**
198
- * The word the `overview` puts before the total of the readings drawn.
218
+ * The name the `overview` gives the total of the readings drawn,
219
+ * `{totalLabel}` in `overview-label`.
199
220
  */
200
221
  totalLabel: string;
201
222
  /**
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { AriaForwardController, byRow, CHART_PLOT, commaList, customElement, drawTooltip, fillTemplate, formatNumbers, HelixElement, HelixResizeEvent, MixinChartSource, markRegion, pressedValue, rangeAdd, requestValue, StatusController, searchableById, writtenList, writtenNumbers, } from '@fusion.dev/helix-core';
7
+ import { AriaForwardController, byRow, CHART_PLOT, commaList, customElement, drawTooltip, formatWords, HelixElement, HelixResizeEvent, MixinChartSource, markRegion, pressedValue, rangeAdd, requestValue, StatusController, searchableById, words, writtenList, writtenNumbers, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property, state } from 'lit/decorators.js';
10
10
  import '../../tooltip/index.js';
@@ -16,9 +16,11 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
16
16
  this.emptyText = 'No readings';
17
17
  this.gap = 2;
18
18
  this.minCell = 8;
19
+ this.overviewLabel = '{busiestLabel}: {busiest}; {totalLabel} {total}.';
19
20
  this.rows = 1;
20
21
  this.selectedLabel = 'selected';
21
- this.selectionLabel = '{count} selected';
22
+ this.selectionLabel = '{count, plural, one {# selected} other {# selected}}';
23
+ this.stripLabel = 'Heatmap';
22
24
  this.thresholds = '';
23
25
  this.tones = '';
24
26
  this.totalLabel = 'Total';
@@ -73,6 +75,7 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
73
75
  }
74
76
  };
75
77
  }
78
+ static { this.words = 'helix-heatmap'; }
76
79
  get visible() {
77
80
  return Math.min(this.points.length, this.room);
78
81
  }
@@ -87,7 +90,7 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
87
90
  }
88
91
  requestValue(this, next, (value) => {
89
92
  this.value = value;
90
- this.status.say(fillTemplate(this.selectionLabel, { count: commaList(value).length }));
93
+ this.status.say(formatWords(this, 'selectionLabel', { count: commaList(value).length }));
91
94
  });
92
95
  }
93
96
  press(index) {
@@ -208,7 +211,7 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
208
211
  const chosen = new Set(this.selectionMode ? commaList(this.value) : []);
209
212
  return html `<div
210
213
  aria-describedby=${readable ? 'helix-chart-summary' : nothing}
211
- aria-label=${this.named || 'Heatmap'}
214
+ aria-label=${this.named || this.stripLabel}
212
215
  part="strip"
213
216
  id=${CHART_PLOT}
214
217
  role=${readable ? 'application' : 'img'}
@@ -254,9 +257,13 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
254
257
  const { busiest, total } = overviewOf(cells);
255
258
  const row = rows[offset + busiest];
256
259
  const text = row?.cells[column]?.text ?? '';
257
- const most = row ? `${this.busiestLabel}: ${row.label}${text === '' ? '' : `, ${text}`}` : '';
258
- const sum = `${this.totalLabel} ${formatNumbers(this.locale)(total)}`;
259
- return html `<p id="helix-chart-summary" part="overview">${most ? `${most}; ${sum}` : sum}.</p>`;
260
+ const said = formatWords(this, 'overviewLabel', {
261
+ busiest: text === '' ? (row?.label ?? '') : `${row?.label ?? ''}, ${text}`,
262
+ busiestLabel: this.busiestLabel,
263
+ total,
264
+ totalLabel: this.totalLabel,
265
+ });
266
+ return html `<p id="helix-chart-summary" part="overview">${said}</p>`;
260
267
  }
261
268
  renderTooltip() {
262
269
  const at = this.pointer.at;
@@ -293,9 +300,11 @@ let HelixHeadlessHeatmap = class HelixHeadlessHeatmap extends MixinChartSource(H
293
300
  }
294
301
  };
295
302
  __decorate([
303
+ words,
296
304
  property({ attribute: 'busiest-label' })
297
305
  ], HelixHeadlessHeatmap.prototype, "busiestLabel", void 0);
298
306
  __decorate([
307
+ words,
299
308
  property({ attribute: 'empty-text' })
300
309
  ], HelixHeadlessHeatmap.prototype, "emptyText", void 0);
301
310
  __decorate([
@@ -304,18 +313,28 @@ __decorate([
304
313
  __decorate([
305
314
  property({ attribute: 'min-cell', type: Number })
306
315
  ], HelixHeadlessHeatmap.prototype, "minCell", void 0);
316
+ __decorate([
317
+ words,
318
+ property({ attribute: 'overview-label' })
319
+ ], HelixHeadlessHeatmap.prototype, "overviewLabel", void 0);
307
320
  __decorate([
308
321
  property({ type: Number })
309
322
  ], HelixHeadlessHeatmap.prototype, "rows", void 0);
310
323
  __decorate([
324
+ words,
311
325
  property({ attribute: 'selected-label' })
312
326
  ], HelixHeadlessHeatmap.prototype, "selectedLabel", void 0);
313
327
  __decorate([
328
+ words,
314
329
  property({ attribute: 'selection-label' })
315
330
  ], HelixHeadlessHeatmap.prototype, "selectionLabel", void 0);
316
331
  __decorate([
317
332
  property({ attribute: 'selection-mode' })
318
333
  ], HelixHeadlessHeatmap.prototype, "selectionMode", void 0);
334
+ __decorate([
335
+ words,
336
+ property({ attribute: 'strip-label' })
337
+ ], HelixHeadlessHeatmap.prototype, "stripLabel", void 0);
319
338
  __decorate([
320
339
  property()
321
340
  ], HelixHeadlessHeatmap.prototype, "thresholds", void 0);
@@ -323,6 +342,7 @@ __decorate([
323
342
  property()
324
343
  ], HelixHeadlessHeatmap.prototype, "tones", void 0);
325
344
  __decorate([
345
+ words,
326
346
  property({ attribute: 'total-label' })
327
347
  ], HelixHeadlessHeatmap.prototype, "totalLabel", void 0);
328
348
  __decorate([
@@ -30,6 +30,11 @@ import { HelixHeadlessButton } from '../../button/root/button-root.js';
30
30
  * @csspart button - The inner button.
31
31
  */
32
32
  export declare class HelixHeadlessIconButton extends HelixHeadlessButton {
33
+ /**
34
+ * The key this family's words are registered under, its styled tag:
35
+ * `registerWords('de', { 'helix-icon-button': { pendingLabel: 'Wird geladen' } })`.
36
+ */
37
+ static words: string;
33
38
  }
34
39
  declare global {
35
40
  interface HTMLElementTagNameMap {
@@ -7,6 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  import { customElement } from '@fusion.dev/helix-core';
8
8
  import { HelixHeadlessButton } from '../../button/root/button-root.js';
9
9
  let HelixHeadlessIconButton = class HelixHeadlessIconButton extends HelixHeadlessButton {
10
+ static { this.words = 'helix-icon-button'; }
10
11
  };
11
12
  HelixHeadlessIconButton = __decorate([
12
13
  customElement('helix-headless-icon-button')
@@ -69,6 +69,11 @@ declare const HelixHeadlessInput_base: (new (...args: any[]) => import("@fusion.
69
69
  * @cssstate invalid - The control has an error to show, from the browser's validation, `validate`, or your `feedback`.
70
70
  */
71
71
  export declare class HelixHeadlessInput extends HelixHeadlessInput_base {
72
+ /**
73
+ * The key this family's words are registered under, its styled tag:
74
+ * `registerWords('de', { 'helix-input': { clearLabel: 'Leeren' } })`.
75
+ */
76
+ static words: string;
72
77
  protected readonly aria: AriaForwardController;
73
78
  /** Typed or dragged, so every edit is announced. See `announcesInput`. */
74
79
  protected readonly announcesInput = true;
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { AriaForwardController, applyOwnRule, customElement, drawIcon, HelixClearEvent, HelixFormElement, holdCaret, MixinControllerValue, MixinField, restoreValue, submitImplicitly, } from '@fusion.dev/helix-core';
7
+ import { AriaForwardController, applyOwnRule, customElement, drawIcon, HelixClearEvent, HelixFormElement, holdCaret, MixinControllerValue, MixinField, restoreValue, submitImplicitly, words, } from '@fusion.dev/helix-core';
8
8
  import { eye, eyeSlash, x } from '@fusion.dev/helix-icons';
9
9
  import { html, nothing } from 'lit';
10
10
  import { property, state } from 'lit/decorators.js';
@@ -59,6 +59,7 @@ let HelixHeadlessInput = class HelixHeadlessInput extends MixinControllerValue(M
59
59
  this.step = '';
60
60
  this.type = 'text';
61
61
  }
62
+ static { this.words = 'helix-input'; }
62
63
  get effectiveType() {
63
64
  return this.revealed && this.type === 'password' ? 'text' : this.type;
64
65
  }
@@ -234,6 +235,7 @@ __decorate([
234
235
  property({ type: Boolean })
235
236
  ], HelixHeadlessInput.prototype, "clearable", void 0);
236
237
  __decorate([
238
+ words,
237
239
  property({ attribute: 'clear-label' })
238
240
  ], HelixHeadlessInput.prototype, "clearLabel", void 0);
239
241
  __decorate([
@@ -270,6 +272,7 @@ __decorate([
270
272
  state()
271
273
  ], HelixHeadlessInput.prototype, "revealed", void 0);
272
274
  __decorate([
275
+ words,
273
276
  property({ attribute: 'reveal-label' })
274
277
  ], HelixHeadlessInput.prototype, "revealLabel", void 0);
275
278
  __decorate([
@@ -97,6 +97,11 @@ declare const HelixHeadlessLightbox_base: (new (...args: any[]) => import("@fusi
97
97
  * @cssstate zoomed - While the shown item is zoomed past its own size.
98
98
  */
99
99
  export declare class HelixHeadlessLightbox extends HelixHeadlessLightbox_base {
100
+ /**
101
+ * The key this family's words are registered under, its styled tag:
102
+ * `registerWords('de', { 'helix-lightbox': { nextLabel: 'Weiter' } })`.
103
+ */
104
+ static words: string;
100
105
  /**
101
106
  * Draws the viewer's own previous, next and close controls over the picture,
102
107
  * and zoom-out and zoom-in controls where `max-zoom` allows zooming.
@@ -120,6 +125,8 @@ export declare class HelixHeadlessLightbox extends HelixHeadlessLightbox_base {
120
125
  * interface.
121
126
  */
122
127
  dismissLabel: string;
128
+ /** The viewer's name where `label` is empty. */
129
+ fallbackLabel: string;
123
130
  /**
124
131
  * How long the user can be idle before the header and footer hide, in
125
132
  * milliseconds.
@@ -152,7 +159,7 @@ export declare class HelixHeadlessLightbox extends HelixHeadlessLightbox_base {
152
159
  previousLabel: string;
153
160
  /**
154
161
  * The name of an item with no `label` of its own, with `{index}` and
155
- * `{count}` filled in.
162
+ * `{count}` filled in, written in the locale.
156
163
  */
157
164
  slideLabel: string;
158
165
  /**
@@ -163,7 +170,7 @@ export declare class HelixHeadlessLightbox extends HelixHeadlessLightbox_base {
163
170
  slideRoleLabel: string;
164
171
  /**
165
172
  * The status text that says which item is shown, with `{index}`, `{count}`
166
- * and the item's `{label}` filled in.
173
+ * and the item's `{label}` filled in, the numbers written in the locale.
167
174
  *
168
175
  * Announced rather than only drawn, because the picture changing under a
169
176
  * reader who cannot see it is otherwise silent. A consumer who has their own
@@ -179,8 +186,11 @@ export declare class HelixHeadlessLightbox extends HelixHeadlessLightbox_base {
179
186
  */
180
187
  zoomOutLabel: string;
181
188
  /**
182
- * What the live region says once a reader has stopped zooming, with the
183
- * scale as a whole `{percent}` filled in. Empty it to say nothing.
189
+ * What the live region says once a reader has stopped zooming. `{scale,
190
+ * number, percent}` writes the scale as a percentage the way the locale
191
+ * writes one, such as `150%`, or `150 %` in French. `{percent}` is the same
192
+ * scale as a whole number, for a sentence that places the sign itself. Empty
193
+ * it to say nothing.
184
194
  */
185
195
  zoomStatusLabel: string;
186
196
  /** Whether the reader has been still long enough to hide the chrome. */