Phase 5 batch kind: ceiling migrates to registry (always-on)
Structurally identical to slab. Stage A migration: registers the kind,
wraps the legacy renderer + system, applies the panel slider-drag fix
recipe.
Files added (packages/nodes/src/ceiling/):
- schema.ts: re-exports CeilingNode from core.
- parametrics.ts: height slider only. Polygon + holes via floor-plan
editors.
- definition.ts: capabilities (no `movable`, `surfaces.top` mapped to
`height`), relations (hosts: ['item'] for ceiling-mounted lights /
fans, cascadeDelete: 'descendants'), toolHints, parametrics.
- renderer.tsx: wrap-export of legacy CeilingRenderer. The legacy
renderer uses TSL shader code for grid-line patterns (~100 lines);
not worth duplicating at Stage A. Per-stage migration plan in
plans/editor-node-registry.md moves the renderer body into this
folder at Stage B/F.
- system.tsx: re-exports legacy CeilingSystem.
- index.ts: barrel.
Files changed:
- packages/viewer/src/index.ts: new public exports for CeilingRenderer
+ CeilingSystem.
- packages/nodes/src/index.ts: appends ceilingDefinition.
- packages/editor/src/components/ui/panels/ceiling-panel.tsx: panel
slider-drag fix recipe applied (nodeRef pattern, useScene.getState()
inside handler, drop subscribed updateNode dep) so the height
slider doesn't trigger the same cascade fence + wall + slab fixed.
Phase 5 progress: shelf ✅, spawn ✅, wall ✅, fence ✅, slab ✅, ceiling ✅.
Six kinds on the registry. Door / window / item / stair / roof / zone
follow.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>