@fusion.dev/helix-headless 0.156.0 → 0.157.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.
package/types/vue.d.ts CHANGED
@@ -6302,6 +6302,16 @@ export type HelixHeadlessDrilldownItemHelixSelectElementEvent =
6302
6302
  export type HelixHeadlessDrilldownItemVueProps = {
6303
6303
  /** Whether the row can be reached at all. */
6304
6304
  disabled?: (HelixHeadlessDrilldownItem["disabled"]) | undefined;
6305
+ /** Whether the link downloads the file when the row is chosen. Only
6306
+ meaningful beside an `href`, and only for a file served from this origin. */
6307
+ download?: (HelixHeadlessDrilldownItem["download"]) | undefined;
6308
+ /** The URL the row links to. Setting it renders the row as a link, unless the
6309
+ row opens a page or is disabled. */
6310
+ href?: (HelixHeadlessDrilldownItem["href"]) | undefined;
6311
+ /** The link's `rel`. Set it whenever you set `target="_blank"`. */
6312
+ rel?: (HelixHeadlessDrilldownItem["rel"]) | undefined;
6313
+ /** Where the link opens, for rows that should open outside the current page. */
6314
+ target?: (HelixHeadlessDrilldownItem["target"]) | undefined;
6305
6315
  /** Identifies the row to your event listeners. */
6306
6316
  value?: (HelixHeadlessDrilldownItem["value"]) | undefined;
6307
6317
  /** Whether this row holds the region's tab stop. Set by the drill-down.
@@ -6328,6 +6338,9 @@ export type HelixHeadlessDrilldownElementEvent<E = Event> = TypedEvent<
6328
6338
  HelixHeadlessDrilldown,
6329
6339
  E
6330
6340
  >;
6341
+ /** `helix-navigate` event type */
6342
+ export type HelixHeadlessDrilldownHelixNavigateElementEvent =
6343
+ HelixHeadlessDrilldownElementEvent<HelixNavigateEvent>;
6331
6344
  /** `helix-select` event type */
6332
6345
  export type HelixHeadlessDrilldownHelixSelectElementEvent =
6333
6346
  HelixHeadlessDrilldownElementEvent<HelixSelectEvent>;
@@ -6343,6 +6356,14 @@ and wins over this. */
6343
6356
  "back-label"?: (HelixHeadlessDrilldown["backLabel"]) | undefined;
6344
6357
  /** The text of the back button. */
6345
6358
  backLabel?: (HelixHeadlessDrilldown["backLabel"]) | undefined;
6359
+ /** Whether the drilldown is a site's navigation: a `navigation` landmark
6360
+ named by `label`, whose pages are lists of links. Without it, each page is
6361
+ a `menu`. */
6362
+ navigation?: (HelixHeadlessDrilldown["navigation"]) | undefined;
6363
+ /** The page showing, as the `value` of the row that opens it. Empty is the
6364
+ top page. Setting it shows that page, and a value no row with a page has
6365
+ shows the top page. */
6366
+ page?: (HelixHeadlessDrilldown["page"]) | undefined;
6346
6367
  /** The text shown and announced when there are no rows and none are loading. */
6347
6368
  "empty-text"?: (HelixHeadlessDrilldown["emptyText"]) | undefined;
6348
6369
  /** The text shown and announced when there are no rows and none are loading. */
@@ -6360,6 +6381,8 @@ say that without the component knowing what a row looks like. */
6360
6381
  };
6361
6382
 
6362
6383
  export type HelixHeadlessDrilldownVueEvents = {
6384
+ /** Fired before a reader moves into a page or back out of one. `detail.value` is the `value` of the row whose page is about to show, empty for the top page. Cancelable: cancel it to stay on the page showing. */
6385
+ "helix-navigate": HelixHeadlessDrilldownHelixNavigateElementEvent;
6363
6386
  /** Fired when a row with no page is chosen. Cancelable: canceling it stops the change and leaves the decision to you. */
6364
6387
  "helix-select": HelixHeadlessDrilldownHelixSelectElementEvent;
6365
6388
  };
@@ -10194,8 +10217,24 @@ narrow exception the server specs describe covers a mirror that can only
10194
10217
  become true long after hydration, and a viewport measured before the first
10195
10218
  paint is the opposite case. See `MixinControllerOpen` on `open`. */
10196
10219
  bandBelow?: (HelixHeadlessMegamenu["bandBelow"]) | undefined;
10220
+ /** How long a pointer leaving the trigger and the panel waits before the panel
10221
+ closes, in milliseconds. The pointer needs the time to cross from the
10222
+ trigger to the panel. */
10223
+ "close-delay"?: (HelixHeadlessMegamenu["closeDelay"] | `${number}`) | undefined;
10224
+ /** How long a pointer leaving the trigger and the panel waits before the panel
10225
+ closes, in milliseconds. The pointer needs the time to cross from the
10226
+ trigger to the panel. */
10227
+ closeDelay?: (HelixHeadlessMegamenu["closeDelay"]) | undefined;
10197
10228
  /** The section's name, used for the default trigger and the panel. */
