@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,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, assignSlots, commaList, customElement, cycle, everyState, fillTemplate, followLink, format, HelixElement, HelixSelectEvent, HelixSelectedEvent, HelixSortEvent, HelixSortedEvent, inRowOrder, MixinCollection, onAndroid, parse, reflectElements, requestChange, sort, splitValues, toggleEvery, whenHydrated, } from '@fusion.dev/helix-core';
7
+ import { AriaForwardController, assignSlots, commaList, customElement, cycle, everyState, followLink, format, formatWords, HelixElement, HelixSelectEvent, HelixSelectedEvent, HelixSortEvent, HelixSortedEvent, inRowOrder, MixinCollection, onAndroid, parse, ReorderController, reflectElements, requestChange, sort, splitValues, toggleEvery, whenHydrated, words, } from '@fusion.dev/helix-core';
8
8
  import { nothing } from 'lit';
9
9
  import { property, state } from 'lit/decorators.js';
10
10
  import { html } from 'lit/static-html.js';
@@ -48,17 +48,25 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
48
48
  constructor() {
49
49
  super(...arguments);
50
50
  this.ascendingLabel = 'ascending';
51
+ this.canceledLabel = 'Canceled';
51
52
  this.columns = '';
52
53
  this.defaultSelected = '';
53
54
  this.defaultSort = '';
54
55
  this.descendingLabel = 'descending';
56
+ this.droppedLabel = 'Dropped';
57
+ this.fallbackLabel = 'Table';
55
58
  this.grid = false;
56
59
  this.label = '';
60
+ this.movedLabel = '{name} moved to position {position} of {count}';
61
+ this.moveRowLabel = 'Move {row}';
62
+ this.pickedUpLabel = 'Picked up {name}';
63
+ this.reorderable = false;
64
+ this.rowGripsLabel = 'Move rows';
57
65
  this.selectable = false;
58
66
  this.selectAllLabel = 'Select every row';
59
67
  this.selectedLabel = '{count} selected';
60
68
  this.selectRowLabel = 'Select {row}';
61
- this.sortedLabel = 'Sorted by {column}, {order}';
69
+ this.sortedLabel = '{direction, select, ascending {Sorted by {column}, ascending} descending {Sorted by {column}, descending} other {Sorted by {column}}}';
62
70
  this.unsortedLabel = 'Not sorted';
63
71
  this.sortState = undefined;
64
72
  this.selectedState = undefined;
@@ -70,11 +78,31 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
70
78
  this.gridKeys = new TableGridController(this, {
71
79
  activate: (place, event) => this.activate(place, event),
72
80
  columns: () => this.tableColumns.filter((column) => column.shown),
81
+ lead: () => this.lead,
73
82
  on: () => this.grid,
74
83
  part: (name) => this.partNamed(name),
75
84
  rows: () => (this.childrenKnown ? this.arrangedRows : []),
76
85
  selectAll: () => this.selectable && this.requestSelected(new Set(this.everyKey)),
77
- selectable: () => this.selectable,
86
+ });
87
+ this.reorder = new ReorderController(this, {
88
+ axis: 'block',
89
+ box: (key) => this.gripOf(this.rowFor(key))?.getBoundingClientRect(),
90
+ enabled: () => this.reorderable && !parse(this.sort),
91
+ grip: (event) => {
92
+ const path = event.composedPath();
93
+ const found = this.keyed.find(({ row }) => path.includes(this.gripOf(row)));
94
+ const element = this.gripOf(found?.row);
95
+ return found && element ? { element, key: found.key } : undefined;
96
+ },
97
+ item: (event) => {
98
+ const path = event.composedPath();
99
+ return this.keyed.find(({ row }) => path.includes(row))?.key;
100
+ },
101
+ keys: () => this.everyKey,
102
+ kind: 'row',
103
+ name: (key) => textOf(this.rowFor(key)?.children[0]) || key,
104
+ preview: (key) => this.rowFor(key),
105
+ refocus: (key) => this.gripOf(this.rowFor(key))?.focus(),
78
106
  });
79
107
  this.heardSort = undefined;
80
108
  this.heardSortBefore = undefined;
@@ -115,6 +143,7 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
115
143
  this.alignment = undefined;
116
144
  this.aligned = '';
117
145
  }
