Skip to content

Interactions ​

The interactions package provides pure helpers for interpreting renderer pick results, viewport math, and app-owned pointer workflows. The optional attachGraphInput binding wires DOM input for vanilla applications. Neither the helpers nor the binding require React or render UI overlays.

State Helpers ​

Current helpers include:

  • hover state from renderer pick results
  • node and edge selection state
  • node drag sessions
  • pan sessions
  • wheel zoom helpers
  • click payload helpers
  • focus viewport helpers
  • lasso state and node hit testing
  • context-menu intent payload helpers
  • tooltip intent payload helpers

These helpers return immutable state or payload objects. Most update helpers return { state, previousState, changed }, allowing integrations to skip redraw work when nothing changed.

Vanilla DOM Binding ​

ts
import { attachGraphInput } from '@graphora/interactions'

const disposeInput = attachGraphInput(container, engine, renderer)
// Before removing the graph:
disposeInput()
engine.destroy()

The binding owns primary-pointer hover, single selection, node dragging, background panning, and wheel zoom. Nodes and edges can be selected. Cancellation releases the gesture without a click; disposal removes listeners and restores touch-action. Mount the renderer on the same container. Add menus, tooltips, and keyboard controls in the application. The React wrapper provides equivalent pointer behavior through its own callback integration.

See the dependency explorer for searchable DOM alternatives to canvas selection, neighbor details, filters, layout switching, and keyboard viewport controls.

App-Owned Listener Flow ​

Vanilla integrations usually follow this pattern:

  1. Convert a DOM event into a screen point relative to the graph container.
  2. Ask the renderer for pick(point).
  3. Pass the pick result into an interaction helper.
  4. Update app state or engine interaction render state.
  5. Let the engine schedule renderer redraws.

The vanilla interaction example covers hover, click selection, dragging, context menus, tooltips, and app-owned status/menu UI.

Selection And Drag ​

Selection state stores selected node IDs and selected edge IDs separately. Node dragging tracks one active node, pointer ID, start/current screen points, current node position, and zoom-aware world delta. Applying a drag uses GraphStore.updateNodePosition.

Lasso Selection ​

Lasso state tracks rectangle or polygon geometry in screen and world space. nodeIdsInLasso identifies nodes in the lasso and applyLassoSelection composes the result with selection state. Edge lasso behavior is deferred.

Context Menus ​

contextMenuEventFromPick creates node, edge, or canvas menu intent payloads with screen point, world point, viewport, and trigger source. Apps own the menu DOM, commands, focus management, and whether to call preventDefault() on the browser event.

Keyboard-triggered menus should provide the screen point where the menu should open, such as the focused item center or viewport center, and pass { trigger: 'keyboard' }.

Tooltips ​

tooltipEventFromPick creates node, edge, or canvas tooltip intent payloads with screen point, world point, viewport, trigger, and delay metadata. Apps own the tooltip DOM, async content, focus behavior, and dismissal.

Tooltip content should not be the only way to access critical graph information. See accessibility-and-input.md for the current accessibility and input-mode quality bar.

Current Boundary ​

The package intentionally stops before global shortcuts, action registries, plugin lifecycles, undo/redo, command palettes, and framework-specific event props. React can adapt these helpers later without changing the core model.

Keyboard focus ​

@graphora/interactions provides pure FocusTarget helpers and configurable shortcut matching. Focus is one immutable node/edge/null value, separate from selection and highlights. moveFocus wraps over application-supplied visible items; reconcileFocus clears an item removed by data updates or filtering. focusToInteractionRenderState preserves all other interaction fields.

Applications own DOM listeners, editable-target classification, command execution, and default prevention. See the interactions package README and the shared keyboard adapter used by vanilla interaction and React callbacks. Optional bindings never capture Tab or install global listeners. A navigation filter is shown for keyboard candidates; general screen-reader companion UI remains future work.