@fusion.dev/helix-headless 0.162.1 → 0.163.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.
@@ -14410,6 +14410,22 @@
14410
14410
  "module": "./root/canvas-root.js"
14411
14411
  }
14412
14412
  },
14413
+ {
14414
+ "kind": "js",
14415
+ "name": "CanvasRoute",
14416
+ "declaration": {
14417
+ "name": "CanvasRoute",
14418
+ "module": "./root/canvas-root.js"
14419
+ }
14420
+ },
14421
+ {
14422
+ "kind": "js",
14423
+ "name": "CanvasRouteEnds",
14424
+ "declaration": {
14425
+ "name": "CanvasRouteEnds",
14426
+ "module": "./root/canvas-root.js"
14427
+ }
14428
+ },
14413
14429
  {
14414
14430
  "kind": "js",
14415
14431
  "name": "CanvasSide",
@@ -15630,7 +15646,7 @@
15630
15646
  "declarations": [
15631
15647
  {
15632
15648
  "kind": "class",
15633
- "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.",
15649
+ "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\n**`edgeRoute` draws the connections' lines your own way**: a function from\nwhere a line leaves and arrives, and the sides it does, to its SVG path, for\na route such as one that bends around the cards between. What it returns\nis the line drawn, the line pressed and focused, and the one an arrowhead\nsits at the end of. Nothing back draws the board's own.\n\nAdd `minimap` to `controls` for a picture of the whole board in a corner:\neach card as a box, and a frame around what is on screen. A press or a drag\non it brings that place to the middle of the view. It is for a pointer, and\na screen reader skips it: the arrow keys and `show()` reach every card.\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.",
15634
15650
  "name": "HelixHeadlessCanvas",
15635
15651
  "cssProperties": [
15636
15652
  {
@@ -15707,6 +15723,18 @@
15707
15723
  "description": "The box a Shift-drag across the empty board draws, which selects the cards it touches.",
15708
15724
  "name": "marquee"
15709
15725
  },
15726
+ {
15727
+ "description": "The picture of the whole board, under `controls=\"minimap\"`.",
15728
+ "name": "minimap"
15729
+ },
15730
+ {
15731
+ "description": "One card in the minimap.",
15732
+ "name": "minimap-node"
15733
+ },
15734
+ {
15735
+ "description": "The frame in the minimap around what is on screen.",
15736
+ "name": "minimap-view"
15737
+ },
15710
15738
  {
15711
15739
  "description": "The button that moves the board down.",
15712
15740
  "name": "pan-down"
@@ -15919,6 +15947,14 @@
15919
15947
  "words": true
15920
15948
  }
15921
15949
  },
15950
+ {
15951
+ "kind": "field",
15952
+ "name": "edgeRoute",
15953
+ "type": {
15954
+ "text": "CanvasRoute | undefined"
15955
+ },
15956
+ "description": "Draws every connection's line: a function from where it leaves and\narrives, and the sides it does, to its SVG path and where its label sits.\n\nAbsent, or returning nothing for a connection, draws the board's own\nroute. A function that throws draws the board's own too, and the error is\nreported to the page as an uncaught one. Set it as a property."
15957
+ },
15922
15958
  {
15923
15959
  "kind": "field",
15924
15960
  "name": "fallbackLabel",
@@ -17118,6 +17154,49 @@
17118
17154
  ],
17119
17155
  "description": "The line a connection is drawn along on the plane, and its middle, where\nboth its cards are on the board; nothing where either is not."
17120
17156
  },
17157
+ {
17158
+ "kind": "method",
17159
+ "name": "draw",
17160
+ "privacy": "private",
17161
+ "return": {
17162
+ "type": {
17163
+ "text": "{ d: string; mid: { x: number; y: number } }"
17164
+ }
17165
+ },
17166
+ "parameters": [
17167
+ {
17168
+ "name": "edge",
17169
+ "type": {
17170
+ "text": "CanvasEdge"
17171
+ }
17172
+ },
17173
+ {
17174
+ "name": "from",
17175
+ "type": {
17176
+ "text": "CanvasNode"
17177
+ }
17178
+ },
17179
+ {
17180
+ "name": "to",
17181
+ "type": {
17182
+ "text": "CanvasNode"
17183
+ }
17184
+ },
17185
+ {
17186
+ "name": "path",
17187
+ "type": {
17188
+ "text": "CanvasPath"
17189
+ }
17190
+ },
17191
+ {
17192
+ "name": "drawnHeads",
17193
+ "type": {
17194
+ "text": "{ start: boolean; end: boolean }"
17195
+ }
17196
+ }
17197
+ ],
17198
+ "description": "One connection's line, by `edgeRoute` where it draws one, and by the board's own where not."
17199
+ },
17121
17200
  {
17122
17201
  "kind": "method",
17123
17202
  "name": "cardOf",
@@ -18411,6 +18490,44 @@
18411
18490
  ],
18412
18491
  "description": "The connection being made, drawn from where it starts to the pointer, or to\nthe card a keyboard reader is on."
18413
18492
  },
18493
+ {
18494
+ "kind": "field",
18495
+ "name": "onScreen",
18496
+ "type": {
18497
+ "text": "{ x: number; y: number; width: number; height: number }"
18498
+ },
18499
+ "privacy": "private",
18500
+ "description": "The part of the document on screen, in its own units.",
18501
+ "readonly": true
18502
+ },
18503
+ {
18504
+ "kind": "field",
18505
+ "name": "minimapArea",
18506
+ "type": {
18507
+ "text": "{ x: number; y: number; width: number; height: number }"
18508
+ },
18509
+ "privacy": "private",
18510
+ "description": "What the minimap shows: every card and what is on screen, with room around them.",
18511
+ "readonly": true
18512
+ },
18513
+ {
18514
+ "kind": "field",
18515
+ "name": "handleMinimapPointer",
18516
+ "privacy": "private",
18517
+ "readonly": true,
18518
+ "description": "A press or a drag on the minimap, which brings the place under it to the\nmiddle of the view.\n\n**The point is read through the picture's own scale**: the area is drawn\nwhole and centered in the box, so the box's spare width or height is split\neither side of it."
18519
+ },
18520
+ {
18521
+ "kind": "method",
18522
+ "name": "renderMinimap",
18523
+ "privacy": "private",
18524
+ "return": {
18525
+ "type": {
18526
+ "text": "TemplateResult | typeof nothing"
18527
+ }
18528
+ },
18529
+ "description": "The minimap, under `controls=\"minimap\"`: each card as a box, and a frame\naround what is on screen.\n\n**A picture for a pointer**, hidden from screen readers and taking no\nfocus, as a map's own overview is: the arrow keys and `show()` already take\na keyboard to any card, and a second way that says nothing a reader can\nuse would be a stop that does nothing."
18530
+ },
18414
18531
  {
18415
18532
  "kind": "field",
18416
18533
  "name": "controls",
@@ -20095,6 +20212,22 @@
20095
20212
  "module": "./canvas-document.js"
20096
20213
  }
20097
20214
  },
