@fusion.dev/helix-headless 0.142.1 → 0.144.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. package/custom-elements.json +25381 -1202
  2. package/dist/accordion/item/accordion-item.d.ts +38 -2
  3. package/dist/accordion/item/accordion-item.js +38 -6
  4. package/dist/accordion/root/accordion-root.d.ts +23 -1
  5. package/dist/accordion/root/accordion-root.js +39 -3
  6. package/dist/announcement/root/announcement-root.d.ts +11 -7
  7. package/dist/announcement/root/announcement-root.js +1 -1
  8. package/dist/app-header/root/app-header-root.d.ts +21 -0
  9. package/dist/app-header/root/app-header-root.js +31 -5
  10. package/dist/area-chart/root/area-chart-root.d.ts +12 -4
  11. package/dist/area-chart/root/area-chart-root.js +39 -11
  12. package/dist/avatar/group/avatar-group.d.ts +24 -3
  13. package/dist/avatar/group/avatar-group.js +34 -2
  14. package/dist/avatar/root/avatar-root.d.ts +17 -1
  15. package/dist/avatar/root/avatar-root.js +31 -10
  16. package/dist/badge/root/badge-root.d.ts +12 -0
  17. package/dist/badge/root/badge-root.js +1 -1
  18. package/dist/bar-chart/root/bar-chart-root.d.ts +30 -5
  19. package/dist/bar-chart/root/bar-chart-root.js +58 -21
  20. package/dist/blockquote/root/blockquote-root.d.ts +12 -7
  21. package/dist/blockquote/root/blockquote-root.js +6 -4
  22. package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +9 -3
  23. package/dist/breadcrumbs/root/breadcrumbs-root.js +9 -1
  24. package/dist/button/root/button-root.d.ts +84 -1
  25. package/dist/button/root/button-root.js +81 -3
  26. package/dist/callout/root/callout-root.d.ts +32 -6
  27. package/dist/callout/root/callout-root.js +26 -7
  28. package/dist/canvas/root/canvas-root.d.ts +1 -0
  29. package/dist/canvas/root/canvas-root.js +10 -1
  30. package/dist/card/root/card-root.d.ts +30 -1
  31. package/dist/card/root/card-root.js +38 -5
  32. package/dist/carousel/root/carousel-root.d.ts +47 -5
  33. package/dist/carousel/root/carousel-root.js +53 -21
  34. package/dist/chat/composer/chat-composer.d.ts +13 -11
  35. package/dist/chat/composer/chat-composer.js +6 -12
  36. package/dist/chat/message/chat-message.js +8 -1
  37. package/dist/chat/root/chat-root.d.ts +1 -0
  38. package/dist/chat/root/chat-root.js +2 -1
  39. package/dist/checkbox/root/checkbox-root.d.ts +7 -0
  40. package/dist/checkbox/root/checkbox-root.js +9 -3
  41. package/dist/checkbox-group/root/checkbox-group-root.d.ts +116 -33
  42. package/dist/checkbox-group/root/checkbox-group-root.js +141 -44
  43. package/dist/code/root/code-root.d.ts +1 -1
  44. package/dist/code-block/lines.d.ts +13 -0
  45. package/dist/code-block/lines.js +2 -0
  46. package/dist/code-block/root/code-block-root.d.ts +49 -0
  47. package/dist/code-block/root/code-block-root.js +44 -3
  48. package/dist/color-input/root/color-input-root.d.ts +60 -2
  49. package/dist/color-input/root/color-input-root.js +55 -7
  50. package/dist/color-picker/channels.d.ts +26 -0
  51. package/dist/color-picker/channels.js +84 -0
  52. package/dist/color-picker/root/color-picker-root.d.ts +118 -12
  53. package/dist/color-picker/root/color-picker-root.js +183 -13
  54. package/dist/combobox/root/combobox-root.d.ts +126 -3
  55. package/dist/combobox/root/combobox-root.js +224 -21
  56. package/dist/command/root/command-root.d.ts +47 -10
  57. package/dist/command/root/command-root.js +45 -4
  58. package/dist/copy-button/from.d.ts +22 -0
  59. package/dist/copy-button/from.js +28 -0
  60. package/dist/copy-button/root/copy-button-root.d.ts +48 -7
  61. package/dist/copy-button/root/copy-button-root.js +54 -8
  62. package/dist/data-table/root/data-table-root.d.ts +164 -10
  63. package/dist/data-table/root/data-table-root.js +488 -57
  64. package/dist/date-input/root/date-input-root.d.ts +123 -9
  65. package/dist/date-input/root/date-input-root.js +147 -45
  66. package/dist/date-picker/root/date-picker-root.d.ts +229 -18
  67. package/dist/date-picker/root/date-picker-root.js +342 -46
  68. package/dist/dialog/description.d.ts +9 -0
  69. package/dist/dialog/description.js +14 -0
  70. package/dist/dialog/root/dialog-root.d.ts +101 -10
  71. package/dist/dialog/root/dialog-root.js +83 -4
  72. package/dist/donut-chart/root/donut-chart-root.d.ts +61 -16
  73. package/dist/donut-chart/root/donut-chart-root.js +48 -13
  74. package/dist/drawer/root/drawer-root.d.ts +93 -7
  75. package/dist/drawer/root/drawer-root.js +126 -5
  76. package/dist/drawer/swipe-start.d.ts +9 -0
  77. package/dist/drawer/swipe-start.js +12 -0
  78. package/dist/drilldown/item/drilldown-item.d.ts +16 -13
  79. package/dist/drilldown/item/drilldown-item.js +6 -2
  80. package/dist/drilldown/root/drilldown-root.d.ts +21 -5
  81. package/dist/drilldown/root/drilldown-root.js +26 -10
  82. package/dist/element-events.generated.js +42 -13
  83. package/dist/empty/root/empty-root.d.ts +1 -1
  84. package/dist/file-input/root/file-input-root.d.ts +65 -1
  85. package/dist/file-input/root/file-input-root.js +76 -12
  86. package/dist/file-input/screen.d.ts +35 -0
  87. package/dist/file-input/screen.js +49 -0
  88. package/dist/filter-input/menu/filter-menu.d.ts +9 -0
  89. package/dist/filter-input/menu/filter-menu.js +8 -0
  90. package/dist/filter-input/root/filter-input-root.d.ts +43 -6
  91. package/dist/filter-input/root/filter-input-root.js +89 -10
  92. package/dist/filter-input/suggest.d.ts +17 -0
  93. package/dist/filter-input/suggest.js +23 -0
  94. package/dist/format-date/options.d.ts +33 -0
  95. package/dist/format-date/options.js +42 -0
  96. package/dist/format-date/root/format-date-root.d.ts +62 -3
  97. package/dist/format-date/root/format-date-root.js +78 -37
  98. package/dist/graph/root/graph-root.d.ts +24 -3
  99. package/dist/graph/root/graph-root.js +66 -12
  100. package/dist/heatmap/root/buckets.d.ts +2 -1
  101. package/dist/heatmap/root/buckets.js +5 -1
  102. package/dist/heatmap/root/heatmap-root.d.ts +47 -9
  103. package/dist/heatmap/root/heatmap-root.js +46 -18
  104. package/dist/icon/index.d.ts +2 -0
  105. package/dist/icon/index.js +2 -0
  106. package/dist/icon/registry.d.ts +37 -0
  107. package/dist/icon/registry.js +83 -0
  108. package/dist/icon/root/icon-root.d.ts +53 -6
  109. package/dist/icon/root/icon-root.js +72 -4
  110. package/dist/icon/root/index.d.ts +2 -0
  111. package/dist/icon/root/index.js +2 -0
  112. package/dist/icon/set.d.ts +1 -0
  113. package/dist/icon/set.js +3 -0
  114. package/dist/icon-button/root/icon-button-root.d.ts +1 -1
  115. package/dist/image/root/image-root.d.ts +23 -2
  116. package/dist/image/root/image-root.js +23 -4
  117. package/dist/input/root/input-root.d.ts +62 -9
  118. package/dist/input/root/input-root.js +61 -5
  119. package/dist/kbd/root/kbd-root.d.ts +26 -11
  120. package/dist/kbd/root/kbd-root.js +35 -38
  121. package/dist/kbd/shortcut.d.ts +18 -0
  122. package/dist/kbd/shortcut.js +35 -0
  123. package/dist/legend/hidden-series.d.ts +8 -0
  124. package/dist/legend/hidden-series.js +13 -0
  125. package/dist/legend/root/legend-root.d.ts +63 -0
  126. package/dist/legend/root/legend-root.js +61 -7
  127. package/dist/lightbox/item/lightbox-item.d.ts +17 -1
  128. package/dist/lightbox/item/lightbox-item.js +10 -1
  129. package/dist/lightbox/root/lightbox-root.d.ts +77 -6
  130. package/dist/lightbox/root/lightbox-root.js +116 -5
  131. package/dist/line-chart/root/line-chart-root.d.ts +29 -4
  132. package/dist/line-chart/root/line-chart-root.js +58 -17
  133. package/dist/list/item/list-item.d.ts +11 -5
  134. package/dist/list/item/list-item.js +5 -6
  135. package/dist/listbox/range.d.ts +17 -0
  136. package/dist/listbox/range.js +5 -0
  137. package/dist/listbox/root/listbox-root.d.ts +184 -4
  138. package/dist/listbox/root/listbox-root.js +229 -23
  139. package/dist/loader/busy.d.ts +17 -0
  140. package/dist/loader/busy.js +24 -0
  141. package/dist/loader/root/loader-root.d.ts +37 -0
  142. package/dist/loader/root/loader-root.js +52 -3
  143. package/dist/map/root/map-root.d.ts +19 -4
  144. package/dist/map/root/map-root.js +36 -7
  145. package/dist/megamenu/root/megamenu-root.d.ts +10 -1
  146. package/dist/megamenu/root/megamenu-root.js +10 -1
  147. package/dist/menu/item/menu-item.d.ts +41 -12
  148. package/dist/menu/item/menu-item.js +46 -3
  149. package/dist/menu/root/menu-root.d.ts +32 -2
  150. package/dist/menu/root/menu-root.js +48 -8
  151. package/dist/meter/root/meter-root.d.ts +13 -0
  152. package/dist/meter/root/meter-root.js +24 -5
  153. package/dist/navigation/root/navigation-root.d.ts +10 -2
  154. package/dist/navigation/root/navigation-root.js +13 -2
  155. package/dist/notifications/feed-keys.d.ts +10 -0
  156. package/dist/notifications/feed-keys.js +14 -0
  157. package/dist/notifications/group/notification-group.d.ts +1 -0
  158. package/dist/notifications/notification/notification.d.ts +29 -0
  159. package/dist/notifications/notification/notification.js +51 -3
  160. package/dist/notifications/root/notifications-root.d.ts +49 -0
  161. package/dist/notifications/root/notifications-root.js +76 -2
  162. package/dist/number-input/root/number-input-root.d.ts +109 -7
  163. package/dist/number-input/root/number-input-root.js +109 -21
  164. package/dist/object-inspector/root/object-inspector-root.d.ts +49 -5
  165. package/dist/object-inspector/root/object-inspector-root.js +92 -12
  166. package/dist/option/root/option-root.d.ts +58 -6
  167. package/dist/option/root/option-root.js +35 -5
  168. package/dist/outline/root/outline-root.d.ts +13 -2
  169. package/dist/outline/root/outline-root.js +4 -2
  170. package/dist/pagination/root/pagination-root.d.ts +19 -1
  171. package/dist/pagination/root/pagination-root.js +49 -9
  172. package/dist/pagination/size/pagination-size.d.ts +13 -3
  173. package/dist/pagination/size/pagination-size.js +7 -0
  174. package/dist/pin-input/format.d.ts +7 -0
  175. package/dist/pin-input/format.js +16 -0
  176. package/dist/pin-input/root/pin-input-root.d.ts +37 -0
  177. package/dist/pin-input/root/pin-input-root.js +48 -7
  178. package/dist/popover/root/popover-root.d.ts +78 -3
  179. package/dist/popover/root/popover-root.js +74 -5
  180. package/dist/progress/root/progress-root.d.ts +23 -1
  181. package/dist/progress/root/progress-root.js +40 -10
  182. package/dist/qr-code/export.d.ts +31 -0
  183. package/dist/qr-code/export.js +10 -0
  184. package/dist/qr-code/root/qr-code-root.d.ts +45 -0
  185. package/dist/qr-code/root/qr-code-root.js +78 -3
  186. package/dist/radio/group/radio-group.d.ts +64 -0
  187. package/dist/radio/group/radio-group.js +66 -12
  188. package/dist/radio/root/radio-root.d.ts +8 -5
  189. package/dist/radio/root/radio-root.js +1 -2
  190. package/dist/rating/root/rating-root.d.ts +49 -1
  191. package/dist/rating/root/rating-root.js +69 -10
  192. package/dist/scatter-chart/root/scatter-chart-root.d.ts +17 -3
  193. package/dist/scatter-chart/root/scatter-chart-root.js +40 -14
  194. package/dist/select/root/select-root.d.ts +93 -3
  195. package/dist/select/root/select-root.js +111 -13
  196. package/dist/skeleton/root/skeleton-root.d.ts +39 -3
  197. package/dist/skeleton/root/skeleton-root.js +33 -4
  198. package/dist/skip-link/root/skip-link-root.d.ts +10 -0
  199. package/dist/skip-link/root/skip-link-root.js +15 -1
  200. package/dist/slider/root/slider-root.d.ts +59 -2
  201. package/dist/slider/root/slider-root.js +82 -8
  202. package/dist/sparkline/root/sparkline-root.d.ts +9 -10
  203. package/dist/speed-dial/item/speed-dial-item.d.ts +11 -5
  204. package/dist/speed-dial/item/speed-dial-item.js +7 -2
  205. package/dist/speed-dial/root/speed-dial-root.d.ts +15 -4
  206. package/dist/speed-dial/root/speed-dial-root.js +19 -5
  207. package/dist/splitter/root/splitter-root.d.ts +28 -6
  208. package/dist/splitter/root/splitter-root.js +35 -1
  209. package/dist/stat/root/stat-root.d.ts +9 -1
  210. package/dist/stat/root/stat-root.js +15 -2
  211. package/dist/steps/root/steps-root.js +1 -1
  212. package/dist/steps/step/step.d.ts +1 -0
  213. package/dist/steps/step/step.js +1 -1
  214. package/dist/switch/root/switch-root.d.ts +14 -2
  215. package/dist/switch/root/switch-root.js +7 -1
  216. package/dist/table/cell/table-cell.d.ts +24 -4
  217. package/dist/table/cell/table-cell.js +21 -1
  218. package/dist/table/column/table-column.d.ts +32 -6
  219. package/dist/table/column/table-column.js +36 -6
  220. package/dist/table/root/table-root.d.ts +94 -3
  221. package/dist/table/root/table-root.js +128 -5
  222. package/dist/table/row/table-row.d.ts +7 -0
  223. package/dist/table/row/table-row.js +9 -1
  224. package/dist/tabs/root/tabs-root.d.ts +6 -1
  225. package/dist/tabs/root/tabs-root.js +6 -2
  226. package/dist/tag/group/tag-group.d.ts +107 -0
  227. package/dist/tag/group/tag-group.js +157 -0
  228. package/dist/tag/index.d.ts +1 -0
  229. package/dist/tag/index.js +1 -0
  230. package/dist/tag/root/tag-root.d.ts +83 -1
  231. package/dist/tag/root/tag-root.js +87 -17
  232. package/dist/tag/selection.d.ts +10 -0
  233. package/dist/tag/selection.js +12 -0
  234. package/dist/textarea/grow.d.ts +22 -0
  235. package/dist/textarea/grow.js +20 -0
  236. package/dist/textarea/root/textarea-root.d.ts +13 -0
  237. package/dist/textarea/root/textarea-root.js +10 -2
  238. package/dist/time-input/root/time-input-root.d.ts +71 -6
  239. package/dist/time-input/root/time-input-root.js +110 -44
  240. package/dist/time-picker/root/time-picker-root.d.ts +155 -26
  241. package/dist/time-picker/root/time-picker-root.js +192 -63
  242. package/dist/toast/hotkey.d.ts +22 -0
  243. package/dist/toast/hotkey.js +23 -0
  244. package/dist/toast/item/toast-item.d.ts +16 -1
  245. package/dist/toast/item/toast-item.js +41 -13
  246. package/dist/toast/root/toast-root.d.ts +105 -8
  247. package/dist/toast/root/toast-root.js +209 -4
  248. package/dist/toggle/group/toggle-group.d.ts +95 -16
  249. package/dist/toggle/group/toggle-group.js +99 -13
  250. package/dist/toggle/root/toggle-root.d.ts +26 -11
  251. package/dist/toggle/root/toggle-root.js +14 -6
  252. package/dist/toolbar/root/toolbar-root.d.ts +55 -15
  253. package/dist/toolbar/root/toolbar-root.js +99 -16
  254. package/dist/tooltip/focus-target.d.ts +6 -0
  255. package/dist/tooltip/focus-target.js +9 -0
  256. package/dist/tooltip/root/tooltip-root.d.ts +73 -15
  257. package/dist/tooltip/root/tooltip-root.js +96 -7
  258. package/dist/tour/naming.d.ts +30 -0
  259. package/dist/tour/naming.js +10 -0
  260. package/dist/tour/root/tour-root.d.ts +67 -3
  261. package/dist/tour/root/tour-root.js +105 -17
  262. package/dist/tour/stop/tour-stop.d.ts +65 -3
  263. package/dist/tour/stop/tour-stop.js +61 -11
  264. package/dist/tour/wait.d.ts +11 -0
  265. package/dist/tour/wait.js +19 -0
  266. package/dist/tree/item/tree-item.d.ts +21 -5
  267. package/dist/tree/item/tree-item.js +14 -4
  268. package/dist/tree/root/tree-root.d.ts +29 -5
  269. package/dist/tree/root/tree-root.js +64 -8
  270. package/dist/trend/root/trend-root.d.ts +36 -1
  271. package/dist/trend/root/trend-root.js +41 -15
  272. package/dist/video/root/keys.d.ts +5 -0
  273. package/dist/video/root/keys.js +13 -1
  274. package/dist/video/root/video-root.d.ts +19 -0
  275. package/dist/video/root/video-root.js +48 -4
  276. package/dist/video-playlist/menu/video-playlist-menu.d.ts +20 -2
  277. package/dist/video-playlist/menu/video-playlist-menu.js +27 -5
  278. package/dist/video-playlist/root/video-playlist-root.js +6 -3
  279. package/dist/virtual-list/root/virtual-list-root.d.ts +52 -4
  280. package/dist/virtual-list/root/virtual-list-root.js +103 -21
  281. package/lint.json +1 -1
  282. package/package.json +5 -5
  283. package/types/jsx.d.ts +9140 -1149
  284. package/types/svelte.d.ts +1 -0
  285. package/types/vue.d.ts +2089 -267
