@fusion.dev/helix-headless 0.160.0 → 0.161.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 (39) hide show
  1. package/custom-elements.json +1729 -50
  2. package/dist/canvas/root/canvas-root.d.ts +59 -2
  3. package/dist/canvas/root/canvas-root.js +123 -8
  4. package/dist/chat/message/chat-message.d.ts +8 -0
  5. package/dist/chat/message/chat-message.js +11 -0
  6. package/dist/chat/root/chat-root.d.ts +47 -1
  7. package/dist/chat/root/chat-root.js +130 -4
  8. package/dist/code-block/lines.d.ts +12 -0
  9. package/dist/code-block/lines.js +41 -0
  10. package/dist/code-block/root/code-block-root.d.ts +88 -5
  11. package/dist/code-block/root/code-block-root.js +154 -10
  12. package/dist/element-events.generated.js +4 -0
  13. package/dist/splitter/root/splitter-root.d.ts +15 -0
  14. package/dist/splitter/root/splitter-root.js +16 -2
  15. package/dist/table/grid-controller.d.ts +7 -1
  16. package/dist/table/grid-controller.js +9 -1
  17. package/dist/table/root/table-root.d.ts +122 -0
  18. package/dist/table/root/table-root.js +293 -17
  19. package/dist/table/row/table-row.d.ts +41 -0
  20. package/dist/table/row/table-row.js +56 -2
  21. package/dist/timeline/item/timeline-item.d.ts +47 -10
  22. package/dist/timeline/item/timeline-item.js +36 -4
  23. package/dist/video-playlist/item/video-playlist-item.d.ts +11 -0
  24. package/dist/video-playlist/item/video-playlist-item.js +5 -0
  25. package/dist/video-playlist/menu/video-playlist-menu.d.ts +6 -0
  26. package/dist/video-playlist/menu/video-playlist-menu.js +11 -0
  27. package/dist/video-playlist/root/video-playlist-root.d.ts +59 -5
  28. package/dist/video-playlist/root/video-playlist-root.js +82 -10
  29. package/dist/virtual-list/fill.d.ts +6 -1
  30. package/dist/virtual-list/fill.js +1 -1
  31. package/dist/virtual-list/keys.d.ts +8 -0
  32. package/dist/virtual-list/keys.js +20 -0
  33. package/dist/virtual-list/root/virtual-list-root.d.ts +98 -13
  34. package/dist/virtual-list/root/virtual-list-root.js +195 -20
  35. package/lint.json +1 -1
  36. package/package.json +5 -5
  37. package/types/jsx.d.ts +936 -68
  38. package/types/vue.d.ts +226 -12
  39. package/types/words.d.ts +79 -0
@@ -15622,7 +15622,7 @@
15622
15622
  "declarations": [
15623
15623
  {
15624
15624
  "kind": "class",
15625
- "description": "A board of cards and connectors, drawn by Helix. On a canvas every position\nis data that someone placed, so drawing is arithmetic over rectangles with no\nlayout to compute. `Map` takes a slotted map, because another renderer draws\nits tiles.\n\nThe format is [JSON Canvas](https://jsoncanvas.org), an open format. Each\nnode has an `x`, `y`, `width`, `height`, and a type. Each edge names the two\nnodes it joins and the sides it leaves and arrives on. A card belongs to a\ngroup when it sits inside the group's bounds.\n\nThe cards are text in the DOM, so a screen reader can read them. The family\nadds a reading order and states each card's connections as text. `order` sets\nthe reading order:\n- `spatial` bands the cards into rows.\n- `edges` follows the arrows, starting from the cards that nothing points to.\n\n**Cards move by default.** The board writes the new `x` and `y` onto the\ncard, the way an input writes its own value, and dispatches two events:\n- `helix-before-move` for every step. Cancel it to hold the positions in your\n own state and apply them yourself.\n- `helix-move` once the move is finished.\n\nA resize dispatches the same pair with a size. Set `readonly` on the board to\nkeep every card in place, such as on a published board. Set `readonly` on one\ncard or connection to keep only that one in place.\n\nSet `snap` to a length in the document's units, such as `32`, and a card\nthat is moved or resized lands on a multiple of it. Carrying a card, a\ncorner, a connection, or the selection box near the edge of the board moves\nthe board under it, so a card can be taken to a place off screen in one\ndrag. A connection let go within 20 pixels of a card arrives at it. A\ndouble click on the empty board zooms in about that point, and Shift with a\ndouble click zooms out.\n\nKeyboard behavior:\n- One card holds the board's tab stop.\n- The arrow keys move through the cards in reading order. The card you land\n on scrolls into view, and its connections are announced with it.\n- The card you land on is selected. Control or Command with an arrow key,\n Home, or End moves without changing the selection, and Space adds the card\n to the selection or takes it out, so you can select cards that are not\n next to each other.\n- Shift with an arrow key moves the card: by 16 units, or to the next\n multiple of `snap` where it is set. Alt with an arrow key resizes it from\n its bottom right corner the same way.\n- The connections leaving a card are stops of their own, straight after it.\n Enter on one moves to the card it arrives at.\n- What a key changes that a reader cannot see is said: where a card moved\n to, its new size, how many cards are selected, and the zoom. A selected\n card or connection says so when a reader arrives on it.\n\nEvery drag also works with clicks, as WCAG 2.5.7 requires for a pointer that\ncannot hold a button down. Click a selected card's move handle, a corner, a\ncard's connection point, or the end of a selected connection to pick it up.\nIt follows the pointer with no button held, and the next click puts it down\nwhere a drag would have. On touch, the next tap sets where it lands. Escape,\nor a press outside the board, puts it back. So a finger connects two cards\nwith three taps: the card, one of its points, and the card to connect to.\n\nConnecting and removing dispatch requests, and your code applies them:\n- Drawing from a card's handle to another card, or pressing C on one card and\n Enter on another, dispatches `helix-connect`.\n- Delete on a card or a connection dispatches `helix-remove`. The event names\n every connection that removing the card would leave without an end.\n\nOnce your page removes what Delete asked for, focus moves to the next stop,\nto the one before where it was the last, and to the board where none is\nleft. A focused card your page removes for its own reasons hands focus on\nthe same way, unless the reader has already moved focus somewhere else.\n\nThe board applies a move itself, because the card already exists. A\nconnection is a new element, and React discards an element the board adds to\nits markup on the next render, so you write the connection.\n\nCards and connections are `helix-canvas-node` and `helix-canvas-edge`\nelements, so they are in the served markup whichever renderer wrote them. The\nlibrary fetches nothing, and an array passed to an element is missing from\nthe first paint of a server-rendered React page. `fromJsonCanvas` turns a\nJSON Canvas document into their props, and `toJsonCanvas()` writes a board\nback out.",
15625
+ "description": "A board of cards and connectors, drawn by Helix. On a canvas every position\nis data that someone placed, so drawing is arithmetic over rectangles with no\nlayout to compute. `Map` takes a slotted map, because another renderer draws\nits tiles.\n\nThe format is [JSON Canvas](https://jsoncanvas.org), an open format. Each\nnode has an `x`, `y`, `width`, `height`, and a type. Each edge names the two\nnodes it joins and the sides it leaves and arrives on. A card belongs to a\ngroup when it sits inside the group's bounds.\n\nThe cards are text in the DOM, so a screen reader can read them. The family\nadds a reading order and states each card's connections as text. `order` sets\nthe reading order:\n- `spatial` bands the cards into rows.\n- `edges` follows the arrows, starting from the cards that nothing points to.\n\n**Cards move by default.** The board writes the new `x` and `y` onto the\ncard, the way an input writes its own value, and dispatches two events:\n- `helix-before-move` for every step. Cancel it to hold the positions in your\n own state and apply them yourself.\n- `helix-move` once the move is finished.\n\nA resize dispatches the same pair with a size. Set `readonly` on the board to\nkeep every card in place, such as on a published board. Set `readonly` on one\ncard or connection to keep only that one in place.\n\nSet `snap` to a length in the document's units, such as `32`, and a card\nthat is moved or resized lands on a multiple of it. Carrying a card, a\ncorner, a connection, or the selection box near the edge of the board moves\nthe board under it, so a card can be taken to a place off screen in one\ndrag. A connection let go within 20 pixels of a card arrives at it. A\ndouble click on the empty board zooms in about that point, and Shift with a\ndouble click zooms out.\n\nKeyboard behavior:\n- One card holds the board's tab stop.\n- The arrow keys move through the cards in reading order. The card you land\n on scrolls into view, and its connections are announced with it.\n- The card you land on is selected. Control or Command with an arrow key,\n Home, or End moves without changing the selection, and Space adds the card\n to the selection or takes it out, so you can select cards that are not\n next to each other.\n- Shift with an arrow key moves the card: by 16 units, or to the next\n multiple of `snap` where it is set. Alt with an arrow key resizes it from\n its bottom right corner the same way.\n- The connections leaving a card are stops of their own, straight after it.\n Enter on one moves to the card it arrives at.\n- What a key changes that a reader cannot see is said: where a card moved\n to, its new size, how many cards are selected, and the zoom. A selected\n card or connection says so when a reader arrives on it.\n- Control or Command with C copies the selected cards, and the connections\n between them, as a JSON Canvas document in text, which another board or\n an app that reads the format takes. A paste is your page's: listen for\n `paste` on the board, read the text with `fromJsonCanvas`, and add the\n cards it holds.\n- Control or Command with Z undoes the last move or resize the board made,\n and with Shift, or Control with Y, makes it again. `undo()` and `redo()`\n do the same from a script. Each asks with `helix-before-move` and tells\n with `helix-move`, as a move does, so a board that holds its positions in\n your state is undone through your state.\n\nEvery drag also works with clicks, as WCAG 2.5.7 requires for a pointer that\ncannot hold a button down. Click a selected card's move handle, a corner, a\ncard's connection point, or the end of a selected connection to pick it up.\nIt follows the pointer with no button held, and the next click puts it down\nwhere a drag would have. On touch, the next tap sets where it lands. Escape,\nor a press outside the board, puts it back. So a finger connects two cards\nwith three taps: the card, one of its points, and the card to connect to.\n\nConnecting and removing dispatch requests, and your code applies them:\n- Drawing from a card's handle to another card, or pressing C on one card and\n Enter on another, dispatches `helix-connect`.\n- Delete on a card or a connection dispatches `helix-remove`. The event names\n every connection that removing the card would leave without an end.\n\nOnce your page removes what Delete asked for, focus moves to the next stop,\nto the one before where it was the last, and to the board where none is\nleft. A focused card your page removes for its own reasons hands focus on\nthe same way, unless the reader has already moved focus somewhere else.\n\nThe board applies a move itself, because the card already exists. A\nconnection is a new element, and React discards an element the board adds to\nits markup on the next render, so you write the connection.\n\nCards and connections are `helix-canvas-node` and `helix-canvas-edge`\nelements, so they are in the served markup whichever renderer wrote them. The\nlibrary fetches nothing, and an array passed to an element is missing from\nthe first paint of a server-rendered React page. `fromJsonCanvas` turns a\nJSON Canvas document into their props, and `toJsonCanvas()` writes a board\nback out.",
15626
15626
  "name": "HelixHeadlessCanvas",
15627
15627
  "cssProperties": [
15628
15628
  {
@@ -15898,6 +15898,19 @@
15898
15898
  "module": "src/mixins/mixin-viewport/mixin-viewport.ts"
15899
15899
  }
15900
15900
  },
15901
+ {
15902
+ "kind": "field",
15903
+ "name": "copiedLabel",
15904
+ "type": {
15905
+ "text": "string"
15906
+ },
15907
+ "default": "'{count, plural, one {# card copied} other {# cards copied}}'",
15908
+ "description": "What screen readers hear after a copy, with `{count}` for the cards copied.",
15909
+ "attribute": "copied-label",
15910
+ "helix": {
15911
+ "words": true
15912
+ }
15913
+ },
15901
15914
  {
15902
15915
  "kind": "field",
15903
15916
  "name": "fallbackLabel",
@@ -16017,6 +16030,19 @@
16017
16030
  "words": true
16018
16031
  }
16019
16032
  },
16033
+ {
16034
+ "kind": "field",
16035
+ "name": "redoneLabel",
16036
+ "type": {
16037
+ "text": "string"
16038
+ },
16039
+ "default": "'Move made again'",
16040
+ "description": "What screen readers hear after a move or a resize is made again.",
16041
+ "attribute": "redone-label",
16042
+ "helix": {
16043
+ "words": true
16044
+ }
16045
+ },
16020
16046
  {
16021
16047
  "kind": "field",
16022
16048
  "name": "resizedLabel",
@@ -16088,15 +16114,6 @@
16088
16114
  "description": "Snaps the cards a reader moves or resizes to a multiple of this many of the\ndocument's units, such as `32` to land on the lines `grid` draws.\n\n**A drag lets go on the nearest line and a key goes to the next one.**\nShift with an arrow moves a card to the next line that way, rather than\nby its step of 16, and Alt with an arrow moves its bottom right corner\nthe same way. A group moves with what it carries, so a card inside one\nkeeps its place in it. Absent, cards land where they are let go.",
16089
16115
  "attribute": "snap"
16090
16116
  },
16091
- {
16092
- "kind": "field",
16093
- "name": "editing",
16094
- "type": {
16095
- "text": "{ target: 'edge' | 'group'; key: string; was: string } | undefined"
16096
- },
16097
- "privacy": "private",
16098
- "description": "A label being edited in place: whose, and what it said before."
16099
- },
16100
16117
  {
16101
16118
  "kind": "field",
16102
16119
  "name": "stoppedLabel",
@@ -16110,6 +16127,15 @@
16110
16127
  "words": true
16111
16128
  }
16112
16129
  },
16130
+ {
16131
+ "kind": "field",
16132
+ "name": "editing",
16133
+ "type": {
16134
+ "text": "{ target: 'edge' | 'group'; key: string; was: string } | undefined"
16135
+ },
16136
+ "privacy": "private",
16137
+ "description": "A label being edited in place: whose, and what it said before."
16138
+ },
16113
16139
  {
16114
16140
  "kind": "field",
16115
16141
  "name": "toneLabels",
@@ -16137,6 +16163,19 @@
16137
16163
  "module": "src/mixins/mixin-viewport/mixin-viewport.ts"
16138
16164
  }
16139
16165
  },
16166
+ {
16167
+ "kind": "field",
16168
+ "name": "undoneLabel",
16169
+ "type": {
16170
+ "text": "string"
16171
+ },
16172
+ "default": "'Move undone'",
16173
+ "description": "What screen readers hear after a move or a resize is undone.",
16174
+ "attribute": "undone-label",
16175
+ "helix": {
16176
+ "words": true
16177
+ }
16178
+ },
16140
16179
  {
16141
16180
  "kind": "field",
16142
16181
  "name": "usingLabel",
@@ -17416,6 +17455,141 @@
17416
17455
  ],
17417
17456
  "description": "Moves cards, having asked first.\n\n**The same contract as `open` on a dialog.** The request goes out before\nanything moves; refused, nothing does, because the consumer is holding the\npositions and will render them. Unrefused, the board writes them onto the\ncards, which is the uncontrolled board a consumer gets by doing nothing.\nReturns whether it applied, so a caller knows whether to report a finish."
17418
17457
  },
17458
+ {
17459
+ "kind": "field",
17460
+ "name": "undoable",
17461
+ "type": {
17462
+ "text": "Array<{ after: MoveDetail; before: MoveDetail }>"
17463
+ },
17464
+ "privacy": "private",
17465
+ "default": "[]",
17466
+ "description": "The moves and resizes the board made, oldest first, each as where its\ncards stood before and after, for `undo` to take back. At most 100."
17467
+ },
17468
+ {
17469
+ "kind": "field",
17470
+ "name": "redoable",
17471
+ "type": {
17472
+ "text": "Array<{ after: MoveDetail; before: MoveDetail }>"
17473
+ },
17474
+ "privacy": "private",
17475
+ "default": "[]",
17476
+ "description": "The moves undone, most recent last, for `redo` to make again."
17477
+ },
17478
+ {
17479
+ "kind": "field",
17480
+ "name": "moving",
17481
+ "type": {
17482
+ "text": "Map<string, { height: number; width: number; x: number; y: number }> | undefined"
17483
+ },
17484
+ "privacy": "private",
17485
+ "description": "Where the cards of the gesture in progress stood before its first step."
17486
+ },
17487
+ {
17488
+ "kind": "field",
17489
+ "name": "replaying",
17490
+ "type": {
17491
+ "text": "boolean"
17492
+ },
17493
+ "privacy": "private",
17494
+ "default": "false",
17495
+ "description": "Whether a move is an undo or a redo, which history does not record again."
17496
+ },
17497
+ {
17498
+ "kind": "method",
17499
+ "name": "finishMove",
17500
+ "privacy": "private",
17501
+ "return": {
17502
+ "type": {
17503
+ "text": "void"
17504
+ }
17505
+ },
17506
+ "parameters": [
17507
+ {
17508
+ "name": "detail",
17509
+ "type": {
17510
+ "text": "MoveDetail"
17511
+ }
17512
+ }
17513
+ ],
17514
+ "description": "Says a move is finished, and keeps it for `undo`: where its cards stood\nbefore the gesture, and where they stand now."
17515
+ },
17516
+ {
17517
+ "kind": "method",
17518
+ "name": "undo",
17519
+ "return": {
17520
+ "type": {
17521
+ "text": "boolean"
17522
+ }
17523
+ },
17524
+ "description": "Puts the cards of the last move or resize back where they stood, asking\nwith `helix-before-move` first. Returns whether anything moved: false\nwith nothing to undo, or when the request was refused.",
17525
+ "type": {
17526
+ "text": "undo() => boolean"
17527
+ }
17528
+ },
17529
+ {
17530
+ "kind": "method",
17531
+ "name": "redo",
17532
+ "return": {
17533
+ "type": {
17534
+ "text": "boolean"
17535
+ }
17536
+ },
17537
+ "description": "Makes the last move or resize `undo` took back again, asking with\n`helix-before-move` first. Returns whether anything moved.",
17538
+ "type": {
17539
+ "text": "redo() => boolean"
17540
+ }
17541
+ },
17542
+ {
17543
+ "kind": "method",
17544
+ "name": "replay",
17545
+ "privacy": "private",
17546
+ "return": {
17547
+ "type": {
17548
+ "text": "boolean"
17549
+ }
17550
+ },
17551
+ "parameters": [
17552
+ {
17553
+ "name": "from",
17554
+ "type": {
17555
+ "text": "Array<{ after: MoveDetail; before: MoveDetail }>"
17556
+ }
17557
+ },
17558
+ {
17559
+ "name": "to",
17560
+ "type": {
17561
+ "text": "Array<{ after: MoveDetail; before: MoveDetail }>"
17562
+ }
17563
+ },
17564
+ {
17565
+ "name": "side",
17566
+ "type": {
17567
+ "text": "'after' | 'before'"
17568
+ }
17569
+ },
17570
+ {
17571
+ "name": "words",
17572
+ "type": {
17573
+ "text": "string"
17574
+ }
17575
+ }
17576
+ ],
17577
+ "description": "Moves the cards of the last entry of `from` to its `side`, and files it in `to`."
17578
+ },
17579
+ {
17580
+ "kind": "field",
17581
+ "name": "handleCopy",
17582
+ "privacy": "private",
17583
+ "readonly": true,
17584
+ "description": "A copy on the board with cards selected writes them, and the connections\nbetween them, as a JSON Canvas document in text. Not from a field a card\nholds, nor over text a reader selected, which are the platform's to copy."
17585
+ },
17586
+ {
17587
+ "kind": "field",
17588
+ "name": "handleHistoryKey",
17589
+ "privacy": "private",
17590
+ "readonly": true,
17591
+ "description": "Control or Command with Z undoes, and with Shift, or Control with Y,\nredoes, from anywhere on the board but a field a card holds, where the\nkeys are the field's."
17592
+ },
17419
17593
  {
17420
17594
  "kind": "field",
17421
17595
  "name": "edgePan",
@@ -19396,6 +19570,15 @@
19396
19570
  "description": "The name of the group of controls, read by screen readers, which names\nwhat the controls drive rather than the mechanism.",
19397
19571
  "fieldName": "controlsLabel"
19398
19572
  },
