@fusion.dev/helix-headless 0.145.0 → 0.146.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 (278) hide show
  1. package/custom-elements.json +7373 -3849
  2. package/dist/accordion/item/accordion-item.d.ts +14 -0
  3. package/dist/accordion/item/accordion-item.js +16 -6
  4. package/dist/accordion/root/accordion-root.d.ts +8 -5
  5. package/dist/announcement/root/announcement-root.d.ts +3 -2
  6. package/dist/announcement/root/announcement-root.js +3 -1
  7. package/dist/app-header/root/app-header-root.d.ts +7 -2
  8. package/dist/app-header/root/app-header-root.js +9 -1
  9. package/dist/app-header/sectioning.d.ts +3 -1
  10. package/dist/app-header/sectioning.js +3 -2
  11. package/dist/avatar/group/avatar-group.d.ts +20 -14
  12. package/dist/avatar/group/avatar-group.js +17 -19
  13. package/dist/badge/root/badge-root.d.ts +3 -1
  14. package/dist/badge/root/badge-root.js +2 -2
  15. package/dist/bar-chart/root/bar-chart-root.d.ts +18 -1
  16. package/dist/bar-chart/root/bar-chart-root.js +52 -15
  17. package/dist/bar-chart/stack.d.ts +15 -0
  18. package/dist/bar-chart/stack.js +19 -0
  19. package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +25 -0
  20. package/dist/breadcrumbs/root/breadcrumbs-root.js +50 -3
  21. package/dist/button/root/button-root.d.ts +26 -0
  22. package/dist/button/root/button-root.js +38 -18
  23. package/dist/button-group/root/button-group-root.d.ts +2 -1
  24. package/dist/button-group/root/button-group-root.js +5 -1
  25. package/dist/canvas/node/canvas-node.d.ts +4 -3
  26. package/dist/canvas/node/canvas-node.js +3 -2
  27. package/dist/canvas/root/canvas-root.js +2 -2
  28. package/dist/card/root/card-root.d.ts +24 -3
  29. package/dist/card/root/card-root.js +20 -8
  30. package/dist/carousel/root/carousel-root.d.ts +43 -4
  31. package/dist/carousel/root/carousel-root.js +40 -12
  32. package/dist/carousel/stops.d.ts +20 -0
  33. package/dist/carousel/stops.js +30 -0
  34. package/dist/chat/message/chat-message.js +5 -4
  35. package/dist/chat/naming.d.ts +5 -1
  36. package/dist/chat/naming.js +4 -2
  37. package/dist/chat/root/chat-root.d.ts +25 -3
  38. package/dist/chat/root/chat-root.js +22 -5
  39. package/dist/checkbox/root/checkbox-root.d.ts +20 -0
  40. package/dist/checkbox/root/checkbox-root.js +14 -1
  41. package/dist/checkbox-group/root/checkbox-group-root.d.ts +8 -2
  42. package/dist/checkbox-group/root/checkbox-group-root.js +12 -10
  43. package/dist/checkbox-group/select-all.d.ts +27 -0
  44. package/dist/checkbox-group/select-all.js +12 -0
  45. package/dist/code-block/highlight.d.ts +15 -0
  46. package/dist/code-block/highlight.js +4 -0
  47. package/dist/code-block/root/code-block-root.d.ts +49 -1
  48. package/dist/code-block/root/code-block-root.js +58 -3
  49. package/dist/color-input/root/color-input-root.d.ts +3 -0
  50. package/dist/color-input/root/color-input-root.js +6 -3
  51. package/dist/color-picker/root/color-picker-root.d.ts +33 -4
  52. package/dist/color-picker/root/color-picker-root.js +80 -21
  53. package/dist/color-picker/swatches.d.ts +12 -0
  54. package/dist/color-picker/swatches.js +26 -0
  55. package/dist/combobox/root/combobox-root.d.ts +43 -0
  56. package/dist/combobox/root/combobox-root.js +79 -15
  57. package/dist/command/root/command-root.d.ts +16 -1
  58. package/dist/command/root/command-root.js +22 -4
  59. package/dist/copy-button/root/copy-button-root.d.ts +5 -0
  60. package/dist/copy-button/root/copy-button-root.js +10 -3
  61. package/dist/data-table/index.d.ts +1 -1
  62. package/dist/data-table/index.js +1 -1
  63. package/dist/data-table/keys.d.ts +24 -0
  64. package/dist/data-table/keys.js +24 -0
  65. package/dist/data-table/root/data-table-root.d.ts +27 -18
  66. package/dist/data-table/root/data-table-root.js +20 -52
  67. package/dist/data-table/tree.d.ts +16 -1
  68. package/dist/data-table/tree.js +2 -3
  69. package/dist/date-input/root/date-input-root.d.ts +3 -1
  70. package/dist/date-input/root/date-input-root.js +18 -7
  71. package/dist/date-picker/root/date-picker-root.js +12 -6
  72. package/dist/dialog/description.js +15 -1
  73. package/dist/dialog/root/dialog-root.d.ts +8 -2
  74. package/dist/dialog/root/dialog-root.js +16 -1
  75. package/dist/divider/root/divider-root.d.ts +3 -0
  76. package/dist/divider/root/divider-root.js +2 -1
  77. package/dist/donut-chart/root/donut-chart-root.d.ts +31 -0
  78. package/dist/donut-chart/root/donut-chart-root.js +48 -1
  79. package/dist/drawer/reveal.d.ts +8 -0
  80. package/dist/drawer/reveal.js +1 -0
  81. package/dist/drawer/root/drawer-root.d.ts +59 -0
  82. package/dist/drawer/root/drawer-root.js +63 -4
  83. package/dist/drilldown/item/drilldown-item.js +1 -1
  84. package/dist/drilldown/root/drilldown-root.d.ts +21 -3
  85. package/dist/drilldown/root/drilldown-root.js +21 -3
  86. package/dist/element-events.generated.js +31 -5
  87. package/dist/empty/root/empty-root.d.ts +3 -1
  88. package/dist/empty/root/empty-root.js +3 -2
  89. package/dist/file-input/root/file-input-root.d.ts +69 -6
  90. package/dist/file-input/root/file-input-root.js +82 -19
  91. package/dist/file-input/screen.d.ts +2 -1
  92. package/dist/filter-input/menu/filter-menu.d.ts +2 -0
  93. package/dist/filter-input/menu/filter-menu.js +12 -4
  94. package/dist/filter-input/root/filter-input-root.d.ts +30 -6
  95. package/dist/filter-input/root/filter-input-root.js +1 -1
  96. package/dist/filter-input/suggest.d.ts +28 -3
  97. package/dist/filter-input/suggest.js +18 -8
  98. package/dist/format-date/root/format-date-root.d.ts +9 -16
  99. package/dist/format-date/root/format-date-root.js +10 -27
  100. package/dist/heatmap/root/heatmap-root.d.ts +24 -13
  101. package/dist/heatmap/root/heatmap-root.js +34 -12
  102. package/dist/icon/root/icon-root.d.ts +12 -1
  103. package/dist/icon/root/icon-root.js +21 -10
  104. package/dist/icon/settle.d.ts +7 -0
  105. package/dist/icon/settle.js +10 -0
  106. package/dist/icon-button/root/icon-button-root.d.ts +2 -0
  107. package/dist/image/root/image-root.d.ts +5 -1
  108. package/dist/image/root/image-root.js +1 -1
  109. package/dist/input/root/input-root.d.ts +12 -2
  110. package/dist/input/root/input-root.js +11 -2
  111. package/dist/kbd/root/kbd-root.d.ts +35 -1
  112. package/dist/kbd/root/kbd-root.js +23 -4
  113. package/dist/legend/root/legend-root.d.ts +55 -8
  114. package/dist/legend/root/legend-root.js +55 -13
  115. package/dist/lightbox/root/lightbox-root.d.ts +49 -6
  116. package/dist/lightbox/root/lightbox-root.js +86 -19
  117. package/dist/lightbox/zoom-controller.d.ts +59 -0
  118. package/dist/lightbox/zoom-controller.js +128 -0
  119. package/dist/lightbox/zoom.d.ts +22 -0
  120. package/dist/lightbox/zoom.js +16 -0
  121. package/dist/line-chart/root/line-chart-root.d.ts +22 -1
  122. package/dist/line-chart/root/line-chart-root.js +21 -1
  123. package/dist/list/item/list-item.d.ts +2 -0
  124. package/dist/list/item/list-item.js +11 -2
  125. package/dist/list/root/list-root.d.ts +62 -13
  126. package/dist/list/root/list-root.js +70 -13
  127. package/dist/list/selection.d.ts +37 -7
  128. package/dist/list/selection.js +16 -7
  129. package/dist/listbox/root/listbox-root.d.ts +37 -1
  130. package/dist/listbox/root/listbox-root.js +49 -3
  131. package/dist/loader/busy.d.ts +10 -0
  132. package/dist/loader/busy.js +11 -0
  133. package/dist/loader/root/loader-root.d.ts +9 -2
  134. package/dist/loader/root/loader-root.js +23 -3
  135. package/dist/megamenu/root/megamenu-root.d.ts +51 -10
  136. package/dist/megamenu/root/megamenu-root.js +76 -5
  137. package/dist/menu/item/menu-item.d.ts +51 -2
  138. package/dist/menu/item/menu-item.js +47 -23
  139. package/dist/menu/root/menu-root.d.ts +14 -0
  140. package/dist/menu/root/menu-root.js +2 -2
  141. package/dist/meter/root/meter-root.d.ts +20 -1
  142. package/dist/meter/root/meter-root.js +11 -15
  143. package/dist/navigation/root/navigation-root.d.ts +2 -1
  144. package/dist/navigation/root/navigation-root.js +2 -2
  145. package/dist/notifications/root/notifications-root.d.ts +10 -3
  146. package/dist/notifications/root/notifications-root.js +19 -7
  147. package/dist/number-input/root/number-input-root.d.ts +17 -8
  148. package/dist/number-input/root/number-input-root.js +2 -7
  149. package/dist/object-inspector/root/object-inspector-root.d.ts +75 -27
  150. package/dist/object-inspector/root/object-inspector-root.js +117 -76
  151. package/dist/object-inspector/rows.d.ts +18 -0
  152. package/dist/object-inspector/rows.js +33 -0
  153. package/dist/option/root/option-root.d.ts +5 -3
  154. package/dist/outline/root/outline-root.d.ts +18 -0
  155. package/dist/outline/root/outline-root.js +23 -5
  156. package/dist/pagination/size/pagination-size.d.ts +1 -0
  157. package/dist/pagination/size/pagination-size.js +1 -1
  158. package/dist/pin-input/code.d.ts +10 -0
  159. package/dist/pin-input/code.js +13 -0
  160. package/dist/pin-input/root/pin-input-root.d.ts +25 -1
  161. package/dist/pin-input/root/pin-input-root.js +10 -11
  162. package/dist/popover/hide-outside.d.ts +14 -0
  163. package/dist/popover/hide-outside.js +41 -0
  164. package/dist/popover/root/popover-root.d.ts +57 -7
  165. package/dist/popover/root/popover-root.js +58 -3
  166. package/dist/progress/root/progress-root.d.ts +20 -0
  167. package/dist/progress/root/progress-root.js +15 -15
  168. package/dist/qr-code/export.d.ts +26 -1
  169. package/dist/qr-code/export.js +14 -0
  170. package/dist/qr-code/root/qr-code-root.d.ts +19 -5
  171. package/dist/qr-code/root/qr-code-root.js +58 -9
  172. package/dist/quote/marks.d.ts +8 -0
  173. package/dist/quote/marks.js +5 -0
  174. package/dist/quote/root/quote-root.d.ts +14 -2
  175. package/dist/quote/root/quote-root.js +23 -1
  176. package/dist/radio/root/radio-root.d.ts +6 -2
  177. package/dist/radio/root/radio-root.js +6 -1
  178. package/dist/rating/root/rating-root.d.ts +9 -4
  179. package/dist/rating/root/rating-root.js +31 -7
  180. package/dist/rating/steps.d.ts +7 -0
  181. package/dist/rating/steps.js +9 -0
  182. package/dist/scatter-chart/fit.d.ts +15 -0
  183. package/dist/scatter-chart/fit.js +35 -0
  184. package/dist/scatter-chart/root/scatter-chart-root.d.ts +21 -1
  185. package/dist/scatter-chart/root/scatter-chart-root.js +30 -17
  186. package/dist/scroll-area/root/scroll-area-root.d.ts +22 -51
  187. package/dist/scroll-area/root/scroll-area-root.js +57 -173
  188. package/dist/scroll-area/scrollbar-controller.d.ts +111 -0
  189. package/dist/scroll-area/scrollbar-controller.js +172 -0
  190. package/dist/scroll-area/scrollbar.d.ts +27 -0
  191. package/dist/scroll-area/scrollbar.js +9 -0
  192. package/dist/select/root/select-root.d.ts +15 -0
  193. package/dist/select/root/select-root.js +18 -6
  194. package/dist/skeleton/root/skeleton-root.d.ts +3 -0
  195. package/dist/skeleton/root/skeleton-root.js +4 -2
  196. package/dist/skip-link/root/skip-link-root.js +2 -2
  197. package/dist/slider/root/slider-root.d.ts +41 -4
  198. package/dist/slider/root/slider-root.js +23 -3
  199. package/dist/sparkline/readings.d.ts +18 -0
  200. package/dist/sparkline/readings.js +19 -0
  201. package/dist/sparkline/root/sparkline-root.d.ts +78 -7
  202. package/dist/sparkline/root/sparkline-root.js +118 -23
  203. package/dist/speed-dial/root/speed-dial-root.js +2 -2
  204. package/dist/splitter/root/splitter-root.d.ts +7 -12
  205. package/dist/splitter/root/splitter-root.js +209 -204
  206. package/dist/stat/root/stat-root.d.ts +14 -5
  207. package/dist/stat/root/stat-root.js +21 -5
  208. package/dist/steps/reach.d.ts +5 -0
  209. package/dist/steps/reach.js +3 -0
  210. package/dist/steps/root/steps-root.d.ts +49 -3
  211. package/dist/steps/root/steps-root.js +44 -5
  212. package/dist/steps/step/step.d.ts +7 -0
  213. package/dist/steps/step/step.js +7 -2
  214. package/dist/switch/root/switch-root.d.ts +10 -0
  215. package/dist/table/column/table-column.d.ts +0 -10
  216. package/dist/table/column/table-column.js +3 -19
  217. package/dist/table/root/table-root.d.ts +31 -10
  218. package/dist/table/root/table-root.js +2 -13
  219. package/dist/tabs/panel/tab-panel.d.ts +16 -3
  220. package/dist/tabs/panel/tab-panel.js +34 -5
  221. package/dist/tabs/root/tabs-root.d.ts +12 -0
  222. package/dist/tabs/root/tabs-root.js +1 -1
  223. package/dist/tabs/tab/tab.d.ts +5 -0
  224. package/dist/tabs/tab/tab.js +5 -2
  225. package/dist/tag/group/tag-group.d.ts +31 -4
  226. package/dist/tag/group/tag-group.js +46 -7
  227. package/dist/tag/root/tag-root.js +9 -2
  228. package/dist/textarea/root/textarea-root.d.ts +28 -1
  229. package/dist/textarea/root/textarea-root.js +40 -1
  230. package/dist/time-input/root/time-input-root.d.ts +5 -1
  231. package/dist/time-input/root/time-input-root.js +16 -8
  232. package/dist/time-picker/root/time-picker-root.d.ts +18 -4
  233. package/dist/time-picker/root/time-picker-root.js +7 -10
  234. package/dist/time-picker/wheel-name.d.ts +9 -0
  235. package/dist/time-picker/wheel-name.js +15 -0
  236. package/dist/timeline/group/timeline-group.js +2 -2
  237. package/dist/toast/item/toast-item.d.ts +14 -1
  238. package/dist/toast/item/toast-item.js +22 -5
  239. package/dist/toast/root/toast-root.d.ts +6 -0
  240. package/dist/toast/root/toast-root.js +16 -1
  241. package/dist/toggle/group/toggle-group.d.ts +24 -3
  242. package/dist/toggle/group/toggle-group.js +34 -5
  243. package/dist/tooltip/root/tooltip-root.d.ts +13 -2
  244. package/dist/tooltip/root/tooltip-root.js +9 -1
  245. package/dist/tour/back.d.ts +10 -0
  246. package/dist/tour/back.js +8 -0
  247. package/dist/tour/root/tour-root.d.ts +30 -2
  248. package/dist/tour/root/tour-root.js +34 -8
  249. package/dist/tree/item/tree-item.d.ts +7 -3
  250. package/dist/tree/item/tree-item.js +3 -0
  251. package/dist/tree/root/tree-root.d.ts +24 -3
  252. package/dist/tree/root/tree-root.js +32 -13
  253. package/dist/tree/selection.js +2 -15
  254. package/dist/trend/root/trend-root.d.ts +43 -18
  255. package/dist/trend/root/trend-root.js +31 -6
  256. package/dist/video/media-events.d.ts +13 -18
  257. package/dist/video/media-events.js +1 -5
  258. package/dist/video/root/video-root.d.ts +18 -5
  259. package/dist/video/root/video-root.js +19 -10
  260. package/dist/video-playlist/menu/video-playlist-menu.d.ts +2 -0
  261. package/dist/video-playlist/menu/video-playlist-menu.js +2 -1
  262. package/dist/video-playlist/root/video-playlist-root.d.ts +7 -1
  263. package/dist/virtual-list/fill.d.ts +0 -8
  264. package/dist/virtual-list/fill.js +1 -17
  265. package/dist/virtual-list/plan.d.ts +49 -0
  266. package/dist/virtual-list/plan.js +16 -0
  267. package/dist/virtual-list/root/virtual-list-root.d.ts +114 -13
  268. package/dist/virtual-list/root/virtual-list-root.js +183 -40
  269. package/lint.json +1 -1
  270. package/package.json +8 -8
  271. package/types/jsx.d.ts +4577 -835
  272. package/types/vue.d.ts +926 -168
  273. package/dist/chat/relative-clock.d.ts +0 -39
  274. package/dist/chat/relative-clock.js +0 -31
  275. package/dist/data-table/root/order.d.ts +0 -141
  276. package/dist/data-table/root/order.js +0 -76
  277. package/dist/tag/selection.d.ts +0 -10
  278. package/dist/tag/selection.js +0 -12