@@ -4,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 { valueAsDate as asDate, customElement, dateAsValue as fromDate, HelixFormElement, HelixNavigateEvent, hostAria, inlineStep, MixinControllerValue, reportValues, requestChange, } from '@fusion.dev/helix-core';
7
+ import { addDays, addMonths, valueAsDate as asDate, barredBy, customElement, fillTemplate, dateAsValue as fromDate, HelixFormElement, HelixNavigateEvent, hostAria, inlineStep, commaList as list, localToday, MixinControllerValue, monthOf, monthOut, periodCells, periodKey, reportValues, requestChange, sameMonth, weekStartOf, YEARS_SHOWN, yearOut, yearPageOf, } from '@fusion.dev/helix-core';
8
8
  import { caretLeft, caretRight } from '@fusion.dev/helix-icons';
9
9
  import { html, nothing } from 'lit';
10
10
  import { property, state } from 'lit/decorators.js';
@@ -21,30 +21,12 @@ const KEYS = new Set([
21
21
  'PageUp',
22
22
  ' ',
23
23
  ]);
24
- const localToday = () => {
25
- const now = new Date();
26
- const month = `${now.getMonth() + 1}`.padStart(2, '0');
27
- const day = `${now.getDate()}`.padStart(2, '0');
28
- return `${now.getFullYear()}-${month}-${day}`;
29
- };
30
- const list = (value) => value
31
- .split(',')
32
- .map((entry) => entry.trim())
33
- .filter(Boolean);
34
- const addDays = (date, days) => new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate() + days));
35
- const sameMonth = (left, right) => left.getUTCFullYear() === right.getUTCFullYear() && left.getUTCMonth() === right.getUTCMonth();
36
- const addMonths = (date, months) => {
37
- const target = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + months, 1));
38
- const last = new Date(Date.UTC(target.getUTCFullYear(), target.getUTCMonth() + 1, 0)).getUTCDate();
39
- return new Date(Date.UTC(target.getUTCFullYear(), target.getUTCMonth(), Math.min(date.getUTCDate(), last)));
40
- };
41
24
  let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControllerValue(HelixFormElement) {
42
25
  constructor() {
43
26
  super(...arguments);
44
27
  this.defaultMonth = '';
45
28
  this.disableDates = '';
46
29
  this.disableDays = '';
47
- this.firstDayOfWeek = 0;
48
30
  this.invalid = false;
49
31
  this.label = 'Date Picker';
50
32
  this.locale = '';
@@ -52,12 +34,21 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
52
34
  this.min = '';
53
35
  this.monthState = undefined;
54
36
  this.months = 1;
37
+ this.monthViewLabel = '{heading}. Choose a month';
55
38
  this.nextLabel = 'Next month';
39
+ this.nextYearLabel = 'Next year';
40
+ this.nextYearsLabel = 'Later years';
56
41
  this.previousLabel = 'Previous month';
57
- this.readOnly = false;
42
+ this.previousYearLabel = 'Previous year';
43
+ this.previousYearsLabel = 'Earlier years';
58
44
  this.focused = '';
45
+ this.choosing = false;
59
46
  this.handleKeydown = (event) => {
60
- if (!KEYS.has(event.key) || this.disabled) {
47
+ if (this.view !== 'day') {
48
+ this.handlePeriodKeydown(event);
49
+ return;
50
+ }
51
+ if (!KEYS.has(event.key) || this.isDisabled) {
61
52
  return;
62
53
  }
63
54
  const path = event.composedPath();
@@ -80,10 +71,10 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
80
71
  this.moveTo(addDays(from, 7));
81
72
  }
82
73
  else if (event.key === 'Home') {
83
- this.moveTo(addDays(from, -((from.getUTCDay() - this.firstDayOfWeek + 7) % 7)));
74
+ this.moveTo(addDays(from, -((from.getUTCDay() - this.weekStart + 7) % 7)));
84
75
  }
85
76
  else if (event.key === 'End') {
86
- this.moveTo(addDays(from, 6 - ((from.getUTCDay() - this.firstDayOfWeek + 7) % 7)));
77
+ this.moveTo(addDays(from, 6 - ((from.getUTCDay() - this.weekStart + 7) % 7)));
87
78
  }
88
79
  else {
89
80
  const step = event.key === 'PageUp' ? -1 : 1;
@@ -91,8 +82,27 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
91
82
  }
92
83
  event.preventDefault();
93
84
  };
85
+ this.pageYear = undefined;
86
+ this.periodFocus = undefined;
87
+ this.handleHeading = () => {
88
+ if (this.isDisabled) {
89
+ return;
90
+ }
91
+ if (this.view === 'day') {
92
+ this.pageYear = this.shown.getUTCFullYear();
93
+ this.periodFocus = this.shown.getUTCMonth();
94
+ this.zoom('month');
95
+ }
96
+ else if (this.view === 'month' && this.maxView === 'year') {
97
+ this.periodFocus = this.periodYear;
98
+ this.zoom('year');
99
+ }
100
+ };
101
+ this.readOnly = false;
94
102
  this.required = false;
95
103
  this.step = 1;
104
+ this.view = 'day';
105
+ this.yearViewLabel = '{heading}. Choose a year';
96
106
  }
97
107
  get month() {
98
108
  return this.monthState ?? (this.defaultMonth || fromDate(this.derivedMonth).slice(0, 7));
@@ -105,6 +115,12 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
105
115
  get selected() {
106
116
  return list(this.value);
107
117
  }
118
+ get weekStart() {
119
+ if (this.firstDayOfWeek !== undefined && Number.isFinite(this.firstDayOfWeek)) {
120
+ return ((Math.floor(this.firstDayOfWeek) % 7) + 7) % 7;
121
+ }
122
+ return this.locale === '' ? 0 : weekStartOf(this.locale);
123
+ }
108
124
  get range() {
109
125
  const dates = this.selected;
110
126
  if (this.mode !== 'range' || dates.length < 2) {
@@ -141,7 +157,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
141
157
  return shown;
142
158
  }
143
159
  weeksOf(month) {
144
- const offset = (month.getUTCDay() - this.firstDayOfWeek + 7) % 7;
160
+ const offset = (month.getUTCDay() - this.weekStart + 7) % 7;
145
161
  const start = addDays(month, -offset);
146
162
  return Array.from({ length: 6 }, (_, week) => Array.from({ length: 7 }, (_, day) => addDays(start, week * 7 + day)));
147
163
  }
@@ -153,24 +169,32 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
153
169
  if (this.max !== '' && iso > this.max) {
154
170
  return true;
155
171
  }
156
- if (list(this.disableDays).includes(String(date.getUTCDay()))) {
157
- return true;
172
+ return barredBy(date, this) !== null;
173
+ }
174
+ clamp(date) {
175
+ const iso = fromDate(date);
176
+ const min = asDate(this.min);
177
+ const max = asDate(this.max);
178
+ if (min && iso < this.min) {
179
+ return min;
158
180
  }
159
- const step = Math.max(1, Math.floor(this.step) || 1);
160
- if (step > 1) {
161
- const base = this.min === '' ? 0 : (asDate(this.min)?.getTime() ?? 0);
162
- const days = Math.round((date.getTime() - base) / 86_400_000);
163
- if (days % step !== 0) {
164
- return true;
165
- }
181
+ if (max && iso > this.max) {
182
+ return max;
166
183
  }
167
- return list(this.disableDates).includes(iso);
184
+ return date;
185
+ }
186
+ get atStart() {
187
+ return asDate(this.min) !== null && monthOf(addMonths(this.shown, -1)) < this.min.slice(0, 7);
188
+ }
189
+ get atEnd() {
190
+ return (asDate(this.max) !== null &&
191
+ monthOf(addMonths(this.shown, this.monthCount)) > this.max.slice(0, 7));
168
192
  }
169
193
  show(date) {
170
- if (this.disabled) {
194
+ if (this.isDisabled) {
171
195
  return;
172
196
  }
173
- const next = `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, '0')}`;
197
+ const next = monthOf(date);
174
198
  if (next === this.month) {
175
199
  return;
176
200
  }
@@ -185,7 +209,8 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
185
209
  next,
186
210
  });
187
211
  }
188
- moveTo(date) {
212
+ moveTo(wanted) {
213
+ const date = this.clamp(wanted);
189
214
  this.focused = fromDate(date);
190
215
  this.show(date);
191
216
  this.updateComplete.then(() => {
@@ -193,7 +218,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
193
218
  });
194
219
  }
195
220
  select(date) {
196
- if (this.disabled) {
221
+ if (this.isDisabled) {
197
222
  return;
198
223
  }
199
224
  if (this.barred(date)) {
@@ -212,8 +237,97 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
212
237
  next = [iso];
213
238
  }
214
239
  this.focused = iso;
240
+ this.choosing = true;
215
241
  this.requestValue(next.join(','));
216
242
  }
243
+ get periodYear() {
244
+ return this.pageYear ?? this.shown.getUTCFullYear();
245
+ }
246
+ get periodStop() {
247
+ if (this.periodFocus !== undefined) {
248
+ return this.periodFocus;
249
+ }
250
+ return this.view === 'year' ? this.periodYear : this.shown.getUTCMonth();
251
+ }
252
+ monthOut(first) {
253
+ return monthOut(first, this.min, this.max);
254
+ }
255
+ yearOut(year) {
256
+ return yearOut(year, this.min, this.max);
257
+ }
258
+ zoom(view) {
259
+ this.view = view;
260
+ void this.updateComplete.then(() => this.focus());
261
+ }
262
+ choosePeriod(at) {
263
+ if (this.isDisabled) {
264
+ return;
265
+ }
266
+ if (this.view === 'year') {
267
+ if (this.yearOut(at)) {
268
+ return;
269
+ }
270
+ this.pageYear = at;
271
+ this.periodFocus = at === this.shown.getUTCFullYear() ? this.shown.getUTCMonth() : 0;
272
+ this.zoom('month');
273
+ return;
274
+ }
275
+ const first = new Date(Date.UTC(this.periodYear, at, 1));
276
+ if (this.monthOut(first)) {
277
+ return;
278
+ }
279
+ this.show(first);
280
+ if (this.month !== monthOf(first)) {
281
+ return;
282
+ }
283
+ this.pageYear = undefined;
284
+ this.periodFocus = undefined;
285
+ this.focused = '';
286
+ this.zoom('day');
287
+ }
288
+ turnPage(direction) {
289
+ const by = this.view === 'year' ? YEARS_SHOWN : 1;
290
+ this.pageYear = this.periodYear + direction * by;
291
+ if (this.view === 'year') {
292
+ this.periodFocus = this.periodStop + direction * by;
293
+ }
294
+ }
295
+ handlePeriodKeydown(event) {
296
+ if (this.isDisabled) {
297
+ return;
298
+ }
299
+ if (event.key === 'Escape') {
300
+ event.preventDefault();
301
+ event.stopPropagation();
302
+ this.pageYear = undefined;
303
+ this.periodFocus = undefined;
304
+ this.zoom('day');
305
+ return;
306
+ }
307
+ const grid = this.partNamed('periods');
308
+ if (!grid || !event.composedPath().includes(grid)) {
309
+ return;
310
+ }
311
+ const stop = this.periodStop;
312
+ if (event.key === 'Enter' || event.key === ' ') {
313
+ event.preventDefault();
314
+ this.choosePeriod(stop);
315
+ return;
316
+ }
317
+ const moved = periodKey(this.view === 'year' ? 'year' : 'month', stop, this.periodYear, event.key, inlineStep(this, event.key));
318
+ if (moved === null) {
319
+ return;
320
+ }
321
+ event.preventDefault();
322
+ this.periodFocus = moved.focus;
323
+ this.pageYear = moved.pageYear;
324
+ void this.updateComplete.then(() => this.focus());
325
+ }
326
+ focus(options) {
327
+ this.renderRoot
328
+ ?.querySelector('[part~="cell"][tabindex="0"], [part~="period"][tabindex="0"]')
329
+ ?.focus(options);
330
+ }
217
331
  connectedCallback() {
218
332
  super.connectedCallback();
219
333
  this.addEventListener('keydown', this.handleKeydown);
@@ -228,6 +342,36 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
228
342
  }
229
343
  return super.requestValue(next);
230
344
  }
345
+ spoken(iso) {
346
+ const date = asDate(iso);
347
+ return date ? this.formats.long.format(date) : iso;
348
+ }
349
+ fault(iso) {
350
+ if (this.min !== '' && iso < this.min) {
351
+ return [
352
+ 'rangeUnderflow',
353
+ fillTemplate(this.rangeUnderflowMessage || 'Choose a date on or after {min}.', {
354
+ min: this.spoken(this.min),
355
+ }),
356
+ ];
357
+ }
358
+ if (this.max !== '' && iso > this.max) {
359
+ return [
360
+ 'rangeOverflow',
361
+ fillTemplate(this.rangeOverflowMessage || 'Choose a date on or before {max}.', {
362
+ max: this.spoken(this.max),
363
+ }),
364
+ ];
365
+ }
366
+ const date = asDate(iso);
367
+ const why = date ? barredBy(date, this) : null;
368
+ if (why === null) {
369
+ return undefined;
370
+ }
371
+ return why === 'listed'
372
+ ? ['badInput', this.unavailableMessage || 'Choose a date that is available.']
373
+ : ['stepMismatch', this.stepMismatchMessage || 'Choose one of the dates the calendar offers.'];
374
+ }
231
375
  reportRequired() {
232
376
  const anchor = this.partNamed('grid') ?? undefined;
233
377
  if (this.required && this.value === '') {
@@ -242,11 +386,27 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
242
386
  : 'Enter dates as YYYY-MM-DD, separated by commas.'), anchor);
243
387
  return;
244
388
  }
389
+ for (const one of held) {
390
+ const fault = this.fault(one);
391
+ if (fault) {
392
+ this.internals.setValidity({ [fault[0]]: true }, fault[1], anchor);
393
+ return;
394
+ }
395
+ }
245
396
  this.internals.setValidity({});
246
397
  }
247
398
  willUpdate(changed) {
248
399
  super.willUpdate(changed);
249
- hostAria(this.internals, { label: this.label, role: 'group' });
400
+ if (changed.has('value') && !this.choosing) {
401
+ this.focused = '';
402
+ }
403
+ this.choosing = false;
404
+ const outside = this.label === 'Date Picker' ? [...(this.internals.labels ?? [])] : [];
405
+ hostAria(this.internals, {
406
+ label: this.label,
407
+ labelledBy: outside,
408
+ role: 'group',
409
+ });
250
410
  this.internals.ariaDisabled = this.isDisabled ? 'true' : null;
251
411
  this.internals.ariaInvalid = this.invalid ? 'true' : null;
252
412
  this.report();
@@ -256,7 +416,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
256
416
  this.reportRequired();
257
417
  }
258
418
  report() {
259
- if (this.disabled) {
419
+ if (this.isDisabled) {
260
420
  this.internals.setFormValue(null);
261
421
  return;
262
422
  }
@@ -274,7 +434,10 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
274
434
  full: new Intl.DateTimeFormat(locale, { dateStyle: 'full', timeZone: 'UTC' }),
275
435
  heading: new Intl.DateTimeFormat(locale, { month: 'long', timeZone: 'UTC', year: 'numeric' }),
276
436
  locale: this.locale,
437
+ long: new Intl.DateTimeFormat(locale, { dateStyle: 'long', timeZone: 'UTC' }),
438
+ monthName: new Intl.DateTimeFormat(locale, { month: 'short', timeZone: 'UTC' }),
277
439
  weekday: new Intl.DateTimeFormat(locale, { timeZone: 'UTC', weekday: 'short' }),
440
+ year: new Intl.DateTimeFormat(locale, { timeZone: 'UTC', year: 'numeric' }),
278
441
  };
279
442
  this.cachedFormats = built;
280
443
  return built;
@@ -308,17 +471,22 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
308
471
  part="previous"
309
472
  type="button"
310
473
  aria-label=${this.previousLabel}
474
+ ?disabled=${this.isDisabled || this.atStart}
311
475
  @click=${() => this.show(addMonths(this.shown, -1))}
312
476
  >
313
477
  ${this.renderPreviousMark()}
314
478
  </button>`
315
479
  : nothing}
316
- <span part="heading">${heading.format(month)}</span>
480
+ ${''}
481
+ <span part="heading" aria-live="polite"
482
+ >${this.renderHeadingText(heading.format(month), this.monthViewLabel)}</span
483
+ >
317
484
  ${last
318
485
  ? html `<button
319
486
  part="next"
320
487
  type="button"
321
488
  aria-label=${this.nextLabel}
489
+ ?disabled=${this.isDisabled || this.atEnd}
322
490
  @click=${() => this.show(addMonths(this.shown, 1))}
323
491
  >
324
492
  ${this.renderNextMark()}
@@ -329,6 +497,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
329
497
  part="grid"
330
498
  role="grid"
331
499
  aria-label=${heading.format(month)}
500
+ aria-readonly=${this.readOnly ? 'true' : nothing}
332
501
  data-unset=${this.value === '' ? '' : nothing}
333
502
  >
334
503
  <div part="week" role="row">
@@ -346,7 +515,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
346
515
  return html `<span
347
516
  part="cell${start ? ' cell-range-start' : ''}${middle ? ' cell-range-middle' : ''}${end ? ' cell-range-end' : ''}"
348
517
  role="gridcell"
349
- aria-disabled=${disabled ? 'true' : nothing}
518
+ aria-disabled=${disabled || outside ? 'true' : nothing}
350
519
  aria-label=${full.format(date)}
351
520
  aria-current=${iso === today ? 'date' : nothing}
352
521
  aria-selected=${!outside && selected ? 'true' : nothing}
@@ -355,11 +524,11 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
355
524
  data-range-middle=${middle ? '' : nothing}
356
525
  data-range-start=${start ? '' : nothing}
357
526
  data-today=${iso === today ? '' : nothing}
358
- tabindex=${!outside && iso === anchor ? '0' : '-1'}
527
+ tabindex=${!outside && iso === anchor && !this.isDisabled ? '0' : '-1'}
359
528
  @click=${outside ? nothing : () => this.select(date)}
360
529
  ><span
361
530
  part="day${!outside && selected && !middle ? ' day-selected' : ''}${iso === today ? ' day-today' : ''}${outside ? ' day-outside' : ''}${disabled ? ' day-disabled' : ''}"
362
- >${date.getUTCDate()}</span
531
+ >${this.renderDay(date, outside)}</span
363
532
  ></span
364
533
  >`;
365
534
  })}