10198
10229
  label?: (HelixHeadlessMegamenu["label"]) | undefined;
10230
+ /** How long a pointer rests on the trigger before the panel opens, in
10231
+ milliseconds, under `open-on="hover"`. A pointer crossing the bar on its
10232
+ way somewhere else opens nothing. */
10233
+ "open-delay"?: (HelixHeadlessMegamenu["openDelay"] | `${number}`) | undefined;
10234
+ /** How long a pointer rests on the trigger before the panel opens, in
10235
+ milliseconds, under `open-on="hover"`. A pointer crossing the bar on its
10236
+ way somewhere else opens nothing. */
10237
+ openDelay?: (HelixHeadlessMegamenu["openDelay"]) | undefined;
10199
10238
  /** Whether hovering over the trigger opens the panel (`hover`), or only a press
10200
10239
  does (`click`).
10201
10240
 
@@ -10212,6 +10251,10 @@ the trigger, and it is the default because that is what a navigation bar
10212
10251
  does. `click` is for a trigger that does something else as well, or a panel
10213
10252
  heavy enough that opening it on the way past is rude. */
10214
10253
  openOn?: (HelixHeadlessMegamenu["openOn"]) | undefined;
10254
+ /** The side of the trigger a card panel opens on, when there is room. It
10255
+ moves if that side does not fit. A band ignores it, since a band spans the
10256
+ page under its bar. */
10257
+ placement?: (HelixHeadlessMegamenu["placement"]) | undefined;
10215
10258
  /** Whether the panel is a card under the trigger or a band across the page.
10216
10259
 
10217
10260
  The resting one is the card, hanging off the trigger and as wide as it
@@ -10379,12 +10422,29 @@ Empty by default, which names the surface by its trigger, so a menu opened
10379
10422
  from "Actions" is announced as "Actions". An `aria-label` or
10380
10423
  `aria-labelledby` on the host names it too, and wins over both. */
10381
10424
  label?: (HelixHeadlessMenu["label"]) | undefined;
10425
+ /** The description a trigger gives under `open-on="long-press"`, saying how
10426
+ to open the menu. Translate it with the rest of your interface. */
10427
+ "long-press-label"?: (HelixHeadlessMenu["longPressLabel"]) | undefined;
10428
+ /** The description a trigger gives under `open-on="long-press"`, saying how
10429
+ to open the menu. Translate it with the rest of your interface. */
10430
+ longPressLabel?: (HelixHeadlessMenu["longPressLabel"]) | undefined;
10382
10431
  /** Space between the trigger and the surface, in pixels. */
10383
10432
  offset?: (HelixHeadlessMenu["offset"]) | undefined;
10433
+ /** What opens the menu from its trigger. `long-press` leaves a press to the
10434
+ trigger's own action and opens the menu on a press held for half a second,
10435
+ or on Alt+Down or Alt+Up. */
10436
+ "open-on"?: (HelixHeadlessMenu["openOn"]) | undefined;
10437
+ /** What opens the menu from its trigger. `long-press` leaves a press to the
10438
+ trigger's own action and opens the menu on a press held for half a second,
10439
+ or on Alt+Down or Alt+Up. */
10440
+ openOn?: (HelixHeadlessMenu["openOn"]) | undefined;
10384
10441
  /** The side the menu opens on, when there is room.
10385
10442
 
10386
10443
  It moves if that side does not fit. */
10387
10444
  placement?: (HelixHeadlessMenu["placement"]) | undefined;
10445
+ /** How a submenu opens. `drill` shows it in place of the page showing, with
10446
+ a way back. `flyout` opens it in a panel of its own beside its row. */
10447
+ submenus?: (HelixHeadlessMenu["submenus"]) | undefined;
10388
10448
  /** The text shown and announced when there are no rows and none are loading. */
10389
10449
  "empty-text"?: (HelixHeadlessMenu["emptyText"]) | undefined;
10390
10450
  /** The text shown and announced when there are no rows and none are loading. */
@@ -10792,6 +10852,12 @@ export type HelixHeadlessNotificationsHelixReadElementEvent =
10792
10852
  HelixHeadlessNotificationsElementEvent<HelixReadEvent>;
10793
10853
 
