Phase 5 Stage D fence: port FenceTool placement to def.tool

Fourth and final Stage D fence affordance — the placement tool itself.

Unlike the drag affordances (curve / move / endpoint), placement is a
two-click flow with state across grid events, not a single drag-down →
drag-up lifecycle. `DragAction` doesn't fit; the component owns its
own emitter subscriptions directly. The kind exposes it via
`def.tool: () => import('./tool')` and ToolManager's existing
`getRegistryTool()` lookup mounts it (legacy `tools.structure.fence =
FenceTool` falls through when the registry entry is missing).

Adds transitional exports from `@pascal-app/editor` for the helpers
the kind-owned tool needs at module scope: `createFenceOnCurrentLevel`,
`markToolCancelConsumed`, `EDITOR_LAYER`. Stage F cleanup moves these
into `@pascal-app/nodes` once every consumer is registry-driven.

Fence Stage D is now complete. Per-kind progress: A  B  C  D 
(four affordances ported — curve, move-endpoint, move, placement).
E (drop legacy panel) and F (cleanup) pending across all kinds.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Wassim SAMAD
2026-05-15 18:22:57 -04:00
co-authored by Claude Opus 4.7
parent c16878c876
commit 7b5a1c607a
3 changed files with 343 additions and 1 deletions
+7
View File
@@ -58,6 +58,13 @@ export const fenceDefinition: NodeDefinition<typeof FenceNode> = {
parametrics: fenceParametrics,
// Stage D: kind-owned placement tool. Two-click flow (start → end)
// with live preview, length / angle HUD, snap to walls / fences /
// grid. Mounted by ToolManager when `useEditor.tool === 'fence'`
// via the registry's getRegistryTool() — falls back to the legacy
// tools[phase][tool] map when missing.
tool: () => import('./tool'),
// Stage B: pure geometry function. Generic <GeometrySystem> rebuilds
// on dirtyNodes; <ParametricNodeRenderer> mounts the empty group.
// `renderer` + `system` fields dropped along with their files.