flow-mindmap 0.5.14 → 0.6.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/dist/style.css CHANGED
@@ -7,4 +7,4 @@
7
7
 
8
8
  Outdated base version: https://github.com/primer/github-syntax-light
9
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:.4em;box-sizing:border-box;border-radius:8px;border:1px solid transparent;line-height:1.2;cursor:default;transition:box-shadow .15s;white-space:nowrap;z-index:1}.zm-node:hover{box-shadow:0 4px 12px #0000001a;z-index:2}.zm-node:not(.is-root):not(.is-editing){cursor:grab}.zm-node.is-root{cursor:default}.zm-node.is-dragging-source{opacity:.4;cursor:grabbing}.zm-node.is-drop-target{outline:2px solid #4caf50;outline-offset:2px;transition:outline-color .1s ease}.zm-node.is-drop-target-before{box-shadow:0 -3px #3b82f6,0 1px 2px #0000000f}.zm-node.is-drop-target-after{box-shadow:0 3px #3b82f6,0 1px 2px #0000000f}.zm-drop-indicator{position:absolute;background:#3b82f6;border-radius:2px;pointer-events:none;z-index:9999;box-shadow:0 0 6px #3b82f680}.zm-drag-ghost{position:absolute;pointer-events:none;z-index:10000;padding:4px 10px;background:#fff;border:1px solid #4caf50;border-radius:4px;box-shadow:0 4px 12px #00000026;font-size:13px;color:#333;white-space:nowrap;max-width:200px;overflow:hidden;text-overflow:ellipsis;will-change:transform,left,top}body.is-dragging{cursor:grabbing!important;-webkit-user-select:none;user-select:none}.zm-node.is-root{font-weight:600}.zm-node.is-selected{outline:2px solid #3b82f6;outline-offset:2px;z-index:3}.zm-node.is-selected-secondary{outline:2px solid #bfdbfe;outline-offset:2px;z-index:2}.zm-text{display:flex;align-items:center;justify-content:center;gap:4px;min-height:1.2em;max-width:200px;overflow:hidden}.zm-text-label{pointer-events:none;overflow:hidden;white-space:pre-line;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;resize:none;overflow:hidden;padding:0;line-height:1.2}.zm-tooltip{position:absolute;max-width:240px;padding:6px 10px;background:#0f172af0;color:#f8fafc;font-size:12px;line-height:1.4;border-radius:6px;box-shadow:0 4px 14px #0000002e;pointer-events:none;z-index:1000;white-space:normal;word-break:break-word;transform:translate(-50%,-100%);animation:zm-tooltip-in .12s ease-out}.zm-tooltip.is-below{transform:translate(-50%)}.zm-tooltip:after{content:"";position:absolute;left:50%;top:100%;transform:translate(-50%);border:4px solid transparent;border-top-color:#0f172af0}.zm-tooltip.is-below:after{top:auto;bottom:100%;border-top-color:transparent;border-bottom-color:#0f172af0}@keyframes zm-tooltip-in{0%{opacity:0;transform:translate(-50%,calc(-100% + 4px))}to{opacity:1;transform:translate(-50%,-100%)}}.zm-tooltip.is-below{animation-name:zm-tooltip-in-below}@keyframes zm-tooltip-in-below{0%{opacity:0;transform:translate(-50%,-4px)}to{opacity:1;transform:translate(-50%)}}.zm-rich{margin-top:6px;width:max-content;overflow:visible;font-size:.78em;line-height:1.35;text-align:left;border-radius:4px;padding:0 .8em .2em;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 14px;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:.92em;white-space:pre-wrap;word-break:break-word;background:#fffffff2;border:1px solid currentColor;border-radius:6px}.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:#fffffff2;border:1px solid currentColor;border-radius:6px;overflow:hidden}.zm-rich-table th{background:#ffffffbf;font-weight:600;text-align:left;padding:3px 10px;border-bottom:1px solid currentColor;border-right:1px solid currentColor;opacity:.9}.zm-rich-table th:last-child{border-right:none}.zm-rich-table td{border-top:1px solid currentColor;border-right:1px solid currentColor;padding:3px 10px;opacity:.9}.zm-rich-table tr:last-child td{border-bottom:none}.zm-rich-table td:last-child{border-right:none}.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:16px;height:16px;border-radius:50%;background:#fff;border:none;transform:translateY(-50%);box-shadow:0 1px 3px #0f172a33;display:flex;align-items:center;justify-content:center}.zm-collapse-bar{display:block;width:7px;height:2px;border-radius:1px;background:var(--zm-collapse-color, #64748b)}.zm-collapse.is-on-left{right:auto;left:-8px}.zm-collapse:hover{transform:translateY(-50%) scale(1.2);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:-6px;bottom:-6px;width:14px;height:14px;background:#3b82f6;border:2px solid #ffffff;border-radius:50%;cursor:nwse-resize;z-index:4;box-shadow:0 1px 4px #0f172a4d;transition:transform .1s}.zm-img-resize-handle:hover{transform:scale(1.2)}.zm-node.is-resizing{cursor:nwse-resize!important}.zm-img-remove-btn{position:absolute;right:-6px;top:-6px;width:16px;height:16px;background:#fff;border:1px solid #e2e8f0;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;color:#64748b;padding:0;z-index:4;box-shadow:0 1px 3px #0f172a26;transition:all .1s}.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-canvas-fab{position:absolute;width:34px;height:34px;display:flex;align-items:center;justify-content:center;border:none;background:#fff;border:1px solid #e8eaed;border-radius:999px;box-shadow:0 2px 8px #0f172a0f,0 1px 2px #0f172a0a;color:#475569;cursor:pointer;z-index:11;opacity:0;pointer-events:none;transform:translateY(4px);transition:opacity .18s ease,transform .18s ease,background .1s,color .1s,box-shadow .12s}.zm-canvas-fab.is-visible{opacity:1;pointer-events:auto;transform:translateY(0)}.zm-canvas-fab:hover{background:#f8fafc;color:#1e293b;box-shadow:0 4px 16px #0f172a1a,0 1px 4px #0f172a0f}.zm-canvas-fab:active{transform:scale(.94)}.zm-canvas-fab-preview{top:16px;right:16px}.zm-canvas-fab-outline{top:16px;left:16px}.zm-toolbar{position:absolute;bottom:16px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:4px;padding:7px 12px;background:#ffffffeb;backdrop-filter:blur(12px) saturate(180%);-webkit-backdrop-filter:blur(12px) saturate(180%);border:1px solid rgba(226,232,240,.6);border-radius:999px;box-shadow:0 4px 20px #0f172a0f,0 1px 3px #0f172a0a;z-index:10;transition:opacity .18s ease,transform .18s ease}.zm-toolbar.is-preview-only{opacity:0;pointer-events:none;transform:translate(-50%) translateY(8px)}.zm-toolbar.is-preview-only.is-hovered{opacity:1;pointer-events:auto;transform:translate(-50%) translateY(0)}.zm-tb-btn{width:32px;height:32px;display:flex;align-items:center;justify-content:center;border:none;background:transparent;border-radius:8px;cursor:pointer;color:#475569;transition:background .12s,color .12s}.zm-tb-btn:hover{background:#f1f5f9;color:#0f172a}.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:#e2e8f0b3;margin:0 4px}.zm-tb-tip{font-size:12px;color:#64748b;min-width:38px;text-align:center}.zm-tb-zoom{cursor:pointer;-webkit-user-select:none;user-select:none}.zm-tb-zoom:hover{color:#3b82f6}.zm-node.is-search-hit{outline:2px solid #f59e0b;outline-offset:2px;z-index:3}.zm-node.is-search-current{outline:3px solid #f97316;outline-offset:3px;z-index:4;box-shadow:0 0 0 4px #f9731626}.zm-node.is-search-dimmed{opacity:.35}.zm-node-markers{display:flex;align-items:center;gap:2px;flex-shrink:0;pointer-events:none}.zm-node-marker{display:inline-flex;width:14px;height:14px;flex-shrink:0}.zm-node-marker svg{display:block;width:14px;height:14px}.zm-node-tags{display:flex;flex-wrap:wrap;gap:3px;justify-content:center;margin-top:3px;max-width:100%;overflow:hidden}.zm-node-tag{display:inline-block;padding:1px 6px;border-radius:999px;font-size:10px;line-height:1.4;font-weight:500;white-space:nowrap;pointer-events:none}.zm-app{display:flex;width:100%;height:100%;background:#f8fafc;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,PingFang SC,Microsoft YaHei,sans-serif;font-size:14px;color:#1e293b;overflow:hidden}.zm-app-main{flex:1;display:flex;flex-direction:column;min-width:0}.zm-app-preview-exit{position:absolute;top:12px;right:12px;z-index:10;width:34px;height:34px;border:1px solid #e8eaed;background:#ffffffeb;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);color:#475569;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 2px 8px #0f172a0f;transition:background .12s,color .12s,transform .12s}.zm-app-preview-exit:hover{background:#f1f5f9;color:#0f172a;transform:scale(1.05)}.zm-app-canvas{flex:1;position:relative;min-height:0}
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:.4em;box-sizing:border-box;border-radius:8px;border:1px solid transparent;line-height:1.2;cursor:default;transition:box-shadow .15s;white-space:nowrap;z-index:1}.zm-node:hover{box-shadow:0 4px 12px #0000001a;z-index:2}.zm-node:not(.is-root):not(.is-editing){cursor:grab}.zm-node.is-root{cursor:default}.zm-node.is-dragging-source{opacity:.4;cursor:grabbing}.zm-node.is-drop-target{outline:2px solid #4caf50;outline-offset:2px;transition:outline-color .1s ease}.zm-node.is-drop-target-before{box-shadow:0 -3px #3b82f6,0 1px 2px #0000000f}.zm-node.is-drop-target-after{box-shadow:0 3px #3b82f6,0 1px 2px #0000000f}.zm-drop-indicator{position:absolute;background:#3b82f6;border-radius:2px;pointer-events:none;z-index:9999;box-shadow:0 0 6px #3b82f680}.zm-drag-ghost{position:absolute;pointer-events:none;z-index:10000;padding:4px 10px;background:#fff;border:1px solid #4caf50;border-radius:4px;box-shadow:0 4px 12px #00000026;font-size:13px;color:#333;white-space:nowrap;max-width:200px;overflow:hidden;text-overflow:ellipsis;will-change:transform,left,top}body.is-dragging{cursor:grabbing!important;-webkit-user-select:none;user-select:none}.zm-node.is-root{font-weight:600}.zm-node.is-selected{outline:2px solid #3b82f6;outline-offset:2px;z-index:3}.zm-node.is-selected-secondary{outline:2px solid #bfdbfe;outline-offset:2px;z-index:2}.zm-text{display:flex;align-items:center;justify-content:center;gap:4px;min-height:1.2em;max-width:200px;overflow:hidden}.zm-text-label{pointer-events:none;overflow:hidden;white-space:pre-line;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;resize:none;overflow:hidden;padding:0;line-height:1.2}.zm-tooltip{position:absolute;max-width:240px;padding:6px 10px;background:#0f172af0;color:#f8fafc;font-size:12px;line-height:1.4;border-radius:6px;box-shadow:0 4px 14px #0000002e;pointer-events:none;z-index:1000;white-space:normal;word-break:break-word;transform:translate(-50%,-100%);animation:zm-tooltip-in .12s ease-out}.zm-tooltip.is-below{transform:translate(-50%)}.zm-tooltip:after{content:"";position:absolute;left:50%;top:100%;transform:translate(-50%);border:4px solid transparent;border-top-color:#0f172af0}.zm-tooltip.is-below:after{top:auto;bottom:100%;border-top-color:transparent;border-bottom-color:#0f172af0}@keyframes zm-tooltip-in{0%{opacity:0;transform:translate(-50%,calc(-100% + 4px))}to{opacity:1;transform:translate(-50%,-100%)}}.zm-tooltip.is-below{animation-name:zm-tooltip-in-below}@keyframes zm-tooltip-in-below{0%{opacity:0;transform:translate(-50%,-4px)}to{opacity:1;transform:translate(-50%)}}.zm-rich{margin-top:6px;width:max-content;overflow:visible;font-size:.78em;line-height:1.35;text-align:left;border-radius:4px;padding:0 .8em .2em;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 14px;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:.92em;white-space:pre-wrap;word-break:break-word;background:#fffffff2;border:1px solid currentColor;border-radius:6px}.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:#fffffff2;border:1px solid currentColor;border-radius:6px;overflow:hidden}.zm-rich-table th{background:#ffffffbf;font-weight:600;text-align:left;padding:3px 10px;border-bottom:1px solid currentColor;border-right:1px solid currentColor;opacity:.9}.zm-rich-table th:last-child{border-right:none}.zm-rich-table td{border-top:1px solid currentColor;border-right:1px solid currentColor;padding:3px 10px;opacity:.9}.zm-rich-table tr:last-child td{border-bottom:none}.zm-rich-table td:last-child{border-right:none}.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:16px;height:16px;border-radius:50%;background:#fff;border:none;transform:translateY(-50%);box-shadow:0 1px 3px #0f172a33;display:flex;align-items:center;justify-content:center}.zm-collapse-bar{display:block;width:7px;height:2px;border-radius:1px;background:var(--zm-collapse-color, #64748b)}.zm-collapse.is-on-left{right:auto;left:-8px}.zm-collapse:hover{transform:translateY(-50%) scale(1.2);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:-6px;bottom:-6px;width:14px;height:14px;background:#3b82f6;border:2px solid #ffffff;border-radius:50%;cursor:nwse-resize;z-index:4;box-shadow:0 1px 4px #0f172a4d;transition:transform .1s}.zm-img-resize-handle:hover{transform:scale(1.2)}.zm-node.is-resizing{cursor:nwse-resize!important}.zm-img-remove-btn{position:absolute;right:-6px;top:-6px;width:16px;height:16px;background:#fff;border:1px solid #e2e8f0;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;color:#64748b;padding:0;z-index:4;box-shadow:0 1px 3px #0f172a26;transition:all .1s}.zm-img-remove-btn:hover{background:#fee2e2;color:#b91c1c;border-color:#fca5a5}.zm-relation-path{fill:none;stroke:#94a3b8;stroke-width:1.5;stroke-dasharray:6 4;stroke-linecap:round;pointer-events:none}.zm-relation-path.is-selected{stroke:#3b82f6}.zm-relation-arrow{fill:#94a3b8;stroke:none;pointer-events:none}.zm-relation-arrow.is-selected{fill:#3b82f6}.zm-relation-hit{fill:none;stroke:transparent;stroke-width:14;pointer-events:stroke;cursor:pointer}.zm-relation-label{font-size:12px;fill:#64748b;paint-order:stroke;stroke:#fff;stroke-width:3px;pointer-events:all;cursor:pointer;-webkit-user-select:none;user-select:none}.zm-relation-guide{stroke:#3b82f6;stroke-width:1;stroke-dasharray:3 3;pointer-events:none;vector-effect:non-scaling-stroke}.zm-relation-handle{fill:#fff;stroke:#3b82f6;stroke-width:1.5;vector-effect:non-scaling-stroke;pointer-events:all;cursor:grab}.zm-relation-handle:hover{fill:#dbeafe}.zm-relation-handle-ctrl{stroke:#f59e0b}.zm-relation-handle-ctrl:hover{fill:#fef3c7}.zm-canvas.is-relation-mode{cursor:crosshair}.zm-node.is-relation-source{box-shadow:0 0 0 2px #3b82f6,0 0 0 5px #3b82f640}.zm-node.is-relation-target{box-shadow:0 0 0 2px #22c55e,0 0 0 5px #22c55e40}.zm-relation-label-input{position:absolute;transform:translate(-50%,-110%);min-width:72px;padding:2px 8px;font-size:12px;line-height:1.5;border:1px solid #3b82f6;border-radius:4px;outline:none;background:#fff;color:#334155;text-align:center;box-shadow:0 2px 8px #0f172a1f;z-index:5}.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-canvas-fab{position:absolute;width:34px;height:34px;display:flex;align-items:center;justify-content:center;border:none;background:#fff;border:1px solid #e8eaed;border-radius:999px;box-shadow:0 2px 8px #0f172a0f,0 1px 2px #0f172a0a;color:#475569;cursor:pointer;z-index:11;opacity:0;pointer-events:none;transform:translateY(4px);transition:opacity .18s ease,transform .18s ease,background .1s,color .1s,box-shadow .12s}.zm-canvas-fab.is-visible{opacity:1;pointer-events:auto;transform:translateY(0)}.zm-canvas-fab:hover{background:#f8fafc;color:#1e293b;box-shadow:0 4px 16px #0f172a1a,0 1px 4px #0f172a0f}.zm-canvas-fab:active{transform:scale(.94)}.zm-canvas-fab-preview{top:16px;right:16px}.zm-canvas-fab-outline{top:16px;left:16px}.zm-toolbar{position:absolute;bottom:16px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:4px;padding:7px 12px;background:#ffffffeb;backdrop-filter:blur(12px) saturate(180%);-webkit-backdrop-filter:blur(12px) saturate(180%);border:1px solid rgba(226,232,240,.6);border-radius:999px;box-shadow:0 4px 20px #0f172a0f,0 1px 3px #0f172a0a;z-index:10;transition:opacity .18s ease,transform .18s ease}.zm-toolbar.is-preview-only{opacity:0;pointer-events:none;transform:translate(-50%) translateY(8px)}.zm-toolbar.is-preview-only.is-hovered{opacity:1;pointer-events:auto;transform:translate(-50%) translateY(0)}.zm-tb-btn{width:32px;height:32px;display:flex;align-items:center;justify-content:center;border:none;background:transparent;border-radius:8px;cursor:pointer;color:#475569;transition:background .12s,color .12s}.zm-tb-btn:hover{background:#f1f5f9;color:#0f172a}.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:#e2e8f0b3;margin:0 4px}.zm-tb-tip{font-size:12px;color:#64748b;min-width:38px;text-align:center}.zm-tb-zoom{cursor:pointer;-webkit-user-select:none;user-select:none}.zm-tb-zoom:hover{color:#3b82f6}.zm-node.is-search-hit{outline:2px solid #f59e0b;outline-offset:2px;z-index:3}.zm-node.is-search-current{outline:3px solid #f97316;outline-offset:3px;z-index:4;box-shadow:0 0 0 4px #f9731626}.zm-node.is-search-dimmed{opacity:.35}.zm-node-markers{display:flex;align-items:center;gap:2px;flex-shrink:0;pointer-events:none}.zm-node-marker{display:inline-flex;width:14px;height:14px;flex-shrink:0}.zm-node-marker svg{display:block;width:14px;height:14px}.zm-node-tags{display:flex;flex-wrap:wrap;gap:3px;justify-content:center;margin-top:3px;max-width:100%;overflow:hidden}.zm-node-tag{display:inline-block;padding:1px 6px;border-radius:999px;font-size:10px;line-height:1.4;font-weight:500;white-space:nowrap;pointer-events:none}.zm-app{display:flex;width:100%;height:100%;background:#f8fafc;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,PingFang SC,Microsoft YaHei,sans-serif;font-size:14px;color:#1e293b;overflow:hidden}.zm-app-main{flex:1;display:flex;flex-direction:column;min-width:0}.zm-app-preview-exit{position:absolute;top:12px;right:12px;z-index:10;width:34px;height:34px;border:1px solid #e8eaed;background:#ffffffeb;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);color:#475569;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 2px 8px #0f172a0f;transition:background .12s,color .12s,transform .12s}.zm-app-preview-exit:hover{background:#f1f5f9;color:#0f172a;transform:scale(1.05)}.zm-app-canvas{flex:1;position:relative;min-height:0}
package/dist/tree.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { MindMapNode } from './types';
1
+ import type { MindMapNode, MindMapRelation } from './types';
2
2
  export declare function uid(): string;
3
3
  export declare function clone<T>(o: T): T;
4
4
  export declare function findNode(root: MindMapNode, id: string): MindMapNode | null;
@@ -42,6 +42,27 @@ export declare function cloneSubtree(root: MindMapNode, nodeId: string): MindMap
42
42
  export declare function hasDescendant(root: MindMapNode, rootId: string, descendantId: string): boolean;
43
43
  export declare function countDescendants(n: MindMapNode): number;
44
44
  export declare const DEFAULT_NEW_NODE_TEXT = "\u65B0\u8282\u70B9";
45
+ export declare function findRelation(root: MindMapNode, id: string): MindMapRelation | null;
46
+ /** Create a relationship between two nodes. Returns the new
47
+ * relation, or null when the pair is invalid: same node on both
48
+ * ends, an unknown node id, or an identical (fromId, toId)
49
+ * connection already exists. */
50
+ export declare function addRelation(root: MindMapNode, fromId: string, toId: string): MindMapRelation | null;
51
+ export declare function removeRelation(root: MindMapNode, id: string): boolean;
52
+ /** Patch a relation in place (label / anchors / control points).
53
+ * `fromId` / `toId` / `id` are ignored — re-attach goes through
54
+ * `reattachRelation`. Returns true on success. */
55
+ export declare function updateRelation(root: MindMapNode, id: string, patch: Partial<Omit<MindMapRelation, 'id' | 'fromId' | 'toId'>>): boolean;
56
+ /** Move one end of a relation to a different node. `end` selects
57
+ * which side ('from' | 'to'). No-op (returns false) when the new
58
+ * node is unknown, equals the other endpoint, or the resulting
59
+ * (fromId, toId) pair already exists. Clears the moved end's
60
+ * anchor offset so the line re-anchors at the new node's edge. */
61
+ export declare function reattachRelation(root: MindMapNode, id: string, end: 'from' | 'to', newNodeId: string): boolean;
62
+ /** Drop every relation that references `nodeId` on either end.
63
+ * Called by the canvas when a node (or its subtree) is removed.
64
+ * Returns the number of relations removed. */
65
+ export declare function removeRelationsForNode(root: MindMapNode, nodeId: string): number;
45
66
  /**
46
67
  * Parse a Markdown string into a MindMapNode tree. Each heading
47
68
  * becomes a node; its level sets the depth.
package/dist/types.d.ts CHANGED
@@ -69,6 +69,59 @@ export interface MindMapNode {
69
69
  * pill color is derived from a hash of the label text.
70
70
  */
71
71
  tags?: string[];
72
+ /**
73
+ * XMind-style relationship lines ("联系") connecting arbitrary
74
+ * pairs of nodes. Only meaningful on the ROOT node — the
75
+ * canvas reads/writes `root.relations`; entries reference
76
+ * other nodes by id. Survives JSON export/import and
77
+ * undo/redo (plain JSON shape), but is NOT serialized to
78
+ * markdown (node ids are regenerated on markdown re-import,
79
+ * so the references would dangle).
80
+ */
81
+ relations?: MindMapRelation[];
82
+ }
83
+ /**
84
+ * A free-form connection between any two nodes (XMind "联系").
85
+ * Rendered as a dashed cubic-bezier curve with an optional text
86
+ * label at the midpoint. When the line is selected the canvas
87
+ * shows four handles: two endpoint anchors (drag along the node
88
+ * edge, or drop onto another node to re-attach) and two bezier
89
+ * control points (free drag).
90
+ */
91
+ export interface MindMapRelation {
92
+ id: string;
93
+ fromId: string;
94
+ toId: string;
95
+ /**
96
+ * Endpoint anchor offset along the node edge, normalized to
97
+ * -1..1. The anchor starts at the point where the centers'
98
+ * connecting line exits the node box; `fromT` / `toT` slide it
99
+ * along the edge perimeter. Default 0 (no offset).
100
+ */
101
+ fromT?: number;
102
+ toT?: number;
103
+ /**
104
+ * Bezier control point overrides in world coordinates. When
105
+ * absent, the canvas derives default control points (perpendicular
106
+ * to the endpoint tangent) so fresh relations get a pleasant
107
+ * automatic curve. Written when the user drags a control handle.
108
+ */
109
+ c1?: {
110
+ x: number;
111
+ y: number;
112
+ };
113
+ c2?: {
114
+ x: number;
115
+ y: number;
116
+ };
117
+ /** Text shown at the curve midpoint. Empty/undefined = no label. */
118
+ label?: string;
119
+ /** Reserved for a future style panel — not yet consumed by the UI. */
120
+ color?: string;
121
+ dash?: boolean;
122
+ /** Arrowheads on the line. Default 'end' (XMind 联系 style —
123
+ * the arrow points at the second-picked node). */
124
+ arrow?: 'none' | 'end' | 'both';
72
125
  }
