@underverse-ui/underverse 1.0.155 → 1.0.157
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/api-reference.json +1 -1
- package/dist/index.cjs +390 -63
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -3
- package/dist/index.d.ts +38 -3
- package/dist/index.js +392 -65
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1055,12 +1055,15 @@ var en_default = {
|
|
|
1055
1055
|
clickToOpenNewTab: "Click to open this link in a new tab.",
|
|
1056
1056
|
clickToOpenLink: "Click to open link.",
|
|
1057
1057
|
noDescription: "No description available.",
|
|
1058
|
-
failedToLoad: "Failed to load link preview. Click to open link."
|
|
1058
|
+
failedToLoad: "Failed to load link preview. Click to open link.",
|
|
1059
|
+
previewFailed: "Preview failed to load",
|
|
1060
|
+
retryPreview: "Retry preview"
|
|
1059
1061
|
},
|
|
1060
1062
|
fileCard: {
|
|
1061
1063
|
unnamed: "Unnamed file",
|
|
1062
1064
|
uploading: "(Uploading...)",
|
|
1063
|
-
uploadFailed: "Upload failed"
|
|
1065
|
+
uploadFailed: "Upload failed",
|
|
1066
|
+
retryUpload: "Retry upload"
|
|
1064
1067
|
},
|
|
1065
1068
|
menubar: {
|
|
1066
1069
|
file: "File",
|
|
@@ -1447,12 +1450,15 @@ var vi_default = {
|
|
|
1447
1450
|
clickToOpenNewTab: "B\u1EA5m \u0111\u1EC3 m\u1EDF li\xEAn k\u1EBFt n\xE0y trong tab m\u1EDBi.",
|
|
1448
1451
|
clickToOpenLink: "B\u1EA5m \u0111\u1EC3 m\u1EDF li\xEAn k\u1EBFt.",
|
|
1449
1452
|
noDescription: "Kh\xF4ng c\xF3 m\xF4 t\u1EA3.",
|
|
1450
|
-
failedToLoad: "T\u1EA3i b\u1EA3n xem tr\u01B0\u1EDBc th\u1EA5t b\u1EA1i. B\u1EA5m \u0111\u1EC3 m\u1EDF li\xEAn k\u1EBFt."
|
|
1453
|
+
failedToLoad: "T\u1EA3i b\u1EA3n xem tr\u01B0\u1EDBc th\u1EA5t b\u1EA1i. B\u1EA5m \u0111\u1EC3 m\u1EDF li\xEAn k\u1EBFt.",
|
|
1454
|
+
previewFailed: "Kh\xF4ng t\u1EA3i \u0111\u01B0\u1EE3c b\u1EA3n xem tr\u01B0\u1EDBc",
|
|
1455
|
+
retryPreview: "Th\u1EED l\u1EA1i"
|
|
1451
1456
|
},
|
|
1452
1457
|
fileCard: {
|
|
1453
1458
|
unnamed: "T\u1EC7p kh\xF4ng t\xEAn",
|
|
1454
1459
|
uploading: "(\u0110ang t\u1EA3i l\xEAn...)",
|
|
1455
|
-
uploadFailed: "T\u1EA3i l\xEAn th\u1EA5t b\u1EA1i"
|
|
1460
|
+
uploadFailed: "T\u1EA3i l\xEAn th\u1EA5t b\u1EA1i",
|
|
1461
|
+
retryUpload: "T\u1EA3i l\u1EA1i"
|
|
1456
1462
|
},
|
|
1457
1463
|
menubar: {
|
|
1458
1464
|
file: "T\u1EADp tin",
|
|
@@ -1839,12 +1845,15 @@ var ko_default = {
|
|
|
1839
1845
|
clickToOpenNewTab: "\uD074\uB9AD\uD558\uC5EC \uC774 \uB9C1\uD06C\uB97C \uC0C8 \uD0ED\uC5D0\uC11C \uC5FD\uB2C8\uB2E4.",
|
|
1840
1846
|
clickToOpenLink: "\uD074\uB9AD\uD558\uC5EC \uB9C1\uD06C\uB97C \uC5FD\uB2C8\uB2E4.",
|
|
1841
1847
|
noDescription: "\uC124\uBA85\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
1842
|
-
failedToLoad: "\uB9C1\uD06C \uBBF8\uB9AC\uBCF4\uAE30\uB97C \uBD88\uB7EC\uC624\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4. \uD074\uB9AD\uD558\uC5EC \uB9C1\uD06C\uB97C \uC5FD\uB2C8\uB2E4."
|
|
1848
|
+
failedToLoad: "\uB9C1\uD06C \uBBF8\uB9AC\uBCF4\uAE30\uB97C \uBD88\uB7EC\uC624\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4. \uD074\uB9AD\uD558\uC5EC \uB9C1\uD06C\uB97C \uC5FD\uB2C8\uB2E4.",
|
|
1849
|
+
previewFailed: "\uBBF8\uB9AC\uBCF4\uAE30\uB97C \uBD88\uB7EC\uC624\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4",
|
|
1850
|
+
retryPreview: "\uB2E4\uC2DC \uC2DC\uB3C4"
|
|
1843
1851
|
},
|
|
1844
1852
|
fileCard: {
|
|
1845
1853
|
unnamed: "\uC774\uB984 \uC5C6\uB294 \uD30C\uC77C",
|
|
1846
1854
|
uploading: "(\uC5C5\uB85C\uB4DC \uC911...)",
|
|
1847
|
-
uploadFailed: "\uC5C5\uB85C\uB4DC\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4."
|
|
1855
|
+
uploadFailed: "\uC5C5\uB85C\uB4DC\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.",
|
|
1856
|
+
retryUpload: "\uB2E4\uC2DC \uC5C5\uB85C\uB4DC"
|
|
1848
1857
|
},
|
|
1849
1858
|
menubar: {
|
|
1850
1859
|
file: "\uD30C\uC77C",
|
|
@@ -2231,12 +2240,15 @@ var ja_default = {
|
|
|
2231
2240
|
clickToOpenNewTab: "\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u3053\u306E\u30EA\u30F3\u30AF\u3092\u65B0\u3057\u3044\u30BF\u30D6\u3067\u958B\u304F\u3002",
|
|
2232
2241
|
clickToOpenLink: "\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u30EA\u30F3\u30AF\u3092\u958B\u304F\u3002",
|
|
2233
2242
|
noDescription: "\u8AAC\u660E\u306F\u3042\u308A\u307E\u305B\u3093\u3002",
|
|
2234
|
-
failedToLoad: "\u30D7\u30EC\u30D3\u30E5\u30FC\u306E\u8AAD\u307F\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u30EA\u30F3\u30AF\u3092\u958B\u304F\u3002"
|
|
2243
|
+
failedToLoad: "\u30D7\u30EC\u30D3\u30E5\u30FC\u306E\u8AAD\u307F\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u30EA\u30F3\u30AF\u3092\u958B\u304F\u3002",
|
|
2244
|
+
previewFailed: "\u30D7\u30EC\u30D3\u30E5\u30FC\u3092\u8AAD\u307F\u8FBC\u3081\u307E\u305B\u3093\u3067\u3057\u305F",
|
|
2245
|
+
retryPreview: "\u518D\u8A66\u884C"
|
|
2235
2246
|
},
|
|
2236
2247
|
fileCard: {
|
|
2237
2248
|
unnamed: "\u540D\u524D\u306A\u3057\u30D5\u30A1\u30A4\u30EB",
|
|
2238
2249
|
uploading: "(\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u4E2D...)",
|
|
2239
|
-
uploadFailed: "\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u5931\u6557"
|
|
2250
|
+
uploadFailed: "\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u5931\u6557",
|
|
2251
|
+
retryUpload: "\u518D\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9"
|
|
2240
2252
|
},
|
|
2241
2253
|
menubar: {
|
|
2242
2254
|
file: "\u30D5\u30A1\u30A4\u30EB",
|
|
@@ -25025,7 +25037,7 @@ var import_core2 = require("@tiptap/core");
|
|
|
25025
25037
|
var import_react45 = require("@tiptap/react");
|
|
25026
25038
|
|
|
25027
25039
|
// src/components/UEditor/BookmarkView.tsx
|
|
25028
|
-
var import_react43 = require("react");
|
|
25040
|
+
var import_react43 = __toESM(require("react"), 1);
|
|
25029
25041
|
var import_react44 = require("@tiptap/react");
|
|
25030
25042
|
var import_lucide_react41 = require("lucide-react");
|
|
25031
25043
|
var import_jsx_runtime77 = require("react/jsx-runtime");
|
|
@@ -25034,12 +25046,18 @@ var BookmarkView = ({ node, updateAttributes, selected, editor }) => {
|
|
|
25034
25046
|
const { url, title, description, image, publisher } = node.attrs;
|
|
25035
25047
|
const [loading2, setLoading] = (0, import_react43.useState)(false);
|
|
25036
25048
|
const [error, setError] = (0, import_react43.useState)(false);
|
|
25049
|
+
const [retryToken, setRetryToken] = (0, import_react43.useState)(0);
|
|
25050
|
+
const fetchedRetryTokenRef = import_react43.default.useRef(-1);
|
|
25051
|
+
const fetchRequestIdRef = import_react43.default.useRef(0);
|
|
25037
25052
|
(0, import_react43.useEffect)(() => {
|
|
25038
|
-
if (title) return;
|
|
25039
|
-
|
|
25053
|
+
if (title && retryToken === 0) return;
|
|
25054
|
+
if (fetchedRetryTokenRef.current === retryToken) return;
|
|
25055
|
+
fetchedRetryTokenRef.current = retryToken;
|
|
25056
|
+
const requestId = fetchRequestIdRef.current + 1;
|
|
25057
|
+
fetchRequestIdRef.current = requestId;
|
|
25040
25058
|
const safeUpdateAttributes = (attrs) => {
|
|
25041
25059
|
Promise.resolve().then(() => {
|
|
25042
|
-
if (
|
|
25060
|
+
if (fetchRequestIdRef.current === requestId && editor && !editor.isDestroyed) {
|
|
25043
25061
|
updateAttributes(attrs);
|
|
25044
25062
|
}
|
|
25045
25063
|
});
|
|
@@ -25066,7 +25084,7 @@ var BookmarkView = ({ node, updateAttributes, selected, editor }) => {
|
|
|
25066
25084
|
setLoading(true);
|
|
25067
25085
|
setError(false);
|
|
25068
25086
|
fetchMetadata(url).then((meta) => {
|
|
25069
|
-
if (
|
|
25087
|
+
if (fetchRequestIdRef.current !== requestId) return;
|
|
25070
25088
|
safeUpdateAttributes({
|
|
25071
25089
|
title: meta.title || new URL(url).hostname || url,
|
|
25072
25090
|
description: meta.description || t("bookmark.noDescription"),
|
|
@@ -25075,33 +25093,22 @@ var BookmarkView = ({ node, updateAttributes, selected, editor }) => {
|
|
|
25075
25093
|
});
|
|
25076
25094
|
setLoading(false);
|
|
25077
25095
|
}).catch(() => {
|
|
25078
|
-
if (
|
|
25096
|
+
if (fetchRequestIdRef.current !== requestId) return;
|
|
25079
25097
|
setError(true);
|
|
25080
25098
|
setLoading(false);
|
|
25081
|
-
try {
|
|
25082
|
-
const hostname = new URL(url).hostname;
|
|
25083
|
-
safeUpdateAttributes({
|
|
25084
|
-
title: hostname || url,
|
|
25085
|
-
description: t("bookmark.failedToLoad"),
|
|
25086
|
-
publisher: hostname
|
|
25087
|
-
});
|
|
25088
|
-
} catch {
|
|
25089
|
-
safeUpdateAttributes({
|
|
25090
|
-
title: url,
|
|
25091
|
-
description: t("bookmark.clickToOpenLink"),
|
|
25092
|
-
publisher: ""
|
|
25093
|
-
});
|
|
25094
|
-
}
|
|
25095
25099
|
});
|
|
25096
|
-
return
|
|
25097
|
-
|
|
25098
|
-
};
|
|
25099
|
-
}, [url, title, editor, updateAttributes, t]);
|
|
25100
|
+
return void 0;
|
|
25101
|
+
}, [url, title, editor, updateAttributes, t, retryToken]);
|
|
25100
25102
|
const handleOpenLink = (e) => {
|
|
25101
25103
|
e.preventDefault();
|
|
25102
25104
|
e.stopPropagation();
|
|
25103
25105
|
window.open(url, "_blank", "noopener,noreferrer");
|
|
25104
25106
|
};
|
|
25107
|
+
const handleRetryPreview = (event) => {
|
|
25108
|
+
event.preventDefault();
|
|
25109
|
+
event.stopPropagation();
|
|
25110
|
+
setRetryToken((value) => value + 1);
|
|
25111
|
+
};
|
|
25105
25112
|
const displayPublisher = publisher || (() => {
|
|
25106
25113
|
try {
|
|
25107
25114
|
return new URL(url).hostname;
|
|
@@ -25137,6 +25144,24 @@ var BookmarkView = ({ node, updateAttributes, selected, editor }) => {
|
|
|
25137
25144
|
/* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("span", { className: "text-[11px] text-primary/80 font-mono mt-2 truncate flex items-center gap-1", children: [
|
|
25138
25145
|
url,
|
|
25139
25146
|
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)(import_lucide_react41.ExternalLink, { className: "h-3 w-3 flex-shrink-0" })
|
|
25147
|
+
] }),
|
|
25148
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: "mt-2 flex flex-wrap items-center gap-2 text-xs text-destructive", children: [
|
|
25149
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("span", { className: "inline-flex items-center gap-1", children: [
|
|
25150
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)(import_lucide_react41.AlertCircle, { className: "h-3.5 w-3.5" }),
|
|
25151
|
+
t("bookmark.previewFailed")
|
|
25152
|
+
] }),
|
|
25153
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsxs)(
|
|
25154
|
+
"button",
|
|
25155
|
+
{
|
|
25156
|
+
type: "button",
|
|
25157
|
+
onClick: handleRetryPreview,
|
|
25158
|
+
className: "inline-flex items-center gap-1 rounded-md border border-destructive/30 px-2 py-0.5 font-medium hover:bg-destructive/10",
|
|
25159
|
+
children: [
|
|
25160
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)(import_lucide_react41.RefreshCw, { className: "h-3 w-3" }),
|
|
25161
|
+
t("bookmark.retryPreview")
|
|
25162
|
+
]
|
|
25163
|
+
}
|
|
25164
|
+
)
|
|
25140
25165
|
] })
|
|
25141
25166
|
] }),
|
|
25142
25167
|
image && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: "relative w-full sm:w-44 h-32 sm:h-auto flex-shrink-0 bg-muted overflow-hidden border-t sm:border-t-0 sm:border-l border-border/50", children: /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
|
|
@@ -25321,6 +25346,7 @@ var FileCardView = ({ node, selected, editor, updateAttributes }) => {
|
|
|
25321
25346
|
const { src, fileName, fileSize, fileType } = node.attrs;
|
|
25322
25347
|
const FileIcon = getFileIcon2(fileType);
|
|
25323
25348
|
const [uploadError, setUploadError] = (0, import_react46.useState)(null);
|
|
25349
|
+
const [retryToken, setRetryToken] = (0, import_react46.useState)(0);
|
|
25324
25350
|
const uploadAttemptedRef = (0, import_react46.useRef)(false);
|
|
25325
25351
|
(0, import_react46.useEffect)(() => {
|
|
25326
25352
|
if (!src || !src.startsWith("data:")) {
|
|
@@ -25352,7 +25378,7 @@ var FileCardView = ({ node, selected, editor, updateAttributes }) => {
|
|
|
25352
25378
|
}
|
|
25353
25379
|
};
|
|
25354
25380
|
void runUpload();
|
|
25355
|
-
}, [src, fileName, fileType, editor, updateAttributes]);
|
|
25381
|
+
}, [src, fileName, fileType, editor, updateAttributes, retryToken]);
|
|
25356
25382
|
const handleDownload = (e) => {
|
|
25357
25383
|
e.preventDefault();
|
|
25358
25384
|
e.stopPropagation();
|
|
@@ -25365,6 +25391,13 @@ var FileCardView = ({ node, selected, editor, updateAttributes }) => {
|
|
|
25365
25391
|
document.body.removeChild(link);
|
|
25366
25392
|
};
|
|
25367
25393
|
const isUploading = (src || "").startsWith("data:");
|
|
25394
|
+
const handleRetryUpload = (event) => {
|
|
25395
|
+
event.preventDefault();
|
|
25396
|
+
event.stopPropagation();
|
|
25397
|
+
uploadAttemptedRef.current = false;
|
|
25398
|
+
setUploadError(null);
|
|
25399
|
+
setRetryToken((value) => value + 1);
|
|
25400
|
+
};
|
|
25368
25401
|
return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(
|
|
25369
25402
|
import_react47.NodeViewWrapper,
|
|
25370
25403
|
{
|
|
@@ -25383,7 +25416,19 @@ var FileCardView = ({ node, selected, editor, updateAttributes }) => {
|
|
|
25383
25416
|
isUploading && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: cn(
|
|
25384
25417
|
"font-medium truncate max-w-[200px]",
|
|
25385
25418
|
uploadError ? "text-destructive" : "text-primary animate-pulse"
|
|
25386
|
-
), children: uploadError ? `${t("fileCard.uploadFailed") || "T\u1EA3i l\xEAn th\u1EA5t b\u1EA1i"}: ${uploadError}` : t("fileCard.uploading") })
|
|
25419
|
+
), children: uploadError ? `${t("fileCard.uploadFailed") || "T\u1EA3i l\xEAn th\u1EA5t b\u1EA1i"}: ${uploadError}` : t("fileCard.uploading") }),
|
|
25420
|
+
isUploading && uploadError && /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(
|
|
25421
|
+
"button",
|
|
25422
|
+
{
|
|
25423
|
+
type: "button",
|
|
25424
|
+
onClick: handleRetryUpload,
|
|
25425
|
+
className: "inline-flex items-center gap-1 rounded-md border border-destructive/30 px-1.5 py-0.5 text-[11px] font-medium text-destructive hover:bg-destructive/10",
|
|
25426
|
+
children: [
|
|
25427
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_lucide_react42.RefreshCw, { className: "h-3 w-3" }),
|
|
25428
|
+
t("fileCard.retryUpload")
|
|
25429
|
+
]
|
|
25430
|
+
}
|
|
25431
|
+
)
|
|
25387
25432
|
] })
|
|
25388
25433
|
] })
|
|
25389
25434
|
] }),
|
|
@@ -28933,6 +28978,20 @@ function createEmptyCellNode(cellNode) {
|
|
|
28933
28978
|
function createCellCopyForColumnDuplicate(cellNode) {
|
|
28934
28979
|
return cellNode.type.create(cellNode.attrs, cellNode.content);
|
|
28935
28980
|
}
|
|
28981
|
+
function createCellWithDuplicatedLogicalColumn(cellNode, widthIndex) {
|
|
28982
|
+
const colspan = Math.max(1, Number(cellNode.attrs.colspan) || 1);
|
|
28983
|
+
let nextColwidth = null;
|
|
28984
|
+
if (Array.isArray(cellNode.attrs.colwidth)) {
|
|
28985
|
+
nextColwidth = [...cellNode.attrs.colwidth];
|
|
28986
|
+
const duplicateWidth = nextColwidth[widthIndex];
|
|
28987
|
+
nextColwidth.splice(widthIndex + 1, 0, typeof duplicateWidth === "number" ? duplicateWidth : 0);
|
|
28988
|
+
}
|
|
28989
|
+
return cellNode.type.create({
|
|
28990
|
+
...cellNode.attrs,
|
|
28991
|
+
colspan: colspan + 1,
|
|
28992
|
+
...nextColwidth ? { colwidth: nextColwidth } : null
|
|
28993
|
+
}, cellNode.content);
|
|
28994
|
+
}
|
|
28936
28995
|
function getTableRows(tableNode) {
|
|
28937
28996
|
const rows = [];
|
|
28938
28997
|
tableNode.forEach((rowNode, rowOffset) => {
|
|
@@ -29108,6 +29167,11 @@ function duplicateTableColumnAt(editor, columnIndex, cellPos) {
|
|
|
29108
29167
|
return rect && rect.top === rowIndex && rect.left <= columnIndex && columnIndex < rect.right;
|
|
29109
29168
|
});
|
|
29110
29169
|
if (!sourceCell) return rowInfo.node;
|
|
29170
|
+
const sourceRect = safeFindCell(map, sourceCell.relativePos);
|
|
29171
|
+
if (sourceRect && (sourceRect.left < columnIndex || sourceRect.right > columnIndex + 1)) {
|
|
29172
|
+
cells[sourceCell.index] = createCellWithDuplicatedLogicalColumn(sourceCell.node, columnIndex - sourceRect.left);
|
|
29173
|
+
return rowInfo.node.type.create(rowInfo.node.attrs, cells);
|
|
29174
|
+
}
|
|
29111
29175
|
cells.splice(sourceCell.index + 1, 0, createCellCopyForColumnDuplicate(sourceCell.node));
|
|
29112
29176
|
return rowInfo.node.type.create(rowInfo.node.attrs, cells);
|
|
29113
29177
|
});
|
|
@@ -30407,6 +30471,25 @@ function getTableFormulaRecalculationOrder(graph) {
|
|
|
30407
30471
|
}
|
|
30408
30472
|
return { order, circular };
|
|
30409
30473
|
}
|
|
30474
|
+
function getAffectedTableFormulaLabels(graph, changedLabels) {
|
|
30475
|
+
const affected = /* @__PURE__ */ new Set();
|
|
30476
|
+
const queue = Array.from(changedLabels, (label) => label.toUpperCase());
|
|
30477
|
+
for (const label of queue) {
|
|
30478
|
+
if (graph.formulas.has(label)) {
|
|
30479
|
+
affected.add(label);
|
|
30480
|
+
}
|
|
30481
|
+
}
|
|
30482
|
+
for (let index = 0; index < queue.length; index += 1) {
|
|
30483
|
+
const label = queue[index];
|
|
30484
|
+
if (!label) continue;
|
|
30485
|
+
for (const dependent of graph.dependents.get(label) ?? []) {
|
|
30486
|
+
if (affected.has(dependent)) continue;
|
|
30487
|
+
affected.add(dependent);
|
|
30488
|
+
queue.push(dependent);
|
|
30489
|
+
}
|
|
30490
|
+
}
|
|
30491
|
+
return affected;
|
|
30492
|
+
}
|
|
30410
30493
|
function evaluateBasicTableFormula(formula, getCellValue) {
|
|
30411
30494
|
const normalized = normalizeTableFormula(formula);
|
|
30412
30495
|
if (!normalized) {
|
|
@@ -30554,10 +30637,19 @@ var FormulaParser = class {
|
|
|
30554
30637
|
const range = parseTableCellRange(token.value);
|
|
30555
30638
|
if (!range) return { value: null, error: "invalid-reference" };
|
|
30556
30639
|
for (const label of getTableCellRangeLabels(range)) {
|
|
30640
|
+
if (name === "COUNT") {
|
|
30641
|
+
const cellValue2 = this.readOptionalCellNumber(label);
|
|
30642
|
+
if (cellValue2 != null) values.push(cellValue2);
|
|
30643
|
+
continue;
|
|
30644
|
+
}
|
|
30557
30645
|
const cellValue = this.readCellNumber(label);
|
|
30558
30646
|
if (cellValue.error) return cellValue;
|
|
30559
30647
|
values.push(cellValue.value);
|
|
30560
30648
|
}
|
|
30649
|
+
} else if (name === "COUNT" && token.type === "cell") {
|
|
30650
|
+
this.index += 1;
|
|
30651
|
+
const cellValue = this.readOptionalCellNumber(token.value);
|
|
30652
|
+
if (cellValue != null) values.push(cellValue);
|
|
30561
30653
|
} else {
|
|
30562
30654
|
const value = this.parseExpression();
|
|
30563
30655
|
if (value.error) return value;
|
|
@@ -30571,7 +30663,7 @@ var FormulaParser = class {
|
|
|
30571
30663
|
}
|
|
30572
30664
|
return { value: null, error: "invalid-formula" };
|
|
30573
30665
|
}
|
|
30574
|
-
if (values.length === 0) {
|
|
30666
|
+
if (values.length === 0 && name !== "COUNT") {
|
|
30575
30667
|
return { value: null, error: "invalid-formula" };
|
|
30576
30668
|
}
|
|
30577
30669
|
if (name === "SUM") return { value: values.reduce((sum, value) => sum + value, 0), error: null };
|
|
@@ -30589,6 +30681,11 @@ var FormulaParser = class {
|
|
|
30589
30681
|
}
|
|
30590
30682
|
return { value: parsed, error: null };
|
|
30591
30683
|
}
|
|
30684
|
+
readOptionalCellNumber(label) {
|
|
30685
|
+
const value = this.getCellValue(label);
|
|
30686
|
+
const parsed = typeof value === "number" ? value : Number.parseFloat(String(value ?? "").trim());
|
|
30687
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
30688
|
+
}
|
|
30592
30689
|
peekOperator(operators) {
|
|
30593
30690
|
const token = this.tokens[this.index];
|
|
30594
30691
|
return token?.type === "operator" && operators.includes(token.value) ? token : null;
|
|
@@ -30652,6 +30749,41 @@ function getSelectionTableCellNode(editor) {
|
|
|
30652
30749
|
}
|
|
30653
30750
|
return null;
|
|
30654
30751
|
}
|
|
30752
|
+
function getSelectionTableInfo(editor) {
|
|
30753
|
+
const { $from } = editor.state.selection;
|
|
30754
|
+
for (let depth = $from.depth; depth > 0; depth -= 1) {
|
|
30755
|
+
const node = $from.node(depth);
|
|
30756
|
+
if (node.type.name === "table") {
|
|
30757
|
+
return {
|
|
30758
|
+
node,
|
|
30759
|
+
pos: $from.before(depth)
|
|
30760
|
+
};
|
|
30761
|
+
}
|
|
30762
|
+
}
|
|
30763
|
+
return null;
|
|
30764
|
+
}
|
|
30765
|
+
function getSelectionTableCellLabel(editor) {
|
|
30766
|
+
const { $from } = editor.state.selection;
|
|
30767
|
+
let cellDepth = -1;
|
|
30768
|
+
let tableDepth = -1;
|
|
30769
|
+
for (let depth = $from.depth; depth > 0; depth -= 1) {
|
|
30770
|
+
const node = $from.node(depth);
|
|
30771
|
+
if (cellDepth < 0 && (node.type.name === "tableCell" || node.type.name === "tableHeader")) {
|
|
30772
|
+
cellDepth = depth;
|
|
30773
|
+
}
|
|
30774
|
+
if (node.type.name === "table") {
|
|
30775
|
+
tableDepth = depth;
|
|
30776
|
+
break;
|
|
30777
|
+
}
|
|
30778
|
+
}
|
|
30779
|
+
if (cellDepth < 0 || tableDepth < 0) return null;
|
|
30780
|
+
const tableNode = $from.node(tableDepth);
|
|
30781
|
+
const tableStart = $from.start(tableDepth);
|
|
30782
|
+
const relativeCellPos = $from.before(cellDepth) - tableStart;
|
|
30783
|
+
const rect = safeFindCell2(import_tables2.TableMap.get(tableNode), relativeCellPos);
|
|
30784
|
+
if (!rect) return null;
|
|
30785
|
+
return `${indexToColumnName(rect.left)}${rect.top + 1}`;
|
|
30786
|
+
}
|
|
30655
30787
|
function isEditingTableFormulaText(editor) {
|
|
30656
30788
|
const cellNode = getSelectionTableCellNode(editor);
|
|
30657
30789
|
return Boolean(cellNode && getCellText(cellNode).startsWith("="));
|
|
@@ -30663,20 +30795,6 @@ function createCellDisplayContent(cellNode, displayValue) {
|
|
|
30663
30795
|
}
|
|
30664
30796
|
return [paragraphType.create(null, cellNode.type.schema.text(displayValue))];
|
|
30665
30797
|
}
|
|
30666
|
-
function buildTableValueGetter(tableNode) {
|
|
30667
|
-
const map = import_tables2.TableMap.get(tableNode);
|
|
30668
|
-
const values = /* @__PURE__ */ new Map();
|
|
30669
|
-
for (const rowInfo of getTableRows2(tableNode)) {
|
|
30670
|
-
for (const entry of rowInfo.cells) {
|
|
30671
|
-
const rect = safeFindCell2(map, entry.relativePos);
|
|
30672
|
-
if (!rect) continue;
|
|
30673
|
-
const label = `${indexToColumnName(rect.left)}${rect.top + 1}`;
|
|
30674
|
-
const computedValue = entry.node.attrs.computedValue;
|
|
30675
|
-
values.set(label, typeof computedValue === "string" && computedValue.trim() ? computedValue : getCellText(entry.node));
|
|
30676
|
-
}
|
|
30677
|
-
}
|
|
30678
|
-
return (label) => values.get(label.toUpperCase());
|
|
30679
|
-
}
|
|
30680
30798
|
function buildTableValueMap(tableNode) {
|
|
30681
30799
|
const map = import_tables2.TableMap.get(tableNode);
|
|
30682
30800
|
const values = /* @__PURE__ */ new Map();
|
|
@@ -30691,10 +30809,6 @@ function buildTableValueMap(tableNode) {
|
|
|
30691
30809
|
}
|
|
30692
30810
|
return values;
|
|
30693
30811
|
}
|
|
30694
|
-
function getFormulaComputedValue(formula, tableNode) {
|
|
30695
|
-
const result = evaluateBasicTableFormula(formula, buildTableValueGetter(tableNode));
|
|
30696
|
-
return result.error ? `#${result.error.toUpperCase()}` : String(result.value);
|
|
30697
|
-
}
|
|
30698
30812
|
function normalizeFormulaInput(formula) {
|
|
30699
30813
|
const trimmed = formula.trim();
|
|
30700
30814
|
if (!trimmed) return "";
|
|
@@ -30705,19 +30819,19 @@ function setSelectedTableCellFormula(editor, formula) {
|
|
|
30705
30819
|
const { state, view } = editor;
|
|
30706
30820
|
if (!normalized) {
|
|
30707
30821
|
const clearedFormula = (0, import_tables2.setCellAttr)("formula", null)(state, view.dispatch.bind(view));
|
|
30708
|
-
const
|
|
30709
|
-
if (clearedFormula ||
|
|
30822
|
+
const clearedValue2 = (0, import_tables2.setCellAttr)("computedValue", null)(editor.state, view.dispatch.bind(view));
|
|
30823
|
+
if (clearedFormula || clearedValue2) {
|
|
30824
|
+
recalculateActiveTableFormulas(editor);
|
|
30710
30825
|
view.focus();
|
|
30711
30826
|
dispatchTableLayoutChange(editor);
|
|
30712
30827
|
return true;
|
|
30713
30828
|
}
|
|
30714
30829
|
return false;
|
|
30715
30830
|
}
|
|
30716
|
-
const rect = (0, import_tables2.selectedRect)(state);
|
|
30717
|
-
const computedValue = getFormulaComputedValue(normalized, rect.table);
|
|
30718
30831
|
const appliedFormula = (0, import_tables2.setCellAttr)("formula", normalized)(state, view.dispatch.bind(view));
|
|
30719
|
-
const
|
|
30720
|
-
if (appliedFormula ||
|
|
30832
|
+
const clearedValue = (0, import_tables2.setCellAttr)("computedValue", null)(editor.state, view.dispatch.bind(view));
|
|
30833
|
+
if (appliedFormula || clearedValue) {
|
|
30834
|
+
recalculateActiveTableFormulas(editor);
|
|
30721
30835
|
view.focus();
|
|
30722
30836
|
dispatchTableLayoutChange(editor);
|
|
30723
30837
|
return true;
|
|
@@ -30799,7 +30913,7 @@ function promoteFormulaTextInTableNode(tableNode) {
|
|
|
30799
30913
|
changed
|
|
30800
30914
|
};
|
|
30801
30915
|
}
|
|
30802
|
-
function recalculateTableNode(tableNode) {
|
|
30916
|
+
function recalculateTableNode(tableNode, options) {
|
|
30803
30917
|
const promoted = promoteFormulaTextInTableNode(tableNode);
|
|
30804
30918
|
tableNode = promoted.tableNode;
|
|
30805
30919
|
const map = import_tables2.TableMap.get(tableNode);
|
|
@@ -30829,13 +30943,16 @@ function recalculateTableNode(tableNode) {
|
|
|
30829
30943
|
}))
|
|
30830
30944
|
);
|
|
30831
30945
|
const { order, circular } = getTableFormulaRecalculationOrder(graph);
|
|
30946
|
+
const affectedLabels = options?.changedLabels ? getAffectedTableFormulaLabels(graph, options.changedLabels) : null;
|
|
30832
30947
|
const computedValues = /* @__PURE__ */ new Map();
|
|
30833
30948
|
const getCellValue = (label) => values.get(label.toUpperCase());
|
|
30834
30949
|
for (const label of circular) {
|
|
30950
|
+
if (affectedLabels && !affectedLabels.has(label)) continue;
|
|
30835
30951
|
computedValues.set(label, formatFormulaError("circular-reference"));
|
|
30836
30952
|
values.set(label, formatFormulaError("circular-reference"));
|
|
30837
30953
|
}
|
|
30838
30954
|
for (const label of order) {
|
|
30955
|
+
if (affectedLabels && !affectedLabels.has(label)) continue;
|
|
30839
30956
|
const entry = formulaEntries.get(label);
|
|
30840
30957
|
if (!entry) continue;
|
|
30841
30958
|
const result = evaluateBasicTableFormula(entry.formula, getCellValue);
|
|
@@ -30880,6 +30997,22 @@ function recalculateSelectedTable(editor) {
|
|
|
30880
30997
|
dispatchTableLayoutChange(editor);
|
|
30881
30998
|
return true;
|
|
30882
30999
|
}
|
|
31000
|
+
function recalculateActiveTableFormulas(editor) {
|
|
31001
|
+
const tableInfo = getSelectionTableInfo(editor);
|
|
31002
|
+
if (!tableInfo) {
|
|
31003
|
+
return recalculateAllTableFormulas(editor);
|
|
31004
|
+
}
|
|
31005
|
+
const activeCellLabel = getSelectionTableCellLabel(editor);
|
|
31006
|
+
const nextTable = recalculateTableNode(tableInfo.node, {
|
|
31007
|
+
changedLabels: activeCellLabel ? [activeCellLabel] : null
|
|
31008
|
+
});
|
|
31009
|
+
if (!nextTable) return false;
|
|
31010
|
+
editor.view.dispatch(
|
|
31011
|
+
editor.state.tr.replaceWith(tableInfo.pos, tableInfo.pos + tableInfo.node.nodeSize, nextTable).setMeta(UEDITOR_TABLE_FORMULA_RECALCULATE_META, true)
|
|
31012
|
+
);
|
|
31013
|
+
dispatchTableLayoutChange(editor);
|
|
31014
|
+
return true;
|
|
31015
|
+
}
|
|
30883
31016
|
function recalculateAllTableFormulas(editor) {
|
|
30884
31017
|
const replacements = [];
|
|
30885
31018
|
editor.state.doc.descendants((node, pos) => {
|
|
@@ -38876,6 +39009,146 @@ var MenuBar = ({
|
|
|
38876
39009
|
] });
|
|
38877
39010
|
};
|
|
38878
39011
|
|
|
39012
|
+
// src/components/UEditor/table-formula-range-picker.ts
|
|
39013
|
+
var import_state9 = require("@tiptap/pm/state");
|
|
39014
|
+
var import_tables4 = require("@tiptap/pm/tables");
|
|
39015
|
+
function getCellText2(cellNode) {
|
|
39016
|
+
return cellNode.textBetween(0, cellNode.content.size, "\n").trim();
|
|
39017
|
+
}
|
|
39018
|
+
function findSelectionFormulaCell(view) {
|
|
39019
|
+
const { $from } = view.state.selection;
|
|
39020
|
+
for (let depth = $from.depth; depth > 0; depth -= 1) {
|
|
39021
|
+
const node = $from.node(depth);
|
|
39022
|
+
if (node.type.name !== "tableCell" && node.type.name !== "tableHeader") continue;
|
|
39023
|
+
if (!getCellText2(node).startsWith("=")) return null;
|
|
39024
|
+
const cellPos = $from.before(depth);
|
|
39025
|
+
const cellDom = view.nodeDOM(cellPos);
|
|
39026
|
+
const tableDepth = depth - 2;
|
|
39027
|
+
const tableNode = tableDepth > 0 ? $from.node(tableDepth) : null;
|
|
39028
|
+
if (!tableNode || tableNode.type.name !== "table") return null;
|
|
39029
|
+
return {
|
|
39030
|
+
cellDom: cellDom instanceof HTMLTableCellElement ? cellDom : null,
|
|
39031
|
+
tablePos: $from.before(tableDepth)
|
|
39032
|
+
};
|
|
39033
|
+
}
|
|
39034
|
+
return null;
|
|
39035
|
+
}
|
|
39036
|
+
function findTableForPos(view, pos) {
|
|
39037
|
+
const $pos = view.state.doc.resolve(pos);
|
|
39038
|
+
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
39039
|
+
const node = $pos.node(depth);
|
|
39040
|
+
if (node.type.name === "table") {
|
|
39041
|
+
return {
|
|
39042
|
+
node,
|
|
39043
|
+
pos: $pos.before(depth),
|
|
39044
|
+
start: $pos.start(depth)
|
|
39045
|
+
};
|
|
39046
|
+
}
|
|
39047
|
+
}
|
|
39048
|
+
return null;
|
|
39049
|
+
}
|
|
39050
|
+
function getCellRelativePosFromDomPos2(map, tableStart, domPos) {
|
|
39051
|
+
const relativeDomPos = domPos - tableStart;
|
|
39052
|
+
const seen = /* @__PURE__ */ new Set();
|
|
39053
|
+
for (const relativeCellPos of map.map) {
|
|
39054
|
+
if (seen.has(relativeCellPos)) continue;
|
|
39055
|
+
seen.add(relativeCellPos);
|
|
39056
|
+
if (relativeDomPos === relativeCellPos || relativeDomPos === relativeCellPos + 1) {
|
|
39057
|
+
return relativeCellPos;
|
|
39058
|
+
}
|
|
39059
|
+
}
|
|
39060
|
+
return null;
|
|
39061
|
+
}
|
|
39062
|
+
function getPickedCellLabel(view, target, tablePos) {
|
|
39063
|
+
const element = resolveEventElement(target);
|
|
39064
|
+
const cell = element?.closest?.("th,td");
|
|
39065
|
+
if (!(cell instanceof HTMLTableCellElement)) return null;
|
|
39066
|
+
const domPos = view.posAtDOM(cell, 0);
|
|
39067
|
+
const tableInfo = findTableForPos(view, domPos);
|
|
39068
|
+
if (!tableInfo || tableInfo.pos !== tablePos) return null;
|
|
39069
|
+
const map = import_tables4.TableMap.get(tableInfo.node);
|
|
39070
|
+
const relativeCellPos = getCellRelativePosFromDomPos2(map, tableInfo.start, domPos);
|
|
39071
|
+
if (relativeCellPos == null) return null;
|
|
39072
|
+
const rect = map.findCell(relativeCellPos);
|
|
39073
|
+
return {
|
|
39074
|
+
cell,
|
|
39075
|
+
label: `${indexToColumnName(rect.left)}${rect.top + 1}`
|
|
39076
|
+
};
|
|
39077
|
+
}
|
|
39078
|
+
function normalizeFormulaRangeLabel(fromLabel, toLabel) {
|
|
39079
|
+
return fromLabel === toLabel ? fromLabel : `${fromLabel}:${toLabel}`;
|
|
39080
|
+
}
|
|
39081
|
+
function replacePickedLabel(view, pickState, nextLabel, currentCell) {
|
|
39082
|
+
if (nextLabel === pickState.currentLabel && currentCell === pickState.currentCell) return pickState;
|
|
39083
|
+
if (nextLabel === pickState.currentLabel) {
|
|
39084
|
+
return {
|
|
39085
|
+
...pickState,
|
|
39086
|
+
currentCell
|
|
39087
|
+
};
|
|
39088
|
+
}
|
|
39089
|
+
let tr = view.state.tr.insertText(nextLabel, pickState.insertedFrom, pickState.insertedTo);
|
|
39090
|
+
const nextTo = pickState.insertedFrom + nextLabel.length;
|
|
39091
|
+
tr = tr.setSelection(import_state9.TextSelection.create(tr.doc, nextTo));
|
|
39092
|
+
view.dispatch(tr);
|
|
39093
|
+
return {
|
|
39094
|
+
...pickState,
|
|
39095
|
+
insertedTo: nextTo,
|
|
39096
|
+
currentLabel: nextLabel,
|
|
39097
|
+
currentCell
|
|
39098
|
+
};
|
|
39099
|
+
}
|
|
39100
|
+
function beginFormulaRangePick(view, event) {
|
|
39101
|
+
if (event.button !== 0) return null;
|
|
39102
|
+
const formulaCell = findSelectionFormulaCell(view);
|
|
39103
|
+
if (!formulaCell) return null;
|
|
39104
|
+
const picked = getPickedCellLabel(view, event.target, formulaCell.tablePos);
|
|
39105
|
+
if (!picked || picked.cell === formulaCell.cellDom) return null;
|
|
39106
|
+
const { from, to } = view.state.selection;
|
|
39107
|
+
let tr = view.state.tr.insertText(picked.label, from, to);
|
|
39108
|
+
tr = tr.setSelection(import_state9.TextSelection.create(tr.doc, from + picked.label.length));
|
|
39109
|
+
view.dispatch(tr);
|
|
39110
|
+
view.focus();
|
|
39111
|
+
event.preventDefault();
|
|
39112
|
+
event.stopPropagation();
|
|
39113
|
+
return {
|
|
39114
|
+
anchorLabel: picked.label,
|
|
39115
|
+
anchorCell: picked.cell,
|
|
39116
|
+
tablePos: formulaCell.tablePos,
|
|
39117
|
+
insertedFrom: from,
|
|
39118
|
+
insertedTo: from + picked.label.length,
|
|
39119
|
+
currentLabel: picked.label,
|
|
39120
|
+
currentCell: picked.cell
|
|
39121
|
+
};
|
|
39122
|
+
}
|
|
39123
|
+
function updateFormulaRangePick(view, pickState, event) {
|
|
39124
|
+
const picked = getPickedCellLabel(view, event.target, pickState.tablePos);
|
|
39125
|
+
if (!picked) return pickState;
|
|
39126
|
+
event.preventDefault();
|
|
39127
|
+
event.stopPropagation();
|
|
39128
|
+
return replacePickedLabel(
|
|
39129
|
+
view,
|
|
39130
|
+
pickState,
|
|
39131
|
+
normalizeFormulaRangeLabel(pickState.anchorLabel, picked.label),
|
|
39132
|
+
picked.cell
|
|
39133
|
+
);
|
|
39134
|
+
}
|
|
39135
|
+
function getFormulaRangePickHighlight(container, pickState) {
|
|
39136
|
+
if (!container.contains(pickState.anchorCell) || !container.contains(pickState.currentCell)) return null;
|
|
39137
|
+
const containerRect = container.getBoundingClientRect();
|
|
39138
|
+
const anchorRect = pickState.anchorCell.getBoundingClientRect();
|
|
39139
|
+
const currentRect = pickState.currentCell.getBoundingClientRect();
|
|
39140
|
+
const left = Math.min(anchorRect.left, currentRect.left) - containerRect.left + container.scrollLeft;
|
|
39141
|
+
const top = Math.min(anchorRect.top, currentRect.top) - containerRect.top + container.scrollTop;
|
|
39142
|
+
const right = Math.max(anchorRect.right, currentRect.right) - containerRect.left + container.scrollLeft;
|
|
39143
|
+
const bottom = Math.max(anchorRect.bottom, currentRect.bottom) - containerRect.top + container.scrollTop;
|
|
39144
|
+
return {
|
|
39145
|
+
left,
|
|
39146
|
+
top,
|
|
39147
|
+
width: Math.max(0, right - left),
|
|
39148
|
+
height: Math.max(0, bottom - top)
|
|
39149
|
+
};
|
|
39150
|
+
}
|
|
39151
|
+
|
|
38879
39152
|
// src/components/UEditor/UEditor.tsx
|
|
38880
39153
|
var import_jsx_runtime95 = require("react/jsx-runtime");
|
|
38881
39154
|
var UEditor = import_react71.default.forwardRef(({
|
|
@@ -38908,7 +39181,6 @@ var UEditor = import_react71.default.forwardRef(({
|
|
|
38908
39181
|
fetchMetadata,
|
|
38909
39182
|
uploadFile,
|
|
38910
39183
|
uploadFileForSave,
|
|
38911
|
-
collaborationOptions,
|
|
38912
39184
|
extraExtensions,
|
|
38913
39185
|
showMenuBar = false,
|
|
38914
39186
|
onSave,
|
|
@@ -38921,6 +39193,9 @@ var UEditor = import_react71.default.forwardRef(({
|
|
|
38921
39193
|
const inFlightPrepareRef = (0, import_react71.useRef)(null);
|
|
38922
39194
|
const lastAppliedContentRef = (0, import_react71.useRef)(content ?? "");
|
|
38923
39195
|
const scheduledFormulaRecalculateRef = (0, import_react71.useRef)(false);
|
|
39196
|
+
const formulaRangePickRef = (0, import_react71.useRef)(null);
|
|
39197
|
+
const formulaRangeSurfaceRef = (0, import_react71.useRef)(null);
|
|
39198
|
+
const [formulaRangeHighlight, setFormulaRangeHighlight] = import_react71.default.useState(null);
|
|
38924
39199
|
const scheduleFormulaRecalculate = import_react71.default.useCallback((editor2, options) => {
|
|
38925
39200
|
if (editor2.isDestroyed || scheduledFormulaRecalculateRef.current) return;
|
|
38926
39201
|
if (!options?.force && isEditingTableFormulaText(editor2)) return;
|
|
@@ -38928,7 +39203,7 @@ var UEditor = import_react71.default.forwardRef(({
|
|
|
38928
39203
|
queueMicrotask(() => {
|
|
38929
39204
|
scheduledFormulaRecalculateRef.current = false;
|
|
38930
39205
|
if (!editor2.isDestroyed && (options?.force || !isEditingTableFormulaText(editor2))) {
|
|
38931
|
-
|
|
39206
|
+
recalculateActiveTableFormulas(editor2);
|
|
38932
39207
|
}
|
|
38933
39208
|
});
|
|
38934
39209
|
}, []);
|
|
@@ -38961,6 +39236,10 @@ var UEditor = import_react71.default.forwardRef(({
|
|
|
38961
39236
|
],
|
|
38962
39237
|
[effectivePlaceholder, t, maxCharacters, uploadImage, resolvedUploadFile, imageInsertMode, maxImageFileSize, allowedImageMimeTypes, fallbackToDataUrl, editable, fetchMetadata, extraExtensions]
|
|
38963
39238
|
);
|
|
39239
|
+
const syncFormulaRangeHighlight = import_react71.default.useCallback((pickState) => {
|
|
39240
|
+
const container = formulaRangeSurfaceRef.current;
|
|
39241
|
+
setFormulaRangeHighlight(container && pickState ? getFormulaRangePickHighlight(container, pickState) : null);
|
|
39242
|
+
}, []);
|
|
38964
39243
|
const editor = (0, import_react72.useEditor)({
|
|
38965
39244
|
immediatelyRender: false,
|
|
38966
39245
|
extensions,
|
|
@@ -38969,6 +39248,37 @@ var UEditor = import_react71.default.forwardRef(({
|
|
|
38969
39248
|
autofocus,
|
|
38970
39249
|
editorProps: {
|
|
38971
39250
|
handleDOMEvents: {
|
|
39251
|
+
mousedown: (view, event) => {
|
|
39252
|
+
if (!(event instanceof MouseEvent)) return false;
|
|
39253
|
+
const pickState = beginFormulaRangePick(view, event);
|
|
39254
|
+
if (!pickState) return false;
|
|
39255
|
+
formulaRangePickRef.current = pickState;
|
|
39256
|
+
syncFormulaRangeHighlight(pickState);
|
|
39257
|
+
return true;
|
|
39258
|
+
},
|
|
39259
|
+
mousemove: (view, event) => {
|
|
39260
|
+
if (!(event instanceof MouseEvent)) return false;
|
|
39261
|
+
const pickState = formulaRangePickRef.current;
|
|
39262
|
+
if (!pickState) return false;
|
|
39263
|
+
if (event.buttons === 0) {
|
|
39264
|
+
formulaRangePickRef.current = null;
|
|
39265
|
+
syncFormulaRangeHighlight(null);
|
|
39266
|
+
return false;
|
|
39267
|
+
}
|
|
39268
|
+
const nextPickState = updateFormulaRangePick(view, pickState, event);
|
|
39269
|
+
formulaRangePickRef.current = nextPickState;
|
|
39270
|
+
syncFormulaRangeHighlight(nextPickState);
|
|
39271
|
+
return true;
|
|
39272
|
+
},
|
|
39273
|
+
mouseup: (_view, event) => {
|
|
39274
|
+
if (!(event instanceof MouseEvent)) return false;
|
|
39275
|
+
if (!formulaRangePickRef.current) return false;
|
|
39276
|
+
formulaRangePickRef.current = null;
|
|
39277
|
+
syncFormulaRangeHighlight(null);
|
|
39278
|
+
event.preventDefault();
|
|
39279
|
+
event.stopPropagation();
|
|
39280
|
+
return true;
|
|
39281
|
+
},
|
|
38972
39282
|
keydown: (_view, event) => {
|
|
38973
39283
|
if (!(event instanceof KeyboardEvent)) return false;
|
|
38974
39284
|
if (event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "ArrowUp" || event.key === "ArrowDown") {
|
|
@@ -39134,7 +39444,10 @@ var UEditor = import_react71.default.forwardRef(({
|
|
|
39134
39444
|
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)(
|
|
39135
39445
|
"div",
|
|
39136
39446
|
{
|
|
39137
|
-
ref:
|
|
39447
|
+
ref: (node) => {
|
|
39448
|
+
editorContentRef.current = node;
|
|
39449
|
+
formulaRangeSurfaceRef.current = node;
|
|
39450
|
+
},
|
|
39138
39451
|
className: "relative flex-1 overflow-y-auto",
|
|
39139
39452
|
style: {
|
|
39140
39453
|
minHeight: editable ? minHeight : void 0,
|
|
@@ -39166,6 +39479,20 @@ var UEditor = import_react71.default.forwardRef(({
|
|
|
39166
39479
|
className: "pointer-events-none hidden absolute z-20 rounded-[2px] border-2 border-primary bg-primary/10"
|
|
39167
39480
|
}
|
|
39168
39481
|
),
|
|
39482
|
+
formulaRangeHighlight && /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
39483
|
+
"span",
|
|
39484
|
+
{
|
|
39485
|
+
"aria-hidden": "true",
|
|
39486
|
+
"data-ueditor-formula-range-highlight": "",
|
|
39487
|
+
className: "pointer-events-none absolute z-20 rounded-[2px] border-2 border-primary bg-primary/10",
|
|
39488
|
+
style: {
|
|
39489
|
+
left: formulaRangeHighlight.left,
|
|
39490
|
+
top: formulaRangeHighlight.top,
|
|
39491
|
+
width: formulaRangeHighlight.width,
|
|
39492
|
+
height: formulaRangeHighlight.height
|
|
39493
|
+
}
|
|
39494
|
+
}
|
|
39495
|
+
),
|
|
39169
39496
|
editable && /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(TableControls, { editor, containerRef: editorContentRef }),
|
|
39170
39497
|
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
39171
39498
|
import_react72.EditorContent,
|