图标可移动
This commit is contained in:
@@ -32,6 +32,9 @@ import {
|
||||
themeList,
|
||||
layoutList,
|
||||
outlineDepthOptions,
|
||||
backgroundRepeatList,
|
||||
backgroundPositionList,
|
||||
backgroundSizeList,
|
||||
} from "./mindmapOptions";
|
||||
import iconConfig from "./mindmapIconConfig";
|
||||
import imageConfig from "./mindmapImageConfig";
|
||||
@@ -288,7 +291,8 @@ const BaseStylePanel = ({ mindmap }: { mindmap: any }) => {
|
||||
const newStyle: Record<string, any> = {};
|
||||
[
|
||||
"backgroundColor", "lineColor", "lineWidth", "lineStyle",
|
||||
"paddingX", "paddingY"
|
||||
"paddingX", "paddingY",
|
||||
"backgroundImage", "backgroundRepeat", "backgroundPosition", "backgroundSize",
|
||||
].forEach(key => {
|
||||
newStyle[key] = mindmap.getThemeConfig(key);
|
||||
});
|
||||
@@ -315,6 +319,31 @@ const BaseStylePanel = ({ mindmap }: { mindmap: any }) => {
|
||||
value={style.backgroundColor}
|
||||
onChange={(v) => updateThemeConfig("backgroundColor", v)}
|
||||
/>
|
||||
<div className="space-y-2">
|
||||
<Label className="text-[11px] text-gray-500">背景图片</Label>
|
||||
<Input
|
||||
value={style.backgroundImage || ""}
|
||||
onChange={(e) => updateThemeConfig("backgroundImage", e.target.value || "")}
|
||||
placeholder="可粘贴图片地址"
|
||||
/>
|
||||
<div className="grid grid-cols-3 gap-2 text-[12px] text-gray-600">
|
||||
<NativeSelect
|
||||
value={style.backgroundRepeat || "no-repeat"}
|
||||
options={backgroundRepeatList.map((i) => ({ label: i.name, value: i.value }))}
|
||||
onChange={(v) => updateThemeConfig("backgroundRepeat", v)}
|
||||
/>
|
||||
<NativeSelect
|
||||
value={style.backgroundPosition || "center center"}
|
||||
options={backgroundPositionList.map((i) => ({ label: i.name, value: i.value }))}
|
||||
onChange={(v) => updateThemeConfig("backgroundPosition", v)}
|
||||
/>
|
||||
<NativeSelect
|
||||
value={style.backgroundSize || "cover"}
|
||||
options={backgroundSizeList.map((i) => ({ label: i.name, value: i.value }))}
|
||||
onChange={(v) => updateThemeConfig("backgroundSize", v)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
@@ -512,12 +541,12 @@ const IconPanel = ({ activeNodes }: { activeNodes: MindMapNode[] }) => {
|
||||
<button
|
||||
key={`${group.type}-${item.name}`}
|
||||
onClick={() => addIcon(group.type, item.name)}
|
||||
className="flex h-9 w-9 items-center justify-center rounded border border-gray-200 bg-white text-xs hover:border-blue-400 hover:shadow-sm"
|
||||
className="flex h-9 w-9 items-center justify-center rounded border border-gray-200 bg-white text-xs hover:border-blue-400 hover:shadow-sm overflow-hidden"
|
||||
>
|
||||
{item.icon ? (
|
||||
typeof item.icon === "string" && item.icon.trim().startsWith("<svg") ? (
|
||||
<span
|
||||
className="inline-flex h-6 w-6 items-center justify-center"
|
||||
className="inline-flex h-6 w-6 items-center justify-center overflow-hidden"
|
||||
// @ts-expect-error: dangerouslySetInnerHTML 用于复用官方 SVG 片段
|
||||
dangerouslySetInnerHTML={{ __html: item.icon }}
|
||||
/>
|
||||
@@ -691,19 +720,76 @@ const FormulaPanel = ({ mindmap }: { mindmap: any }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const NotePanel = ({ mindmap }: { mindmap: any }) => {
|
||||
const [note, setNote] = useState("备注内容");
|
||||
const apply = () => {
|
||||
const active = mindmap?.renderer?.activeNodeList || [];
|
||||
active.forEach((node: any) => mindmap?.execCommand?.("SET_NODE_NOTE", node, note));
|
||||
const NotePanel = ({ mindmap, activeNodes }: { mindmap: any; activeNodes: MindMapNode[] }) => {
|
||||
const [note, setNote] = useState("");
|
||||
|
||||
const readNote = (node: any) => {
|
||||
try {
|
||||
return (
|
||||
node?.getData?.("note") ??
|
||||
node?.nodeData?.data?.note ??
|
||||
node?.data?.note ??
|
||||
""
|
||||
);
|
||||
} catch {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
// 当选中节点变化时,自动展示首个节点的备注
|
||||
useEffect(() => {
|
||||
if (!activeNodes?.length) {
|
||||
setNote("");
|
||||
return;
|
||||
}
|
||||
const current = readNote(activeNodes[0]);
|
||||
setNote(typeof current === "string" ? current : "");
|
||||
}, [activeNodes]);
|
||||
|
||||
const getActiveList = () =>
|
||||
mindmap?.renderer?.activeNodeList?.length
|
||||
? mindmap.renderer.activeNodeList
|
||||
: activeNodes || [];
|
||||
|
||||
const apply = () => {
|
||||
const list = getActiveList();
|
||||
list.forEach((node: any) => mindmap?.execCommand?.("SET_NODE_NOTE", node, note));
|
||||
};
|
||||
|
||||
const clearNote = () => {
|
||||
const list = getActiveList();
|
||||
list.forEach((node: any) => mindmap?.execCommand?.("SET_NODE_NOTE", node, ""));
|
||||
setNote("");
|
||||
};
|
||||
|
||||
if (!activeNodes?.length) {
|
||||
return <div className="p-4 text-sm text-gray-400">请选择节点后编辑备注</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-3">
|
||||
<Label className="text-xs text-gray-500">节点备注</Label>
|
||||
<Input value={note} onChange={(e) => setNote(e.target.value)} />
|
||||
<button className="w-full rounded-md bg-blue-500 px-3 py-2 text-sm text-white hover:bg-blue-600" onClick={apply}>
|
||||
应用到选中节点
|
||||
</button>
|
||||
<Label className="text-xs text-gray-500">节点备注(自动载入首个选中节点)</Label>
|
||||
<textarea
|
||||
className="w-full rounded-md border border-gray-200 p-2 text-sm"
|
||||
rows={38}
|
||||
value={note}
|
||||
onChange={(e) => setNote(e.target.value)}
|
||||
placeholder="输入备注内容"
|
||||
/>
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
className="flex-1 rounded-md bg-blue-500 px-3 py-2 text-sm text-white hover:bg-blue-600"
|
||||
onClick={apply}
|
||||
>
|
||||
保存 / 更新
|
||||
</button>
|
||||
<button
|
||||
className="flex-1 rounded-md border border-gray-300 px-3 py-2 text-sm text-gray-700 hover:bg-gray-50"
|
||||
onClick={clearNote}
|
||||
>
|
||||
清除备注
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -750,7 +836,7 @@ export const MindmapSidebar = ({ mindmap, activeNodes, activeTab, onClose }: Sid
|
||||
case "formula":
|
||||
return <FormulaPanel mindmap={mindmap} />;
|
||||
case "note":
|
||||
return <NotePanel mindmap={mindmap} />;
|
||||
return <NotePanel mindmap={mindmap} activeNodes={activeNodes} />;
|
||||
case "ai":
|
||||
return <AiPanel />;
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user