73
126
  /**
74
127
  * A node body that came from a markdown block. `raw` is the
@@ -381,4 +434,16 @@ export interface MindMapExpose {
381
434
  /** The zero-based index of the currently focused search match,
382
435
  * or -1 when no match is focused. */
383
436
  getSearchIndex: () => number;
437
+ /** Create a relationship line ("联系") between two nodes.
438
+ * Returns the new relation's id, or null when the pair is
439
+ * invalid (same node, unknown id, or already connected in
440
+ * the same direction). */
441
+ addRelation: (fromId: string, toId: string) => string | null;
442
+ /** Remove a relationship line by id (no-op if absent). */
443
+ removeRelation: (relationId: string) => void;
444
+ /** Patch a relationship line (label, anchors, control points).
445
+ * No-op if the relation does not exist. */
446
+ updateRelation: (relationId: string, patch: Partial<Omit<MindMapRelation, 'id' | 'fromId' | 'toId'>>) => void;
447
+ /** Read all relationship lines (empty array when none). */
448
+ getRelations: () => MindMapRelation[];
384
449
  }
package/package.json CHANGED
@@ -1,79 +1,79 @@
1
- {
2
- "name": "flow-mindmap",
3
- "version": "0.5.14",
4
- "description": "A modern, minimalist mind mapping tool — xmind-style, embeddable as a Vue component.",
5
- "type": "module",
6
- "license": "Apache-2.0",
7
- "author": {
8
- "name": "xuze",
9
- "email": "569552263@qq.com"
10
- },
11
- "repository": {
12
- "type": "git",
13
- "url": "git+https://github.com/xz333221/flow-mindmap.git"
14
- },
15
- "bugs": {
16
- "url": "https://github.com/xz333221/flow-mindmap/issues"
17
- },
18
- "keywords": [
19
- "mindmap",
20
- "mind-map",
21
- "xmind",
22
- "vue",
23
- "vue3",
24
- "vite",
25
- "svg",
26
- "canvas",
27
- "tree"
28
- ],
29
- "files": [
30
- "dist",
31
- "README.md",
32
- "LICENSE"
33
- ],
34
- "main": "./dist/flow-mindmap.umd.cjs",
35
- "module": "./dist/flow-mindmap.js",
36
- "types": "./dist/entry.d.ts",
37
- "exports": {
38
- ".": {
39
- "types": "./dist/entry.d.ts",
40
- "import": "./dist/flow-mindmap.js",
41
- "require": "./dist/flow-mindmap.umd.cjs"
42
- },
43
- "./style.css": "./dist/style.css"
44
- },
45
- "scripts": {
46
- "pull": "git pull",
47
- "dev": "vite --port 7851 --strictPort",
48
- "build:types": "vue-tsc -p tsconfig.build.json",
49
- "build:lib": "vite build --mode lib",
50
- "build": "pnpm build:types && pnpm build:lib",
51
- "preview": "vite preview --port 7852",
52
- "typecheck": "vue-tsc --noEmit",
53
- "lint": "eslint . --ext .vue,.ts,.js --max-warnings 0",
54
- "test": "vitest run",
55
- "test:watch": "vitest",
56
- "screenshots": "node scripts/screenshots.mjs"
57
- },
58
- "peerDependencies": {
59
- "vue": "^3.4.0"
60
- },
61
- "devDependencies": {
62
- "@types/dompurify": "^3.2.0",
63
- "@types/node": "^25.9.1",
64
- "@vitejs/plugin-vue": "^5.1.4",
65
- "@vue/test-utils": "^2.4.11",
66
- "happy-dom": "^20.10.1",
67
- "playwright": "^1.60.0",
68
- "typescript": "^5.6.3",
69
- "vite": "^5.4.10",
70
- "vitest": "3.2.4",
71
- "vue": "^3.5.12",
72
- "vue-tsc": "^2.1.10"
73
- },
74
- "dependencies": {
75
- "dompurify": "^3.4.8",
76
- "highlight.js": "^11.11.1",
77
- "marked": "^18.0.5"
78
- }
79
- }
1
+ {
2
+ "name": "flow-mindmap",
3
+ "version": "0.6.0",
4
+ "description": "A modern, minimalist mind mapping tool — xmind-style, embeddable as a Vue component.",
5
+ "type": "module",
6
+ "license": "Apache-2.0",
7
+ "author": {
8
+ "name": "xuze",
9
+ "email": "569552263@qq.com"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/xz333221/flow-mindmap.git"
14
+ },
15
+ "bugs": {
16
+ "url": "https://github.com/xz333221/flow-mindmap/issues"
17
+ },
18
+ "keywords": [
19
+ "mindmap",
20
+ "mind-map",
21
+ "xmind",
22
+ "vue",
23
+ "vue3",
24
+ "vite",
25
+ "svg",
26
+ "canvas",
27
+ "tree"
28
+ ],
29
+ "files": [
30
+ "dist",
31
+ "README.md",
32
+ "LICENSE"
33
+ ],
34
+ "main": "./dist/flow-mindmap.umd.cjs",
35
+ "module": "./dist/flow-mindmap.js",
36
+ "types": "./dist/entry.d.ts",
37
+ "exports": {
38
+ ".": {
39
+ "types": "./dist/entry.d.ts",
40
+ "import": "./dist/flow-mindmap.js",
41
+ "require": "./dist/flow-mindmap.umd.cjs"
42
+ },
43
+ "./style.css": "./dist/style.css"
44
+ },
45
+ "scripts": {
46
+ "pull": "git pull",
47
+ "dev": "vite --port 7851 --strictPort",
48
+ "build:types": "vue-tsc -p tsconfig.build.json",
49
+ "build:lib": "vite build --mode lib",
50
+ "build": "pnpm build:types && pnpm build:lib",
51
+ "preview": "vite preview --port 7852",
52
+ "typecheck": "vue-tsc --noEmit",
53
+ "lint": "eslint . --ext .vue,.ts,.js --max-warnings 0",
54
+ "test": "vitest run",
55
+ "test:watch": "vitest",
56
+ "screenshots": "node scripts/screenshots.mjs"
57
+ },
58
+ "peerDependencies": {
59
+ "vue": "^3.4.0"
60
+ },
61
+ "devDependencies": {
62
+ "@types/dompurify": "^3.2.0",
63
+ "@types/node": "^25.9.1",
64
+ "@vitejs/plugin-vue": "^5.1.4",
65
+ "@vue/test-utils": "^2.4.11",
66
+ "happy-dom": "^20.10.1",
67
+ "playwright": "^1.60.0",
68
+ "typescript": "^5.6.3",
69
+ "vite": "^5.4.10",
70
+ "vitest": "3.2.4",
71
+ "vue": "^3.5.12",
72
+ "vue-tsc": "^2.1.10"
73
+ },
74
+ "dependencies": {
75
+ "dompurify": "^3.4.8",
76
+ "highlight.js": "^11.11.1",
77
+ "marked": "^18.0.5"
78
+ }
79
+ }