diff --git a/src/components/md-deck/editor-panel/LayerEditorPanel.tsx b/src/components/md-deck/editor-panel/LayerEditorPanel.tsx index 0c6e33a..06a43ac 100644 --- a/src/components/md-deck/editor-panel/LayerEditorPanel.tsx +++ b/src/components/md-deck/editor-panel/LayerEditorPanel.tsx @@ -3,6 +3,7 @@ import { DragDropProvider, DragDropSensors, SortableProvider, + useDragDropContext, closestCenter, } from "@thisbeyond/solid-dnd"; import type { DeckStore } from "../hooks/deckStore"; @@ -24,6 +25,10 @@ function LayerEditorPanel(props: LayerEditorPanelProps) { side() === "front" ? store.state.frontLayerConfigs : store.state.backLayerConfigs; + + // Stable IDs for SortableProvider — simply the indices + const ids = createMemo(() => layers().map((_, i) => i)); + const updater = () => side() === "front" ? store.actions.updateFrontLayerConfig @@ -32,8 +37,7 @@ function LayerEditorPanel(props: LayerEditorPanelProps) { const availableFields = createMemo(() => { const cards = store.state.cards; if (!cards?.length) return []; - const used = new Set(layers().map((l) => l.prop)); - return Object.keys(cards[0]).filter((k) => k !== "label" && !used.has(k)); + return Object.keys(cards[0]).filter((k) => k !== "label"); }); const update = ( @@ -73,40 +77,37 @@ function LayerEditorPanel(props: LayerEditorPanelProps) { class="absolute top-full left-0 mt-1 w-full bg-white border border-gray-300 rounded shadow-lg z-20 max-h-48 overflow-y-auto" onClick={(e) => e.stopPropagation()} > - {availableFields().length === 0 ? ( -
所有字段已添加
- ) : ( - - {(f) => ( - - )} - - )} + + {(f) => ( + + )} + )} { - if (droppable) + if (droppable && draggable.id !== droppable.id) { store.actions.reorderLayers( side(), draggable.id as number, droppable.id as number, ); + } }} collisionDetector={closestCenter} > - i)}> + {(layer, index) => ( props.store.state.selectedLayer === props.index; onMount(() => { - const h = (e: MouseEvent) => { if (fontRef && !fontRef.contains(e.target as Node)) setFontOpen(false); }; + const h = (e: MouseEvent) => { + if (fontRef && !fontRef.contains(e.target as Node)) setFontOpen(false); + }; document.addEventListener("click", h); onCleanup(() => document.removeEventListener("click", h)); }); const toggleVisible = () => { - const fn = props.store.state.activeSide === "front" - ? props.store.actions.toggleFrontLayerVisible - : props.store.actions.toggleBackLayerVisible; + const fn = + props.store.state.activeSide === "front" + ? props.store.actions.toggleFrontLayerVisible + : props.store.actions.toggleBackLayerVisible; fn(props.index); }; return (
props.onHoverChange(props.index)} onMouseLeave={() => props.onHoverChange(null)} > - + - - + {props.layer.prop} @@ -87,50 +125,121 @@ export function LayerRow(props: LayerRowProps) { icon={orientChar(props.layer.orientation || "n")} visible={props.layer.visible} open={props.openDropdown === `orient-${props.index}`} - onToggle={() => props.setOpenDropdown(props.openDropdown === `orient-${props.index}` ? null : `orient-${props.index}`)} + onToggle={() => + props.setOpenDropdown( + props.openDropdown === `orient-${props.index}` + ? null + : `orient-${props.index}`, + ) + } title="方向" > - {(o) => } + {(o) => ( + + )} } + icon={ + align + } visible={props.layer.visible} open={props.openDropdown === `align-${props.index}`} - onToggle={() => props.setOpenDropdown(props.openDropdown === `align-${props.index}` ? null : `align-${props.index}`)} + onToggle={() => + props.setOpenDropdown( + props.openDropdown === `align-${props.index}` + ? null + : `align-${props.index}`, + ) + } title="对齐" > - {(o) => } + {(o) => ( + + )}
- + title="字体大小 (mm)" + > + {props.layer.fontSize ?? 3} + {fontOpen() && ( -
e.stopPropagation()}> +
e.stopPropagation()} + >
- props.onUpdateFontSize(e.target.value ? Number(e.target.value) : undefined)} - class="w-14 text-xs px-1.5 py-1 rounded border border-gray-300" step="0.1" min="0.1" /> + + props.onUpdateFontSize( + e.target.value ? Number(e.target.value) : undefined, + ) + } + class="w-14 text-xs px-1.5 py-1 rounded border border-gray-300" + step="0.1" + min="0.1" + /> mm
- {(p) => } + {(p) => ( + + )}
- +
)}
- + title="删除图层" + > + ✕ +
); } @@ -145,10 +254,24 @@ function DropdownButton(props: { }) { return (
- - {props.open &&
e.stopPropagation()}>{props.children}
} + title={props.title} + > + {props.icon} + + {props.open && ( +
e.stopPropagation()} + > + {props.children} +
+ )}
); }