@elixpo/lixsketch 5.5.19 → 5.5.21
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/Circle-6POZCUZD.js +9 -0
- package/dist/react/{CopyPaste-JMIXWUUO.js → CopyPaste-FJN7K5LS.js} +43 -14
- package/dist/react/CopyPaste-FJN7K5LS.js.map +7 -0
- package/dist/react/{EventDispatcher-H5EA4KZN.js → EventDispatcher-O7HCQQNM.js} +14 -13
- package/dist/react/{EventDispatcher-H5EA4KZN.js.map → EventDispatcher-O7HCQQNM.js.map} +1 -1
- package/dist/react/Frame-RLSMJJSK.js +11 -0
- package/dist/react/FreehandStroke-U6GYZOM4.js +9 -0
- package/dist/react/{GraphEngine-KQXHNTZQ.js → GraphEngine-MM6ALA2N.js} +105 -148
- package/dist/react/{GraphEngine-KQXHNTZQ.js.map → GraphEngine-MM6ALA2N.js.map} +2 -2
- package/dist/react/IconShape-7OPXAKLK.js +10 -0
- package/dist/react/ImageShape-LRNJQCF3.js +10 -0
- package/dist/react/Line-WWQFBNX5.js +10 -0
- package/dist/react/Rectangle-S7XUKWYD.js +9 -0
- package/dist/react/{SceneSerializer-ARTKPZVR.js → SceneSerializer-GSJR7ZHC.js} +36 -11
- package/dist/react/SceneSerializer-GSJR7ZHC.js.map +7 -0
- package/dist/react/{Selection-YJNZRBON.js → Selection-ZL3G6IAO.js} +5 -4
- package/dist/react/{SketchEngine-ZGYBIZG7.js → SketchEngine-BFLHJPCG.js} +25 -25
- package/dist/react/{UndoRedo-BZ6W4QTV.js → UndoRedo-NL7KLR5B.js} +2 -2
- package/dist/react/{ZoomPan-NYPDJBD5.js → ZoomPan-FAWA5OPS.js} +5 -1
- package/dist/react/ZoomPan-FAWA5OPS.js.map +7 -0
- package/dist/react/{arrowTool-LKFSZKXC.js → arrowTool-CNVGM6RX.js} +3 -3
- package/dist/react/{chunk-RFHMFWVR.js → chunk-2FMFOPGW.js} +5 -6
- package/dist/react/{chunk-RFHMFWVR.js.map → chunk-2FMFOPGW.js.map} +2 -2
- package/dist/react/{chunk-QYNTPZON.js → chunk-2THKDSWW.js} +9 -5
- package/dist/react/chunk-2THKDSWW.js.map +7 -0
- package/dist/react/{chunk-JOPQ27YH.js → chunk-4BLMNGTR.js} +3 -3
- package/dist/react/{chunk-C62SXFBL.js → chunk-4TAS67SL.js} +23 -22
- package/dist/react/chunk-4TAS67SL.js.map +7 -0
- package/dist/react/{chunk-FV3EPR4L.js → chunk-AH4PWNEB.js} +19 -11
- package/dist/react/chunk-AH4PWNEB.js.map +7 -0
- package/dist/react/{chunk-XCJOF6BM.js → chunk-FETTJLCV.js} +5 -1
- package/dist/react/chunk-FETTJLCV.js.map +7 -0
- package/dist/react/{chunk-JJTII2UQ.js → chunk-GC3KTQDA.js} +78 -15
- package/dist/react/chunk-GC3KTQDA.js.map +7 -0
- package/dist/react/{chunk-2V7G2PLX.js → chunk-GPIYXREE.js} +3 -3
- package/dist/react/{chunk-3VSGFP6U.js → chunk-HFQZYCHJ.js} +8 -4
- package/dist/react/chunk-HFQZYCHJ.js.map +7 -0
- package/dist/react/{chunk-C72OHQLE.js → chunk-ILGAFR56.js} +3 -3
- package/dist/react/{chunk-CF7AK4ES.js → chunk-KVAQPCUH.js} +26 -3
- package/dist/react/chunk-KVAQPCUH.js.map +7 -0
- package/dist/react/{chunk-WEWMB35W.js → chunk-OFGJJKPH.js} +3 -3
- package/dist/react/chunk-PAKA6HUX.js +59 -0
- package/dist/react/chunk-PAKA6HUX.js.map +7 -0
- package/dist/react/{chunk-HKYUJUD7.js → chunk-PXFPPO3R.js} +5 -1
- package/dist/react/chunk-PXFPPO3R.js.map +7 -0
- package/dist/react/{chunk-6G3ITAS5.js → chunk-SZD7DKYJ.js} +18 -9
- package/dist/react/chunk-SZD7DKYJ.js.map +7 -0
- package/dist/react/{chunk-N7NZLF6P.js → chunk-TKXKJNTX.js} +5 -1
- package/dist/react/chunk-TKXKJNTX.js.map +7 -0
- package/dist/react/{chunk-MYYBFZD3.js → chunk-U3TB4KRS.js} +45 -6
- package/dist/react/chunk-U3TB4KRS.js.map +7 -0
- package/dist/react/{chunk-UQBT7F4K.js → chunk-V2QTYSBK.js} +2 -2
- package/dist/react/{chunk-73VA5ALZ.js → chunk-XFQECTTF.js} +48 -19
- package/dist/react/chunk-XFQECTTF.js.map +7 -0
- package/dist/react/{chunk-O64N5JPO.js → chunk-YF3TK7SC.js} +2 -2
- package/dist/react/{circleTool-RDOIMKKV.js → circleTool-KICNRQCI.js} +4 -4
- package/dist/react/{codeTool-O2Z7ZXGP.js → codeTool-NCQ73R6M.js} +5 -4
- package/dist/react/{frameTool-Z5ZDCX6H.js → frameTool-Y6KB67DO.js} +4 -4
- package/dist/react/{freehandTool-AAQCTMVM.js → freehandTool-MMULHCQ7.js} +4 -4
- package/dist/react/{iconTool-AUHRLOO2.js → iconTool-LSW2DYGB.js} +5 -4
- package/dist/react/{imageTool-DRKDCPUV.js → imageTool-2DSR32RX.js} +5 -4
- package/dist/react/index.js +141 -66
- package/dist/react/index.js.map +3 -3
- package/dist/react/{lineTool-XLOOZE3E.js → lineTool-N5I7IGT7.js} +4 -4
- package/dist/react/{rectangleTool-AEYDDJCA.js → rectangleTool-YUT7ZK2E.js} +4 -4
- package/dist/react/{textTool-UORBAAJE.js → textTool-IQOYPELP.js} +6 -5
- package/package.json +1 -1
- package/src/core/CopyPaste.js +34 -4
- package/src/core/GraphEngine.js +129 -185
- package/src/core/SceneSerializer.js +26 -0
- package/src/core/ScreenSpaceControls.js +60 -0
- package/src/core/Selection.js +19 -11
- package/src/core/UndoRedo.js +47 -3
- package/src/core/ZoomPan.js +3 -0
- package/src/react/components/canvas/MultiSelectActions.jsx +4 -1
- package/src/react/components/sidebars/IconSidebar.jsx +14 -23
- package/src/react/components/sidebars/ImageSidebar.jsx +47 -24
- package/src/react/store/useUIStore.js +71 -14
- package/src/shapes/Circle.js +2 -0
- package/src/shapes/Frame.js +26 -2
- package/src/shapes/FreehandStroke.js +2 -0
- package/src/shapes/IconShape.js +23 -25
- package/src/shapes/ImageShape.js +6 -2
- package/src/shapes/Rectangle.js +2 -0
- package/src/tools/codeTool.js +3 -2
- package/src/tools/frameTool.js +19 -9
- package/src/tools/iconTool.js +63 -26
- package/src/tools/imageTool.js +80 -14
- package/src/tools/textTool.js +3 -1
- package/dist/react/Circle-QQMKCKFR.js +0 -8
- package/dist/react/CopyPaste-JMIXWUUO.js.map +0 -7
- package/dist/react/Frame-VADA625S.js +0 -10
- package/dist/react/FreehandStroke-BOWDNAVC.js +0 -8
- package/dist/react/IconShape-32EYI2MA.js +0 -10
- package/dist/react/ImageShape-MYP2DVVH.js +0 -10
- package/dist/react/Line-FCCF2BOB.js +0 -10
- package/dist/react/Rectangle-MZ6ZB6KM.js +0 -8
- package/dist/react/SceneSerializer-ARTKPZVR.js.map +0 -7
- package/dist/react/ZoomPan-NYPDJBD5.js.map +0 -7
- package/dist/react/chunk-3VSGFP6U.js.map +0 -7
- package/dist/react/chunk-6G3ITAS5.js.map +0 -7
- package/dist/react/chunk-73VA5ALZ.js.map +0 -7
- package/dist/react/chunk-C62SXFBL.js.map +0 -7
- package/dist/react/chunk-CF7AK4ES.js.map +0 -7
- package/dist/react/chunk-FV3EPR4L.js.map +0 -7
- package/dist/react/chunk-HKYUJUD7.js.map +0 -7
- package/dist/react/chunk-JJTII2UQ.js.map +0 -7
- package/dist/react/chunk-MYYBFZD3.js.map +0 -7
- package/dist/react/chunk-N7NZLF6P.js.map +0 -7
- package/dist/react/chunk-QYNTPZON.js.map +0 -7
- package/dist/react/chunk-XCJOF6BM.js.map +0 -7
- /package/dist/react/{Circle-QQMKCKFR.js.map → Circle-6POZCUZD.js.map} +0 -0
- /package/dist/react/{Frame-VADA625S.js.map → Frame-RLSMJJSK.js.map} +0 -0
- /package/dist/react/{FreehandStroke-BOWDNAVC.js.map → FreehandStroke-U6GYZOM4.js.map} +0 -0
- /package/dist/react/{IconShape-32EYI2MA.js.map → IconShape-7OPXAKLK.js.map} +0 -0
- /package/dist/react/{ImageShape-MYP2DVVH.js.map → ImageShape-LRNJQCF3.js.map} +0 -0
- /package/dist/react/{Line-FCCF2BOB.js.map → Line-WWQFBNX5.js.map} +0 -0
- /package/dist/react/{Rectangle-MZ6ZB6KM.js.map → Rectangle-S7XUKWYD.js.map} +0 -0
- /package/dist/react/{Selection-YJNZRBON.js.map → Selection-ZL3G6IAO.js.map} +0 -0
- /package/dist/react/{SketchEngine-ZGYBIZG7.js.map → SketchEngine-BFLHJPCG.js.map} +0 -0
- /package/dist/react/{UndoRedo-BZ6W4QTV.js.map → UndoRedo-NL7KLR5B.js.map} +0 -0
- /package/dist/react/{arrowTool-LKFSZKXC.js.map → arrowTool-CNVGM6RX.js.map} +0 -0
- /package/dist/react/{chunk-JOPQ27YH.js.map → chunk-4BLMNGTR.js.map} +0 -0
- /package/dist/react/{chunk-2V7G2PLX.js.map → chunk-GPIYXREE.js.map} +0 -0
- /package/dist/react/{chunk-C72OHQLE.js.map → chunk-ILGAFR56.js.map} +0 -0
- /package/dist/react/{chunk-WEWMB35W.js.map → chunk-OFGJJKPH.js.map} +0 -0
- /package/dist/react/{chunk-UQBT7F4K.js.map → chunk-V2QTYSBK.js.map} +0 -0
- /package/dist/react/{chunk-O64N5JPO.js.map → chunk-YF3TK7SC.js.map} +0 -0
- /package/dist/react/{circleTool-RDOIMKKV.js.map → circleTool-KICNRQCI.js.map} +0 -0
- /package/dist/react/{codeTool-O2Z7ZXGP.js.map → codeTool-NCQ73R6M.js.map} +0 -0
- /package/dist/react/{frameTool-Z5ZDCX6H.js.map → frameTool-Y6KB67DO.js.map} +0 -0
- /package/dist/react/{freehandTool-AAQCTMVM.js.map → freehandTool-MMULHCQ7.js.map} +0 -0
- /package/dist/react/{iconTool-AUHRLOO2.js.map → iconTool-LSW2DYGB.js.map} +0 -0
- /package/dist/react/{imageTool-DRKDCPUV.js.map → imageTool-2DSR32RX.js.map} +0 -0
- /package/dist/react/{lineTool-XLOOZE3E.js.map → lineTool-N5I7IGT7.js.map} +0 -0
- /package/dist/react/{rectangleTool-AEYDDJCA.js.map → rectangleTool-YUT7ZK2E.js.map} +0 -0
- /package/dist/react/{textTool-UORBAAJE.js.map → textTool-IQOYPELP.js.map} +0 -0
package/dist/react/index.js
CHANGED
|
@@ -278,24 +278,78 @@ function invertShapeColors(prevResolved, nextResolved) {
|
|
|
278
278
|
};
|
|
279
279
|
for (const shape of shapes) {
|
|
280
280
|
let changed = false;
|
|
281
|
-
if (shape.
|
|
282
|
-
|
|
283
|
-
|
|
281
|
+
if (shape.shapeName === "icon" || shape.type === "icon") {
|
|
282
|
+
const isDark = nextResolved === "dark";
|
|
283
|
+
const targetDarkColor = "#1a1a2e";
|
|
284
|
+
const bgDarkColor = "#15111f";
|
|
285
|
+
if (shape.group) {
|
|
286
|
+
shape.group.querySelectorAll("*").forEach((element) => {
|
|
287
|
+
if (element.nodeType === 1) {
|
|
288
|
+
const fill = element.getAttribute("fill");
|
|
289
|
+
const stroke = element.getAttribute("stroke");
|
|
290
|
+
if (fill && fill !== "none" && fill !== "transparent") {
|
|
291
|
+
const normFill = fill.toLowerCase().trim();
|
|
292
|
+
if (isDark) {
|
|
293
|
+
if (normFill === targetDarkColor || normFill === "#000000" || normFill === "#000") {
|
|
294
|
+
element.setAttribute("fill", "#ffffff");
|
|
295
|
+
changed = true;
|
|
296
|
+
} else if (normFill === "#ffffff" || normFill === "#fff") {
|
|
297
|
+
element.setAttribute("fill", bgDarkColor);
|
|
298
|
+
changed = true;
|
|
299
|
+
}
|
|
300
|
+
} else {
|
|
301
|
+
if (normFill === "#ffffff" || normFill === "#fff") {
|
|
302
|
+
element.setAttribute("fill", targetDarkColor);
|
|
303
|
+
changed = true;
|
|
304
|
+
} else if (normFill === bgDarkColor) {
|
|
305
|
+
element.setAttribute("fill", "#ffffff");
|
|
306
|
+
changed = true;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
if (stroke && stroke !== "none" && stroke !== "transparent") {
|
|
311
|
+
const normStroke = stroke.toLowerCase().trim();
|
|
312
|
+
if (isDark) {
|
|
313
|
+
if (normStroke === targetDarkColor || normStroke === "#000000" || normStroke === "#000") {
|
|
314
|
+
element.setAttribute("stroke", "#ffffff");
|
|
315
|
+
changed = true;
|
|
316
|
+
} else if (normStroke === "#ffffff" || normStroke === "#fff") {
|
|
317
|
+
element.setAttribute("stroke", bgDarkColor);
|
|
318
|
+
changed = true;
|
|
319
|
+
}
|
|
320
|
+
} else {
|
|
321
|
+
if (normStroke === "#ffffff" || normStroke === "#fff") {
|
|
322
|
+
element.setAttribute("stroke", targetDarkColor);
|
|
323
|
+
changed = true;
|
|
324
|
+
} else if (normStroke === bgDarkColor) {
|
|
325
|
+
element.setAttribute("stroke", "#ffffff");
|
|
326
|
+
changed = true;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
} else {
|
|
334
|
+
if (shape.options) {
|
|
335
|
+
if (normalize(shape.options.stroke) === from) {
|
|
336
|
+
shape.options.stroke = to;
|
|
337
|
+
changed = true;
|
|
338
|
+
}
|
|
339
|
+
if (normalize(shape.options.fill) === from) {
|
|
340
|
+
shape.options.fill = to;
|
|
341
|
+
changed = true;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
if (shape.color !== void 0 && normalize(shape.color) === from) {
|
|
345
|
+
shape.color = to;
|
|
284
346
|
changed = true;
|
|
285
347
|
}
|
|
286
|
-
if (normalize(shape.
|
|
287
|
-
shape.
|
|
348
|
+
if (shape.strokeColor !== void 0 && normalize(shape.strokeColor) === from) {
|
|
349
|
+
shape.strokeColor = to;
|
|
288
350
|
changed = true;
|
|
289
351
|
}
|
|
290
352
|
}
|
|
291
|
-
if (shape.color !== void 0 && normalize(shape.color) === from) {
|
|
292
|
-
shape.color = to;
|
|
293
|
-
changed = true;
|
|
294
|
-
}
|
|
295
|
-
if (shape.strokeColor !== void 0 && normalize(shape.strokeColor) === from) {
|
|
296
|
-
shape.strokeColor = to;
|
|
297
|
-
changed = true;
|
|
298
|
-
}
|
|
299
353
|
if (changed && typeof shape.draw === "function") {
|
|
300
354
|
shape.draw();
|
|
301
355
|
}
|
|
@@ -474,7 +528,7 @@ function useSketchEngine(svgRef, ready = true) {
|
|
|
474
528
|
setZoom: (zoom) => useSketchStore_default.setState({ zoom }),
|
|
475
529
|
getState: () => useSketchStore_default.getState()
|
|
476
530
|
};
|
|
477
|
-
const { SketchEngine } = await import("./SketchEngine-
|
|
531
|
+
const { SketchEngine } = await import("./SketchEngine-BFLHJPCG.js");
|
|
478
532
|
if (cancelled) return;
|
|
479
533
|
const engine = new SketchEngine(svgRef.current);
|
|
480
534
|
await engine.init();
|
|
@@ -2798,6 +2852,13 @@ function IconSidebar() {
|
|
|
2798
2852
|
const [icons, setIcons] = useState12([]);
|
|
2799
2853
|
const [loading, setLoading] = useState12(false);
|
|
2800
2854
|
const debounceRef = useRef5(null);
|
|
2855
|
+
const searchInputRef = useRef5(null);
|
|
2856
|
+
const requestSequenceRef = useRef5(0);
|
|
2857
|
+
useEffect8(() => {
|
|
2858
|
+
if (!visible) return;
|
|
2859
|
+
const frame = requestAnimationFrame(() => searchInputRef.current?.focus());
|
|
2860
|
+
return () => cancelAnimationFrame(frame);
|
|
2861
|
+
}, [visible]);
|
|
2801
2862
|
useEffect8(() => {
|
|
2802
2863
|
if (!visible) return;
|
|
2803
2864
|
const handler = (e) => {
|
|
@@ -2818,6 +2879,7 @@ function IconSidebar() {
|
|
|
2818
2879
|
return () => svgEl.removeEventListener("mousedown", handleCanvasClick);
|
|
2819
2880
|
}, [visible, setActiveTool]);
|
|
2820
2881
|
const fetchIcons = useCallback9(async (searchQuery, cat) => {
|
|
2882
|
+
const requestSequence = ++requestSequenceRef.current;
|
|
2821
2883
|
const params = new URLSearchParams();
|
|
2822
2884
|
if (searchQuery) params.set("q", searchQuery);
|
|
2823
2885
|
if (cat) params.set("category", cat);
|
|
@@ -2825,6 +2887,7 @@ function IconSidebar() {
|
|
|
2825
2887
|
const cacheKey = params.toString();
|
|
2826
2888
|
if (iconResultCache.has(cacheKey)) {
|
|
2827
2889
|
setIcons(iconResultCache.get(cacheKey));
|
|
2890
|
+
setLoading(false);
|
|
2828
2891
|
return;
|
|
2829
2892
|
}
|
|
2830
2893
|
setLoading(true);
|
|
@@ -2834,38 +2897,21 @@ function IconSidebar() {
|
|
|
2834
2897
|
const data = await res.json();
|
|
2835
2898
|
const results = data.results || [];
|
|
2836
2899
|
iconResultCache.set(cacheKey, results);
|
|
2837
|
-
setIcons(results);
|
|
2900
|
+
if (requestSequence === requestSequenceRef.current) setIcons(results);
|
|
2838
2901
|
}
|
|
2839
2902
|
} catch (err) {
|
|
2840
2903
|
console.error("Icon fetch failed:", err);
|
|
2841
2904
|
}
|
|
2842
|
-
setLoading(false);
|
|
2905
|
+
if (requestSequence === requestSequenceRef.current) setLoading(false);
|
|
2843
2906
|
}, []);
|
|
2844
2907
|
useEffect8(() => {
|
|
2845
2908
|
if (!visible) return;
|
|
2846
2909
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
2847
2910
|
debounceRef.current = setTimeout(() => {
|
|
2848
2911
|
fetchIcons(query, category);
|
|
2849
|
-
}, query ?
|
|
2912
|
+
}, query ? 80 : 0);
|
|
2850
2913
|
return () => clearTimeout(debounceRef.current);
|
|
2851
2914
|
}, [query, visible, category, fetchIcons]);
|
|
2852
|
-
const hasPreloaded = useRef5(false);
|
|
2853
|
-
useEffect8(() => {
|
|
2854
|
-
if (!visible || hasPreloaded.current) return;
|
|
2855
|
-
hasPreloaded.current = true;
|
|
2856
|
-
CATEGORIES.forEach((cat) => {
|
|
2857
|
-
const params = new URLSearchParams();
|
|
2858
|
-
if (cat.value) params.set("category", cat.value);
|
|
2859
|
-
params.set("inline", "1");
|
|
2860
|
-
const key = params.toString();
|
|
2861
|
-
if (!iconResultCache.has(key)) {
|
|
2862
|
-
fetch(`${getIconsBaseUrl()}/api/icons/search?${key}`).then((r) => r.ok ? r.json() : null).then((data) => {
|
|
2863
|
-
if (data?.results) iconResultCache.set(key, data.results);
|
|
2864
|
-
}).catch(() => {
|
|
2865
|
-
});
|
|
2866
|
-
}
|
|
2867
|
-
});
|
|
2868
|
-
}, [visible]);
|
|
2869
2915
|
const handleIconClick = useCallback9((icon) => {
|
|
2870
2916
|
if (typeof window === "undefined") return;
|
|
2871
2917
|
const place = (svgContent) => {
|
|
@@ -2905,6 +2951,7 @@ function IconSidebar() {
|
|
|
2905
2951
|
/* @__PURE__ */ jsx14(
|
|
2906
2952
|
"input",
|
|
2907
2953
|
{
|
|
2954
|
+
ref: searchInputRef,
|
|
2908
2955
|
id: "iconSearchInput",
|
|
2909
2956
|
type: "text",
|
|
2910
2957
|
value: query,
|
|
@@ -2967,11 +3014,19 @@ function IconSidebar() {
|
|
|
2967
3014
|
|
|
2968
3015
|
// src/react/components/sidebars/ImageSidebar.jsx
|
|
2969
3016
|
import { useCallback as useCallback10 } from "react";
|
|
2970
|
-
import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3017
|
+
import { Fragment as Fragment8, jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2971
3018
|
function ImageSidebar() {
|
|
2972
3019
|
const { t } = useTranslation();
|
|
2973
3020
|
const selectedShapeSidebar = useSketchStore_default((s) => s.selectedShapeSidebar);
|
|
2974
3021
|
const toggleImageGenerateModal = useUIStore_default((s) => s.toggleImageGenerateModal);
|
|
3022
|
+
const toggleAIModal = useUIStore_default((s) => s.toggleAIModal);
|
|
3023
|
+
const isGraph = typeof window !== "undefined" && window.currentShape?._frameType === "graph";
|
|
3024
|
+
const handleEditGraph = useCallback10(() => {
|
|
3025
|
+
const shape = window.currentShape;
|
|
3026
|
+
if (!shape || shape._frameType !== "graph") return;
|
|
3027
|
+
window.__aiEditTargetFrame = shape;
|
|
3028
|
+
toggleAIModal();
|
|
3029
|
+
}, [toggleAIModal]);
|
|
2975
3030
|
const handleEditWithAI = useCallback10(() => {
|
|
2976
3031
|
const shape = window.currentShape;
|
|
2977
3032
|
if (!shape || shape.shapeName !== "image") return;
|
|
@@ -2989,32 +3044,49 @@ function ImageSidebar() {
|
|
|
2989
3044
|
}
|
|
2990
3045
|
}, []);
|
|
2991
3046
|
return /* @__PURE__ */ jsxs15(ShapeSidebar, { visible: selectedShapeSidebar === "image", children: [
|
|
2992
|
-
/* @__PURE__ */ jsxs15(
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3047
|
+
isGraph && /* @__PURE__ */ jsxs15(Fragment8, { children: [
|
|
3048
|
+
/* @__PURE__ */ jsxs15(
|
|
3049
|
+
"button",
|
|
3050
|
+
{
|
|
3051
|
+
onClick: handleEditGraph,
|
|
3052
|
+
title: "Edit graph",
|
|
3053
|
+
className: "h-9 flex cursor-pointer items-center gap-1.5 px-3 rounded-lg text-text-muted hover:text-accent hover:bg-accent/10 transition-all duration-100",
|
|
3054
|
+
children: [
|
|
3055
|
+
/* @__PURE__ */ jsx15("i", { className: "bx bx-line-chart text-base" }),
|
|
3056
|
+
/* @__PURE__ */ jsx15("span", { className: "text-xs", children: "Edit graph" })
|
|
3057
|
+
]
|
|
3058
|
+
}
|
|
3059
|
+
),
|
|
3060
|
+
/* @__PURE__ */ jsx15(Divider, {})
|
|
3061
|
+
] }),
|
|
3062
|
+
!isGraph && /* @__PURE__ */ jsxs15(Fragment8, { children: [
|
|
3063
|
+
/* @__PURE__ */ jsxs15(
|
|
3064
|
+
"button",
|
|
3065
|
+
{
|
|
3066
|
+
onClick: handleEditWithAI,
|
|
3067
|
+
title: "Edit with AI",
|
|
3068
|
+
className: "h-9 flex items-center gap-1.5 px-3 rounded-lg text-text-muted hover:text-purple-400 hover:bg-purple-500/10 transition-all duration-100",
|
|
3069
|
+
children: [
|
|
3070
|
+
/* @__PURE__ */ jsx15("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor", stroke: "none", children: /* @__PURE__ */ jsx15("path", { d: "M12 2l2.4 7.2L22 12l-7.6 2.8L12 22l-2.4-7.2L2 12l7.6-2.8L12 2z" }) }),
|
|
3071
|
+
/* @__PURE__ */ jsx15("span", { className: "text-xs", children: "AI Edit" })
|
|
3072
|
+
]
|
|
3073
|
+
}
|
|
3074
|
+
),
|
|
3075
|
+
/* @__PURE__ */ jsx15(Divider, {}),
|
|
3076
|
+
/* @__PURE__ */ jsxs15(
|
|
3077
|
+
"button",
|
|
3078
|
+
{
|
|
3079
|
+
onClick: handleReplace,
|
|
3080
|
+
title: "Replace image",
|
|
3081
|
+
className: "h-9 flex items-center gap-1.5 px-3 rounded-lg text-text-muted hover:text-white hover:bg-white/[0.06] transition-all duration-100",
|
|
3082
|
+
children: [
|
|
3083
|
+
/* @__PURE__ */ jsx15("i", { className: "bx bx-upload text-base" }),
|
|
3084
|
+
/* @__PURE__ */ jsx15("span", { className: "text-xs", children: "Replace" })
|
|
3085
|
+
]
|
|
3086
|
+
}
|
|
3087
|
+
),
|
|
3088
|
+
/* @__PURE__ */ jsx15(Divider, {})
|
|
3089
|
+
] }),
|
|
3018
3090
|
/* @__PURE__ */ jsx15(LayerControls, {})
|
|
3019
3091
|
] });
|
|
3020
3092
|
}
|
|
@@ -3050,6 +3122,7 @@ import { jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
|
3050
3122
|
function MultiSelectActions() {
|
|
3051
3123
|
const [count, setCount] = useState13(0);
|
|
3052
3124
|
const [groupState, setGroupState] = useState13("none");
|
|
3125
|
+
const [frameEligible, setFrameEligible] = useState13(false);
|
|
3053
3126
|
useEffect9(() => {
|
|
3054
3127
|
const interval = setInterval(() => {
|
|
3055
3128
|
const ms = window.multiSelection;
|
|
@@ -3058,6 +3131,7 @@ function MultiSelectActions() {
|
|
|
3058
3131
|
setCount((prev) => prev !== n ? n : prev);
|
|
3059
3132
|
if (n < 2) {
|
|
3060
3133
|
setGroupState("none");
|
|
3134
|
+
setFrameEligible(false);
|
|
3061
3135
|
return;
|
|
3062
3136
|
}
|
|
3063
3137
|
let withId = 0;
|
|
@@ -3068,6 +3142,7 @@ function MultiSelectActions() {
|
|
|
3068
3142
|
groupIds.add(s.groupId);
|
|
3069
3143
|
}
|
|
3070
3144
|
});
|
|
3145
|
+
setFrameEligible(Array.from(sel).every((s) => s.shapeName !== "frame" && !s.parentFrame));
|
|
3071
3146
|
if (withId === n && groupIds.size === 1) setGroupState("all");
|
|
3072
3147
|
else if (withId > 0) setGroupState("partial");
|
|
3073
3148
|
else setGroupState("none");
|
|
@@ -3119,7 +3194,7 @@ function MultiSelectActions() {
|
|
|
3119
3194
|
grouped && /* @__PURE__ */ jsx16("span", { className: "ml-1 text-accent-blue", children: "\xB7 grouped" })
|
|
3120
3195
|
] }),
|
|
3121
3196
|
/* @__PURE__ */ jsx16("div", { className: "w-px h-4 bg-border-light" }),
|
|
3122
|
-
!grouped && /* @__PURE__ */ jsxs16(
|
|
3197
|
+
!grouped && frameEligible && /* @__PURE__ */ jsxs16(
|
|
3123
3198
|
"button",
|
|
3124
3199
|
{
|
|
3125
3200
|
onClick: handleFrame,
|
|
@@ -3159,7 +3234,7 @@ function MultiSelectActions() {
|
|
|
3159
3234
|
|
|
3160
3235
|
// src/react/components/canvas/ContextMenu.jsx
|
|
3161
3236
|
import { useState as useState14, useEffect as useEffect10, useCallback as useCallback11, useRef as useRef6 } from "react";
|
|
3162
|
-
import { Fragment as
|
|
3237
|
+
import { Fragment as Fragment9, jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
3163
3238
|
function getCleanSVG() {
|
|
3164
3239
|
const svgEl = window.svg;
|
|
3165
3240
|
if (!svgEl) return null;
|
|
@@ -3504,7 +3579,7 @@ function ContextMenu() {
|
|
|
3504
3579
|
onClick: (e) => e.stopPropagation(),
|
|
3505
3580
|
children: isShape ? (
|
|
3506
3581
|
/* ── Shape context menu ── */
|
|
3507
|
-
/* @__PURE__ */ jsxs17(
|
|
3582
|
+
/* @__PURE__ */ jsxs17(Fragment9, { children: [
|
|
3508
3583
|
/* @__PURE__ */ jsx17(MenuItem, { label: "Cut", shortcut: "Ctrl+X", onClick: handleCut }),
|
|
3509
3584
|
/* @__PURE__ */ jsx17(MenuItem, { label: "Copy", shortcut: "Ctrl+C", onClick: handleCopy }),
|
|
3510
3585
|
/* @__PURE__ */ jsx17(MenuItem, { label: "Paste", shortcut: "Ctrl+V", onClick: handlePaste }),
|
|
@@ -3529,7 +3604,7 @@ function ContextMenu() {
|
|
|
3529
3604
|
] })
|
|
3530
3605
|
) : (
|
|
3531
3606
|
/* ── Canvas context menu ── */
|
|
3532
|
-
/* @__PURE__ */ jsxs17(
|
|
3607
|
+
/* @__PURE__ */ jsxs17(Fragment9, { children: [
|
|
3533
3608
|
/* @__PURE__ */ jsx17(MenuItem, { label: "Paste", shortcut: "Ctrl+V", onClick: handlePaste }),
|
|
3534
3609
|
/* @__PURE__ */ jsx17(MenuItem, { label: "Copy to clipboard as PNG", shortcut: "Shift+Alt+C", onClick: handleCopyPNG }),
|
|
3535
3610
|
/* @__PURE__ */ jsx17(MenuItem, { label: "Copy to clipboard as SVG", onClick: handleCopySVG }),
|
|
@@ -4713,7 +4788,7 @@ var _saveScene = null;
|
|
|
4713
4788
|
var _loadScene = null;
|
|
4714
4789
|
async function ensureSceneSerializer() {
|
|
4715
4790
|
if (_saveScene && _loadScene) return;
|
|
4716
|
-
const m = await import("./SceneSerializer-
|
|
4791
|
+
const m = await import("./SceneSerializer-GSJR7ZHC.js");
|
|
4717
4792
|
_saveScene = m.saveScene;
|
|
4718
4793
|
_loadScene = m.loadScene;
|
|
4719
4794
|
}
|