19573
+ {
19574
+ "name": "copied-label",
19575
+ "type": {
19576
+ "text": "string"
19577
+ },
19578
+ "default": "'{count, plural, one {# card copied} other {# cards copied}}'",
19579
+ "description": "What screen readers hear after a copy, with `{count}` for the cards copied.",
19580
+ "fieldName": "copiedLabel"
19581
+ },
19399
19582
  {
19400
19583
  "name": "fallback-label",
19401
19584
  "type": {
@@ -19484,6 +19667,15 @@
19484
19667
  "description": "The text announced when a connection's end is picked up, with `{from}` and\n`{to}`.",
19485
19668
  "fieldName": "reconnectingLabel"
19486
19669
  },
19670
+ {
19671
+ "name": "redone-label",
19672
+ "type": {
19673
+ "text": "string"
19674
+ },
19675
+ "default": "'Move made again'",
19676
+ "description": "What screen readers hear after a move or a resize is made again.",
19677
+ "fieldName": "redoneLabel"
19678
+ },
19487
19679
  {
19488
19680
  "name": "resized-label",
19489
19681
  "type": {
@@ -19564,6 +19756,15 @@
19564
19756
  "description": "The hint shown when one finger swipes over the board with `gestures=\"cooperative\"`.",
19565
19757
  "fieldName": "twoFingerHintLabel"
19566
19758
  },
19759
+ {
19760
+ "name": "undone-label",
19761
+ "type": {
19762
+ "text": "string"
19763
+ },
19764
+ "default": "'Move undone'",
19765
+ "description": "What screen readers hear after a move or a resize is undone.",
19766
+ "fieldName": "undoneLabel"
19767
+ },
19567
19768
  {
19568
19769
  "name": "using-label",
19569
19770
  "type": {
@@ -24625,7 +24826,7 @@
24625
24826
  "declarations": [
24626
24827
  {
24627
24828
  "kind": "class",
24628
- "description": "Chat has no positioning, no backdrop, and no trigger, so you can put it in\nany container, such as a page, a sidebar, a modal, or a floating panel.\n\nThe transcript stays pinned to the bottom, including while a streamed answer\ngrows, until the user scrolls more than `threshold` away from it.\n\nWith `history` set to `more`, reaching the top fires `helix-history`. Set\n`loading` while you fetch, then prepend the older turns. The turn the user\nwas reading stays in place on screen.\n\nThe log is `aria-live=\"off\"`. A separate status region announces each new\nturn once, when it has finished arriving. It skips the user's own turns\nunless they failed to send, turns loaded as history, and the turns already\nthere when the transcript opened. A turn is said with its author first, such\nas \"Ada: It ships today\" (`arrival-label`), where its author can be named.\n\nPass the turns as children or as `turns` data. Do not use both. Children\nrender from the server and suit most conversations. `turns` draws a long\ntranscript one window at a time, so the log needs a block size of its own.\n\n**A conversation is built from three elements.** The chat holds the\ntranscript, a `Chat.Message` stands for each turn, and a `Chat.Composer` sits\nin the `composer` slot. When the user sends, `helix-send` reaches the chat:\nadd their turn with `author=\"me\"` and `state=\"sending\"`, then set `state` to\n`sent` or `failed` when your server answers. Add the reply as a turn with\n`state=\"streaming\"`, write its text as it arrives, and set `state` to `sent`\nwhen it is complete. While the user types, the composer sends\n`helix-typing`, which you can pass on to the other side. When the other side\ntypes, set `typing` to their name: the status band draws three dots and\n\"Ada is typing\" (`typing-label`), which a screen reader hears, and clearing\nit takes them away. Anything slotted into `status` is drawn first.\n\nA screen reader names each turn by its author and its time, such as \"You, 2\nminutes ago\". Set `me-label` and `message-label` to say it in your language,\nand give each turn by `them` an `author-label`. A turn with neither an author\nlabel nor a time is named by `turn-label`, \"Message\".\n\nA turn from `turns` is drawn in the chat's shadow root, so style it through\nthe forwarded `message-*` parts. A turn by `me` also gets each part with\n`-mine` added, and the turn's state adds `message-meta-failed`,\n`message-content-sending`, and `message-content-streaming`. To style each\nparticipant differently, give `author-styles` the declarations for each\nauthor, such as `{\"ada\": \"--chat-message-background-color: …\"}`: the message\ndrawn for each of their turns takes them as its `style`, so the message's\ncustom properties change for that author alone. Turns passed as children are\nstyled by their `author`, such as `helix-chat-message[author=\"ada\"]`.",
24829
+ "description": "Chat has no positioning, no backdrop, and no trigger, so you can put it in\nany container, such as a page, a sidebar, a modal, or a floating panel.\n\nThe transcript stays pinned to the bottom, including while a streamed answer\ngrows, until the user scrolls more than `threshold` away from it.\n\nWith `history` set to `more`, reaching the top fires `helix-history`. Set\n`loading` while you fetch, then prepend the older turns. The turn the user\nwas reading stays in place on screen.\n\nThe log is `aria-live=\"off\"`. A separate status region announces each new\nturn once, when it has finished arriving. It skips the user's own turns\nunless they failed to send, turns loaded as history, and the turns already\nthere when the transcript opened. A turn is said with its author first, such\nas \"Ada: It ships today\" (`arrival-label`), where its author can be named.\n\nPass the turns as children or as `turns` data. Do not use both. Children\nrender from the server and suit most conversations. `turns` draws a long\ntranscript one window at a time, so the log needs a block size of its own.\n\n**A conversation is built from three elements.** The chat holds the\ntranscript, a `Chat.Message` stands for each turn, and a `Chat.Composer` sits\nin the `composer` slot. When the user sends, `helix-send` reaches the chat:\nadd their turn with `author=\"me\"` and `state=\"sending\"`, then set `state` to\n`sent` or `failed` when your server answers. Add the reply as a turn with\n`state=\"streaming\"`, write its text as it arrives, and set `state` to `sent`\nwhen it is complete. While the user types, the composer sends\n`helix-typing`, which you can pass on to the other side. When the other side\ntypes, set `typing` to their name: the status band draws three dots and\n\"Ada is typing\" (`typing-label`), which a screen reader hears, and clearing\nit takes them away. Anything slotted into `status` is drawn first.\n\n**Keyboard.** The transcript moves between turns the way a feed does. Each\nturn says its place, such as \"3 of 40\", windowed or not.\n\n| Key | What it does |\n|---|---|\n| Page Down, Page Up | On a turn or inside one, moves focus to the next or the previous turn. On the transcript itself, moves focus to the turn at the top of the view. |\n| Control with End | Moves focus to the composer. |\n| Control with Home | Moves focus to the first control above the transcript, or to the transcript. |\n\nWhile you are scrolled away from the newest turn, the `resume` region shows\na button that takes you back, named by `resume-label`, \"Jump to latest\".\nSlot your own control into `resume` to replace it.\n\nA screen reader names each turn by its author and its time, such as \"You, 2\nminutes ago\". Set `me-label` and `message-label` to say it in your language,\nand give each turn by `them` an `author-label`. A turn with neither an author\nlabel nor a time is named by `turn-label`, \"Message\".\n\nA turn from `turns` is drawn in the chat's shadow root, so style it through\nthe forwarded `message-*` parts. A turn by `me` also gets each part with\n`-mine` added, and the turn's state adds `message-meta-failed`,\n`message-content-sending`, and `message-content-streaming`. To style each\nparticipant differently, give `author-styles` the declarations for each\nauthor, such as `{\"ada\": \"--chat-message-background-color: …\"}`: the message\ndrawn for each of their turns takes them as its `style`, so the message's\ncustom properties change for that author alone. Turns passed as children are\nstyled by their `author`, such as `helix-chat-message[author=\"ada\"]`.",
24629
24830
  "name": "HelixHeadlessChat",
24630
24831
  "cssParts": [
24631
24832
  {
@@ -24756,6 +24957,14 @@
24756
24957
  "description": "The control shown while the user is scrolled away from the bottom.",
24757
24958
  "name": "resume"
24758
24959
  },
24960
+ {
24961
+ "description": "The button the `resume` region shows when nothing is slotted into it.",
24962
+ "name": "resume-button"
24963
+ },
24964
+ {
24965
+ "description": "The arrow on the default `resume-button`.",
24966
+ "name": "resume-mark"
24967
+ },
24759
24968
  {
24760
24969
  "description": "The status region, outside the log.",
24761
24970
  "name": "status"
@@ -24787,7 +24996,7 @@
24787
24996
  "name": "header"
24788
24997
  },
24789
24998
  {
24790
- "description": "The control that returns to the bottom, shown while the user has scrolled away.",
24999
+ "description": "The control that returns to the bottom, shown while the user has scrolled away. Defaults to a button named by `resume-label`.",
24791
25000
  "name": "resume"
24792
25001
  },
24793
25002
  {
@@ -24971,6 +25180,19 @@
24971
25180
  "description": "Whether the transcript follows new turns to the bottom.\n\nThe reader's scrolling asks first: `helix-before-pin` is cancelable, so a\nconsumer refusing it takes the decision and assigns their own value.\n`default-pinned` seeds the state this element then owns, and it defaults to\npinned because a conversation opens at its most recent turn.\n\n**Not reflected, and the default is why.** A reflected property that\ndefaults to true writes its attribute on upgrade whether or not the\nconsumer wrote one, so the server serves `<helix-headless-chat label=\"x\">`\nand the client turns it into `<helix-headless-chat label=\"x\" pinned>`: a\nhydration mismatch a React consumer reports and does not patch up. Nothing\nneeds the attribute either, because the one thing that changes with the pin\nis the way back, and that is a part inside the shadow tree where a\nstylesheet can already reach it. Measured rather than assumed: `label,\npinned` after upgrade against `label` from the server.",
24972
25181
  "attribute": "pinned"
24973
25182
  },
25183
+ {
25184
+ "kind": "field",
25185
+ "name": "resumeLabel",
25186
+ "type": {
25187
+ "text": "string"
25188
+ },
25189
+ "default": "'Jump to latest'",
25190
+ "description": "The words on the button that returns to the newest turn, where `resume` is empty.",
25191
+ "attribute": "resume-label",
25192
+ "helix": {
25193
+ "words": true
25194
+ }
25195
+ },
24974
25196
  {
24975
25197
  "kind": "field",
24976
25198
  "name": "threshold",
@@ -25521,6 +25743,81 @@
25521
25743
  },
25522
25744
  "description": "Hands each turn written as a child the words it is named with, once it\nhas hydrated, so its first render is the server's."
25523
25745
  },
25746
+ {
25747
+ "kind": "method",
25748
+ "name": "turnFrom",
25749
+ "privacy": "private",
25750
+ "return": {
25751
+ "type": {
25752
+ "text": "number | undefined"
25753
+ }
25754
+ },
25755
+ "parameters": [
25756
+ {
25757
+ "name": "path",
25758
+ "type": {
25759
+ "text": "readonly EventTarget[]"
25760
+ }
25761
+ }
25762
+ ],
25763
+ "description": "Which turn an event came from, by its place, `-1` for the transcript\nitself, or `undefined` for anywhere else."
25764
+ },
25765
+ {
25766
+ "kind": "method",
25767
+ "name": "topTurn",
25768
+ "privacy": "private",
25769
+ "return": {
25770
+ "type": {
25771
+ "text": "number"
25772
+ }
25773
+ },
25774
+ "description": "The place of the turn at the top of the view, or the first turn."
25775
+ },
25776
+ {
25777
+ "kind": "method",
25778
+ "name": "focusTurn",
25779
+ "privacy": "private",
25780
+ "return": {
25781
+ "type": {
25782
+ "text": "Promise<void>"
25783
+ }
25784
+ },
25785
+ "parameters": [
25786
+ {
25787
+ "name": "at",
25788
+ "type": {
25789
+ "text": "number"
25790
+ }
25791
+ }
25792
+ ],
25793
+ "description": "Moves focus to turn `at`, drawing it first where the transcript is\nwindowed and it is not drawn.\n\n**A turn takes focus only once a reader moves to it**, so the\n`tabindex=\"-1\"` a turn written as a child needs is written then, long\nafter any server's markup has hydrated, and never on a turn nobody moved\nto."
25794
+ },
25795
+ {
25796
+ "kind": "method",
25797
+ "name": "firstControlIn",
25798
+ "privacy": "private",
25799
+ "return": {
25800
+ "type": {
25801
+ "text": "HTMLElement | undefined"
25802
+ }
25803
+ },
25804
+ "parameters": [
25805
+ {
25806
+ "name": "names",
25807
+ "type": {
25808
+ "text": "readonly string[]"
25809
+ }
25810
+ }
25811
+ ],
25812
+ "description": "The first control in the regions `names` holds, in their order."
25813
+ },
25814
+ {
25815
+ "kind": "field",
25816
+ "name": "handleKeydown",
25817
+ "privacy": "private",
25818
+ "readonly": true,
25819
+ "description": "Page Down and Page Up move between turns, and Control with End or Home\nleaves the transcript, the keys the APG's feed answers."
25820
+ },
25524
25821
  {
25525
25822
  "kind": "field",
25526
25823
  "name": "handleSlotChange",
@@ -25551,6 +25848,17 @@
25551
25848
  },
25552
25849
  "description": "The turns fed as data, a window of them, between the room the rest would take."
25553
25850
  },
25851
+ {
25852
+ "kind": "method",
25853
+ "name": "renderResume",
25854
+ "privacy": "protected",
25855
+ "return": {
25856
+ "type": {
25857
+ "text": "TemplateResult"
25858
+ }
25859
+ },
25860
+ "description": "The `resume` slot, with the way back drawn where nothing is slotted, behind a seam:\nthe slot answers a page, and this answers the tier above."
25861
+ },
25554
25862
  {
25555
25863
  "kind": "field",
25556
25864
  "name": "emptyText",
@@ -26241,6 +26549,15 @@
26241
26549
  "description": "Whether the transcript follows new turns to the bottom.\n\nThe reader's scrolling asks first: `helix-before-pin` is cancelable, so a\nconsumer refusing it takes the decision and assigns their own value.\n`default-pinned` seeds the state this element then owns, and it defaults to\npinned because a conversation opens at its most recent turn.\n\n**Not reflected, and the default is why.** A reflected property that\ndefaults to true writes its attribute on upgrade whether or not the\nconsumer wrote one, so the server serves `<helix-headless-chat label=\"x\">`\nand the client turns it into `<helix-headless-chat label=\"x\" pinned>`: a\nhydration mismatch a React consumer reports and does not patch up. Nothing\nneeds the attribute either, because the one thing that changes with the pin\nis the way back, and that is a part inside the shadow tree where a\nstylesheet can already reach it. Measured rather than assumed: `label,\npinned` after upgrade against `label` from the server.",
26242
26550
  "fieldName": "pinned"
26243
26551
  },
26552
+ {
26553
+ "name": "resume-label",
26554
+ "type": {
26555
+ "text": "string"
26556
+ },
26557
+ "default": "'Jump to latest'",
26558
+ "description": "The words on the button that returns to the newest turn, where `resume` is empty.",
26559
+ "fieldName": "resumeLabel"
26560
+ },
26244
26561
  {
26245
26562
  "name": "threshold",
26246
26563
  "type": {
@@ -30109,6 +30426,42 @@
30109
30426
  }
30110
30427
  ],
30111
30428
  "description": "The numbers for a gutter of `count` lines, one to a line, as the text a\n`<pre>` draws beside the code. The stylesheet aligns them to the end."
30429
+ },
30430
+ {
30431
+ "kind": "function",
30432
+ "name": "lineRuns",
30433
+ "return": {
30434
+ "type": {
30435
+ "text": "Array<[number, number]>"
30436
+ }
30437
+ },
30438
+ "parameters": [
30439
+ {
30440
+ "name": "list",
30441
+ "type": {
30442
+ "text": "string"
30443
+ }
30444
+ }
30445
+ ],
30446
+ "description": "The runs of lines a list of numbers and ranges names, such as `2, 4-6`, as\n`[first, last]` pairs counted from 1, in order and merged where they touch.\nAnything that is not a whole number or a range of them is passed over, and\na range written backward is read forward."
30447
+ },
30448
+ {
30449
+ "kind": "function",
30450
+ "name": "lineSpans",
30451
+ "return": {
30452
+ "type": {
30453
+ "text": "Array<[number, number]>"
30454
+ }
30455
+ },
30456
+ "parameters": [
30457
+ {
30458
+ "name": "text",
30459
+ "type": {
30460
+ "text": "string"
30461
+ }
30462
+ }
30463
+ ],
30464
+ "description": "Where each line of `text` starts and ends, as character offsets, the line\nbreak left out. A final line break ends the last line, as `lineCount` reads it."
30112
30465
  }
30113
30466
  ],
30114
30467
  "exports": [
@@ -30127,6 +30480,22 @@
30127
30480
  "name": "gutterNumbers",
30128
30481
  "module": "src/code-block/lines.ts"
30129
30482
  }
30483
+ },
30484
+ {
30485
+ "kind": "js",
30486
+ "name": "lineRuns",
30487
+ "declaration": {
30488
+ "name": "lineRuns",
30489
+ "module": "src/code-block/lines.ts"
30490
+ }
30491
+ },
30492
+ {
30493
+ "kind": "js",
30494
+ "name": "lineSpans",
30495
+ "declaration": {
30496
+ "name": "lineSpans",
30497
+ "module": "src/code-block/lines.ts"
30498
+ }
30130
30499
  }
30131
30500
  ]
30132
30501
  },
