@elixpo/lixsketch 5.4.6 → 5.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/react/AIRenderer-M4LMJ66J.js +1105 -0
- package/dist/react/AIRenderer-M4LMJ66J.js.map +7 -0
- package/dist/react/Arrow-BJDAXPMH.js +8 -0
- package/dist/react/Arrow-BJDAXPMH.js.map +7 -0
- package/dist/react/Circle-KPG7TKIX.js +8 -0
- package/dist/react/Circle-KPG7TKIX.js.map +7 -0
- package/dist/react/CodeShape-K4DIZAIV.js +8 -0
- package/dist/react/CodeShape-K4DIZAIV.js.map +7 -0
- package/dist/react/CopyPaste-4CKJRHJ3.js +569 -0
- package/dist/react/CopyPaste-4CKJRHJ3.js.map +7 -0
- package/dist/react/EraserTrail-PA6IQLQN.js +20 -0
- package/dist/react/EraserTrail-PA6IQLQN.js.map +7 -0
- package/dist/react/EventDispatcher-SRFH6LQZ.js +463 -0
- package/dist/react/EventDispatcher-SRFH6LQZ.js.map +7 -0
- package/dist/react/Frame-6UR5XPAX.js +10 -0
- package/dist/react/Frame-6UR5XPAX.js.map +7 -0
- package/dist/react/FreehandStroke-CK24NUT3.js +8 -0
- package/dist/react/FreehandStroke-CK24NUT3.js.map +7 -0
- package/dist/react/GraphEngine-QE5B2PMR.js +340 -0
- package/dist/react/GraphEngine-QE5B2PMR.js.map +7 -0
- package/dist/react/GraphMathParser-2WMTY4IE.js +10 -0
- package/dist/react/GraphMathParser-2WMTY4IE.js.map +7 -0
- package/dist/react/IconShape-KMIA6T2H.js +10 -0
- package/dist/react/IconShape-KMIA6T2H.js.map +7 -0
- package/dist/react/ImageShape-CHHGBXUQ.js +10 -0
- package/dist/react/ImageShape-CHHGBXUQ.js.map +7 -0
- package/dist/react/LayerOrder-XCHF4MSS.js +66 -0
- package/dist/react/LayerOrder-XCHF4MSS.js.map +7 -0
- package/dist/react/Line-2KOQEEGA.js +10 -0
- package/dist/react/Line-2KOQEEGA.js.map +7 -0
- package/dist/react/LixScriptParser-JYWJX375.js +1033 -0
- package/dist/react/LixScriptParser-JYWJX375.js.map +7 -0
- package/dist/react/MermaidFlowchartRenderer-4QBAZ5MB.js +412 -0
- package/dist/react/MermaidFlowchartRenderer-4QBAZ5MB.js.map +7 -0
- package/dist/react/MermaidSequenceParser-UKG2NSZY.js +8 -0
- package/dist/react/MermaidSequenceParser-UKG2NSZY.js.map +7 -0
- package/dist/react/MermaidSequenceRenderer-HPLHY5II.js +387 -0
- package/dist/react/MermaidSequenceRenderer-HPLHY5II.js.map +7 -0
- package/dist/react/Rectangle-6FE7RN6W.js +8 -0
- package/dist/react/Rectangle-6FE7RN6W.js.map +7 -0
- package/dist/react/ResizeCode-WAMDTKSW.js +2 -0
- package/dist/react/ResizeCode-WAMDTKSW.js.map +7 -0
- package/dist/react/ResizeShapes-LKEQTITP.js +250 -0
- package/dist/react/ResizeShapes-LKEQTITP.js.map +7 -0
- package/dist/react/SceneSerializer-4U4B24JM.js +739 -0
- package/dist/react/SceneSerializer-4U4B24JM.js.map +7 -0
- package/dist/react/Selection-VVUHY5YJ.js +34 -0
- package/dist/react/Selection-VVUHY5YJ.js.map +7 -0
- package/dist/react/SketchEngine-YA4RG3KX.js +413 -0
- package/dist/react/SketchEngine-YA4RG3KX.js.map +7 -0
- package/dist/react/TextShape-54ZJ66E3.js +8 -0
- package/dist/react/TextShape-54ZJ66E3.js.map +7 -0
- package/dist/react/UndoRedo-M2JZUBKN.js +30 -0
- package/dist/react/UndoRedo-M2JZUBKN.js.map +7 -0
- package/dist/react/ZoomPan-U3TXC5AJ.js +186 -0
- package/dist/react/ZoomPan-U3TXC5AJ.js.map +7 -0
- package/dist/react/arrowTool-CWEMIRXK.js +17 -0
- package/dist/react/arrowTool-CWEMIRXK.js.map +7 -0
- package/dist/react/boxicons-5JNJQPUP.woff +0 -0
- package/dist/react/boxicons-6NVWQSCQ.eot +0 -0
- package/dist/react/boxicons-AQ5N6WP7.woff2 +0 -0
- package/dist/react/boxicons-GDR4JU3X.ttf +0 -0
- package/dist/react/boxicons-NNFHLMOR.svg +1660 -0
- package/dist/react/chunk-2OQXI7QB.js +564 -0
- package/dist/react/chunk-2OQXI7QB.js.map +7 -0
- package/dist/react/chunk-5OUBTHHO.js +187 -0
- package/dist/react/chunk-5OUBTHHO.js.map +7 -0
- package/dist/react/chunk-6PFXZKL2.js +628 -0
- package/dist/react/chunk-6PFXZKL2.js.map +7 -0
- package/dist/react/chunk-6SFNWGGZ.js +453 -0
- package/dist/react/chunk-6SFNWGGZ.js.map +7 -0
- package/dist/react/chunk-7TZSIR6V.js +210 -0
- package/dist/react/chunk-7TZSIR6V.js.map +7 -0
- package/dist/react/chunk-AJAZC37E.js +662 -0
- package/dist/react/chunk-AJAZC37E.js.map +7 -0
- package/dist/react/chunk-BU4D2WYQ.js +1213 -0
- package/dist/react/chunk-BU4D2WYQ.js.map +7 -0
- package/dist/react/chunk-BZE4CEBG.js +747 -0
- package/dist/react/chunk-BZE4CEBG.js.map +7 -0
- package/dist/react/chunk-CB2RANCB.js +212 -0
- package/dist/react/chunk-CB2RANCB.js.map +7 -0
- package/dist/react/chunk-DNAG7ML6.js +128 -0
- package/dist/react/chunk-DNAG7ML6.js.map +7 -0
- package/dist/react/chunk-HZWLPXFN.js +198 -0
- package/dist/react/chunk-HZWLPXFN.js.map +7 -0
- package/dist/react/chunk-I6HCCIXB.js +572 -0
- package/dist/react/chunk-I6HCCIXB.js.map +7 -0
- package/dist/react/chunk-IZ5OGWGW.js +235 -0
- package/dist/react/chunk-IZ5OGWGW.js.map +7 -0
- package/dist/react/chunk-JJCJNLNN.js +1490 -0
- package/dist/react/chunk-JJCJNLNN.js.map +7 -0
- package/dist/react/chunk-JQ3IRFDP.js +222 -0
- package/dist/react/chunk-JQ3IRFDP.js.map +7 -0
- package/dist/react/chunk-L5OARZJ7.js +1134 -0
- package/dist/react/chunk-L5OARZJ7.js.map +7 -0
- package/dist/react/chunk-LHRTXNVE.js +1600 -0
- package/dist/react/chunk-LHRTXNVE.js.map +7 -0
- package/dist/react/chunk-Q2GA4MBZ.js +1653 -0
- package/dist/react/chunk-Q2GA4MBZ.js.map +7 -0
- package/dist/react/chunk-QNSE5BAY.js +519 -0
- package/dist/react/chunk-QNSE5BAY.js.map +7 -0
- package/dist/react/chunk-QXFBG7OM.js +191 -0
- package/dist/react/chunk-QXFBG7OM.js.map +7 -0
- package/dist/react/chunk-T6ZVV5ZO.js +714 -0
- package/dist/react/chunk-T6ZVV5ZO.js.map +7 -0
- package/dist/react/chunk-URB6MY46.js +974 -0
- package/dist/react/chunk-URB6MY46.js.map +7 -0
- package/dist/react/chunk-VN62KLOC.js +931 -0
- package/dist/react/chunk-VN62KLOC.js.map +7 -0
- package/dist/react/chunk-VQVEPJSA.js +158 -0
- package/dist/react/chunk-VQVEPJSA.js.map +7 -0
- package/dist/react/chunk-XISEAGBV.js +1632 -0
- package/dist/react/chunk-XISEAGBV.js.map +7 -0
- package/dist/react/chunk-YKJUBFHE.js +575 -0
- package/dist/react/chunk-YKJUBFHE.js.map +7 -0
- package/dist/react/circleTool-NUATSEI2.js +14 -0
- package/dist/react/circleTool-NUATSEI2.js.map +7 -0
- package/dist/react/codeTool-MHCB2FNB.js +38 -0
- package/dist/react/codeTool-MHCB2FNB.js.map +7 -0
- package/dist/react/eraserTool-2GS2LQCS.js +103 -0
- package/dist/react/eraserTool-2GS2LQCS.js.map +7 -0
- package/dist/react/frameTool-PWVKKXSP.js +14 -0
- package/dist/react/frameTool-PWVKKXSP.js.map +7 -0
- package/dist/react/freehandTool-SLYGASVP.js +14 -0
- package/dist/react/freehandTool-SLYGASVP.js.map +7 -0
- package/dist/react/iconTool-GPZ7O7NH.js +18 -0
- package/dist/react/iconTool-GPZ7O7NH.js.map +7 -0
- package/dist/react/imageTool-D5R4XGEU.js +15 -0
- package/dist/react/imageTool-D5R4XGEU.js.map +7 -0
- package/dist/react/index.js +5342 -0
- package/dist/react/index.js.map +7 -0
- package/dist/react/laserTool-XVMV63AV.js +239 -0
- package/dist/react/laserTool-XVMV63AV.js.map +7 -0
- package/dist/react/lineTool-WNI5EMZ5.js +14 -0
- package/dist/react/lineTool-WNI5EMZ5.js.map +7 -0
- package/dist/react/lixCode-OJMVUXXI.ttf +0 -0
- package/dist/react/lixDefault-JEAPAUJL.ttf +0 -0
- package/dist/react/lixFancy-BPXYM5CQ.ttf +0 -0
- package/dist/react/lixFont-CPKEUDVM.woff2 +0 -0
- package/dist/react/rectangleTool-U7DZ6ZTA.js +14 -0
- package/dist/react/rectangleTool-U7DZ6ZTA.js.map +7 -0
- package/dist/react/styles.css +6627 -0
- package/dist/react/textTool-M7S6F3VC.js +21 -0
- package/dist/react/textTool-M7S6F3VC.js.map +7 -0
- package/package.json +39 -5
- package/src/EngineShortcuts.js +83 -27
- package/src/core/AIRenderer.js +30 -18
- package/src/core/CopyPaste.js +22 -3
- package/src/core/GraphEngine.js +64 -41
- package/src/core/MermaidFlowchartRenderer.js +153 -88
- package/src/core/MermaidSequenceRenderer.js +168 -93
- package/src/core/SceneSerializer.js +86 -2
- package/src/core/Selection.js +119 -19
- package/src/core/UndoRedo.js +82 -15
- package/src/core/ZoomPan.js +15 -5
- package/src/index.js +25 -1
- package/src/react/LixSketchCanvas.jsx +347 -0
- package/src/react/components/AppMenu.jsx +475 -0
- package/src/react/components/Footer.jsx +85 -0
- package/src/react/components/Toolbar.jsx +140 -0
- package/src/react/components/canvas/CanvasLoadingOverlay.jsx +76 -0
- package/src/react/components/canvas/ContextMenu.jsx +466 -0
- package/src/react/components/canvas/FindBar.jsx +177 -0
- package/src/react/components/canvas/ImageSourcePicker.jsx +133 -0
- package/src/react/components/canvas/MultiSelectActions.jsx +120 -0
- package/src/react/components/canvas/SVGCanvas.jsx +145 -0
- package/src/react/components/canvas/SaveStatusIndicator.jsx +29 -0
- package/src/react/components/modals/CanvasPropertiesModal.jsx +358 -0
- package/src/react/components/modals/CommandPalette.jsx +307 -0
- package/src/react/components/modals/ExportImageModal.jsx +287 -0
- package/src/react/components/modals/GraphModal.jsx +174 -0
- package/src/react/components/modals/HelpModal.jsx +208 -0
- package/src/react/components/modals/LixScriptModal.jsx +130 -0
- package/src/react/components/modals/ShortcutsModal.jsx +125 -0
- package/src/react/components/sidebars/ArrowSidebar.jsx +173 -0
- package/src/react/components/sidebars/CircleSidebar.jsx +134 -0
- package/src/react/components/sidebars/FrameSidebar.jsx +263 -0
- package/src/react/components/sidebars/IconSidebar.jsx +279 -0
- package/src/react/components/sidebars/ImageSidebar.jsx +69 -0
- package/src/react/components/sidebars/LineSidebar.jsx +109 -0
- package/src/react/components/sidebars/PaintbrushSidebar.jsx +119 -0
- package/src/react/components/sidebars/RectangleSidebar.jsx +165 -0
- package/src/react/components/sidebars/ShapeSidebar.jsx +130 -0
- package/src/react/components/sidebars/TextSidebar.jsx +174 -0
- package/src/react/hooks/inertStores.js +58 -0
- package/src/react/hooks/useSketchEngine.js +76 -0
- package/src/react/hooks/useTranslation.js +92 -0
- package/src/react/index.js +41 -0
- package/src/react/store/useSketchStore.js +234 -0
- package/src/react/store/useUIStore.js +196 -0
- package/src/react/styles/arrowSidebar.css +263 -0
- package/src/react/styles/canvasStroke.css +47 -0
- package/src/react/styles/canvasTools.css +769 -0
- package/src/react/styles/circleSidebar.css +206 -0
- package/src/react/styles/fonts/fonts.css +29 -0
- package/src/react/styles/fonts/lixCode.ttf +0 -0
- package/src/react/styles/fonts/lixDefault.ttf +0 -0
- package/src/react/styles/fonts/lixDocs.ttf +0 -0
- package/src/react/styles/fonts/lixFancy.ttf +0 -0
- package/src/react/styles/fonts/lixFont.woff2 +0 -0
- package/src/react/styles/lineSidebar.css +207 -0
- package/src/react/styles/paintbrushSidebar.css +247 -0
- package/src/react/styles/squareSidebar.css +206 -0
- package/src/react/styles/writeText.css +149 -0
- package/src/react/styles.css +175 -0
- package/src/react/toolsEnum.js +20 -0
- package/src/react/utils/toast.js +18 -0
- package/src/shapes/Frame.js +7 -1
- package/src/shapes/Line.js +11 -5
- package/src/tools/arrowTool.js +30 -4
- package/src/tools/circleTool.js +33 -9
- package/src/tools/codeTool.js +5 -3
- package/src/tools/frameTool.js +47 -7
- package/src/tools/freehandTool.js +12 -4
- package/src/tools/iconTool.js +7 -1
- package/src/tools/imageTool.js +56 -22
- package/src/tools/lineTool.js +27 -3
- package/src/tools/rectangleTool.js +45 -8
- package/src/tools/textTool.js +23 -6
- package/src/utils/allowedImageTypes.js +53 -0
package/src/tools/textTool.js
CHANGED
|
@@ -11,6 +11,8 @@ import {
|
|
|
11
11
|
updateSelectedElement
|
|
12
12
|
} from '../core/UndoRedo.js';
|
|
13
13
|
import { cleanupAttachments, updateAttachedArrows } from './arrowTool.js';
|
|
14
|
+
|
|
15
|
+
function getThemeStroke() { if (typeof document === "undefined") return "#fff"; return document.body && document.body.classList.contains("theme-dark") ? "#fff" : "#1a1a2e"; }
|
|
14
16
|
import {
|
|
15
17
|
addCodeBlock,
|
|
16
18
|
wrapCodeElement,
|
|
@@ -27,7 +29,7 @@ import {
|
|
|
27
29
|
|
|
28
30
|
let textSize = "30px";
|
|
29
31
|
let textFont = "lixFont";
|
|
30
|
-
let textColor =
|
|
32
|
+
let textColor = null;
|
|
31
33
|
let textAlign = "left";
|
|
32
34
|
|
|
33
35
|
let textColorOptions = document.querySelectorAll(".textColorSpan");
|
|
@@ -118,20 +120,27 @@ function addText(event) {
|
|
|
118
120
|
|
|
119
121
|
textElement.setAttribute("x", 0);
|
|
120
122
|
textElement.setAttribute("y", 0);
|
|
121
|
-
textElement.setAttribute("fill", textColor);
|
|
123
|
+
textElement.setAttribute("fill", textColor ?? getThemeStroke());
|
|
122
124
|
textElement.setAttribute("font-size", textSize);
|
|
123
125
|
textElement.setAttribute("font-family", textFont);
|
|
124
126
|
textElement.setAttribute("text-anchor", textAlignElement);
|
|
125
127
|
textElement.setAttribute("cursor", "default");
|
|
126
128
|
textElement.setAttribute("white-space", "pre");
|
|
127
129
|
textElement.setAttribute("dominant-baseline", "hanging");
|
|
130
|
+
// Issue #34 bug #5b: SVG <text> only fires pointer events on the
|
|
131
|
+
// painted glyphs by default — so a click between letters or in the
|
|
132
|
+
// padding around the text never bubbles to the <g> and the selection
|
|
133
|
+
// tool can't pick the shape up. `bounding-box` extends the hit area
|
|
134
|
+
// to the entire bounding box (SVG 2; supported in Chromium/WebKit/
|
|
135
|
+
// Firefox), which is what every other shape tool relies on.
|
|
136
|
+
textElement.setAttribute("pointer-events", "bounding-box");
|
|
128
137
|
textElement.textContent = "";
|
|
129
138
|
|
|
130
139
|
gElement.setAttribute("data-x", x);
|
|
131
140
|
gElement.setAttribute("data-y", y);
|
|
132
141
|
textElement.setAttribute("data-initial-size", textSize);
|
|
133
142
|
textElement.setAttribute("data-initial-font", textFont);
|
|
134
|
-
textElement.setAttribute("data-initial-color", textColor);
|
|
143
|
+
textElement.setAttribute("data-initial-color", textColor ?? getThemeStroke());
|
|
135
144
|
textElement.setAttribute("data-initial-align", textAlign);
|
|
136
145
|
textElement.setAttribute("data-type", "text");
|
|
137
146
|
gElement.appendChild(textElement);
|
|
@@ -247,7 +256,12 @@ function makeTextEditable(textElement, groupElement) {
|
|
|
247
256
|
input.style.lineHeight = "1.2em";
|
|
248
257
|
input.style.textAlign = currentAnchor === "middle" ? "center" : currentAnchor === "end" ? "right" : "left";
|
|
249
258
|
input.style.backgroundColor = "transparent";
|
|
250
|
-
|
|
259
|
+
// Issue #34 bug #5a: dashed creation outline that grows with the
|
|
260
|
+
// text — same visual cue the frame tool uses while drawing. Inset
|
|
261
|
+
// padding-box border so the dashes follow the textarea size as the
|
|
262
|
+
// user types instead of clipping behind the glyphs.
|
|
263
|
+
input.style.border = "1px dashed rgba(255,255,255,0.55)";
|
|
264
|
+
input.style.borderRadius = "3px";
|
|
251
265
|
input.style.outline = "none";
|
|
252
266
|
document.body.appendChild(input);
|
|
253
267
|
|
|
@@ -1001,11 +1015,14 @@ const handleMouseUp = (event) => {
|
|
|
1001
1015
|
rotation: extractRotationFromTransform(selectedElement) || 0,
|
|
1002
1016
|
parentFrame: draggedShapeInitialFrameText
|
|
1003
1017
|
};
|
|
1018
|
+
// Issue #34 bug #2: hoveredFrameText is the actual destination
|
|
1019
|
+
// tracked during drag — textShape.parentFrame is still the OLD
|
|
1020
|
+
// frame at this point.
|
|
1004
1021
|
const newPosWithFrame = {
|
|
1005
1022
|
x: finalTranslateX,
|
|
1006
1023
|
y: finalTranslateY,
|
|
1007
1024
|
rotation: extractRotationFromTransform(selectedElement) || 0,
|
|
1008
|
-
parentFrame:
|
|
1025
|
+
parentFrame: hoveredFrameText || null,
|
|
1009
1026
|
};
|
|
1010
1027
|
|
|
1011
1028
|
const stateChanged = initialX !== finalTranslateX || initialY !== finalTranslateY;
|
|
@@ -1837,4 +1854,4 @@ window.__setCodeLanguage = function(lang) {
|
|
|
1837
1854
|
}
|
|
1838
1855
|
};
|
|
1839
1856
|
|
|
1840
|
-
export { handleTextMouseDown, handleTextMouseMove, handleTextMouseUp, updateCodeToggleForShape, deselectElement as deselectTextElement, enterEditMode };
|
|
1857
|
+
export { handleTextMouseDown, handleTextMouseMove, handleTextMouseUp, updateCodeToggleForShape, deselectElement as deselectTextElement, enterEditMode };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical allowlist for image uploads across LixSketch and any embedding
|
|
3
|
+
* host (e.g. blogs.elixpo). Anything not in this list is rejected at file
|
|
4
|
+
* pick / paste / drop time and again at the server boundary.
|
|
5
|
+
*
|
|
6
|
+
* Static raster + vector formats only. Animated GIF is intentionally excluded
|
|
7
|
+
* (animation isn't supported by the SVG renderer or the blog reader); HEIC,
|
|
8
|
+
* TIFF, video, audio, PDF, and arbitrary files are excluded by omission.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export const ALLOWED_IMAGE_MIME_TYPES = Object.freeze([
|
|
12
|
+
'image/avif',
|
|
13
|
+
'image/jpeg',
|
|
14
|
+
'image/png',
|
|
15
|
+
'image/bmp',
|
|
16
|
+
'image/svg+xml',
|
|
17
|
+
'image/webp',
|
|
18
|
+
]);
|
|
19
|
+
|
|
20
|
+
export const ALLOWED_IMAGE_EXTENSIONS = Object.freeze([
|
|
21
|
+
'.avif',
|
|
22
|
+
'.jpeg',
|
|
23
|
+
'.jpg',
|
|
24
|
+
'.png',
|
|
25
|
+
'.bmp',
|
|
26
|
+
'.svg',
|
|
27
|
+
'.webp',
|
|
28
|
+
]);
|
|
29
|
+
|
|
30
|
+
/** Comma-joined value suitable for an <input accept="…"> attribute. */
|
|
31
|
+
export const IMAGE_ACCEPT_ATTR = ALLOWED_IMAGE_MIME_TYPES.join(',');
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Validate a File / Blob against the allowlist by mime type, falling back
|
|
35
|
+
* to extension matching when the browser doesn't fill in `type` (some
|
|
36
|
+
* drag-drop sources, some SVGs).
|
|
37
|
+
*/
|
|
38
|
+
export function isAllowedImage(file) {
|
|
39
|
+
if (!file) return false;
|
|
40
|
+
const type = (file.type || '').toLowerCase();
|
|
41
|
+
if (type && ALLOWED_IMAGE_MIME_TYPES.includes(type)) return true;
|
|
42
|
+
const name = (file.name || '').toLowerCase();
|
|
43
|
+
if (!name) return false;
|
|
44
|
+
return ALLOWED_IMAGE_EXTENSIONS.some((ext) => name.endsWith(ext));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Same check but for a base64 data URL (e.g. from clipboard paste). */
|
|
48
|
+
export function isAllowedImageDataUrl(dataUrl) {
|
|
49
|
+
if (typeof dataUrl !== 'string') return false;
|
|
50
|
+
const m = dataUrl.match(/^data:([^;]+);/i);
|
|
51
|
+
if (!m) return false;
|
|
52
|
+
return ALLOWED_IMAGE_MIME_TYPES.includes(m[1].toLowerCase());
|
|
53
|
+
}
|