20215
+ {
20216
+ "kind": "js",
20217
+ "name": "CanvasRoute",
20218
+ "declaration": {
20219
+ "name": "CanvasRoute",
20220
+ "module": "./canvas-document.js"
20221
+ }
20222
+ },
20223
+ {
20224
+ "kind": "js",
20225
+ "name": "CanvasRouteEnds",
20226
+ "declaration": {
20227
+ "name": "CanvasRouteEnds",
20228
+ "module": "./canvas-document.js"
20229
+ }
20230
+ },
20098
20231
  {
20099
20232
  "kind": "js",
20100
20233
  "name": "CanvasSide",
@@ -25806,7 +25939,35 @@
25806
25939
  }
25807
25940
  }
25808
25941
  ],
25809
- "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."
25942
+ "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 `tabindex`\nit needs is written then, long after any server's markup has hydrated,\nand never on a turn nobody moved to."
25943
+ },
25944
+ {
25945
+ "kind": "field",
25946
+ "name": "stop",
25947
+ "type": {
25948
+ "text": "HTMLElement | undefined"
25949
+ },
25950
+ "privacy": "private",
25951
+ "description": "The turn that is a tab stop because a reader moved to it."
25952
+ },
25953
+ {
25954
+ "kind": "method",
25955
+ "name": "visit",
25956
+ "privacy": "private",
25957
+ "return": {
25958
+ "type": {
25959
+ "text": "void"
25960
+ }
25961
+ },
25962
+ "parameters": [
25963
+ {
25964
+ "name": "turn",
25965
+ "type": {
25966
+ "text": "HTMLElement"
25967
+ }
25968
+ }
25969
+ ],
25970
+ "description": "Focuses a turn, making it the transcript's one stop a reader moved to.\n\n**`0`, and never `-1`.** Chromium leaves the whole of a shadow host at a\nnegative `tabindex` out of the Tab order, its own controls and what is\nslotted into it alike, so a turn at `-1` lost its links and its Try again\nonce a reader had paged through it. The stop moves with the reader, and a\n`tabindex` you wrote on a turn is left as it is."
25810
25971
  },