@@ -30196,9 +30565,31 @@
30196
30565
  "declarations": [
30197
30566
  {
30198
30567
  "kind": "class",
30199
- "description": "Renders a `<pre><code>` pair: `pre` keeps the whitespace, and `code` marks it\nas code. Long lines scroll inside the block and do not wrap, because a line\nbreak can be significant in code.\n\nA copy button is on by default. Set `no-copy` to remove it. The button copies\nthe slotted text, so there is no second copy of the code to keep in sync.\n\nFor a fragment of code inside a sentence, use `Code`.\n\nSet `line-numbers` to number the lines in a gutter beside the code, hidden\nfrom the accessibility tree and left out of a copy. Set `highlight` to a\nfunction that turns the code into highlighted markup, such as one wrapping\nShiki or Prism, and the block draws what it returns; it is handed the\nblock's `language`, so one function serves every block. The code stays in\nthe slot, so the copy button and the page's own text are the code as\nwritten.\n\nSet `expandable` on a block whose height is capped, such as by\n`--code-block-max-block-size`, and a button under it shows every line and\nthen fewer again, as a docs site's long example does. The button is drawn\nonly while the cap hides something, says whether the block is expanded with\n`aria-expanded`, names the block it opens with `aria-controls`, and the block\ncarries `:state(expanded)` while it is.\n\nSet `diff` to show a change. Put a unified diff, the output of `git diff` or\n`diff -u`, in the same slot, and the block draws the lines it added and\nremoved. The block never computes a diff itself. Line numbers come from the\nhunk headers and are hidden from the accessibility tree. Changed lines are\n`<ins>` and `<del>` with the `+` and `-` kept as text, so the change does not\ndepend on color. Each file in the patch is its own block under its own name,\nand its copy button copies the new version of the file. `variant=\"split\"`\nshows the old version beside the new, each removal opposite its replacement.\n\n**A block that scrolls is a tab stop.** While its lines run past its width or\nits cap, the scroller is a region named for the block, such as \"Code,\napp.ts\", that Tab reaches, so a keyboard scrolls it with the arrow keys in\nevery browser. Chromium and Firefox make a scrolling box focusable on their\nown, and Safari does not. A block that fits is no stop at all.\n\n**The code the block draws is marked untranslated**, `translate=\"no\"` on\nits `<pre>`, so a page translator leaves highlighted lines and a diff as\nwritten. Code in the slot takes its translation mode from the element, which\nwrites nothing onto itself, so set `translate=\"no\"` on the element to keep a\ntranslator off plain code too.\n\nOn the server, the slot renders as ordinary code, so a diff first appears as\nthe patch text in a `<pre>`. The client makes the same first render, which\nkeeps hydration clean, and draws the diff once it can read the content. Diff\nmode is experimental. The rest of the family is stable.",
30568
+ "description": "Renders a `<pre><code>` pair: `pre` keeps the whitespace, and `code` marks it\nas code. Long lines scroll inside the block and do not wrap, because a line\nbreak can be significant in code.\n\nA copy button is on by default. Set `no-copy` to remove it. The button copies\nthe slotted text, so there is no second copy of the code to keep in sync.\n\nFor a fragment of code inside a sentence, use `Code`.\n\nSet `line-numbers` to number the lines in a gutter beside the code, hidden\nfrom the accessibility tree and left out of a copy. Set `mark-lines` to\nmark lines a reader should look at, such as `2, 4-6`: the block draws a\nband behind each run, placed where the lines are laid out, so it follows a\nhighlighter's markup and lines that wrap. Set `wrap` to wrap long lines\nrather than scroll them; a gutter then numbers each line where it starts.\nSet `wrappable` for a button in the header that turns `wrap` on and off,\npressed while the lines wrap.\n\nThe header holds the name, the `actions` slot, and the copy button. Slot a\ncontrol into `actions`, such as a button that sets `wrap` or one that opens\nthe code in an editor, and the block draws a header for it even with no\nname. `copy-icon` and `copied-icon` replace the copy button's two icons. Set `highlight` to a\nfunction that turns the code into highlighted markup, such as one wrapping\nShiki or Prism, and the block draws what it returns; it is handed the\nblock's `language`, so one function serves every block. The code stays in\nthe slot, so the copy button and the page's own text are the code as\nwritten.\n\nSet `expandable` on a block whose height is capped, such as by\n`--code-block-max-block-size`, and a button under it shows every line and\nthen fewer again, as a docs site's long example does. The button is drawn\nonly while the cap hides something, says whether the block is expanded with\n`aria-expanded`, names the block it opens with `aria-controls`, and the block\ncarries `:state(expanded)` while it is.\n\nSet `diff` to show a change. Put a unified diff, the output of `git diff` or\n`diff -u`, in the same slot, and the block draws the lines it added and\nremoved. The block never computes a diff itself. Line numbers come from the\nhunk headers and are hidden from the accessibility tree. Changed lines are\n`<ins>` and `<del>` with the `+` and `-` kept as text, so the change does not\ndepend on color. Each file in the patch is its own block under its own name,\nand its copy button copies the new version of the file. `variant=\"split\"`\nshows the old version beside the new, each removal opposite its replacement.\n\n**A block that scrolls is a tab stop.** While its lines run past its width or\nits cap, the scroller is a region named for the block, such as \"Code,\napp.ts\", that Tab reaches, so a keyboard scrolls it with the arrow keys in\nevery browser. Chromium and Firefox make a scrolling box focusable on their\nown, and Safari does not. A block that fits is no stop at all.\n\n**The code the block draws is marked untranslated**, `translate=\"no\"` on\nits `<pre>`, so a page translator leaves highlighted lines and a diff as\nwritten. Code in the slot takes its translation mode from the element, which\nwrites nothing onto itself, so set `translate=\"no\"` on the element to keep a\ntranslator off plain code too.\n\nOn the server, the slot renders as ordinary code, so a diff first appears as\nthe patch text in a `<pre>`. The client makes the same first render, which\nkeeps hydration clean, and draws the diff once it can read the content. Diff\nmode is experimental. The rest of the family is stable.",
30200
30569
  "name": "HelixHeadlessCodeBlock",
30570
+ "cssProperties": [
30571
+ {
30572
+ "description": "Written by the block on each `number` in a `wrap` block with `line-numbers`: how tall the line it numbers is laid out. Do not set it.",
30573
+ "name": "--code-block-line-size"
30574
+ },
30575
+ {
30576
+ "description": "Written by the block on each `mark`: how wide the code is, scrolled part included. Do not set it.",
30577
+ "name": "--code-block-mark-inline-size"
30578
+ },
30579
+ {
30580
+ "description": "Written by the block on each `mark`: how tall its run of lines is. Do not set it.",
30581
+ "name": "--code-block-mark-size"
30582
+ },
30583
+ {
30584
+ "description": "Written by the block on each `mark`: how far down the code its run of lines starts. Do not set it.",
30585
+ "name": "--code-block-mark-start"
30586
+ }
30587
+ ],
30201
30588
  "cssParts": [
30589
+ {
30590
+ "description": "The box in the header that holds the `actions` slot, drawn while something is slotted there.",
30591
+ "name": "actions"
30592
+ },
30202
30593
  {
30203
30594
  "description": "In a diff, a line only the new version has, an `<ins>`.",
30204
30595
  "name": "added"
@@ -30311,6 +30702,10 @@
30311
30702
  "description": "The block's name: its `label`, or its `language` where it has no label.",
30312
30703
  "name": "label"
30313
30704
  },
30705
+ {
30706
+ "description": "The band behind a run of lines `mark-lines` names. The block writes where the run is laid out into `--code-block-mark-start`, `--code-block-mark-size`, and `--code-block-mark-inline-size` on it. Hidden from the accessibility tree.",
30707
+ "name": "mark"
30708
+ },
30314
30709
  {
30315
30710
  "description": "In a diff, the `+`, `-`, or space that starts a line.",
30316
30711
  "name": "marker"
@@ -30320,7 +30715,7 @@
30320
30715
  "name": "new"
30321
30716
  },
30322
30717
  {
30323
- "description": "In a diff, a line number.",
30718
+ "description": "In a diff, a line number. In a `wrap` block with `line-numbers`, one line's number in the gutter, which the block makes as tall as the line it numbers through `--code-block-line-size`.",
30324
30719
  "name": "number"
30325
30720
  },
30326
30721
  {
@@ -30338,12 +30733,28 @@
30338
30733
  {
30339
30734
  "description": "In a diff, a line's code.",
30340
30735
  "name": "text"
30736
+ },
30737
+ {
30738
+ "description": "The button in the header that wraps the lines and unwraps them, drawn when `wrappable` is set.",
30739
+ "name": "wrap-toggle"
30341
30740
  }
30342
30741
  ],
30343
30742
  "slots": [
30344
30743
  {
30345
30744
  "description": "The code.",
30346
30745
  "name": ""
30746
+ },
30747
+ {
30748
+ "description": "Controls for the block, in the header before the copy button.",
30749
+ "name": "actions"
30750
+ },
30751
+ {
30752
+ "description": "The copy button's icon after a copy. Defaults to a check mark.",
30753
+ "name": "copied-icon"
30754
+ },
30755
+ {
30756
+ "description": "The copy button's icon before a copy. Defaults to a clipboard.",
30757
+ "name": "copy-icon"
30347
30758
  }
30348
30759
  ],
30349
30760
  "members": [
@@ -30508,6 +30919,16 @@
30508
30919
  "attribute": "line-numbers",
30509
30920
  "reflects": true
30510
30921
  },
30922
+ {
30923
+ "kind": "field",
30924
+ "name": "markLines",
30925
+ "type": {
30926
+ "text": "string"
30927
+ },
30928
+ "default": "''",
30929
+ "description": "The lines to mark, as numbers and ranges counted from 1, such as `2, 4-6`.\nEach run is drawn as a band behind its lines. Not for a diff, which marks\nits own changes.",
30930
+ "attribute": "mark-lines"
30931
+ },
30511
30932
  {
30512
30933
  "kind": "field",
30513
30934
  "name": "noCopy",
@@ -30529,6 +30950,51 @@
30529
30950
  "attribute": "variant",
30530
30951
  "reflects": true
30531
30952
  },
30953
+ {
30954
+ "kind": "field",
30955
+ "name": "wrap",
30956
+ "type": {
30957
+ "text": "boolean"
30958
+ },
30959
+ "default": "false",
30960
+ "description": "Whether long lines wrap. Without it they scroll.\n\nOff by default, so long lines scroll, because a line break can be\nsignificant in code and a wrapped line reads as two. For prose-like code,\nsuch as a long command or a log line, a wrap reads better than a scroll.\nWith `line-numbers`, each number stands beside the line it numbers\nhowever many rows that line takes. Reflected, because the stylesheet\nwraps the lines.",
30961
+ "attribute": "wrap",
30962
+ "reflects": true
30963
+ },
30964
+ {
30965
+ "kind": "field",
30966
+ "name": "wrapLabel",
30967
+ "type": {
30968
+ "text": "string"
30969
+ },
30970
+ "default": "'Wrap lines'",
30971
+ "description": "The wrap button's name, which it keeps whether it is pressed or not.",
30972
+ "attribute": "wrap-label",
30973
+ "helix": {
30974
+ "words": true
30975
+ }
30976
+ },
30977
+ {
30978
+ "kind": "field",
30979
+ "name": "wrappable",
30980
+ "type": {
30981
+ "text": "boolean"
30982
+ },
30983
+ "default": "false",
30984
+ "description": "Whether the header has a button that wraps the lines and unwraps them. The\nblock draws a header for it even with no name.",
30985
+ "attribute": "wrappable"
30986
+ },
30987
+ {
30988
+ "kind": "method",
30989
+ "name": "toggleWrap",
30990
+ "privacy": "private",
30991
+ "return": {
30992
+ "type": {
30993
+ "text": "void"
30994
+ }
30995
+ },
30996
+ "description": "Asks to wrap or unwrap the lines, and says so once it has."
30997
+ },
30532
30998
  {
30533
30999
  "kind": "field",
30534
31000
  "name": "parsed",
@@ -30615,6 +31081,36 @@
30615
31081
  },
30616
31082
  "description": "Makes each box that scrolls a tab stop and a region named for its block,\nand takes both away from a box that fits.\n\n**A reader on a keyboard scrolls the code from the box itself.** Chromium\nand Firefox make a scrolling box focusable on their own, and Safari does\nnot, so there the arrow keys could not reach the end of a long line. A\nbox counts while its sheet lets it scroll and its content is wider or\ntaller than it is drawn: an unstyled `<pre>` overflows without scrolling,\nand a stop on it would scroll nothing."
30617
31083
  },
31084
+ {
31085
+ "kind": "method",
31086
+ "name": "lineBoxes",
31087
+ "privacy": "private",
31088
+ "return": {
31089
+ "type": {
31090
+ "text": "Array<{ bottom: number; top: number }>"
31091
+ }
31092
+ },
31093
+ "parameters": [
31094
+ {
31095
+ "name": "code",
31096
+ "type": {
31097
+ "text": "HTMLElement"
31098
+ }
31099
+ }
31100
+ ],
31101
+ "description": "Where each line of the code is laid out in the `<code>`, from the top of\nits content, as the browser placed the text: one row, or several where it\nwraps."
31102
+ },
31103
+ {
31104
+ "kind": "method",
31105
+ "name": "placeLines",
31106
+ "privacy": "private",
31107
+ "return": {
31108
+ "type": {
31109
+ "text": "void"
31110
+ }
31111
+ },
31112
+ "description": "Places each mark behind its run of lines, and makes each number in a\nwrapping gutter as tall as its line, from where the lines are laid out.\n\n**Written onto the elements as custom properties**, which are facts the\nblock computed and CSS cannot, and no render follows from them."
31113
+ },
30618
31114
  {
30619
31115
  "kind": "method",
30620
31116
  "name": "renderExpand",
@@ -30626,6 +31122,25 @@
30626
31122
  },
30627
31123
  "description": "The button that shows every line of a capped block, and fewer again, or\nnothing while the cap hides nothing. Not on a server, which cannot\nmeasure, so a served block draws none and the client adds it."
30628
31124
  },
31125
+ {
31126
+ "kind": "method",
31127
+ "name": "headed",
31128
+ "privacy": "private",
31129
+ "return": {
31130
+ "type": {
31131
+ "text": "boolean"
31132
+ }
31133
+ },
31134
+ "parameters": [
31135
+ {
31136
+ "name": "name",
31137
+ "type": {
31138
+ "text": "string"
31139
+ }
31140
+ }
31141
+ ],
31142
+ "description": "Whether the block draws a header: it has a name, a wrap button, or a control in `actions`."
31143
+ },
30629
31144
  {
30630
31145
  "kind": "method",
30631
31146
  "name": "renderHeader",
@@ -30650,7 +31165,37 @@
30650
31165
  }
30651
31166
  }
30652
31167
  ],
30653
- "description": "The name with the copy button beside it, or nothing when there is no name.\n\n**The button is in the header wherever there is one**, because beside the\ncode it stands over the block and the block has to make room for it. A\ndiff cannot: its washes run to the edge, so the button stood on the hunk\nline and the line under it. In the header it is over nothing.\n\n**No name draws no header**, rather than a bar to hold one button, which\nturned a `Usage` section of one-line imports into a run of empty strips.\nThe button then stands beside the code, in room the block keeps for it."
31168
+ "description": "The name with the copy button beside it, or nothing when there is no name.\n\n**The button is in the header wherever there is one**, because beside the\ncode it stands over the block and the block has to make room for it. A\ndiff cannot: its washes run to the edge, so the button stood on the hunk\nline and the line under it. In the header it is over nothing.\n\n**No name draws no header**, unless the page put a control in `actions`\nor asked for the wrap button. A bar holding the copy button alone turned a\n`Usage` section of one-line imports into a run of empty strips. The button\nthen stands beside the code, in room the block keeps for it."
31169
+ },
31170
+ {
31171
+ "kind": "method",
31172
+ "name": "renderWrapToggle",
31173
+ "privacy": "private",
31174
+ "return": {
31175
+ "type": {
31176
+ "text": "TemplateResult | typeof nothing"
31177
+ }
31178
+ },
31179
+ "description": "The button that wraps the lines and unwraps them, where `wrappable` asks for one. Not for a diff."
31180
+ },
31181
+ {
31182
+ "kind": "method",
31183
+ "name": "slotted",
31184
+ "privacy": "private",
31185
+ "return": {
31186
+ "type": {
31187
+ "text": "boolean"
31188
+ }
31189
+ },
31190
+ "parameters": [
31191
+ {
31192
+ "name": "name",
31193
+ "type": {
31194
+ "text": "string"
31195
+ }
31196
+ }
31197
+ ],
31198
+ "description": "Whether the page slotted something into `name`. Not known on a server or\nwhile hydrating what one sent, which render as though nothing were."
30654
31199
  },
30655
31200
  {
30656
31201
  "kind": "method",
@@ -30704,6 +31249,17 @@
30704
31249
  ],
30705
31250
  "description": "The button that takes the code, behind a seam the styled tier can move.\n\nA method rather than a fragment inline, so a tier above can render its own\ncopy control, wrap this one, or pass it something the base does not know\nabout, without reimplementing the whole template to do it. The tag is\ninterpolated rather than written, so `tier` resolves it: this renders the\nbase button, and a styled subclass that sets `tier` renders the styled one\nfrom the same template."
30706
31251
  },
31252
+ {
31253
+ "kind": "method",
31254
+ "name": "renderCopyIcons",
31255
+ "privacy": "private",
31256
+ "return": {
31257
+ "type": {
31258
+ "text": "TemplateResult"
31259
+ }
31260
+ },
31261
+ "description": "The page's own icons for the copy button, passed on through slots of the\nblock's, where the page slotted them. A slot passed on with nothing in it\nwould stand in for the button's own icon and draw nothing, so it is drawn\nonly for an icon the page gave. In a diff, the first file's button takes\nthem, a slotted element going to one slot."
31262
+ },
30707
31263
  {
30708
31264
  "kind": "method",
30709
31265
  "name": "renderNumber",
@@ -31166,6 +31722,24 @@
31166
31722
  }
31167
31723
  }
31168
31724
  ],
31725
+ "events": [
31726
+ {
31727
+ "type": {
31728
+ "text": "HelixBeforeToggleEvent"
31729
+ },
31730
+ "description": "The wrap button was pressed, with the `wrap` it asks for in `detail.checked`. Cancelable: cancel it to keep the lines as they are.",
31731
+ "name": "helix-before-toggle",
31732
+ "reactProp": "onhelix-before-toggle"
31733
+ },
31734
+ {
31735
+ "type": {
31736
+ "text": "HelixToggleEvent"
31737
+ },
31738
+ "description": "Fired after the wrap button changed `wrap`, with the new value in `detail.checked`.",
31739
+ "name": "helix-toggle",
31740
+ "reactProp": "onhelix-toggle"
31741
+ }
31742
+ ],
31169
31743
  "attributes": [
31170
31744
  {
31171
31745
  "name": "code-label",
@@ -31275,6 +31849,15 @@
31275
31849
  "description": "Whether the lines are numbered in a gutter beside the code.\n\nThe numbers are hidden from the accessibility tree and are not part of a\ncopy, which takes the code alone. Reflected, because the stylesheet lays\nthe gutter out beside the code. A diff numbers its lines from its hunks\nwhether or not this is set.",
31276
31850
  "fieldName": "lineNumbers"
31277
31851
  },
31852
+ {
31853
+ "name": "mark-lines",
31854
+ "type": {
31855
+ "text": "string"
31856
+ },
31857
+ "default": "''",
31858
+ "description": "The lines to mark, as numbers and ranges counted from 1, such as `2, 4-6`.\nEach run is drawn as a band behind its lines. Not for a diff, which marks\nits own changes.",
31859
+ "fieldName": "markLines"
31860
+ },
31278
31861
  {
31279
31862
  "name": "no-copy",
31280
31863
  "type": {
@@ -31291,6 +31874,33 @@
31291
31874
  },
31292
31875
  "description": "How a diff's two versions are arranged. It has no effect without `diff`.\n\nAbsent is unified, each removal above its replacement, which fits any\nwidth. `split` sets the old version beside the new one. Optional rather\nthan defaulted, so the host carries no attribute the consumer did not write.",
31293
31876
  "fieldName": "variant"
31877
+ },
31878
+ {
31879
+ "name": "wrap",
31880
+ "type": {
31881
+ "text": "boolean"
31882
+ },
31883
+ "default": "false",
31884
+ "description": "Whether long lines wrap. Without it they scroll.\n\nOff by default, so long lines scroll, because a line break can be\nsignificant in code and a wrapped line reads as two. For prose-like code,\nsuch as a long command or a log line, a wrap reads better than a scroll.\nWith `line-numbers`, each number stands beside the line it numbers\nhowever many rows that line takes. Reflected, because the stylesheet\nwraps the lines.",
31885
+ "fieldName": "wrap"
31886
+ },
31887
+ {
31888
+ "name": "wrap-label",
31889
+ "type": {
31890
+ "text": "string"
31891
+ },
31892
+ "default": "'Wrap lines'",
31893
+ "description": "The wrap button's name, which it keeps whether it is pressed or not.",
31894
+ "fieldName": "wrapLabel"
31895
+ },
31896
+ {
31897
+ "name": "wrappable",
31898
+ "type": {
31899
+ "text": "boolean"
31900
+ },
31901
+ "default": "false",
31902
+ "description": "Whether the header has a button that wraps the lines and unwraps them. The\nblock draws a header for it even with no name.",
31903
+ "fieldName": "wrappable"
31294
31904
  }
31295
31905
  ],
31296
31906
  "cssStates": [
@@ -73962,15 +74572,22 @@
73962
74572
  "type": {
73963
74573
  "text": "string"
73964
74574
  }
74575
+ },
74576
+ {
74577
+ "name": "cause",
74578
+ "optional": true,
74579
+ "type": {
74580
+ "text": "string"
74581
+ }
73965
74582
  }
73966
74583
  ],
73967
- "description": "Requests a new current item, and returns whether the change was applied.\n\nAnnounces before it acts, so `preventDefault()` on the `helix-before-activate` is\na refusal and nothing moves. Unlike a native control, nothing has moved\nby the time this runs, so refusing is simply not writing: there is\nnothing to put back. Nobody refusing means the set updates itself,\nwhether or not a consumer declared `active`, a declared property being a\nseed and a correction.",
74584
+ "description": "Requests a new current item, and returns whether the change was applied.\n\nAnnounces before it acts, so `preventDefault()` on the `helix-before-activate` is\na refusal and nothing moves. Unlike a native control, nothing has moved\nby the time this runs, so refusing is simply not writing: there is\nnothing to put back. Nobody refusing means the set updates itself,\nwhether or not a consumer declared `active`, a declared property being a\nseed and a correction. `cause` says why, where the family names its\ncauses, and reaches the event as `detail.cause`.",
73968
74585
  "inheritedFrom": {
73969
74586
  "name": "MixinControllerActive",
73970
74587
  "module": "src/mixins/mixin-controller-active/mixin-controller-active.ts"
73971
74588
  },
73972
74589
  "type": {
73973
- "text": "requestActive(next: string) => boolean"
74590
+ "text": "requestActive(next: string, cause?: string) => boolean"
73974
74591
  }
73975
74592
  },
73976
74593
  {
@@ -86449,15 +87066,22 @@
86449
87066
  "type": {
86450
87067
  "text": "string"
86451
87068
  }
87069
+ },
87070
+ {
87071
+ "name": "cause",
87072
+ "optional": true,
87073
+ "type": {
87074
+ "text": "string"
87075
+ }
86452
87076
  }
86453
87077
  ],
86454
- "description": "Requests a new current item, and returns whether the change was applied.\n\nAnnounces before it acts, so `preventDefault()` on the `helix-before-activate` is\na refusal and nothing moves. Unlike a native control, nothing has moved\nby the time this runs, so refusing is simply not writing: there is\nnothing to put back. Nobody refusing means the set updates itself,\nwhether or not a consumer declared `active`, a declared property being a\nseed and a correction.",
87078
+ "description": "Requests a new current item, and returns whether the change was applied.\n\nAnnounces before it acts, so `preventDefault()` on the `helix-before-activate` is\na refusal and nothing moves. Unlike a native control, nothing has moved\nby the time this runs, so refusing is simply not writing: there is\nnothing to put back. Nobody refusing means the set updates itself,\nwhether or not a consumer declared `active`, a declared property being a\nseed and a correction. `cause` says why, where the family names its\ncauses, and reaches the event as `detail.cause`.",
86455
87079
  "inheritedFrom": {
86456
87080
  "name": "MixinControllerActive",
86457
87081
  "module": "src/mixins/mixin-controller-active/mixin-controller-active.ts"
86458
87082
  },
86459
87083
  "type": {
86460
- "text": "requestActive(next: string) => boolean"
87084
+ "text": "requestActive(next: string, cause?: string) => boolean"
86461
87085
  }
86462
87086
  },
86463
87087
  {
@@ -146587,6 +147211,19 @@
146587
147211
  "words": true
146588
147212
  }
146589
147213
  },
147214
+ {
147215
+ "kind": "field",
147216
+ "name": "cornerValueLabel",
147217
+ "type": {
147218
+ "text": "string"
147219
+ },
147220
+ "default": "'{across} across, {down} down'",
147221
+ "description": "What the handle where two dividers cross says it is set to, both dividers\nat once: `{across}` is where the divider that runs down stands, and\n`{down}` where the one that runs across stands, each a percentage.\n\n**Both, because the handle moves both**, and a number names one: the\nhandle's `aria-valuenow` is the divider its `aria-orientation` names, and\nthese words are the whole of where it is.",
147222
+ "attribute": "corner-value-label",
147223
+ "helix": {
147224
+ "words": true
147225
+ }
147226
+ },
146590
147227
  {
146591
147228
  "kind": "field",
146592
147229
  "name": "defaultCollapsed",
@@ -147080,6 +147717,31 @@
147080
147717
  },
147081
147718
  "description": "Starts or stops watching, according to what the axis was asked to be.\n\nCalled from `firstUpdated` and from `updated`, so a consumer switching to\n`auto` after mount is observed and one switching away stops being: an\nobserver left running would keep writing `stacked` that nothing reads, and\na splitter told `horizontal` has been given its answer already."
147082
147719
  },
147720
+ {
147721
+ "kind": "method",
147722
+ "name": "cornerWords",
147723
+ "privacy": "private",
147724
+ "return": {
147725
+ "type": {
147726
+ "text": "string"
147727
+ }
147728
+ },
147729
+ "parameters": [
147730
+ {
147731
+ "name": "own",
147732
+ "type": {
147733
+ "text": "number"
147734
+ }
147735
+ },
147736
+ {
147737
+ "name": "theirs",
147738
+ "type": {
147739
+ "text": "number"
147740
+ }
147741
+ }
147742
+ ],
147743
+ "description": "Where a crossing stands in words: this splitter's divider at `own` and the\nnested one's at `theirs`, as `corner-value-label` puts them."
147744
+ },
147083
147745
  {
147084
147746
  "kind": "field",
147085
147747
  "name": "vertical",
@@ -147705,6 +148367,15 @@
147705
148367
  "description": "The name of the handle where two dividers cross, read by screen readers.",
147706
148368
  "fieldName": "cornerLabel"
147707
148369
  },
148370
+ {
148371
+ "name": "corner-value-label",
148372
+ "type": {
148373
+ "text": "string"
148374
+ },
148375
+ "default": "'{across} across, {down} down'",
148376
+ "description": "What the handle where two dividers cross says it is set to, both dividers\nat once: `{across}` is where the divider that runs down stands, and\n`{down}` where the one that runs across stands, each a percentage.\n\n**Both, because the handle moves both**, and a number names one: the\nhandle's `aria-valuenow` is the divider its `aria-orientation` names, and\nthese words are the whole of where it is.",
148377
+ "fieldName": "cornerValueLabel"
148378
+ },
147708
148379
  {
147709
148380
  "name": "default-collapsed",
147710
148381
  "type": {
@@ -149415,15 +150086,22 @@
149415
150086
  "type": {
149416
150087
  "text": "string"
149417
150088
  }
150089
+ },
150090
+ {
150091
+ "name": "cause",
150092
+ "optional": true,
150093
+ "type": {
150094
+ "text": "string"
150095
+ }
149418
150096
  }
149419
150097
  ],
