diff --git a/frontend/src/components/simulator/BoardOnCanvas.tsx b/frontend/src/components/simulator/BoardOnCanvas.tsx index 75841ec6..42954e97 100644 --- a/frontend/src/components/simulator/BoardOnCanvas.tsx +++ b/frontend/src/components/simulator/BoardOnCanvas.tsx @@ -1,4 +1,6 @@ import React from 'react'; +import { useSimulatorStore } from '../../store/useSimulatorStore'; +import { isBoardSeated } from '../../utils/socketSnap'; import { getProBoard } from '../../lib/proBoardRegistry'; import type { BoardInstance } from '../../types/board'; import { ArduinoUno } from '../velxio-components/ArduinoUno'; @@ -103,6 +105,14 @@ export const BoardOnCanvas = ({ }: BoardOnCanvasProps) => { const { id, boardKind, x, y } = board; const size = BOARD_SIZE[boardKind] ?? getProBoard(boardKind)?.size ?? { w: 300, h: 200 }; + // Seated on a socket component (Round Display back header)? Decides the + // stacking below. Recomputed on every position change; the check is a few + // pad lookups over the component list, cheap at render rate. + const components = useSimulatorStore((st) => st.components); + const seated = React.useMemo( + () => isBoardSeated(id, boardKind, x, y, components), + [id, boardKind, x, y, components], + ); // Status dot color: green=running, amber=compiled, gray=idle const statusColor = board.running ? '#22c55e' : board.compiledProgram ? '#f59e0b' : '#6b7280'; @@ -184,12 +194,15 @@ export const BoardOnCanvas = ({ // sibling of PinOverlay) made moving onto a pin fire mouseleave, which // cleared the hover and hid the pins before you could click one.
diff --git a/frontend/src/utils/socketSnap.ts b/frontend/src/utils/socketSnap.ts index fed4f47e..a2ae90f9 100644 --- a/frontend/src/utils/socketSnap.ts +++ b/frontend/src/utils/socketSnap.ts @@ -93,3 +93,22 @@ export function snapBoardToSocket( } return best ? { x: tentativeX + best.dx, y: tentativeY + best.dy } : null; } + +/** + * True when the board's CURRENT position IS a socket seat (within half a + * pixel). This is the z-order question, not the drag question: a seated + * board must paint above its socket component, an unseated one must stay + * below components like every other board — the blanket zIndex bump that + * preceded this check hid a resistor behind an Arduino in every ordinary + * example. + */ +export function isBoardSeated( + boardId: string, + boardKind: string, + x: number, + y: number, + components: ComponentLike[], +): boolean { + const seat = snapBoardToSocket(boardId, boardKind, x, y, components); + return !!seat && Math.hypot(seat.x - x, seat.y - y) < 0.5; +}