@fusion.dev/helix-headless 0.0.0-dev → 0.0.3

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 (210) hide show
  1. package/custom-elements.json +4513 -4483
  2. package/dist/accordion/item/accordion-item.d.ts +13 -15
  3. package/dist/accordion/item/accordion-item.js +15 -17
  4. package/dist/announcement/root/announcement-root.d.ts +7 -25
  5. package/dist/announcement/root/announcement-root.js +7 -20
  6. package/dist/app-header/root/app-header-root.d.ts +10 -17
  7. package/dist/app-header/root/app-header-root.js +9 -18
  8. package/dist/avatar/group/avatar-group.d.ts +10 -19
  9. package/dist/avatar/group/avatar-group.js +12 -17
  10. package/dist/avatar/root/avatar-root.d.ts +8 -8
  11. package/dist/avatar/root/avatar-root.js +19 -20
  12. package/dist/badge/root/badge-root.d.ts +6 -6
  13. package/dist/badge/root/badge-root.js +13 -13
  14. package/dist/bar-chart/root/bar-chart-root.d.ts +21 -29
  15. package/dist/bar-chart/root/bar-chart-root.js +42 -57
  16. package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +12 -18
  17. package/dist/breadcrumbs/breadcrumb/breadcrumb.js +13 -16
  18. package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +9 -28
  19. package/dist/breadcrumbs/root/breadcrumbs-root.js +9 -28
  20. package/dist/button/root/button-root.d.ts +84 -94
  21. package/dist/button/root/button-root.js +82 -92
  22. package/dist/callout/root/callout-root.d.ts +4 -5
  23. package/dist/carousel/root/carousel-root.d.ts +59 -71
  24. package/dist/carousel/root/carousel-root.js +73 -101
  25. package/dist/chat/composer/chat-composer.d.ts +29 -33
  26. package/dist/chat/composer/chat-composer.js +40 -44
  27. package/dist/chat/message/chat-message.d.ts +25 -25
  28. package/dist/chat/message/chat-message.js +26 -26
  29. package/dist/chat/root/chat-root.d.ts +28 -41
  30. package/dist/chat/root/chat-root.js +27 -40
  31. package/dist/checkbox/root/checkbox-root.d.ts +10 -12
  32. package/dist/checkbox/root/checkbox-root.js +29 -35
  33. package/dist/checkbox-group/root/checkbox-group-root.d.ts +32 -45
  34. package/dist/checkbox-group/root/checkbox-group-root.js +53 -79
  35. package/dist/code-block/root/code-block-root.d.ts +3 -4
  36. package/dist/code-block/root/code-block-root.js +8 -12
  37. package/dist/color-input/root/color-input-root.d.ts +36 -37
  38. package/dist/color-input/root/color-input-root.js +29 -34
  39. package/dist/color-picker/color.d.ts +7 -8
  40. package/dist/color-picker/color.js +7 -8
  41. package/dist/color-picker/root/color-picker-root.d.ts +55 -57
  42. package/dist/color-picker/root/color-picker-root.js +60 -64
  43. package/dist/combobox/root/combobox-root.d.ts +53 -58
  44. package/dist/combobox/root/combobox-root.js +85 -94
  45. package/dist/command/root/command-root.d.ts +8 -8
  46. package/dist/command/root/command-root.js +29 -33
  47. package/dist/copy-button/root/copy-button-root.d.ts +21 -24
  48. package/dist/copy-button/root/copy-button-root.js +25 -35
  49. package/dist/data-table/root/data-table-root.d.ts +77 -76
  50. package/dist/data-table/root/data-table-root.js +95 -84
  51. package/dist/data-table/root/order.d.ts +2 -2
  52. package/dist/data-table/root/order.js +1 -3
  53. package/dist/date-input/root/date-input-root.d.ts +88 -93
  54. package/dist/date-input/root/date-input-root.js +147 -158
  55. package/dist/date-picker/root/date-picker-root.d.ts +75 -83
  56. package/dist/date-picker/root/date-picker-root.js +120 -143
  57. package/dist/dialog/root/dialog-root.d.ts +41 -24
  58. package/dist/dialog/root/dialog-root.js +47 -24
  59. package/dist/divider/root/divider-root.d.ts +5 -6
  60. package/dist/divider/root/divider-root.js +4 -5
  61. package/dist/donut-chart/root/donut-chart-root.d.ts +22 -25
  62. package/dist/donut-chart/root/donut-chart-root.js +37 -51
  63. package/dist/drawer/root/drawer-root.d.ts +24 -29
  64. package/dist/drawer/root/drawer-root.js +15 -22
  65. package/dist/drilldown/item/drilldown-item.d.ts +14 -14
  66. package/dist/drilldown/item/drilldown-item.js +24 -26
  67. package/dist/drilldown/root/drilldown-root.d.ts +8 -10
  68. package/dist/drilldown/root/drilldown-root.js +6 -7
  69. package/dist/element-events.generated.js +1 -1
  70. package/dist/file-input/root/file-input-root.d.ts +20 -24
  71. package/dist/file-input/root/file-input-root.js +42 -57
  72. package/dist/format-date/root/format-date-root.js +1 -1
  73. package/dist/heatmap/root/buckets.d.ts +8 -8
  74. package/dist/heatmap/root/buckets.js +8 -8
  75. package/dist/heatmap/root/heatmap-root.d.ts +57 -63
  76. package/dist/heatmap/root/heatmap-root.js +72 -83
  77. package/dist/icon/root/icon-root.d.ts +4 -4
  78. package/dist/icon/root/icon-root.js +9 -9
  79. package/dist/icon-button/root/icon-button-root.d.ts +4 -6
  80. package/dist/icon-button/root/icon-button-root.js +4 -6
  81. package/dist/image/root/image-root.d.ts +49 -59
  82. package/dist/image/root/image-root.js +55 -65
  83. package/dist/index.d.ts +5 -5
  84. package/dist/index.js +5 -5
  85. package/dist/input/root/input-root.d.ts +61 -85
  86. package/dist/input/root/input-root.js +79 -106
  87. package/dist/kbd/root/kbd-root.d.ts +8 -7
  88. package/dist/kbd/root/kbd-root.js +71 -11
  89. package/dist/legend/root/legend-root.d.ts +1 -1
  90. package/dist/legend/root/legend-root.js +4 -5
  91. package/dist/line-chart/root/line-chart-root.d.ts +26 -30
  92. package/dist/line-chart/root/line-chart-root.js +10 -10
  93. package/dist/list/item/list-item.d.ts +14 -18
  94. package/dist/list/item/list-item.js +18 -22
  95. package/dist/list/root/list-root.d.ts +4 -4
  96. package/dist/list/root/list-root.js +3 -3
  97. package/dist/listbox/root/listbox-root.d.ts +31 -58
  98. package/dist/listbox/root/listbox-root.js +66 -109
  99. package/dist/megamenu/root/megamenu-root.d.ts +34 -35
  100. package/dist/megamenu/root/megamenu-root.js +53 -58
  101. package/dist/menu/item/menu-item.d.ts +39 -53
  102. package/dist/menu/item/menu-item.js +50 -64
  103. package/dist/menu/root/menu-root.d.ts +30 -40
  104. package/dist/menu/root/menu-root.js +49 -82
  105. package/dist/meter/root/meter-root.d.ts +49 -53
  106. package/dist/meter/root/meter-root.js +22 -27
  107. package/dist/navigation/root/navigation-root.js +11 -19
  108. package/dist/notifications/notification/notification.d.ts +16 -22
  109. package/dist/notifications/notification/notification.js +21 -27
  110. package/dist/notifications/root/notifications-root.d.ts +31 -39
  111. package/dist/notifications/root/notifications-root.js +41 -52
  112. package/dist/number-input/root/number-input-root.d.ts +31 -33
  113. package/dist/number-input/root/number-input-root.js +37 -39
  114. package/dist/option/root/option-root.d.ts +73 -74
  115. package/dist/option/root/option-root.js +62 -64
  116. package/dist/outline/root/outline-root.d.ts +38 -44
  117. package/dist/outline/root/outline-root.js +66 -82
  118. package/dist/pagination/root/pagination-root.d.ts +87 -92
  119. package/dist/pagination/root/pagination-root.js +116 -123
  120. package/dist/pagination/size/pagination-size.d.ts +31 -50
  121. package/dist/pagination/size/pagination-size.js +35 -55
  122. package/dist/pagination/summary/pagination-summary.d.ts +12 -12
  123. package/dist/pagination/summary/pagination-summary.js +18 -18
  124. package/dist/pin-input/root/pin-input-root.d.ts +53 -70
  125. package/dist/pin-input/root/pin-input-root.js +74 -94
  126. package/dist/popover/root/popover-root.d.ts +15 -20
  127. package/dist/popover/root/popover-root.js +19 -36
  128. package/dist/progress/root/progress-root.d.ts +12 -14
  129. package/dist/progress/root/progress-root.js +22 -25
  130. package/dist/qr-code/root/qr-code-root.d.ts +11 -11
  131. package/dist/qr-code/root/qr-code-root.js +12 -14
  132. package/dist/radio/group/radio-group.js +19 -26
  133. package/dist/radio/root/radio-root.d.ts +12 -13
  134. package/dist/radio/root/radio-root.js +12 -13
  135. package/dist/rating/root/rating-root.d.ts +25 -30
  136. package/dist/rating/root/rating-root.js +43 -50
  137. package/dist/scroll-area/root/scroll-area-root.d.ts +11 -14
  138. package/dist/scroll-area/root/scroll-area-root.js +39 -33
  139. package/dist/select/root/select-root.d.ts +7 -12
  140. package/dist/select/root/select-root.js +40 -55
  141. package/dist/slider/root/slider-root.d.ts +53 -60
  142. package/dist/slider/root/slider-root.js +74 -85
  143. package/dist/sparkline/root/sparkline-root.d.ts +43 -47
  144. package/dist/sparkline/root/sparkline-root.js +23 -32
  145. package/dist/speed-dial/item/speed-dial-item.d.ts +6 -6
  146. package/dist/speed-dial/item/speed-dial-item.js +9 -9
  147. package/dist/speed-dial/root/speed-dial-root.d.ts +21 -25
  148. package/dist/speed-dial/root/speed-dial-root.js +32 -40
  149. package/dist/splitter/root/splitter-root.d.ts +98 -111
  150. package/dist/splitter/root/splitter-root.js +96 -123
  151. package/dist/stat/root/stat-root.d.ts +2 -7
  152. package/dist/stat/root/stat-root.js +0 -5
  153. package/dist/steps/step/step.d.ts +19 -24
  154. package/dist/steps/step/step.js +27 -32
  155. package/dist/switch/root/switch-root.js +2 -2
  156. package/dist/table/column/table-column.d.ts +54 -60
  157. package/dist/table/column/table-column.js +95 -68
  158. package/dist/table/root/table-root.d.ts +5 -6
  159. package/dist/table/root/table-root.js +7 -10
  160. package/dist/tabs/panel/tab-panel.d.ts +21 -25
  161. package/dist/tabs/panel/tab-panel.js +25 -29
  162. package/dist/tabs/root/tabs-root.d.ts +25 -34
  163. package/dist/tabs/root/tabs-root.js +22 -28
  164. package/dist/tabs/tab/tab.d.ts +12 -12
  165. package/dist/tabs/tab/tab.js +19 -20
  166. package/dist/textarea/root/textarea-root.d.ts +36 -36
  167. package/dist/textarea/root/textarea-root.js +43 -47
  168. package/dist/time-input/root/time-input-root.d.ts +58 -68
  169. package/dist/time-input/root/time-input-root.js +62 -77
  170. package/dist/time-picker/root/time-picker-root.d.ts +73 -79
  171. package/dist/time-picker/root/time-picker-root.js +72 -84
  172. package/dist/timeline/item/timeline-item.d.ts +8 -11
  173. package/dist/timeline/item/timeline-item.js +8 -11
  174. package/dist/timeline/root/timeline-root.d.ts +5 -7
  175. package/dist/timeline/root/timeline-root.js +5 -7
  176. package/dist/toast/item/toast-item.d.ts +9 -27
  177. package/dist/toast/item/toast-item.js +19 -41
  178. package/dist/toast/root/toast-root.d.ts +10 -14
  179. package/dist/toast/root/toast-root.js +4 -5
  180. package/dist/toggle/group/toggle-group.d.ts +6 -15
  181. package/dist/toggle/group/toggle-group.js +21 -36
  182. package/dist/toggle/root/toggle-root.d.ts +26 -27
  183. package/dist/toggle/root/toggle-root.js +30 -31
  184. package/dist/toolbar/root/toolbar-root.d.ts +7 -10
  185. package/dist/toolbar/root/toolbar-root.js +10 -14
  186. package/dist/tooltip/root/tooltip-root.d.ts +52 -59
  187. package/dist/tooltip/root/tooltip-root.js +98 -93
  188. package/dist/tour/root/tour-root.d.ts +19 -23
  189. package/dist/tour/root/tour-root.js +31 -41
  190. package/dist/tour/stop/tour-stop.d.ts +14 -15
  191. package/dist/tour/stop/tour-stop.js +31 -34
  192. package/dist/tree/item/tree-item.d.ts +30 -35
  193. package/dist/tree/item/tree-item.js +43 -55
  194. package/dist/tree/root/tree-root.d.ts +7 -10
  195. package/dist/tree/root/tree-root.js +33 -42
  196. package/dist/trend/root/trend-root.d.ts +3 -5
  197. package/dist/trend/root/trend-root.js +5 -9
  198. package/dist/video/root/video-root.d.ts +100 -124
  199. package/dist/video/root/video-root.js +142 -176
  200. package/dist/video-playlist/item/video-playlist-item.d.ts +16 -16
  201. package/dist/video-playlist/item/video-playlist-item.js +24 -24
  202. package/dist/video-playlist/menu/video-playlist-menu.d.ts +5 -8
  203. package/dist/video-playlist/menu/video-playlist-menu.js +20 -29
  204. package/dist/video-playlist/root/video-playlist-root.d.ts +16 -11
  205. package/dist/video-playlist/root/video-playlist-root.js +21 -25
  206. package/dist/virtual-list/root/virtual-list-root.d.ts +8 -12
  207. package/dist/virtual-list/root/virtual-list-root.js +11 -16
  208. package/jsx.d.ts +9797 -12561
  209. package/package.json +6 -6
  210. package/vue.d.ts +2684 -3228