149420
- "description": "Requests a new current item, and returns whether the change was applied.\n\nAnnounces before it acts, so `preventDefault()` on the `helix-before-activate` is\na refusal and nothing moves. Unlike a native control, nothing has moved\nby the time this runs, so refusing is simply not writing: there is\nnothing to put back. Nobody refusing means the set updates itself,\nwhether or not a consumer declared `active`, a declared property being a\nseed and a correction.",
150098
+ "description": "Requests a new current item, and returns whether the change was applied.\n\nAnnounces before it acts, so `preventDefault()` on the `helix-before-activate` is\na refusal and nothing moves. Unlike a native control, nothing has moved\nby the time this runs, so refusing is simply not writing: there is\nnothing to put back. Nobody refusing means the set updates itself,\nwhether or not a consumer declared `active`, a declared property being a\nseed and a correction. `cause` says why, where the family names its\ncauses, and reaches the event as `detail.cause`.",
149421
150099
  "inheritedFrom": {
149422
150100
  "name": "MixinControllerActive",
149423
150101
  "module": "src/mixins/mixin-controller-active/mixin-controller-active.ts"
149424
150102
  },
149425
150103
  "type": {
149426
- "text": "requestActive(next: string) => boolean"
150104
+ "text": "requestActive(next: string, cause?: string) => boolean"
149427
150105
  }
149428
150106
  },
149429
150107
  {
@@ -154256,7 +154934,7 @@
154256
154934
  "declarations": [
154257
154935
  {
154258
154936
  "kind": "class",
154259
- "description": "Lays out the rows on a CSS grid, so every column lines up across rows and\neach row stays a real element that can be styled, hidden, or made\ninteractive. A `<table>` layout aligns columns but limits almost everything\nelse.\n\nA grid of elements has no table structure for assistive technology, so the\nroles are set explicitly: `table`, `row`, `cell`, `columnheader`, and\n`rowheader` for a `header` cell in a row of values. Rows are\n`display: contents`, so their cells become items of the one grid.\n\n**Sorting.** A column with `sortable` and a `field` draws its heading as a\nbutton that sorts the rows by the text of its cells, numbers by their value.\nYour markup is not reordered: the table draws the rows in the sorted order.\n\n1. Each press cycles the column through ascending, descending, and the\n order the rows were written in, which keeps a server's own ranking\n reachable.\n2. `helix-sort` asks first, with `field:direction`, or empty for the written\n order. Refuse it to keep the order, or to sort the rows yourself and set\n `sort`.\n3. `helix-sorted` follows once the order stands, and `sort` holds it.\n4. The heading carries `aria-sort`, and a screen reader hears `sorted-label`\n (\"Sorted by Name, ascending\") or `unsorted-label` from a polite region.\n\nTab reaches each sort button, and Enter or Space presses it.\n\nThe `heading` slot names the table: slot a heading or a line of text into\nit, and the table is named by its words. An `aria-label` or `aria-labelledby` on the\nhost wins over it.\n\n**Selecting.** `selectable` adds a column of checkboxes.\n\n1. Each row is known by its `value`, or by its place among the rows where it\n has none, and `selected` holds the chosen keys, comma separated, the same\n shape `DataTable` uses. `default-selected` is where it starts.\n2. A row's checkbox is named by `select-row-label` (\"Select {row}\") with the\n words of the row's first cell. The checkbox in the heading selects every\n row, and shows a dash while only some are chosen.\n3. `helix-select` asks first, with every key the change would leave.\n Refuse it to keep the selection. `helix-selected` follows once it stands.\n4. A chosen row takes `:state(selected)`, and a screen reader hears\n `selected-label` (\"2 selected\") from a polite region.\n\nTab reaches each checkbox, and Space ticks it. To act on one row, put a\nlink or a button in a cell, or give the row an `href`.\n\n**Moving rows.** `reorderable` adds a column of grips before the checkboxes,\nunder a heading named by `row-grips-label`.\n\n1. Each row is known by its `value`, or by its place among the rows where it\n has none, as for selecting. Give rows a `value` when they move, so a key\n stays with its row.\n2. A grip is a button named by `move-row-label` (\"Move {row}\") with the\n words of the row's first cell. Drag it to move its row, and the page\n scrolls near an edge. Or press it with Space, Enter, or a click to pick\n the row up, move it with Up, Down, Home, and End, and press it again to\n drop it. A click on another row drops it there, and Escape puts it back.\n3. `helix-before-reorder` asks first, and `helix-reorder` follows with\n `keys`, every row's key in the new order. **You move the rows**: the\n table moves no element of yours, and focus goes back to the moved row's\n grip once you have.\n4. Each step is said in the table's live region, in words you can change:\n `picked-up-label`, `moved-label`, `dropped-label`, and `canceled-label`.\n The grips do nothing while a sort is set.\n\n**A grid.** `grid` makes the table one tab stop that the arrow keys move\nthrough cell by cell, the headings included, as React Aria's table is. The\ntable is then a `grid` and each value a `gridcell`, and the table gives\nevery cell a `tabindex` so focus can rest on it: set `grid` only where the\ncells may carry one.\n\n| Key | What it does |\n|---|---|\n| Right, Left | Moves one cell along the row. Left moves on, on a right-to-left page. |\n| Down, Up | Moves one row, the headings included. |\n| Home, End | Moves to the first or the last cell of the row. |\n| Control with Home or End | Moves to the first or the last cell of the table. |\n| Page Down, Page Up | Moves by the rows that fit in view. |\n| Enter, F2 | Moves into the cell's links and controls. Escape or F2 moves back to the cell, and Tab moves between the controls of one cell. |\n| Enter on a cell of a row with `href` | Follows the row's link. |\n| Enter, Space on a sortable heading | Sorts by the column. |\n| Space on a row, Enter or Space on its checkbox cell | Selects the row, in a `selectable` table. |\n| Enter or Space on a grip cell | Picks the row up, or drops it, in a `reorderable` table. Up, Down, Home, and End move a row picked up, and Escape puts it back. |\n| Shift with Down or Up | Selects the rows it moves across, in a `selectable` table. |\n| Shift with Space | Selects every row from the one last chosen, in a `selectable` table. |\n| Control or Command with A | Selects every row, in a `selectable` table. |\n| A letter or a word | Moves to the next row whose first cell starts with what you typed. |\n| Tab | Leaves the table. |\n\nWhen the rows did not load, set `error-text`, such as \"The orders did not\nload\", and put a button that tries again in the `error` slot. The line shows\nafter the rows in place of the empty and loading lines, the live region says\nit, and the table takes the `error` state. Clear it once you try again.\n\nThe CSS custom properties listed for this component are written by it and\nread by the stylesheet that draws it. Do not set them. Each holds a number\nthe component computes and CSS cannot, so the stylesheet can draw the table\nwithout measuring anything.",
154937
+ "description": "Lays out the rows on a CSS grid, so every column lines up across rows and\neach row stays a real element that can be styled, hidden, or made\ninteractive. A `<table>` layout aligns columns but limits almost everything\nelse.\n\nA grid of elements has no table structure for assistive technology, so the\nroles are set explicitly: `table`, `row`, `cell`, `columnheader`, and\n`rowheader` for a `header` cell in a row of values. Rows are\n`display: contents`, so their cells become items of the one grid.\n\n**Sorting.** A column with `sortable` and a `field` draws its heading as a\nbutton that sorts the rows by the text of its cells, numbers by their value.\nYour markup is not reordered: the table draws the rows in the sorted order.\n\n1. Each press cycles the column through ascending, descending, and the\n order the rows were written in, which keeps a server's own ranking\n reachable.\n2. `helix-sort` asks first, with `field:direction`, or empty for the written\n order. Refuse it to keep the order, or to sort the rows yourself and set\n `sort`.\n3. `helix-sorted` follows once the order stands, and `sort` holds it.\n4. The heading carries `aria-sort`, and a screen reader hears `sorted-label`\n (\"Sorted by Name, ascending\") or `unsorted-label` from a polite region.\n\nTab reaches each sort button, and Enter or Space presses it.\n\nThe `heading` slot names the table: slot a heading or a line of text into\nit, and the table is named by its words. An `aria-label` or `aria-labelledby` on the\nhost wins over it.\n\n**Selecting.** `selectable` adds a column of checkboxes.\n\n1. Each row is known by its `value`, or by its place among the rows where it\n has none, and `selected` holds the chosen keys, comma separated, the same\n shape `DataTable` uses. `default-selected` is where it starts.\n2. A row's checkbox is named by `select-row-label` (\"Select {row}\") with the\n words of the row's first cell. The checkbox in the heading selects every\n row, and shows a dash while only some are chosen.\n3. `helix-select` asks first, with every key the change would leave.\n Refuse it to keep the selection. `helix-selected` follows once it stands.\n4. A chosen row takes `:state(selected)`, and a screen reader hears\n `selected-label` (\"2 selected\") from a polite region.\n\nTab reaches each checkbox, and Space ticks it. To act on one row, put a\nlink or a button in a cell, or give the row an `href`.\n\n`selection-mode=\"single\"` selects one row at a time: ticking a row lets go\nof the one before, the heading holds no checkbox, and Shift and Control with\nA take in nothing more. `selection-behavior=\"replace\"` makes a press on a\nrow, anywhere but its own controls, select it alone, as a file list does,\nand in a `grid` table the arrow keys carry the selection with them. Control\nor Command with a press adds or takes out the row, and with an arrow moves\nwithout selecting. Shift with a press takes in the rows from the one last\nchosen.\n\n**Nesting rows.** A row with `parent` sits under the row of that key, as\na file sits in a folder. The table then draws a column of disclosure\nbuttons, under a heading named by `expand-column-label`: a row with rows\nunder it has a button named by `expand-row-label` (\"Expand {row}\") that\nsays with `aria-expanded` whether it is open, and the rows under a shut row\nare not drawn. `expanded` holds the open rows' keys, comma separated, and\n`default-expanded` is where it starts. A press asks with\n`helix-before-toggle` and tells with `helix-toggle`, both from the row, so\nyou can refuse it or load the rows on the way. A sort orders the rows\nunder each row among themselves, and in a `grid` table the table is a\n`treegrid` whose rows say their depth.\n\n**Moving rows.** `reorderable` adds a column of grips before the checkboxes,\nunder a heading named by `row-grips-label`.\n\n1. Each row is known by its `value`, or by its place among the rows where it\n has none, as for selecting. Give rows a `value` when they move, so a key\n stays with its row.\n2. A grip is a button named by `move-row-label` (\"Move {row}\") with the\n words of the row's first cell. Drag it to move its row, and the page\n scrolls near an edge. Or press it with Space, Enter, or a click to pick\n the row up, move it with Up, Down, Home, and End, and press it again to\n drop it. A click on another row drops it there, and Escape puts it back.\n3. `helix-before-reorder` asks first, and `helix-reorder` follows with\n `keys`, every row's key in the new order. **You move the rows**: the\n table moves no element of yours, and focus goes back to the moved row's\n grip once you have.\n4. Each step is said in the table's live region, in words you can change:\n `picked-up-label`, `moved-label`, `dropped-label`, and `canceled-label`.\n The grips do nothing while a sort is set.\n\n**A grid.** `grid` makes the table one tab stop that the arrow keys move\nthrough cell by cell, the headings included, as React Aria's table is. The\ntable is then a `grid` and each value a `gridcell`, and the table gives\nevery cell a `tabindex` so focus can rest on it: set `grid` only where the\ncells may carry one.\n\n| Key | What it does |\n|---|---|\n| Right, Left | Moves one cell along the row. Left moves on, on a right-to-left page. |\n| Down, Up | Moves one row, the headings included. |\n| Home, End | Moves to the first or the last cell of the row. |\n| Control with Home or End | Moves to the first or the last cell of the table. |\n| Page Down, Page Up | Moves by the rows that fit in view. |\n| Enter, F2 | Moves into the cell's links and controls. Escape or F2 moves back to the cell, and Tab moves between the controls of one cell. |\n| Enter on a cell of a row with `href` | Follows the row's link. |\n| Enter, Space on a sortable heading | Sorts by the column. |\n| Space on a row, Enter or Space on its checkbox cell | Selects the row, in a `selectable` table. |\n| Enter or Space on a disclosure cell | Shows or hides the rows under the row, in a table whose rows nest. |\n| Enter or Space on a grip cell | Picks the row up, or drops it, in a `reorderable` table. Up, Down, Home, and End move a row picked up, and Escape puts it back. |\n| Down, Up, Page Down, Page Up under `selection-behavior=\"replace\"` | Selects the row it moves to alone. Control or Command with the key moves without selecting. |\n| Shift with Down or Up | Selects the rows it moves across, in a `selectable` table. |\n| Shift with Space | Selects every row from the one last chosen, in a `selectable` table. |\n| Control or Command with A | Selects every row, in a `selectable` table. |\n| A letter or a word | Moves to the next row whose first cell starts with what you typed. |\n| Tab | Leaves the table. |\n\n**Loading more.** `load-more` sends `helix-load-more` once the end of the\ntable comes within a screen of view, in the box that scrolls it or the\npage, once for each number of rows: add rows and it can send it again. Set\n`loading` while you fetch, and the table asks for nothing until it clears.\n\nWhen the rows did not load, set `error-text`, such as \"The orders did not\nload\", and put a button that tries again in the `error` slot. The line shows\nafter the rows in place of the empty and loading lines, the live region says\nit, and the table takes the `error` state. Clear it once you try again.\n\nThe CSS custom properties listed for this component are written by it and\nread by the stylesheet that draws it. Do not set them. Each holds a number\nthe component computes and CSS cannot, so the stylesheet can draw the table\nwithout measuring anything.",
154260
154938
  "name": "HelixHeadlessTable",
154261
154939
  "cssProperties": [
154262
154940
  {
@@ -154321,6 +154999,10 @@
154321
154999
  "description": "The line shown after the rows while `error-text` is set, in place of the empty and loading text.",
154322
155000
  "name": "error"
154323
155001
  },
155002
+ {
155003
+ "description": "The heading over the disclosure buttons, in a table whose rows nest.",
155004
+ "name": "expand-head"
155005
+ },
154324
155006
  {
154325
155007
  "description": "An empty box after the rows, in a `grid` table. Tab focuses it on its way out of the table, so the key leaves from the end.",
154326
155008
  "name": "grid-end"
@@ -154441,6 +155123,16 @@
154441
155123
  "description": "The column widths as one track list, written once on the table.\n\nWith `TableColumn` children, each track sizes the column in its place, a\nhidden column counted, so hiding one takes its track with it and the rest\nkeep theirs. The columns decide how many tracks there are and this list\nonly how wide: a track past the last column is dropped, and a column past\nthe last track shares what is left. With no columns declared it is the\nwhole track list. Tracks count as the grid counts them, so `minmax(0, 1fr)`\nis one and `repeat(2, 8rem)` is two, and one the grid would refuse leaves\nits column at the default rather than taking the table down to one column.\n\n**A column's own `width` wins over its track here.** The width is written\non the column it sizes, which is the more particular statement, and it is\nwhere a resize lands: a reader dragging a column's edge writes `width`, so\nwere this list to win, the drag would move the separator and leave the\ntrack where the list put it. This is the table's default for its columns,\nand each column may say otherwise.\n\n**It is also the only track list a server can send.** The shim has no tree\nto walk, so a render there knows of no columns and this attribute is the\nwhole answer: a table given one lays its grid out in the first paint, and a\ntable sized only by its columns is one track wide until it upgrades.\n\n**Data Table has none of this, and should not.** Its columns are its schema\nrather than an option, so there is always a column to write a `width` on\nand a list here would be a second way to say what that says. This table's\ncells are markup, and a table written as rows of cells with no column\ndeclared in it has nowhere else to be sized from.",
154442
155124
  "attribute": "columns"
154443
155125
  },
155126
+ {
155127
+ "kind": "field",
155128
+ "name": "defaultExpanded",
155129
+ "type": {
155130
+ "text": "string"
155131
+ },
155132
+ "default": "''",
155133
+ "description": "The keys of the rows whose rows are shown at the start, separated by\ncommas. Used until `expanded` is set.",
155134
+ "attribute": "default-expanded"
155135
+ },
154444
155136
  {
154445
155137
  "kind": "field",
154446
155138
  "name": "defaultSelected",
@@ -154497,6 +155189,41 @@
154497
155189
  "description": "The text shown and announced when the rows could not load. Set it when a\nfetch fails, and clear it once you try again. Empty, the default, shows\nnothing.\n\nWhile it is set, a line after the rows shows it, or your own content in the\n`error` slot, in place of the empty and loading lines, and the live region\nsays it.",
154498
155190
  "attribute": "error-text"
154499
155191
  },
155192
+ {
155193
+ "kind": "field",
155194
+ "name": "expandColumnLabel",
155195
+ "type": {
155196
+ "text": "string"
155197
+ },
155198
+ "default": "'Expand'",
155199
+ "description": "The name of the heading over the disclosure buttons.",
155200
+ "attribute": "expand-column-label",
155201
+ "helix": {
155202
+ "words": true
155203
+ }
155204
+ },
155205
+ {
155206
+ "kind": "field",
155207
+ "name": "expanded",
155208
+ "type": {
155209
+ "text": "string"
155210
+ },
155211
+ "description": "The keys of the rows whose rows are shown, separated by commas, in a table\nwhose rows nest. A press on a row's disclosure button asks first, and\n`default-expanded` seeds what this element then owns.",
155212
+ "attribute": "expanded"
155213
+ },
155214
+ {
155215
+ "kind": "field",
155216
+ "name": "expandRowLabel",
155217
+ "type": {
155218
+ "text": "string"
155219
+ },
155220
+ "default": "'Expand {row}'",
155221
+ "description": "The name of a row's disclosure button. `{row}` is the words of the row's first cell.",
155222
+ "attribute": "expand-row-label",
155223
+ "helix": {
155224
+ "words": true
155225
+ }
155226
+ },
154500
155227
  {
154501
155228
  "kind": "field",
154502
155229
  "name": "fallbackLabel",
@@ -154530,6 +155257,16 @@
154530
155257
  "description": "Accessible name for the table.\n\nAn `aria-label` or `aria-labelledby` on the host names the table too, and\nwins over this.",
154531
155258
  "attribute": "label"
154532
155259
  },
155260
+ {
155261
+ "kind": "field",
155262
+ "name": "loadMore",
155263
+ "type": {
155264
+ "text": "boolean"
155265
+ },
155266
+ "default": "false",
155267
+ "description": "Sends `helix-load-more` once the end of the table comes within a screen\nof view, so you can add the next rows as a reader nears them.",
155268
+ "attribute": "load-more"
155269
+ },
154533
155270
  {
154534
155271
  "kind": "field",
154535
155272
  "name": "movedLabel",
@@ -154615,6 +155352,19 @@
154615
155352
  "words": true
154616
155353
  }
154617
155354
  },
155355
+ {
155356
+ "kind": "field",
155357
+ "name": "selectColumnLabel",
155358
+ "type": {
155359
+ "text": "string"
155360
+ },
155361
+ "default": "'Select'",
155362
+ "description": "The name of the heading over the checkboxes under\n`selection-mode=\"single\"`, where it holds no checkbox of its own.",
155363
+ "attribute": "select-column-label",
155364
+ "helix": {
155365
+ "words": true
155366
+ }
155367
+ },
154618
155368
  {
154619
155369
  "kind": "field",
154620
155370
  "name": "selected",
@@ -154637,6 +155387,25 @@
154637
155387
  "words": true
154638
155388
  }
154639
155389
  },
155390
+ {
155391
+ "kind": "field",
155392
+ "name": "selectionBehavior",
155393
+ "type": {
155394
+ "text": "'replace' | 'toggle'"
155395
+ },
155396
+ "default": "'toggle'",
155397
+ "description": "What a press on a row, or in a `grid` table a key that moves to one, does\nto the rows already selected: `toggle`, the default, leaves them to the\ncheckboxes, and `replace` selects the row alone.",
155398
+ "attribute": "selection-behavior"
155399
+ },
155400
+ {
155401
+ "kind": "field",
155402
+ "name": "selectionMode",
155403
+ "type": {
155404
+ "text": "'multiple' | 'single' | undefined"
155405
+ },
155406
+ "description": "How many rows a `selectable` table selects: `multiple`, the default, or\n`single`, one at a time.",
155407
+ "attribute": "selection-mode"
155408
+ },
154640
155409
  {
154641
155410
  "kind": "field",
154642
155411
  "name": "selectRowLabel",
@@ -154703,6 +155472,54 @@
154703
155472
  "privacy": "private",
154704
155473
  "default": "undefined"
154705
155474
  },
155475
+ {
155476
+ "kind": "field",
155477
+ "name": "expandedState",
155478
+ "type": {
155479
+ "text": "string | undefined"
155480
+ },
155481
+ "privacy": "private",
155482
+ "default": "undefined"
155483
+ },
155484
+ {
155485
+ "kind": "field",
155486
+ "name": "nests",
155487
+ "type": {
155488
+ "text": "boolean"
155489
+ },
155490
+ "privacy": "private",
155491
+ "description": "Whether any row sits under another, which makes the table a tree.",
155492
+ "readonly": true
155493
+ },
155494
+ {
155495
+ "kind": "field",
155496
+ "name": "open",
155497
+ "type": {
155498
+ "text": "Set<string>"
155499
+ },
155500
+ "privacy": "private",
155501
+ "description": "The keys of the rows whose rows are shown.",
155502
+ "readonly": true
155503
+ },
155504
+ {
155505
+ "kind": "method",
155506
+ "name": "toggleRow",
155507
+ "privacy": "private",
155508
+ "return": {
155509
+ "type": {
155510
+ "text": "void"
155511
+ }
155512
+ },
155513
+ "parameters": [
155514
+ {
155515
+ "name": "key",
155516
+ "type": {
155517
+ "text": "string"
155518
+ }
155519
+ }
155520
+ ],
155521
+ "description": "Shows or hides the rows under the row of `key`, asking first from the row,\nand saying so from it once it stands."
155522
+ },
154706
155523
  {
154707
155524
  "kind": "field",
154708
155525
  "name": "headed",
@@ -154726,7 +155543,7 @@
154726
155543
  "name": "gridKeys",
154727
155544
  "privacy": "private",
154728
155545
  "readonly": true,
154729
- "default": "new TableGridController(this, { activate: (place, event) => this.activate(place, event), columns: () => this.tableColumns.filter((column) => column.shown), lead: () => this.lead, on: () => this.grid, part: (name) => this.partNamed(name), rows: () => (this.childrenKnown ? this.arrangedRows : []), rowWords: () => this.arrangedRows.map((row) => textOf(row.children[0])), selectAll: () => this.selectable && this.requestSelected(new Set([...this.chosen, ...this.enabledKeys])), selectRange: (to, from) => this.selectRange(to, from), })",
155546
+ "default": "new TableGridController(this, { activate: (place, event) => this.activate(place, event), arrive: (to, control) => { if (this.replaces && !control) { this.chooseOnly(to) } }, columns: () => this.tableColumns.filter((column) => column.shown), lead: () => this.lead, on: () => this.grid, part: (name) => this.partNamed(name), rows: () => (this.childrenKnown ? this.arrangedRows : []), rowWords: () => this.arrangedRows.map((row) => textOf(row.children[0])), selectAll: () => this.selectable && !this.single && this.requestSelected(new Set([...this.chosen, ...this.enabledKeys])), selectRange: (to, from) => this.selectRange(to, from), })",
154730
155547
  "description": "The keyboard of a `grid` table, in `grid-controller.ts`."
154731
155548
  },
154732
155549
  {
@@ -154835,6 +155652,36 @@
154835
155652
  "description": "The rows in the order they are drawn: sorted by `sort`, and as written\nwhere there is no sort.\n\n**Drawn in order by assignment.** A manually assigned slot draws its nodes\nin the order they were assigned, so the rows move on screen and in the\naccessibility tree while the consumer's markup stays as it was written,\nwhich is what a framework holding those rows needs.",
154836
155653
  "readonly": true
154837
155654
  },
155655
+ {
155656
+ "kind": "method",
155657
+ "name": "nested",
155658
+ "privacy": "private",
155659
+ "return": {
155660
+ "type": {
155661
+ "text": "Element[]"
155662
+ }
155663
+ },
155664
+ "parameters": [
155665
+ {
155666
+ "name": "rows",
155667
+ "type": {
155668
+ "text": "Element[]"
155669
+ }
155670
+ }
155671
+ ],
155672
+ "description": "The rows of a tree in the order they are drawn: each row followed by the\nrows under it while it is open, at every depth, keeping the order `rows`\nis in among the rows under one row. A row under a key no row has is drawn\nat the top."
155673
+ },
155674
+ {
155675
+ "kind": "method",
155676
+ "name": "shape",
155677
+ "privacy": "private",
155678
+ "return": {
155679
+ "type": {
155680
+ "text": "Map<string, { branch: boolean; level: number }>"
155681
+ }
155682
+ },
155683
+ "description": "How deep each row sits, from 1, and whether rows sit under it, by key."
155684
+ },
154838
155685
  {
154839
155686
  "kind": "field",
154840
155687
  "name": "heardSort",
@@ -154997,6 +155844,52 @@
154997
155844
  },
154998
155845
  "description": "The checkbox in the heading: every row that can be chosen, or none of\nthem where each already is. A `disabled` row keeps what it had."
154999
155846
  },
155847
+ {
155848
+ "kind": "field",
155849
+ "name": "single",
155850
+ "type": {
155851
+ "text": "boolean"
155852
+ },
155853
+ "privacy": "private",
155854
+ "description": "Whether the table selects one row at a time.",
155855
+ "readonly": true
155856
+ },
155857
+ {
155858
+ "kind": "field",
155859
+ "name": "replaces",
155860
+ "type": {
155861
+ "text": "boolean"
155862
+ },
155863
+ "privacy": "private",
155864
+ "description": "Whether a press or a move on a row selects it alone.",
155865
+ "readonly": true
155866
+ },
155867
+ {
155868
+ "kind": "method",
155869
+ "name": "chooseOnly",
155870
+ "privacy": "private",
155871
+ "return": {
155872
+ "type": {
155873
+ "text": "void"
155874
+ }
155875
+ },
155876
+ "parameters": [
155877
+ {
155878
+ "name": "at",
155879
+ "type": {
155880
+ "text": "number"
155881
+ }
155882
+ }
155883
+ ],
155884
+ "description": "Selects the drawn row `at` alone, and makes it where a range runs from.\nAsks nothing where it is already the only one selected."
155885
+ },
155886
+ {
155887
+ "kind": "field",
155888
+ "name": "handleRowClick",
155889
+ "privacy": "private",
155890
+ "readonly": true,
155891
+ "description": "A press on a row under `selection-behavior=\"replace\"`: it selects the row\nalone, Control or Command adds or takes out the row, and Shift takes in\nthe rows from the one last chosen. A press on the row's own controls, its\ncheckbox or its grip is theirs."
155892
+ },
155000
155893
  {
155001
155894
  "kind": "field",
155002
155895
  "name": "anchorKey",
@@ -155267,6 +156160,65 @@
155267
156160
  },
155268
156161
  "description": "Tells every row which edge each of its cells lines up against.\n\n**A rule in each row's shadow root, keyed on position and written by this\ntable.** The cells are the consumer's markup, so nothing may be written onto\nthem, and each of the other ways fails somewhere a table goes:\n\n- This element's own sheet cannot reach them. `::slotted()` matches what is\n assigned here, which is the rows, and never a row's children.\n- A property per column published here, `--table-align-2: end`, still needs\n a rule that knows which column a cell is in, and a fixed ladder of\n `:nth-child` rules in a static sheet is a ceiling on the column count.\n- A custom state set on each cell by script is right only until a cell\n moves, and a cell moving inside a row changes no child list this element\n watches.\n\n`:nth-child` is matched by the browser against wherever a cell is now, so a\ncell that moves takes its new column's edge with no script at all; a column\nthat moves rewrites the rules on the render the watcher asks for; and a\ncolumn hidden along with its cells keeps its place in both counts, since\n`:nth-child` counts a hidden sibling the way `tableColumns` counts a hidden\ncolumn. The row is where they go because only the shadow root holding a\nslot can style what is assigned to it.\n\n**A custom property and nothing else**, which is how this tier publishes a\nfact: the edge is the author's declaration, and what lining up means, a\n`justify-content` or a `text-align`, belongs to whoever draws the cell.\n`initial` on every cell first, so a table nested in an aligned cell does not\ntake the outer column's edge for columns of its own that set none."
155269
156162
  },
