@fusion.dev/helix-headless 0.158.0 → 0.160.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 (58) hide show
  1. package/custom-elements.json +1925 -174
  2. package/dist/app-header/root/app-header-root.d.ts +59 -12
  3. package/dist/app-header/root/app-header-root.js +68 -29
  4. package/dist/button/root/button-root.d.ts +8 -0
  5. package/dist/button/root/button-root.js +4 -0
  6. package/dist/button-group/root/button-group-root.d.ts +20 -7
  7. package/dist/button-group/root/button-group-root.js +30 -5
  8. package/dist/date-input/root/date-input-root.d.ts +108 -19
  9. package/dist/date-input/root/date-input-root.js +112 -13
  10. package/dist/date-picker/root/date-picker-root.d.ts +81 -16
  11. package/dist/date-picker/root/date-picker-root.js +140 -36
  12. package/dist/element-events.generated.js +9 -1
  13. package/dist/format-date/fields.js +1 -0
  14. package/dist/format-date/options.d.ts +3 -1
  15. package/dist/format-date/options.js +4 -1
  16. package/dist/format-date/root/format-date-root.d.ts +27 -11
  17. package/dist/format-date/root/format-date-root.js +6 -0
  18. package/dist/lightbox/item/lightbox-item.d.ts +7 -1
  19. package/dist/lightbox/item/lightbox-item.js +15 -2
  20. package/dist/lightbox/root/lightbox-root.d.ts +8 -4
  21. package/dist/lightbox/root/lightbox-root.js +9 -1
  22. package/dist/lightbox/zoom-controller.d.ts +13 -4
  23. package/dist/lightbox/zoom-controller.js +17 -0
  24. package/dist/listbox/root/listbox-root.js +5 -0
  25. package/dist/notifications/notification/notification.d.ts +1 -0
  26. package/dist/notifications/notification/notification.js +2 -1
  27. package/dist/slider/root/slider-root.d.ts +54 -3
  28. package/dist/slider/root/slider-root.js +124 -2
  29. package/dist/steps/root/steps-root.js +8 -6
  30. package/dist/steps/step/step.d.ts +9 -0
  31. package/dist/steps/step/step.js +19 -2
  32. package/dist/tabs/panel/tab-panel.d.ts +22 -1
  33. package/dist/tabs/panel/tab-panel.js +22 -1
  34. package/dist/tabs/root/tabs-root.d.ts +21 -5
  35. package/dist/tabs/root/tabs-root.js +24 -13
  36. package/dist/tabs/tab/tab.d.ts +4 -2
  37. package/dist/tabs/tab/tab.js +3 -1
  38. package/dist/time-input/root/time-input-root.d.ts +55 -7
  39. package/dist/time-input/root/time-input-root.js +70 -10
  40. package/dist/time-picker/root/time-picker-root.d.ts +27 -5
  41. package/dist/time-picker/root/time-picker-root.js +52 -13
  42. package/dist/toast/item/toast-item.d.ts +27 -8
  43. package/dist/toast/item/toast-item.js +47 -11
  44. package/dist/toast/root/toast-root.d.ts +24 -1
  45. package/dist/toast/root/toast-root.js +54 -0
  46. package/dist/toggle/group/toggle-group.d.ts +18 -1
  47. package/dist/toggle/group/toggle-group.js +8 -2
  48. package/dist/toggle/root/toggle-root.d.ts +2 -2
  49. package/dist/toggle/root/toggle-root.js +2 -1
  50. package/dist/tour/root/tour-root.d.ts +34 -0
  51. package/dist/tour/root/tour-root.js +92 -3
  52. package/dist/tour/stop/tour-stop.d.ts +33 -1
  53. package/dist/tour/stop/tour-stop.js +12 -1
  54. package/lint.json +1 -1
  55. package/package.json +5 -5
  56. package/types/jsx.d.ts +1119 -218
  57. package/types/vue.d.ts +278 -51
  58. package/types/words.d.ts +72 -0
