@xiangfa/mindmap 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +13 -0
- package/README.md +106 -6
- package/README.zh-CN.md +106 -6
- package/dist/components/MindMapAIInput.d.ts +13 -0
- package/dist/components/MindMapContextMenu.d.ts +1 -1
- package/dist/components/MindMapControls.d.ts +1 -1
- package/dist/components/icons.d.ts +4 -0
- package/dist/esm/MindMap2.js +322 -320
- package/dist/esm/components/MindMapAIInput.js +199 -0
- package/dist/esm/components/MindMapContextMenu.js +28 -57
- package/dist/esm/components/MindMapControls.js +14 -27
- package/dist/esm/components/MindMapNode.js +8 -27
- package/dist/esm/components/icons.js +78 -1
- package/dist/esm/hooks/useNodeEdit.js +1 -1
- package/dist/esm/hooks/usePanZoom.js +3 -1
- package/dist/esm/plugins/tags.js +8 -8
- package/dist/esm/style.css +1 -1
- package/dist/esm/utils/export.js +25 -25
- package/dist/esm/utils/i18n.js +6 -0
- package/dist/esm/utils/layout.js +26 -18
- package/dist/esm/utils/markdown.js +1 -1
- package/dist/esm/utils/theme.js +44 -1
- package/dist/index.d.ts +1 -1
- package/dist/mindmap.umd.cjs +75 -16
- package/dist/plugins/tags.d.ts +1 -1
- package/dist/style.css +1 -1
- package/dist/types.d.ts +10 -0
- package/dist/utils/export.d.ts +2 -1
- package/dist/utils/i18n.d.ts +3 -0
- package/dist/utils/theme.d.ts +10 -0
- package/package.json +2 -1
- package/dist/esm/logo.svg +0 -9
- package/dist/logo.svg +0 -9
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { IconClose as e, IconLightning as t, IconLoaderCircle as n, IconPaperclip as r, IconStop as i } from "./icons.js";
|
|
2
|
+
import { useCallback as a, useRef as o, useState as s } from "react";
|
|
3
|
+
import { Fragment as c, jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
4
|
+
//#region src/components/MindMap/components/MindMapAIInput.tsx
|
|
5
|
+
var d = "#Role\nYou are a professional Mind Map Generator specializing in hierarchical information architecture. Your objective is to deconstruct complex topics into a robust, visual Markdown outline.\n\n#Logic and Structure\n- Primary Branches: Use the MECE (Mutually Exclusive, Collectively Exhaustive) principle to ensure no overlap and complete coverage of the topic.\n- Branching Density: Aim for 3-5 primary branches. For narrow topics that do not naturally yield five branches, provide at least 3 branches and prioritize hierarchical depth over breadth.\n- Hierarchical Depth: The structure must not exceed a maximum depth of the Root + 3 levels.\n- Logical Flow: Organize the sequence of branches and sub-nodes based on priority, moving from foundational concepts to advanced applications.\n\n#Formatting Standards\n- Root Node: Place the root node on the first line of the response with no prefix (no hyphen, bullet, or number).\n- Indentation: Use exactly two spaces per level of hierarchy to define the structure.\n- Child Node Prefix: Every child node must start with a hyphen followed by a space (\"- \").\n- Text Constraints: Each node must contain between 2 and 6 visible words. Markdown formatting characters (e.g., **, ==, `) do not count toward this 2-6 word limit.\n- Remarks: Insert contextual notes or brief explanations immediately after relevant nodes using the \"> \" prefix.\n- Inline Styling: Use Obsidian-compatible Markdown for emphasis: **bold**, *italic*, `code`, ~~strikethrough~~, and ==highlighting==.\n\n#Extended Syntax (Optional)\nUse these features only when they naturally enhance the mind map's clarity or structure. Do not force them into every response.\n- Dotted Lines: Use \"-.\" instead of \"-\" for weak, optional, or tentative relationships. Example: \"-. Optional Step\"\n- Multi-line Content: Use \"|\" prefix lines to append additional display lines to a node. Example:\n - Main Point\n | Supporting detail line 1\n | Supporting detail line 2\n- Tags: Add \"#tag\" at the end of node text for categorization. Example: \"- React #frontend #framework\"\n- Cross-links: Define anchors with \"{#id}\" and link with \"-> {#id}\" to connect nodes across branches. Example:\n - Node A {#a}\n - Node B\n -> {#a} \"references\"\n- Folding: Use \"+\" instead of \"-\" to mark a node as initially collapsed (children hidden by default). Example: \"+ Collapsed Section\"\n- LaTeX: Use \"$...$\" for inline math and \"$$...$$\" for display math. Example: \"- Energy: $E = mc^2$\"\n- Frontmatter: Use a \"---\" block at the very top to set layout direction or theme:\n ---\n direction: right\n theme: dark\n ---\n\n#Example Output\nProject Management\n- **Foundational Concepts** #core\n - Project Life Cycle\n > Initiation through closing phases\n | Planning, executing, monitoring\n - Stakeholder Identification\n- *Execution Frameworks*\n - ==Agile Methodologies==\n -. Hybrid Approaches\n- Advanced Optimization\n - Resource Load Balancing\n > Optimizing team allocation\n - Portfolio Risk Mitigation\n\n#Constraints\n- Provide the raw Markdown output only.\n- Do not include any introductory text, conversational fillers, or explanations.\n- Do not include any concluding remarks or summaries.\n- Use extended syntax features (dotted lines, tags, multi-line, cross-links, etc.) only when they genuinely improve the mind map's clarity or structure. Default to basic syntax.\n- FINAL NEGATIVE CONSTRAINT: Do not wrap the output in markdown code fences. Provide the response as raw, plain text.";
|
|
6
|
+
function f(e) {
|
|
7
|
+
if (!e || e.length === 0) return "";
|
|
8
|
+
let t = [];
|
|
9
|
+
for (let n of e) n === "text" ? t.push("text/*,.json,.js,.ts,.xml,.yaml,.yml,.sql,.sh,.md") : n === "image" ? t.push("image/*") : n === "pdf" && t.push("application/pdf");
|
|
10
|
+
return t.join(",");
|
|
11
|
+
}
|
|
12
|
+
function p(e, t) {
|
|
13
|
+
if (t.length === 0) return e;
|
|
14
|
+
let n = [{
|
|
15
|
+
type: "text",
|
|
16
|
+
text: e
|
|
17
|
+
}];
|
|
18
|
+
for (let e of t) if (e.type.startsWith("image/")) n.push({
|
|
19
|
+
type: "image_url",
|
|
20
|
+
image_url: { url: e.base64 }
|
|
21
|
+
});
|
|
22
|
+
else {
|
|
23
|
+
let t = atob(e.base64.split(",")[1] || "");
|
|
24
|
+
n.push({
|
|
25
|
+
type: "text",
|
|
26
|
+
text: `[File: ${e.name}]\n${t}`
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
return n;
|
|
30
|
+
}
|
|
31
|
+
function m(e) {
|
|
32
|
+
let t = e.replace(/<think>[\s\S]*?<\/think>/g, "");
|
|
33
|
+
return t = t.replace(/<think>[\s\S]*$/, ""), t;
|
|
34
|
+
}
|
|
35
|
+
async function* h(e) {
|
|
36
|
+
let t = new TextDecoder(), n = "";
|
|
37
|
+
for (;;) {
|
|
38
|
+
let { done: r, value: i } = await e.read();
|
|
39
|
+
if (r) break;
|
|
40
|
+
n += t.decode(i, { stream: !0 });
|
|
41
|
+
let a = n.split("\n");
|
|
42
|
+
n = a.pop() || "";
|
|
43
|
+
for (let e of a) {
|
|
44
|
+
let t = e.trim();
|
|
45
|
+
if (t === "data: [DONE]") return;
|
|
46
|
+
if (t.startsWith("data: ")) try {
|
|
47
|
+
let e = JSON.parse(t.slice(6)).choices?.[0]?.delta?.content;
|
|
48
|
+
e && (yield e);
|
|
49
|
+
} catch {}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function g({ config: g, theme: _, messages: v, currentMarkdown: y, onMarkdownStream: b, onComplete: x, onError: S }) {
|
|
54
|
+
let [C, w] = s(""), [T, E] = s(!1), [D, O] = s([]), [k, A] = s(null), j = o(null), M = o(null), N = o(0), P = g.attachments && g.attachments.length > 0, F = a(async () => {
|
|
55
|
+
let e = C.trim();
|
|
56
|
+
if (!e && D.length === 0 || T) return;
|
|
57
|
+
E(!0), A(null);
|
|
58
|
+
let t = new AbortController();
|
|
59
|
+
j.current = t;
|
|
60
|
+
try {
|
|
61
|
+
let n = p(e, D), r = g.systemPrompt || d, i = y?.trim() ? `${r}\n\n#Current Mind Map\nThe user already has the following mind map. They may ask you to modify, expand, or optimize it. If the user's request is about the existing content, use it as the base and output the updated version. If the request is about a new topic, generate a fresh mind map.\n\n\`\`\`\n${y.trim()}\n\`\`\`` : r, a = JSON.stringify({
|
|
62
|
+
model: g.model,
|
|
63
|
+
messages: [{
|
|
64
|
+
role: "system",
|
|
65
|
+
content: i
|
|
66
|
+
}, {
|
|
67
|
+
role: "user",
|
|
68
|
+
content: n
|
|
69
|
+
}],
|
|
70
|
+
stream: !0
|
|
71
|
+
}), o = await fetch(g.apiUrl, {
|
|
72
|
+
method: "POST",
|
|
73
|
+
headers: {
|
|
74
|
+
"Content-Type": "application/json",
|
|
75
|
+
Authorization: `Bearer ${g.apiKey}`
|
|
76
|
+
},
|
|
77
|
+
body: a,
|
|
78
|
+
signal: t.signal
|
|
79
|
+
});
|
|
80
|
+
if (!o.ok) throw Error(`API error: ${o.status}`);
|
|
81
|
+
let s = o.body?.getReader();
|
|
82
|
+
if (!s) throw Error("No response body");
|
|
83
|
+
let c = "", l = !1;
|
|
84
|
+
for await (let e of h(s)) if (c += e, !l) {
|
|
85
|
+
l = !0;
|
|
86
|
+
let e = m(c);
|
|
87
|
+
N.current = requestAnimationFrame(() => {
|
|
88
|
+
b(e), l = !1;
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
cancelAnimationFrame(N.current), c && b(m(c)), w(""), O([]), x();
|
|
92
|
+
} catch (e) {
|
|
93
|
+
if (e.name === "AbortError") x();
|
|
94
|
+
else {
|
|
95
|
+
let t = e.message || v.aiError;
|
|
96
|
+
A(t), S(t), setTimeout(() => A(null), 4e3);
|
|
97
|
+
}
|
|
98
|
+
} finally {
|
|
99
|
+
E(!1), j.current = null;
|
|
100
|
+
}
|
|
101
|
+
}, [
|
|
102
|
+
C,
|
|
103
|
+
D,
|
|
104
|
+
T,
|
|
105
|
+
g,
|
|
106
|
+
y,
|
|
107
|
+
v,
|
|
108
|
+
b,
|
|
109
|
+
x,
|
|
110
|
+
S
|
|
111
|
+
]), I = a(() => {
|
|
112
|
+
j.current?.abort();
|
|
113
|
+
}, []), L = a((e) => {
|
|
114
|
+
e.key === "Enter" && !e.shiftKey && (e.preventDefault(), F());
|
|
115
|
+
}, [F]), R = a((e) => {
|
|
116
|
+
let t = e.target.files;
|
|
117
|
+
t && (Array.from(t).forEach((e) => {
|
|
118
|
+
let t = new FileReader();
|
|
119
|
+
t.onload = () => {
|
|
120
|
+
O((n) => [...n, {
|
|
121
|
+
name: e.name,
|
|
122
|
+
type: e.type,
|
|
123
|
+
base64: t.result
|
|
124
|
+
}]);
|
|
125
|
+
}, t.readAsDataURL(e);
|
|
126
|
+
}), e.target.value = "");
|
|
127
|
+
}, []), z = a((e) => {
|
|
128
|
+
O((t) => t.filter((t, n) => n !== e));
|
|
129
|
+
}, []);
|
|
130
|
+
return /* @__PURE__ */ u("div", {
|
|
131
|
+
className: "mindmap-ai-input",
|
|
132
|
+
children: [
|
|
133
|
+
D.length > 0 && /* @__PURE__ */ l("div", {
|
|
134
|
+
className: "mindmap-ai-file-previews",
|
|
135
|
+
children: D.map((t, n) => /* @__PURE__ */ u("span", {
|
|
136
|
+
className: "mindmap-ai-file-chip",
|
|
137
|
+
children: [/* @__PURE__ */ l("span", {
|
|
138
|
+
className: "mindmap-ai-file-name",
|
|
139
|
+
children: t.name
|
|
140
|
+
}), /* @__PURE__ */ l("button", {
|
|
141
|
+
className: "mindmap-ai-file-remove",
|
|
142
|
+
onClick: () => z(n),
|
|
143
|
+
children: /* @__PURE__ */ l(e, { size: 12 })
|
|
144
|
+
})]
|
|
145
|
+
}, n))
|
|
146
|
+
}),
|
|
147
|
+
/* @__PURE__ */ u("div", {
|
|
148
|
+
className: "mindmap-ai-input-row",
|
|
149
|
+
children: [
|
|
150
|
+
P && /* @__PURE__ */ u(c, { children: [/* @__PURE__ */ l("button", {
|
|
151
|
+
className: "mindmap-ai-attach-btn",
|
|
152
|
+
onClick: () => M.current?.click(),
|
|
153
|
+
disabled: T,
|
|
154
|
+
title: v.aiPlaceholder,
|
|
155
|
+
children: /* @__PURE__ */ l(r, { size: 18 })
|
|
156
|
+
}), /* @__PURE__ */ l("input", {
|
|
157
|
+
ref: M,
|
|
158
|
+
type: "file",
|
|
159
|
+
accept: f(g.attachments),
|
|
160
|
+
multiple: !0,
|
|
161
|
+
style: { display: "none" },
|
|
162
|
+
onChange: R
|
|
163
|
+
})] }),
|
|
164
|
+
/* @__PURE__ */ l("input", {
|
|
165
|
+
className: "mindmap-ai-input-field",
|
|
166
|
+
type: "text",
|
|
167
|
+
value: T ? "" : C,
|
|
168
|
+
onChange: (e) => w(e.target.value),
|
|
169
|
+
onKeyDown: L,
|
|
170
|
+
placeholder: T ? v.aiGenerating : v.aiPlaceholder,
|
|
171
|
+
disabled: T
|
|
172
|
+
}),
|
|
173
|
+
/* @__PURE__ */ l("button", {
|
|
174
|
+
className: `mindmap-ai-send-btn${T ? " mindmap-ai-send-btn--loading" : ""}`,
|
|
175
|
+
onClick: T ? I : F,
|
|
176
|
+
disabled: !T && !C.trim() && D.length === 0,
|
|
177
|
+
style: {
|
|
178
|
+
background: T ? "transparent" : !C.trim() && D.length === 0 ? _.controls.hoverBg : _.root.bgColor,
|
|
179
|
+
color: T || !C.trim() && D.length === 0 ? _.controls.textColor : _.root.textColor
|
|
180
|
+
},
|
|
181
|
+
children: T ? /* @__PURE__ */ u(c, { children: [/* @__PURE__ */ l("span", {
|
|
182
|
+
className: "mindmap-ai-spinner",
|
|
183
|
+
children: /* @__PURE__ */ l(n, { size: 20 })
|
|
184
|
+
}), /* @__PURE__ */ l("span", {
|
|
185
|
+
className: "mindmap-ai-stop-icon",
|
|
186
|
+
children: /* @__PURE__ */ l(i, { size: 16 })
|
|
187
|
+
})] }) : /* @__PURE__ */ l(t, { size: 16 })
|
|
188
|
+
})
|
|
189
|
+
]
|
|
190
|
+
}),
|
|
191
|
+
k && /* @__PURE__ */ l("div", {
|
|
192
|
+
className: "mindmap-ai-error",
|
|
193
|
+
children: k
|
|
194
|
+
})
|
|
195
|
+
]
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
//#endregion
|
|
199
|
+
export { g as MindMapAIInput };
|
|
@@ -1,116 +1,87 @@
|
|
|
1
1
|
import { useState as e } from "react";
|
|
2
2
|
import { Fragment as t, jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
3
3
|
//#region src/components/MindMap/components/MindMapContextMenu.tsx
|
|
4
|
-
function i({ position: i,
|
|
5
|
-
let [
|
|
4
|
+
function i({ position: i, messages: a, readonly: o, onNewRootNode: s, onExportSVG: c, onExportPNG: l, onExportMarkdown: u, onDirectionChange: d, onClose: f }) {
|
|
5
|
+
let [p, m] = e(!1), [h, g] = e(!1);
|
|
6
6
|
return /* @__PURE__ */ r("div", {
|
|
7
7
|
className: "mindmap-context-menu",
|
|
8
8
|
style: {
|
|
9
9
|
left: i.x,
|
|
10
|
-
top: i.y
|
|
11
|
-
background: a.contextMenu.bgColor,
|
|
12
|
-
color: a.contextMenu.textColor,
|
|
13
|
-
boxShadow: `0 4px 16px ${a.contextMenu.shadowColor}`,
|
|
14
|
-
borderColor: a.contextMenu.borderColor
|
|
10
|
+
top: i.y
|
|
15
11
|
},
|
|
16
12
|
onClick: (e) => e.stopPropagation(),
|
|
17
13
|
children: [
|
|
18
|
-
!
|
|
14
|
+
!o && /* @__PURE__ */ r(t, { children: [/* @__PURE__ */ n("div", {
|
|
19
15
|
className: "mindmap-ctx-item mindmap-ctx-new-root",
|
|
20
|
-
onClick:
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}), /* @__PURE__ */ n("div", {
|
|
24
|
-
className: "mindmap-ctx-divider",
|
|
25
|
-
style: { borderColor: a.contextMenu.borderColor }
|
|
26
|
-
})] }),
|
|
16
|
+
onClick: s,
|
|
17
|
+
children: a.newRootNode
|
|
18
|
+
}), /* @__PURE__ */ n("div", { className: "mindmap-ctx-divider" })] }),
|
|
27
19
|
/* @__PURE__ */ r("div", {
|
|
28
20
|
className: "mindmap-ctx-item mindmap-ctx-has-sub mindmap-ctx-layout",
|
|
29
|
-
onMouseEnter: () =>
|
|
30
|
-
onMouseLeave: () =>
|
|
31
|
-
style: { color: a.contextMenu.textColor },
|
|
21
|
+
onMouseEnter: () => g(!0),
|
|
22
|
+
onMouseLeave: () => g(!1),
|
|
32
23
|
children: [
|
|
33
|
-
|
|
24
|
+
a.layout,
|
|
34
25
|
/* @__PURE__ */ n("span", {
|
|
35
26
|
className: "mindmap-ctx-arrow",
|
|
36
27
|
children: "▶"
|
|
37
28
|
}),
|
|
38
|
-
|
|
29
|
+
h && /* @__PURE__ */ r("div", {
|
|
39
30
|
className: "mindmap-ctx-submenu",
|
|
40
|
-
style: {
|
|
41
|
-
background: a.contextMenu.bgColor,
|
|
42
|
-
boxShadow: `0 4px 16px ${a.contextMenu.shadowColor}`,
|
|
43
|
-
borderColor: a.contextMenu.borderColor
|
|
44
|
-
},
|
|
45
31
|
children: [
|
|
46
32
|
/* @__PURE__ */ n("div", {
|
|
47
33
|
className: "mindmap-ctx-item mindmap-ctx-layout-left",
|
|
48
34
|
onClick: () => {
|
|
49
|
-
|
|
35
|
+
d("left"), f();
|
|
50
36
|
},
|
|
51
|
-
|
|
52
|
-
children: o.layoutLeft
|
|
37
|
+
children: a.layoutLeft
|
|
53
38
|
}),
|
|
54
39
|
/* @__PURE__ */ n("div", {
|
|
55
40
|
className: "mindmap-ctx-item mindmap-ctx-layout-both",
|
|
56
41
|
onClick: () => {
|
|
57
|
-
|
|
42
|
+
d("both"), f();
|
|
58
43
|
},
|
|
59
|
-
|
|
60
|
-
children: o.layoutBoth
|
|
44
|
+
children: a.layoutBoth
|
|
61
45
|
}),
|
|
62
46
|
/* @__PURE__ */ n("div", {
|
|
63
47
|
className: "mindmap-ctx-item mindmap-ctx-layout-right",
|
|
64
48
|
onClick: () => {
|
|
65
|
-
|
|
49
|
+
d("right"), f();
|
|
66
50
|
},
|
|
67
|
-
|
|
68
|
-
children: o.layoutRight
|
|
51
|
+
children: a.layoutRight
|
|
69
52
|
})
|
|
70
53
|
]
|
|
71
54
|
})
|
|
72
55
|
]
|
|
73
56
|
}),
|
|
74
|
-
/* @__PURE__ */ n("div", {
|
|
75
|
-
className: "mindmap-ctx-divider",
|
|
76
|
-
style: { borderColor: a.contextMenu.borderColor }
|
|
77
|
-
}),
|
|
57
|
+
/* @__PURE__ */ n("div", { className: "mindmap-ctx-divider" }),
|
|
78
58
|
/* @__PURE__ */ r("div", {
|
|
79
59
|
className: "mindmap-ctx-item mindmap-ctx-has-sub mindmap-ctx-export",
|
|
80
|
-
onMouseEnter: () =>
|
|
81
|
-
onMouseLeave: () =>
|
|
82
|
-
style: { color: a.contextMenu.textColor },
|
|
60
|
+
onMouseEnter: () => m(!0),
|
|
61
|
+
onMouseLeave: () => m(!1),
|
|
83
62
|
children: [
|
|
84
|
-
|
|
63
|
+
a.export,
|
|
85
64
|
/* @__PURE__ */ n("span", {
|
|
86
65
|
className: "mindmap-ctx-arrow",
|
|
87
66
|
children: "▶"
|
|
88
67
|
}),
|
|
89
|
-
|
|
68
|
+
p && /* @__PURE__ */ r("div", {
|
|
90
69
|
className: "mindmap-ctx-submenu",
|
|
91
|
-
style: {
|
|
92
|
-
background: a.contextMenu.bgColor,
|
|
93
|
-
boxShadow: `0 4px 16px ${a.contextMenu.shadowColor}`,
|
|
94
|
-
borderColor: a.contextMenu.borderColor
|
|
95
|
-
},
|
|
96
70
|
children: [
|
|
97
71
|
/* @__PURE__ */ n("div", {
|
|
98
72
|
className: "mindmap-ctx-item mindmap-ctx-export-svg",
|
|
99
|
-
onClick:
|
|
100
|
-
|
|
101
|
-
children: o.exportSVG
|
|
73
|
+
onClick: c,
|
|
74
|
+
children: a.exportSVG
|
|
102
75
|
}),
|
|
103
76
|
/* @__PURE__ */ n("div", {
|
|
104
77
|
className: "mindmap-ctx-item mindmap-ctx-export-png",
|
|
105
|
-
onClick:
|
|
106
|
-
|
|
107
|
-
children: o.exportPNG
|
|
78
|
+
onClick: l,
|
|
79
|
+
children: a.exportPNG
|
|
108
80
|
}),
|
|
109
81
|
/* @__PURE__ */ n("div", {
|
|
110
82
|
className: "mindmap-ctx-item mindmap-ctx-export-md",
|
|
111
|
-
onClick:
|
|
112
|
-
|
|
113
|
-
children: o.exportMarkdown
|
|
83
|
+
onClick: u,
|
|
84
|
+
children: a.exportMarkdown
|
|
114
85
|
})
|
|
115
86
|
]
|
|
116
87
|
})
|
|
@@ -1,48 +1,36 @@
|
|
|
1
1
|
import { IconMinus as e, IconPlus as t } from "./icons.js";
|
|
2
2
|
import { Fragment as n, jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
3
3
|
//#region src/components/MindMap/components/MindMapControls.tsx
|
|
4
|
-
function a({ zoom: a,
|
|
5
|
-
return /* @__PURE__ */ i(n, { children: [
|
|
4
|
+
function a({ zoom: a, messages: o, showZoom: s = !0, mode: c, isFullscreen: l, onZoomIn: u, onZoomOut: d, onAutoFit: f, onModeToggle: p, onFullscreenToggle: m }) {
|
|
5
|
+
return /* @__PURE__ */ i(n, { children: [s && /* @__PURE__ */ i("div", {
|
|
6
6
|
className: "mindmap-zoom-controls",
|
|
7
|
-
style: {
|
|
8
|
-
background: o.controls.bgColor,
|
|
9
|
-
color: o.controls.textColor
|
|
10
|
-
},
|
|
11
7
|
children: [
|
|
12
8
|
/* @__PURE__ */ r("button", {
|
|
13
9
|
className: "mindmap-ctrl-btn mindmap-ctrl-zoom-out",
|
|
14
|
-
onClick:
|
|
15
|
-
title:
|
|
16
|
-
style: { color: o.controls.textColor },
|
|
10
|
+
onClick: d,
|
|
11
|
+
title: o.zoomOut,
|
|
17
12
|
children: /* @__PURE__ */ r(e, { size: 16 })
|
|
18
13
|
}),
|
|
19
14
|
/* @__PURE__ */ i("button", {
|
|
20
15
|
className: "mindmap-ctrl-pct",
|
|
21
|
-
onClick:
|
|
22
|
-
title:
|
|
23
|
-
style: { color: o.controls.textColor },
|
|
16
|
+
onClick: f,
|
|
17
|
+
title: o.resetView,
|
|
24
18
|
children: [Math.round(a * 100), "%"]
|
|
25
19
|
}),
|
|
26
20
|
/* @__PURE__ */ r("button", {
|
|
27
21
|
className: "mindmap-ctrl-btn mindmap-ctrl-zoom-in",
|
|
28
|
-
onClick:
|
|
29
|
-
title:
|
|
30
|
-
style: { color: o.controls.textColor },
|
|
22
|
+
onClick: u,
|
|
23
|
+
title: o.zoomIn,
|
|
31
24
|
children: /* @__PURE__ */ r(t, { size: 16 })
|
|
32
25
|
})
|
|
33
26
|
]
|
|
34
27
|
}), /* @__PURE__ */ i("div", {
|
|
35
28
|
className: "mindmap-extra-controls",
|
|
36
|
-
style: {
|
|
37
|
-
background: o.controls.bgColor,
|
|
38
|
-
color: o.controls.textColor
|
|
39
|
-
},
|
|
40
29
|
children: [/* @__PURE__ */ r("button", {
|
|
41
30
|
className: "mindmap-ctrl-btn mindmap-ctrl-mode",
|
|
42
|
-
onClick:
|
|
43
|
-
title:
|
|
44
|
-
|
|
45
|
-
children: l === "view" ? /* @__PURE__ */ i("svg", {
|
|
31
|
+
onClick: p,
|
|
32
|
+
title: c === "view" ? o.textMode : o.viewMode,
|
|
33
|
+
children: c === "view" ? /* @__PURE__ */ i("svg", {
|
|
46
34
|
width: 16,
|
|
47
35
|
height: 16,
|
|
48
36
|
viewBox: "0 0 24 24",
|
|
@@ -73,10 +61,9 @@ function a({ zoom: a, theme: o, messages: s, showZoom: c = !0, mode: l, isFullsc
|
|
|
73
61
|
})
|
|
74
62
|
}), /* @__PURE__ */ r("button", {
|
|
75
63
|
className: "mindmap-ctrl-btn mindmap-ctrl-fullscreen",
|
|
76
|
-
onClick:
|
|
77
|
-
title:
|
|
78
|
-
|
|
79
|
-
children: u ? /* @__PURE__ */ i("svg", {
|
|
64
|
+
onClick: m,
|
|
65
|
+
title: l ? o.exitFullscreen : o.fullscreen,
|
|
66
|
+
children: l ? /* @__PURE__ */ i("svg", {
|
|
80
67
|
width: 16,
|
|
81
68
|
height: 16,
|
|
82
69
|
viewBox: "0 0 24 24",
|
|
@@ -193,17 +193,12 @@ function _({ node: n, fontSize: r, fontWeight: d, fontFamily: m, textColor: _, o
|
|
|
193
193
|
y: -l / 2,
|
|
194
194
|
width: c,
|
|
195
195
|
height: l,
|
|
196
|
-
style: {
|
|
197
|
-
overflow: "visible",
|
|
198
|
-
pointerEvents: "none"
|
|
199
|
-
},
|
|
200
196
|
children: /* @__PURE__ */ f("div", {
|
|
197
|
+
className: "mindmap-latex-content",
|
|
201
198
|
style: {
|
|
202
199
|
fontSize: r * .75,
|
|
203
200
|
lineHeight: `${l}px`,
|
|
204
|
-
color: _
|
|
205
|
-
whiteSpace: "nowrap",
|
|
206
|
-
textAlign: "center"
|
|
201
|
+
color: _
|
|
207
202
|
},
|
|
208
203
|
dangerouslySetInnerHTML: { __html: i }
|
|
209
204
|
})
|
|
@@ -257,17 +252,12 @@ function _({ node: n, fontSize: r, fontWeight: d, fontFamily: m, textColor: _, o
|
|
|
257
252
|
y: u - p / 2,
|
|
258
253
|
width: d,
|
|
259
254
|
height: p,
|
|
260
|
-
style: {
|
|
261
|
-
overflow: "visible",
|
|
262
|
-
pointerEvents: "none"
|
|
263
|
-
},
|
|
264
255
|
children: /* @__PURE__ */ f("div", {
|
|
256
|
+
className: "mindmap-latex-content",
|
|
265
257
|
style: {
|
|
266
258
|
fontSize: o * .75,
|
|
267
259
|
lineHeight: `${p}px`,
|
|
268
260
|
color: _,
|
|
269
|
-
whiteSpace: "nowrap",
|
|
270
|
-
textAlign: "center",
|
|
271
261
|
opacity: .8
|
|
272
262
|
},
|
|
273
263
|
dangerouslySetInnerHTML: { __html: r }
|
|
@@ -322,7 +312,6 @@ function _({ node: n, fontSize: r, fontWeight: d, fontFamily: m, textColor: _, o
|
|
|
322
312
|
dominantBaseline: "central",
|
|
323
313
|
fontSize: N,
|
|
324
314
|
opacity: .5,
|
|
325
|
-
style: { cursor: "help" },
|
|
326
315
|
onMouseEnter: () => v?.(n.id),
|
|
327
316
|
onMouseLeave: () => v?.(null),
|
|
328
317
|
children: [/* @__PURE__ */ f("title", { children: n.remark }), "💬"]
|
|
@@ -336,15 +325,12 @@ function v({ node: e, offset: t, isEditing: n, isPendingEdit: i, isSelected: a,
|
|
|
336
325
|
let t = u.root.bgColor;
|
|
337
326
|
return /* @__PURE__ */ p("g", {
|
|
338
327
|
transform: `translate(${O}, ${k})`,
|
|
339
|
-
className: `mindmap-node-g mindmap-node-root ${c} ${M} ${N}`,
|
|
328
|
+
className: `mindmap-node-g mindmap-node-root ${c} ${M} ${N}${s ? " mindmap-node-ghost" : ""}`,
|
|
329
|
+
"data-branch-index": e.branchIndex,
|
|
340
330
|
onMouseDown: (t) => v(t, e.id),
|
|
341
331
|
onClick: (t) => y(t, e.id),
|
|
342
332
|
onDoubleClick: (t) => b(t, e.id, F),
|
|
343
|
-
style:
|
|
344
|
-
cursor: "pointer",
|
|
345
|
-
opacity: s ? .3 : 1,
|
|
346
|
-
...P
|
|
347
|
-
},
|
|
333
|
+
style: P,
|
|
348
334
|
children: [
|
|
349
335
|
/* @__PURE__ */ f("rect", {
|
|
350
336
|
className: "mindmap-node-bg",
|
|
@@ -454,7 +440,6 @@ function v({ node: e, offset: t, isEditing: n, isPendingEdit: i, isSelected: a,
|
|
|
454
440
|
}),
|
|
455
441
|
e.collapsed !== void 0 && h && E && /* @__PURE__ */ f("g", {
|
|
456
442
|
className: "mindmap-fold-btn",
|
|
457
|
-
style: { cursor: "pointer" },
|
|
458
443
|
onMouseDown: (e) => e.stopPropagation(),
|
|
459
444
|
onClick: (t) => {
|
|
460
445
|
t.stopPropagation(), E(e.id);
|
|
@@ -472,14 +457,11 @@ function v({ node: e, offset: t, isEditing: n, isPendingEdit: i, isSelected: a,
|
|
|
472
457
|
let L = e.depth === 1 ? u.level1.fontSize : u.node.fontSize, R = e.depth === 1 ? u.level1.fontWeight : u.node.fontWeight, z = e.width - u.node.paddingH * 2, B = L / 2 + 4, V = e.side === "left" ? -e.width / 2 - 18 : e.width / 2 + 18;
|
|
473
458
|
return /* @__PURE__ */ p("g", {
|
|
474
459
|
transform: `translate(${O}, ${k})`,
|
|
475
|
-
className: `mindmap-node-g mindmap-node-child ${c} ${M}`,
|
|
460
|
+
className: `mindmap-node-g mindmap-node-child ${c} ${M}${s ? " mindmap-node-ghost" : ""}`,
|
|
461
|
+
"data-branch-index": e.branchIndex,
|
|
476
462
|
onMouseDown: (t) => v(t, e.id),
|
|
477
463
|
onClick: (t) => y(t, e.id),
|
|
478
464
|
onDoubleClick: (t) => b(t, e.id, F),
|
|
479
|
-
style: {
|
|
480
|
-
cursor: "pointer",
|
|
481
|
-
opacity: s ? .3 : 1
|
|
482
|
-
},
|
|
483
465
|
children: [
|
|
484
466
|
/* @__PURE__ */ f("rect", {
|
|
485
467
|
className: "mindmap-node-bg",
|
|
@@ -569,7 +551,6 @@ function v({ node: e, offset: t, isEditing: n, isPendingEdit: i, isSelected: a,
|
|
|
569
551
|
}),
|
|
570
552
|
e.collapsed !== void 0 && h && E && /* @__PURE__ */ f("g", {
|
|
571
553
|
className: "mindmap-fold-btn",
|
|
572
|
-
style: { cursor: "pointer" },
|
|
573
554
|
onMouseDown: (e) => e.stopPropagation(),
|
|
574
555
|
onClick: (t) => {
|
|
575
556
|
t.stopPropagation(), E(e.id);
|
|
@@ -41,5 +41,82 @@ function r({ size: t = 24, className: n }) {
|
|
|
41
41
|
})
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
|
+
function i({ size: n = 24, className: r }) {
|
|
45
|
+
return /* @__PURE__ */ t("svg", {
|
|
46
|
+
width: n,
|
|
47
|
+
height: n,
|
|
48
|
+
viewBox: "0 0 24 24",
|
|
49
|
+
fill: "none",
|
|
50
|
+
stroke: "currentColor",
|
|
51
|
+
strokeWidth: 2,
|
|
52
|
+
strokeLinecap: "round",
|
|
53
|
+
className: r,
|
|
54
|
+
children: [/* @__PURE__ */ e("line", {
|
|
55
|
+
x1: "18",
|
|
56
|
+
y1: "6",
|
|
57
|
+
x2: "6",
|
|
58
|
+
y2: "18"
|
|
59
|
+
}), /* @__PURE__ */ e("line", {
|
|
60
|
+
x1: "6",
|
|
61
|
+
y1: "6",
|
|
62
|
+
x2: "18",
|
|
63
|
+
y2: "18"
|
|
64
|
+
})]
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
function a({ size: t = 24, className: n }) {
|
|
68
|
+
return /* @__PURE__ */ e("svg", {
|
|
69
|
+
width: t,
|
|
70
|
+
height: t,
|
|
71
|
+
viewBox: "0 0 24 24",
|
|
72
|
+
fill: "currentColor",
|
|
73
|
+
className: n,
|
|
74
|
+
children: /* @__PURE__ */ e("path", { d: "M13 2L4.5 13.5H11L10 22L19.5 10.5H13L13 2Z" })
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function o({ size: t = 24, className: n }) {
|
|
78
|
+
return /* @__PURE__ */ e("svg", {
|
|
79
|
+
width: t,
|
|
80
|
+
height: t,
|
|
81
|
+
viewBox: "0 0 24 24",
|
|
82
|
+
fill: "none",
|
|
83
|
+
stroke: "currentColor",
|
|
84
|
+
strokeWidth: 2,
|
|
85
|
+
strokeLinecap: "round",
|
|
86
|
+
strokeLinejoin: "round",
|
|
87
|
+
className: n,
|
|
88
|
+
children: /* @__PURE__ */ e("path", { d: "M21.44 11.05l-9.19 9.19a6 6 0 01-8.49-8.49l9.19-9.19a4 4 0 015.66 5.66l-9.2 9.19a2 2 0 01-2.83-2.83l8.49-8.48" })
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
function s({ size: t = 24, className: n }) {
|
|
92
|
+
return /* @__PURE__ */ e("svg", {
|
|
93
|
+
width: t,
|
|
94
|
+
height: t,
|
|
95
|
+
viewBox: "0 0 24 24",
|
|
96
|
+
fill: "currentColor",
|
|
97
|
+
className: n,
|
|
98
|
+
children: /* @__PURE__ */ e("rect", {
|
|
99
|
+
x: "4",
|
|
100
|
+
y: "4",
|
|
101
|
+
width: "16",
|
|
102
|
+
height: "16",
|
|
103
|
+
rx: "2"
|
|
104
|
+
})
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
function c({ size: t = 24, className: n }) {
|
|
108
|
+
return /* @__PURE__ */ e("svg", {
|
|
109
|
+
width: t,
|
|
110
|
+
height: t,
|
|
111
|
+
viewBox: "0 0 24 24",
|
|
112
|
+
fill: "none",
|
|
113
|
+
stroke: "currentColor",
|
|
114
|
+
strokeWidth: 2,
|
|
115
|
+
strokeLinecap: "round",
|
|
116
|
+
strokeLinejoin: "round",
|
|
117
|
+
className: n,
|
|
118
|
+
children: /* @__PURE__ */ e("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })
|
|
119
|
+
});
|
|
120
|
+
}
|
|
44
121
|
//#endregion
|
|
45
|
-
export { r as IconMinus, n as IconPlus };
|
|
122
|
+
export { i as IconClose, a as IconLightning, c as IconLoaderCircle, r as IconMinus, o as IconPaperclip, n as IconPlus, s as IconStop };
|
|
@@ -2,7 +2,7 @@ import { updateNodeFieldsMulti as e } from "../utils/tree-ops.js";
|
|
|
2
2
|
import { useCallback as t, useEffect as n, useState as r } from "react";
|
|
3
3
|
//#region src/components/MindMap/hooks/useNodeEdit.ts
|
|
4
4
|
function i(e) {
|
|
5
|
-
let t = e.match(/^\[([ x
|
|
5
|
+
let t = e.match(/^\[([ x-])\]\s+(.*)/);
|
|
6
6
|
if (!t) return { text: e };
|
|
7
7
|
let n = t[1], r = t[2];
|
|
8
8
|
return n === " " ? {
|
package/dist/esm/plugins/tags.js
CHANGED
|
@@ -9,15 +9,15 @@ var t = /((?:\s+#[\w-]+)+)$/, n = [
|
|
|
9
9
|
"#6366F1"
|
|
10
10
|
], r = {
|
|
11
11
|
name: "tags",
|
|
12
|
-
transformNodeData(e
|
|
13
|
-
let
|
|
14
|
-
if (!
|
|
15
|
-
let
|
|
16
|
-
for (; (
|
|
17
|
-
return
|
|
12
|
+
transformNodeData(e) {
|
|
13
|
+
let n = e.text.match(t);
|
|
14
|
+
if (!n) return e;
|
|
15
|
+
let r = n[1], i = e.text.slice(0, e.text.length - r.length).trim(), a = [], o = /#([\w-]+)/g, s;
|
|
16
|
+
for (; (s = o.exec(r)) !== null;) a.push(s[1]);
|
|
17
|
+
return a.length > 0 ? {
|
|
18
18
|
...e,
|
|
19
|
-
text:
|
|
20
|
-
tags:
|
|
19
|
+
text: i,
|
|
20
|
+
tags: a
|
|
21
21
|
} : e;
|
|
22
22
|
},
|
|
23
23
|
serializeNodeText(e, t) {
|