@node-edit-utils/core 2.0.6 → 2.0.7
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/lib/canvas/disableCanvasTextMode.d.ts +1 -0
- package/dist/lib/canvas/enableCanvasTextMode.d.ts +1 -0
- package/dist/node-edit-utils.cjs.js +11 -17
- package/dist/node-edit-utils.esm.js +11 -17
- package/dist/node-edit-utils.umd.js +11 -17
- package/dist/node-edit-utils.umd.min.js +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/lib/canvas/disableCanvasTextMode.ts +7 -0
- package/src/lib/canvas/enableCanvasTextMode.ts +7 -0
- package/src/lib/node-tools/events/setupEventListener.ts +2 -2
- package/src/lib/node-tools/text/nodeText.ts +4 -5
- package/src/lib/post-message/processPostMessage.ts +0 -3
- package/src/lib/styles/styles.css +61 -37
- package/src/lib/viewport/resize/updateActivePreset.ts +0 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const disableCanvasTextMode: () => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const enableCanvasTextMode: () => void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Markup Canvas
|
|
3
3
|
* High-performance markup canvas with zoom and pan capabilities
|
|
4
|
-
* @version 2.0.
|
|
4
|
+
* @version 2.0.7
|
|
5
5
|
*/
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
@@ -100,17 +100,14 @@ const bindToWindow = (key, value) => {
|
|
|
100
100
|
const processPostMessage = (event, onNodeSelected) => {
|
|
101
101
|
if (event.data.source === "markup-canvas" && event.data.canvasName === "canvas") {
|
|
102
102
|
if (event.data.action === "zoom") {
|
|
103
|
-
|
|
104
|
-
console.log("zoom", zoom);
|
|
103
|
+
event.data.data;
|
|
105
104
|
}
|
|
106
105
|
}
|
|
107
106
|
if (event.data.source === "application") {
|
|
108
107
|
if (event.data.action === "selectedNodeChanged") {
|
|
109
108
|
const nodeId = event.data.data;
|
|
110
|
-
console.log("selectedNodeChanged in node-edit-utils", nodeId);
|
|
111
109
|
const selectedNode = document.querySelector(`[data-node-id="${nodeId}"]`);
|
|
112
110
|
if (selectedNode) {
|
|
113
|
-
console.log("selectedNode", selectedNode);
|
|
114
111
|
onNodeSelected?.(selectedNode);
|
|
115
112
|
}
|
|
116
113
|
}
|
|
@@ -197,9 +194,8 @@ const setupEventListener$1 = (nodeProvider, onNodeSelected, onEscapePressed, get
|
|
|
197
194
|
handleNodeClick(event, nodeProvider, getEditableNode(), onNodeSelected);
|
|
198
195
|
};
|
|
199
196
|
const documentKeydownHandler = (event) => {
|
|
197
|
+
console.log("Esacpe Handler", event);
|
|
200
198
|
if (event.key === "Escape") {
|
|
201
|
-
event.preventDefault();
|
|
202
|
-
event.stopPropagation();
|
|
203
199
|
onEscapePressed?.();
|
|
204
200
|
}
|
|
205
201
|
};
|
|
@@ -312,14 +308,14 @@ const updateHighlightFrameVisibility = (node, nodeProvider) => {
|
|
|
312
308
|
frame.style.display = hasHiddenClass ? "none" : "";
|
|
313
309
|
};
|
|
314
310
|
|
|
315
|
-
const
|
|
316
|
-
const
|
|
317
|
-
|
|
311
|
+
const disableCanvasTextMode = () => {
|
|
312
|
+
const disableTextEditMode = getCanvasWindowValue(["keyboard", "disableTextEditMode"]);
|
|
313
|
+
disableTextEditMode?.();
|
|
318
314
|
};
|
|
319
315
|
|
|
320
|
-
const
|
|
321
|
-
const
|
|
322
|
-
|
|
316
|
+
const enableCanvasTextMode = () => {
|
|
317
|
+
const enableTextEditMode = getCanvasWindowValue(["keyboard", "enableTextEditMode"]);
|
|
318
|
+
enableTextEditMode?.();
|
|
323
319
|
};
|
|
324
320
|
|
|
325
321
|
const insertLineBreak = () => {
|
|
@@ -415,7 +411,7 @@ const nodeText = () => {
|
|
|
415
411
|
if (editable) {
|
|
416
412
|
editableNode = node;
|
|
417
413
|
makeNodeEditable(node);
|
|
418
|
-
|
|
414
|
+
enableCanvasTextMode();
|
|
419
415
|
cleanup = setupNodeListeners(node, nodeProvider, blurEditMode);
|
|
420
416
|
}
|
|
421
417
|
};
|
|
@@ -432,7 +428,7 @@ const nodeText = () => {
|
|
|
432
428
|
blurInProgress = true;
|
|
433
429
|
const nodeToCleanup = editableNode;
|
|
434
430
|
makeNodeNonEditable(nodeToCleanup);
|
|
435
|
-
|
|
431
|
+
disableCanvasTextMode();
|
|
436
432
|
cleanup?.();
|
|
437
433
|
editableNode = null;
|
|
438
434
|
blurInProgress = false;
|
|
@@ -612,9 +608,7 @@ const calcWidth = (event, startX, startWidth) => {
|
|
|
612
608
|
};
|
|
613
609
|
|
|
614
610
|
const updateActivePreset = (container, width) => {
|
|
615
|
-
console.log("updateActivePreset", width);
|
|
616
611
|
const presetButtons = container.querySelectorAll(".resize-preset-button");
|
|
617
|
-
console.log("presetButtons", presetButtons);
|
|
618
612
|
presetButtons.forEach((button, index) => {
|
|
619
613
|
if (index < RESIZE_PRESETS.length) {
|
|
620
614
|
const preset = RESIZE_PRESETS[index];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Markup Canvas
|
|
3
3
|
* High-performance markup canvas with zoom and pan capabilities
|
|
4
|
-
* @version 2.0.
|
|
4
|
+
* @version 2.0.7
|
|
5
5
|
*/
|
|
6
6
|
// biome-ignore lint/suspicious/noExplicitAny: generic constraint requires flexibility
|
|
7
7
|
function withRAFThrottle(func) {
|
|
@@ -98,17 +98,14 @@ const bindToWindow = (key, value) => {
|
|
|
98
98
|
const processPostMessage = (event, onNodeSelected) => {
|
|
99
99
|
if (event.data.source === "markup-canvas" && event.data.canvasName === "canvas") {
|
|
100
100
|
if (event.data.action === "zoom") {
|
|
101
|
-
|
|
102
|
-
console.log("zoom", zoom);
|
|
101
|
+
event.data.data;
|
|
103
102
|
}
|
|
104
103
|
}
|
|
105
104
|
if (event.data.source === "application") {
|
|
106
105
|
if (event.data.action === "selectedNodeChanged") {
|
|
107
106
|
const nodeId = event.data.data;
|
|
108
|
-
console.log("selectedNodeChanged in node-edit-utils", nodeId);
|
|
109
107
|
const selectedNode = document.querySelector(`[data-node-id="${nodeId}"]`);
|
|
110
108
|
if (selectedNode) {
|
|
111
|
-
console.log("selectedNode", selectedNode);
|
|
112
109
|
onNodeSelected?.(selectedNode);
|
|
113
110
|
}
|
|
114
111
|
}
|
|
@@ -195,9 +192,8 @@ const setupEventListener$1 = (nodeProvider, onNodeSelected, onEscapePressed, get
|
|
|
195
192
|
handleNodeClick(event, nodeProvider, getEditableNode(), onNodeSelected);
|
|
196
193
|
};
|
|
197
194
|
const documentKeydownHandler = (event) => {
|
|
195
|
+
console.log("Esacpe Handler", event);
|
|
198
196
|
if (event.key === "Escape") {
|
|
199
|
-
event.preventDefault();
|
|
200
|
-
event.stopPropagation();
|
|
201
197
|
onEscapePressed?.();
|
|
202
198
|
}
|
|
203
199
|
};
|
|
@@ -310,14 +306,14 @@ const updateHighlightFrameVisibility = (node, nodeProvider) => {
|
|
|
310
306
|
frame.style.display = hasHiddenClass ? "none" : "";
|
|
311
307
|
};
|
|
312
308
|
|
|
313
|
-
const
|
|
314
|
-
const
|
|
315
|
-
|
|
309
|
+
const disableCanvasTextMode = () => {
|
|
310
|
+
const disableTextEditMode = getCanvasWindowValue(["keyboard", "disableTextEditMode"]);
|
|
311
|
+
disableTextEditMode?.();
|
|
316
312
|
};
|
|
317
313
|
|
|
318
|
-
const
|
|
319
|
-
const
|
|
320
|
-
|
|
314
|
+
const enableCanvasTextMode = () => {
|
|
315
|
+
const enableTextEditMode = getCanvasWindowValue(["keyboard", "enableTextEditMode"]);
|
|
316
|
+
enableTextEditMode?.();
|
|
321
317
|
};
|
|
322
318
|
|
|
323
319
|
const insertLineBreak = () => {
|
|
@@ -413,7 +409,7 @@ const nodeText = () => {
|
|
|
413
409
|
if (editable) {
|
|
414
410
|
editableNode = node;
|
|
415
411
|
makeNodeEditable(node);
|
|
416
|
-
|
|
412
|
+
enableCanvasTextMode();
|
|
417
413
|
cleanup = setupNodeListeners(node, nodeProvider, blurEditMode);
|
|
418
414
|
}
|
|
419
415
|
};
|
|
@@ -430,7 +426,7 @@ const nodeText = () => {
|
|
|
430
426
|
blurInProgress = true;
|
|
431
427
|
const nodeToCleanup = editableNode;
|
|
432
428
|
makeNodeNonEditable(nodeToCleanup);
|
|
433
|
-
|
|
429
|
+
disableCanvasTextMode();
|
|
434
430
|
cleanup?.();
|
|
435
431
|
editableNode = null;
|
|
436
432
|
blurInProgress = false;
|
|
@@ -610,9 +606,7 @@ const calcWidth = (event, startX, startWidth) => {
|
|
|
610
606
|
};
|
|
611
607
|
|
|
612
608
|
const updateActivePreset = (container, width) => {
|
|
613
|
-
console.log("updateActivePreset", width);
|
|
614
609
|
const presetButtons = container.querySelectorAll(".resize-preset-button");
|
|
615
|
-
console.log("presetButtons", presetButtons);
|
|
616
610
|
presetButtons.forEach((button, index) => {
|
|
617
611
|
if (index < RESIZE_PRESETS.length) {
|
|
618
612
|
const preset = RESIZE_PRESETS[index];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Markup Canvas
|
|
3
3
|
* High-performance markup canvas with zoom and pan capabilities
|
|
4
|
-
* @version 2.0.
|
|
4
|
+
* @version 2.0.7
|
|
5
5
|
*/
|
|
6
6
|
(function (global, factory) {
|
|
7
7
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
@@ -104,17 +104,14 @@
|
|
|
104
104
|
const processPostMessage = (event, onNodeSelected) => {
|
|
105
105
|
if (event.data.source === "markup-canvas" && event.data.canvasName === "canvas") {
|
|
106
106
|
if (event.data.action === "zoom") {
|
|
107
|
-
|
|
108
|
-
console.log("zoom", zoom);
|
|
107
|
+
event.data.data;
|
|
109
108
|
}
|
|
110
109
|
}
|
|
111
110
|
if (event.data.source === "application") {
|
|
112
111
|
if (event.data.action === "selectedNodeChanged") {
|
|
113
112
|
const nodeId = event.data.data;
|
|
114
|
-
console.log("selectedNodeChanged in node-edit-utils", nodeId);
|
|
115
113
|
const selectedNode = document.querySelector(`[data-node-id="${nodeId}"]`);
|
|
116
114
|
if (selectedNode) {
|
|
117
|
-
console.log("selectedNode", selectedNode);
|
|
118
115
|
onNodeSelected?.(selectedNode);
|
|
119
116
|
}
|
|
120
117
|
}
|
|
@@ -201,9 +198,8 @@
|
|
|
201
198
|
handleNodeClick(event, nodeProvider, getEditableNode(), onNodeSelected);
|
|
202
199
|
};
|
|
203
200
|
const documentKeydownHandler = (event) => {
|
|
201
|
+
console.log("Esacpe Handler", event);
|
|
204
202
|
if (event.key === "Escape") {
|
|
205
|
-
event.preventDefault();
|
|
206
|
-
event.stopPropagation();
|
|
207
203
|
onEscapePressed?.();
|
|
208
204
|
}
|
|
209
205
|
};
|
|
@@ -316,14 +312,14 @@
|
|
|
316
312
|
frame.style.display = hasHiddenClass ? "none" : "";
|
|
317
313
|
};
|
|
318
314
|
|
|
319
|
-
const
|
|
320
|
-
const
|
|
321
|
-
|
|
315
|
+
const disableCanvasTextMode = () => {
|
|
316
|
+
const disableTextEditMode = getCanvasWindowValue(["keyboard", "disableTextEditMode"]);
|
|
317
|
+
disableTextEditMode?.();
|
|
322
318
|
};
|
|
323
319
|
|
|
324
|
-
const
|
|
325
|
-
const
|
|
326
|
-
|
|
320
|
+
const enableCanvasTextMode = () => {
|
|
321
|
+
const enableTextEditMode = getCanvasWindowValue(["keyboard", "enableTextEditMode"]);
|
|
322
|
+
enableTextEditMode?.();
|
|
327
323
|
};
|
|
328
324
|
|
|
329
325
|
const insertLineBreak = () => {
|
|
@@ -419,7 +415,7 @@
|
|
|
419
415
|
if (editable) {
|
|
420
416
|
editableNode = node;
|
|
421
417
|
makeNodeEditable(node);
|
|
422
|
-
|
|
418
|
+
enableCanvasTextMode();
|
|
423
419
|
cleanup = setupNodeListeners(node, nodeProvider, blurEditMode);
|
|
424
420
|
}
|
|
425
421
|
};
|
|
@@ -436,7 +432,7 @@
|
|
|
436
432
|
blurInProgress = true;
|
|
437
433
|
const nodeToCleanup = editableNode;
|
|
438
434
|
makeNodeNonEditable(nodeToCleanup);
|
|
439
|
-
|
|
435
|
+
disableCanvasTextMode();
|
|
440
436
|
cleanup?.();
|
|
441
437
|
editableNode = null;
|
|
442
438
|
blurInProgress = false;
|
|
@@ -616,9 +612,7 @@
|
|
|
616
612
|
};
|
|
617
613
|
|
|
618
614
|
const updateActivePreset = (container, width) => {
|
|
619
|
-
console.log("updateActivePreset", width);
|
|
620
615
|
const presetButtons = container.querySelectorAll(".resize-preset-button");
|
|
621
|
-
console.log("presetButtons", presetButtons);
|
|
622
616
|
presetButtons.forEach((button, index) => {
|
|
623
617
|
if (index < RESIZE_PRESETS.length) {
|
|
624
618
|
const preset = RESIZE_PRESETS[index];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).MarkupCanvas={})}(this,function(e){"use strict";function t(e){let t=null,n=null;const o=(...o)=>{n=o,null===t&&(t=requestAnimationFrame(()=>{n&&e(...n),t=null,n=null}))};return o.cleanup=()=>{null!==t&&(cancelAnimationFrame(t),t=null,n=null)},o}const n=e=>{const t=window.canvas;return e.reduce((e,t)=>e?.[t],t)};function o(e){return e.querySelector(".highlight-frame")}const r=e=>{if(!e)return;const t=o(e);t&&t.remove()},s=["path","rect","circle","ellipse","polygon","line","polyline","text","text-noci"];let a=[],i=0;const
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).MarkupCanvas={})}(this,function(e){"use strict";function t(e){let t=null,n=null;const o=(...o)=>{n=o,null===t&&(t=requestAnimationFrame(()=>{n&&e(...n),t=null,n=null}))};return o.cleanup=()=>{null!==t&&(cancelAnimationFrame(t),t=null,n=null)},o}const n=e=>{const t=window.canvas;return e.reduce((e,t)=>e?.[t],t)};function o(e){return e.querySelector(".highlight-frame")}const r=e=>{if(!e)return;const t=o(e);t&&t.remove()},s=["path","rect","circle","ellipse","polygon","line","polyline","text","text-noci"];let a=[],i=0;const d=(e,t)=>{let n=null;const o=e.clientX,r=e.clientY,d=e.metaKey||e.ctrlKey,l=((e,t)=>{const n=document.elementsFromPoint(e,t);return Array.from(n).reduce((e,t)=>e.found?e:"node-provider"===t.getAttribute("data-role")?(e.found=!0,e):(e.elements.push(t),e),{elements:[],found:!1}).elements})(o,r).filter(e=>!s.includes(e.tagName.toLowerCase())&&!e.classList.contains("select-none"));if(t&&l.includes(t))return t;if(d)return a=[],n=l[0],n;var c,u;u=l,(c=a).length===u.length&&c.every((e,t)=>e===u[t])?i<=l.length&&i++:i=0;return n=l[l.length-1-i],a=l,n},l=(e,t,n,o)=>{const s=e=>{((e,t)=>{if("markup-canvas"===e.data.source&&"canvas"===e.data.canvasName&&"zoom"===e.data.action&&e.data.data,"application"===e.data.source&&"selectedNodeChanged"===e.data.action){const n=e.data.data,o=document.querySelector(`[data-node-id="${n}"]`);o&&t?.(o)}})(e,t)},a=n=>{((e,t,n,o)=>{if(e.preventDefault(),e.stopPropagation(),t&&!t.contains(e.target))return r(t),void o(null);o(d(e,n))})(n,e,o(),t)},i=e=>{console.log("Esacpe Handler",e),"Escape"===e.key&&n?.()};return window.addEventListener("message",s),document.addEventListener("click",a),document.addEventListener("keydown",i),()=>{window.removeEventListener("message",s),document.removeEventListener("click",a),document.removeEventListener("keydown",i)}};function c(e,t){const o=e.getBoundingClientRect(),r=t.getBoundingClientRect(),s=o.top-r.top,a=o.left-r.left,i=n(["zoom","current"])??1;return{top:parseFloat((s/i).toFixed(5)),left:parseFloat((a/i).toFixed(5)),width:Math.max(4,parseFloat((o.width/i).toFixed(5))),height:parseFloat((o.height/i).toFixed(5))}}const u=(e,t)=>{const n=document.createElement("div");n.className="node-tools",t.appendChild(n),((e,t)=>{const n=document.createElement("div");n.className="tag-label",n.textContent=e.tagName.toLowerCase(),t.appendChild(n)})(e,n)},m=(e,t)=>{if(!e)return;const r=o(t);r&&r.remove();const s=((e,t)=>{const{top:o,left:r,width:s,height:a}=c(e,t),i=n(["zoom","current"])??1;document.body.style.setProperty("--zoom",i.toString()),document.body.style.setProperty("--stroke-width",(2/i).toFixed(3));const d=document.createElement("div");d.classList.add("highlight-frame"),d.style.setProperty("--frame-top",`${o}px`),d.style.setProperty("--frame-left",`${r}px`),d.style.setProperty("--frame-width",`${s}px`),d.style.setProperty("--frame-height",`${a}px`);const l=document.createElementNS("http://www.w3.org/2000/svg","svg");l.classList.add("highlight-frame-svg");const u=document.createElementNS("http://www.w3.org/2000/svg","rect");return u.setAttribute("x","0"),u.setAttribute("y","0"),u.setAttribute("width","100%"),u.setAttribute("height","100%"),u.classList.add("highlight-frame-rect"),l.appendChild(u),d.appendChild(l),d})(e,t);"true"===e.contentEditable&&s.classList.add("is-editable"),u(e,s),t.appendChild(s)},p=(e,t)=>{const r=o(t),s=n(["zoom","current"])??1;if(!r)return;s>=.3?t.style.setProperty("--tool-opacity","1"):t.style.setProperty("--tool-opacity","0");const{top:a,left:i,width:d,height:l}=c(e,t);r.style.setProperty("--frame-top",`${a}px`),r.style.setProperty("--frame-left",`${i}px`),r.style.setProperty("--frame-width",`${d}px`),r.style.setProperty("--frame-height",`${l}px`)},v=(e,t)=>{const n=o(t);if(!n)return;const r=e.classList.contains("hidden")||e.classList.contains("select-none");n.style.display=r?"none":""},h=e=>{const t=e=>{"Enter"===e.key&&(e.preventDefault(),e.stopPropagation(),(()=>{const e=window.getSelection();if(e&&e.rangeCount>0){const t=e.getRangeAt(0);t.deleteContents();const n=document.createElement("br");t.insertNode(n),t.setStartAfter(n),t.setEndAfter(n),e.removeAllRanges(),e.addRange(t)}})())};return e.addEventListener("keydown",t),()=>{e.removeEventListener("keydown",t)}},y=(e,t)=>{const n=((e,t)=>{const n=new MutationObserver(e=>{t(e)});return n.observe(e,{subtree:!0,childList:!0,characterData:!0}),n})(e,()=>{p(e,t)});return()=>n.disconnect()},f=()=>{let e=null,t=!1,o=null;const r=()=>{if(t||!e)return;t=!0;var r;(r=e).contentEditable="false",r.classList.remove("is-editable"),r.style.outline="none",(()=>{const e=n(["keyboard","disableTextEditMode"]);e?.()})(),o?.(),e=null,t=!1};return{enableEditMode:(t,s)=>{if(e===t)return;e&&e!==t&&r();const a=(e=>Array.from(e.childNodes).some(e=>e.nodeType===Node.TEXT_NODE&&e.textContent?.trim()))(t);a&&(e=t,(e=>{e.contentEditable="true",e.classList.add("is-editable"),e.style.outline="none"})(t),(()=>{const e=n(["keyboard","enableTextEditMode"]);e?.()})(),o=((e,t,n)=>{if(!t)return()=>{};e.addEventListener("blur",n);const o=h(e),r=y(e,t);return()=>{e.removeEventListener("blur",n),o(),r?.()}})(t,s,r))},blurEditMode:r,getEditableNode:()=>e,isEditing:()=>null!==e}},g=320,b=1680,w=[{name:"Mobile",rawValue:390,value:"320px"},{name:"Tablet Portrait",rawValue:768,value:"768px"},{name:"Tablet Landscape",rawValue:1024,value:"1024px"},{name:"Notebook",rawValue:1280,value:"1280px"},{name:"Desktop",rawValue:1680,value:"1680px"}],E=(e,t,n)=>{const o=parseFloat(document.body.dataset.zoom||"1"),r=((e,t)=>{const n=e+Math.round(t);return Math.max(g,Math.min(b,n))})(n,(e.clientX-t)/o);return r},x=(e,t)=>{e.style.setProperty("--container-width",`${t}px`),((e,t)=>{e.querySelectorAll(".resize-preset-button").forEach((e,n)=>{n<w.length&&(w[n].rawValue===t?e.classList.add("is-active"):e.classList.remove("is-active"))})})(e,t)};e.createCanvasObserver=function(){const e=document.querySelector(".transform-layer");if(!e)return{disconnect:()=>{}};const o=t(()=>{(()=>{const e=n(["zoom","current"]);document.body.style.setProperty("--zoom",e.toFixed(5)),document.body.style.setProperty("--stroke-width",(2/e).toFixed(3)),document.body.dataset.zoom=e.toFixed(5),document.body.dataset.strokeWidth=(2/e).toFixed(3)})()}),r=new MutationObserver(()=>{o()});return r.observe(e,{attributes:!0,attributeOldValue:!0,subtree:!0,childList:!0}),{disconnect:function(){o.cleanup(),r.disconnect()}}},e.createNodeTools=e=>{const n=e;let o=null,s=null,a=null;const i=f(),d=t(p),c=e=>{if(a!==e){if(i.isEditing()){const t=i.getEditableNode();t&&t!==e&&i.blurEditMode()}var t,r;o?.disconnect(),s?.disconnect(),e&&n&&(i.enableEditMode(e,n),o=((e,t)=>{const n=new ResizeObserver(e=>{t(e)});return n.observe(e),n})(n,()=>{d(e,n)}),s=new MutationObserver(()=>{d(e,n),v(e,n)}),s.observe(e,{attributes:!0,attributeFilter:["class"]})),a=e,t="selectedNodeChanged",r=e?.getAttribute("data-node-id")??null,window.parent.postMessage({source:"node-edit-utils",action:t,data:r,timestamp:Date.now()},"*"),m(e,n),e&&n&&v(e,n)}},u=l(n,c,()=>{i.isEditing()&&i.blurEditMode(),a&&n&&(r(n),a=null,o?.disconnect(),s?.disconnect())},i.getEditableNode),h={selectNode:c,getSelectedNode:()=>a,refreshHighlightFrame:()=>{d(a,n)},clearSelectedNode:()=>{r(n),a=null,o?.disconnect(),s?.disconnect()},getEditableNode:()=>i.getEditableNode(),cleanup:()=>{u(),o?.disconnect(),s?.disconnect(),i.blurEditMode(),d.cleanup()}};var y,g;return y="nodeTools",g=h,"undefined"!=typeof window&&(window[y]=g),h},e.createViewport=e=>{const n=document.querySelector(".canvas-container"),o=e.querySelector(".resize-handle");o&&o.remove();const r=(e=>{const t=document.createElement("div");return t.className="resize-handle",e.appendChild(t),t})(e);e.style.setProperty("--container-width","400px"),((e,t,n)=>{const o=document.createElement("div");o.className="resize-presets",w.forEach(e=>{const r=document.createElement("button");r.textContent=e.name,r.className="resize-preset-button",r.addEventListener("click",()=>{n(t,e.rawValue)}),o.appendChild(r)}),e.appendChild(o)})(r,e,x);let s=!1,a=0,i=0;const d=t(t=>{if(!s)return;n&&(n.style.cursor="ew-resize");const o=E(t,a,i);x(e,o)}),l=((e,t,n,o,r)=>(e.addEventListener("mousedown",t),document.addEventListener("mousemove",n),document.addEventListener("mouseup",o),window.addEventListener("blur",r),()=>{e.removeEventListener("mousedown",t),document.removeEventListener("mousemove",n),document.removeEventListener("mouseup",o),window.removeEventListener("blur",r)}))(r,t=>{t.preventDefault(),t.stopPropagation(),s=!0,a=t.clientX,i=e.offsetWidth},d,e=>{e.preventDefault(),e.stopPropagation(),n&&(n.style.cursor="default"),s=!1},()=>{s=!1});return{setWidth:t=>{x(e,t)},cleanup:()=>{s=!1,d?.cleanup(),l(),r.remove()}}}});
|
package/dist/styles.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.node-provider{::selection{background:transparent}::-moz-selection{background:transparent}::-webkit-selection{background:transparent}}.node-tools{bottom:0;display:flex;gap
|
|
1
|
+
:root{--primary-color:oklch(0.6235 0.22 294);--uncode-color:oklch(45.7% 0.24 277.023);--handle-color:oklch(55.2% 0.016 285.938);--handle-color-transparent:oklch(55.2% 0.016 285.938/0.7);--primary-color-selection:oklch(0.59 0.18 294/0.3);--text-color-white:#fff;--spacing-xs:0.25rem;--spacing-sm:0.375rem;--spacing-md:0.5rem;--spacing-lg:1.25rem;--transition-fast:0.1s ease-in-out;--transition-medium:0.2s ease-in-out;--z-index-high:10000;--z-index-medium:1000;--letter-spacing:0.02em;--font-family-primary:"Manrope",sans-serif}.node-provider{::selection{background:transparent}::-moz-selection{background:transparent}::-webkit-selection{background:transparent}}.node-tools{bottom:0;display:flex;gap:var(--spacing-xs);justify-content:center;left:0;opacity:var(--tool-opacity);padding-top:var(--spacing-xs);position:absolute;top:0;transform:scale(calc(1/var(--zoom))) translate3d(0,100%,0);transform-origin:bottom left;transition:opacity var(--transition-fast);z-index:var(--z-index-high)}.highlight-frame{font-family:var(--font-family-primary);height:var(--frame-height);left:var(--frame-left);letter-spacing:var(--letter-spacing);pointer-events:none;position:absolute;top:var(--frame-top);width:var(--frame-width);z-index:var(--z-index-medium)}.highlight-frame-svg{height:100%;left:0;overflow:visible;position:absolute;top:0;width:100%}.highlight-frame-rect{fill:none;stroke:var(--primary-color);stroke-width:var(--stroke-width)}.tag-label{align-items:center;background-color:var(--primary-color);border-radius:var(--spacing-sm);color:var(--text-color-white);display:flex;font-size:.575rem;font-weight:500;height:1rem;justify-content:center;line-height:1;padding:.5625rem var(--spacing-sm);text-transform:uppercase}.viewport{position:relative;width:var(--container-width)}.resize-handle{align-items:center;cursor:ew-resize;display:flex;height:40px;justify-content:center;opacity:0;pointer-events:auto;position:absolute;right:-12px;top:var(--spacing-lg);transform:scale(calc(1/var(--zoom)));transform-origin:top left;transition:opacity var(--transition-fast),visibility var(--transition-fast);visibility:hidden;width:12px;z-index:var(--z-index-high)}.viewport:hover .resize-handle{opacity:1;visibility:visible}.resize-handle:before{background:var(--handle-color);border-radius:4px;content:"";height:32px;position:relative;right:0;top:0;transition:transform var(--transition-medium);width:3px}.resize-handle:hover:before{transform:scaleY(1.3)}.resize-presets{display:flex;flex-direction:column;font-family:var(--font-family-primary);gap:var(--spacing-xs);left:0;letter-spacing:var(--letter-spacing);opacity:0;padding-left:var(--spacing-lg);position:absolute;top:0;transition:visibility var(--transition-fast),opacity var(--transition-fast);visibility:hidden}.resize-handle:hover .resize-presets{opacity:1;visibility:visible}.resize-preset-button{text-wrap:nowrap;backdrop-filter:blur(8px);background:var(--handle-color-transparent);border:none;border-radius:var(--spacing-md);color:var(--text-color-white);cursor:pointer;font-size:.625rem;padding:var(--spacing-xs) var(--spacing-md);text-align:left;transition:background var(--transition-fast);width:fit-content;&:hover{background:var(--handle-color)}&.is-active{background:var(--uncode-color)}}.is-editable{outline:none;user-select:text;&::selection{background:var(--primary-color-selection)}&::-moz-selection{background:var(--primary-color-selection)}&::-webkit-selection{background:var(--primary-color-selection)}}
|
package/package.json
CHANGED
|
@@ -16,9 +16,9 @@ export const setupEventListener = (
|
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
const documentKeydownHandler = (event: KeyboardEvent) => {
|
|
19
|
+
console.log("Esacpe Handler", event);
|
|
20
|
+
|
|
19
21
|
if (event.key === "Escape") {
|
|
20
|
-
event.preventDefault();
|
|
21
|
-
event.stopPropagation();
|
|
22
22
|
onEscapePressed?.();
|
|
23
23
|
}
|
|
24
24
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { disableCanvasTextMode } from "../../canvas/disableCanvasTextMode";
|
|
2
|
+
import { enableCanvasTextMode } from "../../canvas/enableCanvasTextMode";
|
|
3
3
|
import { setupNodeListeners } from "./events/setupNodeListeners";
|
|
4
4
|
import { hasTextContent } from "./helpers/hasTextContent";
|
|
5
5
|
import { makeNodeEditable } from "./helpers/makeNodeEditable";
|
|
@@ -26,7 +26,7 @@ export const nodeText = (): NodeText => {
|
|
|
26
26
|
editableNode = node;
|
|
27
27
|
|
|
28
28
|
makeNodeEditable(node);
|
|
29
|
-
|
|
29
|
+
enableCanvasTextMode();
|
|
30
30
|
|
|
31
31
|
cleanup = setupNodeListeners(node, nodeProvider, blurEditMode);
|
|
32
32
|
}
|
|
@@ -50,8 +50,7 @@ export const nodeText = (): NodeText => {
|
|
|
50
50
|
const nodeToCleanup = editableNode;
|
|
51
51
|
|
|
52
52
|
makeNodeNonEditable(nodeToCleanup);
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
disableCanvasTextMode();
|
|
55
54
|
cleanup?.();
|
|
56
55
|
|
|
57
56
|
editableNode = null;
|
|
@@ -2,18 +2,15 @@ export const processPostMessage = (event: MessageEvent, onNodeSelected?: (node:
|
|
|
2
2
|
if (event.data.source === "markup-canvas" && event.data.canvasName === "canvas") {
|
|
3
3
|
if (event.data.action === "zoom") {
|
|
4
4
|
const zoom = event.data.data;
|
|
5
|
-
console.log("zoom", zoom);
|
|
6
5
|
}
|
|
7
6
|
}
|
|
8
7
|
|
|
9
8
|
if (event.data.source === "application") {
|
|
10
9
|
if (event.data.action === "selectedNodeChanged") {
|
|
11
10
|
const nodeId = event.data.data;
|
|
12
|
-
console.log("selectedNodeChanged in node-edit-utils", nodeId);
|
|
13
11
|
const selectedNode = document.querySelector(`[data-node-id="${nodeId}"]`);
|
|
14
12
|
|
|
15
13
|
if (selectedNode) {
|
|
16
|
-
console.log("selectedNode", selectedNode);
|
|
17
14
|
onNodeSelected?.(selectedNode as HTMLElement);
|
|
18
15
|
}
|
|
19
16
|
}
|
|
@@ -1,3 +1,28 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--primary-color: oklch(0.6235 0.22 294);
|
|
3
|
+
--uncode-color: oklch(45.7% 0.24 277.023);
|
|
4
|
+
|
|
5
|
+
--handle-color: oklch(55.2% 0.016 285.938);
|
|
6
|
+
--handle-color-transparent: oklch(55.2% 0.016 285.938 / 0.7);
|
|
7
|
+
--primary-color-selection: oklch(0.59 0.18 294 / 0.3);
|
|
8
|
+
|
|
9
|
+
--text-color-white: white;
|
|
10
|
+
|
|
11
|
+
--spacing-xs: 0.25rem;
|
|
12
|
+
--spacing-sm: 0.375rem;
|
|
13
|
+
--spacing-md: 0.5rem;
|
|
14
|
+
--spacing-lg: 1.25rem;
|
|
15
|
+
|
|
16
|
+
--transition-fast: 0.1s ease-in-out;
|
|
17
|
+
--transition-medium: 0.2s ease-in-out;
|
|
18
|
+
|
|
19
|
+
--z-index-high: 10000;
|
|
20
|
+
--z-index-medium: 1000;
|
|
21
|
+
|
|
22
|
+
--letter-spacing: 0.02em;
|
|
23
|
+
--font-family-primary: "Manrope", sans-serif;
|
|
24
|
+
}
|
|
25
|
+
|
|
1
26
|
.node-provider {
|
|
2
27
|
::selection {
|
|
3
28
|
background: transparent;
|
|
@@ -17,13 +42,13 @@
|
|
|
17
42
|
left: 0;
|
|
18
43
|
bottom: 0;
|
|
19
44
|
top: 0;
|
|
20
|
-
gap:
|
|
21
|
-
z-index:
|
|
45
|
+
gap: var(--spacing-xs);
|
|
46
|
+
z-index: var(--z-index-high);
|
|
22
47
|
transform: scale(calc(1 / var(--zoom))) translate3d(0, 100%, 0);
|
|
23
48
|
transform-origin: bottom left;
|
|
24
|
-
transition: opacity
|
|
49
|
+
transition: opacity var(--transition-fast);
|
|
25
50
|
opacity: var(--tool-opacity);
|
|
26
|
-
padding-top:
|
|
51
|
+
padding-top: var(--spacing-xs);
|
|
27
52
|
display: flex;
|
|
28
53
|
justify-content: center;
|
|
29
54
|
}
|
|
@@ -34,11 +59,10 @@
|
|
|
34
59
|
left: var(--frame-left);
|
|
35
60
|
width: var(--frame-width);
|
|
36
61
|
height: var(--frame-height);
|
|
37
|
-
z-index:
|
|
62
|
+
z-index: var(--z-index-medium);
|
|
38
63
|
pointer-events: none;
|
|
39
|
-
font-family:
|
|
40
|
-
letter-spacing:
|
|
41
|
-
/* outline: calc(0.125em / var(--zoom)) solid oklch(62.7% 0.265 303.9); */
|
|
64
|
+
font-family: var(--font-family-primary);
|
|
65
|
+
letter-spacing: var(--letter-spacing);
|
|
42
66
|
}
|
|
43
67
|
|
|
44
68
|
.highlight-frame-svg {
|
|
@@ -52,20 +76,20 @@
|
|
|
52
76
|
|
|
53
77
|
.highlight-frame-rect {
|
|
54
78
|
fill: none;
|
|
55
|
-
stroke:
|
|
79
|
+
stroke: var(--primary-color);
|
|
56
80
|
stroke-width: var(--stroke-width);
|
|
57
81
|
}
|
|
58
82
|
|
|
59
83
|
.tag-label {
|
|
60
|
-
background-color:
|
|
61
|
-
color: white;
|
|
84
|
+
background-color: var(--primary-color);
|
|
85
|
+
color: var(--text-color-white);
|
|
62
86
|
font-size: 0.575rem;
|
|
63
87
|
font-weight: 500;
|
|
64
88
|
text-transform: uppercase;
|
|
65
|
-
height:
|
|
66
|
-
padding: 0
|
|
89
|
+
height: 1rem;
|
|
90
|
+
padding: 0.5625rem var(--spacing-sm);
|
|
67
91
|
line-height: 1;
|
|
68
|
-
border-radius:
|
|
92
|
+
border-radius: var(--spacing-sm);
|
|
69
93
|
display: flex;
|
|
70
94
|
align-items: center;
|
|
71
95
|
justify-content: center;
|
|
@@ -78,12 +102,12 @@
|
|
|
78
102
|
|
|
79
103
|
.resize-handle {
|
|
80
104
|
position: absolute;
|
|
81
|
-
top:
|
|
105
|
+
top: var(--spacing-lg);
|
|
82
106
|
right: -12px;
|
|
83
107
|
width: 12px;
|
|
84
108
|
height: 40px;
|
|
85
109
|
cursor: ew-resize;
|
|
86
|
-
z-index:
|
|
110
|
+
z-index: var(--z-index-high);
|
|
87
111
|
display: flex;
|
|
88
112
|
opacity: 0;
|
|
89
113
|
visibility: hidden;
|
|
@@ -93,8 +117,8 @@
|
|
|
93
117
|
transform: scale(calc(1 / var(--zoom)));
|
|
94
118
|
transform-origin: top left;
|
|
95
119
|
transition:
|
|
96
|
-
opacity
|
|
97
|
-
visibility
|
|
120
|
+
opacity var(--transition-fast),
|
|
121
|
+
visibility var(--transition-fast);
|
|
98
122
|
}
|
|
99
123
|
|
|
100
124
|
.viewport:hover .resize-handle {
|
|
@@ -109,9 +133,9 @@
|
|
|
109
133
|
right: 0;
|
|
110
134
|
width: 3px;
|
|
111
135
|
height: 32px;
|
|
112
|
-
background:
|
|
136
|
+
background: var(--handle-color);
|
|
113
137
|
border-radius: 4px;
|
|
114
|
-
transition: transform
|
|
138
|
+
transition: transform var(--transition-medium);
|
|
115
139
|
}
|
|
116
140
|
|
|
117
141
|
.resize-handle:hover::before {
|
|
@@ -122,17 +146,17 @@
|
|
|
122
146
|
position: absolute;
|
|
123
147
|
top: 0;
|
|
124
148
|
left: 0;
|
|
125
|
-
padding-left:
|
|
149
|
+
padding-left: var(--spacing-lg);
|
|
126
150
|
display: flex;
|
|
127
151
|
flex-direction: column;
|
|
128
|
-
gap:
|
|
152
|
+
gap: var(--spacing-xs);
|
|
129
153
|
visibility: hidden;
|
|
130
154
|
opacity: 0;
|
|
131
|
-
font-family:
|
|
132
|
-
letter-spacing:
|
|
155
|
+
font-family: var(--font-family-primary);
|
|
156
|
+
letter-spacing: var(--letter-spacing);
|
|
133
157
|
transition:
|
|
134
|
-
visibility
|
|
135
|
-
opacity
|
|
158
|
+
visibility var(--transition-fast),
|
|
159
|
+
opacity var(--transition-fast);
|
|
136
160
|
}
|
|
137
161
|
|
|
138
162
|
.resize-handle:hover .resize-presets {
|
|
@@ -141,25 +165,25 @@
|
|
|
141
165
|
}
|
|
142
166
|
|
|
143
167
|
.resize-preset-button {
|
|
144
|
-
background:
|
|
168
|
+
background: var(--handle-color-transparent);
|
|
145
169
|
border: none;
|
|
146
170
|
cursor: pointer;
|
|
147
|
-
padding:
|
|
148
|
-
border-radius:
|
|
149
|
-
font-size: 0.
|
|
171
|
+
padding: var(--spacing-xs) var(--spacing-md);
|
|
172
|
+
border-radius: var(--spacing-md);
|
|
173
|
+
font-size: 0.625rem;
|
|
150
174
|
text-wrap: nowrap;
|
|
151
175
|
text-align: left;
|
|
152
176
|
backdrop-filter: blur(8px);
|
|
153
|
-
transition: background
|
|
154
|
-
color: white;
|
|
177
|
+
transition: background var(--transition-fast);
|
|
178
|
+
color: var(--text-color-white);
|
|
155
179
|
width: fit-content;
|
|
156
180
|
|
|
157
181
|
&:hover {
|
|
158
|
-
background:
|
|
182
|
+
background: var(--handle-color);
|
|
159
183
|
}
|
|
160
184
|
|
|
161
185
|
&.is-active {
|
|
162
|
-
background:
|
|
186
|
+
background: var(--uncode-color);
|
|
163
187
|
}
|
|
164
188
|
}
|
|
165
189
|
|
|
@@ -168,14 +192,14 @@
|
|
|
168
192
|
user-select: text;
|
|
169
193
|
|
|
170
194
|
&::selection {
|
|
171
|
-
background:
|
|
195
|
+
background: var(--primary-color-selection);
|
|
172
196
|
}
|
|
173
197
|
|
|
174
198
|
&::-moz-selection {
|
|
175
|
-
background:
|
|
199
|
+
background: var(--primary-color-selection);
|
|
176
200
|
}
|
|
177
201
|
|
|
178
202
|
&::-webkit-selection {
|
|
179
|
-
background:
|
|
203
|
+
background: var(--primary-color-selection);
|
|
180
204
|
}
|
|
181
205
|
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { RESIZE_PRESETS } from "../constants";
|
|
2
2
|
|
|
3
3
|
export const updateActivePreset = (container: HTMLElement, width: number): void => {
|
|
4
|
-
console.log("updateActivePreset", width);
|
|
5
4
|
const presetButtons = container.querySelectorAll<HTMLButtonElement>(".resize-preset-button");
|
|
6
|
-
console.log("presetButtons", presetButtons);
|
|
7
5
|
presetButtons.forEach((button, index) => {
|
|
8
6
|
if (index < RESIZE_PRESETS.length) {
|
|
9
7
|
const preset = RESIZE_PRESETS[index];
|