@@ -367,7 +536,86 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
367
536
  </div>
368
537
  </div>`;
369
538
  }
539
+ renderDay(date, outside) {
540
+ return this.dayContent && !outside ? this.dayContent(fromDate(date)) : date.getUTCDate();
541
+ }
542
+ renderHeadingText(text, label) {
543
+ const steps = this.maxView !== undefined &&
544
+ (this.view === 'day' || (this.view === 'month' && this.maxView === 'year'));
545
+ if (!steps) {
546
+ return text;
547
+ }
548
+ return html `<button
549
+ part="heading-button"
550
+ type="button"
551
+ aria-label=${fillTemplate(label, { heading: text })}
552
+ ?disabled=${this.isDisabled}
553
+ @click=${this.handleHeading}
554
+ >${text}</button>`;
555
+ }
556
+ renderPeriods() {
557
+ const { monthName, year: yearName } = this.formats;
558
+ const years = this.view === 'year';
559
+ const page = years ? yearPageOf(this.periodYear) : this.periodYear;
560
+ const heading = years
561
+ ? `${yearName.format(new Date(Date.UTC(page, 0, 1)))} – ${yearName.format(new Date(Date.UTC(page + YEARS_SHOWN - 1, 0, 1)))}`
562
+ : yearName.format(new Date(Date.UTC(page, 0, 1)));
563
+ const stop = this.periodStop;
564
+ const cells = periodCells({
565
+ max: this.max,
566
+ min: this.min,
567
+ page: this.periodYear,
568
+ shown: this.shown,
569
+ today: localToday(),
570
+ view: years ? 'year' : 'month',
571
+ }).map(({ at, chosen, current, first, out }) => {
572
+ const words = years ? yearName.format(first) : monthName.format(first);
573
+ return html `<span
574
+ part="period${chosen ? ' period-selected' : ''}${current ? ' period-current' : ''}${out ? ' period-disabled' : ''}"
575
+ role="gridcell"
576
+ aria-current=${current ? 'date' : nothing}
577
+ aria-disabled=${out ? 'true' : nothing}
578
+ aria-label=${years ? words : `${words} ${yearName.format(first)}`}
579
+ aria-selected=${chosen ? 'true' : nothing}
580
+ tabindex=${at === stop && !this.isDisabled ? '0' : '-1'}
581
+ @click=${() => this.choosePeriod(at)}
582
+ >${words}</span
583
+ >`;
584
+ });
585
+ const rows = [0, 3, 6, 9].map((from) => html `<div part="period-row" role="row">${cells.slice(from, from + 3)}</div>`);
586
+ return html `<div part="month">
587
+ <div part="header">
588
+ <button
589
+ part="previous"
590
+ type="button"
591
+ aria-label=${years ? this.previousYearsLabel : this.previousYearLabel}
592
+ ?disabled=${this.isDisabled || this.yearOut(page - 1)}
593
+ @click=${() => this.turnPage(-1)}
594
+ >
595
+ ${this.renderPreviousMark()}
596
+ </button>
597
+ <span part="heading" aria-live="polite"
598
+ >${this.renderHeadingText(heading, this.yearViewLabel)}</span
599
+ >
600
+ <button
601
+ part="next"
602
+ type="button"
603
+ aria-label=${years ? this.nextYearsLabel : this.nextYearLabel}
604
+ ?disabled=${this.isDisabled || this.yearOut(years ? page + YEARS_SHOWN : page + 1)}
605
+ @click=${() => this.turnPage(1)}
606
+ >
607
+ ${this.renderNextMark()}
608
+ </button>
609
+ </div>
610
+ <div part="periods" role="grid" aria-label=${heading}>${rows}</div>
611
+ </div>`;
612
+ }
370
613
  render() {
614
+ if (this.view !== 'day') {
615
+ return html `<div part="months" style="--date-picker-column-count: 1">
616
+ ${this.renderPeriods()}
617
+ </div>`;
618
+ }
371
619
  const shown = this.shown;
372
620
  const count = this.monthCount;
373
621
  return html `<div part="months" style="--date-picker-column-count: ${Math.min(count, 2)}">
