figmatic-print-builder/elements/TableElement.jsx

131 lines
5.0 KiB
JavaScript

import { Group, Rect, Text, Transformer } from "react-konva";
import { useRef, useEffect } from "react";
import useEditorStore from "../useEditorStore";
export default function TableElement({ element }) {
const updateElement = useEditorStore((state) => state.updateElement);
const setSelectedId = useEditorStore((state) => state.setSelectedId);
const selectedId = useEditorStore((state) => state.selectedId);
const groupRef = useRef();
const trRef = useRef();
const isSelected = selectedId === element.id;
useEffect(() => {
if (isSelected && trRef.current && groupRef.current) {
trRef.current.nodes([groupRef.current]);
trRef.current.getLayer().batchDraw();
}
}, [isSelected]);
const visibleColumns = element.columns.filter((col) => col.visible);
const totalWidth = visibleColumns.reduce((sum, col) => sum + col.width, 0);
return (
<>
<Group
ref={groupRef}
x={element.x}
y={element.y}
rotation={element.rotation}
draggable
onClick={() => setSelectedId(element.id)}
onDragEnd={(e) => {
const snap = (v) => Math.round(v / 10) * 10;
updateElement(element.id, {
x: snap(e.target.x()),
y: snap(e.target.y()),
});
}}
onTransformEnd={() => {
const node = groupRef.current;
updateElement(element.id, {
rotation: node.rotation(),
});
}}
>
{/* Header Row */}
{visibleColumns.map((col, i) => {
const xPos = visibleColumns
.slice(0, i)
.reduce((sum, c) => sum + c.width, 0);
return (
<Group key={col.key}>
<Rect
x={xPos}
y={0}
width={col.width}
height={element.rowHeight}
fill={element.headerBg}
stroke={element.borderColor}
strokeWidth={1}
/>
<Text
text={col.label}
x={xPos + 5}
y={element.rowHeight / 2 - 7}
fontSize={12}
fontStyle="bold"
fill="#000"
/>
</Group>
);
})}
{/* Sample Data Rows */}
{element.showSampleData && element.sampleData && element.sampleData.map((row, rowIdx) => (
<Group key={rowIdx}>
{visibleColumns.map((col, colIdx) => {
const xPos = visibleColumns
.slice(0, colIdx)
.reduce((sum, c) => sum + c.width, 0);
const yPos = element.rowHeight * (rowIdx + 1);
return (
<Group key={`${rowIdx}-${col.key}`}>
<Rect
x={xPos}
y={yPos}
width={col.width}
height={element.rowHeight}
stroke={element.borderColor}
strokeWidth={1}
fill="#fff"
/>
<Text
text={row[col.key] || ""}
x={xPos + 5}
y={yPos + element.rowHeight / 2 - 7}
fontSize={11}
fill="#000"
/>
</Group>
);
})}
</Group>
))}
</Group>
{isSelected && (
<Transformer
ref={trRef}
enabledAnchors={[
"top-left",
"top-right",
"bottom-left",
"bottom-right",
]}
rotateEnabled={true}
boundBoxFunc={(oldBox, newBox) => {
if (newBox.width < 100 || newBox.height < 50) {
return oldBox;
}
return newBox;
}}
/>
)}
</>
);
}