flow-mindmap 0.2.0 → 0.2.2

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/dist/style.css CHANGED
@@ -1 +1,10 @@
1
- .zm-node-menu{position:fixed;z-index:40;min-width:168px;padding:4px;background:#fff;border:1px solid #e2e8f0;border-radius:8px;box-shadow:0 8px 24px #0f172a24;display:flex;flex-direction:column;gap:2px;font-size:13px;color:#1e293b;-webkit-user-select:none;user-select:none}.zm-node-menu-item{display:flex;align-items:center;gap:8px;padding:6px 10px;border:none;background:transparent;color:inherit;font:inherit;text-align:left;border-radius:4px;cursor:pointer;width:100%;transition:background .1s}.zm-node-menu-item:hover:not(:disabled){background:#f1f5f9}.zm-node-menu-item:active:not(:disabled){background:#e2e8f0}.zm-node-menu-item:disabled{color:#94a3b8;cursor:not-allowed}.zm-mindmap{position:relative;width:100%;height:100%;overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,PingFang SC,Microsoft YaHei,sans-serif;-webkit-user-select:none;user-select:none}.zm-canvas{position:absolute;top:0;right:0;bottom:0;left:0;cursor:grab}.zm-canvas:active{cursor:grabbing}.zm-world{position:absolute;left:0;top:0;transform-origin:0 0}.zm-svg-layer{position:absolute;pointer-events:none;overflow:visible}.zm-marquee{position:absolute;border:1px dashed #3b82f6;background:#3b82f614;pointer-events:none;z-index:5}.zm-svg{position:absolute;left:0;top:0;pointer-events:none;overflow:visible;shape-rendering:geometricPrecision}.zm-node{position:absolute;display:flex;align-items:center;justify-content:center;padding:0 .8em;box-sizing:border-box;border-radius:8px;border:1px solid;line-height:1.2;cursor:default;transition:box-shadow .15s;box-shadow:0 1px 2px #0000000f;white-space:nowrap;z-index:1}.zm-node:hover{box-shadow:0 4px 12px #0000001a;z-index:2}.zm-node.is-root{font-weight:600}.zm-node.is-selected{outline:2px solid #3b82f6;outline-offset:2px;z-index:3}.zm-text{display:inline-flex;align-items:center;gap:4px;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.zm-text-label{pointer-events:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;flex-shrink:1}.zm-input{border:none;outline:none;background:transparent;color:inherit;font:inherit;text-align:center;width:100%;min-width:40px}.zm-rich{pointer-events:none;margin-top:6px;width:100%;max-width:260px;max-height:160px;overflow:auto;font-size:.78em;line-height:1.35;text-align:left;background:#0000000a;border-radius:4px;padding:6px 8px;color:inherit}.zm-rich-code{margin:0;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:.92em;white-space:pre-wrap;word-break:break-word}.zm-rich-list{margin:0;padding-left:1.2em;list-style:disc}.zm-rich-list li{margin:1px 0}.zm-rich-table{width:100%;border-collapse:collapse;font-size:.92em}.zm-rich-table td{border:1px solid currentColor;opacity:.7;padding:2px 5px}.zm-rich-paragraph{white-space:pre-wrap;word-break:break-word}.zm-btn{position:absolute;width:18px;height:18px;border-radius:50%;border:none;background:#3b82f6;color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;opacity:0;transition:opacity .15s,transform .15s;z-index:4}.zm-node:hover .zm-btn,.zm-node.is-selected .zm-btn{opacity:1}.zm-btn:hover{transform:scale(1.15)}.zm-collapse{right:-8px;top:50%;width:14px;height:14px;background:#fff;border:1.5px solid;transform:translateY(-50%);box-shadow:0 1px 3px #0f172a2e}.zm-collapse.is-on-left{right:auto;left:-8px}.zm-collapse:hover{transform:translateY(-50%) scale(1.15);background:#fff}.zm-collapse-badge{position:absolute;top:50%;transform:translateY(-50%);left:calc(100% + 8px);min-width:18px;height:18px;padding:0 5px;border-radius:5px;color:#fff;font-size:11px;font-weight:600;line-height:18px;text-align:center;box-shadow:0 1px 2px #00000026;cursor:pointer;-webkit-user-select:none;user-select:none;z-index:2;transition:filter .1s}.zm-collapse-badge.is-on-left{left:auto;right:calc(100% + 8px)}.zm-collapse-badge:hover{filter:brightness(.9)}.zm-node.has-image{flex-direction:column;padding:8px;gap:6px;white-space:normal}.zm-node-img{display:block;pointer-events:none;-webkit-user-select:none;user-select:none;-webkit-user-drag:none;object-fit:contain;border-radius:4px}.zm-node-link,.zm-node-note-btn{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:none;background:transparent;color:currentColor;border-radius:3px;cursor:pointer;flex-shrink:0;text-decoration:none;opacity:.75;transition:opacity .1s,background .1s;pointer-events:auto}.zm-node-link:hover,.zm-node-note-btn:hover{opacity:1;background:#0f172a14}.zm-node-link svg,.zm-node-note-btn svg{display:block}.zm-img-resize-handle{position:absolute;right:-5px;bottom:-5px;width:10px;height:10px;background:#fff;border:1.5px solid #3b82f6;border-radius:2px;cursor:nwse-resize;z-index:4;box-shadow:0 1px 3px #0f172a33}.zm-node.is-resizing{cursor:nwse-resize!important}.zm-img-remove-btn{position:absolute;right:-5px;bottom:14px;width:14px;height:14px;background:#fff;border:1px solid #cbd5e1;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;color:#64748b;padding:0;z-index:4;box-shadow:0 1px 2px #0f172a1f}.zm-img-remove-btn:hover{background:#fee2e2;color:#b91c1c;border-color:#fca5a5}.zm-order-badge{display:inline-block;margin-left:6px;padding:0 5px;font-size:10px;font-weight:600;line-height:16px;color:#475569;background:#e2e8f0;border-radius:3px;font-variant-numeric:tabular-nums;pointer-events:none;-webkit-user-select:none;user-select:none;vertical-align:middle}.zm-toolbar{position:absolute;bottom:16px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:4px;padding:6px 10px;background:#fff;border:1px solid #e2e8f0;border-radius:999px;box-shadow:0 4px 12px #0000000f;z-index:10}.zm-tb-btn{width:32px;height:32px;display:flex;align-items:center;justify-content:center;border:none;background:transparent;border-radius:6px;cursor:pointer;color:#475569}.zm-tb-btn:hover{background:#f1f5f9;color:#1e293b}.zm-tb-btn img{filter:invert(20%) sepia(15%) saturate(500%) hue-rotate(180deg);transition:filter .1s}.zm-tb-btn:hover img{filter:invert(15%) sepia(30%) saturate(800%) hue-rotate(180deg)}.zm-tb-btn.active{background:var(--zm-tb-active, #fff7ed);color:var(--zm-tb-active-fg, #c2410c)}.zm-tb-divider{width:1px;height:18px;background:#e2e8f0;margin:0 4px}.zm-tb-tip{font-size:12px;color:#64748b;min-width:38px;text-align:center}
1
+ .zm-node-menu{position:fixed;z-index:40;min-width:168px;padding:4px;background:#fff;border:1px solid #e2e8f0;border-radius:8px;box-shadow:0 8px 24px #0f172a24;display:flex;flex-direction:column;gap:2px;font-size:13px;color:#1e293b;-webkit-user-select:none;user-select:none}.zm-node-menu-item{display:flex;align-items:center;gap:8px;padding:6px 10px;border:none;background:transparent;color:inherit;font:inherit;text-align:left;border-radius:4px;cursor:pointer;width:100%;transition:background .1s}.zm-node-menu-item:hover:not(:disabled){background:#f1f5f9}.zm-node-menu-item:active:not(:disabled){background:#e2e8f0}.zm-node-menu-item:disabled{color:#94a3b8;cursor:not-allowed}.zm-node-menu-icon{display:inline-flex;align-items:center;justify-content:center;width:13px;height:13px;font-size:10px;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-weight:600;color:#64748b;flex-shrink:0}.zm-node-menu-icon-code{font-size:10px;letter-spacing:-1px}.zm-node-menu-icon-table{font-size:12px;font-family:inherit}pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*!
2
+ Theme: GitHub
3
+ Description: Light theme as seen on github.com
4
+ Author: github.com
5
+ Maintainer: @Hirse
6
+ Updated: 2021-05-15
7
+
8
+ Outdated base version: https://github.com/primer/github-syntax-light
9
+ Current colors taken from GitHub's CSS
10
+ */.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-variable,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id{color:#005cc5}.hljs-regexp,.hljs-string,.hljs-meta .hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-comment,.hljs-code,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0}.zm-mindmap{position:relative;width:100%;height:100%;overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,PingFang SC,Microsoft YaHei,sans-serif;-webkit-user-select:none;user-select:none}.zm-canvas{position:absolute;top:0;right:0;bottom:0;left:0;cursor:grab}.zm-canvas:active{cursor:grabbing}.zm-world{position:absolute;left:0;top:0;transform-origin:0 0}.zm-svg-layer{position:absolute;pointer-events:none;overflow:visible}.zm-marquee{position:absolute;border:1px dashed #3b82f6;background:#3b82f614;pointer-events:none;z-index:5}.zm-svg{position:absolute;left:0;top:0;pointer-events:none;overflow:visible;shape-rendering:geometricPrecision}.zm-node{position:absolute;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:0 .8em;box-sizing:border-box;border-radius:8px;border:1px solid;line-height:1.2;cursor:default;transition:box-shadow .15s;box-shadow:0 1px 2px #0000000f;white-space:nowrap;z-index:1}.zm-node:hover{box-shadow:0 4px 12px #0000001a;z-index:2}.zm-node.is-root{font-weight:600}.zm-node.is-selected{outline:2px solid #3b82f6;outline-offset:2px;z-index:3}.zm-text{display:flex;align-items:center;justify-content:center;gap:4px;min-height:1.2em;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.zm-text-label{pointer-events:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;flex-shrink:1}.zm-input{border:none;outline:none;background:transparent;color:inherit;font:inherit;text-align:center;width:100%;min-width:40px}.zm-rich{margin-top:6px;width:max-content;overflow:visible;font-size:.78em;line-height:1.35;text-align:left;background:#0000000a;border-radius:4px;padding:4px 6px;color:inherit}.zm-rich-above{margin:0 0 2px}.zm-rich-no-overflow{max-height:none;overflow:visible}.zm-rich-code{margin:0;padding:6px 8px;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:.92em;white-space:pre-wrap;word-break:break-word;background:#ffffff8c;border:1px solid currentColor;border-radius:6px;box-shadow:0 1px 2px #0f172a14}.zm-rich-list{margin:0;padding-left:1.2em;list-style:disc}.zm-rich-list li{margin:1px 0}.zm-rich-table{width:100%;border-collapse:separate;border-spacing:0;font-size:.92em;background:#ffffff8c;border:1px solid currentColor;border-radius:6px;overflow:hidden;box-shadow:0 1px 2px #0f172a14}.zm-rich-table td{border-top:1px solid currentColor;border-right:1px solid currentColor;padding:3px 6px;opacity:.9}.zm-rich-table tr:last-child td{border-bottom:none}.zm-rich-table td:last-child{border-right:none}.zm-rich-table-sort{position:relative;background:#fff6;font-weight:600;text-align:left;cursor:pointer;-webkit-user-select:none;user-select:none;padding:3px 6px;border-bottom:1px solid currentColor;border-right:1px solid currentColor;pointer-events:auto}.zm-rich-table-sort:last-child{border-right:none}.zm-rich-table-sort:hover{background:#ffffffa6}.zm-rich-table-sort.is-sorted{background:#ffffffb3}.zm-rich-sort-mark{position:absolute;right:4px;top:50%;transform:translateY(-50%);font-size:9px;color:#94a3b8}.zm-rich-table-sort.is-sorted .zm-rich-sort-mark{color:#1d4ed8}.zm-rich-edit{width:100%;min-height:90px;margin:0;padding:4px 6px;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:.92em;line-height:1.4;color:inherit;background:#fff9;border:1px solid currentColor;border-radius:3px;outline:none;resize:vertical;white-space:pre;box-sizing:border-box}.zm-rich-edit:focus{border-color:#3b82f6;box-shadow:0 0 0 2px #3b82f626}.zm-rich-paragraph{white-space:pre-wrap;word-break:break-word}.zm-btn{position:absolute;width:18px;height:18px;border-radius:50%;border:none;background:#3b82f6;color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;opacity:0;transition:opacity .15s,transform .15s;z-index:4}.zm-node:hover .zm-btn,.zm-node.is-selected .zm-btn{opacity:1}.zm-btn:hover{transform:scale(1.15)}.zm-collapse{right:-8px;top:50%;width:14px;height:14px;background:#fff;border:1.5px solid;transform:translateY(-50%);box-shadow:0 1px 3px #0f172a2e}.zm-collapse.is-on-left{right:auto;left:-8px}.zm-collapse:hover{transform:translateY(-50%) scale(1.15);background:#fff}.zm-collapse-badge{position:absolute;top:50%;transform:translateY(-50%);left:calc(100% + 8px);min-width:18px;height:18px;padding:0 5px;border-radius:5px;color:#fff;font-size:11px;font-weight:600;line-height:18px;text-align:center;box-shadow:0 1px 2px #00000026;cursor:pointer;-webkit-user-select:none;user-select:none;z-index:2;transition:filter .1s}.zm-collapse-badge.is-on-left{left:auto;right:calc(100% + 8px)}.zm-collapse-badge:hover{filter:brightness(.9)}.zm-node.has-image{flex-direction:column;padding:8px;gap:6px;white-space:normal}.zm-node-img{display:block;pointer-events:none;-webkit-user-select:none;user-select:none;-webkit-user-drag:none;object-fit:contain;border-radius:4px}.zm-node-link,.zm-node-note-btn{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:none;background:transparent;color:currentColor;border-radius:3px;cursor:pointer;flex-shrink:0;text-decoration:none;opacity:.75;transition:opacity .1s,background .1s;pointer-events:auto}.zm-node-link:hover,.zm-node-note-btn:hover{opacity:1;background:#0f172a14}.zm-node-link svg,.zm-node-note-btn svg{display:block}.zm-img-resize-handle{position:absolute;right:-5px;bottom:-5px;width:10px;height:10px;background:#fff;border:1.5px solid #3b82f6;border-radius:2px;cursor:nwse-resize;z-index:4;box-shadow:0 1px 3px #0f172a33}.zm-node.is-resizing{cursor:nwse-resize!important}.zm-img-remove-btn{position:absolute;right:-5px;bottom:14px;width:14px;height:14px;background:#fff;border:1px solid #cbd5e1;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;color:#64748b;padding:0;z-index:4;box-shadow:0 1px 2px #0f172a1f}.zm-img-remove-btn:hover{background:#fee2e2;color:#b91c1c;border-color:#fca5a5}.zm-order-badge{display:inline-block;margin-left:6px;padding:0 5px;font-size:10px;font-weight:600;line-height:16px;color:#475569;background:#e2e8f0;border-radius:3px;font-variant-numeric:tabular-nums;pointer-events:none;-webkit-user-select:none;user-select:none;vertical-align:middle}.zm-toolbar{position:absolute;bottom:16px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:4px;padding:6px 10px;background:#fff;border:1px solid #e2e8f0;border-radius:999px;box-shadow:0 4px 12px #0000000f;z-index:10}.zm-tb-btn{width:32px;height:32px;display:flex;align-items:center;justify-content:center;border:none;background:transparent;border-radius:6px;cursor:pointer;color:#475569}.zm-tb-btn:hover{background:#f1f5f9;color:#1e293b}.zm-tb-btn img{filter:invert(20%) sepia(15%) saturate(500%) hue-rotate(180deg);transition:filter .1s}.zm-tb-btn:hover img{filter:invert(15%) sepia(30%) saturate(800%) hue-rotate(180deg)}.zm-tb-btn.active{background:var(--zm-tb-active, #fff7ed);color:var(--zm-tb-active-fg, #c2410c)}.zm-tb-divider{width:1px;height:18px;background:#e2e8f0;margin:0 4px}.zm-tb-tip{font-size:12px;color:#64748b;min-width:38px;text-align:center}
package/dist/types.d.ts CHANGED
@@ -222,6 +222,26 @@ export interface MindMapExpose {
222
222
  applyNodeNote: (nodeId: string, text: string) => void;
223
223
  /** Remove a node's note (no-op if absent). */
224
224
  removeNodeNote: (nodeId: string) => void;
225
+ /** Set a node's image from a URL or data: URI. Fetches the
226
+ * asset to read its natural dimensions; clamps to IMG_MAX_W
227
+ * with a preserved aspect ratio. Empty string removes the
228
+ * image. */
229
+ applyNodeImageByUrl: (nodeId: string, url: string) => void;
230
+ /** Set a node's image from a fully-resolved MindMapImage.
231
+ * Used by the file-picker flow (readImageFile) and the drag
232
+ * resize handle. Prefer `applyNodeImageByUrl` from the
233
+ * panel — it fetches the natural dimensions for you. */
234
+ applyNodeImage: (nodeId: string, image: MindMapImage) => void;
235
+ /** Remove a node's image (no-op if absent). */
236
+ removeNodeImage: (nodeId: string) => void;
237
+ /** Set a node's rich body (code block or table). Pass `null`
238
+ * to remove the body. The renderer reads `kind` to decide
239
+ * which preview layout to use. */
240
+ applyNodeRichContent: (nodeId: string, content: {
241
+ kind: 'code' | 'table';
242
+ raw: string;
243
+ lang?: string;
244
+ } | null) => void;
225
245
  undo: () => void;
226
246
  redo: () => void;
227
247
  canUndo: () => boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flow-mindmap",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "A modern, minimalist mind mapping tool — xmind-style, embeddable as a Vue component.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -57,8 +57,10 @@
57
57
  "vue": "^3.4.0"
58
58
  },
59
59
  "devDependencies": {
60
+ "@types/dompurify": "^3.2.0",
60
61
  "@types/node": "^25.9.1",
61
62
  "@vitejs/plugin-vue": "^5.1.4",
63
+ "@vue/test-utils": "^2.4.11",
62
64
  "happy-dom": "^20.10.1",
63
65
  "playwright": "^1.60.0",
64
66
  "typescript": "^5.6.3",
@@ -66,5 +68,10 @@
66
68
  "vitest": "3.2.4",
67
69
  "vue": "^3.5.12",
68
70
  "vue-tsc": "^2.1.10"
71
+ },
72
+ "dependencies": {
73
+ "dompurify": "^3.4.8",
74
+ "highlight.js": "^11.11.1",
75
+ "marked": "^18.0.5"
69
76
  }
70
77
  }