@underverse-ui/underverse 1.0.156 → 1.0.158
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 +861 -238
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +865 -242
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -6042,7 +6042,7 @@ var Modal = ({
|
|
|
6042
6042
|
const modalContent = /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
6043
6043
|
"div",
|
|
6044
6044
|
{
|
|
6045
|
-
className: cn("fixed inset-0 z-9999 flex items-center justify-center p-4 md:p-6", overlayClassName),
|
|
6045
|
+
className: cn("fixed inset-0 z-[9999] flex items-center justify-center p-4 md:p-6", overlayClassName),
|
|
6046
6046
|
style: { overscrollBehavior: "contain" },
|
|
6047
6047
|
onMouseDown: handleOverlayMouseDown,
|
|
6048
6048
|
onMouseUp: handleOverlayMouseUp,
|
|
@@ -27217,6 +27217,111 @@ var import_react55 = require("react");
|
|
|
27217
27217
|
var import_extension_image = __toESM(require("@tiptap/extension-image"), 1);
|
|
27218
27218
|
var import_core9 = require("@tiptap/core");
|
|
27219
27219
|
var import_react56 = require("@tiptap/react");
|
|
27220
|
+
|
|
27221
|
+
// src/components/UEditor/table-dom-utils.ts
|
|
27222
|
+
var MIN_TABLE_ROW_HEIGHT = 36;
|
|
27223
|
+
var COLUMN_RESIZE_LINE_THICKNESS = 2;
|
|
27224
|
+
var ROW_RESIZE_LINE_THICKNESS = 2;
|
|
27225
|
+
var UEDITOR_TABLE_LAYOUT_CHANGE_EVENT = "ueditor-table-layout-change";
|
|
27226
|
+
var TABLE_RESIZE_HIT_ZONE = 10;
|
|
27227
|
+
function findTableRowNodeInfo(view, rowElement) {
|
|
27228
|
+
const firstCell = rowElement.querySelector("th,td");
|
|
27229
|
+
if (!firstCell) return null;
|
|
27230
|
+
const cellPos = view.posAtDOM(firstCell, 0);
|
|
27231
|
+
const $pos = view.state.doc.resolve(cellPos);
|
|
27232
|
+
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
27233
|
+
const node = $pos.node(depth);
|
|
27234
|
+
if (node.type.name === "tableRow") {
|
|
27235
|
+
return {
|
|
27236
|
+
pos: $pos.before(depth),
|
|
27237
|
+
node
|
|
27238
|
+
};
|
|
27239
|
+
}
|
|
27240
|
+
}
|
|
27241
|
+
return null;
|
|
27242
|
+
}
|
|
27243
|
+
function resolveEventElement(target) {
|
|
27244
|
+
if (target instanceof Element) return target;
|
|
27245
|
+
if (target instanceof Node) return target.parentElement;
|
|
27246
|
+
return null;
|
|
27247
|
+
}
|
|
27248
|
+
function getSelectionTableCell(view) {
|
|
27249
|
+
const browserSelection = window.getSelection();
|
|
27250
|
+
const anchorElement = resolveEventElement(browserSelection?.anchorNode ?? null);
|
|
27251
|
+
const anchorCell = anchorElement?.closest?.("th,td");
|
|
27252
|
+
if (anchorCell instanceof HTMLElement) {
|
|
27253
|
+
return anchorCell;
|
|
27254
|
+
}
|
|
27255
|
+
const { from } = view.state.selection;
|
|
27256
|
+
const domAtPos = view.domAtPos(from);
|
|
27257
|
+
const element = resolveEventElement(domAtPos.node);
|
|
27258
|
+
const cell = element?.closest?.("th,td");
|
|
27259
|
+
return cell instanceof HTMLElement ? cell : null;
|
|
27260
|
+
}
|
|
27261
|
+
function isRowResizeHotspot(cell, clientX, clientY) {
|
|
27262
|
+
const rect = cell.getBoundingClientRect();
|
|
27263
|
+
const nearBottom = rect.bottom - clientY <= TABLE_RESIZE_HIT_ZONE;
|
|
27264
|
+
const nearRight = rect.right - clientX <= TABLE_RESIZE_HIT_ZONE;
|
|
27265
|
+
return nearBottom && !nearRight;
|
|
27266
|
+
}
|
|
27267
|
+
function isColumnResizeHotspot(cell, clientX, clientY) {
|
|
27268
|
+
const rect = cell.getBoundingClientRect();
|
|
27269
|
+
const nearRight = rect.right - clientX <= TABLE_RESIZE_HIT_ZONE;
|
|
27270
|
+
const nearBottom = rect.bottom - clientY <= TABLE_RESIZE_HIT_ZONE;
|
|
27271
|
+
return nearRight && !nearBottom;
|
|
27272
|
+
}
|
|
27273
|
+
function getRelativeBoundaryMetrics(surface, table, row, cell) {
|
|
27274
|
+
const surfaceRect = surface.getBoundingClientRect();
|
|
27275
|
+
const tableRect = table.getBoundingClientRect();
|
|
27276
|
+
const rowRect = row.getBoundingClientRect();
|
|
27277
|
+
const cellRect = cell.getBoundingClientRect();
|
|
27278
|
+
return {
|
|
27279
|
+
left: tableRect.left - surfaceRect.left + surface.scrollLeft,
|
|
27280
|
+
top: tableRect.top - surfaceRect.top + surface.scrollTop,
|
|
27281
|
+
width: tableRect.width,
|
|
27282
|
+
height: tableRect.height,
|
|
27283
|
+
rowBottom: rowRect.bottom - surfaceRect.top + surface.scrollTop,
|
|
27284
|
+
columnRight: cellRect.right - surfaceRect.left + surface.scrollLeft
|
|
27285
|
+
};
|
|
27286
|
+
}
|
|
27287
|
+
function getRelativeCellMetrics(surface, cell) {
|
|
27288
|
+
const surfaceRect = surface.getBoundingClientRect();
|
|
27289
|
+
const cellRect = cell.getBoundingClientRect();
|
|
27290
|
+
return {
|
|
27291
|
+
left: cellRect.left - surfaceRect.left + surface.scrollLeft,
|
|
27292
|
+
top: cellRect.top - surfaceRect.top + surface.scrollTop,
|
|
27293
|
+
width: cellRect.width,
|
|
27294
|
+
height: cellRect.height
|
|
27295
|
+
};
|
|
27296
|
+
}
|
|
27297
|
+
function getRelativeSelectedCellsMetrics(surface) {
|
|
27298
|
+
const selectedCells = Array.from(
|
|
27299
|
+
surface.querySelectorAll("td.selectedCell, th.selectedCell")
|
|
27300
|
+
);
|
|
27301
|
+
if (selectedCells.length === 0) {
|
|
27302
|
+
return null;
|
|
27303
|
+
}
|
|
27304
|
+
const surfaceRect = surface.getBoundingClientRect();
|
|
27305
|
+
let left = Number.POSITIVE_INFINITY;
|
|
27306
|
+
let top = Number.POSITIVE_INFINITY;
|
|
27307
|
+
let right = Number.NEGATIVE_INFINITY;
|
|
27308
|
+
let bottom = Number.NEGATIVE_INFINITY;
|
|
27309
|
+
selectedCells.forEach((cell) => {
|
|
27310
|
+
const rect = cell.getBoundingClientRect();
|
|
27311
|
+
left = Math.min(left, rect.left);
|
|
27312
|
+
top = Math.min(top, rect.top);
|
|
27313
|
+
right = Math.max(right, rect.right);
|
|
27314
|
+
bottom = Math.max(bottom, rect.bottom);
|
|
27315
|
+
});
|
|
27316
|
+
return {
|
|
27317
|
+
left: left - surfaceRect.left + surface.scrollLeft,
|
|
27318
|
+
top: top - surfaceRect.top + surface.scrollTop,
|
|
27319
|
+
width: right - left,
|
|
27320
|
+
height: bottom - top
|
|
27321
|
+
};
|
|
27322
|
+
}
|
|
27323
|
+
|
|
27324
|
+
// src/components/UEditor/resizable-image.tsx
|
|
27220
27325
|
var import_jsx_runtime82 = require("react/jsx-runtime");
|
|
27221
27326
|
var MIN_IMAGE_SIZE_PX = 40;
|
|
27222
27327
|
var IMAGE_LAYOUTS = /* @__PURE__ */ new Set(["block", "left", "right"]);
|
|
@@ -27298,6 +27403,7 @@ function ResizableImageNodeView(props) {
|
|
|
27298
27403
|
const { node, selected, updateAttributes, editor, getPos } = props;
|
|
27299
27404
|
const wrapperRef = (0, import_react55.useRef)(null);
|
|
27300
27405
|
const imgRef = (0, import_react55.useRef)(null);
|
|
27406
|
+
const resizePreviewRef = (0, import_react55.useRef)(null);
|
|
27301
27407
|
const [isHovered, setIsHovered] = (0, import_react55.useState)(false);
|
|
27302
27408
|
const [isResizing, setIsResizing] = (0, import_react55.useState)(false);
|
|
27303
27409
|
const widthAttr = toNullableNumber(node.attrs["width"]);
|
|
@@ -27305,11 +27411,59 @@ function ResizableImageNodeView(props) {
|
|
|
27305
27411
|
const textAlign = String(node.attrs["textAlign"] ?? "");
|
|
27306
27412
|
const imageLayout = parseImageLayout(node.attrs["imageLayout"]);
|
|
27307
27413
|
const dragStateRef = (0, import_react55.useRef)(null);
|
|
27414
|
+
const dispatchTableLayoutChange2 = () => {
|
|
27415
|
+
editor.view.dom.dispatchEvent(new CustomEvent(UEDITOR_TABLE_LAYOUT_CHANGE_EVENT, { bubbles: true }));
|
|
27416
|
+
};
|
|
27417
|
+
const getImageDisplayStyle = (width, height) => ({
|
|
27418
|
+
width: width ? `${width}px` : void 0,
|
|
27419
|
+
height: width && height ? "auto" : height ? `${height}px` : void 0,
|
|
27420
|
+
aspectRatio: width && height ? `${width} / ${height}` : void 0
|
|
27421
|
+
});
|
|
27422
|
+
const setResizePreviewStyle = (width, height, visible, resetBase = false) => {
|
|
27423
|
+
const preview = resizePreviewRef.current;
|
|
27424
|
+
if (!preview) return;
|
|
27425
|
+
const drag = dragStateRef.current;
|
|
27426
|
+
const baseW = resetBase || !drag ? Math.max(MIN_IMAGE_SIZE_PX, Math.round(width)) : drag.previewBaseW;
|
|
27427
|
+
const baseH = resetBase || !drag ? Math.max(MIN_IMAGE_SIZE_PX, Math.round(height)) : drag.previewBaseH;
|
|
27428
|
+
const scaleX = width / baseW;
|
|
27429
|
+
const scaleY = height / baseH;
|
|
27430
|
+
if (resetBase) {
|
|
27431
|
+
preview.style.width = `${baseW}px`;
|
|
27432
|
+
preview.style.height = `${baseH}px`;
|
|
27433
|
+
}
|
|
27434
|
+
preview.style.maxWidth = "none";
|
|
27435
|
+
preview.style.maxHeight = "none";
|
|
27436
|
+
preview.style.transform = visible ? `translateZ(0) scale(${scaleX}, ${scaleY})` : "translateZ(0) scale(1)";
|
|
27437
|
+
preview.style.display = visible ? "block" : "none";
|
|
27438
|
+
};
|
|
27439
|
+
const applyPendingResizeFrame = () => {
|
|
27440
|
+
const drag = dragStateRef.current;
|
|
27441
|
+
if (!drag) return;
|
|
27442
|
+
drag.frameId = null;
|
|
27443
|
+
setResizePreviewStyle(drag.pendingW, drag.pendingH, true);
|
|
27444
|
+
};
|
|
27445
|
+
const scheduleResizeFrame = () => {
|
|
27446
|
+
const drag = dragStateRef.current;
|
|
27447
|
+
if (!drag || drag.frameId !== null) return;
|
|
27448
|
+
drag.frameId = window.requestAnimationFrame(applyPendingResizeFrame);
|
|
27449
|
+
};
|
|
27450
|
+
(0, import_react55.useEffect)(() => {
|
|
27451
|
+
return () => {
|
|
27452
|
+
const drag = dragStateRef.current;
|
|
27453
|
+
if (drag && drag.frameId !== null) {
|
|
27454
|
+
window.cancelAnimationFrame(drag.frameId);
|
|
27455
|
+
}
|
|
27456
|
+
dragStateRef.current = null;
|
|
27457
|
+
document.body.style.cursor = "";
|
|
27458
|
+
};
|
|
27459
|
+
}, []);
|
|
27308
27460
|
(0, import_react55.useEffect)(() => {
|
|
27309
27461
|
const img = imgRef.current;
|
|
27310
27462
|
if (!img) return;
|
|
27311
|
-
|
|
27312
|
-
img.style.
|
|
27463
|
+
const displayStyle = getImageDisplayStyle(widthAttr, heightAttr);
|
|
27464
|
+
img.style.width = typeof displayStyle.width === "string" ? displayStyle.width : "";
|
|
27465
|
+
img.style.height = typeof displayStyle.height === "string" ? displayStyle.height : "";
|
|
27466
|
+
img.style.aspectRatio = typeof displayStyle.aspectRatio === "string" ? displayStyle.aspectRatio : "";
|
|
27313
27467
|
}, [widthAttr, heightAttr]);
|
|
27314
27468
|
const selectNode = () => {
|
|
27315
27469
|
const pos = typeof getPos === "function" ? getPos() : null;
|
|
@@ -27340,12 +27494,17 @@ function ResizableImageNodeView(props) {
|
|
|
27340
27494
|
startY: event.clientY,
|
|
27341
27495
|
startW,
|
|
27342
27496
|
startH,
|
|
27343
|
-
lastW: startW,
|
|
27344
|
-
lastH: startH,
|
|
27345
27497
|
aspect,
|
|
27346
|
-
maxW: Math.max(MIN_IMAGE_SIZE_PX, maxW)
|
|
27498
|
+
maxW: Math.max(MIN_IMAGE_SIZE_PX, maxW),
|
|
27499
|
+
previewBaseW: Math.max(MIN_IMAGE_SIZE_PX, Math.round(startW)),
|
|
27500
|
+
previewBaseH: Math.max(MIN_IMAGE_SIZE_PX, Math.round(startH)),
|
|
27501
|
+
pendingW: startW,
|
|
27502
|
+
pendingH: startH,
|
|
27503
|
+
frameId: null
|
|
27347
27504
|
};
|
|
27348
27505
|
setIsResizing(true);
|
|
27506
|
+
setResizePreviewStyle(startW, startH, true, true);
|
|
27507
|
+
document.body.style.cursor = "nwse-resize";
|
|
27349
27508
|
event.currentTarget.setPointerCapture(event.pointerId);
|
|
27350
27509
|
};
|
|
27351
27510
|
const onResizePointerMove = (event) => {
|
|
@@ -27358,19 +27517,33 @@ function ResizableImageNodeView(props) {
|
|
|
27358
27517
|
const nextSize = Math.abs(dx) >= Math.abs(dy) ? sizeFromWidth(drag.startW + dx, drag.aspect, drag.maxW) : sizeFromHeight(drag.startH + dy, drag.aspect, drag.maxW);
|
|
27359
27518
|
const nextW = nextSize.width;
|
|
27360
27519
|
const nextH = nextSize.height;
|
|
27361
|
-
drag.
|
|
27362
|
-
drag.
|
|
27363
|
-
|
|
27364
|
-
img.style.height = `${Math.round(nextH)}px`;
|
|
27520
|
+
drag.pendingW = nextW;
|
|
27521
|
+
drag.pendingH = nextH;
|
|
27522
|
+
scheduleResizeFrame();
|
|
27365
27523
|
};
|
|
27366
27524
|
const finishResize = () => {
|
|
27367
27525
|
const drag = dragStateRef.current;
|
|
27368
27526
|
dragStateRef.current = null;
|
|
27369
27527
|
setIsResizing(false);
|
|
27528
|
+
document.body.style.cursor = "";
|
|
27370
27529
|
if (!drag) return;
|
|
27530
|
+
if (drag.frameId !== null) {
|
|
27531
|
+
window.cancelAnimationFrame(drag.frameId);
|
|
27532
|
+
drag.frameId = null;
|
|
27533
|
+
}
|
|
27534
|
+
const img = imgRef.current;
|
|
27535
|
+
const nextW = Math.round(drag.pendingW);
|
|
27536
|
+
const nextH = Math.round(drag.pendingH);
|
|
27537
|
+
setResizePreviewStyle(nextW, nextH, false);
|
|
27538
|
+
if (img) {
|
|
27539
|
+
img.style.width = `${nextW}px`;
|
|
27540
|
+
img.style.height = "auto";
|
|
27541
|
+
img.style.aspectRatio = `${nextW} / ${nextH}`;
|
|
27542
|
+
}
|
|
27543
|
+
dispatchTableLayoutChange2();
|
|
27371
27544
|
updateAttributes({
|
|
27372
|
-
width:
|
|
27373
|
-
height:
|
|
27545
|
+
width: nextW,
|
|
27546
|
+
height: nextH,
|
|
27374
27547
|
imageWidthPreset: null
|
|
27375
27548
|
});
|
|
27376
27549
|
};
|
|
@@ -27419,9 +27592,30 @@ function ResizableImageNodeView(props) {
|
|
|
27419
27592
|
selected ? "ring-2 ring-primary/60 ring-offset-2 ring-offset-background" : "",
|
|
27420
27593
|
isResizing ? "select-none" : ""
|
|
27421
27594
|
].join(" "),
|
|
27595
|
+
style: getImageDisplayStyle(widthAttr, heightAttr)
|
|
27596
|
+
}
|
|
27597
|
+
),
|
|
27598
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
27599
|
+
"div",
|
|
27600
|
+
{
|
|
27601
|
+
ref: resizePreviewRef,
|
|
27602
|
+
"aria-hidden": "true",
|
|
27603
|
+
"data-ueditor-image-resize-preview": "",
|
|
27604
|
+
className: [
|
|
27605
|
+
"pointer-events-none absolute left-0 top-0 z-20 hidden rounded-lg",
|
|
27606
|
+
"border border-primary/70 bg-background/30 bg-center bg-no-repeat bg-[length:100%_100%]",
|
|
27607
|
+
"opacity-45 shadow-md ring-2 ring-primary/25 will-change-transform",
|
|
27608
|
+
"select-none"
|
|
27609
|
+
].join(" "),
|
|
27422
27610
|
style: {
|
|
27423
27611
|
width: widthAttr ? `${widthAttr}px` : void 0,
|
|
27424
|
-
height: heightAttr ? `${heightAttr}px` : void 0
|
|
27612
|
+
height: heightAttr ? `${heightAttr}px` : void 0,
|
|
27613
|
+
maxWidth: "none",
|
|
27614
|
+
maxHeight: "none",
|
|
27615
|
+
backgroundImage: `url("${String(node.attrs["src"] ?? "").replace(/"/g, "%22")}")`,
|
|
27616
|
+
transform: "translateZ(0) scale(1)",
|
|
27617
|
+
transformOrigin: "top left",
|
|
27618
|
+
display: isResizing ? "block" : "none"
|
|
27425
27619
|
}
|
|
27426
27620
|
}
|
|
27427
27621
|
),
|
|
@@ -27429,6 +27623,7 @@ function ResizableImageNodeView(props) {
|
|
|
27429
27623
|
"div",
|
|
27430
27624
|
{
|
|
27431
27625
|
"aria-hidden": "true",
|
|
27626
|
+
"data-ueditor-image-resize-handle": "",
|
|
27432
27627
|
onPointerDown: onResizePointerDown,
|
|
27433
27628
|
onPointerMove: onResizePointerMove,
|
|
27434
27629
|
onPointerUp: onResizePointerUp,
|
|
@@ -27685,109 +27880,6 @@ var letter_spacing_default = LetterSpacing;
|
|
|
27685
27880
|
var import_extension_table = require("@tiptap/extension-table");
|
|
27686
27881
|
var import_state6 = require("@tiptap/pm/state");
|
|
27687
27882
|
|
|
27688
|
-
// src/components/UEditor/table-dom-utils.ts
|
|
27689
|
-
var MIN_TABLE_ROW_HEIGHT = 36;
|
|
27690
|
-
var COLUMN_RESIZE_LINE_THICKNESS = 2;
|
|
27691
|
-
var ROW_RESIZE_LINE_THICKNESS = 2;
|
|
27692
|
-
var UEDITOR_TABLE_LAYOUT_CHANGE_EVENT = "ueditor-table-layout-change";
|
|
27693
|
-
var TABLE_RESIZE_HIT_ZONE = 10;
|
|
27694
|
-
function findTableRowNodeInfo(view, rowElement) {
|
|
27695
|
-
const firstCell = rowElement.querySelector("th,td");
|
|
27696
|
-
if (!firstCell) return null;
|
|
27697
|
-
const cellPos = view.posAtDOM(firstCell, 0);
|
|
27698
|
-
const $pos = view.state.doc.resolve(cellPos);
|
|
27699
|
-
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
27700
|
-
const node = $pos.node(depth);
|
|
27701
|
-
if (node.type.name === "tableRow") {
|
|
27702
|
-
return {
|
|
27703
|
-
pos: $pos.before(depth),
|
|
27704
|
-
node
|
|
27705
|
-
};
|
|
27706
|
-
}
|
|
27707
|
-
}
|
|
27708
|
-
return null;
|
|
27709
|
-
}
|
|
27710
|
-
function resolveEventElement(target) {
|
|
27711
|
-
if (target instanceof Element) return target;
|
|
27712
|
-
if (target instanceof Node) return target.parentElement;
|
|
27713
|
-
return null;
|
|
27714
|
-
}
|
|
27715
|
-
function getSelectionTableCell(view) {
|
|
27716
|
-
const browserSelection = window.getSelection();
|
|
27717
|
-
const anchorElement = resolveEventElement(browserSelection?.anchorNode ?? null);
|
|
27718
|
-
const anchorCell = anchorElement?.closest?.("th,td");
|
|
27719
|
-
if (anchorCell instanceof HTMLElement) {
|
|
27720
|
-
return anchorCell;
|
|
27721
|
-
}
|
|
27722
|
-
const { from } = view.state.selection;
|
|
27723
|
-
const domAtPos = view.domAtPos(from);
|
|
27724
|
-
const element = resolveEventElement(domAtPos.node);
|
|
27725
|
-
const cell = element?.closest?.("th,td");
|
|
27726
|
-
return cell instanceof HTMLElement ? cell : null;
|
|
27727
|
-
}
|
|
27728
|
-
function isRowResizeHotspot(cell, clientX, clientY) {
|
|
27729
|
-
const rect = cell.getBoundingClientRect();
|
|
27730
|
-
const nearBottom = rect.bottom - clientY <= TABLE_RESIZE_HIT_ZONE;
|
|
27731
|
-
const nearRight = rect.right - clientX <= TABLE_RESIZE_HIT_ZONE;
|
|
27732
|
-
return nearBottom && !nearRight;
|
|
27733
|
-
}
|
|
27734
|
-
function isColumnResizeHotspot(cell, clientX, clientY) {
|
|
27735
|
-
const rect = cell.getBoundingClientRect();
|
|
27736
|
-
const nearRight = rect.right - clientX <= TABLE_RESIZE_HIT_ZONE;
|
|
27737
|
-
const nearBottom = rect.bottom - clientY <= TABLE_RESIZE_HIT_ZONE;
|
|
27738
|
-
return nearRight && !nearBottom;
|
|
27739
|
-
}
|
|
27740
|
-
function getRelativeBoundaryMetrics(surface, table, row, cell) {
|
|
27741
|
-
const surfaceRect = surface.getBoundingClientRect();
|
|
27742
|
-
const tableRect = table.getBoundingClientRect();
|
|
27743
|
-
const rowRect = row.getBoundingClientRect();
|
|
27744
|
-
const cellRect = cell.getBoundingClientRect();
|
|
27745
|
-
return {
|
|
27746
|
-
left: tableRect.left - surfaceRect.left + surface.scrollLeft,
|
|
27747
|
-
top: tableRect.top - surfaceRect.top + surface.scrollTop,
|
|
27748
|
-
width: tableRect.width,
|
|
27749
|
-
height: tableRect.height,
|
|
27750
|
-
rowBottom: rowRect.bottom - surfaceRect.top + surface.scrollTop,
|
|
27751
|
-
columnRight: cellRect.right - surfaceRect.left + surface.scrollLeft
|
|
27752
|
-
};
|
|
27753
|
-
}
|
|
27754
|
-
function getRelativeCellMetrics(surface, cell) {
|
|
27755
|
-
const surfaceRect = surface.getBoundingClientRect();
|
|
27756
|
-
const cellRect = cell.getBoundingClientRect();
|
|
27757
|
-
return {
|
|
27758
|
-
left: cellRect.left - surfaceRect.left + surface.scrollLeft,
|
|
27759
|
-
top: cellRect.top - surfaceRect.top + surface.scrollTop,
|
|
27760
|
-
width: cellRect.width,
|
|
27761
|
-
height: cellRect.height
|
|
27762
|
-
};
|
|
27763
|
-
}
|
|
27764
|
-
function getRelativeSelectedCellsMetrics(surface) {
|
|
27765
|
-
const selectedCells = Array.from(
|
|
27766
|
-
surface.querySelectorAll("td.selectedCell, th.selectedCell")
|
|
27767
|
-
);
|
|
27768
|
-
if (selectedCells.length === 0) {
|
|
27769
|
-
return null;
|
|
27770
|
-
}
|
|
27771
|
-
const surfaceRect = surface.getBoundingClientRect();
|
|
27772
|
-
let left = Number.POSITIVE_INFINITY;
|
|
27773
|
-
let top = Number.POSITIVE_INFINITY;
|
|
27774
|
-
let right = Number.NEGATIVE_INFINITY;
|
|
27775
|
-
let bottom = Number.NEGATIVE_INFINITY;
|
|
27776
|
-
selectedCells.forEach((cell) => {
|
|
27777
|
-
const rect = cell.getBoundingClientRect();
|
|
27778
|
-
left = Math.min(left, rect.left);
|
|
27779
|
-
top = Math.min(top, rect.top);
|
|
27780
|
-
right = Math.max(right, rect.right);
|
|
27781
|
-
bottom = Math.max(bottom, rect.bottom);
|
|
27782
|
-
});
|
|
27783
|
-
return {
|
|
27784
|
-
left: left - surfaceRect.left + surface.scrollLeft,
|
|
27785
|
-
top: top - surfaceRect.top + surface.scrollTop,
|
|
27786
|
-
width: right - left,
|
|
27787
|
-
height: bottom - top
|
|
27788
|
-
};
|
|
27789
|
-
}
|
|
27790
|
-
|
|
27791
27883
|
// src/components/UEditor/table-align-utils.ts
|
|
27792
27884
|
function findTableNodeInfoAtResolvedPos($pos) {
|
|
27793
27885
|
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
@@ -28589,6 +28681,9 @@ var HIGHLIGHT_COLOR_SWATCHES = [
|
|
|
28589
28681
|
function buildColorOptions(colors, prefix) {
|
|
28590
28682
|
return colors.map((color, index) => ({ name: `${prefix} ${index + 1}`, color }));
|
|
28591
28683
|
}
|
|
28684
|
+
function getSwatchCheckClass(color) {
|
|
28685
|
+
return /^#(?:fff|ffffff)$/i.test(color) ? "text-foreground" : "text-white drop-shadow-[0_1px_1px_rgba(0,0,0,0.8)]";
|
|
28686
|
+
}
|
|
28592
28687
|
var useEditorColors = () => {
|
|
28593
28688
|
const t = useSmartTranslations("UEditor");
|
|
28594
28689
|
const textColors = (0, import_react60.useMemo)(
|
|
@@ -28663,7 +28758,7 @@ var EditorColorPalette = ({
|
|
|
28663
28758
|
currentColor === c.color ? "border-primary ring-2 ring-primary/25" : "border-border/70"
|
|
28664
28759
|
),
|
|
28665
28760
|
style: { backgroundColor: c.color || "transparent" },
|
|
28666
|
-
children: currentColor === c.color && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_lucide_react47.Check, { className: "h-3.5 w-3.5
|
|
28761
|
+
children: currentColor === c.color && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_lucide_react47.Check, { className: cn("h-3.5 w-3.5", getSwatchCheckClass(c.color)) }) })
|
|
28667
28762
|
}
|
|
28668
28763
|
) }, `${c.name}-${c.color}`)) }),
|
|
28669
28764
|
/* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(
|
|
@@ -28978,6 +29073,20 @@ function createEmptyCellNode(cellNode) {
|
|
|
28978
29073
|
function createCellCopyForColumnDuplicate(cellNode) {
|
|
28979
29074
|
return cellNode.type.create(cellNode.attrs, cellNode.content);
|
|
28980
29075
|
}
|
|
29076
|
+
function createCellWithDuplicatedLogicalColumn(cellNode, widthIndex) {
|
|
29077
|
+
const colspan = Math.max(1, Number(cellNode.attrs.colspan) || 1);
|
|
29078
|
+
let nextColwidth = null;
|
|
29079
|
+
if (Array.isArray(cellNode.attrs.colwidth)) {
|
|
29080
|
+
nextColwidth = [...cellNode.attrs.colwidth];
|
|
29081
|
+
const duplicateWidth = nextColwidth[widthIndex];
|
|
29082
|
+
nextColwidth.splice(widthIndex + 1, 0, typeof duplicateWidth === "number" ? duplicateWidth : 0);
|
|
29083
|
+
}
|
|
29084
|
+
return cellNode.type.create({
|
|
29085
|
+
...cellNode.attrs,
|
|
29086
|
+
colspan: colspan + 1,
|
|
29087
|
+
...nextColwidth ? { colwidth: nextColwidth } : null
|
|
29088
|
+
}, cellNode.content);
|
|
29089
|
+
}
|
|
28981
29090
|
function getTableRows(tableNode) {
|
|
28982
29091
|
const rows = [];
|
|
28983
29092
|
tableNode.forEach((rowNode, rowOffset) => {
|
|
@@ -29153,6 +29262,11 @@ function duplicateTableColumnAt(editor, columnIndex, cellPos) {
|
|
|
29153
29262
|
return rect && rect.top === rowIndex && rect.left <= columnIndex && columnIndex < rect.right;
|
|
29154
29263
|
});
|
|
29155
29264
|
if (!sourceCell) return rowInfo.node;
|
|
29265
|
+
const sourceRect = safeFindCell(map, sourceCell.relativePos);
|
|
29266
|
+
if (sourceRect && (sourceRect.left < columnIndex || sourceRect.right > columnIndex + 1)) {
|
|
29267
|
+
cells[sourceCell.index] = createCellWithDuplicatedLogicalColumn(sourceCell.node, columnIndex - sourceRect.left);
|
|
29268
|
+
return rowInfo.node.type.create(rowInfo.node.attrs, cells);
|
|
29269
|
+
}
|
|
29156
29270
|
cells.splice(sourceCell.index + 1, 0, createCellCopyForColumnDuplicate(sourceCell.node));
|
|
29157
29271
|
return rowInfo.node.type.create(rowInfo.node.attrs, cells);
|
|
29158
29272
|
});
|
|
@@ -30452,6 +30566,25 @@ function getTableFormulaRecalculationOrder(graph) {
|
|
|
30452
30566
|
}
|
|
30453
30567
|
return { order, circular };
|
|
30454
30568
|
}
|
|
30569
|
+
function getAffectedTableFormulaLabels(graph, changedLabels) {
|
|
30570
|
+
const affected = /* @__PURE__ */ new Set();
|
|
30571
|
+
const queue = Array.from(changedLabels, (label) => label.toUpperCase());
|
|
30572
|
+
for (const label of queue) {
|
|
30573
|
+
if (graph.formulas.has(label)) {
|
|
30574
|
+
affected.add(label);
|
|
30575
|
+
}
|
|
30576
|
+
}
|
|
30577
|
+
for (let index = 0; index < queue.length; index += 1) {
|
|
30578
|
+
const label = queue[index];
|
|
30579
|
+
if (!label) continue;
|
|
30580
|
+
for (const dependent of graph.dependents.get(label) ?? []) {
|
|
30581
|
+
if (affected.has(dependent)) continue;
|
|
30582
|
+
affected.add(dependent);
|
|
30583
|
+
queue.push(dependent);
|
|
30584
|
+
}
|
|
30585
|
+
}
|
|
30586
|
+
return affected;
|
|
30587
|
+
}
|
|
30455
30588
|
function evaluateBasicTableFormula(formula, getCellValue) {
|
|
30456
30589
|
const normalized = normalizeTableFormula(formula);
|
|
30457
30590
|
if (!normalized) {
|
|
@@ -30599,10 +30732,19 @@ var FormulaParser = class {
|
|
|
30599
30732
|
const range = parseTableCellRange(token.value);
|
|
30600
30733
|
if (!range) return { value: null, error: "invalid-reference" };
|
|
30601
30734
|
for (const label of getTableCellRangeLabels(range)) {
|
|
30735
|
+
if (name === "COUNT") {
|
|
30736
|
+
const cellValue2 = this.readOptionalCellNumber(label);
|
|
30737
|
+
if (cellValue2 != null) values.push(cellValue2);
|
|
30738
|
+
continue;
|
|
30739
|
+
}
|
|
30602
30740
|
const cellValue = this.readCellNumber(label);
|
|
30603
30741
|
if (cellValue.error) return cellValue;
|
|
30604
30742
|
values.push(cellValue.value);
|
|
30605
30743
|
}
|
|
30744
|
+
} else if (name === "COUNT" && token.type === "cell") {
|
|
30745
|
+
this.index += 1;
|
|
30746
|
+
const cellValue = this.readOptionalCellNumber(token.value);
|
|
30747
|
+
if (cellValue != null) values.push(cellValue);
|
|
30606
30748
|
} else {
|
|
30607
30749
|
const value = this.parseExpression();
|
|
30608
30750
|
if (value.error) return value;
|
|
@@ -30616,7 +30758,7 @@ var FormulaParser = class {
|
|
|
30616
30758
|
}
|
|
30617
30759
|
return { value: null, error: "invalid-formula" };
|
|
30618
30760
|
}
|
|
30619
|
-
if (values.length === 0) {
|
|
30761
|
+
if (values.length === 0 && name !== "COUNT") {
|
|
30620
30762
|
return { value: null, error: "invalid-formula" };
|
|
30621
30763
|
}
|
|
30622
30764
|
if (name === "SUM") return { value: values.reduce((sum, value) => sum + value, 0), error: null };
|
|
@@ -30634,6 +30776,11 @@ var FormulaParser = class {
|
|
|
30634
30776
|
}
|
|
30635
30777
|
return { value: parsed, error: null };
|
|
30636
30778
|
}
|
|
30779
|
+
readOptionalCellNumber(label) {
|
|
30780
|
+
const value = this.getCellValue(label);
|
|
30781
|
+
const parsed = typeof value === "number" ? value : Number.parseFloat(String(value ?? "").trim());
|
|
30782
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
30783
|
+
}
|
|
30637
30784
|
peekOperator(operators) {
|
|
30638
30785
|
const token = this.tokens[this.index];
|
|
30639
30786
|
return token?.type === "operator" && operators.includes(token.value) ? token : null;
|
|
@@ -30697,6 +30844,41 @@ function getSelectionTableCellNode(editor) {
|
|
|
30697
30844
|
}
|
|
30698
30845
|
return null;
|
|
30699
30846
|
}
|
|
30847
|
+
function getSelectionTableInfo(editor) {
|
|
30848
|
+
const { $from } = editor.state.selection;
|
|
30849
|
+
for (let depth = $from.depth; depth > 0; depth -= 1) {
|
|
30850
|
+
const node = $from.node(depth);
|
|
30851
|
+
if (node.type.name === "table") {
|
|
30852
|
+
return {
|
|
30853
|
+
node,
|
|
30854
|
+
pos: $from.before(depth)
|
|
30855
|
+
};
|
|
30856
|
+
}
|
|
30857
|
+
}
|
|
30858
|
+
return null;
|
|
30859
|
+
}
|
|
30860
|
+
function getSelectionTableCellLabel(editor) {
|
|
30861
|
+
const { $from } = editor.state.selection;
|
|
30862
|
+
let cellDepth = -1;
|
|
30863
|
+
let tableDepth = -1;
|
|
30864
|
+
for (let depth = $from.depth; depth > 0; depth -= 1) {
|
|
30865
|
+
const node = $from.node(depth);
|
|
30866
|
+
if (cellDepth < 0 && (node.type.name === "tableCell" || node.type.name === "tableHeader")) {
|
|
30867
|
+
cellDepth = depth;
|
|
30868
|
+
}
|
|
30869
|
+
if (node.type.name === "table") {
|
|
30870
|
+
tableDepth = depth;
|
|
30871
|
+
break;
|
|
30872
|
+
}
|
|
30873
|
+
}
|
|
30874
|
+
if (cellDepth < 0 || tableDepth < 0) return null;
|
|
30875
|
+
const tableNode = $from.node(tableDepth);
|
|
30876
|
+
const tableStart = $from.start(tableDepth);
|
|
30877
|
+
const relativeCellPos = $from.before(cellDepth) - tableStart;
|
|
30878
|
+
const rect = safeFindCell2(import_tables2.TableMap.get(tableNode), relativeCellPos);
|
|
30879
|
+
if (!rect) return null;
|
|
30880
|
+
return `${indexToColumnName(rect.left)}${rect.top + 1}`;
|
|
30881
|
+
}
|
|
30700
30882
|
function isEditingTableFormulaText(editor) {
|
|
30701
30883
|
const cellNode = getSelectionTableCellNode(editor);
|
|
30702
30884
|
return Boolean(cellNode && getCellText(cellNode).startsWith("="));
|
|
@@ -30708,20 +30890,6 @@ function createCellDisplayContent(cellNode, displayValue) {
|
|
|
30708
30890
|
}
|
|
30709
30891
|
return [paragraphType.create(null, cellNode.type.schema.text(displayValue))];
|
|
30710
30892
|
}
|
|
30711
|
-
function buildTableValueGetter(tableNode) {
|
|
30712
|
-
const map = import_tables2.TableMap.get(tableNode);
|
|
30713
|
-
const values = /* @__PURE__ */ new Map();
|
|
30714
|
-
for (const rowInfo of getTableRows2(tableNode)) {
|
|
30715
|
-
for (const entry of rowInfo.cells) {
|
|
30716
|
-
const rect = safeFindCell2(map, entry.relativePos);
|
|
30717
|
-
if (!rect) continue;
|
|
30718
|
-
const label = `${indexToColumnName(rect.left)}${rect.top + 1}`;
|
|
30719
|
-
const computedValue = entry.node.attrs.computedValue;
|
|
30720
|
-
values.set(label, typeof computedValue === "string" && computedValue.trim() ? computedValue : getCellText(entry.node));
|
|
30721
|
-
}
|
|
30722
|
-
}
|
|
30723
|
-
return (label) => values.get(label.toUpperCase());
|
|
30724
|
-
}
|
|
30725
30893
|
function buildTableValueMap(tableNode) {
|
|
30726
30894
|
const map = import_tables2.TableMap.get(tableNode);
|
|
30727
30895
|
const values = /* @__PURE__ */ new Map();
|
|
@@ -30736,10 +30904,6 @@ function buildTableValueMap(tableNode) {
|
|
|
30736
30904
|
}
|
|
30737
30905
|
return values;
|
|
30738
30906
|
}
|
|
30739
|
-
function getFormulaComputedValue(formula, tableNode) {
|
|
30740
|
-
const result = evaluateBasicTableFormula(formula, buildTableValueGetter(tableNode));
|
|
30741
|
-
return result.error ? `#${result.error.toUpperCase()}` : String(result.value);
|
|
30742
|
-
}
|
|
30743
30907
|
function normalizeFormulaInput(formula) {
|
|
30744
30908
|
const trimmed = formula.trim();
|
|
30745
30909
|
if (!trimmed) return "";
|
|
@@ -30750,19 +30914,19 @@ function setSelectedTableCellFormula(editor, formula) {
|
|
|
30750
30914
|
const { state, view } = editor;
|
|
30751
30915
|
if (!normalized) {
|
|
30752
30916
|
const clearedFormula = (0, import_tables2.setCellAttr)("formula", null)(state, view.dispatch.bind(view));
|
|
30753
|
-
const
|
|
30754
|
-
if (clearedFormula ||
|
|
30917
|
+
const clearedValue2 = (0, import_tables2.setCellAttr)("computedValue", null)(editor.state, view.dispatch.bind(view));
|
|
30918
|
+
if (clearedFormula || clearedValue2) {
|
|
30919
|
+
recalculateActiveTableFormulas(editor);
|
|
30755
30920
|
view.focus();
|
|
30756
30921
|
dispatchTableLayoutChange(editor);
|
|
30757
30922
|
return true;
|
|
30758
30923
|
}
|
|
30759
30924
|
return false;
|
|
30760
30925
|
}
|
|
30761
|
-
const rect = (0, import_tables2.selectedRect)(state);
|
|
30762
|
-
const computedValue = getFormulaComputedValue(normalized, rect.table);
|
|
30763
30926
|
const appliedFormula = (0, import_tables2.setCellAttr)("formula", normalized)(state, view.dispatch.bind(view));
|
|
30764
|
-
const
|
|
30765
|
-
if (appliedFormula ||
|
|
30927
|
+
const clearedValue = (0, import_tables2.setCellAttr)("computedValue", null)(editor.state, view.dispatch.bind(view));
|
|
30928
|
+
if (appliedFormula || clearedValue) {
|
|
30929
|
+
recalculateActiveTableFormulas(editor);
|
|
30766
30930
|
view.focus();
|
|
30767
30931
|
dispatchTableLayoutChange(editor);
|
|
30768
30932
|
return true;
|
|
@@ -30844,7 +31008,7 @@ function promoteFormulaTextInTableNode(tableNode) {
|
|
|
30844
31008
|
changed
|
|
30845
31009
|
};
|
|
30846
31010
|
}
|
|
30847
|
-
function recalculateTableNode(tableNode) {
|
|
31011
|
+
function recalculateTableNode(tableNode, options) {
|
|
30848
31012
|
const promoted = promoteFormulaTextInTableNode(tableNode);
|
|
30849
31013
|
tableNode = promoted.tableNode;
|
|
30850
31014
|
const map = import_tables2.TableMap.get(tableNode);
|
|
@@ -30874,13 +31038,16 @@ function recalculateTableNode(tableNode) {
|
|
|
30874
31038
|
}))
|
|
30875
31039
|
);
|
|
30876
31040
|
const { order, circular } = getTableFormulaRecalculationOrder(graph);
|
|
31041
|
+
const affectedLabels = options?.changedLabels ? getAffectedTableFormulaLabels(graph, options.changedLabels) : null;
|
|
30877
31042
|
const computedValues = /* @__PURE__ */ new Map();
|
|
30878
31043
|
const getCellValue = (label) => values.get(label.toUpperCase());
|
|
30879
31044
|
for (const label of circular) {
|
|
31045
|
+
if (affectedLabels && !affectedLabels.has(label)) continue;
|
|
30880
31046
|
computedValues.set(label, formatFormulaError("circular-reference"));
|
|
30881
31047
|
values.set(label, formatFormulaError("circular-reference"));
|
|
30882
31048
|
}
|
|
30883
31049
|
for (const label of order) {
|
|
31050
|
+
if (affectedLabels && !affectedLabels.has(label)) continue;
|
|
30884
31051
|
const entry = formulaEntries.get(label);
|
|
30885
31052
|
if (!entry) continue;
|
|
30886
31053
|
const result = evaluateBasicTableFormula(entry.formula, getCellValue);
|
|
@@ -30925,6 +31092,22 @@ function recalculateSelectedTable(editor) {
|
|
|
30925
31092
|
dispatchTableLayoutChange(editor);
|
|
30926
31093
|
return true;
|
|
30927
31094
|
}
|
|
31095
|
+
function recalculateActiveTableFormulas(editor) {
|
|
31096
|
+
const tableInfo = getSelectionTableInfo(editor);
|
|
31097
|
+
if (!tableInfo) {
|
|
31098
|
+
return recalculateAllTableFormulas(editor);
|
|
31099
|
+
}
|
|
31100
|
+
const activeCellLabel = getSelectionTableCellLabel(editor);
|
|
31101
|
+
const nextTable = recalculateTableNode(tableInfo.node, {
|
|
31102
|
+
changedLabels: activeCellLabel ? [activeCellLabel] : null
|
|
31103
|
+
});
|
|
31104
|
+
if (!nextTable) return false;
|
|
31105
|
+
editor.view.dispatch(
|
|
31106
|
+
editor.state.tr.replaceWith(tableInfo.pos, tableInfo.pos + tableInfo.node.nodeSize, nextTable).setMeta(UEDITOR_TABLE_FORMULA_RECALCULATE_META, true)
|
|
31107
|
+
);
|
|
31108
|
+
dispatchTableLayoutChange(editor);
|
|
31109
|
+
return true;
|
|
31110
|
+
}
|
|
30928
31111
|
function recalculateAllTableFormulas(editor) {
|
|
30929
31112
|
const replacements = [];
|
|
30930
31113
|
editor.state.doc.descendants((node, pos) => {
|
|
@@ -30961,9 +31144,41 @@ function applyTableCellBackground(editor, color) {
|
|
|
30961
31144
|
}
|
|
30962
31145
|
editor.chain().focus().setCellAttribute("backgroundColor", value).run();
|
|
30963
31146
|
}
|
|
31147
|
+
function applyTableCellAttribute(editor, name, value, options = {}) {
|
|
31148
|
+
const shouldFocus = options.focus ?? true;
|
|
31149
|
+
const { state, view } = editor;
|
|
31150
|
+
const applied = (0, import_tables3.setCellAttr)(name, value)(state, view.dispatch.bind(view));
|
|
31151
|
+
if (applied) {
|
|
31152
|
+
if (shouldFocus) view.focus();
|
|
31153
|
+
return;
|
|
31154
|
+
}
|
|
31155
|
+
const chain = editor.chain();
|
|
31156
|
+
if (shouldFocus) chain.focus();
|
|
31157
|
+
chain.setCellAttribute(name, value).run();
|
|
31158
|
+
}
|
|
31159
|
+
function BorderStylePreviewIcon({ style }) {
|
|
31160
|
+
const isNone = style === "none";
|
|
31161
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
31162
|
+
"span",
|
|
31163
|
+
{
|
|
31164
|
+
"aria-hidden": "true",
|
|
31165
|
+
className: cn(
|
|
31166
|
+
"relative inline-flex h-4 w-4 shrink-0 rounded-[2px]",
|
|
31167
|
+
isNone ? "border border-border/70 bg-muted/30" : "border text-current"
|
|
31168
|
+
),
|
|
31169
|
+
style: isNone ? void 0 : {
|
|
31170
|
+
borderStyle: style,
|
|
31171
|
+
borderWidth: style === "double" ? 3 : 2
|
|
31172
|
+
},
|
|
31173
|
+
children: isNone && /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { className: "absolute left-1/2 top-0 h-full w-px -translate-x-1/2 rotate-45 bg-muted-foreground/70" })
|
|
31174
|
+
}
|
|
31175
|
+
);
|
|
31176
|
+
}
|
|
30964
31177
|
var BubbleMenuContent = ({
|
|
30965
31178
|
editor,
|
|
30966
31179
|
onKeepOpenChange,
|
|
31180
|
+
onLinkInputOpenChange,
|
|
31181
|
+
onRequestClose,
|
|
30967
31182
|
fontSizes,
|
|
30968
31183
|
lineHeights,
|
|
30969
31184
|
initialShowLinkInput = false
|
|
@@ -30994,6 +31209,8 @@ var BubbleMenuContent = ({
|
|
|
30994
31209
|
const currentCellBgColor = normalizeStyleValue(editor.getAttributes("tableCell").backgroundColor || editor.getAttributes("tableHeader").backgroundColor) || "";
|
|
30995
31210
|
const currentCellFormula = normalizeStyleValue(editor.getAttributes("tableCell").formula || editor.getAttributes("tableHeader").formula) || "";
|
|
30996
31211
|
const currentCellNumberFormat = normalizeStyleValue(editor.getAttributes("tableCell").numberFormat || editor.getAttributes("tableHeader").numberFormat) || "text";
|
|
31212
|
+
const currentCellBorderStyle = editor.getAttributes("tableCell").borderStyle || editor.getAttributes("tableHeader").borderStyle || "solid";
|
|
31213
|
+
const currentCellBorderWidth = editor.getAttributes("tableCell").borderWidth || editor.getAttributes("tableHeader").borderWidth || "1px";
|
|
30997
31214
|
const isInTable2 = (0, import_tables3.isInTable)(editor.state);
|
|
30998
31215
|
const canMergeCells = isInTable2 && editor.can().mergeCells();
|
|
30999
31216
|
const canSplitCell = isInTable2 && editor.can().splitCell();
|
|
@@ -31007,6 +31224,15 @@ var BubbleMenuContent = ({
|
|
|
31007
31224
|
() => (lineHeights ?? getDefaultLineHeights()).filter((option) => ["1.2", "1.5", "1.75"].includes(option.value)),
|
|
31008
31225
|
[lineHeights]
|
|
31009
31226
|
);
|
|
31227
|
+
const borderColors = (0, import_react64.useMemo)(
|
|
31228
|
+
() => [
|
|
31229
|
+
highlightColors[0] ?? { name: t("colors.default"), color: "" },
|
|
31230
|
+
{ name: "Black", color: "#000000" },
|
|
31231
|
+
{ name: "White", color: "#ffffff" },
|
|
31232
|
+
...highlightColors.slice(1)
|
|
31233
|
+
],
|
|
31234
|
+
[highlightColors, t]
|
|
31235
|
+
);
|
|
31010
31236
|
(0, import_react64.useEffect)(() => {
|
|
31011
31237
|
setFontSizeDraft(currentFontSize.replace(/px$/i, ""));
|
|
31012
31238
|
}, [currentFontSize]);
|
|
@@ -31027,7 +31253,55 @@ var BubbleMenuContent = ({
|
|
|
31027
31253
|
};
|
|
31028
31254
|
(0, import_react64.useEffect)(() => {
|
|
31029
31255
|
onKeepOpenChange?.(showLinkInput);
|
|
31030
|
-
|
|
31256
|
+
onLinkInputOpenChange?.(showLinkInput);
|
|
31257
|
+
}, [onKeepOpenChange, onLinkInputOpenChange, showLinkInput]);
|
|
31258
|
+
(0, import_react64.useEffect)(() => {
|
|
31259
|
+
onKeepOpenChange?.(Boolean(activeColorPalette));
|
|
31260
|
+
}, [activeColorPalette, onKeepOpenChange]);
|
|
31261
|
+
const closeTransientPanels = (0, import_react64.useCallback)(() => {
|
|
31262
|
+
setActiveColorPalette(null);
|
|
31263
|
+
setShowLinkInput(false);
|
|
31264
|
+
onKeepOpenChange?.(false);
|
|
31265
|
+
onLinkInputOpenChange?.(false);
|
|
31266
|
+
onRequestClose?.();
|
|
31267
|
+
}, [onKeepOpenChange, onLinkInputOpenChange, onRequestClose]);
|
|
31268
|
+
const applyTableCellAttributeAndClose = (0, import_react64.useCallback)((name, value) => {
|
|
31269
|
+
applyTableCellAttribute(editor, name, value, { focus: false });
|
|
31270
|
+
closeTransientPanels();
|
|
31271
|
+
}, [closeTransientPanels, editor]);
|
|
31272
|
+
const clearTableCellBorderAndClose = (0, import_react64.useCallback)(() => {
|
|
31273
|
+
applyTableCellAttribute(editor, "borderColor", null, { focus: false });
|
|
31274
|
+
applyTableCellAttribute(editor, "borderStyle", null, { focus: false });
|
|
31275
|
+
applyTableCellAttribute(editor, "borderWidth", null, { focus: false });
|
|
31276
|
+
closeTransientPanels();
|
|
31277
|
+
}, [closeTransientPanels, editor]);
|
|
31278
|
+
const applyTableCellBorderColorAndClose = (0, import_react64.useCallback)((color) => {
|
|
31279
|
+
const value = color || null;
|
|
31280
|
+
applyTableCellAttribute(editor, "borderColor", value, { focus: false });
|
|
31281
|
+
closeTransientPanels();
|
|
31282
|
+
}, [closeTransientPanels, editor]);
|
|
31283
|
+
const closeColorPalette = (0, import_react64.useCallback)(() => {
|
|
31284
|
+
setActiveColorPalette(null);
|
|
31285
|
+
onKeepOpenChange?.(false);
|
|
31286
|
+
}, [onKeepOpenChange]);
|
|
31287
|
+
const applyInlineColorAndClose = (0, import_react64.useCallback)((color) => {
|
|
31288
|
+
if (activeColorPalette === "text") {
|
|
31289
|
+
if (color === "inherit") {
|
|
31290
|
+
editor.chain().focus().unsetColor().run();
|
|
31291
|
+
} else {
|
|
31292
|
+
editor.chain().focus().setColor(color).run();
|
|
31293
|
+
}
|
|
31294
|
+
} else if (activeColorPalette === "highlight") {
|
|
31295
|
+
if (color === "") {
|
|
31296
|
+
editor.chain().focus().unsetHighlight().run();
|
|
31297
|
+
} else {
|
|
31298
|
+
editor.chain().focus().toggleHighlight({ color }).run();
|
|
31299
|
+
}
|
|
31300
|
+
} else {
|
|
31301
|
+
applyTableCellBackground(editor, color);
|
|
31302
|
+
}
|
|
31303
|
+
closeColorPalette();
|
|
31304
|
+
}, [activeColorPalette, closeColorPalette, editor]);
|
|
31031
31305
|
(0, import_react64.useEffect)(() => {
|
|
31032
31306
|
if (!showLinkInput) return;
|
|
31033
31307
|
const close2 = () => setShowLinkInput(false);
|
|
@@ -31059,51 +31333,53 @@ var BubbleMenuContent = ({
|
|
|
31059
31333
|
const isTextPalette = activeColorPalette === "text";
|
|
31060
31334
|
const isHighlightPalette = activeColorPalette === "highlight";
|
|
31061
31335
|
if (activeColorPalette === "cell-border") {
|
|
31062
|
-
const currentBorderStyle = editor.getAttributes("tableCell").borderStyle || editor.getAttributes("tableHeader").borderStyle || "solid";
|
|
31063
|
-
const currentBorderWidth = editor.getAttributes("tableCell").borderWidth || editor.getAttributes("tableHeader").borderWidth || "1px";
|
|
31064
31336
|
const currentBorderColor = editor.getAttributes("tableCell").borderColor || editor.getAttributes("tableHeader").borderColor || "currentColor";
|
|
31065
|
-
return /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: "flex flex-col gap-2 p-2 w-56 text-sm", children: [
|
|
31337
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: "flex flex-col gap-2 p-2 w-56 text-sm", "data-ueditor-keep-open": true, children: [
|
|
31066
31338
|
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("div", { className: "font-semibold text-xs text-muted-foreground uppercase tracking-wider mb-1", children: t("tableMenu.cellBorder") || "Cell Borders" }),
|
|
31067
31339
|
/* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
31068
31340
|
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("label", { className: "text-xs text-muted-foreground", children: t("tableMenu.borderStyle") || "Border Style" }),
|
|
31069
|
-
/* @__PURE__ */ (0, import_jsx_runtime87.
|
|
31070
|
-
"
|
|
31341
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("div", { className: "grid grid-cols-3 gap-1", role: "group", "aria-label": t("tableMenu.borderStyle") || "Border Style", children: [
|
|
31342
|
+
["solid", "Solid"],
|
|
31343
|
+
["dashed", "Dashed"],
|
|
31344
|
+
["dotted", "Dotted"],
|
|
31345
|
+
["double", "Double"],
|
|
31346
|
+
["none", "None"]
|
|
31347
|
+
].map(([style, label]) => /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)(
|
|
31348
|
+
"button",
|
|
31071
31349
|
{
|
|
31072
|
-
|
|
31073
|
-
|
|
31074
|
-
|
|
31075
|
-
|
|
31076
|
-
|
|
31077
|
-
|
|
31350
|
+
type: "button",
|
|
31351
|
+
"data-ueditor-close-on-select": true,
|
|
31352
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
31353
|
+
onClick: () => applyTableCellAttributeAndClose("borderStyle", style),
|
|
31354
|
+
className: cn(
|
|
31355
|
+
"inline-flex h-8 items-center justify-center gap-1.5 rounded-md px-2 text-xs font-medium transition-colors hover:bg-muted",
|
|
31356
|
+
currentCellBorderStyle === style ? "bg-primary/10 text-primary" : "bg-muted/40 text-foreground"
|
|
31357
|
+
),
|
|
31078
31358
|
children: [
|
|
31079
|
-
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
31080
|
-
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("
|
|
31081
|
-
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("option", { value: "dotted", children: "Dotted" }),
|
|
31082
|
-
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("option", { value: "double", children: "Double" }),
|
|
31083
|
-
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("option", { value: "none", children: "None" })
|
|
31359
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)(BorderStylePreviewIcon, { style }),
|
|
31360
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { children: label })
|
|
31084
31361
|
]
|
|
31085
|
-
}
|
|
31086
|
-
|
|
31362
|
+
},
|
|
31363
|
+
style
|
|
31364
|
+
)) })
|
|
31087
31365
|
] }),
|
|
31088
31366
|
/* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
31089
31367
|
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("label", { className: "text-xs text-muted-foreground", children: t("tableMenu.borderWidth") || "Border Width" }),
|
|
31090
|
-
/* @__PURE__ */ (0, import_jsx_runtime87.
|
|
31091
|
-
"
|
|
31368
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("div", { className: "grid grid-cols-4 gap-1", role: "group", "aria-label": t("tableMenu.borderWidth") || "Border Width", children: ["1px", "2px", "3px", "4px"].map((width) => /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
31369
|
+
"button",
|
|
31092
31370
|
{
|
|
31093
|
-
|
|
31094
|
-
|
|
31095
|
-
|
|
31096
|
-
|
|
31097
|
-
|
|
31098
|
-
|
|
31099
|
-
|
|
31100
|
-
|
|
31101
|
-
|
|
31102
|
-
|
|
31103
|
-
|
|
31104
|
-
|
|
31105
|
-
}
|
|
31106
|
-
)
|
|
31371
|
+
type: "button",
|
|
31372
|
+
"data-ueditor-close-on-select": true,
|
|
31373
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
31374
|
+
onClick: () => applyTableCellAttributeAndClose("borderWidth", width),
|
|
31375
|
+
className: cn(
|
|
31376
|
+
"h-8 rounded-md px-2 text-xs font-medium transition-colors hover:bg-muted",
|
|
31377
|
+
currentCellBorderWidth === width ? "bg-primary/10 text-primary" : "bg-muted/40 text-foreground"
|
|
31378
|
+
),
|
|
31379
|
+
children: width
|
|
31380
|
+
},
|
|
31381
|
+
width
|
|
31382
|
+
)) })
|
|
31107
31383
|
] }),
|
|
31108
31384
|
/* @__PURE__ */ (0, import_jsx_runtime87.jsxs)(
|
|
31109
31385
|
"button",
|
|
@@ -31125,70 +31401,36 @@ var BubbleMenuContent = ({
|
|
|
31125
31401
|
]
|
|
31126
31402
|
}
|
|
31127
31403
|
),
|
|
31128
|
-
/* @__PURE__ */ (0, import_jsx_runtime87.
|
|
31129
|
-
|
|
31130
|
-
|
|
31131
|
-
|
|
31132
|
-
|
|
31133
|
-
|
|
31134
|
-
|
|
31135
|
-
|
|
31136
|
-
|
|
31137
|
-
|
|
31138
|
-
children: t("tableMenu.clearBorder") || "Clear Border"
|
|
31139
|
-
}
|
|
31140
|
-
),
|
|
31141
|
-
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
31142
|
-
"button",
|
|
31143
|
-
{
|
|
31144
|
-
type: "button",
|
|
31145
|
-
onClick: () => setActiveColorPalette(null),
|
|
31146
|
-
className: "text-xs font-medium text-primary hover:underline",
|
|
31147
|
-
children: t("tableMenu.done") || "Done"
|
|
31148
|
-
}
|
|
31149
|
-
)
|
|
31150
|
-
] })
|
|
31404
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("div", { className: "flex items-center justify-between gap-2 mt-2 pt-2 border-t border-border", children: /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
31405
|
+
"button",
|
|
31406
|
+
{
|
|
31407
|
+
type: "button",
|
|
31408
|
+
"data-ueditor-close-on-select": true,
|
|
31409
|
+
onClick: clearTableCellBorderAndClose,
|
|
31410
|
+
className: "text-xs text-destructive hover:underline",
|
|
31411
|
+
children: t("tableMenu.clearBorder") || "Clear Border"
|
|
31412
|
+
}
|
|
31413
|
+
) })
|
|
31151
31414
|
] });
|
|
31152
31415
|
}
|
|
31153
31416
|
if (activeColorPalette === "cell-border-color") {
|
|
31154
31417
|
const currentBorderColor = normalizeStyleValue(editor.getAttributes("tableCell").borderColor || editor.getAttributes("tableHeader").borderColor) || "";
|
|
31155
|
-
return /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("div", { className: "w-56", children: /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
31418
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("div", { className: "w-56", "data-ueditor-keep-open": true, children: /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
31156
31419
|
EditorColorPalette,
|
|
31157
31420
|
{
|
|
31158
|
-
colors:
|
|
31421
|
+
colors: borderColors,
|
|
31159
31422
|
currentColor: currentBorderColor,
|
|
31160
|
-
onSelect:
|
|
31161
|
-
const value = color || null;
|
|
31162
|
-
editor.chain().focus().setCellAttribute("borderColor", value).run();
|
|
31163
|
-
setActiveColorPalette("cell-border");
|
|
31164
|
-
},
|
|
31423
|
+
onSelect: applyTableCellBorderColorAndClose,
|
|
31165
31424
|
label: t("tableMenu.borderColor") || "Border Color"
|
|
31166
31425
|
}
|
|
31167
31426
|
) });
|
|
31168
31427
|
}
|
|
31169
|
-
return /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("div", { className: "w-56", children: /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
31428
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("div", { className: "w-56", "data-ueditor-keep-open": true, children: /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
31170
31429
|
EditorColorPalette,
|
|
31171
31430
|
{
|
|
31172
31431
|
colors: isTextPalette ? textColors : highlightColors,
|
|
31173
31432
|
currentColor: isTextPalette ? currentTextColor : isHighlightPalette ? currentHighlightColor : currentCellBgColor,
|
|
31174
|
-
onSelect:
|
|
31175
|
-
if (isTextPalette) {
|
|
31176
|
-
if (color === "inherit") {
|
|
31177
|
-
editor.chain().focus().unsetColor().run();
|
|
31178
|
-
} else {
|
|
31179
|
-
editor.chain().focus().setColor(color).run();
|
|
31180
|
-
}
|
|
31181
|
-
} else if (isHighlightPalette) {
|
|
31182
|
-
if (color === "") {
|
|
31183
|
-
editor.chain().focus().unsetHighlight().run();
|
|
31184
|
-
} else {
|
|
31185
|
-
editor.chain().focus().toggleHighlight({ color }).run();
|
|
31186
|
-
}
|
|
31187
|
-
} else {
|
|
31188
|
-
applyTableCellBackground(editor, color);
|
|
31189
|
-
}
|
|
31190
|
-
setActiveColorPalette(null);
|
|
31191
|
-
},
|
|
31433
|
+
onSelect: applyInlineColorAndClose,
|
|
31192
31434
|
label: isTextPalette ? t("colors.textColor") : isHighlightPalette ? t("colors.highlight") : t("tableMenu.cellBackground") || "Cell background"
|
|
31193
31435
|
}
|
|
31194
31436
|
) });
|
|
@@ -31513,6 +31755,9 @@ var BubbleMenuContent = ({
|
|
|
31513
31755
|
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
31514
31756
|
ToolbarButton,
|
|
31515
31757
|
{
|
|
31758
|
+
onMouseDown: () => {
|
|
31759
|
+
onKeepOpenChange?.(true);
|
|
31760
|
+
},
|
|
31516
31761
|
onClick: () => setActiveColorPalette("cell-border"),
|
|
31517
31762
|
active: Boolean(
|
|
31518
31763
|
editor.getAttributes("tableCell").borderColor || editor.getAttributes("tableHeader").borderColor || editor.getAttributes("tableCell").borderStyle || editor.getAttributes("tableHeader").borderStyle || editor.getAttributes("tableCell").borderWidth || editor.getAttributes("tableHeader").borderWidth
|
|
@@ -31594,14 +31839,27 @@ var CustomBubbleMenu = ({
|
|
|
31594
31839
|
const SHOW_DELAY_MS = 180;
|
|
31595
31840
|
const BUBBLE_MENU_OFFSET = 16;
|
|
31596
31841
|
const [isVisible, setIsVisible] = (0, import_react64.useState)(false);
|
|
31842
|
+
const [linkInputOpen, setLinkInputOpen] = (0, import_react64.useState)(false);
|
|
31597
31843
|
const [position, setPosition] = (0, import_react64.useState)({ top: 0, left: 0 });
|
|
31598
31844
|
const menuRef = (0, import_react64.useRef)(null);
|
|
31599
31845
|
const keepOpenRef = (0, import_react64.useRef)(false);
|
|
31600
31846
|
const showTimeoutRef = (0, import_react64.useRef)(null);
|
|
31847
|
+
const suppressShowUntilRef = (0, import_react64.useRef)(0);
|
|
31601
31848
|
const setKeepOpen = (0, import_react64.useCallback)((next) => {
|
|
31602
31849
|
keepOpenRef.current = next;
|
|
31850
|
+
if (!next) setLinkInputOpen(false);
|
|
31603
31851
|
if (next) setIsVisible(true);
|
|
31604
31852
|
}, []);
|
|
31853
|
+
const closeBubbleMenu = (0, import_react64.useCallback)(() => {
|
|
31854
|
+
suppressShowUntilRef.current = Date.now() + 1e3;
|
|
31855
|
+
keepOpenRef.current = false;
|
|
31856
|
+
setLinkInputOpen(false);
|
|
31857
|
+
setIsVisible(false);
|
|
31858
|
+
if (showTimeoutRef.current) {
|
|
31859
|
+
clearTimeout(showTimeoutRef.current);
|
|
31860
|
+
showTimeoutRef.current = null;
|
|
31861
|
+
}
|
|
31862
|
+
}, []);
|
|
31605
31863
|
(0, import_react64.useEffect)(() => {
|
|
31606
31864
|
const clearShowTimeout = () => {
|
|
31607
31865
|
if (showTimeoutRef.current) {
|
|
@@ -31613,6 +31871,11 @@ var CustomBubbleMenu = ({
|
|
|
31613
31871
|
const { state, view } = editor;
|
|
31614
31872
|
const { from, to, empty } = state.selection;
|
|
31615
31873
|
const isLinkActive = editor.isActive("link");
|
|
31874
|
+
if (Date.now() < suppressShowUntilRef.current) {
|
|
31875
|
+
clearShowTimeout();
|
|
31876
|
+
setIsVisible(false);
|
|
31877
|
+
return;
|
|
31878
|
+
}
|
|
31616
31879
|
if (!keepOpenRef.current && (empty && !isLinkActive || !view.hasFocus())) {
|
|
31617
31880
|
clearShowTimeout();
|
|
31618
31881
|
setIsVisible(false);
|
|
@@ -31624,6 +31887,11 @@ var CustomBubbleMenu = ({
|
|
|
31624
31887
|
start = view.coordsAtPos(from);
|
|
31625
31888
|
end = view.coordsAtPos(to);
|
|
31626
31889
|
} catch {
|
|
31890
|
+
if (keepOpenRef.current) {
|
|
31891
|
+
clearShowTimeout();
|
|
31892
|
+
setIsVisible(true);
|
|
31893
|
+
return;
|
|
31894
|
+
}
|
|
31627
31895
|
clearShowTimeout();
|
|
31628
31896
|
setIsVisible(false);
|
|
31629
31897
|
return;
|
|
@@ -31681,15 +31949,34 @@ var CustomBubbleMenu = ({
|
|
|
31681
31949
|
left: `${position.left}px`,
|
|
31682
31950
|
transform: "translate(-50%, -100%)"
|
|
31683
31951
|
},
|
|
31684
|
-
onMouseDown: (e) =>
|
|
31685
|
-
|
|
31952
|
+
onMouseDown: (e) => {
|
|
31953
|
+
const target = e.target;
|
|
31954
|
+
if (target?.closest?.("[data-ueditor-close-on-select]")) {
|
|
31955
|
+
keepOpenRef.current = false;
|
|
31956
|
+
} else if (target?.closest?.("[data-ueditor-keep-open]")) {
|
|
31957
|
+
keepOpenRef.current = true;
|
|
31958
|
+
}
|
|
31959
|
+
e.preventDefault();
|
|
31960
|
+
},
|
|
31961
|
+
children: editor.isActive("link") && !keepOpenRef.current && !linkInputOpen ? /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
31962
|
+
LinkPreviewContent,
|
|
31963
|
+
{
|
|
31964
|
+
editor,
|
|
31965
|
+
onEdit: () => {
|
|
31966
|
+
setLinkInputOpen(true);
|
|
31967
|
+
setKeepOpen(true);
|
|
31968
|
+
}
|
|
31969
|
+
}
|
|
31970
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
31686
31971
|
BubbleMenuContent,
|
|
31687
31972
|
{
|
|
31688
31973
|
editor,
|
|
31689
31974
|
onKeepOpenChange: setKeepOpen,
|
|
31975
|
+
onLinkInputOpenChange: setLinkInputOpen,
|
|
31976
|
+
onRequestClose: closeBubbleMenu,
|
|
31690
31977
|
fontSizes,
|
|
31691
31978
|
lineHeights,
|
|
31692
|
-
initialShowLinkInput:
|
|
31979
|
+
initialShowLinkInput: linkInputOpen
|
|
31693
31980
|
}
|
|
31694
31981
|
)
|
|
31695
31982
|
}
|
|
@@ -38125,6 +38412,7 @@ function useUEditorTableInteractions(editor, editable = true) {
|
|
|
38125
38412
|
proseMirror.addEventListener("keyup", handleSelectionChange);
|
|
38126
38413
|
proseMirror.addEventListener("focusin", handleSelectionChange);
|
|
38127
38414
|
document.addEventListener("selectionchange", handleSelectionChange);
|
|
38415
|
+
surface?.addEventListener(UEDITOR_TABLE_LAYOUT_CHANGE_EVENT, handleActiveCellLayoutChange);
|
|
38128
38416
|
surface?.addEventListener("scroll", handleActiveCellLayoutChange, scrollListenerOptions);
|
|
38129
38417
|
window.addEventListener("resize", handleActiveCellLayoutChange);
|
|
38130
38418
|
document.addEventListener("pointermove", handlePointerMove);
|
|
@@ -38144,6 +38432,7 @@ function useUEditorTableInteractions(editor, editable = true) {
|
|
|
38144
38432
|
proseMirror.removeEventListener("keyup", handleSelectionChange);
|
|
38145
38433
|
proseMirror.removeEventListener("focusin", handleSelectionChange);
|
|
38146
38434
|
document.removeEventListener("selectionchange", handleSelectionChange);
|
|
38435
|
+
surface?.removeEventListener(UEDITOR_TABLE_LAYOUT_CHANGE_EVENT, handleActiveCellLayoutChange);
|
|
38147
38436
|
surface?.removeEventListener("scroll", handleActiveCellLayoutChange, scrollListenerOptions);
|
|
38148
38437
|
window.removeEventListener("resize", handleActiveCellLayoutChange);
|
|
38149
38438
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
@@ -38178,6 +38467,144 @@ function useUEditorTableInteractions(editor, editable = true) {
|
|
|
38178
38467
|
var import_react69 = __toESM(require("react"), 1);
|
|
38179
38468
|
var import_react70 = require("@tiptap/react");
|
|
38180
38469
|
var import_lucide_react54 = require("lucide-react");
|
|
38470
|
+
|
|
38471
|
+
// src/components/UEditor/preview-html.ts
|
|
38472
|
+
var DEFAULT_TABLE_COLUMN_WIDTH = 100;
|
|
38473
|
+
var TIPTAP_TABLE_MIN_COLUMN_WIDTH = 25;
|
|
38474
|
+
function parsePixelWidth2(value) {
|
|
38475
|
+
if (!value) return null;
|
|
38476
|
+
const match = String(value).match(/(?:^|[\s:])(\d+(?:\.\d+)?)px\b/i) ?? String(value).match(/^(\d+(?:\.\d+)?)$/);
|
|
38477
|
+
if (!match) return null;
|
|
38478
|
+
const parsed = Number.parseFloat(match[1] ?? match[0]);
|
|
38479
|
+
return Number.isFinite(parsed) && parsed > 0 ? Math.round(parsed) : null;
|
|
38480
|
+
}
|
|
38481
|
+
function parseStyleWidth(style) {
|
|
38482
|
+
return parsePixelWidth2(style.width) ?? parsePixelWidth2(style.minWidth);
|
|
38483
|
+
}
|
|
38484
|
+
function parseStyleHeight(style) {
|
|
38485
|
+
return parsePixelWidth2(style.height) ?? parsePixelWidth2(style.minHeight);
|
|
38486
|
+
}
|
|
38487
|
+
function getCellColspan(cell) {
|
|
38488
|
+
return Math.max(1, cell.colSpan || Number.parseInt(cell.getAttribute("colspan") || "1", 10) || 1);
|
|
38489
|
+
}
|
|
38490
|
+
function getCellWidths(cell) {
|
|
38491
|
+
const dataColwidth = cell.getAttribute("data-colwidth") || cell.getAttribute("colwidth");
|
|
38492
|
+
if (dataColwidth) {
|
|
38493
|
+
const widths = dataColwidth.split(/[,\s]+/).map((part) => parsePixelWidth2(part)).filter((width2) => typeof width2 === "number");
|
|
38494
|
+
if (widths.length > 0) return widths;
|
|
38495
|
+
}
|
|
38496
|
+
const width = parsePixelWidth2(cell.getAttribute("width")) ?? parseStyleWidth(cell.style);
|
|
38497
|
+
if (!width) return null;
|
|
38498
|
+
const colspan = getCellColspan(cell);
|
|
38499
|
+
return Array.from({ length: colspan }, () => Math.max(DEFAULT_TABLE_COLUMN_WIDTH, Math.round(width / colspan)));
|
|
38500
|
+
}
|
|
38501
|
+
function getColumnCount(table) {
|
|
38502
|
+
const colCount = table.querySelectorAll("colgroup > col").length;
|
|
38503
|
+
if (colCount > 0) return colCount;
|
|
38504
|
+
return Math.max(
|
|
38505
|
+
0,
|
|
38506
|
+
...Array.from(table.rows).map(
|
|
38507
|
+
(row) => Array.from(row.cells).reduce((count, cell) => count + getCellColspan(cell), 0)
|
|
38508
|
+
)
|
|
38509
|
+
);
|
|
38510
|
+
}
|
|
38511
|
+
function resolveColumnWidths(table) {
|
|
38512
|
+
const columnCount = getColumnCount(table);
|
|
38513
|
+
if (columnCount <= 0) return [];
|
|
38514
|
+
const widths = Array.from({ length: columnCount }, () => DEFAULT_TABLE_COLUMN_WIDTH);
|
|
38515
|
+
const cols = Array.from(table.querySelectorAll("colgroup > col"));
|
|
38516
|
+
cols.slice(0, columnCount).forEach((col, index) => {
|
|
38517
|
+
const width = parsePixelWidth2(col.getAttribute("width")) ?? parseStyleWidth(col.style);
|
|
38518
|
+
if (width && width > TIPTAP_TABLE_MIN_COLUMN_WIDTH) {
|
|
38519
|
+
widths[index] = width;
|
|
38520
|
+
}
|
|
38521
|
+
});
|
|
38522
|
+
Array.from(table.rows).forEach((row) => {
|
|
38523
|
+
let columnIndex = 0;
|
|
38524
|
+
Array.from(row.cells).forEach((cell) => {
|
|
38525
|
+
const cellWidths = getCellWidths(cell);
|
|
38526
|
+
if (cellWidths) {
|
|
38527
|
+
cellWidths.slice(0, getCellColspan(cell)).forEach((width, offset) => {
|
|
38528
|
+
if (width > TIPTAP_TABLE_MIN_COLUMN_WIDTH && columnIndex + offset < widths.length) {
|
|
38529
|
+
widths[columnIndex + offset] = width;
|
|
38530
|
+
}
|
|
38531
|
+
});
|
|
38532
|
+
}
|
|
38533
|
+
columnIndex += getCellColspan(cell);
|
|
38534
|
+
});
|
|
38535
|
+
});
|
|
38536
|
+
return widths;
|
|
38537
|
+
}
|
|
38538
|
+
function setStyleProperty(element, property, value) {
|
|
38539
|
+
element.style.setProperty(property, value);
|
|
38540
|
+
}
|
|
38541
|
+
function resolveRowHeight(row) {
|
|
38542
|
+
const explicitRowHeight = parsePixelWidth2(row.getAttribute("data-row-height")) ?? parseStyleHeight(row.style);
|
|
38543
|
+
if (explicitRowHeight) return Math.max(MIN_TABLE_ROW_HEIGHT, explicitRowHeight);
|
|
38544
|
+
const cellHeight = Array.from(row.cells).reduce((maxHeight, cell) => {
|
|
38545
|
+
const height = parsePixelWidth2(cell.getAttribute("height")) ?? parseStyleHeight(cell.style);
|
|
38546
|
+
return height ? Math.max(maxHeight, height) : maxHeight;
|
|
38547
|
+
}, 0);
|
|
38548
|
+
return Math.max(MIN_TABLE_ROW_HEIGHT, cellHeight);
|
|
38549
|
+
}
|
|
38550
|
+
function normalizePreviewRowHeight(row) {
|
|
38551
|
+
const rowHeight = resolveRowHeight(row);
|
|
38552
|
+
row.style.height = `${rowHeight}px`;
|
|
38553
|
+
row.style.minHeight = `${rowHeight}px`;
|
|
38554
|
+
Array.from(row.cells).forEach((cell) => {
|
|
38555
|
+
cell.style.height = `${rowHeight}px`;
|
|
38556
|
+
cell.style.minHeight = `${rowHeight}px`;
|
|
38557
|
+
});
|
|
38558
|
+
}
|
|
38559
|
+
function normalizePreviewTable(table) {
|
|
38560
|
+
const widths = resolveColumnWidths(table);
|
|
38561
|
+
if (widths.length === 0) return;
|
|
38562
|
+
let colgroup = table.querySelector("colgroup");
|
|
38563
|
+
if (!colgroup) {
|
|
38564
|
+
colgroup = document.createElement("colgroup");
|
|
38565
|
+
table.insertBefore(colgroup, table.firstChild);
|
|
38566
|
+
}
|
|
38567
|
+
while (colgroup.children.length < widths.length) {
|
|
38568
|
+
colgroup.appendChild(document.createElement("col"));
|
|
38569
|
+
}
|
|
38570
|
+
Array.from(colgroup.children).forEach((child, index) => {
|
|
38571
|
+
if (child.tagName.toLowerCase() !== "col") return;
|
|
38572
|
+
const col = child;
|
|
38573
|
+
if (index >= widths.length) {
|
|
38574
|
+
child.remove();
|
|
38575
|
+
return;
|
|
38576
|
+
}
|
|
38577
|
+
col.style.width = `${widths[index]}px`;
|
|
38578
|
+
col.style.minWidth = `${widths[index]}px`;
|
|
38579
|
+
col.setAttribute("width", String(widths[index]));
|
|
38580
|
+
});
|
|
38581
|
+
const tableWidth = widths.reduce((sum, width) => sum + width, 0);
|
|
38582
|
+
setStyleProperty(table, "width", `${tableWidth}px`);
|
|
38583
|
+
setStyleProperty(table, "min-width", `${tableWidth}px`);
|
|
38584
|
+
setStyleProperty(table, "table-layout", "fixed");
|
|
38585
|
+
Array.from(table.rows).forEach((row) => {
|
|
38586
|
+
let columnIndex = 0;
|
|
38587
|
+
normalizePreviewRowHeight(row);
|
|
38588
|
+
Array.from(row.cells).forEach((cell) => {
|
|
38589
|
+
const colspan = getCellColspan(cell);
|
|
38590
|
+
const cellWidth = widths.slice(columnIndex, columnIndex + colspan).reduce((sum, width) => sum + width, 0);
|
|
38591
|
+
if (cellWidth > 0) {
|
|
38592
|
+
cell.style.width = `${cellWidth}px`;
|
|
38593
|
+
cell.style.minWidth = `${cellWidth}px`;
|
|
38594
|
+
}
|
|
38595
|
+
columnIndex += colspan;
|
|
38596
|
+
});
|
|
38597
|
+
});
|
|
38598
|
+
}
|
|
38599
|
+
function prepareUEditorPreviewHtml(html) {
|
|
38600
|
+
if (typeof document === "undefined" || !html) return html;
|
|
38601
|
+
const container = document.createElement("div");
|
|
38602
|
+
container.innerHTML = html;
|
|
38603
|
+
container.querySelectorAll("table").forEach((table) => normalizePreviewTable(table));
|
|
38604
|
+
return container.innerHTML;
|
|
38605
|
+
}
|
|
38606
|
+
|
|
38607
|
+
// src/components/UEditor/menu-bar.tsx
|
|
38181
38608
|
var import_jsx_runtime94 = require("react/jsx-runtime");
|
|
38182
38609
|
function MenuTableInsertGrid({
|
|
38183
38610
|
insertLabel,
|
|
@@ -38660,6 +39087,10 @@ var MenuBar = ({
|
|
|
38660
39087
|
const [showSourceDialog, setShowSourceDialog] = (0, import_react69.useState)(false);
|
|
38661
39088
|
const [sourceHtml, setSourceHtml] = (0, import_react69.useState)("");
|
|
38662
39089
|
const [showPreviewDialog, setShowPreviewDialog] = (0, import_react69.useState)(false);
|
|
39090
|
+
const previewHtml = (0, import_react69.useMemo)(
|
|
39091
|
+
() => showPreviewDialog ? prepareUEditorPreviewHtml(editor.getHTML()) : "",
|
|
39092
|
+
[editor, showPreviewDialog]
|
|
39093
|
+
);
|
|
38663
39094
|
const openSourceDialog = () => {
|
|
38664
39095
|
setSourceHtml(editor.getHTML());
|
|
38665
39096
|
setShowSourceDialog(true);
|
|
@@ -38668,10 +39099,7 @@ var MenuBar = ({
|
|
|
38668
39099
|
setShowPreviewDialog(true);
|
|
38669
39100
|
};
|
|
38670
39101
|
const handlePreview = () => {
|
|
38671
|
-
if (onPreview)
|
|
38672
|
-
onPreview();
|
|
38673
|
-
return;
|
|
38674
|
-
}
|
|
39102
|
+
if (onPreview?.(editor.getHTML()) === false) return;
|
|
38675
39103
|
openPreviewDialog();
|
|
38676
39104
|
};
|
|
38677
39105
|
const applySourceHtml = () => {
|
|
@@ -38906,12 +39334,12 @@ var MenuBar = ({
|
|
|
38906
39334
|
"div",
|
|
38907
39335
|
{
|
|
38908
39336
|
"data-testid": "preview-content",
|
|
38909
|
-
className: "min-h-0 flex-1 overflow-y-auto overscroll-contain
|
|
39337
|
+
className: "min-h-0 flex-1 overflow-y-auto overscroll-contain",
|
|
38910
39338
|
children: editor.isEmpty ? /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("p", { className: "text-muted-foreground text-sm", children: t("menubar.previewEmpty") }) : /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(
|
|
38911
39339
|
"div",
|
|
38912
39340
|
{
|
|
38913
39341
|
className: UEDITOR_PROSEMIRROR_CLASS_NAME,
|
|
38914
|
-
dangerouslySetInnerHTML: { __html:
|
|
39342
|
+
dangerouslySetInnerHTML: { __html: previewHtml }
|
|
38915
39343
|
}
|
|
38916
39344
|
)
|
|
38917
39345
|
}
|
|
@@ -38921,6 +39349,146 @@ var MenuBar = ({
|
|
|
38921
39349
|
] });
|
|
38922
39350
|
};
|
|
38923
39351
|
|
|
39352
|
+
// src/components/UEditor/table-formula-range-picker.ts
|
|
39353
|
+
var import_state9 = require("@tiptap/pm/state");
|
|
39354
|
+
var import_tables4 = require("@tiptap/pm/tables");
|
|
39355
|
+
function getCellText2(cellNode) {
|
|
39356
|
+
return cellNode.textBetween(0, cellNode.content.size, "\n").trim();
|
|
39357
|
+
}
|
|
39358
|
+
function findSelectionFormulaCell(view) {
|
|
39359
|
+
const { $from } = view.state.selection;
|
|
39360
|
+
for (let depth = $from.depth; depth > 0; depth -= 1) {
|
|
39361
|
+
const node = $from.node(depth);
|
|
39362
|
+
if (node.type.name !== "tableCell" && node.type.name !== "tableHeader") continue;
|
|
39363
|
+
if (!getCellText2(node).startsWith("=")) return null;
|
|
39364
|
+
const cellPos = $from.before(depth);
|
|
39365
|
+
const cellDom = view.nodeDOM(cellPos);
|
|
39366
|
+
const tableDepth = depth - 2;
|
|
39367
|
+
const tableNode = tableDepth > 0 ? $from.node(tableDepth) : null;
|
|
39368
|
+
if (!tableNode || tableNode.type.name !== "table") return null;
|
|
39369
|
+
return {
|
|
39370
|
+
cellDom: cellDom instanceof HTMLTableCellElement ? cellDom : null,
|
|
39371
|
+
tablePos: $from.before(tableDepth)
|
|
39372
|
+
};
|
|
39373
|
+
}
|
|
39374
|
+
return null;
|
|
39375
|
+
}
|
|
39376
|
+
function findTableForPos(view, pos) {
|
|
39377
|
+
const $pos = view.state.doc.resolve(pos);
|
|
39378
|
+
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
39379
|
+
const node = $pos.node(depth);
|
|
39380
|
+
if (node.type.name === "table") {
|
|
39381
|
+
return {
|
|
39382
|
+
node,
|
|
39383
|
+
pos: $pos.before(depth),
|
|
39384
|
+
start: $pos.start(depth)
|
|
39385
|
+
};
|
|
39386
|
+
}
|
|
39387
|
+
}
|
|
39388
|
+
return null;
|
|
39389
|
+
}
|
|
39390
|
+
function getCellRelativePosFromDomPos2(map, tableStart, domPos) {
|
|
39391
|
+
const relativeDomPos = domPos - tableStart;
|
|
39392
|
+
const seen = /* @__PURE__ */ new Set();
|
|
39393
|
+
for (const relativeCellPos of map.map) {
|
|
39394
|
+
if (seen.has(relativeCellPos)) continue;
|
|
39395
|
+
seen.add(relativeCellPos);
|
|
39396
|
+
if (relativeDomPos === relativeCellPos || relativeDomPos === relativeCellPos + 1) {
|
|
39397
|
+
return relativeCellPos;
|
|
39398
|
+
}
|
|
39399
|
+
}
|
|
39400
|
+
return null;
|
|
39401
|
+
}
|
|
39402
|
+
function getPickedCellLabel(view, target, tablePos) {
|
|
39403
|
+
const element = resolveEventElement(target);
|
|
39404
|
+
const cell = element?.closest?.("th,td");
|
|
39405
|
+
if (!(cell instanceof HTMLTableCellElement)) return null;
|
|
39406
|
+
const domPos = view.posAtDOM(cell, 0);
|
|
39407
|
+
const tableInfo = findTableForPos(view, domPos);
|
|
39408
|
+
if (!tableInfo || tableInfo.pos !== tablePos) return null;
|
|
39409
|
+
const map = import_tables4.TableMap.get(tableInfo.node);
|
|
39410
|
+
const relativeCellPos = getCellRelativePosFromDomPos2(map, tableInfo.start, domPos);
|
|
39411
|
+
if (relativeCellPos == null) return null;
|
|
39412
|
+
const rect = map.findCell(relativeCellPos);
|
|
39413
|
+
return {
|
|
39414
|
+
cell,
|
|
39415
|
+
label: `${indexToColumnName(rect.left)}${rect.top + 1}`
|
|
39416
|
+
};
|
|
39417
|
+
}
|
|
39418
|
+
function normalizeFormulaRangeLabel(fromLabel, toLabel) {
|
|
39419
|
+
return fromLabel === toLabel ? fromLabel : `${fromLabel}:${toLabel}`;
|
|
39420
|
+
}
|
|
39421
|
+
function replacePickedLabel(view, pickState, nextLabel, currentCell) {
|
|
39422
|
+
if (nextLabel === pickState.currentLabel && currentCell === pickState.currentCell) return pickState;
|
|
39423
|
+
if (nextLabel === pickState.currentLabel) {
|
|
39424
|
+
return {
|
|
39425
|
+
...pickState,
|
|
39426
|
+
currentCell
|
|
39427
|
+
};
|
|
39428
|
+
}
|
|
39429
|
+
let tr = view.state.tr.insertText(nextLabel, pickState.insertedFrom, pickState.insertedTo);
|
|
39430
|
+
const nextTo = pickState.insertedFrom + nextLabel.length;
|
|
39431
|
+
tr = tr.setSelection(import_state9.TextSelection.create(tr.doc, nextTo));
|
|
39432
|
+
view.dispatch(tr);
|
|
39433
|
+
return {
|
|
39434
|
+
...pickState,
|
|
39435
|
+
insertedTo: nextTo,
|
|
39436
|
+
currentLabel: nextLabel,
|
|
39437
|
+
currentCell
|
|
39438
|
+
};
|
|
39439
|
+
}
|
|
39440
|
+
function beginFormulaRangePick(view, event) {
|
|
39441
|
+
if (event.button !== 0) return null;
|
|
39442
|
+
const formulaCell = findSelectionFormulaCell(view);
|
|
39443
|
+
if (!formulaCell) return null;
|
|
39444
|
+
const picked = getPickedCellLabel(view, event.target, formulaCell.tablePos);
|
|
39445
|
+
if (!picked || picked.cell === formulaCell.cellDom) return null;
|
|
39446
|
+
const { from, to } = view.state.selection;
|
|
39447
|
+
let tr = view.state.tr.insertText(picked.label, from, to);
|
|
39448
|
+
tr = tr.setSelection(import_state9.TextSelection.create(tr.doc, from + picked.label.length));
|
|
39449
|
+
view.dispatch(tr);
|
|
39450
|
+
view.focus();
|
|
39451
|
+
event.preventDefault();
|
|
39452
|
+
event.stopPropagation();
|
|
39453
|
+
return {
|
|
39454
|
+
anchorLabel: picked.label,
|
|
39455
|
+
anchorCell: picked.cell,
|
|
39456
|
+
tablePos: formulaCell.tablePos,
|
|
39457
|
+
insertedFrom: from,
|
|
39458
|
+
insertedTo: from + picked.label.length,
|
|
39459
|
+
currentLabel: picked.label,
|
|
39460
|
+
currentCell: picked.cell
|
|
39461
|
+
};
|
|
39462
|
+
}
|
|
39463
|
+
function updateFormulaRangePick(view, pickState, event) {
|
|
39464
|
+
const picked = getPickedCellLabel(view, event.target, pickState.tablePos);
|
|
39465
|
+
if (!picked) return pickState;
|
|
39466
|
+
event.preventDefault();
|
|
39467
|
+
event.stopPropagation();
|
|
39468
|
+
return replacePickedLabel(
|
|
39469
|
+
view,
|
|
39470
|
+
pickState,
|
|
39471
|
+
normalizeFormulaRangeLabel(pickState.anchorLabel, picked.label),
|
|
39472
|
+
picked.cell
|
|
39473
|
+
);
|
|
39474
|
+
}
|
|
39475
|
+
function getFormulaRangePickHighlight(container, pickState) {
|
|
39476
|
+
if (!container.contains(pickState.anchorCell) || !container.contains(pickState.currentCell)) return null;
|
|
39477
|
+
const containerRect = container.getBoundingClientRect();
|
|
39478
|
+
const anchorRect = pickState.anchorCell.getBoundingClientRect();
|
|
39479
|
+
const currentRect = pickState.currentCell.getBoundingClientRect();
|
|
39480
|
+
const left = Math.min(anchorRect.left, currentRect.left) - containerRect.left + container.scrollLeft;
|
|
39481
|
+
const top = Math.min(anchorRect.top, currentRect.top) - containerRect.top + container.scrollTop;
|
|
39482
|
+
const right = Math.max(anchorRect.right, currentRect.right) - containerRect.left + container.scrollLeft;
|
|
39483
|
+
const bottom = Math.max(anchorRect.bottom, currentRect.bottom) - containerRect.top + container.scrollTop;
|
|
39484
|
+
return {
|
|
39485
|
+
left,
|
|
39486
|
+
top,
|
|
39487
|
+
width: Math.max(0, right - left),
|
|
39488
|
+
height: Math.max(0, bottom - top)
|
|
39489
|
+
};
|
|
39490
|
+
}
|
|
39491
|
+
|
|
38924
39492
|
// src/components/UEditor/UEditor.tsx
|
|
38925
39493
|
var import_jsx_runtime95 = require("react/jsx-runtime");
|
|
38926
39494
|
var UEditor = import_react71.default.forwardRef(({
|
|
@@ -38965,6 +39533,9 @@ var UEditor = import_react71.default.forwardRef(({
|
|
|
38965
39533
|
const inFlightPrepareRef = (0, import_react71.useRef)(null);
|
|
38966
39534
|
const lastAppliedContentRef = (0, import_react71.useRef)(content ?? "");
|
|
38967
39535
|
const scheduledFormulaRecalculateRef = (0, import_react71.useRef)(false);
|
|
39536
|
+
const formulaRangePickRef = (0, import_react71.useRef)(null);
|
|
39537
|
+
const formulaRangeSurfaceRef = (0, import_react71.useRef)(null);
|
|
39538
|
+
const [formulaRangeHighlight, setFormulaRangeHighlight] = import_react71.default.useState(null);
|
|
38968
39539
|
const scheduleFormulaRecalculate = import_react71.default.useCallback((editor2, options) => {
|
|
38969
39540
|
if (editor2.isDestroyed || scheduledFormulaRecalculateRef.current) return;
|
|
38970
39541
|
if (!options?.force && isEditingTableFormulaText(editor2)) return;
|
|
@@ -38972,7 +39543,7 @@ var UEditor = import_react71.default.forwardRef(({
|
|
|
38972
39543
|
queueMicrotask(() => {
|
|
38973
39544
|
scheduledFormulaRecalculateRef.current = false;
|
|
38974
39545
|
if (!editor2.isDestroyed && (options?.force || !isEditingTableFormulaText(editor2))) {
|
|
38975
|
-
|
|
39546
|
+
recalculateActiveTableFormulas(editor2);
|
|
38976
39547
|
}
|
|
38977
39548
|
});
|
|
38978
39549
|
}, []);
|
|
@@ -39005,6 +39576,10 @@ var UEditor = import_react71.default.forwardRef(({
|
|
|
39005
39576
|
],
|
|
39006
39577
|
[effectivePlaceholder, t, maxCharacters, uploadImage, resolvedUploadFile, imageInsertMode, maxImageFileSize, allowedImageMimeTypes, fallbackToDataUrl, editable, fetchMetadata, extraExtensions]
|
|
39007
39578
|
);
|
|
39579
|
+
const syncFormulaRangeHighlight = import_react71.default.useCallback((pickState) => {
|
|
39580
|
+
const container = formulaRangeSurfaceRef.current;
|
|
39581
|
+
setFormulaRangeHighlight(container && pickState ? getFormulaRangePickHighlight(container, pickState) : null);
|
|
39582
|
+
}, []);
|
|
39008
39583
|
const editor = (0, import_react72.useEditor)({
|
|
39009
39584
|
immediatelyRender: false,
|
|
39010
39585
|
extensions,
|
|
@@ -39013,6 +39588,37 @@ var UEditor = import_react71.default.forwardRef(({
|
|
|
39013
39588
|
autofocus,
|
|
39014
39589
|
editorProps: {
|
|
39015
39590
|
handleDOMEvents: {
|
|
39591
|
+
mousedown: (view, event) => {
|
|
39592
|
+
if (!(event instanceof MouseEvent)) return false;
|
|
39593
|
+
const pickState = beginFormulaRangePick(view, event);
|
|
39594
|
+
if (!pickState) return false;
|
|
39595
|
+
formulaRangePickRef.current = pickState;
|
|
39596
|
+
syncFormulaRangeHighlight(pickState);
|
|
39597
|
+
return true;
|
|
39598
|
+
},
|
|
39599
|
+
mousemove: (view, event) => {
|
|
39600
|
+
if (!(event instanceof MouseEvent)) return false;
|
|
39601
|
+
const pickState = formulaRangePickRef.current;
|
|
39602
|
+
if (!pickState) return false;
|
|
39603
|
+
if (event.buttons === 0) {
|
|
39604
|
+
formulaRangePickRef.current = null;
|
|
39605
|
+
syncFormulaRangeHighlight(null);
|
|
39606
|
+
return false;
|
|
39607
|
+
}
|
|
39608
|
+
const nextPickState = updateFormulaRangePick(view, pickState, event);
|
|
39609
|
+
formulaRangePickRef.current = nextPickState;
|
|
39610
|
+
syncFormulaRangeHighlight(nextPickState);
|
|
39611
|
+
return true;
|
|
39612
|
+
},
|
|
39613
|
+
mouseup: (_view, event) => {
|
|
39614
|
+
if (!(event instanceof MouseEvent)) return false;
|
|
39615
|
+
if (!formulaRangePickRef.current) return false;
|
|
39616
|
+
formulaRangePickRef.current = null;
|
|
39617
|
+
syncFormulaRangeHighlight(null);
|
|
39618
|
+
event.preventDefault();
|
|
39619
|
+
event.stopPropagation();
|
|
39620
|
+
return true;
|
|
39621
|
+
},
|
|
39016
39622
|
keydown: (_view, event) => {
|
|
39017
39623
|
if (!(event instanceof KeyboardEvent)) return false;
|
|
39018
39624
|
if (event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "ArrowUp" || event.key === "ArrowDown") {
|
|
@@ -39178,7 +39784,10 @@ var UEditor = import_react71.default.forwardRef(({
|
|
|
39178
39784
|
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)(
|
|
39179
39785
|
"div",
|
|
39180
39786
|
{
|
|
39181
|
-
ref:
|
|
39787
|
+
ref: (node) => {
|
|
39788
|
+
editorContentRef.current = node;
|
|
39789
|
+
formulaRangeSurfaceRef.current = node;
|
|
39790
|
+
},
|
|
39182
39791
|
className: "relative flex-1 overflow-y-auto",
|
|
39183
39792
|
style: {
|
|
39184
39793
|
minHeight: editable ? minHeight : void 0,
|
|
@@ -39210,6 +39819,20 @@ var UEditor = import_react71.default.forwardRef(({
|
|
|
39210
39819
|
className: "pointer-events-none hidden absolute z-20 rounded-[2px] border-2 border-primary bg-primary/10"
|
|
39211
39820
|
}
|
|
39212
39821
|
),
|
|
39822
|
+
formulaRangeHighlight && /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
39823
|
+
"span",
|
|
39824
|
+
{
|
|
39825
|
+
"aria-hidden": "true",
|
|
39826
|
+
"data-ueditor-formula-range-highlight": "",
|
|
39827
|
+
className: "pointer-events-none absolute z-20 rounded-[2px] border-2 border-primary bg-primary/10",
|
|
39828
|
+
style: {
|
|
39829
|
+
left: formulaRangeHighlight.left,
|
|
39830
|
+
top: formulaRangeHighlight.top,
|
|
39831
|
+
width: formulaRangeHighlight.width,
|
|
39832
|
+
height: formulaRangeHighlight.height
|
|
39833
|
+
}
|
|
39834
|
+
}
|
|
39835
|
+
),
|
|
39213
39836
|
editable && /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(TableControls, { editor, containerRef: editorContentRef }),
|
|
39214
39837
|
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
39215
39838
|
import_react72.EditorContent,
|