kakidash 0.0.1 → 0.0.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/kakidash.cjs +48 -0
- package/package.json +3 -3
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";var W=Object.defineProperty;var $=(N,t,e)=>t in N?W(N,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):N[t]=e;var c=(N,t,e)=>$(N,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class j{constructor(t){c(this,"root");c(this,"theme","default");this.root=t}findNode(t){return this.findNodeRecursive(this.root,t)}findNodeRecursive(t,e){if(t.id===e)return t;for(const i of t.children){const s=this.findNodeRecursive(i,e);if(s)return s}return null}moveNode(t,e){const i=this.findNode(t),s=this.findNode(e);if(!i||!s||i.isRoot||i.parentId===e||this.isDescendant(i,e))return!1;if(i.parentId){const n=this.findNode(i.parentId);n&&n.removeChild(t)}return s.addChild(i),!0}addSibling(t,e,i){const s=this.findNode(t);if(!s||!s.parentId)return!1;const n=this.findNode(s.parentId);if(!n)return!1;const r=n.children.findIndex(a=>a.id===t);if(r===-1)return!1;const o=i==="before"?r:r+1;return n.insertChild(e,o),!0}insertParent(t,e){const i=this.findNode(t);if(!i||!i.parentId)return!1;const s=this.findNode(i.parentId);if(!s)return!1;const n=s.children.findIndex(r=>r.id===t);return n===-1?!1:(s.removeChild(t),s.insertChild(e,n),e.addChild(i),!0)}isDescendant(t,e){if(t.id===e)return!0;for(const i of t.children)if(this.isDescendant(i,e))return!0;return!1}}class b{constructor(t,e,i=null,s=!1,n,r){c(this,"id");c(this,"topic");c(this,"children");c(this,"style");c(this,"parentId");c(this,"isRoot");c(this,"image");c(this,"layoutSide");this.id=t,this.topic=e,this.children=[],this.style={fontSize:s?"24px":"16px"},this.parentId=i,this.isRoot=s,this.image=n,this.layoutSide=r}addChild(t){t.parentId=this.id,this.children.push(t)}insertChild(t,e){t.parentId=this.id,e>=0&&e<=this.children.length?this.children.splice(e,0,t):this.children.push(t)}removeChild(t){this.children=this.children.filter(e=>e.id!==t)}updateTopic(t){this.topic=t}}class Z{constructor(t=10){c(this,"past",[]);c(this,"future",[]);c(this,"maxHistorySize");this.maxHistorySize=t}push(t){this.past.push(t),this.past.length>this.maxHistorySize&&this.past.shift(),this.future=[]}undo(t){if(this.past.length===0)return null;const e=this.past.pop();return e?(this.future.push(t),e):null}get canUndo(){return this.past.length>0}redo(t){if(this.future.length===0)return null;const e=this.future.pop();return e?(this.past.push(t),this.past.length>this.maxHistorySize&&this.past.shift(),e):null}get canRedo(){return this.future.length>0}clear(){this.past=[],this.future=[]}}class V{constructor(t){c(this,"mindMap");c(this,"historyManager");c(this,"clipboard",null);this.mindMap=t,this.historyManager=new Z(10)}saveState(){this.historyManager.push(this.exportData())}undo(){const t=this.historyManager.undo(this.exportData());return t?(this.importData(t),!0):!1}get canUndo(){return this.historyManager.canUndo}addNode(t,e="New Node",i){const s=this.mindMap.findNode(t);if(!s)return null;this.saveState();const n=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substr(2),r=new b(n,e,null,!1,void 0,i);return s.addChild(r),r}addImageNode(t,e){const i=this.mindMap.findNode(t);if(!i)return null;this.saveState();const s=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substr(2),n=new b(s,"",t,!1,e);return i.addChild(n),n}removeNode(t,e=!0){const i=this.mindMap.findNode(t);if(!i||i.isRoot||!i.parentId)return!1;const s=this.mindMap.findNode(i.parentId);return s?(e&&this.saveState(),s.removeChild(t),!0):!1}updateNodeTopic(t,e){const i=this.mindMap.findNode(t);return i?(this.saveState(),i.updateTopic(e),!0):!1}updateNodeStyle(t,e){const i=this.mindMap.findNode(t);return i?(this.saveState(),i.style={...i.style,...e},!0):!1}setTheme(t){this.mindMap.theme!==t&&(this.saveState(),this.mindMap.theme=t)}moveNode(t,e,i){const s=this.mindMap.findNode(t);if(s&&s.parentId===e)return i&&s.layoutSide!==i?(this.saveState(),s.layoutSide=i,!0):!1;if(!s)return!1;if(this.saveState(),this.mindMap.moveNode(t,e)){if(i){const n=this.mindMap.findNode(t);n&&(n.layoutSide=i)}return!0}return!1}addSibling(t,e,i="New Node"){const s=this.mindMap.findNode(t);if(!s||!s.parentId)return null;this.saveState();const n=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substr(2),r=new b(n,i);return this.mindMap.addSibling(t,r,e)?r:null}reorderNode(t,e,i){const s=this.mindMap.findNode(t),n=this.mindMap.findNode(e);if(!s||!n||!n.parentId||s.id===n.id||s.isRoot)return!1;const r=this.mindMap.findNode(n.parentId);if(!r)return!1;if(this.saveState(),s.parentId!==r.id){let d=r;for(;d.parentId;){if(d.id===s.id)return!1;if(!d.parentId)break;const h=this.mindMap.findNode(d.parentId);if(!h)break;d=h}}if(s.parentId&&s.parentId!==r.id){const d=this.mindMap.findNode(s.parentId);d&&d.removeChild(s.id),s.parentId=r.id}else s.parentId===r.id&&r.removeChild(s.id);const o=r.children.findIndex(d=>d.id===e);if(o===-1)return r.addChild(s),!0;const a=i==="before"?o:o+1;return r.insertChild(s,a),r.isRoot&&n.layoutSide&&(s.layoutSide=n.layoutSide),!0}insertNodeAsParent(t,e){const i=this.mindMap.findNode(t),s=this.mindMap.findNode(e);if(!i||!s||!s.parentId||i.id===s.id)return!1;const n=this.mindMap.findNode(s.parentId);if(!n)return!1;let r=n;for(;r;){if(r.id===i.id)return!1;if(!r.parentId)break;r=this.mindMap.findNode(r.parentId)}if(this.saveState(),i.parentId){const a=this.mindMap.findNode(i.parentId);a&&a.removeChild(i.id)}const o=n.children.findIndex(a=>a.id===e);return o===-1?!1:(n.isRoot&&s.layoutSide&&(i.layoutSide=s.layoutSide),n.removeChild(e),n.insertChild(i,o),i.parentId=n.id,i.addChild(s),!0)}insertParent(t,e="New Parent"){const i=this.mindMap.findNode(t);if(!i||!i.parentId)return null;this.saveState();const s=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substr(2),n=new b(s,e);return this.mindMap.insertParent(t,n)?n:null}copyNode(t){const e=this.mindMap.findNode(t);e&&(this.clipboard=this.deepCloneNode(e),navigator.clipboard&&navigator.clipboard.writeText(e.topic).catch(i=>{console.error("Failed to write to clipboard",i)}))}cutNode(t){const e=this.mindMap.findNode(t);e&&!e.isRoot&&e.parentId&&(this.copyNode(t),this.removeNode(t))}pasteNode(t){if(!this.clipboard)return null;const e=this.mindMap.findNode(t);if(!e)return null;this.saveState();const i=this.deepCloneNode(this.clipboard);return this.regenerateIds(i),e.addChild(i),i}deepCloneNode(t){const e=new b(t.id,t.topic,null,!1,t.image,t.layoutSide);return e.style={...t.style},e.children=t.children.map(i=>this.deepCloneNode(i)),e.children.forEach(i=>i.parentId=e.id),e}regenerateIds(t){t.id=typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():Date.now().toString(36)+Math.random().toString(36).substr(2),t.children.forEach(e=>{e.parentId=t.id,this.regenerateIds(e)})}exportData(){const t=e=>({id:e.id,topic:e.topic,root:e.isRoot||void 0,children:e.children.length>0?e.children.map(t):void 0,style:Object.keys(e.style).length>0?e.style:void 0,image:e.image,layoutSide:e.layoutSide});return{nodeData:t(this.mindMap.root),theme:this.mindMap.theme}}importData(t){const e=(i,s=null)=>{const n=!!i.root,r=new b(i.id,i.topic,s,n,i.image,i.layoutSide);return i.style&&(r.style={...i.style}),i.children&&i.children.length>0&&i.children.forEach(o=>{const a=e(o,r.id);r.addChild(a)}),r};this.mindMap.root=e(t.nodeData),t.theme&&(this.mindMap.theme=t.theme)}}const I=class I{constructor(t){c(this,"container");c(this,"svg");c(this,"nodeContainer");this.container=t,this.container.style.position="relative",this.container.style.width="100%",this.container.style.height="100%",this.container.style.overflow="hidden",this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.position="absolute",this.svg.style.top="0",this.svg.style.left="0",this.svg.style.width="100%",this.svg.style.height="100%",this.svg.style.zIndex="0",this.svg.style.pointerEvents="none",this.svg.style.overflow="visible",this.svg.style.transformOrigin="0 0",this.container.appendChild(this.svg),this.nodeContainer=document.createElement("div"),this.nodeContainer.style.position="absolute",this.nodeContainer.style.top="0",this.nodeContainer.style.left="0",this.nodeContainer.style.width="100%",this.nodeContainer.style.height="100%",this.nodeContainer.style.zIndex="1",this.nodeContainer.style.transformOrigin="0 0",this.container.appendChild(this.nodeContainer)}render(t,e=null,i="Right"){this.svg.innerHTML="",this.nodeContainer.innerHTML="",this.renderNode(t.root,0,this.container.clientHeight/2,e,i,!0,void 0,t)}updateTransform(t,e,i=1){const s=`translate(${t}px, ${e}px) scale(${i})`;this.svg.style.transform=s,this.nodeContainer.style.transform=s}getThemeColor(t,e){if(e.theme==="colorful"){if(t.isRoot)return"#333";let i=t;for(;i.parentId&&i.parentId!==e.root.id;){const r=e.findNode(i.parentId);if(!r)break;i=r}const n=e.root.children.findIndex(r=>r.id===i.id);if(n!==-1)return I.RAINBOW_PALETTE[n%I.RAINBOW_PALETTE.length]}return"#ccc"}renderNode(t,e,i,s,n,r,o="right",a){const d=document.createElement("div");if(d.dataset.id=t.id,t.image){const m=document.createElement("img");m.src=t.image,m.style.maxWidth="150px",m.style.maxHeight="150px",m.style.display="block",d.appendChild(m);const u=document.createElement("div");u.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line><line x1="11" y1="8" x2="11" y2="14"></line><line x1="8" y1="11" x2="14" y2="11"></line></svg>',u.style.position="absolute",u.style.bottom="5px",u.style.right="5px",u.style.backgroundColor="rgba(255, 255, 255, 0.9)",u.style.borderRadius="50%",u.style.width="24px",u.style.height="24px",u.style.display="flex",u.style.justifyContent="center",u.style.alignItems="center",u.style.cursor="pointer",u.title="Zoom Image",u.style.boxShadow="0 1px 3px rgba(0,0,0,0.2)",d.appendChild(u),u.addEventListener("click",x=>{x.stopPropagation(),this.showImageModal(t.image)}),d.style.padding="5px"}else d.textContent=t.topic,d.style.whiteSpace="pre";d.className="mindmap-node",t.isRoot||(d.draggable=!0),d.style.position="absolute",d.style.padding="8px 12px",t.image&&(d.style.padding="5px"),d.style.backgroundColor="white";const h=(a==null?void 0:a.theme)||"default",f=a?this.getThemeColor(t,a):"#ccc";h==="simple"&&!t.isRoot?d.style.border="none":h==="colorful"?d.style.border=`2px solid ${f}`:d.style.border="1px solid #ccc",d.style.borderRadius="4px",t.isRoot&&(d.style.fontSize="1.2em",d.style.fontWeight="bold",d.style.border="2px solid #333"),t.style.color&&(d.style.color=t.style.color),t.style.fontSize&&(d.style.fontSize=t.style.fontSize),t.style.fontWeight&&(d.style.fontWeight=t.style.fontWeight),t.style.fontStyle&&(d.style.fontStyle=t.style.fontStyle),t.style.background&&(d.style.backgroundColor=t.style.background);const{width:p}=this.measureNode(t);let l=e;if(o==="left"&&!r?l=e-p:r&&(l=e-p/2),d.style.left=`${l}px`,d.style.top=`${i}px`,d.style.transform="translate(0, -50%)",d.style.zIndex="10",d.style.cursor="default",d.style.userSelect="none",t.id===s&&(d.style.outline="2px solid #007bff",d.style.boxShadow="0 0 5px rgba(0, 123, 255, 0.5)"),this.nodeContainer.appendChild(d),t.children.length===0)return;let y=[],g=[];r&&n==="Both"?t.children.forEach((m,u)=>{(m.layoutSide||(u%2===0?"right":"left"))==="right"?y.push(m):g.push(m)}):n==="Left"?g=t.children:n==="Right"?y=t.children:o==="left"?g=t.children:y=t.children,y.length>0&&this.renderChildrenStack(t,y,e,i,s,n,"right",p,a),g.length>0&&this.renderChildrenStack(t,g,e,i,s,n,"left",p,a)}renderChildrenStack(t,e,i,s,n,r,o,a,d){const h=e.reduce((y,g)=>y+this.getNodeHeight(g),0);let f=s-h/2;const p=80;let l=0;t.isRoot?l=o==="right"?i+a/2:i-a/2:o==="right"?l=i+a:(l=i,l=i-a),e.forEach(y=>{const g=this.getNodeHeight(y),m=f+g/2;let u=0;o==="right"?u=l+p:u=l-p,this.renderNode(y,u,m,n,r,!1,o,d);const x=d?this.getThemeColor(y,d):"#ccc";this.drawConnection(l,s,u,m,x),f+=g})}getChildrenHeight(t){return t.children.reduce((e,i)=>e+this.getNodeHeight(i),0)}getNodeHeight(t){const{height:e}=this.measureNode(t),i=20;if(t.children.length===0)return e+i;const s=this.getChildrenHeight(t);return Math.max(e+i,s)}measureNode(t){if(t.image)return{width:160,height:160};const e=document.createElement("div");e.textContent=t.topic,e.className="mindmap-node",e.style.visibility="hidden",e.style.position="absolute",e.style.whiteSpace="pre",e.style.padding="8px 12px",e.style.border="1px solid #ccc",t.isRoot&&(e.style.fontSize="1.2em",e.style.fontWeight="bold",e.style.border="2px solid #333"),t.style.color&&(e.style.color=t.style.color),t.style.fontSize&&(e.style.fontSize=t.style.fontSize),t.style.fontWeight&&(e.style.fontWeight=t.style.fontWeight),t.style.fontStyle&&(e.style.fontStyle=t.style.fontStyle),t.style.background&&(e.style.backgroundColor=t.style.background),this.nodeContainer.appendChild(e);const i=e.offsetWidth,s=e.offsetHeight;return this.nodeContainer.removeChild(e),{width:i||100,height:s||40}}drawConnection(t,e,i,s,n="#ccc"){const r=document.createElementNS("http://www.w3.org/2000/svg","path"),o=t+(i-t)/2,a=t+(i-t)/2,d=`M ${t} ${e} C ${o} ${e}, ${a} ${s}, ${i} ${s}`;r.setAttribute("d",d),r.setAttribute("stroke",n),r.setAttribute("fill","none"),r.setAttribute("stroke-width","2"),this.svg.appendChild(r)}showImageModal(t){const e=document.createElement("div");e.style.position="fixed",e.style.top="0",e.style.left="0",e.style.width="100vw",e.style.height="100vh",e.style.backgroundColor="rgba(0,0,0,0.8)",e.style.zIndex="1000",e.style.display="flex",e.style.justifyContent="center",e.style.alignItems="center",e.style.cursor="zoom-out";const i=document.createElement("img");i.src=t,i.style.maxWidth="90%",i.style.maxHeight="90%",i.style.boxShadow="0 0 20px rgba(0,0,0,0.5)",e.appendChild(i),document.body.appendChild(e),e.addEventListener("click",()=>{document.body.removeChild(e)})}};c(I,"RAINBOW_PALETTE",["#E74C3C","#3498DB","#2ECC71","#F1C40F","#9B59B6","#E67E22","#1ABC9C"]);let E=I;const C=class C{constructor(t){c(this,"container");c(this,"editorEl");c(this,"currentNodeId",null);c(this,"onUpdate");this.container=t,this.editorEl=this.createEditor(),this.container.appendChild(this.editorEl),this.editorEl.addEventListener("mousedown",e=>e.stopPropagation()),this.editorEl.addEventListener("click",e=>e.stopPropagation()),this.editorEl.addEventListener("dblclick",e=>e.stopPropagation())}createEditor(){const t=document.createElement("div");t.className="style-editor",t.style.position="absolute",t.style.top="20px",t.style.right="20px",t.style.display="none",t.style.backgroundColor="white",t.style.border="1px solid #eee",t.style.borderRadius="8px",t.style.padding="8px",t.style.boxShadow="0 4px 12px rgba(0,0,0,0.1)",t.style.zIndex="2000",t.style.pointerEvents="auto",t.style.fontFamily="Arial, sans-serif",t.style.display="flex",t.style.flexDirection="column",t.style.gap="8px",t.style.margin="0",t.style.boxSizing="border-box",t.style.minWidth="220px";const e=document.createElement("div");e.style.display="flex",e.style.gap="8px",e.style.alignItems="center";const i=document.createElement("select");i.style.padding="4px 8px",i.style.borderRadius="4px",i.style.border="1px solid #ccc",i.style.fontSize="14px",i.style.flex="1",C.FONT_SIZES.forEach(h=>{const f=document.createElement("option");f.value=h.value,f.textContent=h.label,i.appendChild(f)}),i.onchange=h=>{this.currentNodeId&&this.onUpdate&&this.onUpdate(this.currentNodeId,{fontSize:h.target.value})},e.appendChild(i);const n=(h,f,p)=>{const l=document.createElement("button");return l.textContent=h,l.style.width="32px",l.style.height="32px",l.style.padding="0",l.style.display="flex",l.style.justifyContent="center",l.style.alignItems="center",l.style.border="1px solid #ddd",l.style.backgroundColor="#f5f5f5",l.style.borderRadius="4px",l.style.cursor="pointer",l.style.fontSize="14px",f&&(l.style[f]=f==="fontWeight"?"bold":"italic"),l.onclick=p,l},r=n("B","fontWeight",()=>{if(this.currentNodeId&&this.onUpdate){const h=r.classList.contains("active"),f=h?"normal":"bold";this.onUpdate(this.currentNodeId,{fontWeight:f}),this.updateButtonState(r,!h)}}),o=n("I","fontStyle",()=>{if(this.currentNodeId&&this.onUpdate){const h=o.classList.contains("active"),f=h?"normal":"italic";this.onUpdate(this.currentNodeId,{fontStyle:f}),this.updateButtonState(o,!h)}});e.appendChild(r),e.appendChild(o),t.appendChild(e);const a=document.createElement("div");a.style.display="flex",a.style.gap="4px",a.style.alignItems="center",a.style.justifyContent="space-between";const d=document.createElement("input");return d.type="color",d.style.width="24px",d.style.height="24px",d.style.border="1px solid #ccc",d.style.padding="0",d.style.backgroundColor="transparent",d.style.cursor="pointer",d.style.appearance="none",d.onchange=h=>{this.currentNodeId&&this.onUpdate&&(this.onUpdate(this.currentNodeId,{color:h.target.value}),this.updateActivePaletteItem(h.target.value))},C.PALETTE.forEach((h,f)=>{const p=document.createElement("div");p.className="color-swatch",p.dataset.color=h,p.textContent=(f+1).toString(),p.style.width="24px",p.style.height="24px",p.style.backgroundColor=h,p.style.borderRadius="4px",p.style.cursor="pointer",p.style.border="1px solid transparent",p.style.color=h==="#F1C40F"?"black":"white",p.style.fontSize="12px",p.style.fontWeight="bold",p.style.display="flex",p.style.justifyContent="center",p.style.alignItems="center",p.onclick=()=>{this.currentNodeId&&this.onUpdate&&(this.onUpdate(this.currentNodeId,{color:h}),d.value=h,this.updateActivePaletteItem(h))},a.appendChild(p)}),a.appendChild(d),t.appendChild(a),t}updateActivePaletteItem(t){this.editorEl.querySelectorAll(".color-swatch").forEach(i=>{var n;const s=i;((n=s.dataset.color)==null?void 0:n.toLowerCase())===t.toLowerCase()?(s.style.border="2px solid #ccc",s.style.transform="scale(1.1)"):(s.style.border="1px solid transparent",s.style.transform="scale(1)")})}updateButtonState(t,e){e?(t.classList.add("active"),t.style.backgroundColor="#e0e0e0",t.style.borderColor="#999"):(t.classList.remove("active"),t.style.backgroundColor="#f5f5f5",t.style.borderColor="#ddd")}show(t,e){this.currentNodeId=t,this.editorEl.style.display="flex";const i=this.editorEl.querySelector("select");i.value=e.fontSize||"";const s=this.editorEl.querySelector('input[type="color"]'),n=e.color||"#000000";s.value=n,this.updateActivePaletteItem(n);const r=this.editorEl.querySelectorAll("button")[0];this.updateButtonState(r,e.fontWeight==="bold");const o=this.editorEl.querySelectorAll("button")[1];this.updateButtonState(o,e.fontStyle==="italic")}hide(){this.editorEl.style.display="none",this.currentNodeId=null}};c(C,"FONT_SIZES",[{label:"12px",value:"12px"},{label:"14px",value:"14px"},{label:"16px",value:"16px"},{label:"18px",value:"18px"},{label:"24px",value:"24px"},{label:"32px",value:"32px"},{label:"48px",value:"48px"}]),c(C,"PALETTE",["#000000","#E74C3C","#E67E22","#F1C40F","#2ECC71","#3498DB","#9B59B6"]);let w=C;class q{constructor(t,e){c(this,"container");c(this,"element");c(this,"options");c(this,"currentMode","Right");c(this,"currentTheme","default");c(this,"layoutButtons",new Map);c(this,"themeButtons",new Map);this.container=t,this.options=e,this.element=document.createElement("div"),this.render()}render(){this.element.style.position="absolute",this.element.style.top="20px",this.element.style.left="20px",this.element.style.display="flex",this.element.style.flexDirection="column",this.element.style.backgroundColor="white",this.element.style.borderRadius="8px",this.element.style.boxShadow="0 2px 10px rgba(0,0,0,0.1)",this.element.style.padding="5px",this.element.style.zIndex="2000",this.element.style.gap="5px",this.element.style.pointerEvents="auto",this.element.addEventListener("click",t=>t.stopPropagation()),this.element.addEventListener("mousedown",t=>t.stopPropagation()),this.createLayoutButton("Right",this.getRightIcon()),this.createLayoutButton("Left",this.getLeftIcon()),this.createLayoutButton("Both",this.getBothIcon()),this.addSeparator(),this.createThemeButton("default",this.getThemeDefaultIcon()),this.createThemeButton("simple",this.getThemeSimpleIcon()),this.createThemeButton("colorful",this.getThemeColorfulIcon()),this.addSeparator(),this.createIconActionButton("Reset Zoom",this.getZoomResetIcon(),()=>{this.options.onZoomReset&&this.options.onZoomReset()}),this.container.appendChild(this.element),this.updateActiveButtons()}addSeparator(){const t=document.createElement("div");t.style.height="1px",t.style.backgroundColor="#ccc",t.style.margin="5px 2px",this.element.appendChild(t)}createLayoutButton(t,e){const i=document.createElement("button");i.innerHTML=e,this.styleButton(i),i.title=`Layout: ${t}`,i.addEventListener("click",()=>{this.setMode(t)}),this.element.appendChild(i),this.layoutButtons.set(t,i)}createThemeButton(t,e){const i=document.createElement("button");i.innerHTML=e,this.styleButton(i),i.title=`Theme: ${t}`,i.addEventListener("click",()=>{this.setTheme(t)}),this.element.appendChild(i),this.themeButtons.set(t,i)}createIconActionButton(t,e,i){const s=document.createElement("button");s.innerHTML=e,this.styleButton(s),s.title=t,s.addEventListener("click",i),this.element.appendChild(s)}styleButton(t){t.style.width="32px",t.style.height="32px",t.style.border="none",t.style.background="transparent",t.style.cursor="pointer",t.style.borderRadius="4px",t.style.display="flex",t.style.alignItems="center",t.style.justifyContent="center",t.style.color="#555"}updateActiveButtons(){this.layoutButtons.forEach((t,e)=>{e===this.currentMode?(t.style.backgroundColor="#e6f7ff",t.style.color="#007bff"):(t.style.backgroundColor="transparent",t.style.color="#555")}),this.themeButtons.forEach((t,e)=>{e===this.currentTheme?(t.style.backgroundColor="#e6f7ff",t.style.color="#007bff"):(t.style.backgroundColor="transparent",t.style.color="#555")})}setMode(t){this.currentMode!==t&&(this.currentMode=t,this.updateActiveButtons(),this.options.onLayoutChange(t))}setTheme(t){this.currentTheme!==t&&(this.currentTheme=t,this.updateActiveButtons(),this.options.onThemeChange(t))}getRightIcon(){return`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
2
|
+
<circle cx="5" cy="12" r="3"></circle>
|
|
3
|
+
<path d="M8 12h8"></path>
|
|
4
|
+
<path d="M8 12 L16 5"></path>
|
|
5
|
+
<path d="M8 12 L16 19"></path>
|
|
6
|
+
<circle cx="19" cy="5" r="2"></circle>
|
|
7
|
+
<circle cx="19" cy="12" r="2"></circle>
|
|
8
|
+
<circle cx="19" cy="19" r="2"></circle>
|
|
9
|
+
</svg>`}getLeftIcon(){return`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
10
|
+
<circle cx="19" cy="12" r="3"></circle>
|
|
11
|
+
<path d="M16 12h-8"></path>
|
|
12
|
+
<path d="M16 12 L8 5"></path>
|
|
13
|
+
<path d="M16 12 L8 19"></path>
|
|
14
|
+
<circle cx="5" cy="5" r="2"></circle>
|
|
15
|
+
<circle cx="5" cy="12" r="2"></circle>
|
|
16
|
+
<circle cx="5" cy="19" r="2"></circle>
|
|
17
|
+
</svg>`}getBothIcon(){return'<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M12 9V5"></path><circle cx="12" cy="2" r="2"></circle><path d="M12 15v4"></path><circle cx="12" cy="22" r="2"></circle><path d="M9 12H5"></path><circle cx="2" cy="12" r="2"></circle><path d="M15 12h4"></path><circle cx="22" cy="12" r="2"></circle></svg>'}getThemeDefaultIcon(){return`<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
18
|
+
<rect x="3" y="3" width="18" height="18" rx="4" ry="4" top="3" />
|
|
19
|
+
<line x1="8" y1="12" x2="16" y2="12" />
|
|
20
|
+
</svg>`}getThemeSimpleIcon(){return`<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
21
|
+
<line x1="4" y1="6" x2="20" y2="6" />
|
|
22
|
+
<line x1="4" y1="12" x2="20" y2="12" />
|
|
23
|
+
<line x1="4" y1="18" x2="20" y2="18" />
|
|
24
|
+
</svg>`}getThemeColorfulIcon(){return`<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
25
|
+
<path d="M12 2C6.477 2 2 6.477 2 12c0 4.418 2.865 8.167 6.839 9.49.5.166.86-.2.86-.677v-.36c0-.46.38-.853.84-.853h1.76c1.93 0 3.5-1.57 3.5-3.5 0-.54.42-1 .99-1h.26c2.6 0 4.75-1.95 4.94-4.5C22.25 6.7 17.65 2 12 2z" />
|
|
26
|
+
<circle cx="7.5" cy="8.5" r="1.5" fill="currentColor" stroke="none" />
|
|
27
|
+
<circle cx="12.5" cy="6.5" r="1.5" fill="currentColor" stroke="none" />
|
|
28
|
+
<circle cx="16.5" cy="9.5" r="1.5" fill="currentColor" stroke="none" />
|
|
29
|
+
</svg>`}getZoomResetIcon(){return`<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
30
|
+
<circle cx="11" cy="11" r="8"></circle>
|
|
31
|
+
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
|
32
|
+
<line x1="5" y1="5" x2="17" y2="17"></line>
|
|
33
|
+
<line x1="17" y1="5" x2="5" y2="17"></line>
|
|
34
|
+
</svg>`}}class _{constructor(t,e){c(this,"container");c(this,"options");c(this,"selectedNodeId",null);c(this,"draggedNodeId",null);c(this,"isPanning",!1);c(this,"lastMouseX",0);c(this,"lastMouseY",0);c(this,"isReadOnly",!1);c(this,"cleanupFns",[]);this.container=t,this.container.tabIndex=0,this.container.style.outline="none",this.container.style.cursor="default",this.options=e,this.attachEvents()}setReadOnly(t){this.isReadOnly=t,t&&this.draggedNodeId&&(this.draggedNodeId=null)}destroy(){this.cleanupFns.forEach(t=>t()),this.cleanupFns=[]}updateSelection(t){this.selectedNodeId=t}attachEvents(){let t=null;const e=(r,o,a,d)=>{r.addEventListener(o,a,d),this.cleanupFns.push(()=>{typeof r.removeEventListener=="function"&&r.removeEventListener(o,a,d)})};e(this.container,"focus",()=>{}),e(this.container,"blur",()=>{}),e(this.container,"scroll",()=>{(this.container.scrollTop!==0||this.container.scrollLeft!==0)&&(this.container.scrollTop=0,this.container.scrollLeft=0)}),e(this.container,"click",r=>{const a=r.target.closest(".mindmap-node");a&&a.dataset.id?this.options.onNodeClick(a.dataset.id):this.options.onNodeClick(""),this.container.focus()}),e(this.container,"mousedown",r=>{const o=r,a=o.target;!a.closest(".mindmap-node")&&a.tagName!=="INPUT"&&(this.isPanning=!0,this.lastMouseX=o.clientX,this.lastMouseY=o.clientY,this.container.style.cursor="all-scroll")}),e(window,"mousemove",r=>{const o=r;if(this.isPanning){const a=o.clientX-this.lastMouseX,d=o.clientY-this.lastMouseY;this.lastMouseX=o.clientX,this.lastMouseY=o.clientY,this.options.onPan&&this.options.onPan(a,d)}});const i=()=>{this.isPanning&&(this.isPanning=!1,this.container.style.cursor="default")};e(window,"mouseup",i),e(window,"mouseleave",i),e(this.container,"wheel",r=>{const o=r;if(o.preventDefault(),o.ctrlKey||o.metaKey){this.options.onZoom&&this.options.onZoom(o.deltaY,o.clientX,o.clientY);return}let a=1;o.deltaMode===1?a=33:o.deltaMode===2&&(a=window.innerHeight);const d=-o.deltaX*a,h=-o.deltaY*a;this.options.onPan&&this.options.onPan(d,h)},{passive:!1}),e(document,"keydown",r=>{var h,f,p,l,y,g,m,u,x,S,M,k,R,T,L,B,D,P,A,O,z,U,X,Y,H,K;const o=r;if(!this.selectedNodeId||this.isReadOnly&&!["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","h","j","k","l","c"].includes(o.key))return;const a=["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","h","j","k","l"];switch((["Tab","Enter","Delete","Backspace"].includes(o.key)||a.includes(o.key))&&o.preventDefault(),o.key){case"Tab":if(this.isReadOnly)return;o.shiftKey?(f=(h=this.options).onInsertParent)==null||f.call(h,this.selectedNodeId):this.options.onAddChild(this.selectedNodeId);break;case"Enter":if(this.isReadOnly)return;this.options.onAddSibling(this.selectedNodeId,o.shiftKey?"before":"after");break;case"Delete":case"Backspace":if(this.isReadOnly)return;this.options.onDeleteNode(this.selectedNodeId);break;case"ArrowUp":case"k":(this.isReadOnly||!o.ctrlKey&&!o.metaKey&&!o.altKey)&&((l=(p=this.options).onNavigate)==null||l.call(p,this.selectedNodeId,"Up"));break;case"ArrowDown":case"j":(this.isReadOnly||!o.ctrlKey&&!o.metaKey&&!o.altKey)&&((g=(y=this.options).onNavigate)==null||g.call(y,this.selectedNodeId,"Down"));break;case"ArrowLeft":case"h":(this.isReadOnly||!o.ctrlKey&&!o.metaKey&&!o.altKey)&&((u=(m=this.options).onNavigate)==null||u.call(m,this.selectedNodeId,"Left"));break;case"ArrowRight":case"l":(this.isReadOnly||!o.ctrlKey&&!o.metaKey&&!o.altKey)&&((S=(x=this.options).onNavigate)==null||S.call(x,this.selectedNodeId,"Right"));break;case"F2":{if(this.isReadOnly)return;o.preventDefault();const v=this.container.querySelector(`.mindmap-node[data-id="${this.selectedNodeId}"]`);v&&this.startEditing(v,this.selectedNodeId);break}case"c":(o.metaKey||o.ctrlKey)&&(o.preventDefault(),(k=(M=this.options).onCopyNode)==null||k.call(M,this.selectedNodeId));break;case"v":if(this.isReadOnly)return;(o.metaKey||o.ctrlKey)&&(t&&clearTimeout(t),t=setTimeout(()=>{var v,F;this.selectedNodeId&&((F=(v=this.options).onPasteNode)==null||F.call(v,this.selectedNodeId))},50));break;case"x":if(this.isReadOnly)return;(o.metaKey||o.ctrlKey)&&(o.preventDefault(),(T=(R=this.options).onCutNode)==null||T.call(R,this.selectedNodeId));break;case"z":if(this.isReadOnly)return;(o.metaKey||o.ctrlKey)&&(o.preventDefault(),o.shiftKey||(B=(L=this.options).onUndo)==null||B.call(L));break;case"b":if(this.isReadOnly)return;(o.metaKey||o.ctrlKey)&&(o.preventDefault(),(P=(D=this.options).onStyleAction)==null||P.call(D,this.selectedNodeId,{type:"bold"}));break;case"i":{if(this.isReadOnly)return;if(o.metaKey||o.ctrlKey)o.preventDefault(),(O=(A=this.options).onStyleAction)==null||O.call(A,this.selectedNodeId,{type:"italic"});else{o.preventDefault();const v=this.container.querySelector(`.mindmap-node[data-id="${this.selectedNodeId}"]`);v&&this.startEditing(v,this.selectedNodeId)}break}case"+":case"=":if(this.isReadOnly)return;(o.key==="+"||o.key==="="&&o.shiftKey)&&((U=(z=this.options).onStyleAction)==null||U.call(z,this.selectedNodeId,{type:"increaseSize"}));break;case"-":if(this.isReadOnly)return;(Y=(X=this.options).onStyleAction)==null||Y.call(X,this.selectedNodeId,{type:"decreaseSize"});break}if(/^[1-7]$/.test(o.key)){if(this.isReadOnly)return;if(!o.ctrlKey&&!o.metaKey&&!o.altKey){const v=parseInt(o.key)-1;(K=(H=this.options).onStyleAction)==null||K.call(H,this.selectedNodeId,{type:"color",index:v})}}}),e(document,"paste",r=>{var h,f,p,l,y;const o=r;if(t&&(clearTimeout(t),t=null),this.isReadOnly||!this.selectedNodeId)return;const a=(h=o.clipboardData)==null?void 0:h.items;if(!a||a.length===0){(p=(f=this.options).onPasteNode)==null||p.call(f,this.selectedNodeId);return}let d=!1;for(const g of a)if(g.type.startsWith("image/")){const m=g.getAsFile();if(m){const u=new FileReader;u.onload=x=>{var S;(S=x.target)!=null&&S.result&&this.options.onPasteImage&&this.selectedNodeId&&this.options.onPasteImage(this.selectedNodeId,x.target.result)},u.readAsDataURL(m)}o.preventDefault(),d=!0;break}d||(y=(l=this.options).onPasteNode)==null||y.call(l,this.selectedNodeId)});const s=document.createElement("style");s.textContent=`
|
|
35
|
+
.mindmap-node.drag-over-top {
|
|
36
|
+
border-top: 4px solid #007bff !important;
|
|
37
|
+
}
|
|
38
|
+
.mindmap-node.drag-over-bottom {
|
|
39
|
+
border-bottom: 4px solid #007bff !important;
|
|
40
|
+
}
|
|
41
|
+
.mindmap-node.drag-over-left {
|
|
42
|
+
border-left: 4px solid #007bff !important;
|
|
43
|
+
}
|
|
44
|
+
.mindmap-node.drag-over-right {
|
|
45
|
+
border-right: 4px solid #007bff !important;
|
|
46
|
+
}
|
|
47
|
+
`,document.head.appendChild(s),this.container.addEventListener("dragstart",r=>{var d;if(this.isReadOnly){r.preventDefault();return}const a=r.target.closest(".mindmap-node");a&&a.dataset.id&&(this.draggedNodeId=a.dataset.id,(d=r.dataTransfer)==null||d.setData("text/plain",a.dataset.id),r.dataTransfer&&(r.dataTransfer.effectAllowed="move"))}),this.cleanupFns.push(()=>{});const n=(r,o)=>{const a=o.getBoundingClientRect(),d=r.clientX-a.left,h=r.clientY-a.top,f=a.width,p=a.height;return h<p*.25?"top":h>p*.75?"bottom":d<f*.25?"left":(d>f*.75,"right")};e(this.container,"dragstart",r=>{var h;const o=r;if(this.isReadOnly){o.preventDefault();return}const d=o.target.closest(".mindmap-node");d&&d.dataset.id&&(this.draggedNodeId=d.dataset.id,(h=o.dataTransfer)==null||h.setData("text/plain",d.dataset.id),o.dataTransfer&&(o.dataTransfer.effectAllowed="move"))}),e(this.container,"dragover",r=>{const o=r;if(this.isReadOnly)return;o.preventDefault();const d=o.target.closest(".mindmap-node");if(d&&d.dataset.id&&this.draggedNodeId&&d.dataset.id!==this.draggedNodeId){const h=n(o,d);d.classList.remove("drag-over-top","drag-over-bottom","drag-over-left","drag-over-right"),d.classList.add(`drag-over-${h}`),o.dataTransfer&&(o.dataTransfer.dropEffect="move")}}),e(this.container,"dragleave",r=>{const a=r.target.closest(".mindmap-node");a&&a.classList.remove("drag-over-top","drag-over-bottom","drag-over-left","drag-over-right")}),e(this.container,"drop",r=>{const o=r;o.preventDefault();const d=o.target.closest(".mindmap-node");if(this.container.querySelectorAll(".mindmap-node").forEach(h=>{h.classList.remove("drag-over-top","drag-over-bottom","drag-over-left","drag-over-right")}),!this.isReadOnly){if(d&&d.dataset.id&&this.draggedNodeId){const h=d.dataset.id;if(this.draggedNodeId!==h){const f=n(o,d);this.options.onDropNode(this.draggedNodeId,h,f)}}this.draggedNodeId=null}}),e(this.container,"dragend",()=>{this.draggedNodeId=null,this.container.querySelectorAll(".mindmap-node").forEach(r=>{r.classList.remove("drag-over-top","drag-over-bottom","drag-over-left","drag-over-right")})}),e(this.container,"dblclick",r=>{if(this.isReadOnly)return;const a=r.target.closest(".mindmap-node");a&&a.dataset.id&&this.startEditing(a,a.dataset.id)})}editNode(t){const e=this.container.querySelector(`.mindmap-node[data-id="${t}"]`);e&&this.startEditing(e,t)}startEditing(t,e){const i=t.textContent||"",s=document.createElement("textarea");s.value=i,s.style.position="absolute",s.style.top=t.style.top,s.style.left=t.style.left,s.style.transform=t.style.transform,s.style.overflow="hidden",s.style.resize="none",s.style.minHeight="1em";const n=window.getComputedStyle(t);s.style.font=n.font,s.style.padding=n.padding,s.style.boxSizing="border-box",s.style.backgroundColor=n.backgroundColor,s.style.border="none",s.style.outline="none",s.style.boxShadow="none",s.style.borderTop=n.borderTop,s.style.borderRight=n.borderRight,s.style.borderBottom=n.borderBottom,s.style.borderLeft=n.borderLeft,s.style.borderRadius=n.borderRadius,s.style.zIndex="100";const r=t.style.outline,o=t.style.boxShadow;t.style.outline="none",t.style.boxShadow="none";const a=()=>{const l=document.createElement("span");l.style.font=n.font,l.style.padding=n.padding,l.style.whiteSpace="pre-wrap",l.style.visibility="hidden",l.style.position="absolute",l.textContent=s.value||"",(s.value.endsWith(`
|
|
48
|
+
`)||s.value==="")&&(l.textContent+=""),document.body.appendChild(l);const y=l.offsetWidth+20,g=l.offsetHeight+10;s.style.width=Math.max(y,t.offsetWidth)+"px",s.style.height=Math.max(g,t.offsetHeight)+"px",document.body.removeChild(l)};a(),s.addEventListener("input",a);let d=!1;const h=()=>{s.parentNode&&s.parentNode.contains(s)&&s.parentNode.removeChild(s),t.style.outline=r,t.style.boxShadow=o},f=()=>{if(d)return;d=!0;const l=s.value;l!==i&&this.options.onUpdateNode&&this.options.onUpdateNode(e,l),h()};s.addEventListener("blur",()=>{d||f()});const p=()=>{d||(d=!0,h())};s.addEventListener("keydown",l=>{if(l.stopPropagation(),!l.isComposing)if(l.key==="Enter"){if(l.shiftKey)return;l.preventDefault(),f()}else l.key==="Escape"&&(l.preventDefault(),p())}),t.parentElement?t.parentElement.appendChild(s):this.container.appendChild(s),s.focus({preventScroll:!0}),s.select()}}class G{constructor(){c(this,"listeners",{})}on(t,e){var i;this.listeners[t]||(this.listeners[t]=[]),(i=this.listeners[t])==null||i.push(e)}addListener(t,e){this.on(t,e)}off(t,e){const i=this.listeners[t];i&&(this.listeners[t]=i.filter(s=>s!==e))}removeListener(t,e){this.off(t,e)}emit(t,e){var i;(i=this.listeners[t])==null||i.forEach(s=>s(e))}}class J extends G{constructor(e){super();c(this,"mindMap");c(this,"service");c(this,"renderer");c(this,"interactionHandler");c(this,"styleEditor");c(this,"layoutSwitcher");c(this,"layoutMode","Right");c(this,"selectedNodeId",null);c(this,"panX",0);c(this,"panY",0);c(this,"targetPanX",0);c(this,"targetPanY",0);c(this,"scale",1);c(this,"isBatching",!1);c(this,"animationFrameId",null);const i=new b("root","Root Topic",null,!0);this.mindMap=new j(i),this.service=new V(this.mindMap),this.renderer=new E(e);const s=document.createElement("div");s.style.position="absolute",s.style.top="0",s.style.left="0",s.style.width="100%",s.style.height="100%",s.style.pointerEvents="none",s.style.zIndex="2000",e.style.overscrollBehavior="none",e.style.touchAction="none",e.appendChild(s),this.styleEditor=new w(s),this.styleEditor.onUpdate=(n,r)=>{this.interactionHandler.isReadOnly||this.service.updateNodeStyle(n,r)&&(this.render(),this.emit("model:change",void 0))},this.panX=e.clientWidth/2,this.targetPanX=this.panX,this.targetPanY=this.panY,this.layoutSwitcher=new q(s,{onLayoutChange:n=>this.setLayoutMode(n),onThemeChange:n=>this.setTheme(n),onZoomReset:()=>this.resetZoom()}),this.startAnimationLoop(),this.interactionHandler=new _(e,{onNodeClick:n=>this.selectNode(n||null),onAddChild:n=>this.addChildNode(n),onInsertParent:n=>this.insertParentNode(n),onAddSibling:(n,r)=>this.addSiblingNode(n,r),onDeleteNode:n=>this.removeNode(n),onDropNode:(n,r,o)=>this.moveNode(n,r,o),onUpdateNode:(n,r)=>this.updateNodeTopic(n,r),onNavigate:(n,r)=>this.navigateNode(n,r),onPan:(n,r)=>this.panBoard(n,r),onCopyNode:n=>this.copyNode(n),onPasteNode:n=>this.pasteNode(n),onCutNode:n=>this.cutNode(n),onPasteImage:(n,r)=>this.pasteImage(n,r),onZoom:(n,r,o)=>this.zoomBoard(n,r,o),onUndo:()=>{this.service.undo()&&(this.render(),this.emit("model:change",void 0))},onStyleAction:(n,r)=>{if(this.interactionHandler.isReadOnly)return;const o=this.mindMap.findNode(n);if(!o)return;const a=o.style||{};let d=null;if(r.type==="bold")d={fontWeight:a.fontWeight==="bold"?"normal":"bold"};else if(r.type==="italic")d={fontStyle:a.fontStyle==="italic"?"normal":"italic"};else if(r.type==="color")r.index>=0&&r.index<w.PALETTE.length&&(d={color:w.PALETTE[r.index]});else if(r.type==="increaseSize"||r.type==="decreaseSize"){const h=w.FONT_SIZES,f=a.fontSize||"";let p=h.findIndex(y=>y.value===f);p===-1&&(p=0);let l=p;r.type==="increaseSize"?l=Math.min(h.length-1,p+1):l=Math.max(0,p-1),l!==p&&(d={fontSize:h[l].value})}d&&this.service.updateNodeStyle(n,d)&&(this.render(),this.emit("model:change",void 0),this.selectedNodeId===n&&this.styleEditor.show(n,{...a,...d}))}}),this.render()}addNode(e,i,s){const n=this.service.addNode(e,i,s);return n&&(this.render(),this.emit("node:add",{id:n.id,topic:n.topic}),this.emit("model:change",void 0)),n}addSibling(e,i="after",s="New Sibling"){const n=this.mindMap.findNode(e);if(!n||!n.parentId)return null;const r=this.mindMap.findNode(n.parentId);r&&r.isRoot&&this.layoutMode==="Both"&&this.ensureExplicitLayoutSides(r);const o=this.service.addSibling(e,i,s);if(o){if(r&&r.isRoot&&this.layoutMode==="Both"){const a=n.layoutSide||(r.children.indexOf(n)%2===0?"right":"left");o.layoutSide=a}this.render(),this.emit("node:add",{id:o.id,topic:o.topic}),this.emit("model:change",void 0)}return o}insertParent(e,i="New Parent"){const s=this.service.insertParent(e,i);return s&&(this.render(),this.emit("node:add",{id:s.id,topic:s.topic}),this.emit("model:change",void 0)),s}deleteNode(e){this.service.removeNode(e)&&(this.render(),this.emit("node:remove",e),this.emit("model:change",void 0))}updateNode(e,i){let s=!1;this.interactionHandler.isReadOnly||(i.topic!==void 0&&this.service.updateNodeTopic(e,i.topic)&&(s=!0),i.style!==void 0&&this.service.updateNodeStyle(e,i.style)&&(s=!0),s&&(this.render(),i.topic!==void 0&&this.emit("node:update",{id:e,topic:i.topic}),this.emit("model:change",void 0)))}updateNodeStyle(e,i){this.service.updateNodeStyle(e,i)}setTheme(e){this.service.setTheme(e),this.layoutSwitcher.setTheme(e),this.render(),this.emit("model:change",void 0)}getMindMap(){return this.mindMap}getNode(e){return this.mindMap.findNode(e)||void 0}getRoot(){return this.mindMap.root}findNodes(e){const i=[],s=n=>{e(n)&&i.push(n),n.children.forEach(s)};return s(this.mindMap.root),i}setReadOnly(e){this.interactionHandler.setReadOnly(e),e&&(this.styleEditor.hide(),this.selectNode(null))}destroy(){this.animationFrameId!==null&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.interactionHandler.destroy(),this.renderer.container}batch(e){this.isBatching=!0;try{e()}finally{this.isBatching=!1,this.render()}}addChildNode(e){const i=this.mindMap.findNode(e);i&&i.isRoot&&this.layoutMode==="Both"&&this.ensureExplicitLayoutSides(i);let s;if(this.layoutMode==="Both"&&i&&i.isRoot){let r=0,o=0;i.children.forEach((a,d)=>{(a.layoutSide||(d%2===0?"right":"left"))==="left"?r++:o++}),s=r<o?"left":"right"}const n=this.addNode(e,"New Child",s);n&&(this.selectNode(n.id),this.ensureNodeVisible(n.id),this.interactionHandler.editNode(n.id))}addSiblingNode(e,i="after"){const s=this.addSibling(e,i,"New Sibling");s&&(this.selectNode(s.id),this.ensureNodeVisible(s.id),this.interactionHandler.editNode(s.id))}insertParentNode(e){const i=this.insertParent(e,"New Parent");i&&(this.selectNode(i.id),this.ensureNodeVisible(i.id),this.interactionHandler.editNode(i.id))}removeNode(e){const i=this.mindMap.findNode(e),s=(i==null?void 0:i.parentId)||null,n=this.selectedNodeId===e;this.deleteNode(e),n&&s&&this.selectNode(s)}ensureExplicitLayoutSides(e){!e.isRoot||this.layoutMode!=="Both"||e.children.forEach((i,s)=>{i.layoutSide||(i.layoutSide=s%2===0?"right":"left")})}moveNode(e,i,s){const n=this.mindMap.findNode(i);if(n){if(s==="top"){if(n.isRoot)return;this.service.reorderNode(e,i,"before")}else if(s==="bottom"){if(n.isRoot)return;this.service.reorderNode(e,i,"after")}else if(n.isRoot){const r=s==="left"?"left":"right";this.service.moveNode(e,i,r)}else{const r=this.getNodeDirection(n);let o="addChild";r==="right"?s==="right"?o="addChild":o="insertParent":s==="left"?o="addChild":o="insertParent",o==="addChild"?this.service.moveNode(e,i):this.service.insertNodeAsParent(e,i)}this.render(),this.emit("node:move",{nodeId:e,newParentId:i,position:s}),this.emit("model:change",void 0)}}updateNodeTopic(e,i){this.updateNode(e,{topic:i}),setTimeout(()=>this.ensureNodeVisible(e),0)}selectNode(e){if(this.selectedNodeId!==e){if(this.selectedNodeId=e,this.interactionHandler.updateSelection(e),e){const i=this.mindMap.findNode(e);i&&(!i.image&&!this.interactionHandler.isReadOnly?this.styleEditor.show(e,i.style):this.styleEditor.hide())}else this.styleEditor.hide();this.render(),this.emit("node:select",e)}}panBoard(e,i){this.targetPanX+=e,this.targetPanY+=i}zoomBoard(e,i,s){const a=this.renderer.container.getBoundingClientRect(),d=i-a.left,h=s-a.top,f=Math.min(Math.max(this.scale*(1-e*.001),.1),5),p=d-(d-this.panX)*(f/this.scale),l=h-(h-this.panY)*(f/this.scale);this.panX=p,this.panY=l,this.targetPanX=p,this.targetPanY=l,this.scale=f,this.renderer.updateTransform(this.panX,this.panY,this.scale)}resetZoom(){this.scale=1,this.panX=this.renderer.container.clientWidth/2,this.panY=0,this.targetPanX=this.panX,this.targetPanY=this.panY,this.render()}copyNode(e){this.service.copyNode(e)}pasteNode(e){const i=this.service.pasteNode(e);i&&(this.render(),this.selectNode(i.id),this.emit("node:add",{id:i.id,topic:i.topic}),this.emit("model:change",void 0),setTimeout(()=>this.ensureNodeVisible(i.id,!0),0))}pasteImage(e,i){const s=this.service.addImageNode(e,i);s&&(this.render(),this.selectNode(s.id),this.emit("node:add",{id:s.id,topic:""}),this.emit("model:change",void 0),setTimeout(()=>this.ensureNodeVisible(s.id,!0),0))}cutNode(e){const i=this.mindMap.findNode(e);if(i){const s=i.parentId;this.service.cutNode(e),this.selectNode(s),this.render(),this.emit("node:remove",e),this.emit("model:change",void 0)}}render(){this.isBatching||(this.renderer.render(this.mindMap,this.selectedNodeId,this.layoutMode),this.renderer.updateTransform(this.panX,this.panY,this.scale))}updateLayout(e){e==="Standard"?this.setLayoutMode("Both"):this.setLayoutMode(e)}setLayoutMode(e){this.layoutMode=e,this.layoutSwitcher.setMode(e);const i=this.renderer.container.clientWidth;e==="Right"?this.panX=i*.2:e==="Left"?this.panX=i*.8:this.panX=i*.5,this.panY=0,this.targetPanX=this.panX,this.targetPanY=this.panY,this.render()}getLayoutMode(){return this.layoutMode}navigateNode(e,i){const s=this.mindMap.findNode(e);if(s){switch(i){case"Left":if(s.isRoot){let n;this.layoutMode==="Left"?n=s.children[0]:this.layoutMode==="Both"&&(n=s.children.find((r,o)=>(r.layoutSide||(o%2!==0?"left":"right"))==="left")),n&&this.selectNode(n.id)}else s.parentId&&(this.getNodeDirection(s)==="right"?this.selectNode(s.parentId):s.children.length>0&&this.selectNode(s.children[0].id));break;case"Right":if(s.isRoot){let n;this.layoutMode==="Right"?n=s.children[0]:this.layoutMode==="Both"&&(n=s.children.find((r,o)=>(r.layoutSide||(o%2===0?"right":"left"))==="right")),n&&this.selectNode(n.id)}else s.parentId&&(this.getNodeDirection(s)==="right"?s.children.length>0&&this.selectNode(s.children[0].id):this.selectNode(s.parentId));break;case"Up":if(s.parentId){const n=this.mindMap.findNode(s.parentId);if(n){const r=this.getNodeDirection(s),o=n.children.filter(d=>this.getNodeDirection(d)===r),a=o.findIndex(d=>d.id===e);a>0&&this.selectNode(o[a-1].id)}}break;case"Down":if(s.parentId){const n=this.mindMap.findNode(s.parentId);if(n){const r=this.getNodeDirection(s),o=n.children.filter(d=>this.getNodeDirection(d)===r),a=o.findIndex(d=>d.id===e);a!==-1&&a<o.length-1&&this.selectNode(o[a+1].id)}}break}this.selectedNodeId&&this.selectedNodeId!==e&&setTimeout(()=>this.ensureNodeVisible(this.selectedNodeId,!0),0)}}getData(){return this.service.exportData()}loadData(e){try{this.service.importData(e),this.selectNode(null),this.render(),this.emit("model:load",e),e.theme&&this.layoutSwitcher.setTheme(e.theme),this.emit("model:change",void 0)}catch(i){console.error("Failed to load data",i)}}getRootId(){return this.mindMap.root.id}getNodeDirection(e){if(e.isRoot||this.layoutMode==="Right")return"right";if(this.layoutMode==="Left")return"left";let i=e;for(;i.parentId;){const s=this.mindMap.findNode(i.parentId);if(!s)break;if(s.isRoot)return i.layoutSide?i.layoutSide:s.children.findIndex(r=>r.id===i.id)%2===0?"right":"left";i=s}return"right"}startAnimationLoop(){let e=performance.now();const i=()=>{const s=performance.now(),n=(s-e)/1e3;e=s;const r=1-Math.exp(-8*n),o=this.targetPanX-this.panX,a=this.targetPanY-this.panY;Math.abs(o)>.1||Math.abs(a)>.1?(this.panX+=o*r,this.panY+=a*r,this.renderer.updateTransform(this.panX,this.panY,this.scale)):(this.panX!==this.targetPanX||this.panY!==this.targetPanY)&&(this.panX=this.targetPanX,this.panY=this.targetPanY,this.renderer.updateTransform(this.panX,this.panY,this.scale)),Number.isNaN(this.panX)&&(this.panX=0),Number.isNaN(this.panY)&&(this.panY=0),this.animationFrameId=requestAnimationFrame(i)};i()}ensureNodeVisible(e,i=!1){const s=this.renderer.container.querySelector(`.mindmap-node[data-id="${e}"]`);if(!s)return;const n=s.getBoundingClientRect(),r=this.renderer.container.getBoundingClientRect(),o=50;let a=0,d=0;const h=n.left<r.left+o,f=n.right>r.right-o,p=n.top<r.top+o,l=n.bottom>r.bottom-o;if(i&&(h||f||p||l)){const y=n.left+n.width/2,g=n.top+n.height/2,m=r.left+r.width/2,u=r.top+r.height/2;a=m-y,d=u-g}else h?a=r.left+o-n.left:f&&(a=r.right-o-n.right),p?d=r.top+o-n.top:l&&(d=r.bottom-o-n.bottom);(a!==0||d!==0)&&this.panBoard(a,d)}}exports.Kakidash=J;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kakidash",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "A lightweight, dependency-free Mindmap library for the browser.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
"url": "https://github.com/hiroooo000/kakidash/issues"
|
|
12
12
|
},
|
|
13
13
|
"type": "module",
|
|
14
|
-
"main": "./dist/kakidash.
|
|
14
|
+
"main": "./dist/kakidash.cjs",
|
|
15
15
|
"module": "./dist/kakidash.es.js",
|
|
16
16
|
"types": "./dist/index.d.ts",
|
|
17
17
|
"exports": {
|
|
18
18
|
".": {
|
|
19
19
|
"import": "./dist/kakidash.es.js",
|
|
20
|
-
"require": "./dist/kakidash.
|
|
20
|
+
"require": "./dist/kakidash.cjs"
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"files": [
|