Selection & Accessibility
With interaction.selectable turned on, connections become keyboard- and screen-reader-friendly: each one is a focusable button that can be selected, and Delete asks the app to remove it. The library never changes your data — it only reports what the user did.
const linker = createVisualLinker(el, { interaction: { selectable: true } })
linker.on('connection:selectionchange', ({ selectedIds }) => {})
linker.on('connection:delete-request', ({ connections }) => {}) // you remove them — or don't
linker.setSelectedConnections(['a-b']) // controlled use; emits nothingHow it behaves
- Every connection is focusable. The Tab order is the order of
connections. - A click, or Enter / Space on a focused line, selects that line alone.
- Ctrl, Cmd or Shift together with the click or key toggles the line within a multi-selection.
- Escape, or a pointer press anywhere outside the lines, clears the selection.
- A selectable line shows a pointer cursor, with or without
interaction.hover. - A connection that disappears drops out of the selection.
- Delete or Backspace emits
connection:delete-requestwith the selected connections — or, when the focused line isn't selected, just that one. Nothing is removed.
Look and feel
A selected line gets the same width bump a hover gets plus a halo. Change it with the selected state, which takes the same fields as hover. It sits between the base style and hover: while a line is both selected and hovered, hover wins. The halo color is the theme's selectedHalo (--vl-selected-color); the focus ring on the focused line is focusRing (--vl-focus-color). Markers, ports and labels have a selected state too — see Visual States.
selected
{ color?; width?; dashed?; opacity? } · default: — (unset, the default selected look)
On a connection's style or in the lines group. See Connection Styling.
Accessibility
Every visible line carries role="img" and an aria-label. Without interaction.selectable, the invisible hit path is hidden from assistive technology. With it, the hit path is tabindex="0" with role="button" and aria-pressed, and the focus is drawn on the visible line.
ariaLabel
string · default: "Connection: {from block id} → {to block id}"
On a ConnectionDescriptor. The accessible name of the line.
Options, methods and events
interaction.selectable
boolean · default: false
In the interaction group of the configuration. Off by default, so existing diagrams don't suddenly gain tab stops.
setSelectedConnections(ids: readonly string[]): void
A method of the engine. Replaces the selection. Ids not among the current connections are ignored. It emits no event, so the app can drive the selection without feedback loops.
connection:selectionchange
{ selectedIds: string[] }
The set of selected connections changed because of user input.
connection:delete-request
{ connections: ConnectionDescriptor[] }
Delete or Backspace was pressed on a focused connection.
In Vue
<VisualLinker> takes the selection as the selected prop — an array of connection ids, usable with v-model:selected. Leave it unset to let the engine own the selection. @connection-selectionchange receives the same array, and @connection-delete-request the connections to delete.
<VisualLinker
v-model:selected="selected"
:connections="connections"
:config="{ interaction: { selectable: true } }"
@connection-delete-request="(requested) => remove(requested)"
>
…
</VisualLinker>