figmatic-print-builder/LayersPanel.jsx

163 lines
4.8 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import useEditorStore from "./useEditorStore";
import { Eye, EyeOff, Trash2 } from "lucide-react";
export default function LayersPanel() {
const elements = useEditorStore((state) => state.elements);
const selectedId = useEditorStore((state) => state.selectedId);
const setSelectedId = useEditorStore((state) => state.setSelectedId);
const deleteElement = useEditorStore((state) => state.deleteElement);
const showLayers = useEditorStore((state) => state.showLayers);
const toggleLayers = useEditorStore((state) => state.toggleLayers);
if (!showLayers) return null;
const getElementIcon = (type) => {
const icons = {
text: "T",
image: "🖼️",
qrcode: "⊡",
line: "─",
rectangle: "▭",
summary: "Σ",
table: "⊞",
};
return icons[type] || "•";
};
const getElementLabel = (element) => {
if (element.type === "text") return element.text.substring(0, 20);
if (element.type === "image") return element.src ? "Image" : "Empty Image";
return element.type.charAt(0).toUpperCase() + element.type.slice(1);
};
return (
<div style={styles.panel}>
<div style={styles.header}>
<h4 style={styles.title}>Layers</h4>
<button onClick={toggleLayers} style={styles.closeBtn}>
×
</button>
</div>
<div style={styles.layersList}>
{elements.length === 0 ? (
<div style={styles.emptyState}>No elements</div>
) : (
[...elements].reverse().map((element, index) => (
<div
key={element.id}
style={{
...styles.layerItem,
...(selectedId === element.id ? styles.layerItemSelected : {}),
}}
onClick={() => setSelectedId(element.id)}
>
<div style={styles.layerInfo}>
<span style={styles.layerIcon}>{getElementIcon(element.type)}</span>
<span style={styles.layerLabel}>{getElementLabel(element)}</span>
</div>
<button
onClick={(e) => {
e.stopPropagation();
deleteElement(element.id);
}}
style={styles.deleteBtn}
title="Delete"
>
<Trash2 size={14} />
</button>
</div>
))
)}
</div>
</div>
);
}
const styles = {
panel: {
width: 220,
background: "#fff",
borderRight: "1px solid #ddd",
display: "flex",
flexDirection: "column",
height: "100%",
},
header: {
padding: "12px 16px",
borderBottom: "1px solid #ddd",
display: "flex",
justifyContent: "space-between",
alignItems: "center",
},
title: {
margin: 0,
fontSize: 14,
fontWeight: 600,
},
closeBtn: {
background: "none",
border: "none",
fontSize: 24,
cursor: "pointer",
padding: 0,
lineHeight: 1,
color: "#666",
},
layersList: {
flex: 1,
overflowY: "auto",
padding: 8,
},
emptyState: {
textAlign: "center",
color: "#999",
fontSize: 13,
marginTop: 20,
},
layerItem: {
padding: "8px 12px",
marginBottom: 4,
borderRadius: 4,
cursor: "pointer",
display: "flex",
justifyContent: "space-between",
alignItems: "center",
transition: "all 0.2s",
border: "1px solid transparent",
},
layerItemSelected: {
background: "#e3f2fd",
border: "1px solid #2196f3",
},
layerInfo: {
display: "flex",
alignItems: "center",
gap: 8,
flex: 1,
overflow: "hidden",
},
layerIcon: {
fontSize: 16,
width: 20,
textAlign: "center",
},
layerLabel: {
fontSize: 13,
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
},
deleteBtn: {
background: "none",
border: "none",
cursor: "pointer",
padding: 4,
display: "flex",
alignItems: "center",
color: "#666",
opacity: 0.6,
transition: "opacity 0.2s",
},
};