156163
+ {
156164
+ "kind": "field",
156165
+ "name": "endWatcher",
156166
+ "type": {
156167
+ "text": "IntersectionObserver | undefined"
156168
+ },
156169
+ "privacy": "private",
156170
+ "description": "Watches the end of a `load-more` table coming near the box that scrolls it."
156171
+ },
156172
+ {
156173
+ "kind": "field",
156174
+ "name": "watchedEnd",
156175
+ "type": {
156176
+ "text": "Element | undefined"
156177
+ },
156178
+ "privacy": "private",
156179
+ "description": "The end being watched, so a new one is watched again."
156180
+ },
156181
+ {
156182
+ "kind": "field",
156183
+ "name": "askedAt",
156184
+ "type": {
156185
+ "text": "number | undefined"
156186
+ },
156187
+ "privacy": "private",
156188
+ "description": "The number of rows `helix-load-more` was last sent for."
156189
+ },
156190
+ {
156191
+ "kind": "method",
156192
+ "name": "watchEnd",
156193
+ "privacy": "private",
156194
+ "return": {
156195
+ "type": {
156196
+ "text": "void"
156197
+ }
156198
+ },
156199
+ "description": "Starts or stops watching the end of the table, against the box that\nscrolls it, or the page, with a screen of room below it, so the next rows\nare asked for before a reader reaches the last. List does the same."
156200
+ },
156201
+ {
156202
+ "kind": "field",
156203
+ "name": "endInView",
156204
+ "type": {
156205
+ "text": "boolean"
156206
+ },
156207
+ "privacy": "private",
156208
+ "default": "false",
156209
+ "description": "Whether the end of the table was in reach when last measured."
156210
+ },
156211
+ {
156212
+ "kind": "method",
156213
+ "name": "askForMore",
156214
+ "privacy": "private",
156215
+ "return": {
156216
+ "type": {
156217
+ "text": "void"
156218
+ }
156219
+ },
156220
+ "description": "Sends `helix-load-more`, once for each number of rows, and never while loading."
156221
+ },
155270
156222
  {
155271
156223
  "kind": "method",
155272
156224
  "name": "renderGripHead",
@@ -155278,6 +156230,17 @@
155278
156230
  },
155279
156231
  "description": "The heading over the row grips, named by `row-grips-label`."
155280
156232
  },
156233
+ {
156234
+ "kind": "method",
156235
+ "name": "renderExpandHead",
156236
+ "privacy": "private",
156237
+ "return": {
156238
+ "type": {
156239
+ "text": "TemplateResult | typeof nothing"
156240
+ }
156241
+ },
156242
+ "description": "The heading over the disclosure buttons, in a table whose rows nest."
156243
+ },
155281
156244
  {
155282
156245
  "kind": "method",
155283
156246
  "name": "renderSelectAll",
@@ -155818,6 +156781,22 @@
155818
156781
  "name": "helix-before-reorder",
155819
156782
  "reactProp": "onhelix-before-reorder"
155820
156783
  },
156784
+ {
156785
+ "type": {
156786
+ "text": "HelixBeforeToggleEvent"
156787
+ },
156788
+ "description": "Fired from a row when its disclosure button is pressed, with whether it would be open in `detail.checked`. Cancelable: cancel it to keep the row as it is.",
156789
+ "name": "helix-before-toggle",
156790
+ "reactProp": "onhelix-before-toggle"
156791
+ },
156792
+ {
156793
+ "type": {
156794
+ "text": "HelixLoadMoreEvent"
156795
+ },
156796
+ "description": "Fired, in a table with `load-more`, when the end of the table comes within a screen of view, once for each number of rows.",
156797
+ "name": "helix-load-more",
156798
+ "reactProp": "onhelix-load-more"
156799
+ },
155821
156800
  {
155822
156801
  "type": {
155823
156802
  "text": "HelixReorderEvent"
@@ -155857,6 +156836,14 @@
155857
156836
  "description": "Fired after the sort order changes, with the new order.",
155858
156837
  "name": "helix-sorted",
155859
156838
  "reactProp": "onhelix-sorted"
156839
+ },
156840
+ {
156841
+ "type": {
156842
+ "text": "HelixToggleEvent"
156843
+ },
156844
+ "description": "Fired from a row once the rows under it are shown or hidden, with whether it is open in `detail.checked`.",
156845
+ "name": "helix-toggle",
156846
+ "reactProp": "onhelix-toggle"
155860
156847
  }
155861
156848
  ],
155862
156849
  "attributes": [
@@ -155887,6 +156874,15 @@
155887
156874
  "description": "The column widths as one track list, written once on the table.\n\nWith `TableColumn` children, each track sizes the column in its place, a\nhidden column counted, so hiding one takes its track with it and the rest\nkeep theirs. The columns decide how many tracks there are and this list\nonly how wide: a track past the last column is dropped, and a column past\nthe last track shares what is left. With no columns declared it is the\nwhole track list. Tracks count as the grid counts them, so `minmax(0, 1fr)`\nis one and `repeat(2, 8rem)` is two, and one the grid would refuse leaves\nits column at the default rather than taking the table down to one column.\n\n**A column's own `width` wins over its track here.** The width is written\non the column it sizes, which is the more particular statement, and it is\nwhere a resize lands: a reader dragging a column's edge writes `width`, so\nwere this list to win, the drag would move the separator and leave the\ntrack where the list put it. This is the table's default for its columns,\nand each column may say otherwise.\n\n**It is also the only track list a server can send.** The shim has no tree\nto walk, so a render there knows of no columns and this attribute is the\nwhole answer: a table given one lays its grid out in the first paint, and a\ntable sized only by its columns is one track wide until it upgrades.\n\n**Data Table has none of this, and should not.** Its columns are its schema\nrather than an option, so there is always a column to write a `width` on\nand a list here would be a second way to say what that says. This table's\ncells are markup, and a table written as rows of cells with no column\ndeclared in it has nowhere else to be sized from.",
155888
156875
  "fieldName": "columns"
155889
156876
  },
