@xiangfa/mindmap 0.3.0 → 0.4.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 +74 -6
- package/README.zh-CN.md +74 -6
- package/dist/components/MindMapAIInput.d.ts +13 -0
- package/dist/components/icons.d.ts +4 -0
- package/dist/esm/MindMap2.js +289 -275
- package/dist/esm/components/MindMapAIInput.js +209 -0
- 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/i18n.js +6 -0
- package/dist/esm/utils/markdown.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/mindmap.umd.cjs +76 -14
- package/dist/plugins/tags.d.ts +1 -1
- package/dist/style.css +1 -1
- package/dist/types.d.ts +9 -0
- package/dist/utils/i18n.d.ts +3 -0
- package/package.json +2 -1
- package/dist/esm/logo.svg +0 -9
- package/dist/logo.svg +0 -9
|
@@ -0,0 +1,209 @@
|
|
|
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- Task Status Logic:\n - `- [x] ` : Assigned to foundational, prerequisite, or essential concepts.\n - `- [-] ` : Assigned to intermediate, active, or transitional concepts.\n - `- [ ] ` : Assigned to advanced, future-state, or specialized concepts.\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- [x] **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
|
+
style: {
|
|
133
|
+
background: _.controls.bgColor,
|
|
134
|
+
color: _.controls.textColor,
|
|
135
|
+
borderColor: _.contextMenu.borderColor
|
|
136
|
+
},
|
|
137
|
+
children: [
|
|
138
|
+
D.length > 0 && /* @__PURE__ */ l("div", {
|
|
139
|
+
className: "mindmap-ai-file-previews",
|
|
140
|
+
children: D.map((t, n) => /* @__PURE__ */ u("span", {
|
|
141
|
+
className: "mindmap-ai-file-chip",
|
|
142
|
+
style: { background: _.controls.hoverBg },
|
|
143
|
+
children: [/* @__PURE__ */ l("span", {
|
|
144
|
+
className: "mindmap-ai-file-name",
|
|
145
|
+
children: t.name
|
|
146
|
+
}), /* @__PURE__ */ l("button", {
|
|
147
|
+
className: "mindmap-ai-file-remove",
|
|
148
|
+
onClick: () => z(n),
|
|
149
|
+
style: { color: _.controls.textColor },
|
|
150
|
+
children: /* @__PURE__ */ l(e, { size: 12 })
|
|
151
|
+
})]
|
|
152
|
+
}, n))
|
|
153
|
+
}),
|
|
154
|
+
/* @__PURE__ */ u("div", {
|
|
155
|
+
className: "mindmap-ai-input-row",
|
|
156
|
+
children: [
|
|
157
|
+
P && /* @__PURE__ */ u(c, { children: [/* @__PURE__ */ l("button", {
|
|
158
|
+
className: "mindmap-ai-attach-btn",
|
|
159
|
+
onClick: () => M.current?.click(),
|
|
160
|
+
disabled: T,
|
|
161
|
+
title: v.aiPlaceholder,
|
|
162
|
+
style: { color: _.controls.textColor },
|
|
163
|
+
children: /* @__PURE__ */ l(r, { size: 18 })
|
|
164
|
+
}), /* @__PURE__ */ l("input", {
|
|
165
|
+
ref: M,
|
|
166
|
+
type: "file",
|
|
167
|
+
accept: f(g.attachments),
|
|
168
|
+
multiple: !0,
|
|
169
|
+
style: { display: "none" },
|
|
170
|
+
onChange: R
|
|
171
|
+
})] }),
|
|
172
|
+
/* @__PURE__ */ l("input", {
|
|
173
|
+
className: "mindmap-ai-input-field",
|
|
174
|
+
type: "text",
|
|
175
|
+
value: T ? "" : C,
|
|
176
|
+
onChange: (e) => w(e.target.value),
|
|
177
|
+
onKeyDown: L,
|
|
178
|
+
placeholder: T ? v.aiGenerating : v.aiPlaceholder,
|
|
179
|
+
disabled: T,
|
|
180
|
+
style: { color: _.controls.textColor }
|
|
181
|
+
}),
|
|
182
|
+
/* @__PURE__ */ l("button", {
|
|
183
|
+
className: `mindmap-ai-send-btn${T ? " mindmap-ai-send-btn--loading" : ""}`,
|
|
184
|
+
onClick: T ? I : F,
|
|
185
|
+
disabled: !T && !C.trim() && D.length === 0,
|
|
186
|
+
style: {
|
|
187
|
+
background: T ? "transparent" : !C.trim() && D.length === 0 ? _.controls.hoverBg : _.root.bgColor,
|
|
188
|
+
color: T || !C.trim() && D.length === 0 ? _.controls.textColor : _.root.textColor
|
|
189
|
+
},
|
|
190
|
+
children: T ? /* @__PURE__ */ u(c, { children: [/* @__PURE__ */ l("span", {
|
|
191
|
+
className: "mindmap-ai-spinner",
|
|
192
|
+
children: /* @__PURE__ */ l(n, { size: 20 })
|
|
193
|
+
}), /* @__PURE__ */ l("span", {
|
|
194
|
+
className: "mindmap-ai-stop-icon",
|
|
195
|
+
children: /* @__PURE__ */ l(i, { size: 16 })
|
|
196
|
+
})] }) : /* @__PURE__ */ l(t, { size: 16 })
|
|
197
|
+
})
|
|
198
|
+
]
|
|
199
|
+
}),
|
|
200
|
+
k && /* @__PURE__ */ l("div", {
|
|
201
|
+
className: "mindmap-ai-error",
|
|
202
|
+
style: { color: "#ef4444" },
|
|
203
|
+
children: k
|
|
204
|
+
})
|
|
205
|
+
]
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
//#endregion
|
|
209
|
+
export { g as MindMapAIInput };
|
|
@@ -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) {
|
package/dist/esm/style.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
.mindmap-container{width:100%;height:100%;position:relative;overflow:hidden}.mindmap-svg{cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none;width:100%;height:100%;display:block}.mindmap-svg:focus{outline:none}.mindmap-svg.dragging-canvas,.mindmap-svg.dragging-node{cursor:grabbing}.mindmap-node-animated{transition:transform .3s ease-out}.mindmap-edge-animated{transition:d .3s ease-out}@keyframes mindmap-node-appear{0%{opacity:0;transform:scale(.85)}to{opacity:1;transform:scale(1)}}.mindmap-node-new{animation:.3s ease-out mindmap-node-appear}@keyframes mindmap-expand-appear{0%{opacity:0;transform:scale(.5)}to{opacity:1;transform:scale(1)}}.mindmap-node-expanding{animation:.3s ease-out both mindmap-expand-appear}@keyframes mindmap-edge-draw{0%{stroke-dashoffset:300px}to{stroke-dashoffset:0}}.mindmap-edge-expanding{stroke-dasharray:300;animation:.3s ease-out both mindmap-edge-draw}.mindmap-edit-input{text-align:center;box-sizing:border-box;background:0 0;border:none;outline:none;width:100%;height:100%;margin:0;padding:0}.mindmap-edit-root{color:#fff;background:0 0}.mindmap-edit-child{color:inherit;background:0 0;border-radius:4px}.mindmap-zoom-controls{-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border-radius:8px;align-items:center;gap:2px;padding:4px;display:flex;position:absolute;bottom:16px;left:16px;box-shadow:0 2px 8px #0000001a}.mindmap-ctrl-btn{cursor:pointer;width:32px;height:32px;color:inherit;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;transition:background .15s,color .15s;display:flex}.mindmap-ctrl-btn:hover{background:#80808033}.mindmap-ctrl-pct{cursor:pointer;min-width:48px;height:32px;color:inherit;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;font-family:system-ui,sans-serif;font-size:13px;font-weight:500;transition:background .15s;display:flex}.mindmap-ctrl-pct:hover{background:#80808033}.mindmap-extra-controls{-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);z-index:20;border-radius:8px;align-items:center;gap:2px;padding:4px;display:flex;position:absolute;bottom:16px;right:16px;box-shadow:0 2px 8px #0000001a}.mindmap-text-editor{resize:none;box-sizing:border-box;z-index:10;border:none;outline:none;width:100%;height:100%;padding:24px;font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,monospace;font-size:15px;line-height:1.7;position:absolute;inset:0}.mindmap-add-btn{opacity:0;cursor:pointer;transition:opacity .2s}.mindmap-node-g:hover .mindmap-add-btn{opacity:1}.mindmap-context-menu{-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);z-index:1000;border:1px solid;border-radius:8px;min-width:150px;padding:4px 0;font-family:system-ui,-apple-system,sans-serif;position:absolute}.mindmap-ctx-item{cursor:pointer;white-space:nowrap;justify-content:space-between;align-items:center;padding:8px 16px;font-size:14px;display:flex;position:relative}.mindmap-ctx-item:hover{filter:brightness(.92);background:#8080801a}.mindmap-ctx-arrow{opacity:.5;margin-left:12px;font-size:8px}.mindmap-ctx-divider{opacity:.3;border-top:1px solid;height:0;margin:4px 8px}.mindmap-ctx-submenu{-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);border:1px solid;border-radius:8px;min-width:140px;padding:4px 0;position:absolute;top:-4px;left:100%}.mindmap-ctx-has-sub{position:relative}.mindmap-dialog-backdrop{-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);z-index:2000;background:#0003;justify-content:center;align-items:center;font-family:system-ui,-apple-system,sans-serif;animation:.15s ease-out mindmap-fade-in;display:flex;position:absolute;inset:0}@keyframes mindmap-fade-in{0%{opacity:0}to{opacity:1}}.mindmap-dialog-modal{border:1px solid;border-radius:12px;width:calc(100% - 32px);max-width:480px;max-height:80%;padding:24px;animation:.2s ease-out mindmap-dialog-enter;position:relative;overflow-y:auto;box-shadow:0 8px 32px #0003}@keyframes mindmap-dialog-enter{0%{opacity:0;transform:scale(.95)translateY(8px)}to{opacity:1;transform:scale(1)translateY(0)}}.mindmap-dialog-header{justify-content:space-between;align-items:center;margin-bottom:16px;display:flex}.mindmap-dialog-title{margin:0;font-size:16px;font-weight:600}.mindmap-dialog-close{cursor:pointer;width:28px;height:28px;color:inherit;opacity:.5;background:0 0;border:none;border-radius:6px;flex-shrink:0;justify-content:center;align-items:center;transition:opacity .15s,background .15s;display:flex}.mindmap-dialog-close:hover{opacity:1;background:#80808033}@media (width<=500px){.mindmap-dialog-modal{max-height:90%;padding:16px}}@media (width<=768px){.mindmap-ctrl-btn{width:28px;height:28px}.mindmap-ctrl-btn svg{width:14px;height:14px}.mindmap-ctrl-pct{min-width:40px;height:28px;font-size:12px}.mindmap-zoom-controls,.mindmap-extra-controls{gap:1px;padding:3px;bottom:12px}.mindmap-zoom-controls{left:12px}.mindmap-extra-controls{right:12px}}.mindmap-node-content{white-space:nowrap;box-sizing:border-box;justify-content:center;align-items:center;gap:4px;line-height:1;display:flex;overflow:hidden}.mindmap-node-root-content{line-height:1}.mindmap-node-content strong{font-weight:700}.mindmap-node-content em{font-style:italic}.mindmap-node-content del{opacity:.6;text-decoration:line-through}.mindmap-node-content .mindmap-inline-code{background:#8080801f;border-radius:3px;padding:1px 4px;font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:.88em}.mindmap-node-content .mindmap-highlight{color:#fac800;background:#fcd34d33;border-radius:2px;padding:1px 2px}.mindmap-node-content .mindmap-link{color:#2563eb;cursor:pointer;text-decoration:none}.mindmap-node-content .mindmap-link:hover{text-decoration:underline}.mindmap-node-content .mindmap-inline-image{vertical-align:middle;border-radius:2px;max-width:80px;max-height:1.2em}.mindmap-node-root-content .mindmap-inline-code{background:#ffffff26}.mindmap-node-root-content .mindmap-highlight{color:#fcd34d;background:#fbbf2433}.mindmap-node-root-content .mindmap-link{color:#93c5fd}.mindmap-task-icon{vertical-align:middle;flex-shrink:0}.mindmap-remark-indicator{opacity:.5;cursor:help;flex-shrink:0;font-size:.7em;line-height:1;transition:opacity .15s}.mindmap-remark-indicator:hover{opacity:1}.mindmap-remark-tooltip{white-space:pre-wrap;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);z-index:1000;pointer-events:none;border-radius:8px;max-width:280px;padding:8px 12px;font-family:system-ui,-apple-system,sans-serif;font-size:13px;line-height:1.5;animation:.15s ease-out mindmap-fade-in;position:absolute;box-shadow:0 4px 16px #00000026}
|
|
1
|
+
.mindmap-container{width:100%;height:100%;position:relative;overflow:hidden}.mindmap-svg{cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none;width:100%;height:100%;display:block}.mindmap-svg:focus{outline:none}.mindmap-svg.dragging-canvas,.mindmap-svg.dragging-node{cursor:grabbing}.mindmap-node-animated{transition:transform .3s ease-out}.mindmap-edge-animated{transition:d .3s ease-out}@keyframes mindmap-node-appear{0%{opacity:0;transform:scale(.85)}to{opacity:1;transform:scale(1)}}.mindmap-node-new{animation:.3s ease-out mindmap-node-appear}@keyframes mindmap-expand-appear{0%{opacity:0;transform:scale(.5)}to{opacity:1;transform:scale(1)}}.mindmap-node-expanding{animation:.3s ease-out both mindmap-expand-appear}@keyframes mindmap-edge-draw{0%{stroke-dashoffset:300px}to{stroke-dashoffset:0}}.mindmap-edge-expanding{stroke-dasharray:300;animation:.3s ease-out both mindmap-edge-draw}.mindmap-edit-input{text-align:center;box-sizing:border-box;background:0 0;border:none;outline:none;width:100%;height:100%;margin:0;padding:0}.mindmap-edit-root{color:#fff;background:0 0}.mindmap-edit-child{color:inherit;background:0 0;border-radius:4px}.mindmap-zoom-controls{-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border-radius:8px;align-items:center;gap:2px;padding:4px;display:flex;position:absolute;bottom:16px;left:16px;box-shadow:0 2px 8px #0000001a}.mindmap-ctrl-btn{cursor:pointer;width:32px;height:32px;color:inherit;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;transition:background .15s,color .15s;display:flex}.mindmap-ctrl-btn:hover{background:#80808033}.mindmap-ctrl-pct{cursor:pointer;min-width:48px;height:32px;color:inherit;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;font-family:system-ui,sans-serif;font-size:13px;font-weight:500;transition:background .15s;display:flex}.mindmap-ctrl-pct:hover{background:#80808033}.mindmap-extra-controls{-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);z-index:20;border-radius:8px;align-items:center;gap:2px;padding:4px;display:flex;position:absolute;bottom:16px;right:16px;box-shadow:0 2px 8px #0000001a}.mindmap-text-editor{resize:none;box-sizing:border-box;z-index:10;border:none;outline:none;width:100%;height:100%;padding:24px;font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,monospace;font-size:15px;line-height:1.7;position:absolute;inset:0}.mindmap-add-btn{opacity:0;cursor:pointer;transition:opacity .2s}.mindmap-node-g:hover .mindmap-add-btn{opacity:1}.mindmap-context-menu{-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);z-index:1000;border:1px solid;border-radius:8px;min-width:150px;padding:4px 0;font-family:system-ui,-apple-system,sans-serif;position:absolute}.mindmap-ctx-item{cursor:pointer;white-space:nowrap;justify-content:space-between;align-items:center;padding:8px 16px;font-size:14px;display:flex;position:relative}.mindmap-ctx-item:hover{filter:brightness(.92);background:#8080801a}.mindmap-ctx-arrow{opacity:.5;margin-left:12px;font-size:8px}.mindmap-ctx-divider{opacity:.3;border-top:1px solid;height:0;margin:4px 8px}.mindmap-ctx-submenu{-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);border:1px solid;border-radius:8px;min-width:140px;padding:4px 0;position:absolute;top:-4px;left:100%}.mindmap-ctx-has-sub{position:relative}.mindmap-dialog-backdrop{-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);z-index:2000;background:#0003;justify-content:center;align-items:center;font-family:system-ui,-apple-system,sans-serif;animation:.15s ease-out mindmap-fade-in;display:flex;position:absolute;inset:0}@keyframes mindmap-fade-in{0%{opacity:0}to{opacity:1}}.mindmap-dialog-modal{border:1px solid;border-radius:12px;width:calc(100% - 32px);max-width:480px;max-height:80%;padding:24px;animation:.2s ease-out mindmap-dialog-enter;position:relative;overflow-y:auto;box-shadow:0 8px 32px #0003}@keyframes mindmap-dialog-enter{0%{opacity:0;transform:scale(.95)translateY(8px)}to{opacity:1;transform:scale(1)translateY(0)}}.mindmap-dialog-header{justify-content:space-between;align-items:center;margin-bottom:16px;display:flex}.mindmap-dialog-title{margin:0;font-size:16px;font-weight:600}.mindmap-dialog-close{cursor:pointer;width:28px;height:28px;color:inherit;opacity:.5;background:0 0;border:none;border-radius:6px;flex-shrink:0;justify-content:center;align-items:center;transition:opacity .15s,background .15s;display:flex}.mindmap-dialog-close:hover{opacity:1;background:#80808033}@media (width<=500px){.mindmap-dialog-modal{max-height:90%;padding:16px}}@media (width<=768px){.mindmap-ctrl-btn{width:28px;height:28px}.mindmap-ctrl-btn svg{width:14px;height:14px}.mindmap-ctrl-pct{min-width:40px;height:28px;font-size:12px}.mindmap-zoom-controls,.mindmap-extra-controls{gap:1px;padding:3px;bottom:12px}.mindmap-zoom-controls{left:12px}.mindmap-extra-controls{right:12px}}.mindmap-node-content{white-space:nowrap;box-sizing:border-box;justify-content:center;align-items:center;gap:4px;line-height:1;display:flex;overflow:hidden}.mindmap-node-root-content{line-height:1}.mindmap-node-content strong{font-weight:700}.mindmap-node-content em{font-style:italic}.mindmap-node-content del{opacity:.6;text-decoration:line-through}.mindmap-node-content .mindmap-inline-code{background:#8080801f;border-radius:3px;padding:1px 4px;font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:.88em}.mindmap-node-content .mindmap-highlight{color:#fac800;background:#fcd34d33;border-radius:2px;padding:1px 2px}.mindmap-node-content .mindmap-link{color:#2563eb;cursor:pointer;text-decoration:none}.mindmap-node-content .mindmap-link:hover{text-decoration:underline}.mindmap-node-content .mindmap-inline-image{vertical-align:middle;border-radius:2px;max-width:80px;max-height:1.2em}.mindmap-node-root-content .mindmap-inline-code{background:#ffffff26}.mindmap-node-root-content .mindmap-highlight{color:#fcd34d;background:#fbbf2433}.mindmap-node-root-content .mindmap-link{color:#93c5fd}.mindmap-task-icon{vertical-align:middle;flex-shrink:0}.mindmap-remark-indicator{opacity:.5;cursor:help;flex-shrink:0;font-size:.7em;line-height:1;transition:opacity .15s}.mindmap-remark-indicator:hover{opacity:1}.mindmap-remark-tooltip{white-space:pre-wrap;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);z-index:1000;pointer-events:none;border-radius:8px;max-width:280px;padding:8px 12px;font-family:system-ui,-apple-system,sans-serif;font-size:13px;line-height:1.5;animation:.15s ease-out mindmap-fade-in;position:absolute;box-shadow:0 4px 16px #00000026}.mindmap-ai-input{-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);z-index:30;border:1px solid;border-radius:26px;outline:none;width:calc(100% - 32px);max-width:600px;font-family:system-ui,-apple-system,sans-serif;animation:.15s ease-out mindmap-fade-in;position:absolute;bottom:56px;left:50%;transform:translate(-50%)}.mindmap-ai-input-row{align-items:center;gap:4px;padding:6px 6px 6px 16px;display:flex}.mindmap-ai-input-field{color:inherit;background:0 0;border:none;outline:none;flex:1;min-width:0;font-family:inherit;font-size:14px;line-height:1.5}.mindmap-ai-input-field:focus{box-shadow:none}.mindmap-ai-input-field::placeholder{opacity:.5}.mindmap-ai-input-field:disabled{opacity:.5;cursor:not-allowed}.mindmap-ai-send-btn{cursor:pointer;border:none;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;width:36px;height:36px;transition:background .15s,opacity .15s,transform .1s;display:flex;position:relative}.mindmap-ai-send-btn:hover:not(:disabled){opacity:.85;transform:scale(1.05)}.mindmap-ai-send-btn:disabled{cursor:not-allowed;opacity:.4}.mindmap-ai-send-btn--loading{cursor:pointer}@keyframes mindmap-ai-spin{to{transform:rotate(360deg)}}.mindmap-ai-spinner{justify-content:center;align-items:center;transition:opacity .2s;animation:.8s linear infinite mindmap-ai-spin;display:flex}.mindmap-ai-stop-icon{opacity:0;color:#ef4444;justify-content:center;align-items:center;transition:opacity .2s,transform .2s;display:flex;position:absolute;transform:scale(.5)}.mindmap-ai-send-btn--loading:hover .mindmap-ai-spinner{opacity:0}.mindmap-ai-send-btn--loading:hover .mindmap-ai-stop-icon{opacity:1;transform:scale(1)}.mindmap-ai-send-btn--loading:hover{background:#ef44441a!important}.mindmap-ai-attach-btn{cursor:pointer;opacity:.5;background:0 0;border:none;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;width:32px;height:32px;transition:opacity .15s,background .15s;display:flex}.mindmap-ai-attach-btn:hover:not(:disabled){opacity:1;background:#80808026}.mindmap-ai-attach-btn:disabled{cursor:not-allowed;opacity:.3}.mindmap-ai-file-previews{flex-wrap:wrap;gap:6px;padding:8px 12px 0;display:flex}.mindmap-ai-file-chip{border-radius:12px;align-items:center;gap:4px;max-width:160px;padding:3px 8px;font-size:12px;display:inline-flex}.mindmap-ai-file-name{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.mindmap-ai-file-remove{cursor:pointer;opacity:.5;background:0 0;border:none;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;width:16px;height:16px;padding:0;transition:opacity .15s;display:flex}.mindmap-ai-file-remove:hover{opacity:1}.mindmap-ai-error{padding:0 16px 8px;font-size:12px;animation:.15s ease-out mindmap-fade-in}@media (width<=768px){.mindmap-ai-input{border-radius:20px;max-width:calc(100% - 24px);bottom:48px}.mindmap-ai-input-row{padding:4px 4px 4px 12px}.mindmap-ai-send-btn{width:32px;height:32px}}
|
|
2
2
|
/*$vite$:1*/
|
package/dist/esm/utils/i18n.js
CHANGED
|
@@ -17,6 +17,9 @@ var e = {
|
|
|
17
17
|
exportPNG: "导出为 PNG",
|
|
18
18
|
exportMarkdown: "导出为 Markdown",
|
|
19
19
|
layout: "布局",
|
|
20
|
+
aiPlaceholder: "让 AI 生成思维导图...",
|
|
21
|
+
aiGenerating: "生成中...",
|
|
22
|
+
aiError: "生成失败",
|
|
20
23
|
close: "关闭"
|
|
21
24
|
}, t = {
|
|
22
25
|
newNode: "New Node",
|
|
@@ -36,6 +39,9 @@ var e = {
|
|
|
36
39
|
exportPNG: "Export as PNG",
|
|
37
40
|
exportMarkdown: "Export as Markdown",
|
|
38
41
|
layout: "Layout",
|
|
42
|
+
aiPlaceholder: "Ask AI to generate a mind map...",
|
|
43
|
+
aiGenerating: "Generating...",
|
|
44
|
+
aiError: "Generation failed",
|
|
39
45
|
close: "Close"
|
|
40
46
|
}, n = {
|
|
41
47
|
"zh-CN": e,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { runCollectFollowLines as e, runParseLine as t, runPostParseTree as n, runPreParseMarkdown as r, runSerializeFollowLines as i, runSerializeListMarker as a, runSerializeNodeText as o, runSerializePreamble as s, runTransformNodeData as c } from "../plugins/runner.js";
|
|
2
2
|
//#region src/components/MindMap/utils/markdown.ts
|
|
3
3
|
function l(e) {
|
|
4
|
-
let t = e.match(/^\[([ x
|
|
4
|
+
let t = e.match(/^\[([ x-])\]\s+(.*)/);
|
|
5
5
|
if (!t) return { text: e };
|
|
6
6
|
let n = t[1], r = t[2];
|
|
7
7
|
return n === " " ? {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { MindMap } from './MindMap';
|
|
2
|
-
export type { MindMapData, MindMapProps, MindMapRef, MindMapEvent, LayoutDirection, ThemeMode, ToolbarConfig, TaskStatus, CrossLink } from './types';
|
|
2
|
+
export type { MindMapData, MindMapProps, MindMapRef, MindMapEvent, LayoutDirection, ThemeMode, ToolbarConfig, TaskStatus, CrossLink, MindMapAIConfig, AIAttachmentType } from './types';
|
|
3
3
|
export type { MindMapMessages } from './utils/i18n';
|
|
4
4
|
export { resolveMessages, detectLocale } from './utils/i18n';
|
|
5
5
|
export { buildExportSVG, buildExportSVGForPNG, exportToPNG } from './utils/export';
|