10794
10854
  export type HelixHeadlessNotificationsVueProps = {
10855
+ /** What the feed says when unread notifications arrive, with `{count}` the
10856
+ number of them. Empty it to say nothing. */
10857
+ "arrived-label"?: (HelixHeadlessNotifications["arrivedLabel"]) | undefined;
10858
+ /** What the feed says when unread notifications arrive, with `{count}` the
10859
+ number of them. Empty it to say nothing. */
10860
+ arrivedLabel?: (HelixHeadlessNotifications["arrivedLabel"]) | undefined;
10795
10861
  /** The region's name where `label` is empty. */
10796
10862
  "fallback-label"?: (HelixHeadlessNotifications["fallbackLabel"]) | undefined;
10797
10863
  /** The region's name where `label` is empty. */
@@ -16077,6 +16143,10 @@ A word property: register it for a locale under the host's key. A family
16077
16143
  that names the control otherwise, such as Tag's `Remove {label}`,
16078
16144
  declares its own English with `@words` above the override. */
16079
16145
  dismissLabel?: (HelixHeadlessToastItem["dismissLabel"]) | undefined;
16146
+ /** Whether the region holds the message back, because more messages are
16147
+ showing than its `max-visible`. The region sets it. A waiting message is
16148
+ hidden, its timer has not started, and it is said once it shows. */
16149
+ waiting?: (HelixHeadlessToastItem["waiting"]) | undefined;
16080
16150
  };
16081
16151
 
