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
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:
- Convert a DOM event into a screen point relative to the graph container.
- Ask the renderer for
pick(point). - Pass the pick result into an interaction helper.
- Update app state or engine interaction render state.
- 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.