Phase 4 follow-on: floor-plan interaction + def.toolHints + spawn floorplan builder
Three additions on top of the floor-plan registry contract:
1. def.toolHints + RegisteredToolHelper (registry contract for the
shortcut hint panel)
- New ToolHint type in core: { key, label } static array.
- Added `def.toolHints?: ToolHint[]` to NodeDefinition.
- New <RegisteredToolHelper hints={...}> in editor — same visual
styling as WallHelper / ItemHelper but data-driven.
- HelperManager: registry-first check before falling through to the
hand-written per-tool switch. Per-tool helper files get deleted
as their kind migrates `toolHints` in.
- Shelf + spawn definitions ship toolHints today; wall ports in
Phase 3 Milestone C alongside its tool/affordance port.
2. Floor-plan interaction layer (selection + drag-to-move)
- <FloorplanRegistryLayer> now wraps each entry in an interactive
<g>:
* Click → useViewer.setSelection({ selectedIds: [id] }).
Selection visual is a thicker accent-colored stroke applied
via withSelectionStyle() recursion through the FloorplanGeometry
tree — kinds don't author selection decoration.
* Drag → imperative SVG transform during the gesture, single
updateNode commit on pointerup. Same "smooth move" pattern as
MoveRegistryNodeTool for 3D drag: no per-tick store update,
no React re-render storm, no zundo bloat. Coordinate
conversion via svg.getScreenCTM().inverse().
* useScene.temporal.pause/resume brackets the gesture so one
drag = one undo step.
- Global pointermove / pointerup listeners so the gesture survives
the cursor leaving the entry's bounding box (matches the legacy
elevator-resize-drag and item-drag patterns in floorplan-panel).
3. Spawn floor-plan builder (deferred wiring)
- buildSpawnFloorplan written but NOT wired on the definition —
spawn already renders in the legacy floorplan-panel.tsx via
`floorplanSpawnEntries`, and wiring def.floorplan now would
double-render. The pure builder lives in nodes/src/spawn/
floorplan.ts ready to wire when the legacy inline branch is
removed (Phase 5 spawn-floorplan migration PR — same shape as
wall's feature flag, but per kind inside the legacy panel).
Plan updated: floor-plan interaction section locks the click/drag
contract in, wall-floor-plan-as-legacy note flags everything advanced
the user sees today as legacy that ports alongside Milestone C.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
ac36297e7e
commit
d10d7f8deb
@@ -54,5 +54,6 @@ export type {
|
||||
SurfaceQuery,
|
||||
SurfacesConfig,
|
||||
SystemContribution,
|
||||
ToolHint,
|
||||
Vec2,
|
||||
} from './types'
|
||||
|
||||
@@ -47,6 +47,20 @@ export type FloorplanStyle = {
|
||||
opacity?: number
|
||||
}
|
||||
|
||||
// ─── ToolHint ────────────────────────────────────────────────────────
|
||||
//
|
||||
// A single key + label entry in the contextual shortcut hint panel.
|
||||
// `HelperManager` consults `def.toolHints` when the active tool matches
|
||||
// a registered kind; matches the existing per-tool helper components
|
||||
// today (e.g. WallHelper renders three of these entries).
|
||||
|
||||
export type ToolHint = {
|
||||
/** Key combo or input label, e.g. 'Left click', 'Shift', 'Esc'. */
|
||||
key: string
|
||||
/** Description of what the input does. Sentence case. */
|
||||
label: string
|
||||
}
|
||||
|
||||
export type FloorplanGeometry =
|
||||
| ({ kind: 'path'; d: string } & FloorplanStyle)
|
||||
| ({ kind: 'polygon'; points: readonly FloorplanPoint[] } & FloorplanStyle)
|
||||
@@ -146,6 +160,17 @@ export type NodeDefinition<S extends ZodObject<any>> = {
|
||||
system?: SystemContribution
|
||||
tool?: LazyComponent
|
||||
affordances?: Affordance<z.infer<S>>[]
|
||||
/**
|
||||
* Contextual shortcut hints shown by `HelperManager` when this kind's
|
||||
* tool is active. Pure data — `HelperManager` renders these via a
|
||||
* generic <RegisteredToolHelper>. Drops the need for a hand-written
|
||||
* `<XxxHelper>` component per kind.
|
||||
*
|
||||
* Static array for now (covers ~all current uses). If a kind needs
|
||||
* state-dependent hints (e.g. different keys during a drag), it keeps
|
||||
* its bespoke helper component instead.
|
||||
*/
|
||||
toolHints?: ToolHint[]
|
||||
|
||||
/**
|
||||
* Optional translucent preview of the node — used by the move tool to
|
||||
|
||||
Reference in New Issue
Block a user