Skip to content
Entangle UI v0.13.0

NodeGraphInteractionState

NodeGraphInteractionState = { kind: "idle"; } | { delta: Point2D; kind: "drag-nodes"; nodeIds: ReadonlySet<string>; startWorld: Point2D; } | { blocked: boolean; containedNodeIds: ReadonlySet<string>; delta: Point2D; groupIds: ReadonlySet<string>; kind: "drag-groups"; startWorld: Point2D; } | { blocked: boolean; delta: Point2D; groupId: string; handle: NodeGraphGroupResizeHandle; kind: "resize-group"; startBounds: { height: number; width: number; x: number; y: number; }; } | { candidate: NodeGraphPortRef | null; currentWorld: Point2D; invalid: boolean; kind: "connect"; reconnectEdgeId?: string; reconnectEnd?: "source" | "target"; source: NodeGraphPortRef; } | { additive: boolean; currentWorld: Point2D; kind: "marquee"; startWorld: Point2D; }

Defined in: src/components/editor/NodeGraph/NodeGraphStore.ts:56

{ kind: "idle"; }


{ delta: Point2D; kind: "drag-nodes"; nodeIds: ReadonlySet<string>; startWorld: Point2D; }

delta: Point2D

Cumulative drag delta in world units (snapped if grid active).

kind: "drag-nodes"

nodeIds: ReadonlySet<string>

Ids of nodes being dragged together. Set (not Array) so per-node subscribers can do O(1) membership checks in the hot per-frame selector path — a Cartesian Array.includes was a measurable cost at high node counts when the user dragged the whole selection.

startWorld: Point2D

Pointer-down world position (start of the drag).


{ blocked: boolean; containedNodeIds: ReadonlySet<string>; delta: Point2D; groupIds: ReadonlySet<string>; kind: "drag-groups"; startWorld: Point2D; }

blocked: boolean

True when the projected positions of the dragged groups would overlap any other (non-dragged) group. The HTML overlay paints a rejection state and the pointerup handler refuses to commit when this is set.

containedNodeIds: ReadonlySet<string>

Ids of nodes that were fully contained inside one of the dragged groups at gesture start. They ride along with the group(s) and receive the same drag delta — see rectContains in nodeGraphMath.

delta: Point2D

Cumulative drag delta (snapped if grid active).

groupIds: ReadonlySet<string>

Ids of groups being dragged together. See nodeIds for why Set.

kind: "drag-groups"

startWorld: Point2D

Pointer-down world position.


{ blocked: boolean; delta: Point2D; groupId: string; handle: NodeGraphGroupResizeHandle; kind: "resize-group"; startBounds: { height: number; width: number; x: number; y: number; }; }

blocked: boolean

Set when the resized bounds would overlap another group.

delta: Point2D

Cumulative pointer delta in world units (snapped).

groupId: string

handle: NodeGraphGroupResizeHandle

kind: "resize-group"

startBounds: object

Original bounds at the start of the resize.

height: number

width: number

x: number

y: number


{ candidate: NodeGraphPortRef | null; currentWorld: Point2D; invalid: boolean; kind: "connect"; reconnectEdgeId?: string; reconnectEnd?: "source" | "target"; source: NodeGraphPortRef; }

candidate: NodeGraphPortRef | null

Hovered candidate target port, or null when none.

currentWorld: Point2D

Current pointer position in world coordinates.

invalid: boolean

Whether the candidate is currently rejected by isValidConnection.

kind: "connect"

optional reconnectEdgeId?: string

Set while re-dragging an existing edge’s endpoint. The edge is hidden from the edge layer for the duration so only the preview shows, and the drop either moves the endpoint, deletes the edge (detach), or — on a click with no drag — selects it.

optional reconnectEnd?: "source" | "target"

Which end of reconnectEdgeId is being dragged.

source: NodeGraphPortRef

Fixed endpoint the preview draws from. For a new connection this is the port the drag started on; for a reconnect it’s the other end of the edge being edited (the one staying put).


{ additive: boolean; currentWorld: Point2D; kind: "marquee"; startWorld: Point2D; }

additive: boolean

Whether the additive modifier was held at gesture start.

currentWorld: Point2D

Current pointer position in world coordinates.

kind: "marquee"

startWorld: Point2D

Marquee start in world coordinates.