@@ -12,8 +12,7 @@ import { type PropertyValues, type TemplateResult } from 'lit';
12
12
  * component renders a pane per slide carrying `role="group"`,
13
13
  * `aria-roledescription="slide"` and a name reading its position in the set,
14
14
  * and assigns the slide into it: a screen-reader user hears where they are, and
15
- * a slide that is itself a link is still a link, which it was not while the role
16
- * was being written on top of it. See `assign`.
15
+ * a slide that is itself a link is still a link. See `assign`.
17
16
  *
18
17
  * **Rotation stops on focus and on hover, and once stopped it stays stopped.**
19
18
  * The APG is explicit: rotation must not resume unless the reader asks for it,
@@ -57,9 +56,9 @@ export declare class HelixHeadlessCarousel extends HelixElement {
57
56
  */
58
57
  static shadowRootOptions: ShadowRootInit;
59
58
  /**
60
- * Accessible name for the carousel.
59
+ * Whether the carousel advances on its own.
61
60
  */
62
- label: string;
61
+ autoplay: boolean;
63
62
  /**
64
63
  * The slide in view, counted from zero.
65
64
  *
@@ -74,26 +73,9 @@ export declare class HelixHeadlessCarousel extends HelixElement {
74
73
  * extracted, because a slide is addressed by position and every one of those
75
74
  * mixins is keyed by a name. One consumer is not a mixin: if a second numeric
76
75
  * state turns up, this is what it is extracted from.
77
- *
78
- *
79
76
  */
80
77
  get index(): number;
81
78
  set index(next: number);
82
- /**
83
- * Which way the track runs.
84
- *
85
- * Behavior rather than presentation, which is why it is here: the scroll
86
- * position and the nearest-slide arithmetic are both single-axis, and a
87
- * styled-tier attribute cannot change which one they read. Two sites branch
88
- * on it, `scrollTo` and the drag settle, and nothing else in the component
89
- * knows about the axis at all.
90
- *
91
- * A vertical track needs a height, which a horizontal one does not: width
92
- * comes from the page and height does not, so the styled tier gives it
93
- * `--carousel-block-size` and a consumer sets that to whatever the slides
94
- * want.
95
- */
96
- orientation?: 'horizontal' | 'vertical';
97
79
  /**
98
80
  * Whether the previous and next controls are shown.
99
81
  *
@@ -124,20 +106,35 @@ export declare class HelixHeadlessCarousel extends HelixElement {
124
106
  * Slide to start on, where nothing declared one.
125
107
  */
126
108
  defaultIndex: number;
109
+ /**
110
+ * How long each slide is held, in milliseconds.
111
+ */
112
+ interval: number;
127
113
  /** The slide in view, whoever set it, and `undefined` until somebody has. */
128
114
  private indexState;
129
115
  /**
130
- * Whether moving past either end wraps to the other.
116
+ * Accessible name for the carousel.
131
117
  */
132
- loop: boolean;
118
+ label: string;
133
119
  /**
134
- * Whether the carousel advances on its own.
120
+ * Whether moving past either end wraps to the other.
135
121
  */
136
- autoplay: boolean;
122
+ loop: boolean;
137
123
  /**
138
- * How long each slide is held, in milliseconds.
124
+ * Which way the track runs.
125
+ *
126
+ * Behavior rather than presentation, which is why it is here: the scroll
127
+ * position and the nearest-slide arithmetic are both single-axis, and a
128
+ * styled-tier attribute cannot change which one they read. Two sites branch
129
+ * on it, `scrollTo` and the drag settle, and nothing else in the component
130
+ * knows about the axis at all.
131
+ *
132
+ * A vertical track needs a height, which a horizontal one does not: width
133
+ * comes from the page and height does not, so the styled tier gives it
134
+ * `--carousel-block-size` and a consumer sets that to whatever the slides
135
+ * want.
139
136
  */
140
- interval: number;
137
+ orientation?: 'horizontal' | 'vertical';
141
138
  /**
142
139
  * Whether rotation is running.
143
140
  *
@@ -149,14 +146,13 @@ export declare class HelixHeadlessCarousel extends HelixElement {
149
146
  * How many slides are shown across the track at once. Absent shows one.
150
147
  *
151
148
  * **Here rather than on the styled tier, because it decides how many places
152
- * the track can stop.** It was declared above as a width, which is what it
153
- * looks like from the stylesheet: one rule per value setting a custom
154
- * property, and the slides divide the track by it. But a carousel showing
155
- * four of six slides has three positions, not six, and everything that counts
156
- * positions is in this file. Left up there, `goTo` clamped to the last
157
- * *slide*, so three of the six indicators pointed at a scroll offset the
158
- * track had already reached and could not pass: pressing next walked the dots
159
- * to the end while the slides stopped moving a third of the way through.
149
+ * the track can stop.** From the stylesheet it looks like a width, one rule
150
+ * per value setting a custom property that the slides divide the track by.
151
+ * But a carousel showing four of six slides has three positions, not six, and
152
+ * everything that counts positions is in this file. Declared up there, `goTo`
153
+ * clamps to the last *slide*, so three of the six indicators point at an
154
+ * offset the track has already reached: pressing next walks the dots to the
155
+ * end while the slides stop moving a third of the way through.
160
156
  *
161
157
  * No default, because it reflects. A reflected property with a value writes
162
158
  * its attribute on upgrade, and the host then carries something a consumer's
@@ -254,12 +250,11 @@ export declare class HelixHeadlessCarousel extends HelixElement {
254
250
  /**
255
251
  * Owns the timer, from the state rather than from the call site.
256
252
  *
257
- * `start()` and `stop()` each held the interval and `connectedCallback`
258
- * started one, which the rules forbid: a DOM move re-ran connect and restarted
259
- * rotation the reader had stopped, and the server, which never runs connect at
260
- * all, rendered the control saying the opposite of what it would do. The
261
- * state is what is declared and the timer follows it, which also means one
262
- * place clears it.
253
+ * Never hold the interval in `start()` and `stop()` and start one from
254
+ * `connectedCallback`: a DOM move re-runs connect and restarts rotation the
255
+ * reader stopped, and the server, which never runs connect at all, renders
256
+ * the control saying the opposite of what it will do. The state is what is
257
+ * declared and the timer follows it, which also means one place clears it.
263
258
  */
264
259
  private runTimer;
265
260
  /**
@@ -281,9 +276,8 @@ export declare class HelixHeadlessCarousel extends HelixElement {
281
276
  *
282
277
  * **`scrollend` is the only honest place to commit an index and much too late
283
278
  * to show one.** It fires once momentum has fully settled, which on iOS is
284
- * most of a second after the finger has left the glass, so the dots sat on
285
- * the old slide for the whole of the coast and then jumped. Reported exactly
286
- * that way, as the delay on the indicator being too great.
279
+ * most of a second after the finger has left the glass, so the dots sit on
280
+ * the old slide for the whole of the coast and then jump.
287
281
  *
288
282
  * So showing and committing are separated. This moves the marker and nothing
289
283
  * else: no state is written and no event is dispatched, because neither is
@@ -305,13 +299,13 @@ export declare class HelixHeadlessCarousel extends HelixElement {
305
299
  * Reads where a reader's drag settled, and only a reader's.
306
300
  *
307
301
  * **The scroll we issued ourselves ends with a `scrollend` too, and taking it
308
- * as a reading is what makes the dots jump back.** This ran on every one, so
309
- * the index a reader had just chosen was overwritten by whichever slide
310
- * happened to be nearest the leading edge at the moment the animation
311
- * finished. Any disagreement there is enough: a snap settling a pixel short of
312
- * a midpoint, a target clamped by the scroller's own maximum, a fractional
313
- * layout, or a smooth scroll cut off by the next click. The component asked
314
- * for slide four, the pixels said three, and the pixels won.
302
+ * as a reading is what makes the dots jump back.** Run on every one, the
303
+ * index a reader just chose is overwritten by whichever slide happened to be
304
+ * nearest the leading edge when the animation finished. Any disagreement
305
+ * there is enough: a snap settling a pixel short of a midpoint, a target
306
+ * clamped by the scroller's own maximum, a fractional layout, or a smooth
307
+ * scroll cut off by the next click. The component asked for slide four, the
308
+ * pixels said three, and the pixels won.
315
309
  *
316
310
  * Which is the wrong precedence in one direction only. A drag is the reader
317
311
  * moving the track and the index has to follow it; a click is the reader
@@ -363,31 +357,25 @@ export declare class HelixHeadlessCarousel extends HelixElement {
363
357
  * **The panes carry the ARIA and the consumer's element carries none**, which
364
358
  * is the whole reason this is a manual assignment rather than a plain slot.
365
359
  * The APG wants each slide to be a `group` with `aria-roledescription="slide"`
366
- * and a name saying where it sits in the run, and this used to be four
367
- * `setAttribute` calls onto the elements a consumer wrote. Two things were
368
- * wrong with that, and only one of them was about frameworks.
360
+ * and a name saying where it sits in the run, and writing those onto the
361
+ * elements a consumer wrote fails twice, only one of them about frameworks.
369
362
  *
370
363
  * **A React consumer's slides are nodes React is in the middle of hydrating.**
371
- * The attributes landed before React reached them, so React found a DOM it had
372
- * not rendered and reported a mismatch it says it will not patch up. It means
373
- * it: the ARIA survived and the announcement was correct, so nothing looked
374
- * wrong and the console was the only tell. Deferring the write was tried
375
- * first, and a frame is a race rather than an ordering: measured in Chromium
376
- * on the landing page, a tab opened in the foreground still reported the
377
- * mismatch, and a tab opened hidden did not, only because `requestAnimationFrame`
378
- * had not run there yet. `Chat` reached this same conclusion for the same
379
- * reason and its comment on `shadowRootOptions` says so.
364
+ * Attributes landing before React reaches them are a DOM it did not render,
365
+ * which it reports as a mismatch and will not patch up: the ARIA survives and
366
+ * the announcement is correct, so the console is the only tell. Deferring the
367
+ * write does not help, a frame being a race rather than an ordering: measured
368
+ * in Chromium on the landing page, a tab opened in the foreground still
369
+ * reported the mismatch and a tab opened hidden did not, only because
370
+ * `requestAnimationFrame` had not run there yet. `Chat`'s comment on
371
+ * `shadowRootOptions` reaches the same conclusion.
380
372
  *
381
373
  * **And `role="group"` on a consumer's `<a href>` is not additive.** It
382
374
  * replaces the implicit link role, so six insight cards on the landing page
383
- * announced as groups and left the links list entirely. Every slide that is
384
- * itself a control had this, and no amount of deferring the write would have
385
- * helped, because the write was the bug. A pane around the slide is what the
386
- * pattern actually asks for: a group holding a link, rather than a link
387
- * relabeled as a group.
388
- *
389
- * So nothing is written onto a consumer's element at all now, and the
390
- * mismatch is gone by construction rather than by timing.
375
+ * announced as groups and left the links list entirely. No amount of
376
+ * deferring helps, because the write is the bug. A pane around the slide is
377
+ * what the pattern actually asks for: a group holding a link, rather than a
378
+ * link relabeled as a group.
391
379
  */
392
380
  private assign;
393
381
  protected render(): TemplateResult;
@@ -21,8 +21,7 @@ import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
21
21
  * component renders a pane per slide carrying `role="group"`,
22
22
  * `aria-roledescription="slide"` and a name reading its position in the set,
23
23
  * and assigns the slide into it: a screen-reader user hears where they are, and
24
- * a slide that is itself a link is still a link, which it was not while the role
25
- * was being written on top of it. See `assign`.
24
+ * a slide that is itself a link is still a link. See `assign`.
26
25
  *
27
26
  * **Rotation stops on focus and on hover, and once stopped it stays stopped.**
28
27
  * The APG is explicit: rotation must not resume unless the reader asks for it,
@@ -55,27 +54,27 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
55
54
  constructor() {
56
55
  super(...arguments);
57
56
  /**
58
- * Accessible name for the carousel.
57
+ * Whether the carousel advances on its own.
59
58
  */
60
- this.label = 'Carousel';
59
+ this.autoplay = false;
61
60
  /**
62
61
  * Slide to start on, where nothing declared one.
63
62
  */
64
63
  this.defaultIndex = 0;
65
- /** The slide in view, whoever set it, and `undefined` until somebody has. */
66
- this.indexState = undefined;
67
64
  /**
68
- * Whether moving past either end wraps to the other.
65
+ * How long each slide is held, in milliseconds.
69
66
  */
70
- this.loop = false;
67
+ this.interval = 5000;
68
+ /** The slide in view, whoever set it, and `undefined` until somebody has. */
69
+ this.indexState = undefined;
71
70
  /**
72
- * Whether the carousel advances on its own.
71
+ * Accessible name for the carousel.
73
72
  */
74
- this.autoplay = false;
73
+ this.label = 'Carousel';
75
74
  /**
76
- * How long each slide is held, in milliseconds.
75
+ * Whether moving past either end wraps to the other.
77
76
  */
78
- this.interval = 5000;
77
+ this.loop = false;
79
78
  /**
80
79
  * Whether rotation is running.
81
80
  *
@@ -124,9 +123,8 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
124
123
  *
125
124
  * **`scrollend` is the only honest place to commit an index and much too late
126
125
  * to show one.** It fires once momentum has fully settled, which on iOS is
127
- * most of a second after the finger has left the glass, so the dots sat on
128
- * the old slide for the whole of the coast and then jumped. Reported exactly
129
- * that way, as the delay on the indicator being too great.
126
+ * most of a second after the finger has left the glass, so the dots sit on
127
+ * the old slide for the whole of the coast and then jump.
130
128
  *
131
129
  * So showing and committing are separated. This moves the marker and nothing
132
130
  * else: no state is written and no event is dispatched, because neither is
@@ -159,13 +157,13 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
159
157
  * Reads where a reader's drag settled, and only a reader's.
160
158
  *
161
159
  * **The scroll we issued ourselves ends with a `scrollend` too, and taking it
162
- * as a reading is what makes the dots jump back.** This ran on every one, so
163
- * the index a reader had just chosen was overwritten by whichever slide
164
- * happened to be nearest the leading edge at the moment the animation
165
- * finished. Any disagreement there is enough: a snap settling a pixel short of
166
- * a midpoint, a target clamped by the scroller's own maximum, a fractional
167
- * layout, or a smooth scroll cut off by the next click. The component asked
168
- * for slide four, the pixels said three, and the pixels won.
160
+ * as a reading is what makes the dots jump back.** Run on every one, the
161
+ * index a reader just chose is overwritten by whichever slide happened to be
162
+ * nearest the leading edge when the animation finished. Any disagreement
163
+ * there is enough: a snap settling a pixel short of a midpoint, a target
164
+ * clamped by the scroller's own maximum, a fractional layout, or a smooth
165
+ * scroll cut off by the next click. The component asked for slide four, the
166
+ * pixels said three, and the pixels won.
169
167
  *
170
168
  * Which is the wrong precedence in one direction only. A drag is the reader
171
169
  * moving the track and the index has to follow it; a click is the reader
@@ -190,7 +188,7 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
190
188
  to refuse, and `preventDefault()` could not un-drag it. This is the case
191
189
  the controlled-change helper's own documentation distinguishes, a native
192
190
  control that has already moved, and putting it on that path would offer a
193
- refusal that cannot be honoured. */
191
+ refusal that cannot be honored. */
194
192
  if (nearest === this.index) {
195
193
  return;
196
194
  }
@@ -258,8 +256,6 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
258
256
  * extracted, because a slide is addressed by position and every one of those
259
257
  * mixins is keyed by a name. One consumer is not a mixin: if a second numeric
260
258
  * state turns up, this is what it is extracted from.
261
- *
262
- *
263
259
  */
264
260
  get index() {
265
261
  return this.indexState ?? this.defaultIndex;
@@ -294,19 +290,15 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
294
290
  }
295
291
  /** The slides, in light-DOM order. Empty on the server, which has no tree. */
296
292
  get slides() {
297
- /* `?? []` is the server, and the comment above it was already right and
298
- still did not save it: this said "client only" while `render` read it to
299
- count the indicators, so every carousel SSR spec died on an unhandled
300
- spread of `undefined`. Third time in this library, after the menu item
301
- and the table, and the only one of the three the note was written on.
302
- Knowing where a getter must not be reached is not the same as it not
303
- being reached, which is what the guard is for.
293
+ /* `?? []` is the server, and a note saying "client only" is not a guard:
294
+ `render` reads this to count the indicators, so an unhandled spread of
295
+ `undefined` kills every carousel SSR pass.
304
296
 
305
297
  Empty is also the honest answer rather than damage control. The
306
298
  indicators are one per position and a position is counted from the
307
- children, which the server cannot see, so they
308
- arrive with the upgrade. Nothing moves when they do: the tags are hidden
309
- until they are defined. */
299
+ children, which the server cannot see, so they arrive with the upgrade.
300
+ Nothing moves when they do: the tags are hidden until they are
301
+ defined. */
310
302
  return [...(this.children ?? [])].filter((child) => child instanceof HTMLElement);
311
303
  }
312
304
  /** Moves to a slide, wrapping only where `loop` says to. */
@@ -390,12 +382,6 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
390
382
  if (!slide || !track) {
391
383
  return;
392
384
  }
393
- /* The preference is read here, because this is where the motion is.
394
- *
395
- * `scroll-behavior: auto` in a reduce block does nothing: it restates the
396
- * initial value, and the scroll that actually animates is this call, which
397
- * names `smooth` outright and overrides the property either way. A reader
398
- * who asked not to be moved was moved. */
399
385
  const vertical = this.orientation === 'vertical';
400
386
  const target = this.edgeOf(slide, track, this.bleed(track));
401
387
  /* Already there, and saying so rather than asking anyway.
@@ -413,8 +399,7 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
413
399
  *
414
400
  * `scroll-behavior: auto` in a reduce block does nothing: it restates the
415
401
  * initial value, and the scroll that actually animates is this call, which
416
- * names `smooth` outright and overrides the property either way. A reader
417
- * who asked not to be moved was moved. */
402
+ * names `smooth` outright and overrides the property either way. */
418
403
  const still = globalThis.matchMedia?.('(prefers-reduced-motion: reduce)').matches ?? false;
419
404
  /* The scroll about to run is ours, so the `scrollend` it produces is not a
420
405
  reader saying where they went. See `handleScroll`. */
@@ -443,12 +428,11 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
443
428
  /**
444
429
  * Owns the timer, from the state rather than from the call site.
445
430
  *
446
- * `start()` and `stop()` each held the interval and `connectedCallback`
447
- * started one, which the rules forbid: a DOM move re-ran connect and restarted
448
- * rotation the reader had stopped, and the server, which never runs connect at
449
- * all, rendered the control saying the opposite of what it would do. The
450
- * state is what is declared and the timer follows it, which also means one
451
- * place clears it.
431
+ * Never hold the interval in `start()` and `stop()` and start one from
432
+ * `connectedCallback`: a DOM move re-runs connect and restarts rotation the
433
+ * reader stopped, and the server, which never runs connect at all, renders
434
+ * the control saying the opposite of what it will do. The state is what is
435
+ * declared and the timer follows it, which also means one place clears it.
452
436
  */
453
437
  runTimer() {
454
438
  clearInterval(this.timer);
@@ -520,24 +504,20 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
520
504
  super.updated(changed);
521
505
  /* The track follows `index`, whoever moved it.
522
506
  *
523
- * This was called from inside `goTo`'s apply callback, which returns early
524
- * in controlled mode, so a controlled carousel announced where it would go,
525
- * the consumer assigned `index`, and the track never moved: the dots
526
- * updated and the slides sat still. Every other path in was equally
527
- * stranded, a plain `carousel.index = 2` included, apply being the only
528
- * caller. Here it is one place and it covers all of them. */
507
+ * Not from inside `goTo`'s apply callback: that returns early in controlled
508
+ * mode, so the dots update and the slides sit still, and it is not the only
509
+ * path in either, a plain `carousel.index = 2` reaching no apply at all. */
529
510
  if (changed.has('index')) {
530
511
  this.scrollToIndex();
531
512
  }
532
513
  this.runTimer();
533
514
  /* Back inside the set when the set shrinks.
534
515
  *
535
- * Nothing re-clamped `index`, and the indicators carry a roving tab stop
536
- * keyed on it, so a carousel whose slides were removed under it was left
537
- * with no tab stop, no current dot and a focus restore pointing at nothing.
538
- * In `updated` rather than `willUpdate` because `slides` is empty on the
539
- * server, and through `goTo` so a controlled consumer is told rather than
540
- * overwritten. */
516
+ * The indicators carry a roving tab stop keyed on `index`, so a carousel
517
+ * whose slides are removed under it is left with no tab stop, no current
518
+ * dot and a focus restore pointing at nothing. In `updated` rather than
519
+ * `willUpdate` because `slides` is empty on the server, and through `goTo`
520
+ * so a controlled consumer is told rather than overwritten. */
541
521
  const count = this.slides.length;
542
522
  if (count > 0 && this.index > count - 1) {
543
523
  this.goTo(count - 1);
@@ -550,31 +530,25 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
550
530
  * **The panes carry the ARIA and the consumer's element carries none**, which
551
531
  * is the whole reason this is a manual assignment rather than a plain slot.
552
532
  * The APG wants each slide to be a `group` with `aria-roledescription="slide"`
553
- * and a name saying where it sits in the run, and this used to be four
554
- * `setAttribute` calls onto the elements a consumer wrote. Two things were
555
- * wrong with that, and only one of them was about frameworks.
533
+ * and a name saying where it sits in the run, and writing those onto the
534
+ * elements a consumer wrote fails twice, only one of them about frameworks.
556
535
  *
557
536
  * **A React consumer's slides are nodes React is in the middle of hydrating.**
558
- * The attributes landed before React reached them, so React found a DOM it had
559
- * not rendered and reported a mismatch it says it will not patch up. It means
560
- * it: the ARIA survived and the announcement was correct, so nothing looked
561
- * wrong and the console was the only tell. Deferring the write was tried
562
- * first, and a frame is a race rather than an ordering: measured in Chromium
563
- * on the landing page, a tab opened in the foreground still reported the
564
- * mismatch, and a tab opened hidden did not, only because `requestAnimationFrame`
565
- * had not run there yet. `Chat` reached this same conclusion for the same
566
- * reason and its comment on `shadowRootOptions` says so.
537
+ * Attributes landing before React reaches them are a DOM it did not render,
538
+ * which it reports as a mismatch and will not patch up: the ARIA survives and
539
+ * the announcement is correct, so the console is the only tell. Deferring the
540
+ * write does not help, a frame being a race rather than an ordering: measured
541
+ * in Chromium on the landing page, a tab opened in the foreground still
542
+ * reported the mismatch and a tab opened hidden did not, only because
543
+ * `requestAnimationFrame` had not run there yet. `Chat`'s comment on
544
+ * `shadowRootOptions` reaches the same conclusion.
567
545
  *
568
546
  * **And `role="group"` on a consumer's `<a href>` is not additive.** It
569
547
  * replaces the implicit link role, so six insight cards on the landing page
570
- * announced as groups and left the links list entirely. Every slide that is
571
- * itself a control had this, and no amount of deferring the write would have
572
- * helped, because the write was the bug. A pane around the slide is what the
573
- * pattern actually asks for: a group holding a link, rather than a link
574
- * relabeled as a group.
575
- *
576
- * So nothing is written onto a consumer's element at all now, and the
577
- * mismatch is gone by construction rather than by timing.
548
+ * announced as groups and left the links list entirely. No amount of
549
+ * deferring helps, because the write is the bug. A pane around the slide is
550
+ * what the pattern actually asks for: a group holding a link, rather than a
551
+ * link relabeled as a group.
578
552
  */
579
553
  assign() {
580
554
  const panes = this.renderRoot?.querySelectorAll?.('[part="slide"] slot');
@@ -659,16 +633,14 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
659
633
  ${
660
634
  /* Plain buttons, not a half-built tablist.
661
635
  *
662
- * They were `role="tab"` inside `role="tablist"` with no
663
- * `aria-controls`, while the slides were `role="group"` rather
664
- * than tabpanels: the APG has two carousel patterns and this
665
- * was the announcement of one over the structure of the other,
666
- * so a reader was told to expect panels that do not exist.
667
- *
668
- * The basic pattern is what this is: buttons that move the
669
- * carousel, with the current one marked. `aria-current` is the
670
- * right word for "the one you are on" where nothing is being
671
- * selected. */
636
+ * `role="tab"` in a `role="tablist"` promises tabpanels, and
637
+ * the slides are `role="group"`: the APG has two carousel
638
+ * patterns and taking the announcement of one over the
639
+ * structure of the other tells a reader to expect panels that
640
+ * do not exist. This is the basic pattern, buttons that move
641
+ * the carousel with the current one marked, and `aria-current`
642
+ * is the right word for "the one you are on" where nothing is
643
+ * being selected. */
672
644
  ''}
673
645
  ${Array.from({ length: this.positions }).map((_place, at) => html `<button
674
646
  part="indicator"
@@ -685,14 +657,11 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
685
657
  }
686
658
  };
687
659
  __decorate([
688
- property()
689
- ], HelixHeadlessCarousel.prototype, "label", void 0);
660
+ property({ type: Boolean })
661
+ ], HelixHeadlessCarousel.prototype, "autoplay", void 0);
690
662
  __decorate([
691
663
  property({ type: Number })
692
664
  ], HelixHeadlessCarousel.prototype, "index", null);
693
- __decorate([
694
- property({ reflect: true })
695
- ], HelixHeadlessCarousel.prototype, "orientation", void 0);
696
665
  __decorate([
697
666
  property({ reflect: true })
698
667
  ], HelixHeadlessCarousel.prototype, "controls", void 0);
@@ -700,14 +669,17 @@ __decorate([
700
669
  property({ attribute: 'default-index', type: Number })
701
670
  ], HelixHeadlessCarousel.prototype, "defaultIndex", void 0);
702
671
  __decorate([
703
- property({ type: Boolean })
704
- ], HelixHeadlessCarousel.prototype, "loop", void 0);
672
+ property({ type: Number })
673
+ ], HelixHeadlessCarousel.prototype, "interval", void 0);
674
+ __decorate([
675
+ property()
676
+ ], HelixHeadlessCarousel.prototype, "label", void 0);
705
677
  __decorate([
706
678
  property({ type: Boolean })
707
- ], HelixHeadlessCarousel.prototype, "autoplay", void 0);
679
+ ], HelixHeadlessCarousel.prototype, "loop", void 0);
708
680
  __decorate([
709
- property({ type: Number })
710
- ], HelixHeadlessCarousel.prototype, "interval", void 0);
681
+ property({ reflect: true })
682
+ ], HelixHeadlessCarousel.prototype, "orientation", void 0);
711
683
  __decorate([
712
684
  state()
713
685
  ], HelixHeadlessCarousel.prototype, "rotating", void 0);
@@ -39,15 +39,27 @@ import { type PropertyValues, type TemplateResult } from 'lit';
39
39
  */
40
40
  export declare class HelixHeadlessChatComposer extends HelixElement {
41
41
  /**
42
- * What the reader has written.
43
- *
44
- * Read it, or set it to seed a draft.
42
+ * Whether the composer refuses input, while a turn is in flight say.
45
43
  */
46
- value: string;
44
+ disabled: boolean;
45
+ /**
46
+ * Accessible name for the field.
47
+ */
48
+ label: string;
47
49
  /**
48
50
  * Shown in an empty field.
49
51
  */
50
52
  placeholder: string;
53
+ /**
54
+ * How many rows the field opens at.
55
+ *
56
+ * It grows from there.
57
+ */
58
+ rows: number;
59
+ /**
60
+ * Label for the control that sends.
61
+ */
62
+ sendLabel: string;
51
63
  /**
52
64
  * What sends: pressing Enter, or only the control.
53
65
  *
@@ -57,23 +69,11 @@ export declare class HelixHeadlessChatComposer extends HelixElement {
57
69
  */
58
70
  submitOn: 'button' | 'enter';
59
71
  /**
60
- * Whether the composer refuses input, while a turn is in flight say.
61
- */
62
- disabled: boolean;
63
- /**
64
- * Accessible name for the field.
65
- */
66
- label: string;
67
- /**
68
- * Label for the control that sends.
69
- */
70
- sendLabel: string;
71
- /**
72
- * How many rows the field opens at.
72
+ * What the reader has written.
73
73
  *
74
- * It grows from there.
74
+ * Read it, or set it to seed a draft.
75
75
  */
76
- rows: number;
76
+ value: string;
77
77
  private draft;
78
78
  /**
79
79
  * @internal Read by the transcript to find the composer among its children.
@@ -105,24 +105,20 @@ export declare class HelixHeadlessChatComposer extends HelixElement {
105
105
  *
106
106
  * **A glyph with the label as its accessible name, rather than the label as
107
107
  * text.** The word "Send" beside a field is the widest thing in the row and
108
- * says nothing a return key does not, and every composer a reader has used in
109
- * the last five years marks it rather than spells it. The return glyph is the
110
- * mark because Enter is what actually sends, which `submit-on` says out loud:
111
- * the control and the key are one affordance and should look like it.
112
- *
113
- * `send-label` is unchanged and is now the accessible name rather than the
114
- * visible one, so a screen reader hears the same word it always did.
108
+ * says nothing a return key does not. The return glyph is the mark because
109
+ * Enter is what actually sends, which `submit-on` says out loud: the control
110
+ * and the key are one affordance and should look like it. `send-label` is the
111
+ * accessible name rather than a visible one, so a screen reader still hears
112
+ * the word.
115
113
  */
116
114
  protected renderSend(): TemplateResult;
117
115
  /**
118
116
  * The field, and a row of tools under it.
119
117
  *
120
- * **One row was the wrong shape and it got worse the more a composer had to
121
- * carry.** Everything sat on a single line: an attachment control, the field,
122
- * a stop control and a send button, so the field was squeezed from both sides
123
- * and every tool a consumer added took width away from the thing being typed
124
- * into. Under it, the field spans the whole composer at every width and the
125
- * tools have a line of their own to grow along.
118
+ * **The tools take a line of their own rather than sharing the field's.** On
119
+ * one line every tool a consumer adds takes width away from the thing being
120
+ * typed into; under it, the field spans the whole composer at every width and
121
+ * the tools have room to grow along.
126
122
  *
127
123
  * Send is at the trailing end of that line rather than in the field, which is
128
124
  * the same corner and costs no overlay: a control positioned inside a
@@ -138,7 +134,7 @@ export declare class HelixHeadlessChatComposer extends HelixElement {
138
134
  * whatever `<helix-chat>` it is slotted into, and neither element declares an
139
135
  * `input`: a consumer binding one on either received an undeclared event whose
140
136
  * target was a control they cannot reach. What a composer offers is
141
- * `helix-send`, once, when the reader is done. See 308.
137
+ * `helix-send`, once, when the reader is done.
142
138
  */
143
139
  private readonly handleInput;
144
140
  private readonly handleSend;