156877
+ {
156878
+ "name": "default-expanded",
156879
+ "type": {
156880
+ "text": "string"
156881
+ },
156882
+ "default": "''",
156883
+ "description": "The keys of the rows whose rows are shown at the start, separated by\ncommas. Used until `expanded` is set.",
156884
+ "fieldName": "defaultExpanded"
156885
+ },
155890
156886
  {
155891
156887
  "name": "default-selected",
155892
156888
  "type": {
@@ -155932,6 +156928,32 @@
155932
156928
  "description": "The text shown and announced when the rows could not load. Set it when a\nfetch fails, and clear it once you try again. Empty, the default, shows\nnothing.\n\nWhile it is set, a line after the rows shows it, or your own content in the\n`error` slot, in place of the empty and loading lines, and the live region\nsays it.",
155933
156929
  "fieldName": "errorText"
155934
156930
  },
156931
+ {
156932
+ "name": "expand-column-label",
156933
+ "type": {
156934
+ "text": "string"
156935
+ },
156936
+ "default": "'Expand'",
156937
+ "description": "The name of the heading over the disclosure buttons.",
156938
+ "fieldName": "expandColumnLabel"
156939
+ },
156940
+ {
156941
+ "name": "expanded",
156942
+ "type": {
156943
+ "text": "string"
156944
+ },
156945
+ "description": "The keys of the rows whose rows are shown, separated by commas, in a table\nwhose rows nest. A press on a row's disclosure button asks first, and\n`default-expanded` seeds what this element then owns.",
156946
+ "fieldName": "expanded"
156947
+ },
156948
+ {
156949
+ "name": "expand-row-label",
156950
+ "type": {
156951
+ "text": "string"
156952
+ },
156953
+ "default": "'Expand {row}'",
156954
+ "description": "The name of a row's disclosure button. `{row}` is the words of the row's first cell.",
156955
+ "fieldName": "expandRowLabel"
156956
+ },
155935
156957
  {
155936
156958
  "name": "fallback-label",
155937
156959
  "type": {
@@ -155959,6 +156981,15 @@
155959
156981
  "description": "Accessible name for the table.\n\nAn `aria-label` or `aria-labelledby` on the host names the table too, and\nwins over this.",
155960
156982
  "fieldName": "label"
155961
156983
  },
156984
+ {
156985
+ "name": "load-more",
156986
+ "type": {
156987
+ "text": "boolean"
156988
+ },
156989
+ "default": "false",
156990
+ "description": "Sends `helix-load-more` once the end of the table comes within a screen\nof view, so you can add the next rows as a reader nears them.",
156991
+ "fieldName": "loadMore"
156992
+ },
155962
156993
  {
155963
156994
  "name": "moved-label",
155964
156995
  "type": {
@@ -156022,6 +157053,15 @@
156022
157053
  "description": "The name of the checkbox in the heading that selects every row.",
156023
157054
  "fieldName": "selectAllLabel"
156024
157055
  },
157056
+ {
157057
+ "name": "select-column-label",
157058
+ "type": {
157059
+ "text": "string"
157060
+ },
157061
+ "default": "'Select'",
157062
+ "description": "The name of the heading over the checkboxes under\n`selection-mode=\"single\"`, where it holds no checkbox of its own.",
157063
+ "fieldName": "selectColumnLabel"
157064
+ },
156025
157065
  {
156026
157066
  "name": "selected",
156027
157067
  "type": {
@@ -156039,6 +157079,23 @@
156039
157079
  "description": "What screen readers hear when the chosen rows change. `{count}` is how many\nrows are chosen, written in the locale, and a language that needs plural\nforms writes them: `{count, plural, one {# wybrany} few {# wybrane} many\n{# wybranych} other {# wybranego}}`.",
156040
157080
  "fieldName": "selectedLabel"
156041
157081
  },
157082
+ {
157083
+ "name": "selection-behavior",
157084
+ "type": {
157085
+ "text": "'replace' | 'toggle'"
157086
+ },
157087
+ "default": "'toggle'",
157088
+ "description": "What a press on a row, or in a `grid` table a key that moves to one, does\nto the rows already selected: `toggle`, the default, leaves them to the\ncheckboxes, and `replace` selects the row alone.",
157089
+ "fieldName": "selectionBehavior"
157090
+ },
157091
+ {
157092
+ "name": "selection-mode",
157093
+ "type": {
157094
+ "text": "'multiple' | 'single' | undefined"
157095
+ },
157096
+ "description": "How many rows a `selectable` table selects: `multiple`, the default, or\n`single`, one at a time.",
157097
+ "fieldName": "selectionMode"
157098
+ },
156042
157099
  {
156043
157100
  "name": "select-row-label",
156044
157101
  "type": {
@@ -156197,8 +157254,14 @@
156197
157254
  "declarations": [
156198
157255
  {
156199
157256
  "kind": "class",
156200
- "description": "The row renders its cells straight through and lays out none of them, so a\nstylesheet can place them in the table's grid and every column lines up\nacross rows. The row still exists as an element, so you can style it, hide\nit, or make it interactive.\n\nIn a `selectable` table the row draws a checkbox cell before its own cells,\nand `value` is the key the table's `selected` lists it by. `disabled` keeps\nthe row out of the selection and out of its link.\n\nIn a `reorderable` table the row draws a grip cell before those, holding a\nbutton named by the table's `move-row-label`, and `value` is the key\n`helix-reorder` lists it by. The table says which row is moving and where\nthe drop indicator is, with the `dragging`, `drop-before`, and `drop-after`\nstates.\n\n**`href` makes the whole row a link**, as a row action does in React Aria's\ntable: a press anywhere on the row follows it, except on a link or a control\nof the row's own, and Control, Command or Shift open it the way they open a\nlink. A drag that selects text follows nothing. A row in a table is not a\nstop of its own, so put the same link in a cell, usually the row header,\nwhich is what the keyboard and a screen reader reach. In a `grid` table,\nEnter on any cell of the row follows it as well.",
157257
+ "description": "The row renders its cells straight through and lays out none of them, so a\nstylesheet can place them in the table's grid and every column lines up\nacross rows. The row still exists as an element, so you can style it, hide\nit, or make it interactive.\n\nIn a `selectable` table the row draws a checkbox cell before its own cells,\nand `value` is the key the table's `selected` lists it by. `disabled` keeps\nthe row out of the selection and out of its link.\n\nIn a `reorderable` table the row draws a grip cell before those, holding a\nbutton named by the table's `move-row-label`, and `value` is the key\n`helix-reorder` lists it by. The table says which row is moving and where\nthe drop indicator is, with the `dragging`, `drop-before`, and `drop-after`\nstates.\n\n**`parent` nests the row under another**, by that row's key. The table\nthen draws a column of disclosure buttons: a row with rows under it has one,\nnamed by the table's `expand-row-label` and saying whether it is open with\n`aria-expanded`, and its rows are drawn only while it is open. The cell is\nindented by the row's depth through `--table-row-level`.\n\n**`href` makes the whole row a link**, as a row action does in React Aria's\ntable: a press anywhere on the row follows it, except on a link or a control\nof the row's own, and Control, Command or Shift open it the way they open a\nlink. A drag that selects text follows nothing. A row in a table is not a\nstop of its own, so put the same link in a cell, usually the row header,\nwhich is what the keyboard and a screen reader reach. In a `grid` table,\nEnter on any cell of the row follows it as well.",
156201
157258
  "name": "HelixHeadlessTableRow",
157259
+ "cssProperties": [
157260
+ {
157261
+ "description": "Written by the row on its `expand` cell: how deep the row sits, from 1. Do not set it.",
157262
+ "name": "--table-row-level"
157263
+ }
157264
+ ],
156202
157265
  "cssParts": [
156203
157266
  {
156204
157267
  "description": "The row's checkbox, in a `selectable` table.",
@@ -156244,6 +157307,18 @@
156244
157307
  "description": "Added to `checkbox-mark` while only some rows are selected.",
156245
157308
  "name": "checkbox-mark-indeterminate"
156246
157309
  },
157310
+ {
157311
+ "description": "The cell that holds the row's disclosure button, in a table whose rows nest. It carries `--table-row-level`, the row's depth from 1.",
157312
+ "name": "expand"
157313
+ },
157314
+ {
157315
+ "description": "The button that shows and hides the rows under this one.",
157316
+ "name": "expand-button"
157317
+ },
157318
+ {
157319
+ "description": "The caret on the disclosure button, which points along the line, turned down by the styled tier while the row is open.",
157320
+ "name": "expand-mark"
157321
+ },
156247
157322
  {
156248
157323
  "description": "The cell that holds the row's grip, in a `reorderable` table.",
156249
157324
  "name": "grip"
@@ -156293,6 +157368,16 @@
156293
157368
  "description": "The URL a press on the row follows, which makes the whole row a link.\nEmpty, the default, leaves presses to the row's cells.",
156294
157369
  "attribute": "href"
156295
157370
  },
157371
+ {
157372
+ "kind": "field",
157373
+ "name": "parent",
157374
+ "type": {
157375
+ "text": "string"
157376
+ },
157377
+ "default": "''",
157378
+ "description": "The key of the row this one sits under, in a table whose rows nest: that\nrow's `value`, or its place among the rows where it has none. Empty, the\ndefault, is a row at the top.",
157379
+ "attribute": "parent"
157380
+ },
156296
157381
  {
156297
157382
  "kind": "field",
156298
157383
  "name": "rel",
@@ -156369,6 +157454,17 @@
156369
157454
  },
156370
157455
  "description": "The grip cell, in a `reorderable` table: a cell of the row's own before the\ncheckbox cell, holding the button that moves the row. In a grid the cell\ntakes focus and Space or Enter on it picks the row up, and the button\nleaves the tab order. `aria-disabled` while a sort decides the order."
156371
157456
  },
157457
+ {
157458
+ "kind": "method",
157459
+ "name": "renderExpand",
157460
+ "privacy": "protected",
157461
+ "return": {
157462
+ "type": {
157463
+ "text": "TemplateResult | typeof nothing"
157464
+ }
157465
+ },
157466
+ "description": "The disclosure cell, in a table whose rows nest: a button where rows sit\nunder this one, and an empty cell where none do, so the columns stay in\nline. In a grid the cell takes focus and Space or Enter on it presses the\nbutton, which leaves the tab order."
157467
+ },
156372
157468
  {
156373
157469
  "kind": "field",
156374
157470
  "name": "tier",
@@ -156728,6 +157824,15 @@
156728
157824
  "description": "The URL a press on the row follows, which makes the whole row a link.\nEmpty, the default, leaves presses to the row's cells.",
156729
157825
  "fieldName": "href"
156730
157826
  },
157827
+ {
157828
+ "name": "parent",
157829
+ "type": {
157830
+ "text": "string"
157831
+ },
157832
+ "default": "''",
157833
+ "description": "The key of the row this one sits under, in a table whose rows nest: that\nrow's `value`, or its place among the rows where it has none. Empty, the\ndefault, is a row at the top.",
157834
+ "fieldName": "parent"
157835
+ },
156731
157836
  {
156732
157837
  "name": "rel",
156733
157838
  "type": {
@@ -156769,6 +157874,10 @@
156769
157874
  "description": "The row being moved goes before this one when it is dropped.",
156770
157875
  "name": "drop-before"
156771
157876
  },
157877
+ {
157878
+ "description": "While the rows under this one are shown.",
157879
+ "name": "expanded"
157880
+ },
156772
157881
  {
156773
157882
  "description": "While the row has `href` and is not `disabled`, so a press on it follows the link.",
156774
157883
  "name": "link"
@@ -157825,15 +158934,22 @@
157825
158934
  "type": {
157826
158935
  "text": "string"
157827
158936
  }
158937
+ },
158938
+ {
158939
+ "name": "cause",
158940
+ "optional": true,
158941
+ "type": {
158942
+ "text": "string"
158943
+ }
157828
158944
  }
157829
158945
  ],
157830
- "description": "Requests a new current item, and returns whether the change was applied.\n\nAnnounces before it acts, so `preventDefault()` on the `helix-before-activate` is\na refusal and nothing moves. Unlike a native control, nothing has moved\nby the time this runs, so refusing is simply not writing: there is\nnothing to put back. Nobody refusing means the set updates itself,\nwhether or not a consumer declared `active`, a declared property being a\nseed and a correction.",
158946
+ "description": "Requests a new current item, and returns whether the change was applied.\n\nAnnounces before it acts, so `preventDefault()` on the `helix-before-activate` is\na refusal and nothing moves. Unlike a native control, nothing has moved\nby the time this runs, so refusing is simply not writing: there is\nnothing to put back. Nobody refusing means the set updates itself,\nwhether or not a consumer declared `active`, a declared property being a\nseed and a correction. `cause` says why, where the family names its\ncauses, and reaches the event as `detail.cause`.",
157831
158947
  "inheritedFrom": {
157832
158948
  "name": "MixinControllerActive",
157833
158949
  "module": "src/mixins/mixin-controller-active/mixin-controller-active.ts"
157834
158950
  },
157835
158951
  "type": {
157836
- "text": "requestActive(next: string) => boolean"
158952
+ "text": "requestActive(next: string, cause?: string) => boolean"
157837
158953
  }
157838
158954
  },
157839
158955
  {
@@ -170171,7 +171287,7 @@
170171
171287
  "declarations": [
170172
171288
  {
170173
171289
  "kind": "class",
170174
- "description": "Given `datetime`, the label you write is wrapped in a `<time>` element, so a\nmachine-readable value such as \"2026-08-19\" travels with a label such as\n\"yesterday\". Without `datetime`, the label is a `<span>`.\n\n**`relative` writes the time for you** as how long ago it was, such as \"3\nhours ago\", from `datetime`, where the `time` slot is empty. The words move\non as they go stale, \"3 hours ago\" becoming \"4 hours ago\", with one wakeup\nshared by every reading on the page, as `FormatDate` keeps its own. They are\nin the language of the page, or of the nearest `lang`.\n\nEach entry draws the connector line that arrives at it and hides it when it\nis the first entry, using `:host(:first-child)`. This needs no index, no\ncounting parent, and no script. `Steps` and `Breadcrumbs` work the same way.\n\n`tone` sets the kind of event and is the only thing that colors the mark. It\nuses the same values as `Announcement`.",
171290
+ "description": "Given `datetime`, the label you write is wrapped in a `<time>` element, so a\nmachine-readable value such as \"2026-08-19\" travels with a label such as\n\"yesterday\". Without `datetime`, the label is a `<span>`.\n\n**`relative` writes the time for you** as how long ago it was, such as \"3\nhours ago\", from `datetime`, where the `time` slot is empty. The words move\non as they go stale, \"3 hours ago\" becoming \"4 hours ago\", with one wakeup\nshared by every reading on the page, as `FormatDate` keeps its own. They are\nin the language of the page, or of the nearest `lang`.\n\nEach entry draws the connector line that arrives at it and hides it when it\nis the first entry, using `:host(:first-child)`. This needs no index, no\ncounting parent, and no script. `Steps` and `Breadcrumbs` work the same way.\n\n`tone` sets the kind of event and is the only thing that colors the mark. It\nuses the same values as `Announcement`. **A screen reader hears the tone as\na word**, from `tone-labels`: the mark is an image named \"Error\",\n\"Information\", \"Success\" or \"Warning\", so the color is not the only place\nthe meaning is. `neutral` and `primary` say nothing unless you name them.\n\n**`pending` marks an event that has not happened yet**, such as one that is\nscheduled. The mark is the open circle, and a screen reader hears\n`pending-label`, \"Scheduled\", with the tone's word.",
170175
171291
  "name": "HelixHeadlessTimelineItem",
170176
171292
  "cssParts": [
170177
171293
  {
@@ -170183,7 +171299,7 @@
170183
171299
  "name": "dot"
170184
171300
  },
170185
171301
  {
170186
- "description": "The mark on the line.",
171302
+ "description": "The mark on the line. An image named by the tone's word, and by `pending-label`, where either applies.",
170187
171303
  "name": "marker"
170188
171304
  },
170189
171305
  {
@@ -170201,7 +171317,7 @@
170201
171317
  "name": ""
170202
171318
  },
170203
171319
  {
170204
- "description": "The mark on the line. Defaults to a dot, which is the slot's fallback content.",
171320
+ "description": "The mark on the line. Defaults to a dot, which is the slot's fallback content. A mark you slot is read as the tone's word, where the entry has one.",
170205
171321
  "name": "marker"
170206
171322
  },
170207
171323
  {
@@ -170210,6 +171326,16 @@
170210
171326
  }
170211
171327
  ],
170212
171328
  "members": [
171329
+ {
171330
+ "kind": "field",
171331
+ "name": "words",
171332
+ "type": {
171333
+ "text": "string"
171334
+ },
171335
+ "static": true,
171336
+ "default": "'helix-timeline-item'",
171337
+ "description": "The key this part's words are registered under, its styled tag:\n`registerWords('de', { 'helix-timeline-item': { toneLabels: { danger: 'Fehler' } } })`."
171338
+ },
170213
171339
  {
170214
171340
  "kind": "field",
170215
171341
  "name": "datetime",
@@ -170222,12 +171348,14 @@
170222
171348
  },
170223
171349
  {
170224
171350
  "kind": "field",
170225
- "name": "relative",
171351
+ "name": "pending",
170226
171352
  "type": {
170227
- "text": "'long' | 'narrow' | 'short' | undefined"
171353
+ "text": "boolean"
170228
171354
  },
170229
- "description": "Writes the time as how long ago it was, or how long until it, from\n`datetime`, where the `time` slot is empty: `long` (\"3 hours ago\"),\n`short` (\"3 hr. ago\") or `narrow` (\"3h ago\"). Set with no value, it is\n`long`. The words move on as they go stale.",
170230
- "attribute": "relative"
171355
+ "default": "false",
171356
+ "description": "Marks an event that has not happened yet, such as one that is scheduled.\nThe mark is the open circle, and a screen reader hears `pending-label`.",
171357
+ "attribute": "pending",
171358
+ "reflects": true
170231
171359
  },
170232
171360
  {
170233
171361
  "kind": "field",
@@ -170282,16 +171410,71 @@
170282
171410
  ],
170283
171411
  "description": "What the reading says at `now`, and when it stops being true."
170284
171412
  },
171413
+ {
171414
+ "kind": "field",
171415
+ "name": "pendingLabel",
171416
+ "type": {
171417
+ "text": "string"
171418
+ },
171419
+ "default": "'Scheduled'",
171420
+ "description": "What a screen reader hears for an entry that is `pending`.",
171421
+ "attribute": "pending-label",
171422
+ "helix": {
171423
+ "words": true
171424
+ }
171425
+ },
171426
+ {
171427
+ "kind": "field",
171428
+ "name": "relative",
171429
+ "type": {
171430
+ "text": "'long' | 'narrow' | 'short' | undefined"
171431
+ },
171432
+ "description": "Writes the time as how long ago it was, or how long until it, from\n`datetime`, where the `time` slot is empty: `long` (\"3 hours ago\"),\n`short` (\"3 hr. ago\") or `narrow` (\"3h ago\"). Set with no value, it is\n`long`. The words move on as they go stale.",
171433
+ "attribute": "relative"
171434
+ },
170285
171435
  {
170286
171436
  "kind": "field",
170287
171437
  "name": "tone",
170288
171438
  "type": {
170289
171439
  "text": "'danger' | 'info' | 'neutral' | 'primary' | 'success' | 'warning' | undefined"
170290
171440
  },
170291
- "description": "The kind of event. It sets the color of the mark and nothing else.",
171441
+ "description": "The kind of event. It sets the color of the mark, and a screen reader\nhears it as the word `tone-labels` gives it.",
170292
171442
  "attribute": "tone",
170293
171443
  "reflects": true
170294
171444
  },
171445
+ {
171446
+ "kind": "field",
171447
+ "name": "toneLabel",
171448
+ "type": {
171449
+ "text": "string"
171450
+ },
171451
+ "default": "''",
171452
+ "description": "What a screen reader is told this entry's tone is, such as \"Failed\".\nAbsent is the tone's word in `tone-labels`.",
171453
+ "attribute": "tone-label"
171454
+ },
171455
+ {
171456
+ "kind": "field",
171457
+ "name": "toneLabels",
171458
+ "type": {
171459
+ "text": "Partial<Record<TimelineTone, string>>"
171460
+ },
171461
+ "default": "{ danger: 'Error', info: 'Information', success: 'Success', warning: 'Warning', }",
171462
+ "description": "What a screen reader is told each tone is, by the tone's name, written as\nJSON in the attribute: `tone-labels='{\"danger\":\"Failed\"}'`. A tone with no\nword is not read, which is `neutral` and `primary` in English.",
171463
+ "attribute": "tone-labels",
171464
+ "helix": {
171465
+ "words": true
171466
+ }
171467
+ },
171468
+ {
171469
+ "kind": "field",
171470
+ "name": "markName",
171471
+ "type": {
171472
+ "text": "string"
171473
+ },
171474
+ "privacy": "private",
171475
+ "description": "What the mark says: the tone's word and the pending word, where either applies.",
171476
+ "readonly": true
171477
+ },
170295
171478
  {
170296
171479
  "kind": "method",
170297
171480
  "name": "renderMarker",
@@ -170301,7 +171484,7 @@
170301
171484
  "text": "TemplateResult"
170302
171485
  }
170303
171486
  },
170304
- "description": "The mark for an entry that slotted none, which the tone decides.\n\n**A seam is a `protected render…()` and never a getter.** A slot's fallback\nanswers a consumer and a seam answers the tier above, and a getter answers\nneither. The check tests for parentheses, `${this.x}` being permitted\nbecause a property is not markup a tier would redraw, so a getter returning\na template reads as a bare reference and is let through.\n\nToned entries are reporting something, so they take the circle with a\ncenter, which is `Steps` drawing the stage a reader is standing on. Untoned\nones are just things that happened and take the open circle, which is\n`Steps` drawing a stage nobody has reached. The same two glyphs in both\ncomponents rather than two that resemble each other: a shape drawn twice\ndrifts, and these are already the marks a reader has learned one page over."
171487
+ "description": "The mark for an entry that slotted none, which the tone decides.\n\n**A seam is a `protected render…()` and never a getter.** A slot's fallback\nanswers a consumer and a seam answers the tier above, and a getter answers\nneither. The check tests for parentheses, `${this.x}` being permitted\nbecause a property is not markup a tier would redraw, so a getter returning\na template reads as a bare reference and is let through.\n\nToned entries are reporting something, so they take the circle with a\ncenter, which is `Steps` drawing the stage a reader is standing on. Untoned\nones are just things that happened and take the open circle, which is\n`Steps` drawing a stage nobody has reached, and so does a `pending`\nentry, which nobody has reached yet either. The same two glyphs in both\ncomponents rather than two that resemble each other: a shape drawn twice\ndrifts, and these are already the marks a reader has learned one page over."
170305
171488
  },
170306
171489
  {
170307
171490
  "kind": "field",
@@ -170653,6 +171836,24 @@
170653
171836
  "description": "When it happened, in machine-readable form. Setting it wraps the time in a\n`<time>` element.\n\nWhatever `<time>` accepts, which is a date, a time, both, a duration or a\nweek. Unset, the label is written as it was given and nothing claims to\nknow what instant it names.",
170654
171837
  "fieldName": "datetime"
170655
171838
  },
171839
+ {
171840
+ "name": "pending",
171841
+ "type": {
171842
+ "text": "boolean"
171843
+ },
171844
+ "default": "false",
171845
+ "description": "Marks an event that has not happened yet, such as one that is scheduled.\nThe mark is the open circle, and a screen reader hears `pending-label`.",
171846
+ "fieldName": "pending"
171847
+ },
171848
+ {
171849
+ "name": "pending-label",
171850
+ "type": {
171851
+ "text": "string"
171852
+ },
171853
+ "default": "'Scheduled'",
171854
+ "description": "What a screen reader hears for an entry that is `pending`.",
171855
+ "fieldName": "pendingLabel"
171856
+ },
170656
171857
  {
170657
171858
  "name": "relative",
170658
171859
  "type": {
@@ -170666,8 +171867,26 @@
170666
171867
  "type": {
170667
171868
  "text": "'danger' | 'info' | 'neutral' | 'primary' | 'success' | 'warning' | undefined"
170668
171869
  },
170669
- "description": "The kind of event. It sets the color of the mark and nothing else.",
171870
+ "description": "The kind of event. It sets the color of the mark, and a screen reader\nhears it as the word `tone-labels` gives it.",
170670
171871
  "fieldName": "tone"
171872
+ },
171873
+ {
171874
+ "name": "tone-label",
171875
+ "type": {
171876
+ "text": "string"
171877
+ },
171878
+ "default": "''",
171879
+ "description": "What a screen reader is told this entry's tone is, such as \"Failed\".\nAbsent is the tone's word in `tone-labels`.",
171880
+ "fieldName": "toneLabel"
171881
+ },
171882
+ {
171883
+ "name": "tone-labels",
171884
+ "type": {
171885
+ "text": "Partial<Record<TimelineTone, string>>"
171886
+ },
171887
+ "default": "{ danger: 'Error', info: 'Information', success: 'Success', warning: 'Warning', }",
171888
+ "description": "What a screen reader is told each tone is, by the tone's name, written as\nJSON in the attribute: `tone-labels='{\"danger\":\"Failed\"}'`. A tone with no\nword is not read, which is `neutral` and `primary` in English.",
171889
+ "fieldName": "toneLabels"
170671
171890
  }
170672
171891
  ],
170673
171892
  "superclass": {
@@ -181857,15 +183076,22 @@
181857
183076
  "type": {
181858
183077
  "text": "string"
181859
183078
  }
183079
+ },
183080
+ {
183081
+ "name": "cause",
183082
+ "optional": true,
183083
+ "type": {
183084
+ "text": "string"
183085
+ }
181860
183086
  }
181861
183087
  ],
181862
- "description": "Requests a new current item, and returns whether the change was applied.\n\nAnnounces before it acts, so `preventDefault()` on the `helix-before-activate` is\na refusal and nothing moves. Unlike a native control, nothing has moved\nby the time this runs, so refusing is simply not writing: there is\nnothing to put back. Nobody refusing means the set updates itself,\nwhether or not a consumer declared `active`, a declared property being a\nseed and a correction.",
183088
+ "description": "Requests a new current item, and returns whether the change was applied.\n\nAnnounces before it acts, so `preventDefault()` on the `helix-before-activate` is\na refusal and nothing moves. Unlike a native control, nothing has moved\nby the time this runs, so refusing is simply not writing: there is\nnothing to put back. Nobody refusing means the set updates itself,\nwhether or not a consumer declared `active`, a declared property being a\nseed and a correction. `cause` says why, where the family names its\ncauses, and reaches the event as `detail.cause`.",
181863
183089
  "inheritedFrom": {
181864
183090
  "name": "MixinControllerActive",
181865
183091
  "module": "src/mixins/mixin-controller-active/mixin-controller-active.ts"
181866
183092
  },
181867
183093
  "type": {
181868
- "text": "requestActive(next: string) => boolean"
183094
+ "text": "requestActive(next: string, cause?: string) => boolean"
181869
183095
  }
181870
183096
  },
181871
183097
  {
@@ -183515,6 +184741,10 @@
183515
184741
  "description": "The list item that holds the button.",
183516
184742
  "name": "container"
183517
184743
  },
184744
+ {
184745
+ "description": "The `indicator` slot, at the end of the row, rendered only while the entry is playing. It draws no box until you give it one.",
184746
+ "name": "indicator"
184747
+ },
183518
184748
  {
183519
184749
  "description": "The row, which is a button.",
183520
184750
  "name": "item"
@@ -183541,6 +184771,10 @@
183541
184771
  "description": "The entry's name.",
183542
184772
  "name": ""
183543
184773
  },
184774
+ {
184775
+ "description": "A mark shown on the entry that is playing, such as an equalizer icon. Rendered only while the entry is current.",
184776
+ "name": "indicator"
184777
+ },
183544
184778
  {
183545
184779
  "description": "A thumbnail. Defaults to an image of `poster`.",
183546
184780
  "name": "media"
@@ -183571,6 +184805,14 @@
183571
184805
  "attribute": "disabled",
183572
184806
  "reflects": true
183573
184807
  },
184808
+ {
184809
+ "kind": "field",
184810
+ "name": "focusable",
184811
+ "type": {
184812
+ "text": "boolean | undefined"
184813
+ },
184814
+ "description": "Whether the entry holds the playlist's tab stop. Unset, every entry is in\nthe tab order, which is what a server renders.\n\n**Written by the playlist, with no attribute, and it reaches the button.**\nThe playlist gives the stop to the entry a reader last focused, or to the\ncurrent one, and the arrow keys reach the rest."
184815
+ },
183574
184816
  {
183575
184817
  "kind": "field",
183576
184818
  "name": "poster",
@@ -184241,6 +185483,25 @@
184241
185483
  "readonly": true,
184242
185484
  "description": "Notes the menu opening and closing, for the built-in trigger.\n\nThe trigger is this element's own button, so the state is written onto it\nhere. The menu cannot write onto a plain button slotted into it."
184243
185485
  },
185486
+ {
185487
+ "kind": "method",
185488
+ "name": "focusPlaying",
185489
+ "privacy": "private",
185490
+ "return": {
185491
+ "type": {
185492
+ "text": "void"
185493
+ }
185494
+ },
185495
+ "parameters": [
185496
+ {
185497
+ "name": "menu",
185498
+ "type": {
185499
+ "text": "HTMLElement & { updateComplete?: Promise<unknown> }"
185500
+ }
185501
+ }
185502
+ ],
185503
+ "description": "Puts focus on the entry playing once the menu has opened, as a list of\nchoices opens on the one chosen. The menu focuses its first row as it\nopens, so this follows that."
185504
+ },
184244
185505
  {
184245
185506
  "kind": "field",
184246
185507
  "name": "observer",
@@ -184895,9 +186156,13 @@
184895
186156
  "declarations": [
184896
186157
  {
184897
186158
  "kind": "class",
184898
- "description": "**You slot the player**, so it keeps your appearance, extra controls,\ncaptions, and poster treatment. `Sandbox` takes its preview and `Menu` its\ntrigger the same way.\n\n**Entries are markup.** React skips properties it would set imperatively\nduring hydration, so an array property on a custom element is missing on the\nfirst paint of a server-rendered page. `using-the-elements.mdx` has the\nmeasurement. Markup also makes each entry a real button with its name inside.\n\n**The playlist does not play media.** It sets `src` on the player and tracks\nwhich entry is current. The current entry moves when:\n\n- an entry is pressed,\n- the player dispatches `helix-next` or `helix-previous`, or\n- the player reaches the end.\n\nOn `ended` the playlist advances and the next clip starts playing, because\nthe user already pressed play once. `repeat` decides what happens at the\nend: `one` plays the same entry again, and `all` goes from the last entry\nback to the first. Without it, the playlist stops on the last entry and\nsends `helix-end`. `shuffle` plays the entries in a random order, starting\nfrom the one that is current, and `previous` retraces that order.\n\n**The player is named by the current entry**, and the device's own media\ncontrols show the entry as the title. A player you gave a `label` keeps\nyour name, and only the title follows the entry.\n\n**Keyboard.** Each entry is a button in the tab order, and Enter or Space\nplays it. The arrow keys move focus to the entry before or after, and Home\nand End to the first and the last, passing over disabled entries. The\ncurrent entry carries `aria-current`. While focus is on the player, the\nplayer's own keys work, and `Video` lists them, and Shift with N or P plays\nthe next or the previous entry. The player's previous and next controls\nmove through the entries in the same order the playlist does.\n\n**What a screen reader hears.** A list named by `label`, with a button for\neach entry. When the playlist moves to another entry, by a press, by the\nplayer's controls, or at the end of a clip, a live region says\n`playing-label`, \"Now playing\" and the entry's name.",
186159
+ "description": "**You slot the player**, so it keeps your appearance, extra controls,\ncaptions, and poster treatment. `Sandbox` takes its preview and `Menu` its\ntrigger the same way.\n\n**Entries are markup.** React skips properties it would set imperatively\nduring hydration, so an array property on a custom element is missing on the\nfirst paint of a server-rendered page. `using-the-elements.mdx` has the\nmeasurement. Markup also makes each entry a real button with its name inside.\n\n**The playlist does not play media.** It sets `src` on the player and tracks\nwhich entry is current. The current entry moves when:\n\n- an entry is pressed,\n- the player dispatches `helix-next` or `helix-previous`, or\n- the player reaches the end.\n\nOn `ended` the playlist advances and the next clip starts playing, because\nthe user already pressed play once. `no-advance` turns that off, and the\nplaylist stays on the entry that ended. `repeat` decides what happens at the\nend: `one` plays the same entry again, and `all` goes from the last entry\nback to the first. Without it, the playlist stops on the last entry and\nsends `helix-end`. `shuffle` plays the entries in a random order, starting\nfrom the one that is current, and `previous` retraces that order.\n\n**`helix-before-activate` says why the playlist is moving**, in\n`detail.cause`: `press` for an entry or a menu choice, `next` and\n`previous` for the player's controls and the methods, `ended` at the end of\na clip, and `removed` when the current entry leaves the playlist. Cancel an\n`ended` move to show your own \"Up next\" countdown, then call `next()`.\n\n**Removing the current entry moves the playlist on**, to the entry after it,\nor to the one before it when it was the last. A clip that was playing keeps\nplaying in the entry that takes its place.\n\n**The player is named by the current entry**, and the device's own media\ncontrols show the entry as the title. A player you gave a `label` keeps\nyour name, and only the title follows the entry.\n\n**Keyboard.** The entries take one stop in the tab order: the entry you\nlast focused, or the current entry before you have focused one. Enter or\nSpace plays it. The arrow keys move focus to the entry before or after, and\nHome and End to the first and the last, passing over disabled entries. The\ncurrent entry carries `aria-current`. While focus is on the player, the\nplayer's own keys work, and `Video` lists them, and Shift with N or P plays\nthe next or the previous entry. The player's previous and next controls\nmove through the entries in the same order the playlist does.\n\n**What a screen reader hears.** A list named by `label`, with a button for\neach entry. When the playlist moves to another entry, by a press, by the\nplayer's controls, or at the end of a clip, a live region says\n`playing-label`, \"Now playing\" and the entry's name.",
184899
186160
  "name": "HelixHeadlessVideoPlaylist",
184900
186161
  "cssParts": [
186162
+ {
186163
+ "description": "The box that holds the `empty` slot, drawn while there are no entries.",
186164
+ "name": "empty"
186165
+ },
184901
186166
  {
184902
186167
  "description": "The list of entries.",
184903
186168
  "name": "items"
@@ -184916,6 +186181,10 @@
184916
186181
  "description": "The entries.",
184917
186182
  "name": ""
184918
186183
  },
186184
+ {
186185
+ "description": "Shown while the playlist has no entries. Defaults to `empty-label`.",
186186
+ "name": "empty"
186187
+ },
184919
186188
  {
184920
186189
  "description": "The player that plays the entries.",
184921
186190
  "name": "player"
@@ -184932,6 +186201,19 @@
184932
186201
  "default": "'helix-video-playlist'",
184933
186202
  "description": "The key this family's words are registered under, its styled tag:\n`registerWords('de', { 'helix-video-playlist': { label: 'Wiedergabeliste' } })`."
184934
186203
  },
186204
+ {
186205
+ "kind": "field",
186206
+ "name": "emptyLabel",
186207
+ "type": {
186208
+ "text": "string"
186209
+ },
186210
+ "default": "'No videos'",
186211
+ "description": "What the playlist says while it has no entries. The `empty` slot replaces it.",
186212
+ "attribute": "empty-label",
186213
+ "helix": {
186214
+ "words": true
186215
+ }
186216
+ },
184935
186217
  {
184936
186218
  "kind": "field",
184937
186219
  "name": "label",
@@ -184945,6 +186227,16 @@
184945
186227
  "words": true
184946
186228
  }
184947
186229
  },
186230
+ {
186231
+ "kind": "field",
186232
+ "name": "noAdvance",
186233
+ "type": {
186234
+ "text": "boolean"
186235
+ },
186236
+ "default": "false",
186237
+ "description": "Stays on an entry when its clip ends, where the playlist would otherwise\nplay the next one. The player's controls, a press, and `next()` still\nmove. `repeat=\"one\"` still plays the entry again.",
186238
+ "attribute": "no-advance"
186239
+ },
184948
186240
  {
184949
186241
  "kind": "field",
184950
186242
  "name": "playingLabel",
@@ -185014,6 +186306,43 @@
185014
186306
  "default": "false",
185015
186307
  "description": "Whether the entry changed because somebody moved through the playlist.\n\nAll three ways it moves are the reader going somewhere: pressing an entry,\npressing next or previous, or a clip ending and the next one following it.\nEvery one of those means play, and the one case that does not is the first\nrender, where the playlist is simply pointing the player at its opening\nentry and nobody has asked for anything yet.\n\nA press is also what makes the play legal. Autoplay is refused when nothing\nthe reader did asked for it, so starting here works because this is inside\nthe gesture that chose the entry, and where it is refused anyway the player\nshows its start control and waits."
185016
186308
  },
186309
+ {
186310
+ "kind": "field",
186311
+ "name": "known",
186312
+ "type": {
186313
+ "text": "{ current: string | undefined; values: string[] }"
186314
+ },
186315
+ "privacy": "private",
186316
+ "default": "{ current: undefined, values: [], }",
186317
+ "description": "The entries' values in the order of the last update, and the one that was\ncurrent then. Read when entries leave, to find the neighbor of a current\nentry that has gone."
186318
+ },
186319
+ {
186320
+ "kind": "field",
186321
+ "name": "stop",
186322
+ "type": {
186323
+ "text": "string | undefined"
186324
+ },
186325
+ "privacy": "private",
186326
+ "description": "The entry that holds the list's tab stop: the one a reader last focused.\nBefore they focus one, the current entry holds it."
186327
+ },
186328
+ {
186329
+ "kind": "field",
186330
+ "name": "pointed",
186331
+ "type": {
186332
+ "text": "HelixHeadlessVideoPlaylistItem | undefined"
186333
+ },
186334
+ "privacy": "private",
186335
+ "description": "The entry the player was last pointed at."
186336
+ },
186337
+ {
186338
+ "kind": "field",
186339
+ "name": "watcher",
186340
+ "type": {
186341
+ "text": "MutationObserver | undefined"
186342
+ },
186343
+ "privacy": "private",
186344
+ "description": "Hears entries arrive and leave, which change no property here."
186345
+ },
185017
186346
  {
185018
186347
  "kind": "field",
185019
186348
  "name": "player",
@@ -185058,6 +186387,12 @@
185058
186387
  "type": {
185059
186388
  "text": "number"
185060
186389
  }
186390
+ },
186391
+ {
186392
+ "name": "cause",
186393
+ "type": {
186394
+ "text": "'ended' | 'next' | 'previous'"
186395
+ }
185061
186396
  }
185062
186397
  ],
185063
186398
  "description": "Moves by one in the playing order and plays what it lands on. At an end it\nstays, unless `repeat` is `all`.\n\nA move a consumer refuses with `helix-before-activate` plays nothing, and\nleaves nothing behind to play on a later change."
@@ -185114,6 +186449,39 @@
185114
186449
  "privacy": "private",
185115
186450
  "readonly": true
185116
186451
  },
186452
+ {
186453
+ "kind": "field",
186454
+ "name": "handleFocusIn",
186455
+ "privacy": "private",
186456
+ "readonly": true,
186457
+ "description": "An entry that takes focus takes the tab stop with it."
186458
+ },
186459
+ {
186460
+ "kind": "field",
186461
+ "name": "handleEntries",
186462
+ "privacy": "private",
186463
+ "readonly": true,
186464
+ "description": "Entries arrived or left. Where the current entry left, the playlist moves\nto the entry after it, or to the one before it when it was the last, and\nkeeps playing where it was playing."
186465
+ },
186466
+ {
186467
+ "kind": "method",
186468
+ "name": "placeStop",
186469
+ "privacy": "private",
186470
+ "return": {
186471
+ "type": {
186472
+ "text": "void"
186473
+ }
186474
+ },
186475
+ "parameters": [
186476
+ {
186477
+ "name": "items",
186478
+ "type": {
186479
+ "text": "HelixHeadlessVideoPlaylistItem[]"
186480
+ }
186481
+ }
186482
+ ],
186483
+ "description": "Gives one entry the tab stop and takes it from the rest: the entry last\nfocused, then the current entry, then the first that can be chosen."
186484
+ },
185117
186485
  {
185118
186486
  "kind": "field",
185119
186487
  "name": "handleKeydown",
@@ -185221,15 +186589,22 @@
185221
186589
  "type": {
185222
186590
  "text": "string"
185223
186591
  }
186592
+ },
186593
+ {
186594
+ "name": "cause",
186595
+ "optional": true,
186596
+ "type": {
186597
+ "text": "string"
186598
+ }
185224
186599
  }
185225
186600
  ],
185226
- "description": "Requests a new current item, and returns whether the change was applied.\n\nAnnounces before it acts, so `preventDefault()` on the `helix-before-activate` is\na refusal and nothing moves. Unlike a native control, nothing has moved\nby the time this runs, so refusing is simply not writing: there is\nnothing to put back. Nobody refusing means the set updates itself,\nwhether or not a consumer declared `active`, a declared property being a\nseed and a correction.",
186601
+ "description": "Requests a new current item, and returns whether the change was applied.\n\nAnnounces before it acts, so `preventDefault()` on the `helix-before-activate` is\na refusal and nothing moves. Unlike a native control, nothing has moved\nby the time this runs, so refusing is simply not writing: there is\nnothing to put back. Nobody refusing means the set updates itself,\nwhether or not a consumer declared `active`, a declared property being a\nseed and a correction. `cause` says why, where the family names its\ncauses, and reaches the event as `detail.cause`.",
185227
186602
  "inheritedFrom": {
185228
186603
  "name": "MixinControllerActive",
185229
186604
  "module": "src/mixins/mixin-controller-active/mixin-controller-active.ts"
185230
186605
  },
185231
186606
  "type": {
185232
- "text": "requestActive(next: string) => boolean"
186607
+ "text": "requestActive(next: string, cause?: string) => boolean"
185233
186608
  }
185234
186609
  },
185235
186610
  {
@@ -185637,7 +187012,7 @@
185637
187012
  "type": {
185638
187013
  "text": "HelixBeforeActivateEvent"
185639
187014
  },
185640
- "description": "The current entry is about to change. Cancelable: cancel it to keep the current entry.",
187015
+ "description": "The current entry is about to change, and `detail.cause` says why: `press`, `next`, `previous`, `ended`, or `removed`. Cancelable: cancel it to keep the current entry.",
185641
187016
  "name": "helix-before-activate",
185642
187017
  "reactProp": "onhelix-before-activate"
185643
187018
  },
@@ -185651,6 +187026,15 @@
185651
187026
  }
185652
187027
  ],
185653
187028
  "attributes": [
187029
+ {
187030
+ "name": "empty-label",
187031
+ "type": {
187032
+ "text": "string"
187033
+ },
187034
+ "default": "'No videos'",
187035
+ "description": "What the playlist says while it has no entries. The `empty` slot replaces it.",
187036
+ "fieldName": "emptyLabel"
187037
+ },
185654
187038
  {
185655
187039
  "name": "label",
185656
187040
  "type": {
@@ -185660,6 +187044,15 @@
185660
187044
  "description": "The list's name, read by screen readers.",
185661
187045
  "fieldName": "label"
185662
187046
  },
187047
+ {
187048
+ "name": "no-advance",
187049
+ "type": {
187050
+ "text": "boolean"
187051
+ },
187052
+ "default": "false",
187053
+ "description": "Stays on an entry when its clip ends, where the playlist would otherwise\nplay the next one. The player's controls, a press, and `next()` still\nmove. `repeat=\"one\"` still plays the entry again.",
187054
+ "fieldName": "noAdvance"
187055
+ },
185663
187056
  {
185664
187057
  "name": "playing-label",
185665
187058
  "type": {
@@ -189016,7 +190409,7 @@
189016
190409
  }
189017
190410
  }
189018
190411
  ],
189019
- "description": "Fills one element's holes, its own and those below it, from an item."
190412
+ "description": "Fills one element's holes, its own and those below it, from an item.\n\nThe element itself whatever hole it carries, so a row whose root is a link\ntakes its `data-field-href` as readily as its text."
189020
190413
  },
189021
190414
  {
189022
190415
  "kind": "function",
@@ -189169,6 +190562,52 @@
189169
190562
  }
189170
190563
  ],
189171
190564
  "description": "Which item a key moves to in a list of `count` items laid out `across`\nitems to a line, from `at`.\n\nIndex arithmetic, because most of the items are not drawn: the list moves to\nan index, scrolls it into view, and focuses the row once it is there. The\nkeys are the ones a listbox answers, and in a grid the ones a grid of\noptions answers:\n\n- Up and Down move one line, to the item in the same column. Down from the\n line above a shorter last line goes to the last item.\n- Left and Right move one item, in a grid only, with `forward` naming the\n one that moves ahead along the line: Right, or Left on a right-to-left\n page. In a list they move nothing, and are left to the row.\n- Home and End move to the first and the last item.\n- Page Up and Page Down move by `page` lines, the number of lines on screen\n less one, so the line at one edge of the box lands at the other.\n\n`undefined` for a key the list does not take, and for an empty list."
190565
+ },
190566
+ {
190567
+ "kind": "function",
190568
+ "name": "skipDisabled",
190569
+ "return": {
190570
+ "type": {
190571
+ "text": "number | undefined"
190572
+ }
190573
+ },
190574
+ "parameters": [
190575
+ {
190576
+ "name": "key",
190577
+ "type": {
190578
+ "text": "string"
190579
+ }
190580
+ },
190581
+ {
190582
+ "name": "from",
190583
+ "type": {
190584
+ "text": "number"
190585
+ }
190586
+ },
190587
+ {
190588
+ "name": "to",
190589
+ "type": {
190590
+ "text": "number"
190591
+ }
190592
+ },
190593
+ {
190594
+ "name": "count",
190595
+ "type": {
190596
+ "text": "number"
190597
+ }
190598
+ },
190599
+ {
190600
+ "name": "disabled",
190601
+ "type": {
190602
+ "text": "(index: number) => boolean"
190603
+ }
190604
+ },
190605
+ {
190606
+ "name": "across",
190607
+ "default": "1"
190608
+ }
190609
+ ],
190610
+ "description": "Where a key lands once disabled items are passed over: from `to`, which\n`stepIndex` gave, on in the way the key moves until an item that is not\ndisabled. A line move steps a line at a time, in the same column. Home looks\nforward from the first item and End back from the last. `undefined` where\nevery item that way is disabled, and the key moves nothing."
189172
190611
  }
189173
190612
  ],
