This commit is contained in:
Andras Schmelczer 2026-09-11 16:58:56 +01:00
commit 9689bfcc18

View file

@ -111,10 +111,19 @@ interface Props {
flooring: FlooringPlan;
skirting: SkirtingPlan;
selectedPiece: string | null;
select: (id: string) => void;
select?: (id: string) => void;
interactive?: boolean;
}
export function FloorPlan({ room, geometry, flooring, skirting, selectedPiece, select }: Props) {
export function FloorPlan({
room,
geometry,
flooring,
skirting,
selectedPiece,
select,
interactive = true,
}: Props) {
const hatch = useId().replaceAll(':', '');
const allPoints = geometry.edges.flatMap((edge) => [edge.start, edge.end]);
const minX = Math.min(0, ...allPoints.map((p) => p.x)),
@ -159,13 +168,18 @@ export function FloorPlan({ room, geometry, flooring, skirting, selectedPiece, s
<div className="drawing-legend">
<span>
<i className="floor-key" />
Flooring
Flooring cuts
</span>
<span>
<i className="skirt-key" />
Skirting
Skirting cuts
</span>
<span>
<i className="uncut-key" />
Uncut
</span>
</div>
{interactive && <p className="drawing-help">Select a numbered piece for cut details.</p>}
<div className="drawing-viewport">
<svg
className="room-svg"
@ -212,18 +226,18 @@ export function FloorPlan({ room, geometry, flooring, skirting, selectedPiece, s
className={`floor-piece ${cut ? 'svg-cut floor-cut' : 'uncut'}`}
data-material="flooring"
data-piece-id={piece.id}
role={cut ? 'button' : undefined}
tabIndex={cut ? 0 : undefined}
role={cut && interactive ? 'button' : undefined}
tabIndex={cut && interactive ? 0 : undefined}
aria-hidden={cut ? undefined : true}
aria-label={cut ? `Select flooring cut ${piece.id}` : undefined}
aria-pressed={cut ? selectedPiece === piece.id : undefined}
onClick={cut ? () => select(piece.id) : undefined}
onClick={cut && interactive ? () => select?.(piece.id) : undefined}
onKeyDown={
cut
? (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
select(piece.id);
select?.(piece.id);
}
}
: undefined
@ -283,18 +297,18 @@ export function FloorPlan({ room, geometry, flooring, skirting, selectedPiece, s
className={`skirt-piece ${cut ? 'svg-cut skirt-cut' : 'uncut'}`}
data-material="skirting"
data-piece-id={piece.id}
role={cut ? 'button' : undefined}
tabIndex={cut ? 0 : undefined}
role={cut && interactive ? 'button' : undefined}
tabIndex={cut && interactive ? 0 : undefined}
aria-hidden={cut ? undefined : true}
aria-label={cut ? `Select skirting cut ${piece.id}` : undefined}
aria-pressed={cut ? selectedPiece === piece.id : undefined}
onClick={cut ? () => select(piece.id) : undefined}
onClick={cut && interactive ? () => select?.(piece.id) : undefined}
onKeyDown={
cut
? (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
select(piece.id);
select?.(piece.id);
}
}
: undefined
@ -302,8 +316,8 @@ export function FloorPlan({ room, geometry, flooring, skirting, selectedPiece, s
>
<polygon
points={points(polygon)}
fill={selectedPiece === piece.id ? '#17263f' : '#b74900'}
stroke="#8d3800"
fill={cut ? (selectedPiece === piece.id ? '#17263f' : '#b74900') : '#d8d5cd'}
stroke={cut ? '#8d3800' : '#79756b'}
strokeWidth={span * 0.001}
/>
{cut && (
@ -317,20 +331,20 @@ export function FloorPlan({ room, geometry, flooring, skirting, selectedPiece, s
/>
)}
{label && (
<g transform={`translate(${label.x} ${label.y})`} pointerEvents="none">
<g className="skirting-code" transform={`translate(${label.x} ${label.y})`}>
<rect
x={-font * 1.1}
y={-font * 0.58}
width={font * 2.2}
height={font * 1.16}
fill="#fffdf7"
stroke="#b74900"
fill="#b74900"
stroke="#8d3800"
strokeWidth={span * 0.0012}
/>
<text
textAnchor="middle"
dominantBaseline="middle"
fill="#8d3800"
fill="#fff"
fontSize={font * 0.8}
fontWeight="700"
>