@@ -390,6 +638,9 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
390
638
  __decorate([
391
639
  property({ attribute: 'bad-input-message' })
392
640
  ], HelixHeadlessDatePicker.prototype, "badInputMessage", void 0);
641
+ __decorate([
642
+ property({ attribute: false })
643
+ ], HelixHeadlessDatePicker.prototype, "dayContent", void 0);
393
644
  __decorate([
394
645
  property({ attribute: 'default-month' })
395
646
  ], HelixHeadlessDatePicker.prototype, "defaultMonth", void 0);
@@ -405,6 +656,9 @@ __decorate([
405
656
  __decorate([
406
657
  property({ reflect: true, type: Boolean })
407
658
  ], HelixHeadlessDatePicker.prototype, "invalid", void 0);
659
+ __decorate([
660
+ property({ attribute: false })
661
+ ], HelixHeadlessDatePicker.prototype, "isDateUnavailable", void 0);
408
662
  __decorate([
409
663
  property()
410
664
  ], HelixHeadlessDatePicker.prototype, "label", void 0);
@@ -414,6 +668,9 @@ __decorate([
414
668
  __decorate([
415
669
  property()
416
670
  ], HelixHeadlessDatePicker.prototype, "max", void 0);
671
+ __decorate([
672
+ property({ attribute: 'max-view' })
673
+ ], HelixHeadlessDatePicker.prototype, "maxView", void 0);
417
674
  __decorate([
418
675
  property()
419
676
  ], HelixHeadlessDatePicker.prototype, "min", void 0);
@@ -426,27 +683,66 @@ __decorate([
426
683
  __decorate([
427
684
  property({ type: Number })
428
685
  ], HelixHeadlessDatePicker.prototype, "months", void 0);
686
+ __decorate([
687
+ property({ attribute: 'month-view-label' })
688
+ ], HelixHeadlessDatePicker.prototype, "monthViewLabel", void 0);
429
689
  __decorate([
430
690
  property({ attribute: 'next-label' })
431
691
  ], HelixHeadlessDatePicker.prototype, "nextLabel", void 0);
692
+ __decorate([
693
+ property({ attribute: 'next-year-label' })
694
+ ], HelixHeadlessDatePicker.prototype, "nextYearLabel", void 0);
695
+ __decorate([
696
+ property({ attribute: 'next-years-label' })
697
+ ], HelixHeadlessDatePicker.prototype, "nextYearsLabel", void 0);
432
698
  __decorate([
433
699
  property({ attribute: 'previous-label' })
434
700
  ], HelixHeadlessDatePicker.prototype, "previousLabel", void 0);
435
701
  __decorate([
436
- property({ attribute: 'readonly', reflect: true, type: Boolean })
437
- ], HelixHeadlessDatePicker.prototype, "readOnly", void 0);
702
+ property({ attribute: 'previous-year-label' })
703
+ ], HelixHeadlessDatePicker.prototype, "previousYearLabel", void 0);
704
+ __decorate([
705
+ property({ attribute: 'previous-years-label' })
706
+ ], HelixHeadlessDatePicker.prototype, "previousYearsLabel", void 0);
707
+ __decorate([
708
+ property({ attribute: 'range-overflow-message' })
709
+ ], HelixHeadlessDatePicker.prototype, "rangeOverflowMessage", void 0);
438
710
  __decorate([
439
711
  state()
440
712
  ], HelixHeadlessDatePicker.prototype, "focused", void 0);
713
+ __decorate([
714
+ state()
715
+ ], HelixHeadlessDatePicker.prototype, "pageYear", void 0);
716
+ __decorate([
717
+ state()
718
+ ], HelixHeadlessDatePicker.prototype, "periodFocus", void 0);
719
+ __decorate([
720
+ property({ attribute: 'range-underflow-message' })
721
+ ], HelixHeadlessDatePicker.prototype, "rangeUnderflowMessage", void 0);
722
+ __decorate([
723
+ property({ attribute: 'readonly', reflect: true, type: Boolean })
724
+ ], HelixHeadlessDatePicker.prototype, "readOnly", void 0);
441
725
  __decorate([
442
726
  property({ reflect: true, type: Boolean })
443
727
  ], HelixHeadlessDatePicker.prototype, "required", void 0);
444
728
  __decorate([
445
729
  property({ type: Number })
446
730
  ], HelixHeadlessDatePicker.prototype, "step", void 0);
731
+ __decorate([
732
+ property({ attribute: 'step-mismatch-message' })
733
+ ], HelixHeadlessDatePicker.prototype, "stepMismatchMessage", void 0);
734
+ __decorate([
735
+ property({ attribute: 'unavailable-message' })
736
+ ], HelixHeadlessDatePicker.prototype, "unavailableMessage", void 0);
447
737
  __decorate([
448
738
  property({ attribute: 'value-missing-message' })
449
739
  ], HelixHeadlessDatePicker.prototype, "valueMissingMessage", void 0);
740
+ __decorate([
741
+ property()
742
+ ], HelixHeadlessDatePicker.prototype, "view", void 0);
743
+ __decorate([
744
+ property({ attribute: 'year-view-label' })
745
+ ], HelixHeadlessDatePicker.prototype, "yearViewLabel", void 0);
450
746
  HelixHeadlessDatePicker = __decorate([
451
747
  customElement('helix-headless-date-picker')
452
748
  ], HelixHeadlessDatePicker);
@@ -0,0 +1,9 @@
1
+ /**
2
+ * The elements at the start of a slot that hold words and no control, up to the
3
+ * first one that is or holds a control.
4
+ *
5
+ * What a dialog is described by. A question above a form describes the dialog,
6
+ * and the form does not: a description that read out every field label would
7
+ * repeat what a reader hears again as they reach each field.
8
+ */
9
+ export declare const wordsIn: (slot: HTMLSlotElement | null) => Element[];
@@ -0,0 +1,14 @@
1
+ const CONTROL = 'a[href], audio[controls], button, details, form, iframe, input, select, textarea, video[controls], [contenteditable], [tabindex]';
2
+ const isControl = (element) => element.localName.includes('-') || element.matches(CONTROL);
3
+ export const wordsIn = (slot) => {
4
+ const words = [];
5
+ for (const one of slot?.assignedElements({ flatten: true }) ?? []) {
6
+ if (isControl(one) || [...one.querySelectorAll('*')].some(isControl)) {
7
+ break;
8
+ }
9
+ if ((one.textContent ?? '').trim() !== '') {
10
+ words.push(one);
11
+ }
12
+ }
13
+ return words;
14
+ };