@canvas-harness/react 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +19 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +19 -4
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/context.tsx","../src/hooks/use-interaction.ts","../src/internal/editor-mount.tsx","../src/internal/use-arrow-tool.ts","../src/internal/use-interaction-gesture.ts","../src/internal/use-overlay-host.ts","../src/internal/use-pan-zoom.ts","../src/internal/use-resize-observer.ts","../src/Canvas.tsx","../src/Minimap.tsx","../src/hooks/use-node.ts","../src/hooks/use-edge.ts","../src/hooks/use-selection.ts","../src/hooks/use-camera.ts","../src/hooks/use-presence.ts","../src/hooks/use-history.ts","../src/index.ts"],"names":["jsx","useRef","useEffect","CLICK_MAX_PIXELS","screenToWorld","worldToNodeLocal","projectToNodeBoundary","createPalmRejectionState","notePenActive","shouldRejectTouch","notePenInactive","useState","camera","hitTestAny","jsxs","useSyncExternalStore"],"mappings":"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","file":"index.js","sourcesContent":["import type { CanvasStore } from '@canvas-harness/core'\nimport { type ReactNode, createContext, useContext } from 'react'\n\nconst CanvasContext = createContext<CanvasStore | null>(null)\n\nexport type CanvasProviderProps = {\n store: CanvasStore\n children: ReactNode\n}\n\n/**\n * Provides a {@link CanvasStore} to descendant hooks via context.\n * Wrap your app (or just the canvas + its panels) once at the top\n * level. `<Canvas>` reads the same store from context.\n *\n * @example\n * const store = useRef(createCanvasStore()).current\n * <CanvasProvider store={store}>\n * <Toolbar />\n * <Canvas tool=\"select\" />\n * <Sidebar />\n * </CanvasProvider>\n */\nexport function CanvasProvider({ store, children }: CanvasProviderProps) {\n return <CanvasContext.Provider value={store}>{children}</CanvasContext.Provider>\n}\n\n/**\n * Returns the {@link CanvasStore} from context. Use this when you need\n * to mutate the store from event handlers (e.g. tool buttons, side\n * panels). For reactive reads, prefer the more specific hooks\n * (`useNode`, `useSelection`, `useCamera`, ...).\n *\n * Throws if called outside a `<CanvasProvider>`.\n *\n * @example\n * function ClearButton() {\n * const store = useCanvasStore()\n * return <button onClick={() => store.batch(() => {\n * for (const n of store.getAllNodes()) store.removeNode(n.id)\n * })}>Clear</button>\n * }\n */\nexport function useCanvasStore(): CanvasStore {\n const store = useContext(CanvasContext)\n if (!store) {\n throw new Error(\n 'useCanvasStore() must be used inside <CanvasProvider>. ' +\n 'Wrap your tree with <CanvasProvider store={store}>.',\n )\n }\n return store\n}\n","import type {\n EdgeId,\n InteractionMode,\n InteractionState,\n NodeId,\n PointerInfo,\n} from '@canvas-harness/core'\nimport { useSyncExternalStore } from 'react'\nimport { useCanvasStore } from '../context'\n\n/**\n * Full interaction state. Fires on **any** change — mode flips,\n * pointermoves, drag delta updates, marquee rect updates, ...\n *\n * Most consumers want a narrower hook (`useInteractionMode`,\n * `useCursor`, `useIsMoving`, `useDraggedIds`). Reach for this one only\n * if you need multiple fields together.\n *\n * @example\n * const state = useInteractionState()\n * if (state.mode === 'marqueeing') drawMarqueeOverlay(state.marqueeRect)\n */\nexport function useInteractionState(): InteractionState {\n const store = useCanvasStore()\n return useSyncExternalStore(\n cb => store.subscribe('interaction', cb),\n () => store.getInteractionState(),\n )\n}\n\n/**\n * Just the interaction mode. Re-renders only on mode transitions,\n * never on pointermove.\n *\n * Use to gate heavy effects (\"only run X when mode === 'idle'\") or\n * disable UI affordances during a drag.\n *\n * @example\n * const mode = useInteractionMode()\n * <button disabled={mode !== 'idle'}>Run AI suggestion</button>\n */\nexport function useInteractionMode(): InteractionMode {\n const store = useCanvasStore()\n return useSyncExternalStore(\n cb => {\n let lastMode = store.getInteractionState().mode\n return store.subscribe('interaction', state => {\n if (state.mode !== lastMode) {\n lastMode = state.mode\n cb()\n }\n })\n },\n () => store.getInteractionState().mode,\n )\n}\n\n/**\n * Latest pointer info — `worldX/Y`, `screenX/Y`, `pointerType`,\n * optional `pressure` (for pens). Updated on every pointermove.\n *\n * @example\n * const cursor = useCursor()\n * <div>x: {cursor?.worldX.toFixed(1)}</div>\n */\nexport function useCursor(): PointerInfo | null {\n const store = useCanvasStore()\n return useSyncExternalStore(\n cb => store.subscribe('interaction', cb),\n () => store.getInteractionState().pointer,\n )\n}\n\n/**\n * `true` while the user is panning, zooming, dragging, resizing, or\n * rotating. Derived from {@link useInteractionMode}.\n *\n * Useful for skipping expensive renders during motion (the library\n * does this internally for the bitmap cache; consumers can do the same\n * for custom-node React views).\n *\n * @example\n * const isMoving = useIsMoving()\n * return isMoving ? <Skeleton /> : <ExpensiveChart />\n */\nexport function useIsMoving(): boolean {\n const mode = useInteractionMode()\n return (\n mode === 'panning' ||\n mode === 'zooming' ||\n mode === 'dragging' ||\n mode === 'resizing' ||\n mode === 'rotating'\n )\n}\n\n/**\n * Ids being dragged or resized right now. Empty array when idle (with\n * a stable reference, so consumers can use as a dep).\n *\n * @example\n * const ids = useDraggedIds()\n * useEffect(() => { … }, [ids]) // safe; same array between gestures\n */\nconst EMPTY_DRAGGED: NodeId[] = []\nexport function useDraggedIds(): readonly (NodeId | EdgeId)[] {\n const store = useCanvasStore()\n return useSyncExternalStore(\n cb => store.subscribe('interaction', cb),\n () => {\n const state = store.getInteractionState()\n return state.draggedIds.length === 0 ? EMPTY_DRAGGED : state.draggedIds\n },\n )\n}\n\n/**\n * `true` when the most recent pointer was a stylus. Falls back to\n * `false` before any pointer event has fired.\n *\n * Use to surface pen-specific UI (pressure-aware tools, ink hints).\n *\n * @example\n * const isPen = useIsPenActive()\n * {isPen && <PressureToolbar />}\n */\nexport function useIsPenActive(): boolean {\n const cursor = useCursor()\n return cursor?.pointerType === 'pen'\n}\n","import {\n type CanvasStore,\n type Edge,\n type EditorAdapter,\n type EditorAdapterFactory,\n type Node,\n asNodeId,\n createDefaultTextareaEditor,\n edgeLabelBoundsWorld,\n} from '@canvas-harness/core'\nimport { useEffect, useRef } from 'react'\n\n/**\n * EditorMount — wires an `EditorAdapter` to the in-canvas edit lifecycle.\n * Mounts the adapter at the editing node's screen position; tears it\n * down on commit / cancel.\n *\n * Camera is locked during edit (see `usePanZoom`) so the editor stays\n * pinned to the node it's editing without needing to chase pan/zoom.\n *\n * `factory` defaults to `createDefaultTextareaEditor` (a plain\n * `<textarea>`). Consumers can plug Lexical/ProseMirror/TipTap by\n * passing a custom factory.\n */\nexport function EditorMount({\n store,\n factory = createDefaultTextareaEditor,\n}: {\n store: CanvasStore\n factory?: EditorAdapterFactory\n}) {\n const hostRef = useRef<HTMLDivElement>(null)\n\n useEffect(() => {\n const host = hostRef.current\n if (!host) return\n\n let activeAdapter: EditorAdapter | null = null\n let currentEditingKey: string | null = null\n\n const teardown = (): void => {\n if (activeAdapter) {\n activeAdapter.destroy()\n activeAdapter = null\n }\n currentEditingKey = null\n }\n\n const onInteraction = () => {\n const state = store.getInteractionState()\n const target = state.mode === 'editing' ? state.editingTarget : null\n const key = target ? `${target.kind}:${target.id}` : null\n\n // No-op when state is unchanged.\n if (key === currentEditingKey) return\n\n // Tear down a stale editor (commit/cancel/switch).\n teardown()\n if (!target) return\n\n // Resolve the node passed to the editor adapter. For a node target\n // it's just the node; for an edge target we synthesize a Node that\n // boxes the label's world rect + the edge's style, so the existing\n // textarea editor positions + styles itself correctly.\n let editorNode: Node | null = null\n if (target.kind === 'node') {\n editorNode = store.getNode(target.id) ?? null\n } else {\n const edge = store.getEdge(target.id)\n const geom = store.getEdgeGeometry(target.id)\n if (edge && geom) editorNode = synthesizeLabelNode(edge, geom)\n }\n if (!editorNode) return\n\n currentEditingKey = key\n activeAdapter = factory({\n node: editorNode,\n container: host,\n camera: store.getCamera(),\n dpr: window.devicePixelRatio || 1,\n onCommit: text => {\n store.commitEdit(text)\n },\n onCancel: () => {\n store.cancelEdit()\n },\n })\n }\n\n onInteraction()\n const unsub = store.subscribe('interaction', onInteraction)\n return () => {\n unsub()\n teardown()\n }\n }, [store, factory])\n\n return (\n <div\n ref={hostRef}\n style={{\n position: 'absolute',\n inset: 0,\n pointerEvents: 'none',\n // Children (the textarea) re-enable pointer events themselves.\n }}\n />\n )\n}\n\n/**\n * Builds a synthetic Node that represents an edge's label rect for the\n * editor adapter. The adapter only reads `x/y/w/h/style/content`; the\n * synthetic node won't be stored or rendered as a real node — it's\n * just a positioning + styling vehicle for the textarea.\n */\nconst synthesizeLabelNode = (\n edge: Edge,\n geom: import('@canvas-harness/core').EdgeGeometry,\n): Node | null => {\n // Edge labels default to 'handwriting' (matches node content + the\n // renderer's `drawEdgeLabel` default). Explicit so the textarea\n // editor doesn't fall through to its own default and cause a font\n // flicker on first edit commit.\n const labelStyle = { fontFamily: 'handwriting' as const, ...edge.style }\n\n const bounds = edgeLabelBoundsWorld(edge, geom)\n if (!bounds) {\n // Empty content — fabricate a small box at the label's would-be\n // anchor so the editor still has somewhere to mount.\n if (geom.samples.length < 2) return null\n const mid = geom.samples[Math.floor(geom.samples.length / 2)]!\n return {\n id: asNodeId(`__edge-label:${edge.id}`),\n type: 'text',\n x: mid.x - 60,\n y: mid.y - 12,\n w: 120,\n h: 24,\n angle: 0,\n z: 0,\n groups: [],\n content: '',\n style: labelStyle,\n }\n }\n return {\n id: asNodeId(`__edge-label:${edge.id}`),\n type: 'text',\n x: bounds.x,\n y: bounds.y,\n w: bounds.w,\n h: bounds.h,\n angle: 0,\n z: 0,\n groups: [],\n content: edge.content ?? '',\n style: { ...labelStyle, autoFit: false }, // labels don't autofit height\n }\n}\n","/**\n * useArrowTool — Arrow-tool gesture for edge creation.\n *\n * Flow per ARCHITECTURE.md §6.3:\n * pointerdown over node → start edge with source attached at the\n * clamped boundary point on that node\n * pointerdown empty → start edge with free-floating source\n * pointermove → target follows pointer; if over a candidate\n * node, snap target to that node's boundary\n * pointerup → commit (target = node attachment OR worldPoint)\n *\n * The renderer paints the draft edge from interaction.draftEdge while in\n * mode 'creating-edge'.\n */\nimport {\n type CanvasStore,\n type EdgeEnd,\n type NodeId,\n type Vec2,\n asEdgeId,\n hitTestPoint,\n projectToNodeBoundary,\n screenToWorld,\n worldToNodeLocal,\n} from '@canvas-harness/core'\nimport { useEffect, useRef } from 'react'\n\nconst CLICK_MAX_PIXELS = 4\n\n/**\n * Defaults applied to every edge the arrow tool creates. Lets a\n * consumer (e.g. a style-memory hook) inject the user's last-used\n * pathStyle / arrowheads / style without forcing every edge through\n * a custom factory.\n */\nexport type ArrowToolDefaults = {\n pathStyle?: import('@canvas-harness/core').PathStyle\n style?: import('@canvas-harness/core').EdgeStyle\n}\n\nexport const useArrowTool = (\n ref: React.RefObject<HTMLElement | null>,\n store: CanvasStore,\n enabled: boolean,\n defaults?: ArrowToolDefaults,\n): void => {\n // Refs so the create handler always reads the latest defaults\n // without forcing the listener effect to re-mount on every change.\n const defaultsRef = useRef(defaults)\n defaultsRef.current = defaults\n\n useEffect(() => {\n if (!enabled) return\n const el = ref.current\n if (!el) return\n\n let pointerDownAt: { x: number; y: number } | null = null\n let active = false\n let sourceEnd: EdgeEnd | null = null\n\n const screenFromEvent = (e: PointerEvent): Vec2 => {\n const rect = el.getBoundingClientRect()\n return { x: e.clientX - rect.left, y: e.clientY - rect.top }\n }\n const worldFromEvent = (e: PointerEvent): Vec2 =>\n screenToWorld(screenFromEvent(e), store.getCamera())\n\n /**\n * If the world point lies over a node, returns an attached EdgeEnd\n * with localOffset clamped/projected to that node's boundary.\n * Otherwise returns a free-floating worldPoint end.\n */\n const endFromWorldPoint = (world: Vec2): { end: EdgeEnd; nodeId: NodeId | null } => {\n const hit = hitTestPoint(store, world, store.getCamera().z)\n if (hit && hit.kind === 'body') {\n const node = store.getNode(hit.nodeId)!\n const localOffset = projectToNodeBoundary(world, node)\n return { end: { nodeId: node.id, localOffset }, nodeId: node.id }\n }\n return { end: { worldPoint: world }, nodeId: null }\n }\n\n /** End that just follows the pointer; if over a node, attach via clamped local. */\n const followingEnd = (world: Vec2): { end: EdgeEnd; nodeId: NodeId | null } => {\n const hit = hitTestPoint(store, world, store.getCamera().z)\n if (hit && hit.kind === 'body') {\n const node = store.getNode(hit.nodeId)!\n // For follow-the-pointer, snap to the actual pointer position\n // projected to the node boundary (not \"nearest edge\").\n const local = worldToNodeLocal(world, node)\n const clamped = {\n x: Math.max(0, Math.min(node.w, local.x)),\n y: Math.max(0, Math.min(node.h, local.y)),\n }\n return { end: { nodeId: node.id, localOffset: clamped }, nodeId: node.id }\n }\n return { end: { worldPoint: world }, nodeId: null }\n }\n\n const onPointerDown = (e: PointerEvent) => {\n if (e.button !== 0) return\n pointerDownAt = screenFromEvent(e)\n const world = worldFromEvent(e)\n const { end } = endFromWorldPoint(world)\n sourceEnd = end\n el.setPointerCapture(e.pointerId)\n e.preventDefault()\n }\n\n const onPointerMove = (e: PointerEvent) => {\n if (!pointerDownAt || !sourceEnd) return\n const screen = screenFromEvent(e)\n const dx = screen.x - pointerDownAt.x\n const dy = screen.y - pointerDownAt.y\n // Only start showing the draft once the user moves past the click threshold.\n if (!active && Math.abs(dx) < CLICK_MAX_PIXELS && Math.abs(dy) < CLICK_MAX_PIXELS) return\n active = true\n const world = worldFromEvent(e)\n const { end: target, nodeId: snapTargetNodeId } = followingEnd(world)\n store.setInteractionState({\n mode: 'creating-edge',\n draftEdge: {\n source: sourceEnd,\n target,\n reconnectingId: null,\n snapTargetNodeId,\n },\n })\n }\n\n const onPointerUp = (e: PointerEvent) => {\n if (!pointerDownAt) return\n if (el.hasPointerCapture(e.pointerId)) el.releasePointerCapture(e.pointerId)\n const wasActive = active\n\n if (wasActive && sourceEnd) {\n const world = worldFromEvent(e)\n const { end: target } = endFromWorldPoint(world)\n const d = defaultsRef.current\n store.addEdge({\n id: asEdgeId(store.generateId()),\n source: sourceEnd,\n target,\n pathStyle: d?.pathStyle ?? 'bezier',\n groups: [],\n ...(d?.style ? { style: d.style } : {}),\n })\n }\n\n store.resetInteractionState()\n pointerDownAt = null\n active = false\n sourceEnd = null\n }\n\n const onPointerCancel = (e: PointerEvent) => {\n if (el.hasPointerCapture(e.pointerId)) el.releasePointerCapture(e.pointerId)\n store.resetInteractionState()\n pointerDownAt = null\n active = false\n sourceEnd = null\n }\n\n el.addEventListener('pointerdown', onPointerDown)\n el.addEventListener('pointermove', onPointerMove)\n el.addEventListener('pointerup', onPointerUp)\n el.addEventListener('pointercancel', onPointerCancel)\n return () => {\n el.removeEventListener('pointerdown', onPointerDown)\n el.removeEventListener('pointermove', onPointerMove)\n el.removeEventListener('pointerup', onPointerUp)\n el.removeEventListener('pointercancel', onPointerCancel)\n }\n }, [ref, store, enabled])\n}\n","/**\n * useInteraction — owns the gesture state machine for the Select tool.\n *\n * Handles click-select, shift-toggle, marquee, drag, resize. Talks to the\n * store via setInteractionState (transient) and applyOp/updateNode (commits).\n *\n * The pan/zoom hook (usePanZoom) handles middle-button pan and wheel/pinch\n * zoom; this hook handles primary-button gestures only.\n */\nimport {\n type CanvasStore,\n type DragOriginal,\n type EdgeEnd,\n type EdgeId,\n type NodeId,\n type ResizeHandle,\n type Vec2,\n type WorldRect,\n computeAutoFitHeight,\n createPalmRejectionState,\n hitTestAny,\n marqueeNodes,\n midpointToCubicControls,\n notePenActive,\n notePenInactive,\n projectToNodeBoundary,\n screenToWorld,\n shouldAutoFit,\n shouldRejectTouch,\n worldToNodeLocal,\n} from '@canvas-harness/core'\nimport { useEffect } from 'react'\n\nconst CLICK_MAX_PIXELS = 4 // pointerup within this many pixels of pointerdown = click\n\n/** Touch hold time (ms) before a stationary pointerdown promotes to drag. */\nconst LONG_PRESS_MS = 500\n/** Max pixel movement during the long-press window without canceling it. */\nconst LONG_PRESS_MAX_MOVE_PX = 10\n\nexport type InteractionTool =\n | 'select'\n | 'pan'\n | 'rect'\n | 'ellipse'\n | 'diamond'\n | 'capsule'\n | 'arrow'\n | 'text'\n\nexport const useInteractionGesture = (\n ref: React.RefObject<HTMLElement | null>,\n store: CanvasStore,\n tool: InteractionTool,\n): void => {\n useEffect(() => {\n const el = ref.current\n if (!el) return\n if (tool !== 'select') return // shape tools handle their own clicks in Canvas.tsx\n\n let pointerDownAt: { x: number; y: number } | null = null\n let activeGesture:\n | 'idle'\n | 'click-pending'\n | 'drag'\n | 'resize'\n | 'rotate'\n | 'marquee'\n | 'reconnect-edge'\n | 'edge-midpoint' = 'idle'\n let resizeHandle: ResizeHandle | null = null\n let dragOriginals: DragOriginal[] = []\n let marqueeStartWorld: Vec2 | null = null\n let marqueeShift = false\n let reconnectEdgeId: EdgeId | null = null\n let reconnectEnd: 'source' | 'target' | null = null\n let midpointEdgeId: EdgeId | null = null\n // Rotation gesture state.\n let rotateNodeId: NodeId | null = null\n let rotateOriginAngle = 0 // node.angle at gesture start\n let rotatePointerStartAngle = 0 // pointer angle from node center at gesture start\n\n // Phase 11 — palm rejection + long-press.\n const palm = createPalmRejectionState()\n let longPressTimer: ReturnType<typeof setTimeout> | null = null\n const clearLongPress = (): void => {\n if (longPressTimer !== null) {\n clearTimeout(longPressTimer)\n longPressTimer = null\n }\n }\n\n const screenFromEvent = (e: PointerEvent): Vec2 => {\n const rect = el.getBoundingClientRect()\n return { x: e.clientX - rect.left, y: e.clientY - rect.top }\n }\n\n const worldFromEvent = (e: PointerEvent): Vec2 =>\n screenToWorld(screenFromEvent(e), store.getCamera())\n\n const snapshotOriginals = (ids: NodeId[]): DragOriginal[] => {\n const result: DragOriginal[] = []\n for (const id of ids) {\n const n = store.getNode(id)\n if (n) result.push({ id, x: n.x, y: n.y, w: n.w, h: n.h, angle: n.angle })\n }\n return result\n }\n\n const beginDrag = (ids: NodeId[]): void => {\n dragOriginals = snapshotOriginals(ids)\n store.setInteractionState({\n mode: 'dragging',\n draggedIds: ids,\n dragOriginals,\n dragDelta: { x: 0, y: 0 },\n })\n }\n\n const beginResize = (id: NodeId, handle: ResizeHandle): void => {\n dragOriginals = snapshotOriginals([id])\n store.setInteractionState({\n mode: 'resizing',\n draggedIds: [id],\n dragOriginals,\n resizeHandle: handle,\n resizeLockAspect: false,\n resizeFromCenter: false,\n })\n }\n\n const pointerAngleFromCenter = (\n node: { x: number; y: number; w: number; h: number },\n world: Vec2,\n ): number => {\n const cx = node.x + node.w / 2\n const cy = node.y + node.h / 2\n return Math.atan2(world.y - cy, world.x - cx)\n }\n\n const beginRotate = (id: NodeId, worldAtStart: Vec2): void => {\n const node = store.getNode(id)\n if (!node) return\n rotateNodeId = id\n rotateOriginAngle = node.angle\n rotatePointerStartAngle = pointerAngleFromCenter(node, worldAtStart)\n store.setInteractionState({\n mode: 'rotating',\n draggedIds: [id],\n })\n }\n\n /** Snap angle to 15° increments when Shift is held. */\n const ROTATE_SNAP_RAD = (15 * Math.PI) / 180\n const updateRotate = (worldPoint: Vec2, shift: boolean): void => {\n if (!rotateNodeId) return\n const node = store.getNode(rotateNodeId)\n if (!node) return\n const pointerAngle = pointerAngleFromCenter(node, worldPoint)\n const delta = pointerAngle - rotatePointerStartAngle\n let next = rotateOriginAngle + delta\n if (shift) next = Math.round(next / ROTATE_SNAP_RAD) * ROTATE_SNAP_RAD\n store.updateNode(rotateNodeId, { angle: next })\n }\n\n const commitRotate = (): void => {\n rotateNodeId = null\n store.resetInteractionState()\n }\n\n const updateDrag = (delta: Vec2): void => {\n store.setInteractionState({ dragDelta: delta })\n }\n\n const updateResize = (worldPoint: Vec2, modifiers: { shift: boolean; alt: boolean }): void => {\n const orig = dragOriginals[0]\n if (!orig || !resizeHandle) return\n const next = computeResizeGeometry(orig, resizeHandle, worldPoint, modifiers)\n // Commit live to the store so the static canvas reflects it; phase 3\n // single-node resize. Multi-select group resize is similar but scales\n // each member proportionally — left for §11.6 follow-up.\n store.updateNode(orig.id, next)\n store.setInteractionState({\n resizeLockAspect: modifiers.shift,\n resizeFromCenter: modifiers.alt,\n })\n }\n\n const commitDrag = (): void => {\n const interaction = store.getInteractionState()\n const delta = interaction.dragDelta\n if (delta.x !== 0 || delta.y !== 0) {\n store.batch(() => {\n for (const orig of dragOriginals) {\n store.updateNode(orig.id, { x: orig.x + delta.x, y: orig.y + delta.y })\n }\n })\n }\n store.resetInteractionState()\n }\n\n const commitResize = (): void => {\n // updateResize already committed via store.updateNode each pointermove;\n // we only need to clear the interaction state. The history-aware\n // version (phase 8 undo) will collapse these into one OpBatch.\n // Refit autofit nodes now that the resize stream is over (we\n // suppress mid-stream refit so the user's drag isn't overridden).\n const selected = store.getSelection()\n for (const id of selected) {\n const node = store.getNode(id as NodeId)\n if (!node) continue\n if (!shouldAutoFit(node)) continue\n const fitted = computeAutoFitHeight(node)\n // Grow-only — preserve a user's deliberately-tall node.\n if (fitted > node.h) store.updateNode(node.id, { h: fitted })\n }\n store.resetInteractionState()\n }\n\n const beginMarquee = (start: Vec2, shift: boolean): void => {\n marqueeStartWorld = start\n marqueeShift = shift\n store.setInteractionState({\n mode: 'marqueeing',\n marqueeRect: { x: start.x, y: start.y, w: 0, h: 0 },\n marqueeAdditive: shift,\n })\n }\n\n const updateMarquee = (current: Vec2): void => {\n if (!marqueeStartWorld) return\n const rect: WorldRect = {\n x: Math.min(marqueeStartWorld.x, current.x),\n y: Math.min(marqueeStartWorld.y, current.y),\n w: Math.abs(current.x - marqueeStartWorld.x),\n h: Math.abs(current.y - marqueeStartWorld.y),\n }\n store.setInteractionState({ marqueeRect: rect })\n }\n\n const commitMarquee = (): void => {\n const interaction = store.getInteractionState()\n const rect = interaction.marqueeRect\n if (rect && (rect.w > 0 || rect.h > 0)) {\n const hits = marqueeNodes(store, rect)\n if (marqueeShift) {\n const existing = new Set(store.getSelection() as NodeId[])\n for (const id of hits) existing.add(id)\n store.setSelection([...existing])\n } else {\n store.setSelection(hits)\n }\n }\n store.resetInteractionState()\n }\n\n const onPointerDown = (e: PointerEvent) => {\n if (e.button !== 0) return\n if (e.pointerType === 'pen') notePenActive(palm)\n else if (e.pointerType === 'touch' && shouldRejectTouch(palm, Date.now())) return\n pointerDownAt = screenFromEvent(e)\n const world = worldFromEvent(e)\n const camera = store.getCamera()\n const selection = store.getSelection()\n const selectedNodeIds = new Set<NodeId>()\n const selectedEdgeIds = new Set<EdgeId>()\n for (const id of selection) {\n if (store.getNode(id as NodeId)) selectedNodeIds.add(id as NodeId)\n else if (store.getEdge(id as EdgeId)) selectedEdgeIds.add(id as EdgeId)\n }\n const hit = hitTestAny(store, world, camera.z, selectedNodeIds, selectedEdgeIds)\n\n if (hit?.kind === 'rotate-handle') {\n activeGesture = 'rotate'\n beginRotate(hit.nodeId, world)\n el.setPointerCapture(e.pointerId)\n e.preventDefault()\n return\n }\n\n if (hit?.kind === 'resize-handle') {\n resizeHandle = hit.handle\n activeGesture = 'resize'\n beginResize(hit.nodeId, hit.handle)\n el.setPointerCapture(e.pointerId)\n e.preventDefault()\n return\n }\n\n if (hit?.kind === 'midpoint-handle') {\n midpointEdgeId = hit.edgeId\n activeGesture = 'edge-midpoint'\n el.setPointerCapture(e.pointerId)\n e.preventDefault()\n return\n }\n\n if (hit?.kind === 'source-handle' || hit?.kind === 'target-handle') {\n reconnectEdgeId = hit.edgeId\n reconnectEnd = hit.kind === 'source-handle' ? 'source' : 'target'\n activeGesture = 'reconnect-edge'\n const edge = store.getEdge(hit.edgeId)\n if (edge) {\n store.setInteractionState({\n mode: 'reconnecting-edge',\n draftEdge: {\n source: edge.source,\n target: edge.target,\n reconnectingId: hit.edgeId,\n snapTargetNodeId: null,\n },\n })\n }\n el.setPointerCapture(e.pointerId)\n e.preventDefault()\n return\n }\n\n if (hit?.kind === 'body' && 'nodeId' in hit) {\n const alreadySelected = selectedNodeIds.has(hit.nodeId)\n if (e.shiftKey) {\n const next = new Set(selectedNodeIds)\n if (alreadySelected) next.delete(hit.nodeId)\n else next.add(hit.nodeId)\n store.setSelection([...next])\n } else if (!alreadySelected) {\n store.setSelection([hit.nodeId])\n }\n activeGesture = 'click-pending'\n el.setPointerCapture(e.pointerId)\n // Touch can't hover, so a stationary press should promote to\n // drag after LONG_PRESS_MS. Mouse / pen rely on the existing\n // pixel-threshold path.\n if (e.pointerType === 'touch') {\n const targetIds = e.shiftKey\n ? ([...selectedNodeIds, hit.nodeId] as NodeId[])\n : [hit.nodeId]\n clearLongPress()\n longPressTimer = setTimeout(() => {\n longPressTimer = null\n if (activeGesture !== 'click-pending') return\n activeGesture = 'drag'\n beginDrag(targetIds)\n }, LONG_PRESS_MS)\n }\n e.preventDefault()\n return\n }\n\n // Edge body hit.\n if (hit?.kind === 'body' && 'edgeId' in hit) {\n if (e.shiftKey) {\n const next = new Set(selectedEdgeIds)\n if (selectedEdgeIds.has(hit.edgeId)) next.delete(hit.edgeId)\n else next.add(hit.edgeId)\n store.setSelection([...selectedNodeIds, ...next])\n } else {\n store.setSelection([hit.edgeId])\n }\n activeGesture = 'click-pending'\n el.setPointerCapture(e.pointerId)\n e.preventDefault()\n return\n }\n\n // Click on empty space.\n if (!e.shiftKey) store.setSelection([])\n activeGesture = 'click-pending'\n el.setPointerCapture(e.pointerId)\n }\n\n const onPointerMove = (e: PointerEvent) => {\n if (!pointerDownAt) return\n const screen = screenFromEvent(e)\n const dx = screen.x - pointerDownAt.x\n const dy = screen.y - pointerDownAt.y\n\n // Movement past LONG_PRESS_MAX_MOVE_PX cancels the long-press\n // promotion (user is dragging, not holding still).\n if (\n longPressTimer !== null &&\n (Math.abs(dx) > LONG_PRESS_MAX_MOVE_PX || Math.abs(dy) > LONG_PRESS_MAX_MOVE_PX)\n ) {\n clearLongPress()\n }\n\n // First time pointermove crosses click threshold: decide gesture.\n if (activeGesture === 'click-pending') {\n if (Math.abs(dx) < CLICK_MAX_PIXELS && Math.abs(dy) < CLICK_MAX_PIXELS) return\n const startWorld = screenToWorld(pointerDownAt, store.getCamera())\n const camera = store.getCamera()\n const selectedIds = new Set(\n store.getSelection().filter(id => store.getNode(id as NodeId)) as NodeId[],\n )\n // re-test at the down-position; if it was over a node body, drag it\n const hit = hitTestAny(store, startWorld, camera.z, selectedIds, new Set())\n if (hit?.kind === 'body' && 'nodeId' in hit && selectedIds.has(hit.nodeId)) {\n activeGesture = 'drag'\n beginDrag([...selectedIds])\n } else {\n activeGesture = 'marquee'\n beginMarquee(startWorld, e.shiftKey)\n }\n }\n\n if (activeGesture === 'drag') {\n const camera = store.getCamera()\n updateDrag({ x: dx / camera.z, y: dy / camera.z })\n } else if (activeGesture === 'resize') {\n const world = worldFromEvent(e)\n updateResize(world, { shift: e.shiftKey, alt: e.altKey })\n } else if (activeGesture === 'rotate') {\n updateRotate(worldFromEvent(e), e.shiftKey)\n } else if (activeGesture === 'marquee') {\n updateMarquee(worldFromEvent(e))\n } else if (activeGesture === 'reconnect-edge' && reconnectEdgeId && reconnectEnd) {\n updateReconnect(worldFromEvent(e))\n } else if (activeGesture === 'edge-midpoint' && midpointEdgeId) {\n updateEdgeMidpoint(worldFromEvent(e))\n }\n }\n\n const updateEdgeMidpoint = (world: Vec2): void => {\n if (!midpointEdgeId) return\n const geom = store.getEdgeGeometry(midpointEdgeId)\n if (!geom) return\n const { c1, c2 } = midpointToCubicControls(geom.source, world, geom.target)\n store.updateEdge(midpointEdgeId, { control: [c1, c2] })\n }\n\n const updateReconnect = (world: Vec2): void => {\n if (!reconnectEdgeId || !reconnectEnd) return\n const edge = store.getEdge(reconnectEdgeId)\n if (!edge) return\n const camera = store.getCamera()\n // Follow the pointer; if over another node, snap to that node's\n // boundary (clamped).\n const newEnd = followingEnd(world, camera.z)\n const draftSource = reconnectEnd === 'source' ? newEnd.end : edge.source\n const draftTarget = reconnectEnd === 'target' ? newEnd.end : edge.target\n store.setInteractionState({\n mode: 'reconnecting-edge',\n draftEdge: {\n source: draftSource,\n target: draftTarget,\n reconnectingId: reconnectEdgeId,\n snapTargetNodeId: newEnd.nodeId,\n },\n })\n }\n\n const followingEnd = (\n world: Vec2,\n cameraZ: number,\n ): { end: EdgeEnd; nodeId: NodeId | null } => {\n const hit = hitTestAny(store, world, cameraZ)\n if (hit?.kind === 'body' && 'nodeId' in hit) {\n const node = store.getNode(hit.nodeId)\n if (node) {\n const local = worldToNodeLocal(world, node)\n const clamped = {\n x: Math.max(0, Math.min(node.w, local.x)),\n y: Math.max(0, Math.min(node.h, local.y)),\n }\n return { end: { nodeId: node.id, localOffset: clamped }, nodeId: node.id }\n }\n }\n return { end: { worldPoint: world }, nodeId: null }\n }\n\n const commitReconnect = (e: PointerEvent): void => {\n if (!reconnectEdgeId || !reconnectEnd) return\n const world = worldFromEvent(e)\n // For commit, snap to the boundary (so endpoint isn't inside the rect).\n const hit = hitTestAny(store, world, store.getCamera().z)\n let newEnd: EdgeEnd\n if (hit?.kind === 'body' && 'nodeId' in hit) {\n const node = store.getNode(hit.nodeId)\n if (node) {\n const localOffset = projectToNodeBoundary(world, node)\n newEnd = { nodeId: node.id, localOffset }\n } else {\n newEnd = { worldPoint: world }\n }\n } else {\n newEnd = { worldPoint: world }\n }\n store.updateEdge(\n reconnectEdgeId,\n reconnectEnd === 'source' ? { source: newEnd } : { target: newEnd },\n )\n store.resetInteractionState()\n }\n\n const onPointerUp = (e: PointerEvent) => {\n if (e.pointerType === 'pen') notePenInactive(palm, Date.now())\n clearLongPress()\n if (!pointerDownAt) return\n if (el.hasPointerCapture(e.pointerId)) el.releasePointerCapture(e.pointerId)\n switch (activeGesture) {\n case 'drag':\n commitDrag()\n break\n case 'resize':\n commitResize()\n break\n case 'rotate':\n commitRotate()\n break\n case 'marquee':\n commitMarquee()\n break\n case 'reconnect-edge':\n commitReconnect(e)\n break\n case 'edge-midpoint':\n // updateEdgeMidpoint already wrote each move via store.updateEdge;\n // pointerup just clears the gesture state.\n break\n // 'click-pending' was already handled in pointerdown (selection set);\n // nothing more to do.\n }\n pointerDownAt = null\n activeGesture = 'idle'\n resizeHandle = null\n dragOriginals = []\n marqueeStartWorld = null\n reconnectEdgeId = null\n midpointEdgeId = null\n reconnectEnd = null\n }\n\n const onKeyDown = (e: KeyboardEvent) => {\n // Skip when focus is in an editor (built-in textarea, consumer's\n // <input>, or any contenteditable surface). Otherwise Backspace\n // typed inside the edit overlay bubbles to window and triggers\n // `removeNode` on the selected node — the user types a typo,\n // hits Backspace, and the node they're editing vanishes behind\n // the still-open textarea. Bug surfaces on Escape because that's\n // when the overlay closes and the user sees the empty canvas.\n const target = e.target as HTMLElement | null\n if (\n target &&\n (target.tagName === 'TEXTAREA' || target.tagName === 'INPUT' || target.isContentEditable)\n )\n return\n if (e.key === 'Escape') {\n store.setSelection([])\n store.resetInteractionState()\n }\n if ((e.key === 'Delete' || e.key === 'Backspace') && store.getSelection().length > 0) {\n const ids = store.getSelection()\n store.batch(() => {\n for (const id of ids) {\n if (store.getNode(id as NodeId)) store.removeNode(id as NodeId)\n else if (store.getEdge(id as EdgeId)) store.removeEdge(id as EdgeId)\n }\n })\n store.setSelection([])\n }\n }\n\n el.addEventListener('pointerdown', onPointerDown)\n el.addEventListener('pointermove', onPointerMove)\n el.addEventListener('pointerup', onPointerUp)\n el.addEventListener('pointercancel', onPointerUp)\n window.addEventListener('keydown', onKeyDown)\n return () => {\n el.removeEventListener('pointerdown', onPointerDown)\n el.removeEventListener('pointermove', onPointerMove)\n el.removeEventListener('pointerup', onPointerUp)\n el.removeEventListener('pointercancel', onPointerUp)\n window.removeEventListener('keydown', onKeyDown)\n }\n }, [ref, store, tool])\n}\n\n/**\n * Computes the new node geometry given a resize gesture.\n * Phase 3: single-node resize. Multi-select group resize is similar but\n * scales each member proportionally — left for §11.6 follow-up.\n */\nconst computeResizeGeometry = (\n orig: DragOriginal,\n handle: ResizeHandle,\n pointer: Vec2,\n modifiers: { shift: boolean; alt: boolean },\n): { x: number; y: number; w: number; h: number } => {\n // For phase 3 we only support axis-aligned resize (no rotation handling\n // in the gesture math yet). Rotated resize is a §11.6 follow-up.\n let x = orig.x\n let y = orig.y\n let w = orig.w\n let h = orig.h\n\n const rightFixed = handle === 'nw' || handle === 'w' || handle === 'sw'\n const leftFixed = handle === 'ne' || handle === 'e' || handle === 'se'\n const bottomFixed = handle === 'nw' || handle === 'n' || handle === 'ne'\n const topFixed = handle === 'sw' || handle === 's' || handle === 'se'\n\n if (rightFixed) {\n const right = orig.x + orig.w\n w = Math.max(1, right - pointer.x)\n x = right - w\n } else if (leftFixed) {\n w = Math.max(1, pointer.x - orig.x)\n }\n if (bottomFixed) {\n const bottom = orig.y + orig.h\n h = Math.max(1, bottom - pointer.y)\n y = bottom - h\n } else if (topFixed) {\n h = Math.max(1, pointer.y - orig.y)\n }\n\n if (modifiers.shift) {\n // Lock aspect ratio. Compare the requested w/h ratio to the original\n // and pick whichever dimension produces the smaller change.\n const targetAspect = orig.w / orig.h\n const currentAspect = w / h\n if (currentAspect > targetAspect) {\n w = h * targetAspect\n if (rightFixed) x = orig.x + orig.w - w\n } else {\n h = w / targetAspect\n if (bottomFixed) y = orig.y + orig.h - h\n }\n }\n\n if (modifiers.alt) {\n // Resize from center: mirror the delta across the original center.\n const cx = orig.x + orig.w / 2\n const cy = orig.y + orig.h / 2\n if (handle !== 'n' && handle !== 's') {\n w = Math.max(1, w * 2 - orig.w + (orig.w - Math.abs(orig.w - w * 0)))\n // Simpler: recompute by mirroring whichever side moved\n const newW = Math.abs(pointer.x - cx) * 2\n w = Math.max(1, newW)\n x = cx - w / 2\n }\n if (handle !== 'e' && handle !== 'w') {\n const newH = Math.abs(pointer.y - cy) * 2\n h = Math.max(1, newH)\n y = cy - h / 2\n }\n }\n\n return { x, y, w, h }\n}\n","/**\n * useOverlayHost — tracks the renderer's overlay-mounted custom-node ids.\n *\n * The renderer fires `onOverlayChange` with the new mount set every time\n * LOD or visibility shifts which custom nodes should be in React-rendered\n * land. This hook just keeps a state list of ids; the Canvas component\n * then renders one positioned div per id with the corresponding view.\n *\n * Phase 5 keeps this in the playground; phase 9 formalizes a similar hook\n * in `@canvas-harness/react`.\n */\nimport type { NodeId } from '@canvas-harness/core'\nimport { useEffect, useState } from 'react'\n\nexport const useOverlayHost = (): {\n mountedIds: NodeId[]\n setMountedIds: (ids: NodeId[]) => void\n} => {\n const [mountedIds, setMountedIds] = useState<NodeId[]>([])\n // Stable reference for the renderer callback so the renderer doesn't re-emit.\n useEffect(() => {}, [])\n return { mountedIds, setMountedIds }\n}\n","import {\n type CanvasStore,\n clampZoom,\n createPalmRejectionState,\n notePenActive,\n notePenInactive,\n panByScreen,\n shouldRejectTouch,\n zoomAtScreenPoint,\n} from '@canvas-harness/core'\nimport { useEffect, useRef } from 'react'\n\n/**\n * Wires up wheel zoom, middle-button / spacebar pan, and (phase 11)\n * touch pinch-zoom + two-finger pan + pointer-type write-through.\n *\n * When the active tool is `'pan'` (the Hand tool), any left-button\n * drag pans the camera — equivalent to space-hold + left-drag. The\n * space-hold modifier still works regardless of active tool, so a\n * user can quickly pan mid-edit without switching tools.\n *\n * Pointermove fires faster than the display refreshes (often 120-240Hz).\n * Calling `store.setCamera` on every event saturates the main thread at\n * large scene sizes. Instead we accumulate pending deltas and flush\n * once per rAF, so the store sees at most one camera update per frame\n * regardless of input rate.\n *\n * Phase 11 additions:\n * - Two simultaneous `pointerType: 'touch'` pointers → pinch zoom +\n * two-finger pan (no wheel involved).\n * - Pen pressure / pointerType written to `interaction.pointer` so\n * consumers can read via `useCursor()`.\n * - Palm rejection: touch events ignored while pen is active or for\n * PALM_REJECTION_GRACE_MS after pen-up.\n */\nexport const usePanZoom = (\n ref: React.RefObject<HTMLElement | null>,\n store: CanvasStore,\n /** Active canvas tool. When `'pan'`, left-button drag pans the camera. */\n tool?: string,\n): void => {\n // `tool` is read inside pointer handlers; ref-bind so changes don't\n // tear down + re-mount the whole gesture effect (which would lose\n // in-flight pan state on tool switch — not a real-world risk, but\n // the ref-bind also keeps listeners stable).\n const toolRef = useRef<string | undefined>(tool)\n toolRef.current = tool\n\n useEffect(() => {\n const el = ref.current\n if (!el) return\n\n let panning = false\n let panActivatedBySpace = false\n let lastX = 0\n let lastY = 0\n\n // Per-frame buffers — flushed in flushPending via rAF.\n let pendingDx = 0\n let pendingDy = 0\n let pendingZoomFactor = 1\n let pendingZoomAnchor: { x: number; y: number } | null = null\n let scheduled = false\n let rafId = 0\n\n // Mode-propagation: the canvas wraps every gesture in a `panning`\n // closure flag but never reflected it into the store's interaction\n // mode — which meant `isMoving` stayed false during pan/zoom and\n // none of the motion-LOD optimisations (rough auto-disable, text\n // bitmap downscale, layered fast-path) ever fired.\n //\n // Pointer-driven gestures have explicit start/end events. Wheel\n // events don't — so we keep a deadline and poll it from rAF.\n // (Original implementation used setTimeout per wheel event; on\n // Chrome that's ~5-10µs per clearTimeout+setTimeout pair from\n // timer-heap bookkeeping, which at 120Hz trackpad scroll added\n // ~1ms/frame measurable cost. rAF-poll runs at display rate\n // regardless of input rate — same correctness, ~zero overhead.)\n const MOTION_RESET_MS = 150\n let motionEndDeadline = 0\n let motionEndPolling = false\n const setMotion = (mode: 'panning' | 'zooming' | null): void => {\n const current = store.getInteractionState().mode\n if (mode === null) {\n if (current === 'panning' || current === 'zooming') {\n store.setInteractionState({ mode: 'idle' })\n }\n return\n }\n // Don't overwrite editing or any other deliberate mode.\n if (current !== 'idle' && current !== 'panning' && current !== 'zooming') return\n if (current !== mode) store.setInteractionState({ mode })\n }\n const pollMotionEnd = (): void => {\n if (performance.now() >= motionEndDeadline) {\n motionEndPolling = false\n setMotion(null)\n return\n }\n requestAnimationFrame(pollMotionEnd)\n }\n const pulseMotion = (mode: 'panning' | 'zooming'): void => {\n motionEndDeadline = performance.now() + MOTION_RESET_MS\n // Only fire `setMotion` (which can emit an interaction event)\n // when the mode actually needs to change. Guards inside\n // `setMotion` already do this, but checking here saves the\n // function call entirely for the 99% of wheel events where\n // we're already in the target mode.\n const current = store.getInteractionState().mode\n if (current !== mode) setMotion(mode)\n if (!motionEndPolling) {\n motionEndPolling = true\n requestAnimationFrame(pollMotionEnd)\n }\n }\n\n // Active touch pointers for pinch + two-finger pan. Keyed by\n // pointerId. Only `pointerType: 'touch'` participates here.\n type ActiveTouch = { id: number; x: number; y: number }\n const activeTouches = new Map<number, ActiveTouch>()\n let lastPinchDistance = 0\n let lastPinchMidpoint: { x: number; y: number } | null = null\n\n const palm = createPalmRejectionState()\n\n const flushPending = (): void => {\n scheduled = false\n rafId = 0\n // Apply zoom first; pan applies on top of the new camera so order is intuitive.\n if (pendingZoomFactor !== 1 && pendingZoomAnchor) {\n const camera = store.getCamera()\n store.setCamera(\n zoomAtScreenPoint(camera, clampZoom(camera.z * pendingZoomFactor), pendingZoomAnchor),\n )\n pendingZoomFactor = 1\n pendingZoomAnchor = null\n }\n if (pendingDx !== 0 || pendingDy !== 0) {\n const camera = store.getCamera()\n store.setCamera(panByScreen(camera, { x: pendingDx, y: pendingDy }))\n pendingDx = 0\n pendingDy = 0\n }\n }\n\n const schedule = (): void => {\n if (scheduled) return\n scheduled = true\n rafId = requestAnimationFrame(flushPending)\n }\n\n const isEditing = (): boolean => store.getInteractionState().mode === 'editing'\n\n const screenFromClient = (clientX: number, clientY: number): { x: number; y: number } => {\n const rect = el.getBoundingClientRect()\n return { x: clientX - rect.left, y: clientY - rect.top }\n }\n\n const updatePointerInfo = (e: PointerEvent): void => {\n // Write pointer info to the store so `useCursor()` reads include\n // pointerType + pressure. Cheap — InteractionState is one atom.\n const { x: sx, y: sy } = screenFromClient(e.clientX, e.clientY)\n const camera = store.getCamera()\n store.setInteractionState({\n pointer: {\n worldX: sx / camera.z + camera.x,\n worldY: sy / camera.z + camera.y,\n screenX: sx,\n screenY: sy,\n pointerType: e.pointerType as 'mouse' | 'touch' | 'pen',\n pressure: e.pointerType === 'pen' ? e.pressure : undefined,\n },\n })\n }\n\n const onWheel = (e: WheelEvent) => {\n // Lock camera while editing — textarea overlay is positioned at a\n // fixed screen rect; letting the camera move would desync it.\n if (isEditing()) return\n e.preventDefault()\n if (e.ctrlKey || e.metaKey) {\n // pinch-zoom signal (trackpads send wheel+ctrl)\n const factor = Math.exp(-e.deltaY * 0.01)\n pendingZoomFactor *= factor\n pendingZoomAnchor = screenFromClient(e.clientX, e.clientY)\n pulseMotion('zooming')\n } else {\n pendingDx += -e.deltaX\n pendingDy += -e.deltaY\n pulseMotion('panning')\n }\n schedule()\n }\n\n const resetPinchTracking = (): void => {\n lastPinchDistance = 0\n lastPinchMidpoint = null\n }\n\n const recomputePinchSeed = (): void => {\n // Recompute the seed (distance + midpoint) from the current two\n // touches. Called when entering pinch mode and whenever one of the\n // two touches changes identity (e.g. a third lifted, leaving two).\n const pts = [...activeTouches.values()]\n if (pts.length !== 2) {\n resetPinchTracking()\n return\n }\n const [a, b] = pts\n lastPinchDistance = Math.hypot(a!.x - b!.x, a!.y - b!.y)\n lastPinchMidpoint = { x: (a!.x + b!.x) / 2, y: (a!.y + b!.y) / 2 }\n }\n\n const onPointerDown = (e: PointerEvent) => {\n if (isEditing()) return\n\n if (e.pointerType === 'pen') {\n notePenActive(palm)\n } else if (e.pointerType === 'touch' && shouldRejectTouch(palm, Date.now())) {\n return\n }\n\n // Track touch pointers for pinch.\n if (e.pointerType === 'touch') {\n const pt = screenFromClient(e.clientX, e.clientY)\n activeTouches.set(e.pointerId, { id: e.pointerId, x: pt.x, y: pt.y })\n if (activeTouches.size === 2) {\n recomputePinchSeed()\n el.setPointerCapture(e.pointerId)\n setMotion('zooming')\n e.preventDefault()\n }\n return\n }\n\n // middle button = pan; or left button while space held; or\n // left button while Hand (`pan`) tool is active.\n const handToolActive = toolRef.current === 'pan'\n if (e.button === 1 || (e.button === 0 && (panActivatedBySpace || handToolActive))) {\n panning = true\n lastX = e.clientX\n lastY = e.clientY\n el.setPointerCapture(e.pointerId)\n setMotion('panning')\n e.preventDefault()\n }\n }\n\n const onPointerMove = (e: PointerEvent) => {\n updatePointerInfo(e)\n\n // Pinch path — two touches active.\n if (e.pointerType === 'touch' && activeTouches.has(e.pointerId)) {\n const pt = screenFromClient(e.clientX, e.clientY)\n activeTouches.set(e.pointerId, { id: e.pointerId, x: pt.x, y: pt.y })\n if (activeTouches.size === 2 && lastPinchMidpoint && lastPinchDistance > 0) {\n const pts = [...activeTouches.values()]\n const [a, b] = pts\n const dist = Math.hypot(a!.x - b!.x, a!.y - b!.y)\n const mid = { x: (a!.x + b!.x) / 2, y: (a!.y + b!.y) / 2 }\n const factor = dist / lastPinchDistance\n if (Number.isFinite(factor) && factor > 0) {\n pendingZoomFactor *= factor\n pendingZoomAnchor = mid\n }\n pendingDx += mid.x - lastPinchMidpoint.x\n pendingDy += mid.y - lastPinchMidpoint.y\n lastPinchDistance = dist\n lastPinchMidpoint = mid\n schedule()\n }\n return\n }\n\n if (!panning) return\n const dx = e.clientX - lastX\n const dy = e.clientY - lastY\n lastX = e.clientX\n lastY = e.clientY\n pendingDx += dx\n pendingDy += dy\n schedule()\n }\n\n const onPointerUp = (e: PointerEvent) => {\n if (e.pointerType === 'pen') notePenInactive(palm, Date.now())\n\n if (e.pointerType === 'touch' && activeTouches.has(e.pointerId)) {\n activeTouches.delete(e.pointerId)\n if (el.hasPointerCapture(e.pointerId)) el.releasePointerCapture(e.pointerId)\n // Dropped from 2 → 1: leave pinch mode but keep the remaining\n // touch as a no-op (the gesture hook handles single-touch).\n // Reseed in case three touches collapsed to two.\n if (activeTouches.size === 2) recomputePinchSeed()\n else {\n resetPinchTracking()\n setMotion(null)\n }\n return\n }\n\n if (!panning) return\n panning = false\n if (el.hasPointerCapture(e.pointerId)) el.releasePointerCapture(e.pointerId)\n setMotion(null)\n }\n\n const onPointerCancel = (e: PointerEvent) => {\n // Browser canceled the gesture (e.g. user pulled-to-refresh). Clean up.\n if (e.pointerType === 'touch') {\n activeTouches.delete(e.pointerId)\n if (activeTouches.size < 2) {\n resetPinchTracking()\n setMotion(null)\n }\n }\n if (panning) {\n panning = false\n setMotion(null)\n }\n if (e.pointerType === 'pen') notePenInactive(palm, Date.now())\n }\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.code === 'Space') panActivatedBySpace = true\n }\n const onKeyUp = (e: KeyboardEvent) => {\n if (e.code === 'Space') panActivatedBySpace = false\n }\n\n el.addEventListener('wheel', onWheel, { passive: false })\n el.addEventListener('pointerdown', onPointerDown)\n el.addEventListener('pointermove', onPointerMove)\n el.addEventListener('pointerup', onPointerUp)\n el.addEventListener('pointercancel', onPointerCancel)\n window.addEventListener('keydown', onKeyDown)\n window.addEventListener('keyup', onKeyUp)\n return () => {\n el.removeEventListener('wheel', onWheel)\n el.removeEventListener('pointerdown', onPointerDown)\n el.removeEventListener('pointermove', onPointerMove)\n el.removeEventListener('pointerup', onPointerUp)\n el.removeEventListener('pointercancel', onPointerCancel)\n window.removeEventListener('keydown', onKeyDown)\n window.removeEventListener('keyup', onKeyUp)\n // motion-end rAF poll exits on its own when motionEndPolling\n // becomes false; no explicit cancel needed.\n if (rafId !== 0) cancelAnimationFrame(rafId)\n }\n }, [ref, store])\n}\n","import { useEffect, useState } from 'react'\n\n/**\n * Tracks an element's CSS-pixel size via ResizeObserver.\n * Returns { w, h } in CSS pixels; 0/0 until the first observation.\n */\nexport const useResizeObserver = (ref: React.RefObject<HTMLElement | null>) => {\n const [size, setSize] = useState({ w: 0, h: 0 })\n\n useEffect(() => {\n const el = ref.current\n if (!el) return\n const ro = new ResizeObserver(entries => {\n const entry = entries[0]\n if (!entry) return\n const { width, height } = entry.contentRect\n setSize({ w: Math.round(width), h: Math.round(height) })\n })\n ro.observe(el)\n return () => ro.disconnect()\n }, [ref])\n\n return size\n}\n","import {\n type CanvasBackground,\n type CanvasStore,\n type EditorAdapterFactory,\n type NodeId,\n type Renderer,\n copy,\n createRenderer,\n cut,\n hitTestAny,\n paste,\n screenToWorld,\n} from '@canvas-harness/core'\nimport { type ReactNode, useEffect, useRef, useState } from 'react'\nimport { CanvasProvider, useCanvasStore } from './context'\nimport { useInteractionMode } from './hooks/use-interaction'\nimport { EditorMount } from './internal/editor-mount'\nimport { type ArrowToolDefaults, useArrowTool } from './internal/use-arrow-tool'\nimport { type InteractionTool, useInteractionGesture } from './internal/use-interaction-gesture'\nimport { useOverlayHost } from './internal/use-overlay-host'\nimport { usePanZoom } from './internal/use-pan-zoom'\nimport { useResizeObserver } from './internal/use-resize-observer'\nimport type { ThemeResolver } from './types'\n\n/**\n * Pointer info passed to `onClick` / `onDoubleClick`. Includes the\n * point in both screen space and world space so consumers don't have\n * to convert.\n */\nexport type CanvasPointerEvent = {\n /** Position relative to the canvas element. */\n screen: { x: number; y: number }\n /** Position in scene coordinates (camera-adjusted). */\n world: { x: number; y: number }\n /** Tool active when the event fired. */\n tool: string\n /** The native MouseEvent — read modifiers, button, etc. */\n native: MouseEvent\n}\n\n/**\n * Fired on pointerup after a drag-to-create gesture (non-select tool,\n * drag larger than ~5px). The consumer maps the rect into a new node\n * (defaults, type, style — all consumer policy).\n */\nexport type CanvasCreateDragEvent = {\n /** Bounding rect of the drag, in world coordinates. */\n rect: { x: number; y: number; w: number; h: number }\n /** Tool active when the gesture ended. */\n tool: string\n native: PointerEvent\n}\n\nexport type CanvasProps = {\n /**\n * Optional — when omitted, the component reads the store from\n * `<CanvasProvider>` context. Pass directly for tests or\n * standalone-canvas use.\n */\n store?: CanvasStore\n /**\n * Current tool. The library handles `'select'` and `'arrow'`\n * internally; any other string passes through to `onClick` /\n * `onCreateDrag` so consumers can wire their own shape-create /\n * text-tool / lasso / ... logic.\n */\n tool: string\n /** Theme resolver — see ARCHITECTURE.md §13.10 for the token catalog. */\n theme?: ThemeResolver\n /**\n * Pluggable in-place editor factory; defaults to the built-in\n * `<textarea>`. Implement to swap in Lexical / ProseMirror / TipTap.\n */\n editorAdapter?: EditorAdapterFactory\n /** Called once when the renderer is mounted. Useful for perf overlays. */\n onRenderer?: (r: Renderer) => void\n /** Click on the canvas surface (not over a node handle). */\n onClick?: (e: CanvasPointerEvent) => void\n /** Double-click on the surface. The library has already triggered\n * `beginEdit` if the click landed on a node body. */\n onDoubleClick?: (e: CanvasPointerEvent) => void\n /**\n * Drag-to-create — fires on pointerup when the user dragged with a\n * non-select tool. Sub-threshold drags fall through to `onClick`.\n *\n * @example\n * onCreateDrag={({ rect, tool }) => {\n * if (tool === 'rect') store.addNode({ ...rect, type: 'rect', ... })\n * }}\n */\n onCreateDrag?: (e: CanvasCreateDragEvent) => void\n /**\n * Defaults applied to every edge the built-in arrow tool creates.\n * Lets a consumer remember the user's last-used pathStyle / style /\n * arrowheads. Shape + text tools route through `onClick` /\n * `onCreateDrag` so consumer controls those defaults directly.\n */\n arrowDefaults?: ArrowToolDefaults\n /**\n * Page background + optional infinite dot/grid pattern. Local-only\n * (not part of the synced scene). Update by changing the prop —\n * `<Canvas>` calls `renderer.setBackground` and forces a repaint.\n *\n * @example\n * <Canvas background={{ color: '#fffaf3', pattern: 'dots', gap: 24 }} />\n */\n background?: CanvasBackground\n /**\n * Color for all selection chrome: outline, resize + rotate handles,\n * edge endpoint + midpoint handles, marquee, drag-create preview,\n * and the draft edge during creation. Defaults to `#3b82f6`. Update\n * by changing the prop — `<Canvas>` calls\n * `renderer.setSelectionColor` without recreating the renderer.\n *\n * Accepts any CSS color literal (hex, rgb(), named). Typically you\n * also want to pass the same value to `<Minimap viewportColor={...} />`\n * so the two stay visually in sync.\n *\n * @example\n * <Canvas selectionColor=\"#10b981\" />\n */\n selectionColor?: string\n /**\n * Render a custom node's React subtree. Called once per\n * library-mounted custom-node id; positioning is handled by the\n * overlay container (consumer fills the slot).\n *\n * @example\n * renderCustomNodeView={id => {\n * const node = store.getNode(id)\n * if (node?.type === 'chart-card') return <ChartCardView node={node} />\n * return null\n * }}\n */\n renderCustomNodeView?: (id: NodeId) => ReactNode\n /** Extra content rendered inside the canvas absolute container. */\n children?: ReactNode\n}\n\n/**\n * Mounts the canvas surface (static + interactive layers + DOM overlay\n * for custom-node views + in-place editor mount). Owns the renderer\n * lifecycle, gesture hooks, resize observer.\n *\n * Use inside a {@link CanvasProvider} (or pass `store` directly).\n *\n * @example\n * function App() {\n * const store = useRef(createCanvasStore()).current\n * const [tool, setTool] = useState('select')\n * return (\n * <CanvasProvider store={store}>\n * <Canvas\n * tool={tool}\n * onClick={e => console.log('click at', e.world)}\n * onCreateDrag={e => {\n * store.addNode({ id: asNodeId(store.generateId()), type: e.tool, ...e.rect, angle: 0, z: 0, groups: [] })\n * }}\n * />\n * <Toolbar onSelect={setTool} />\n * </CanvasProvider>\n * )\n * }\n */\nexport function Canvas(props: CanvasProps) {\n if (props.store) {\n return (\n <CanvasProvider store={props.store}>\n <CanvasSurface {...props} />\n </CanvasProvider>\n )\n }\n return <CanvasSurface {...props} />\n}\n\n/** Minimum pointer-drag (screen px) below which a drag-create falls\n * through to `onClick`. Same heuristic tldraw uses. */\nconst DRAG_CREATE_MIN_SIZE_PX = 5\n\nfunction CanvasSurface({\n tool,\n theme,\n editorAdapter,\n onRenderer,\n onClick,\n onDoubleClick,\n onCreateDrag,\n arrowDefaults,\n background,\n selectionColor,\n renderCustomNodeView,\n children,\n}: CanvasProps) {\n const store = useCanvasStore()\n const wrapRef = useRef<HTMLDivElement>(null)\n const staticRef = useRef<HTMLCanvasElement>(null)\n const interactiveRef = useRef<HTMLCanvasElement>(null)\n const overlayRef = useRef<HTMLDivElement>(null)\n const rendererRef = useRef<Renderer | null>(null)\n const toolRef = useRef(tool)\n toolRef.current = tool\n\n const { w, h } = useResizeObserver(wrapRef)\n usePanZoom(wrapRef, store, tool)\n useInteractionGesture(wrapRef, store, tool as InteractionTool)\n const interactionMode = useInteractionMode()\n useArrowTool(wrapRef, store, tool === 'arrow', arrowDefaults)\n\n const { mountedIds, setMountedIds } = useOverlayHost()\n const [camera, setCamera] = useState(() => store.getCamera())\n\n useEffect(() => store.subscribe('camera', c => setCamera({ ...c })), [store])\n\n // Renderer lifecycle. Creates on first mount + size>0; disposes on\n // unmount. `background` and `selectionColor` are intentionally\n // omitted from the dep array — their updates flow through the\n // separate setBackground / setSelectionColor effects below so the\n // renderer isn't torn down on every prop change.\n // biome-ignore lint/correctness/useExhaustiveDependencies: see comment above\n useEffect(() => {\n if (!staticRef.current || !interactiveRef.current || w === 0 || h === 0) return\n if (rendererRef.current) {\n rendererRef.current.setSize(w, h)\n return\n }\n const r = createRenderer({\n store,\n staticCanvas: staticRef.current,\n interactiveCanvas: interactiveRef.current,\n theme,\n width: w,\n height: h,\n background,\n selectionColor,\n onOverlayChange: ids => setMountedIds(ids),\n })\n r.start()\n rendererRef.current = r\n onRenderer?.(r)\n return () => {\n r.dispose()\n rendererRef.current = null\n }\n // `background` + `selectionColor` intentionally omitted — we\n // forward updates via the separate setBackground /\n // setSelectionColor effects below so the renderer isn't torn down\n // on every prop change.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [store, theme, w, h, onRenderer, setMountedIds])\n\n // Forward background prop updates without re-creating the renderer.\n useEffect(() => {\n rendererRef.current?.setBackground(background)\n }, [background])\n\n // Forward selectionColor updates the same way — runtime swap, no rebuild.\n useEffect(() => {\n if (selectionColor !== undefined) rendererRef.current?.setSelectionColor(selectionColor)\n }, [selectionColor])\n\n // Surface-level click — fires for any unhandled click (gesture hooks\n // consume their own). Consumer uses this to implement shape-tool /\n // text-tool create.\n useEffect(() => {\n const el = wrapRef.current\n if (!el) return\n const dispatch = (e: MouseEvent, cb: ((ev: CanvasPointerEvent) => void) | undefined): void => {\n if (!cb) return\n const rect = el.getBoundingClientRect()\n const screen = { x: e.clientX - rect.left, y: e.clientY - rect.top }\n const world = screenToWorld(screen, store.getCamera())\n cb({ screen, world, tool: toolRef.current, native: e })\n }\n const onClickHandler = (e: MouseEvent) => dispatch(e, onClick)\n const onDoubleClickHandler = (e: MouseEvent) => {\n // Built-in: dbl-click a node body OR an edge label → beginEdit.\n // Consumer's onDoubleClick fires too if provided (e.g. for the\n // \"dbl-click empty board to create a text node\" pattern).\n if (toolRef.current === 'select') {\n const rect = el.getBoundingClientRect()\n const screen = { x: e.clientX - rect.left, y: e.clientY - rect.top }\n const camera = store.getCamera()\n const world = screenToWorld(screen, camera)\n const hit = hitTestAny(store, world, camera.z)\n if (hit && hit.kind === 'body' && 'nodeId' in hit) {\n store.beginEdit(hit.nodeId)\n } else if (hit && hit.kind === 'body' && 'edgeId' in hit) {\n store.beginEdit(hit.edgeId)\n } else if (hit && hit.kind === 'label') {\n store.beginEdit(hit.edgeId)\n } else if (hit && hit.kind === 'midpoint-handle') {\n // Dbl-click the midpoint → restore auto-route.\n store.updateEdge(hit.edgeId, { control: undefined })\n }\n }\n dispatch(e, onDoubleClick)\n }\n el.addEventListener('click', onClickHandler)\n el.addEventListener('dblclick', onDoubleClickHandler)\n return () => {\n el.removeEventListener('click', onClickHandler)\n el.removeEventListener('dblclick', onDoubleClickHandler)\n }\n }, [store, onClick, onDoubleClick])\n\n // `justCommittedRef` lives at component scope (not inside the\n // gesture useEffect) so it survives effect remounts triggered by\n // any `onCreateDrag` reference change. Otherwise: a setState from\n // anywhere in the tree between pointerup and the synthetic click\n // would remount the effect, reset the flag, and let the click\n // through — producing a phantom tap-to-create node at the drop\n // point. See README / regression note (May 2026).\n const justCommittedRef = useRef(false)\n\n // Drag-to-create for non-select tools. tldraw/excalidraw style:\n // press at corner-A, drag to corner-B, release → shape sized to the\n // dragged rect. Sub-threshold drags fall through to onClick so a\n // tap still creates a default-size shape.\n useEffect(() => {\n const el = wrapRef.current\n if (!el || !onCreateDrag) return\n let startWorld: { x: number; y: number } | null = null\n let startScreen: { x: number; y: number } | null = null\n let activePointerId: number | null = null\n let committed = false\n\n const screenFromEvent = (e: PointerEvent): { x: number; y: number } => {\n const rect = el.getBoundingClientRect()\n return { x: e.clientX - rect.left, y: e.clientY - rect.top }\n }\n const worldFromEvent = (e: PointerEvent): { x: number; y: number } =>\n screenToWorld(screenFromEvent(e), store.getCamera())\n\n const isShapeTool = (t: string): boolean => t !== 'select' && t !== 'arrow' && t !== 'text'\n\n const onPointerDown = (e: PointerEvent): void => {\n if (e.button !== 0) return\n if (!isShapeTool(toolRef.current)) return\n if (store.getInteractionState().mode === 'editing') return\n // Only engage on empty surface — clicks on existing nodes should\n // not initiate a create. Cheap broad-phase: hit-test the world point.\n const camera = store.getCamera()\n const world = screenToWorld(screenFromEvent(e), camera)\n if (hitTestAny(store, world, camera.z)) return\n\n startWorld = world\n startScreen = screenFromEvent(e)\n activePointerId = e.pointerId\n committed = false\n el.setPointerCapture(e.pointerId)\n }\n\n const onPointerMove = (e: PointerEvent): void => {\n if (startWorld === null || startScreen === null) return\n if (e.pointerId !== activePointerId) return\n const screen = screenFromEvent(e)\n const dx = screen.x - startScreen.x\n const dy = screen.y - startScreen.y\n if (\n !committed &&\n Math.abs(dx) < DRAG_CREATE_MIN_SIZE_PX &&\n Math.abs(dy) < DRAG_CREATE_MIN_SIZE_PX\n ) {\n return\n }\n // Cross the threshold → enter creating-shape mode + paint preview.\n if (!committed) committed = true\n const world = worldFromEvent(e)\n const rect = {\n x: Math.min(startWorld.x, world.x),\n y: Math.min(startWorld.y, world.y),\n w: Math.abs(world.x - startWorld.x),\n h: Math.abs(world.y - startWorld.y),\n }\n store.setInteractionState({\n mode: 'creating-shape',\n createDraftRect: rect,\n createTool: toolRef.current,\n })\n }\n\n const onPointerUp = (e: PointerEvent): void => {\n if (activePointerId !== e.pointerId) return\n if (el.hasPointerCapture(e.pointerId)) el.releasePointerCapture(e.pointerId)\n const wasCommitted = committed\n activePointerId = null\n if (!wasCommitted || !startWorld) {\n startWorld = null\n startScreen = null\n return\n }\n const world = worldFromEvent(e)\n const rect = {\n x: Math.min(startWorld.x, world.x),\n y: Math.min(startWorld.y, world.y),\n w: Math.abs(world.x - startWorld.x),\n h: Math.abs(world.y - startWorld.y),\n }\n startWorld = null\n startScreen = null\n // Reset interaction state before firing the callback so consumer\n // sees an idle store.\n store.resetInteractionState()\n // Suppress the synthetic click that browsers fire after a successful drag.\n justCommittedRef.current = true\n setTimeout(() => {\n justCommittedRef.current = false\n }, 0)\n onCreateDrag({ rect, tool: toolRef.current, native: e })\n }\n\n const onClickCapture = (e: MouseEvent): void => {\n if (justCommittedRef.current) {\n e.stopPropagation()\n e.preventDefault()\n }\n }\n\n el.addEventListener('pointerdown', onPointerDown)\n el.addEventListener('pointermove', onPointerMove)\n el.addEventListener('pointerup', onPointerUp)\n el.addEventListener('pointercancel', onPointerUp)\n // Capture phase so we run BEFORE the click dispatcher.\n el.addEventListener('click', onClickCapture, true)\n return () => {\n el.removeEventListener('pointerdown', onPointerDown)\n el.removeEventListener('pointermove', onPointerMove)\n el.removeEventListener('pointerup', onPointerUp)\n el.removeEventListener('pointercancel', onPointerUp)\n el.removeEventListener('click', onClickCapture, true)\n }\n }, [store, onCreateDrag])\n\n // Cmd/Ctrl+C/X/V — copy/cut/paste. Skip when an input is focused so\n // the editor's native text-clipboard isn't hijacked.\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n const target = e.target as HTMLElement | null\n if (target && (target.tagName === 'TEXTAREA' || target.tagName === 'INPUT')) return\n const meta = e.metaKey || e.ctrlKey\n if (!meta) return\n if (e.key === 'c' || e.key === 'C') {\n e.preventDefault()\n void copy(store)\n } else if (e.key === 'x' || e.key === 'X') {\n e.preventDefault()\n void cut(store)\n } else if (e.key === 'v' || e.key === 'V') {\n e.preventDefault()\n void paste(store)\n } else if (e.key === ']') {\n // Cmd+] = bring forward; Cmd+Shift+] = bring to front.\n const selection = store.getSelection()\n if (selection.length === 0) return\n e.preventDefault()\n if (e.shiftKey) store.bringToFront(selection)\n else store.bringForward(selection)\n } else if (e.key === '[') {\n // Cmd+[ = send backward; Cmd+Shift+[ = send to back.\n const selection = store.getSelection()\n if (selection.length === 0) return\n e.preventDefault()\n if (e.shiftKey) store.sendToBack(selection)\n else store.sendBackward(selection)\n }\n }\n window.addEventListener('keydown', onKey)\n return () => window.removeEventListener('keydown', onKey)\n }, [store])\n\n // CSS transform on overlay div so child positions in world coords follow camera with one composite op.\n const overlayTransform = `translate(${-camera.x * camera.z}px, ${-camera.y * camera.z}px) scale(${camera.z})`\n\n return (\n <div\n ref={wrapRef}\n data-canvas-host=\"\"\n style={{\n position: 'absolute',\n inset: 0,\n background: '#f8fafc',\n overflow: 'hidden',\n cursor:\n tool === 'pan'\n ? interactionMode === 'panning'\n ? 'grabbing'\n : 'grab'\n : tool === 'select'\n ? 'default'\n : 'crosshair',\n touchAction: 'none',\n }}\n >\n <canvas ref={staticRef} style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }} />\n <div\n ref={overlayRef}\n style={{\n position: 'absolute',\n inset: 0,\n transformOrigin: '0 0',\n transform: overlayTransform,\n pointerEvents: 'none',\n }}\n >\n {renderCustomNodeView\n ? mountedIds.map(id => (\n <OverlayItem key={id} id={id}>\n {renderCustomNodeView(id)}\n </OverlayItem>\n ))\n : null}\n </div>\n <canvas\n ref={interactiveRef}\n style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}\n />\n <EditorMount store={store} factory={editorAdapter} />\n {children}\n </div>\n )\n}\n\n/**\n * One mounted custom-node React subtree. Positions itself at the node's\n * world coords; the overlay parent CSS-transform handles camera.\n *\n * Re-reads the node on each 'change' event (Phase-9 simplification; a\n * future hook tightening pass could narrow to per-id subscription).\n */\nfunction OverlayItem({ id, children }: { id: NodeId; children: ReactNode }) {\n const store = useCanvasStore()\n const [node, setNode] = useState(() => store.getNode(id))\n useEffect(() => {\n return store.subscribe('change', () => setNode(store.getNode(id)))\n }, [id, store])\n if (!node) return null\n return (\n <div\n style={{\n position: 'absolute',\n left: node.x,\n top: node.y,\n width: node.w,\n height: node.h,\n transform: node.angle !== 0 ? `rotate(${node.angle}rad)` : undefined,\n transformOrigin: 'center',\n }}\n >\n {children}\n </div>\n )\n}\n","import {\n DEFAULT_MINIMAP_MAX_NODES,\n drawMinimapViewport,\n minimapScreenToWorld,\n renderMinimapContent,\n sceneBounds,\n worldViewportFromCamera,\n} from '@canvas-harness/core'\nimport { type CSSProperties, useEffect, useRef, useState } from 'react'\nimport { useCanvasStore } from './context'\n\n/**\n * Bird's-eye overview of the entire scene + a viewport rectangle\n * showing where the camera is. Click or drag inside to pan.\n *\n * Perf model — see IMPROVEMENTS.md and core/render/minimap.ts:\n * - Scene content is rendered into an offscreen-canvas cache **once\n * per committed batch** (`'change'` event). Cost: O(N) per\n * commit, not per frame.\n * - On camera changes (pan/zoom), only the viewport rectangle is\n * redrawn over the cached image. Cost: O(1) per frame.\n * - Above `maxNodes`, the content render is skipped and a small\n * placeholder text is shown instead.\n *\n * @example\n * <Minimap width={200} height={150} position=\"bottom-right\" />\n */\nexport type MinimapProps = {\n /** Map width in CSS px. Default 200. */\n width?: number\n /** Map height in CSS px. Default 150. */\n height?: number\n /** Above this many nodes, content render is skipped (placeholder\n * shown instead). Default 5000. */\n maxNodes?: number\n /** Fixed-position corner shortcut. Use `style` for custom placement. */\n position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'\n /** Override container styles entirely (skip `position`). */\n style?: CSSProperties\n /** Color of the viewport rect overlay. Default brand blue. */\n viewportColor?: string\n /** Background color drawn behind the cached content + applied to the\n * default container background. Default white. */\n backgroundColor?: string\n /** Container border color (the surrounding chip). Default light slate. */\n borderColor?: string\n /** Fallback node color when a node has no `style.backgroundColor`.\n * Default neutral slate. */\n defaultNodeColor?: string\n}\n\nconst POSITION_STYLES: Record<NonNullable<MinimapProps['position']>, CSSProperties> = {\n 'top-left': { top: 12, left: 12 },\n 'top-right': { top: 12, right: 12 },\n 'bottom-left': { bottom: 12, left: 12 },\n 'bottom-right': { bottom: 12, right: 12 },\n}\n\nexport function Minimap({\n width = 200,\n height = 150,\n maxNodes = DEFAULT_MINIMAP_MAX_NODES,\n position = 'bottom-right',\n style,\n viewportColor = '#3b82f6',\n backgroundColor = '#ffffff',\n borderColor = '#cbd5e1',\n defaultNodeColor = '#94a3b8',\n}: MinimapProps) {\n const store = useCanvasStore()\n const containerRef = useRef<HTMLDivElement>(null)\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const cacheRef = useRef<HTMLCanvasElement | null>(null)\n const cachedBoundsRef = useRef<ReturnType<typeof sceneBounds>>(null)\n // Set on 'change' — repaint regenerates the cache the next tick.\n // Camera-only ticks reuse the cache (just blit + draw viewport).\n const dirtyRef = useRef(true)\n const rafRef = useRef(0)\n const [overCap, setOverCap] = useState(false)\n\n // Build the offscreen cache canvas once per size.\n useEffect(() => {\n const c = document.createElement('canvas')\n const dpr = window.devicePixelRatio || 1\n c.width = Math.ceil(width * dpr)\n c.height = Math.ceil(height * dpr)\n cacheRef.current = c\n dirtyRef.current = true\n }, [width, height])\n\n // Schedule a repaint (rAF-coalesced).\n const schedule = (): void => {\n if (rafRef.current !== 0) return\n rafRef.current = requestAnimationFrame(() => {\n rafRef.current = 0\n repaint()\n })\n }\n\n /**\n * Approach C — scene content cached on every committed mutation;\n * camera ticks reuse the cache + draw a fresh viewport rect on top.\n *\n * - `dirty?` regen cache (O(N), once per `'change'` event) + blit.\n * - `clean?` blit cache + draw viewport rect (O(1) per camera tick).\n *\n * Drops per-pan-frame work from ~0.5ms to ~0.02ms at 5k nodes. The\n * differentiator over react-flow's per-frame-O(N) approach.\n */\n const repaint = (): void => {\n const canvas = canvasRef.current\n if (!canvas) return\n const ctx = canvas.getContext('2d')\n if (!ctx) return\n const dpr = window.devicePixelRatio || 1\n\n if (dirtyRef.current) {\n const cache = cacheRef.current\n if (cache) {\n const cctx = cache.getContext('2d')\n if (cctx) {\n cctx.setTransform(dpr, 0, 0, dpr, 0, 0)\n cctx.clearRect(0, 0, width, height)\n cctx.fillStyle = backgroundColor\n cctx.fillRect(0, 0, width, height)\n const ok = renderMinimapContent(cctx, store, width, height, {\n maxNodes,\n defaultNodeColor,\n })\n cachedBoundsRef.current = ok ? sceneBounds(store) : null\n setOverCap(!ok && store.getNodeCount() > maxNodes)\n }\n }\n dirtyRef.current = false\n }\n\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0)\n ctx.clearRect(0, 0, width, height)\n if (cacheRef.current) {\n // Cache canvas is dpr-sized in physical pixels; drawn at logical\n // (width × height) under the current dpr transform → 1:1 mapping.\n ctx.drawImage(cacheRef.current, 0, 0, width, height)\n } else {\n ctx.fillStyle = backgroundColor\n ctx.fillRect(0, 0, width, height)\n }\n\n const bounds = cachedBoundsRef.current\n if (bounds && bounds.w > 0 && bounds.h > 0) {\n const camera = store.getCamera()\n const wrap = containerRef.current?.closest<HTMLElement>('[data-canvas-host]')\n const screenW = wrap?.clientWidth ?? window.innerWidth\n const screenH = wrap?.clientHeight ?? window.innerHeight\n drawMinimapViewport(\n ctx,\n worldViewportFromCamera(camera, screenW, screenH),\n bounds,\n width,\n height,\n viewportColor,\n )\n }\n }\n\n // Subscribe to relevant store events. `schedule` is stable for the\n // lifetime of this component (closure captures a ref) — adding it\n // would needlessly re-subscribe on every render.\n // biome-ignore lint/correctness/useExhaustiveDependencies: see comment above\n useEffect(() => {\n const onChange = (): void => {\n // Committed mutation — cache needs to regen on next tick.\n dirtyRef.current = true\n schedule()\n }\n const onCamera = (): void => {\n // Pan/zoom — cache is fine, just re-blit + redraw the viewport.\n schedule()\n }\n const unsubChange = store.subscribe('change', onChange)\n const unsubCamera = store.subscribe('camera', onCamera)\n // Initial paint.\n schedule()\n return () => {\n unsubChange()\n unsubCamera()\n if (rafRef.current !== 0) {\n cancelAnimationFrame(rafRef.current)\n // Must reset to 0; otherwise schedule() short-circuits on the\n // next mount thinking an rAF is still pending (it's not — we\n // just cancelled it). Surfaces under React StrictMode.\n rafRef.current = 0\n }\n }\n // schedule + repaint are stable; eslint can't see that.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [store])\n\n // Click + drag to pan the camera.\n useEffect(() => {\n const canvas = canvasRef.current\n if (!canvas) return\n let dragging = false\n const move = (e: PointerEvent): void => {\n const rect = canvas.getBoundingClientRect()\n const worldCenter = minimapScreenToWorld(\n store,\n e.clientX - rect.left,\n e.clientY - rect.top,\n width,\n height,\n )\n if (!worldCenter) return\n const wrap = containerRef.current?.closest<HTMLElement>('[data-canvas-host]')\n const screenW = wrap?.clientWidth ?? window.innerWidth\n const screenH = wrap?.clientHeight ?? window.innerHeight\n const camera = store.getCamera()\n // Center the viewport on the clicked world point.\n store.setCamera({\n x: worldCenter.x - screenW / camera.z / 2,\n y: worldCenter.y - screenH / camera.z / 2,\n })\n }\n const down = (e: PointerEvent): void => {\n if (e.button !== 0) return\n dragging = true\n canvas.setPointerCapture(e.pointerId)\n move(e)\n }\n const drag = (e: PointerEvent): void => {\n if (!dragging) return\n move(e)\n }\n const up = (e: PointerEvent): void => {\n if (!dragging) return\n dragging = false\n if (canvas.hasPointerCapture(e.pointerId)) canvas.releasePointerCapture(e.pointerId)\n }\n canvas.addEventListener('pointerdown', down)\n canvas.addEventListener('pointermove', drag)\n canvas.addEventListener('pointerup', up)\n canvas.addEventListener('pointercancel', up)\n return () => {\n canvas.removeEventListener('pointerdown', down)\n canvas.removeEventListener('pointermove', drag)\n canvas.removeEventListener('pointerup', up)\n canvas.removeEventListener('pointercancel', up)\n }\n }, [store, width, height])\n\n // Default container styling — uses backgroundColor + borderColor\n // props. When the consumer passes a custom `style`, bg + border come\n // from there (escape hatch).\n const containerStyle: CSSProperties = style ?? {\n position: 'absolute',\n ...POSITION_STYLES[position],\n width,\n height,\n background: backgroundColor,\n border: `1px solid ${borderColor}`,\n borderRadius: 6,\n boxShadow: '0 1px 3px rgba(0,0,0,.08)',\n overflow: 'hidden',\n zIndex: 10,\n }\n\n return (\n <div ref={containerRef} style={containerStyle}>\n <canvas\n ref={canvasRef}\n width={Math.ceil(\n width * (typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1),\n )}\n height={Math.ceil(\n height * (typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1),\n )}\n style={{ width, height, display: 'block', cursor: 'crosshair' }}\n />\n {overCap && (\n <div\n style={{\n position: 'absolute',\n inset: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: '#64748b',\n fontFamily: 'system-ui, -apple-system, sans-serif',\n fontSize: 11,\n textAlign: 'center',\n padding: 8,\n pointerEvents: 'none',\n }}\n >\n Minimap disabled\n <br />({store.getNodeCount()} > {maxNodes})\n </div>\n )}\n </div>\n )\n}\n","import type { Node, NodeId } from '@canvas-harness/core'\nimport { useEffect, useState, useSyncExternalStore } from 'react'\nimport { useCanvasStore } from '../context'\n\n/**\n * Subscribes to a single node. Re-renders **only** when that node\n * changes — moves on other nodes are free.\n *\n * The recommended hook for custom-node React views, layer panels keyed\n * by id, and any per-node UI.\n *\n * @example\n * function StickyView({ id }: { id: NodeId }) {\n * const node = useNode(id)\n * if (!node) return null\n * return <div>{node.content ?? 'empty'}</div>\n * }\n */\nexport function useNode(id: NodeId): Node | undefined {\n const store = useCanvasStore()\n return useSyncExternalStore(\n cb => {\n // Re-emit only when a batch touches this node.\n return store.subscribe('change', batch => {\n for (const op of batch.ops) {\n if ('node' in op && op.node.id === id) {\n cb()\n return\n }\n if ('id' in op && (op.id as unknown) === id) {\n cb()\n return\n }\n }\n })\n },\n () => store.getNode(id),\n )\n}\n\n/**\n * Returns every node (optionally filtered). Re-renders on **every**\n * committed batch — expensive. Use for sidebars / minimaps / layer\n * panels that legitimately see all nodes; never inside per-node\n * components.\n *\n * @example\n * // Layer panel: list every node grouped by type.\n * function Layers() {\n * const nodes = useNodes()\n * return <ul>{nodes.map(n => <li key={n.id}>{n.type}</li>)}</ul>\n * }\n *\n * @example\n * // Filtered: only text nodes.\n * const textNodes = useNodes(n => n.type === 'text')\n */\nexport function useNodes(predicate?: (n: Node) => boolean): Node[] {\n const store = useCanvasStore()\n const [nodes, setNodes] = useState<Node[]>(() => {\n const all = store.getAllNodes()\n return predicate ? all.filter(predicate) : all\n })\n useEffect(() => {\n const recompute = (): void => {\n const all = store.getAllNodes()\n setNodes(predicate ? all.filter(predicate) : all)\n }\n return store.subscribe('change', recompute)\n }, [store, predicate])\n return nodes\n}\n","import type { Edge, EdgeId } from '@canvas-harness/core'\nimport { useEffect, useState, useSyncExternalStore } from 'react'\nimport { useCanvasStore } from '../context'\n\n/**\n * Subscribes to a single edge. Re-renders only when that edge mutates\n * (style change, endpoint reconnect, etc.). Use inside per-edge UI\n * like a label component or an inspector panel.\n *\n * @example\n * function EdgeLabel({ id }: { id: EdgeId }) {\n * const edge = useEdge(id)\n * return <span>{edge?.style?.strokeColor ?? 'default'}</span>\n * }\n */\nexport function useEdge(id: EdgeId): Edge | undefined {\n const store = useCanvasStore()\n return useSyncExternalStore(\n cb =>\n store.subscribe('change', batch => {\n for (const op of batch.ops) {\n if ('edge' in op && op.edge.id === id) {\n cb()\n return\n }\n if ('id' in op && (op.id as unknown) === id) {\n cb()\n return\n }\n }\n }),\n () => store.getEdge(id),\n )\n}\n\n/**\n * Returns every edge (optionally filtered). Re-renders on every\n * committed batch — expensive. Use for inspector panels or minimaps;\n * never inside per-edge components.\n *\n * @example\n * const dashed = useEdges(e => e.style?.strokeStyle === 'dashed')\n */\nexport function useEdges(predicate?: (e: Edge) => boolean): Edge[] {\n const store = useCanvasStore()\n const [edges, setEdges] = useState<Edge[]>(() => {\n const all = store.getAllEdges()\n return predicate ? all.filter(predicate) : all\n })\n useEffect(() => {\n const recompute = (): void => {\n const all = store.getAllEdges()\n setEdges(predicate ? all.filter(predicate) : all)\n }\n return store.subscribe('change', recompute)\n }, [store, predicate])\n return edges\n}\n","import type { EdgeId, NodeId } from '@canvas-harness/core'\nimport { useSyncExternalStore } from 'react'\nimport { useCanvasStore } from '../context'\n\n/**\n * Returns the current selection — an array of node and/or edge ids.\n * Re-renders only when the selection changes.\n *\n * @example\n * function DeleteButton() {\n * const store = useCanvasStore()\n * const selection = useSelection()\n * return (\n * <button disabled={selection.length === 0} onClick={() => {\n * for (const id of selection) {\n * if (store.getNode(id as NodeId)) store.removeNode(id as NodeId)\n * else store.removeEdge(id as EdgeId)\n * }\n * }}>\n * Delete ({selection.length})\n * </button>\n * )\n * }\n */\nexport function useSelection(): (NodeId | EdgeId)[] {\n const store = useCanvasStore()\n return useSyncExternalStore(\n cb => store.subscribe('selection', cb),\n () => store.getSelection(),\n )\n}\n","import type { CameraState } from '@canvas-harness/core'\nimport { useSyncExternalStore } from 'react'\nimport { useCanvasStore } from '../context'\n\n/**\n * Returns the current camera (`{ x, y, z }`). Re-renders on every\n * camera change — pan / zoom / `store.setCamera(...)`.\n *\n * Useful for status bars, minimaps, or positioning overlays in world\n * coordinates.\n *\n * @example\n * function ZoomReadout() {\n * const { z } = useCamera()\n * return <span>{Math.round(z * 100)}%</span>\n * }\n */\nexport function useCamera(): CameraState {\n const store = useCanvasStore()\n return useSyncExternalStore(\n cb => store.subscribe('camera', cb),\n () => store.getCamera(),\n )\n}\n","import type { ClientId, PresenceState } from '@canvas-harness/core'\nimport { useEffect, useState, useSyncExternalStore } from 'react'\nimport { useCanvasStore } from '../context'\n\n/**\n * This client's own presence — cursor / selection / editing / color /\n * name. Re-renders when local presence updates.\n *\n * Set local presence via `store.presence.setLocal({...})`. The library\n * forwards it through the attached `SyncAdapter` automatically.\n *\n * @example\n * const me = useLocalPresence()\n * <div>signed in as {me.name}</div>\n */\nexport function useLocalPresence(): PresenceState {\n const store = useCanvasStore()\n return useSyncExternalStore(\n cb =>\n store.subscribe('presence', e => {\n if ('removed' in e && e.removed) return\n if (e.state.clientId === store.clientId) cb()\n }),\n () => store.presence.getLocal(),\n )\n}\n\n/**\n * Reads remote presence.\n *\n * - `usePresence(clientId)` — one remote client's state, or\n * `undefined` if they've left.\n * - `usePresence()` — map of every remote client. Re-renders on every\n * remote update (join / leave / cursor move). Use sparingly.\n *\n * @example\n * // Paint every remote cursor.\n * const remotes = usePresence()\n * for (const p of remotes.values()) drawCursor(p)\n *\n * @example\n * // Just one peer.\n * const peer = usePresence(asClientId('alice'))\n */\nexport function usePresence(clientId: ClientId): PresenceState | undefined\nexport function usePresence(): ReadonlyMap<ClientId, PresenceState>\nexport function usePresence(clientId?: ClientId): unknown {\n const store = useCanvasStore()\n // Map view — re-renders on every remote change. Fresh Map reference\n // each call, so we use state + effect (not useSyncExternalStore).\n const [, force] = useState(0)\n useEffect(() => {\n if (clientId !== undefined) return // single-client path below handles its own subscription\n return store.subscribe('presence', e => {\n if ('removed' in e && e.removed) return force(n => n + 1)\n if (e.state.clientId !== store.clientId) force(n => n + 1)\n })\n }, [store, clientId])\n\n // Single-client path — atom-like stable reference from the map.\n // We still need to re-render when this client's record changes.\n // Implementing via state for simplicity.\n const [snap, setSnap] = useState<PresenceState | undefined>(() =>\n clientId === undefined ? undefined : store.presence.get(clientId),\n )\n useEffect(() => {\n if (clientId === undefined) return\n return store.subscribe('presence', e => {\n if ('removed' in e && e.removed && e.clientId === clientId) setSnap(undefined)\n else if (!('removed' in e) && e.state.clientId === clientId) setSnap(e.state)\n })\n }, [store, clientId])\n\n if (clientId !== undefined) return snap\n return store.presence.getAll()\n}\n","import { useSyncExternalStore } from 'react'\nimport { useCanvasStore } from '../context'\n\n/**\n * `true` when there's something to undo. Updates after every committed\n * batch (the only thing that changes the stack).\n *\n * @example\n * const canUndo = useCanUndo()\n * <button disabled={!canUndo} onClick={() => store.undo()}>Undo</button>\n */\nexport function useCanUndo(): boolean {\n const store = useCanvasStore()\n return useSyncExternalStore(\n cb => store.subscribe('change', cb),\n () => store.canUndo(),\n )\n}\n\n/**\n * `true` when there's something to redo. See {@link useCanUndo}.\n *\n * @example\n * const canRedo = useCanRedo()\n * <button disabled={!canRedo} onClick={() => store.redo()}>Redo</button>\n */\nexport function useCanRedo(): boolean {\n const store = useCanvasStore()\n return useSyncExternalStore(\n cb => store.subscribe('change', cb),\n () => store.canRedo(),\n )\n}\n","/**\n * @canvas-harness/react\n *\n * React bindings: `<Canvas>` component + data/interaction/presence/history hooks.\n * See ARCHITECTURE.md §13 and IMPLEMENTATION.md Phase 9.\n */\nexport const VERSION = '0.0.0'\n\nexport { Canvas } from './Canvas'\nexport type { CanvasCreateDragEvent, CanvasPointerEvent, CanvasProps } from './Canvas'\nexport type { ArrowToolDefaults } from './internal/use-arrow-tool'\nexport { Minimap } from './Minimap'\nexport type { MinimapProps } from './Minimap'\nexport { CanvasProvider, useCanvasStore } from './context'\nexport type { CanvasProviderProps } from './context'\nexport type { ThemeResolver } from './types'\n\n// Data hooks\nexport { useNode, useNodes } from './hooks/use-node'\nexport { useEdge, useEdges } from './hooks/use-edge'\nexport { useSelection } from './hooks/use-selection'\nexport { useCamera } from './hooks/use-camera'\n\n// Interaction hooks\nexport {\n useCursor,\n useDraggedIds,\n useInteractionMode,\n useInteractionState,\n useIsMoving,\n useIsPenActive,\n} from './hooks/use-interaction'\n\n// Presence hooks\nexport { useLocalPresence, usePresence } from './hooks/use-presence'\n\n// History hooks\nexport { useCanRedo, useCanUndo } from './hooks/use-history'\n\n// Re-export the per-tool gesture type so consumers can type their tool state.\nexport type { InteractionTool } from './internal/use-interaction-gesture'\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/context.tsx","../src/hooks/use-interaction.ts","../src/internal/editor-mount.tsx","../src/internal/use-arrow-tool.ts","../src/internal/use-interaction-gesture.ts","../src/internal/use-overlay-host.ts","../src/internal/use-pan-zoom.ts","../src/internal/use-resize-observer.ts","../src/Canvas.tsx","../src/Minimap.tsx","../src/hooks/use-node.ts","../src/hooks/use-edge.ts","../src/hooks/use-selection.ts","../src/hooks/use-camera.ts","../src/hooks/use-presence.ts","../src/hooks/use-history.ts","../src/index.ts"],"names":["jsx","useRef","useEffect","CLICK_MAX_PIXELS","screenToWorld","worldToNodeLocal","projectToNodeBoundary","createPalmRejectionState","notePenActive","shouldRejectTouch","notePenInactive","useState","camera","hitTestAny","jsxs","useSyncExternalStore"],"mappings":"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","file":"index.js","sourcesContent":["import type { CanvasStore } from '@canvas-harness/core'\nimport { type ReactNode, createContext, useContext } from 'react'\n\nconst CanvasContext = createContext<CanvasStore | null>(null)\n\nexport type CanvasProviderProps = {\n store: CanvasStore\n children: ReactNode\n}\n\n/**\n * Provides a {@link CanvasStore} to descendant hooks via context.\n * Wrap your app (or just the canvas + its panels) once at the top\n * level. `<Canvas>` reads the same store from context.\n *\n * @example\n * const store = useRef(createCanvasStore()).current\n * <CanvasProvider store={store}>\n * <Toolbar />\n * <Canvas tool=\"select\" />\n * <Sidebar />\n * </CanvasProvider>\n */\nexport function CanvasProvider({ store, children }: CanvasProviderProps) {\n return <CanvasContext.Provider value={store}>{children}</CanvasContext.Provider>\n}\n\n/**\n * Returns the {@link CanvasStore} from context. Use this when you need\n * to mutate the store from event handlers (e.g. tool buttons, side\n * panels). For reactive reads, prefer the more specific hooks\n * (`useNode`, `useSelection`, `useCamera`, ...).\n *\n * Throws if called outside a `<CanvasProvider>`.\n *\n * @example\n * function ClearButton() {\n * const store = useCanvasStore()\n * return <button onClick={() => store.batch(() => {\n * for (const n of store.getAllNodes()) store.removeNode(n.id)\n * })}>Clear</button>\n * }\n */\nexport function useCanvasStore(): CanvasStore {\n const store = useContext(CanvasContext)\n if (!store) {\n throw new Error(\n 'useCanvasStore() must be used inside <CanvasProvider>. ' +\n 'Wrap your tree with <CanvasProvider store={store}>.',\n )\n }\n return store\n}\n","import type {\n EdgeId,\n InteractionMode,\n InteractionState,\n NodeId,\n PointerInfo,\n} from '@canvas-harness/core'\nimport { useSyncExternalStore } from 'react'\nimport { useCanvasStore } from '../context'\n\n/**\n * Full interaction state. Fires on **any** change — mode flips,\n * pointermoves, drag delta updates, marquee rect updates, ...\n *\n * Most consumers want a narrower hook (`useInteractionMode`,\n * `useCursor`, `useIsMoving`, `useDraggedIds`). Reach for this one only\n * if you need multiple fields together.\n *\n * @example\n * const state = useInteractionState()\n * if (state.mode === 'marqueeing') drawMarqueeOverlay(state.marqueeRect)\n */\nexport function useInteractionState(): InteractionState {\n const store = useCanvasStore()\n return useSyncExternalStore(\n cb => store.subscribe('interaction', cb),\n () => store.getInteractionState(),\n )\n}\n\n/**\n * Just the interaction mode. Re-renders only on mode transitions,\n * never on pointermove.\n *\n * Use to gate heavy effects (\"only run X when mode === 'idle'\") or\n * disable UI affordances during a drag.\n *\n * @example\n * const mode = useInteractionMode()\n * <button disabled={mode !== 'idle'}>Run AI suggestion</button>\n */\nexport function useInteractionMode(): InteractionMode {\n const store = useCanvasStore()\n return useSyncExternalStore(\n cb => {\n let lastMode = store.getInteractionState().mode\n return store.subscribe('interaction', state => {\n if (state.mode !== lastMode) {\n lastMode = state.mode\n cb()\n }\n })\n },\n () => store.getInteractionState().mode,\n )\n}\n\n/**\n * Latest pointer info — `worldX/Y`, `screenX/Y`, `pointerType`,\n * optional `pressure` (for pens). Updated on every pointermove.\n *\n * @example\n * const cursor = useCursor()\n * <div>x: {cursor?.worldX.toFixed(1)}</div>\n */\nexport function useCursor(): PointerInfo | null {\n const store = useCanvasStore()\n return useSyncExternalStore(\n cb => store.subscribe('interaction', cb),\n () => store.getInteractionState().pointer,\n )\n}\n\n/**\n * `true` while the user is panning, zooming, dragging, resizing, or\n * rotating. Derived from {@link useInteractionMode}.\n *\n * Useful for skipping expensive renders during motion (the library\n * does this internally for the bitmap cache; consumers can do the same\n * for custom-node React views).\n *\n * @example\n * const isMoving = useIsMoving()\n * return isMoving ? <Skeleton /> : <ExpensiveChart />\n */\nexport function useIsMoving(): boolean {\n const mode = useInteractionMode()\n return (\n mode === 'panning' ||\n mode === 'zooming' ||\n mode === 'dragging' ||\n mode === 'resizing' ||\n mode === 'rotating'\n )\n}\n\n/**\n * Ids being dragged or resized right now. Empty array when idle (with\n * a stable reference, so consumers can use as a dep).\n *\n * @example\n * const ids = useDraggedIds()\n * useEffect(() => { … }, [ids]) // safe; same array between gestures\n */\nconst EMPTY_DRAGGED: NodeId[] = []\nexport function useDraggedIds(): readonly (NodeId | EdgeId)[] {\n const store = useCanvasStore()\n return useSyncExternalStore(\n cb => store.subscribe('interaction', cb),\n () => {\n const state = store.getInteractionState()\n return state.draggedIds.length === 0 ? EMPTY_DRAGGED : state.draggedIds\n },\n )\n}\n\n/**\n * `true` when the most recent pointer was a stylus. Falls back to\n * `false` before any pointer event has fired.\n *\n * Use to surface pen-specific UI (pressure-aware tools, ink hints).\n *\n * @example\n * const isPen = useIsPenActive()\n * {isPen && <PressureToolbar />}\n */\nexport function useIsPenActive(): boolean {\n const cursor = useCursor()\n return cursor?.pointerType === 'pen'\n}\n","import {\n type CanvasStore,\n type Edge,\n type EditorAdapter,\n type EditorAdapterFactory,\n type Node,\n asNodeId,\n createDefaultTextareaEditor,\n edgeLabelBoundsWorld,\n} from '@canvas-harness/core'\nimport { useEffect, useRef } from 'react'\n\n/**\n * EditorMount — wires an `EditorAdapter` to the in-canvas edit lifecycle.\n * Mounts the adapter at the editing node's screen position; tears it\n * down on commit / cancel.\n *\n * Camera is locked during edit (see `usePanZoom`) so the editor stays\n * pinned to the node it's editing without needing to chase pan/zoom.\n *\n * `factory` defaults to `createDefaultTextareaEditor` (a plain\n * `<textarea>`). Consumers can plug Lexical/ProseMirror/TipTap by\n * passing a custom factory.\n */\nexport function EditorMount({\n store,\n factory = createDefaultTextareaEditor,\n}: {\n store: CanvasStore\n factory?: EditorAdapterFactory\n}) {\n const hostRef = useRef<HTMLDivElement>(null)\n\n useEffect(() => {\n const host = hostRef.current\n if (!host) return\n\n let activeAdapter: EditorAdapter | null = null\n let currentEditingKey: string | null = null\n\n const teardown = (): void => {\n if (activeAdapter) {\n activeAdapter.destroy()\n activeAdapter = null\n }\n currentEditingKey = null\n }\n\n const onInteraction = () => {\n const state = store.getInteractionState()\n const target = state.mode === 'editing' ? state.editingTarget : null\n const key = target ? `${target.kind}:${target.id}` : null\n\n // No-op when state is unchanged.\n if (key === currentEditingKey) return\n\n // Tear down a stale editor (commit/cancel/switch).\n teardown()\n if (!target) return\n\n // Resolve the node passed to the editor adapter. For a node target\n // it's just the node; for an edge target we synthesize a Node that\n // boxes the label's world rect + the edge's style, so the existing\n // textarea editor positions + styles itself correctly.\n let editorNode: Node | null = null\n if (target.kind === 'node') {\n editorNode = store.getNode(target.id) ?? null\n } else {\n const edge = store.getEdge(target.id)\n const geom = store.getEdgeGeometry(target.id)\n if (edge && geom) editorNode = synthesizeLabelNode(edge, geom)\n }\n if (!editorNode) return\n\n currentEditingKey = key\n activeAdapter = factory({\n node: editorNode,\n container: host,\n camera: store.getCamera(),\n dpr: window.devicePixelRatio || 1,\n onCommit: text => {\n store.commitEdit(text)\n },\n onCancel: () => {\n store.cancelEdit()\n },\n })\n }\n\n onInteraction()\n const unsub = store.subscribe('interaction', onInteraction)\n return () => {\n unsub()\n teardown()\n }\n }, [store, factory])\n\n return (\n <div\n ref={hostRef}\n style={{\n position: 'absolute',\n inset: 0,\n pointerEvents: 'none',\n // Children (the textarea) re-enable pointer events themselves.\n }}\n />\n )\n}\n\n/**\n * Builds a synthetic Node that represents an edge's label rect for the\n * editor adapter. The adapter only reads `x/y/w/h/style/content`; the\n * synthetic node won't be stored or rendered as a real node — it's\n * just a positioning + styling vehicle for the textarea.\n */\nconst synthesizeLabelNode = (\n edge: Edge,\n geom: import('@canvas-harness/core').EdgeGeometry,\n): Node | null => {\n // Edge labels default to 'handwriting' (matches node content + the\n // renderer's `drawEdgeLabel` default). Explicit so the textarea\n // editor doesn't fall through to its own default and cause a font\n // flicker on first edit commit.\n const labelStyle = { fontFamily: 'handwriting' as const, ...edge.style }\n\n const bounds = edgeLabelBoundsWorld(edge, geom)\n if (!bounds) {\n // Empty content — fabricate a small box at the label's would-be\n // anchor so the editor still has somewhere to mount.\n if (geom.samples.length < 2) return null\n const mid = geom.samples[Math.floor(geom.samples.length / 2)]!\n return {\n id: asNodeId(`__edge-label:${edge.id}`),\n type: 'text',\n x: mid.x - 60,\n y: mid.y - 12,\n w: 120,\n h: 24,\n angle: 0,\n z: 0,\n groups: [],\n content: '',\n style: labelStyle,\n }\n }\n return {\n id: asNodeId(`__edge-label:${edge.id}`),\n type: 'text',\n x: bounds.x,\n y: bounds.y,\n w: bounds.w,\n h: bounds.h,\n angle: 0,\n z: 0,\n groups: [],\n content: edge.content ?? '',\n style: { ...labelStyle, autoFit: false }, // labels don't autofit height\n }\n}\n","/**\n * useArrowTool — Arrow-tool gesture for edge creation.\n *\n * Flow per ARCHITECTURE.md §6.3:\n * pointerdown over node → start edge with source attached at the\n * clamped boundary point on that node\n * pointerdown empty → start edge with free-floating source\n * pointermove → target follows pointer; if over a candidate\n * node, snap target to that node's boundary\n * pointerup → commit (target = node attachment OR worldPoint)\n *\n * The renderer paints the draft edge from interaction.draftEdge while in\n * mode 'creating-edge'.\n */\nimport {\n type CanvasStore,\n type EdgeEnd,\n type NodeId,\n type Vec2,\n asEdgeId,\n hitTestPoint,\n projectToNodeBoundary,\n screenToWorld,\n worldToNodeLocal,\n} from '@canvas-harness/core'\nimport { useEffect, useRef } from 'react'\n\nconst CLICK_MAX_PIXELS = 4\n\n/**\n * Defaults applied to every edge the arrow tool creates. Lets a\n * consumer (e.g. a style-memory hook) inject the user's last-used\n * pathStyle / arrowheads / style without forcing every edge through\n * a custom factory.\n */\nexport type ArrowToolDefaults = {\n pathStyle?: import('@canvas-harness/core').PathStyle\n style?: import('@canvas-harness/core').EdgeStyle\n}\n\nexport const useArrowTool = (\n ref: React.RefObject<HTMLElement | null>,\n store: CanvasStore,\n enabled: boolean,\n defaults?: ArrowToolDefaults,\n): void => {\n // Refs so the create handler always reads the latest defaults\n // without forcing the listener effect to re-mount on every change.\n const defaultsRef = useRef(defaults)\n defaultsRef.current = defaults\n\n useEffect(() => {\n if (!enabled) return\n const el = ref.current\n if (!el) return\n\n let pointerDownAt: { x: number; y: number } | null = null\n let active = false\n let sourceEnd: EdgeEnd | null = null\n\n const screenFromEvent = (e: PointerEvent): Vec2 => {\n const rect = el.getBoundingClientRect()\n return { x: e.clientX - rect.left, y: e.clientY - rect.top }\n }\n const worldFromEvent = (e: PointerEvent): Vec2 =>\n screenToWorld(screenFromEvent(e), store.getCamera())\n\n /**\n * If the world point lies over a node, returns an attached EdgeEnd\n * with localOffset clamped/projected to that node's boundary.\n * Otherwise returns a free-floating worldPoint end.\n */\n const endFromWorldPoint = (world: Vec2): { end: EdgeEnd; nodeId: NodeId | null } => {\n const hit = hitTestPoint(store, world, store.getCamera().z)\n if (hit && hit.kind === 'body') {\n const node = store.getNode(hit.nodeId)!\n const localOffset = projectToNodeBoundary(world, node)\n return { end: { nodeId: node.id, localOffset }, nodeId: node.id }\n }\n return { end: { worldPoint: world }, nodeId: null }\n }\n\n /** End that just follows the pointer; if over a node, attach via clamped local. */\n const followingEnd = (world: Vec2): { end: EdgeEnd; nodeId: NodeId | null } => {\n const hit = hitTestPoint(store, world, store.getCamera().z)\n if (hit && hit.kind === 'body') {\n const node = store.getNode(hit.nodeId)!\n // For follow-the-pointer, snap to the actual pointer position\n // projected to the node boundary (not \"nearest edge\").\n const local = worldToNodeLocal(world, node)\n const clamped = {\n x: Math.max(0, Math.min(node.w, local.x)),\n y: Math.max(0, Math.min(node.h, local.y)),\n }\n return { end: { nodeId: node.id, localOffset: clamped }, nodeId: node.id }\n }\n return { end: { worldPoint: world }, nodeId: null }\n }\n\n const onPointerDown = (e: PointerEvent) => {\n if (e.button !== 0) return\n pointerDownAt = screenFromEvent(e)\n const world = worldFromEvent(e)\n const { end } = endFromWorldPoint(world)\n sourceEnd = end\n el.setPointerCapture(e.pointerId)\n e.preventDefault()\n }\n\n const onPointerMove = (e: PointerEvent) => {\n if (!pointerDownAt || !sourceEnd) return\n const screen = screenFromEvent(e)\n const dx = screen.x - pointerDownAt.x\n const dy = screen.y - pointerDownAt.y\n // Only start showing the draft once the user moves past the click threshold.\n if (!active && Math.abs(dx) < CLICK_MAX_PIXELS && Math.abs(dy) < CLICK_MAX_PIXELS) return\n active = true\n const world = worldFromEvent(e)\n const { end: target, nodeId: snapTargetNodeId } = followingEnd(world)\n store.setInteractionState({\n mode: 'creating-edge',\n draftEdge: {\n source: sourceEnd,\n target,\n reconnectingId: null,\n snapTargetNodeId,\n },\n })\n }\n\n const onPointerUp = (e: PointerEvent) => {\n if (!pointerDownAt) return\n if (el.hasPointerCapture(e.pointerId)) el.releasePointerCapture(e.pointerId)\n const wasActive = active\n\n if (wasActive && sourceEnd) {\n const world = worldFromEvent(e)\n const { end: target } = endFromWorldPoint(world)\n const d = defaultsRef.current\n store.addEdge({\n id: asEdgeId(store.generateId()),\n source: sourceEnd,\n target,\n pathStyle: d?.pathStyle ?? 'bezier',\n groups: [],\n ...(d?.style ? { style: d.style } : {}),\n })\n }\n\n store.resetInteractionState()\n pointerDownAt = null\n active = false\n sourceEnd = null\n }\n\n const onPointerCancel = (e: PointerEvent) => {\n if (el.hasPointerCapture(e.pointerId)) el.releasePointerCapture(e.pointerId)\n store.resetInteractionState()\n pointerDownAt = null\n active = false\n sourceEnd = null\n }\n\n el.addEventListener('pointerdown', onPointerDown)\n el.addEventListener('pointermove', onPointerMove)\n el.addEventListener('pointerup', onPointerUp)\n el.addEventListener('pointercancel', onPointerCancel)\n return () => {\n el.removeEventListener('pointerdown', onPointerDown)\n el.removeEventListener('pointermove', onPointerMove)\n el.removeEventListener('pointerup', onPointerUp)\n el.removeEventListener('pointercancel', onPointerCancel)\n }\n }, [ref, store, enabled])\n}\n","/**\n * useInteraction — owns the gesture state machine for the Select tool.\n *\n * Handles click-select, shift-toggle, marquee, drag, resize. Talks to the\n * store via setInteractionState (transient) and applyOp/updateNode (commits).\n *\n * The pan/zoom hook (usePanZoom) handles middle-button pan and wheel/pinch\n * zoom; this hook handles primary-button gestures only.\n */\nimport {\n type CanvasStore,\n type DragOriginal,\n type EdgeEnd,\n type EdgeId,\n type NodeId,\n type ResizeHandle,\n type Vec2,\n type WorldRect,\n computeAutoFitHeight,\n createPalmRejectionState,\n hitTestAny,\n marqueeNodes,\n midpointToCubicControls,\n notePenActive,\n notePenInactive,\n projectToNodeBoundary,\n screenToWorld,\n shouldAutoFit,\n shouldRejectTouch,\n worldToNodeLocal,\n} from '@canvas-harness/core'\nimport { useEffect } from 'react'\n\nconst CLICK_MAX_PIXELS = 4 // pointerup within this many pixels of pointerdown = click\n\n/** Touch hold time (ms) before a stationary pointerdown promotes to drag. */\nconst LONG_PRESS_MS = 500\n/** Max pixel movement during the long-press window without canceling it. */\nconst LONG_PRESS_MAX_MOVE_PX = 10\n\nexport type InteractionTool =\n | 'select'\n | 'pan'\n | 'rect'\n | 'ellipse'\n | 'diamond'\n | 'capsule'\n | 'arrow'\n | 'text'\n\nexport const useInteractionGesture = (\n ref: React.RefObject<HTMLElement | null>,\n store: CanvasStore,\n tool: InteractionTool,\n): void => {\n useEffect(() => {\n const el = ref.current\n if (!el) return\n if (tool !== 'select') return // shape tools handle their own clicks in Canvas.tsx\n\n let pointerDownAt: { x: number; y: number } | null = null\n let activeGesture:\n | 'idle'\n | 'click-pending'\n | 'drag'\n | 'resize'\n | 'rotate'\n | 'marquee'\n | 'reconnect-edge'\n | 'edge-midpoint' = 'idle'\n let resizeHandle: ResizeHandle | null = null\n let dragOriginals: DragOriginal[] = []\n let marqueeStartWorld: Vec2 | null = null\n let marqueeShift = false\n let reconnectEdgeId: EdgeId | null = null\n let reconnectEnd: 'source' | 'target' | null = null\n let midpointEdgeId: EdgeId | null = null\n // Rotation gesture state.\n let rotateNodeId: NodeId | null = null\n let rotateOriginAngle = 0 // node.angle at gesture start\n let rotatePointerStartAngle = 0 // pointer angle from node center at gesture start\n\n // Phase 11 — palm rejection + long-press.\n const palm = createPalmRejectionState()\n let longPressTimer: ReturnType<typeof setTimeout> | null = null\n const clearLongPress = (): void => {\n if (longPressTimer !== null) {\n clearTimeout(longPressTimer)\n longPressTimer = null\n }\n }\n\n const screenFromEvent = (e: PointerEvent): Vec2 => {\n const rect = el.getBoundingClientRect()\n return { x: e.clientX - rect.left, y: e.clientY - rect.top }\n }\n\n const worldFromEvent = (e: PointerEvent): Vec2 =>\n screenToWorld(screenFromEvent(e), store.getCamera())\n\n const snapshotOriginals = (ids: NodeId[]): DragOriginal[] => {\n const result: DragOriginal[] = []\n for (const id of ids) {\n const n = store.getNode(id)\n if (n) result.push({ id, x: n.x, y: n.y, w: n.w, h: n.h, angle: n.angle })\n }\n return result\n }\n\n const beginDrag = (ids: NodeId[]): void => {\n dragOriginals = snapshotOriginals(ids)\n store.setInteractionState({\n mode: 'dragging',\n draggedIds: ids,\n dragOriginals,\n dragDelta: { x: 0, y: 0 },\n })\n }\n\n const beginResize = (id: NodeId, handle: ResizeHandle): void => {\n dragOriginals = snapshotOriginals([id])\n store.setInteractionState({\n mode: 'resizing',\n draggedIds: [id],\n dragOriginals,\n resizeHandle: handle,\n resizeLockAspect: false,\n resizeFromCenter: false,\n })\n }\n\n const pointerAngleFromCenter = (\n node: { x: number; y: number; w: number; h: number },\n world: Vec2,\n ): number => {\n const cx = node.x + node.w / 2\n const cy = node.y + node.h / 2\n return Math.atan2(world.y - cy, world.x - cx)\n }\n\n const beginRotate = (id: NodeId, worldAtStart: Vec2): void => {\n const node = store.getNode(id)\n if (!node) return\n rotateNodeId = id\n rotateOriginAngle = node.angle\n rotatePointerStartAngle = pointerAngleFromCenter(node, worldAtStart)\n store.setInteractionState({\n mode: 'rotating',\n draggedIds: [id],\n })\n }\n\n /** Snap angle to 15° increments when Shift is held. */\n const ROTATE_SNAP_RAD = (15 * Math.PI) / 180\n const updateRotate = (worldPoint: Vec2, shift: boolean): void => {\n if (!rotateNodeId) return\n const node = store.getNode(rotateNodeId)\n if (!node) return\n const pointerAngle = pointerAngleFromCenter(node, worldPoint)\n const delta = pointerAngle - rotatePointerStartAngle\n let next = rotateOriginAngle + delta\n if (shift) next = Math.round(next / ROTATE_SNAP_RAD) * ROTATE_SNAP_RAD\n store.updateNode(rotateNodeId, { angle: next })\n }\n\n const commitRotate = (): void => {\n rotateNodeId = null\n store.resetInteractionState()\n }\n\n const updateDrag = (delta: Vec2): void => {\n store.setInteractionState({ dragDelta: delta })\n }\n\n const updateResize = (worldPoint: Vec2, modifiers: { shift: boolean; alt: boolean }): void => {\n const orig = dragOriginals[0]\n if (!orig || !resizeHandle) return\n const next = computeResizeGeometry(orig, resizeHandle, worldPoint, modifiers)\n // Commit live to the store so the static canvas reflects it; phase 3\n // single-node resize. Multi-select group resize is similar but scales\n // each member proportionally — left for §11.6 follow-up.\n store.updateNode(orig.id, next)\n store.setInteractionState({\n resizeLockAspect: modifiers.shift,\n resizeFromCenter: modifiers.alt,\n })\n }\n\n const commitDrag = (): void => {\n const interaction = store.getInteractionState()\n const delta = interaction.dragDelta\n if (delta.x !== 0 || delta.y !== 0) {\n store.batch(() => {\n for (const orig of dragOriginals) {\n store.updateNode(orig.id, { x: orig.x + delta.x, y: orig.y + delta.y })\n }\n })\n }\n store.resetInteractionState()\n }\n\n const commitResize = (): void => {\n // updateResize already committed via store.updateNode each pointermove;\n // we only need to clear the interaction state. The history-aware\n // version (phase 8 undo) will collapse these into one OpBatch.\n // Refit autofit nodes now that the resize stream is over (we\n // suppress mid-stream refit so the user's drag isn't overridden).\n const selected = store.getSelection()\n for (const id of selected) {\n const node = store.getNode(id as NodeId)\n if (!node) continue\n if (!shouldAutoFit(node)) continue\n const fitted = computeAutoFitHeight(node)\n // Grow-only — preserve a user's deliberately-tall node.\n if (fitted > node.h) store.updateNode(node.id, { h: fitted })\n }\n store.resetInteractionState()\n }\n\n const beginMarquee = (start: Vec2, shift: boolean): void => {\n marqueeStartWorld = start\n marqueeShift = shift\n store.setInteractionState({\n mode: 'marqueeing',\n marqueeRect: { x: start.x, y: start.y, w: 0, h: 0 },\n marqueeAdditive: shift,\n })\n }\n\n const updateMarquee = (current: Vec2): void => {\n if (!marqueeStartWorld) return\n const rect: WorldRect = {\n x: Math.min(marqueeStartWorld.x, current.x),\n y: Math.min(marqueeStartWorld.y, current.y),\n w: Math.abs(current.x - marqueeStartWorld.x),\n h: Math.abs(current.y - marqueeStartWorld.y),\n }\n store.setInteractionState({ marqueeRect: rect })\n }\n\n const commitMarquee = (): void => {\n const interaction = store.getInteractionState()\n const rect = interaction.marqueeRect\n if (rect && (rect.w > 0 || rect.h > 0)) {\n const hits = marqueeNodes(store, rect)\n if (marqueeShift) {\n const existing = new Set(store.getSelection() as NodeId[])\n for (const id of hits) existing.add(id)\n store.setSelection([...existing])\n } else {\n store.setSelection(hits)\n }\n }\n store.resetInteractionState()\n }\n\n const onPointerDown = (e: PointerEvent) => {\n if (e.button !== 0) return\n if (e.pointerType === 'pen') notePenActive(palm)\n else if (e.pointerType === 'touch' && shouldRejectTouch(palm, Date.now())) return\n pointerDownAt = screenFromEvent(e)\n const world = worldFromEvent(e)\n const camera = store.getCamera()\n const selection = store.getSelection()\n const selectedNodeIds = new Set<NodeId>()\n const selectedEdgeIds = new Set<EdgeId>()\n for (const id of selection) {\n if (store.getNode(id as NodeId)) selectedNodeIds.add(id as NodeId)\n else if (store.getEdge(id as EdgeId)) selectedEdgeIds.add(id as EdgeId)\n }\n const hit = hitTestAny(store, world, camera.z, selectedNodeIds, selectedEdgeIds)\n\n if (hit?.kind === 'rotate-handle') {\n activeGesture = 'rotate'\n beginRotate(hit.nodeId, world)\n el.setPointerCapture(e.pointerId)\n e.preventDefault()\n return\n }\n\n if (hit?.kind === 'resize-handle') {\n resizeHandle = hit.handle\n activeGesture = 'resize'\n beginResize(hit.nodeId, hit.handle)\n el.setPointerCapture(e.pointerId)\n e.preventDefault()\n return\n }\n\n if (hit?.kind === 'midpoint-handle') {\n midpointEdgeId = hit.edgeId\n activeGesture = 'edge-midpoint'\n el.setPointerCapture(e.pointerId)\n e.preventDefault()\n return\n }\n\n if (hit?.kind === 'source-handle' || hit?.kind === 'target-handle') {\n reconnectEdgeId = hit.edgeId\n reconnectEnd = hit.kind === 'source-handle' ? 'source' : 'target'\n activeGesture = 'reconnect-edge'\n const edge = store.getEdge(hit.edgeId)\n if (edge) {\n store.setInteractionState({\n mode: 'reconnecting-edge',\n draftEdge: {\n source: edge.source,\n target: edge.target,\n reconnectingId: hit.edgeId,\n snapTargetNodeId: null,\n },\n })\n }\n el.setPointerCapture(e.pointerId)\n e.preventDefault()\n return\n }\n\n if (hit?.kind === 'body' && 'nodeId' in hit) {\n const alreadySelected = selectedNodeIds.has(hit.nodeId)\n if (e.shiftKey) {\n const next = new Set(selectedNodeIds)\n if (alreadySelected) next.delete(hit.nodeId)\n else next.add(hit.nodeId)\n store.setSelection([...next])\n } else if (!alreadySelected) {\n store.setSelection([hit.nodeId])\n }\n activeGesture = 'click-pending'\n el.setPointerCapture(e.pointerId)\n // Touch can't hover, so a stationary press should promote to\n // drag after LONG_PRESS_MS. Mouse / pen rely on the existing\n // pixel-threshold path.\n if (e.pointerType === 'touch') {\n const targetIds = e.shiftKey\n ? ([...selectedNodeIds, hit.nodeId] as NodeId[])\n : [hit.nodeId]\n clearLongPress()\n longPressTimer = setTimeout(() => {\n longPressTimer = null\n if (activeGesture !== 'click-pending') return\n activeGesture = 'drag'\n beginDrag(targetIds)\n }, LONG_PRESS_MS)\n }\n e.preventDefault()\n return\n }\n\n // Edge body hit.\n if (hit?.kind === 'body' && 'edgeId' in hit) {\n if (e.shiftKey) {\n const next = new Set(selectedEdgeIds)\n if (selectedEdgeIds.has(hit.edgeId)) next.delete(hit.edgeId)\n else next.add(hit.edgeId)\n store.setSelection([...selectedNodeIds, ...next])\n } else {\n store.setSelection([hit.edgeId])\n }\n activeGesture = 'click-pending'\n el.setPointerCapture(e.pointerId)\n e.preventDefault()\n return\n }\n\n // Click on empty space.\n if (!e.shiftKey) store.setSelection([])\n activeGesture = 'click-pending'\n el.setPointerCapture(e.pointerId)\n }\n\n const onPointerMove = (e: PointerEvent) => {\n if (!pointerDownAt) return\n const screen = screenFromEvent(e)\n const dx = screen.x - pointerDownAt.x\n const dy = screen.y - pointerDownAt.y\n\n // Movement past LONG_PRESS_MAX_MOVE_PX cancels the long-press\n // promotion (user is dragging, not holding still).\n if (\n longPressTimer !== null &&\n (Math.abs(dx) > LONG_PRESS_MAX_MOVE_PX || Math.abs(dy) > LONG_PRESS_MAX_MOVE_PX)\n ) {\n clearLongPress()\n }\n\n // First time pointermove crosses click threshold: decide gesture.\n if (activeGesture === 'click-pending') {\n if (Math.abs(dx) < CLICK_MAX_PIXELS && Math.abs(dy) < CLICK_MAX_PIXELS) return\n const startWorld = screenToWorld(pointerDownAt, store.getCamera())\n const camera = store.getCamera()\n const selectedIds = new Set(\n store.getSelection().filter(id => store.getNode(id as NodeId)) as NodeId[],\n )\n // re-test at the down-position; if it was over a node body, drag it\n const hit = hitTestAny(store, startWorld, camera.z, selectedIds, new Set())\n if (hit?.kind === 'body' && 'nodeId' in hit && selectedIds.has(hit.nodeId)) {\n activeGesture = 'drag'\n beginDrag([...selectedIds])\n } else {\n activeGesture = 'marquee'\n beginMarquee(startWorld, e.shiftKey)\n }\n }\n\n if (activeGesture === 'drag') {\n const camera = store.getCamera()\n updateDrag({ x: dx / camera.z, y: dy / camera.z })\n } else if (activeGesture === 'resize') {\n const world = worldFromEvent(e)\n updateResize(world, { shift: e.shiftKey, alt: e.altKey })\n } else if (activeGesture === 'rotate') {\n updateRotate(worldFromEvent(e), e.shiftKey)\n } else if (activeGesture === 'marquee') {\n updateMarquee(worldFromEvent(e))\n } else if (activeGesture === 'reconnect-edge' && reconnectEdgeId && reconnectEnd) {\n updateReconnect(worldFromEvent(e))\n } else if (activeGesture === 'edge-midpoint' && midpointEdgeId) {\n updateEdgeMidpoint(worldFromEvent(e))\n }\n }\n\n const updateEdgeMidpoint = (world: Vec2): void => {\n if (!midpointEdgeId) return\n const geom = store.getEdgeGeometry(midpointEdgeId)\n if (!geom) return\n const { c1, c2 } = midpointToCubicControls(geom.source, world, geom.target)\n store.updateEdge(midpointEdgeId, { control: [c1, c2] })\n }\n\n const updateReconnect = (world: Vec2): void => {\n if (!reconnectEdgeId || !reconnectEnd) return\n const edge = store.getEdge(reconnectEdgeId)\n if (!edge) return\n const camera = store.getCamera()\n // Follow the pointer; if over another node, snap to that node's\n // boundary (clamped).\n const newEnd = followingEnd(world, camera.z)\n const draftSource = reconnectEnd === 'source' ? newEnd.end : edge.source\n const draftTarget = reconnectEnd === 'target' ? newEnd.end : edge.target\n store.setInteractionState({\n mode: 'reconnecting-edge',\n draftEdge: {\n source: draftSource,\n target: draftTarget,\n reconnectingId: reconnectEdgeId,\n snapTargetNodeId: newEnd.nodeId,\n },\n })\n }\n\n const followingEnd = (\n world: Vec2,\n cameraZ: number,\n ): { end: EdgeEnd; nodeId: NodeId | null } => {\n const hit = hitTestAny(store, world, cameraZ)\n if (hit?.kind === 'body' && 'nodeId' in hit) {\n const node = store.getNode(hit.nodeId)\n if (node) {\n const local = worldToNodeLocal(world, node)\n const clamped = {\n x: Math.max(0, Math.min(node.w, local.x)),\n y: Math.max(0, Math.min(node.h, local.y)),\n }\n return { end: { nodeId: node.id, localOffset: clamped }, nodeId: node.id }\n }\n }\n return { end: { worldPoint: world }, nodeId: null }\n }\n\n const commitReconnect = (e: PointerEvent): void => {\n if (!reconnectEdgeId || !reconnectEnd) return\n const world = worldFromEvent(e)\n // For commit, snap to the boundary (so endpoint isn't inside the rect).\n const hit = hitTestAny(store, world, store.getCamera().z)\n let newEnd: EdgeEnd\n if (hit?.kind === 'body' && 'nodeId' in hit) {\n const node = store.getNode(hit.nodeId)\n if (node) {\n const localOffset = projectToNodeBoundary(world, node)\n newEnd = { nodeId: node.id, localOffset }\n } else {\n newEnd = { worldPoint: world }\n }\n } else {\n newEnd = { worldPoint: world }\n }\n store.updateEdge(\n reconnectEdgeId,\n reconnectEnd === 'source' ? { source: newEnd } : { target: newEnd },\n )\n store.resetInteractionState()\n }\n\n const onPointerUp = (e: PointerEvent) => {\n if (e.pointerType === 'pen') notePenInactive(palm, Date.now())\n clearLongPress()\n if (!pointerDownAt) return\n if (el.hasPointerCapture(e.pointerId)) el.releasePointerCapture(e.pointerId)\n switch (activeGesture) {\n case 'drag':\n commitDrag()\n break\n case 'resize':\n commitResize()\n break\n case 'rotate':\n commitRotate()\n break\n case 'marquee':\n commitMarquee()\n break\n case 'reconnect-edge':\n commitReconnect(e)\n break\n case 'edge-midpoint':\n // updateEdgeMidpoint already wrote each move via store.updateEdge;\n // pointerup just clears the gesture state.\n break\n // 'click-pending' was already handled in pointerdown (selection set);\n // nothing more to do.\n }\n pointerDownAt = null\n activeGesture = 'idle'\n resizeHandle = null\n dragOriginals = []\n marqueeStartWorld = null\n reconnectEdgeId = null\n midpointEdgeId = null\n reconnectEnd = null\n }\n\n const onKeyDown = (e: KeyboardEvent) => {\n // Skip when focus is in an editor (built-in textarea, consumer's\n // <input>, or any contenteditable surface). Otherwise Backspace\n // typed inside the edit overlay bubbles to window and triggers\n // `removeNode` on the selected node — the user types a typo,\n // hits Backspace, and the node they're editing vanishes behind\n // the still-open textarea. Bug surfaces on Escape because that's\n // when the overlay closes and the user sees the empty canvas.\n const target = e.target as HTMLElement | null\n if (\n target &&\n (target.tagName === 'TEXTAREA' || target.tagName === 'INPUT' || target.isContentEditable)\n )\n return\n if (e.key === 'Escape') {\n store.setSelection([])\n store.resetInteractionState()\n }\n if ((e.key === 'Delete' || e.key === 'Backspace') && store.getSelection().length > 0) {\n const ids = store.getSelection()\n store.batch(() => {\n for (const id of ids) {\n if (store.getNode(id as NodeId)) store.removeNode(id as NodeId)\n else if (store.getEdge(id as EdgeId)) store.removeEdge(id as EdgeId)\n }\n })\n store.setSelection([])\n }\n }\n\n el.addEventListener('pointerdown', onPointerDown)\n el.addEventListener('pointermove', onPointerMove)\n el.addEventListener('pointerup', onPointerUp)\n el.addEventListener('pointercancel', onPointerUp)\n window.addEventListener('keydown', onKeyDown)\n return () => {\n el.removeEventListener('pointerdown', onPointerDown)\n el.removeEventListener('pointermove', onPointerMove)\n el.removeEventListener('pointerup', onPointerUp)\n el.removeEventListener('pointercancel', onPointerUp)\n window.removeEventListener('keydown', onKeyDown)\n }\n }, [ref, store, tool])\n}\n\n/**\n * Computes the new node geometry given a resize gesture.\n * Phase 3: single-node resize. Multi-select group resize is similar but\n * scales each member proportionally — left for §11.6 follow-up.\n */\nconst computeResizeGeometry = (\n orig: DragOriginal,\n handle: ResizeHandle,\n pointer: Vec2,\n modifiers: { shift: boolean; alt: boolean },\n): { x: number; y: number; w: number; h: number } => {\n // For phase 3 we only support axis-aligned resize (no rotation handling\n // in the gesture math yet). Rotated resize is a §11.6 follow-up.\n let x = orig.x\n let y = orig.y\n let w = orig.w\n let h = orig.h\n\n const rightFixed = handle === 'nw' || handle === 'w' || handle === 'sw'\n const leftFixed = handle === 'ne' || handle === 'e' || handle === 'se'\n const bottomFixed = handle === 'nw' || handle === 'n' || handle === 'ne'\n const topFixed = handle === 'sw' || handle === 's' || handle === 'se'\n\n if (rightFixed) {\n const right = orig.x + orig.w\n w = Math.max(1, right - pointer.x)\n x = right - w\n } else if (leftFixed) {\n w = Math.max(1, pointer.x - orig.x)\n }\n if (bottomFixed) {\n const bottom = orig.y + orig.h\n h = Math.max(1, bottom - pointer.y)\n y = bottom - h\n } else if (topFixed) {\n h = Math.max(1, pointer.y - orig.y)\n }\n\n if (modifiers.shift) {\n // Lock aspect ratio. Compare the requested w/h ratio to the original\n // and pick whichever dimension produces the smaller change.\n const targetAspect = orig.w / orig.h\n const currentAspect = w / h\n if (currentAspect > targetAspect) {\n w = h * targetAspect\n if (rightFixed) x = orig.x + orig.w - w\n } else {\n h = w / targetAspect\n if (bottomFixed) y = orig.y + orig.h - h\n }\n }\n\n if (modifiers.alt) {\n // Resize from center: mirror the delta across the original center.\n const cx = orig.x + orig.w / 2\n const cy = orig.y + orig.h / 2\n if (handle !== 'n' && handle !== 's') {\n w = Math.max(1, w * 2 - orig.w + (orig.w - Math.abs(orig.w - w * 0)))\n // Simpler: recompute by mirroring whichever side moved\n const newW = Math.abs(pointer.x - cx) * 2\n w = Math.max(1, newW)\n x = cx - w / 2\n }\n if (handle !== 'e' && handle !== 'w') {\n const newH = Math.abs(pointer.y - cy) * 2\n h = Math.max(1, newH)\n y = cy - h / 2\n }\n }\n\n return { x, y, w, h }\n}\n","/**\n * useOverlayHost — tracks the renderer's overlay-mounted custom-node ids.\n *\n * The renderer fires `onOverlayChange` with the new mount set every time\n * LOD or visibility shifts which custom nodes should be in React-rendered\n * land. This hook just keeps a state list of ids; the Canvas component\n * then renders one positioned div per id with the corresponding view.\n *\n * Phase 5 keeps this in the playground; phase 9 formalizes a similar hook\n * in `@canvas-harness/react`.\n */\nimport type { NodeId } from '@canvas-harness/core'\nimport { useEffect, useState } from 'react'\n\nexport const useOverlayHost = (): {\n mountedIds: NodeId[]\n setMountedIds: (ids: NodeId[]) => void\n} => {\n const [mountedIds, setMountedIds] = useState<NodeId[]>([])\n // Stable reference for the renderer callback so the renderer doesn't re-emit.\n useEffect(() => {}, [])\n return { mountedIds, setMountedIds }\n}\n","import {\n type CanvasStore,\n clampZoom,\n createPalmRejectionState,\n notePenActive,\n notePenInactive,\n panByScreen,\n shouldRejectTouch,\n zoomAtScreenPoint,\n} from '@canvas-harness/core'\nimport { useEffect, useRef } from 'react'\n\n/**\n * Wires up wheel zoom, middle-button / spacebar pan, and (phase 11)\n * touch pinch-zoom + two-finger pan + pointer-type write-through.\n *\n * When the active tool is `'pan'` (the Hand tool), any left-button\n * drag pans the camera — equivalent to space-hold + left-drag. The\n * space-hold modifier still works regardless of active tool, so a\n * user can quickly pan mid-edit without switching tools.\n *\n * Pointermove fires faster than the display refreshes (often 120-240Hz).\n * Calling `store.setCamera` on every event saturates the main thread at\n * large scene sizes. Instead we accumulate pending deltas and flush\n * once per rAF, so the store sees at most one camera update per frame\n * regardless of input rate.\n *\n * Phase 11 additions:\n * - Two simultaneous `pointerType: 'touch'` pointers → pinch zoom +\n * two-finger pan (no wheel involved).\n * - Pen pressure / pointerType written to `interaction.pointer` so\n * consumers can read via `useCursor()`.\n * - Palm rejection: touch events ignored while pen is active or for\n * PALM_REJECTION_GRACE_MS after pen-up.\n */\nexport const usePanZoom = (\n ref: React.RefObject<HTMLElement | null>,\n store: CanvasStore,\n /** Active canvas tool. When `'pan'`, left-button drag pans the camera. */\n tool?: string,\n): void => {\n // `tool` is read inside pointer handlers; ref-bind so changes don't\n // tear down + re-mount the whole gesture effect (which would lose\n // in-flight pan state on tool switch — not a real-world risk, but\n // the ref-bind also keeps listeners stable).\n const toolRef = useRef<string | undefined>(tool)\n toolRef.current = tool\n\n useEffect(() => {\n const el = ref.current\n if (!el) return\n\n let panning = false\n let panActivatedBySpace = false\n let lastX = 0\n let lastY = 0\n\n // Per-frame buffers — flushed in flushPending via rAF.\n let pendingDx = 0\n let pendingDy = 0\n let pendingZoomFactor = 1\n let pendingZoomAnchor: { x: number; y: number } | null = null\n let scheduled = false\n let rafId = 0\n\n // Mode-propagation: the canvas wraps every gesture in a `panning`\n // closure flag but never reflected it into the store's interaction\n // mode — which meant `isMoving` stayed false during pan/zoom and\n // none of the motion-LOD optimisations (rough auto-disable, text\n // bitmap downscale, layered fast-path) ever fired.\n //\n // Pointer-driven gestures have explicit start/end events. Wheel\n // events don't — so we keep a deadline and poll it from rAF.\n // (Original implementation used setTimeout per wheel event; on\n // Chrome that's ~5-10µs per clearTimeout+setTimeout pair from\n // timer-heap bookkeeping, which at 120Hz trackpad scroll added\n // ~1ms/frame measurable cost. rAF-poll runs at display rate\n // regardless of input rate — same correctness, ~zero overhead.)\n const MOTION_RESET_MS = 150\n let motionEndDeadline = 0\n let motionEndPolling = false\n const setMotion = (mode: 'panning' | 'zooming' | null): void => {\n const current = store.getInteractionState().mode\n if (mode === null) {\n if (current === 'panning' || current === 'zooming') {\n store.setInteractionState({ mode: 'idle' })\n }\n return\n }\n // Don't overwrite editing or any other deliberate mode.\n if (current !== 'idle' && current !== 'panning' && current !== 'zooming') return\n if (current !== mode) store.setInteractionState({ mode })\n }\n const pollMotionEnd = (): void => {\n if (performance.now() >= motionEndDeadline) {\n motionEndPolling = false\n setMotion(null)\n return\n }\n requestAnimationFrame(pollMotionEnd)\n }\n const pulseMotion = (mode: 'panning' | 'zooming'): void => {\n motionEndDeadline = performance.now() + MOTION_RESET_MS\n // Only fire `setMotion` (which can emit an interaction event)\n // when the mode actually needs to change. Guards inside\n // `setMotion` already do this, but checking here saves the\n // function call entirely for the 99% of wheel events where\n // we're already in the target mode.\n const current = store.getInteractionState().mode\n if (current !== mode) setMotion(mode)\n if (!motionEndPolling) {\n motionEndPolling = true\n requestAnimationFrame(pollMotionEnd)\n }\n }\n\n // Active touch pointers for pinch + two-finger pan. Keyed by\n // pointerId. Only `pointerType: 'touch'` participates here.\n type ActiveTouch = { id: number; x: number; y: number }\n const activeTouches = new Map<number, ActiveTouch>()\n let lastPinchDistance = 0\n let lastPinchMidpoint: { x: number; y: number } | null = null\n\n const palm = createPalmRejectionState()\n\n const flushPending = (): void => {\n scheduled = false\n rafId = 0\n // Apply zoom first; pan applies on top of the new camera so order is intuitive.\n if (pendingZoomFactor !== 1 && pendingZoomAnchor) {\n // Clamp the accumulated factor so a stream of wheel events\n // queued in one frame can't teleport the user past a 2x /\n // 0.5x jump. Excess folds back into `pendingZoomFactor` and\n // applies on the next frame, turning a fast scroll into a\n // smooth multi-frame zoom instead of one visual jump.\n const MAX_PER_FRAME = 2\n const MIN_PER_FRAME = 0.5\n let appliedFactor = pendingZoomFactor\n let drained = true\n if (appliedFactor > MAX_PER_FRAME) {\n appliedFactor = MAX_PER_FRAME\n pendingZoomFactor = pendingZoomFactor / MAX_PER_FRAME\n drained = false\n } else if (appliedFactor < MIN_PER_FRAME) {\n appliedFactor = MIN_PER_FRAME\n pendingZoomFactor = pendingZoomFactor / MIN_PER_FRAME\n drained = false\n } else {\n pendingZoomFactor = 1\n }\n const camera = store.getCamera()\n store.setCamera(\n zoomAtScreenPoint(camera, clampZoom(camera.z * appliedFactor), pendingZoomAnchor),\n )\n // Keep the anchor alive across frames until the residual\n // factor has drained — otherwise the leftover zoom on the\n // next frame would have no pivot point.\n if (drained) pendingZoomAnchor = null\n else schedule()\n }\n if (pendingDx !== 0 || pendingDy !== 0) {\n const camera = store.getCamera()\n store.setCamera(panByScreen(camera, { x: pendingDx, y: pendingDy }))\n pendingDx = 0\n pendingDy = 0\n }\n }\n\n const schedule = (): void => {\n if (scheduled) return\n scheduled = true\n rafId = requestAnimationFrame(flushPending)\n }\n\n const isEditing = (): boolean => store.getInteractionState().mode === 'editing'\n\n const screenFromClient = (clientX: number, clientY: number): { x: number; y: number } => {\n const rect = el.getBoundingClientRect()\n return { x: clientX - rect.left, y: clientY - rect.top }\n }\n\n const updatePointerInfo = (e: PointerEvent): void => {\n // Write pointer info to the store so `useCursor()` reads include\n // pointerType + pressure. Cheap — InteractionState is one atom.\n const { x: sx, y: sy } = screenFromClient(e.clientX, e.clientY)\n const camera = store.getCamera()\n store.setInteractionState({\n pointer: {\n worldX: sx / camera.z + camera.x,\n worldY: sy / camera.z + camera.y,\n screenX: sx,\n screenY: sy,\n pointerType: e.pointerType as 'mouse' | 'touch' | 'pen',\n pressure: e.pointerType === 'pen' ? e.pressure : undefined,\n },\n })\n }\n\n const onWheel = (e: WheelEvent) => {\n // Lock camera while editing — textarea overlay is positioned at a\n // fixed screen rect; letting the camera move would desync it.\n if (isEditing()) return\n e.preventDefault()\n if (e.ctrlKey || e.metaKey) {\n // Mouse wheel vs trackpad pinch heuristic. A notched mouse\n // wheel sends `|deltaY| ≥ 100` per click (OS-normalized);\n // trackpad pinch sends a stream of small (1-20) values.\n // Mouse: discrete 10% step per notch — predictable, lots of\n // gradations (100→90→81→73→66…), lands near any value.\n // Trackpad: continuous exponential — feels like pinch.\n // Without this split, one mouse notch was `exp(-1) ≈ 0.37` —\n // a 63% drop in a single click.\n const factor =\n Math.abs(e.deltaY) >= 100 ? (e.deltaY > 0 ? 1 / 1.1 : 1.1) : Math.exp(-e.deltaY * 0.01)\n pendingZoomFactor *= factor\n pendingZoomAnchor = screenFromClient(e.clientX, e.clientY)\n pulseMotion('zooming')\n } else {\n pendingDx += -e.deltaX\n pendingDy += -e.deltaY\n pulseMotion('panning')\n }\n schedule()\n }\n\n const resetPinchTracking = (): void => {\n lastPinchDistance = 0\n lastPinchMidpoint = null\n }\n\n const recomputePinchSeed = (): void => {\n // Recompute the seed (distance + midpoint) from the current two\n // touches. Called when entering pinch mode and whenever one of the\n // two touches changes identity (e.g. a third lifted, leaving two).\n const pts = [...activeTouches.values()]\n if (pts.length !== 2) {\n resetPinchTracking()\n return\n }\n const [a, b] = pts\n lastPinchDistance = Math.hypot(a!.x - b!.x, a!.y - b!.y)\n lastPinchMidpoint = { x: (a!.x + b!.x) / 2, y: (a!.y + b!.y) / 2 }\n }\n\n const onPointerDown = (e: PointerEvent) => {\n if (isEditing()) return\n\n if (e.pointerType === 'pen') {\n notePenActive(palm)\n } else if (e.pointerType === 'touch' && shouldRejectTouch(palm, Date.now())) {\n return\n }\n\n // Track touch pointers for pinch.\n if (e.pointerType === 'touch') {\n const pt = screenFromClient(e.clientX, e.clientY)\n activeTouches.set(e.pointerId, { id: e.pointerId, x: pt.x, y: pt.y })\n if (activeTouches.size === 2) {\n recomputePinchSeed()\n el.setPointerCapture(e.pointerId)\n setMotion('zooming')\n e.preventDefault()\n }\n return\n }\n\n // middle button = pan; or left button while space held; or\n // left button while Hand (`pan`) tool is active.\n const handToolActive = toolRef.current === 'pan'\n if (e.button === 1 || (e.button === 0 && (panActivatedBySpace || handToolActive))) {\n panning = true\n lastX = e.clientX\n lastY = e.clientY\n el.setPointerCapture(e.pointerId)\n setMotion('panning')\n e.preventDefault()\n }\n }\n\n const onPointerMove = (e: PointerEvent) => {\n updatePointerInfo(e)\n\n // Pinch path — two touches active.\n if (e.pointerType === 'touch' && activeTouches.has(e.pointerId)) {\n const pt = screenFromClient(e.clientX, e.clientY)\n activeTouches.set(e.pointerId, { id: e.pointerId, x: pt.x, y: pt.y })\n if (activeTouches.size === 2 && lastPinchMidpoint && lastPinchDistance > 0) {\n const pts = [...activeTouches.values()]\n const [a, b] = pts\n const dist = Math.hypot(a!.x - b!.x, a!.y - b!.y)\n const mid = { x: (a!.x + b!.x) / 2, y: (a!.y + b!.y) / 2 }\n const factor = dist / lastPinchDistance\n if (Number.isFinite(factor) && factor > 0) {\n pendingZoomFactor *= factor\n pendingZoomAnchor = mid\n }\n pendingDx += mid.x - lastPinchMidpoint.x\n pendingDy += mid.y - lastPinchMidpoint.y\n lastPinchDistance = dist\n lastPinchMidpoint = mid\n schedule()\n }\n return\n }\n\n if (!panning) return\n const dx = e.clientX - lastX\n const dy = e.clientY - lastY\n lastX = e.clientX\n lastY = e.clientY\n pendingDx += dx\n pendingDy += dy\n schedule()\n }\n\n const onPointerUp = (e: PointerEvent) => {\n if (e.pointerType === 'pen') notePenInactive(palm, Date.now())\n\n if (e.pointerType === 'touch' && activeTouches.has(e.pointerId)) {\n activeTouches.delete(e.pointerId)\n if (el.hasPointerCapture(e.pointerId)) el.releasePointerCapture(e.pointerId)\n // Dropped from 2 → 1: leave pinch mode but keep the remaining\n // touch as a no-op (the gesture hook handles single-touch).\n // Reseed in case three touches collapsed to two.\n if (activeTouches.size === 2) recomputePinchSeed()\n else {\n resetPinchTracking()\n setMotion(null)\n }\n return\n }\n\n if (!panning) return\n panning = false\n if (el.hasPointerCapture(e.pointerId)) el.releasePointerCapture(e.pointerId)\n setMotion(null)\n }\n\n const onPointerCancel = (e: PointerEvent) => {\n // Browser canceled the gesture (e.g. user pulled-to-refresh). Clean up.\n if (e.pointerType === 'touch') {\n activeTouches.delete(e.pointerId)\n if (activeTouches.size < 2) {\n resetPinchTracking()\n setMotion(null)\n }\n }\n if (panning) {\n panning = false\n setMotion(null)\n }\n if (e.pointerType === 'pen') notePenInactive(palm, Date.now())\n }\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.code === 'Space') panActivatedBySpace = true\n }\n const onKeyUp = (e: KeyboardEvent) => {\n if (e.code === 'Space') panActivatedBySpace = false\n }\n\n el.addEventListener('wheel', onWheel, { passive: false })\n el.addEventListener('pointerdown', onPointerDown)\n el.addEventListener('pointermove', onPointerMove)\n el.addEventListener('pointerup', onPointerUp)\n el.addEventListener('pointercancel', onPointerCancel)\n window.addEventListener('keydown', onKeyDown)\n window.addEventListener('keyup', onKeyUp)\n return () => {\n el.removeEventListener('wheel', onWheel)\n el.removeEventListener('pointerdown', onPointerDown)\n el.removeEventListener('pointermove', onPointerMove)\n el.removeEventListener('pointerup', onPointerUp)\n el.removeEventListener('pointercancel', onPointerCancel)\n window.removeEventListener('keydown', onKeyDown)\n window.removeEventListener('keyup', onKeyUp)\n // motion-end rAF poll exits on its own when motionEndPolling\n // becomes false; no explicit cancel needed.\n if (rafId !== 0) cancelAnimationFrame(rafId)\n }\n }, [ref, store])\n}\n","import { useEffect, useState } from 'react'\n\n/**\n * Tracks an element's CSS-pixel size via ResizeObserver.\n * Returns { w, h } in CSS pixels; 0/0 until the first observation.\n */\nexport const useResizeObserver = (ref: React.RefObject<HTMLElement | null>) => {\n const [size, setSize] = useState({ w: 0, h: 0 })\n\n useEffect(() => {\n const el = ref.current\n if (!el) return\n const ro = new ResizeObserver(entries => {\n const entry = entries[0]\n if (!entry) return\n const { width, height } = entry.contentRect\n setSize({ w: Math.round(width), h: Math.round(height) })\n })\n ro.observe(el)\n return () => ro.disconnect()\n }, [ref])\n\n return size\n}\n","import {\n type CanvasBackground,\n type CanvasStore,\n type EditorAdapterFactory,\n type NodeId,\n type Renderer,\n copy,\n createRenderer,\n cut,\n hitTestAny,\n paste,\n screenToWorld,\n} from '@canvas-harness/core'\nimport { type ReactNode, useEffect, useRef, useState } from 'react'\nimport { CanvasProvider, useCanvasStore } from './context'\nimport { useInteractionMode } from './hooks/use-interaction'\nimport { EditorMount } from './internal/editor-mount'\nimport { type ArrowToolDefaults, useArrowTool } from './internal/use-arrow-tool'\nimport { type InteractionTool, useInteractionGesture } from './internal/use-interaction-gesture'\nimport { useOverlayHost } from './internal/use-overlay-host'\nimport { usePanZoom } from './internal/use-pan-zoom'\nimport { useResizeObserver } from './internal/use-resize-observer'\nimport type { ThemeResolver } from './types'\n\n/**\n * Pointer info passed to `onClick` / `onDoubleClick`. Includes the\n * point in both screen space and world space so consumers don't have\n * to convert.\n */\nexport type CanvasPointerEvent = {\n /** Position relative to the canvas element. */\n screen: { x: number; y: number }\n /** Position in scene coordinates (camera-adjusted). */\n world: { x: number; y: number }\n /** Tool active when the event fired. */\n tool: string\n /** The native MouseEvent — read modifiers, button, etc. */\n native: MouseEvent\n}\n\n/**\n * Fired on pointerup after a drag-to-create gesture (non-select tool,\n * drag larger than ~5px). The consumer maps the rect into a new node\n * (defaults, type, style — all consumer policy).\n */\nexport type CanvasCreateDragEvent = {\n /** Bounding rect of the drag, in world coordinates. */\n rect: { x: number; y: number; w: number; h: number }\n /** Tool active when the gesture ended. */\n tool: string\n native: PointerEvent\n}\n\nexport type CanvasProps = {\n /**\n * Optional — when omitted, the component reads the store from\n * `<CanvasProvider>` context. Pass directly for tests or\n * standalone-canvas use.\n */\n store?: CanvasStore\n /**\n * Current tool. The library handles `'select'` and `'arrow'`\n * internally; any other string passes through to `onClick` /\n * `onCreateDrag` so consumers can wire their own shape-create /\n * text-tool / lasso / ... logic.\n */\n tool: string\n /** Theme resolver — see ARCHITECTURE.md §13.10 for the token catalog. */\n theme?: ThemeResolver\n /**\n * Pluggable in-place editor factory; defaults to the built-in\n * `<textarea>`. Implement to swap in Lexical / ProseMirror / TipTap.\n */\n editorAdapter?: EditorAdapterFactory\n /** Called once when the renderer is mounted. Useful for perf overlays. */\n onRenderer?: (r: Renderer) => void\n /** Click on the canvas surface (not over a node handle). */\n onClick?: (e: CanvasPointerEvent) => void\n /** Double-click on the surface. The library has already triggered\n * `beginEdit` if the click landed on a node body. */\n onDoubleClick?: (e: CanvasPointerEvent) => void\n /**\n * Drag-to-create — fires on pointerup when the user dragged with a\n * non-select tool. Sub-threshold drags fall through to `onClick`.\n *\n * @example\n * onCreateDrag={({ rect, tool }) => {\n * if (tool === 'rect') store.addNode({ ...rect, type: 'rect', ... })\n * }}\n */\n onCreateDrag?: (e: CanvasCreateDragEvent) => void\n /**\n * Defaults applied to every edge the built-in arrow tool creates.\n * Lets a consumer remember the user's last-used pathStyle / style /\n * arrowheads. Shape + text tools route through `onClick` /\n * `onCreateDrag` so consumer controls those defaults directly.\n */\n arrowDefaults?: ArrowToolDefaults\n /**\n * Page background + optional infinite dot/grid pattern. Local-only\n * (not part of the synced scene). Update by changing the prop —\n * `<Canvas>` calls `renderer.setBackground` and forces a repaint.\n *\n * @example\n * <Canvas background={{ color: '#fffaf3', pattern: 'dots', gap: 24 }} />\n */\n background?: CanvasBackground\n /**\n * Color for all selection chrome: outline, resize + rotate handles,\n * edge endpoint + midpoint handles, marquee, drag-create preview,\n * and the draft edge during creation. Defaults to `#3b82f6`. Update\n * by changing the prop — `<Canvas>` calls\n * `renderer.setSelectionColor` without recreating the renderer.\n *\n * Accepts any CSS color literal (hex, rgb(), named). Typically you\n * also want to pass the same value to `<Minimap viewportColor={...} />`\n * so the two stay visually in sync.\n *\n * @example\n * <Canvas selectionColor=\"#10b981\" />\n */\n selectionColor?: string\n /**\n * Render a custom node's React subtree. Called once per\n * library-mounted custom-node id; positioning is handled by the\n * overlay container (consumer fills the slot).\n *\n * @example\n * renderCustomNodeView={id => {\n * const node = store.getNode(id)\n * if (node?.type === 'chart-card') return <ChartCardView node={node} />\n * return null\n * }}\n */\n renderCustomNodeView?: (id: NodeId) => ReactNode\n /** Extra content rendered inside the canvas absolute container. */\n children?: ReactNode\n}\n\n/**\n * Mounts the canvas surface (static + interactive layers + DOM overlay\n * for custom-node views + in-place editor mount). Owns the renderer\n * lifecycle, gesture hooks, resize observer.\n *\n * Use inside a {@link CanvasProvider} (or pass `store` directly).\n *\n * @example\n * function App() {\n * const store = useRef(createCanvasStore()).current\n * const [tool, setTool] = useState('select')\n * return (\n * <CanvasProvider store={store}>\n * <Canvas\n * tool={tool}\n * onClick={e => console.log('click at', e.world)}\n * onCreateDrag={e => {\n * store.addNode({ id: asNodeId(store.generateId()), type: e.tool, ...e.rect, angle: 0, z: 0, groups: [] })\n * }}\n * />\n * <Toolbar onSelect={setTool} />\n * </CanvasProvider>\n * )\n * }\n */\nexport function Canvas(props: CanvasProps) {\n if (props.store) {\n return (\n <CanvasProvider store={props.store}>\n <CanvasSurface {...props} />\n </CanvasProvider>\n )\n }\n return <CanvasSurface {...props} />\n}\n\n/** Minimum pointer-drag (screen px) below which a drag-create falls\n * through to `onClick`. Same heuristic tldraw uses. */\nconst DRAG_CREATE_MIN_SIZE_PX = 5\n\nfunction CanvasSurface({\n tool,\n theme,\n editorAdapter,\n onRenderer,\n onClick,\n onDoubleClick,\n onCreateDrag,\n arrowDefaults,\n background,\n selectionColor,\n renderCustomNodeView,\n children,\n}: CanvasProps) {\n const store = useCanvasStore()\n const wrapRef = useRef<HTMLDivElement>(null)\n const staticRef = useRef<HTMLCanvasElement>(null)\n const interactiveRef = useRef<HTMLCanvasElement>(null)\n const overlayRef = useRef<HTMLDivElement>(null)\n const rendererRef = useRef<Renderer | null>(null)\n const toolRef = useRef(tool)\n toolRef.current = tool\n\n const { w, h } = useResizeObserver(wrapRef)\n usePanZoom(wrapRef, store, tool)\n useInteractionGesture(wrapRef, store, tool as InteractionTool)\n const interactionMode = useInteractionMode()\n useArrowTool(wrapRef, store, tool === 'arrow', arrowDefaults)\n\n const { mountedIds, setMountedIds } = useOverlayHost()\n const [camera, setCamera] = useState(() => store.getCamera())\n\n useEffect(() => store.subscribe('camera', c => setCamera({ ...c })), [store])\n\n // Renderer lifecycle. Creates on first mount + size>0; disposes on\n // unmount. `background` and `selectionColor` are intentionally\n // omitted from the dep array — their updates flow through the\n // separate setBackground / setSelectionColor effects below so the\n // renderer isn't torn down on every prop change.\n // biome-ignore lint/correctness/useExhaustiveDependencies: see comment above\n useEffect(() => {\n if (!staticRef.current || !interactiveRef.current || w === 0 || h === 0) return\n if (rendererRef.current) {\n rendererRef.current.setSize(w, h)\n return\n }\n const r = createRenderer({\n store,\n staticCanvas: staticRef.current,\n interactiveCanvas: interactiveRef.current,\n theme,\n width: w,\n height: h,\n background,\n selectionColor,\n onOverlayChange: ids => setMountedIds(ids),\n })\n r.start()\n rendererRef.current = r\n onRenderer?.(r)\n return () => {\n r.dispose()\n rendererRef.current = null\n }\n // `background` + `selectionColor` intentionally omitted — we\n // forward updates via the separate setBackground /\n // setSelectionColor effects below so the renderer isn't torn down\n // on every prop change.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [store, theme, w, h, onRenderer, setMountedIds])\n\n // Forward background prop updates without re-creating the renderer.\n useEffect(() => {\n rendererRef.current?.setBackground(background)\n }, [background])\n\n // Forward selectionColor updates the same way — runtime swap, no rebuild.\n useEffect(() => {\n if (selectionColor !== undefined) rendererRef.current?.setSelectionColor(selectionColor)\n }, [selectionColor])\n\n // Surface-level click — fires for any unhandled click (gesture hooks\n // consume their own). Consumer uses this to implement shape-tool /\n // text-tool create.\n useEffect(() => {\n const el = wrapRef.current\n if (!el) return\n const dispatch = (e: MouseEvent, cb: ((ev: CanvasPointerEvent) => void) | undefined): void => {\n if (!cb) return\n const rect = el.getBoundingClientRect()\n const screen = { x: e.clientX - rect.left, y: e.clientY - rect.top }\n const world = screenToWorld(screen, store.getCamera())\n cb({ screen, world, tool: toolRef.current, native: e })\n }\n const onClickHandler = (e: MouseEvent) => dispatch(e, onClick)\n const onDoubleClickHandler = (e: MouseEvent) => {\n // Built-in: dbl-click a node body OR an edge label → beginEdit.\n // Consumer's onDoubleClick fires too if provided (e.g. for the\n // \"dbl-click empty board to create a text node\" pattern).\n if (toolRef.current === 'select') {\n const rect = el.getBoundingClientRect()\n const screen = { x: e.clientX - rect.left, y: e.clientY - rect.top }\n const camera = store.getCamera()\n const world = screenToWorld(screen, camera)\n const hit = hitTestAny(store, world, camera.z)\n if (hit && hit.kind === 'body' && 'nodeId' in hit) {\n store.beginEdit(hit.nodeId)\n } else if (hit && hit.kind === 'body' && 'edgeId' in hit) {\n store.beginEdit(hit.edgeId)\n } else if (hit && hit.kind === 'label') {\n store.beginEdit(hit.edgeId)\n } else if (hit && hit.kind === 'midpoint-handle') {\n // Dbl-click the midpoint → restore auto-route.\n store.updateEdge(hit.edgeId, { control: undefined })\n }\n }\n dispatch(e, onDoubleClick)\n }\n el.addEventListener('click', onClickHandler)\n el.addEventListener('dblclick', onDoubleClickHandler)\n return () => {\n el.removeEventListener('click', onClickHandler)\n el.removeEventListener('dblclick', onDoubleClickHandler)\n }\n }, [store, onClick, onDoubleClick])\n\n // `justCommittedRef` lives at component scope (not inside the\n // gesture useEffect) so it survives effect remounts triggered by\n // any `onCreateDrag` reference change. Otherwise: a setState from\n // anywhere in the tree between pointerup and the synthetic click\n // would remount the effect, reset the flag, and let the click\n // through — producing a phantom tap-to-create node at the drop\n // point. See README / regression note (May 2026).\n const justCommittedRef = useRef(false)\n\n // Drag-to-create for non-select tools. tldraw/excalidraw style:\n // press at corner-A, drag to corner-B, release → shape sized to the\n // dragged rect. Sub-threshold drags fall through to onClick so a\n // tap still creates a default-size shape.\n useEffect(() => {\n const el = wrapRef.current\n if (!el || !onCreateDrag) return\n let startWorld: { x: number; y: number } | null = null\n let startScreen: { x: number; y: number } | null = null\n let activePointerId: number | null = null\n let committed = false\n\n const screenFromEvent = (e: PointerEvent): { x: number; y: number } => {\n const rect = el.getBoundingClientRect()\n return { x: e.clientX - rect.left, y: e.clientY - rect.top }\n }\n const worldFromEvent = (e: PointerEvent): { x: number; y: number } =>\n screenToWorld(screenFromEvent(e), store.getCamera())\n\n const isShapeTool = (t: string): boolean => t !== 'select' && t !== 'arrow' && t !== 'text'\n\n const onPointerDown = (e: PointerEvent): void => {\n if (e.button !== 0) return\n if (!isShapeTool(toolRef.current)) return\n if (store.getInteractionState().mode === 'editing') return\n // Only engage on empty surface — clicks on existing nodes should\n // not initiate a create. Cheap broad-phase: hit-test the world point.\n const camera = store.getCamera()\n const world = screenToWorld(screenFromEvent(e), camera)\n if (hitTestAny(store, world, camera.z)) return\n\n startWorld = world\n startScreen = screenFromEvent(e)\n activePointerId = e.pointerId\n committed = false\n el.setPointerCapture(e.pointerId)\n }\n\n const onPointerMove = (e: PointerEvent): void => {\n if (startWorld === null || startScreen === null) return\n if (e.pointerId !== activePointerId) return\n const screen = screenFromEvent(e)\n const dx = screen.x - startScreen.x\n const dy = screen.y - startScreen.y\n if (\n !committed &&\n Math.abs(dx) < DRAG_CREATE_MIN_SIZE_PX &&\n Math.abs(dy) < DRAG_CREATE_MIN_SIZE_PX\n ) {\n return\n }\n // Cross the threshold → enter creating-shape mode + paint preview.\n if (!committed) committed = true\n const world = worldFromEvent(e)\n const rect = {\n x: Math.min(startWorld.x, world.x),\n y: Math.min(startWorld.y, world.y),\n w: Math.abs(world.x - startWorld.x),\n h: Math.abs(world.y - startWorld.y),\n }\n store.setInteractionState({\n mode: 'creating-shape',\n createDraftRect: rect,\n createTool: toolRef.current,\n })\n }\n\n const onPointerUp = (e: PointerEvent): void => {\n if (activePointerId !== e.pointerId) return\n if (el.hasPointerCapture(e.pointerId)) el.releasePointerCapture(e.pointerId)\n const wasCommitted = committed\n activePointerId = null\n if (!wasCommitted || !startWorld) {\n startWorld = null\n startScreen = null\n return\n }\n const world = worldFromEvent(e)\n const rect = {\n x: Math.min(startWorld.x, world.x),\n y: Math.min(startWorld.y, world.y),\n w: Math.abs(world.x - startWorld.x),\n h: Math.abs(world.y - startWorld.y),\n }\n startWorld = null\n startScreen = null\n // Reset interaction state before firing the callback so consumer\n // sees an idle store.\n store.resetInteractionState()\n // Suppress the synthetic click that browsers fire after a successful drag.\n justCommittedRef.current = true\n setTimeout(() => {\n justCommittedRef.current = false\n }, 0)\n onCreateDrag({ rect, tool: toolRef.current, native: e })\n }\n\n const onClickCapture = (e: MouseEvent): void => {\n if (justCommittedRef.current) {\n e.stopPropagation()\n e.preventDefault()\n }\n }\n\n el.addEventListener('pointerdown', onPointerDown)\n el.addEventListener('pointermove', onPointerMove)\n el.addEventListener('pointerup', onPointerUp)\n el.addEventListener('pointercancel', onPointerUp)\n // Capture phase so we run BEFORE the click dispatcher.\n el.addEventListener('click', onClickCapture, true)\n return () => {\n el.removeEventListener('pointerdown', onPointerDown)\n el.removeEventListener('pointermove', onPointerMove)\n el.removeEventListener('pointerup', onPointerUp)\n el.removeEventListener('pointercancel', onPointerUp)\n el.removeEventListener('click', onClickCapture, true)\n }\n }, [store, onCreateDrag])\n\n // Cmd/Ctrl+C/X/V — copy/cut/paste. Skip when an input is focused so\n // the editor's native text-clipboard isn't hijacked.\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n const target = e.target as HTMLElement | null\n if (target && (target.tagName === 'TEXTAREA' || target.tagName === 'INPUT')) return\n const meta = e.metaKey || e.ctrlKey\n if (!meta) return\n if (e.key === 'c' || e.key === 'C') {\n e.preventDefault()\n void copy(store)\n } else if (e.key === 'x' || e.key === 'X') {\n e.preventDefault()\n void cut(store)\n } else if (e.key === 'v' || e.key === 'V') {\n e.preventDefault()\n void paste(store)\n } else if (e.key === ']') {\n // Cmd+] = bring forward; Cmd+Shift+] = bring to front.\n const selection = store.getSelection()\n if (selection.length === 0) return\n e.preventDefault()\n if (e.shiftKey) store.bringToFront(selection)\n else store.bringForward(selection)\n } else if (e.key === '[') {\n // Cmd+[ = send backward; Cmd+Shift+[ = send to back.\n const selection = store.getSelection()\n if (selection.length === 0) return\n e.preventDefault()\n if (e.shiftKey) store.sendToBack(selection)\n else store.sendBackward(selection)\n }\n }\n window.addEventListener('keydown', onKey)\n return () => window.removeEventListener('keydown', onKey)\n }, [store])\n\n // CSS transform on overlay div so child positions in world coords follow camera with one composite op.\n const overlayTransform = `translate(${-camera.x * camera.z}px, ${-camera.y * camera.z}px) scale(${camera.z})`\n\n return (\n <div\n ref={wrapRef}\n data-canvas-host=\"\"\n style={{\n position: 'absolute',\n inset: 0,\n background: '#f8fafc',\n overflow: 'hidden',\n cursor:\n tool === 'pan'\n ? interactionMode === 'panning'\n ? 'grabbing'\n : 'grab'\n : tool === 'select'\n ? 'default'\n : 'crosshair',\n touchAction: 'none',\n }}\n >\n <canvas ref={staticRef} style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }} />\n <div\n ref={overlayRef}\n style={{\n position: 'absolute',\n inset: 0,\n transformOrigin: '0 0',\n transform: overlayTransform,\n pointerEvents: 'none',\n }}\n >\n {renderCustomNodeView\n ? mountedIds.map(id => (\n <OverlayItem key={id} id={id}>\n {renderCustomNodeView(id)}\n </OverlayItem>\n ))\n : null}\n </div>\n <canvas\n ref={interactiveRef}\n style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}\n />\n <EditorMount store={store} factory={editorAdapter} />\n {children}\n </div>\n )\n}\n\n/**\n * One mounted custom-node React subtree. Positions itself at the node's\n * world coords; the overlay parent CSS-transform handles camera.\n *\n * Re-reads the node on each 'change' event (Phase-9 simplification; a\n * future hook tightening pass could narrow to per-id subscription).\n */\nfunction OverlayItem({ id, children }: { id: NodeId; children: ReactNode }) {\n const store = useCanvasStore()\n const [node, setNode] = useState(() => store.getNode(id))\n useEffect(() => {\n return store.subscribe('change', () => setNode(store.getNode(id)))\n }, [id, store])\n if (!node) return null\n return (\n <div\n style={{\n position: 'absolute',\n left: node.x,\n top: node.y,\n width: node.w,\n height: node.h,\n transform: node.angle !== 0 ? `rotate(${node.angle}rad)` : undefined,\n transformOrigin: 'center',\n }}\n >\n {children}\n </div>\n )\n}\n","import {\n DEFAULT_MINIMAP_MAX_NODES,\n drawMinimapViewport,\n minimapScreenToWorld,\n renderMinimapContent,\n sceneBounds,\n worldViewportFromCamera,\n} from '@canvas-harness/core'\nimport { type CSSProperties, useEffect, useRef, useState } from 'react'\nimport { useCanvasStore } from './context'\n\n/**\n * Bird's-eye overview of the entire scene + a viewport rectangle\n * showing where the camera is. Click or drag inside to pan.\n *\n * Perf model — see IMPROVEMENTS.md and core/render/minimap.ts:\n * - Scene content is rendered into an offscreen-canvas cache **once\n * per committed batch** (`'change'` event). Cost: O(N) per\n * commit, not per frame.\n * - On camera changes (pan/zoom), only the viewport rectangle is\n * redrawn over the cached image. Cost: O(1) per frame.\n * - Above `maxNodes`, the content render is skipped and a small\n * placeholder text is shown instead.\n *\n * @example\n * <Minimap width={200} height={150} position=\"bottom-right\" />\n */\nexport type MinimapProps = {\n /** Map width in CSS px. Default 200. */\n width?: number\n /** Map height in CSS px. Default 150. */\n height?: number\n /** Above this many nodes, content render is skipped (placeholder\n * shown instead). Default 5000. */\n maxNodes?: number\n /** Fixed-position corner shortcut. Use `style` for custom placement. */\n position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'\n /** Override container styles entirely (skip `position`). */\n style?: CSSProperties\n /** Color of the viewport rect overlay. Default brand blue. */\n viewportColor?: string\n /** Background color drawn behind the cached content + applied to the\n * default container background. Default white. */\n backgroundColor?: string\n /** Container border color (the surrounding chip). Default light slate. */\n borderColor?: string\n /** Fallback node color when a node has no `style.backgroundColor`.\n * Default neutral slate. */\n defaultNodeColor?: string\n}\n\nconst POSITION_STYLES: Record<NonNullable<MinimapProps['position']>, CSSProperties> = {\n 'top-left': { top: 12, left: 12 },\n 'top-right': { top: 12, right: 12 },\n 'bottom-left': { bottom: 12, left: 12 },\n 'bottom-right': { bottom: 12, right: 12 },\n}\n\nexport function Minimap({\n width = 200,\n height = 150,\n maxNodes = DEFAULT_MINIMAP_MAX_NODES,\n position = 'bottom-right',\n style,\n viewportColor = '#3b82f6',\n backgroundColor = '#ffffff',\n borderColor = '#cbd5e1',\n defaultNodeColor = '#94a3b8',\n}: MinimapProps) {\n const store = useCanvasStore()\n const containerRef = useRef<HTMLDivElement>(null)\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const cacheRef = useRef<HTMLCanvasElement | null>(null)\n const cachedBoundsRef = useRef<ReturnType<typeof sceneBounds>>(null)\n // Set on 'change' — repaint regenerates the cache the next tick.\n // Camera-only ticks reuse the cache (just blit + draw viewport).\n const dirtyRef = useRef(true)\n const rafRef = useRef(0)\n const [overCap, setOverCap] = useState(false)\n\n // Build the offscreen cache canvas once per size.\n useEffect(() => {\n const c = document.createElement('canvas')\n const dpr = window.devicePixelRatio || 1\n c.width = Math.ceil(width * dpr)\n c.height = Math.ceil(height * dpr)\n cacheRef.current = c\n dirtyRef.current = true\n }, [width, height])\n\n // Schedule a repaint (rAF-coalesced).\n const schedule = (): void => {\n if (rafRef.current !== 0) return\n rafRef.current = requestAnimationFrame(() => {\n rafRef.current = 0\n repaint()\n })\n }\n\n /**\n * Approach C — scene content cached on every committed mutation;\n * camera ticks reuse the cache + draw a fresh viewport rect on top.\n *\n * - `dirty?` regen cache (O(N), once per `'change'` event) + blit.\n * - `clean?` blit cache + draw viewport rect (O(1) per camera tick).\n *\n * Drops per-pan-frame work from ~0.5ms to ~0.02ms at 5k nodes. The\n * differentiator over react-flow's per-frame-O(N) approach.\n */\n const repaint = (): void => {\n const canvas = canvasRef.current\n if (!canvas) return\n const ctx = canvas.getContext('2d')\n if (!ctx) return\n const dpr = window.devicePixelRatio || 1\n\n if (dirtyRef.current) {\n const cache = cacheRef.current\n if (cache) {\n const cctx = cache.getContext('2d')\n if (cctx) {\n cctx.setTransform(dpr, 0, 0, dpr, 0, 0)\n cctx.clearRect(0, 0, width, height)\n cctx.fillStyle = backgroundColor\n cctx.fillRect(0, 0, width, height)\n const ok = renderMinimapContent(cctx, store, width, height, {\n maxNodes,\n defaultNodeColor,\n })\n cachedBoundsRef.current = ok ? sceneBounds(store) : null\n setOverCap(!ok && store.getNodeCount() > maxNodes)\n }\n }\n dirtyRef.current = false\n }\n\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0)\n ctx.clearRect(0, 0, width, height)\n if (cacheRef.current) {\n // Cache canvas is dpr-sized in physical pixels; drawn at logical\n // (width × height) under the current dpr transform → 1:1 mapping.\n ctx.drawImage(cacheRef.current, 0, 0, width, height)\n } else {\n ctx.fillStyle = backgroundColor\n ctx.fillRect(0, 0, width, height)\n }\n\n const bounds = cachedBoundsRef.current\n if (bounds && bounds.w > 0 && bounds.h > 0) {\n const camera = store.getCamera()\n const wrap = containerRef.current?.closest<HTMLElement>('[data-canvas-host]')\n const screenW = wrap?.clientWidth ?? window.innerWidth\n const screenH = wrap?.clientHeight ?? window.innerHeight\n drawMinimapViewport(\n ctx,\n worldViewportFromCamera(camera, screenW, screenH),\n bounds,\n width,\n height,\n viewportColor,\n )\n }\n }\n\n // Subscribe to relevant store events. `schedule` is stable for the\n // lifetime of this component (closure captures a ref) — adding it\n // would needlessly re-subscribe on every render.\n // biome-ignore lint/correctness/useExhaustiveDependencies: see comment above\n useEffect(() => {\n const onChange = (): void => {\n // Committed mutation — cache needs to regen on next tick.\n dirtyRef.current = true\n schedule()\n }\n const onCamera = (): void => {\n // Pan/zoom — cache is fine, just re-blit + redraw the viewport.\n schedule()\n }\n const unsubChange = store.subscribe('change', onChange)\n const unsubCamera = store.subscribe('camera', onCamera)\n // Initial paint.\n schedule()\n return () => {\n unsubChange()\n unsubCamera()\n if (rafRef.current !== 0) {\n cancelAnimationFrame(rafRef.current)\n // Must reset to 0; otherwise schedule() short-circuits on the\n // next mount thinking an rAF is still pending (it's not — we\n // just cancelled it). Surfaces under React StrictMode.\n rafRef.current = 0\n }\n }\n // schedule + repaint are stable; eslint can't see that.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [store])\n\n // Click + drag to pan the camera.\n useEffect(() => {\n const canvas = canvasRef.current\n if (!canvas) return\n let dragging = false\n const move = (e: PointerEvent): void => {\n const rect = canvas.getBoundingClientRect()\n const worldCenter = minimapScreenToWorld(\n store,\n e.clientX - rect.left,\n e.clientY - rect.top,\n width,\n height,\n )\n if (!worldCenter) return\n const wrap = containerRef.current?.closest<HTMLElement>('[data-canvas-host]')\n const screenW = wrap?.clientWidth ?? window.innerWidth\n const screenH = wrap?.clientHeight ?? window.innerHeight\n const camera = store.getCamera()\n // Center the viewport on the clicked world point.\n store.setCamera({\n x: worldCenter.x - screenW / camera.z / 2,\n y: worldCenter.y - screenH / camera.z / 2,\n })\n }\n const down = (e: PointerEvent): void => {\n if (e.button !== 0) return\n dragging = true\n canvas.setPointerCapture(e.pointerId)\n move(e)\n }\n const drag = (e: PointerEvent): void => {\n if (!dragging) return\n move(e)\n }\n const up = (e: PointerEvent): void => {\n if (!dragging) return\n dragging = false\n if (canvas.hasPointerCapture(e.pointerId)) canvas.releasePointerCapture(e.pointerId)\n }\n canvas.addEventListener('pointerdown', down)\n canvas.addEventListener('pointermove', drag)\n canvas.addEventListener('pointerup', up)\n canvas.addEventListener('pointercancel', up)\n return () => {\n canvas.removeEventListener('pointerdown', down)\n canvas.removeEventListener('pointermove', drag)\n canvas.removeEventListener('pointerup', up)\n canvas.removeEventListener('pointercancel', up)\n }\n }, [store, width, height])\n\n // Default container styling — uses backgroundColor + borderColor\n // props. When the consumer passes a custom `style`, bg + border come\n // from there (escape hatch).\n const containerStyle: CSSProperties = style ?? {\n position: 'absolute',\n ...POSITION_STYLES[position],\n width,\n height,\n background: backgroundColor,\n border: `1px solid ${borderColor}`,\n borderRadius: 6,\n boxShadow: '0 1px 3px rgba(0,0,0,.08)',\n overflow: 'hidden',\n zIndex: 10,\n }\n\n return (\n <div ref={containerRef} style={containerStyle}>\n <canvas\n ref={canvasRef}\n width={Math.ceil(\n width * (typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1),\n )}\n height={Math.ceil(\n height * (typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1),\n )}\n style={{ width, height, display: 'block', cursor: 'crosshair' }}\n />\n {overCap && (\n <div\n style={{\n position: 'absolute',\n inset: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: '#64748b',\n fontFamily: 'system-ui, -apple-system, sans-serif',\n fontSize: 11,\n textAlign: 'center',\n padding: 8,\n pointerEvents: 'none',\n }}\n >\n Minimap disabled\n <br />({store.getNodeCount()} > {maxNodes})\n </div>\n )}\n </div>\n )\n}\n","import type { Node, NodeId } from '@canvas-harness/core'\nimport { useEffect, useState, useSyncExternalStore } from 'react'\nimport { useCanvasStore } from '../context'\n\n/**\n * Subscribes to a single node. Re-renders **only** when that node\n * changes — moves on other nodes are free.\n *\n * The recommended hook for custom-node React views, layer panels keyed\n * by id, and any per-node UI.\n *\n * @example\n * function StickyView({ id }: { id: NodeId }) {\n * const node = useNode(id)\n * if (!node) return null\n * return <div>{node.content ?? 'empty'}</div>\n * }\n */\nexport function useNode(id: NodeId): Node | undefined {\n const store = useCanvasStore()\n return useSyncExternalStore(\n cb => {\n // Re-emit only when a batch touches this node.\n return store.subscribe('change', batch => {\n for (const op of batch.ops) {\n if ('node' in op && op.node.id === id) {\n cb()\n return\n }\n if ('id' in op && (op.id as unknown) === id) {\n cb()\n return\n }\n }\n })\n },\n () => store.getNode(id),\n )\n}\n\n/**\n * Returns every node (optionally filtered). Re-renders on **every**\n * committed batch — expensive. Use for sidebars / minimaps / layer\n * panels that legitimately see all nodes; never inside per-node\n * components.\n *\n * @example\n * // Layer panel: list every node grouped by type.\n * function Layers() {\n * const nodes = useNodes()\n * return <ul>{nodes.map(n => <li key={n.id}>{n.type}</li>)}</ul>\n * }\n *\n * @example\n * // Filtered: only text nodes.\n * const textNodes = useNodes(n => n.type === 'text')\n */\nexport function useNodes(predicate?: (n: Node) => boolean): Node[] {\n const store = useCanvasStore()\n const [nodes, setNodes] = useState<Node[]>(() => {\n const all = store.getAllNodes()\n return predicate ? all.filter(predicate) : all\n })\n useEffect(() => {\n const recompute = (): void => {\n const all = store.getAllNodes()\n setNodes(predicate ? all.filter(predicate) : all)\n }\n return store.subscribe('change', recompute)\n }, [store, predicate])\n return nodes\n}\n","import type { Edge, EdgeId } from '@canvas-harness/core'\nimport { useEffect, useState, useSyncExternalStore } from 'react'\nimport { useCanvasStore } from '../context'\n\n/**\n * Subscribes to a single edge. Re-renders only when that edge mutates\n * (style change, endpoint reconnect, etc.). Use inside per-edge UI\n * like a label component or an inspector panel.\n *\n * @example\n * function EdgeLabel({ id }: { id: EdgeId }) {\n * const edge = useEdge(id)\n * return <span>{edge?.style?.strokeColor ?? 'default'}</span>\n * }\n */\nexport function useEdge(id: EdgeId): Edge | undefined {\n const store = useCanvasStore()\n return useSyncExternalStore(\n cb =>\n store.subscribe('change', batch => {\n for (const op of batch.ops) {\n if ('edge' in op && op.edge.id === id) {\n cb()\n return\n }\n if ('id' in op && (op.id as unknown) === id) {\n cb()\n return\n }\n }\n }),\n () => store.getEdge(id),\n )\n}\n\n/**\n * Returns every edge (optionally filtered). Re-renders on every\n * committed batch — expensive. Use for inspector panels or minimaps;\n * never inside per-edge components.\n *\n * @example\n * const dashed = useEdges(e => e.style?.strokeStyle === 'dashed')\n */\nexport function useEdges(predicate?: (e: Edge) => boolean): Edge[] {\n const store = useCanvasStore()\n const [edges, setEdges] = useState<Edge[]>(() => {\n const all = store.getAllEdges()\n return predicate ? all.filter(predicate) : all\n })\n useEffect(() => {\n const recompute = (): void => {\n const all = store.getAllEdges()\n setEdges(predicate ? all.filter(predicate) : all)\n }\n return store.subscribe('change', recompute)\n }, [store, predicate])\n return edges\n}\n","import type { EdgeId, NodeId } from '@canvas-harness/core'\nimport { useSyncExternalStore } from 'react'\nimport { useCanvasStore } from '../context'\n\n/**\n * Returns the current selection — an array of node and/or edge ids.\n * Re-renders only when the selection changes.\n *\n * @example\n * function DeleteButton() {\n * const store = useCanvasStore()\n * const selection = useSelection()\n * return (\n * <button disabled={selection.length === 0} onClick={() => {\n * for (const id of selection) {\n * if (store.getNode(id as NodeId)) store.removeNode(id as NodeId)\n * else store.removeEdge(id as EdgeId)\n * }\n * }}>\n * Delete ({selection.length})\n * </button>\n * )\n * }\n */\nexport function useSelection(): (NodeId | EdgeId)[] {\n const store = useCanvasStore()\n return useSyncExternalStore(\n cb => store.subscribe('selection', cb),\n () => store.getSelection(),\n )\n}\n","import type { CameraState } from '@canvas-harness/core'\nimport { useSyncExternalStore } from 'react'\nimport { useCanvasStore } from '../context'\n\n/**\n * Returns the current camera (`{ x, y, z }`). Re-renders on every\n * camera change — pan / zoom / `store.setCamera(...)`.\n *\n * Useful for status bars, minimaps, or positioning overlays in world\n * coordinates.\n *\n * @example\n * function ZoomReadout() {\n * const { z } = useCamera()\n * return <span>{Math.round(z * 100)}%</span>\n * }\n */\nexport function useCamera(): CameraState {\n const store = useCanvasStore()\n return useSyncExternalStore(\n cb => store.subscribe('camera', cb),\n () => store.getCamera(),\n )\n}\n","import type { ClientId, PresenceState } from '@canvas-harness/core'\nimport { useEffect, useState, useSyncExternalStore } from 'react'\nimport { useCanvasStore } from '../context'\n\n/**\n * This client's own presence — cursor / selection / editing / color /\n * name. Re-renders when local presence updates.\n *\n * Set local presence via `store.presence.setLocal({...})`. The library\n * forwards it through the attached `SyncAdapter` automatically.\n *\n * @example\n * const me = useLocalPresence()\n * <div>signed in as {me.name}</div>\n */\nexport function useLocalPresence(): PresenceState {\n const store = useCanvasStore()\n return useSyncExternalStore(\n cb =>\n store.subscribe('presence', e => {\n if ('removed' in e && e.removed) return\n if (e.state.clientId === store.clientId) cb()\n }),\n () => store.presence.getLocal(),\n )\n}\n\n/**\n * Reads remote presence.\n *\n * - `usePresence(clientId)` — one remote client's state, or\n * `undefined` if they've left.\n * - `usePresence()` — map of every remote client. Re-renders on every\n * remote update (join / leave / cursor move). Use sparingly.\n *\n * @example\n * // Paint every remote cursor.\n * const remotes = usePresence()\n * for (const p of remotes.values()) drawCursor(p)\n *\n * @example\n * // Just one peer.\n * const peer = usePresence(asClientId('alice'))\n */\nexport function usePresence(clientId: ClientId): PresenceState | undefined\nexport function usePresence(): ReadonlyMap<ClientId, PresenceState>\nexport function usePresence(clientId?: ClientId): unknown {\n const store = useCanvasStore()\n // Map view — re-renders on every remote change. Fresh Map reference\n // each call, so we use state + effect (not useSyncExternalStore).\n const [, force] = useState(0)\n useEffect(() => {\n if (clientId !== undefined) return // single-client path below handles its own subscription\n return store.subscribe('presence', e => {\n if ('removed' in e && e.removed) return force(n => n + 1)\n if (e.state.clientId !== store.clientId) force(n => n + 1)\n })\n }, [store, clientId])\n\n // Single-client path — atom-like stable reference from the map.\n // We still need to re-render when this client's record changes.\n // Implementing via state for simplicity.\n const [snap, setSnap] = useState<PresenceState | undefined>(() =>\n clientId === undefined ? undefined : store.presence.get(clientId),\n )\n useEffect(() => {\n if (clientId === undefined) return\n return store.subscribe('presence', e => {\n if ('removed' in e && e.removed && e.clientId === clientId) setSnap(undefined)\n else if (!('removed' in e) && e.state.clientId === clientId) setSnap(e.state)\n })\n }, [store, clientId])\n\n if (clientId !== undefined) return snap\n return store.presence.getAll()\n}\n","import { useSyncExternalStore } from 'react'\nimport { useCanvasStore } from '../context'\n\n/**\n * `true` when there's something to undo. Updates after every committed\n * batch (the only thing that changes the stack).\n *\n * @example\n * const canUndo = useCanUndo()\n * <button disabled={!canUndo} onClick={() => store.undo()}>Undo</button>\n */\nexport function useCanUndo(): boolean {\n const store = useCanvasStore()\n return useSyncExternalStore(\n cb => store.subscribe('change', cb),\n () => store.canUndo(),\n )\n}\n\n/**\n * `true` when there's something to redo. See {@link useCanUndo}.\n *\n * @example\n * const canRedo = useCanRedo()\n * <button disabled={!canRedo} onClick={() => store.redo()}>Redo</button>\n */\nexport function useCanRedo(): boolean {\n const store = useCanvasStore()\n return useSyncExternalStore(\n cb => store.subscribe('change', cb),\n () => store.canRedo(),\n )\n}\n","/**\n * @canvas-harness/react\n *\n * React bindings: `<Canvas>` component + data/interaction/presence/history hooks.\n * See ARCHITECTURE.md §13 and IMPLEMENTATION.md Phase 9.\n */\nexport const VERSION = '0.0.0'\n\nexport { Canvas } from './Canvas'\nexport type { CanvasCreateDragEvent, CanvasPointerEvent, CanvasProps } from './Canvas'\nexport type { ArrowToolDefaults } from './internal/use-arrow-tool'\nexport { Minimap } from './Minimap'\nexport type { MinimapProps } from './Minimap'\nexport { CanvasProvider, useCanvasStore } from './context'\nexport type { CanvasProviderProps } from './context'\nexport type { ThemeResolver } from './types'\n\n// Data hooks\nexport { useNode, useNodes } from './hooks/use-node'\nexport { useEdge, useEdges } from './hooks/use-edge'\nexport { useSelection } from './hooks/use-selection'\nexport { useCamera } from './hooks/use-camera'\n\n// Interaction hooks\nexport {\n useCursor,\n useDraggedIds,\n useInteractionMode,\n useInteractionState,\n useIsMoving,\n useIsPenActive,\n} from './hooks/use-interaction'\n\n// Presence hooks\nexport { useLocalPresence, usePresence } from './hooks/use-presence'\n\n// History hooks\nexport { useCanRedo, useCanUndo } from './hooks/use-history'\n\n// Re-export the per-tool gesture type so consumers can type their tool state.\nexport type { InteractionTool } from './internal/use-interaction-gesture'\n"]}
|