189174
190613
  "exports": [
@@ -189179,6 +190618,14 @@
189179
190618
  "name": "stepIndex",
189180
190619
  "module": "src/virtual-list/keys.ts"
189181
190620
  }
190621
+ },
190622
+ {
190623
+ "kind": "js",
190624
+ "name": "skipDisabled",
190625
+ "declaration": {
190626
+ "name": "skipDisabled",
190627
+ "module": "src/virtual-list/keys.ts"
190628
+ }
189182
190629
  }
189183
190630
  ]
189184
190631
  },
@@ -189298,7 +190745,7 @@
189298
190745
  "declarations": [
189299
190746
  {
189300
190747
  "kind": "class",
189301
- "description": "The items arrive as data, in one of two ways:\n\n- `items` takes an array. A framework sets it as a property, and React\n hydration keeps it.\n- `for` names a `<script type=\"application/json\">` that holds an array, which\n a server sends as markup.\n\nEach item is drawn into a row in one of two ways:\n\n- `renderItem` is a function from an item and its index to the row's\n content: a Lit template, a string, or a DOM node.\n- A `<template>` child defines one row. `data-field=\"name\"` fills an element\n with the item's `name` as text, and `data-field-href=\"url\"` writes the\n item's `url` into `href`, the same for any attribute. A field may be a path\n of keys, such as `author.name`.\n\nRows are your markup in the light DOM, so your stylesheet styles them.\n\n**A grid.** `columns` lays the items out that many to a line, as a grid of\nequal columns, and windows the set a line at a time, as React Aria's grid\nlayout does. Each item draws one element, a cell of the grid, and\n`estimate` is the height of a line. Space the items with padding inside\neach one, which the list measures with the line.\n\n**Keyboard.** The list is one tab stop.\n\n| Key | What it does |\n|---|---|\n| Down, Up | Moves to the next or the previous item, or in a grid to the item in the same column on the next or the previous line. |\n| Right, Left | In a grid, moves to the next or the previous item along the line, the other way round on a right-to-left page. |\n| Home, End | Moves to the first or the last item. |\n| Page Down, Page Up | Moves by the number of items, or of lines in a grid, on screen. |\n| A letter or a word | Moves to the next item whose text starts with what you typed. |\n| Tab | Moves into the focused row's own links and buttons, then out of the list. |\n\nAn item that is not drawn is scrolled into view and focused, so a keyboard\nreaches the whole set. When the row holding the tab stop scrolls away, the\nstop moves to the first row on screen. Typing matches each item's\n`text-field`, which is the first `data-field` of the row template by default,\nor the item itself when it is a string or a number.\n\nEach row says its place in the whole set with `aria-posinset` and\n`aria-setsize`, so a screen reader says \"4,000 of 10,000\". The row holding\nfocus stays drawn when it scrolls out.\n\n**Selecting.** `selection-mode` makes the list a list box a reader chooses\nfrom: `single` selects one item and `multiple` any number. Space or a press\nselects an item, Shift with Space, an arrow, Home, End or a press takes in\nthe items from the last one chosen, and Control or Command with A selects\nthem all, in `multiple`. `value` holds the chosen items' keys, separated by\ncommas, in the order of the set: `key-field` names each item's key, and a\nstring or a number item is its own key. A change asks with\n`helix-before-change` and tells with `change`. Each row is an `option`\nmarked `aria-selected`, so a row's own links and buttons are not reached\nthere: keep those to a list without `selection-mode`.\n\n**Loading more.** `helix-range-change` fires as the items on screen change,\nand `range` holds them. `helix-load-more` fires once a reader is within one\nscreen of the end, once for each length of the set: add to `items` and it can\nfire again. While you fetch, set `loading`: the list is busy, and a row after\nthe last item says \"Loading more\" (`loading-label`, or your own content in\nthe `loading` slot). `scrollToIndex` takes a reader to an item.\n\n**An empty list.** Set `empty-label`, or put your own content in the `empty`\nslot, for a row shown when there are no items and none are loading, such as\n\"No messages yet\" and a link to write one. Without either, an empty list\nshows nothing, since a list whose items have not arrived yet has not said\nit has none.\n\nThe list takes the `empty` state while it has read its items and holds none,\nand the `loading` state while `loading` is set, so your stylesheet can\nchange the box around it for either. A list with no name is reported once\nin a development build. Name it with `label` or `aria-label`.\n\n**Row height.** Rows are placed by `estimate` until they are drawn. Then the\nlist reads the drawn rows' height once and places every row by it, so a\nwrong estimate still reaches the last item. Set `measured` for rows of\ndifferent heights. Once the list draws rows of different heights, such as\nrows that wrap on a narrow screen, it places each row by its own height\nwhether `measured` is set or not.\n\nThe list follows its source. A new `items` array, an edit to the script's\ntext, or a script replaced under the same id draws the new rows. A row that\nstays in view keeps its element as the list scrolls.\n\nThe viewport scrolls on this tier. It carries `data-scroller`, and `core`\nships `[data-scroller] { overflow: auto }` into every shadow root, so\n`scrollTop` works with no stylesheet. You still need to set a block size.",
190748
+ "description": "The items arrive as data, in one of two ways:\n\n- `items` takes an array. A framework sets it as a property, and React\n hydration keeps it.\n- `for` names a `<script type=\"application/json\">` that holds an array, which\n a server sends as markup.\n\nEach item is drawn into a row in one of two ways:\n\n- `renderItem` is a function from an item and its index to the row's\n content: a Lit template, a string, or a DOM node.\n- A `<template>` child defines one row. `data-field=\"name\"` fills an element\n with the item's `name` as text, and `data-field-href=\"url\"` writes the\n item's `url` into `href`, the same for any attribute. A field may be a path\n of keys, such as `author.name`.\n\nRows are your markup in the light DOM, so your stylesheet styles them.\n\n**A grid.** `columns` lays the items out that many to a line, as a grid of\nequal columns, and windows the set a line at a time, as React Aria's grid\nlayout does. Each item draws one element, a cell of the grid, and\n`estimate` is the height of a line. `min-column-width` lays out as many\ncolumns as fit the box instead, as React Aria's grid layout does with its\nsmallest item size, and follows the box as it resizes. `gap` spaces the rows, and the columns\nof a grid, by a number of pixels the list counts in each row's place.\n\n**Keyboard.** The list is one tab stop.\n\n| Key | What it does |\n|---|---|\n| Down, Up | Moves to the next or the previous item, or in a grid to the item in the same column on the next or the previous line. |\n| Right, Left | In a grid, moves to the next or the previous item along the line, the other way round on a right-to-left page. |\n| Home, End | Moves to the first or the last item. |\n| Page Down, Page Up | Moves by the number of items, or of lines in a grid, on screen. |\n| A letter or a word | Moves to the next item whose text starts with what you typed. |\n| Escape | Lets go of every chosen item, in a list with `selection-mode`. |\n| Tab | Moves into the focused row's own links and buttons, then out of the list. |\n\nAn item that is not drawn is scrolled into view and focused, so a keyboard\nreaches the whole set. When the row holding the tab stop scrolls away, the\nstop moves to the first row on screen. Typing matches each item's\n`text-field`, which is the first `data-field` of the row template by default,\nor the item itself when it is a string or a number.\n\nEach row says its place in the whole set with `aria-posinset` and\n`aria-setsize`, so a screen reader says \"4,000 of 10,000\". The row holding\nfocus stays drawn when it scrolls out.\n\n**Selecting.** `selection-mode` makes the list a list box a reader chooses\nfrom: `single` selects one item and `multiple` any number. Space or a press\nselects an item, Shift with Space, an arrow, Home, End or a press takes in\nthe items from the last one chosen, and Control or Command with A selects\nthem all, in `multiple`. Escape lets go of every chosen item, and keeps the\nkey from the dialog or menu around the list while there was something to\nlet go of. `value` holds the chosen items' keys, separated by commas, in\nthe order of the set: `key-field` names each item's key, and a string or a\nnumber item is its own key. A change asks with `helix-before-change` and\ntells with `change`. Each row is an `option` marked `aria-selected`, so a\nrow's own links and buttons are not reached there: keep those to a list\nwithout `selection-mode`.\n\n`selection-behavior=\"replace\"` selects the item pressed alone, as a file\nlist does, and the arrow keys carry the selection with them. Control or\nCommand with a press or with Space adds or takes out one item, and with an\narrow moves without selecting.\n\n**Disabled items.** `disabled-keys` names items by their keys, separated by\ncommas. Their rows carry `aria-disabled`, the keys and typing pass over\nthem, and a press, Space, or Control with A does not select them.\n\n**Loading more.** `helix-range-change` fires as the items on screen change,\nand `range` holds them. `helix-load-more` fires once a reader is within one\nscreen of the end, once for each length of the set: add to `items` and it can\nfire again. While you fetch, set `loading`: the list is busy, and a row after\nthe last item says \"Loading more\" (`loading-label`, or your own content in\nthe `loading` slot). `scrollToIndex` takes a reader to an item.\n\n**An empty list.** Set `empty-label`, or put your own content in the `empty`\nslot, for a row shown when there are no items and none are loading, such as\n\"No messages yet\" and a link to write one. Without either, an empty list\nshows nothing, since a list whose items have not arrived yet has not said\nit has none.\n\nThe list takes the `empty` state while it has read its items and holds none,\nand the `loading` state while `loading` is set, so your stylesheet can\nchange the box around it for either. A list with no name is reported once\nin a development build. Name it with `label` or `aria-label`.\n\n**Row height.** Rows are placed by `estimate` until they are drawn. Then the\nlist reads the drawn rows' height once and places every row by it, so a\nwrong estimate still reaches the last item. Set `measured` for rows of\ndifferent heights. Once the list draws rows of different heights, such as\nrows that wrap on a narrow screen, it places each row by its own height\nwhether `measured` is set or not.\n\nThe list follows its source. A new `items` array, an edit to the script's\ntext, or a script replaced under the same id draws the new rows. A row that\nstays in view keeps its element as the list scrolls.\n\nThe viewport scrolls on this tier. It carries `data-scroller`, and `core`\nships `[data-scroller] { overflow: auto }` into every shadow root, so\n`scrollTop` works with no stylesheet. You still need to set a block size.",
189302
190749
  "name": "HelixHeadlessVirtualList",
189303
190750
  "cssParts": [
189304
190751
  {
@@ -189357,6 +190804,16 @@
189357
190804
  "description": "How many items a line holds. One, the default, is a list; more lays the\nitems out as a grid of that many equal columns, windowed a line at a\ntime, with Left and Right moving along a line.",
189358
190805
  "attribute": "columns"
189359
190806
  },
190807
+ {
190808
+ "kind": "field",
190809
+ "name": "disabledKeys",
190810
+ "type": {
190811
+ "text": "string"
190812
+ },
190813
+ "default": "''",
190814
+ "description": "The keys of the items a reader cannot choose or move to, separated by\ncommas, as `value` writes keys. Their rows carry `aria-disabled`.",
190815
+ "attribute": "disabled-keys"
190816
+ },
189360
190817
  {
189361
190818
  "kind": "field",
189362
190819
  "name": "emptyLabel",
@@ -189387,6 +190844,16 @@
189387
190844
  "description": "The id of the script element that holds the items as JSON. `items` wins\nwhere both are set.",
189388
190845
  "attribute": "for"
189389
190846
  },
190847
+ {
190848
+ "kind": "field",
190849
+ "name": "gap",
190850
+ "type": {
190851
+ "text": "number"
190852
+ },
190853
+ "default": "0",
190854
+ "description": "The space between two rows, and between two columns in a grid, in\npixels. The list counts it in each row's place, so a gap does not walk\nthe rows away from the scroll position the way a margin on each row\nwould.",
190855
+ "attribute": "gap"
190856
+ },
189390
190857
  {
189391
190858
  "kind": "field",
189392
190859
  "name": "items",
@@ -189448,14 +190915,34 @@
189448
190915
  "description": "Places each row by its own measured height. Without it, rows are placed\nby one height: `estimate` until rows are drawn, then the drawn rows' height,\nread once. Rows that come out different heights are placed by their own\nheights either way.\n\n**Off by default, because the straight line is better when it holds.** One\nheight makes offset and index convert by division, which can never\ndisagree with itself; measuring is what a set of genuinely different\nheights needs and costs a read of each row as it renders. A list of\none-line rows should leave this alone.",
189449
190916
  "attribute": "measured"
189450
190917
  },
190918
+ {
190919
+ "kind": "field",
190920
+ "name": "minColumnWidth",
190921
+ "type": {
190922
+ "text": "number"
190923
+ },
190924
+ "default": "0",
190925
+ "description": "The narrowest a column of a grid may be, in pixels. Set, the list lays\nout as many columns as fit the box at that width, at least one, and\nfollows the box as it resizes, which `columns` then does not decide.",
190926
+ "attribute": "min-column-width"
190927
+ },
189451
190928
  {
189452
190929
  "kind": "field",
189453
190930
  "name": "renderItem",
189454
190931
  "type": {
189455
- "text": "VirtualListRenderer | undefined"
190932
+ "text": "VirtualListRenderer<any> | undefined"
189456
190933
  },
189457
190934
  "description": "Draws one item into its row, given the item and its index. Set it as a\nproperty.\n\nIt returns what Lit renders: a template from `html`, a string, or a DOM\nnode. The list wraps each result in a `<div>` that carries the row's role\nand place in the set. Where it is unset, the row `<template>` is used."
189458
190935
  },
190936
+ {
190937
+ "kind": "field",
190938
+ "name": "selectionBehavior",
190939
+ "type": {
190940
+ "text": "'replace' | 'toggle'"
190941
+ },
190942
+ "default": "'toggle'",
190943
+ "description": "What a press does to the items already chosen: `toggle` adds or takes out\nthe item, and `replace` selects it alone and lets the arrow keys carry the\nselection, with Control or Command adding or taking out one item.",
190944
+ "attribute": "selection-behavior"
190945
+ },
189459
190946
  {
189460
190947
  "kind": "field",
189461
190948
  "name": "selectionMode",
@@ -189517,7 +191004,7 @@
189517
191004
  "kind": "field",
189518
191005
  "name": "filledBy",
189519
191006
  "type": {
189520
- "text": "VirtualListRenderer | undefined"
191007
+ "text": "VirtualListRenderer<any> | undefined"
189521
191008
  },
189522
191009
  "privacy": "private",
189523
191010
  "description": "The function the drawn rows were filled by, so a new one draws them again."
@@ -189587,6 +191074,24 @@
189587
191074
  "privacy": "private",
189588
191075
  "description": "Watches the source and the tree around it.\n\n**The list read its source once per `for`**, so a page that wrote new JSON\ninto the script, the way a framework updates a text child, kept the old\nrows. The script's own text is watched, and the tree it sits in, for a\nscript replaced under the same id."
189589
191076
  },
191077
+ {
191078
+ "kind": "field",
191079
+ "name": "sizes",
191080
+ "type": {
191081
+ "text": "ResizeObserver | undefined"
191082
+ },
191083
+ "privacy": "private",
191084
+ "description": "Watches the drawn rows for a change of size after they were drawn: an\nimage that loads, a row that opens, text a page edits in place.\n\n**Measured once, a row that grew later kept its old height**, so the\nwindow and the spacers placed every row after it by the old one. React\nAria's virtualizer observes its items for the same reason. A frame later,\nso a size the next render changes is not asked of the browser's pass over\nthe observers a second time."
191085
+ },
191086
+ {
191087
+ "kind": "field",
191088
+ "name": "resized",
191089
+ "type": {
191090
+ "text": "number | undefined"
191091
+ },
191092
+ "privacy": "private",
191093
+ "description": "The frame the next measure of resized rows waits for."
191094
+ },
189590
191095
  {
189591
191096
  "kind": "field",
189592
191097
  "name": "aria",
@@ -189600,7 +191105,7 @@
189600
191105
  "name": "virtualize",
189601
191106
  "privacy": "private",
189602
191107
  "readonly": true,
189603
- "default": "new VirtualizeController(this, { container: () => this.partNamed('viewport'), count: () => Math.ceil(this.data.length / this.across), estimate: () => this.estimate, measured: () => this.measured, rows: () => this.lines(), })"
191108
+ "default": "new VirtualizeController(this, { container: () => this.partNamed('viewport'), count: () => Math.ceil(this.data.length / this.across), estimate: () => this.estimate, gap: () => this.space, measured: () => this.measured, rows: () => this.lines(), })"
189604
191109
  },
189605
191110
  {
189606
191111
  "kind": "field",
@@ -189611,6 +191116,16 @@
189611
191116
  "description": "The items on screen, as `items.slice(first, last)` reads them.\n\nRead from the scroll offset when asked. Both are 0 before the list has a\nbox to measure.",
189612
191117
  "readonly": true
189613
191118
  },
191119
+ {
191120
+ "kind": "field",
191121
+ "name": "space",
191122
+ "type": {
191123
+ "text": "number"
191124
+ },
191125
+ "privacy": "private",
191126
+ "description": "The gap in pixels, none where it is not a positive number.",
191127
+ "readonly": true
191128
+ },
189614
191129
  {
189615
191130
  "kind": "field",
189616
191131
  "name": "across",
@@ -189618,9 +191133,49 @@
189618
191133
  "text": "number"
189619
191134
  },
189620
191135
  "privacy": "private",
189621
- "description": "How many items a line holds: `columns`, at least one.",
191136
+ "description": "How many items a line holds: as many as fit at `min-column-width` where\nit is set and the box has a width, and `columns` otherwise, at least one.",
189622
191137
  "readonly": true
189623
191138
  },
191139
+ {
191140
+ "kind": "field",
191141
+ "name": "boxWidth",
191142
+ "type": {
191143
+ "text": "number"
191144
+ },
191145
+ "privacy": "private",
191146
+ "default": "0",
191147
+ "description": "How wide the box is, read for `min-column-width`."
191148
+ },
191149
+ {
191150
+ "kind": "field",
191151
+ "name": "widthWatch",
191152
+ "type": {
191153
+ "text": "ResizeObserver | undefined"
191154
+ },
191155
+ "privacy": "private",
191156
+ "description": "Watches the box's width, for `min-column-width`."
191157
+ },
191158
+ {
191159
+ "kind": "field",
191160
+ "name": "measuredAcross",
191161
+ "type": {
191162
+ "text": "number"
191163
+ },
191164
+ "privacy": "private",
191165
+ "default": "1",
191166
+ "description": "The items to a line the measurements were taken at."
191167
+ },
191168
+ {
191169
+ "kind": "method",
191170
+ "name": "watchWidth",
191171
+ "privacy": "private",
191172
+ "return": {
191173
+ "type": {
191174
+ "text": "void"
191175
+ }
191176
+ },
191177
+ "description": "Watches the box for its width while `min-column-width` asks for it."
191178
+ },
189624
191179
  {
189625
191180
  "kind": "method",
189626
191181
  "name": "itemsOn",
@@ -189700,6 +191255,44 @@
189700
191255
  },
189701
191256
  "description": "The drawn lines, for the controller to measure: each row in a list, and\nthe first item of each line in a grid, whose cell is as tall as its line."
189702
191257
  },
191258
+ {
191259
+ "kind": "method",
191260
+ "name": "keepPlace",
191261
+ "privacy": "private",
191262
+ "return": {
191263
+ "type": {
191264
+ "text": "void"
191265
+ }
191266
+ },
191267
+ "parameters": [
191268
+ {
191269
+ "name": "was",
191270
+ "type": {
191271
+ "text": "readonly unknown[] | undefined"
191272
+ }
191273
+ }
191274
+ ],
191275
+ "description": "Keeps the reader on the item they were reading when items arrive before\nit, as a feed loading newer posts above does.\n\n**Every index moves by what arrived**, so the drawn rows are renumbered,\nthe tab stop moves with its item, and the controller is told, which moves\nthe scroll offset by the room the new items take. Recognized where the\nnew array ends with the old one: the same items, or the same keys under\n`key-field`."
191276
+ },
191277
+ {
191278
+ "kind": "method",
191279
+ "name": "watchSize",
191280
+ "privacy": "private",
191281
+ "return": {
191282
+ "type": {
191283
+ "text": "void"
191284
+ }
191285
+ },
191286
+ "parameters": [
191287
+ {
191288
+ "name": "elements",
191289
+ "type": {
191290
+ "text": "Element[]"
191291
+ }
191292
+ }
191293
+ ],
191294
+ "description": "Watches a row drawn on this pass for a change of size."
191295
+ },
189703
191296
  {
189704
191297
  "kind": "method",
189705
191298
  "name": "handleMutations",
@@ -189751,6 +191344,35 @@
189751
191344
  },
189752
191345
  "description": "The text typing matches for each item: `text-field`, the template's first\n`data-field`, or a string or number item itself."
189753
191346
  },