package/types/vue.d.ts CHANGED
@@ -215,6 +215,7 @@ import type {
215
215
  HelixSelectedEvent,
216
216
  HelixSortEvent,
217
217
  HelixSortedEvent,
218
+ HelixClearEvent,
218
219
  HelixRejectEvent,
219
220
  HelixFacetEvent,
220
221
  HelixBeforeActivateEvent,
@@ -226,7 +227,6 @@ import type {
226
227
  HelixGraphSignalEvent,
227
228
  HelixGraphZoomEvent,
228
229
  HelixResizeEvent,
229
- HelixClearEvent,
230
230
  HelixShortcutEvent,
231
231
  HelixActionEvent,
232
232
  HelixMapPartChangeEvent,
@@ -245,9 +245,9 @@ import type {
245
245
  HelixBeforeResizeEvent,
246
246
  HelixCollapseEvent,
247
247
  HelixResizedEvent,
248
+ HelixLoadEvent,
248
249
  HelixTourAskEvent,
249
250
  HelixTourStatusEvent,
250
- HelixLoadEvent,
251
251
  HelixEndEvent,
252
252
  HelixNextEvent,
253
253
  HelixPreviousEvent,
@@ -530,9 +530,18 @@ export type HelixHeadlessAppHeaderElementEvent<E = Event> = TypedEvent<
530
530
  HelixHeadlessAppHeader,
531
531
  E
532
532
  >;
533
+ /** `helix-before-close` event type */
534
+ export type HelixHeadlessAppHeaderHelixBeforeCloseElementEvent =
535
+ HelixHeadlessAppHeaderElementEvent<HelixBeforeCloseEvent>;
536
+ /** `helix-before-open` event type */
537
+ export type HelixHeadlessAppHeaderHelixBeforeOpenElementEvent =
538
+ HelixHeadlessAppHeaderElementEvent<HelixBeforeOpenEvent>;
533
539
  /** `helix-scrolled` event type */
534
540
  export type HelixHeadlessAppHeaderHelixScrolledElementEvent =
535
541
  HelixHeadlessAppHeaderElementEvent<HelixScrolledEvent>;
542
+ /** `toggle` event type */
543
+ export type HelixHeadlessAppHeaderToggleElementEvent =
544
+ HelixHeadlessAppHeaderElementEvent<ToggleEvent>;
536
545
 
537
546
  export type HelixHeadlessAppHeaderVueProps = {
538
547
  /** Where the middle region sits in the bar.
@@ -582,11 +591,46 @@ page scrolls up. */
582
591
  /** The id of the element whose scrolling lifts the bar, for an app shell that
583
592
  scrolls a container instead of the window. Unset is the window. */
584
593
  scroller?: (HelixHeadlessAppHeader["scroller"]) | undefined;
594
+ /** Where the toggle that opens a folded middle region sits: at the end of the
595
+ bar, after the trailing content, or with `start`, before the leading
596
+ content.
597
+
598
+ Optional, so the resting bar writes no attribute onto the host. */
599
+ "toggle-placement"?: (HelixHeadlessAppHeader["togglePlacement"]) | undefined;
600
+ /** Where the toggle that opens a folded middle region sits: at the end of the
601
+ bar, after the trailing content, or with `start`, before the leading
602
+ content.
603
+
604
+ Optional, so the resting bar writes no attribute onto the host. */
605
+ togglePlacement?: (HelixHeadlessAppHeader["togglePlacement"]) | undefined;
606
+ /** Whether the element starts open. Ignored once `open` is written. */
607
+ "default-open"?: (HelixHeadlessAppHeader["defaultOpen"]) | undefined;
608
+ /** Whether the element starts open. Ignored once `open` is written. */
609
+ defaultOpen?: (HelixHeadlessAppHeader["defaultOpen"]) | undefined;
610
+ /** Whether the element is open.
611
+
612
+ One property, not two, so `dialog.open` answers the question anyone
613
+ asking it meant. Writing always applies; `<helix-dialog open>` is the
614
+ same statement in markup.
615
+
616
+ **Not reflected, and that is required rather than tidy.** Reflection
617
+ writes the resolved state back as an attribute, so an element that opened
618
+ itself would put `open` on its own host: cloned, serialized for
619
+ hydration, or diffed by a framework, it comes back holding whatever the
620
+ last reader did rather than what the author wrote. `:state(open)` carries
621
+ the resolved state for stylesheets, which is what the mirror is for. */
622
+ open?: (HelixHeadlessAppHeader["open"]) | undefined;
585
623
  };
586
624
 
587
625
  export type HelixHeadlessAppHeaderVueEvents = {
626
+ /** The folded region is about to close. Cancelable: cancel it to keep it open. */
627
+ "helix-before-close": HelixHeadlessAppHeaderHelixBeforeCloseElementEvent;
628
+ /** The folded region is about to open. Cancelable: cancel it to keep it closed. */
629
+ "helix-before-open": HelixHeadlessAppHeaderHelixBeforeOpenElementEvent;
588
630
  /** Fired when the page crosses the scroll threshold, with the new state. A custom state cannot be observed the way an attribute can, so listen for this event to follow it. The event uses the header's own threshold and hysteresis, so you do not need a second scroll listener. */
589
631
  "helix-scrolled": HelixHeadlessAppHeaderHelixScrolledElementEvent;
632
+ /** The folded region opened or closed. The event carries `newState` and `oldState`. */
633
+ toggle: HelixHeadlessAppHeaderToggleElementEvent;
590
634
  };
591
635
 
592
636
  /** `HelixHeadlessAreaChart` component event */
@@ -1233,6 +1277,14 @@ export type HelixHeadlessButtonGroupHelixBeforeChangeElementEvent =
1233
1277
  HelixHeadlessButtonGroupElementEvent<HelixBeforeChangeEvent>;
1234
1278
 
1235
1279
  export type HelixHeadlessButtonGroupVueProps = {
1280
+ /** Keeps at least one button pressed once one is, as React Aria's
1281
+ `disallowEmptySelection`: a press that would leave none pressed is
1282
+ refused. */
1283
+ "disallow-empty-selection"?: (HelixHeadlessButtonGroup["disallowEmptySelection"]) | undefined;
1284
+ /** Keeps at least one button pressed once one is, as React Aria's
1285
+ `disallowEmptySelection`: a press that would leave none pressed is
1286
+ refused. */
1287
+ disallowEmptySelection?: (HelixHeadlessButtonGroup["disallowEmptySelection"]) | undefined;
1236
1288
  /** The group's name, read by screen readers.
1237
1289
 
1238
1290
  On the host through internals, so an author's `aria-label` still overrides
@@ -5026,37 +5078,56 @@ export type HelixHeadlessDateInputHelixBeforeCloseElementEvent =
5026
5078
  /** `helix-before-open` event type */
5027
5079
  export type HelixHeadlessDateInputHelixBeforeOpenElementEvent =
5028
5080
  HelixHeadlessDateInputElementEvent<HelixBeforeOpenEvent>;
5081
+ /** `helix-clear` event type */
5082
+ export type HelixHeadlessDateInputHelixClearElementEvent =
5083
+ HelixHeadlessDateInputElementEvent<HelixClearEvent>;
5029
5084
  /** `toggle` event type */
5030
5085
  export type HelixHeadlessDateInputToggleElementEvent =
5031
5086
  HelixHeadlessDateInputElementEvent<ToggleEvent>;
5032
5087
 
5033
5088
  export type HelixHeadlessDateInputVueProps = {
5034
- /** What the browser may autofill here, as one of the platform's own tokens.
5089
+ /** What the browser may autofill here, as one of the platform's own tokens,
5090
+ such as `bday`.
5035
5091
 
5036
5092
  Empty leaves the attribute off, which is the browser's default and is what
5037
5093
  lets autofill work at all: hardcoding `off` here means a birthday or a
5038
- postal code can never be filled in for a reader. */
5094
+ postal code can never be filled in for a reader. With `segmented`, a
5095
+ hidden native date input carries it, since no browser fills the segments. */
5039
5096
  autocomplete?: (HelixHeadlessDateInput["autocomplete"]) | undefined;
5040
- /** The calendar the written date and the calendar's days are in: `gregory`,
5041
- `buddhist`, `japanese`, `roc`, or `iso8601`.
5042
-
5043
- Absent is the locale's own where it is one of the five, and `gregory` for
5044
- every other, as Date Picker's `calendar` is. The value is `YYYY-MM-DD` in
5045
- every calendar, and a focused field is ISO in every calendar. In
5046
- `segmented`, the segments are the Gregorian day, month, and year, in the
5047
- order the locale writes them, or ISO order for `iso8601`. */
5097
+ /** The calendar the written date, the segments, and the calendar's days are
5098
+ in: `gregory`, `buddhist`, `japanese`, `roc`, or `iso8601`, or a calendar
5099
+ with months of its own that Date Picker's `calendar` names, such as
5100
+ `persian`, `hebrew`, `islamic-umalqura`, `ethiopic`, or `chinese`.
5101
+
5102
+ Absent is the locale's own where its months are the Gregorian months, and
5103
+ `gregory` for every other, as Date Picker's `calendar` is. The value is
5104
+ `YYYY-MM-DD` in every calendar, and a focused text field is ISO in every
5105
+ calendar. In `segmented`, the segments are the day, month, and year as
5106
+ the calendar counts them, in the order the locale writes them: Mehr 14,
5107
+ 1405 is month 7 and day 14 of 1405 under `persian`. Under the five with
5108
+ Gregorian months they are the Gregorian day, month, and year, or ISO order
5109
+ for `iso8601`. */
5048
5110
  calendar?: (HelixHeadlessDateInput["calendar"]) | undefined;
5049
5111
  /** The name of the calendar's grid of days, read by screen readers. */
5050
5112
  "calendar-label"?: (HelixHeadlessDateInput["calendarLabel"]) | undefined;
5051
5113
  /** The name of the calendar's grid of days, read by screen readers. */
5052
5114
  calendarLabel?: (HelixHeadlessDateInput["calendarLabel"]) | undefined;
5115
+ /** Whether the field shows a button that empties it, as Input's `clearable`
5116
+ does. Shown only while the field holds something to clear and is neither
5117
+ disabled nor read-only. */
5118
+ clearable?: (HelixHeadlessDateInput["clearable"]) | undefined;
5119
+ /** The accessible name of the clear button, which shows only an icon. */
5120
+ "clear-label"?: (HelixHeadlessDateInput["clearLabel"]) | undefined;
5121
+ /** The accessible name of the clear button, which shows only an icon. */
5122
+ clearLabel?: (HelixHeadlessDateInput["clearLabel"]) | undefined;
5053
5123
  /** How a date is written in the field: `short` through `full`, or ISO.
5054
5124
 
5055
5125
  **The field renders when it is idle and holds the value when it is being
5056
5126
  edited.** A written date is a rendering, and a document being edited must
5057
5127
  not be a rendering of something else: `Intl.DateTimeFormat` formats and does
5058
- not parse, so `4 August 2026` cannot be typed back, and writing a parser per
5059
- locale is how a field ends up rejecting what it just displayed.
5128
+ not parse, so a rendering such as `Tuesday, August 4, 2026` is no text to
5129
+ edit. The field does read a date typed in the locale's order and digits as
5130
+ you leave it, which covers what a reader types.
5060
5131
 
5061
5132
  The way out is not to choose between the two but to separate them in time.
5062
5133
  Idle, the field shows `4 August 2026`, which is what a date is for reading.
@@ -5078,8 +5149,9 @@ submits and what `min` and `max` compare against. */
5078
5149
  **The field renders when it is idle and holds the value when it is being
5079
5150
  edited.** A written date is a rendering, and a document being edited must
5080
5151
  not be a rendering of something else: `Intl.DateTimeFormat` formats and does
5081
- not parse, so `4 August 2026` cannot be typed back, and writing a parser per
5082
- locale is how a field ends up rejecting what it just displayed.
5152
+ not parse, so a rendering such as `Tuesday, August 4, 2026` is no text to
5153
+ edit. The field does read a date typed in the locale's order and digits as
5154
+ you leave it, which covers what a reader types.
5083
5155
 
5084
5156
  The way out is not to choose between the two but to separate them in time.
5085
5157
  Idle, the field shows `4 August 2026`, which is what a date is for reading.
@@ -5217,6 +5289,14 @@ the date.
5217
5289
  **The name goes in**, so a row of them is heard as which one each
5218
5290
  removes rather than as "Remove" said once per date. */
5219
5291
  removeLabel?: (HelixHeadlessDateInput["removeLabel"]) | undefined;
5292
+ /** What a screen reader hears about the dates chosen in the calendar, with
5293
+ `{kind}`, `{start}`, `{end}` and `{count}` filled in as Date Picker's
5294
+ `selection-label` says. */
5295
+ "selection-label"?: (HelixHeadlessDateInput["selectionLabel"]) | undefined;
5296
+ /** What a screen reader hears about the dates chosen in the calendar, with
5297
+ `{kind}`, `{start}`, `{end}` and `{count}` filled in as Date Picker's
5298
+ `selection-label` says. */
5299
+ selectionLabel?: (HelixHeadlessDateInput["selectionLabel"]) | undefined;
5220
5300
  /** How far apart the selectable dates are, in days.
5221
5301
 
5222
5302
  `<input type="date" step>`'s own unit, handed to the calendar this renders
@@ -5228,6 +5308,14 @@ platform's base. */
5228
5308
  "step-mismatch-message"?: (HelixHeadlessDateInput["stepMismatchMessage"]) | undefined;
5229
5309
  /** The message shown when a date is not on `step`. */
5230
5310
  stepMismatchMessage?: (HelixHeadlessDateInput["stepMismatchMessage"]) | undefined;
5311
+ /** The time zone today is read in, such as `America/New_York`, handed to the
5312
+ calendar: the day marked today, and the month an empty field opens on.
5313
+ Empty is the reader's own. Dates are plain `YYYY-MM-DD` and carry no zone. */
5314
+ "time-zone"?: (HelixHeadlessDateInput["timeZone"]) | undefined;
5315
+ /** The time zone today is read in, such as `America/New_York`, handed to the
5316
+ calendar: the day marked today, and the month an empty field opens on.
5317
+ Empty is the reader's own. Dates are plain `YYYY-MM-DD` and carry no zone. */
5318
+ timeZone?: (HelixHeadlessDateInput["timeZone"]) | undefined;
5231
5319
  /** The name of the button that opens the calendar, read by screen readers. */
5232
5320
  "trigger-label"?: (HelixHeadlessDateInput["triggerLabel"]) | undefined;
5233
5321
  /** The name of the button that opens the calendar, read by screen readers. */
@@ -5236,6 +5324,12 @@ platform's base. */
5236
5324
  "unavailable-message"?: (HelixHeadlessDateInput["unavailableMessage"]) | undefined;
5237
5325
  /** The message shown when `disable-dates` or `disable-days` bars a date. */
5238
5326
  unavailableMessage?: (HelixHeadlessDateInput["unavailableMessage"]) | undefined;
5327
+ /** The message for text that is no date, where `bad-input-message` is not
5328
+ set. `{mode}` is `single`, `range`, or `multiple`. */
5329
+ "unreadable-message"?: (HelixHeadlessDateInput["unreadableMessage"]) | undefined;
5330
+ /** The message for text that is no date, where `bad-input-message` is not
5331
+ set. `{mode}` is `single`, `range`, or `multiple`. */
5332
+ unreadableMessage?: (HelixHeadlessDateInput["unreadableMessage"]) | undefined;
5239
5333
  /** The name of the calendar's heading where it shows a page of years, with
5240
5334
  `{heading}` filled in. */
5241
5335
  "year-view-label"?: (HelixHeadlessDateInput["yearViewLabel"]) | undefined;
@@ -5264,6 +5358,18 @@ are not, where `bad-input-message` is not set. `{kind}` is `date` or
5264
5358
  are not, where `bad-input-message` is not set. `{kind}` is `date` or
5265
5359
  `time`. */
5266
5360
  incompleteMessage?: (HelixHeadlessDateInput["incompleteMessage"]) | undefined;
5361
+ /** What a screen reader hears before the segments of a range's second date
5362
+ or time, after each segment's own name. */
5363
+ "range-end-label"?: (HelixHeadlessDateInput["rangeEndLabel"]) | undefined;
5364
+ /** What a screen reader hears before the segments of a range's second date
5365
+ or time, after each segment's own name. */
5366
+ rangeEndLabel?: (HelixHeadlessDateInput["rangeEndLabel"]) | undefined;
5367
+ /** What a screen reader hears before the segments of a range's first date
5368
+ or time, after each segment's own name: "month, Start, Stay". */
5369
+ "range-start-label"?: (HelixHeadlessDateInput["rangeStartLabel"]) | undefined;
5370
+ /** What a screen reader hears before the segments of a range's first date
5371
+ or time, after each segment's own name: "month, Start, Stay". */
5372
+ rangeStartLabel?: (HelixHeadlessDateInput["rangeStartLabel"]) | undefined;
5267
5373
  /** Whether the field is a row of segments, one for each part of the date or
5268
5374
  time, in place of a line of text.
5269
5375
 
@@ -5487,6 +5593,8 @@ export type HelixHeadlessDateInputVueEvents = {
5487
5593
  "helix-before-close": HelixHeadlessDateInputHelixBeforeCloseElementEvent;
5488
5594
  /** Fired before the calendar opens. Cancelable: call `preventDefault()` to keep it closed. */
5489
5595
  "helix-before-open": HelixHeadlessDateInputHelixBeforeOpenElementEvent;
5596
+ /** Fired after the clear button has emptied the field, after `input` and `change`. */
5597
+ "helix-clear": HelixHeadlessDateInputHelixClearElementEvent;
5490
5598
  /** Fired after the value changes. */
5491
5599
  input: HelixHeadlessDateInputElementEvent;
5492
5600
  /** Fired when the calendar opens or closes, with `newState` and `oldState`. */
@@ -5530,14 +5638,16 @@ it is one of the five, such as `buddhist` for `th-TH` or `japanese` for
5530
5638
  `ja-JP-u-ca-japanese`, and `gregory` for every other, such as `persian`
5531
5639
  for `fa-IR`.
5532
5640
 
5533
- `persian`, `hebrew`, `islamic-umalqura`, `islamic-civil`, `ethiopic`,
5534
- `coptic`, and `indian` draw a calendar with months of its own, as React
5535
- Aria's calendars do: each grid is one of that calendar's months, the
5536
- Hebrew leap month and Ethiopia's five-day thirteenth month included, and
5537
- Previous, Next and the page keys move by those months. `month` and
5641
+ `persian`, `hebrew`, `islamic`, `islamic-umalqura`, `islamic-civil`,
5642
+ `islamic-tbla`, `islamic-rgsa`, `ethiopic`, `ethioaa`, `coptic`,
5643
+ `indian`, `chinese`, and `dangi` draw a calendar with months of its own,
5644
+ as React Aria's calendars do: each grid is one of that calendar's months,
5645
+ the Hebrew and Chinese leap months and Ethiopia's five-day thirteenth
5646
+ month included, and Previous, Next and the page keys move by those
5647
+ months. With `max-view`, the months view shows that calendar's year, of
5648
+ twelve or thirteen months, and the years view its years. `month` and
5538
5649
  `helix-navigate` then name a month by its first day, `YYYY-MM-DD`. The
5539
- heading stays text, as the months and years views are drawn in Gregorian
5540
- months only. The value is `YYYY-MM-DD` in every calendar. */
5650
+ value is `YYYY-MM-DD` in every calendar. */
5541
5651
  calendar?: (HelixHeadlessDatePicker["calendar"]) | undefined;
5542
5652
  /** The month to open on when `month` is not set. */
5543
5653
  "default-month"?: (HelixHeadlessDatePicker["defaultMonth"]) | undefined;
@@ -5684,6 +5794,18 @@ else set needs. */
5684
5794
  readOnly?: (HelixHeadlessDatePicker["readOnly"]) | undefined;
5685
5795
  /** Stops the form from submitting while no date is chosen. */
5686
5796
  required?: (HelixHeadlessDatePicker["required"]) | undefined;
5797
+ /** What a screen reader hears about the chosen dates: the grid's
5798
+ description, said again whenever the dates change. `{kind}` is `date`,
5799
+ `start` while a range holds one end, `range`, or `dates` for `multiple`.
5800
+ `{start}` and `{end}` are dates written in `locale`, and `{count}` is how
5801
+ many dates are chosen. */
5802
+ "selection-label"?: (HelixHeadlessDatePicker["selectionLabel"]) | undefined;
5803
+ /** What a screen reader hears about the chosen dates: the grid's
5804
+ description, said again whenever the dates change. `{kind}` is `date`,
5805
+ `start` while a range holds one end, `range`, or `dates` for `multiple`.
5806
+ `{start}` and `{end}` are dates written in `locale`, and `{count}` is how
5807
+ many dates are chosen. */
5808
+ selectionLabel?: (HelixHeadlessDatePicker["selectionLabel"]) | undefined;
5687
5809
  /** How far apart the selectable dates are, in days.
5688
5810
 
5689
5811
  `<input type="date" step>`'s own unit, counted from `min` where there is
@@ -7028,12 +7150,14 @@ export type HelixHeadlessFilterInputVueEvents = {
7028
7150
 
7029
7151
  export type HelixHeadlessFormatDateVueProps = {
7030
7152
  /** The calendar a date is written in: `gregory`, `buddhist`, `japanese`,
7031
- `roc`, or `iso8601`, the calendars Date Picker and Date Input draw.
7032
-
7033
- Absent is the locale's own where it is one of the five, such as
7034
- `buddhist` for `th-TH`, and `gregory` for every other, such as `persian`
7035
- for `fa-IR`, so a date written here reads as the same date a Date Picker
7036
- beside it shows. */
7153
+ `roc`, or `iso8601`, or a calendar with months of its own, such as
7154
+ `persian`, `hebrew`, `islamic-umalqura`, `ethiopic`, or `chinese`: every
7155
+ calendar Date Picker and Date Input draw.
7156
+
7157
+ Absent is the locale's own where its months are the Gregorian months,
7158
+ such as `buddhist` for `th-TH`, and `gregory` for every other, such as
7159
+ `persian` for `fa-IR`, so a date written here reads as the same date a
7160
+ Date Picker beside it shows. Write `calendar="persian"` for Mehr 14, 1405. */
7037
7161
  calendar?: (HelixHeadlessFormatDate["calendar"]) | undefined;
7038
7162
  /** The timestamp, in any format `Date` can parse.
7039
7163
 
@@ -7059,6 +7183,14 @@ browser may use either. */
7059
7183
  dateStyle?: (HelixHeadlessFormatDate["dateStyle"]) | undefined;
7060
7184
  /** How the day of the month is written, where a date is shown. */
7061
7185
  day?: (HelixHeadlessFormatDate["day"]) | undefined;
7186
+ /** Writes the part of the day in words, such as "in the morning" or "at
7187
+ night", in its `long`, `short`, or `narrow` form, where `hour` is on a
7188
+ twelve-hour clock. */
7189
+ "day-period"?: (HelixHeadlessFormatDate["dayPeriod"]) | undefined;
7190
+ /** Writes the part of the day in words, such as "in the morning" or "at
7191
+ night", in its `long`, `short`, or `narrow` form, where `hour` is on a
7192
+ twelve-hour clock. */
7193
+ dayPeriod?: (HelixHeadlessFormatDate["dayPeriod"]) | undefined;
7062
7194
  /** Shows how long ago the timestamp was, in a compact form such as "3h", in
7063
7195
  place of the date.
7064
7196
 
@@ -7076,6 +7208,12 @@ Off by default, which draws the date as one run of text, as Shoelace and
7076
7208
  Web Awesome do. An `elapsed` or `relative` reading is one phrase either
7077
7209
  way. */
7078
7210
  fields?: (HelixHeadlessFormatDate["fields"]) | undefined;
7211
+ /** How many digits of a fraction of a second to write after `second`: 1, 2,
7212
+ or 3, as in 09:41:07.250. */
7213
+ "fractional-second-digits"?: (HelixHeadlessFormatDate["fractionalSecondDigits"]) | undefined;
7214
+ /** How many digits of a fraction of a second to write after `second`: 1, 2,
7215
+ or 3, as in 09:41:07.250. */
7216
+ fractionalSecondDigits?: (HelixHeadlessFormatDate["fractionalSecondDigits"]) | undefined;
7079
7217
  /** Draws an `elapsed` or `relative` reading once and leaves it, where it
7080
7218
  would otherwise move on as it goes stale.
7081
7219
 
@@ -7138,9 +7276,13 @@ Empty is the runtime's own. */
7138
7276
 
7139
7277
  Empty is the runtime's own. */
7140
7278
  timeZone?: (HelixHeadlessFormatDate["timeZone"]) | undefined;
7141
- /** Shows the name of the time zone, in its `long` or `short` form. */
7279
+ /** Shows the name of the time zone: `long` or `short`, as Pacific Daylight
7280
+ Time or PDT, `longOffset` or `shortOffset`, as GMT-07:00 or GMT-7, or
7281
+ `longGeneric` or `shortGeneric`, as Pacific Time or PT. */
7142
7282
  "time-zone-name"?: (HelixHeadlessFormatDate["timeZoneName"]) | undefined;
7143
- /** Shows the name of the time zone, in its `long` or `short` form. */
7283
+ /** Shows the name of the time zone: `long` or `short`, as Pacific Daylight
7284
+ Time or PDT, `longOffset` or `shortOffset`, as GMT-07:00 or GMT-7, or
7285
+ `longGeneric` or `shortGeneric`, as Pacific Time or PT. */
7144
7286
  timeZoneName?: (HelixHeadlessFormatDate["timeZoneName"]) | undefined;
7145
7287
  /** How the weekday is written, where one is shown. */
7146
7288
  weekday?: (HelixHeadlessFormatDate["weekday"]) | undefined;
@@ -13475,6 +13617,14 @@ rather than a thumb sitting on nothing. */
13475
13617
  middle of the track, or `end` at `max`. Absent is `start`. A range fills
13476
13618
  between its thumbs and ignores it. */
13477
13619
  origin?: (HelixHeadlessSlider["origin"]) | undefined;
13620
+ /** How far Page Up and Page Down move a thumb, in the slider's own units, as
13621
+ React Aria's `pageSize` and Zag's `largeStep` do. Absent leaves the keys
13622
+ to the platform, which moves a tenth of the track. */
13623
+ "page-step"?: (HelixHeadlessSlider["pageStep"] | `${number}`) | undefined;
13624
+ /** How far Page Up and Page Down move a thumb, in the slider's own units, as
13625
+ React Aria's `pageSize` and Zag's `largeStep` do. Absent leaves the keys
13626
+ to the platform, which moves a tenth of the track. */
13627
+ pageStep?: (HelixHeadlessSlider["pageStep"]) | undefined;
13478
13628
  /** Adds a second thumb, so the value is a pair.
13479
13629
 
13480
13630
  The pair is one string, `"10,50"`, which is what `value` and
@@ -14862,7 +15012,19 @@ known by its place among the rows as written. */
14862
15012
 
14863
15013
  export type HelixHeadlessTableRowVueEvents = {};
14864
15014
 
15015
+ /** `HelixHeadlessTabPanel` component event */
15016
+ export type HelixHeadlessTabPanelElementEvent<E = Event> = TypedEvent<
15017
+ HelixHeadlessTabPanel,
15018
+ E
15019
+ >;
15020
+ /** `helix-load` event type */
15021
+ export type HelixHeadlessTabPanelHelixLoadElementEvent =
15022
+ HelixHeadlessTabPanelElementEvent<HelixLoadEvent>;
15023
+
14865
15024
  export type HelixHeadlessTabPanelVueProps = {
15025
+ /** Whether the panel's content waits in a `<template>` until the panel is
15026
+ first shown. */
15027
+ lazy?: (HelixHeadlessTabPanel["lazy"]) | undefined;
14866
15028
  /** Whether this panel is the visible one. */
14867
15029
  selected?: (HelixHeadlessTabPanel["selected"]) | undefined;
14868
15030
  /** Pairs the panel with the tab of the same value. */
@@ -14880,7 +15042,10 @@ the pattern names one anyway. */
14880
15042
  label?: (HelixHeadlessTabPanel["label"]) | undefined;
14881
15043
  };
14882
15044
 
14883
- export type HelixHeadlessTabPanelVueEvents = {};
15045
+ export type HelixHeadlessTabPanelVueEvents = {
15046
+ /** Fired the first time a `lazy` panel is shown, once its template's content is in. */
15047
+ "helix-load": HelixHeadlessTabPanelHelixLoadElementEvent;
15048
+ };
14884
15049
 
14885
15050
  /** `HelixHeadlessTabs` component event */
14886
15051
  export type HelixHeadlessTabsElementEvent<E = Event> = TypedEvent<
@@ -15396,6 +15561,9 @@ export type HelixHeadlessTimeInputHelixBeforeCloseElementEvent =
15396
15561
  /** `helix-before-open` event type */
15397
15562
  export type HelixHeadlessTimeInputHelixBeforeOpenElementEvent =
15398
15563
  HelixHeadlessTimeInputElementEvent<HelixBeforeOpenEvent>;
15564
+ /** `helix-clear` event type */
15565
+ export type HelixHeadlessTimeInputHelixClearElementEvent =
15566
+ HelixHeadlessTimeInputElementEvent<HelixClearEvent>;
15399
15567
  /** `toggle` event type */
15400
15568
  export type HelixHeadlessTimeInputToggleElementEvent =
15401
15569
  HelixHeadlessTimeInputElementEvent<ToggleEvent>;
@@ -15406,6 +15574,14 @@ export type HelixHeadlessTimeInputVueProps = {
15406
15574
  Empty leaves the attribute off, which is the browser's default and is what
15407
15575
  lets autofill work at all. */
15408
15576
  autocomplete?: (HelixHeadlessTimeInput["autocomplete"]) | undefined;
15577
+ /** Whether the field shows a button that empties it, as Input's `clearable`
15578
+ does. Shown only while the field holds something to clear and is neither
15579
+ disabled nor read-only. */
15580
+ clearable?: (HelixHeadlessTimeInput["clearable"]) | undefined;
15581
+ /** The accessible name of the clear button, which shows only an icon. */
15582
+ "clear-label"?: (HelixHeadlessTimeInput["clearLabel"]) | undefined;
15583
+ /** The accessible name of the clear button, which shows only an icon. */
15584
+ clearLabel?: (HelixHeadlessTimeInput["clearLabel"]) | undefined;
15409
15585
  /** Times that cannot be chosen, as `HH:mm`, separated by commas or spaces.
15410
15586
 
15411
15587
  Handed to the list, which offers them as unavailable, and checked against
@@ -15509,6 +15685,12 @@ never something this element would refuse to read back. */
15509
15685
  "unavailable-message"?: (HelixHeadlessTimeInput["unavailableMessage"]) | undefined;
15510
15686
  /** The message shown when `disable-times` bars a time. */
15511
15687
  unavailableMessage?: (HelixHeadlessTimeInput["unavailableMessage"]) | undefined;
15688
+ /** The message for text that is no time, where `bad-input-message` is not
15689
+ set. `{mode}` is `single`, `range`, or `multiple`, and `{shape}` is `HH:mm`, or `HH:mm:ss` with `seconds`. */
15690
+ "unreadable-message"?: (HelixHeadlessTimeInput["unreadableMessage"]) | undefined;
15691
+ /** The message for text that is no time, where `bad-input-message` is not
15692
+ set. `{mode}` is `single`, `range`, or `multiple`, and `{shape}` is `HH:mm`, or `HH:mm:ss` with `seconds`. */
15693
+ unreadableMessage?: (HelixHeadlessTimeInput["unreadableMessage"]) | undefined;
15512
15694
  /** Whether the panel shows one list of times or a column for each part of the
15513
15695
  time.
15514
15696
 
@@ -15546,6 +15728,18 @@ are not, where `bad-input-message` is not set. `{kind}` is `date` or
15546
15728
  are not, where `bad-input-message` is not set. `{kind}` is `date` or
15547
15729
  `time`. */
15548
15730
  incompleteMessage?: (HelixHeadlessTimeInput["incompleteMessage"]) | undefined;
15731
+ /** What a screen reader hears before the segments of a range's second date
15732
+ or time, after each segment's own name. */
15733
+ "range-end-label"?: (HelixHeadlessTimeInput["rangeEndLabel"]) | undefined;
15734
+ /** What a screen reader hears before the segments of a range's second date
15735
+ or time, after each segment's own name. */
15736
+ rangeEndLabel?: (HelixHeadlessTimeInput["rangeEndLabel"]) | undefined;
15737
+ /** What a screen reader hears before the segments of a range's first date
15738
+ or time, after each segment's own name: "month, Start, Stay". */
15739
+ "range-start-label"?: (HelixHeadlessTimeInput["rangeStartLabel"]) | undefined;
15740
+ /** What a screen reader hears before the segments of a range's first date
15741
+ or time, after each segment's own name: "month, Start, Stay". */
15742
+ rangeStartLabel?: (HelixHeadlessTimeInput["rangeStartLabel"]) | undefined;
15549
15743
  /** Whether the field is a row of segments, one for each part of the date or
15550
15744
  time, in place of a line of text.
15551
15745
 
@@ -15758,6 +15952,8 @@ export type HelixHeadlessTimeInputVueEvents = {
15758
15952
  "helix-before-close": HelixHeadlessTimeInputHelixBeforeCloseElementEvent;
15759
15953
  /** Fired before the list opens. Cancelable: canceling it keeps the list closed and leaves the decision to you. */
15760
15954
  "helix-before-open": HelixHeadlessTimeInputHelixBeforeOpenElementEvent;
15955
+ /** Fired after the clear button has emptied the field, after `input` and `change`. */
15956
+ "helix-clear": HelixHeadlessTimeInputHelixClearElementEvent;
15761
15957
  /** Fired after the value changes. */
15762
15958
  input: HelixHeadlessTimeInputElementEvent;
15763
15959
  /** Fired after the list opens or closes, with `newState` and `oldState`. */
@@ -16244,6 +16440,12 @@ consumer's server markup does not have. A sheet carries the resting
16244
16440
  arrangement in its own `:host` rule and the selectors describe only the
16245
16441
  departures, which is what `orientation` does. */
16246
16442
  placement?: (HelixHeadlessToast["placement"]) | undefined;
16443
+ /** The edge a touch or a pen swipes a message toward to dismiss it: `end`,
16444
+ the end of the line, or `start`, `top` or `bottom`. Unset is `end`. */
16445
+ "swipe-direction"?: (HelixHeadlessToast["swipeDirection"]) | undefined;
16446
+ /** The edge a touch or a pen swipes a message toward to dismiss it: `end`,
16447
+ the end of the line, or `start`, `top` or `bottom`. Unset is `end`. */
16448
+ swipeDirection?: (HelixHeadlessToast["swipeDirection"]) | undefined;
16247
16449
  };
16248
16450
 
16249
16451
  export type HelixHeadlessToastVueEvents = {
@@ -16264,6 +16466,18 @@ export type HelixHeadlessToggleGroupHelixSelectElementEvent =
16264
16466
  HelixHeadlessToggleGroupElementEvent<HelixSelectEvent>;
16265
16467
 
16266
16468
  export type HelixHeadlessToggleGroupVueProps = {
16469
+ /** Whether a press on the chosen item, or Space or Enter on it, takes it
16470
+ back so nothing is chosen, as React Aria's `ToggleButtonGroup` and
16471
+ Radix's `ToggleGroup` do in a single group. Absent, a single group always
16472
+ keeps its choice once it has one, as a radio group does. A multiple group
16473
+ releases a pressed item either way. */
16474
+ "allow-empty-selection"?: (HelixHeadlessToggleGroup["allowEmptySelection"]) | undefined;
16475
+ /** Whether a press on the chosen item, or Space or Enter on it, takes it
16476
+ back so nothing is chosen, as React Aria's `ToggleButtonGroup` and
16477
+ Radix's `ToggleGroup` do in a single group. Absent, a single group always
16478
+ keeps its choice once it has one, as a radio group does. A multiple group
16479
+ releases a pressed item either way. */
16480
+ allowEmptySelection?: (HelixHeadlessToggleGroup["allowEmptySelection"]) | undefined;
16267
16481
  /** Where the group's label sits. `start` puts it on the track's line.
16268
16482
 
16269
16483
  Absent is above, which is what a field looks like and what almost every
@@ -16744,6 +16958,14 @@ The shape is `Carousel`'s, which is the nearest thing in the library: a
16744
16958
  "next-label"?: (HelixHeadlessTour["nextLabel"]) | undefined;
16745
16959
  /** Label for the control that goes on. */
16746
16960
  nextLabel?: (HelixHeadlessTour["nextLabel"]) | undefined;
16961
+ /** What a press outside the current stop and its target does while the tour
16962
+ runs. Unset, nothing: the page stays usable. `close` ends the tour, as
16963
+ Skip does, and `block` refuses the press. */
16964
+ "outside-press"?: (HelixHeadlessTour["outsidePress"]) | undefined;
16965
+ /** What a press outside the current stop and its target does while the tour
16966
+ runs. Unset, nothing: the page stays usable. `close` ends the tour, as
16967
+ Skip does, and `block` refuses the press. */
16968
+ outsidePress?: (HelixHeadlessTour["outsidePress"]) | undefined;
16747
16969
  /** Draws each stop's place in the run in its panel, as well as saying it. */
16748
16970
  progress?: (HelixHeadlessTour["progress"]) | undefined;
16749
16971
  /** Each stop's place in the run, with `{index}` and `{count}` filled in and
@@ -16852,6 +17074,9 @@ heading. */
16852
17074
  Reflected, because the styled tier places a dialog and a floating panel by
16853
17075
  it, and unset at rest, so no default is written onto the host. */
16854
17076
  type?: (HelixHeadlessTourStop["type"]) | undefined;
17077
+ /** Run as the tour reaches the stop, before it is shown: see the description
17078
+ above. A function, so it is set from script and has no attribute. */
17079
+ effect?: (HelixHeadlessTourStop["effect"]) | undefined;
16855
17080
  };
16856
17081
 
16857
17082
  export type HelixHeadlessTourStopVueEvents = {
@@ -18128,6 +18353,8 @@ export type CustomCssProperties = {
18128
18353
  "--toast-duration"?: (string) | undefined;
18129
18354
  /** How far a swipe has moved the message across, in pixels, toward the right. */
18130
18355
  "--toast-swipe-x"?: (string) | undefined;
18356
+ /** How far a swipe has moved the message down, in pixels, under a `swipe-direction` of `top` or `bottom`. */
18357
+ "--toast-swipe-y"?: (string) | undefined;
18131
18358
  /** The lit box's height, in pixels, padding included. Written on the spotlight while it lights a target. */
18132
18359
  "--tour-spotlight-height"?: (string) | undefined;
18133
18360
  /** The lit box's width, in pixels, padding included. Written on the spotlight while it lights a target. */
@@ -18168,7 +18395,7 @@ export interface WcToolkitVueGlobalComponents {
18168
18395
  HelixHeadlessAnnouncementVueProps,
18169
18396
  HelixHeadlessAnnouncementVueEvents
18170
18397
  >;
18171
- /** Tracks whether the page has scrolled and sets the custom state 'scrolled', so the styled tier can lift the bar without a scroll handler of its own. The state is read when the element connects. A fresh load starts at the top, which matches the server markup, and a reload partway down the page is corrected on hydration. The element uses a custom state because an attribute such as 'data-scrolled', written onto its own host, is one the server did not send. A hydrating framework would report a mismatch whenever the page reloads far enough down. 'ElementInternals.states' is not in the DOM, so hydration has nothing to compare. Select the state with ':state(scrolled)'. The page is the window unless 'scroller' names the element that scrolls, for an app shell whose content scrolls inside a container. **Set 'hide-on-scroll' for a bar that moves out of the way.** Scrolling down past the bar's own height hides it, and scrolling up shows it again, as does focus moving into it. The custom state 'hidden' is on the host while it is hidden, and the styled tier slides a 'sticky' bar up out of view. **Set 'fold-below' to fold the middle region on a narrow screen.** Below that many pixels of the bar's own width, the middle region is hidden behind a toggle at the end of the bar, named by 'menu-label'. The toggle says whether the region is open with 'aria-expanded', and the region opens below the row. Escape closes it and puts focus back on the toggle. The custom state 'folded' is on the host while the bar is that narrow, and 'open' while the folded region is open. A server serves the bar unfolded, and the browser folds it once it has measured it. The host is the page's 'banner' landmark. Placed inside 'main', 'article', 'aside', 'nav' or 'section', it is a plain box instead, as a native '<header>' is there, so a header inside a card or a pane does not add a second banner. The ancestors are read as the accessibility tree reads them, through the slots that take the header in, so one slotted into a component that draws a '<nav>', such as 'Navigation', is not a banner either. A server cannot see the ancestors, so it serves the banner and the browser corrects it when the element connects. */
18398
+ /** Tracks whether the page has scrolled and sets the custom state 'scrolled', so the styled tier can lift the bar without a scroll handler of its own. The state is read when the element connects. A fresh load starts at the top, which matches the server markup, and a reload partway down the page is corrected on hydration. The element uses a custom state because an attribute such as 'data-scrolled', written onto its own host, is one the server did not send. A hydrating framework would report a mismatch whenever the page reloads far enough down. 'ElementInternals.states' is not in the DOM, so hydration has nothing to compare. Select the state with ':state(scrolled)'. The page is the window unless 'scroller' names the element that scrolls, for an app shell whose content scrolls inside a container. **Set 'hide-on-scroll' for a bar that moves out of the way.** Scrolling down past the bar's own height hides it, and scrolling up shows it again, as does focus moving into it. The custom state 'hidden' is on the host while it is hidden, and the styled tier slides a 'sticky' bar up out of view. **Set 'fold-below' to fold the middle region on a narrow screen.** Below that many pixels of the bar's own width, the middle region is hidden behind a toggle at the end of the bar, named by 'menu-label', or at its start with 'toggle-placement="start"'. The toggle says whether the region is open with 'aria-expanded', and the region opens below the row. The region follows the toggle's region in focus order, so Tab from the toggle at the end goes into the open region. The custom state 'folded' is on the host while the bar is that narrow, and 'open' while the folded region is open. A server serves the bar unfolded, and the browser folds it once it has measured it. **'open' says whether the folded region is open, and setting it opens or closes the region.** 'requestOpen(true)' and 'requestOpen(false)' do the same and send 'helix-before-open' or 'helix-before-close' first, which you can cancel, and 'toggleOpen()' asks for the opposite. 'toggle' follows every change. The region closes on Escape, which puts focus back on the toggle, when focus moves to something outside the header, and on a press outside it. A bar that widens past 'fold-below' closes its region. The host is the page's 'banner' landmark. Placed inside 'main', 'article', 'aside', 'nav' or 'section', it is a plain box instead, as a native '<header>' is there, so a header inside a card or a pane does not add a second banner. The ancestors are read as the accessibility tree reads them, through the slots that take the header in, so one slotted into a component that draws a '<nav>', such as 'Navigation', is not a banner either. A server cannot see the ancestors, so it serves the banner and the browser corrects it when the element connects. */
18172
18399
  "helix-headless-app-header": DefineCustomElement<
18173
18400
  HelixHeadlessAppHeader,
18174
18401
  HelixHeadlessAppHeaderVueProps,
@@ -18222,7 +18449,7 @@ export interface WcToolkitVueGlobalComponents {
18222
18449
  HelixHeadlessBreadcrumbsVueProps,
18223
18450
  HelixHeadlessBreadcrumbsVueEvents
18224
18451
  >;
18225
- /** Sets 'role="group"' on the host through internals, and 'label' names the group. Without a name, a screen reader announces the buttons as separate controls, and a development build warns once with the kind 'missing-name'. The group does not manage focus, so each button keeps its own tab stop. For one tab stop with arrow keys between a mix of controls, the APG toolbar pattern, use Toolbar. Buttons are slotted, so they stay your own elements and keep their own appearance and size. **Buttons that stay pressed.** With 'selection-mode', each button with a 'value' is a toggle button: a press presses or releases it, and it says so with 'aria-pressed'. 'single' keeps one pressed at a time, and a press on the pressed one releases it. 'multiple' lets any number be pressed. 'value' is the pressed values, comma separated. A press sends a cancelable 'helix-before-change' with the value it would leave, then 'change'. The pressed state is written on the control inside each button's shadow root, so the markup you rendered is never changed and a framework hydrating it sees what its server sent. That is also why only Helix buttons are toggles: a native '<button>' or a button without a 'value' stays a plain action button in the group, and a native one without its own 'aria-pressed' warns once, with the runtime kind 'untold-toggle'. The inner control also carries '--button-group-pressed', '1' or '0', for a '::part(button)' rule of yours. Use Toggle Group instead for a choice that belongs in a form, or one where the arrow keys choose as they move: it is a 'radiogroup' of options with a form value, 'required' and validation. A Button Group in a selection mode is a set of actions that stay on, such as bold and italic, or a view that a press switches, and it submits nothing. **Keyboard.** In a selection mode the group is one tab stop: the button focus was last on, then the first pressed one, then the first one. | Key | What it does | |---|---| | Right, Down | Moves to the next button, from the last back to the first. | | Left, Up | Moves to the button before, from the first round to the last. | | Home, End | Moves to the first or the last button. | | Space, Enter | Presses or releases the focused button. | Left and Right swap on a right-to-left page, and a disabled button is passed over. In a selection mode the group is a 'toolbar', with 'aria-orientation' under 'orientation="vertical"'. Inside a toolbar it stays a named 'group', and the toolbar's own arrow keys walk its buttons, so a reader meets one toolbar. */
18452
+ /** Sets 'role="group"' on the host through internals, and 'label' names the group. Without a name, a screen reader announces the buttons as separate controls, and a development build warns once with the kind 'missing-name'. The group does not manage focus, so each button keeps its own tab stop. For one tab stop with arrow keys between a mix of controls, the APG toolbar pattern, use Toolbar. Buttons are slotted, so they stay your own elements and keep their own appearance and size. **Buttons that stay pressed.** With 'selection-mode', each button with a 'value' is a toggle button: a press presses or releases it. 'multiple' lets any number be pressed, and each button says so with 'aria-pressed'. 'single' keeps one pressed at a time: the group is a 'radiogroup' and each button a 'radio' that says so with 'aria-checked', as React Aria's toggle button group is. A press on the pressed one releases it, unless 'disallow-empty-selection' keeps one pressed. 'value' is the pressed values, comma separated. A press sends a cancelable 'helix-before-change' with the value it would leave, then 'change'. A pressed Helix button has ':state(pressed)' on its own element. The pressed state is written on the control inside each button's shadow root, so the markup you rendered is never changed and a framework hydrating it sees what its server sent. That is also why only Helix buttons are toggles: a native '<button>' or a button without a 'value' stays a plain action button in the group, and a native one without its own 'aria-pressed' warns once, with the runtime kind 'untold-toggle'. The inner control also carries '--button-group-pressed', '1' or '0', for a '::part(button)' rule of yours. Use Toggle Group instead for a choice that belongs in a form, or one where the arrow keys choose as they move: it is a 'radiogroup' of options with a form value, 'required' and validation. A Button Group in a selection mode is a set of actions that stay on, such as bold and italic, or a view that a press switches, and it submits nothing. **Keyboard.** In a selection mode the group is one tab stop: the button focus was last on, then the first pressed one, then the first one. | Key | What it does | |---|---| | Right, Down | Moves to the next button, from the last back to the first. | | Left, Up | Moves to the button before, from the first round to the last. | | Home, End | Moves to the first or the last button. | | Space, Enter | Presses or releases the focused button. | Left and Right swap on a right-to-left page, and a disabled button is passed over. Under 'multiple' the group is a 'toolbar', with 'aria-orientation' under 'orientation="vertical"'. Inside a toolbar it stays a named 'group', and the toolbar's own arrow keys walk its buttons, so a reader meets one toolbar. Under 'single' it is a 'radiogroup' either way. */
18226
18453
  "helix-headless-button-group": DefineCustomElement<
18227
18454
  HelixHeadlessButtonGroup,
18228
18455
  HelixHeadlessButtonGroupVueProps,
@@ -18348,13 +18575,13 @@ export interface WcToolkitVueGlobalComponents {
18348
18575
  HelixHeadlessDataTableVueProps,
18349
18576
  HelixHeadlessDataTableVueEvents
18350
18577
  >;
18351
- /** The calendar is 'DatePicker', which handles months, ranges, disabled days, the first day of the week, and the grid's keyboard behavior. The date input adds the field, the overlay, and the connection between them. You can type a date as well as pick one. The native '<input type="date">' gives a picker and locale formatting but allows almost no styling, so the field is a text field. Typing sends 'input' on each keystroke and 'change' when you leave the field, as a text field does. A date picked from the calendar sends both. The trigger and ArrowDown open the calendar with focus on the selected day, Tab moves between the calendar's controls without leaving it, and Escape closes it and returns focus to the field. A press into the field opens the calendar too. Tab into the field opens nothing, and Tab out of the field closes the calendar. With 'segmented', the field is a row of segments in place of the text: a month, a day and a year in the order the locale writes them, each set with digits or the arrow keys. Alt+Down opens the calendar from a segment. Text that is not a date gives the form an empty value, as a native date field does, and 'value' keeps the text so it can be corrected. **Keyboard.** The field is one tab stop, or each segment is with 'segmented', and the trigger is one more. | Key | What it does | |---|---| | Down | In the text field, opens the calendar with focus on the chosen day. | | Alt with Down | Opens the calendar, from the text field or a segment. | | Enter | In the text field, takes the typed date and submits the form, as a native field does. | | Escape | Closes the calendar and puts focus back in the field. | | Tab | In the open calendar, moves between its controls. Out of the field, closes it. | | Up, Down on a segment | Steps the segment by one, round from its last value to its first. | | Page Up, Page Down on a segment | Steps by a page: a week of days, two months, or five years. | | Home, End on a segment | Goes to the segment's first or last value. | | Digits on a segment | Fill it, and move to the next once it can take no more. | | Backspace, Delete on a segment | Empty the segment. | | Left, Right on a segment | Move to the previous or the next segment, along the line of text. | In the calendar, the keys are 'DatePicker''s: the arrows move by a day or a week, Page Up and Page Down by a month, with Shift by a year, and Home and End to the start and the end of the week. */
18578
+ /** The calendar is 'DatePicker', which handles months, ranges, disabled days, the first day of the week, and the grid's keyboard behavior. The date input adds the field, the overlay, and the connection between them. You can type a date as well as pick one. The native '<input type="date">' gives a picker and locale formatting but allows almost no styling, so the field is a text field. Typing sends 'input' on each keystroke and 'change' when you leave the field, as a text field does. A date picked from the calendar sends both. The field reads ISO, '2026-08-04', and a date written in the order, the digits, and the month names of 'locale', '8/4/2026' or 'Aug 4, 2026' in 'en-US' and '4.8.2026' in 'de-DE', which becomes the value as you leave the field. The trigger and ArrowDown open the calendar with focus on the selected day, Tab moves between the calendar's controls without leaving it, and Escape closes it and returns focus to the field. A press into the field opens the calendar too. Tab into the field opens nothing, and Tab out of the field closes the calendar. The text field is a 'combobox' with 'aria-haspopup="dialog"', 'aria-expanded', and 'aria-controls', as in the APG date picker combobox, since Down opens the calendar from it. With 'segmented', the field is a row of segments in place of the text: a month, a day and a year in the order the locale writes them, each set with digits or the arrow keys. Alt+Down opens the calendar from a segment. A 'range' is two rows with a dash between them, the start and the end, as React Aria's DateRangePicker draws them, and 'multiple' keeps the text. Text that is not a date gives the form an empty value, as a native date field does, and 'value' keeps the text so it can be corrected. **Keyboard.** The field is one tab stop, or each segment is with 'segmented', and the trigger is one more. | Key | What it does | |---|---| | Down | In the text field, opens the calendar with focus on the chosen day. | | Alt with Down | Opens the calendar, from the text field or a segment. | | Enter | In the text field, takes the typed date and submits the form, as a native field does. | | Escape | Closes the calendar and puts focus back in the field. | | Tab | In the open calendar, moves between its controls. Out of the field, closes it. | | Up, Down on a segment | Steps the segment by one, round from its last value to its first. | | Page Up, Page Down on a segment | Steps by a page: a week of days, two months, or five years. | | Home, End on a segment | Goes to the segment's first or last value. | | Digits on a segment | Fill it, and move to the next once it can take no more. | | Backspace, Delete on a segment | Empty the segment. | | Left, Right on a segment | Move to the previous or the next segment, along the line of text. | In the calendar, the keys are 'DatePicker''s: the arrows move by a day or a week, Page Up and Page Down by a month, with Shift by a year, and Home and End to the start and the end of the week. */
18352
18579
  "helix-headless-date-input": DefineCustomElement<
18353
18580
  HelixHeadlessDateInput,
18354
18581
  HelixHeadlessDateInputVueProps,
18355
18582
  HelixHeadlessDateInputVueEvents
18356
18583
  >;
18357
- /** A grid of days that follows the APG date grid pattern: - The grid is one tab stop. Only the focused cell is in the tab sequence. - Arrow keys move by day and by week. - 'PageUp' and 'PageDown' move by month. - 'Home' and 'End' move to the start and end of the week. **Dates are 'YYYY-MM-DD' strings, and every calculation is in UTC**, because a local-time 'Date' shifts across a time zone or daylight-saving boundary. **The days are the Gregorian calendar's**, written in 'calendar': the locale's own where its months are the Gregorian months, as 'th-TH' writes 2569 for 2026, and 'gregory' where they are not, as for 'fa-IR'. 'month' sets which month the grid shows, separately from 'value', so paging selects nothing and you can control the view. When unset, it follows the first selected date, then the current month. 'mode' sets how many dates are held. Unset holds one, 'range' holds two and marks the dates between them, and 'multiple' toggles each date. All three read and write the same comma-separated 'value'. 'max-view' makes the heading a button that steps back to the months of the year, and with 'year' to a page of years, as Zag's date picker does. The arrows, Home, End and the page keys move there, Enter or a press chooses, and Escape goes back to the days. 'isDateUnavailable' and 'dayContent' are properties for a script: a rule that bars dates, and what each day shows in place of its number. The month heading is a live region, so a screen reader hears the new month when Previous or Next is pressed. Neither moves past 'min' or 'max', and the keys stop at them too. A value outside the bounds, on a barred day, or off 'step' reports 'rangeUnderflow', 'rangeOverflow', 'badInput' or 'stepMismatch', so a form does not submit it. */
18584
+ /** A grid of days that follows the APG date grid pattern: - The grid is one tab stop. Only the focused cell is in the tab sequence. - Arrow keys move by day and by week. - 'PageUp' and 'PageDown' move by month. - 'Home' and 'End' move to the start and end of the week. **Dates are 'YYYY-MM-DD' strings, and every calculation is in UTC**, because a local-time 'Date' shifts across a time zone or daylight-saving boundary. **The months are the ones 'calendar' counts**: the Gregorian months for the locale's own calendar where its months are the Gregorian months, as 'th-TH' writes 2569 for 2026, and 'gregory' where they are not, as for 'fa-IR' with no 'calendar'. Name a calendar with months of its own, such as 'persian', and every view counts its days, months, and years from 'Intl'. 'month' sets which month the grid shows, separately from 'value', so paging selects nothing and you can control the view. When unset, it follows the first selected date, then the current month. 'mode' sets how many dates are held. Unset holds one, 'range' holds two and marks the dates between them, and 'multiple' toggles each date. All three read and write the same comma-separated 'value'. With a 'mode', the grid carries 'aria-multiselectable'. While a range holds one end, the grid draws the range to the day under the pointer or the focus, marking those cells 'data-range-preview'. The chosen date, range, or count of dates is the grid's description, in a region screen readers announce when it changes, as React Aria's calendars do. 'selection-label' words it. 'max-view' makes the heading a button that steps back to the months of the year, and with 'year' to a page of years, as Zag's date picker does. The arrows, Home, End and the page keys move there, Enter or a press chooses, and Escape goes back to the days. 'isDateUnavailable' and 'dayContent' are properties for a script: a rule that bars dates, and what each day shows in place of its number. The month heading is a live region, so a screen reader hears the new month when Previous or Next is pressed. Neither moves past 'min' or 'max', and the keys stop at them too. A value outside the bounds, on a barred day, or off 'step' reports 'rangeUnderflow', 'rangeOverflow', 'badInput' or 'stepMismatch', so a form does not submit it. */
18358
18585
  "helix-headless-date-picker": DefineCustomElement<
18359
18586
  HelixHeadlessDatePicker,
18360
18587
  HelixHeadlessDatePickerVueProps,
@@ -18450,7 +18677,7 @@ export interface WcToolkitVueGlobalComponents {
18450
18677
  HelixHeadlessFilterInputVueProps,
18451
18678
  HelixHeadlessFilterInputVueEvents
18452
18679
  >;
18453
- /** Formats a date with 'Intl' where it is shown, so you do not write the same 'Intl' call and options in your own code. **'elapsed' shows compact relative time for a feed**, such as "42m", "3h", or "1d". After six days it shows a date. In en-US, 'Intl.NumberFormat' narrow renders both 'minute' and 'month' as 'm', so a compact "3m" could mean three minutes or three months. 'elapsedTime' in 'helix/core' does the measurement. **'relative' shows the same reading in words**, such as "3 hours ago" at 'long', "3 hr. ago" at 'short' and "3h ago" at 'narrow', the styles 'sl-relative-time' offers. 'numeric="always"' says "1 day ago" where the default says "yesterday". **'date-style' and 'time-style' take each locale's own pattern**, such as "Tuesday, August 4, 2026" at 'full', and stand in for the separate fields, which 'Intl' refuses beside them. 'hour-cycle' sets a twelve or twenty-four hour clock either way. **The text refreshes on one timer shared by the page.** Each element schedules an update for when its current reading expires, and an element showing a date schedules none, so a long feed left open costs almost nothing. 'frozen' draws the reading once and leaves it. **'fields' draws each field of a date as a part of its own**, such as 'day', 'month' and 'year', so a stylesheet can set the year in a lighter ink or the weekday in capitals with '::part()'. The text between the fields is the locale's own and has no part. An 'elapsed' or 'relative' reading is one phrase, with no parts inside it. **The output is always '<time datetime>'**, so copy and paste and scripts parsing the page get the exact instant, whatever the visible text says. A screen reader reads the text, so an 'elapsed' reading is named in full, such as "3 hours ago", and carries the whole date as its title. **A date with no time, such as '2026-08-04', is that day everywhere.** It is formatted in UTC unless 'time-zone' says otherwise, as Date Input and Date Picker format their dates, so a reader west of UTC sees August 4 and not August 3. **A date is written in a calendar Date Picker draws**: the locale's own where its months are the Gregorian months, as 'th-TH' writes 2569 for 2026, and 'gregory' where they are not, as for 'fa-IR'. 'calendar' picks one of the five. */
18680
+ /** Formats a date with 'Intl' where it is shown, so you do not write the same 'Intl' call and options in your own code. **'elapsed' shows compact relative time for a feed**, such as "42m", "3h", or "1d". After six days it shows a date. In en-US, 'Intl.NumberFormat' narrow renders both 'minute' and 'month' as 'm', so a compact "3m" could mean three minutes or three months. 'elapsedTime' in 'helix/core' does the measurement. **'relative' shows the same reading in words**, such as "3 hours ago" at 'long', "3 hr. ago" at 'short' and "3h ago" at 'narrow', the styles 'sl-relative-time' offers. 'numeric="always"' says "1 day ago" where the default says "yesterday". **'date-style' and 'time-style' take each locale's own pattern**, such as "Tuesday, August 4, 2026" at 'full', and stand in for the separate fields, which 'Intl' refuses beside them. 'hour-cycle' sets a twelve or twenty-four hour clock either way. **The text refreshes on one timer shared by the page.** Each element schedules an update for when its current reading expires, and an element showing a date schedules none, so a long feed left open costs almost nothing. 'frozen' draws the reading once and leaves it. **'fields' draws each field of a date as a part of its own**, such as 'day', 'month' and 'year', so a stylesheet can set the year in a lighter ink or the weekday in capitals with '::part()'. The text between the fields is the locale's own and has no part. An 'elapsed' or 'relative' reading is one phrase, with no parts inside it. **The output is always '<time datetime>'**, so copy and paste and scripts parsing the page get the exact instant, whatever the visible text says. A screen reader reads the text, so an 'elapsed' reading is named in full, such as "3 hours ago", and carries the whole date as its title. **A date with no time, such as '2026-08-04', is that day everywhere.** It is formatted in UTC unless 'time-zone' says otherwise, as Date Input and Date Picker format their dates, so a reader west of UTC sees August 4 and not August 3. **A date is written in a calendar Date Picker draws**: the locale's own where its months are the Gregorian months, as 'th-TH' writes 2569 for 2026, and 'gregory' where they are not, as for 'fa-IR'. 'calendar' picks any of them, 'persian' and 'hebrew' included. */
18454
18681
  "helix-headless-format-date": DefineCustomElement<
18455
18682
  HelixHeadlessFormatDate,
18456
18683
  HelixHeadlessFormatDateVueProps,
@@ -18504,13 +18731,13 @@ export interface WcToolkitVueGlobalComponents {
18504
18731
  HelixHeadlessLegendVueProps,
18505
18732
  HelixHeadlessLegendVueEvents
18506
18733
  >;
18507
- /** Wraps one piece of content in the lightbox, such as a picture, a video frame, or a chart. The lightbox shows one item at a time, and the root decides which. Each item is a 'group' with the role description 'slide', named by its 'label' or, without one, by its place in the set, such as "2 of 5", as the APG carousel pattern names a slide. The lightbox supplies both words, so they are translated on the lightbox. An item that is not current is hidden and stays in the DOM, as a 'TabPanel' does. Crawlers can read it, it is in the server-rendered markup, and an '<img>' that has decoded does not decode again when you go back to it. */
18734
+ /** Wraps one piece of content in the lightbox, such as a picture, a video frame, or a chart. The lightbox shows one item at a time, and the root decides which. Each item is a 'group' with the role description 'slide', named by its 'label' or, without one, by its place in the set, such as "2 of 5", as the APG carousel pattern names a slide. The lightbox supplies both words, so they are translated on the lightbox. A 'description', while there is one, describes the group, so a screen reader says it with the name. An item that is not current is hidden and stays in the DOM, as a 'TabPanel' does. Crawlers can read it, it is in the server-rendered markup, and an '<img>' that has decoded does not decode again when you go back to it. */
18508
18735
  "helix-headless-lightbox-item": DefineCustomElement<
18509
18736
  HelixHeadlessLightboxItem,
18510
18737
  HelixHeadlessLightboxItemVueProps,
18511
18738
  HelixHeadlessLightboxItemVueEvents
18512
18739
  >;
18513
- /** The frame around content you open, such as a picture, a video frame, or a chart. The lightbox draws no content of its own. It provides the frame, the keyboard behavior, and text that states the current position in the set. The modal behavior comes from a native '<dialog>' opened with 'showModal()', which provides the top layer, a backdrop, Escape to close, and 'inert' on the rest of the document. Every way of closing goes through 'requestOpen', as in 'Dialog' and 'Drawer'. A lightbox shows one item at a time and has no scrolling track, so 'active' holds the current item, as in 'Tabs'. The arrow keys change the item while focus stays in the dialog. Set 'controls' for the viewer's own previous, next and close controls, named by 'previous-label', 'next-label' and 'dismiss-label', whose glyphs you can replace in the 'previous-icon', 'next-icon' and 'dismiss-icon' slots. Without it, compose the chrome yourself in the 'header' and 'footer' slots, with buttons that send '--previous', '--next' and '--close'. **Set 'max-zoom' to let a reader zoom into the shown item**, such as '3'. Two fingers pinch it, a double click or a double tap zooms all the way in about the point pressed and back out, and once zoomed one pointer drags it about. '+' and '-' zoom in and out from the keyboard, and '0' puts it back. The scale and the offset are on the 'viewport' part as '--lightbox-zoom', '--lightbox-pan-x' and '--lightbox-pan-y', written only while zoomed, and a swipe moves to the next item only while the item is at its own size. With 'controls', the viewer also draws zoom-out and zoom-in controls, for a pointer with no wheel and no second finger. Once a reader stops zooming, the live region says the new scale in the words of 'zoom-status-label', such as "Zoomed to 150%". Each item is a slide: a 'group' with the role description in 'slide-role-label', named by its 'label' or by 'slide-label'. A touch or a pen swiped across the picture shows the next or the previous item, the way the line of text runs. A press on the empty area around the item closes the viewer, as a press on the backdrop does. Under 'max-zoom', a press beside the item zooms on a double press and closes nothing, and only the space outside the viewport closes the viewer. A press that dragged closes nothing. **Keyboard.** Opening moves focus to the viewer itself, which a screen reader names. | Key | What it does | |---|---| | Right, Down | Shows the next item. On a right-to-left page, Left does. While the item is zoomed, the arrows move about it instead. | | Left, Up | Shows the previous item. | | Home, End | Shows the first or the last item. | | '+', '-', '0' | Zooms in, zooms out, and puts the item back at its own size, where 'max-zoom' allows zooming. | | Tab, Shift+Tab | Moves through the controls in the viewer, from the last round to the first and from the first round to the last. | | Escape | Closes the viewer. A 'helix-before-close' listener can refuse. | A development build warns when a viewer opens with no 'label'. The chrome hides when there is no input, through 'IdleController', and comes back on a pointer move, a key press, or a focus. It stays while focus is on a control in the header or the footer, so a keyboard reader is never left on a control that has gone. 'fullscreen' uses 'FullscreenController', as 'Video' does. While the viewer is open, the page behind it does not scroll. */
18740
+ /** The frame around content you open, such as a picture, a video frame, or a chart. The lightbox draws no content of its own. It provides the frame, the keyboard behavior, and text that states the current position in the set. The modal behavior comes from a native '<dialog>' opened with 'showModal()', which provides the top layer, a backdrop, Escape to close, and 'inert' on the rest of the document. Every way of closing goes through 'requestOpen', as in 'Dialog' and 'Drawer'. A lightbox shows one item at a time and has no scrolling track, so 'active' holds the current item, as in 'Tabs'. The arrow keys change the item while focus stays in the dialog. Set 'controls' for the viewer's own previous, next and close controls, named by 'previous-label', 'next-label' and 'dismiss-label', whose glyphs you can replace in the 'previous-icon', 'next-icon' and 'dismiss-icon' slots. Without it, compose the chrome yourself in the 'header' and 'footer' slots, with buttons that send '--previous', '--next' and '--close'. **Set 'max-zoom' to let a reader zoom into the shown item**, such as '3'. Two fingers pinch it, and so does a trackpad pinch or the wheel with Ctrl held, about the point under the pointer. A double click or a double tap zooms all the way in about the point pressed and back out, and once zoomed one pointer drags it about and the wheel moves it. '+' and '-' zoom in and out from the keyboard, and '0' puts it back. The scale and the offset are on the 'viewport' part as '--lightbox-zoom', '--lightbox-pan-x' and '--lightbox-pan-y', written only while zoomed, and a swipe moves to the next item only while the item is at its own size. With 'controls', the viewer also draws zoom-out and zoom-in controls, for a pointer with no wheel and no second finger. Once a reader stops zooming, the live region says the new scale in the words of 'zoom-status-label', such as "Zoomed to 150%". Each item is a slide: a 'group' with the role description in 'slide-role-label', named by its 'label' or by 'slide-label'. A touch or a pen swiped across the picture shows the next or the previous item, the way the line of text runs. A press on the empty area around the item closes the viewer, as a press on the backdrop does. Under 'max-zoom', a press beside the item zooms on a double press and closes nothing, and only the space outside the viewport closes the viewer. A press that dragged closes nothing. **Keyboard.** Opening moves focus to the viewer itself, which a screen reader names. | Key | What it does | |---|---| | Right, Down | Shows the next item. On a right-to-left page, Left does. While the item is zoomed, the arrows move about it instead. | | Left, Up | Shows the previous item. | | Home, End | Shows the first or the last item. | | '+', '-', '0' | Zooms in, zooms out, and puts the item back at its own size, where 'max-zoom' allows zooming. | | Tab, Shift+Tab | Moves through the controls in the viewer, from the last round to the first and from the first round to the last. | | Escape | Closes the viewer. A 'helix-before-close' listener can refuse. | A development build warns when a viewer opens with no 'label'. The chrome hides when there is no input, through 'IdleController', and comes back on a pointer move, a key press, or a focus. It stays while focus is on a control in the header or the footer, so a keyboard reader is never left on a control that has gone. 'fullscreen' uses 'FullscreenController', as 'Video' does. While the viewer is open, the page behind it does not scroll. */
18514
18741
  "helix-headless-lightbox": DefineCustomElement<
18515
18742
  HelixHeadlessLightbox,
18516
18743
  HelixHeadlessLightboxVueProps,
@@ -18798,7 +19025,7 @@ export interface WcToolkitVueGlobalComponents {
18798
19025
  HelixHeadlessSkipLinkVueProps,
18799
19026
  HelixHeadlessSkipLinkVueEvents
18800
19027
  >;
18801
- /** Renders a native '<input type="range">', so the drag, the arrow keys, Home, End, the page keys, and the touch target come from the platform. A native range has a hit area larger than its thumb, sized for a finger. The value is a string, like every other form control's, and 'MixinControllerValue' holds text. Use 'valueAsNumber' for arithmetic. Marks are drawn by the component. The ticks of a '<datalist>' cannot be styled, and Firefox does not render them for a range. Marks are decoration. 'step' sets where the value can land, and the input enforces it whether or not marks are drawn. 'markers' is a count, so a slider from zero to a hundred does not draw a hundred and one marks by accident. A range with two thumbs is two inputs stacked on one track, because there is no native two-thumb range. Each thumb keeps its own value, and a named range submits one entry per thumb under its name, the lowest first. A range given more than two values, such as 'default-value="20,50,80"', has a thumb for each, as React Aria's slider takes any number of thumbs: each stops at its neighbors, and the ones between the first and the last are named by 'thumb-label'. 'min-steps-between-thumbs' keeps them that many steps apart, and the readout joins the two as 'range-text' writes them. 'origin' sets where a single thumb's fill starts: at 'min', at the middle of the track, or at 'max'. A balance or an offset from zero fills from the middle, as Zag's slider 'origin' does. The fill's ends are published as '--slider-from' and '--slider-to'. 'format-options' writes the value with 'Intl.NumberFormat' in 'locale', as a currency, a percent or a unit, and 'formatter' writes it with a function of your own, such as words for a scale. Either one is what a screen reader hears, what the readout shows and what the marker labels say. 'value-text' still wraps it in a sentence, with the formatted value in its place. 'required' comes with the field mixin and cannot fail. A range is never empty: the platform shows its midpoint when no value is set, and 'willUpdate' seeds that midpoint into 'defaultValue', so the value matches the handle from the first render. HTML does not apply 'required' to a range either, so it is not set on the input. It only adds the marker beside the label. **Keyboard.** Each thumb is one tab stop, and its keys are the native range's. | Key | What it does | |---|---| | Right, Up | Moves the thumb up by 'step'. | | Left, Down | Moves the thumb down by 'step'. | | Page Up, Page Down | Moves the thumb by a larger step. | | Home, End | Moves the thumb to its lowest or highest value. | Under 'readonly' none of these move the thumb, and Tab still reaches it. Each thumb is an '<input type="range">' with 'aria-valuetext' where the value is formatted or worded. A range's thumbs say they stop at each other with 'aria-valuemin' and 'aria-valuemax'. */
19028
+ /** Renders a native '<input type="range">', so the drag, the arrow keys, Home, End, the page keys, and the touch target come from the platform. A native range has a hit area larger than its thumb, sized for a finger. The value is a string, like every other form control's, and 'MixinControllerValue' holds text. Use 'valueAsNumber' for arithmetic. Marks are drawn by the component. The ticks of a '<datalist>' cannot be styled, and Firefox does not render them for a range. Marks are decoration. 'step' sets where the value can land, and the input enforces it whether or not marks are drawn. 'markers' is a count, so a slider from zero to a hundred does not draw a hundred and one marks by accident. A range with two thumbs is two inputs stacked on one track, because there is no native two-thumb range. Each thumb keeps its own value, and a named range submits one entry per thumb under its name, the lowest first. A range given more than two values, such as 'default-value="20,50,80"', has a thumb for each, as React Aria's slider takes any number of thumbs: each stops at its neighbors, and the ones between the first and the last are named by 'thumb-label'. 'min-steps-between-thumbs' keeps them that many steps apart, and the readout joins the two as 'range-text' writes them. A press on a range's track takes the nearest thumb to the point pressed, and moving the pointer drags it, as React Aria's and Web Awesome's sliders do. The thumb takes focus, and 'change' is sent as the press ends. 'origin' sets where a single thumb's fill starts: at 'min', at the middle of the track, or at 'max'. A balance or an offset from zero fills from the middle, as Zag's slider 'origin' does. The fill's ends are published as '--slider-from' and '--slider-to'. 'format-options' writes the value with 'Intl.NumberFormat' in 'locale', as a currency, a percent or a unit, and 'formatter' writes it with a function of your own, such as words for a scale. Either one is what a screen reader hears, what the readout shows and what the marker labels say. 'value-text' still wraps it in a sentence, with the formatted value in its place. 'required' comes with the field mixin and cannot fail. A range is never empty: the platform shows its midpoint when no value is set, and 'willUpdate' seeds that midpoint into 'defaultValue', so the value matches the handle from the first render. HTML does not apply 'required' to a range either, so it is not set on the input. It only adds the marker beside the label. **Keyboard.** Each thumb is one tab stop, and its keys are the native range's. | Key | What it does | |---|---| | Right, Up | Moves the thumb up by 'step'. | | Left, Down | Moves the thumb down by 'step'. | | Page Up, Page Down | Moves the thumb by 'page-step', or by the platform's larger step where it is not set. | | Home, End | Moves the thumb to its lowest or highest value. | Under 'readonly' none of these move the thumb, and Tab still reaches it. Each thumb is an '<input type="range">' with 'aria-valuetext' where the value is formatted or worded. A range's thumbs say they stop at each other with 'aria-valuemin' and 'aria-valuemax'. */
18802
19029
  "helix-headless-slider": DefineCustomElement<
18803
19030
  HelixHeadlessSlider,
18804
19031
  HelixHeadlessSliderVueProps,
@@ -18852,7 +19079,7 @@ export interface WcToolkitVueGlobalComponents {
18852
19079
  HelixHeadlessStepsVueProps,
18853
19080
  HelixHeadlessStepsVueEvents
18854
19081
  >;
18855
- /** Only the step's name is a button. The marker is 'aria-hidden' decoration, so it is outside the button. The name uses 'Button', so the hover wash, the focus ring, and the disabled style come from 'Button'. Every step can be pressed and fires 'helix-select'. To stop the user from moving to a step, set 'disabled' on it. The marker is a slot, and its fallback shows the step's state: a check for a finished stage, a target for the current stage, and an empty ring for a stage not reached yet. Only that one mark is rendered, so the accessibility tree has no hidden marks. The half lines on each side of the mark are drawn on the step's '::before' and '::after' from properties the list sets, so the step renders no extra element for them. A finished stage says so in words: the name's button is described by 'complete-label', "Complete" unless you translate it, and a stage that becomes complete while the page is open says it once in a polite live region. The current stage's button carries 'aria-current="step"', and only the button, so the state is said once, on the control. */
19082
+ /** Only the step's name is a button. The marker is 'aria-hidden' decoration, so it is outside the button. The name uses 'Button', so the hover wash, the focus ring, and the disabled style come from 'Button'. Every step can be pressed and fires 'helix-select'. To stop the user from moving to a step, set 'disabled' on it. The marker is a slot, and its fallback shows the step's state: a check for a finished stage, a target for the current stage, and an empty ring for a stage not reached yet. Only that one mark is rendered, so the accessibility tree has no hidden marks. The half lines on each side of the mark are drawn on the step's '::before' and '::after' from properties the list sets, so the step renders no extra element for them. A finished stage says so in words: the name's button is described by 'complete-label', "Complete" unless you translate it, and a stage that becomes complete while the page is open says it once in a polite live region. The current stage's button carries 'aria-current="step"', and only the button, so the state is said once, on the control. A stage's 'content', while it holds anything, is a group named by the stage's name, so a screen reader moving into it hears which stage it belongs to. */
18856
19083
  "helix-headless-step": DefineCustomElement<
18857
19084
  HelixHeadlessStep,
18858
19085
  HelixHeadlessStepVueProps,
@@ -18888,19 +19115,19 @@ export interface WcToolkitVueGlobalComponents {
18888
19115
  HelixHeadlessTableRowVueProps,
18889
19116
  HelixHeadlessTableRowVueEvents
18890
19117
  >;
18891
- /** An inactive panel is hidden and stays mounted. Anything typed into it is still there when the person comes back, and the content of every panel is in the server-rendered markup for crawlers, whichever tab is open. The host is the 'tabpanel' while its tab is selected, through 'ElementInternals', so the tab's 'aria-controls' can reach it from the tab's shadow root. The box inside is a tab stop only while the panel holds nothing focusable, as the ARIA tabs pattern and React Aria's tab panel do: Tab from the tab list lands on the panel's first link or control where there is one, and on the panel itself where there is none. */
19118
+ /** An inactive panel is hidden and stays mounted. Anything typed into it is still there when the person comes back, and the content of every panel is in the server-rendered markup for crawlers, whichever tab is open. The host is the 'tabpanel' while its tab is selected, through 'ElementInternals', so the tab's 'aria-controls' can reach it from the tab's shadow root. The box inside is a tab stop only while the panel holds nothing focusable, as the ARIA tabs pattern and React Aria's tab panel do: Tab from the tab list lands on the panel's first link or control where there is one, and on the panel itself where there is none. **Set 'lazy' for a panel that is expensive to draw.** Its content waits in a '<template>' inside it, and goes into the panel the first time the panel is shown, so it costs nothing until a reader opens that tab. Once in, it stays. The panel sends 'helix-load' at the same moment, for content your code renders itself. */
18892
19119
  "helix-headless-tab-panel": DefineCustomElement<
18893
19120
  HelixHeadlessTabPanel,
18894
19121
  HelixHeadlessTabPanelVueProps,
18895
19122
  HelixHeadlessTabPanelVueEvents
18896
19123
  >;
18897
- /** Selection works through an event, the same as in the accordion and the tree. A tab dispatches 'helix-select', and the root pairs it with the panel of the same value. Nothing registers with anything, so tabs added later work with no extra setup. The tab list is a single tab stop, and the arrow keys move between tabs through 'KeyboardNavigationController', the same as in the radio and toggle groups. Selection follows focus, which suits a small set where showing a panel is cheap. Set 'manual' when showing a panel is expensive, so focus can move without selecting. 'orientation="vertical"' sets the tabs in a column beside the panels, and the tab list says 'aria-orientation="vertical"'. The arrow keys of both axes move between tabs either way. A tab with an 'href' is a link, for tabs that are pages of a site. Pressing it follows the link. Where any tab is a link, the arrow keys move focus without choosing on every tab of the list, as under 'manual', so arrowing past a tab never leaves the page and the list answers the keys one way. Mark the tab of the page you are on with 'selected', or set 'active' to its value. Each tab says which panel it controls through 'aria-controls', set as an element reference to the panel's host, where the engine has reflection. Keys, on the tab list: Left and Right Arrow move between tabs, and so do Up and Down; Home and End go to the first and the last. The horizontal arrows follow the reading direction, so on a right-to-left page Left moves on. Disabled tabs are passed over. Tab leaves the list for the selected panel, which is a tab stop only while it holds nothing focusable. **Keyboard.** | Key | What it does | |---|---| | Right, Down | Moves to the next tab, from the last round to the first. Selects it, unless 'manual' is set or a tab is a link. | | Left, Up | Moves to the tab before, from the first round to the last. | | Home, End | Moves to the first or the last tab. | | Enter, Space | Selects the tab with focus, or follows its link. | | Tab | Leaves the list for the selected panel. | Removing the selected tab selects the first enabled tab that is left, and 'active' says so, with 'helix-activate'. Where the removed tab had focus, focus moves to the tab now selected. **More tabs than fit.** With 'scroll-controls', a strip that scrolls shows a button at each end it can scroll toward, as Web Awesome's tab group does, and a press scrolls it most of its own length. The buttons are for the pointer, so they are out of the tab order and hidden from screen readers; the arrow keys already reach every tab, and the strip scrolls the selected tab into view. A strip scrolls once a stylesheet gives the 'tabs' part an 'overflow', as the styled tier does. A tab with 'dismissible' can be closed: see 'Tabs.Tab'. The 'indicator' part moves to the selected tab and carries its place and size, so a mark of your own can be drawn there: style the part, or slot an element into 'indicator', which sits inside the part and reads the same properties. */
19124
+ /** Selection works through an event, the same as in the accordion and the tree. A tab dispatches 'helix-select', and the root pairs it with the panel of the same value. Nothing registers with anything, so tabs added later work with no extra setup. The tab list is a single tab stop, and the arrow keys move between tabs through 'KeyboardNavigationController', the same as in the radio and toggle groups. Selection follows focus, which suits a small set where showing a panel is cheap. Set 'manual' when showing a panel is expensive, so focus can move without selecting. 'orientation="vertical"' sets the tabs in a column beside the panels, and the tab list says 'aria-orientation="vertical"'. The arrow keys of both axes move between tabs either way. A tab with an 'href' is a link, for tabs that are pages of a site. Pressing it follows the link. Where any tab is a link, the arrow keys move focus without choosing on every tab of the list, as under 'manual', so arrowing past a tab never leaves the page and the list answers the keys one way. Mark the tab of the page you are on with 'selected', or set 'active' to its value. Each tab says which panel it controls through 'aria-controls', set as an element reference to the panel's host, where the engine has reflection. Keys, on the tab list: Left and Right Arrow move between tabs, and so do Up and Down; Home and End go to the first and the last. The horizontal arrows follow the reading direction, so on a right-to-left page Left moves on. Disabled tabs are passed over. Tab leaves the list for the selected panel, which is a tab stop only while it holds nothing focusable. **Keyboard.** | Key | What it does | |---|---| | Right, Down | Moves to the next tab, from the last round to the first. Selects it, unless 'manual' is set or a tab is a link. | | Left, Up | Moves to the tab before, from the first round to the last. | | Home, End | Moves to the first or the last tab. | | Enter, Space | Selects the tab with focus, or follows its link. | | Tab | Leaves the list for the selected panel. | Removing the selected tab selects the enabled tab beside it, the next one or else the one before, and 'active' says so, with 'helix-activate'. Where the removed tab had focus, focus moves to the tab now selected. **More tabs than fit.** With 'scroll-controls', a strip that scrolls shows a button at each end it can scroll toward, as Web Awesome's tab group does, and a press scrolls it most of its own length. The buttons are for the pointer, so they are out of the tab order and hidden from screen readers; the arrow keys already reach every tab, and the strip scrolls the selected tab into view. A strip scrolls once a stylesheet gives the 'tabs' part an 'overflow', as the styled tier does. A tab with 'dismissible' can be closed: see 'Tabs.Tab'. The 'indicator' part moves to the selected tab and carries its place and size, so a mark of your own can be drawn there: style the part, or slot an element into 'indicator', which sits inside the part and reads the same properties. */
18898
19125
  "helix-headless-tabs": DefineCustomElement<
18899
19126
  HelixHeadlessTabs,
18900
19127
  HelixHeadlessTabsVueProps,
18901
19128
  HelixHeadlessTabsVueEvents
18902
19129
  >;
18903
- /** A tab is an element, because it manages selection and its own tab stop. With an 'href', the tab is a link: 'role="tab"' on an '<a>', which a press, Enter and the browser's own link gestures follow. 'helix-select' is sent first, and canceling it keeps the browser from following, so a client-side router follows it instead. With 'dismissible', the tab can be closed, as Web Awesome's closable tab can: a press on its 'dismiss' mark, or Delete or Backspace while the tab has focus, sends 'helix-dismiss'. The tab does not remove itself, because your code owns the set, so remove the tab and its panel in your handler. Focus moves to the tab beside it, and the tab set selects a tab that is left. The tab says the key through 'aria-keyshortcuts', and the mark is for the pointer, hidden from screen readers. */
19130
+ /** A tab is an element, because it manages selection and its own tab stop. With an 'href', the tab is a link: 'role="tab"' on an '<a>', which a press, Enter and the browser's own link gestures follow. 'helix-select' is sent first, and canceling it keeps the browser from following, so a client-side router follows it instead. With 'dismissible', the tab can be closed, as Web Awesome's closable tab can: a press on its 'dismiss' mark, or Delete or Backspace while the tab has focus, sends 'helix-dismiss'. The tab does not remove itself, because your code owns the set, so remove the tab and its panel in your handler. Focus moves to the tab beside it, and where the tab was selected, the tab set selects that same tab. The tab says the key through 'aria-keyshortcuts', and the mark is for the pointer, hidden from screen readers. */
18904
19131
  "helix-headless-tab": DefineCustomElement<
18905
19132
  HelixHeadlessTab,
18906
19133
  HelixHeadlessTabVueProps,
@@ -18924,13 +19151,13 @@ export interface WcToolkitVueGlobalComponents {
18924
19151
  HelixHeadlessTextareaVueProps,
18925
19152
  HelixHeadlessTextareaVueEvents
18926
19153
  >;
18927
- /** The list is a 'TimePicker', which you can also use on its own, for example in a settings pane. This element adds the field, the overlay, and the form association, the same arrangement Date Input has with 'DatePicker' and Color Input has with 'ColorPicker'. You can type a time or pick one. The list offers times at a step, and the field lets you enter any time, such as '09:07'. The value is always 'HH:mm' on a 24-hour clock, or 'HH:mm:ss' with 'seconds', because that is what the form submits, what 'min' and 'max' compare against, and what sorts correctly as a string. While idle, the field shows the time in the user's locale format. Once the caret is in the field, it shows the value itself, because a formatted time such as '2:30 PM' cannot be typed back and 'Intl' has no parser for it. Typing sends 'input' on each keystroke and 'change' when you leave the field. The trigger and ArrowDown open the list, and so does a press into the field; Tab into the field opens nothing. In the list, the arrow keys, typed digits and PageUp and PageDown move through the times, and Enter, Space or a click chooses one and closes the panel. With 'variant="wheels"' each wheel moves the time as you turn it, the panel stays open, and Enter or Escape closes it. With 'segmented', the field is a row of segments in place of the text: an hour, a minute, and AM or PM where the clock has them, each set with digits or the arrow keys. Alt+Down opens the list from a segment. Text that is not a time gives the form an empty value, as a native time field does, and 'value' keeps the text so it can be corrected. **Keyboard.** The field is one tab stop, or each segment is with 'segmented', and the trigger is one more. | Key | What it does | |---|---| | Down | In the text field, opens the list on the chosen time. | | Alt with Down | Opens the list, from the text field or a segment. | | Enter | In the text field, takes the typed time and submits the form, as a native field does. In the list, chooses the highlighted time. | | Escape | Closes the list and puts focus back in the field. | | Up, Down on a segment | Steps the segment by one, round from its last value to its first. | | Page Up, Page Down on a segment | Steps by a page: two hours, or fifteen minutes or seconds. | | Home, End on a segment | Goes to the segment's first or last value. | | Digits on a segment | Fill it, and move to the next once it can take no more. | | A letter on the half of the day | Picks the half whose name starts with it, such as A for AM. | | Backspace, Delete on a segment | Empty the segment. | | Left, Right on a segment | Move to the previous or the next segment, along the line of text. | In the list, the keys are 'TimePicker''s. */
19154
+ /** The list is a 'TimePicker', which you can also use on its own, for example in a settings pane. This element adds the field, the overlay, and the form association, the same arrangement Date Input has with 'DatePicker' and Color Input has with 'ColorPicker'. You can type a time or pick one. The list offers times at a step, and the field lets you enter any time, such as '09:07'. The value is always 'HH:mm' on a 24-hour clock, or 'HH:mm:ss' with 'seconds', because that is what the form submits, what 'min' and 'max' compare against, and what sorts correctly as a string. While idle, the field shows the time in the user's locale format. Once the caret is in the field, it shows the value itself. You can type '14:30', or a time as you write one, such as '2:30 PM', '2.30pm', or '14h30', and the field reads it as you leave it, with AM and PM in the locale's words. Typing sends 'input' on each keystroke and 'change' when you leave the field. The trigger and ArrowDown open the list, and so does a press into the field; Tab into the field opens nothing. The text field is a 'combobox' with 'aria-haspopup="dialog"', 'aria-expanded', and 'aria-controls', since Down opens the list from it. In the list, the arrow keys, typed digits and PageUp and PageDown move through the times, and Enter, Space or a click chooses one and closes the panel. With 'variant="wheels"' each wheel moves the time as you turn it, the panel stays open, and Enter or Escape closes it. With 'segmented', the field is a row of segments in place of the text: an hour, a minute, and AM or PM where the clock has them, each set with digits or the arrow keys. Alt+Down opens the list from a segment. A 'range' is two rows with a dash between them, the start and the end, and 'multiple' keeps the text. Text that is not a time gives the form an empty value, as a native time field does, and 'value' keeps the text so it can be corrected. **Keyboard.** The field is one tab stop, or each segment is with 'segmented', and the trigger is one more. | Key | What it does | |---|---| | Down | In the text field, opens the list on the chosen time. | | Alt with Down | Opens the list, from the text field or a segment. | | Enter | In the text field, takes the typed time and submits the form, as a native field does. In the list, chooses the highlighted time. | | Escape | Closes the list and puts focus back in the field. | | Up, Down on a segment | Steps the segment by one, round from its last value to its first. | | Page Up, Page Down on a segment | Steps by a page: two hours, or fifteen minutes or seconds. | | Home, End on a segment | Goes to the segment's first or last value. | | Digits on a segment | Fill it, and move to the next once it can take no more. | | A letter on the half of the day | Picks the half whose name starts with it, such as A for AM. | | Backspace, Delete on a segment | Empty the segment. | | Left, Right on a segment | Move to the previous or the next segment, along the line of text. | In the list, the keys are 'TimePicker''s. */
18928
19155
  "helix-headless-time-input": DefineCustomElement<
18929
19156
  HelixHeadlessTimeInput,
18930
19157
  HelixHeadlessTimeInputVueProps,
18931
19158
  HelixHeadlessTimeInputVueEvents
18932
19159
  >;
18933
- /** Shows the times at each 'step' as a 'Listbox', which provides the keyboard behavior, typeahead, scrolling into view, and announcements for a set of options. 'variant="wheels"' shows a column each for the hour, the minute, and the meridiem, and one for the second with 'seconds'. Left and Right move between the wheels, and Tab does too. 'hour-cycle' writes every time on a twelve or a twenty-four hour clock whatever the locale, and 'seconds' holds times to the second. The step keeps the list usable. At the default of 15 minutes a day is 96 rows, which people can scroll or type into. At 1 minute it is 1,440. Use the list for the times your product offers, and Time Input for any time, the same way Date Input separates typing a date from picking one on the calendar. The value is always 'HH:mm' on a 24-hour clock, or 'HH:mm:ss' with 'seconds'. A form submits that shape, 'min' and 'max' compare against it, and it sorts as a string. Each row's text follows the person's own conventions, from 'Intl'. The chosen row is marked in the served markup. The listbox gets the answer as '.value', and Lit SSR serializes no property binding, so without more the 96 served rows would carry no mark until the listbox upgrades and runs 'place'. Each option also gets 'selected', an attribute binding that does serialize, and 'place' then writes the same answer from the same value. This is the same 'selected' you write on 'Option' elsewhere in Helix, and Date Picker marks its choice in markup for the same reason. The list and the wheels both do this, because each wheel is also a listbox. **Keyboard.** The list is one tab stop, and each wheel is one. | Key | What it does | |---|---| | Down, Up | Moves to the next or the previous time, or in a wheel to the next or the previous hour, minute, second, or half of the day. | | Home, End | Moves to the first or the last time, or the first or the last in a wheel. | | Page Down, Page Up | Moves by as many times as the list shows at once. | | Digits | Moves to the next time that starts with what you typed, such as '9' for 9:00. | | Enter, Space | Chooses the highlighted time. Moving chooses too, except under 'manual' or with a 'mode'. With a 'mode', Space adds or removes the time. | | Right, Left | In the wheels, moves to the next or the previous wheel, mirrored right to left. | | Tab | Moves to the next wheel, then out of the picker. | **ARIA.** The list is a 'listbox' named by 'label', a slotted label, the host's 'aria-label' or its 'aria-labelledby'. A development build warns where all four are empty. The list is described by the hint, or by the message in 'feedback' in its place, and carries 'aria-multiselectable' with a 'mode' and 'aria-invalid' while 'feedback' says what is wrong. The wheels are a 'group' with that name, holding one 'listbox' per wheel, named "Hour", "Minute", "Second" and "AM/PM" in the page's language, and each described the same way. */
19160
+ /** Shows the times at each 'step' as a 'Listbox', which provides the keyboard behavior, typeahead, scrolling into view, and announcements for a set of options. 'variant="wheels"' shows a column each for the hour, the minute, and the meridiem, and one for the second with 'seconds'. Left and Right move between the wheels, and Tab does too. 'hour-cycle' writes every time on a twelve or a twenty-four hour clock whatever the locale, and 'seconds' holds times to the second. The step keeps the list usable. At the default of 15 minutes a day is 96 rows, which people can scroll or type into. At 1 minute it is 1,440. Use the list for the times your product offers, and Time Input for any time, the same way Date Input separates typing a date from picking one on the calendar. The value is always 'HH:mm' on a 24-hour clock, or 'HH:mm:ss' with 'seconds'. A form submits that shape, 'min' and 'max' compare against it, and it sorts as a string. Each row's text follows the person's own conventions, from 'Intl'. The chosen row is marked in the served markup. The listbox gets the answer as '.value', and Lit SSR serializes no property binding, so without more the 96 served rows would carry no mark until the listbox upgrades and runs 'place'. Each option also gets 'selected', an attribute binding that does serialize, and 'place' then writes the same answer from the same value. This is the same 'selected' you write on 'Option' elsewhere in Helix, and Date Picker marks its choice in markup for the same reason. The list and the wheels both do this, because each wheel is also a listbox. **Keyboard.** The list is one tab stop, and each wheel is one. | Key | What it does | |---|---| | Down, Up | Moves to the next or the previous time, or in a wheel to the next or the previous hour, minute, second, or half of the day. | | Home, End | Moves to the first or the last time, or the first or the last in a wheel. | | Page Down, Page Up | Moves by as many times as the list shows at once. | | Digits | Moves to the next time that starts with what you typed, such as '9' for 9:00. | | Enter, Space | Chooses the highlighted time. Moving chooses too, except under 'manual' or with a 'mode'. With a 'mode', Space adds or removes the time. | | Right, Left | In the wheels, moves to the next or the previous wheel, mirrored right to left. | | Tab | Moves to the next wheel, then out of the picker. | **ARIA.** The list is a 'listbox' named by 'label', a slotted label, the host's 'aria-label' or its 'aria-labelledby'. A development build warns where all four are empty. The list is described by the hint, or by the message in 'feedback' in its place, and carries 'aria-multiselectable' with a 'mode'. It carries 'aria-invalid' while 'feedback' says what is wrong, while it holds a time outside 'min' and 'max' or one the picker does not offer, and, for a 'required' picker with no time, once the reader has chosen one or a form has refused the picker. The wheels are a 'group' with that name, holding one 'listbox' per wheel, named "Hour", "Minute", "Second" and "AM/PM" in the page's language, and each described the same way. */
18934
19161
  "helix-headless-time-picker": DefineCustomElement<
18935
19162
  HelixHeadlessTimePicker,
18936
19163
  HelixHeadlessTimePickerVueProps,
@@ -18954,19 +19181,19 @@ export interface WcToolkitVueGlobalComponents {
18954
19181
  HelixHeadlessTimelineVueProps,
18955
19182
  HelixHeadlessTimelineVueEvents
18956
19183
  >;
18957
- /** Each message is an element because it has a timeout, a tone, a dismiss control, and a lifetime that pauses. **Each item runs its own timer.** A timer held by the region would restart with each new message, and the last of three messages would stay for nine seconds. It pauses while the pointer or focus is on the message, and while the page is hidden, so a message is not spent in a background tab. **Each message is an 'alertdialog' named by its words**, which is how a reader who moves into the stack hears which message they are on. Give it a 'heading' and a 'description', and the heading names it and the description describes it, for a message with a title and a line of detail. The region says each message once as it arrives, a 'danger' one assertively, so a message is never a live region of its own. A touch or a pen swipes a message toward the end of the line, and past halfway, or quickly, dismisses it through the same 'helix-dismiss' as its control. While it moves, the distance is on the 'item' part as '--toast-swipe-x'. **Escape dismisses the message holding focus**, through the same 'helix-dismiss', and focus moves to the next message. **Messages are inverted by default.** The item flips 'color-scheme', so a new message stands out from the page without using a color that carries meaning. */
19184
+ /** Each message is an element because it has a timeout, a tone, a dismiss control, and a lifetime that pauses. **Each item runs its own timer.** A timer held by the region would restart with each new message, and the last of three messages would stay for nine seconds. It pauses while the pointer or focus is on the message or anywhere in the region's stack, and while the page is hidden, so a message is not spent in a background tab. **Each message is an 'alertdialog' named by its words**, which is how a reader who moves into the stack hears which message they are on. Give it a 'heading' and a 'description', and the heading names it and the description describes it, for a message with a title and a line of detail. The region says each message once as it arrives, a 'danger' one assertively, so a message is never a live region of its own. A touch or a pen swipes a message toward the end of the line, or toward the edge the region's 'swipe-direction' names, and past halfway, or quickly, dismisses it through the same 'helix-dismiss' as its control. While it moves, the distance is on the 'item' part as '--toast-swipe-x' or '--toast-swipe-y'. **Escape dismisses the message holding focus**, through the same 'helix-dismiss', and focus moves to the next message. **Messages are inverted by default.** The item flips 'color-scheme', so a new message stands out from the page without using a color that carries meaning. */
18958
19185
  "helix-headless-toast-item": DefineCustomElement<
18959
19186
  HelixHeadlessToastItem,
18960
19187
  HelixHeadlessToastItemVueProps,
18961
19188
  HelixHeadlessToastItemVueEvents
18962
19189
  >;
18963
- /** The region and its items are one family because a live region must be in the document before a message is added to it. Assistive technology often does not announce a region that arrives already holding its message. 'Radio.Group' is part of its family for the same reason. **The region is a landmark named by 'label', and it says each message once as it arrives**: a 'danger' message assertively, and every other one politely. It says the word for the tone, the heading, the description and the text, and not the actions, through two live regions of its own, the 'live' parts, which it empties again a moment later. The stack itself is not a live region, so a message is never said twice, and changing the words of a message already showing says nothing. Each message is an 'alertdialog' named by its words, so a reader who moves into the stack hears which message they are on. **'hotkey' takes focus to the stack and back**, F8 unless you set it, and 'label' says which key: '{hotkey}' in it is filled in, so the default name is "Notifications (F8)". Pressed while focus is in the stack, it gives focus back to where it was. **The region never creates or removes items.** You render items and remove them. An item requests closing with a cancelable 'helix-dismiss' event. A dismissed item hides itself and stays in the DOM, so your framework's state and the DOM stay in sync. It hides on its own unless you set 'open', which makes the state yours. **'add()' shows a message from script**, for a page with no framework state to render them from: it appends a message of the region's own tier and removes it once it has been dismissed and has finished leaving. Messages you render yourself stay yours, and the region never removes them. A touch or a pen swipes a message away toward the end of the line. **The stack is in the top layer.** The 'region' part is a 'popover="manual"' shown while a message is showing, and shown again above a modal dialog that opened after it. Position the 'region' part, which is the box in the top layer. While a modal 'Dialog', 'Drawer' or 'Lightbox' is open, the browser makes everything outside it inert, the stack included, so a message stays visible and its actions cannot be pressed. Where the browser has 'ariaNotify', a message that arrives then is announced through it. For a message with an action, render a second region inside the dialog. When a message with focus inside it is dismissed, focus moves to the next message, then the one before it, then back to where it was before it entered the stack. **'max-visible' limits how many messages show at once**, as Zag's 'max' does. The messages after that many, in document order, wait: each is hidden, its timer has not started, and the region says it once it shows, when a message before it goes. A waiting message has ':state(waiting)'. **Keyboard.** | Key | What it does | |---|---| | F8, or your 'hotkey' | Moves focus to the first control in the stack, and back to where it was when pressed in the stack. | | Tab, Shift+Tab | Moves between the controls of the messages. | | Escape | Dismisses the message holding focus. Focus moves to the next message, then the one before it, then back to where it was. | */
19190
+ /** The region and its items are one family because a live region must be in the document before a message is added to it. Assistive technology often does not announce a region that arrives already holding its message. 'Radio.Group' is part of its family for the same reason. **The region is a landmark named by 'label', and it says each message once as it arrives**: a 'danger' message assertively, and every other one politely. It says the word for the tone, the heading, the description and the text, and not the actions, through two live regions of its own, the 'live' parts, which it empties again a moment later. The stack itself is not a live region, so a message is never said twice, and changing the words of a message already showing says nothing. Each message is an 'alertdialog' named by its words, so a reader who moves into the stack hears which message they are on. **'hotkey' takes focus to the stack and back**, F8 unless you set it, and 'label' says which key: '{hotkey}' in it is filled in, so the default name is "Notifications (F8)". Pressed while focus is in the stack, it gives focus back to where it was. **The region never creates or removes items.** You render items and remove them. An item requests closing with a cancelable 'helix-dismiss' event. A dismissed item hides itself and stays in the DOM, so your framework's state and the DOM stay in sync. It hides on its own unless you set 'open', which makes the state yours. **'add()' shows a message from script**, for a page with no framework state to render them from: it appends a message of the region's own tier and removes it once it has been dismissed and has finished leaving. Messages you render yourself stay yours, and the region never removes them. A touch or a pen swipes a message away toward the end of the line, or toward the edge 'swipe-direction' names. **Every message's timer waits while a pointer or focus is in the stack**, as React Aria's and Radix's regions do, so a reader moving from one message to the next does not lose the one behind them. **The stack is in the top layer.** The 'region' part is a 'popover="manual"' shown while a message is showing, and shown again above a modal dialog that opened after it. Position the 'region' part, which is the box in the top layer. While a modal 'Dialog', 'Drawer' or 'Lightbox' is open, the browser makes everything outside it inert, the stack included, so a message stays visible and its actions cannot be pressed. Where the browser has 'ariaNotify', a message that arrives then is announced through it. For a message with an action, render a second region inside the dialog. When a message with focus inside it is dismissed, focus moves to the next message, then the one before it, then back to where it was before it entered the stack. **'max-visible' limits how many messages show at once**, as Zag's 'max' does. The messages after that many, in document order, wait: each is hidden, its timer has not started, and the region says it once it shows, when a message before it goes. A waiting message has ':state(waiting)'. **Keyboard.** | Key | What it does | |---|---| | F8, or your 'hotkey' | Moves focus to the first control in the stack, and back to where it was when pressed in the stack. | | Tab, Shift+Tab | Moves between the controls of the messages. | | Escape | Dismisses the message holding focus. Focus moves to the next message, then the one before it, then back to where it was. | */
18964
19191
  "helix-headless-toast": DefineCustomElement<
18965
19192
  HelixHeadlessToast,
18966
19193
  HelixHeadlessToastVueProps,
18967
19194
  HelixHeadlessToastVueEvents
18968
19195
  >;
18969
- /** The indicator is one element that moves to the selected item. A single moving object is easier to follow than a fill that swaps, and it shows where the selection came from. Its size and position are measured from the selected item and written to the indicator as custom properties, because labels have different lengths. Measurement happens on the client, so the server renders the indicator hidden and it fades in once measured. 'selection-mode="multiple"' makes the group a toolbar of buttons that each say whether they are pressed with 'aria-pressed', as React Aria's ToggleButtonGroup and Radix's ToggleGroup do. A press presses or releases one item, the arrow keys move focus without pressing, and 'value' is the pressed values, comma separated, which 'values' also gives as a list. Use 'values' where an item's value holds a comma. The form receives one entry per pressed value, and a page the browser brings back presses the same items again. The indicator stays hidden, and each pressed item is marked with ':state(pressed)'. Inside a toolbar it is a named group of that toolbar's controls instead, so a reader meets one toolbar. 'orientation="vertical"' runs the items down a column, says so to the accessibility tree, and the up and down arrows move between them. **Keyboard.** The group is one tab stop: the chosen item, or the first that can be chosen, as in a radio group, and in a multiple group the item focus was last on. | Key | What it does | |---|---| | Right, Down | Moves to the next item, from the last back to the first. In a single group, chooses it. | | Left, Up | Moves to the item before, from the first round to the last. In a single group, chooses it. | | Home, End | Moves to the first or the last item. In a single group, chooses it. | | Space, Enter | Chooses the focused item, or presses or releases it in a multiple group. | Left and Right swap on a right-to-left page, and a disabled item is passed over. A single group is a 'radiogroup' of items with 'role="radio"' and 'aria-checked'. A multiple group is a 'toolbar' of buttons with 'aria-pressed', or a 'group' inside a toolbar. The group is named by 'label' and carries 'aria-orientation' under 'orientation'. */
19196
+ /** The indicator is one element that moves to the selected item. A single moving object is easier to follow than a fill that swaps, and it shows where the selection came from. Its size and position are measured from the selected item and written to the indicator as custom properties, because labels have different lengths. Measurement happens on the client, so the server renders the indicator hidden and it fades in once measured. 'selection-mode="multiple"' makes the group a toolbar of buttons that each say whether they are pressed with 'aria-pressed', as React Aria's ToggleButtonGroup and Radix's ToggleGroup do. A press presses or releases one item, the arrow keys move focus without pressing, and 'value' is the pressed values, comma separated, which 'values' also gives as a list. Use 'values' where an item's value holds a comma. The form receives one entry per pressed value, and a page the browser brings back presses the same items again. The indicator stays hidden, and each pressed item is marked with ':state(pressed)'. Inside a toolbar it is a named group of that toolbar's controls instead, so a reader meets one toolbar. 'orientation="vertical"' runs the items down a column, says so to the accessibility tree, and the up and down arrows move between them. **Keyboard.** The group is one tab stop: the chosen item, or the first that can be chosen, as in a radio group, and in a multiple group the item focus was last on. | Key | What it does | |---|---| | Right, Down | Moves to the next item, from the last back to the first. In a single group, chooses it. | | Left, Up | Moves to the item before, from the first round to the last. In a single group, chooses it. | | Home, End | Moves to the first or the last item. In a single group, chooses it. | | Space, Enter | Chooses the focused item, or presses or releases it in a multiple group. With 'allow-empty-selection', takes back the chosen item. | Left and Right swap on a right-to-left page, and a disabled item is passed over. A single group is a 'radiogroup' of items with 'role="radio"' and 'aria-checked'. A multiple group is a 'toolbar' of buttons with 'aria-pressed', or a 'group' inside a toolbar. The group is named by 'label' and carries 'aria-orientation' under 'orientation'. */
18970
19197
  "helix-headless-toggle-group": DefineCustomElement<
18971
19198
  HelixHeadlessToggleGroup,
18972
19199
  HelixHeadlessToggleGroupVueProps,
@@ -18990,13 +19217,13 @@ export interface WcToolkitVueGlobalComponents {
18990
19217
  HelixHeadlessTooltipVueProps,
18991
19218
  HelixHeadlessTooltipVueEvents
18992
19219
  >;
18993
- /** The root holds the order of the stops: which stop is current, what Next and Back do, and when the tour is finished. Each stop holds its target, and you write all the text. **The spotlight is a shadow.** The scrim is a box the size of the current target with a very large 'box-shadow' spread, and the shadow paints the darkness. A 'clip-path' on a full-screen scrim breaks as soon as an element between the scrim and the viewport is transformed. The root measures the target's position in the browser. Nothing is measured on the server, because a tour starts only on request. 'open', 'default-open', 'helix-before-open', 'helix-before-close' and 'toggle' work as they do on 'Dialog'. Setting 'open' starts the run, and 'skip()' and 'requestOpen(false)' end it early. The box the light falls on is on the 'spotlight' part as '--tour-spotlight-x', '--tour-spotlight-y', '--tour-spotlight-width' and '--tour-spotlight-height', for a sheet that draws its own light, such as a ring around the target. Each stop is told its place in the run, from 'progress-label', such as "2 of 5". It describes the stop's panel, so a screen reader says it at every stop, and 'progress' draws it in the panel as well. A dialog or a floating stop, which has nothing to light, is shown over the 'backdrop' part. At a 'wait' stop the run waits for that stop's target to be on the page, and moves on by itself. **Focus follows the run.** Opening moves focus to the first stop's panel, and moving on from a control in a stop moves it to the next one. Ending the tour puts focus back on the element that had it when the tour opened, unless you have moved it somewhere else on the page. A stop does not trap focus, so you can still 'Tab' out to the element it describes. **The target is scrolled into view** before its stop is shown, by the least distance that brings it on screen, so the stop that points at it is on screen too. **Keyboard.** Focus is on the current stop's panel, which is not in the 'Tab' order itself. | Key | What it does | |---|---| | Right | Goes to the next stop. On the last stop it does nothing, and Next finishes the tour. | | Left | Goes back to the previous stop. | | Escape | Skips the tour, and puts focus back where it was when the tour opened. | | Tab, Shift+Tab | Moves through the controls in the stop, and on out to the page. A stop does not trap focus. | | Enter, Space | On Back, Next, or Skip, presses it. | The arrow that points the way the line runs goes on, and the other goes back, so on a right-to-left page Left goes on and Right goes back. A text field in a stop keeps its own arrows. The tour is a region named by 'label' while it runs. A development build warns when a tour opens with no 'label'. */
19220
+ /** The root holds the order of the stops: which stop is current, what Next and Back do, and when the tour is finished. Each stop holds its target, and you write all the text. **The spotlight is a shadow.** The scrim is a box the size of the current target with a very large 'box-shadow' spread, and the shadow paints the darkness. A 'clip-path' on a full-screen scrim breaks as soon as an element between the scrim and the viewport is transformed. The root measures the target's position in the browser. Nothing is measured on the server, because a tour starts only on request. 'open', 'default-open', 'helix-before-open', 'helix-before-close' and 'toggle' work as they do on 'Dialog'. Setting 'open' starts the run, and 'skip()' and 'requestOpen(false)' end it early. The box the light falls on is on the 'spotlight' part as '--tour-spotlight-x', '--tour-spotlight-y', '--tour-spotlight-width' and '--tour-spotlight-height', for a sheet that draws its own light, such as a ring around the target. Each stop is told its place in the run, from 'progress-label', such as "2 of 5". It describes the stop's panel, so a screen reader says it at every stop, and 'progress' draws it in the panel as well. A dialog or a floating stop, which has nothing to light, is shown over the 'backdrop' part. At a 'wait' stop the run waits for that stop's target to be on the page, and moves on by itself. **Focus follows the run.** Opening moves focus to the first stop's panel, and moving on from a control in a stop moves it to the next one. Ending the tour puts focus back on the element that had it when the tour opened, unless you have moved it somewhere else on the page. A stop does not trap focus, so you can still 'Tab' out to the element it describes. **The target is scrolled into view** before its stop is shown, by the least distance that brings it on screen, so the stop that points at it is on screen too. **A stop's 'effect' runs as the tour reaches it**, before it is shown, and the stop waits for a promise it returns, with ':state(preparing)' on the tour meanwhile. A function it returns runs when the tour leaves the stop. **A press outside the current stop and its target does nothing by default**, so a reader can use the page the tour is describing. Set 'outside-press="close"' to end the tour on one, through 'helix-before-close' as Skip does, or 'outside-press="block"' to refuse it, so the stop and its target are all a pointer can reach while the tour runs, as Zag's 'preventInteraction' does. **Keyboard.** Focus is on the current stop's panel, which is not in the 'Tab' order itself. | Key | What it does | |---|---| | Right | Goes to the next stop. On the last stop it does nothing, and Next finishes the tour. | | Left | Goes back to the previous stop. | | Escape | Skips the tour, and puts focus back where it was when the tour opened. | | Tab, Shift+Tab | Moves through the controls in the stop, and on out to the page. A stop does not trap focus. | | Enter, Space | On Back, Next, or Skip, presses it. | The arrow that points the way the line runs goes on, and the other goes back, so on a right-to-left page Left goes on and Right goes back. A text field in a stop keeps its own arrows. The tour is a region named by 'label' while it runs. A development build warns when a tour opens with no 'label'. */
18994
19221
  "helix-headless-tour": DefineCustomElement<
18995
19222
  HelixHeadlessTour,
18996
19223
  HelixHeadlessTourVueProps,
18997
19224
  HelixHeadlessTourVueEvents
18998
19225
  >;
18999
- /** A stop names its target with 'for' and holds the content you put in it. The stop handles three things: - **Placement.** The panel is anchored to the target by the same floating positioning as the other Helix overlays. - **Stacking.** The panel is a popover, so it is in the top layer and shows above dialogs, scrolling regions, and other stacking contexts. - **Visibility.** The stop shows when it is 'current', which the root sets. Put any content in the stop, such as a 'Card', or a heading and a line of text. The 'heading' and 'description' slots are optional places for the title and the line under it, which then name and describe the panel. **A stop has a type.** Without one it is a bubble pointing at its target. 'type="dialog"' is a panel in the middle of the window, over a backdrop, for a welcome or a summary with nothing to point at. 'type="floating"' is a panel in a corner of the window, which the styled tier puts at the end of the line, for a note that points at nothing in particular. 'type="wait"' shows nothing: the tour waits for the element 'for' names to be on the page, such as a menu the reader has to open, and moves on by itself. **The buttons are slot fallback.** With nothing in the 'actions' slot, you get Back, Next, and Skip, already wired. Slot your own 'actions' and drive them with 'next()', 'back()', and 'skip()' on the root. **'for' is an id, as with 'Tooltip'**, so you can point at a target elsewhere on the page from markup. It resolves against the stop's root node, so a stop inside a shadow tree points at a target in that tree. The panel is a 'group', and a 'dialog' for a dialog stop, only while the stop is shown. It is named by the 'heading' slot, then by the first heading in the content, then by 'label', and otherwise by its place in the tour. It is described by the 'description' slot, or where that is empty by the words at the start of the content, and by its place, such as "2 of 5", so a screen reader says where the reader is at every stop. 'focus()' moves focus to the panel, which is what the tour does when it opens or moves on. */
19226
+ /** A stop names its target with 'for' and holds the content you put in it. The stop handles three things: - **Placement.** The panel is anchored to the target by the same floating positioning as the other Helix overlays. - **Stacking.** The panel is a popover, so it is in the top layer and shows above dialogs, scrolling regions, and other stacking contexts. - **Visibility.** The stop shows when it is 'current', which the root sets. Put any content in the stop, such as a 'Card', or a heading and a line of text. The 'heading' and 'description' slots are optional places for the title and the line under it, which then name and describe the panel. **A stop has a type.** Without one it is a bubble pointing at its target. 'type="dialog"' is a panel in the middle of the window, over a backdrop, for a welcome or a summary with nothing to point at. 'type="floating"' is a panel in a corner of the window, which the styled tier puts at the end of the line, for a note that points at nothing in particular. 'type="wait"' shows nothing: the tour waits for the element 'for' names to be on the page, such as a menu the reader has to open, and moves on by itself. **The buttons are slot fallback.** With nothing in the 'actions' slot, you get Back, Next, and Skip, already wired. Slot your own 'actions' and drive them with 'next()', 'back()', and 'skip()' on the root. **Set 'effect' to prepare the page for a stop**, such as opening the menu it points into or loading what it describes. It is a function, set from script, that the tour runs as it reaches the stop. Return a promise and the stop waits for it, and the tour has ':state(preparing)' meanwhile; return a function, or resolve to one, and the tour runs it when it leaves the stop. Zag's tour step has the same 'effect'. **'for' is an id, as with 'Tooltip'**, so you can point at a target elsewhere on the page from markup. It resolves against the stop's root node, so a stop inside a shadow tree points at a target in that tree. The panel is a 'group', and a 'dialog' for a dialog stop, only while the stop is shown. It is named by the 'heading' slot, then by the first heading in the content, then by 'label', and otherwise by its place in the tour. It is described by the 'description' slot, or where that is empty by the words at the start of the content, and by its place, such as "2 of 5", so a screen reader says where the reader is at every stop. 'focus()' moves focus to the panel, which is what the tour does when it opens or moves on. */
19000
19227
  "helix-headless-tour-stop": DefineCustomElement<
19001
19228
  HelixHeadlessTourStop,
19002
19229
  HelixHeadlessTourStopVueProps,