@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
@@ -1,4 +1,4 @@
1
- import { HelixElement } from '@fusion.dev/helix-core';
1
+ import { AriaForwardController, HelixElement } from '@fusion.dev/helix-core';
2
2
  import { type PropertyValues, type TemplateResult } from 'lit';
3
3
  /**
4
4
  * @summary A set of destinations, with a marker on the current one.
@@ -15,7 +15,9 @@ import { type PropertyValues, type TemplateResult } from 'lit';
15
15
  *
16
16
  * The component moves a marker to the current item. It finds the current item
17
17
  * by reading `aria-current`, so the attribute that screen readers announce also
18
- * places the marker.
18
+ * places the marker. Any value but `false` counts, so a sidebar of sections on
19
+ * one page can mark the section in view with `aria-current="location"`. Where
20
+ * several are marked, `page` wins.
19
21
  *
20
22
  * Set `orientation="vertical"` to stack the destinations in a column, for a
21
23
  * sidebar.
@@ -35,8 +37,14 @@ export declare class HelixHeadlessNavigation extends HelixElement {
35
37
  private readonly indicator;
36
38
  /**
37
39
  * The landmark's name, read by screen readers.
40
+ *
41
+ * An `aria-label` or `aria-labelledby` on the host names the landmark too,
42
+ * and wins over this, so a footer navigation written the usual way is not a
43
+ * second "Main".
38
44
  */
39
45
  label: string;
46
+ /** Carries a host `aria-label` and `aria-labelledby` to the `<nav>`. */
47
+ protected readonly aria: AriaForwardController;
40
48
  /**
41
49
  * Stacks the destinations in a column, for a sidebar, where unset is a row
42
50
  * for a header or a footer. The marker follows the current destination down
@@ -4,19 +4,30 @@ 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, HelixElement, IndicatorController } from '@fusion.dev/helix-core';
7
+ import { AriaForwardController, customElement, HelixElement, IndicatorController, } from '@fusion.dev/helix-core';
8
8
  import { html } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  let HelixHeadlessNavigation = class HelixHeadlessNavigation extends HelixElement {
11
11
  constructor() {
12
12
  super(...arguments);
13
13
  this.indicator = new IndicatorController(this, {
14
- active: () => this.items.find((item) => item.getAttribute('aria-current') === 'page'),
14
+ active: () => {
15
+ const items = this.items;
16
+ const marked = (item) => {
17
+ const current = item.getAttribute('aria-current');
18
+ return current !== null && current !== 'false';
19
+ };
20
+ return (items.find((item) => item.getAttribute('aria-current') === 'page') ?? items.find(marked));
21
+ },
15
22
  indicator: () => this.partNamed('indicator'),
16
23
  observe: () => this.items,
17
24
  surface: () => this.partNamed('nav'),
18
25
  });
19
26
  this.label = 'Main';
27
+ this.aria = new AriaForwardController(this, {
28
+ label: true,
29
+ target: () => this.partNamed('nav'),
30
+ });
20
31
  }
21
32
  get items() {
22
33
  const slot = this.renderRoot.querySelector('slot');
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Where a key moves focus in a feed of `count` rows, from the row at `at`, or
3
+ * `undefined` for a key the feed does not take.
4
+ *
5
+ * `onRow` says whether focus is on the row's own box. The arrows and `Home` and
6
+ * `End` move only from there, so a control inside a row keeps its keys.
7
+ * `PageDown` and `PageUp` move from anywhere in a row, which is how the APG feed
8
+ * pattern moves on from inside an article. The answer stays inside the feed.
9
+ */
10
+ export declare const feedStep: (key: string, at: number, count: number, onRow: boolean) => number | undefined;
@@ -0,0 +1,14 @@
1
+ export const feedStep = (key, at, count, onRow) => {
2
+ if (count <= 0) {
3
+ return undefined;
4
+ }
5
+ const anywhere = { PageDown: at + 1, PageUp: at - 1 };
6
+ const fromRow = {
7
+ ArrowDown: at + 1,
8
+ ArrowUp: at - 1,
9
+ End: count - 1,
10
+ Home: 0,
11
+ };
12
+ const to = anywhere[key] ?? (onRow ? fromRow[key] : undefined);
13
+ return to === undefined ? undefined : Math.max(0, Math.min(to, count - 1));
14
+ };
@@ -33,6 +33,7 @@ declare const HelixHeadlessNotificationGroup_base: (new (...args: any[]) => impo
33
33
  *
34
34
  * @event {HelixBeforeCloseEvent} helix-before-close - Fired before the group collapses. Cancelable.
35
35
  * @event {HelixBeforeOpenEvent} helix-before-open - Fired before the group expands. Cancelable: cancel it to keep the group collapsed.
36
+ * @event {ToggleEvent} toggle - The group expanded or collapsed. The event carries `newState` and `oldState`.
36
37
  *
37
38
  * @csspart actions - The trailing region of the header.
38
39
  * @csspart count - The number of notifications in the group.
@@ -79,6 +79,12 @@ export declare class HelixHeadlessNotification extends HelixHeadlessNotification
79
79
  * Empty is the runtime's own.
80
80
  */
81
81
  locale: string;
82
+ /**
83
+ * @internal Set by the feed: this row's place in it, counting from one, read
84
+ * as `aria-posinset`. Zero leaves the place to the browser, which counts the
85
+ * rows it can see.
86
+ */
87
+ position: number;
82
88
  /**
83
89
  * Whether the notification has been read.
84
90
  *
@@ -96,6 +102,24 @@ export declare class HelixHeadlessNotification extends HelixHeadlessNotification
96
102
  */
97
103
  get read(): boolean;
98
104
  set read(next: boolean);
105
+ /**
106
+ * @internal Set by the feed: how many rows the feed holds in all, read as
107
+ * `aria-setsize`, and `-1` when nobody knows. Zero leaves it to the browser.
108
+ */
109
+ setSize: number;
110
+ /**
111
+ * @internal Set by the feed: whether `Tab` stops on this row. Every row is a
112
+ * stop until the feed has chosen one, which is also what a server sends, so
113
+ * the first render on the client is the server's.
114
+ */
115
+ stop: boolean;
116
+ /**
117
+ * What a screen reader hears before an unread notification's text.
118
+ *
119
+ * The unread mark is drawn, so a reader who cannot see it hears this word in
120
+ * its place. Translate it with the rest of your interface.
121
+ */
122
+ unreadLabel: string;
99
123
  /**
100
124
  * @internal Read by the list to identify its children across the light DOM,
101
125
  * which is cheaper than `instanceof` and is why this is public rather than
@@ -192,6 +216,11 @@ export declare class HelixHeadlessNotification extends HelixHeadlessNotification
192
216
  protected render(): TemplateResult;
193
217
  private readonly handleActions;
194
218
  private readonly handleDismiss;
219
+ /**
220
+ * Where focus goes when this row leaves: the next row's first control, the
221
+ * one before, then the first control left in the feed.
222
+ */
223
+ private neighbor;
195
224
  }
