@xiangfa/mindmap 0.3.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.
Files changed (64) hide show
  1. package/README.md +534 -0
  2. package/README.zh-CN.md +534 -0
  3. package/dist/MindMap.d.ts +3 -0
  4. package/dist/components/MindMapContextMenu.d.ts +20 -0
  5. package/dist/components/MindMapControls.d.ts +16 -0
  6. package/dist/components/MindMapNode.d.ts +32 -0
  7. package/dist/components/icons.d.ts +8 -0
  8. package/dist/esm/MindMap2.js +713 -0
  9. package/dist/esm/components/MindMapContextMenu.js +123 -0
  10. package/dist/esm/components/MindMapControls.js +114 -0
  11. package/dist/esm/components/MindMapNode.js +588 -0
  12. package/dist/esm/components/icons.js +45 -0
  13. package/dist/esm/hooks/useDrag.js +346 -0
  14. package/dist/esm/hooks/useNewNodeAnimation.js +20 -0
  15. package/dist/esm/hooks/useNodeEdit.js +57 -0
  16. package/dist/esm/hooks/usePanZoom.js +85 -0
  17. package/dist/esm/hooks/useTheme.js +16 -0
  18. package/dist/esm/index.js +14 -0
  19. package/dist/esm/logo.svg +9 -0
  20. package/dist/esm/plugins/cross-link.js +65 -0
  21. package/dist/esm/plugins/dotted-line.js +23 -0
  22. package/dist/esm/plugins/folding.js +20 -0
  23. package/dist/esm/plugins/front-matter.js +19 -0
  24. package/dist/esm/plugins/index.js +19 -0
  25. package/dist/esm/plugins/latex.js +132 -0
  26. package/dist/esm/plugins/multi-line.js +39 -0
  27. package/dist/esm/plugins/runner.js +128 -0
  28. package/dist/esm/plugins/tags.js +55 -0
  29. package/dist/esm/style.css +2 -0
  30. package/dist/esm/utils/export.js +50 -0
  31. package/dist/esm/utils/i18n.js +61 -0
  32. package/dist/esm/utils/inline-markdown.js +189 -0
  33. package/dist/esm/utils/layout.js +208 -0
  34. package/dist/esm/utils/markdown.js +288 -0
  35. package/dist/esm/utils/theme.js +119 -0
  36. package/dist/esm/utils/tree-ops.js +136 -0
  37. package/dist/hooks/useDrag.d.ts +40 -0
  38. package/dist/hooks/useNewNodeAnimation.d.ts +2 -0
  39. package/dist/hooks/useNodeEdit.d.ts +17 -0
  40. package/dist/hooks/usePanZoom.d.ts +26 -0
  41. package/dist/hooks/useTheme.d.ts +3 -0
  42. package/dist/index.d.ts +16 -0
  43. package/dist/logo.svg +9 -0
  44. package/dist/mindmap.umd.cjs +24 -0
  45. package/dist/plugins/cross-link.d.ts +2 -0
  46. package/dist/plugins/dotted-line.d.ts +2 -0
  47. package/dist/plugins/folding.d.ts +2 -0
  48. package/dist/plugins/front-matter.d.ts +2 -0
  49. package/dist/plugins/index.d.ts +11 -0
  50. package/dist/plugins/latex.d.ts +20 -0
  51. package/dist/plugins/multi-line.d.ts +2 -0
  52. package/dist/plugins/runner.d.ts +30 -0
  53. package/dist/plugins/tags.d.ts +2 -0
  54. package/dist/plugins/types.d.ts +78 -0
  55. package/dist/style.css +2 -0
  56. package/dist/types.d.ts +105 -0
  57. package/dist/utils/export.d.ts +18 -0
  58. package/dist/utils/i18n.d.ts +22 -0
  59. package/dist/utils/inline-markdown.d.ts +66 -0
  60. package/dist/utils/layout.d.ts +14 -0
  61. package/dist/utils/markdown.d.ts +20 -0
  62. package/dist/utils/theme.d.ts +62 -0
  63. package/dist/utils/tree-ops.d.ts +36 -0
  64. package/package.json +65 -0
