ai-chatbot/packages/editor/src/lib/editor-api.ts
Wassim SAMAD cfc1fb1672 refactor(editor): delete curving + endpoint reshaping flags
Migrate `curvingWall`, `curvingFence`, `movingWallEndpoint`, `movingFenceEndpoint`
(and their setters) off `useEditor` onto the authoritative interaction scope.
The `reshaping` scope variant gains an `endpoint` discriminator; existence
checks read `useIsCurveReshape()` / `useEndpointReshape()`, and the few sites
that need the node (affordance-tool mounts, wall-vs-fence type checks) read it
from `useReshapingNode()` — a frozen drag-start snapshot, mirroring the old
flags so the tools' own per-frame writes don't feed back. `MovingWallEndpoint`
/ `MovingFenceEndpoint` move to the kind-owned tools that consume them.

`editor-api` is simpler: endpoint engagement is kind-agnostic, and the
`engageMove` reshape clears are gone (the scope is single-owner).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 12:18:50 -04:00

41 lines
1.9 KiB
TypeScript

import type { AnyNode, EditorApi } from '@pascal-app/core'
import useEditor from '../store/use-editor'
import useInteractionScope from '../store/use-interaction-scope'
import { endpointReshapeScope } from './interaction/scope'
/**
* Concrete {@link EditorApi} backed by `useEditor` + the interaction scope.
* Descriptors call into editor state through this interface; the editor owns
* the actual store wiring so core stays decoupled.
*
* `engageMove` no longer clears any in-progress endpoint drag or curve gesture:
* `setMovingNode` begins the `moving` scope, and the scope is single-owner, so
* it atomically replaces any prior reshape — there is no separate flag to reset.
*/
export function createEditorApi(): EditorApi {
return {
engageMove(node: AnyNode) {
const editor = useEditor.getState()
editor.setPlacementDragMode(false)
// `setMovingNode` is typed against a narrower union than `AnyNode`
// (every concrete kind enumerated). Descriptors pass any node; the
// cast lets registry-driven move kinds through without forcing a
// schema-level type widening.
editor.setMovingNode(node as Parameters<typeof editor.setMovingNode>[0])
},
engageMoveDrag(node: AnyNode) {
const editor = useEditor.getState()
// Flag drag mode BEFORE mounting the move tool so the coordinator reads
// it at setup and wires its commit-on-release listener.
editor.setPlacementDragMode(true)
editor.setMovingNode(node as Parameters<typeof editor.setMovingNode>[0])
},
engageEndpointMove(node: AnyNode, endpoint: 'start' | 'end') {
// Endpoint reshape is kind-agnostic: the scope carries the node id + which
// endpoint, and consumers recover the node from the scene. Adding a new
// endpoint-draggable kind needs no entry here.
useInteractionScope.getState().begin(endpointReshapeScope(node.id, endpoint))
},
}
}