@@ -27,6 +27,16 @@ declare const HelixHeadlessDrawer_base: (new (...args: any[]) => import("@fusion
27
27
  * the nearest. While a swipe moves the panel, the distance is written on it as
28
28
  * `--drawer-swipe-x` and `--drawer-swipe-y`. `swipe="false"` turns swiping off.
29
29
  *
30
+ * `snap` is the snap point the panel rests at, and `:state(snapped)` is on the
31
+ * host while that is less than the whole panel. `snapTo()` moves it to
32
+ * another. **Focus moving to a control past the
33
+ * window's edge opens the panel to its largest snap point**, so a reader
34
+ * moving through a half open sheet with `Tab` never lands on a control they
35
+ * cannot see.
36
+ *
37
+ * Set `dismissible` to draw a close control in the corner, labeled by
38
+ * `dismiss-label`, as `Dialog` draws one.
39
+ *
30
40
  * The panel's name is `label` when you set it. Otherwise it is the heading in
31
41
  * the `header` slot, or the elements an `aria-labelledby` on the host names.
32
42
  *
@@ -51,6 +61,7 @@ declare const HelixHeadlessDrawer_base: (new (...args: any[]) => import("@fusion
51
61
  * @documentation https://fusion.dev/helix/components/drawer
52
62
  *
53
63
  * @slot - The drawer's content.
64
+ * @slot dismiss-icon - Replaces the glyph inside the close control.
54
65
  * @slot footer - Content pinned below the scrolling area, such as the drawer's actions.
55
66
  * @slot header - Content pinned above the scrolling area.
56
67
  *
@@ -60,6 +71,8 @@ declare const HelixHeadlessDrawer_base: (new (...args: any[]) => import("@fusion
60
71
  * @event {ToggleEvent} toggle - Sent when the drawer opens or closes, with `newState` and `oldState`.
61
72
  *
62
73
  * @csspart content - The scrolling content region.
74
+ * @csspart dismiss - The close control, drawn when the drawer is `dismissible`.
75
+ * @csspart dismiss-mark - The glyph on the close control, where none is slotted.
63
76
  * @csspart footer - The footer region.
64
77
  * @csspart header - The header region.
65
78
  * @csspart panel - The sliding panel.
@@ -70,6 +83,7 @@ declare const HelixHeadlessDrawer_base: (new (...args: any[]) => import("@fusion
70
83
  * @cssstate entering - From the moment the drawer opens until its entrance has finished.
71
84
  * @cssstate exiting - From the moment the drawer closes until its exit has finished.
72
85
  * @cssstate open - While the drawer is open.
86
+ * @cssstate snapped - While the panel rests at a snap point that shows less than the whole panel.
73
87
  */
74
88
  export declare class HelixHeadlessDrawer extends HelixHeadlessDrawer_base {
75
89
  protected readonly commands: CommandController;
@@ -86,6 +100,18 @@ export declare class HelixHeadlessDrawer extends HelixHeadlessDrawer_base {
86
100
  * that a resting value is an attribute's absence.
87
101
  */
88
102
  closedBy?: 'any' | 'closerequest' | 'none';
103
+ /**
104
+ * Draws a control that closes the drawer, in the corner where the title is.
105
+ *
106
+ * Pressing it is `close()`, so it sends `helix-before-close` like every other
107
+ * way out.
108
+ */
109
+ dismissible: boolean;
110
+ /**
111
+ * The close control's accessible name. Translate it with the rest of your
112
+ * interface.
113
+ */
114
+ dismissLabel: string;
89
115
  /**
90
116
  * Accessible name for the panel. When it is empty, the heading in the
91
117
  * `header` slot names the panel.
@@ -153,6 +179,8 @@ export declare class HelixHeadlessDrawer extends HelixHeadlessDrawer_base {
153
179
  protected readonly phases: OpenPhaseController;
154
180
  /** How far the panel rests toward its edge, in pixels, at the snap point it settled on. */
155
181
  private rest;
182
+ /** The fraction of the panel on screen at the snap point it rests at. */
183
+ private shown;
156
184
  /** The edge the panel leaves through, from its placement and the writing direction. */
157
185
  private get edge();
158
186
  /** The panel's size along the swipe, in pixels. */
@@ -165,6 +193,30 @@ export declare class HelixHeadlessDrawer extends HelixHeadlessDrawer_base {
165
193
  private place;
166
194
  /** Brings a released swipe to rest: at a snap point, or closed through the request. */
167
195
  private settle;
196
+ /**
197
+ * The fraction of the panel on screen at the snap point it rests at, such as
198
+ * `0.5`. It is `1`, the whole panel, while the drawer is closed or has no
199
+ * `snap-points`.
200
+ */
201
+ get snap(): number;
202
+ /**
203
+ * Puts the panel at rest at a snap point, and says on the host, as
204
+ * `:state(snapped)`, while that is short of the whole panel.
205
+ */
206
+ private restAt;
207
+ /** Says whether the panel rests short of the whole, and nothing while closed. */
208
+ private markSnap;
209
+ /**
210
+ * Moves the open panel to rest at the snap point nearest `point`, a fraction
211
+ * of the panel such as `1` for the whole of it.
212
+ */
213
+ snapTo(point: number): void;
214
+ /**
215
+ * Focus moving to a control past the window's edge, in a panel resting short
216
+ * of the whole: the panel opens to its largest snap point, so the control is
217
+ * on screen.
218
+ */
219
+ private readonly handleFocusIn;
168
220
  /** Opens the drawer. */
169
221
  show(): void;
170
222
  /**
@@ -216,9 +268,16 @@ export declare class HelixHeadlessDrawer extends HelixHeadlessDrawer_base {
216
268
  * reflection keeps the fallback name.
217
269
  */
218
270
  private nameByHeader;
271
+ connectedCallback(): void;
219
272
  disconnectedCallback(): void;
220
273
  protected updated(changed: PropertyValues): void;
221
274
  protected render(): TemplateResult;
275
+ /**
276
+ * The glyph on the close control, behind a seam: slot fallback, so a
277
+ * consumer replaces it by slotting, and a method, so a tier above replaces it
278
+ * by overriding. As `Dialog` draws it.
279
+ */
280
+ protected renderDismissIcon(): TemplateResult;
222
281
  }
223
282
  declare global {
224
283
  interface HTMLElementTagNameMap {
@@ -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 { AriaForwardController, CommandController, customElement, edgeOffset, HelixElement, headingsIn, isRtl, lockScroll, MixinControllerOpen, OpenPhaseController, onUnlessFalse, parseSnapPoints, reflectElements, SwipeController, settleSwipe, snapTravel, swipeAxis, swipeEdge, towardEdge, unlockScroll, } from '@fusion.dev/helix-core';
7
+ import { AriaForwardController, CommandController, customElement, drawDismiss, drawDismissGlyph, edgeOffset, HelixElement, headingsIn, isRtl, lockScroll, MixinControllerOpen, OpenPhaseController, onUnlessFalse, parseSnapPoints, reflectElements, SwipeController, settleSwipe, snapTravel, swipeAxis, swipeEdge, towardEdge, unlockScroll, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
+ import { beyondWindow } from '../reveal.js';
10
11
  import { startsSwipe } from '../swipe-start.js';
11
12
  let HelixHeadlessDrawer = class HelixHeadlessDrawer extends MixinControllerOpen(HelixElement) {
12
13
  constructor() {
@@ -18,6 +19,8 @@ let HelixHeadlessDrawer = class HelixHeadlessDrawer extends MixinControllerOpen(
18
19
  '--toggle': () => this.toggleOpen(),
19
20
  },
20
21
  });
22
+ this.dismissible = false;
23
+ this.dismissLabel = 'Close';
21
24
  this.label = '';
22
25
  this.aria = new AriaForwardController(this, { target: () => this.panel });
23
26
  this.modal = true;
@@ -33,6 +36,7 @@ let HelixHeadlessDrawer = class HelixHeadlessDrawer extends MixinControllerOpen(
33
36
  surface: () => this.panel,
34
37
  });
35
38
  this.rest = 0;
39
+ this.shown = 1;
36
40
  this.swipes = new SwipeController(this, {
37
41
  axis: () => (this.open && this.swipe ? swipeAxis(this.edge) : undefined),
38
42
  end: (dx, dy, vx, vy) => this.settle(dx, dy, vx, vy),
@@ -40,6 +44,15 @@ let HelixHeadlessDrawer = class HelixHeadlessDrawer extends MixinControllerOpen(
40
44
  start: (target, event) => startsSwipe(target, event.pointerType, swipeAxis(this.edge), this.partNamed('content')),
41
45
  surface: () => this.panel,
42
46
  });
47
+ this.handleFocusIn = (event) => {
48
+ const target = event.composedPath()[0];
49
+ if (this.shown >= 1 || !(target instanceof Element) || typeof window === 'undefined') {
50
+ return;
51
+ }
52
+ if (beyondWindow(target.getBoundingClientRect(), window.innerWidth, window.innerHeight)) {
53
+ this.snapTo(1);
54
+ }
55
+ };
43
56
  this.handleKeydown = (event) => {
44
57
  if (event.key !== 'Escape' ||
45
58
  event.defaultPrevented ||
@@ -117,9 +130,31 @@ let HelixHeadlessDrawer = class HelixHeadlessDrawer extends MixinControllerOpen(
117
130
  return;
118
131
  }
119
132
  if (shown !== 0) {
120
- this.rest = snapTravel(size, shown);
133
+ this.restAt(shown);
121
134
  }
135
+ else {
136
+ this.place(this.rest);
137
+ }
138
+ }
139
+ get snap() {
140
+ return this.open ? this.shown : 1;
141
+ }
142
+ restAt(shown) {
143
+ this.shown = shown;
144
+ this.rest = snapTravel(this.extent, shown);
122
145
  this.place(this.rest);
146
+ this.markSnap();
147
+ }
148
+ markSnap() {
149
+ this.toggleState('snapped', this.open && this.shown < 1);
150
+ }
151
+ snapTo(point) {
152
+ if (!this.open) {
153
+ return;
154
+ }
155
+ const points = parseSnapPoints(this.snapPoints);
156
+ const nearest = points.reduce((best, one) => Math.abs(one - point) < Math.abs(best - point) ? one : best);
157
+ this.restAt(nearest);
123
158
  }
124
159
  show() {
125
160
  this.requestOpen(true);
@@ -143,8 +178,13 @@ let HelixHeadlessDrawer = class HelixHeadlessDrawer extends MixinControllerOpen(
143
178
  : headingsIn(slot?.assignedElements({ flatten: true }) ?? []);
144
179
  this.namedByHeader = reflectElements(this.panel, 'ariaLabelledByElements', heading, this.namedByHeader);
145
180
  }
181
+ connectedCallback() {
182
+ super.connectedCallback();
183
+ this.addEventListener('focusin', this.handleFocusIn);
184
+ }
146
185
  disconnectedCallback() {
147
186
  super.disconnectedCallback();
187
+ this.removeEventListener('focusin', this.handleFocusIn);
148
188
  unlockScroll(this);
149
189
  }
150
190
  updated(changed) {
@@ -152,7 +192,9 @@ let HelixHeadlessDrawer = class HelixHeadlessDrawer extends MixinControllerOpen(
152
192
  this.nameByHeader();
153
193
  if (changed.has('open') && !this.open) {
154
194
  this.rest = 0;
195
+ this.shown = 1;
155
196
  this.place(0);
197
+ this.markSnap();
156
198
  }
157
199
  if (this.open && this.modal) {
158
200
  lockScroll(this);
@@ -171,8 +213,7 @@ let HelixHeadlessDrawer = class HelixHeadlessDrawer extends MixinControllerOpen(
171
213
  else {
172
214
  panel.show();
173
215
  }
174
- this.rest = snapTravel(this.extent, parseSnapPoints(this.snapPoints)[0] ?? 1);
175
- this.place(this.rest);
216
+ this.restAt(parseSnapPoints(this.snapPoints)[0] ?? 1);
176
217
  }
177
218
  else if (!this.open && panel.open) {
178
219
  panel.close();
@@ -192,12 +233,30 @@ let HelixHeadlessDrawer = class HelixHeadlessDrawer extends MixinControllerOpen(
192
233
  <div part="header"><slot name="header" @slotchange=${this.nameByHeader}></slot></div>
193
234
  <div part="content"><slot></slot></div>
194
235
  <div part="footer"><slot name="footer"></slot></div>
236
+ ${this.dismissible
237
+ ? drawDismiss({
238
+ label: this.dismissLabel,
239
+ mark: this.renderDismissIcon(),
240
+ onDismiss: () => this.close(),
241
+ })
242
+ : nothing}
195
243
  </dialog>`;
196
244
  }
245
+ renderDismissIcon() {
246
+ return html `<slot name="dismiss-icon">
247
+ ${drawDismissGlyph()}
248
+ </slot>`;
249
+ }
197
250
  };
198
251
  __decorate([
199
252
  property({ attribute: 'closedby', reflect: true })
200
253
  ], HelixHeadlessDrawer.prototype, "closedBy", void 0);
254
+ __decorate([
255
+ property({ reflect: true, type: Boolean })
256
+ ], HelixHeadlessDrawer.prototype, "dismissible", void 0);
257
+ __decorate([
258
+ property({ attribute: 'dismiss-label' })
259
+ ], HelixHeadlessDrawer.prototype, "dismissLabel", void 0);
201
260
  __decorate([
202
261
  property()
203
262
  ], HelixHeadlessDrawer.prototype, "label", void 0);
@@ -51,7 +51,7 @@ let HelixHeadlessDrilldownItem = class HelixHeadlessDrilldownItem extends HelixE
51
51
  this.dispatchEvent(new HelixSelectEvent({ value: this.value }));
52
52
  }
53
53
  renderMark() {
54
- return html `<slot name="chevron"
54
+ return html `<slot name="chevron" aria-hidden="true"
55
55
  ><svg part="mark" data-mirror fill="currentColor" viewBox=${caretRight.viewBox} aria-hidden="true">
56
56
  ${unsafeSVG(caretRight.content)}
57
57
  </svg></slot
@@ -21,9 +21,16 @@ declare const HelixHeadlessDrilldown_base: (new (...args: any[]) => import("@fus
21
21
  * which `Menu` shares.
22
22
  *
23
23
  * After each move the host carries `data-direction`, `forward` into a page or
24
- * `back` out of one, so a stylesheet can slide the new page in from the side
25
- * the reader is going. The styled tier does, and holds still under reduced
26
- * motion.
24
+ * `back` out of one, and records `:state(forward)` or `:state(back)`, so a
25
+ * stylesheet can slide the new page in from the side the reader is going. Both
26
+ * are written again on every move, so an animation keyed on them runs for each
27
+ * page, two moves the same way included. The styled tier slides the page and
28
+ * swaps it at once under `prefers-reduced-motion`.
29
+ *
30
+ * Keys, on a row: Up and Down Arrow move between the rows, Home and End go to
31
+ * the first and the last, and a typed letter moves to the next row whose name
32
+ * starts with it. Enter, Space, or Right Arrow opens a row's page, and Left
33
+ * Arrow or Escape goes back, the two arrows swapping on a right-to-left page.
27
34
  *
28
35
  * The rows of the page showing are a `menu`, named by `label` on the top page
29
36
  * and by the page's title below it. The back button and the title sit above
@@ -50,7 +57,9 @@ declare const HelixHeadlessDrilldown_base: (new (...args: any[]) => import("@fus
50
57
  * @csspart page - The menu the rows are in.
51
58
  * @csspart title - The name of the page showing.
52
59
  *
60
+ * @cssstate back - The last move went back out of a page.
53
61
  * @cssstate drilled - A row's page is showing, so a frame around the drilldown can style itself for that depth.
62
+ * @cssstate forward - The last move went into a page.
54
63
  */
55
64
  export declare class HelixHeadlessDrilldown extends HelixHeadlessDrilldown_base {
56
65
  /**
@@ -80,6 +89,8 @@ export declare class HelixHeadlessDrilldown extends HelixHeadlessDrilldown_base
80
89
  * not suppress it.
81
90
  */
82
91
  private direction?;
92
+ /** Whether a move happened since the last update, so its marks are written again. */
93
+ private moved;
83
94
  private readonly drilldown;
84
95
  /**
85
96
  * The rows on the page showing, which is what the keys move over.
@@ -139,6 +150,13 @@ export declare class HelixHeadlessDrilldown extends HelixHeadlessDrilldown_base
139
150
  connectedCallback(): void;
140
151
  disconnectedCallback(): void;
141
152
  protected updated(changed: PropertyValues): void;
153
+ /**
154
+ * Writes which way the last move went. After a move, the marks come off and
155
+ * the page's style is read before they go back on, so an animation keyed on
156
+ * them starts again for the new page: two moves the same way would otherwise
157
+ * leave the same rule in force and the second page would arrive still.
158
+ */
159
+ private markDirection;
142
160
  /** Walks the tree marking which rows are on the page showing. */
143
161
  private mark;
144
162
  /**
@@ -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, DrilldownController, HelixElement, inlineStep, KeyboardNavigationController, keyClaimed, MixinCollection, slottedWords, } from '@fusion.dev/helix-core';
7
+ import { AriaForwardController, customElement, DrilldownController, HelixElement, inlineStep, KeyboardNavigationController, keyClaimed, MixinCollection, slottedWords, typeaheadBy, } from '@fusion.dev/helix-core';
8
8
  import { caretLeft } from '@fusion.dev/helix-icons';
9
9
  import { html, nothing } from 'lit';
10
10
  import { property, state } from 'lit/decorators.js';
@@ -15,6 +15,7 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
15
15
  super(...arguments);
16
16
  this.label = 'Navigation';
17
17
  this.backLabel = 'Back';
18
+ this.moved = false;
18
19
  this.drilldown = new DrilldownController(this, {
19
20
  isRow: (element) => 'isDrilldownItem' in element && element.isDrilldownItem === true,
20
21
  root: () => [...this.children],
@@ -37,7 +38,7 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
37
38
  })),
38
39
  reserved: () => ['ArrowLeft', 'ArrowRight'],
39
40
  selects: () => false,
40
- typeahead: (item) => item.words,
41
+ typeahead: typeaheadBy((item) => item.words),
41
42
  });
42
43
  this.handleFocusIn = (event) => {
43
44
  const item = this.drilldown.rows.find((row) => row.contains(event.target));
@@ -100,6 +101,7 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
100
101
  return;
101
102
  }
102
103
  this.direction = 'forward';
104
+ this.moved = true;
103
105
  this.updateComplete.then(() => this.items[0]?.focusItem());
104
106
  }
105
107
  back() {
@@ -108,6 +110,7 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
108
110
  return false;
109
111
  }
110
112
  this.direction = 'back';
113
+ this.moved = true;
111
114
  this.updateComplete.then(() => leaving?.focusItem());
112
115
  return true;
113
116
  }
@@ -134,12 +137,27 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
134
137
  }
135
138
  this.placeTabStop();
136
139
  this.toggleState('drilled', !this.drilldown.atRoot);
140
+ this.markDirection();
141
+ }
142
+ markDirection() {
143
+ if (this.moved) {
144
+ this.moved = false;
145
+ this.removeAttribute('data-direction');
146
+ this.toggleState('back', false);
147
+ this.toggleState('forward', false);
148
+ const page = this.partNamed('page');
149
+ if (page && typeof getComputedStyle === 'function') {
150
+ getComputedStyle(page).animationName;
151
+ }
152
+ }
137
153
  if (this.direction === undefined) {
138
154
  this.removeAttribute('data-direction');
139
155
  }
140
156
  else {
141
157
  this.setAttribute('data-direction', this.direction);
142
158
  }
159
+ this.toggleState('back', this.direction === 'back');
160
+ this.toggleState('forward', this.direction === 'forward');
143
161
  }
144
162
  mark(item, page, onPage) {
145
163
  item.onPage = onPage;
@@ -151,7 +169,7 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
151
169
  }
152
170
  }
153
171
  renderBackIcon() {
154
- return html `<slot name="back-icon"
172
+ return html `<slot name="back-icon" aria-hidden="true"
155
173
  ><svg part="back-mark" data-mirror fill="currentColor" viewBox=${caretLeft.viewBox} aria-hidden="true">
156
174
  ${unsafeSVG(caretLeft.content)}
157
175
  </svg></slot
@@ -4,6 +4,7 @@ registerElementEvents({
4
4
  'helix-headless-announcement': ['helix-dismiss'],
5
5
  'helix-headless-app-header': ['helix-scrolled'],
6
6
  'helix-headless-avatar': ['error', 'load'],
7
+ 'helix-headless-button': ['helix-press'],
7
8
  'helix-headless-callout': ['helix-dismiss'],
8
9
  'helix-headless-canvas': [
9
10
  'helix-before-move',
@@ -49,6 +50,7 @@ registerElementEvents({
49
50
  'helix-before-open',
50
51
  'helix-create',
51
52
  'helix-filter',
53
+ 'helix-load-more',
52
54
  'input',
53
55
  'toggle',
54
56
  ],
@@ -56,10 +58,11 @@ registerElementEvents({
56
58
  'helix-before-close',
57
59
  'helix-before-open',
58
60
  'helix-filter',
61
+ 'helix-load-more',
59
62
  'helix-select',
60
63
  'toggle',
61
64
  ],
62
- 'helix-headless-copy-button': ['helix-copy', 'helix-copy-error'],
65
+ 'helix-headless-copy-button': ['helix-copy', 'helix-copy-error', 'helix-press'],
63
66
  'helix-headless-data-table': [
64
67
  'helix-activate',
65
68
  'helix-expand',
@@ -114,6 +117,7 @@ registerElementEvents({
114
117
  ],
115
118
  'helix-headless-heatmap': ['helix-resize'],
116
119
  'helix-headless-icon': ['error', 'load'],
120
+ 'helix-headless-icon-button': ['helix-press'],
117
121
  'helix-headless-image': ['error', 'load'],
118
122
  'helix-headless-input': ['change', 'helix-before-change', 'helix-clear', 'input'],
119
123
  'helix-headless-kbd': ['helix-shortcut'],
@@ -128,7 +132,13 @@ registerElementEvents({
128
132
  ],
129
133
  'helix-headless-list': ['change', 'helix-action', 'helix-before-change'],
130
134
  'helix-headless-list-item': ['helix-action'],
131
- 'helix-headless-listbox': ['change', 'helix-before-change', 'helix-filter', 'input'],
135
+ 'helix-headless-listbox': [
136
+ 'change',
137
+ 'helix-before-change',
138
+ 'helix-filter',
139
+ 'helix-load-more',
140
+ 'input',
141
+ ],
132
142
  'helix-headless-map': [
133
143
  'change',
134
144
  'helix-activate',
@@ -163,9 +173,12 @@ registerElementEvents({
163
173
  'helix-headless-object-inspector': [
164
174
  'helix-activate',
165
175
  'helix-before-activate',
176
+ 'helix-before-close',
177
+ 'helix-before-open',
166
178
  'helix-copy',
167
179
  'helix-filter',
168
180
  'helix-filtered',
181
+ 'toggle',
169
182
  ],
170
183
  'helix-headless-option': ['helix-select'],
171
184
  'helix-headless-outline': ['helix-activate'],
@@ -176,7 +189,13 @@ registerElementEvents({
176
189
  'helix-headless-qr-code': ['error'],
177
190
  'helix-headless-radio': ['helix-select'],
178
191
  'helix-headless-radio-group': ['change', 'helix-before-change', 'helix-select', 'input'],
179
- 'helix-headless-rating': ['change', 'helix-before-change', 'helix-clear', 'input'],
192
+ 'helix-headless-rating': [
193
+ 'change',
194
+ 'helix-before-change',
195
+ 'helix-clear',
196
+ 'helix-preview',
197
+ 'input',
198
+ ],
180
199
  'helix-headless-scroll-area': ['scroll', 'scrollend'],
181
200
  'helix-headless-select': [
182
201
  'change',
@@ -184,6 +203,7 @@ registerElementEvents({
184
203
  'helix-before-close',
185
204
  'helix-before-open',
186
205
  'helix-filter',
206
+ 'helix-load-more',
187
207
  'input',
188
208
  'toggle',
189
209
  ],
@@ -210,7 +230,7 @@ registerElementEvents({
210
230
  'helix-headless-tabs': ['helix-activate', 'helix-before-activate', 'helix-select'],
211
231
  'helix-headless-tag': ['helix-dismiss'],
212
232
  'helix-headless-tag-group': ['change', 'helix-before-change', 'helix-dismiss'],
213
- 'helix-headless-textarea': ['change', 'helix-before-change', 'input'],
233
+ 'helix-headless-textarea': ['change', 'helix-before-change', 'helix-clear', 'input'],
214
234
  'helix-headless-time-input': [
215
235
  'change',
216
236
  'helix-before-change',
@@ -232,6 +252,7 @@ registerElementEvents({
232
252
  'helix-before-open',
233
253
  'helix-complete',
234
254
  'helix-tour-ask',
255
+ 'helix-tour-status',
235
256
  'toggle',
236
257
  ],
237
258
  'helix-headless-tour-stop': ['helix-tour-ask'],
@@ -273,5 +294,10 @@ registerElementEvents({
273
294
  'helix-headless-video-playlist': ['helix-activate', 'helix-before-activate', 'helix-end'],
274
295
  'helix-headless-video-playlist-item': ['helix-select'],
275
296
  'helix-headless-video-playlist-menu': ['helix-select'],
276
- 'helix-headless-virtual-list': ['helix-load-more', 'helix-range-change'],
297
+ 'helix-headless-virtual-list': [
298
+ 'change',
299
+ 'helix-before-change',
300
+ 'helix-load-more',
301
+ 'helix-range-change',
302
+ ],
277
303
  });
@@ -11,7 +11,9 @@ import { type TemplateResult } from 'lit';
11
11
  * was loading, and the announcement tells a screen reader user that the search
12
12
  * returned nothing. It is announced from a status region of its own, which is
13
13
  * rendered empty and filled a frame after the view appears. Screen readers read
14
- * a region that arrives with its text already in it inconsistently.
14
+ * a region that arrives with its text already in it inconsistently. For the
15
+ * seven seconds the region holds its copy, the heading and the message are
16
+ * hidden from screen readers, so the words are in the page once.
15
17
  *
16
18
  * Every region is a bare slot. There is no `empty-state-heading` or
17
19
  * `empty-state-actions` element: assign your own heading and actions to the
@@ -18,9 +18,10 @@ let HelixHeadlessEmpty = class HelixHeadlessEmpty extends HelixElement {
18
18
  }
19
19
  render() {
20
20
  const say = () => this.arrival.say();
21
+ const copied = this.arrival.said !== '' && !this.noAnnounce ? 'true' : nothing;
21
22
  return html `<slot name="icon"></slot>
22
- <slot name="heading" @slotchange=${say}></slot>
23
- <slot @slotchange=${say}></slot>
23
+ <slot aria-hidden=${copied} name="heading" @slotchange=${say}></slot>
24
+ <slot aria-hidden=${copied} @slotchange=${say}></slot>
24
25
  <slot name="actions"></slot>
25
26
  ${this.noAnnounce
26
27
  ? nothing
@@ -20,7 +20,22 @@ declare const HelixHeadlessFileInput_base: (new (...args: any[]) => import("@fus
20
20
  * is screened: `accept`, `max-file-size`, `max-files` and your own `validate`
21
21
  * can refuse it. A refused file is left out, `helix-reject` lists each one with
22
22
  * its reason, and a reader hears `rejected-text` with the names filled in.
23
- * `directory` asks the picker for a folder.
23
+ * A reader also hears `added-text` for the files a drop or a paste adds, and
24
+ * `removed-text` for a file a remove button takes out, since neither moves
25
+ * focus or says anything on its own. `directory` asks the picker for a folder. `transformFiles` changes the files
26
+ * a field takes before it holds them, such as shrinking an image.
27
+ *
28
+ * Each chosen file is a row: its name, its size and type as tags, and a
29
+ * remove button. `renderFile` draws the row's details your own way, and the
30
+ * `remove-icon` slot replaces the button's icon.
31
+ *
32
+ * **Keyboard.** The input is the tab stop, and each file's remove button is
33
+ * one more.
34
+ *
35
+ * | Key | What it does |
36
+ * |---|---|
37
+ * | Enter, Space | On the input, opens the picker. On a remove button, removes that file and moves focus to the button of the file in its place, or back to the input. |
38
+ * | Control+V, Command+V | Takes files from the clipboard, as a drop does. |
24
39
  *
25
40
  * @since 0.1.0
26
41
  * @status stable
@@ -31,6 +46,7 @@ declare const HelixHeadlessFileInput_base: (new (...args: any[]) => import("@fus
31
46
  * @slot feedback - The message that says what is wrong with the chosen files.
32
47
  * @slot hint - Help under the field.
33
48
  * @slot label - The label, for content richer than the `label` text.
49
+ * @slot remove-icon - The icon on each file's remove button, in place of the bin. Each button shows a copy.
34
50
  * @slot trigger - The content that opens the picker when pressed.
35
51
  *
36
52
  * @event {Event} change - Fired after the value changes.
@@ -53,7 +69,7 @@ declare const HelixHeadlessFileInput_base: (new (...args: any[]) => import("@fus
53
69
  * @csspart kind-start - The category before the label.
54
70
  * @csspart label - The label above the field.
55
71
  * @csspart list - The chosen files.
56
- * @csspart live - The live region that says `rejected-text` when files are refused. It is rendered from the first refusal.
72
+ * @csspart live - The live region that says `added-text`, `rejected-text`, and `removed-text`. It is rendered from the first time it has something to say.
57
73
  * @csspart meta - The row that holds a file's size and type.
58
74
  * @csspart name - A file's name.
59
75
  * @csspart remove - The control that removes a file.
@@ -66,6 +82,8 @@ declare const HelixHeadlessFileInput_base: (new (...args: any[]) => import("@fus
66
82
  * @csspart size-start - The category before the label.
67
83
  * @csspart trigger - The label that opens the picker.
68
84
  *
85
+ * @cssstate dropping - Files are being dragged over the field.
86
+ * @cssstate has-files - The field holds at least one file.
69
87
  * @cssstate invalid - The control has an error to show, from the browser's validation or from your `feedback`.
70
88
  */
71
89
  export declare class HelixHeadlessFileInput extends HelixHeadlessFileInput_base {
@@ -77,6 +95,11 @@ export declare class HelixHeadlessFileInput extends HelixHeadlessFileInput_base
77
95
  * filter is the only check the platform makes and a drop never meets it.
78
96
  */
79
97
  accept: string;
98
+ /**
99
+ * What a reader hears when a drop or a paste adds files, with `{names}` and
100
+ * `{count}` filled in.
101
+ */
102
+ addedText: string;
80
103
  /**
81
104
  * Which camera or microphone a mobile picker should offer, if any.
82
105
  */
@@ -110,6 +133,10 @@ export declare class HelixHeadlessFileInput extends HelixHeadlessFileInput_base
110
133
  * filled in.
111
134
  */
112
135
  rejectedText: string;
136
+ /**
137
+ * What a reader hears when a file is removed, with `{name}` filled in.
138
+ */
139
+ removedText: string;
113
140
  /**
114
141
  * The accessible name of the control that removes a file. `{name}` is
115
142
  * replaced with the file's name.
@@ -119,6 +146,19 @@ export declare class HelixHeadlessFileInput extends HelixHeadlessFileInput_base
119
146
  * `{name}` has it added after it.
120
147
  */
121
148
  removeLabel: string;
149
+ /**
150
+ * Draws a file's row in place of its name, size, and type: a Lit template, a
151
+ * string, or a DOM node, given the file and its place in the list. The
152
+ * remove button stays beside it.
153
+ */
154
+ renderFile?: (file: File, index: number) => unknown;
155
+ /**
156
+ * Your own step between taking files and holding them, such as shrinking an
157
+ * image, as Zag's file upload `transformFiles`. It is given the files taken
158
+ * from one pick, drop, or paste and returns the files to hold, or a promise
159
+ * of them. A promise that rejects refuses those files, with its message.
160
+ */
161
+ transformFiles?: (files: File[]) => File[] | Promise<File[]>;
122
162
  /**
123
163
  * The trigger's text when nothing is slotted into it.
124
164
  */
@@ -128,15 +168,38 @@ export declare class HelixHeadlessFileInput extends HelixHeadlessFileInput_base
128
168
  * nothing to take it. A property, since a function cannot be an attribute.
129
169
  */
130
170
  validate?: (file: File) => string | null | undefined;
131
- /** The live region, rendered from the first refusal. */
171
+ /** The live region, rendered from the first time it has something to say. */
132
172
  private readonly status;
133
173
  /**
134
174
  * Screens arriving files and commits what is taken, after the files the
135
- * field keeps. Refused files are announced and said.
175
+ * field keeps, through `transformFiles` where it is set.
136
176
  */
137
177
  private take;
138
- /** Sends `helix-reject` and says which files were left out. */
139
- private refuse;
178
+ /**
179
+ * Commits what an arrival leaves, sends `helix-reject` for what it refused,
180
+ * and says both.
181
+ *
182
+ * Nothing taken and nothing moved, as when every dropped file is refused, is
183
+ * no change to announce. A pick is the platform's own `change`, relayed
184
+ * whatever it holds, and the picker itself tells a reader what was chosen,
185
+ * so `added-text` is said for a drop or a paste only.
186
+ */
187
+ private finish;
188
+ /**
189
+ * A sentence about some files, with `{count}` and `{names}` filled in.
190
+ *
191
+ * The names as the page's language lists them, which in English is the comma
192
+ * list it always was: `unit` and `short` join with commas and no "and". The
193
+ * count is written as the language writes a number.
194
+ */
195
+ private listed;
196
+ /** The element slotted into `remove-icon`, which each remove button copies. */
197
+ private removeIcon;
198
+ /** One copy of `removeIcon` per row, kept so a render does not replace it. */
199
+ private readonly removeIcons;
200
+ private readonly handleRemoveIcon;
201
+ /** The icon on one row's remove button: a copy of `remove-icon`, or the bin. */
202
+ private removeMark;
140
203
  /** Takes files pasted onto the field, as a drop takes them. */
141
204
  private readonly handlePaste;
142
205
  /**