floorplan-panel: dismantle legacy SVG layers replaced by the registry

The Phase 5 / 6 migration moved 7 kinds (fence, column, spawn, item,
elevator, stair, roof) to the registry's `def.floorplan` path, but the
legacy SVG layers in `floorplan-panel.tsx` were left mounted with empty
entry arrays — dead code carrying ~3k lines of useless cost in the diff.

Removed:
 - `FloorplanGeometryLayer` (~1.7k lines): inline component rendering
   walls / slabs / ceilings / openings from `wallPolygons` /
   `slabPolygons` / `ceilingPolygons` / `openingsPolygons` — all
   permanently empty stubs after the migration. Wall / slab / ceiling
   / door / window now render via `FloorplanRegistryLayer`.
 - `FloorplanFenceLayer` (~265 lines): fence entries always empty
   post-migration; fence renders via the registry.
 - `FloorplanElevatorLayer` (~420 lines): elevator entries always
   empty post-migration.
 - `FloorplanNodeLayer` (~415 lines): rendered items / spawns / stairs.
   Items + spawns are registry-driven; stair only needed the in-flight
   preview, which is now mounted directly via `FloorplanStairLayer`
   (preserved as a sibling of the registry layer).
 - `FloorplanItemImage` (~40 lines): internal helper used only by
   `FloorplanNodeLayer`.
 - `floorplan-roof-layer.tsx` (113 lines): roof / roof-segment now
   registry-driven.

Net: -2,989 lines from `floorplan-panel.tsx`, plus the deleted roof
layer file. The remaining 14k-line monolith still owns the orchestration
state (selection lookups, marquee, helper lifecycles, hit-test plumbing)
— that's a separate teardown.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Wassim SAMAD
2026-05-19 17:53:57 -04:00
co-authored by Claude Opus 4.7
parent 1ec65acc5f
commit c6bef1ec2f
2 changed files with 9 additions and 3102 deletions
@@ -1,113 +0,0 @@
'use client'
import type { Point2D, RoofNode, RoofSegmentNode } from '@pascal-app/core'
import { memo } from 'react'
import { toSvgX, toSvgY } from '../svg-paths'
type FloorplanLineSegment = {
start: Point2D
end: Point2D
}
type FloorplanRoofSegmentEntry = {
segment: RoofSegmentNode
points: string
ridgeLine: FloorplanLineSegment | null
}
type FloorplanRoofEntry = {
roof: RoofNode
segments: FloorplanRoofSegmentEntry[]
}
type FloorplanRoofPalette = {
roofFill: string
roofActiveFill: string
roofSelectedFill: string
roofStroke: string
roofActiveStroke: string
roofSelectedStroke: string
roofRidgeStroke: string
roofSelectedRidgeStroke: string
}
type FloorplanRoofLayerProps = {
highlightedIdSet: ReadonlySet<string>
palette: FloorplanRoofPalette
roofEntries: FloorplanRoofEntry[]
selectedIdSet: ReadonlySet<string>
}
export const FloorplanRoofLayer = memo(function FloorplanRoofLayer({
highlightedIdSet,
palette,
roofEntries,
selectedIdSet,
}: FloorplanRoofLayerProps) {
if (roofEntries.length === 0) {
return null
}
return (
<>
{roofEntries.map(({ roof, segments }) => {
const roofSelected = selectedIdSet.has(roof.id)
const roofHighlighted = highlightedIdSet.has(roof.id)
const hasSelectedSegment = segments.some(({ segment }) => selectedIdSet.has(segment.id))
const hasHighlightedSegment = segments.some(({ segment }) =>
highlightedIdSet.has(segment.id),
)
const isRoofActive =
roofSelected || roofHighlighted || hasSelectedSegment || hasHighlightedSegment
return (
<g key={roof.id} pointerEvents="none">
{segments.map(({ points, ridgeLine, segment }) => {
const isSegmentSelected = selectedIdSet.has(segment.id)
const isSegmentHighlighted = highlightedIdSet.has(segment.id)
const isSegmentActive = isSegmentSelected || isSegmentHighlighted
return (
<g key={segment.id}>
<polygon
fill={
isSegmentActive
? palette.roofSelectedFill
: isRoofActive
? palette.roofActiveFill
: palette.roofFill
}
points={points}
stroke={
isSegmentActive
? palette.roofSelectedStroke
: isRoofActive
? palette.roofActiveStroke
: palette.roofStroke
}
strokeWidth={isSegmentActive ? '2.25' : isRoofActive ? '1.75' : '1.1'}
vectorEffect="non-scaling-stroke"
/>
{ridgeLine ? (
<line
fill="none"
stroke={
isSegmentActive ? palette.roofSelectedRidgeStroke : palette.roofRidgeStroke
}
strokeWidth={isSegmentActive ? '2' : '1.4'}
vectorEffect="non-scaling-stroke"
x1={toSvgX(ridgeLine.start.x)}
x2={toSvgX(ridgeLine.end.x)}
y1={toSvgY(ridgeLine.start.y)}
y2={toSvgY(ridgeLine.end.y)}
/>
) : null}
</g>
)
})}
</g>
)
})}
</>
)
})
File diff suppressed because it is too large Load Diff