@xom11/whiteboard 0.7.0 → 0.9.1
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/README.md +51 -1
- package/dist/chunk-74VEEZBV.mjs +619 -0
- package/dist/chunk-74VEEZBV.mjs.map +1 -0
- package/dist/chunk-DU2NFHRR.mjs +103 -0
- package/dist/chunk-DU2NFHRR.mjs.map +1 -0
- package/dist/{chunk-SHFOGORM.mjs → chunk-DU3RHKT5.mjs} +4 -4
- package/dist/{chunk-SHFOGORM.mjs.map → chunk-DU3RHKT5.mjs.map} +1 -1
- package/dist/{chunk-HYXFHEDJ.mjs → chunk-IUVV52HO.mjs} +22 -7
- package/dist/chunk-IUVV52HO.mjs.map +1 -0
- package/dist/{chunk-BJX4YNA5.mjs → chunk-KEYZ5EZT.mjs} +26 -9
- package/dist/chunk-KEYZ5EZT.mjs.map +1 -0
- package/dist/{chunk-LPM4MM45.mjs → chunk-SBDMF4NQ.mjs} +3 -2
- package/dist/chunk-SBDMF4NQ.mjs.map +1 -0
- package/dist/{chunk-3SSQKRRO.mjs → chunk-ZVN356JZ.mjs} +4 -4
- package/dist/{chunk-3SSQKRRO.mjs.map → chunk-ZVN356JZ.mjs.map} +1 -1
- package/dist/geometry-2d.js +250 -218
- package/dist/geometry-2d.js.map +1 -1
- package/dist/geometry-2d.mjs +2 -2
- package/dist/geometry-3d.d.mts +1 -1
- package/dist/geometry-3d.d.ts +1 -1
- package/dist/geometry-3d.js +3276 -1201
- package/dist/geometry-3d.js.map +1 -1
- package/dist/geometry-3d.mjs +3 -2
- package/dist/graph-2d.js +360 -66
- package/dist/graph-2d.js.map +1 -1
- package/dist/graph-2d.mjs +2 -2
- package/dist/{host-2QGKMGCT.mjs → host-LZH2FZ2N.mjs} +3 -3
- package/dist/{host-2QGKMGCT.mjs.map → host-LZH2FZ2N.mjs.map} +1 -1
- package/dist/host-PIIDSMVE.mjs +3187 -0
- package/dist/host-PIIDSMVE.mjs.map +1 -0
- package/dist/{host-T2W6R6SO.mjs → host-VDNAJMLC.mjs} +221 -216
- package/dist/host-VDNAJMLC.mjs.map +1 -0
- package/dist/index.d.mts +6 -5
- package/dist/index.d.ts +6 -5
- package/dist/index.js +4365 -1821
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +246 -102
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
- package/dist/chunk-BJX4YNA5.mjs.map +0 -1
- package/dist/chunk-DJTBZEAR.mjs +0 -25
- package/dist/chunk-DJTBZEAR.mjs.map +0 -1
- package/dist/chunk-HM7RIXJE.mjs +0 -331
- package/dist/chunk-HM7RIXJE.mjs.map +0 -1
- package/dist/chunk-HYXFHEDJ.mjs.map +0 -1
- package/dist/chunk-LPM4MM45.mjs.map +0 -1
- package/dist/host-T2W6R6SO.mjs.map +0 -1
- package/dist/host-XUFON6CQ.mjs +0 -1422
- package/dist/host-XUFON6CQ.mjs.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { serializeBoard, renderGeometrySvgFromState, isGeometryCustomData } from './chunk-
|
|
3
|
-
import { useChordShortcut, MobileToolDrawer } from './chunk-
|
|
2
|
+
import { serializeBoard, renderGeometrySvgFromState, isGeometryCustomData, safeJsx } from './chunk-KEYZ5EZT.mjs';
|
|
3
|
+
import { useChordShortcut, MobileToolDrawer } from './chunk-SBDMF4NQ.mjs';
|
|
4
4
|
import { resolveAttrColors, paletteFor, themeLabel, themeAxis, themeGrid } from './chunk-HTBLO5JO.mjs';
|
|
5
5
|
import { useIsMobile } from './chunk-P2AOIF7S.mjs';
|
|
6
6
|
import { insertStampImage } from './chunk-C6SCVOMC.mjs';
|
|
@@ -320,14 +320,8 @@ function handleDown(ctx, e) {
|
|
|
320
320
|
const tmp1 = ctx.boardRef.current.create("intersection", [a, b, 1], { visible: false, withLabel: false });
|
|
321
321
|
const d0 = Math.hypot((tmp0.X?.() ?? 0) - x, (tmp0.Y?.() ?? 0) - y);
|
|
322
322
|
const d1 = Math.hypot((tmp1.X?.() ?? 0) - x, (tmp1.Y?.() ?? 0) - y);
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
} catch {
|
|
326
|
-
}
|
|
327
|
-
try {
|
|
328
|
-
ctx.boardRef.current.removeObject(tmp1);
|
|
329
|
-
} catch {
|
|
330
|
-
}
|
|
323
|
+
safeJsx("handlers.removeObject(intersect.tmp0)", () => ctx.boardRef.current.removeObject(tmp0));
|
|
324
|
+
safeJsx("handlers.removeObject(intersect.tmp1)", () => ctx.boardRef.current.removeObject(tmp1));
|
|
331
325
|
const idx = d0 <= d1 ? 0 : 1;
|
|
332
326
|
ctx.create("intersection", [aId, bId, idx], attrs);
|
|
333
327
|
}
|
|
@@ -364,7 +358,7 @@ function handleDown(ctx, e) {
|
|
|
364
358
|
})();
|
|
365
359
|
if (ctx.pendingRef.current.length > 0 && ctx.boardRef.current) {
|
|
366
360
|
const prev = ctx.pendingRef.current[ctx.pendingRef.current.length - 1];
|
|
367
|
-
|
|
361
|
+
safeJsx("handlers.createPreviewSegment", () => {
|
|
368
362
|
const seg = ctx.boardRef.current.create("segment", [prev, pick2], {
|
|
369
363
|
strokeColor: "#3b82f6",
|
|
370
364
|
strokeWidth: 1.5,
|
|
@@ -374,8 +368,7 @@ function handleDown(ctx, e) {
|
|
|
374
368
|
withLabel: false
|
|
375
369
|
});
|
|
376
370
|
ctx.previewSegRef.current.push(seg);
|
|
377
|
-
}
|
|
378
|
-
}
|
|
371
|
+
});
|
|
379
372
|
}
|
|
380
373
|
ctx.pendingRef.current.push(pick2);
|
|
381
374
|
ctx.setPendingCount(ctx.pendingRef.current.length);
|
|
@@ -486,10 +479,7 @@ function handleUp(ctx, e) {
|
|
|
486
479
|
if (!sc2) return;
|
|
487
480
|
const [ex, ey] = sc2;
|
|
488
481
|
if (mq.rect) {
|
|
489
|
-
|
|
490
|
-
ctx.boardRef.current?.removeObject(mq.rect);
|
|
491
|
-
} catch {
|
|
492
|
-
}
|
|
482
|
+
safeJsx("handlers.removeObject(marquee.rect)", () => ctx.boardRef.current?.removeObject(mq.rect));
|
|
493
483
|
}
|
|
494
484
|
if (Math.hypot(ex - mq.startSx, ey - mq.startSy) < 4) return;
|
|
495
485
|
const x1 = Math.min(mq.startSx, ex), x2 = Math.max(mq.startSx, ex);
|
|
@@ -522,10 +512,7 @@ function handleUp(ctx, e) {
|
|
|
522
512
|
}
|
|
523
513
|
}
|
|
524
514
|
ctx.setSelectionTick((tt) => tt + 1);
|
|
525
|
-
|
|
526
|
-
board.update();
|
|
527
|
-
} catch {
|
|
528
|
-
}
|
|
515
|
+
safeJsx("handlers.board.update(marquee)", () => board.update());
|
|
529
516
|
return;
|
|
530
517
|
}
|
|
531
518
|
if (t !== "move") return;
|
|
@@ -572,12 +559,9 @@ function handleMove(ctx, e) {
|
|
|
572
559
|
const [x2u, y2u] = ux2 && ux2.length >= 2 ? [ux2[0], ux2[1]] : toUsr(Math.max(startSx, sx), Math.max(startSy, sy));
|
|
573
560
|
const rect = ctx.marqueeRef.current.rect;
|
|
574
561
|
if (rect) {
|
|
575
|
-
|
|
576
|
-
ctx.boardRef.current.removeObject(rect);
|
|
577
|
-
} catch {
|
|
578
|
-
}
|
|
562
|
+
safeJsx("handlers.removeObject(marquee.prevRect)", () => ctx.boardRef.current.removeObject(rect));
|
|
579
563
|
}
|
|
580
|
-
|
|
564
|
+
safeJsx("handlers.createMarqueePolygon", () => {
|
|
581
565
|
ctx.marqueeRef.current.rect = ctx.boardRef.current.create("polygon", [
|
|
582
566
|
[x1u, y1u],
|
|
583
567
|
[x2u, y1u],
|
|
@@ -592,8 +576,7 @@ function handleMove(ctx, e) {
|
|
|
592
576
|
highlight: false,
|
|
593
577
|
withLabel: false
|
|
594
578
|
});
|
|
595
|
-
}
|
|
596
|
-
}
|
|
579
|
+
});
|
|
597
580
|
}
|
|
598
581
|
return;
|
|
599
582
|
}
|
|
@@ -603,14 +586,13 @@ function handleMove(ctx, e) {
|
|
|
603
586
|
ctx.previewRafRef.current = requestAnimationFrame(() => {
|
|
604
587
|
ctx.previewRafRef.current = null;
|
|
605
588
|
if (!ctx.boardRef.current || !ctx.phantomRef.current) return;
|
|
606
|
-
|
|
589
|
+
safeJsx("handlers.phantomMove", () => {
|
|
607
590
|
const coords = ctx.boardRef.current.getUsrCoordsOfMouse(e);
|
|
608
591
|
const JXG = ctx.jxgRef.current;
|
|
609
592
|
if (!JXG) return;
|
|
610
593
|
ctx.phantomRef.current.setPositionDirectly(JXG.COORDS_BY_USER, [coords[0], coords[1]]);
|
|
611
594
|
ctx.boardRef.current.update();
|
|
612
|
-
}
|
|
613
|
-
}
|
|
595
|
+
});
|
|
614
596
|
});
|
|
615
597
|
}
|
|
616
598
|
var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
@@ -622,6 +604,7 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
622
604
|
const jxgRef = useRef(null);
|
|
623
605
|
const axisObjsRef = useRef({});
|
|
624
606
|
const creationLogRef = useRef([]);
|
|
607
|
+
const redoStackRef = useRef([]);
|
|
625
608
|
const [tool, setTool] = useState("move");
|
|
626
609
|
const toolRef = useRef("move");
|
|
627
610
|
toolRef.current = tool;
|
|
@@ -671,13 +654,17 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
671
654
|
return a;
|
|
672
655
|
});
|
|
673
656
|
}, []);
|
|
657
|
+
const pushCreationLog = useCallback((entry) => {
|
|
658
|
+
creationLogRef.current.push(entry);
|
|
659
|
+
redoStackRef.current = [];
|
|
660
|
+
}, []);
|
|
674
661
|
const pushLog = useCallback(
|
|
675
662
|
(id, type, args, attrs, obj) => {
|
|
676
|
-
|
|
663
|
+
pushCreationLog({ id, type, args, attrs });
|
|
677
664
|
objMapRef.current.set(id, obj);
|
|
678
665
|
setHistoryTick((t) => t + 1);
|
|
679
666
|
},
|
|
680
|
-
[]
|
|
667
|
+
[pushCreationLog]
|
|
681
668
|
);
|
|
682
669
|
const create = useCallback(
|
|
683
670
|
(type, args, attrs = {}) => {
|
|
@@ -760,16 +747,10 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
760
747
|
if (patch.remove) {
|
|
761
748
|
const vl = valueLabelsRef.current.get(o);
|
|
762
749
|
if (vl) {
|
|
763
|
-
|
|
764
|
-
boardRef.current.removeObject(vl);
|
|
765
|
-
} catch {
|
|
766
|
-
}
|
|
750
|
+
safeJsx("MiniBoard.removeObject(valueLabel)", () => boardRef.current.removeObject(vl));
|
|
767
751
|
valueLabelsRef.current.delete(o);
|
|
768
752
|
}
|
|
769
|
-
|
|
770
|
-
boardRef.current.removeObject(o);
|
|
771
|
-
} catch {
|
|
772
|
-
}
|
|
753
|
+
safeJsx("MiniBoard.removeObject(target)", () => boardRef.current.removeObject(o));
|
|
773
754
|
const board = boardRef.current;
|
|
774
755
|
const aliveIds = /* @__PURE__ */ new Set();
|
|
775
756
|
for (const [id, obj2] of objMapRef.current.entries()) {
|
|
@@ -794,7 +775,7 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
794
775
|
const targetId = localIdOf(o);
|
|
795
776
|
if (targetId) {
|
|
796
777
|
const id = nextLocalId();
|
|
797
|
-
|
|
778
|
+
pushCreationLog({ id, type: "valueLabel", args: [targetId], attrs: {} });
|
|
798
779
|
objMapRef.current.set(id, txt);
|
|
799
780
|
setHistoryTick((t) => t + 1);
|
|
800
781
|
}
|
|
@@ -803,10 +784,7 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
803
784
|
const txt = valueLabelsRef.current.get(o);
|
|
804
785
|
valueLabelsRef.current.delete(o);
|
|
805
786
|
if (txt) {
|
|
806
|
-
|
|
807
|
-
boardRef.current.removeObject(txt);
|
|
808
|
-
} catch {
|
|
809
|
-
}
|
|
787
|
+
safeJsx("MiniBoard.removeObject(valueLabel.text)", () => boardRef.current.removeObject(txt));
|
|
810
788
|
const txtId = localIdOf(txt);
|
|
811
789
|
if (txtId) {
|
|
812
790
|
creationLogRef.current = creationLogRef.current.filter((e) => e.id !== txtId);
|
|
@@ -817,10 +795,7 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
817
795
|
}
|
|
818
796
|
}
|
|
819
797
|
if (patch.attrs) {
|
|
820
|
-
|
|
821
|
-
o.setAttribute(patch.attrs);
|
|
822
|
-
} catch {
|
|
823
|
-
}
|
|
798
|
+
safeJsx("MiniBoard.setAttribute", () => o.setAttribute(patch.attrs));
|
|
824
799
|
const id = localIdOf(o);
|
|
825
800
|
if (id) {
|
|
826
801
|
const entry = creationLogRef.current.find((e) => e.id === id);
|
|
@@ -828,19 +803,13 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
828
803
|
setHistoryTick((t) => t + 1);
|
|
829
804
|
}
|
|
830
805
|
}
|
|
831
|
-
|
|
832
|
-
boardRef.current.update();
|
|
833
|
-
} catch {
|
|
834
|
-
}
|
|
806
|
+
safeJsx("MiniBoard.board.update(mutate)", () => boardRef.current.update());
|
|
835
807
|
}, [createValueLabelFor, localIdOf, nextLocalId]);
|
|
836
808
|
const clearPreviewSegs = useCallback(() => {
|
|
837
809
|
const b = boardRef.current;
|
|
838
810
|
if (!b) return;
|
|
839
811
|
for (const s of previewSegRef.current) {
|
|
840
|
-
|
|
841
|
-
b.removeObject(s);
|
|
842
|
-
} catch {
|
|
843
|
-
}
|
|
812
|
+
safeJsx("MiniBoard.removeObject(previewSeg)", () => b.removeObject(s));
|
|
844
813
|
}
|
|
845
814
|
previewSegRef.current = [];
|
|
846
815
|
}, []);
|
|
@@ -848,17 +817,11 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
848
817
|
const b = boardRef.current;
|
|
849
818
|
if (!b) return;
|
|
850
819
|
if (previewShapeRef.current) {
|
|
851
|
-
|
|
852
|
-
b.removeObject(previewShapeRef.current);
|
|
853
|
-
} catch {
|
|
854
|
-
}
|
|
820
|
+
safeJsx("MiniBoard.removeObject(previewShape)", () => b.removeObject(previewShapeRef.current));
|
|
855
821
|
previewShapeRef.current = null;
|
|
856
822
|
}
|
|
857
823
|
if (phantomRef.current) {
|
|
858
|
-
|
|
859
|
-
b.removeObject(phantomRef.current);
|
|
860
|
-
} catch {
|
|
861
|
-
}
|
|
824
|
+
safeJsx("MiniBoard.removeObject(phantom)", () => b.removeObject(phantomRef.current));
|
|
862
825
|
phantomRef.current = null;
|
|
863
826
|
}
|
|
864
827
|
}, []);
|
|
@@ -870,7 +833,7 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
870
833
|
}, [clearPreviewSegs, removePhantom]);
|
|
871
834
|
const applySelectionStyle = useCallback((obj) => {
|
|
872
835
|
if (!obj || selOriginalRef.current.has(obj)) return;
|
|
873
|
-
|
|
836
|
+
safeJsx("MiniBoard.applySelectionStyle", () => {
|
|
874
837
|
const visProp = obj.visProp ?? {};
|
|
875
838
|
selOriginalRef.current.set(obj, {
|
|
876
839
|
strokeColor: visProp.strokecolor,
|
|
@@ -882,19 +845,17 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
882
845
|
} else {
|
|
883
846
|
obj.setAttribute({ strokeColor: "#06b6d4", strokeWidth: 3 });
|
|
884
847
|
}
|
|
885
|
-
}
|
|
886
|
-
}
|
|
848
|
+
});
|
|
887
849
|
}, []);
|
|
888
850
|
const restoreSelectionStyle = useCallback((obj) => {
|
|
889
851
|
const orig = selOriginalRef.current.get(obj);
|
|
890
852
|
if (!orig) return;
|
|
891
|
-
|
|
853
|
+
safeJsx("MiniBoard.restoreSelectionStyle", () => {
|
|
892
854
|
const attrs = {};
|
|
893
855
|
if (orig.strokeColor !== void 0) attrs.strokeColor = orig.strokeColor;
|
|
894
856
|
if (orig.strokeWidth !== void 0) attrs.strokeWidth = orig.strokeWidth;
|
|
895
857
|
obj.setAttribute(attrs);
|
|
896
|
-
}
|
|
897
|
-
}
|
|
858
|
+
});
|
|
898
859
|
selOriginalRef.current.delete(obj);
|
|
899
860
|
}, []);
|
|
900
861
|
const clearSelection = useCallback(() => {
|
|
@@ -903,10 +864,7 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
903
864
|
}
|
|
904
865
|
selectedSetRef.current.clear();
|
|
905
866
|
setSelectionTick((t) => t + 1);
|
|
906
|
-
|
|
907
|
-
boardRef.current?.update();
|
|
908
|
-
} catch {
|
|
909
|
-
}
|
|
867
|
+
safeJsx("MiniBoard.board.update(clearSelection)", () => boardRef.current?.update());
|
|
910
868
|
}, [restoreSelectionStyle]);
|
|
911
869
|
const toggleSelect = useCallback((obj, additive) => {
|
|
912
870
|
if (!obj) return;
|
|
@@ -926,10 +884,7 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
926
884
|
}
|
|
927
885
|
}
|
|
928
886
|
setSelectionTick((t) => t + 1);
|
|
929
|
-
|
|
930
|
-
boardRef.current?.update();
|
|
931
|
-
} catch {
|
|
932
|
-
}
|
|
887
|
+
safeJsx("MiniBoard.board.update(toggleSelect)", () => boardRef.current?.update());
|
|
933
888
|
}, [applySelectionStyle, restoreSelectionStyle]);
|
|
934
889
|
const deleteSelected = useCallback(() => {
|
|
935
890
|
const board = boardRef.current;
|
|
@@ -937,10 +892,7 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
937
892
|
if (selectedSetRef.current.size === 0) return;
|
|
938
893
|
for (const o of selectedSetRef.current) selOriginalRef.current.delete(o);
|
|
939
894
|
for (const o of selectedSetRef.current) {
|
|
940
|
-
|
|
941
|
-
board.removeObject(o);
|
|
942
|
-
} catch {
|
|
943
|
-
}
|
|
895
|
+
safeJsx("MiniBoard.removeObject(selected)", () => board.removeObject(o));
|
|
944
896
|
}
|
|
945
897
|
selectedSetRef.current.clear();
|
|
946
898
|
const aliveIds = /* @__PURE__ */ new Set();
|
|
@@ -1013,10 +965,7 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
1013
965
|
const b = boardRef.current;
|
|
1014
966
|
if (!b) return;
|
|
1015
967
|
if (previewShapeRef.current) {
|
|
1016
|
-
|
|
1017
|
-
b.removeObject(previewShapeRef.current);
|
|
1018
|
-
} catch {
|
|
1019
|
-
}
|
|
968
|
+
safeJsx("MiniBoard.removeObject(refreshPreview)", () => b.removeObject(previewShapeRef.current));
|
|
1020
969
|
previewShapeRef.current = null;
|
|
1021
970
|
}
|
|
1022
971
|
const t = toolRef.current;
|
|
@@ -1135,7 +1084,7 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
1135
1084
|
}
|
|
1136
1085
|
case "toggleLabel": {
|
|
1137
1086
|
const obj = picks[0];
|
|
1138
|
-
|
|
1087
|
+
safeJsx("MiniBoard.toggleLabel", () => {
|
|
1139
1088
|
if (obj.label) {
|
|
1140
1089
|
const visible = obj.label.visProp.visible !== false;
|
|
1141
1090
|
obj.label.setAttribute({ visible: !visible });
|
|
@@ -1144,23 +1093,21 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
1144
1093
|
obj.setAttribute({ withLabel: !cur });
|
|
1145
1094
|
}
|
|
1146
1095
|
boardRef.current.update();
|
|
1147
|
-
}
|
|
1148
|
-
}
|
|
1096
|
+
});
|
|
1149
1097
|
break;
|
|
1150
1098
|
}
|
|
1151
1099
|
case "toggleVisible": {
|
|
1152
1100
|
const obj = picks[0];
|
|
1153
|
-
|
|
1101
|
+
safeJsx("MiniBoard.toggleVisible", () => {
|
|
1154
1102
|
const visible = obj.visProp.visible !== false;
|
|
1155
1103
|
obj.setAttribute({ visible: !visible });
|
|
1156
1104
|
boardRef.current.update();
|
|
1157
|
-
}
|
|
1158
|
-
}
|
|
1105
|
+
});
|
|
1159
1106
|
break;
|
|
1160
1107
|
}
|
|
1161
1108
|
case "delete": {
|
|
1162
1109
|
const obj = picks[0];
|
|
1163
|
-
|
|
1110
|
+
safeJsx("MiniBoard.deleteOne", () => {
|
|
1164
1111
|
boardRef.current.removeObject(obj);
|
|
1165
1112
|
const board = boardRef.current;
|
|
1166
1113
|
const aliveIds = /* @__PURE__ */ new Set();
|
|
@@ -1175,8 +1122,7 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
1175
1122
|
if (!aliveIds.has(id)) objMapRef.current.delete(id);
|
|
1176
1123
|
}
|
|
1177
1124
|
setHistoryTick((t) => t + 1);
|
|
1178
|
-
}
|
|
1179
|
-
}
|
|
1125
|
+
});
|
|
1180
1126
|
break;
|
|
1181
1127
|
}
|
|
1182
1128
|
}
|
|
@@ -1211,7 +1157,7 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
1211
1157
|
}
|
|
1212
1158
|
const stepId = nextLocalId();
|
|
1213
1159
|
const stepObj = boardRef.current.create("transform", step.params, step.attrs);
|
|
1214
|
-
|
|
1160
|
+
pushCreationLog({ id: stepId, type: "transform", args: stepLogArgs, attrs: step.attrs });
|
|
1215
1161
|
objMapRef.current.set(stepId, stepObj);
|
|
1216
1162
|
transformObjs.push(stepObj);
|
|
1217
1163
|
transformIds.push(stepId);
|
|
@@ -1225,7 +1171,7 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
1225
1171
|
const newName = srcName ? `${srcName}'` : nextLabel();
|
|
1226
1172
|
const attrs = { name: newName, size: 3, color: "#0ea5e9", strokeColor: "#0ea5e9", fillColor: "#0ea5e9" };
|
|
1227
1173
|
const obj = boardRef.current.create("point", [src, transformParent], attrs);
|
|
1228
|
-
|
|
1174
|
+
pushCreationLog({ id, type: "point", args: [srcId ?? src, transformLogRef], attrs });
|
|
1229
1175
|
objMapRef.current.set(id, obj);
|
|
1230
1176
|
return obj;
|
|
1231
1177
|
});
|
|
@@ -1256,6 +1202,30 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
1256
1202
|
}
|
|
1257
1203
|
setHistoryTick((t) => t + 1);
|
|
1258
1204
|
}, [create, flashWarn, localIdOf, nextLabel, nextLocalId]);
|
|
1205
|
+
const recreateFromLogEntry = useCallback((el) => {
|
|
1206
|
+
const board = boardRef.current;
|
|
1207
|
+
if (!board) return false;
|
|
1208
|
+
const idMap = objMapRef.current;
|
|
1209
|
+
const resolved = el.args.map((a) => typeof a === "string" && idMap.has(a) ? idMap.get(a) : a);
|
|
1210
|
+
try {
|
|
1211
|
+
if (el.type === "valueLabel") {
|
|
1212
|
+
const target = resolved[0];
|
|
1213
|
+
if (!target) return false;
|
|
1214
|
+
const txt = createValueLabelFor(target);
|
|
1215
|
+
if (!txt) return false;
|
|
1216
|
+
idMap.set(el.id, txt);
|
|
1217
|
+
valueLabelsRef.current.set(target, txt);
|
|
1218
|
+
return true;
|
|
1219
|
+
}
|
|
1220
|
+
const themedAttrs = resolveAttrColors({ ...el.attrs }, paletteFor(isDarkRef.current));
|
|
1221
|
+
const obj = board.create(el.type, resolved, themedAttrs);
|
|
1222
|
+
idMap.set(el.id, obj);
|
|
1223
|
+
return true;
|
|
1224
|
+
} catch (err) {
|
|
1225
|
+
console.warn("Recreate failed for", el.type, err);
|
|
1226
|
+
return false;
|
|
1227
|
+
}
|
|
1228
|
+
}, [createValueLabelFor]);
|
|
1259
1229
|
const undoLast = useCallback(() => {
|
|
1260
1230
|
const b = boardRef.current;
|
|
1261
1231
|
if (!b) return;
|
|
@@ -1265,21 +1235,31 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
1265
1235
|
const obj = objMapRef.current.get(last.id);
|
|
1266
1236
|
objMapRef.current.delete(last.id);
|
|
1267
1237
|
if (obj) {
|
|
1268
|
-
|
|
1269
|
-
b.removeObject(obj);
|
|
1270
|
-
} catch {
|
|
1271
|
-
}
|
|
1238
|
+
safeJsx("MiniBoard.removeObject(undo)", () => b.removeObject(obj));
|
|
1272
1239
|
clearPending();
|
|
1240
|
+
redoStackRef.current.push(last);
|
|
1273
1241
|
setHistoryTick((t) => t + 1);
|
|
1274
|
-
|
|
1275
|
-
b.update();
|
|
1276
|
-
} catch {
|
|
1277
|
-
}
|
|
1242
|
+
safeJsx("MiniBoard.board.update(undo)", () => b.update());
|
|
1278
1243
|
return;
|
|
1279
1244
|
}
|
|
1280
1245
|
}
|
|
1281
1246
|
setHistoryTick((t) => t + 1);
|
|
1282
1247
|
}, [clearPending]);
|
|
1248
|
+
const redoNext = useCallback(() => {
|
|
1249
|
+
const b = boardRef.current;
|
|
1250
|
+
if (!b) return;
|
|
1251
|
+
const entry = redoStackRef.current.pop();
|
|
1252
|
+
if (!entry) {
|
|
1253
|
+
setHistoryTick((t) => t + 1);
|
|
1254
|
+
return;
|
|
1255
|
+
}
|
|
1256
|
+
const ok = recreateFromLogEntry(entry);
|
|
1257
|
+
if (ok) {
|
|
1258
|
+
creationLogRef.current.push(entry);
|
|
1259
|
+
}
|
|
1260
|
+
setHistoryTick((t) => t + 1);
|
|
1261
|
+
safeJsx("MiniBoard.board.update(redo)", () => b.update());
|
|
1262
|
+
}, [recreateFromLogEntry]);
|
|
1283
1263
|
useEffect(() => {
|
|
1284
1264
|
const onKey = (e) => {
|
|
1285
1265
|
const ae = document.activeElement;
|
|
@@ -1291,6 +1271,13 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
1291
1271
|
undoLastRef.current();
|
|
1292
1272
|
return;
|
|
1293
1273
|
}
|
|
1274
|
+
if ((e.metaKey || e.ctrlKey) && (e.key.toLowerCase() === "z" && e.shiftKey || e.key.toLowerCase() === "y" && !e.shiftKey)) {
|
|
1275
|
+
if (inField) return;
|
|
1276
|
+
e.preventDefault();
|
|
1277
|
+
e.stopPropagation();
|
|
1278
|
+
redoNextRef.current();
|
|
1279
|
+
return;
|
|
1280
|
+
}
|
|
1294
1281
|
if (e.key === "Escape" && !inField) {
|
|
1295
1282
|
if (pendingRef.current.length > 0) {
|
|
1296
1283
|
e.preventDefault();
|
|
@@ -1337,16 +1324,14 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
1337
1324
|
if (!sc) return [];
|
|
1338
1325
|
const [sx, sy] = sc;
|
|
1339
1326
|
const list = [];
|
|
1340
|
-
|
|
1327
|
+
safeJsx("MiniBoard.objectsAt.loop", () => {
|
|
1341
1328
|
const objs = b.objectsList || [];
|
|
1342
1329
|
for (const o of objs) {
|
|
1343
|
-
|
|
1330
|
+
safeJsx("MiniBoard.objectsAt.hasPoint", () => {
|
|
1344
1331
|
if (o.hasPoint && o.hasPoint(sx, sy)) list.push(o);
|
|
1345
|
-
}
|
|
1346
|
-
}
|
|
1332
|
+
});
|
|
1347
1333
|
}
|
|
1348
|
-
}
|
|
1349
|
-
}
|
|
1334
|
+
});
|
|
1350
1335
|
return list;
|
|
1351
1336
|
}, [screenCoordsOf]);
|
|
1352
1337
|
const findNearestPoint = useCallback((evt, tolPx = 12) => {
|
|
@@ -1356,24 +1341,23 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
1356
1341
|
if (!sc) return null;
|
|
1357
1342
|
const [sx, sy] = sc;
|
|
1358
1343
|
const tol2 = tolPx * tolPx;
|
|
1359
|
-
|
|
1360
|
-
|
|
1344
|
+
const bestRef = { current: null };
|
|
1345
|
+
safeJsx("MiniBoard.findNearestPoint.loop", () => {
|
|
1361
1346
|
const objs = b.objectsList || [];
|
|
1362
1347
|
for (const o of objs) {
|
|
1363
|
-
|
|
1364
|
-
if (objKind(o) !== "point")
|
|
1348
|
+
safeJsx("MiniBoard.findNearestPoint.iter", () => {
|
|
1349
|
+
if (objKind(o) !== "point") return;
|
|
1365
1350
|
const pc = o.coords?.scrCoords;
|
|
1366
|
-
if (!pc)
|
|
1351
|
+
if (!pc) return;
|
|
1367
1352
|
const dx = pc[1] - sx;
|
|
1368
1353
|
const dy = pc[2] - sy;
|
|
1369
1354
|
const d2 = dx * dx + dy * dy;
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
}
|
|
1355
|
+
const cur = bestRef.current;
|
|
1356
|
+
if (d2 <= tol2 && (!cur || d2 < cur.d2)) bestRef.current = { obj: o, d2 };
|
|
1357
|
+
});
|
|
1373
1358
|
}
|
|
1374
|
-
}
|
|
1375
|
-
|
|
1376
|
-
return best ? best.obj : null;
|
|
1359
|
+
});
|
|
1360
|
+
return bestRef.current ? bestRef.current.obj : null;
|
|
1377
1361
|
}, [screenCoordsOf]);
|
|
1378
1362
|
const promoteLabel = useCallback((o) => {
|
|
1379
1363
|
if (!o) return o;
|
|
@@ -1381,31 +1365,25 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
1381
1365
|
if (t !== "text") return o;
|
|
1382
1366
|
const b = boardRef.current;
|
|
1383
1367
|
if (!b) return o;
|
|
1384
|
-
|
|
1368
|
+
const promoted = safeJsx("MiniBoard.promoteLabel", () => {
|
|
1385
1369
|
for (const c of b.objectsList || []) {
|
|
1386
1370
|
if (c.label === o) return c;
|
|
1387
1371
|
}
|
|
1388
|
-
|
|
1389
|
-
}
|
|
1390
|
-
return o;
|
|
1372
|
+
return null;
|
|
1373
|
+
}, null);
|
|
1374
|
+
return promoted ?? o;
|
|
1391
1375
|
}, []);
|
|
1392
1376
|
const pendingTransformRef = useRef(null);
|
|
1393
1377
|
const transformSubsRef = useRef(/* @__PURE__ */ new Set());
|
|
1394
1378
|
const emitTransform = useCallback((info) => {
|
|
1395
1379
|
transformSubsRef.current.forEach((cb) => {
|
|
1396
|
-
|
|
1397
|
-
cb(info);
|
|
1398
|
-
} catch {
|
|
1399
|
-
}
|
|
1380
|
+
safeJsx("MiniBoard.emitTransform.cb", () => cb(info));
|
|
1400
1381
|
});
|
|
1401
1382
|
}, []);
|
|
1402
1383
|
const selectSubsRef = useRef(/* @__PURE__ */ new Set());
|
|
1403
1384
|
const emitSelect = useCallback((snap) => {
|
|
1404
1385
|
selectSubsRef.current.forEach((cb) => {
|
|
1405
|
-
|
|
1406
|
-
cb(snap);
|
|
1407
|
-
} catch {
|
|
1408
|
-
}
|
|
1386
|
+
safeJsx("MiniBoard.emitSelect.cb", () => cb(snap));
|
|
1409
1387
|
});
|
|
1410
1388
|
}, []);
|
|
1411
1389
|
const moveDownRef = useRef(null);
|
|
@@ -1417,7 +1395,7 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
1417
1395
|
const JXG = (await import('jsxgraph')).default;
|
|
1418
1396
|
if (cancelled || !containerRef.current) return;
|
|
1419
1397
|
jxgRef.current = JXG;
|
|
1420
|
-
|
|
1398
|
+
safeJsx("MiniBoard.applyJxgOptions", () => {
|
|
1421
1399
|
const opts = JXG.Options;
|
|
1422
1400
|
if (opts) {
|
|
1423
1401
|
opts.text = opts.text || {};
|
|
@@ -1430,8 +1408,7 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
1430
1408
|
opts.label.strokeColor = themeLabel(isDarkRef.current);
|
|
1431
1409
|
opts.text.strokeColor = themeLabel(isDarkRef.current);
|
|
1432
1410
|
}
|
|
1433
|
-
}
|
|
1434
|
-
}
|
|
1411
|
+
});
|
|
1435
1412
|
const board = JXG.JSXGraph.initBoard(containerId, {
|
|
1436
1413
|
boundingbox: initialState?.bbox ?? [-10, 10, 10, -10],
|
|
1437
1414
|
axis: false,
|
|
@@ -1452,43 +1429,20 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
1452
1429
|
});
|
|
1453
1430
|
boardRef.current = board;
|
|
1454
1431
|
if (initialState && initialState.elements.length > 0) {
|
|
1455
|
-
const idMap = objMapRef.current;
|
|
1456
1432
|
for (const el of initialState.elements) {
|
|
1457
|
-
|
|
1458
|
-
try {
|
|
1459
|
-
if (el.type === "valueLabel") {
|
|
1460
|
-
const target = resolved[0];
|
|
1461
|
-
if (target) {
|
|
1462
|
-
const txt = createValueLabelFor(target);
|
|
1463
|
-
if (txt) {
|
|
1464
|
-
idMap.set(el.id, txt);
|
|
1465
|
-
valueLabelsRef.current.set(target, txt);
|
|
1466
|
-
}
|
|
1467
|
-
}
|
|
1468
|
-
continue;
|
|
1469
|
-
}
|
|
1470
|
-
const themedAttrs = resolveAttrColors({ ...el.attrs }, paletteFor(isDarkRef.current));
|
|
1471
|
-
const obj = board.create(el.type, resolved, themedAttrs);
|
|
1472
|
-
idMap.set(el.id, obj);
|
|
1473
|
-
} catch (err) {
|
|
1474
|
-
console.warn("Replay failed for", el.type, err);
|
|
1475
|
-
}
|
|
1433
|
+
recreateFromLogEntry(el);
|
|
1476
1434
|
}
|
|
1477
1435
|
creationLogRef.current = [...initialState.elements];
|
|
1478
1436
|
labelIdxRef.current = initialState.elements.filter((e) => e.type === "point").length;
|
|
1479
1437
|
}
|
|
1480
1438
|
if (showAxisRef.current) {
|
|
1481
|
-
|
|
1439
|
+
safeJsx("MiniBoard.initAxes", () => {
|
|
1482
1440
|
axisObjsRef.current.x = board.create("axis", [[0, 0], [1, 0]], { strokeColor: themeAxis(isDarkRef.current), name: "", withLabel: false });
|
|
1483
1441
|
axisObjsRef.current.y = board.create("axis", [[0, 0], [0, 1]], { strokeColor: themeAxis(isDarkRef.current), name: "", withLabel: false });
|
|
1484
|
-
}
|
|
1485
|
-
}
|
|
1442
|
+
});
|
|
1486
1443
|
}
|
|
1487
1444
|
if (showGridRef.current) {
|
|
1488
|
-
|
|
1489
|
-
board.create("grid", [], { strokeColor: themeGrid(isDarkRef.current), strokeOpacity: 1 });
|
|
1490
|
-
} catch {
|
|
1491
|
-
}
|
|
1445
|
+
safeJsx("MiniBoard.initGrid", () => board.create("grid", [], { strokeColor: themeGrid(isDarkRef.current), strokeOpacity: 1 }));
|
|
1492
1446
|
}
|
|
1493
1447
|
board.on("down", (e) => {
|
|
1494
1448
|
const ctx = {
|
|
@@ -1639,6 +1593,8 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
1639
1593
|
setShowGrid: (b) => setShowGridRef.current(b),
|
|
1640
1594
|
undo: () => undoLastRef.current(),
|
|
1641
1595
|
canUndo: () => creationLogRef.current.length > 0,
|
|
1596
|
+
redo: () => redoNextRef.current(),
|
|
1597
|
+
canRedo: () => redoStackRef.current.length > 0,
|
|
1642
1598
|
subscribe: (cb) => {
|
|
1643
1599
|
subscribersRef.current.add(cb);
|
|
1644
1600
|
return () => {
|
|
@@ -1651,15 +1607,14 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
1651
1607
|
const b = boardRef.current;
|
|
1652
1608
|
if (!b) return [];
|
|
1653
1609
|
const out = [];
|
|
1654
|
-
|
|
1610
|
+
safeJsx("MiniBoard.getAllPointNames", () => {
|
|
1655
1611
|
const objs = b.objectsList || [];
|
|
1656
1612
|
for (const o of objs) {
|
|
1657
1613
|
if (objKind(o) === "point" && typeof o.name === "string" && o.name) {
|
|
1658
1614
|
out.push(o.name);
|
|
1659
1615
|
}
|
|
1660
1616
|
}
|
|
1661
|
-
}
|
|
1662
|
-
}
|
|
1617
|
+
});
|
|
1663
1618
|
return out;
|
|
1664
1619
|
},
|
|
1665
1620
|
onSelect: (cb) => {
|
|
@@ -1720,10 +1675,7 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
1720
1675
|
previewRafRef.current = null;
|
|
1721
1676
|
}
|
|
1722
1677
|
if (boardRef.current && jxgRef.current) {
|
|
1723
|
-
|
|
1724
|
-
jxgRef.current.JSXGraph.freeBoard(boardRef.current);
|
|
1725
|
-
} catch {
|
|
1726
|
-
}
|
|
1678
|
+
safeJsx("MiniBoard.freeBoard", () => jxgRef.current.JSXGraph.freeBoard(boardRef.current));
|
|
1727
1679
|
boardRef.current = null;
|
|
1728
1680
|
}
|
|
1729
1681
|
};
|
|
@@ -1731,19 +1683,13 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
1731
1683
|
useEffect(() => {
|
|
1732
1684
|
const b = boardRef.current;
|
|
1733
1685
|
if (!b) return;
|
|
1734
|
-
|
|
1686
|
+
safeJsx("MiniBoard.toggleAxis", () => {
|
|
1735
1687
|
if (axisObjsRef.current.x) {
|
|
1736
|
-
|
|
1737
|
-
b.removeObject(axisObjsRef.current.x);
|
|
1738
|
-
} catch {
|
|
1739
|
-
}
|
|
1688
|
+
safeJsx("MiniBoard.removeObject(axisX)", () => b.removeObject(axisObjsRef.current.x));
|
|
1740
1689
|
axisObjsRef.current.x = void 0;
|
|
1741
1690
|
}
|
|
1742
1691
|
if (axisObjsRef.current.y) {
|
|
1743
|
-
|
|
1744
|
-
b.removeObject(axisObjsRef.current.y);
|
|
1745
|
-
} catch {
|
|
1746
|
-
}
|
|
1692
|
+
safeJsx("MiniBoard.removeObject(axisY)", () => b.removeObject(axisObjsRef.current.y));
|
|
1747
1693
|
axisObjsRef.current.y = void 0;
|
|
1748
1694
|
}
|
|
1749
1695
|
if (showAxis) {
|
|
@@ -1751,28 +1697,23 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
1751
1697
|
axisObjsRef.current.y = b.create("axis", [[0, 0], [0, 1]], { strokeColor: themeAxis(isDarkRef.current), name: "", withLabel: false });
|
|
1752
1698
|
}
|
|
1753
1699
|
b.update();
|
|
1754
|
-
}
|
|
1755
|
-
}
|
|
1700
|
+
});
|
|
1756
1701
|
}, [showAxis]);
|
|
1757
1702
|
useEffect(() => {
|
|
1758
1703
|
const b = boardRef.current;
|
|
1759
1704
|
if (!b) return;
|
|
1760
|
-
|
|
1705
|
+
safeJsx("MiniBoard.toggleGrid", () => {
|
|
1761
1706
|
const objs = Object.values(b.objects || {});
|
|
1762
1707
|
for (const o of objs) {
|
|
1763
1708
|
if (o && (o.elType === "grid" || o.type === "grid" || o.visProp && o.visProp.type === "grid")) {
|
|
1764
|
-
|
|
1765
|
-
b.removeObject(o);
|
|
1766
|
-
} catch {
|
|
1767
|
-
}
|
|
1709
|
+
safeJsx("MiniBoard.removeObject(grid)", () => b.removeObject(o));
|
|
1768
1710
|
}
|
|
1769
1711
|
}
|
|
1770
1712
|
if (showGrid) {
|
|
1771
1713
|
b.create("grid", [], { strokeColor: themeGrid(isDarkRef.current), strokeOpacity: 1 });
|
|
1772
1714
|
}
|
|
1773
1715
|
b.update();
|
|
1774
|
-
}
|
|
1775
|
-
}
|
|
1716
|
+
});
|
|
1776
1717
|
}, [showGrid]);
|
|
1777
1718
|
const handleToolChange = useCallback((t) => {
|
|
1778
1719
|
clearPending();
|
|
@@ -1780,10 +1721,9 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
1780
1721
|
setTool(t);
|
|
1781
1722
|
const b = boardRef.current;
|
|
1782
1723
|
if (b) {
|
|
1783
|
-
|
|
1724
|
+
safeJsx("MiniBoard.setPanForTool", () => {
|
|
1784
1725
|
if (b.attr?.pan) b.attr.pan.enabled = t !== "select";
|
|
1785
|
-
}
|
|
1786
|
-
}
|
|
1726
|
+
});
|
|
1787
1727
|
}
|
|
1788
1728
|
}, [clearPending]);
|
|
1789
1729
|
const handleToolChangeRef = useRef(handleToolChange);
|
|
@@ -1791,10 +1731,7 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
1791
1731
|
const subscribersRef = useRef(/* @__PURE__ */ new Set());
|
|
1792
1732
|
const notifySubscribers = useCallback(() => {
|
|
1793
1733
|
subscribersRef.current.forEach((cb) => {
|
|
1794
|
-
|
|
1795
|
-
cb();
|
|
1796
|
-
} catch {
|
|
1797
|
-
}
|
|
1734
|
+
safeJsx("MiniBoard.notifySubscriber.cb", () => cb());
|
|
1798
1735
|
});
|
|
1799
1736
|
}, []);
|
|
1800
1737
|
useEffect(() => {
|
|
@@ -1802,6 +1739,8 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
|
|
|
1802
1739
|
}, [tool, showAxis, showGrid, historyTick, notifySubscribers]);
|
|
1803
1740
|
const undoLastRef = useRef(undoLast);
|
|
1804
1741
|
undoLastRef.current = undoLast;
|
|
1742
|
+
const redoNextRef = useRef(redoNext);
|
|
1743
|
+
redoNextRef.current = redoNext;
|
|
1805
1744
|
const clearPendingRef = useRef(clearPending);
|
|
1806
1745
|
clearPendingRef.current = clearPending;
|
|
1807
1746
|
const finalizeTransformCreateRef = useRef(finalizeTransformCreate);
|
|
@@ -1885,6 +1824,12 @@ function UndoIcon() {
|
|
|
1885
1824
|
/* @__PURE__ */ jsx("path", { d: "M3.51 13a9 9 0 1 0 2.13-9.36L3 7" })
|
|
1886
1825
|
] });
|
|
1887
1826
|
}
|
|
1827
|
+
function RedoIcon() {
|
|
1828
|
+
return /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1829
|
+
/* @__PURE__ */ jsx("polyline", { points: "21 7 21 13 15 13" }),
|
|
1830
|
+
/* @__PURE__ */ jsx("path", { d: "M20.49 13a9 9 0 1 1-2.13-9.36L21 7" })
|
|
1831
|
+
] });
|
|
1832
|
+
}
|
|
1888
1833
|
function AxisIcon() {
|
|
1889
1834
|
return /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1890
1835
|
/* @__PURE__ */ jsx("line", { x1: "4", y1: "20", x2: "20", y2: "20" }),
|
|
@@ -1929,7 +1874,7 @@ function useToolHoverTooltip() {
|
|
|
1929
1874
|
return { hover, portalReady, showHover, hideHover };
|
|
1930
1875
|
}
|
|
1931
1876
|
function DesktopGeometryPanel(props) {
|
|
1932
|
-
const { activeTool, onToolChange, showAxis, showGrid, onShowAxisChange, onShowGridChange, onUndo, canUndo, onClose, isDark, chordGroup } = props;
|
|
1877
|
+
const { activeTool, onToolChange, showAxis, showGrid, onShowAxisChange, onShowGridChange, onUndo, canUndo, onRedo, canRedo, onClose, isDark, chordGroup } = props;
|
|
1933
1878
|
const grouped = useMemo(() => {
|
|
1934
1879
|
return TOOLS.reduce((acc, t) => {
|
|
1935
1880
|
var _a;
|
|
@@ -1978,9 +1923,23 @@ function DesktopGeometryPanel(props) {
|
|
|
1978
1923
|
disabled: !canUndo,
|
|
1979
1924
|
title: "Ho\xE0n t\xE1c (Ctrl/Cmd+Z)",
|
|
1980
1925
|
"aria-label": "Ho\xE0n t\xE1c",
|
|
1926
|
+
"data-testid": "undo-btn",
|
|
1981
1927
|
className: "ml-auto inline-flex items-center justify-center rounded p-1 text-slate-600 transition hover:bg-slate-100 hover:text-slate-900 disabled:cursor-not-allowed disabled:text-slate-300 disabled:hover:bg-transparent",
|
|
1982
1928
|
children: /* @__PURE__ */ jsx(UndoIcon, {})
|
|
1983
1929
|
}
|
|
1930
|
+
),
|
|
1931
|
+
/* @__PURE__ */ jsx(
|
|
1932
|
+
"button",
|
|
1933
|
+
{
|
|
1934
|
+
type: "button",
|
|
1935
|
+
onClick: onRedo,
|
|
1936
|
+
disabled: !canRedo,
|
|
1937
|
+
title: "L\xE0m l\u1EA1i (Ctrl/Cmd+Shift+Z)",
|
|
1938
|
+
"aria-label": "L\xE0m l\u1EA1i",
|
|
1939
|
+
"data-testid": "redo-btn",
|
|
1940
|
+
className: "inline-flex items-center justify-center rounded p-1 text-slate-600 transition hover:bg-slate-100 hover:text-slate-900 disabled:cursor-not-allowed disabled:text-slate-300 disabled:hover:bg-transparent",
|
|
1941
|
+
children: /* @__PURE__ */ jsx(RedoIcon, {})
|
|
1942
|
+
}
|
|
1984
1943
|
)
|
|
1985
1944
|
] }) }),
|
|
1986
1945
|
groupKeys.map((group) => {
|
|
@@ -2101,6 +2060,8 @@ function MobileGeometryPanel(props) {
|
|
|
2101
2060
|
onShowGridChange,
|
|
2102
2061
|
onUndo,
|
|
2103
2062
|
canUndo,
|
|
2063
|
+
onRedo,
|
|
2064
|
+
canRedo,
|
|
2104
2065
|
isDark,
|
|
2105
2066
|
drawerOpen,
|
|
2106
2067
|
onDrawerClose
|
|
@@ -2149,6 +2110,13 @@ function MobileGeometryPanel(props) {
|
|
|
2149
2110
|
icon: /* @__PURE__ */ jsx(UndoIcon, {}),
|
|
2150
2111
|
onClick: onUndo,
|
|
2151
2112
|
disabled: !canUndo
|
|
2113
|
+
},
|
|
2114
|
+
{
|
|
2115
|
+
label: "L\xE0m l\u1EA1i",
|
|
2116
|
+
title: "L\xE0m l\u1EA1i (Ctrl/Cmd+Shift+Z)",
|
|
2117
|
+
icon: /* @__PURE__ */ jsx(RedoIcon, {}),
|
|
2118
|
+
onClick: onRedo,
|
|
2119
|
+
disabled: !canRedo
|
|
2152
2120
|
}
|
|
2153
2121
|
],
|
|
2154
2122
|
groups,
|
|
@@ -2533,7 +2501,7 @@ var TransformParamPopover = ({ kind, anchor, defaultValue, onConfirm, onCancel,
|
|
|
2533
2501
|
return createPortal(node, document.body);
|
|
2534
2502
|
};
|
|
2535
2503
|
var GeometryEditorPanel = forwardRef(
|
|
2536
|
-
function GeometryEditorPanel2({ initialState, onInsert, onClose, withLeftPanel = false, onStateChange, isDark, isMobile = false, onOpenDrawer }, ref) {
|
|
2504
|
+
function GeometryEditorPanel2({ initialState, onInsert, onClose, withLeftPanel = false, onStateChange, isDark, isMobile = false, onOpenDrawer, onUndo, onRedo, canUndo, canRedo }, ref) {
|
|
2537
2505
|
const handleRef = useRef(null);
|
|
2538
2506
|
const [ready, setReady] = useState(false);
|
|
2539
2507
|
const [propsPopover, setPropsPopover] = useState(null);
|
|
@@ -2550,7 +2518,8 @@ var GeometryEditorPanel = forwardRef(
|
|
|
2550
2518
|
tool: h.getTool(),
|
|
2551
2519
|
showAxis: h.getShowAxis(),
|
|
2552
2520
|
showGrid: h.getShowGrid(),
|
|
2553
|
-
canUndo: h.canUndo()
|
|
2521
|
+
canUndo: h.canUndo(),
|
|
2522
|
+
canRedo: h.canRedo()
|
|
2554
2523
|
});
|
|
2555
2524
|
}, []);
|
|
2556
2525
|
const handleReady = useCallback((h) => {
|
|
@@ -2592,6 +2561,7 @@ var GeometryEditorPanel = forwardRef(
|
|
|
2592
2561
|
setShowAxis: (b) => handleRef.current?.setShowAxis(b),
|
|
2593
2562
|
setShowGrid: (b) => handleRef.current?.setShowGrid(b),
|
|
2594
2563
|
undo: () => handleRef.current?.undo(),
|
|
2564
|
+
redo: () => handleRef.current?.redo(),
|
|
2595
2565
|
insert: performInsert,
|
|
2596
2566
|
hasContent: () => (handleRef.current?.getCreationLog().length ?? 0) > 0
|
|
2597
2567
|
}), [performInsert]);
|
|
@@ -2641,17 +2611,45 @@ var GeometryEditorPanel = forwardRef(
|
|
|
2641
2611
|
] }),
|
|
2642
2612
|
"D\u1EF1ng h\xECnh h\u1ECDc"
|
|
2643
2613
|
] }),
|
|
2644
|
-
isMobile && /* @__PURE__ */
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2614
|
+
isMobile && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2615
|
+
/* @__PURE__ */ jsx(
|
|
2616
|
+
"button",
|
|
2617
|
+
{
|
|
2618
|
+
type: "button",
|
|
2619
|
+
onClick: onUndo,
|
|
2620
|
+
disabled: !canUndo,
|
|
2621
|
+
"aria-label": "Ho\xE0n t\xE1c",
|
|
2622
|
+
title: "Ho\xE0n t\xE1c (Ctrl/Cmd+Z)",
|
|
2623
|
+
"data-testid": "undo-btn-mobile",
|
|
2624
|
+
className: "inline-flex h-9 w-9 items-center justify-center rounded transition hover:bg-white/15 disabled:opacity-40",
|
|
2625
|
+
children: /* @__PURE__ */ jsx(UndoIcon, {})
|
|
2626
|
+
}
|
|
2627
|
+
),
|
|
2628
|
+
/* @__PURE__ */ jsx(
|
|
2629
|
+
"button",
|
|
2630
|
+
{
|
|
2631
|
+
type: "button",
|
|
2632
|
+
onClick: onRedo,
|
|
2633
|
+
disabled: !canRedo,
|
|
2634
|
+
"aria-label": "L\xE0m l\u1EA1i",
|
|
2635
|
+
title: "L\xE0m l\u1EA1i (Ctrl/Cmd+Shift+Z)",
|
|
2636
|
+
"data-testid": "redo-btn-mobile",
|
|
2637
|
+
className: "inline-flex h-9 w-9 items-center justify-center rounded transition hover:bg-white/15 disabled:opacity-40",
|
|
2638
|
+
children: /* @__PURE__ */ jsx(RedoIcon, {})
|
|
2639
|
+
}
|
|
2640
|
+
),
|
|
2641
|
+
/* @__PURE__ */ jsx(
|
|
2642
|
+
"button",
|
|
2643
|
+
{
|
|
2644
|
+
type: "button",
|
|
2645
|
+
onClick: handleInsert,
|
|
2646
|
+
disabled: !ready,
|
|
2647
|
+
"data-testid": "geometry-insert-btn-mobile",
|
|
2648
|
+
className: "rounded bg-white/15 px-3 py-1.5 text-xs font-semibold transition hover:bg-white/25 disabled:opacity-50",
|
|
2649
|
+
children: "Ch\xE8n"
|
|
2650
|
+
}
|
|
2651
|
+
)
|
|
2652
|
+
] }),
|
|
2655
2653
|
/* @__PURE__ */ jsx("button", { onClick: onClose, "aria-label": "\u0110\xF3ng", className: "inline-flex h-9 w-9 items-center justify-center rounded transition hover:bg-white/15", children: /* @__PURE__ */ jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2656
2654
|
/* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" }),
|
|
2657
2655
|
/* @__PURE__ */ jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" })
|
|
@@ -2762,7 +2760,8 @@ var INITIAL_GEOM_STATE = {
|
|
|
2762
2760
|
tool: "move",
|
|
2763
2761
|
showAxis: false,
|
|
2764
2762
|
showGrid: false,
|
|
2765
|
-
canUndo: false
|
|
2763
|
+
canUndo: false,
|
|
2764
|
+
canRedo: false
|
|
2766
2765
|
};
|
|
2767
2766
|
var GeometryStampHost = forwardRef(
|
|
2768
2767
|
function GeometryStampHost2({ api, editingElement, onClose, isDark }, ref) {
|
|
@@ -2828,6 +2827,8 @@ var GeometryStampHost = forwardRef(
|
|
|
2828
2827
|
onShowGridChange: (b) => panelRef.current?.setShowGrid(b),
|
|
2829
2828
|
onUndo: () => panelRef.current?.undo(),
|
|
2830
2829
|
canUndo: geomState.canUndo,
|
|
2830
|
+
onRedo: () => panelRef.current?.redo(),
|
|
2831
|
+
canRedo: geomState.canRedo,
|
|
2831
2832
|
onClose,
|
|
2832
2833
|
isDark,
|
|
2833
2834
|
isMobile,
|
|
@@ -2847,7 +2848,11 @@ var GeometryStampHost = forwardRef(
|
|
|
2847
2848
|
withLeftPanel: !isMobile,
|
|
2848
2849
|
isDark,
|
|
2849
2850
|
isMobile,
|
|
2850
|
-
onOpenDrawer: () => setDrawerOpen(true)
|
|
2851
|
+
onOpenDrawer: () => setDrawerOpen(true),
|
|
2852
|
+
onUndo: () => panelRef.current?.undo(),
|
|
2853
|
+
onRedo: () => panelRef.current?.redo(),
|
|
2854
|
+
canUndo: geomState.canUndo,
|
|
2855
|
+
canRedo: geomState.canRedo
|
|
2851
2856
|
}
|
|
2852
2857
|
)
|
|
2853
2858
|
] });
|
|
@@ -2855,5 +2860,5 @@ var GeometryStampHost = forwardRef(
|
|
|
2855
2860
|
);
|
|
2856
2861
|
|
|
2857
2862
|
export { GeometryStampHost };
|
|
2858
|
-
//# sourceMappingURL=host-
|
|
2859
|
-
//# sourceMappingURL=host-
|
|
2863
|
+
//# sourceMappingURL=host-VDNAJMLC.mjs.map
|
|
2864
|
+
//# sourceMappingURL=host-VDNAJMLC.mjs.map
|