Skip to content

Drag nodes safely

Read as Markdown

Drag a card beyond its painted body and keep its connection attached until the pointer ends.

The card captures one pointer ID on pointer down. useRef stores that gesture synchronously between native events, while rendered state remains frame-coalesced.

Record root-logical pointer and workspace node origins. Each move uses an immutable functional update. Event types expose capture, cancel, and loss notifications.

const dragSession = useRef<NodeDragSession | null>(null);
const onPointerDown = (node: DiagramNode, event: PibblPointerEvent) => {
const pointerStart = rootToWorkspace(event);
event.currentTarget.setPointerCapture(event.pointerId);
dragSession.current = {
kind: "node",
pointerId: event.pointerId,
nodeId: node.id,
pointerStart,
nodeStart: { x: node.x, y: node.y },
};
};
const onPointerMove = (event: PibblPointerEvent) => {
const session = dragSession.current;
if (!session || session.pointerId !== event.pointerId) return;
const point = rootToWorkspace(event);
setNodes((current) =>
current.map((node) =>
node.id === session.nodeId
? {
...node,
x: session.nodeStart.x + point.x - session.pointerStart.x,
y: session.nodeStart.y + point.y - session.pointerStart.y,
}
: node,
),
);
};

Matching the pointer ID prevents a second pointer from stealing the drag. Capturing before the pointer leaves the card prevents outside moves from disappearing; pointer up, cancellation, and capture loss all clear the same session so a stale owner cannot move a node later.

Predict why a move before the next paint still has a current owner. Then clamp positions to x -40..1232 and y -40..816 for generous panning overscan.

Idea moves outside its original card and its edge follows. Release, pointercancel, and lostpointercapture clear the session so later moves cannot change it.

Capture is per pointer ID, and refs retain synchronous gesture ownership. See Manage state and lifecycle.

Open the interactive workbench

Read the Input, focus, and native HTML companion for ownership, adaptation, failure modes, and verification. Agent start provides the version-selection workflow.

Documentation built with @pibbl/core 0.0.2, revision c321a83. ALPHA — NOT FOR PRODUCTION USE.