package/README.md ADDED
@@ -0,0 +1,534 @@
1
+ <div align="center">
2
+
3
+ # Open MindMap
4
+
5
+ A beautiful, interactive mind map component for React.
6
+
7
+ **Natively supports AI stream output** with Markdown list syntax and **iOS-style UI**.
8
+
9
+ Zero dependencies. SVG-based. Keyboard-first. Dark mode ready.
10
+
11
+ [![npm version](https://img.shields.io/npm/v/@xiangfa/mindmap.svg?style=flat-square)](https://www.npmjs.com/package/@xiangfa/mindmap)
12
+ [![npm downloads](https://img.shields.io/npm/dm/@xiangfa/mindmap.svg?style=flat-square)](https://www.npmjs.com/package/@xiangfa/mindmap)
13
+ [![bundle size](https://img.shields.io/bundlephobia/minzip/@xiangfa/mindmap?style=flat-square)](https://bundlephobia.com/package/@xiangfa/mindmap)
14
+ [![license](https://img.shields.io/github/license/u14app/mindmap?style=flat-square)](https://github.com/u14app/mindmap/blob/main/LICENSE)
15
+
16
+ English | [中文](README.zh-CN.md)
17
+
18
+ </div>
19
+
20
+ ---
21
+
22
+ ## Features
23
+
24
+ - **AI stream ready** — natively supports AI streaming output; feed a markdown list in, get a real-time mind map out
25
+ - **Pure SVG rendering** — no canvas, no external layout engines, razor-sharp at any zoom level
26
+ - **iOS-style UI** — frosted glass controls, rounded corners, smooth animations, clean and polished design
27
+ - **Plugin system** — 7 built-in plugins for extended syntax (dotted lines, folding, multi-line, tags, cross-links, LaTeX, frontmatter); fully extensible
28
+ - **Inline formatting** — **bold**, _italic_, `code`, ~~strikethrough~~, ==highlight==, and [links](url) inside nodes
29
+ - **Task status** — `[x]` done, `[ ]` todo, `[-]` in-progress checkboxes
30
+ - **Remarks** — multi-line remarks attached to nodes via `>` syntax
31
+ - **Text editing mode** — toggle between visual mind map and plain-text markdown editing
32
+ - **Full-screen mode** — expand the component to fill the viewport
33
+ - **LaTeX math** — render `$...$` inline and `$$...$$` display formulas (requires KaTeX)
34
+ - **Cross-links** — draw edges between arbitrary nodes via `{#anchor}` / `-> {#target}`
35
+ - **Readonly mode** — display-only with pan/zoom/select but no editing; ideal for presentations and embeds
36
+ - **Multiple root nodes** — build separate trees on the same canvas
37
+ - **Drag & drop** — reorder siblings by dragging; drag root's children across the center line to rebalance sides
38
+ - **Keyboard shortcuts** — Enter to create, Delete to remove, Cmd+C/V to copy/paste, Shift+ shortcuts for zoom & layout
39
+ - **Markdown I/O** — feed a markdown list in, get a mind map out (great for AI streaming)
40
+ - **i18n** — auto-detects browser language; built-in Chinese and English, fully customizable via props
41
+ - **Dark mode** — auto-detects `prefers-color-scheme`, or set `light` / `dark` explicitly
42
+ - **Export** — SVG, high-DPI PNG, and Markdown export out of the box
43
+ - **Import** — paste JSON or markdown data via the context menu import dialog
44
+ - **Context menu** — right-click to add root nodes, import data, export, or change layout
45
+ - **Layout modes** — left, right, or balanced (both) layout directions
46
+ - **Mobile optimized** — full touch support with single-finger pan/drag and two-finger pinch-to-zoom centered on content
47
+ - **Toolbar control** — show/hide zoom controls via the `toolbar` prop
48
+ - **Tiny footprint** — zero runtime dependencies beyond React
49
+
50
+ ## Installation
51
+
52
+ ```bash
53
+ # npm
54
+ npm install @xiangfa/mindmap
55
+
56
+ # pnpm
57
+ pnpm add @xiangfa/mindmap
58
+
59
+ # yarn
60
+ yarn add @xiangfa/mindmap
61
+ ```
62
+
63
+ For LaTeX math rendering, also install KaTeX (optional):
64
+
65
+ ```bash
66
+ npm install katex
67
+ ```
68
+
69
+ ## Quick Start
70
+
71
+ ```tsx
72
+ import { MindMap } from "@xiangfa/mindmap";
73
+ import "@xiangfa/mindmap/style.css";
74
+
75
+ const data = `
76
+ My Mind Map
77
+ - First Topic
78
+ - Subtopic A
79
+ - Subtopic B
80
+ - Second Topic
81
+ `;
82
+
83
+ function App() {
84
+ return <MindMap markdown={data} />;
85
+ }
86
+ ```
87
+
88
+ > **Note:** The component fills its parent container. Make sure the parent has explicit dimensions.
89
+
90
+ ## Usage
91
+
92
+ ### Multiple Root Nodes
93
+
94
+ Pass an array to render independent trees on the same canvas:
95
+
96
+ ```tsx
97
+ <MindMap data={[tree1, tree2, tree3]} />
98
+ ```
99
+
100
+ ### Markdown Input
101
+
102
+ Feed a markdown list directly — perfect for streaming AI responses:
103
+
104
+ ```tsx
105
+ const markdown = `
106
+ Machine Learning
107
+ - Supervised Learning
108
+ - Classification
109
+ - Regression
110
+ - Unsupervised Learning
111
+
112
+ Application Areas
113
+ - NLP
114
+ - Computer Vision
115
+ `;
116
+
117
+ <MindMap markdown={markdown} />;
118
+ ```
119
+
120
+ Separate root trees with a blank line in the markdown.
121
+
122
+ ### Readonly Mode
123
+
124
+ Display a mind map without allowing edits — perfect for presentations, documentation, or embedding:
125
+
126
+ ```tsx
127
+ <MindMap data={data} readonly />
128
+ ```
129
+
130
+ In readonly mode, users can still pan, zoom, and select nodes, but cannot create, edit, or delete nodes. The context menu hides editing actions (new root node, import) while keeping view-only actions (export, layout).
131
+
132
+ ### Dark Mode
133
+
134
+ ```tsx
135
+ <MindMap data={data} theme="auto" /> {/* follow system (default) */}
136
+ <MindMap data={data} theme="dark" /> {/* always dark */}
137
+ <MindMap data={data} theme="light" /> {/* always light */}
138
+ ```
139
+
140
+ ### Layout Direction
141
+
142
+ ```tsx
143
+ <MindMap data={data} defaultDirection="both" /> {/* balanced (default) */}
144
+ <MindMap data={data} defaultDirection="right" /> {/* all children right */}
145
+ <MindMap data={data} defaultDirection="left" /> {/* all children left */}
146
+ ```
147
+
148
+ ### i18n / Localization
149
+
150
+ The UI language is auto-detected from the browser's language setting. Built-in support for Chinese (`zh-CN`) and English (`en-US`), with English as the default fallback. You can also override the locale or any text string:
151
+
152
+ ```tsx
153
+ {
154
+ /* Auto-detect (default) - uses browser language */
155
+ }
156
+ <MindMap data={data} />;
157
+
158
+ {
159
+ /* Force a specific locale */
160
+ }
161
+ <MindMap data={data} locale="en-US" />;
162
+
163
+ {
164
+ /* Override specific strings */
165
+ }
166
+ <MindMap data={data} locale="en-US" messages={{ newNode: "New Topic" }} />;
167
+
168
+ {
169
+ /* Fully custom locale */
170
+ }
171
+ <MindMap
172
+ data={data}
173
+ messages={{
174
+ newNode: "Nuevo nodo",
175
+ zoomIn: "Acercar",
176
+ zoomOut: "Alejar",
177
+ // ... override any key from MindMapMessages
178
+ }}
179
+ />;
180
+ ```
181
+
182
+ ### Plugins
183
+
184
+ The plugin system extends the mind map with additional syntax and rendering capabilities. All 7 built-in plugins are enabled by default. You can also select specific plugins:
185
+
186
+ ```tsx
187
+ import {
188
+ MindMap,
189
+ allPlugins, // all 7 plugins
190
+ frontMatterPlugin, // YAML frontmatter
191
+ dottedLinePlugin, // dotted line edges
192
+ foldingPlugin, // collapsible nodes
193
+ multiLinePlugin, // multi-line content
194
+ tagsPlugin, // hashtag support
195
+ crossLinkPlugin, // cross-references
196
+ latexPlugin, // LaTeX math (requires KaTeX)
197
+ } from "@xiangfa/mindmap";
198
+
199
+ {
200
+ /* Use all plugins (default behavior) */
201
+ }
202
+ <MindMap data={data} plugins={allPlugins} />;
203
+
204
+ {
205
+ /* Pick only the plugins you need */
206
+ }
207
+ <MindMap data={data} plugins={[foldingPlugin, tagsPlugin]} />;
208
+
209
+ {
210
+ /* Disable all plugins */
211
+ }
212
+ <MindMap data={data} plugins={[]} />;
213
+ ```
214
+
215
+ ### Ref API
216
+
217
+ Access imperative methods via a ref:
218
+
219
+ ```tsx
220
+ import { useRef } from "react";
221
+ import { MindMap, type MindMapRef } from "@xiangfa/mindmap";
222
+
223
+ function App() {
224
+ const ref = useRef<MindMapRef>(null);
225
+
226
+ const handleExportPNG = async () => {
227
+ const blob = await ref.current!.exportToPNG();
228
+ // ... download blob
229
+ };
230
+
231
+ const handleExportSVG = () => {
232
+ const svgString = ref.current!.exportToSVG();
233
+ // ... download svg
234
+ };
235
+
236
+ return <MindMap ref={ref} data={data} />;
237
+ }
238
+ ```
239
+
240
+ ### Listening for Changes
241
+
242
+ ```tsx
243
+ <MindMap
244
+ data={data}
245
+ onDataChange={(newData) => {
246
+ console.log("Mind map updated:", newData);
247
+ }}
248
+ />
249
+ ```
250
+
251
+ ### Toolbar Visibility
252
+
253
+ Control the toolbar via the `toolbar` prop:
254
+
255
+ ```tsx
256
+ {
257
+ /* Hide all toolbar buttons */
258
+ }
259
+ <MindMap data={data} toolbar={false} />;
260
+
261
+ {
262
+ /* Hide zoom controls (text mode and fullscreen buttons remain) */
263
+ }
264
+ <MindMap data={data} toolbar={{ zoom: false }} />;
265
+ ```
266
+
267
+ The toolbar includes zoom controls (bottom-left) and text mode / fullscreen toggle buttons (bottom-right). The `toolbar` prop controls zoom visibility; the text mode and fullscreen buttons are always available.
268
+
269
+ ### Mobile / Touch Support
270
+
271
+ The mind map has full touch support out of the box:
272
+
273
+ - **Single finger on canvas** — pan the view
274
+ - **Single finger on node** — drag to reorder siblings
275
+ - **Two-finger pinch** — zoom in/out (always centers on mind map content)
276
+
277
+ No configuration needed — touch support is always active alongside mouse events.
278
+
279
+ ## Extended Syntax
280
+
281
+ The mind map supports rich markdown-like syntax. Features marked with _(plugin)_ require the corresponding plugin to be enabled (all are enabled by default).
282
+
283
+ ### Inline Formatting
284
+
285
+ Format text inside any node:
286
+
287
+ ```
288
+ **bold text**
289
+ *italic text*
290
+ `inline code`
291
+ ~~strikethrough~~
292
+ ==highlight==
293
+ [link text](https://example.com)
294
+ ```
295
+
296
+ ### Task Status
297
+
298
+ Add checkboxes to track task state:
299
+
300
+ ```
301
+ - [x] Completed task
302
+ - [ ] Pending task
303
+ - [-] In-progress task
304
+ ```
305
+
306
+ ### Remarks
307
+
308
+ Attach multi-line remarks to a node using `>`:
309
+
310
+ ```
311
+ - Node with a remark
312
+ > This is a remark line
313
+ > It can span multiple lines
314
+ ```
315
+
316
+ ### Frontmatter _(plugin)_
317
+
318
+ Set default options at the top of your markdown:
319
+
320
+ ```
321
+ ---
322
+ direction: left
323
+ theme: dark
324
+ ---
325
+ - Root Node
326
+ - Child
327
+ ```
328
+
329
+ Supported fields: `direction` (`left` | `right` | `both`), `theme` (`light` | `dark` | `auto`).
330
+
331
+ ### Dotted Line _(plugin)_
332
+
333
+ Use `-.` instead of `-` to render a node with a dotted edge:
334
+
335
+ ```
336
+ - Solid edge node
337
+ -. Dotted edge child
338
+ ```
339
+
340
+ ### Folding / Collapsible Nodes _(plugin)_
341
+
342
+ Use `+` instead of `-` to make a node initially collapsed:
343
+
344
+ ```
345
+ - Visible node
346
+ + This node starts collapsed
347
+ - Hidden child
348
+ ```
349
+
350
+ ### Multi-line Content _(plugin)_
351
+
352
+ Use `|` to add continuation lines to a node:
353
+
354
+ ```
355
+ - First line of the node
356
+ | Second line
357
+ | Third line
358
+ ```
359
+
360
+ ### Tags _(plugin)_
361
+
362
+ Add hashtags to nodes for visual labeling:
363
+
364
+ ```
365
+ - React #framework #frontend
366
+ - PostgreSQL #database
367
+ ```
368
+
369
+ ### Cross-links _(plugin)_
370
+
371
+ Draw edges between arbitrary nodes:
372
+
373
+ ```
374
+ - Node A {#a}
375
+ - Child
376
+ - Node B {#b}
377
+ -> {#a} "references"
378
+ ```
379
+
380
+ - `{#id}` — define an anchor on a node
381
+ - `-> {#id}` — solid cross-link to the anchor
382
+ - `-> {#id} "label"` — cross-link with a label
383
+ - `-.> {#id}` — dotted cross-link
384
+
385
+ ### LaTeX Math _(plugin)_
386
+
387
+ Render mathematical formulas (requires [KaTeX](https://katex.org/)):
388
+
389
+ ```
390
+ - Inline math: $E = mc^2$
391
+ - Display math: $$\sum_{i=1}^{n} x_i$$
392
+ ```
393
+
394
+ ## API Reference
395
+
396
+ ### Props
397
+
398
+ | Prop | Type | Default | Description |
399
+ | ------------------ | ------------------------------- | ------------ | ------------------------------------------------------------------------- |
400
+ | `data` | `MindMapData \| MindMapData[]` | _required_ | Tree data (single root or array of roots) |
401
+ | `markdown` | `string` | - | Markdown list source (overrides `data` when set) |
402
+ | `defaultDirection` | `'left' \| 'right' \| 'both'` | `'both'` | Initial layout direction |
403
+ | `theme` | `'light' \| 'dark' \| 'auto'` | `'auto'` | Color theme |
404
+ | `locale` | `string` | _auto_ | UI language (auto-detected from browser, or `'zh-CN'`, `'en-US'`, custom) |
405
+ | `messages` | `Partial<MindMapMessages>` | - | Override any UI text string |
406
+ | `readonly` | `boolean` | `false` | Display-only mode (no editing, no creating) |
407
+ | `toolbar` | `boolean \| ToolbarConfig` | `true` | Show/hide zoom controls |
408
+ | `plugins` | `MindMapPlugin[]` | `allPlugins` | Plugins to enable for extended syntax |
409
+ | `onDataChange` | `(data: MindMapData[]) => void` | - | Called when the tree is modified by user interaction |
410
+
411
+ ### ToolbarConfig
412
+
413
+ ```ts
414
+ interface ToolbarConfig {
415
+ zoom?: boolean; // show zoom controls (default: true)
416
+ }
417
+ ```
418
+
419
+ ### Ref Methods
420
+
421
+ | Method | Returns | Description |
422
+ | ------------------- | --------------- | -------------------------------------- |
423
+ | `exportToSVG()` | `string` | Returns the mind map as an SVG string |
424
+ | `exportToPNG()` | `Promise<Blob>` | Renders a high-DPI PNG blob |
425
+ | `exportToOutline()` | `string` | Serializes the tree as a markdown list |
426
+ | `getData()` | `MindMapData[]` | Returns the current tree data |
427
+ | `setData(data)` | `void` | Replaces the tree data |
428
+ | `setMarkdown(md)` | `void` | Parses markdown and replaces the tree |
429
+ | `fitView()` | `void` | Resets zoom and pan to fit all nodes |
430
+ | `setDirection(dir)` | `void` | Changes the layout direction |
431
+
432
+ ### Data Structure
433
+
434
+ ```ts
435
+ interface MindMapData {
436
+ id: string;
437
+ text: string;
438
+ children?: MindMapData[];
439
+ remark?: string; // multi-line remark
440
+ taskStatus?: "todo" | "doing" | "done";
441
+ // Plugin extension fields (populated by corresponding plugins)
442
+ dottedLine?: boolean; // dotted-line plugin
443
+ multiLineContent?: string[]; // multi-line plugin
444
+ tags?: string[]; // tags plugin
445
+ anchorId?: string; // cross-link plugin
446
+ crossLinks?: CrossLink[]; // cross-link plugin
447
+ collapsed?: boolean; // folding plugin
448
+ }
449
+
450
+ interface CrossLink {
451
+ targetAnchorId: string;
452
+ label?: string;
453
+ dotted?: boolean;
454
+ }
455
+ ```
456
+
457
+ ## Keyboard Shortcuts
458
+
459
+ | Shortcut | Action |
460
+ | ---------------------- | ------------------------------------------- |
461
+ | `Enter` | Create a child node under the selected node |
462
+ | `Delete` / `Backspace` | Delete the selected node |
463
+ | `Double-click` | Edit node text |
464
+ | `Cmd/Ctrl + C` | Copy subtree |
465
+ | `Cmd/Ctrl + X` | Cut subtree |
466
+ | `Cmd/Ctrl + V` | Paste subtree as child |
467
+ | `Escape` | Close context menu / dialog |
468
+ | `Shift + +` | Zoom in |
469
+ | `Shift + -` | Zoom out |
470
+ | `Shift + 0` | Reset view (fit all nodes) |
471
+ | `Shift + L` | Left layout |
472
+ | `Shift + R` | Right layout |
473
+ | `Shift + M` | Both layout (balanced) |
474
+ | Scroll wheel | Zoom in / out |
475
+ | Click + drag on canvas | Pan |
476
+ | Click + drag on node | Reorder among siblings |
477
+ | Right-click | Open context menu |
478
+
479
+ ## Utility Functions
480
+
481
+ These are also exported for advanced use cases:
482
+
483
+ ```ts
484
+ import {
485
+ // Markdown parsing
486
+ parseMarkdownList, // md string → single MindMapData
487
+ toMarkdownList, // single MindMapData → md string
488
+ parseMarkdownMultiRoot, // md string → MindMapData[]
489
+ toMarkdownMultiRoot, // MindMapData[] → md string
490
+ parseMarkdownWithFrontMatter, // md string → MindMapData[] (with plugin support)
491
+
492
+ // Inline markdown
493
+ parseInlineMarkdown, // text → inline tokens
494
+ stripInlineMarkdown, // remove markdown formatting from text
495
+
496
+ // Export
497
+ buildExportSVG, // programmatic SVG generation
498
+ exportToPNG, // SVG string → PNG Blob
499
+
500
+ // i18n
501
+ resolveMessages, // build a full MindMapMessages object
502
+ detectLocale, // detect browser locale
503
+
504
+ // Plugins
505
+ allPlugins, // all 7 built-in plugins
506
+ frontMatterPlugin,
507
+ dottedLinePlugin,
508
+ foldingPlugin,
509
+ multiLinePlugin,
510
+ tagsPlugin,
511
+ crossLinkPlugin,
512
+ latexPlugin,
513
+ } from "@xiangfa/mindmap";
514
+ ```
515
+
516
+ ## Development
517
+
518
+ ```bash
519
+ git clone https://github.com/u14app/mindmap.git
520
+ cd mindmap
521
+ pnpm install
522
+ pnpm dev # start dev server
523
+ pnpm build # type-check and build
524
+ pnpm build:lib # build as library
525
+ pnpm lint # run linter
526
+ ```
527
+
528
+ ## Contributing
529
+
530
+ Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) before submitting a pull request.
531
+
532
+ ## License
533
+
534
+ [MIT](LICENSE)