25811
25972
  {
25812
25973
  "kind": "method",
@@ -101285,7 +101446,7 @@
101285
101446
  "declarations": [
101286
101447
  {
101287
101448
  "kind": "class",
101288
- "description": "Wraps a map drawn by MapLibre, Leaflet, or another renderer. The frame adds\na name for the map, a column of controls, and a strip for the map credit.\nHelix does not draw the map itself.\n\nThe controls are one column, and `controls` names which ones: `fullscreen`,\n`layers`, `tilt`, `zoom`, and `compass`, top to bottom. `zoom compass\nfullscreen` by default. The compass's needle points north as the map turns,\nand pressing it turns the map to face north.\n\nAdd `pan` and `rotate` for buttons around the compass that move and turn the\nmap. Dragging is otherwise the only way a pointer moves the map, so add them\nwhere the map has to be usable without dragging, as WCAG 2.2 asks at level\nAA. The arrow keys pan the map and Shift with Left or Right turns it either\nway.\n\nThe pan and zoom buttons and the arrow keys send `helix-map-pan` and\n`helix-map-zoom`. Move your map in response, or connect it with\n`connectMap` from `@fusion.dev/helix-map`, which does this for you.\n\nAdd `tilt` to `controls` for the 3D button, which a map with 3D buildings\nor terrain needs. It is a toggle. Pressed, it tilts the map 50 degrees, and\n`connectMap` raises the buildings and the ground. Pressed again, it makes the\nmap flat, and lays them flat too. Shift with Up or Down tilts the map in\nsteps. Turning and tilting send `helix-map-rotate` and `helix-map-tilt`,\nwhich `connectMap` answers on MapLibre. Leaflet draws maps flat and does not\nrotate.\n\nAdd `layers` to `controls` for a layers button. It opens a menu with a tile\nfor each layer, which sets the layer's `hidden` attribute. Layers with the\nsame `group`, such as a route and its dotted legs, share one tile. A tile\nsends `helix-before-toggle` from the layer first, so you can store the\nchoice or refuse it, and `helix-toggle` from it once `hidden` holds the\nchoice.\n\nImagery, a `helix-map-raster` with `ground`, is a map type and not a tile.\nThe menu opens with a card for each type, Standard, Hybrid, and Satellite,\nwith a picture of the map in it, and `map-type` says which is chosen.\nStandard hides the imagery, Hybrid draws it under the roads and names, and\nSatellite draws it alone. Choosing one sends `helix-before-change` with its\nname, and `change` once `map-type` holds it. `connectMap` does not draw a\nhidden layer, so a layer you write with `hidden` starts turned off.\n\nMarkers, routes, areas, live positions, and points layers go inside the\nframe as child elements.",
101449
+ "description": "Wraps a map drawn by MapLibre, Leaflet, or another renderer. The frame adds\na name for the map, a column of controls, and a strip for the map credit.\nHelix does not draw the map itself.\n\nThe controls are one column, and `controls` names which ones: `fullscreen`,\n`layers`, `tilt`, `zoom`, and `compass`, top to bottom. `zoom compass\nfullscreen` by default. The compass's needle points north as the map turns,\nand pressing it turns the map to face north.\n\nAdd `pan` and `rotate` for buttons around the compass that move and turn the\nmap. Dragging is otherwise the only way a pointer moves the map, so add them\nwhere the map has to be usable without dragging, as WCAG 2.2 asks at level\nAA. The arrow keys pan the map and Shift with Left or Right turns it either\nway.\n\nThe pan and zoom buttons and the arrow keys send `helix-map-pan` and\n`helix-map-zoom`. Move your map in response, or connect it with\n`connectMap` from `@fusion.dev/helix-map`, which does this for you.\n\nAdd `tilt` to `controls` for the 3D button, which a map with 3D buildings\nor terrain needs. It is a toggle. Pressed, it tilts the map 50 degrees, and\n`connectMap` raises the buildings and the ground. Pressed again, it makes the\nmap flat, and lays them flat too. Shift with Up or Down tilts the map in\nsteps. Turning and tilting send `helix-map-rotate` and `helix-map-tilt`,\nwhich `connectMap` answers on MapLibre. Leaflet draws maps flat and does not\nrotate.\n\nAdd `layers` to `controls` for a layers button. It opens a menu with a tile\nfor each layer, which sets the layer's `hidden` attribute. Layers with the\nsame `group`, such as a route and its dotted legs, share one tile. A tile\nsends `helix-before-toggle` from the layer first, so you can store the\nchoice or refuse it, and `helix-toggle` from it once `hidden` holds the\nchoice. Escape closes the menu and returns focus to its button, and the menu\ncloses when focus moves on from it or a press lands outside the map.\n\nImagery, a `helix-map-raster` with `ground`, is a map type and not a tile.\nThe menu opens with a card for each type, Standard, Hybrid, and Satellite,\nwith a picture of the map in it, and `map-type` says which is chosen.\nStandard hides the imagery, Hybrid draws it under the roads and names, and\nSatellite draws it alone. Choosing one sends `helix-before-change` with its\nname, and `change` once `map-type` holds it. `connectMap` does not draw a\nhidden layer, so a layer you write with `hidden` starts turned off.\n\nMarkers, routes, areas, live positions, and points layers go inside the\nframe as child elements.",
101289
101450
  "name": "HelixHeadlessMap",
101290
101451
  "cssProperties": [
101291
101452
  {
@@ -102068,6 +102229,13 @@
102068
102229
  "readonly": true,
102069
102230
  "description": "Closes the layers menu on a press anywhere outside the frame."
102070
102231
  },
102232
+ {
102233
+ "kind": "field",
102234
+ "name": "handleMenuFocusOut",
102235
+ "privacy": "private",
102236
+ "readonly": true,
102237
+ "description": "Closes the layers menu when focus moves on from its button and the menu,\nas a Tab past the last tile does. Focus leaving the page, with nothing\nfocused in its place, leaves the menu as it is."
102238
+ },
102071
102239
  {
102072
102240
  "kind": "field",
102073
102241
  "name": "handleMenuKeydown",
@@ -106768,7 +106936,7 @@
106768
106936
  "declarations": [
106769
106937
  {
106770
106938
  "kind": "class",
106771
- "description": "One element covers three kinds of row, and what you give it decides which:\n- Content in the `submenu` slot makes the row open a submenu page.\n- `checked` makes the row a choice.\n- With neither, the row is a command.\n\nThe role follows the kind. A row with `checked` is `menuitemcheckbox` with\n`aria-checked`, and `exclusive` makes it `menuitemradio`, for a set where\nonly one can be on. A row that opens a page keeps `menuitem` and sets\n`aria-haspopup`.\n\nChoosing a choice row checks or unchecks it before `helix-select` is sent,\nso a listener reads the new `checked`. An `exclusive` row turns on and turns\noff the `exclusive` rows next to it. Cancel `helix-before-toggle` to keep a\nrow as it is and set `checked` yourself.\n\nThe menu sets whether the row's page is showing as a property, never as an\nattribute. An attribute written onto your element after it upgrades causes a\nhydration mismatch.\n\n`shortcut` shows a row's keyboard shortcut after its label, drawn by `Kbd`\nin the platform's glyphs, and gives the row `aria-keyshortcuts`. It binds\nnothing: the shortcut is the page's to bind. Other trailing words, such as a\ncount, go in the `end` slot.\n\nThe row is named by its label alone. Words in `description`, a line under the\nlabel, and in `end` describe it instead, through `aria-describedby`, as\nReact Aria's menu item does with its description: a reader hears \"Copy\",\nthen \"Copies the selection\".\n\nA development build warns when a row has no words to be named by, such as a\nrow holding only an icon with no label.\n\nThe check mark and the caret are the fallbacks of the `check` and `chevron`\nslots, so a mark of your own replaces either by being slotted. Neither is\nread as part of the row's name.",
106939
+ "description": "One element covers three kinds of row, and what you give it decides which:\n- Content in the `submenu` slot makes the row open a submenu page.\n- `checked` makes the row a choice.\n- With neither, the row is a command.\n\nThe role follows the kind. A row with `checkable` or `checked` is\n`menuitemcheckbox` with `aria-checked`, and an `exclusive` row is\n`menuitemradio`, for a set where only one can be on. A row that opens a page\nkeeps `menuitem` and sets `aria-haspopup`.\n\nChoosing a choice row checks or unchecks it before `helix-select` is sent,\nso a listener reads the new `checked`. An `exclusive` row turns on and turns\noff the `exclusive` rows next to it. Cancel `helix-before-toggle` to keep a\nrow as it is and set `checked` yourself.\n\nSpace on a choice row changes it and leaves the menu open, so a reader can\nset several in a row, as the APG's menu does. Enter and a press change it and\nclose the menu. `close-on-select=\"false\"` on the row keeps the menu open after\nany choice of it, and `close-on-select` on the row closes it after a Space as\nwell.\n\nThe menu sets whether the row's page is showing as a property, never as an\nattribute. An attribute written onto your element after it upgrades causes a\nhydration mismatch.\n\n`shortcut` shows a row's keyboard shortcut after its label, drawn by `Kbd`\nin the platform's glyphs, and gives the row `aria-keyshortcuts`. It binds\nnothing: the shortcut is the page's to bind. Other trailing words, such as a\ncount, go in the `end` slot.\n\nThe row is named by its label alone. Words in `description`, a line under the\nlabel, and in `end` describe it instead, through `aria-describedby`, as\nReact Aria's menu item does with its description: a reader hears \"Copy\",\nthen \"Copies the selection\".\n\nA development build warns when a row has no words to be named by, such as a\nrow holding only an icon with no label.\n\nThe check mark and the caret are the fallbacks of the `check` and `chevron`\nslots, so a mark of your own replaces either by being slotted. Neither is\nread as part of the row's name.",
106772
106940
  "name": "HelixHeadlessMenuItem",
106773
106941
  "cssParts": [
106774
106942
  {
@@ -106846,7 +107014,7 @@
106846
107014
  "text": "boolean"
106847
107015
  },
106848
107016
  "default": "false",
106849
- "description": "Whether the row is one of a set of choices.\n\nSeparate from `checked`, and it has to be. A row that is off is still a\nchoice, and `checked` alone cannot say so: an unticked row and a row that\nwas never tickable look identical from here. Announcing only the ticked one\nas a checkbox tells a reader its siblings are commands, which is the one\nthing they are not.\n\n`checked` implies it, so a row that is on never has to say both.\n\nChoosing the row checks or unchecks it, after a `helix-before-toggle` that\nyou can cancel.",
107017
+ "description": "Whether the row is one of a set of choices.\n\nSeparate from `checked`, and it has to be. A row that is off is still a\nchoice, and `checked` alone cannot say so: an unticked row and a row that\nwas never tickable look identical from here. Announcing only the ticked one\nas a checkbox tells a reader its siblings are commands, which is the one\nthing they are not.\n\n`checked` and `exclusive` imply it, so a row that is on, or one of a set,\nnever has to say both.\n\nChoosing the row checks or unchecks it, after a `helix-before-toggle` that\nyou can cancel.",
106850
107018
  "attribute": "checkable",
106851
107019
  "reflects": true
106852
107020
  },
@@ -106860,6 +107028,15 @@
106860
107028
  "description": "Whether the row is checked.\n\nThe row changes it when it is chosen. Not reflected: the attribute is the\nstate you start the row in, and `:state(checked)` carries the current one.",
106861
107029
  "attribute": "checked"
106862
107030
  },
107031
+ {
107032
+ "kind": "field",
107033
+ "name": "closeOnSelect",
107034
+ "type": {
107035
+ "text": "boolean | undefined"
107036
+ },
107037
+ "description": "Whether choosing the row closes the menu.\n\nUnset takes the menu's `close-on-select`, which is on, and keeps the menu\nopen after a Space on a choice row. Write `close-on-select=\"false\"` for a\nrow that changes something the reader is watching, such as a zoom step.",
107038
+ "attribute": "close-on-select"
107039
+ },
106863
107040
  {
106864
107041
  "kind": "field",
106865
107042
  "name": "disabled",
@@ -106888,7 +107065,7 @@
106888
107065
  "text": "boolean"
106889
107066
  },
106890
107067
  "default": "false",
106891
- "description": "Whether only one row in its set can be checked at a time.\n\nThe set is the run of `exclusive` rows next to this one, up to the first\nelement that is not one, such as a divider. Choosing a row in it checks\nthat row and unchecks the others. Choosing the row that is checked leaves\nit checked. `menuitemradio` tells a reader which kind of set they are in,\nwhere `menuitemcheckbox` says every row is independent.\n\nMeaningless without `checkable`, since a row that cannot be ticked is not\none of a set of anything.",
107068
+ "description": "Whether only one row in its set can be checked at a time.\n\nThe set is the run of `exclusive` rows next to this one, up to the first\nelement that is not one, such as a divider. Choosing a row in it checks\nthat row and unchecks the others. Choosing the row that is checked leaves\nit checked. `menuitemradio` tells a reader which kind of set they are in,\nwhere `menuitemcheckbox` says every row is independent.\n\nIt makes the row a choice, so it needs no `checkable` beside it.",
106892
107069
  "attribute": "exclusive",
106893
107070
  "reflects": true
106894
107071
  },
@@ -107146,7 +107323,14 @@
107146
107323
  "type": {
107147
107324
  "text": "void"
107148
107325
  }
107149
- }
107326
+ },
107327
+ "parameters": [
107328
+ {
107329
+ "name": "space",
107330
+ "default": "false"
107331
+ }
107332
+ ],
107333
+ "description": "Chooses the row. `space` is whether a Space chose it, which keeps the menu\nopen on a choice row unless the row says otherwise."
107150
107334
  },
107151
107335
  {
107152
107336
  "kind": "field",
@@ -107154,6 +107338,16 @@
107154
107338
  "privacy": "private",
107155
107339
  "readonly": true
107156
107340
  },
107341
+ {
107342
+ "kind": "field",
107343
+ "name": "spacePressed",
107344
+ "type": {
107345
+ "text": "boolean"
107346
+ },
107347
+ "privacy": "private",
107348
+ "default": "false",
107349
+ "description": "Whether the click on its way is the one a Space on a linked row sent."
107350
+ },
107157
107351
  {
107158
107352
  "kind": "field",
107159
107353
  "name": "handleKeydown",
@@ -107545,7 +107739,7 @@
107545
107739
  "text": "boolean"
107546
107740
  },
107547
107741
  "default": "false",
107548
- "description": "Whether the row is one of a set of choices.\n\nSeparate from `checked`, and it has to be. A row that is off is still a\nchoice, and `checked` alone cannot say so: an unticked row and a row that\nwas never tickable look identical from here. Announcing only the ticked one\nas a checkbox tells a reader its siblings are commands, which is the one\nthing they are not.\n\n`checked` implies it, so a row that is on never has to say both.\n\nChoosing the row checks or unchecks it, after a `helix-before-toggle` that\nyou can cancel.",
107742
+ "description": "Whether the row is one of a set of choices.\n\nSeparate from `checked`, and it has to be. A row that is off is still a\nchoice, and `checked` alone cannot say so: an unticked row and a row that\nwas never tickable look identical from here. Announcing only the ticked one\nas a checkbox tells a reader its siblings are commands, which is the one\nthing they are not.\n\n`checked` and `exclusive` imply it, so a row that is on, or one of a set,\nnever has to say both.\n\nChoosing the row checks or unchecks it, after a `helix-before-toggle` that\nyou can cancel.",
107549
107743
  "fieldName": "checkable"
107550
107744
  },
107551
107745
  {
@@ -107557,6 +107751,14 @@
107557
107751
  "description": "Whether the row is checked.\n\nThe row changes it when it is chosen. Not reflected: the attribute is the\nstate you start the row in, and `:state(checked)` carries the current one.",
107558
107752
  "fieldName": "checked"
107559
107753
  },
107754
+ {
107755
+ "name": "close-on-select",
107756
+ "type": {
107757
+ "text": "boolean | undefined"
107758
+ },
107759
+ "description": "Whether choosing the row closes the menu.\n\nUnset takes the menu's `close-on-select`, which is on, and keeps the menu\nopen after a Space on a choice row. Write `close-on-select=\"false\"` for a\nrow that changes something the reader is watching, such as a zoom step.",
107760
+ "fieldName": "closeOnSelect"
107761
+ },
107560
107762
  {
107561
107763
  "name": "disabled",
107562
107764
  "type": {
@@ -107581,7 +107783,7 @@
107581
107783
  "text": "boolean"
107582
107784
  },
107583
107785
  "default": "false",
107584
- "description": "Whether only one row in its set can be checked at a time.\n\nThe set is the run of `exclusive` rows next to this one, up to the first\nelement that is not one, such as a divider. Choosing a row in it checks\nthat row and unchecks the others. Choosing the row that is checked leaves\nit checked. `menuitemradio` tells a reader which kind of set they are in,\nwhere `menuitemcheckbox` says every row is independent.\n\nMeaningless without `checkable`, since a row that cannot be ticked is not\none of a set of anything.",
107786
+ "description": "Whether only one row in its set can be checked at a time.\n\nThe set is the run of `exclusive` rows next to this one, up to the first\nelement that is not one, such as a divider. Choosing a row in it checks\nthat row and unchecks the others. Choosing the row that is checked leaves\nit checked. `menuitemradio` tells a reader which kind of set they are in,\nwhere `menuitemcheckbox` says every row is independent.\n\nIt makes the row a choice, so it needs no `checkable` beside it.",
107585
107787
  "fieldName": "exclusive"
107586
107788
  },
107587
107789
  {
@@ -107703,7 +107905,7 @@
107703
107905
  "declarations": [
107704
107906
  {
107705
107907
  "kind": "class",
107706
- "description": "The trigger is slotted and stays your own element, as with the tooltip. The\nmenu renders its surface in the top layer with the popover API, so an\nancestor with `overflow: hidden` does not clip it and it needs no `z-index`.\n\nSlot a `helix-button` or `helix-icon-button` as the trigger, and the menu\ntells it that it opens a menu and whether the menu is open, inside its own\nshadow root. On a plain element, such as a `<button>`, the menu writes\n`aria-haspopup=\"menu\"` and `aria-expanded`, from a frame after its own first\nrender, so a server's markup is never changed while a framework hydrates it.\nIt never writes `aria-expanded` where you wrote it yourself.\n\nSubmenus drill down by default. A submenu replaces the panel's content, and a\nback row returns to the previous page. One panel stays inside a narrow\nwindow, and works on touch screens, which have no hover.\n\n**`submenus=\"flyout\"` opens each submenu in a panel of its own beside its\nrow**, as React Aria's `SubmenuTrigger` and Radix's `Sub` do. Resting the\npointer on the row opens it, and a pointer crossing toward the open panel\nover the rows between keeps it open, as Radix's grace area does. Right Arrow\nopens a row's submenu on its first row, and Left Arrow or Escape closes it\nand returns focus to the row, the two arrows swapping on a right-to-left\npage. The row says `aria-expanded`, and the panel is a `menu` named by the\nrow.\n\nThe root holds which page is open, because only one page shows at a time. It\nsets this on items as a property, never as an attribute. An attribute written\nonto your element after it upgrades causes a hydration mismatch.\n\nGroup rows under a heading with `Menu.Section`, which is a `group` named by\nits heading. Between runs of rows, a `<helix-divider>` is a separator a\nscreen reader announces.\n\nKeys: Enter, Space or Down Arrow on the trigger opens the menu on its first\nrow, and Up Arrow on its last. In the menu, Up and Down Arrow move between\nrows, Home and End go to the first and the last, a typed letter moves to\nthe next row whose name starts with it, Enter and Space choose, Right Arrow\nopens a row's submenu and Left Arrow goes back, the two swapping on a\nright-to-left page. Left Arrow on the top page does nothing. Escape closes\nthe menu and returns focus to the trigger. Tab closes it and moves on.\n\nWhile it is open, the surface carries the trigger's width as\n`--floating-anchor-inline-size` and the room left below it as\n`--floating-available-block-size`, as Radix's dropdown menu publishes its\ntrigger's width, for a menu as wide as its trigger:\n`helix-menu::part(surface) { min-inline-size: var(--floating-anchor-inline-size) }`.\n\nWith `context`, the trigger is an area and the menu is its context menu: a\nright-click, a long press, Shift+F10 or the menu key over the area opens it\nat the pointer, or at the area's corner from the keyboard, as Radix's context\nmenu does. A press on the area does not open it, and closing it returns focus\nto where it was. A touch or a pen held still on the area opens it too, on\nevery browser, since iOS sends no `contextmenu` for one.\n\n**A trigger with its own action.** With `open-on=\"long-press\"`, a press on\nthe trigger is the trigger's own, and a press held for half a second opens\nthe menu, as React Aria's `trigger=\"longPress\"` does. Alt+Down or Alt+Up\nopens it from the keyboard, and the trigger is described by\n`long-press-label`, which says so.",
107908
+ "description": "The trigger is slotted and stays your own element, as with the tooltip. The\nmenu renders its surface in the top layer with the popover API, so an\nancestor with `overflow: hidden` does not clip it and it needs no `z-index`.\n\nSlot a `helix-button` or `helix-icon-button` as the trigger, and the menu\ntells it that it opens a menu and whether the menu is open, inside its own\nshadow root. On a plain element, such as a `<button>`, the menu writes\n`aria-haspopup=\"menu\"` and `aria-expanded`, from a frame after its own first\nrender, so a server's markup is never changed while a framework hydrates it.\nIt never writes `aria-expanded` where you wrote it yourself.\n\nSubmenus drill down by default. A submenu replaces the panel's content, and a\nback row returns to the previous page. One panel stays inside a narrow\nwindow, and works on touch screens, which have no hover.\n\n**`submenus=\"flyout\"` opens each submenu in a panel of its own beside its\nrow**, as React Aria's `SubmenuTrigger` and Radix's `Sub` do. Resting the\npointer on the row opens it, and a pointer crossing toward the open panel\nover the rows between keeps it open, as Radix's grace area does. Right Arrow\nopens a row's submenu on its first row, and Left Arrow or Escape closes it\nand returns focus to the row, the two arrows swapping on a right-to-left\npage. The row says `aria-expanded`, and the panel is a `menu` named by the\nrow.\n\nThe root holds which page is open, because only one page shows at a time. It\nsets this on items as a property, never as an attribute. An attribute written\nonto your element after it upgrades causes a hydration mismatch.\n\nGroup rows under a heading with `Menu.Section`, which is a `group` named by\nits heading. Between runs of rows, a `<helix-divider>` is a separator a\nscreen reader announces.\n\nKeys: Enter, Space or Down Arrow on the trigger opens the menu on its first\nrow, and Up Arrow on its last. In the menu, Up and Down Arrow move between\nrows, Home and End go to the first and the last, a typed letter moves to\nthe next row whose name starts with it, Enter and Space choose (Space on a\nchoice row changes it and leaves the menu open), Right Arrow\nopens a row's submenu and Left Arrow goes back, the two swapping on a\nright-to-left page. Left Arrow on the top page does nothing. Escape closes\nthe menu and returns focus to the trigger. Tab closes it and moves on.\n\nWhile it is open, the surface carries the trigger's width as\n`--floating-anchor-inline-size` and the room left below it as\n`--floating-available-block-size`, as Radix's dropdown menu publishes its\ntrigger's width, for a menu as wide as its trigger:\n`helix-menu::part(surface) { min-inline-size: var(--floating-anchor-inline-size) }`.\n\nWith `context`, the trigger is an area and the menu is its context menu: a\nright-click, a long press, Shift+F10 or the menu key over the area opens it\nat the pointer, or at the area's corner from the keyboard, as Radix's context\nmenu does. A press on the area does not open it, and closing it returns focus\nto where it was. A touch or a pen held still on the area opens it too, on\nevery browser, since iOS sends no `contextmenu` for one.\n\n**A trigger with its own action.** With `open-on=\"long-press\"`, a press on\nthe trigger is the trigger's own, and a press held for half a second opens\nthe menu, as React Aria's `trigger=\"longPress\"` does. Alt+Down or Alt+Up\nopens it from the keyboard, and the trigger is described by\n`long-press-label`, which says so.",
107707
107909
  "name": "HelixHeadlessMenu",
107708
107910
  "cssProperties": [
107709
107911
  {
@@ -107787,6 +107989,16 @@
107787
107989
  "words": true
107788
107990
  }
107789
107991
  },
107992
+ {
107993
+ "kind": "field",
107994
+ "name": "closeOnSelect",
107995
+ "type": {
107996
+ "text": "boolean"
107997
+ },
107998
+ "default": "true",
107999
+ "description": "Whether choosing a row closes the menu.\n\nOn by default, and a Space on a choice row leaves the menu open either way.\nWrite `close-on-select=\"false\"` to keep the menu open after every choice, as\nArk UI's `closeOnSelect` does. A row's own `close-on-select` wins over this.",
108000
+ "attribute": "close-on-select"
108001
+ },
107790
108002
  {
107791
108003
  "kind": "field",
107792
108004
  "name": "context",
@@ -109146,6 +109358,15 @@
109146
109358
  "description": "The text of the row that returns from a submenu.",
109147
109359
  "fieldName": "backLabel"
109148
109360
  },
109361
+ {
109362
+ "name": "close-on-select",
109363
+ "type": {
109364
+ "text": "boolean"
109365
+ },
109366
+ "default": "true",
109367
+ "description": "Whether choosing a row closes the menu.\n\nOn by default, and a Space on a choice row leaves the menu open either way.\nWrite `close-on-select=\"false\"` to keep the menu open after every choice, as\nArk UI's `closeOnSelect` does. A row's own `close-on-select` wins over this.",
109368
+ "fieldName": "closeOnSelect"
109369
+ },
109149
109370
  {
109150
109371
  "name": "context",
109151
109372
  "type": {
@@ -149963,7 +150184,7 @@
149963
150184
  "text": "number"
149964
150185
  },
149965
150186
  "privacy": "private",
149966
- "description": "The index of the stage the reader is on, or `-1`.",
150187
+ "description": "The index of the stage the reader is on, or `-1`.\n\nRead from `active` once anything has set it, because a move writes\n`active` at once and each step's `current` only on the next update: two\ncalls to `next()` in one task then move two stages.",
149967
150188
  "readonly": true
149968
150189
  },
149969
150190
  {
@@ -192420,6 +192641,6 @@
192420
192641
  ],
192421
192642
  "helix": {
192422
192643
  "package": "@fusion.dev/helix-headless",
192423
- "version": "0.162.1"
192644
+ "version": "0.163.0"
192424
192645
  }
192425
192646
  }
@@ -1,4 +1,4 @@
1
1
  export { HelixHeadlessCanvasEdge } from './edge/canvas-edge.js';
2
2
  export { HelixHeadlessCanvasNode } from './node/canvas-node.js';
3
- export type { CanvasDocument, CanvasEdge, CanvasEdgeProps, CanvasEnd, CanvasNode, CanvasNodeProps, CanvasPath, CanvasSide, CanvasTone, } from './root/canvas-root.js';
3
+ export type { CanvasDocument, CanvasEdge, CanvasEdgeProps, CanvasEnd, CanvasNode, CanvasNodeProps, CanvasPath, CanvasRoute, CanvasRouteEnds, CanvasSide, CanvasTone, } from './root/canvas-root.js';
4
4
  export { fromJsonCanvas, HelixHeadlessCanvas } from './root/canvas-root.js';
@@ -91,6 +91,39 @@ export declare const port: (node: CanvasNode, side: CanvasSide) => {
91
91
  };
92
92
  /** How a connector travels between the two cards it joins. */
93
93
  export type CanvasPath = 'curve' | 'straight' | 'step';
94
+ /** What a board's `edgeRoute` is given for one connection, in the board's own units. */
95
+ export interface CanvasRouteEnds {
96
+ /** The connection. */
97
+ edge: CanvasEdge;
98
+ /** Where it arrives, on the side of the card it arrives at. */
99
+ end: {
100
+ x: number;
101
+ y: number;
102
+ };
103
+ /** The side of the card it leaves. */
104
+ fromSide: CanvasSide;
105
+ /** The route the board would draw: the connection's `path`, or the board's. */
106
+ path: CanvasPath;
107
+ /** Where it leaves, on the side of the card it leaves. */
108
+ start: {
109
+ x: number;
110
+ y: number;
111
+ };
112
+ /** The side of the card it arrives at. */
113
+ toSide: CanvasSide;
114
+ }
115
+ /**
116
+ * Draws a connection's line: its SVG path from `start` to `end`, and where its
117
+ * label sits, the middle of the two ends where it says nothing. Nothing back
118
+ * draws the board's own.
119
+ */
120
+ export type CanvasRoute = (ends: CanvasRouteEnds) => {
121
+ d: string;
122
+ mid?: {
123
+ x: number;
124
+ y: number;
125
+ } | undefined;
126
+ } | undefined;
94
127
  /** A point in the document's own units. */
95
128
  type Point = {
96
129
  x: number;
@@ -1,7 +1,7 @@
1
1
  import { type CanvasView, HelixElement, type ViewportPanDetail, type ViewportWay, type ViewportZoomDetail } from '@fusion.dev/helix-core';
2
2
  import { type PropertyValues, type TemplateResult } from 'lit';
3
- import { type CanvasDocument, type CanvasTone } from './canvas-document.js';
4
- export type { CanvasDocument, CanvasEdge, CanvasEdgeProps, CanvasEnd, CanvasNode, CanvasNodeProps, CanvasPath, CanvasSide, CanvasTone, } from './canvas-document.js';
3
+ import { type CanvasDocument, type CanvasRoute, type CanvasTone } from './canvas-document.js';
4
+ export type { CanvasDocument, CanvasEdge, CanvasEdgeProps, CanvasEnd, CanvasNode, CanvasNodeProps, CanvasPath, CanvasRoute, CanvasRouteEnds, CanvasSide, CanvasTone, } from './canvas-document.js';
5
5
  export { fromJsonCanvas } from './canvas-document.js';
6
6
  declare const HelixHeadlessCanvas_base: (new (...args: any[]) => import("@fusion.dev/helix-core").ViewportElement) & typeof HelixElement;
7
7
  /**
@@ -92,6 +92,17 @@ declare const HelixHeadlessCanvas_base: (new (...args: any[]) => import("@fusion
92
92
  * connection is a new element, and React discards an element the board adds to
93
93
  * its markup on the next render, so you write the connection.
94
94
  *
95
+ * **`edgeRoute` draws the connections' lines your own way**: a function from
96
+ * where a line leaves and arrives, and the sides it does, to its SVG path, for
97
+ * a route such as one that bends around the cards between. What it returns
98
+ * is the line drawn, the line pressed and focused, and the one an arrowhead
99
+ * sits at the end of. Nothing back draws the board's own.
100
+ *
101
+ * Add `minimap` to `controls` for a picture of the whole board in a corner:
102
+ * each card as a box, and a frame around what is on screen. A press or a drag
103
+ * on it brings that place to the middle of the view. It is for a pointer, and
104
+ * a screen reader skips it: the arrow keys and `show()` reach every card.
105
+ *
95
106
  * Cards and connections are `helix-canvas-node` and `helix-canvas-edge`
96
107
  * elements, so they are in the served markup whichever renderer wrote them. The
97
108
  * library fetches nothing, and an array passed to an element is missing from
@@ -148,6 +159,9 @@ declare const HelixHeadlessCanvas_base: (new (...args: any[]) => import("@fusion
148
159
  * @csspart label-editor - The field for editing a connection's label or a group's name, placed over that text.
149
160
  * @csspart live - A live region that screen readers announce while a connection is being made.
150
161
  * @csspart marquee - The box a Shift-drag across the empty board draws, which selects the cards it touches.
162
+ * @csspart minimap - The picture of the whole board, under `controls="minimap"`.
163
+ * @csspart minimap-node - One card in the minimap.
164
+ * @csspart minimap-view - The frame in the minimap around what is on screen.
151
165
  * @csspart pan-down - The button that moves the board down.
152
166
  * @csspart pan-end - The button that moves the board toward the end of a line of text: right in English.
153
167
  * @csspart pan-start - The button that moves the board toward the start of a line of text: left in English.
@@ -210,6 +224,15 @@ export declare class HelixHeadlessCanvas extends HelixHeadlessCanvas_base {
210
224
  controlsLabel: string;
211
225
  /** What screen readers hear after a copy, with `{count}` for the cards copied. */
212
226
  copiedLabel: string;
227
+ /**
228
+ * Draws every connection's line: a function from where it leaves and
229
+ * arrives, and the sides it does, to its SVG path and where its label sits.
230
+ *
231
+ * Absent, or returning nothing for a connection, draws the board's own
232
+ * route. A function that throws draws the board's own too, and the error is
233
+ * reported to the page as an uncaught one. Set it as a property.
234
+ */
235
+ edgeRoute?: CanvasRoute;
213
236
  /** The board's name where `label` is empty. */
214
237
  fallbackLabel: string;
215
238
  /**
@@ -702,6 +725,8 @@ export declare class HelixHeadlessCanvas extends HelixHeadlessCanvas_base {
702
725
  * both its cards are on the board; nothing where either is not.
703
726
  */
704
727
  private geometryOf;
728
+ /** One connection's line, by `edgeRoute` where it draws one, and by the board's own where not. */
729
+ private draw;
705
730
  /** The card an event came from, wherever inside it the event began. */
706
731
  private cardOf;
707
732
  /**
@@ -1244,6 +1269,29 @@ export declare class HelixHeadlessCanvas extends HelixHeadlessCanvas_base {
1244
1269
  * the card a keyboard reader is on.
1245
1270
  */
1246
1271
  private renderDraft;
1272
+ /** The part of the document on screen, in its own units. */
1273
+ private get onScreen();
1274
+ /** What the minimap shows: every card and what is on screen, with room around them. */
1275
+ private get minimapArea();
1276
+ /**
1277
+ * A press or a drag on the minimap, which brings the place under it to the
1278
+ * middle of the view.
1279
+ *
1280
+ * **The point is read through the picture's own scale**: the area is drawn
1281
+ * whole and centered in the box, so the box's spare width or height is split
1282
+ * either side of it.
1283
+ */
1284
+ private readonly handleMinimapPointer;
1285
+ /**
1286
+ * The minimap, under `controls="minimap"`: each card as a box, and a frame
1287
+ * around what is on screen.
1288
+ *
1289
+ * **A picture for a pointer**, hidden from screen readers and taking no
1290
+ * focus, as a map's own overview is: the arrow keys and `show()` already take
1291
+ * a keyboard to any card, and a second way that says nothing a reader can
1292
+ * use would be a stop that does nothing.
1293
+ */
1294
+ private renderMinimap;
1247
1295
  protected render(): TemplateResult;
1248
1296
  }
1249
1297
  declare global {