@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.js
CHANGED
|
@@ -5856,7 +5856,7 @@ var Modal = ({
|
|
|
5856
5856
|
const modalContent = /* @__PURE__ */ jsxs13(
|
|
5857
5857
|
"div",
|
|
5858
5858
|
{
|
|
5859
|
-
className: cn("fixed inset-0 z-9999 flex items-center justify-center p-4 md:p-6", overlayClassName),
|
|
5859
|
+
className: cn("fixed inset-0 z-[9999] flex items-center justify-center p-4 md:p-6", overlayClassName),
|
|
5860
5860
|
style: { overscrollBehavior: "contain" },
|
|
5861
5861
|
onMouseDown: handleOverlayMouseDown,
|
|
5862
5862
|
onMouseUp: handleOverlayMouseUp,
|
|
@@ -24707,7 +24707,7 @@ function useLocale2() {
|
|
|
24707
24707
|
}
|
|
24708
24708
|
|
|
24709
24709
|
// src/components/UEditor/UEditor.tsx
|
|
24710
|
-
import React83, { useEffect as useEffect38, useImperativeHandle as useImperativeHandle4, useMemo as
|
|
24710
|
+
import React83, { useEffect as useEffect38, useImperativeHandle as useImperativeHandle4, useMemo as useMemo25, useRef as useRef37 } from "react";
|
|
24711
24711
|
import { useEditor, EditorContent } from "@tiptap/react";
|
|
24712
24712
|
|
|
24713
24713
|
// src/components/UEditor/extensions.ts
|
|
@@ -27062,6 +27062,111 @@ import { useEffect as useEffect34, useRef as useRef29, useState as useState44 }
|
|
|
27062
27062
|
import Image4 from "@tiptap/extension-image";
|
|
27063
27063
|
import { mergeAttributes as mergeAttributes4 } from "@tiptap/core";
|
|
27064
27064
|
import { NodeViewWrapper as NodeViewWrapper4, ReactNodeViewRenderer as ReactNodeViewRenderer4 } from "@tiptap/react";
|
|
27065
|
+
|
|
27066
|
+
// src/components/UEditor/table-dom-utils.ts
|
|
27067
|
+
var MIN_TABLE_ROW_HEIGHT = 36;
|
|
27068
|
+
var COLUMN_RESIZE_LINE_THICKNESS = 2;
|
|
27069
|
+
var ROW_RESIZE_LINE_THICKNESS = 2;
|
|
27070
|
+
var UEDITOR_TABLE_LAYOUT_CHANGE_EVENT = "ueditor-table-layout-change";
|
|
27071
|
+
var TABLE_RESIZE_HIT_ZONE = 10;
|
|
27072
|
+
function findTableRowNodeInfo(view, rowElement) {
|
|
27073
|
+
const firstCell = rowElement.querySelector("th,td");
|
|
27074
|
+
if (!firstCell) return null;
|
|
27075
|
+
const cellPos = view.posAtDOM(firstCell, 0);
|
|
27076
|
+
const $pos = view.state.doc.resolve(cellPos);
|
|
27077
|
+
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
27078
|
+
const node = $pos.node(depth);
|
|
27079
|
+
if (node.type.name === "tableRow") {
|
|
27080
|
+
return {
|
|
27081
|
+
pos: $pos.before(depth),
|
|
27082
|
+
node
|
|
27083
|
+
};
|
|
27084
|
+
}
|
|
27085
|
+
}
|
|
27086
|
+
return null;
|
|
27087
|
+
}
|
|
27088
|
+
function resolveEventElement(target) {
|
|
27089
|
+
if (target instanceof Element) return target;
|
|
27090
|
+
if (target instanceof Node) return target.parentElement;
|
|
27091
|
+
return null;
|
|
27092
|
+
}
|
|
27093
|
+
function getSelectionTableCell(view) {
|
|
27094
|
+
const browserSelection = window.getSelection();
|
|
27095
|
+
const anchorElement = resolveEventElement(browserSelection?.anchorNode ?? null);
|
|
27096
|
+
const anchorCell = anchorElement?.closest?.("th,td");
|
|
27097
|
+
if (anchorCell instanceof HTMLElement) {
|
|
27098
|
+
return anchorCell;
|
|
27099
|
+
}
|
|
27100
|
+
const { from } = view.state.selection;
|
|
27101
|
+
const domAtPos = view.domAtPos(from);
|
|
27102
|
+
const element = resolveEventElement(domAtPos.node);
|
|
27103
|
+
const cell = element?.closest?.("th,td");
|
|
27104
|
+
return cell instanceof HTMLElement ? cell : null;
|
|
27105
|
+
}
|
|
27106
|
+
function isRowResizeHotspot(cell, clientX, clientY) {
|
|
27107
|
+
const rect = cell.getBoundingClientRect();
|
|
27108
|
+
const nearBottom = rect.bottom - clientY <= TABLE_RESIZE_HIT_ZONE;
|
|
27109
|
+
const nearRight = rect.right - clientX <= TABLE_RESIZE_HIT_ZONE;
|
|
27110
|
+
return nearBottom && !nearRight;
|
|
27111
|
+
}
|
|
27112
|
+
function isColumnResizeHotspot(cell, clientX, clientY) {
|
|
27113
|
+
const rect = cell.getBoundingClientRect();
|
|
27114
|
+
const nearRight = rect.right - clientX <= TABLE_RESIZE_HIT_ZONE;
|
|
27115
|
+
const nearBottom = rect.bottom - clientY <= TABLE_RESIZE_HIT_ZONE;
|
|
27116
|
+
return nearRight && !nearBottom;
|
|
27117
|
+
}
|
|
27118
|
+
function getRelativeBoundaryMetrics(surface, table, row, cell) {
|
|
27119
|
+
const surfaceRect = surface.getBoundingClientRect();
|
|
27120
|
+
const tableRect = table.getBoundingClientRect();
|
|
27121
|
+
const rowRect = row.getBoundingClientRect();
|
|
27122
|
+
const cellRect = cell.getBoundingClientRect();
|
|
27123
|
+
return {
|
|
27124
|
+
left: tableRect.left - surfaceRect.left + surface.scrollLeft,
|
|
27125
|
+
top: tableRect.top - surfaceRect.top + surface.scrollTop,
|
|
27126
|
+
width: tableRect.width,
|
|
27127
|
+
height: tableRect.height,
|
|
27128
|
+
rowBottom: rowRect.bottom - surfaceRect.top + surface.scrollTop,
|
|
27129
|
+
columnRight: cellRect.right - surfaceRect.left + surface.scrollLeft
|
|
27130
|
+
};
|
|
27131
|
+
}
|
|
27132
|
+
function getRelativeCellMetrics(surface, cell) {
|
|
27133
|
+
const surfaceRect = surface.getBoundingClientRect();
|
|
27134
|
+
const cellRect = cell.getBoundingClientRect();
|
|
27135
|
+
return {
|
|
27136
|
+
left: cellRect.left - surfaceRect.left + surface.scrollLeft,
|
|
27137
|
+
top: cellRect.top - surfaceRect.top + surface.scrollTop,
|
|
27138
|
+
width: cellRect.width,
|
|
27139
|
+
height: cellRect.height
|
|
27140
|
+
};
|
|
27141
|
+
}
|
|
27142
|
+
function getRelativeSelectedCellsMetrics(surface) {
|
|
27143
|
+
const selectedCells = Array.from(
|
|
27144
|
+
surface.querySelectorAll("td.selectedCell, th.selectedCell")
|
|
27145
|
+
);
|
|
27146
|
+
if (selectedCells.length === 0) {
|
|
27147
|
+
return null;
|
|
27148
|
+
}
|
|
27149
|
+
const surfaceRect = surface.getBoundingClientRect();
|
|
27150
|
+
let left = Number.POSITIVE_INFINITY;
|
|
27151
|
+
let top = Number.POSITIVE_INFINITY;
|
|
27152
|
+
let right = Number.NEGATIVE_INFINITY;
|
|
27153
|
+
let bottom = Number.NEGATIVE_INFINITY;
|
|
27154
|
+
selectedCells.forEach((cell) => {
|
|
27155
|
+
const rect = cell.getBoundingClientRect();
|
|
27156
|
+
left = Math.min(left, rect.left);
|
|
27157
|
+
top = Math.min(top, rect.top);
|
|
27158
|
+
right = Math.max(right, rect.right);
|
|
27159
|
+
bottom = Math.max(bottom, rect.bottom);
|
|
27160
|
+
});
|
|
27161
|
+
return {
|
|
27162
|
+
left: left - surfaceRect.left + surface.scrollLeft,
|
|
27163
|
+
top: top - surfaceRect.top + surface.scrollTop,
|
|
27164
|
+
width: right - left,
|
|
27165
|
+
height: bottom - top
|
|
27166
|
+
};
|
|
27167
|
+
}
|
|
27168
|
+
|
|
27169
|
+
// src/components/UEditor/resizable-image.tsx
|
|
27065
27170
|
import { jsx as jsx82, jsxs as jsxs68 } from "react/jsx-runtime";
|
|
27066
27171
|
var MIN_IMAGE_SIZE_PX = 40;
|
|
27067
27172
|
var IMAGE_LAYOUTS = /* @__PURE__ */ new Set(["block", "left", "right"]);
|
|
@@ -27143,6 +27248,7 @@ function ResizableImageNodeView(props) {
|
|
|
27143
27248
|
const { node, selected, updateAttributes, editor, getPos } = props;
|
|
27144
27249
|
const wrapperRef = useRef29(null);
|
|
27145
27250
|
const imgRef = useRef29(null);
|
|
27251
|
+
const resizePreviewRef = useRef29(null);
|
|
27146
27252
|
const [isHovered, setIsHovered] = useState44(false);
|
|
27147
27253
|
const [isResizing, setIsResizing] = useState44(false);
|
|
27148
27254
|
const widthAttr = toNullableNumber(node.attrs["width"]);
|
|
@@ -27150,11 +27256,59 @@ function ResizableImageNodeView(props) {
|
|
|
27150
27256
|
const textAlign = String(node.attrs["textAlign"] ?? "");
|
|
27151
27257
|
const imageLayout = parseImageLayout(node.attrs["imageLayout"]);
|
|
27152
27258
|
const dragStateRef = useRef29(null);
|
|
27259
|
+
const dispatchTableLayoutChange2 = () => {
|
|
27260
|
+
editor.view.dom.dispatchEvent(new CustomEvent(UEDITOR_TABLE_LAYOUT_CHANGE_EVENT, { bubbles: true }));
|
|
27261
|
+
};
|
|
27262
|
+
const getImageDisplayStyle = (width, height) => ({
|
|
27263
|
+
width: width ? `${width}px` : void 0,
|
|
27264
|
+
height: width && height ? "auto" : height ? `${height}px` : void 0,
|
|
27265
|
+
aspectRatio: width && height ? `${width} / ${height}` : void 0
|
|
27266
|
+
});
|
|
27267
|
+
const setResizePreviewStyle = (width, height, visible, resetBase = false) => {
|
|
27268
|
+
const preview = resizePreviewRef.current;
|
|
27269
|
+
if (!preview) return;
|
|
27270
|
+
const drag = dragStateRef.current;
|
|
27271
|
+
const baseW = resetBase || !drag ? Math.max(MIN_IMAGE_SIZE_PX, Math.round(width)) : drag.previewBaseW;
|
|
27272
|
+
const baseH = resetBase || !drag ? Math.max(MIN_IMAGE_SIZE_PX, Math.round(height)) : drag.previewBaseH;
|
|
27273
|
+
const scaleX = width / baseW;
|
|
27274
|
+
const scaleY = height / baseH;
|
|
27275
|
+
if (resetBase) {
|
|
27276
|
+
preview.style.width = `${baseW}px`;
|
|
27277
|
+
preview.style.height = `${baseH}px`;
|
|
27278
|
+
}
|
|
27279
|
+
preview.style.maxWidth = "none";
|
|
27280
|
+
preview.style.maxHeight = "none";
|
|
27281
|
+
preview.style.transform = visible ? `translateZ(0) scale(${scaleX}, ${scaleY})` : "translateZ(0) scale(1)";
|
|
27282
|
+
preview.style.display = visible ? "block" : "none";
|
|
27283
|
+
};
|
|
27284
|
+
const applyPendingResizeFrame = () => {
|
|
27285
|
+
const drag = dragStateRef.current;
|
|
27286
|
+
if (!drag) return;
|
|
27287
|
+
drag.frameId = null;
|
|
27288
|
+
setResizePreviewStyle(drag.pendingW, drag.pendingH, true);
|
|
27289
|
+
};
|
|
27290
|
+
const scheduleResizeFrame = () => {
|
|
27291
|
+
const drag = dragStateRef.current;
|
|
27292
|
+
if (!drag || drag.frameId !== null) return;
|
|
27293
|
+
drag.frameId = window.requestAnimationFrame(applyPendingResizeFrame);
|
|
27294
|
+
};
|
|
27295
|
+
useEffect34(() => {
|
|
27296
|
+
return () => {
|
|
27297
|
+
const drag = dragStateRef.current;
|
|
27298
|
+
if (drag && drag.frameId !== null) {
|
|
27299
|
+
window.cancelAnimationFrame(drag.frameId);
|
|
27300
|
+
}
|
|
27301
|
+
dragStateRef.current = null;
|
|
27302
|
+
document.body.style.cursor = "";
|
|
27303
|
+
};
|
|
27304
|
+
}, []);
|
|
27153
27305
|
useEffect34(() => {
|
|
27154
27306
|
const img = imgRef.current;
|
|
27155
27307
|
if (!img) return;
|
|
27156
|
-
|
|
27157
|
-
img.style.
|
|
27308
|
+
const displayStyle = getImageDisplayStyle(widthAttr, heightAttr);
|
|
27309
|
+
img.style.width = typeof displayStyle.width === "string" ? displayStyle.width : "";
|
|
27310
|
+
img.style.height = typeof displayStyle.height === "string" ? displayStyle.height : "";
|
|
27311
|
+
img.style.aspectRatio = typeof displayStyle.aspectRatio === "string" ? displayStyle.aspectRatio : "";
|
|
27158
27312
|
}, [widthAttr, heightAttr]);
|
|
27159
27313
|
const selectNode = () => {
|
|
27160
27314
|
const pos = typeof getPos === "function" ? getPos() : null;
|
|
@@ -27185,12 +27339,17 @@ function ResizableImageNodeView(props) {
|
|
|
27185
27339
|
startY: event.clientY,
|
|
27186
27340
|
startW,
|
|
27187
27341
|
startH,
|
|
27188
|
-
lastW: startW,
|
|
27189
|
-
lastH: startH,
|
|
27190
27342
|
aspect,
|
|
27191
|
-
maxW: Math.max(MIN_IMAGE_SIZE_PX, maxW)
|
|
27343
|
+
maxW: Math.max(MIN_IMAGE_SIZE_PX, maxW),
|
|
27344
|
+
previewBaseW: Math.max(MIN_IMAGE_SIZE_PX, Math.round(startW)),
|
|
27345
|
+
previewBaseH: Math.max(MIN_IMAGE_SIZE_PX, Math.round(startH)),
|
|
27346
|
+
pendingW: startW,
|
|
27347
|
+
pendingH: startH,
|
|
27348
|
+
frameId: null
|
|
27192
27349
|
};
|
|
27193
27350
|
setIsResizing(true);
|
|
27351
|
+
setResizePreviewStyle(startW, startH, true, true);
|
|
27352
|
+
document.body.style.cursor = "nwse-resize";
|
|
27194
27353
|
event.currentTarget.setPointerCapture(event.pointerId);
|
|
27195
27354
|
};
|
|
27196
27355
|
const onResizePointerMove = (event) => {
|
|
@@ -27203,19 +27362,33 @@ function ResizableImageNodeView(props) {
|
|
|
27203
27362
|
const nextSize = Math.abs(dx) >= Math.abs(dy) ? sizeFromWidth(drag.startW + dx, drag.aspect, drag.maxW) : sizeFromHeight(drag.startH + dy, drag.aspect, drag.maxW);
|
|
27204
27363
|
const nextW = nextSize.width;
|
|
27205
27364
|
const nextH = nextSize.height;
|
|
27206
|
-
drag.
|
|
27207
|
-
drag.
|
|
27208
|
-
|
|
27209
|
-
img.style.height = `${Math.round(nextH)}px`;
|
|
27365
|
+
drag.pendingW = nextW;
|
|
27366
|
+
drag.pendingH = nextH;
|
|
27367
|
+
scheduleResizeFrame();
|
|
27210
27368
|
};
|
|
27211
27369
|
const finishResize = () => {
|
|
27212
27370
|
const drag = dragStateRef.current;
|
|
27213
27371
|
dragStateRef.current = null;
|
|
27214
27372
|
setIsResizing(false);
|
|
27373
|
+
document.body.style.cursor = "";
|
|
27215
27374
|
if (!drag) return;
|
|
27375
|
+
if (drag.frameId !== null) {
|
|
27376
|
+
window.cancelAnimationFrame(drag.frameId);
|
|
27377
|
+
drag.frameId = null;
|
|
27378
|
+
}
|
|
27379
|
+
const img = imgRef.current;
|
|
27380
|
+
const nextW = Math.round(drag.pendingW);
|
|
27381
|
+
const nextH = Math.round(drag.pendingH);
|
|
27382
|
+
setResizePreviewStyle(nextW, nextH, false);
|
|
27383
|
+
if (img) {
|
|
27384
|
+
img.style.width = `${nextW}px`;
|
|
27385
|
+
img.style.height = "auto";
|
|
27386
|
+
img.style.aspectRatio = `${nextW} / ${nextH}`;
|
|
27387
|
+
}
|
|
27388
|
+
dispatchTableLayoutChange2();
|
|
27216
27389
|
updateAttributes({
|
|
27217
|
-
width:
|
|
27218
|
-
height:
|
|
27390
|
+
width: nextW,
|
|
27391
|
+
height: nextH,
|
|
27219
27392
|
imageWidthPreset: null
|
|
27220
27393
|
});
|
|
27221
27394
|
};
|
|
@@ -27264,9 +27437,30 @@ function ResizableImageNodeView(props) {
|
|
|
27264
27437
|
selected ? "ring-2 ring-primary/60 ring-offset-2 ring-offset-background" : "",
|
|
27265
27438
|
isResizing ? "select-none" : ""
|
|
27266
27439
|
].join(" "),
|
|
27440
|
+
style: getImageDisplayStyle(widthAttr, heightAttr)
|
|
27441
|
+
}
|
|
27442
|
+
),
|
|
27443
|
+
/* @__PURE__ */ jsx82(
|
|
27444
|
+
"div",
|
|
27445
|
+
{
|
|
27446
|
+
ref: resizePreviewRef,
|
|
27447
|
+
"aria-hidden": "true",
|
|
27448
|
+
"data-ueditor-image-resize-preview": "",
|
|
27449
|
+
className: [
|
|
27450
|
+
"pointer-events-none absolute left-0 top-0 z-20 hidden rounded-lg",
|
|
27451
|
+
"border border-primary/70 bg-background/30 bg-center bg-no-repeat bg-[length:100%_100%]",
|
|
27452
|
+
"opacity-45 shadow-md ring-2 ring-primary/25 will-change-transform",
|
|
27453
|
+
"select-none"
|
|
27454
|
+
].join(" "),
|
|
27267
27455
|
style: {
|
|
27268
27456
|
width: widthAttr ? `${widthAttr}px` : void 0,
|
|
27269
|
-
height: heightAttr ? `${heightAttr}px` : void 0
|
|
27457
|
+
height: heightAttr ? `${heightAttr}px` : void 0,
|
|
27458
|
+
maxWidth: "none",
|
|
27459
|
+
maxHeight: "none",
|
|
27460
|
+
backgroundImage: `url("${String(node.attrs["src"] ?? "").replace(/"/g, "%22")}")`,
|
|
27461
|
+
transform: "translateZ(0) scale(1)",
|
|
27462
|
+
transformOrigin: "top left",
|
|
27463
|
+
display: isResizing ? "block" : "none"
|
|
27270
27464
|
}
|
|
27271
27465
|
}
|
|
27272
27466
|
),
|
|
@@ -27274,6 +27468,7 @@ function ResizableImageNodeView(props) {
|
|
|
27274
27468
|
"div",
|
|
27275
27469
|
{
|
|
27276
27470
|
"aria-hidden": "true",
|
|
27471
|
+
"data-ueditor-image-resize-handle": "",
|
|
27277
27472
|
onPointerDown: onResizePointerDown,
|
|
27278
27473
|
onPointerMove: onResizePointerMove,
|
|
27279
27474
|
onPointerUp: onResizePointerUp,
|
|
@@ -27530,109 +27725,6 @@ var letter_spacing_default = LetterSpacing;
|
|
|
27530
27725
|
import { Table as Table3 } from "@tiptap/extension-table";
|
|
27531
27726
|
import { Plugin as Plugin4 } from "@tiptap/pm/state";
|
|
27532
27727
|
|
|
27533
|
-
// src/components/UEditor/table-dom-utils.ts
|
|
27534
|
-
var MIN_TABLE_ROW_HEIGHT = 36;
|
|
27535
|
-
var COLUMN_RESIZE_LINE_THICKNESS = 2;
|
|
27536
|
-
var ROW_RESIZE_LINE_THICKNESS = 2;
|
|
27537
|
-
var UEDITOR_TABLE_LAYOUT_CHANGE_EVENT = "ueditor-table-layout-change";
|
|
27538
|
-
var TABLE_RESIZE_HIT_ZONE = 10;
|
|
27539
|
-
function findTableRowNodeInfo(view, rowElement) {
|
|
27540
|
-
const firstCell = rowElement.querySelector("th,td");
|
|
27541
|
-
if (!firstCell) return null;
|
|
27542
|
-
const cellPos = view.posAtDOM(firstCell, 0);
|
|
27543
|
-
const $pos = view.state.doc.resolve(cellPos);
|
|
27544
|
-
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
27545
|
-
const node = $pos.node(depth);
|
|
27546
|
-
if (node.type.name === "tableRow") {
|
|
27547
|
-
return {
|
|
27548
|
-
pos: $pos.before(depth),
|
|
27549
|
-
node
|
|
27550
|
-
};
|
|
27551
|
-
}
|
|
27552
|
-
}
|
|
27553
|
-
return null;
|
|
27554
|
-
}
|
|
27555
|
-
function resolveEventElement(target) {
|
|
27556
|
-
if (target instanceof Element) return target;
|
|
27557
|
-
if (target instanceof Node) return target.parentElement;
|
|
27558
|
-
return null;
|
|
27559
|
-
}
|
|
27560
|
-
function getSelectionTableCell(view) {
|
|
27561
|
-
const browserSelection = window.getSelection();
|
|
27562
|
-
const anchorElement = resolveEventElement(browserSelection?.anchorNode ?? null);
|
|
27563
|
-
const anchorCell = anchorElement?.closest?.("th,td");
|
|
27564
|
-
if (anchorCell instanceof HTMLElement) {
|
|
27565
|
-
return anchorCell;
|
|
27566
|
-
}
|
|
27567
|
-
const { from } = view.state.selection;
|
|
27568
|
-
const domAtPos = view.domAtPos(from);
|
|
27569
|
-
const element = resolveEventElement(domAtPos.node);
|
|
27570
|
-
const cell = element?.closest?.("th,td");
|
|
27571
|
-
return cell instanceof HTMLElement ? cell : null;
|
|
27572
|
-
}
|
|
27573
|
-
function isRowResizeHotspot(cell, clientX, clientY) {
|
|
27574
|
-
const rect = cell.getBoundingClientRect();
|
|
27575
|
-
const nearBottom = rect.bottom - clientY <= TABLE_RESIZE_HIT_ZONE;
|
|
27576
|
-
const nearRight = rect.right - clientX <= TABLE_RESIZE_HIT_ZONE;
|
|
27577
|
-
return nearBottom && !nearRight;
|
|
27578
|
-
}
|
|
27579
|
-
function isColumnResizeHotspot(cell, clientX, clientY) {
|
|
27580
|
-
const rect = cell.getBoundingClientRect();
|
|
27581
|
-
const nearRight = rect.right - clientX <= TABLE_RESIZE_HIT_ZONE;
|
|
27582
|
-
const nearBottom = rect.bottom - clientY <= TABLE_RESIZE_HIT_ZONE;
|
|
27583
|
-
return nearRight && !nearBottom;
|
|
27584
|
-
}
|
|
27585
|
-
function getRelativeBoundaryMetrics(surface, table, row, cell) {
|
|
27586
|
-
const surfaceRect = surface.getBoundingClientRect();
|
|
27587
|
-
const tableRect = table.getBoundingClientRect();
|
|
27588
|
-
const rowRect = row.getBoundingClientRect();
|
|
27589
|
-
const cellRect = cell.getBoundingClientRect();
|
|
27590
|
-
return {
|
|
27591
|
-
left: tableRect.left - surfaceRect.left + surface.scrollLeft,
|
|
27592
|
-
top: tableRect.top - surfaceRect.top + surface.scrollTop,
|
|
27593
|
-
width: tableRect.width,
|
|
27594
|
-
height: tableRect.height,
|
|
27595
|
-
rowBottom: rowRect.bottom - surfaceRect.top + surface.scrollTop,
|
|
27596
|
-
columnRight: cellRect.right - surfaceRect.left + surface.scrollLeft
|
|
27597
|
-
};
|
|
27598
|
-
}
|
|
27599
|
-
function getRelativeCellMetrics(surface, cell) {
|
|
27600
|
-
const surfaceRect = surface.getBoundingClientRect();
|
|
27601
|
-
const cellRect = cell.getBoundingClientRect();
|
|
27602
|
-
return {
|
|
27603
|
-
left: cellRect.left - surfaceRect.left + surface.scrollLeft,
|
|
27604
|
-
top: cellRect.top - surfaceRect.top + surface.scrollTop,
|
|
27605
|
-
width: cellRect.width,
|
|
27606
|
-
height: cellRect.height
|
|
27607
|
-
};
|
|
27608
|
-
}
|
|
27609
|
-
function getRelativeSelectedCellsMetrics(surface) {
|
|
27610
|
-
const selectedCells = Array.from(
|
|
27611
|
-
surface.querySelectorAll("td.selectedCell, th.selectedCell")
|
|
27612
|
-
);
|
|
27613
|
-
if (selectedCells.length === 0) {
|
|
27614
|
-
return null;
|
|
27615
|
-
}
|
|
27616
|
-
const surfaceRect = surface.getBoundingClientRect();
|
|
27617
|
-
let left = Number.POSITIVE_INFINITY;
|
|
27618
|
-
let top = Number.POSITIVE_INFINITY;
|
|
27619
|
-
let right = Number.NEGATIVE_INFINITY;
|
|
27620
|
-
let bottom = Number.NEGATIVE_INFINITY;
|
|
27621
|
-
selectedCells.forEach((cell) => {
|
|
27622
|
-
const rect = cell.getBoundingClientRect();
|
|
27623
|
-
left = Math.min(left, rect.left);
|
|
27624
|
-
top = Math.min(top, rect.top);
|
|
27625
|
-
right = Math.max(right, rect.right);
|
|
27626
|
-
bottom = Math.max(bottom, rect.bottom);
|
|
27627
|
-
});
|
|
27628
|
-
return {
|
|
27629
|
-
left: left - surfaceRect.left + surface.scrollLeft,
|
|
27630
|
-
top: top - surfaceRect.top + surface.scrollTop,
|
|
27631
|
-
width: right - left,
|
|
27632
|
-
height: bottom - top
|
|
27633
|
-
};
|
|
27634
|
-
}
|
|
27635
|
-
|
|
27636
27728
|
// src/components/UEditor/table-align-utils.ts
|
|
27637
27729
|
function findTableNodeInfoAtResolvedPos($pos) {
|
|
27638
27730
|
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
@@ -28472,6 +28564,9 @@ var HIGHLIGHT_COLOR_SWATCHES = [
|
|
|
28472
28564
|
function buildColorOptions(colors, prefix) {
|
|
28473
28565
|
return colors.map((color, index) => ({ name: `${prefix} ${index + 1}`, color }));
|
|
28474
28566
|
}
|
|
28567
|
+
function getSwatchCheckClass(color) {
|
|
28568
|
+
return /^#(?:fff|ffffff)$/i.test(color) ? "text-foreground" : "text-white drop-shadow-[0_1px_1px_rgba(0,0,0,0.8)]";
|
|
28569
|
+
}
|
|
28475
28570
|
var useEditorColors = () => {
|
|
28476
28571
|
const t = useSmartTranslations("UEditor");
|
|
28477
28572
|
const textColors = useMemo22(
|
|
@@ -28546,7 +28641,7 @@ var EditorColorPalette = ({
|
|
|
28546
28641
|
currentColor === c.color ? "border-primary ring-2 ring-primary/25" : "border-border/70"
|
|
28547
28642
|
),
|
|
28548
28643
|
style: { backgroundColor: c.color || "transparent" },
|
|
28549
|
-
children: currentColor === c.color && /* @__PURE__ */ jsx84("span", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx84(Check11, { className: "h-3.5 w-3.5
|
|
28644
|
+
children: currentColor === c.color && /* @__PURE__ */ jsx84("span", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx84(Check11, { className: cn("h-3.5 w-3.5", getSwatchCheckClass(c.color)) }) })
|
|
28550
28645
|
}
|
|
28551
28646
|
) }, `${c.name}-${c.color}`)) }),
|
|
28552
28647
|
/* @__PURE__ */ jsxs70(
|
|
@@ -28861,6 +28956,20 @@ function createEmptyCellNode(cellNode) {
|
|
|
28861
28956
|
function createCellCopyForColumnDuplicate(cellNode) {
|
|
28862
28957
|
return cellNode.type.create(cellNode.attrs, cellNode.content);
|
|
28863
28958
|
}
|
|
28959
|
+
function createCellWithDuplicatedLogicalColumn(cellNode, widthIndex) {
|
|
28960
|
+
const colspan = Math.max(1, Number(cellNode.attrs.colspan) || 1);
|
|
28961
|
+
let nextColwidth = null;
|
|
28962
|
+
if (Array.isArray(cellNode.attrs.colwidth)) {
|
|
28963
|
+
nextColwidth = [...cellNode.attrs.colwidth];
|
|
28964
|
+
const duplicateWidth = nextColwidth[widthIndex];
|
|
28965
|
+
nextColwidth.splice(widthIndex + 1, 0, typeof duplicateWidth === "number" ? duplicateWidth : 0);
|
|
28966
|
+
}
|
|
28967
|
+
return cellNode.type.create({
|
|
28968
|
+
...cellNode.attrs,
|
|
28969
|
+
colspan: colspan + 1,
|
|
28970
|
+
...nextColwidth ? { colwidth: nextColwidth } : null
|
|
28971
|
+
}, cellNode.content);
|
|
28972
|
+
}
|
|
28864
28973
|
function getTableRows(tableNode) {
|
|
28865
28974
|
const rows = [];
|
|
28866
28975
|
tableNode.forEach((rowNode, rowOffset) => {
|
|
@@ -29036,6 +29145,11 @@ function duplicateTableColumnAt(editor, columnIndex, cellPos) {
|
|
|
29036
29145
|
return rect && rect.top === rowIndex && rect.left <= columnIndex && columnIndex < rect.right;
|
|
29037
29146
|
});
|
|
29038
29147
|
if (!sourceCell) return rowInfo.node;
|
|
29148
|
+
const sourceRect = safeFindCell(map, sourceCell.relativePos);
|
|
29149
|
+
if (sourceRect && (sourceRect.left < columnIndex || sourceRect.right > columnIndex + 1)) {
|
|
29150
|
+
cells[sourceCell.index] = createCellWithDuplicatedLogicalColumn(sourceCell.node, columnIndex - sourceRect.left);
|
|
29151
|
+
return rowInfo.node.type.create(rowInfo.node.attrs, cells);
|
|
29152
|
+
}
|
|
29039
29153
|
cells.splice(sourceCell.index + 1, 0, createCellCopyForColumnDuplicate(sourceCell.node));
|
|
29040
29154
|
return rowInfo.node.type.create(rowInfo.node.attrs, cells);
|
|
29041
29155
|
});
|
|
@@ -30357,6 +30471,25 @@ function getTableFormulaRecalculationOrder(graph) {
|
|
|
30357
30471
|
}
|
|
30358
30472
|
return { order, circular };
|
|
30359
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
|
+
}
|
|
30360
30493
|
function evaluateBasicTableFormula(formula, getCellValue) {
|
|
30361
30494
|
const normalized = normalizeTableFormula(formula);
|
|
30362
30495
|
if (!normalized) {
|
|
@@ -30504,10 +30637,19 @@ var FormulaParser = class {
|
|
|
30504
30637
|
const range = parseTableCellRange(token.value);
|
|
30505
30638
|
if (!range) return { value: null, error: "invalid-reference" };
|
|
30506
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
|
+
}
|
|
30507
30645
|
const cellValue = this.readCellNumber(label);
|
|
30508
30646
|
if (cellValue.error) return cellValue;
|
|
30509
30647
|
values.push(cellValue.value);
|
|
30510
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);
|
|
30511
30653
|
} else {
|
|
30512
30654
|
const value = this.parseExpression();
|
|
30513
30655
|
if (value.error) return value;
|
|
@@ -30521,7 +30663,7 @@ var FormulaParser = class {
|
|
|
30521
30663
|
}
|
|
30522
30664
|
return { value: null, error: "invalid-formula" };
|
|
30523
30665
|
}
|
|
30524
|
-
if (values.length === 0) {
|
|
30666
|
+
if (values.length === 0 && name !== "COUNT") {
|
|
30525
30667
|
return { value: null, error: "invalid-formula" };
|
|
30526
30668
|
}
|
|
30527
30669
|
if (name === "SUM") return { value: values.reduce((sum, value) => sum + value, 0), error: null };
|
|
@@ -30539,6 +30681,11 @@ var FormulaParser = class {
|
|
|
30539
30681
|
}
|
|
30540
30682
|
return { value: parsed, error: null };
|
|
30541
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
|
+
}
|
|
30542
30689
|
peekOperator(operators) {
|
|
30543
30690
|
const token = this.tokens[this.index];
|
|
30544
30691
|
return token?.type === "operator" && operators.includes(token.value) ? token : null;
|
|
@@ -30602,6 +30749,41 @@ function getSelectionTableCellNode(editor) {
|
|
|
30602
30749
|
}
|
|
30603
30750
|
return null;
|
|
30604
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(TableMap2.get(tableNode), relativeCellPos);
|
|
30784
|
+
if (!rect) return null;
|
|
30785
|
+
return `${indexToColumnName(rect.left)}${rect.top + 1}`;
|
|
30786
|
+
}
|
|
30605
30787
|
function isEditingTableFormulaText(editor) {
|
|
30606
30788
|
const cellNode = getSelectionTableCellNode(editor);
|
|
30607
30789
|
return Boolean(cellNode && getCellText(cellNode).startsWith("="));
|
|
@@ -30613,20 +30795,6 @@ function createCellDisplayContent(cellNode, displayValue) {
|
|
|
30613
30795
|
}
|
|
30614
30796
|
return [paragraphType.create(null, cellNode.type.schema.text(displayValue))];
|
|
30615
30797
|
}
|
|
30616
|
-
function buildTableValueGetter(tableNode) {
|
|
30617
|
-
const map = TableMap2.get(tableNode);
|
|
30618
|
-
const values = /* @__PURE__ */ new Map();
|
|
30619
|
-
for (const rowInfo of getTableRows2(tableNode)) {
|
|
30620
|
-
for (const entry of rowInfo.cells) {
|
|
30621
|
-
const rect = safeFindCell2(map, entry.relativePos);
|
|
30622
|
-
if (!rect) continue;
|
|
30623
|
-
const label = `${indexToColumnName(rect.left)}${rect.top + 1}`;
|
|
30624
|
-
const computedValue = entry.node.attrs.computedValue;
|
|
30625
|
-
values.set(label, typeof computedValue === "string" && computedValue.trim() ? computedValue : getCellText(entry.node));
|
|
30626
|
-
}
|
|
30627
|
-
}
|
|
30628
|
-
return (label) => values.get(label.toUpperCase());
|
|
30629
|
-
}
|
|
30630
30798
|
function buildTableValueMap(tableNode) {
|
|
30631
30799
|
const map = TableMap2.get(tableNode);
|
|
30632
30800
|
const values = /* @__PURE__ */ new Map();
|
|
@@ -30641,10 +30809,6 @@ function buildTableValueMap(tableNode) {
|
|
|
30641
30809
|
}
|
|
30642
30810
|
return values;
|
|
30643
30811
|
}
|
|
30644
|
-
function getFormulaComputedValue(formula, tableNode) {
|
|
30645
|
-
const result = evaluateBasicTableFormula(formula, buildTableValueGetter(tableNode));
|
|
30646
|
-
return result.error ? `#${result.error.toUpperCase()}` : String(result.value);
|
|
30647
|
-
}
|
|
30648
30812
|
function normalizeFormulaInput(formula) {
|
|
30649
30813
|
const trimmed = formula.trim();
|
|
30650
30814
|
if (!trimmed) return "";
|
|
@@ -30655,19 +30819,19 @@ function setSelectedTableCellFormula(editor, formula) {
|
|
|
30655
30819
|
const { state, view } = editor;
|
|
30656
30820
|
if (!normalized) {
|
|
30657
30821
|
const clearedFormula = setCellAttr("formula", null)(state, view.dispatch.bind(view));
|
|
30658
|
-
const
|
|
30659
|
-
if (clearedFormula ||
|
|
30822
|
+
const clearedValue2 = setCellAttr("computedValue", null)(editor.state, view.dispatch.bind(view));
|
|
30823
|
+
if (clearedFormula || clearedValue2) {
|
|
30824
|
+
recalculateActiveTableFormulas(editor);
|
|
30660
30825
|
view.focus();
|
|
30661
30826
|
dispatchTableLayoutChange(editor);
|
|
30662
30827
|
return true;
|
|
30663
30828
|
}
|
|
30664
30829
|
return false;
|
|
30665
30830
|
}
|
|
30666
|
-
const rect = selectedRect2(state);
|
|
30667
|
-
const computedValue = getFormulaComputedValue(normalized, rect.table);
|
|
30668
30831
|
const appliedFormula = setCellAttr("formula", normalized)(state, view.dispatch.bind(view));
|
|
30669
|
-
const
|
|
30670
|
-
if (appliedFormula ||
|
|
30832
|
+
const clearedValue = setCellAttr("computedValue", null)(editor.state, view.dispatch.bind(view));
|
|
30833
|
+
if (appliedFormula || clearedValue) {
|
|
30834
|
+
recalculateActiveTableFormulas(editor);
|
|
30671
30835
|
view.focus();
|
|
30672
30836
|
dispatchTableLayoutChange(editor);
|
|
30673
30837
|
return true;
|
|
@@ -30749,7 +30913,7 @@ function promoteFormulaTextInTableNode(tableNode) {
|
|
|
30749
30913
|
changed
|
|
30750
30914
|
};
|
|
30751
30915
|
}
|
|
30752
|
-
function recalculateTableNode(tableNode) {
|
|
30916
|
+
function recalculateTableNode(tableNode, options) {
|
|
30753
30917
|
const promoted = promoteFormulaTextInTableNode(tableNode);
|
|
30754
30918
|
tableNode = promoted.tableNode;
|
|
30755
30919
|
const map = TableMap2.get(tableNode);
|
|
@@ -30779,13 +30943,16 @@ function recalculateTableNode(tableNode) {
|
|
|
30779
30943
|
}))
|
|
30780
30944
|
);
|
|
30781
30945
|
const { order, circular } = getTableFormulaRecalculationOrder(graph);
|
|
30946
|
+
const affectedLabels = options?.changedLabels ? getAffectedTableFormulaLabels(graph, options.changedLabels) : null;
|
|
30782
30947
|
const computedValues = /* @__PURE__ */ new Map();
|
|
30783
30948
|
const getCellValue = (label) => values.get(label.toUpperCase());
|
|
30784
30949
|
for (const label of circular) {
|
|
30950
|
+
if (affectedLabels && !affectedLabels.has(label)) continue;
|
|
30785
30951
|
computedValues.set(label, formatFormulaError("circular-reference"));
|
|
30786
30952
|
values.set(label, formatFormulaError("circular-reference"));
|
|
30787
30953
|
}
|
|
30788
30954
|
for (const label of order) {
|
|
30955
|
+
if (affectedLabels && !affectedLabels.has(label)) continue;
|
|
30789
30956
|
const entry = formulaEntries.get(label);
|
|
30790
30957
|
if (!entry) continue;
|
|
30791
30958
|
const result = evaluateBasicTableFormula(entry.formula, getCellValue);
|
|
@@ -30830,6 +30997,22 @@ function recalculateSelectedTable(editor) {
|
|
|
30830
30997
|
dispatchTableLayoutChange(editor);
|
|
30831
30998
|
return true;
|
|
30832
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
|
+
}
|
|
30833
31016
|
function recalculateAllTableFormulas(editor) {
|
|
30834
31017
|
const replacements = [];
|
|
30835
31018
|
editor.state.doc.descendants((node, pos) => {
|
|
@@ -30866,9 +31049,41 @@ function applyTableCellBackground(editor, color) {
|
|
|
30866
31049
|
}
|
|
30867
31050
|
editor.chain().focus().setCellAttribute("backgroundColor", value).run();
|
|
30868
31051
|
}
|
|
31052
|
+
function applyTableCellAttribute(editor, name, value, options = {}) {
|
|
31053
|
+
const shouldFocus = options.focus ?? true;
|
|
31054
|
+
const { state, view } = editor;
|
|
31055
|
+
const applied = setCellAttr2(name, value)(state, view.dispatch.bind(view));
|
|
31056
|
+
if (applied) {
|
|
31057
|
+
if (shouldFocus) view.focus();
|
|
31058
|
+
return;
|
|
31059
|
+
}
|
|
31060
|
+
const chain = editor.chain();
|
|
31061
|
+
if (shouldFocus) chain.focus();
|
|
31062
|
+
chain.setCellAttribute(name, value).run();
|
|
31063
|
+
}
|
|
31064
|
+
function BorderStylePreviewIcon({ style }) {
|
|
31065
|
+
const isNone = style === "none";
|
|
31066
|
+
return /* @__PURE__ */ jsx87(
|
|
31067
|
+
"span",
|
|
31068
|
+
{
|
|
31069
|
+
"aria-hidden": "true",
|
|
31070
|
+
className: cn(
|
|
31071
|
+
"relative inline-flex h-4 w-4 shrink-0 rounded-[2px]",
|
|
31072
|
+
isNone ? "border border-border/70 bg-muted/30" : "border text-current"
|
|
31073
|
+
),
|
|
31074
|
+
style: isNone ? void 0 : {
|
|
31075
|
+
borderStyle: style,
|
|
31076
|
+
borderWidth: style === "double" ? 3 : 2
|
|
31077
|
+
},
|
|
31078
|
+
children: isNone && /* @__PURE__ */ jsx87("span", { className: "absolute left-1/2 top-0 h-full w-px -translate-x-1/2 rotate-45 bg-muted-foreground/70" })
|
|
31079
|
+
}
|
|
31080
|
+
);
|
|
31081
|
+
}
|
|
30869
31082
|
var BubbleMenuContent = ({
|
|
30870
31083
|
editor,
|
|
30871
31084
|
onKeepOpenChange,
|
|
31085
|
+
onLinkInputOpenChange,
|
|
31086
|
+
onRequestClose,
|
|
30872
31087
|
fontSizes,
|
|
30873
31088
|
lineHeights,
|
|
30874
31089
|
initialShowLinkInput = false
|
|
@@ -30899,6 +31114,8 @@ var BubbleMenuContent = ({
|
|
|
30899
31114
|
const currentCellBgColor = normalizeStyleValue(editor.getAttributes("tableCell").backgroundColor || editor.getAttributes("tableHeader").backgroundColor) || "";
|
|
30900
31115
|
const currentCellFormula = normalizeStyleValue(editor.getAttributes("tableCell").formula || editor.getAttributes("tableHeader").formula) || "";
|
|
30901
31116
|
const currentCellNumberFormat = normalizeStyleValue(editor.getAttributes("tableCell").numberFormat || editor.getAttributes("tableHeader").numberFormat) || "text";
|
|
31117
|
+
const currentCellBorderStyle = editor.getAttributes("tableCell").borderStyle || editor.getAttributes("tableHeader").borderStyle || "solid";
|
|
31118
|
+
const currentCellBorderWidth = editor.getAttributes("tableCell").borderWidth || editor.getAttributes("tableHeader").borderWidth || "1px";
|
|
30902
31119
|
const isInTable2 = isSelectionInTable(editor.state);
|
|
30903
31120
|
const canMergeCells = isInTable2 && editor.can().mergeCells();
|
|
30904
31121
|
const canSplitCell = isInTable2 && editor.can().splitCell();
|
|
@@ -30912,6 +31129,15 @@ var BubbleMenuContent = ({
|
|
|
30912
31129
|
() => (lineHeights ?? getDefaultLineHeights()).filter((option) => ["1.2", "1.5", "1.75"].includes(option.value)),
|
|
30913
31130
|
[lineHeights]
|
|
30914
31131
|
);
|
|
31132
|
+
const borderColors = useMemo23(
|
|
31133
|
+
() => [
|
|
31134
|
+
highlightColors[0] ?? { name: t("colors.default"), color: "" },
|
|
31135
|
+
{ name: "Black", color: "#000000" },
|
|
31136
|
+
{ name: "White", color: "#ffffff" },
|
|
31137
|
+
...highlightColors.slice(1)
|
|
31138
|
+
],
|
|
31139
|
+
[highlightColors, t]
|
|
31140
|
+
);
|
|
30915
31141
|
useEffect36(() => {
|
|
30916
31142
|
setFontSizeDraft(currentFontSize.replace(/px$/i, ""));
|
|
30917
31143
|
}, [currentFontSize]);
|
|
@@ -30932,7 +31158,55 @@ var BubbleMenuContent = ({
|
|
|
30932
31158
|
};
|
|
30933
31159
|
useEffect36(() => {
|
|
30934
31160
|
onKeepOpenChange?.(showLinkInput);
|
|
30935
|
-
|
|
31161
|
+
onLinkInputOpenChange?.(showLinkInput);
|
|
31162
|
+
}, [onKeepOpenChange, onLinkInputOpenChange, showLinkInput]);
|
|
31163
|
+
useEffect36(() => {
|
|
31164
|
+
onKeepOpenChange?.(Boolean(activeColorPalette));
|
|
31165
|
+
}, [activeColorPalette, onKeepOpenChange]);
|
|
31166
|
+
const closeTransientPanels = useCallback22(() => {
|
|
31167
|
+
setActiveColorPalette(null);
|
|
31168
|
+
setShowLinkInput(false);
|
|
31169
|
+
onKeepOpenChange?.(false);
|
|
31170
|
+
onLinkInputOpenChange?.(false);
|
|
31171
|
+
onRequestClose?.();
|
|
31172
|
+
}, [onKeepOpenChange, onLinkInputOpenChange, onRequestClose]);
|
|
31173
|
+
const applyTableCellAttributeAndClose = useCallback22((name, value) => {
|
|
31174
|
+
applyTableCellAttribute(editor, name, value, { focus: false });
|
|
31175
|
+
closeTransientPanels();
|
|
31176
|
+
}, [closeTransientPanels, editor]);
|
|
31177
|
+
const clearTableCellBorderAndClose = useCallback22(() => {
|
|
31178
|
+
applyTableCellAttribute(editor, "borderColor", null, { focus: false });
|
|
31179
|
+
applyTableCellAttribute(editor, "borderStyle", null, { focus: false });
|
|
31180
|
+
applyTableCellAttribute(editor, "borderWidth", null, { focus: false });
|
|
31181
|
+
closeTransientPanels();
|
|
31182
|
+
}, [closeTransientPanels, editor]);
|
|
31183
|
+
const applyTableCellBorderColorAndClose = useCallback22((color) => {
|
|
31184
|
+
const value = color || null;
|
|
31185
|
+
applyTableCellAttribute(editor, "borderColor", value, { focus: false });
|
|
31186
|
+
closeTransientPanels();
|
|
31187
|
+
}, [closeTransientPanels, editor]);
|
|
31188
|
+
const closeColorPalette = useCallback22(() => {
|
|
31189
|
+
setActiveColorPalette(null);
|
|
31190
|
+
onKeepOpenChange?.(false);
|
|
31191
|
+
}, [onKeepOpenChange]);
|
|
31192
|
+
const applyInlineColorAndClose = useCallback22((color) => {
|
|
31193
|
+
if (activeColorPalette === "text") {
|
|
31194
|
+
if (color === "inherit") {
|
|
31195
|
+
editor.chain().focus().unsetColor().run();
|
|
31196
|
+
} else {
|
|
31197
|
+
editor.chain().focus().setColor(color).run();
|
|
31198
|
+
}
|
|
31199
|
+
} else if (activeColorPalette === "highlight") {
|
|
31200
|
+
if (color === "") {
|
|
31201
|
+
editor.chain().focus().unsetHighlight().run();
|
|
31202
|
+
} else {
|
|
31203
|
+
editor.chain().focus().toggleHighlight({ color }).run();
|
|
31204
|
+
}
|
|
31205
|
+
} else {
|
|
31206
|
+
applyTableCellBackground(editor, color);
|
|
31207
|
+
}
|
|
31208
|
+
closeColorPalette();
|
|
31209
|
+
}, [activeColorPalette, closeColorPalette, editor]);
|
|
30936
31210
|
useEffect36(() => {
|
|
30937
31211
|
if (!showLinkInput) return;
|
|
30938
31212
|
const close2 = () => setShowLinkInput(false);
|
|
@@ -30964,51 +31238,53 @@ var BubbleMenuContent = ({
|
|
|
30964
31238
|
const isTextPalette = activeColorPalette === "text";
|
|
30965
31239
|
const isHighlightPalette = activeColorPalette === "highlight";
|
|
30966
31240
|
if (activeColorPalette === "cell-border") {
|
|
30967
|
-
const currentBorderStyle = editor.getAttributes("tableCell").borderStyle || editor.getAttributes("tableHeader").borderStyle || "solid";
|
|
30968
|
-
const currentBorderWidth = editor.getAttributes("tableCell").borderWidth || editor.getAttributes("tableHeader").borderWidth || "1px";
|
|
30969
31241
|
const currentBorderColor = editor.getAttributes("tableCell").borderColor || editor.getAttributes("tableHeader").borderColor || "currentColor";
|
|
30970
|
-
return /* @__PURE__ */ jsxs73("div", { className: "flex flex-col gap-2 p-2 w-56 text-sm", children: [
|
|
31242
|
+
return /* @__PURE__ */ jsxs73("div", { className: "flex flex-col gap-2 p-2 w-56 text-sm", "data-ueditor-keep-open": true, children: [
|
|
30971
31243
|
/* @__PURE__ */ jsx87("div", { className: "font-semibold text-xs text-muted-foreground uppercase tracking-wider mb-1", children: t("tableMenu.cellBorder") || "Cell Borders" }),
|
|
30972
31244
|
/* @__PURE__ */ jsxs73("div", { className: "flex flex-col gap-1", children: [
|
|
30973
31245
|
/* @__PURE__ */ jsx87("label", { className: "text-xs text-muted-foreground", children: t("tableMenu.borderStyle") || "Border Style" }),
|
|
30974
|
-
/* @__PURE__ */
|
|
30975
|
-
"
|
|
31246
|
+
/* @__PURE__ */ jsx87("div", { className: "grid grid-cols-3 gap-1", role: "group", "aria-label": t("tableMenu.borderStyle") || "Border Style", children: [
|
|
31247
|
+
["solid", "Solid"],
|
|
31248
|
+
["dashed", "Dashed"],
|
|
31249
|
+
["dotted", "Dotted"],
|
|
31250
|
+
["double", "Double"],
|
|
31251
|
+
["none", "None"]
|
|
31252
|
+
].map(([style, label]) => /* @__PURE__ */ jsxs73(
|
|
31253
|
+
"button",
|
|
30976
31254
|
{
|
|
30977
|
-
|
|
30978
|
-
|
|
30979
|
-
|
|
30980
|
-
|
|
30981
|
-
|
|
30982
|
-
|
|
31255
|
+
type: "button",
|
|
31256
|
+
"data-ueditor-close-on-select": true,
|
|
31257
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
31258
|
+
onClick: () => applyTableCellAttributeAndClose("borderStyle", style),
|
|
31259
|
+
className: cn(
|
|
31260
|
+
"inline-flex h-8 items-center justify-center gap-1.5 rounded-md px-2 text-xs font-medium transition-colors hover:bg-muted",
|
|
31261
|
+
currentCellBorderStyle === style ? "bg-primary/10 text-primary" : "bg-muted/40 text-foreground"
|
|
31262
|
+
),
|
|
30983
31263
|
children: [
|
|
30984
|
-
/* @__PURE__ */ jsx87(
|
|
30985
|
-
/* @__PURE__ */ jsx87("
|
|
30986
|
-
/* @__PURE__ */ jsx87("option", { value: "dotted", children: "Dotted" }),
|
|
30987
|
-
/* @__PURE__ */ jsx87("option", { value: "double", children: "Double" }),
|
|
30988
|
-
/* @__PURE__ */ jsx87("option", { value: "none", children: "None" })
|
|
31264
|
+
/* @__PURE__ */ jsx87(BorderStylePreviewIcon, { style }),
|
|
31265
|
+
/* @__PURE__ */ jsx87("span", { children: label })
|
|
30989
31266
|
]
|
|
30990
|
-
}
|
|
30991
|
-
|
|
31267
|
+
},
|
|
31268
|
+
style
|
|
31269
|
+
)) })
|
|
30992
31270
|
] }),
|
|
30993
31271
|
/* @__PURE__ */ jsxs73("div", { className: "flex flex-col gap-1", children: [
|
|
30994
31272
|
/* @__PURE__ */ jsx87("label", { className: "text-xs text-muted-foreground", children: t("tableMenu.borderWidth") || "Border Width" }),
|
|
30995
|
-
/* @__PURE__ */
|
|
30996
|
-
"
|
|
31273
|
+
/* @__PURE__ */ jsx87("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__ */ jsx87(
|
|
31274
|
+
"button",
|
|
30997
31275
|
{
|
|
30998
|
-
|
|
30999
|
-
|
|
31000
|
-
|
|
31001
|
-
|
|
31002
|
-
|
|
31003
|
-
|
|
31004
|
-
|
|
31005
|
-
|
|
31006
|
-
|
|
31007
|
-
|
|
31008
|
-
|
|
31009
|
-
|
|
31010
|
-
}
|
|
31011
|
-
)
|
|
31276
|
+
type: "button",
|
|
31277
|
+
"data-ueditor-close-on-select": true,
|
|
31278
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
31279
|
+
onClick: () => applyTableCellAttributeAndClose("borderWidth", width),
|
|
31280
|
+
className: cn(
|
|
31281
|
+
"h-8 rounded-md px-2 text-xs font-medium transition-colors hover:bg-muted",
|
|
31282
|
+
currentCellBorderWidth === width ? "bg-primary/10 text-primary" : "bg-muted/40 text-foreground"
|
|
31283
|
+
),
|
|
31284
|
+
children: width
|
|
31285
|
+
},
|
|
31286
|
+
width
|
|
31287
|
+
)) })
|
|
31012
31288
|
] }),
|
|
31013
31289
|
/* @__PURE__ */ jsxs73(
|
|
31014
31290
|
"button",
|
|
@@ -31030,70 +31306,36 @@ var BubbleMenuContent = ({
|
|
|
31030
31306
|
]
|
|
31031
31307
|
}
|
|
31032
31308
|
),
|
|
31033
|
-
/* @__PURE__ */
|
|
31034
|
-
|
|
31035
|
-
|
|
31036
|
-
|
|
31037
|
-
|
|
31038
|
-
|
|
31039
|
-
|
|
31040
|
-
|
|
31041
|
-
|
|
31042
|
-
|
|
31043
|
-
children: t("tableMenu.clearBorder") || "Clear Border"
|
|
31044
|
-
}
|
|
31045
|
-
),
|
|
31046
|
-
/* @__PURE__ */ jsx87(
|
|
31047
|
-
"button",
|
|
31048
|
-
{
|
|
31049
|
-
type: "button",
|
|
31050
|
-
onClick: () => setActiveColorPalette(null),
|
|
31051
|
-
className: "text-xs font-medium text-primary hover:underline",
|
|
31052
|
-
children: t("tableMenu.done") || "Done"
|
|
31053
|
-
}
|
|
31054
|
-
)
|
|
31055
|
-
] })
|
|
31309
|
+
/* @__PURE__ */ jsx87("div", { className: "flex items-center justify-between gap-2 mt-2 pt-2 border-t border-border", children: /* @__PURE__ */ jsx87(
|
|
31310
|
+
"button",
|
|
31311
|
+
{
|
|
31312
|
+
type: "button",
|
|
31313
|
+
"data-ueditor-close-on-select": true,
|
|
31314
|
+
onClick: clearTableCellBorderAndClose,
|
|
31315
|
+
className: "text-xs text-destructive hover:underline",
|
|
31316
|
+
children: t("tableMenu.clearBorder") || "Clear Border"
|
|
31317
|
+
}
|
|
31318
|
+
) })
|
|
31056
31319
|
] });
|
|
31057
31320
|
}
|
|
31058
31321
|
if (activeColorPalette === "cell-border-color") {
|
|
31059
31322
|
const currentBorderColor = normalizeStyleValue(editor.getAttributes("tableCell").borderColor || editor.getAttributes("tableHeader").borderColor) || "";
|
|
31060
|
-
return /* @__PURE__ */ jsx87("div", { className: "w-56", children: /* @__PURE__ */ jsx87(
|
|
31323
|
+
return /* @__PURE__ */ jsx87("div", { className: "w-56", "data-ueditor-keep-open": true, children: /* @__PURE__ */ jsx87(
|
|
31061
31324
|
EditorColorPalette,
|
|
31062
31325
|
{
|
|
31063
|
-
colors:
|
|
31326
|
+
colors: borderColors,
|
|
31064
31327
|
currentColor: currentBorderColor,
|
|
31065
|
-
onSelect:
|
|
31066
|
-
const value = color || null;
|
|
31067
|
-
editor.chain().focus().setCellAttribute("borderColor", value).run();
|
|
31068
|
-
setActiveColorPalette("cell-border");
|
|
31069
|
-
},
|
|
31328
|
+
onSelect: applyTableCellBorderColorAndClose,
|
|
31070
31329
|
label: t("tableMenu.borderColor") || "Border Color"
|
|
31071
31330
|
}
|
|
31072
31331
|
) });
|
|
31073
31332
|
}
|
|
31074
|
-
return /* @__PURE__ */ jsx87("div", { className: "w-56", children: /* @__PURE__ */ jsx87(
|
|
31333
|
+
return /* @__PURE__ */ jsx87("div", { className: "w-56", "data-ueditor-keep-open": true, children: /* @__PURE__ */ jsx87(
|
|
31075
31334
|
EditorColorPalette,
|
|
31076
31335
|
{
|
|
31077
31336
|
colors: isTextPalette ? textColors : highlightColors,
|
|
31078
31337
|
currentColor: isTextPalette ? currentTextColor : isHighlightPalette ? currentHighlightColor : currentCellBgColor,
|
|
31079
|
-
onSelect:
|
|
31080
|
-
if (isTextPalette) {
|
|
31081
|
-
if (color === "inherit") {
|
|
31082
|
-
editor.chain().focus().unsetColor().run();
|
|
31083
|
-
} else {
|
|
31084
|
-
editor.chain().focus().setColor(color).run();
|
|
31085
|
-
}
|
|
31086
|
-
} else if (isHighlightPalette) {
|
|
31087
|
-
if (color === "") {
|
|
31088
|
-
editor.chain().focus().unsetHighlight().run();
|
|
31089
|
-
} else {
|
|
31090
|
-
editor.chain().focus().toggleHighlight({ color }).run();
|
|
31091
|
-
}
|
|
31092
|
-
} else {
|
|
31093
|
-
applyTableCellBackground(editor, color);
|
|
31094
|
-
}
|
|
31095
|
-
setActiveColorPalette(null);
|
|
31096
|
-
},
|
|
31338
|
+
onSelect: applyInlineColorAndClose,
|
|
31097
31339
|
label: isTextPalette ? t("colors.textColor") : isHighlightPalette ? t("colors.highlight") : t("tableMenu.cellBackground") || "Cell background"
|
|
31098
31340
|
}
|
|
31099
31341
|
) });
|
|
@@ -31418,6 +31660,9 @@ var BubbleMenuContent = ({
|
|
|
31418
31660
|
/* @__PURE__ */ jsx87(
|
|
31419
31661
|
ToolbarButton,
|
|
31420
31662
|
{
|
|
31663
|
+
onMouseDown: () => {
|
|
31664
|
+
onKeepOpenChange?.(true);
|
|
31665
|
+
},
|
|
31421
31666
|
onClick: () => setActiveColorPalette("cell-border"),
|
|
31422
31667
|
active: Boolean(
|
|
31423
31668
|
editor.getAttributes("tableCell").borderColor || editor.getAttributes("tableHeader").borderColor || editor.getAttributes("tableCell").borderStyle || editor.getAttributes("tableHeader").borderStyle || editor.getAttributes("tableCell").borderWidth || editor.getAttributes("tableHeader").borderWidth
|
|
@@ -31499,14 +31744,27 @@ var CustomBubbleMenu = ({
|
|
|
31499
31744
|
const SHOW_DELAY_MS = 180;
|
|
31500
31745
|
const BUBBLE_MENU_OFFSET = 16;
|
|
31501
31746
|
const [isVisible, setIsVisible] = useState48(false);
|
|
31747
|
+
const [linkInputOpen, setLinkInputOpen] = useState48(false);
|
|
31502
31748
|
const [position, setPosition] = useState48({ top: 0, left: 0 });
|
|
31503
31749
|
const menuRef = useRef33(null);
|
|
31504
31750
|
const keepOpenRef = useRef33(false);
|
|
31505
31751
|
const showTimeoutRef = useRef33(null);
|
|
31752
|
+
const suppressShowUntilRef = useRef33(0);
|
|
31506
31753
|
const setKeepOpen = useCallback22((next) => {
|
|
31507
31754
|
keepOpenRef.current = next;
|
|
31755
|
+
if (!next) setLinkInputOpen(false);
|
|
31508
31756
|
if (next) setIsVisible(true);
|
|
31509
31757
|
}, []);
|
|
31758
|
+
const closeBubbleMenu = useCallback22(() => {
|
|
31759
|
+
suppressShowUntilRef.current = Date.now() + 1e3;
|
|
31760
|
+
keepOpenRef.current = false;
|
|
31761
|
+
setLinkInputOpen(false);
|
|
31762
|
+
setIsVisible(false);
|
|
31763
|
+
if (showTimeoutRef.current) {
|
|
31764
|
+
clearTimeout(showTimeoutRef.current);
|
|
31765
|
+
showTimeoutRef.current = null;
|
|
31766
|
+
}
|
|
31767
|
+
}, []);
|
|
31510
31768
|
useEffect36(() => {
|
|
31511
31769
|
const clearShowTimeout = () => {
|
|
31512
31770
|
if (showTimeoutRef.current) {
|
|
@@ -31518,6 +31776,11 @@ var CustomBubbleMenu = ({
|
|
|
31518
31776
|
const { state, view } = editor;
|
|
31519
31777
|
const { from, to, empty } = state.selection;
|
|
31520
31778
|
const isLinkActive = editor.isActive("link");
|
|
31779
|
+
if (Date.now() < suppressShowUntilRef.current) {
|
|
31780
|
+
clearShowTimeout();
|
|
31781
|
+
setIsVisible(false);
|
|
31782
|
+
return;
|
|
31783
|
+
}
|
|
31521
31784
|
if (!keepOpenRef.current && (empty && !isLinkActive || !view.hasFocus())) {
|
|
31522
31785
|
clearShowTimeout();
|
|
31523
31786
|
setIsVisible(false);
|
|
@@ -31529,6 +31792,11 @@ var CustomBubbleMenu = ({
|
|
|
31529
31792
|
start = view.coordsAtPos(from);
|
|
31530
31793
|
end = view.coordsAtPos(to);
|
|
31531
31794
|
} catch {
|
|
31795
|
+
if (keepOpenRef.current) {
|
|
31796
|
+
clearShowTimeout();
|
|
31797
|
+
setIsVisible(true);
|
|
31798
|
+
return;
|
|
31799
|
+
}
|
|
31532
31800
|
clearShowTimeout();
|
|
31533
31801
|
setIsVisible(false);
|
|
31534
31802
|
return;
|
|
@@ -31586,15 +31854,34 @@ var CustomBubbleMenu = ({
|
|
|
31586
31854
|
left: `${position.left}px`,
|
|
31587
31855
|
transform: "translate(-50%, -100%)"
|
|
31588
31856
|
},
|
|
31589
|
-
onMouseDown: (e) =>
|
|
31590
|
-
|
|
31857
|
+
onMouseDown: (e) => {
|
|
31858
|
+
const target = e.target;
|
|
31859
|
+
if (target?.closest?.("[data-ueditor-close-on-select]")) {
|
|
31860
|
+
keepOpenRef.current = false;
|
|
31861
|
+
} else if (target?.closest?.("[data-ueditor-keep-open]")) {
|
|
31862
|
+
keepOpenRef.current = true;
|
|
31863
|
+
}
|
|
31864
|
+
e.preventDefault();
|
|
31865
|
+
},
|
|
31866
|
+
children: editor.isActive("link") && !keepOpenRef.current && !linkInputOpen ? /* @__PURE__ */ jsx87(
|
|
31867
|
+
LinkPreviewContent,
|
|
31868
|
+
{
|
|
31869
|
+
editor,
|
|
31870
|
+
onEdit: () => {
|
|
31871
|
+
setLinkInputOpen(true);
|
|
31872
|
+
setKeepOpen(true);
|
|
31873
|
+
}
|
|
31874
|
+
}
|
|
31875
|
+
) : /* @__PURE__ */ jsx87(
|
|
31591
31876
|
BubbleMenuContent,
|
|
31592
31877
|
{
|
|
31593
31878
|
editor,
|
|
31594
31879
|
onKeepOpenChange: setKeepOpen,
|
|
31880
|
+
onLinkInputOpenChange: setLinkInputOpen,
|
|
31881
|
+
onRequestClose: closeBubbleMenu,
|
|
31595
31882
|
fontSizes,
|
|
31596
31883
|
lineHeights,
|
|
31597
|
-
initialShowLinkInput:
|
|
31884
|
+
initialShowLinkInput: linkInputOpen
|
|
31598
31885
|
}
|
|
31599
31886
|
)
|
|
31600
31887
|
}
|
|
@@ -38041,6 +38328,7 @@ function useUEditorTableInteractions(editor, editable = true) {
|
|
|
38041
38328
|
proseMirror.addEventListener("keyup", handleSelectionChange);
|
|
38042
38329
|
proseMirror.addEventListener("focusin", handleSelectionChange);
|
|
38043
38330
|
document.addEventListener("selectionchange", handleSelectionChange);
|
|
38331
|
+
surface?.addEventListener(UEDITOR_TABLE_LAYOUT_CHANGE_EVENT, handleActiveCellLayoutChange);
|
|
38044
38332
|
surface?.addEventListener("scroll", handleActiveCellLayoutChange, scrollListenerOptions);
|
|
38045
38333
|
window.addEventListener("resize", handleActiveCellLayoutChange);
|
|
38046
38334
|
document.addEventListener("pointermove", handlePointerMove);
|
|
@@ -38060,6 +38348,7 @@ function useUEditorTableInteractions(editor, editable = true) {
|
|
|
38060
38348
|
proseMirror.removeEventListener("keyup", handleSelectionChange);
|
|
38061
38349
|
proseMirror.removeEventListener("focusin", handleSelectionChange);
|
|
38062
38350
|
document.removeEventListener("selectionchange", handleSelectionChange);
|
|
38351
|
+
surface?.removeEventListener(UEDITOR_TABLE_LAYOUT_CHANGE_EVENT, handleActiveCellLayoutChange);
|
|
38063
38352
|
surface?.removeEventListener("scroll", handleActiveCellLayoutChange, scrollListenerOptions);
|
|
38064
38353
|
window.removeEventListener("resize", handleActiveCellLayoutChange);
|
|
38065
38354
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
@@ -38091,7 +38380,7 @@ function useUEditorTableInteractions(editor, editable = true) {
|
|
|
38091
38380
|
}
|
|
38092
38381
|
|
|
38093
38382
|
// src/components/UEditor/menu-bar.tsx
|
|
38094
|
-
import React82, { useRef as useRef36, useState as useState49 } from "react";
|
|
38383
|
+
import React82, { useMemo as useMemo24, useRef as useRef36, useState as useState49 } from "react";
|
|
38095
38384
|
import { useEditorState as useEditorState3 } from "@tiptap/react";
|
|
38096
38385
|
import {
|
|
38097
38386
|
AlignCenter as AlignCenter4,
|
|
@@ -38122,6 +38411,144 @@ import {
|
|
|
38122
38411
|
Undo as UndoIcon2,
|
|
38123
38412
|
Upload as Upload4
|
|
38124
38413
|
} from "lucide-react";
|
|
38414
|
+
|
|
38415
|
+
// src/components/UEditor/preview-html.ts
|
|
38416
|
+
var DEFAULT_TABLE_COLUMN_WIDTH = 100;
|
|
38417
|
+
var TIPTAP_TABLE_MIN_COLUMN_WIDTH = 25;
|
|
38418
|
+
function parsePixelWidth2(value) {
|
|
38419
|
+
if (!value) return null;
|
|
38420
|
+
const match = String(value).match(/(?:^|[\s:])(\d+(?:\.\d+)?)px\b/i) ?? String(value).match(/^(\d+(?:\.\d+)?)$/);
|
|
38421
|
+
if (!match) return null;
|
|
38422
|
+
const parsed = Number.parseFloat(match[1] ?? match[0]);
|
|
38423
|
+
return Number.isFinite(parsed) && parsed > 0 ? Math.round(parsed) : null;
|
|
38424
|
+
}
|
|
38425
|
+
function parseStyleWidth(style) {
|
|
38426
|
+
return parsePixelWidth2(style.width) ?? parsePixelWidth2(style.minWidth);
|
|
38427
|
+
}
|
|
38428
|
+
function parseStyleHeight(style) {
|
|
38429
|
+
return parsePixelWidth2(style.height) ?? parsePixelWidth2(style.minHeight);
|
|
38430
|
+
}
|
|
38431
|
+
function getCellColspan(cell) {
|
|
38432
|
+
return Math.max(1, cell.colSpan || Number.parseInt(cell.getAttribute("colspan") || "1", 10) || 1);
|
|
38433
|
+
}
|
|
38434
|
+
function getCellWidths(cell) {
|
|
38435
|
+
const dataColwidth = cell.getAttribute("data-colwidth") || cell.getAttribute("colwidth");
|
|
38436
|
+
if (dataColwidth) {
|
|
38437
|
+
const widths = dataColwidth.split(/[,\s]+/).map((part) => parsePixelWidth2(part)).filter((width2) => typeof width2 === "number");
|
|
38438
|
+
if (widths.length > 0) return widths;
|
|
38439
|
+
}
|
|
38440
|
+
const width = parsePixelWidth2(cell.getAttribute("width")) ?? parseStyleWidth(cell.style);
|
|
38441
|
+
if (!width) return null;
|
|
38442
|
+
const colspan = getCellColspan(cell);
|
|
38443
|
+
return Array.from({ length: colspan }, () => Math.max(DEFAULT_TABLE_COLUMN_WIDTH, Math.round(width / colspan)));
|
|
38444
|
+
}
|
|
38445
|
+
function getColumnCount(table) {
|
|
38446
|
+
const colCount = table.querySelectorAll("colgroup > col").length;
|
|
38447
|
+
if (colCount > 0) return colCount;
|
|
38448
|
+
return Math.max(
|
|
38449
|
+
0,
|
|
38450
|
+
...Array.from(table.rows).map(
|
|
38451
|
+
(row) => Array.from(row.cells).reduce((count, cell) => count + getCellColspan(cell), 0)
|
|
38452
|
+
)
|
|
38453
|
+
);
|
|
38454
|
+
}
|
|
38455
|
+
function resolveColumnWidths(table) {
|
|
38456
|
+
const columnCount = getColumnCount(table);
|
|
38457
|
+
if (columnCount <= 0) return [];
|
|
38458
|
+
const widths = Array.from({ length: columnCount }, () => DEFAULT_TABLE_COLUMN_WIDTH);
|
|
38459
|
+
const cols = Array.from(table.querySelectorAll("colgroup > col"));
|
|
38460
|
+
cols.slice(0, columnCount).forEach((col, index) => {
|
|
38461
|
+
const width = parsePixelWidth2(col.getAttribute("width")) ?? parseStyleWidth(col.style);
|
|
38462
|
+
if (width && width > TIPTAP_TABLE_MIN_COLUMN_WIDTH) {
|
|
38463
|
+
widths[index] = width;
|
|
38464
|
+
}
|
|
38465
|
+
});
|
|
38466
|
+
Array.from(table.rows).forEach((row) => {
|
|
38467
|
+
let columnIndex = 0;
|
|
38468
|
+
Array.from(row.cells).forEach((cell) => {
|
|
38469
|
+
const cellWidths = getCellWidths(cell);
|
|
38470
|
+
if (cellWidths) {
|
|
38471
|
+
cellWidths.slice(0, getCellColspan(cell)).forEach((width, offset) => {
|
|
38472
|
+
if (width > TIPTAP_TABLE_MIN_COLUMN_WIDTH && columnIndex + offset < widths.length) {
|
|
38473
|
+
widths[columnIndex + offset] = width;
|
|
38474
|
+
}
|
|
38475
|
+
});
|
|
38476
|
+
}
|
|
38477
|
+
columnIndex += getCellColspan(cell);
|
|
38478
|
+
});
|
|
38479
|
+
});
|
|
38480
|
+
return widths;
|
|
38481
|
+
}
|
|
38482
|
+
function setStyleProperty(element, property, value) {
|
|
38483
|
+
element.style.setProperty(property, value);
|
|
38484
|
+
}
|
|
38485
|
+
function resolveRowHeight(row) {
|
|
38486
|
+
const explicitRowHeight = parsePixelWidth2(row.getAttribute("data-row-height")) ?? parseStyleHeight(row.style);
|
|
38487
|
+
if (explicitRowHeight) return Math.max(MIN_TABLE_ROW_HEIGHT, explicitRowHeight);
|
|
38488
|
+
const cellHeight = Array.from(row.cells).reduce((maxHeight, cell) => {
|
|
38489
|
+
const height = parsePixelWidth2(cell.getAttribute("height")) ?? parseStyleHeight(cell.style);
|
|
38490
|
+
return height ? Math.max(maxHeight, height) : maxHeight;
|
|
38491
|
+
}, 0);
|
|
38492
|
+
return Math.max(MIN_TABLE_ROW_HEIGHT, cellHeight);
|
|
38493
|
+
}
|
|
38494
|
+
function normalizePreviewRowHeight(row) {
|
|
38495
|
+
const rowHeight = resolveRowHeight(row);
|
|
38496
|
+
row.style.height = `${rowHeight}px`;
|
|
38497
|
+
row.style.minHeight = `${rowHeight}px`;
|
|
38498
|
+
Array.from(row.cells).forEach((cell) => {
|
|
38499
|
+
cell.style.height = `${rowHeight}px`;
|
|
38500
|
+
cell.style.minHeight = `${rowHeight}px`;
|
|
38501
|
+
});
|
|
38502
|
+
}
|
|
38503
|
+
function normalizePreviewTable(table) {
|
|
38504
|
+
const widths = resolveColumnWidths(table);
|
|
38505
|
+
if (widths.length === 0) return;
|
|
38506
|
+
let colgroup = table.querySelector("colgroup");
|
|
38507
|
+
if (!colgroup) {
|
|
38508
|
+
colgroup = document.createElement("colgroup");
|
|
38509
|
+
table.insertBefore(colgroup, table.firstChild);
|
|
38510
|
+
}
|
|
38511
|
+
while (colgroup.children.length < widths.length) {
|
|
38512
|
+
colgroup.appendChild(document.createElement("col"));
|
|
38513
|
+
}
|
|
38514
|
+
Array.from(colgroup.children).forEach((child, index) => {
|
|
38515
|
+
if (child.tagName.toLowerCase() !== "col") return;
|
|
38516
|
+
const col = child;
|
|
38517
|
+
if (index >= widths.length) {
|
|
38518
|
+
child.remove();
|
|
38519
|
+
return;
|
|
38520
|
+
}
|
|
38521
|
+
col.style.width = `${widths[index]}px`;
|
|
38522
|
+
col.style.minWidth = `${widths[index]}px`;
|
|
38523
|
+
col.setAttribute("width", String(widths[index]));
|
|
38524
|
+
});
|
|
38525
|
+
const tableWidth = widths.reduce((sum, width) => sum + width, 0);
|
|
38526
|
+
setStyleProperty(table, "width", `${tableWidth}px`);
|
|
38527
|
+
setStyleProperty(table, "min-width", `${tableWidth}px`);
|
|
38528
|
+
setStyleProperty(table, "table-layout", "fixed");
|
|
38529
|
+
Array.from(table.rows).forEach((row) => {
|
|
38530
|
+
let columnIndex = 0;
|
|
38531
|
+
normalizePreviewRowHeight(row);
|
|
38532
|
+
Array.from(row.cells).forEach((cell) => {
|
|
38533
|
+
const colspan = getCellColspan(cell);
|
|
38534
|
+
const cellWidth = widths.slice(columnIndex, columnIndex + colspan).reduce((sum, width) => sum + width, 0);
|
|
38535
|
+
if (cellWidth > 0) {
|
|
38536
|
+
cell.style.width = `${cellWidth}px`;
|
|
38537
|
+
cell.style.minWidth = `${cellWidth}px`;
|
|
38538
|
+
}
|
|
38539
|
+
columnIndex += colspan;
|
|
38540
|
+
});
|
|
38541
|
+
});
|
|
38542
|
+
}
|
|
38543
|
+
function prepareUEditorPreviewHtml(html) {
|
|
38544
|
+
if (typeof document === "undefined" || !html) return html;
|
|
38545
|
+
const container = document.createElement("div");
|
|
38546
|
+
container.innerHTML = html;
|
|
38547
|
+
container.querySelectorAll("table").forEach((table) => normalizePreviewTable(table));
|
|
38548
|
+
return container.innerHTML;
|
|
38549
|
+
}
|
|
38550
|
+
|
|
38551
|
+
// src/components/UEditor/menu-bar.tsx
|
|
38125
38552
|
import { Fragment as Fragment35, jsx as jsx93, jsxs as jsxs78 } from "react/jsx-runtime";
|
|
38126
38553
|
function MenuTableInsertGrid({
|
|
38127
38554
|
insertLabel,
|
|
@@ -38604,6 +39031,10 @@ var MenuBar = ({
|
|
|
38604
39031
|
const [showSourceDialog, setShowSourceDialog] = useState49(false);
|
|
38605
39032
|
const [sourceHtml, setSourceHtml] = useState49("");
|
|
38606
39033
|
const [showPreviewDialog, setShowPreviewDialog] = useState49(false);
|
|
39034
|
+
const previewHtml = useMemo24(
|
|
39035
|
+
() => showPreviewDialog ? prepareUEditorPreviewHtml(editor.getHTML()) : "",
|
|
39036
|
+
[editor, showPreviewDialog]
|
|
39037
|
+
);
|
|
38607
39038
|
const openSourceDialog = () => {
|
|
38608
39039
|
setSourceHtml(editor.getHTML());
|
|
38609
39040
|
setShowSourceDialog(true);
|
|
@@ -38612,10 +39043,7 @@ var MenuBar = ({
|
|
|
38612
39043
|
setShowPreviewDialog(true);
|
|
38613
39044
|
};
|
|
38614
39045
|
const handlePreview = () => {
|
|
38615
|
-
if (onPreview)
|
|
38616
|
-
onPreview();
|
|
38617
|
-
return;
|
|
38618
|
-
}
|
|
39046
|
+
if (onPreview?.(editor.getHTML()) === false) return;
|
|
38619
39047
|
openPreviewDialog();
|
|
38620
39048
|
};
|
|
38621
39049
|
const applySourceHtml = () => {
|
|
@@ -38850,12 +39278,12 @@ var MenuBar = ({
|
|
|
38850
39278
|
"div",
|
|
38851
39279
|
{
|
|
38852
39280
|
"data-testid": "preview-content",
|
|
38853
|
-
className: "min-h-0 flex-1 overflow-y-auto overscroll-contain
|
|
39281
|
+
className: "min-h-0 flex-1 overflow-y-auto overscroll-contain",
|
|
38854
39282
|
children: editor.isEmpty ? /* @__PURE__ */ jsx93("p", { className: "text-muted-foreground text-sm", children: t("menubar.previewEmpty") }) : /* @__PURE__ */ jsx93(
|
|
38855
39283
|
"div",
|
|
38856
39284
|
{
|
|
38857
39285
|
className: UEDITOR_PROSEMIRROR_CLASS_NAME,
|
|
38858
|
-
dangerouslySetInnerHTML: { __html:
|
|
39286
|
+
dangerouslySetInnerHTML: { __html: previewHtml }
|
|
38859
39287
|
}
|
|
38860
39288
|
)
|
|
38861
39289
|
}
|
|
@@ -38865,6 +39293,146 @@ var MenuBar = ({
|
|
|
38865
39293
|
] });
|
|
38866
39294
|
};
|
|
38867
39295
|
|
|
39296
|
+
// src/components/UEditor/table-formula-range-picker.ts
|
|
39297
|
+
import { TextSelection as TextSelection4 } from "@tiptap/pm/state";
|
|
39298
|
+
import { TableMap as TableMap4 } from "@tiptap/pm/tables";
|
|
39299
|
+
function getCellText2(cellNode) {
|
|
39300
|
+
return cellNode.textBetween(0, cellNode.content.size, "\n").trim();
|
|
39301
|
+
}
|
|
39302
|
+
function findSelectionFormulaCell(view) {
|
|
39303
|
+
const { $from } = view.state.selection;
|
|
39304
|
+
for (let depth = $from.depth; depth > 0; depth -= 1) {
|
|
39305
|
+
const node = $from.node(depth);
|
|
39306
|
+
if (node.type.name !== "tableCell" && node.type.name !== "tableHeader") continue;
|
|
39307
|
+
if (!getCellText2(node).startsWith("=")) return null;
|
|
39308
|
+
const cellPos = $from.before(depth);
|
|
39309
|
+
const cellDom = view.nodeDOM(cellPos);
|
|
39310
|
+
const tableDepth = depth - 2;
|
|
39311
|
+
const tableNode = tableDepth > 0 ? $from.node(tableDepth) : null;
|
|
39312
|
+
if (!tableNode || tableNode.type.name !== "table") return null;
|
|
39313
|
+
return {
|
|
39314
|
+
cellDom: cellDom instanceof HTMLTableCellElement ? cellDom : null,
|
|
39315
|
+
tablePos: $from.before(tableDepth)
|
|
39316
|
+
};
|
|
39317
|
+
}
|
|
39318
|
+
return null;
|
|
39319
|
+
}
|
|
39320
|
+
function findTableForPos(view, pos) {
|
|
39321
|
+
const $pos = view.state.doc.resolve(pos);
|
|
39322
|
+
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
39323
|
+
const node = $pos.node(depth);
|
|
39324
|
+
if (node.type.name === "table") {
|
|
39325
|
+
return {
|
|
39326
|
+
node,
|
|
39327
|
+
pos: $pos.before(depth),
|
|
39328
|
+
start: $pos.start(depth)
|
|
39329
|
+
};
|
|
39330
|
+
}
|
|
39331
|
+
}
|
|
39332
|
+
return null;
|
|
39333
|
+
}
|
|
39334
|
+
function getCellRelativePosFromDomPos2(map, tableStart, domPos) {
|
|
39335
|
+
const relativeDomPos = domPos - tableStart;
|
|
39336
|
+
const seen = /* @__PURE__ */ new Set();
|
|
39337
|
+
for (const relativeCellPos of map.map) {
|
|
39338
|
+
if (seen.has(relativeCellPos)) continue;
|
|
39339
|
+
seen.add(relativeCellPos);
|
|
39340
|
+
if (relativeDomPos === relativeCellPos || relativeDomPos === relativeCellPos + 1) {
|
|
39341
|
+
return relativeCellPos;
|
|
39342
|
+
}
|
|
39343
|
+
}
|
|
39344
|
+
return null;
|
|
39345
|
+
}
|
|
39346
|
+
function getPickedCellLabel(view, target, tablePos) {
|
|
39347
|
+
const element = resolveEventElement(target);
|
|
39348
|
+
const cell = element?.closest?.("th,td");
|
|
39349
|
+
if (!(cell instanceof HTMLTableCellElement)) return null;
|
|
39350
|
+
const domPos = view.posAtDOM(cell, 0);
|
|
39351
|
+
const tableInfo = findTableForPos(view, domPos);
|
|
39352
|
+
if (!tableInfo || tableInfo.pos !== tablePos) return null;
|
|
39353
|
+
const map = TableMap4.get(tableInfo.node);
|
|
39354
|
+
const relativeCellPos = getCellRelativePosFromDomPos2(map, tableInfo.start, domPos);
|
|
39355
|
+
if (relativeCellPos == null) return null;
|
|
39356
|
+
const rect = map.findCell(relativeCellPos);
|
|
39357
|
+
return {
|
|
39358
|
+
cell,
|
|
39359
|
+
label: `${indexToColumnName(rect.left)}${rect.top + 1}`
|
|
39360
|
+
};
|
|
39361
|
+
}
|
|
39362
|
+
function normalizeFormulaRangeLabel(fromLabel, toLabel) {
|
|
39363
|
+
return fromLabel === toLabel ? fromLabel : `${fromLabel}:${toLabel}`;
|
|
39364
|
+
}
|
|
39365
|
+
function replacePickedLabel(view, pickState, nextLabel, currentCell) {
|
|
39366
|
+
if (nextLabel === pickState.currentLabel && currentCell === pickState.currentCell) return pickState;
|
|
39367
|
+
if (nextLabel === pickState.currentLabel) {
|
|
39368
|
+
return {
|
|
39369
|
+
...pickState,
|
|
39370
|
+
currentCell
|
|
39371
|
+
};
|
|
39372
|
+
}
|
|
39373
|
+
let tr = view.state.tr.insertText(nextLabel, pickState.insertedFrom, pickState.insertedTo);
|
|
39374
|
+
const nextTo = pickState.insertedFrom + nextLabel.length;
|
|
39375
|
+
tr = tr.setSelection(TextSelection4.create(tr.doc, nextTo));
|
|
39376
|
+
view.dispatch(tr);
|
|
39377
|
+
return {
|
|
39378
|
+
...pickState,
|
|
39379
|
+
insertedTo: nextTo,
|
|
39380
|
+
currentLabel: nextLabel,
|
|
39381
|
+
currentCell
|
|
39382
|
+
};
|
|
39383
|
+
}
|
|
39384
|
+
function beginFormulaRangePick(view, event) {
|
|
39385
|
+
if (event.button !== 0) return null;
|
|
39386
|
+
const formulaCell = findSelectionFormulaCell(view);
|
|
39387
|
+
if (!formulaCell) return null;
|
|
39388
|
+
const picked = getPickedCellLabel(view, event.target, formulaCell.tablePos);
|
|
39389
|
+
if (!picked || picked.cell === formulaCell.cellDom) return null;
|
|
39390
|
+
const { from, to } = view.state.selection;
|
|
39391
|
+
let tr = view.state.tr.insertText(picked.label, from, to);
|
|
39392
|
+
tr = tr.setSelection(TextSelection4.create(tr.doc, from + picked.label.length));
|
|
39393
|
+
view.dispatch(tr);
|
|
39394
|
+
view.focus();
|
|
39395
|
+
event.preventDefault();
|
|
39396
|
+
event.stopPropagation();
|
|
39397
|
+
return {
|
|
39398
|
+
anchorLabel: picked.label,
|
|
39399
|
+
anchorCell: picked.cell,
|
|
39400
|
+
tablePos: formulaCell.tablePos,
|
|
39401
|
+
insertedFrom: from,
|
|
39402
|
+
insertedTo: from + picked.label.length,
|
|
39403
|
+
currentLabel: picked.label,
|
|
39404
|
+
currentCell: picked.cell
|
|
39405
|
+
};
|
|
39406
|
+
}
|
|
39407
|
+
function updateFormulaRangePick(view, pickState, event) {
|
|
39408
|
+
const picked = getPickedCellLabel(view, event.target, pickState.tablePos);
|
|
39409
|
+
if (!picked) return pickState;
|
|
39410
|
+
event.preventDefault();
|
|
39411
|
+
event.stopPropagation();
|
|
39412
|
+
return replacePickedLabel(
|
|
39413
|
+
view,
|
|
39414
|
+
pickState,
|
|
39415
|
+
normalizeFormulaRangeLabel(pickState.anchorLabel, picked.label),
|
|
39416
|
+
picked.cell
|
|
39417
|
+
);
|
|
39418
|
+
}
|
|
39419
|
+
function getFormulaRangePickHighlight(container, pickState) {
|
|
39420
|
+
if (!container.contains(pickState.anchorCell) || !container.contains(pickState.currentCell)) return null;
|
|
39421
|
+
const containerRect = container.getBoundingClientRect();
|
|
39422
|
+
const anchorRect = pickState.anchorCell.getBoundingClientRect();
|
|
39423
|
+
const currentRect = pickState.currentCell.getBoundingClientRect();
|
|
39424
|
+
const left = Math.min(anchorRect.left, currentRect.left) - containerRect.left + container.scrollLeft;
|
|
39425
|
+
const top = Math.min(anchorRect.top, currentRect.top) - containerRect.top + container.scrollTop;
|
|
39426
|
+
const right = Math.max(anchorRect.right, currentRect.right) - containerRect.left + container.scrollLeft;
|
|
39427
|
+
const bottom = Math.max(anchorRect.bottom, currentRect.bottom) - containerRect.top + container.scrollTop;
|
|
39428
|
+
return {
|
|
39429
|
+
left,
|
|
39430
|
+
top,
|
|
39431
|
+
width: Math.max(0, right - left),
|
|
39432
|
+
height: Math.max(0, bottom - top)
|
|
39433
|
+
};
|
|
39434
|
+
}
|
|
39435
|
+
|
|
38868
39436
|
// src/components/UEditor/UEditor.tsx
|
|
38869
39437
|
import { jsx as jsx94, jsxs as jsxs79 } from "react/jsx-runtime";
|
|
38870
39438
|
var UEditor = React83.forwardRef(({
|
|
@@ -38909,6 +39477,9 @@ var UEditor = React83.forwardRef(({
|
|
|
38909
39477
|
const inFlightPrepareRef = useRef37(null);
|
|
38910
39478
|
const lastAppliedContentRef = useRef37(content ?? "");
|
|
38911
39479
|
const scheduledFormulaRecalculateRef = useRef37(false);
|
|
39480
|
+
const formulaRangePickRef = useRef37(null);
|
|
39481
|
+
const formulaRangeSurfaceRef = useRef37(null);
|
|
39482
|
+
const [formulaRangeHighlight, setFormulaRangeHighlight] = React83.useState(null);
|
|
38912
39483
|
const scheduleFormulaRecalculate = React83.useCallback((editor2, options) => {
|
|
38913
39484
|
if (editor2.isDestroyed || scheduledFormulaRecalculateRef.current) return;
|
|
38914
39485
|
if (!options?.force && isEditingTableFormulaText(editor2)) return;
|
|
@@ -38916,11 +39487,11 @@ var UEditor = React83.forwardRef(({
|
|
|
38916
39487
|
queueMicrotask(() => {
|
|
38917
39488
|
scheduledFormulaRecalculateRef.current = false;
|
|
38918
39489
|
if (!editor2.isDestroyed && (options?.force || !isEditingTableFormulaText(editor2))) {
|
|
38919
|
-
|
|
39490
|
+
recalculateActiveTableFormulas(editor2);
|
|
38920
39491
|
}
|
|
38921
39492
|
});
|
|
38922
39493
|
}, []);
|
|
38923
|
-
const resolvedUploadFile =
|
|
39494
|
+
const resolvedUploadFile = useMemo25(() => {
|
|
38924
39495
|
if (uploadFile) return uploadFile;
|
|
38925
39496
|
if (uploadFileForSave) {
|
|
38926
39497
|
return async (file) => {
|
|
@@ -38930,7 +39501,7 @@ var UEditor = React83.forwardRef(({
|
|
|
38930
39501
|
}
|
|
38931
39502
|
return uploadImage;
|
|
38932
39503
|
}, [uploadFile, uploadFileForSave, uploadImage]);
|
|
38933
|
-
const extensions =
|
|
39504
|
+
const extensions = useMemo25(
|
|
38934
39505
|
() => [
|
|
38935
39506
|
...buildUEditorExtensions({
|
|
38936
39507
|
placeholder: effectivePlaceholder,
|
|
@@ -38949,6 +39520,10 @@ var UEditor = React83.forwardRef(({
|
|
|
38949
39520
|
],
|
|
38950
39521
|
[effectivePlaceholder, t, maxCharacters, uploadImage, resolvedUploadFile, imageInsertMode, maxImageFileSize, allowedImageMimeTypes, fallbackToDataUrl, editable, fetchMetadata, extraExtensions]
|
|
38951
39522
|
);
|
|
39523
|
+
const syncFormulaRangeHighlight = React83.useCallback((pickState) => {
|
|
39524
|
+
const container = formulaRangeSurfaceRef.current;
|
|
39525
|
+
setFormulaRangeHighlight(container && pickState ? getFormulaRangePickHighlight(container, pickState) : null);
|
|
39526
|
+
}, []);
|
|
38952
39527
|
const editor = useEditor({
|
|
38953
39528
|
immediatelyRender: false,
|
|
38954
39529
|
extensions,
|
|
@@ -38957,6 +39532,37 @@ var UEditor = React83.forwardRef(({
|
|
|
38957
39532
|
autofocus,
|
|
38958
39533
|
editorProps: {
|
|
38959
39534
|
handleDOMEvents: {
|
|
39535
|
+
mousedown: (view, event) => {
|
|
39536
|
+
if (!(event instanceof MouseEvent)) return false;
|
|
39537
|
+
const pickState = beginFormulaRangePick(view, event);
|
|
39538
|
+
if (!pickState) return false;
|
|
39539
|
+
formulaRangePickRef.current = pickState;
|
|
39540
|
+
syncFormulaRangeHighlight(pickState);
|
|
39541
|
+
return true;
|
|
39542
|
+
},
|
|
39543
|
+
mousemove: (view, event) => {
|
|
39544
|
+
if (!(event instanceof MouseEvent)) return false;
|
|
39545
|
+
const pickState = formulaRangePickRef.current;
|
|
39546
|
+
if (!pickState) return false;
|
|
39547
|
+
if (event.buttons === 0) {
|
|
39548
|
+
formulaRangePickRef.current = null;
|
|
39549
|
+
syncFormulaRangeHighlight(null);
|
|
39550
|
+
return false;
|
|
39551
|
+
}
|
|
39552
|
+
const nextPickState = updateFormulaRangePick(view, pickState, event);
|
|
39553
|
+
formulaRangePickRef.current = nextPickState;
|
|
39554
|
+
syncFormulaRangeHighlight(nextPickState);
|
|
39555
|
+
return true;
|
|
39556
|
+
},
|
|
39557
|
+
mouseup: (_view, event) => {
|
|
39558
|
+
if (!(event instanceof MouseEvent)) return false;
|
|
39559
|
+
if (!formulaRangePickRef.current) return false;
|
|
39560
|
+
formulaRangePickRef.current = null;
|
|
39561
|
+
syncFormulaRangeHighlight(null);
|
|
39562
|
+
event.preventDefault();
|
|
39563
|
+
event.stopPropagation();
|
|
39564
|
+
return true;
|
|
39565
|
+
},
|
|
38960
39566
|
keydown: (_view, event) => {
|
|
38961
39567
|
if (!(event instanceof KeyboardEvent)) return false;
|
|
38962
39568
|
if (event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "ArrowUp" || event.key === "ArrowDown") {
|
|
@@ -39122,7 +39728,10 @@ var UEditor = React83.forwardRef(({
|
|
|
39122
39728
|
/* @__PURE__ */ jsxs79(
|
|
39123
39729
|
"div",
|
|
39124
39730
|
{
|
|
39125
|
-
ref:
|
|
39731
|
+
ref: (node) => {
|
|
39732
|
+
editorContentRef.current = node;
|
|
39733
|
+
formulaRangeSurfaceRef.current = node;
|
|
39734
|
+
},
|
|
39126
39735
|
className: "relative flex-1 overflow-y-auto",
|
|
39127
39736
|
style: {
|
|
39128
39737
|
minHeight: editable ? minHeight : void 0,
|
|
@@ -39154,6 +39763,20 @@ var UEditor = React83.forwardRef(({
|
|
|
39154
39763
|
className: "pointer-events-none hidden absolute z-20 rounded-[2px] border-2 border-primary bg-primary/10"
|
|
39155
39764
|
}
|
|
39156
39765
|
),
|
|
39766
|
+
formulaRangeHighlight && /* @__PURE__ */ jsx94(
|
|
39767
|
+
"span",
|
|
39768
|
+
{
|
|
39769
|
+
"aria-hidden": "true",
|
|
39770
|
+
"data-ueditor-formula-range-highlight": "",
|
|
39771
|
+
className: "pointer-events-none absolute z-20 rounded-[2px] border-2 border-primary bg-primary/10",
|
|
39772
|
+
style: {
|
|
39773
|
+
left: formulaRangeHighlight.left,
|
|
39774
|
+
top: formulaRangeHighlight.top,
|
|
39775
|
+
width: formulaRangeHighlight.width,
|
|
39776
|
+
height: formulaRangeHighlight.height
|
|
39777
|
+
}
|
|
39778
|
+
}
|
|
39779
|
+
),
|
|
39157
39780
|
editable && /* @__PURE__ */ jsx94(TableControls, { editor, containerRef: editorContentRef }),
|
|
39158
39781
|
/* @__PURE__ */ jsx94(
|
|
39159
39782
|
EditorContent,
|