@xom11/whiteboard 0.9.1 → 0.10.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/dist/{chunk-ZVN356JZ.mjs → chunk-D257NCQW.mjs} +3 -3
- package/dist/{chunk-ZVN356JZ.mjs.map → chunk-D257NCQW.mjs.map} +1 -1
- package/dist/{chunk-KEYZ5EZT.mjs → chunk-G7FR3AIV.mjs} +44 -5
- package/dist/chunk-G7FR3AIV.mjs.map +1 -0
- package/dist/chunk-PWIMZIB6.mjs +62 -0
- package/dist/chunk-PWIMZIB6.mjs.map +1 -0
- package/dist/chunk-WQOABS6N.mjs +197 -0
- package/dist/chunk-WQOABS6N.mjs.map +1 -0
- package/dist/{chunk-DU3RHKT5.mjs → chunk-YVJP7NRG.mjs} +4 -4
- package/dist/{chunk-DU3RHKT5.mjs.map → chunk-YVJP7NRG.mjs.map} +1 -1
- package/dist/geometry-2d.js +102 -18
- package/dist/geometry-2d.js.map +1 -1
- package/dist/geometry-2d.mjs +2 -2
- package/dist/geometry-3d.js +152 -93
- package/dist/geometry-3d.js.map +1 -1
- package/dist/geometry-3d.mjs +2 -2
- package/dist/graph-2d.js +88 -20
- package/dist/graph-2d.js.map +1 -1
- package/dist/graph-2d.mjs +1 -1
- package/dist/{host-PIIDSMVE.mjs → host-N6ACNJKI.mjs} +51 -12
- package/dist/host-N6ACNJKI.mjs.map +1 -0
- package/dist/{host-LZH2FZ2N.mjs → host-NKGV6RF2.mjs} +91 -23
- package/dist/host-NKGV6RF2.mjs.map +1 -0
- package/dist/{host-VDNAJMLC.mjs → host-XVK7UCRE.mjs} +62 -18
- package/dist/host-XVK7UCRE.mjs.map +1 -0
- package/dist/index.d.mts +127 -1
- package/dist/index.d.ts +127 -1
- package/dist/index.js +1336 -177
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +993 -52
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -1
- package/dist/chunk-DU2NFHRR.mjs +0 -103
- package/dist/chunk-DU2NFHRR.mjs.map +0 -1
- package/dist/chunk-IUVV52HO.mjs +0 -144
- package/dist/chunk-IUVV52HO.mjs.map +0 -1
- package/dist/chunk-KEYZ5EZT.mjs.map +0 -1
- package/dist/host-LZH2FZ2N.mjs.map +0 -1
- package/dist/host-PIIDSMVE.mjs.map +0 -1
- package/dist/host-VDNAJMLC.mjs.map +0 -1
package/dist/geometry-3d.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
export { geometry3dStamp } from './chunk-
|
|
3
|
-
export { isGeometry3DCustomData } from './chunk-
|
|
2
|
+
export { geometry3dStamp } from './chunk-PWIMZIB6.mjs';
|
|
3
|
+
export { isGeometry3DCustomData } from './chunk-WQOABS6N.mjs';
|
|
4
4
|
import './chunk-HTBLO5JO.mjs';
|
|
5
5
|
import './chunk-BJTO5JO5.mjs';
|
|
6
6
|
//# sourceMappingURL=geometry-3d.mjs.map
|
package/dist/graph-2d.js
CHANGED
|
@@ -907,9 +907,15 @@ function CloseIcon() {
|
|
|
907
907
|
] });
|
|
908
908
|
}
|
|
909
909
|
function UndoIcon() {
|
|
910
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "
|
|
911
|
-
/* @__PURE__ */ jsxRuntime.jsx("
|
|
912
|
-
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3
|
|
910
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
911
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3 10 L8 5 L8 8 L15 8 A5 5 0 0 1 20 13 L20 16" }),
|
|
912
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3 10 L8 15 L8 12" })
|
|
913
|
+
] });
|
|
914
|
+
}
|
|
915
|
+
function RedoIcon() {
|
|
916
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
917
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 10 L16 5 L16 8 L9 8 A5 5 0 0 0 4 13 L4 16" }),
|
|
918
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 10 L16 15 L16 12" })
|
|
913
919
|
] });
|
|
914
920
|
}
|
|
915
921
|
function ResetViewIcon() {
|
|
@@ -994,9 +1000,23 @@ function PanelBody(props) {
|
|
|
994
1000
|
disabled: !props.canUndo,
|
|
995
1001
|
title: "Ho\xE0n t\xE1c (Ctrl/Cmd+Z)",
|
|
996
1002
|
"aria-label": "Ho\xE0n t\xE1c",
|
|
1003
|
+
"data-testid": "undo-btn",
|
|
997
1004
|
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",
|
|
998
1005
|
children: /* @__PURE__ */ jsxRuntime.jsx(UndoIcon, {})
|
|
999
1006
|
}
|
|
1007
|
+
),
|
|
1008
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1009
|
+
"button",
|
|
1010
|
+
{
|
|
1011
|
+
type: "button",
|
|
1012
|
+
onClick: props.onRedo,
|
|
1013
|
+
disabled: !props.canRedo,
|
|
1014
|
+
title: "L\xE0m l\u1EA1i (Ctrl/Cmd+Shift+Z)",
|
|
1015
|
+
"aria-label": "L\xE0m l\u1EA1i",
|
|
1016
|
+
"data-testid": "redo-btn",
|
|
1017
|
+
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",
|
|
1018
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(RedoIcon, {})
|
|
1019
|
+
}
|
|
1000
1020
|
)
|
|
1001
1021
|
] }) }),
|
|
1002
1022
|
/* @__PURE__ */ jsxRuntime.jsx(Section, { label: "C\xF4ng c\u1EE5", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-4 gap-1", children: GRAPH_TOOLS.map((t) => {
|
|
@@ -1352,6 +1372,7 @@ var init_EditorPanel = __esm({
|
|
|
1352
1372
|
const [errors, setErrors] = react.useState({});
|
|
1353
1373
|
const [tool, setToolState] = react.useState("move");
|
|
1354
1374
|
const undoStackRef = react.useRef([]);
|
|
1375
|
+
const redoStackRef = react.useRef([]);
|
|
1355
1376
|
const idCounterRef = react.useRef(1);
|
|
1356
1377
|
const toolRef = react.useRef(tool);
|
|
1357
1378
|
toolRef.current = tool;
|
|
@@ -1362,6 +1383,7 @@ var init_EditorPanel = __esm({
|
|
|
1362
1383
|
const pushUndo = react.useCallback((g) => {
|
|
1363
1384
|
undoStackRef.current.push(g);
|
|
1364
1385
|
if (undoStackRef.current.length > 30) undoStackRef.current.shift();
|
|
1386
|
+
redoStackRef.current = [];
|
|
1365
1387
|
}, []);
|
|
1366
1388
|
const setErrorsWithNotify = react.useCallback(
|
|
1367
1389
|
(updater) => {
|
|
@@ -1378,7 +1400,8 @@ var init_EditorPanel = __esm({
|
|
|
1378
1400
|
tool: t,
|
|
1379
1401
|
showAxis: g.view.showAxis,
|
|
1380
1402
|
showGrid: g.view.showGrid,
|
|
1381
|
-
canUndo: undoStackRef.current.length > 0
|
|
1403
|
+
canUndo: undoStackRef.current.length > 0,
|
|
1404
|
+
canRedo: redoStackRef.current.length > 0
|
|
1382
1405
|
});
|
|
1383
1406
|
}, []);
|
|
1384
1407
|
const updateGraph = react.useCallback(
|
|
@@ -1393,6 +1416,58 @@ var init_EditorPanel = __esm({
|
|
|
1393
1416
|
},
|
|
1394
1417
|
[pushUndo, notifyStateChange]
|
|
1395
1418
|
);
|
|
1419
|
+
const doUndo = react.useCallback(() => {
|
|
1420
|
+
const prev = undoStackRef.current.pop();
|
|
1421
|
+
if (!prev) return;
|
|
1422
|
+
redoStackRef.current.push(graphRef.current);
|
|
1423
|
+
if (redoStackRef.current.length > 30) redoStackRef.current.shift();
|
|
1424
|
+
graphRef.current = prev;
|
|
1425
|
+
forceUpdate((n) => n + 1);
|
|
1426
|
+
propsRef.current.onStateChange({
|
|
1427
|
+
tool: toolRef.current,
|
|
1428
|
+
showAxis: prev.view.showAxis,
|
|
1429
|
+
showGrid: prev.view.showGrid,
|
|
1430
|
+
canUndo: undoStackRef.current.length > 0,
|
|
1431
|
+
canRedo: redoStackRef.current.length > 0
|
|
1432
|
+
});
|
|
1433
|
+
propsRef.current.onGraphChange?.(prev);
|
|
1434
|
+
}, []);
|
|
1435
|
+
const doRedo = react.useCallback(() => {
|
|
1436
|
+
const next = redoStackRef.current.pop();
|
|
1437
|
+
if (!next) return;
|
|
1438
|
+
undoStackRef.current.push(graphRef.current);
|
|
1439
|
+
if (undoStackRef.current.length > 30) undoStackRef.current.shift();
|
|
1440
|
+
graphRef.current = next;
|
|
1441
|
+
forceUpdate((n) => n + 1);
|
|
1442
|
+
propsRef.current.onStateChange({
|
|
1443
|
+
tool: toolRef.current,
|
|
1444
|
+
showAxis: next.view.showAxis,
|
|
1445
|
+
showGrid: next.view.showGrid,
|
|
1446
|
+
canUndo: undoStackRef.current.length > 0,
|
|
1447
|
+
canRedo: redoStackRef.current.length > 0
|
|
1448
|
+
});
|
|
1449
|
+
propsRef.current.onGraphChange?.(next);
|
|
1450
|
+
}, []);
|
|
1451
|
+
react.useEffect(() => {
|
|
1452
|
+
const onKey = (e) => {
|
|
1453
|
+
const ae = document.activeElement;
|
|
1454
|
+
const inField = !!(ae && (ae.tagName === "INPUT" || ae.tagName === "TEXTAREA" || ae.isContentEditable));
|
|
1455
|
+
if (inField) return;
|
|
1456
|
+
if (!(e.metaKey || e.ctrlKey)) return;
|
|
1457
|
+
const key = e.key.toLowerCase();
|
|
1458
|
+
if (key === "z" && !e.shiftKey) {
|
|
1459
|
+
e.preventDefault();
|
|
1460
|
+
e.stopPropagation();
|
|
1461
|
+
doUndo();
|
|
1462
|
+
} else if (key === "z" && e.shiftKey || key === "y" && !e.shiftKey) {
|
|
1463
|
+
e.preventDefault();
|
|
1464
|
+
e.stopPropagation();
|
|
1465
|
+
doRedo();
|
|
1466
|
+
}
|
|
1467
|
+
};
|
|
1468
|
+
window.addEventListener("keydown", onKey, { capture: true });
|
|
1469
|
+
return () => window.removeEventListener("keydown", onKey, { capture: true });
|
|
1470
|
+
}, [doUndo, doRedo]);
|
|
1396
1471
|
const onBoardEvent = react.useCallback((ev) => {
|
|
1397
1472
|
const currentTool = toolRef.current;
|
|
1398
1473
|
if (currentTool === "point-on-curve" && ev.type === "click-curve" && ev.functionId && ev.x !== void 0) {
|
|
@@ -1445,7 +1520,8 @@ var init_EditorPanel = __esm({
|
|
|
1445
1520
|
tool: t,
|
|
1446
1521
|
showAxis: g.view.showAxis,
|
|
1447
1522
|
showGrid: g.view.showGrid,
|
|
1448
|
-
canUndo: undoStackRef.current.length > 0
|
|
1523
|
+
canUndo: undoStackRef.current.length > 0,
|
|
1524
|
+
canRedo: redoStackRef.current.length > 0
|
|
1449
1525
|
});
|
|
1450
1526
|
},
|
|
1451
1527
|
setShowAxis: (b) => updateGraph((g) => ({ ...g, view: { ...g.view, showAxis: b } })),
|
|
@@ -1454,19 +1530,8 @@ var init_EditorPanel = __esm({
|
|
|
1454
1530
|
...g,
|
|
1455
1531
|
view: { ...g.view, xMin: -10, xMax: 10, yMin: -10, yMax: 10 }
|
|
1456
1532
|
})),
|
|
1457
|
-
undo:
|
|
1458
|
-
|
|
1459
|
-
if (!prev) return;
|
|
1460
|
-
graphRef.current = prev;
|
|
1461
|
-
forceUpdate((n) => n + 1);
|
|
1462
|
-
propsRef.current.onStateChange({
|
|
1463
|
-
tool: toolRef.current,
|
|
1464
|
-
showAxis: prev.view.showAxis,
|
|
1465
|
-
showGrid: prev.view.showGrid,
|
|
1466
|
-
canUndo: undoStackRef.current.length > 0
|
|
1467
|
-
});
|
|
1468
|
-
propsRef.current.onGraphChange?.(prev);
|
|
1469
|
-
},
|
|
1533
|
+
undo: doUndo,
|
|
1534
|
+
redo: doRedo,
|
|
1470
1535
|
addFunction: (expr) => {
|
|
1471
1536
|
const g = graphRef.current;
|
|
1472
1537
|
if (g.functions.length >= MAX_FUNCTIONS) {
|
|
@@ -1559,7 +1624,7 @@ var init_EditorPanel = __esm({
|
|
|
1559
1624
|
}),
|
|
1560
1625
|
// deps: updateGraph stable; errors changes when function errors change; setErrorsWithNotify stable
|
|
1561
1626
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1562
|
-
[updateGraph, errors, setErrorsWithNotify]
|
|
1627
|
+
[updateGraph, errors, setErrorsWithNotify, doUndo, doRedo]
|
|
1563
1628
|
);
|
|
1564
1629
|
react.useEffect(() => {
|
|
1565
1630
|
if (!initialGraphNotifiedRef.current) {
|
|
@@ -1859,7 +1924,8 @@ var init_host = __esm({
|
|
|
1859
1924
|
tool: "move",
|
|
1860
1925
|
showAxis: true,
|
|
1861
1926
|
showGrid: true,
|
|
1862
|
-
canUndo: false
|
|
1927
|
+
canUndo: false,
|
|
1928
|
+
canRedo: false
|
|
1863
1929
|
};
|
|
1864
1930
|
Graph2DStampHost = react.forwardRef(
|
|
1865
1931
|
function Graph2DStampHost2({ api, editingElement, onClose, isDark }, ref) {
|
|
@@ -1919,6 +1985,8 @@ var init_host = __esm({
|
|
|
1919
1985
|
onResetView: () => panelRef.current?.resetView(),
|
|
1920
1986
|
onUndo: () => panelRef.current?.undo(),
|
|
1921
1987
|
canUndo: graphUIState.canUndo,
|
|
1988
|
+
onRedo: () => panelRef.current?.redo(),
|
|
1989
|
+
canRedo: graphUIState.canRedo,
|
|
1922
1990
|
onClose,
|
|
1923
1991
|
isDark,
|
|
1924
1992
|
isMobile,
|