146
+ static { this.words = 'helix-table'; }
118
147
  get selected() {
119
148
  return this.selectedState ?? this.defaultSelected;
120
149
  }
@@ -131,6 +160,19 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
131
160
  this.sortState = next;
132
161
  this.requestUpdate('sort', previous);
133
162
  }
163
+ get lead() {
164
+ return [
165
+ ...(this.reorderable ? ['grip'] : []),
166
+ ...(this.selectable ? ['select'] : []),
167
+ ];
168
+ }
169
+ rowFor(key) {
170
+ return this.keyed.find((one) => one.key === key)?.row;
171
+ }
172
+ gripOf(row) {
173
+ const cell = row?.shadowRoot?.querySelector('[part~="grip"]');
174
+ return this.grid ? cell : cell?.querySelector('button');
175
+ }
134
176
  requestSort(next) {
135
177
  return requestChange({
136
178
  apply: (value) => {
@@ -174,21 +216,25 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
174
216
  ? this.tableColumns.find((one) => one.field === parsed.field)
175
217
  : undefined;
176
218
  said = parsed
177
- ? fillTemplate(this.sortedLabel, {
178
- column: column?.textContent?.trim() || parsed.field,
179
- order: parsed.direction === 'asc' ? this.ascendingLabel : this.descendingLabel,
180
- })
219
+ ? this.sortSaid(column?.textContent?.trim() || parsed.field, parsed.direction === 'asc' ? 'ascending' : 'descending')
181
220
  : this.unsortedLabel;
182
221
  }
183
222
  this.heardSort = current;
184
223
  const selected = this.selectable ? this.selected : '';
185
224
  if (this.hasUpdated && current === this.heardSortBefore && selected !== this.heardSelected) {
186
- said = fillTemplate(this.selectedLabel, { count: this.chosen.size });
225
+ said = formatWords(this, 'selectedLabel', { count: this.chosen.size });
187
226
  }
188
227
  this.heardSortBefore = current;
189
228
  this.heardSelected = selected;
190
229
  return said;
191
230
  }
231
+ sortSaid(column, direction) {
232
+ return formatWords(this, 'sortedLabel', {
233
+ column,
234
+ direction,
235
+ order: direction === 'ascending' ? this.ascendingLabel : this.descendingLabel,
236
+ });
237
+ }
192
238
  get keyed() {
193
239
  return this.slotted.map((row, index) => ({
194
240
  key: row.value || String(index),
@@ -228,7 +274,8 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
228
274
  this.requestSelected(keys);
229
275
  }
230
276
  activate(place, event) {
231
- const lead = this.selectable && place.column === 0;
277
+ const leads = this.lead;
278
+ const lead = leads[place.column] === 'select';
232
279
  if (event.key === 'F2') {
233
280
  return false;
234
281
  }
@@ -238,7 +285,7 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
238
285
  return true;
239
286
  }
240
287
  const shown = this.tableColumns.filter((one) => one.shown);
241
- const column = shown[place.column - (this.selectable ? 1 : 0)];
288
+ const column = shown[place.column - leads.length];
242
289
  if (column?.canSort) {
243
290
  this.toggleSort(column.field);
244
291
  return true;
@@ -259,15 +306,22 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
259
306
  }
260
307
  markSelected() {
261
308
  const keys = this.chosen;
309
+ const still = Boolean(parse(this.sort));
262
310
  for (const { key, row } of this.keyed) {
263
311
  if (!row.isTableRow) {
264
312
  continue;
265
313
  }
266
- const label = fillTemplate(this.selectRowLabel, { row: textOf(row.children[0]) || key });
314
+ const name = textOf(row.children[0]) || key;
315
+ const label = formatWords(this, 'selectRowLabel', { row: name });
316
+ const grip = this.reorderable ? formatWords(this, 'moveRowLabel', { row: name }) : '';
317
+ const move = this.reorder.moveOf(key);
267
318
  whenHydrated(row, () => {
268
319
  row.selectable = this.selectable;
269
320
  row.selected = keys.has(key);
270
321
  row.selectLabel = label;
322
+ row.gripLabel = grip;
323
+ row.gripStill = still;
324
+ row.move = move;
271
325
  });
272
326
  }
273
327
  }
@@ -290,10 +344,7 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
290
344
  : undefined;
291
345
  column.sortWords =
292
346
  android && column.sorted
293
- ? fillTemplate(this.sortedLabel, {
294
- column: column.textContent?.trim() || column.field,
295
- order: column.sorted === 'ascending' ? this.ascendingLabel : this.descendingLabel,
296
- })
347
+ ? this.sortSaid(column.textContent?.trim() || column.field, column.sorted)
297
348
  : '';
298
349
  }
299
350
  }
@@ -302,7 +353,8 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
302
353
  }
303
354
  get template() {
304
355
  const tracks = this.tracks;
305
- return this.selectable && tracks ? `max-content ${tracks}` : tracks;
356
+ const lead = this.lead.map(() => 'max-content ').join('');
357
+ return tracks ? lead + tracks : tracks;
306
358
  }
307
359
  get tracks() {
308
360
  const declared = this.tableColumns;
@@ -416,6 +468,17 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
416
468
  this.gridKeys.place();
417
469
  }
418
470
  }
471
+ renderGripHead() {
472
+ if (!this.reorderable) {
473
+ return nothing;
474
+ }
475
+ return html `<span
476
+ part="grip-head"
477
+ role="columnheader"
478
+ aria-label=${this.rowGripsLabel}
479
+ tabindex=${this.grid ? (this.gridKeys.isStop({ column: 0, row: -1 }) ? '0' : '-1') : nothing}
480
+ ></span>`;
481
+ }
419
482
  renderSelectAll() {
420
483
  if (!this.selectable) {
421
484
  return nothing;
@@ -424,8 +487,9 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
424
487
  const { checked, indeterminate } = everyState(this.chosen, every);
425
488
  const checkbox = this.tag('checkbox');
426
489
  const grid = this.grid;
490
+ const column = this.lead.indexOf('select');
427
491
  return html `<span part="select-all" role="columnheader"
428
- tabindex=${grid ? (this.gridKeys.isStop({ column: 0, row: -1 }) ? '0' : '-1') : nothing}
492
+ tabindex=${grid ? (this.gridKeys.isStop({ column, row: -1 }) ? '0' : '-1') : nothing}
429
493
  ><${checkbox}
430
494
  part="checkbox"
431
495
  tabindex=${grid ? '-1' : nothing}
@@ -449,10 +513,10 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
449
513
  role=${grid ? 'grid' : 'table'}
450
514
  aria-multiselectable=${grid && this.selectable ? 'true' : nothing}
451
515
  aria-busy=${this.loading ? 'true' : nothing}
452
- aria-label=${this.label || 'Table'}
516
+ aria-label=${this.label || this.fallbackLabel}
453
517
  style=${template ? `--table-template: ${template}` : ''}
454
518
  >
455
- <div part="head" role="row">${this.renderSelectAll()}<slot name="columns"></slot></div>
519
+ <div part="head" role="row">${this.renderGripHead()}${this.renderSelectAll()}<slot name="columns"></slot></div>
456
520
  <slot
457
521
  @slotchange=${(event) => {
458
522
  this.countRows(event);
@@ -460,12 +524,17 @@ let HelixHeadlessTable = class HelixHeadlessTable extends MixinCollection(HelixE
460
524
  }}
461
525
  ></slot>
462
526
  ${this.renderStatus(this.hasRows, grid ? 'gridcell' : 'cell')}
463
- </div>${end}${this.renderLive(this.hasRows)}`;
527
+ </div>${end}${this.renderLive(this.hasRows)}${this.reorder.drawDragPreview()}`;
464
528
  }
465
529
  };
466
530
  __decorate([
531
+ words,
467
532
  property({ attribute: 'ascending-label' })
468
533
  ], HelixHeadlessTable.prototype, "ascendingLabel", void 0);
534
+ __decorate([
535
+ words,
536
+ property({ attribute: 'canceled-label' })
537
+ ], HelixHeadlessTable.prototype, "canceledLabel", void 0);
469
538
  __decorate([
470
539
  property()
471
540
  ], HelixHeadlessTable.prototype, "columns", void 0);
@@ -476,36 +545,69 @@ __decorate([
476
545
  property({ attribute: 'default-sort' })
477
546
  ], HelixHeadlessTable.prototype, "defaultSort", void 0);
478
547
  __decorate([
548
+ words,
479
549
  property({ attribute: 'descending-label' })
480
550
  ], HelixHeadlessTable.prototype, "descendingLabel", void 0);
551
+ __decorate([
552
+ words,
553
+ property({ attribute: 'dropped-label' })
554
+ ], HelixHeadlessTable.prototype, "droppedLabel", void 0);
555
+ __decorate([
556
+ words,
557
+ property({ attribute: 'fallback-label' })
558
+ ], HelixHeadlessTable.prototype, "fallbackLabel", void 0);
481
559
  __decorate([
482
560
  property({ type: Boolean })
483
561
  ], HelixHeadlessTable.prototype, "grid", void 0);
484
562
  __decorate([
485
563
  property()
486
564
  ], HelixHeadlessTable.prototype, "label", void 0);
565
+ __decorate([
566
+ words,
567
+ property({ attribute: 'moved-label' })
568
+ ], HelixHeadlessTable.prototype, "movedLabel", void 0);
569
+ __decorate([
570
+ words,
571
+ property({ attribute: 'move-row-label' })
572
+ ], HelixHeadlessTable.prototype, "moveRowLabel", void 0);
573
+ __decorate([
574
+ words,
575
+ property({ attribute: 'picked-up-label' })
576
+ ], HelixHeadlessTable.prototype, "pickedUpLabel", void 0);
577
+ __decorate([
578
+ property({ type: Boolean })
579
+ ], HelixHeadlessTable.prototype, "reorderable", void 0);
580
+ __decorate([
581
+ words,
582
+ property({ attribute: 'row-grips-label' })
583
+ ], HelixHeadlessTable.prototype, "rowGripsLabel", void 0);
487
584
  __decorate([
488
585
  property({ type: Boolean })
489
586
  ], HelixHeadlessTable.prototype, "selectable", void 0);
490
587
  __decorate([
588
+ words,
491
589
  property({ attribute: 'select-all-label' })
492
590
  ], HelixHeadlessTable.prototype, "selectAllLabel", void 0);
493
591
  __decorate([
494
592
  property()
495
593
  ], HelixHeadlessTable.prototype, "selected", null);
496
594
  __decorate([
595
+ words,
497
596
  property({ attribute: 'selected-label' })
498
597
  ], HelixHeadlessTable.prototype, "selectedLabel", void 0);
499
598
  __decorate([
599
+ words,
500
600
  property({ attribute: 'select-row-label' })
501
601
  ], HelixHeadlessTable.prototype, "selectRowLabel", void 0);
502
602
  __decorate([
503
603
  property()
504
604
  ], HelixHeadlessTable.prototype, "sort", null);
505
605
  __decorate([
606
+ words,
506
607
  property({ attribute: 'sorted-label' })
507
608
  ], HelixHeadlessTable.prototype, "sortedLabel", void 0);
508
609
  __decorate([
610
+ words,
509
611
  property({ attribute: 'unsorted-label' })
510
612
  ], HelixHeadlessTable.prototype, "unsortedLabel", void 0);
511
613
  __decorate([
@@ -1,6 +1,8 @@
1
1
  import { HelixElement } from '@fusion.dev/helix-core';
2
2
  import { nothing, type PropertyValues, type TemplateResult } from 'lit';
3
3
  import '../../checkbox/index.js';
4
+ /** Where a row stands in a move: the row being moved, or the one the drop indicator is beside. */
5
+ export type TableRowMove = 'dragging' | 'drop-after' | 'drop-before';
4
6
  /**
5
7
  * @summary One row of a table.
6
8
  *
@@ -13,6 +15,12 @@ import '../../checkbox/index.js';
13
15
  * In a `selectable` table the row draws a checkbox cell before its own cells,
14
16
  * and `value` is the key the table's `selected` lists it by.
15
17
  *
18
+ * In a `reorderable` table the row draws a grip cell before those, holding a
19
+ * button named by the table's `move-row-label`, and `value` is the key
20
+ * `helix-reorder` lists it by. The table says which row is moving and where
21
+ * the drop indicator is, with the `dragging`, `drop-before`, and `drop-after`
22
+ * states.
23
+ *
16
24
  * **`href` makes the whole row a link**, as a row action does in React Aria's
17
25
  * table: a press anywhere on the row follows it, except on a link or a control
18
26
  * of the row's own, and Control, Command or Shift open it the way they open a
@@ -39,9 +47,15 @@ import '../../checkbox/index.js';
39
47
  * @csspart checkbox-mark-checked - Added to `checkbox-mark` while its box is checked.
40
48
  * @csspart checkbox-mark-dash - Added to `checkbox-mark` while it draws the dash, which it keeps until its box is checked.
41
49
  * @csspart checkbox-mark-indeterminate - Added to `checkbox-mark` while only some rows are selected.
50
+ * @csspart grip - The cell that holds the row's grip, in a `reorderable` table.
51
+ * @csspart grip-button - The button that moves the row.
52
+ * @csspart grip-mark - The icon on the grip.
42
53
  * @csspart select - The cell that holds the row's checkbox, in a `selectable` table.
43
54
  * @csspart select-selected - Added to `select` while the row is selected.
44
55
  *
56
+ * @cssstate dragging - The row is being moved, in a `reorderable` table.
57
+ * @cssstate drop-after - The row being moved goes after this one when it is dropped.
58
+ * @cssstate drop-before - The row being moved goes before this one when it is dropped.
45
59
  * @cssstate link - While the row has `href`, so a press on it follows the link.
46
60
  * @cssstate selected - While the row is selected, in a `selectable` table.
47
61
  */
@@ -77,6 +91,27 @@ export declare class HelixHeadlessTableRow extends HelixElement {
77
91
  selected: boolean;
78
92
  /** @internal The name of the row's checkbox, written by the table. Not a consumer's to set. */
79
93
  selectLabel: string;
94
+ /**
95
+ * @internal The name of the row's grip, written by a `reorderable` table, and
96
+ * empty in a table that does not reorder, which draws no grip. Not a
97
+ * consumer's to set.
98
+ */
99
+ gripLabel: string;
100
+ /**
101
+ * @internal Whether the grip does nothing for now, as while the table is
102
+ * sorted, written by the table. Not a consumer's to set.
103
+ */
104
+ gripStill: boolean;
105
+ /**
106
+ * @internal Whether the grip cell holds the grid's one tab stop, written by
107
+ * the table that sets `gridCell`. Not a consumer's to set.
108
+ */
109
+ gripStop: boolean;
110
+ /**
111
+ * @internal Where the row stands in a move, written by a `reorderable` table.
112
+ * Not a consumer's to set.
113
+ */
114
+ move: TableRowMove | undefined;
80
115
  /**
81
116
  * @internal Whether the row is a row of a `grid` table, written by that
82
117
  * table. Not a consumer's to set. The checkbox cell is then a `gridcell`
@@ -121,6 +156,13 @@ export declare class HelixHeadlessTableRow extends HelixElement {
121
156
  * table's `selected` says.
122
157
  */
123
158
  protected renderSelect(): TemplateResult | typeof nothing;
159
+ /**
160
+ * The grip cell, in a `reorderable` table: a cell of the row's own before the
161
+ * checkbox cell, holding the button that moves the row. In a grid the cell
162
+ * takes focus and Space or Enter on it picks the row up, and the button
163
+ * leaves the tab order. `aria-disabled` while a sort decides the order.
164
+ */
165
+ protected renderGrip(): TemplateResult | typeof nothing;
124
166
  protected render(): TemplateResult;
125
167
  }
126
168
  declare global {
@@ -5,8 +5,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import { customElement, followLink, HelixElement, hostAria, pressedOwnControl, } from '@fusion.dev/helix-core';
8
+ import { dotsSixVertical } from '@fusion.dev/helix-icons';
8
9
  import { nothing } from 'lit';
9
10
  import { property, state } from 'lit/decorators.js';
11
+ import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
10
12
  import { html } from 'lit/static-html.js';
11
13
  import '../../checkbox/index.js';
12
14
  let HelixHeadlessTableRow = class HelixHeadlessTableRow extends HelixElement {
@@ -20,6 +22,10 @@ let HelixHeadlessTableRow = class HelixHeadlessTableRow extends HelixElement {
20
22
  this.selectable = false;
21
23
  this.selected = false;
22
24
  this.selectLabel = '';
25
+ this.gripLabel = '';
26
+ this.gripStill = false;
27
+ this.gripStop = false;
28
+ this.move = undefined;
23
29
  this.gridCell = false;
24
30
  this.selectStop = false;
25
31
  this.columnRules = undefined;
@@ -64,6 +70,9 @@ let HelixHeadlessTableRow = class HelixHeadlessTableRow extends HelixElement {
64
70
  this.internals.ariaSelected = this.gridCell && this.selectable ? String(this.selected) : null;
65
71
  this.toggleState('selected', this.selectable && this.selected);
66
72
  this.toggleState('link', this.href !== '');
73
+ this.toggleState('dragging', this.move === 'dragging');
74
+ this.toggleState('drop-after', this.move === 'drop-after');
75
+ this.toggleState('drop-before', this.move === 'drop-before');
67
76
  }
68
77
  connectedCallback() {
69
78
  super.connectedCallback();
@@ -95,8 +104,26 @@ let HelixHeadlessTableRow = class HelixHeadlessTableRow extends HelixElement {
95
104
  ></${checkbox}
96
105
  ></span>`;
97
106
  }
107
+ renderGrip() {
108
+ if (!this.gripLabel) {
109
+ return nothing;
110
+ }
111
+ const grid = this.gridCell;
112
+ return html `<span
113
+ part="grip"
114
+ role=${grid ? 'gridcell' : 'cell'}
115
+ tabindex=${grid ? (this.gripStop ? '0' : '-1') : nothing}
116
+ ><button
117
+ part="grip-button"
118
+ type="button"
119
+ tabindex=${grid ? '-1' : nothing}
120
+ aria-label=${this.gripLabel}
121
+ aria-disabled=${this.gripStill ? 'true' : nothing}
122
+ ><svg aria-hidden="true" fill="currentColor" part="grip-mark" viewBox=${dotsSixVertical.viewBox}>${unsafeSVG(dotsSixVertical.content)}</svg></button
123
+ ></span>`;
124
+ }
98
125
  render() {
99
- return html `${this.renderSelect()}<slot @slotchange=${this.handleSlotChange}></slot>`;
126
+ return html `${this.renderGrip()}${this.renderSelect()}<slot @slotchange=${this.handleSlotChange}></slot>`;
100
127
  }
101
128
  };
102
129
  __decorate([
@@ -120,6 +147,18 @@ __decorate([
120
147
  __decorate([
121
148
  state()
122
149
  ], HelixHeadlessTableRow.prototype, "selectLabel", void 0);
150
+ __decorate([
151
+ state()
152
+ ], HelixHeadlessTableRow.prototype, "gripLabel", void 0);
153
+ __decorate([
154
+ state()
155
+ ], HelixHeadlessTableRow.prototype, "gripStill", void 0);
156
+ __decorate([
157
+ state()
158
+ ], HelixHeadlessTableRow.prototype, "gripStop", void 0);
159
+ __decorate([
160
+ state()
161
+ ], HelixHeadlessTableRow.prototype, "move", void 0);
123
162
  __decorate([
124
163
  state()
125
164
  ], HelixHeadlessTableRow.prototype, "gridCell", void 0);
@@ -63,6 +63,11 @@ declare const HelixHeadlessTabs_base: (new (...args: any[]) => import("@fusion.d
63
63
  * @csspart tabs - The tab list.
64
64
  */
65
65
  export declare class HelixHeadlessTabs extends HelixHeadlessTabs_base {
66
+ /**
67
+ * The key this family's words are registered under, its styled tag:
68
+ * `registerWords('de', { 'helix-tabs': { label: 'Reiter' } })`.
69
+ */
70
+ static words: string;
66
71
  protected readonly keys: KeyboardNavigationController;
67
72
  private readonly indicator;
68
73
  /** Carries a host `aria-label` and `aria-labelledby` to the tab list. */
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { AriaForwardController, customElement, HelixElement, IndicatorController, KeyboardNavigationController, MixinControllerActive, whenHydrated, } from '@fusion.dev/helix-core';
7
+ import { AriaForwardController, customElement, HelixElement, IndicatorController, KeyboardNavigationController, MixinControllerActive, whenHydrated, words, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  import { HelixHeadlessTabPanel } from '../panel/tab-panel.js';
@@ -40,6 +40,7 @@ let HelixHeadlessTabs = class HelixHeadlessTabs extends MixinControllerActive(He
40
40
  this.indicator.place();
41
41
  };
42
42
  }
43
+ static { this.words = 'helix-tabs'; }
43
44
  get tabs() {
44
45
  return [...this.children].filter((child) => child instanceof HelixHeadlessTab);
45
46
  }
@@ -111,6 +112,7 @@ let HelixHeadlessTabs = class HelixHeadlessTabs extends MixinControllerActive(He
111
112
  }
112
113
  };
113
114
  __decorate([
115
+ words,
114
116
  property()
115
117
  ], HelixHeadlessTabs.prototype, "label", void 0);
116
118
  __decorate([
@@ -46,6 +46,11 @@ export type TagSelectionMode = SelectionMode;
46
46
  * @csspart empty - Holds the `empty` slot while the group has no tags, rendered only then. Takes focus when the last tag is removed.
47
47
  */
48
48
  export declare class HelixHeadlessTagGroup extends HelixElement {
49
+ /**
50
+ * The key this part's words are registered under, its styled tag:
51
+ * `registerWords('de', { 'helix-tag-group': { emptyLabel: 'Keine Schlagwörter' } })`.
52
+ */
53
+ static words: string;
49
54
  /**
50
55
  * The words the group shows and says once its last tag is removed, where
51
56
  * nothing is in the `empty` slot.
@@ -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 { commaList, customElement, deepActiveElement, deepContains, focusItemOf, HelixElement, hostAria, KeyboardNavigationController, pressedValue, prunedValue, requestValue, rovingStop, slottedWords, typeaheadByWords, whenHydrated, } from '@fusion.dev/helix-core';
7
+ import { commaList, customElement, deepActiveElement, deepContains, focusItemOf, HelixElement, hostAria, KeyboardNavigationController, pressedValue, prunedValue, requestValue, rovingStop, slottedWords, typeaheadByWords, whenHydrated, words, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  import { HelixHeadlessTag } from '../root/tag-root.js';
@@ -92,6 +92,7 @@ let HelixHeadlessTagGroup = class HelixHeadlessTagGroup extends HelixElement {
92
92
  }
93
93
  };
94
94
  }
95
+ static { this.words = 'helix-tag-group'; }
95
96
  get written() {
96
97
  return typeof this.value === 'string'
97
98
  ? this.value
@@ -182,6 +183,7 @@ let HelixHeadlessTagGroup = class HelixHeadlessTagGroup extends HelixElement {
182
183
  }
183
184
  };
184
185
  __decorate([
186
+ words,
185
187
  property({ attribute: 'empty-label' })
186
188
  ], HelixHeadlessTagGroup.prototype, "emptyLabel", void 0);
187
189
  __decorate([
@@ -50,13 +50,26 @@ declare const HelixHeadlessTag_base: (new (...args: any[]) => import("@fusion.de
50
50
  * @cssstate selected - The tag is selected in a `Tag.Group` that selects.
51
51
  */
52
52
  export declare class HelixHeadlessTag extends HelixHeadlessTag_base {
53
- dismissLabel: string;
53
+ /**
54
+ * The key this family's words are registered under, its styled tag:
55
+ * `registerWords('de', { 'helix-tag': { dismissLabel: '{label} entfernen' } })`.
56
+ */
57
+ static words: string;
54
58
  /**
55
59
  * Takes the tag out of reach: its link and its remove button stop
56
60
  * answering, and in a `Tag.Group` the arrow keys pass over it and it cannot
57
61
  * be selected or removed.
58
62
  */
59
63
  disabled: boolean;
64
+ /**
65
+ * The remove button's name, read by screen readers, with `{label}` for the
66
+ * tag's own words.
67
+ *
68
+ * "Remove" rather than the mixin's "Dismiss": a tag is taken out of a set,
69
+ * which is a different act from closing a message. One sentence with the
70
+ * tag's words in it, so a translation puts them where its language does.
71
+ */
72
+ dismissLabel: string;
60
73
  /**
61
74
  * Whether the tag holds its group's tab stop.
62
75
  *
@@ -4,17 +4,18 @@ 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, drawDismiss, drawDismissGlyph, HelixElement, hostAria, MixinDismissible, slottedWords, } from '@fusion.dev/helix-core';
7
+ import { customElement, drawDismiss, drawDismissGlyph, formatWords, HelixElement, hostAria, MixinDismissible, slottedWords, words, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  let HelixHeadlessTag = class HelixHeadlessTag extends MixinDismissible(HelixElement) {
11
11
  constructor() {
12
12
  super(...arguments);
13
- this.dismissLabel = 'Remove';
14
13
  this.disabled = false;
14
+ this.dismissLabel = 'Remove {label}';
15
15
  this.href = '';
16
16
  this.value = '';
17
17
  }
18
+ static { this.words = 'helix-tag'; }
18
19
  get words() {
19
20
  return this.childrenKnown ? slottedWords(this, ['start', '']) : '';
20
21
  }
@@ -45,13 +46,11 @@ let HelixHeadlessTag = class HelixHeadlessTag extends MixinDismissible(HelixElem
45
46
  this.toggleState('selected', this.selected === true);
46
47
  }
47
48
  get removeName() {
48
- const words = this.words;
49
- if (this.dismissLabel.includes('{label}')) {
50
- return this.dismissLabel.replace('{label}', words).trim();
49
+ const { dismissLabel, words } = this;
50
+ if (dismissLabel.includes('{label}')) {
51
+ return formatWords(this, 'dismissLabel', { label: words }).trim();
51
52
  }
52
- return words === '' || this.dismissLabel.includes(words)
53
- ? this.dismissLabel
54
- : `${this.dismissLabel} ${words}`;
53
+ return words === '' || dismissLabel.includes(words) ? dismissLabel : `${dismissLabel} ${words}`;
55
54
  }
56
55
  firstUpdated(changed) {
57
56
  super.firstUpdated(changed);
@@ -95,6 +94,10 @@ let HelixHeadlessTag = class HelixHeadlessTag extends MixinDismissible(HelixElem
95
94
  __decorate([
96
95
  property({ reflect: true, type: Boolean })
97
96
  ], HelixHeadlessTag.prototype, "disabled", void 0);
97
+ __decorate([
98
+ words,
99
+ property({ attribute: 'dismiss-label' })
100
+ ], HelixHeadlessTag.prototype, "dismissLabel", void 0);
98
101
  __decorate([
99
102
  property({ attribute: false })
100
103
  ], HelixHeadlessTag.prototype, "focusable", void 0);
@@ -60,6 +60,11 @@ declare const HelixHeadlessTextarea_base: (new (...args: any[]) => import("@fusi
60
60
  * @cssstate invalid - The control has an error to show, from the browser's validation, `validate`, or your `feedback`.
61
61
  */
62
62
  export declare class HelixHeadlessTextarea extends HelixHeadlessTextarea_base {
63
+ /**
64
+ * The key this family's words are registered under, its styled tag:
65
+ * `registerWords('de', { 'helix-textarea': { clearLabel: 'Leeren' } })`.
66
+ */
67
+ static words: string;
63
68
  protected readonly aria: AriaForwardController;
64
69
  /** Typed or dragged, so every edit is announced. See `announcesInput`. */
65
70
  protected readonly announcesInput = true;