191347
+ {
191348
+ "kind": "field",
191349
+ "name": "disabled",
191350
+ "type": {
191351
+ "text": "Set<string>"
191352
+ },
191353
+ "privacy": "private",
191354
+ "description": "The keys `disabled-keys` names.",
191355
+ "readonly": true
191356
+ },
191357
+ {
191358
+ "kind": "method",
191359
+ "name": "isDisabled",
191360
+ "privacy": "private",
191361
+ "return": {
191362
+ "type": {
191363
+ "text": "boolean"
191364
+ }
191365
+ },
191366
+ "parameters": [
191367
+ {
191368
+ "name": "at",
191369
+ "type": {
191370
+ "text": "number"
191371
+ }
191372
+ }
191373
+ ],
191374
+ "description": "Whether item `at` is one a reader cannot choose or move to."
191375
+ },
189754
191376
  {
189755
191377
  "kind": "method",
189756
191378
  "name": "indexOf",
@@ -189855,6 +191477,10 @@
189855
191477
  {
189856
191478
  "name": "extend",
189857
191479
  "default": "false"
191480
+ },
191481
+ {
191482
+ "name": "toggle",
191483
+ "default": "false"
189858
191484
  }
189859
191485
  ],
189860
191486
  "description": "Selects item `at`, or lets it go, asking first. With `extend`, in\n`multiple`, the items from the anchor to it are taken in, as Data Table\nand List take in a range. Otherwise the item is where the next range runs\nfrom."
@@ -189995,9 +191621,15 @@
189995
191621
  "type": {
189996
191622
  "text": "ReadonlySet<string>"
189997
191623
  }
191624
+ },
191625
+ {
191626
+ "name": "off",
191627
+ "type": {
191628
+ "text": "ReadonlySet<string>"
191629
+ }
189998
191630
  }
189999
191631
  ],
190000
- "description": "Writes a row's role, and whether it is chosen in a list that selects:\n`option` with `aria-selected` there, and `listitem` otherwise. Every pass,\nsince a choice changes no row's content."
191632
+ "description": "Writes a row's role, and whether it is chosen in a list that selects:\n`option` with `aria-selected` there, and `listitem` otherwise, and\n`aria-disabled` on an item `disabled-keys` names. Every pass,\nsince a choice changes no row's content."
190001
191633
  },
190002
191634
  {
190003
191635
  "kind": "method",
@@ -190085,6 +191717,17 @@
190085
191717
  },
190086
191718
  "description": "Puts the windowed rows into the light DOM, and takes the rest out.\n\n**A row that stays in the window keeps its element.** Clearing and\ncloning every row on every move replaced the node a reader had focused,\nso a link in a row lost focus to the body on any scroll, even with its row\nstill on screen. Rows are keyed by item: the ones leaving go, the ones\narriving are drawn in their place, and the ones staying are not moved.\n\n**The row holding focus is drawn outside the window too**, beside it on the\nside it belongs, and the spacer on that side gives up its room.\n\n**One row holds the tab stop**, the one the reader last focused while it is\ndrawn, and the first row on screen once it is not. Its own links and\nbuttons are in the tab order, and those of every other row wait."
190087
191719
  },
191720
+ {
191721
+ "kind": "method",
191722
+ "name": "spacerSizes",
191723
+ "privacy": "private",
191724
+ "return": {
191725
+ "type": {
191726
+ "text": "{ after: number; before: number }"
191727
+ }
191728
+ },
191729
+ "description": "The spacers' heights: the window's, with the line kept for focus taking its own room."
191730
+ },
190088
191731
  {
190089
191732
  "kind": "field",
190090
191733
  "name": "tier",
@@ -190469,6 +192112,15 @@
190469
192112
  "description": "How many items a line holds. One, the default, is a list; more lays the\nitems out as a grid of that many equal columns, windowed a line at a\ntime, with Left and Right moving along a line.",
190470
192113
  "fieldName": "columns"
190471
192114
  },
192115
+ {
192116
+ "name": "disabled-keys",
192117
+ "type": {
192118
+ "text": "string"
192119
+ },
192120
+ "default": "''",
192121
+ "description": "The keys of the items a reader cannot choose or move to, separated by\ncommas, as `value` writes keys. Their rows carry `aria-disabled`.",
192122
+ "fieldName": "disabledKeys"
192123
+ },
190472
192124
  {
190473
192125
  "name": "empty-label",
190474
192126
  "type": {
@@ -190496,6 +192148,15 @@
190496
192148
  "description": "The id of the script element that holds the items as JSON. `items` wins\nwhere both are set.",
190497
192149
  "fieldName": "for"
190498
192150
  },
192151
+ {
192152
+ "name": "gap",
192153
+ "type": {
192154
+ "text": "number"
192155
+ },
192156
+ "default": "0",
192157
+ "description": "The space between two rows, and between two columns in a grid, in\npixels. The list counts it in each row's place, so a gap does not walk\nthe rows away from the scroll position the way a margin on each row\nwould.",
192158
+ "fieldName": "gap"
192159
+ },
190499
192160
  {
190500
192161
  "name": "key-field",
190501
192162
  "type": {
@@ -190541,6 +192202,24 @@
190541
192202
  "description": "Places each row by its own measured height. Without it, rows are placed\nby one height: `estimate` until rows are drawn, then the drawn rows' height,\nread once. Rows that come out different heights are placed by their own\nheights either way.\n\n**Off by default, because the straight line is better when it holds.** One\nheight makes offset and index convert by division, which can never\ndisagree with itself; measuring is what a set of genuinely different\nheights needs and costs a read of each row as it renders. A list of\none-line rows should leave this alone.",
190542
192203
  "fieldName": "measured"
190543
192204
  },
192205
+ {
192206
+ "name": "min-column-width",
192207
+ "type": {
192208
+ "text": "number"
192209
+ },
192210
+ "default": "0",
192211
+ "description": "The narrowest a column of a grid may be, in pixels. Set, the list lays\nout as many columns as fit the box at that width, at least one, and\nfollows the box as it resizes, which `columns` then does not decide.",
192212
+ "fieldName": "minColumnWidth"
192213
+ },
192214
+ {
192215
+ "name": "selection-behavior",
192216
+ "type": {
192217
+ "text": "'replace' | 'toggle'"
192218
+ },
192219
+ "default": "'toggle'",
192220
+ "description": "What a press does to the items already chosen: `toggle` adds or takes out\nthe item, and `replace` selects it alone and lets the arrow keys carry the\nselection, with Control or Command adding or taking out one item.",
192221
+ "fieldName": "selectionBehavior"
192222
+ },
190544
192223
  {
190545
192224
  "name": "selection-mode",
190546
192225
  "type": {
@@ -190635,6 +192314,6 @@
190635
192314
  ],
190636
192315
  "helix": {
190637
192316
  "package": "@fusion.dev/helix-headless",
190638
- "version": "0.160.0"
192317
+ "version": "0.161.0"
190639
192318
  }
190640
192319
  }