@node-edit-utils/core 2.0.6 → 2.0.8

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.
@@ -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.6
4
+ * @version 2.0.8
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
- const zoom = event.data.data;
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,6 +194,7 @@ 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
199
  event.preventDefault();
202
200
  event.stopPropagation();
@@ -312,14 +310,14 @@ const updateHighlightFrameVisibility = (node, nodeProvider) => {
312
310
  frame.style.display = hasHiddenClass ? "none" : "";
313
311
  };
314
312
 
315
- const disableCanvasKeyboard = () => {
316
- const disable = getCanvasWindowValue(["keyboard", "disable"]);
317
- disable?.();
313
+ const disableCanvasTextMode = () => {
314
+ const disableTextEditMode = getCanvasWindowValue(["keyboard", "disableTextEditMode"]);
315
+ disableTextEditMode?.();
318
316
  };
319
317
 
320
- const enableCanvasKeyboard = () => {
321
- const enable = getCanvasWindowValue(["keyboard", "enable"]);
322
- enable?.();
318
+ const enableCanvasTextMode = () => {
319
+ const enableTextEditMode = getCanvasWindowValue(["keyboard", "enableTextEditMode"]);
320
+ enableTextEditMode?.();
323
321
  };
324
322
 
325
323
  const insertLineBreak = () => {
@@ -415,7 +413,7 @@ const nodeText = () => {
415
413
  if (editable) {
416
414
  editableNode = node;
417
415
  makeNodeEditable(node);
418
- disableCanvasKeyboard();
416
+ enableCanvasTextMode();
419
417
  cleanup = setupNodeListeners(node, nodeProvider, blurEditMode);
420
418
  }
421
419
  };
@@ -432,7 +430,7 @@ const nodeText = () => {
432
430
  blurInProgress = true;
433
431
  const nodeToCleanup = editableNode;
434
432
  makeNodeNonEditable(nodeToCleanup);
435
- enableCanvasKeyboard();
433
+ disableCanvasTextMode();
436
434
  cleanup?.();
437
435
  editableNode = null;
438
436
  blurInProgress = false;
@@ -469,6 +467,7 @@ const createNodeTools = (element) => {
469
467
  if (selectedNode === node) {
470
468
  return;
471
469
  }
470
+ selectedNode = node;
472
471
  if (text.isEditing()) {
473
472
  const currentEditable = text.getEditableNode();
474
473
  if (currentEditable && currentEditable !== node) {
@@ -491,7 +490,6 @@ const createNodeTools = (element) => {
491
490
  attributeFilter: ["class"],
492
491
  });
493
492
  }
494
- selectedNode = node;
495
493
  sendPostMessage("selectedNodeChanged", node?.getAttribute("data-node-id") ?? null);
496
494
  highlightNode(node, nodeProvider) ?? null;
497
495
  if (node && nodeProvider) {
@@ -612,9 +610,7 @@ const calcWidth = (event, startX, startWidth) => {
612
610
  };
613
611
 
614
612
  const updateActivePreset = (container, width) => {
615
- console.log("updateActivePreset", width);
616
613
  const presetButtons = container.querySelectorAll(".resize-preset-button");
617
- console.log("presetButtons", presetButtons);
618
614
  presetButtons.forEach((button, index) => {
619
615
  if (index < RESIZE_PRESETS.length) {
620
616
  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.6
4
+ * @version 2.0.8
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
- const zoom = event.data.data;
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,6 +192,7 @@ 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
197
  event.preventDefault();
200
198
  event.stopPropagation();
@@ -310,14 +308,14 @@ const updateHighlightFrameVisibility = (node, nodeProvider) => {
310
308
  frame.style.display = hasHiddenClass ? "none" : "";
311
309
  };
312
310
 
313
- const disableCanvasKeyboard = () => {
314
- const disable = getCanvasWindowValue(["keyboard", "disable"]);
315
- disable?.();
311
+ const disableCanvasTextMode = () => {
312
+ const disableTextEditMode = getCanvasWindowValue(["keyboard", "disableTextEditMode"]);
313
+ disableTextEditMode?.();
316
314
  };
317
315
 
318
- const enableCanvasKeyboard = () => {
319
- const enable = getCanvasWindowValue(["keyboard", "enable"]);
320
- enable?.();
316
+ const enableCanvasTextMode = () => {
317
+ const enableTextEditMode = getCanvasWindowValue(["keyboard", "enableTextEditMode"]);
318
+ enableTextEditMode?.();
321
319
  };
322
320
 
323
321
  const insertLineBreak = () => {
@@ -413,7 +411,7 @@ const nodeText = () => {
413
411
  if (editable) {
414
412
  editableNode = node;
415
413
  makeNodeEditable(node);
416
- disableCanvasKeyboard();
414
+ enableCanvasTextMode();
417
415
  cleanup = setupNodeListeners(node, nodeProvider, blurEditMode);
418
416
  }
419
417
  };
@@ -430,7 +428,7 @@ const nodeText = () => {
430
428
  blurInProgress = true;
431
429
  const nodeToCleanup = editableNode;
432
430
  makeNodeNonEditable(nodeToCleanup);
433
- enableCanvasKeyboard();
431
+ disableCanvasTextMode();
434
432
  cleanup?.();
435
433
  editableNode = null;
436
434
  blurInProgress = false;
@@ -467,6 +465,7 @@ const createNodeTools = (element) => {
467
465
  if (selectedNode === node) {
468
466
  return;
469
467
  }
468
+ selectedNode = node;
470
469
  if (text.isEditing()) {
471
470
  const currentEditable = text.getEditableNode();
472
471
  if (currentEditable && currentEditable !== node) {
@@ -489,7 +488,6 @@ const createNodeTools = (element) => {
489
488
  attributeFilter: ["class"],
490
489
  });
491
490
  }
492
- selectedNode = node;
493
491
  sendPostMessage("selectedNodeChanged", node?.getAttribute("data-node-id") ?? null);
494
492
  highlightNode(node, nodeProvider) ?? null;
495
493
  if (node && nodeProvider) {
@@ -610,9 +608,7 @@ const calcWidth = (event, startX, startWidth) => {
610
608
  };
611
609
 
612
610
  const updateActivePreset = (container, width) => {
613
- console.log("updateActivePreset", width);
614
611
  const presetButtons = container.querySelectorAll(".resize-preset-button");
615
- console.log("presetButtons", presetButtons);
616
612
  presetButtons.forEach((button, index) => {
617
613
  if (index < RESIZE_PRESETS.length) {
618
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.6
4
+ * @version 2.0.8
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
- const zoom = event.data.data;
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,6 +198,7 @@
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
203
  event.preventDefault();
206
204
  event.stopPropagation();
@@ -316,14 +314,14 @@
316
314
  frame.style.display = hasHiddenClass ? "none" : "";
317
315
  };
318
316
 
319
- const disableCanvasKeyboard = () => {
320
- const disable = getCanvasWindowValue(["keyboard", "disable"]);
321
- disable?.();
317
+ const disableCanvasTextMode = () => {
318
+ const disableTextEditMode = getCanvasWindowValue(["keyboard", "disableTextEditMode"]);
319
+ disableTextEditMode?.();
322
320
  };
323
321
 
324
- const enableCanvasKeyboard = () => {
325
- const enable = getCanvasWindowValue(["keyboard", "enable"]);
326
- enable?.();
322
+ const enableCanvasTextMode = () => {
323
+ const enableTextEditMode = getCanvasWindowValue(["keyboard", "enableTextEditMode"]);
324
+ enableTextEditMode?.();
327
325
  };
328
326
 
329
327
  const insertLineBreak = () => {
@@ -419,7 +417,7 @@
419
417
  if (editable) {
420
418
  editableNode = node;
421
419
  makeNodeEditable(node);
422
- disableCanvasKeyboard();
420
+ enableCanvasTextMode();
423
421
  cleanup = setupNodeListeners(node, nodeProvider, blurEditMode);
424
422
  }
425
423
  };
@@ -436,7 +434,7 @@
436
434
  blurInProgress = true;
437
435
  const nodeToCleanup = editableNode;
438
436
  makeNodeNonEditable(nodeToCleanup);
439
- enableCanvasKeyboard();
437
+ disableCanvasTextMode();
440
438
  cleanup?.();
441
439
  editableNode = null;
442
440
  blurInProgress = false;
@@ -473,6 +471,7 @@
473
471
  if (selectedNode === node) {
474
472
  return;
475
473
  }
474
+ selectedNode = node;
476
475
  if (text.isEditing()) {
477
476
  const currentEditable = text.getEditableNode();
478
477
  if (currentEditable && currentEditable !== node) {
@@ -495,7 +494,6 @@
495
494
  attributeFilter: ["class"],
496
495
  });
497
496
  }
498
- selectedNode = node;
499
497
  sendPostMessage("selectedNodeChanged", node?.getAttribute("data-node-id") ?? null);
500
498
  highlightNode(node, nodeProvider) ?? null;
501
499
  if (node && nodeProvider) {
@@ -616,9 +614,7 @@
616
614
  };
617
615
 
618
616
  const updateActivePreset = (container, width) => {
619
- console.log("updateActivePreset", width);
620
617
  const presetButtons = container.querySelectorAll(".resize-preset-button");
621
- console.log("presetButtons", presetButtons);
622
618
  presetButtons.forEach((button, index) => {
623
619
  if (index < RESIZE_PRESETS.length) {
624
620
  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 l=(e,t)=>{let n=null;const o=e.clientX,r=e.clientY,l=e.metaKey||e.ctrlKey,d=((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&&d.includes(t))return t;if(l)return a=[],n=d[0],n;var c,u;u=d,(c=a).length===u.length&&c.every((e,t)=>e===u[t])?i<=d.length&&i++:i=0;return n=d[d.length-1-i],a=d,n},d=(e,t,n,o)=>{const s=e=>{((e,t)=>{if("markup-canvas"===e.data.source&&"canvas"===e.data.canvasName&&"zoom"===e.data.action){const t=e.data.data;console.log("zoom",t)}if("application"===e.data.source&&"selectedNodeChanged"===e.data.action){const n=e.data.data;console.log("selectedNodeChanged in node-edit-utils",n);const o=document.querySelector(`[data-node-id="${n}"]`);o&&(console.log("selectedNode",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(l(e,n))})(n,e,o(),t)},i=e=>{"Escape"===e.key&&(e.preventDefault(),e.stopPropagation(),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 l=document.createElement("div");l.classList.add("highlight-frame"),l.style.setProperty("--frame-top",`${o}px`),l.style.setProperty("--frame-left",`${r}px`),l.style.setProperty("--frame-width",`${s}px`),l.style.setProperty("--frame-height",`${a}px`);const d=document.createElementNS("http://www.w3.org/2000/svg","svg");d.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"),d.appendChild(u),l.appendChild(d),l})(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:l,height:d}=c(e,t);r.style.setProperty("--frame-top",`${a}px`),r.style.setProperty("--frame-left",`${i}px`),r.style.setProperty("--frame-width",`${l}px`),r.style.setProperty("--frame-height",`${d}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)}},f=(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()},y=()=>{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","enable"]);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","disable"]);e?.()})(),o=((e,t,n)=>{if(!t)return()=>{};e.addEventListener("blur",n);const o=h(e),r=f(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)=>{console.log("updateActivePreset",t);const n=e.querySelectorAll(".resize-preset-button");console.log("presetButtons",n),n.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=y(),l=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,()=>{l(e,n)}),s=new MutationObserver(()=>{l(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=d(n,c,()=>{i.isEditing()&&i.blurEditMode(),a&&n&&(r(n),a=null,o?.disconnect(),s?.disconnect())},i.getEditableNode),h={selectNode:c,getSelectedNode:()=>a,refreshHighlightFrame:()=>{l(a,n)},clearSelectedNode:()=>{r(n),a=null,o?.disconnect(),s?.disconnect()},getEditableNode:()=>i.getEditableNode(),cleanup:()=>{u(),o?.disconnect(),s?.disconnect(),i.blurEditMode(),l.cleanup()}};var f,g;return f="nodeTools",g=h,"undefined"!=typeof window&&(window[f]=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 l=t(t=>{if(!s)return;n&&(n.style.cursor="ew-resize");const o=E(t,a,i);x(e,o)}),d=((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},l,e=>{e.preventDefault(),e.stopPropagation(),n&&(n.style.cursor="default"),s=!1},()=>{s=!1});return{setWidth:t=>{x(e,t)},cleanup:()=>{s=!1,l?.cleanup(),d(),r.remove()}}}});
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&&(e.preventDefault(),e.stopPropagation(),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)}},f=(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()},y=()=>{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=f(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=y(),d=t(p),c=e=>{if(a!==e){if(a=e,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"]})),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 f,g;return f="nodeTools",g=h,"undefined"!=typeof window&&(window[f]=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:.25rem;justify-content:center;left:0;opacity:var(--tool-opacity);padding-top:.25rem;position:absolute;top:0;transform:scale(calc(1/var(--zoom))) translate3d(0,100%,0);transform-origin:bottom left;transition:opacity .1s ease;z-index:10000}.highlight-frame{font-family:Manrope,sans-serif;height:var(--frame-height);left:var(--frame-left);letter-spacing:.02em;pointer-events:none;position:absolute;top:var(--frame-top);width:var(--frame-width);z-index:1000}.highlight-frame-svg{height:100%;left:0;overflow:visible;position:absolute;top:0;width:100%}.highlight-frame-rect{fill:none;stroke:oklch(45.7% .24 277.023);stroke-width:var(--stroke-width)}.tag-label{align-items:center;background-color:oklch(45.7% .24 277.023);border-radius:.375rem;color:#fff;display:flex;font-size:.575rem;font-weight:500;height:1.25rem;justify-content:center;line-height:1;padding:0 .375rem;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:1.25rem;transform:scale(calc(1/var(--zoom)));transform-origin:top left;transition:opacity .1s ease-in-out,visibility .1s ease-in-out;visibility:hidden;width:12px;z-index:10000}.viewport:hover .resize-handle{opacity:1;visibility:visible}.resize-handle:before{background:oklch(55.2% .016 285.938);border-radius:4px;content:"";height:32px;position:relative;right:0;top:0;transition:transform .2s ease-in-out;width:3px}.resize-handle:hover:before{transform:scaleY(1.3)}.resize-presets{display:flex;flex-direction:column;font-family:Manrope,sans-serif;gap:.25rem;left:0;letter-spacing:.02em;opacity:0;padding-left:1.25rem;position:absolute;top:0;transition:visibility .1s ease-in-out,opacity .1s ease-in-out;visibility:hidden}.resize-handle:hover .resize-presets{opacity:1;visibility:visible}.resize-preset-button{text-wrap:nowrap;backdrop-filter:blur(8px);background:oklch(55.2% .016 285.938/.7);border:none;border-radius:.5rem;color:#fff;cursor:pointer;font-size:.6875rem;padding:.25rem .5rem;text-align:left;transition:background .1s ease-in-out;width:fit-content;&:hover{background:oklch(55.2% .016 285.938/1)}&.is-active{background:oklch(45.7% .24 277.023)}}.is-editable{outline:none;user-select:text;&::selection{background:oklch(62.7% .265 303.9/.3)}&::-moz-selection{background:oklch(62.7% .265 303.9/.3)}&::-webkit-selection{background:oklch(62.7% .265 303.9/.3)}}
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@node-edit-utils/core",
3
- "version": "2.0.6",
3
+ "version": "2.0.8",
4
4
  "description": "Utilities for editing nodes in a dom tree.",
5
5
  "type": "module",
6
6
  "main": "dist/node-edit-utils.cjs.js",
@@ -0,0 +1,7 @@
1
+ import { getCanvasWindowValue } from "@/lib/canvas/helpers/getCanvasWindowValue";
2
+
3
+ export const disableCanvasTextMode = () => {
4
+ const disableTextEditMode = getCanvasWindowValue(["keyboard", "disableTextEditMode"]);
5
+
6
+ disableTextEditMode?.();
7
+ };
@@ -0,0 +1,7 @@
1
+ import { getCanvasWindowValue } from "@/lib/canvas/helpers/getCanvasWindowValue";
2
+
3
+ export const enableCanvasTextMode = () => {
4
+ const enableTextEditMode = getCanvasWindowValue(["keyboard", "enableTextEditMode"]);
5
+
6
+ enableTextEditMode?.();
7
+ };
@@ -41,6 +41,8 @@ export const createNodeTools = (element: HTMLElement | null): NodeTools => {
41
41
  return;
42
42
  }
43
43
 
44
+ selectedNode = node;
45
+
44
46
  if (text.isEditing()) {
45
47
  const currentEditable = text.getEditableNode();
46
48
  if (currentEditable && currentEditable !== node) {
@@ -69,7 +71,6 @@ export const createNodeTools = (element: HTMLElement | null): NodeTools => {
69
71
  });
70
72
  }
71
73
 
72
- selectedNode = node;
73
74
  sendPostMessage("selectedNodeChanged", node?.getAttribute("data-node-id") ?? null);
74
75
  highlightNode(node, nodeProvider as HTMLElement) ?? null;
75
76
 
@@ -16,9 +16,12 @@ 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
22
  event.preventDefault();
21
23
  event.stopPropagation();
24
+
22
25
  onEscapePressed?.();
23
26
  }
24
27
  };
@@ -1,5 +1,5 @@
1
- import { disableCanvasKeyboard } from "../../canvas/disableCanvasKeyboard";
2
- import { enableCanvasKeyboard } from "../../canvas/enableCanvasKeyboard";
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
- disableCanvasKeyboard();
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
- enableCanvasKeyboard();
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: 0.25rem;
21
- z-index: 10000;
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 0.1s ease;
49
+ transition: opacity var(--transition-fast);
25
50
  opacity: var(--tool-opacity);
26
- padding-top: 0.25rem;
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: 1000;
62
+ z-index: var(--z-index-medium);
38
63
  pointer-events: none;
39
- font-family: "Manrope", sans-serif;
40
- letter-spacing: 0.02em;
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: oklch(45.7% 0.24 277.023);
79
+ stroke: var(--primary-color);
56
80
  stroke-width: var(--stroke-width);
57
81
  }
58
82
 
59
83
  .tag-label {
60
- background-color: oklch(45.7% 0.24 277.023);
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: 1.25rem;
66
- padding: 0 0.375rem;
89
+ height: 1rem;
90
+ padding: 0.5625rem var(--spacing-sm);
67
91
  line-height: 1;
68
- border-radius: 0.375rem;
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: 1.25rem;
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: 10000;
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 0.1s ease-in-out,
97
- visibility 0.1s ease-in-out;
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: oklch(55.2% 0.016 285.938);
136
+ background: var(--handle-color);
113
137
  border-radius: 4px;
114
- transition: transform 0.2s ease-in-out;
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: 1.25rem;
149
+ padding-left: var(--spacing-lg);
126
150
  display: flex;
127
151
  flex-direction: column;
128
- gap: 0.25rem;
152
+ gap: var(--spacing-xs);
129
153
  visibility: hidden;
130
154
  opacity: 0;
131
- font-family: "Manrope", sans-serif;
132
- letter-spacing: 0.02em;
155
+ font-family: var(--font-family-primary);
156
+ letter-spacing: var(--letter-spacing);
133
157
  transition:
134
- visibility 0.1s ease-in-out,
135
- opacity 0.1s ease-in-out;
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: oklch(55.2% 0.016 285.938 / 0.7);
168
+ background: var(--handle-color-transparent);
145
169
  border: none;
146
170
  cursor: pointer;
147
- padding: 0.25rem 0.5rem;
148
- border-radius: 0.5rem;
149
- font-size: 0.6875rem;
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 0.1s ease-in-out;
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: oklch(55.2% 0.016 285.938 / 1);
182
+ background: var(--handle-color);
159
183
  }
160
184
 
161
185
  &.is-active {
162
- background: oklch(45.7% 0.24 277.023);
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: oklch(62.7% 0.265 303.9 / 0.3);
195
+ background: var(--primary-color-selection);
172
196
  }
173
197
 
174
198
  &::-moz-selection {
175
- background: oklch(62.7% 0.265 303.9 / 0.3);
199
+ background: var(--primary-color-selection);
176
200
  }
177
201
 
178
202
  &::-webkit-selection {
179
- background: oklch(62.7% 0.265 303.9 / 0.3);
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];