196
225
  declare global {
197
226
  interface HTMLElementTagNameMap {
@@ -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 { customElement, HelixElement, HelixReadEvent, hostAria, MixinDismissible, requestChange, slotFilled, } from '@fusion.dev/helix-core';
7
+ import { customElement, deepActiveElement, deepContains, focusableElements, HelixElement, HelixReadEvent, hostAria, MixinDismissible, requestChange, slotFilled, } from '@fusion.dev/helix-core';
8
8
  import { x } from '@fusion.dev/helix-icons';
9
9
  import { nothing } from 'lit';
10
10
  import { property } from 'lit/decorators.js';
@@ -17,6 +17,10 @@ let HelixHeadlessNotification = class HelixHeadlessNotification extends MixinDis
17
17
  this.at = '';
18
18
  this.defaultRead = false;
19
19
  this.locale = '';
20
+ this.position = 0;
21
+ this.setSize = 0;
22
+ this.stop = true;
23
+ this.unreadLabel = 'Unread';
20
24
  this.isNotification = true;
21
25
  this.readState = undefined;
22
26
  this.handleActions = () => {
@@ -25,7 +29,9 @@ let HelixHeadlessNotification = class HelixHeadlessNotification extends MixinDis
25
29
  this.handleDismiss = (event) => {
26
30
  event.stopPropagation();
27
31
  if (this.dismiss()) {
32
+ const next = deepContains(this, deepActiveElement()) ? this.neighbor() : null;
28
33
  this.remove();
34
+ next?.focus();
29
35
  }
30
36
  };
31
37
  }
@@ -55,6 +61,8 @@ let HelixHeadlessNotification = class HelixHeadlessNotification extends MixinDis
55
61
  willUpdate(changed) {
56
62
  super.willUpdate(changed);
57
63
  hostAria(this.internals, { role: 'listitem' });
64
+ this.internals.ariaPosInSet = this.position > 0 ? String(this.position) : null;
65
+ this.internals.ariaSetSize = this.setSize === 0 ? null : String(this.setSize);
58
66
  this.toggleState('read', this.read);
59
67
  }
60
68
  updated(changed) {
@@ -102,10 +110,15 @@ let HelixHeadlessNotification = class HelixHeadlessNotification extends MixinDis
102
110
  ></${stamp}>`;
103
111
  }
104
112
  render() {
105
- return html `<div part="item">
113
+ return html `<div
114
+ part="item"
115
+ role="group"
116
+ aria-labelledby="label"
117
+ tabindex=${this.stop ? 0 : -1}
118
+ >
106
119
  <span part="media"><slot name="media"></slot></span>
107
120
  <div part="body">
108
- <div part="label"><slot></slot></div>
121
+ <div id="label" part="label">${this.read ? nothing : html `<span role="img" aria-label=${this.unreadLabel}></span>`}<slot></slot></div>
109
122
  <slot name="description"></slot>
110
123
  <slot name="detail"></slot>
111
124
  <span part="actions"><slot name="actions" @slotchange=${this.handleActions}></slot></span>
@@ -116,6 +129,29 @@ let HelixHeadlessNotification = class HelixHeadlessNotification extends MixinDis
116
129
  </div>
117
130
  </div>`;
118
131
  }
132
+ neighbor() {
133
+ let feed = this.parentElement;
134
+ while (feed && !('markEveryoneRead' in feed)) {
135
+ feed = feed.parentElement;
136
+ }
137
+ const rows = feed
138
+ ? feed.items
139
+ : [...(this.parentElement?.children ?? [])].filter((one) => 'isNotification' in one);
140
+ const at = rows.indexOf(this);
141
+ const order = [...rows.slice(at + 1), ...rows.slice(0, Math.max(at, 0)).reverse()];
142
+ for (const row of order) {
143
+ const target = row.shadowRoot?.querySelector('[part="dismiss"]') ?? focusableElements(row)[0];
144
+ if (target) {
145
+ return target;
146
+ }
147
+ }
148
+ if (!feed) {
149
+ return null;
150
+ }
151
+ return (feed.shadowRoot?.querySelector('[part="mark-all"]') ??
152
+ focusableElements(feed).find((one) => !this.contains(one)) ??
153
+ null);
154
+ }
119
155
  };
120
156
  __decorate([
121
157
  property()
@@ -126,9 +162,21 @@ __decorate([
126
162
  __decorate([
127
163
  property()
128
164
  ], HelixHeadlessNotification.prototype, "locale", void 0);
165
+ __decorate([
166
+ property({ attribute: false })
167
+ ], HelixHeadlessNotification.prototype, "position", void 0);
129
168
  __decorate([
130
169
  property({ type: Boolean })
131
170
  ], HelixHeadlessNotification.prototype, "read", null);
171
+ __decorate([
172
+ property({ attribute: false })
173
+ ], HelixHeadlessNotification.prototype, "setSize", void 0);
174
+ __decorate([
175
+ property({ attribute: false })
176
+ ], HelixHeadlessNotification.prototype, "stop", void 0);
177
+ __decorate([
178
+ property({ attribute: 'unread-label' })
179
+ ], HelixHeadlessNotification.prototype, "unreadLabel", void 0);
132
180
  HelixHeadlessNotification = __decorate([
133
181
  customElement('helix-headless-notification')
134
182
  ], HelixHeadlessNotification);
@@ -21,6 +21,14 @@ declare const HelixHeadlessNotifications_base: (new (...args: any[]) => import("
21
21
  * the items and written to an attribute, so a stylesheet and a badge can both
22
22
  * use it without counting.
23
23
  *
24
+ * **The feed is one `Tab` stop for its rows.** Each row takes focus itself and
25
+ * is read by its label. `ArrowDown` and `ArrowUp` move to the next and the
26
+ * previous row, `Home` and `End` to the first and the last, and `PageDown` and
27
+ * `PageUp` move a row on or back from anywhere inside one, as in the APG feed
28
+ * pattern. The controls inside a row stay in the `Tab` order. Set `total` when
29
+ * the feed holds one page of a longer list, and each row says its place in the
30
+ * whole of it.
31
+ *
24
32
  * @since 0.1.0
25
33
  * @status stable
26
34
  * @category feedback
@@ -67,6 +75,14 @@ export declare class HelixHeadlessNotifications extends HelixHeadlessNotificatio
67
75
  * Label for the mark-all control.
68
76
  */
69
77
  markAllLabel: string;
78
+ /**
79
+ * How many notifications there are in all, where the feed holds only some of
80
+ * them, read as each row's `aria-setsize`. `-1` says the count is unknown.
81
+ *
82
+ * Unset, the browser counts the rows it can see, which is right for a feed
83
+ * that holds everything.
84
+ */
85
+ total?: number;
70
86
  /**
71
87
  * How many items are unread, counted from the items themselves.
72
88
  *
@@ -158,6 +174,32 @@ export declare class HelixHeadlessNotifications extends HelixHeadlessNotificatio
158
174
  */
159
175
  private readonly handleRead;
160
176
  private assign;
177
+ /** The row `Tab` stops on, once a reader has been to one. */
178
+ private stopRow;
179
+ /**
180
+ * The rows a reader can reach with the keys: every row in the feed, in order,
181
+ * less the ones a folded group renders nowhere.
182
+ */
183
+ private get reachable();
184
+ /** The row whose own box is the element focus is on, if it is one. */
185
+ private rowFocused;
186
+ /** A row taking focus becomes the feed's stop, so `Tab` comes back to it. */
187
+ private readonly handleFocusIn;
188
+ /**
189
+ * Moves between rows.
190
+ *
191
+ * The arrows and `Home` and `End` only from a row's own box, so a control in
192
+ * a row keeps its keys. `PageDown` and `PageUp` from anywhere in a row, which
193
+ * is how the APG feed pattern moves on from inside an article.
194
+ */
195
+ private readonly handleKeydown;
196
+ /**
197
+ * Tells each row whether it is the stop, and where it sits in the feed.
198
+ *
199
+ * Through each row's own properties, written once it has hydrated, so a
200
+ * server's markup stays the server's: every row is a stop until this runs.
201
+ */
202
+ private rove;
161
203
  connectedCallback(): void;
162
204
  disconnectedCallback(): void;
163
205
  protected willUpdate(changed: PropertyValues): void;
@@ -202,6 +244,13 @@ export declare class HelixHeadlessNotifications extends HelixHeadlessNotificatio
202
244
  private markEmpty;
203
245
  protected updated(changed: PropertyValues): void;
204
246
  protected render(): TemplateResult;
247
+ /**
248
+ * Marks everything read, and keeps focus in the feed.
249
+ *
250
+ * The button shows only while something is unread, so the press that
251
+ * succeeds removes the button it was made on. Focus moves to the first row's
252
+ * control, or the first control left in the feed.
253
+ */
205
254
  private readonly handleMarkAll;
206
255
  }
207
256
  declare global {
@@ -4,9 +4,10 @@ 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, HelixElement, HelixReadEvent, hostAria, MixinCollection, markRegion, } from '@fusion.dev/helix-core';
7
+ import { customElement, deepContains, focusableElements, HelixElement, HelixReadEvent, hostAria, MixinCollection, markRegion, rovingStop, whenHydrated, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
+ import { feedStep } from '../feed-keys.js';
10
11
  let HelixHeadlessNotifications = class HelixHeadlessNotifications extends MixinCollection(HelixElement) {
11
12
  constructor() {
12
13
  super(...arguments);
@@ -20,8 +21,53 @@ let HelixHeadlessNotifications = class HelixHeadlessNotifications extends MixinC
20
21
  this.handleRead = () => {
21
22
  queueMicrotask(() => this.requestUpdate());
22
23
  };
23
- this.handleMarkAll = () => {
24
+ this.handleFocusIn = (event) => {
25
+ const row = this.rowFocused(event.composedPath()[0]);
26
+ if (row && row !== this.stopRow) {
27
+ this.stopRow = row;
28
+ this.rove();
29
+ }
30
+ };
31
+ this.handleKeydown = (event) => {
32
+ if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey) {
33
+ return;
34
+ }
35
+ const rows = this.reachable;
36
+ const from = event.composedPath()[0];
37
+ const own = this.rowFocused(from);
38
+ const inside = own ?? rows.find((row) => from instanceof Node && deepContains(row, from));
39
+ if (!inside) {
40
+ return;
41
+ }
42
+ const to = feedStep(event.key, rows.indexOf(inside), rows.length, own !== undefined);
43
+ if (to === undefined) {
44
+ return;
45
+ }
46
+ event.preventDefault();
47
+ const next = rows[to];
48
+ if (next) {
49
+ this.stopRow = next;
50
+ this.rove();
51
+ rowBox(next)?.focus();
52
+ }
53
+ };
54
+ this.handleMarkAll = (event) => {
55
+ const button = event.currentTarget;
56
+ const focused = this.shadowRoot?.activeElement === button;
24
57
  this.markEveryoneRead();
58
+ if (!focused) {
59
+ return;
60
+ }
61
+ void this.updateComplete.then(() => {
62
+ if (button.isConnected) {
63
+ return;
64
+ }
65
+ const target = this.items
66
+ .map((row) => row.shadowRoot?.querySelector('[part="dismiss"]') ??
67
+ focusableElements(row)[0])
68
+ .find((one) => one !== undefined) ?? focusableElements(this)[0];
69
+ target?.focus();
70
+ });
25
71
  };
26
72
  }
27
73
  static { this.shadowRootOptions = {
@@ -91,13 +137,36 @@ let HelixHeadlessNotifications = class HelixHeadlessNotifications extends MixinC
91
137
  slot?.assign?.(...[...this.children].filter((child) => child.getAttribute('slot') === name));
92
138
  }
93
139
  }
140
+ get reachable() {
141
+ return this.items.filter((row) => !('assignedSlot' in row) || row.assignedSlot !== null);
142
+ }
143
+ rowFocused(target) {
144
+ return this.reachable.find((row) => rowBox(row) === target);
145
+ }
146
+ rove() {
147
+ const rows = this.reachable;
148
+ const stop = rovingStop(rows, this.stopRow);
149
+ const direct = this.rows;
150
+ for (const row of this.items) {
151
+ const position = direct.indexOf(row) + 1;
152
+ whenHydrated(row, () => {
153
+ row.stop = row === stop;
154
+ row.position = this.total === undefined ? 0 : position;
155
+ row.setSize = this.total ?? 0;
156
+ });
157
+ }
158
+ }
94
159
  connectedCallback() {
95
160
  super.connectedCallback();
96
161
  this.addEventListener('helix-read', this.handleRead);
162
+ this.addEventListener('focusin', this.handleFocusIn);
163
+ this.addEventListener('keydown', this.handleKeydown);
97
164
  }
98
165
  disconnectedCallback() {
99
166
  super.disconnectedCallback();
100
167
  this.removeEventListener('helix-read', this.handleRead);
168
+ this.removeEventListener('focusin', this.handleFocusIn);
169
+ this.removeEventListener('keydown', this.handleKeydown);
101
170
  }
102
171
  willUpdate(changed) {
103
172
  super.willUpdate(changed);
@@ -115,6 +184,7 @@ let HelixHeadlessNotifications = class HelixHeadlessNotifications extends MixinC
115
184
  this.assign();
116
185
  this.markEmpty();
117
186
  this.markMedia();
187
+ this.rove();
118
188
  const unread = this.unread > 0 ? String(this.unread) : null;
119
189
  if (this.getAttribute('unread') !== unread) {
120
190
  if (unread === null) {
@@ -152,7 +222,11 @@ __decorate([
152
222
  __decorate([
153
223
  property({ attribute: 'mark-all-label' })
154
224
  ], HelixHeadlessNotifications.prototype, "markAllLabel", void 0);
225
+ __decorate([
226
+ property({ type: Number })
227
+ ], HelixHeadlessNotifications.prototype, "total", void 0);
155
228
  HelixHeadlessNotifications = __decorate([
156
229
  customElement('helix-headless-notifications')
157
230
  ], HelixHeadlessNotifications);
158
231
  export { HelixHeadlessNotifications };
232
+ const rowBox = (row) => row.shadowRoot?.querySelector('[part="item"]') ?? null;
@@ -18,8 +18,20 @@ declare const HelixHeadlessNumberInput_base: (new (...args: any[]) => import("@f
18
18
  *
19
19
  * `inputmode="decimal"` keeps the numeric keypad on phones.
20
20
  *
21
- * Validity still comes from the platform: `min`, `max`, and `step` are mirrored
22
- * onto the host's own `setValidity`.
21
+ * `format-options` shows the number with `Intl.NumberFormat` in `locale`, as a
22
+ * currency, a percent or a unit, while the field is not being edited. Focus
23
+ * shows the number itself, and a typed `$1,200` or `25%` is read back with the
24
+ * same options. The value stays the plain number: `1200`, or `0.25` for 25%.
25
+ * The locale's group separators are read in every field, so `1,234` is a
26
+ * number in `en-US`.
27
+ *
28
+ * On iOS and iPadOS the field is a text field described as a number field,
29
+ * with no `role="spinbutton"`, which VoiceOver reads as a slider you cannot
30
+ * type in. React Aria's NumberField does the same.
31
+ *
32
+ * Validity follows the platform's rules: `min`, `max`, and `step` are checked
33
+ * and reported through the host's own `setValidity`, under the platform's flag
34
+ * names.
23
35
  *
24
36
  * Stepping is separate from typing, so a number is not corrected while you type
25
37
  * it.
@@ -31,6 +43,9 @@ declare const HelixHeadlessNumberInput_base: (new (...args: any[]) => import("@f
31
43
  * @documentation https://fusion.dev/helix/components/number-input
32
44
  *
33
45
  * @slot end - Content after the number, such as a unit.
46
+ * @slot feedback - The message that says what is wrong, for content richer than a string. It shows while there is a message.
47
+ * @slot hint - Help under the control, for content richer than the `hint` text.
48
+ * @slot label - The label, for content richer than the `label` text.
34
49
  * @slot start - Content before the number, such as a unit or an icon.
35
50
  *
36
51
  * @event {Event} change - The user finished changing the value. Relayed from the native field.
@@ -76,6 +91,16 @@ export declare class HelixHeadlessNumberInput extends HelixHeadlessNumberInput_b
76
91
  * The name of the step down button, read by screen readers.
77
92
  */
78
93
  decrementLabel: string;
94
+ /**
95
+ * `Intl.NumberFormat` options the number is shown with while the field is
96
+ * not being edited: a currency, a percent, a unit, or a number of decimals.
97
+ * Written as JSON in the attribute.
98
+ *
99
+ * ```html
100
+ * <helix-number-input format-options='{"style":"currency","currency":"EUR"}'></helix-number-input>
101
+ * ```
102
+ */
103
+ formatOptions?: Intl.NumberFormatOptions;
79
104
  /**
80
105
  * The name of the step up button, read by screen readers.
81
106
  */
@@ -88,6 +113,15 @@ export declare class HelixHeadlessNumberInput extends HelixHeadlessNumberInput_b
88
113
  * what a reader wants from a whole key.
89
114
  */
90
115
  largeStep?: number;
116
+ /**
117
+ * The locale a typed number is read in, such as `de-DE`. Empty reads it in
118
+ * the browser's language.
119
+ *
120
+ * Where the locale writes a decimal comma, `1,5` is read as one and a half,
121
+ * which is what the decimal keypad on a phone in that locale types. A dot is
122
+ * read as a decimal point in every locale.
123
+ */
124
+ locale: string;
91
125
  /**
92
126
  * The largest value allowed.
93
127
  *
@@ -120,6 +154,11 @@ export declare class HelixHeadlessNumberInput extends HelixHeadlessNumberInput_b
120
154
  * Prevents editing. The value is still submitted with the form.
121
155
  */
122
156
  readOnly: boolean;
157
+ /**
158
+ * What the field is described as on iOS and iPadOS, where it carries no
159
+ * spinbutton role. See the class description.
160
+ */
161
+ roleDescription: string;
123
162
  /**
124
163
  * Makes the label a grip that changes the value when it is dragged.
125
164
  *
@@ -132,14 +171,50 @@ export declare class HelixHeadlessNumberInput extends HelixHeadlessNumberInput_b
132
171
  */
133
172
  scrub: boolean;
134
173
  /**
135
- * How far one step moves.
174
+ * How far one step moves. A value off the step grid, counted from `min`, is
175
+ * invalid, as it is in a native number field.
136
176
  */
137
177
  step: number;
138
- /** Focus is delegated to the field, so the host is never the focus target. */
139
- static shadowRootOptions: ShadowRootInit;
178
+ /**
179
+ * The message the browser shows when the number is off the step grid, with
180
+ * `{below}` and `{above}` filled in with the nearest valid values.
181
+ */
182
+ stepMismatchMessage?: string;
183
+ /**
184
+ * What a screen reader says for the value, with `{value}` filled in, such as
185
+ * `{value} kilograms`.
186
+ *
187
+ * A unit slotted into `end` is drawn beside the number and is not part of
188
+ * what the spinbutton announces, so it goes here too. Empty announces the
189
+ * number alone.
190
+ */
191
+ valueText: string;
192
+ /**
193
+ * Whether the mouse wheel steps the number while the field has focus, as
194
+ * React Aria's NumberField does unless told not to. Off, the wheel scrolls
195
+ * the page, which is what a reader passing over a form expects.
196
+ */
197
+ wheel: boolean;
198
+ /** Whether the field has focus, so it shows the number itself and not its format. */
199
+ private editing;
200
+ /**
201
+ * What the field shows: the value as written while it is edited, and with
202
+ * `format-options` once it is not.
203
+ */
204
+ private get shown();
205
+ /** Steps on the wheel, where asked, while the field has focus. */
206
+ private readonly handleWheel;
207
+ private readonly handleFocus;
208
+ /**
209
+ * Whether this is an iPhone or an iPad, read once on the client. A server
210
+ * has no navigator and renders the spinbutton.
211
+ */
212
+ private readonly touchApple;
140
213
  private get control();
141
214
  /** The value as a number, or `null` where the field holds nothing usable. */
142
215
  private get numeric();
216
+ /** Whether `value` is on the step grid, counted from `min`. */
217
+ private onStep;
143
218
  /**
144
219
  * A value pulled into range and onto the step grid.
145
220
  *
@@ -254,7 +329,19 @@ export declare class HelixHeadlessNumberInput extends HelixHeadlessNumberInput_b
254
329
  * the same as preventing one.
255
330
  */
256
331
  private readonly handleBlur;
257
- /** Relayed, because `change` does not cross a shadow boundary on its own. */
332
+ /**
333
+ * Pulls a typed number into range and onto the step grid, and returns
334
+ * whether that moved the value.
335
+ */
336
+ private settle;
337
+ /**
338
+ * Relayed, because `change` does not cross a shadow boundary on its own.
339
+ *
340
+ * **Settled first.** The field's `change` arrives before its `blur`, so
341
+ * relaying it as it came announced the number as typed, 150 in a field whose
342
+ * `max` is 100, and the clamp that followed sent `input` alone: a consumer
343
+ * saving on `change` kept 150 while the form submitted 100.
344
+ */
258
345
  private readonly handleChange;
259
346
  /**
260
347
  * The four keys a spinner answers, which `Input` does not bind.
@@ -274,7 +361,13 @@ export declare class HelixHeadlessNumberInput extends HelixHeadlessNumberInput_b
274
361
  * message is what a native spinner would have said.
275
362
  */
276
363
  private sync;
277
- /** Puts the cursor in the field. */
364
+ /**
365
+ * Puts the cursor in the field.
366
+ *
367
+ * **No `delegatesFocus`**, because the platform's delegate is the first
368
+ * focusable element, which is the Decrease stepper: a label pressed for the
369
+ * field landed on it, and the arrows then did nothing.
370
+ */
278
371
  focus(options?: FocusOptions): void;
279
372
  /** Selects the number, so typing replaces it. */
280
373
  select(): void;
@@ -287,6 +380,15 @@ export declare class HelixHeadlessNumberInput extends HelixHeadlessNumberInput_b
287
380
  private releaseCaret;
288
381
  protected willUpdate(changed: PropertyValues): void;
289
382
  protected updated(changed: PropertyValues): void;
383
+ /**
384
+ * Enter submits the form, as it does in a native text field.
385
+ *
386
+ * On `keypress`, where the platform runs its own implicit submission, so a
387
+ * consumer who prevents the `keydown` for Enter stops this too.
388
+ */
389
+ private readonly handleKeypress;
390
+ /** @internal A single line of text counts against implicit submission. */
391
+ protected get blocksImplicitSubmission(): boolean;
290
392
  protected render(): TemplateResult;
291
393
  /**
292
394
  * The value as a number, or `NaN` while the control is empty.