@underverse-ui/underverse 1.0.157 → 1.0.159
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 +559 -212
- 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 +563 -216
- 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) {
|
|
@@ -28410,12 +28502,12 @@ function buildUEditorExtensions({
|
|
|
28410
28502
|
table_row_default,
|
|
28411
28503
|
CustomTableCell.configure({
|
|
28412
28504
|
HTMLAttributes: {
|
|
28413
|
-
class: "border border-border
|
|
28505
|
+
class: "border border-border px-2 py-0 min-w-25"
|
|
28414
28506
|
}
|
|
28415
28507
|
}),
|
|
28416
28508
|
CustomTableHeader.configure({
|
|
28417
28509
|
HTMLAttributes: {
|
|
28418
|
-
class: "border border-border
|
|
28510
|
+
class: "border border-border px-2 py-0 bg-muted font-semibold min-w-25"
|
|
28419
28511
|
}
|
|
28420
28512
|
}),
|
|
28421
28513
|
import_extension_character_count.default.configure({
|
|
@@ -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)(
|
|
@@ -31049,9 +31144,41 @@ function applyTableCellBackground(editor, color) {
|
|
|
31049
31144
|
}
|
|
31050
31145
|
editor.chain().focus().setCellAttribute("backgroundColor", value).run();
|
|
31051
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
|
+
}
|
|
31052
31177
|
var BubbleMenuContent = ({
|
|
31053
31178
|
editor,
|
|
31054
31179
|
onKeepOpenChange,
|
|
31180
|
+
onLinkInputOpenChange,
|
|
31181
|
+
onRequestClose,
|
|
31055
31182
|
fontSizes,
|
|
31056
31183
|
lineHeights,
|
|
31057
31184
|
initialShowLinkInput = false
|
|
@@ -31082,6 +31209,8 @@ var BubbleMenuContent = ({
|
|
|
31082
31209
|
const currentCellBgColor = normalizeStyleValue(editor.getAttributes("tableCell").backgroundColor || editor.getAttributes("tableHeader").backgroundColor) || "";
|
|
31083
31210
|
const currentCellFormula = normalizeStyleValue(editor.getAttributes("tableCell").formula || editor.getAttributes("tableHeader").formula) || "";
|
|
31084
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";
|
|
31085
31214
|
const isInTable2 = (0, import_tables3.isInTable)(editor.state);
|
|
31086
31215
|
const canMergeCells = isInTable2 && editor.can().mergeCells();
|
|
31087
31216
|
const canSplitCell = isInTable2 && editor.can().splitCell();
|
|
@@ -31095,6 +31224,15 @@ var BubbleMenuContent = ({
|
|
|
31095
31224
|
() => (lineHeights ?? getDefaultLineHeights()).filter((option) => ["1.2", "1.5", "1.75"].includes(option.value)),
|
|
31096
31225
|
[lineHeights]
|
|
31097
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
|
+
);
|
|
31098
31236
|
(0, import_react64.useEffect)(() => {
|
|
31099
31237
|
setFontSizeDraft(currentFontSize.replace(/px$/i, ""));
|
|
31100
31238
|
}, [currentFontSize]);
|
|
@@ -31115,7 +31253,55 @@ var BubbleMenuContent = ({
|
|
|
31115
31253
|
};
|
|
31116
31254
|
(0, import_react64.useEffect)(() => {
|
|
31117
31255
|
onKeepOpenChange?.(showLinkInput);
|
|
31118
|
-
|
|
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]);
|
|
31119
31305
|
(0, import_react64.useEffect)(() => {
|
|
31120
31306
|
if (!showLinkInput) return;
|
|
31121
31307
|
const close2 = () => setShowLinkInput(false);
|
|
@@ -31147,51 +31333,53 @@ var BubbleMenuContent = ({
|
|
|
31147
31333
|
const isTextPalette = activeColorPalette === "text";
|
|
31148
31334
|
const isHighlightPalette = activeColorPalette === "highlight";
|
|
31149
31335
|
if (activeColorPalette === "cell-border") {
|
|
31150
|
-
const currentBorderStyle = editor.getAttributes("tableCell").borderStyle || editor.getAttributes("tableHeader").borderStyle || "solid";
|
|
31151
|
-
const currentBorderWidth = editor.getAttributes("tableCell").borderWidth || editor.getAttributes("tableHeader").borderWidth || "1px";
|
|
31152
31336
|
const currentBorderColor = editor.getAttributes("tableCell").borderColor || editor.getAttributes("tableHeader").borderColor || "currentColor";
|
|
31153
|
-
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: [
|
|
31154
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" }),
|
|
31155
31339
|
/* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
31156
31340
|
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("label", { className: "text-xs text-muted-foreground", children: t("tableMenu.borderStyle") || "Border Style" }),
|
|
31157
|
-
/* @__PURE__ */ (0, import_jsx_runtime87.
|
|
31158
|
-
"
|
|
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",
|
|
31159
31349
|
{
|
|
31160
|
-
|
|
31161
|
-
|
|
31162
|
-
|
|
31163
|
-
|
|
31164
|
-
|
|
31165
|
-
|
|
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
|
+
),
|
|
31166
31358
|
children: [
|
|
31167
|
-
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
31168
|
-
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("
|
|
31169
|
-
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("option", { value: "dotted", children: "Dotted" }),
|
|
31170
|
-
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("option", { value: "double", children: "Double" }),
|
|
31171
|
-
/* @__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 })
|
|
31172
31361
|
]
|
|
31173
|
-
}
|
|
31174
|
-
|
|
31362
|
+
},
|
|
31363
|
+
style
|
|
31364
|
+
)) })
|
|
31175
31365
|
] }),
|
|
31176
31366
|
/* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
31177
31367
|
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("label", { className: "text-xs text-muted-foreground", children: t("tableMenu.borderWidth") || "Border Width" }),
|
|
31178
|
-
/* @__PURE__ */ (0, import_jsx_runtime87.
|
|
31179
|
-
"
|
|
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",
|
|
31180
31370
|
{
|
|
31181
|
-
|
|
31182
|
-
|
|
31183
|
-
|
|
31184
|
-
|
|
31185
|
-
|
|
31186
|
-
|
|
31187
|
-
|
|
31188
|
-
|
|
31189
|
-
|
|
31190
|
-
|
|
31191
|
-
|
|
31192
|
-
|
|
31193
|
-
}
|
|
31194
|
-
)
|
|
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
|
+
)) })
|
|
31195
31383
|
] }),
|
|
31196
31384
|
/* @__PURE__ */ (0, import_jsx_runtime87.jsxs)(
|
|
31197
31385
|
"button",
|
|
@@ -31213,70 +31401,36 @@ var BubbleMenuContent = ({
|
|
|
31213
31401
|
]
|
|
31214
31402
|
}
|
|
31215
31403
|
),
|
|
31216
|
-
/* @__PURE__ */ (0, import_jsx_runtime87.
|
|
31217
|
-
|
|
31218
|
-
|
|
31219
|
-
|
|
31220
|
-
|
|
31221
|
-
|
|
31222
|
-
|
|
31223
|
-
|
|
31224
|
-
|
|
31225
|
-
|
|
31226
|
-
children: t("tableMenu.clearBorder") || "Clear Border"
|
|
31227
|
-
}
|
|
31228
|
-
),
|
|
31229
|
-
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
31230
|
-
"button",
|
|
31231
|
-
{
|
|
31232
|
-
type: "button",
|
|
31233
|
-
onClick: () => setActiveColorPalette(null),
|
|
31234
|
-
className: "text-xs font-medium text-primary hover:underline",
|
|
31235
|
-
children: t("tableMenu.done") || "Done"
|
|
31236
|
-
}
|
|
31237
|
-
)
|
|
31238
|
-
] })
|
|
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
|
+
) })
|
|
31239
31414
|
] });
|
|
31240
31415
|
}
|
|
31241
31416
|
if (activeColorPalette === "cell-border-color") {
|
|
31242
31417
|
const currentBorderColor = normalizeStyleValue(editor.getAttributes("tableCell").borderColor || editor.getAttributes("tableHeader").borderColor) || "";
|
|
31243
|
-
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)(
|
|
31244
31419
|
EditorColorPalette,
|
|
31245
31420
|
{
|
|
31246
|
-
colors:
|
|
31421
|
+
colors: borderColors,
|
|
31247
31422
|
currentColor: currentBorderColor,
|
|
31248
|
-
onSelect:
|
|
31249
|
-
const value = color || null;
|
|
31250
|
-
editor.chain().focus().setCellAttribute("borderColor", value).run();
|
|
31251
|
-
setActiveColorPalette("cell-border");
|
|
31252
|
-
},
|
|
31423
|
+
onSelect: applyTableCellBorderColorAndClose,
|
|
31253
31424
|
label: t("tableMenu.borderColor") || "Border Color"
|
|
31254
31425
|
}
|
|
31255
31426
|
) });
|
|
31256
31427
|
}
|
|
31257
|
-
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)(
|
|
31258
31429
|
EditorColorPalette,
|
|
31259
31430
|
{
|
|
31260
31431
|
colors: isTextPalette ? textColors : highlightColors,
|
|
31261
31432
|
currentColor: isTextPalette ? currentTextColor : isHighlightPalette ? currentHighlightColor : currentCellBgColor,
|
|
31262
|
-
onSelect:
|
|
31263
|
-
if (isTextPalette) {
|
|
31264
|
-
if (color === "inherit") {
|
|
31265
|
-
editor.chain().focus().unsetColor().run();
|
|
31266
|
-
} else {
|
|
31267
|
-
editor.chain().focus().setColor(color).run();
|
|
31268
|
-
}
|
|
31269
|
-
} else if (isHighlightPalette) {
|
|
31270
|
-
if (color === "") {
|
|
31271
|
-
editor.chain().focus().unsetHighlight().run();
|
|
31272
|
-
} else {
|
|
31273
|
-
editor.chain().focus().toggleHighlight({ color }).run();
|
|
31274
|
-
}
|
|
31275
|
-
} else {
|
|
31276
|
-
applyTableCellBackground(editor, color);
|
|
31277
|
-
}
|
|
31278
|
-
setActiveColorPalette(null);
|
|
31279
|
-
},
|
|
31433
|
+
onSelect: applyInlineColorAndClose,
|
|
31280
31434
|
label: isTextPalette ? t("colors.textColor") : isHighlightPalette ? t("colors.highlight") : t("tableMenu.cellBackground") || "Cell background"
|
|
31281
31435
|
}
|
|
31282
31436
|
) });
|
|
@@ -31601,6 +31755,9 @@ var BubbleMenuContent = ({
|
|
|
31601
31755
|
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
31602
31756
|
ToolbarButton,
|
|
31603
31757
|
{
|
|
31758
|
+
onMouseDown: () => {
|
|
31759
|
+
onKeepOpenChange?.(true);
|
|
31760
|
+
},
|
|
31604
31761
|
onClick: () => setActiveColorPalette("cell-border"),
|
|
31605
31762
|
active: Boolean(
|
|
31606
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
|
|
@@ -31682,14 +31839,27 @@ var CustomBubbleMenu = ({
|
|
|
31682
31839
|
const SHOW_DELAY_MS = 180;
|
|
31683
31840
|
const BUBBLE_MENU_OFFSET = 16;
|
|
31684
31841
|
const [isVisible, setIsVisible] = (0, import_react64.useState)(false);
|
|
31842
|
+
const [linkInputOpen, setLinkInputOpen] = (0, import_react64.useState)(false);
|
|
31685
31843
|
const [position, setPosition] = (0, import_react64.useState)({ top: 0, left: 0 });
|
|
31686
31844
|
const menuRef = (0, import_react64.useRef)(null);
|
|
31687
31845
|
const keepOpenRef = (0, import_react64.useRef)(false);
|
|
31688
31846
|
const showTimeoutRef = (0, import_react64.useRef)(null);
|
|
31847
|
+
const suppressShowUntilRef = (0, import_react64.useRef)(0);
|
|
31689
31848
|
const setKeepOpen = (0, import_react64.useCallback)((next) => {
|
|
31690
31849
|
keepOpenRef.current = next;
|
|
31850
|
+
if (!next) setLinkInputOpen(false);
|
|
31691
31851
|
if (next) setIsVisible(true);
|
|
31692
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
|
+
}, []);
|
|
31693
31863
|
(0, import_react64.useEffect)(() => {
|
|
31694
31864
|
const clearShowTimeout = () => {
|
|
31695
31865
|
if (showTimeoutRef.current) {
|
|
@@ -31701,6 +31871,11 @@ var CustomBubbleMenu = ({
|
|
|
31701
31871
|
const { state, view } = editor;
|
|
31702
31872
|
const { from, to, empty } = state.selection;
|
|
31703
31873
|
const isLinkActive = editor.isActive("link");
|
|
31874
|
+
if (Date.now() < suppressShowUntilRef.current) {
|
|
31875
|
+
clearShowTimeout();
|
|
31876
|
+
setIsVisible(false);
|
|
31877
|
+
return;
|
|
31878
|
+
}
|
|
31704
31879
|
if (!keepOpenRef.current && (empty && !isLinkActive || !view.hasFocus())) {
|
|
31705
31880
|
clearShowTimeout();
|
|
31706
31881
|
setIsVisible(false);
|
|
@@ -31712,6 +31887,11 @@ var CustomBubbleMenu = ({
|
|
|
31712
31887
|
start = view.coordsAtPos(from);
|
|
31713
31888
|
end = view.coordsAtPos(to);
|
|
31714
31889
|
} catch {
|
|
31890
|
+
if (keepOpenRef.current) {
|
|
31891
|
+
clearShowTimeout();
|
|
31892
|
+
setIsVisible(true);
|
|
31893
|
+
return;
|
|
31894
|
+
}
|
|
31715
31895
|
clearShowTimeout();
|
|
31716
31896
|
setIsVisible(false);
|
|
31717
31897
|
return;
|
|
@@ -31769,15 +31949,34 @@ var CustomBubbleMenu = ({
|
|
|
31769
31949
|
left: `${position.left}px`,
|
|
31770
31950
|
transform: "translate(-50%, -100%)"
|
|
31771
31951
|
},
|
|
31772
|
-
onMouseDown: (e) =>
|
|
31773
|
-
|
|
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)(
|
|
31774
31971
|
BubbleMenuContent,
|
|
31775
31972
|
{
|
|
31776
31973
|
editor,
|
|
31777
31974
|
onKeepOpenChange: setKeepOpen,
|
|
31975
|
+
onLinkInputOpenChange: setLinkInputOpen,
|
|
31976
|
+
onRequestClose: closeBubbleMenu,
|
|
31778
31977
|
fontSizes,
|
|
31779
31978
|
lineHeights,
|
|
31780
|
-
initialShowLinkInput:
|
|
31979
|
+
initialShowLinkInput: linkInputOpen
|
|
31781
31980
|
}
|
|
31782
31981
|
)
|
|
31783
31982
|
}
|
|
@@ -37697,10 +37896,16 @@ var UEDITOR_PROSEMIRROR_CLASS_NAME = cn(
|
|
|
37697
37896
|
"[&_td]:align-top",
|
|
37698
37897
|
"[&_td]:box-border",
|
|
37699
37898
|
"[&_td]:select-text",
|
|
37899
|
+
"[&_td]:px-2",
|
|
37900
|
+
"[&_td]:py-0",
|
|
37901
|
+
"[&_td_p]:my-0",
|
|
37700
37902
|
"[&_th]:relative",
|
|
37701
37903
|
"[&_th]:align-top",
|
|
37702
37904
|
"[&_th]:box-border",
|
|
37703
37905
|
"[&_th]:select-text",
|
|
37906
|
+
"[&_th]:px-2",
|
|
37907
|
+
"[&_th]:py-0",
|
|
37908
|
+
"[&_th_p]:my-0",
|
|
37704
37909
|
"[&_.selectedCell]:after:content-['']",
|
|
37705
37910
|
"[&_.selectedCell]:after:absolute",
|
|
37706
37911
|
"[&_.selectedCell]:after:inset-0",
|
|
@@ -38213,6 +38418,7 @@ function useUEditorTableInteractions(editor, editable = true) {
|
|
|
38213
38418
|
proseMirror.addEventListener("keyup", handleSelectionChange);
|
|
38214
38419
|
proseMirror.addEventListener("focusin", handleSelectionChange);
|
|
38215
38420
|
document.addEventListener("selectionchange", handleSelectionChange);
|
|
38421
|
+
surface?.addEventListener(UEDITOR_TABLE_LAYOUT_CHANGE_EVENT, handleActiveCellLayoutChange);
|
|
38216
38422
|
surface?.addEventListener("scroll", handleActiveCellLayoutChange, scrollListenerOptions);
|
|
38217
38423
|
window.addEventListener("resize", handleActiveCellLayoutChange);
|
|
38218
38424
|
document.addEventListener("pointermove", handlePointerMove);
|
|
@@ -38232,6 +38438,7 @@ function useUEditorTableInteractions(editor, editable = true) {
|
|
|
38232
38438
|
proseMirror.removeEventListener("keyup", handleSelectionChange);
|
|
38233
38439
|
proseMirror.removeEventListener("focusin", handleSelectionChange);
|
|
38234
38440
|
document.removeEventListener("selectionchange", handleSelectionChange);
|
|
38441
|
+
surface?.removeEventListener(UEDITOR_TABLE_LAYOUT_CHANGE_EVENT, handleActiveCellLayoutChange);
|
|
38235
38442
|
surface?.removeEventListener("scroll", handleActiveCellLayoutChange, scrollListenerOptions);
|
|
38236
38443
|
window.removeEventListener("resize", handleActiveCellLayoutChange);
|
|
38237
38444
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
@@ -38266,6 +38473,145 @@ function useUEditorTableInteractions(editor, editable = true) {
|
|
|
38266
38473
|
var import_react69 = __toESM(require("react"), 1);
|
|
38267
38474
|
var import_react70 = require("@tiptap/react");
|
|
38268
38475
|
var import_lucide_react54 = require("lucide-react");
|
|
38476
|
+
|
|
38477
|
+
// src/components/UEditor/preview-html.ts
|
|
38478
|
+
var DEFAULT_TABLE_COLUMN_WIDTH = 100;
|
|
38479
|
+
var TIPTAP_TABLE_MIN_COLUMN_WIDTH = 25;
|
|
38480
|
+
function parsePixelWidth2(value) {
|
|
38481
|
+
if (!value) return null;
|
|
38482
|
+
const match = String(value).match(/(?:^|[\s:])(\d+(?:\.\d+)?)px\b/i) ?? String(value).match(/^(\d+(?:\.\d+)?)$/);
|
|
38483
|
+
if (!match) return null;
|
|
38484
|
+
const parsed = Number.parseFloat(match[1] ?? match[0]);
|
|
38485
|
+
return Number.isFinite(parsed) && parsed > 0 ? Math.round(parsed) : null;
|
|
38486
|
+
}
|
|
38487
|
+
function parseStyleWidth(style) {
|
|
38488
|
+
return parsePixelWidth2(style.width) ?? parsePixelWidth2(style.minWidth);
|
|
38489
|
+
}
|
|
38490
|
+
function parseStyleHeight(style) {
|
|
38491
|
+
return parsePixelWidth2(style.height) ?? parsePixelWidth2(style.minHeight);
|
|
38492
|
+
}
|
|
38493
|
+
function getCellColspan(cell) {
|
|
38494
|
+
return Math.max(1, cell.colSpan || Number.parseInt(cell.getAttribute("colspan") || "1", 10) || 1);
|
|
38495
|
+
}
|
|
38496
|
+
function getCellWidths(cell) {
|
|
38497
|
+
const dataColwidth = cell.getAttribute("data-colwidth") || cell.getAttribute("colwidth");
|
|
38498
|
+
if (dataColwidth) {
|
|
38499
|
+
const widths = dataColwidth.split(/[,\s]+/).map((part) => parsePixelWidth2(part)).filter((width2) => typeof width2 === "number");
|
|
38500
|
+
if (widths.length > 0) return widths;
|
|
38501
|
+
}
|
|
38502
|
+
const width = parsePixelWidth2(cell.getAttribute("width")) ?? parseStyleWidth(cell.style);
|
|
38503
|
+
if (!width) return null;
|
|
38504
|
+
const colspan = getCellColspan(cell);
|
|
38505
|
+
return Array.from({ length: colspan }, () => Math.max(DEFAULT_TABLE_COLUMN_WIDTH, Math.round(width / colspan)));
|
|
38506
|
+
}
|
|
38507
|
+
function getColumnCount(table) {
|
|
38508
|
+
const colCount = table.querySelectorAll("colgroup > col").length;
|
|
38509
|
+
if (colCount > 0) return colCount;
|
|
38510
|
+
return Math.max(
|
|
38511
|
+
0,
|
|
38512
|
+
...Array.from(table.rows).map(
|
|
38513
|
+
(row) => Array.from(row.cells).reduce((count, cell) => count + getCellColspan(cell), 0)
|
|
38514
|
+
)
|
|
38515
|
+
);
|
|
38516
|
+
}
|
|
38517
|
+
function resolveColumnWidths(table) {
|
|
38518
|
+
const columnCount = getColumnCount(table);
|
|
38519
|
+
if (columnCount <= 0) return [];
|
|
38520
|
+
const widths = Array.from({ length: columnCount }, () => DEFAULT_TABLE_COLUMN_WIDTH);
|
|
38521
|
+
const cols = Array.from(table.querySelectorAll("colgroup > col"));
|
|
38522
|
+
cols.slice(0, columnCount).forEach((col, index) => {
|
|
38523
|
+
const width = parsePixelWidth2(col.getAttribute("width")) ?? parseStyleWidth(col.style);
|
|
38524
|
+
if (width && width > TIPTAP_TABLE_MIN_COLUMN_WIDTH) {
|
|
38525
|
+
widths[index] = width;
|
|
38526
|
+
}
|
|
38527
|
+
});
|
|
38528
|
+
Array.from(table.rows).forEach((row) => {
|
|
38529
|
+
let columnIndex = 0;
|
|
38530
|
+
Array.from(row.cells).forEach((cell) => {
|
|
38531
|
+
const cellWidths = getCellWidths(cell);
|
|
38532
|
+
if (cellWidths) {
|
|
38533
|
+
cellWidths.slice(0, getCellColspan(cell)).forEach((width, offset) => {
|
|
38534
|
+
if (width > TIPTAP_TABLE_MIN_COLUMN_WIDTH && columnIndex + offset < widths.length) {
|
|
38535
|
+
widths[columnIndex + offset] = width;
|
|
38536
|
+
}
|
|
38537
|
+
});
|
|
38538
|
+
}
|
|
38539
|
+
columnIndex += getCellColspan(cell);
|
|
38540
|
+
});
|
|
38541
|
+
});
|
|
38542
|
+
return widths;
|
|
38543
|
+
}
|
|
38544
|
+
function setStyleProperty(element, property, value) {
|
|
38545
|
+
element.style.setProperty(property, value);
|
|
38546
|
+
}
|
|
38547
|
+
function resolveExplicitRowHeight(row) {
|
|
38548
|
+
const explicitRowHeight = parsePixelWidth2(row.getAttribute("data-row-height")) ?? parseStyleHeight(row.style);
|
|
38549
|
+
if (explicitRowHeight) return Math.max(MIN_TABLE_ROW_HEIGHT, explicitRowHeight);
|
|
38550
|
+
const cellHeight = Array.from(row.cells).reduce((maxHeight, cell) => {
|
|
38551
|
+
const height = parsePixelWidth2(cell.getAttribute("height")) ?? parseStyleHeight(cell.style);
|
|
38552
|
+
return height ? Math.max(maxHeight, height) : maxHeight;
|
|
38553
|
+
}, 0);
|
|
38554
|
+
return cellHeight ? Math.max(MIN_TABLE_ROW_HEIGHT, cellHeight) : null;
|
|
38555
|
+
}
|
|
38556
|
+
function normalizePreviewRowHeight(row) {
|
|
38557
|
+
const rowHeight = resolveExplicitRowHeight(row);
|
|
38558
|
+
if (!rowHeight) return;
|
|
38559
|
+
row.style.height = `${rowHeight}px`;
|
|
38560
|
+
row.style.minHeight = `${rowHeight}px`;
|
|
38561
|
+
Array.from(row.cells).forEach((cell) => {
|
|
38562
|
+
cell.style.height = `${rowHeight}px`;
|
|
38563
|
+
cell.style.minHeight = `${rowHeight}px`;
|
|
38564
|
+
});
|
|
38565
|
+
}
|
|
38566
|
+
function normalizePreviewTable(table) {
|
|
38567
|
+
const widths = resolveColumnWidths(table);
|
|
38568
|
+
if (widths.length === 0) return;
|
|
38569
|
+
let colgroup = table.querySelector("colgroup");
|
|
38570
|
+
if (!colgroup) {
|
|
38571
|
+
colgroup = document.createElement("colgroup");
|
|
38572
|
+
table.insertBefore(colgroup, table.firstChild);
|
|
38573
|
+
}
|
|
38574
|
+
while (colgroup.children.length < widths.length) {
|
|
38575
|
+
colgroup.appendChild(document.createElement("col"));
|
|
38576
|
+
}
|
|
38577
|
+
Array.from(colgroup.children).forEach((child, index) => {
|
|
38578
|
+
if (child.tagName.toLowerCase() !== "col") return;
|
|
38579
|
+
const col = child;
|
|
38580
|
+
if (index >= widths.length) {
|
|
38581
|
+
child.remove();
|
|
38582
|
+
return;
|
|
38583
|
+
}
|
|
38584
|
+
col.style.width = `${widths[index]}px`;
|
|
38585
|
+
col.style.minWidth = `${widths[index]}px`;
|
|
38586
|
+
col.setAttribute("width", String(widths[index]));
|
|
38587
|
+
});
|
|
38588
|
+
const tableWidth = widths.reduce((sum, width) => sum + width, 0);
|
|
38589
|
+
setStyleProperty(table, "width", `${tableWidth}px`);
|
|
38590
|
+
setStyleProperty(table, "min-width", `${tableWidth}px`);
|
|
38591
|
+
setStyleProperty(table, "table-layout", "fixed");
|
|
38592
|
+
Array.from(table.rows).forEach((row) => {
|
|
38593
|
+
let columnIndex = 0;
|
|
38594
|
+
normalizePreviewRowHeight(row);
|
|
38595
|
+
Array.from(row.cells).forEach((cell) => {
|
|
38596
|
+
const colspan = getCellColspan(cell);
|
|
38597
|
+
const cellWidth = widths.slice(columnIndex, columnIndex + colspan).reduce((sum, width) => sum + width, 0);
|
|
38598
|
+
if (cellWidth > 0) {
|
|
38599
|
+
cell.style.width = `${cellWidth}px`;
|
|
38600
|
+
cell.style.minWidth = `${cellWidth}px`;
|
|
38601
|
+
}
|
|
38602
|
+
columnIndex += colspan;
|
|
38603
|
+
});
|
|
38604
|
+
});
|
|
38605
|
+
}
|
|
38606
|
+
function prepareUEditorPreviewHtml(html) {
|
|
38607
|
+
if (typeof document === "undefined" || !html) return html;
|
|
38608
|
+
const container = document.createElement("div");
|
|
38609
|
+
container.innerHTML = html;
|
|
38610
|
+
container.querySelectorAll("table").forEach((table) => normalizePreviewTable(table));
|
|
38611
|
+
return container.innerHTML;
|
|
38612
|
+
}
|
|
38613
|
+
|
|
38614
|
+
// src/components/UEditor/menu-bar.tsx
|
|
38269
38615
|
var import_jsx_runtime94 = require("react/jsx-runtime");
|
|
38270
38616
|
function MenuTableInsertGrid({
|
|
38271
38617
|
insertLabel,
|
|
@@ -38748,6 +39094,10 @@ var MenuBar = ({
|
|
|
38748
39094
|
const [showSourceDialog, setShowSourceDialog] = (0, import_react69.useState)(false);
|
|
38749
39095
|
const [sourceHtml, setSourceHtml] = (0, import_react69.useState)("");
|
|
38750
39096
|
const [showPreviewDialog, setShowPreviewDialog] = (0, import_react69.useState)(false);
|
|
39097
|
+
const previewHtml = (0, import_react69.useMemo)(
|
|
39098
|
+
() => showPreviewDialog ? prepareUEditorPreviewHtml(editor.getHTML()) : "",
|
|
39099
|
+
[editor, showPreviewDialog]
|
|
39100
|
+
);
|
|
38751
39101
|
const openSourceDialog = () => {
|
|
38752
39102
|
setSourceHtml(editor.getHTML());
|
|
38753
39103
|
setShowSourceDialog(true);
|
|
@@ -38756,10 +39106,7 @@ var MenuBar = ({
|
|
|
38756
39106
|
setShowPreviewDialog(true);
|
|
38757
39107
|
};
|
|
38758
39108
|
const handlePreview = () => {
|
|
38759
|
-
if (onPreview)
|
|
38760
|
-
onPreview();
|
|
38761
|
-
return;
|
|
38762
|
-
}
|
|
39109
|
+
if (onPreview?.(editor.getHTML()) === false) return;
|
|
38763
39110
|
openPreviewDialog();
|
|
38764
39111
|
};
|
|
38765
39112
|
const applySourceHtml = () => {
|
|
@@ -38994,12 +39341,12 @@ var MenuBar = ({
|
|
|
38994
39341
|
"div",
|
|
38995
39342
|
{
|
|
38996
39343
|
"data-testid": "preview-content",
|
|
38997
|
-
className: "min-h-0 flex-1 overflow-y-auto overscroll-contain
|
|
39344
|
+
className: "min-h-0 flex-1 overflow-y-auto overscroll-contain",
|
|
38998
39345
|
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)(
|
|
38999
39346
|
"div",
|
|
39000
39347
|
{
|
|
39001
39348
|
className: UEDITOR_PROSEMIRROR_CLASS_NAME,
|
|
39002
|
-
dangerouslySetInnerHTML: { __html:
|
|
39349
|
+
dangerouslySetInnerHTML: { __html: previewHtml }
|
|
39003
39350
|
}
|
|
39004
39351
|
)
|
|
39005
39352
|
}
|