16082
16152
  export type HelixHeadlessToastItemVueEvents = {
@@ -16102,6 +16172,14 @@ Empty turns it off. */
16102
16172
  /** Accessible name for the region, with `{hotkey}` filled in. Translate it with
16103
16173
  the rest of your interface. */
16104
16174
  label?: (HelixHeadlessToast["label"]) | undefined;
16175
+ /** How many messages show at once. The messages after that many wait, hidden
16176
+ and with their timers stopped, until a message before them goes. Unset,
16177
+ every message shows. */
16178
+ "max-visible"?: (HelixHeadlessToast["maxVisible"] | `${number}`) | undefined;
16179
+ /** How many messages show at once. The messages after that many wait, hidden
16180
+ and with their timers stopped, until a message before them goes. Unset,
16181
+ every message shows. */
16182
+ maxVisible?: (HelixHeadlessToast["maxVisible"]) | undefined;
16105
16183
  /** Which corner or edge the stack sits at.
16106
16184
 
16107
16185
  Named here rather than on each message, because where a page puts its
@@ -18279,13 +18357,13 @@ export interface WcToolkitVueGlobalComponents {
18279
18357
  HelixHeadlessDrawerVueProps,
18280
18358
  HelixHeadlessDrawerVueEvents
18281
18359
  >;
18282
- /** A row that opens a page contains that page: the page's rows are this row's own children, assigned to the 'page' slot. There are no ids to wire, and moving a row moves its page with it. What the item renders depends on the stack: - On the page that is showing, it renders its row. - When its own page is showing, it renders only that page's rows. Its row belongs to the page above. - When a page further down its own is showing, it renders its page's slot alone, so the rows below reach the page. - Otherwise it renders nothing. The rows stay in the light DOM untouched, so there is no state to keep. Choosing a row dispatches an event, and the stack decides whether that drills in or runs a command. A row that opens a page shows a caret after its text and sets 'aria-haspopup', the same way 'Menu' marks a row with a submenu. The server render leaves both out, because the server cannot see the children. The row is named by its label alone. Words in 'description', a line under the label, and in 'end' describe it instead, through 'aria-describedby', as 'Menu.Item' does: a reader hears "Theme", then "Dark". */
18360
+ /** A row that opens a page contains that page: the page's rows are this row's own children, assigned to the 'page' slot. There are no ids to wire, and moving a row moves its page with it. What the item renders depends on the stack: - On the page that is showing, it renders its row. - When its own page is showing, it renders only that page's rows. Its row belongs to the page above. - When a page further down its own is showing, it renders its page's slot alone, so the rows below reach the page. - Otherwise it renders nothing. The rows stay in the light DOM untouched, so there is no state to keep. Choosing a row dispatches an event, and the stack decides whether that drills in or runs a command. A row that opens a page shows a caret after its text and sets 'aria-haspopup', the same way 'Menu' marks a row with a submenu. The server render leaves both out, because the server cannot see the children. **A row with an 'href' is a link.** The row itself renders as an '<a>' carrying 'menuitem', as 'Menu.Item' does, so a middle click, a modified click and the status bar keep working. Enter follows it, and Space does too. Choosing it fires 'helix-select' first: cancel the event and the link is not followed, so a router can take the navigation. A row that opens a page, or a disabled row, renders no link. A development build warns when a row has no words to be named by, such as a row holding only an icon with no label. The row is named by its label alone. Words in 'description', a line under the label, and in 'end' describe it instead, through 'aria-describedby', as 'Menu.Item' does: a reader hears "Theme", then "Dark". */
18283
18361
  "helix-headless-drilldown-item": DefineCustomElement<
18284
18362
  HelixHeadlessDrilldownItem,
18285
18363
  HelixHeadlessDrilldownItemVueProps,
18286
18364
  HelixHeadlessDrilldownItemVueEvents
18287
18365
  >;
18288
- /** One panel whose content changes as you move between pages. Use it where there is no room for a second column, such as on a phone, or on a touch screen with no hover to open one. It is a region that stays where you put it, such as inside a drawer, a sidebar, or a settings panel. A 'Menu' opens from a trigger and closes when you are done. 'Menu' can drill into pages too, through the same controller. Rows are places to go and commands to run. Nothing here is form-associated and nothing is submitted. To choose a value, use a 'Listbox'. A row that opens a page contains that page, so the stack holds one reference and reads the rest from the DOM. The behavior lives in 'DrilldownController', which 'Menu' shares. After each move the host carries 'data-direction', 'forward' into a page or 'back' out of one, and records ':state(forward)' or ':state(back)', so a stylesheet can slide the new page in from the side the reader is going. Both are written again on every move, so an animation keyed on them runs for each page, two moves the same way included. The styled tier slides the page and swaps it at once under 'prefers-reduced-motion'. Keys, on a row: Up and Down Arrow move between the rows, Home and End go to the first and the last, and a typed letter moves to the next row whose name starts with it. Enter, Space, or Right Arrow opens a row's page, and Left Arrow or Escape goes back, the two arrows swapping on a right-to-left page. The rows of the page showing are a 'menu', named by 'label' on the top page and by the page's title below it. The back button and the title sit above the menu. Disabled rows stay reachable with the arrow keys, and typing a letter moves to the next row whose name starts with it. */
18366
+ /** One panel whose content changes as you move between pages. Use it where there is no room for a second column, such as on a phone, or on a touch screen with no hover to open one. It is a region that stays where you put it, such as inside a drawer, a sidebar, or a settings panel. A 'Menu' opens from a trigger and closes when you are done. 'Menu' can drill into pages too, through the same controller. Rows are places to go and commands to run. Nothing here is form-associated and nothing is submitted. To choose a value, use a 'Listbox'. A row that opens a page contains that page, so the stack holds one reference and reads the rest from the DOM. The behavior lives in 'DrilldownController', which 'Menu' shares. **'page' is the page showing**, as the 'value' of the row that opens it, and empty on the top page. Set it to show a page, such as one a link to a settings screen names. A reader's move updates it, and 'helix-navigate' comes first, so you can refuse the move or take it yourself. After each move the host carries 'data-direction', 'forward' into a page or 'back' out of one, and records ':state(forward)' or ':state(back)', so a stylesheet can slide the new page in from the side the reader is going. Both are written again on every move, so an animation keyed on them runs for each page, two moves the same way included. The styled tier slides the page and swaps it at once under 'prefers-reduced-motion'. **Keyboard.** The drilldown is one tab stop, on the row last focused. | Key | What it does | |---|---| | Down Arrow, Up Arrow | Moves to the next or the previous row. | | Home, End | Moves to the first or the last row. | | A letter | Moves to the next row whose name starts with it. | | Enter, Space | Chooses the row: opens its page, follows its link, or sends 'helix-select'. | | Right Arrow | Opens the row's page. Left Arrow on a right-to-left page. | | Left Arrow, Escape | Goes back one page, with focus on the row that opened it. Right Arrow on a right-to-left page. | The rows of the page showing are a 'menu', named by 'label' on the top page and by the page's title below it. **'navigation' makes it a site's navigation.** The host is a 'navigation' landmark named by 'label', each page is a list, and each row is a list item holding a link or a button, as the APG's disclosure navigation is built, so a reader meets places to go in place of a menu of commands. The keys stay the same. The back button and the title sit above the menu. Disabled rows stay reachable with the arrow keys, and typing a letter moves to the next row whose name starts with it. */
18289
18367
  "helix-headless-drilldown": DefineCustomElement<
18290
18368
  HelixHeadlessDrilldown,
18291
18369
  HelixHeadlessDrilldownVueProps,
@@ -18495,19 +18573,19 @@ export interface WcToolkitVueGlobalComponents {
18495
18573
  HelixHeadlessMapTerrainVueProps,
18496
18574
  HelixHeadlessMapTerrainVueEvents
18497
18575
  >;
18498
- /** A disclosure: a button that shows and hides a region of your own links. It does not use 'role="menu"' or 'menuitem', which are for application commands. Those roles take over the arrow keys, announce "menu" to someone looking for navigation, and put every link inside a role that is not a link. As a disclosure, middle clicks, modified clicks, and the status bar keep working. Use 'Menu' for a row of commands. It renders no links. A router renders its own anchors and cannot render them inside this shadow root, so the panel is a slot for the lists and headings you write. It opens on hover by default, and a press always opens it too. 'open-on' sets which. Hover is the default because in a navigation bar people expect to move along the row and see each section. When one panel opens in place of another, each says which way the reader moved, as Radix's 'data-motion' does. Moving toward the end of the bar, the one opening is ':state(from-end)' and the one closing is ':state(to-start)'; moving back, they are ':state(from-start)' and ':state(to-end)'. A stylesheet slides them on that. Start and end follow the reading direction, so on a right-to-left page the end is on the left. A panel that opens or closes on its own carries none of the four. A press on another megamenu's trigger hands over the same way as hovering it. While a panel is open its surface carries its own size, as '--megamenu-surface-inline-size' and '--megamenu-surface-block-size', and a panel that took over from another also carries that one's size, as '--megamenu-from-inline-size' and '--megamenu-from-block-size'. Radix's navigation menu publishes the same pair from its shared viewport, so a stylesheet can grow or shrink one panel into the next. The panel's default slot is the 'columns' part and draws no box, so a sheet can give the columns one of their own. While a panel is open, an 'indicator' slot is rendered beside its trigger, as Radix's indicator marks the open one: slot a mark of your own, such as a bar or an arrow pointing at the panel, and it shows only while the panel is open. The styled tier rests it on the trigger's bottom edge. Left and Right Arrow move between the triggers of the megamenus beside this one, and Home and End go to the first and the last, as Radix's navigation menu does. In a 'Navigation', which holds them in a slot, the arrows are the navigation's, and move between its destinations under its 'arrows'. Down Arrow on the trigger of an open panel moves focus to the panel's first link, Escape closes the panel and returns focus to its trigger, and Tab moves through the panel's links and closes it on the way out. The trigger says 'aria-expanded', and the panel is a group named by 'label'. */
18576
+ /** A disclosure: a button that shows and hides a region of your own links. It does not use 'role="menu"' or 'menuitem', which are for application commands. Those roles take over the arrow keys, announce "menu" to someone looking for navigation, and put every link inside a role that is not a link. As a disclosure, middle clicks, modified clicks, and the status bar keep working. Use 'Menu' for a row of commands. It renders no links. A router renders its own anchors and cannot render them inside this shadow root, so the panel is a slot for the lists and headings you write. It opens on hover by default, and a press always opens it too. 'open-on' sets which. Hover is the default because in a navigation bar people expect to move along the row and see each section. A pointer resting on the trigger opens the panel after 'open-delay', and leaving closes it after 'close-delay'. Moving from one open panel's trigger to another's opens the next at once, as Radix's 'skipDelayDuration' does. When one panel opens in place of another, each says which way the reader moved, as Radix's 'data-motion' does. Moving toward the end of the bar, the one opening is ':state(from-end)' and the one closing is ':state(to-start)'; moving back, they are ':state(from-start)' and ':state(to-end)'. A stylesheet slides them on that. Start and end follow the reading direction, so on a right-to-left page the end is on the left. A panel that opens or closes on its own carries none of the four. A press on another megamenu's trigger hands over the same way as hovering it. While a panel is open its surface carries its own size, as '--megamenu-surface-inline-size' and '--megamenu-surface-block-size', and a panel that took over from another also carries that one's size, as '--megamenu-from-inline-size' and '--megamenu-from-block-size'. Radix's navigation menu publishes the same pair from its shared viewport, so a stylesheet can grow or shrink one panel into the next. While a link in the panel carries 'aria-current="page"', the host has ':state(current)', so the trigger of the section holding the page you are on can say so, as Radix's navigation menu marks its active link. The panel's default slot is the 'columns' part and draws no box, so a sheet can give the columns one of their own. While a panel is open, an 'indicator' slot is rendered beside its trigger, as Radix's indicator marks the open one: slot a mark of your own, such as a bar or an arrow pointing at the panel, and it shows only while the panel is open. The styled tier rests it on the trigger's bottom edge. Left and Right Arrow move between the triggers of the megamenus beside this one, and Home and End go to the first and the last, as Radix's navigation menu does. In a 'Navigation', which holds them in a slot, the arrows are the navigation's, and move between its destinations under its 'arrows'. Down Arrow on the trigger of an open panel moves focus to the panel's first link, Escape closes the panel and returns focus to its trigger, and Tab moves through the panel's links and closes it on the way out. The trigger says 'aria-expanded', and the panel is a group named by 'label'. A Helix trigger, such as 'helix-button', is told whether the panel is open inside its own shadow root. On a plain element, such as a '<button>', the megamenu writes 'aria-expanded', from a frame after its own first render, so a server's markup is never changed while a framework hydrates it. It never writes it where you wrote 'aria-expanded' yourself. */
18499
18577
  "helix-headless-megamenu": DefineCustomElement<
18500
18578
  HelixHeadlessMegamenu,
18501
18579
  HelixHeadlessMegamenuVueProps,
18502
18580
  HelixHeadlessMegamenuVueEvents
18503
18581
  >;
18504
- /** One element covers three kinds of row, and what you give it decides which: - Content in the 'submenu' slot makes the row open a submenu page. - 'checked' makes the row a choice. - With neither, the row is a command. The role follows the kind. A row with 'checked' is 'menuitemcheckbox' with 'aria-checked', and 'exclusive' makes it 'menuitemradio', for a set where only one can be on. A row that opens a page keeps 'menuitem' and sets 'aria-haspopup'. Choosing a choice row checks or unchecks it before 'helix-select' is sent, so a listener reads the new 'checked'. An 'exclusive' row turns on and turns off the 'exclusive' rows next to it. Cancel 'helix-before-toggle' to keep a row as it is and set 'checked' yourself. The menu sets whether the row's page is showing as a property, never as an attribute. An attribute written onto your element after it upgrades causes a hydration mismatch. 'shortcut' shows a row's keyboard shortcut after its label, drawn by 'Kbd' in the platform's glyphs, and gives the row 'aria-keyshortcuts'. It binds nothing: the shortcut is the page's to bind. Other trailing words, such as a count, go in the 'end' slot. The row is named by its label alone. Words in 'description', a line under the label, and in 'end' describe it instead, through 'aria-describedby', as React Aria's menu item does with its description: a reader hears "Copy", then "Copies the selection". The check mark and the caret are the fallbacks of the 'check' and 'chevron' slots, so a mark of your own replaces either by being slotted. Neither is read as part of the row's name. */
18582
+ /** One element covers three kinds of row, and what you give it decides which: - Content in the 'submenu' slot makes the row open a submenu page. - 'checked' makes the row a choice. - With neither, the row is a command. The role follows the kind. A row with 'checked' is 'menuitemcheckbox' with 'aria-checked', and 'exclusive' makes it 'menuitemradio', for a set where only one can be on. A row that opens a page keeps 'menuitem' and sets 'aria-haspopup'. Choosing a choice row checks or unchecks it before 'helix-select' is sent, so a listener reads the new 'checked'. An 'exclusive' row turns on and turns off the 'exclusive' rows next to it. Cancel 'helix-before-toggle' to keep a row as it is and set 'checked' yourself. The menu sets whether the row's page is showing as a property, never as an attribute. An attribute written onto your element after it upgrades causes a hydration mismatch. 'shortcut' shows a row's keyboard shortcut after its label, drawn by 'Kbd' in the platform's glyphs, and gives the row 'aria-keyshortcuts'. It binds nothing: the shortcut is the page's to bind. Other trailing words, such as a count, go in the 'end' slot. The row is named by its label alone. Words in 'description', a line under the label, and in 'end' describe it instead, through 'aria-describedby', as React Aria's menu item does with its description: a reader hears "Copy", then "Copies the selection". A development build warns when a row has no words to be named by, such as a row holding only an icon with no label. The check mark and the caret are the fallbacks of the 'check' and 'chevron' slots, so a mark of your own replaces either by being slotted. Neither is read as part of the row's name. */
18505
18583
  "helix-headless-menu-item": DefineCustomElement<
18506
18584
  HelixHeadlessMenuItem,
18507
18585
  HelixHeadlessMenuItemVueProps,
18508
18586
  HelixHeadlessMenuItemVueEvents
18509
18587
  >;
18510
- /** The trigger is slotted and stays your own element, as with the tooltip. The menu renders its surface in the top layer with the popover API, so an ancestor with 'overflow: hidden' does not clip it and it needs no 'z-index'. Slot a 'helix-button' or 'helix-icon-button' as the trigger, and the menu tells it that it opens a menu and whether the menu is open. A plain '<button>' can only be told by writing attributes onto your markup, which the menu does not do, so give it 'aria-haspopup="menu"' and set its 'aria-expanded' from the 'toggle' event. Submenus drill down. A submenu replaces the panel's content, and a back row returns to the previous page. One panel avoids the diagonal pointer path that side-by-side panels need, stays inside a narrow window, and works on touch screens, which have no hover. The root holds which page is open, because only one page shows at a time. It sets this on items as a property, never as an attribute. An attribute written onto your element after it upgrades causes a hydration mismatch. Group rows under a heading with 'Menu.Section', which is a 'group' named by its heading. Between runs of rows, a '<helix-divider>' is a separator a screen reader announces. Keys: Enter, Space or Down Arrow on the trigger opens the menu on its first row, and Up Arrow on its last. In the menu, Up and Down Arrow move between rows, Home and End go to the first and the last, a typed letter moves to the next row whose name starts with it, Enter and Space choose, Right Arrow opens a row's submenu and Left Arrow goes back, the two swapping on a right-to-left page, and Escape closes the menu and returns focus to the trigger. Tab closes it and moves on. While it is open, the surface carries the trigger's width as '--floating-anchor-inline-size' and the room left below it as '--floating-available-block-size', as Radix's dropdown menu publishes its trigger's width, for a menu as wide as its trigger: 'helix-menu::part(surface) { min-inline-size: var(--floating-anchor-inline-size) }'. With 'context', the trigger is an area and the menu is its context menu: a right-click, a long press, Shift+F10 or the menu key over the area opens it at the pointer, or at the area's corner from the keyboard, as Radix's context menu does. A press on the area does not open it, and closing it returns focus to where it was. */
18588
+ /** The trigger is slotted and stays your own element, as with the tooltip. The menu renders its surface in the top layer with the popover API, so an ancestor with 'overflow: hidden' does not clip it and it needs no 'z-index'. Slot a 'helix-button' or 'helix-icon-button' as the trigger, and the menu tells it that it opens a menu and whether the menu is open, inside its own shadow root. On a plain element, such as a '<button>', the menu writes 'aria-haspopup="menu"' and 'aria-expanded', from a frame after its own first render, so a server's markup is never changed while a framework hydrates it. It never writes 'aria-expanded' where you wrote it yourself. Submenus drill down by default. A submenu replaces the panel's content, and a back row returns to the previous page. One panel stays inside a narrow window, and works on touch screens, which have no hover. **'submenus="flyout"' opens each submenu in a panel of its own beside its row**, as React Aria's 'SubmenuTrigger' and Radix's 'Sub' do. Resting the pointer on the row opens it, and a pointer crossing toward the open panel over the rows between keeps it open, as Radix's grace area does. Right Arrow opens a row's submenu on its first row, and Left Arrow or Escape closes it and returns focus to the row, the two arrows swapping on a right-to-left page. The row says 'aria-expanded', and the panel is a 'menu' named by the row. The root holds which page is open, because only one page shows at a time. It sets this on items as a property, never as an attribute. An attribute written onto your element after it upgrades causes a hydration mismatch. Group rows under a heading with 'Menu.Section', which is a 'group' named by its heading. Between runs of rows, a '<helix-divider>' is a separator a screen reader announces. Keys: Enter, Space or Down Arrow on the trigger opens the menu on its first row, and Up Arrow on its last. In the menu, Up and Down Arrow move between rows, Home and End go to the first and the last, a typed letter moves to the next row whose name starts with it, Enter and Space choose, Right Arrow opens a row's submenu and Left Arrow goes back, the two swapping on a right-to-left page, and Escape closes the menu and returns focus to the trigger. Tab closes it and moves on. While it is open, the surface carries the trigger's width as '--floating-anchor-inline-size' and the room left below it as '--floating-available-block-size', as Radix's dropdown menu publishes its trigger's width, for a menu as wide as its trigger: 'helix-menu::part(surface) { min-inline-size: var(--floating-anchor-inline-size) }'. With 'context', the trigger is an area and the menu is its context menu: a right-click, a long press, Shift+F10 or the menu key over the area opens it at the pointer, or at the area's corner from the keyboard, as Radix's context menu does. A press on the area does not open it, and closing it returns focus to where it was. A touch or a pen held still on the area opens it too, on every browser, since iOS sends no 'contextmenu' for one. **A trigger with its own action.** With 'open-on="long-press"', a press on the trigger is the trigger's own, and a press held for half a second opens the menu, as React Aria's 'trigger="longPress"' does. Alt+Down or Alt+Up opens it from the keyboard, and the trigger is described by 'long-press-label', which says so. */
18511
18589
  "helix-headless-menu": DefineCustomElement<
18512
18590
  HelixHeadlessMenu,
18513
18591
  HelixHeadlessMenuVueProps,
@@ -18543,7 +18621,7 @@ export interface WcToolkitVueGlobalComponents {
18543
18621
  HelixHeadlessNotificationVueProps,
18544
18622
  HelixHeadlessNotificationVueEvents
18545
18623
  >;
18546
- /** Notifications are slotted children. Each one is your own markup, with an avatar, a link, or a button in it. Feeds usually hold tens of items, so writing them out lets an item hold anything. The list does not virtualize. Windowing needs the list to own the data, and here you own it, so N notifications are N elements. For a feed of thousands, use a data table with a custom cell. Read state is reported to you. Marking read goes from the root to the item and from the item to you, so a canceled 'helix-read' changes nothing, and if you own 'read', nothing changes until you set it. 'unread' is derived from the items and written to an attribute, so a stylesheet and a badge can both use it without counting. **The feed is one 'Tab' stop for its rows.** Each row takes focus itself and is read by its label. 'ArrowDown' and 'ArrowUp' move to the next and the previous row, 'Home' and 'End' to the first and the last, and 'PageDown' and 'PageUp' move a row on or back from anywhere inside one, as in the APG feed pattern. The controls inside a row stay in the 'Tab' order. Set 'total' when the feed holds one page of a longer list, and each row says its place in the whole of it. **Keyboard.** | Key | What it does | |---|---| | Down, Up | On a row, moves to the next or the previous row. | | Home, End | On a row, moves to the first or the last row. | | Page Down, Page Up | From anywhere in a row, moves to the next or the previous row. | | Control+End | From anywhere in the feed, moves to the first control after it on the page. | | Control+Home | From anywhere in the feed, moves to the nearest control before it on the page. | | Tab | Moves through the controls in a row, and on out of the feed. | **'load-more' adds a button after the list** that sends 'helix-load-more', for a feed that holds one page of a longer list. Append the next page, set 'loading' while it is on its way, and take 'load-more' off once there is nothing more. While the feed is loading the button stays, so focus stays on it, and it is 'aria-disabled' and sends nothing. **'load-error' says a page could not be fetched**, such as "Could not load notifications": it shows under the rows there are, in the 'error' part, in place of the empty and loading lines, and a screen reader hears it. Clear it when you ask again. */
18624
+ /** Notifications are slotted children. Each one is your own markup, with an avatar, a link, or a button in it. Feeds usually hold tens of items, so writing them out lets an item hold anything. The list does not virtualize. Windowing needs the list to own the data, and here you own it, so N notifications are N elements. For a feed of thousands, use a data table with a custom cell. Read state is reported to you. Marking read goes from the root to the item and from the item to you, so a canceled 'helix-read' changes nothing, and if you own 'read', nothing changes until you set it. 'unread' is derived from the items and written to an attribute, so a stylesheet and a badge can both use it without counting. **The feed is one 'Tab' stop for its rows.** Each row takes focus itself and is read by its label. 'ArrowDown' and 'ArrowUp' move to the next and the previous row, 'Home' and 'End' to the first and the last, and 'PageDown' and 'PageUp' move a row on or back from anywhere inside one, as in the APG feed pattern. The controls inside a row stay in the 'Tab' order. Set 'total' when the feed holds one page of a longer list, and each row says its place in the whole of it. **Keyboard.** | Key | What it does | |---|---| | Down, Up | On a row, moves to the next or the previous row. | | Home, End | On a row, moves to the first or the last row. | | Page Down, Page Up | From anywhere in a row, moves to the next or the previous row. | | Control+End | From anywhere in the feed, moves to the first control after it on the page. | | Control+Home | From anywhere in the feed, moves to the nearest control before it on the page. | | Tab | Moves through the controls in a row, and on out of the feed. | **A notification that arrives says so.** Unread rows added above the rows there were are counted in the live region, "1 new notification", in 'arrived-label'. Rows that arrive while 'loading' is set say nothing, so set it while a page is on its way. **'load-more' adds a button after the list** that sends 'helix-load-more', for a feed that holds one page of a longer list. Append the next page, set 'loading' while it is on its way, and take 'load-more' off once there is nothing more. While the feed is loading the button stays, so focus stays on it, and it is 'aria-disabled' and sends nothing. **'load-error' says a page could not be fetched**, such as "Could not load notifications": it shows under the rows there are, in the 'error' part, in place of the empty and loading lines, and a screen reader hears it. Clear it when you ask again. */
18547
18625
  "helix-headless-notifications": DefineCustomElement<
18548
18626
  HelixHeadlessNotifications,
18549
18627
  HelixHeadlessNotificationsVueProps,
@@ -18837,13 +18915,13 @@ export interface WcToolkitVueGlobalComponents {
18837
18915
  HelixHeadlessTimelineVueProps,
18838
18916
  HelixHeadlessTimelineVueEvents
18839
18917
  >;
18840
- /** 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'. **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. */
18918
+ /** 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. */
18841
18919
  "helix-headless-toast-item": DefineCustomElement<
18842
18920
  HelixHeadlessToastItem,
18843
18921
  HelixHeadlessToastItemVueProps,
18844
18922
  HelixHeadlessToastItemVueEvents
18845
18923
  >;
18846
- /** 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. */
18924
+ /** 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. | */
18847
18925
  "helix-headless-toast": DefineCustomElement<
18848
18926
  HelixHeadlessToast,
18849
18927
  HelixHeadlessToastVueProps,
package/types/words.d.ts CHANGED
@@ -2228,6 +2228,13 @@ declare module '@fusion.dev/helix-core' {
2228
2228
  * English: `Loading`
2229
2229
  */
2230
2230
  loadingText: Message
2231
+ /**
2232
+ * The description a trigger gives under `open-on="long-press"`, saying how
2233
+ * to open the menu. Translate it with the rest of your interface.
2234
+ *
2235
+ * English: `Long press or press Alt+Down to show the menu`
2236
+ */
2237
+ longPressLabel: Message
2231
2238
  }
2232
2239
  'helix-meter': {
2233
2240
  /**
@@ -2275,6 +2282,13 @@ declare module '@fusion.dev/helix-core' {
2275
2282
  unreadLabel: Message
2276
2283
  }
2277
2284
  'helix-notifications': {
2285
+ /**
2286
+ * What the feed says when unread notifications arrive, with `{count}` the
2287
+ * number of them. Empty it to say nothing.
2288
+ *
2289
+ * English: `{count, plural, one {# new notification} other {# new notifications}}`
2290
+ */
2291
+ arrivedLabel: Message
2278
2292
  /**
2279
2293
  * The text shown and announced when there are no rows and none are loading.
2280
2294
  *