Skip to content

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

Type Declaration

{ kind: "idle"; }

kind

kind: "idle"

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

delta

delta: Point2D

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

kind

kind: "drag-nodes"

nodeIds

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

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

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

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

delta: Point2D

Cumulative drag delta (snapped if grid active).

groupIds

groupIds: ReadonlySet<string>

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

kind

kind: "drag-groups"

startWorld

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

blocked: boolean

Set when the resized bounds would overlap another group.

delta

delta: Point2D

Cumulative pointer delta in world units (snapped).

groupId

groupId: string

handle

handle: NodeGraphGroupResizeHandle

kind

kind: "resize-group"

startBounds

startBounds: object

Original bounds at the start of the resize.

startBounds.height

height: number

startBounds.width

width: number

startBounds.x

x: number

startBounds.y

y: number

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

candidate

candidate: NodeGraphPortRef | null

Hovered candidate target port, or null when none.

currentWorld

currentWorld: Point2D

Current pointer position in world coordinates.

invalid

invalid: boolean

Whether the candidate is currently rejected by isValidConnection.

kind

kind: "connect"

reconnectEdgeId?

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.

reconnectEnd?

optional reconnectEnd: "source" | "target"

Which end of reconnectEdgeId is being dragged.

source

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

additive: boolean

Whether the additive modifier was held at gesture start.

currentWorld

currentWorld: Point2D

Current pointer position in world coordinates.

kind

kind: "marquee"

startWorld

startWorld: Point2D

Marquee start in world coordinates.