@underverse-ui/underverse 1.0.141 → 1.0.143
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 +412 -265
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +414 -266
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -25261,6 +25261,7 @@ import Typography from "@tiptap/extension-typography";
|
|
|
25261
25261
|
import Subscript from "@tiptap/extension-subscript";
|
|
25262
25262
|
import Superscript from "@tiptap/extension-superscript";
|
|
25263
25263
|
import HorizontalRule from "@tiptap/extension-horizontal-rule";
|
|
25264
|
+
import Gapcursor from "@tiptap/extension-gapcursor";
|
|
25264
25265
|
import { common, createLowlight } from "lowlight";
|
|
25265
25266
|
|
|
25266
25267
|
// src/components/UEditor/slash-command.tsx
|
|
@@ -26051,7 +26052,6 @@ import { mergeAttributes as mergeAttributes4 } from "@tiptap/core";
|
|
|
26051
26052
|
import { NodeViewWrapper as NodeViewWrapper4, ReactNodeViewRenderer as ReactNodeViewRenderer4 } from "@tiptap/react";
|
|
26052
26053
|
import { jsx as jsx81, jsxs as jsxs67 } from "react/jsx-runtime";
|
|
26053
26054
|
var MIN_IMAGE_SIZE_PX = 40;
|
|
26054
|
-
var AXIS_LOCK_THRESHOLD_PX = 4;
|
|
26055
26055
|
var IMAGE_LAYOUTS = /* @__PURE__ */ new Set(["block", "left", "right"]);
|
|
26056
26056
|
var IMAGE_WIDTH_PRESETS = /* @__PURE__ */ new Set(["sm", "md", "lg"]);
|
|
26057
26057
|
function toNullableNumber(value) {
|
|
@@ -26092,6 +26092,41 @@ function getImageLayoutStyles(layout) {
|
|
|
26092
26092
|
}
|
|
26093
26093
|
return {};
|
|
26094
26094
|
}
|
|
26095
|
+
function getAspectRatio({
|
|
26096
|
+
img,
|
|
26097
|
+
widthAttr,
|
|
26098
|
+
heightAttr,
|
|
26099
|
+
fallbackWidth,
|
|
26100
|
+
fallbackHeight
|
|
26101
|
+
}) {
|
|
26102
|
+
if (widthAttr && heightAttr) return widthAttr / heightAttr;
|
|
26103
|
+
if (img.naturalWidth > 0 && img.naturalHeight > 0) return img.naturalWidth / img.naturalHeight;
|
|
26104
|
+
if (fallbackWidth > 0 && fallbackHeight > 0) return fallbackWidth / fallbackHeight;
|
|
26105
|
+
return 1;
|
|
26106
|
+
}
|
|
26107
|
+
function sizeFromWidth(width, aspect, maxWidth) {
|
|
26108
|
+
let nextW = clamp8(width, MIN_IMAGE_SIZE_PX, maxWidth);
|
|
26109
|
+
let nextH = nextW / aspect;
|
|
26110
|
+
if (nextH < MIN_IMAGE_SIZE_PX) {
|
|
26111
|
+
nextH = MIN_IMAGE_SIZE_PX;
|
|
26112
|
+
nextW = clamp8(nextH * aspect, MIN_IMAGE_SIZE_PX, maxWidth);
|
|
26113
|
+
nextH = nextW / aspect;
|
|
26114
|
+
}
|
|
26115
|
+
return { width: nextW, height: nextH };
|
|
26116
|
+
}
|
|
26117
|
+
function sizeFromHeight(height, aspect, maxWidth) {
|
|
26118
|
+
let nextH = Math.max(MIN_IMAGE_SIZE_PX, height);
|
|
26119
|
+
let nextW = nextH * aspect;
|
|
26120
|
+
if (nextW > maxWidth) {
|
|
26121
|
+
nextW = maxWidth;
|
|
26122
|
+
nextH = nextW / aspect;
|
|
26123
|
+
}
|
|
26124
|
+
if (nextW < MIN_IMAGE_SIZE_PX) {
|
|
26125
|
+
nextW = MIN_IMAGE_SIZE_PX;
|
|
26126
|
+
nextH = nextW / aspect;
|
|
26127
|
+
}
|
|
26128
|
+
return { width: nextW, height: nextH };
|
|
26129
|
+
}
|
|
26095
26130
|
function ResizableImageNodeView(props) {
|
|
26096
26131
|
const { node, selected, updateAttributes, editor, getPos } = props;
|
|
26097
26132
|
const wrapperRef = useRef29(null);
|
|
@@ -26102,7 +26137,6 @@ function ResizableImageNodeView(props) {
|
|
|
26102
26137
|
const heightAttr = toNullableNumber(node.attrs["height"]);
|
|
26103
26138
|
const textAlign = String(node.attrs["textAlign"] ?? "");
|
|
26104
26139
|
const imageLayout = parseImageLayout(node.attrs["imageLayout"]);
|
|
26105
|
-
const preserveAspectByDefault = imageLayout === "left" || imageLayout === "right";
|
|
26106
26140
|
const dragStateRef = useRef29(null);
|
|
26107
26141
|
useEffect34(() => {
|
|
26108
26142
|
const img = imgRef.current;
|
|
@@ -26126,7 +26160,13 @@ function ResizableImageNodeView(props) {
|
|
|
26126
26160
|
const maxW = editorEl ? editorEl.getBoundingClientRect().width : Number.POSITIVE_INFINITY;
|
|
26127
26161
|
const startW = Math.max(MIN_IMAGE_SIZE_PX, rect.width);
|
|
26128
26162
|
const startH = Math.max(MIN_IMAGE_SIZE_PX, rect.height);
|
|
26129
|
-
const aspect =
|
|
26163
|
+
const aspect = getAspectRatio({
|
|
26164
|
+
img,
|
|
26165
|
+
widthAttr,
|
|
26166
|
+
heightAttr,
|
|
26167
|
+
fallbackWidth: startW,
|
|
26168
|
+
fallbackHeight: startH
|
|
26169
|
+
});
|
|
26130
26170
|
dragStateRef.current = {
|
|
26131
26171
|
pointerId: event.pointerId,
|
|
26132
26172
|
startX: event.clientX,
|
|
@@ -26135,7 +26175,6 @@ function ResizableImageNodeView(props) {
|
|
|
26135
26175
|
startH,
|
|
26136
26176
|
lastW: startW,
|
|
26137
26177
|
lastH: startH,
|
|
26138
|
-
axis: null,
|
|
26139
26178
|
aspect,
|
|
26140
26179
|
maxW: Math.max(MIN_IMAGE_SIZE_PX, maxW)
|
|
26141
26180
|
};
|
|
@@ -26149,24 +26188,9 @@ function ResizableImageNodeView(props) {
|
|
|
26149
26188
|
if (event.pointerId !== drag.pointerId) return;
|
|
26150
26189
|
const dx = event.clientX - drag.startX;
|
|
26151
26190
|
const dy = event.clientY - drag.startY;
|
|
26152
|
-
|
|
26153
|
-
|
|
26154
|
-
const
|
|
26155
|
-
if (shouldPreserveAspect) {
|
|
26156
|
-
if (Math.abs(dx) >= Math.abs(dy)) {
|
|
26157
|
-
nextW = clamp8(drag.startW + dx, MIN_IMAGE_SIZE_PX, drag.maxW);
|
|
26158
|
-
nextH = clamp8(nextW / drag.aspect, MIN_IMAGE_SIZE_PX, Number.POSITIVE_INFINITY);
|
|
26159
|
-
} else {
|
|
26160
|
-
nextH = clamp8(drag.startH + dy, MIN_IMAGE_SIZE_PX, Number.POSITIVE_INFINITY);
|
|
26161
|
-
nextW = clamp8(nextH * drag.aspect, MIN_IMAGE_SIZE_PX, drag.maxW);
|
|
26162
|
-
}
|
|
26163
|
-
} else {
|
|
26164
|
-
if (!drag.axis && (Math.abs(dx) > AXIS_LOCK_THRESHOLD_PX || Math.abs(dy) > AXIS_LOCK_THRESHOLD_PX)) {
|
|
26165
|
-
drag.axis = Math.abs(dx) >= Math.abs(dy) ? "x" : "y";
|
|
26166
|
-
}
|
|
26167
|
-
if (drag.axis === "x") nextW = clamp8(drag.startW + dx, MIN_IMAGE_SIZE_PX, drag.maxW);
|
|
26168
|
-
if (drag.axis === "y") nextH = clamp8(drag.startH + dy, MIN_IMAGE_SIZE_PX, Number.POSITIVE_INFINITY);
|
|
26169
|
-
}
|
|
26191
|
+
const nextSize = Math.abs(dx) >= Math.abs(dy) ? sizeFromWidth(drag.startW + dx, drag.aspect, drag.maxW) : sizeFromHeight(drag.startH + dy, drag.aspect, drag.maxW);
|
|
26192
|
+
const nextW = nextSize.width;
|
|
26193
|
+
const nextH = nextSize.height;
|
|
26170
26194
|
drag.lastW = nextW;
|
|
26171
26195
|
drag.lastH = nextH;
|
|
26172
26196
|
img.style.width = `${Math.round(nextW)}px`;
|
|
@@ -27089,6 +27113,7 @@ function buildUEditorExtensions({
|
|
|
27089
27113
|
}
|
|
27090
27114
|
}),
|
|
27091
27115
|
HorizontalRule,
|
|
27116
|
+
Gapcursor,
|
|
27092
27117
|
Link.configure({
|
|
27093
27118
|
openOnClick: false,
|
|
27094
27119
|
protocols: ["http", "https", "mailto", "tel"],
|
|
@@ -27122,7 +27147,7 @@ function buildUEditorExtensions({
|
|
|
27122
27147
|
handleWidth: 10,
|
|
27123
27148
|
allowTableNodeSelection: true,
|
|
27124
27149
|
HTMLAttributes: {
|
|
27125
|
-
class: "border-collapse
|
|
27150
|
+
class: "border-collapse my-4"
|
|
27126
27151
|
}
|
|
27127
27152
|
}),
|
|
27128
27153
|
table_row_default,
|
|
@@ -27205,6 +27230,7 @@ import {
|
|
|
27205
27230
|
Subscript as SubscriptIcon,
|
|
27206
27231
|
Superscript as SuperscriptIcon,
|
|
27207
27232
|
Table as TableIcon,
|
|
27233
|
+
TableCellsMerge,
|
|
27208
27234
|
Trash2 as Trash22,
|
|
27209
27235
|
Type as Type2,
|
|
27210
27236
|
Underline as UnderlineIcon,
|
|
@@ -27475,6 +27501,43 @@ function isSelectedImage(editor) {
|
|
|
27475
27501
|
const { selection } = editor.state;
|
|
27476
27502
|
return selection instanceof NodeSelection && selection.node.type.name === "image";
|
|
27477
27503
|
}
|
|
27504
|
+
function toPositiveNumber(value) {
|
|
27505
|
+
if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
|
|
27506
|
+
if (typeof value === "string") {
|
|
27507
|
+
const parsed = Number.parseInt(value, 10);
|
|
27508
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
|
|
27509
|
+
}
|
|
27510
|
+
return null;
|
|
27511
|
+
}
|
|
27512
|
+
function getImageElementAtSelection(editor, pos) {
|
|
27513
|
+
const nodeDom = editor.view.nodeDOM(pos);
|
|
27514
|
+
if (!(nodeDom instanceof HTMLElement)) return null;
|
|
27515
|
+
if (nodeDom.tagName === "IMG") return nodeDom;
|
|
27516
|
+
return nodeDom.querySelector("img");
|
|
27517
|
+
}
|
|
27518
|
+
function getImageAspectRatio(editor, attrs, pos) {
|
|
27519
|
+
const widthAttr = toPositiveNumber(attrs.width);
|
|
27520
|
+
const heightAttr = toPositiveNumber(attrs.height);
|
|
27521
|
+
if (widthAttr && heightAttr) return widthAttr / heightAttr;
|
|
27522
|
+
const imageElement = typeof pos === "number" ? getImageElementAtSelection(editor, pos) : null;
|
|
27523
|
+
if (!imageElement) return null;
|
|
27524
|
+
if (imageElement.naturalWidth > 0 && imageElement.naturalHeight > 0) {
|
|
27525
|
+
return imageElement.naturalWidth / imageElement.naturalHeight;
|
|
27526
|
+
}
|
|
27527
|
+
const rect = imageElement.getBoundingClientRect();
|
|
27528
|
+
if (rect.width > 0 && rect.height > 0) return rect.width / rect.height;
|
|
27529
|
+
const width = toPositiveNumber(imageElement.getAttribute("width")) ?? toPositiveNumber(imageElement.style.width);
|
|
27530
|
+
const height = toPositiveNumber(imageElement.getAttribute("height")) ?? toPositiveNumber(imageElement.style.height);
|
|
27531
|
+
return width && height ? width / height : null;
|
|
27532
|
+
}
|
|
27533
|
+
function getImagePresetAttributes(editor, width, preset, attrs, pos) {
|
|
27534
|
+
const aspect = getImageAspectRatio(editor, attrs, pos);
|
|
27535
|
+
return {
|
|
27536
|
+
width,
|
|
27537
|
+
height: aspect ? Math.round(width / aspect) : toPositiveNumber(attrs.height),
|
|
27538
|
+
imageWidthPreset: preset
|
|
27539
|
+
};
|
|
27540
|
+
}
|
|
27478
27541
|
function applyImageLayout(editor, layout) {
|
|
27479
27542
|
const { state, view } = editor;
|
|
27480
27543
|
const { selection, schema } = state;
|
|
@@ -27509,15 +27572,15 @@ function applyImageWidthPreset(editor, preset) {
|
|
|
27509
27572
|
const mode = attrs.imageLayout === "left" || attrs.imageLayout === "right" ? "wrap" : "block";
|
|
27510
27573
|
const width = IMAGE_WIDTHS_BY_LAYOUT[mode][preset];
|
|
27511
27574
|
if (!isSelectedImage(editor)) {
|
|
27512
|
-
editor.chain().focus().updateAttributes("image",
|
|
27575
|
+
editor.chain().focus().updateAttributes("image", getImagePresetAttributes(editor, width, preset, attrs)).run();
|
|
27513
27576
|
return;
|
|
27514
27577
|
}
|
|
27515
27578
|
const { state, view } = editor;
|
|
27516
27579
|
const selection = state.selection;
|
|
27580
|
+
const nextAttrs = getImagePresetAttributes(editor, width, preset, selection.node.attrs, selection.from);
|
|
27517
27581
|
const transaction = state.tr.setNodeMarkup(selection.from, void 0, {
|
|
27518
27582
|
...selection.node.attrs,
|
|
27519
|
-
|
|
27520
|
-
imageWidthPreset: preset
|
|
27583
|
+
...nextAttrs
|
|
27521
27584
|
});
|
|
27522
27585
|
view.dispatch(transaction.scrollIntoView());
|
|
27523
27586
|
view.focus();
|
|
@@ -27645,6 +27708,229 @@ var ImageInput = ({ onSubmit, onCancel }) => {
|
|
|
27645
27708
|
] });
|
|
27646
27709
|
};
|
|
27647
27710
|
|
|
27711
|
+
// src/components/UEditor/table-cell-commands.ts
|
|
27712
|
+
import { TextSelection as TextSelection2 } from "@tiptap/pm/state";
|
|
27713
|
+
import { selectedRect, TableMap } from "@tiptap/pm/tables";
|
|
27714
|
+
function getCellSelectionPositions(selection) {
|
|
27715
|
+
const value = selection;
|
|
27716
|
+
const anchor = value.$anchorCell?.pos;
|
|
27717
|
+
const head = value.$headCell?.pos;
|
|
27718
|
+
return typeof anchor === "number" && typeof head === "number" ? { anchor, head } : null;
|
|
27719
|
+
}
|
|
27720
|
+
function findTableInfoFromCellPos(editor, cellPos) {
|
|
27721
|
+
const $pos = editor.state.doc.resolve(cellPos);
|
|
27722
|
+
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
27723
|
+
const node = $pos.node(depth);
|
|
27724
|
+
if (node.type.name === "table") {
|
|
27725
|
+
return {
|
|
27726
|
+
table: node,
|
|
27727
|
+
tablePos: $pos.before(depth),
|
|
27728
|
+
tableStart: $pos.start(depth)
|
|
27729
|
+
};
|
|
27730
|
+
}
|
|
27731
|
+
}
|
|
27732
|
+
return null;
|
|
27733
|
+
}
|
|
27734
|
+
function getFocusableCellPos(editor, cellPos) {
|
|
27735
|
+
const cellNode = editor.state.doc.nodeAt(cellPos);
|
|
27736
|
+
if (!cellNode) return cellPos + 1;
|
|
27737
|
+
let offset = cellPos + 1;
|
|
27738
|
+
let node = cellNode.firstChild ?? null;
|
|
27739
|
+
while (node && !node.isTextblock) {
|
|
27740
|
+
offset += 1;
|
|
27741
|
+
node = node.firstChild ?? null;
|
|
27742
|
+
}
|
|
27743
|
+
return node?.isTextblock ? offset + 1 : cellPos + 1;
|
|
27744
|
+
}
|
|
27745
|
+
function focusCell(editor, cellPos) {
|
|
27746
|
+
const selection = TextSelection2.near(editor.state.doc.resolve(getFocusableCellPos(editor, cellPos)));
|
|
27747
|
+
editor.view.dispatch(editor.state.tr.setSelection(selection));
|
|
27748
|
+
editor.view.focus();
|
|
27749
|
+
}
|
|
27750
|
+
function collectChildren(node) {
|
|
27751
|
+
const children = [];
|
|
27752
|
+
node.forEach((child) => children.push(child));
|
|
27753
|
+
return children;
|
|
27754
|
+
}
|
|
27755
|
+
function createEmptyCellNode(cellNode) {
|
|
27756
|
+
return cellNode.type.createAndFill(cellNode.attrs) ?? cellNode;
|
|
27757
|
+
}
|
|
27758
|
+
function getSelectedTableRect(editor) {
|
|
27759
|
+
const cellSelection = getCellSelectionPositions(editor.state.selection);
|
|
27760
|
+
if (cellSelection) {
|
|
27761
|
+
const tableInfo = findTableInfoFromCellPos(editor, cellSelection.anchor);
|
|
27762
|
+
if (tableInfo) {
|
|
27763
|
+
const map = TableMap.get(tableInfo.table);
|
|
27764
|
+
const rect = map.rectBetween(
|
|
27765
|
+
cellSelection.anchor - tableInfo.tableStart,
|
|
27766
|
+
cellSelection.head - tableInfo.tableStart
|
|
27767
|
+
);
|
|
27768
|
+
return {
|
|
27769
|
+
...rect,
|
|
27770
|
+
map,
|
|
27771
|
+
table: tableInfo.table,
|
|
27772
|
+
tableStart: tableInfo.tableStart
|
|
27773
|
+
};
|
|
27774
|
+
}
|
|
27775
|
+
}
|
|
27776
|
+
return selectedRect(editor.state);
|
|
27777
|
+
}
|
|
27778
|
+
function parsePixelWidth(value) {
|
|
27779
|
+
if (!value) return null;
|
|
27780
|
+
const parsed = Number.parseFloat(value);
|
|
27781
|
+
return Number.isFinite(parsed) && parsed > 0 ? Math.round(parsed) : null;
|
|
27782
|
+
}
|
|
27783
|
+
function getDomColumnWidths(editor, rect) {
|
|
27784
|
+
const tableDom = editor.view.nodeDOM(rect.tableStart - 1);
|
|
27785
|
+
if (!(tableDom instanceof HTMLTableElement)) return null;
|
|
27786
|
+
const cols = Array.from(tableDom.querySelectorAll("colgroup > col"));
|
|
27787
|
+
if (cols.length === 0) return null;
|
|
27788
|
+
const widths = [];
|
|
27789
|
+
for (let col = rect.left; col < rect.right; col += 1) {
|
|
27790
|
+
const colElement = cols[col];
|
|
27791
|
+
if (!colElement) return null;
|
|
27792
|
+
const width = parsePixelWidth(colElement.style.width) ?? parsePixelWidth(colElement.getAttribute("width")) ?? Math.round(colElement.getBoundingClientRect().width);
|
|
27793
|
+
if (!Number.isFinite(width) || width <= 0) return null;
|
|
27794
|
+
widths.push(width);
|
|
27795
|
+
}
|
|
27796
|
+
return widths.length > 0 ? widths : null;
|
|
27797
|
+
}
|
|
27798
|
+
function getNodeColumnWidths(rect) {
|
|
27799
|
+
const widths = [];
|
|
27800
|
+
for (let col = rect.left; col < rect.right; col += 1) {
|
|
27801
|
+
let width = null;
|
|
27802
|
+
const seen = /* @__PURE__ */ new Set();
|
|
27803
|
+
for (let row = 0; row < rect.map.height && width == null; row += 1) {
|
|
27804
|
+
const cellPos = rect.map.map[row * rect.map.width + col];
|
|
27805
|
+
if (seen.has(cellPos)) continue;
|
|
27806
|
+
seen.add(cellPos);
|
|
27807
|
+
const cell = rect.table.nodeAt(cellPos);
|
|
27808
|
+
const colwidth = cell?.attrs.colwidth;
|
|
27809
|
+
if (!Array.isArray(colwidth)) continue;
|
|
27810
|
+
const cellLeft = rect.map.colCount(cellPos);
|
|
27811
|
+
const widthIndex = col - cellLeft;
|
|
27812
|
+
const candidate = colwidth[widthIndex];
|
|
27813
|
+
if (typeof candidate === "number" && candidate > 0) {
|
|
27814
|
+
width = candidate;
|
|
27815
|
+
}
|
|
27816
|
+
}
|
|
27817
|
+
if (width == null) return null;
|
|
27818
|
+
widths.push(width);
|
|
27819
|
+
}
|
|
27820
|
+
return widths.length > 0 ? widths : null;
|
|
27821
|
+
}
|
|
27822
|
+
function getSelectedColumnWidths(editor, rect) {
|
|
27823
|
+
return getDomColumnWidths(editor, rect) ?? getNodeColumnWidths(rect);
|
|
27824
|
+
}
|
|
27825
|
+
function dispatchTableLayoutChange(editor) {
|
|
27826
|
+
editor.view.dom.dispatchEvent(new CustomEvent(UEDITOR_TABLE_LAYOUT_CHANGE_EVENT, { bubbles: true }));
|
|
27827
|
+
}
|
|
27828
|
+
function mergeTableCellsPreservingColumnWidths(editor) {
|
|
27829
|
+
const rect = getSelectedTableRect(editor);
|
|
27830
|
+
const widths = getSelectedColumnWidths(editor, rect);
|
|
27831
|
+
const merged = editor.chain().focus().mergeCells().run();
|
|
27832
|
+
if (!merged) return merged;
|
|
27833
|
+
if (!widths) {
|
|
27834
|
+
dispatchTableLayoutChange(editor);
|
|
27835
|
+
return merged;
|
|
27836
|
+
}
|
|
27837
|
+
const nextRect = getSelectedTableRect(editor);
|
|
27838
|
+
const cellPos = nextRect.map.map[nextRect.top * nextRect.map.width + nextRect.left];
|
|
27839
|
+
const absolutePos = nextRect.tableStart + cellPos;
|
|
27840
|
+
const node = editor.state.doc.nodeAt(absolutePos);
|
|
27841
|
+
if (!node) return merged;
|
|
27842
|
+
editor.view.dispatch(
|
|
27843
|
+
editor.state.tr.setNodeMarkup(absolutePos, node.type, {
|
|
27844
|
+
...node.attrs,
|
|
27845
|
+
colwidth: widths
|
|
27846
|
+
})
|
|
27847
|
+
);
|
|
27848
|
+
dispatchTableLayoutChange(editor);
|
|
27849
|
+
return true;
|
|
27850
|
+
}
|
|
27851
|
+
function runTableCommandAtCellPos(editor, cellPos, command) {
|
|
27852
|
+
if (cellPos == null) return false;
|
|
27853
|
+
focusCell(editor, cellPos);
|
|
27854
|
+
return command(editor.chain().focus(null, { scrollIntoView: false })).run();
|
|
27855
|
+
}
|
|
27856
|
+
function getTableCornerCellPos(editor, activePos) {
|
|
27857
|
+
const tableInfo = findTableInfoFromCellPos(editor, activePos);
|
|
27858
|
+
if (!tableInfo) return null;
|
|
27859
|
+
const map = TableMap.get(tableInfo.table);
|
|
27860
|
+
return tableInfo.tableStart + map.positionAt(map.height - 1, map.width - 1, tableInfo.table);
|
|
27861
|
+
}
|
|
27862
|
+
function replaceTableAtCellPos(editor, cellPos, updateTable) {
|
|
27863
|
+
if (cellPos == null) return false;
|
|
27864
|
+
const tableInfo = findTableInfoFromCellPos(editor, cellPos);
|
|
27865
|
+
if (!tableInfo) return false;
|
|
27866
|
+
const nextTable = updateTable(tableInfo.table);
|
|
27867
|
+
if (!nextTable) return false;
|
|
27868
|
+
editor.view.dispatch(editor.state.tr.replaceWith(tableInfo.tablePos, tableInfo.tablePos + tableInfo.table.nodeSize, nextTable));
|
|
27869
|
+
dispatchTableLayoutChange(editor);
|
|
27870
|
+
return true;
|
|
27871
|
+
}
|
|
27872
|
+
function duplicateTableRowAt(editor, rowIndex, cellPos) {
|
|
27873
|
+
return replaceTableAtCellPos(editor, cellPos, (tableNode) => {
|
|
27874
|
+
const rows = collectChildren(tableNode);
|
|
27875
|
+
const rowNode = rows[rowIndex];
|
|
27876
|
+
if (!rowNode) return null;
|
|
27877
|
+
rows.splice(rowIndex + 1, 0, rowNode.copy(rowNode.content));
|
|
27878
|
+
return tableNode.type.create(tableNode.attrs, rows);
|
|
27879
|
+
});
|
|
27880
|
+
}
|
|
27881
|
+
function clearTableRowAt(editor, rowIndex, cellPos) {
|
|
27882
|
+
return replaceTableAtCellPos(editor, cellPos, (tableNode) => {
|
|
27883
|
+
const rows = collectChildren(tableNode);
|
|
27884
|
+
const rowNode = rows[rowIndex];
|
|
27885
|
+
if (!rowNode) return null;
|
|
27886
|
+
const cells = collectChildren(rowNode).map((cellNode) => createEmptyCellNode(cellNode));
|
|
27887
|
+
rows[rowIndex] = rowNode.type.create(rowNode.attrs, cells);
|
|
27888
|
+
return tableNode.type.create(tableNode.attrs, rows);
|
|
27889
|
+
});
|
|
27890
|
+
}
|
|
27891
|
+
function duplicateTableColumnAt(editor, columnIndex, cellPos) {
|
|
27892
|
+
return replaceTableAtCellPos(editor, cellPos, (tableNode) => {
|
|
27893
|
+
const rows = collectChildren(tableNode).map((rowNode) => {
|
|
27894
|
+
const cells = collectChildren(rowNode);
|
|
27895
|
+
const cellNode = cells[columnIndex];
|
|
27896
|
+
if (!cellNode) return rowNode;
|
|
27897
|
+
cells.splice(columnIndex + 1, 0, cellNode.copy(cellNode.content));
|
|
27898
|
+
return rowNode.type.create(rowNode.attrs, cells);
|
|
27899
|
+
});
|
|
27900
|
+
return tableNode.type.create(tableNode.attrs, rows);
|
|
27901
|
+
});
|
|
27902
|
+
}
|
|
27903
|
+
function clearTableColumnAt(editor, columnIndex, cellPos) {
|
|
27904
|
+
return replaceTableAtCellPos(editor, cellPos, (tableNode) => {
|
|
27905
|
+
const rows = collectChildren(tableNode).map((rowNode) => {
|
|
27906
|
+
const cells = collectChildren(rowNode);
|
|
27907
|
+
const cellNode = cells[columnIndex];
|
|
27908
|
+
if (!cellNode) return rowNode;
|
|
27909
|
+
cells[columnIndex] = createEmptyCellNode(cellNode);
|
|
27910
|
+
return rowNode.type.create(rowNode.attrs, cells);
|
|
27911
|
+
});
|
|
27912
|
+
return tableNode.type.create(tableNode.attrs, rows);
|
|
27913
|
+
});
|
|
27914
|
+
}
|
|
27915
|
+
function expandTableFromCell(editor, activeCellPos, rows, columns) {
|
|
27916
|
+
let cornerCellPos = getTableCornerCellPos(editor, activeCellPos);
|
|
27917
|
+
if (cornerCellPos == null) return false;
|
|
27918
|
+
for (let index = 0; index < rows; index += 1) {
|
|
27919
|
+
const ok = runTableCommandAtCellPos(editor, cornerCellPos, (chain) => chain.addRowAfter());
|
|
27920
|
+
if (!ok) return false;
|
|
27921
|
+
cornerCellPos = getTableCornerCellPos(editor, cornerCellPos);
|
|
27922
|
+
if (cornerCellPos == null) return false;
|
|
27923
|
+
}
|
|
27924
|
+
for (let index = 0; index < columns; index += 1) {
|
|
27925
|
+
const ok = runTableCommandAtCellPos(editor, cornerCellPos, (chain) => chain.addColumnAfter());
|
|
27926
|
+
if (!ok) return false;
|
|
27927
|
+
cornerCellPos = getTableCornerCellPos(editor, cornerCellPos);
|
|
27928
|
+
if (cornerCellPos == null) return false;
|
|
27929
|
+
}
|
|
27930
|
+
dispatchTableLayoutChange(editor);
|
|
27931
|
+
return true;
|
|
27932
|
+
}
|
|
27933
|
+
|
|
27648
27934
|
// src/components/UEditor/typography-options.ts
|
|
27649
27935
|
function normalizeStyleValue(value) {
|
|
27650
27936
|
return typeof value === "string" ? value.trim().replace(/^['"]|['"]$/g, "") : "";
|
|
@@ -27840,6 +28126,8 @@ var EditorToolbar = ({
|
|
|
27840
28126
|
const currentTableAlign = tableAlignAttr === "center" || tableAlignAttr === "right" ? tableAlignAttr : "left";
|
|
27841
28127
|
const isTableSelected = tableInfo !== null;
|
|
27842
28128
|
const hasTableContext = isTableSelected || tableCommandAnchorPosRef.current !== null;
|
|
28129
|
+
const canMergeCells = hasTableContext && editor.can().mergeCells();
|
|
28130
|
+
const canSplitCell = hasTableContext && editor.can().splitCell();
|
|
27843
28131
|
const currentFontFamily = normalizeStyleValue(textStyleAttrs.fontFamily);
|
|
27844
28132
|
const currentFontSize = normalizeStyleValue(textStyleAttrs.fontSize);
|
|
27845
28133
|
const currentTextColor = normalizeStyleValue(textStyleAttrs.color) || "inherit";
|
|
@@ -28609,13 +28897,68 @@ var EditorToolbar = ({
|
|
|
28609
28897
|
),
|
|
28610
28898
|
/* @__PURE__ */ jsx85(ToolbarDivider, {}),
|
|
28611
28899
|
/* @__PURE__ */ jsx85(ToolbarButton, { onClick: () => editor.chain().focus().undo().run(), disabled: !editor.can().undo(), title: t("toolbar.undo"), children: /* @__PURE__ */ jsx85(UndoIcon, { className: "w-4 h-4" }) }),
|
|
28612
|
-
/* @__PURE__ */ jsx85(ToolbarButton, { onClick: () => editor.chain().focus().redo().run(), disabled: !editor.can().redo(), title: t("toolbar.redo"), children: /* @__PURE__ */ jsx85(RedoIcon, { className: "w-4 h-4" }) })
|
|
28613
|
-
|
|
28614
|
-
}
|
|
28615
|
-
|
|
28616
|
-
|
|
28617
|
-
|
|
28618
|
-
|
|
28900
|
+
/* @__PURE__ */ jsx85(ToolbarButton, { onClick: () => editor.chain().focus().redo().run(), disabled: !editor.can().redo(), title: t("toolbar.redo"), children: /* @__PURE__ */ jsx85(RedoIcon, { className: "w-4 h-4" }) }),
|
|
28901
|
+
hasTableContext && /* @__PURE__ */ jsxs71(Fragment28, { children: [
|
|
28902
|
+
/* @__PURE__ */ jsx85(ToolbarDivider, {}),
|
|
28903
|
+
/* @__PURE__ */ jsx85(
|
|
28904
|
+
ToolbarButton,
|
|
28905
|
+
{
|
|
28906
|
+
onClick: () => editor.chain().focus().addColumnBefore().run(),
|
|
28907
|
+
disabled: !editor.can().addColumnBefore(),
|
|
28908
|
+
title: t("tableMenu.addColumnBefore"),
|
|
28909
|
+
children: /* @__PURE__ */ jsx85(ArrowLeft, { className: "w-4 h-4" })
|
|
28910
|
+
}
|
|
28911
|
+
),
|
|
28912
|
+
/* @__PURE__ */ jsx85(
|
|
28913
|
+
ToolbarButton,
|
|
28914
|
+
{
|
|
28915
|
+
onClick: () => editor.chain().focus().addColumnAfter().run(),
|
|
28916
|
+
disabled: !editor.can().addColumnAfter(),
|
|
28917
|
+
title: t("tableMenu.addColumnAfter"),
|
|
28918
|
+
children: /* @__PURE__ */ jsx85(ArrowRight, { className: "w-4 h-4" })
|
|
28919
|
+
}
|
|
28920
|
+
),
|
|
28921
|
+
/* @__PURE__ */ jsx85(
|
|
28922
|
+
ToolbarButton,
|
|
28923
|
+
{
|
|
28924
|
+
onClick: () => editor.chain().focus().addRowBefore().run(),
|
|
28925
|
+
disabled: !editor.can().addRowBefore(),
|
|
28926
|
+
title: t("tableMenu.addRowBefore"),
|
|
28927
|
+
children: /* @__PURE__ */ jsx85(ArrowUp, { className: "w-4 h-4" })
|
|
28928
|
+
}
|
|
28929
|
+
),
|
|
28930
|
+
/* @__PURE__ */ jsx85(
|
|
28931
|
+
ToolbarButton,
|
|
28932
|
+
{
|
|
28933
|
+
onClick: () => editor.chain().focus().addRowAfter().run(),
|
|
28934
|
+
disabled: !editor.can().addRowAfter(),
|
|
28935
|
+
title: t("tableMenu.addRowAfter"),
|
|
28936
|
+
children: /* @__PURE__ */ jsx85(ArrowDown, { className: "w-4 h-4" })
|
|
28937
|
+
}
|
|
28938
|
+
),
|
|
28939
|
+
/* @__PURE__ */ jsx85(
|
|
28940
|
+
ToolbarButton,
|
|
28941
|
+
{
|
|
28942
|
+
onClick: () => {
|
|
28943
|
+
if (canSplitCell) {
|
|
28944
|
+
editor.chain().focus().splitCell().run();
|
|
28945
|
+
return;
|
|
28946
|
+
}
|
|
28947
|
+
mergeTableCellsPreservingColumnWidths(editor);
|
|
28948
|
+
},
|
|
28949
|
+
active: canSplitCell,
|
|
28950
|
+
disabled: !canMergeCells && !canSplitCell,
|
|
28951
|
+
title: canSplitCell ? t("tableMenu.splitCell") : t("tableMenu.mergeCells"),
|
|
28952
|
+
children: /* @__PURE__ */ jsx85(TableCellsMerge, { className: "w-4 h-4" })
|
|
28953
|
+
}
|
|
28954
|
+
)
|
|
28955
|
+
] })
|
|
28956
|
+
] });
|
|
28957
|
+
};
|
|
28958
|
+
|
|
28959
|
+
// src/components/UEditor/menus.tsx
|
|
28960
|
+
import { useCallback as useCallback22, useEffect as useEffect36, useMemo as useMemo23, useRef as useRef33, useState as useState48 } from "react";
|
|
28961
|
+
import { useEditorState as useEditorState2 } from "@tiptap/react";
|
|
28619
28962
|
import { isInTable as isSelectionInTable, setCellAttr } from "@tiptap/pm/tables";
|
|
28620
28963
|
import { createPortal as createPortal8 } from "react-dom";
|
|
28621
28964
|
import {
|
|
@@ -28631,7 +28974,7 @@ import {
|
|
|
28631
28974
|
RotateCcw as RotateCcw3,
|
|
28632
28975
|
Subscript as SubscriptIcon2,
|
|
28633
28976
|
Superscript as SuperscriptIcon2,
|
|
28634
|
-
TableCellsMerge,
|
|
28977
|
+
TableCellsMerge as TableCellsMerge2,
|
|
28635
28978
|
Trash2 as Trash23,
|
|
28636
28979
|
Type as Type3,
|
|
28637
28980
|
Underline as UnderlineIcon2,
|
|
@@ -28640,231 +28983,6 @@ import {
|
|
|
28640
28983
|
Unlink,
|
|
28641
28984
|
ExternalLink as ExternalLink3
|
|
28642
28985
|
} from "lucide-react";
|
|
28643
|
-
|
|
28644
|
-
// src/components/UEditor/table-cell-commands.ts
|
|
28645
|
-
import { TextSelection as TextSelection2 } from "@tiptap/pm/state";
|
|
28646
|
-
import { selectedRect, TableMap } from "@tiptap/pm/tables";
|
|
28647
|
-
function getCellSelectionPositions(selection) {
|
|
28648
|
-
const value = selection;
|
|
28649
|
-
const anchor = value.$anchorCell?.pos;
|
|
28650
|
-
const head = value.$headCell?.pos;
|
|
28651
|
-
return typeof anchor === "number" && typeof head === "number" ? { anchor, head } : null;
|
|
28652
|
-
}
|
|
28653
|
-
function findTableInfoFromCellPos(editor, cellPos) {
|
|
28654
|
-
const $pos = editor.state.doc.resolve(cellPos);
|
|
28655
|
-
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
28656
|
-
const node = $pos.node(depth);
|
|
28657
|
-
if (node.type.name === "table") {
|
|
28658
|
-
return {
|
|
28659
|
-
table: node,
|
|
28660
|
-
tablePos: $pos.before(depth),
|
|
28661
|
-
tableStart: $pos.start(depth)
|
|
28662
|
-
};
|
|
28663
|
-
}
|
|
28664
|
-
}
|
|
28665
|
-
return null;
|
|
28666
|
-
}
|
|
28667
|
-
function getFocusableCellPos(editor, cellPos) {
|
|
28668
|
-
const cellNode = editor.state.doc.nodeAt(cellPos);
|
|
28669
|
-
if (!cellNode) return cellPos + 1;
|
|
28670
|
-
let offset = cellPos + 1;
|
|
28671
|
-
let node = cellNode.firstChild ?? null;
|
|
28672
|
-
while (node && !node.isTextblock) {
|
|
28673
|
-
offset += 1;
|
|
28674
|
-
node = node.firstChild ?? null;
|
|
28675
|
-
}
|
|
28676
|
-
return node?.isTextblock ? offset + 1 : cellPos + 1;
|
|
28677
|
-
}
|
|
28678
|
-
function focusCell(editor, cellPos) {
|
|
28679
|
-
const selection = TextSelection2.near(editor.state.doc.resolve(getFocusableCellPos(editor, cellPos)));
|
|
28680
|
-
editor.view.dispatch(editor.state.tr.setSelection(selection));
|
|
28681
|
-
editor.view.focus();
|
|
28682
|
-
}
|
|
28683
|
-
function collectChildren(node) {
|
|
28684
|
-
const children = [];
|
|
28685
|
-
node.forEach((child) => children.push(child));
|
|
28686
|
-
return children;
|
|
28687
|
-
}
|
|
28688
|
-
function createEmptyCellNode(cellNode) {
|
|
28689
|
-
return cellNode.type.createAndFill(cellNode.attrs) ?? cellNode;
|
|
28690
|
-
}
|
|
28691
|
-
function getSelectedTableRect(editor) {
|
|
28692
|
-
const cellSelection = getCellSelectionPositions(editor.state.selection);
|
|
28693
|
-
if (cellSelection) {
|
|
28694
|
-
const tableInfo = findTableInfoFromCellPos(editor, cellSelection.anchor);
|
|
28695
|
-
if (tableInfo) {
|
|
28696
|
-
const map = TableMap.get(tableInfo.table);
|
|
28697
|
-
const rect = map.rectBetween(
|
|
28698
|
-
cellSelection.anchor - tableInfo.tableStart,
|
|
28699
|
-
cellSelection.head - tableInfo.tableStart
|
|
28700
|
-
);
|
|
28701
|
-
return {
|
|
28702
|
-
...rect,
|
|
28703
|
-
map,
|
|
28704
|
-
table: tableInfo.table,
|
|
28705
|
-
tableStart: tableInfo.tableStart
|
|
28706
|
-
};
|
|
28707
|
-
}
|
|
28708
|
-
}
|
|
28709
|
-
return selectedRect(editor.state);
|
|
28710
|
-
}
|
|
28711
|
-
function parsePixelWidth(value) {
|
|
28712
|
-
if (!value) return null;
|
|
28713
|
-
const parsed = Number.parseFloat(value);
|
|
28714
|
-
return Number.isFinite(parsed) && parsed > 0 ? Math.round(parsed) : null;
|
|
28715
|
-
}
|
|
28716
|
-
function getDomColumnWidths(editor, rect) {
|
|
28717
|
-
const tableDom = editor.view.nodeDOM(rect.tableStart - 1);
|
|
28718
|
-
if (!(tableDom instanceof HTMLTableElement)) return null;
|
|
28719
|
-
const cols = Array.from(tableDom.querySelectorAll("colgroup > col"));
|
|
28720
|
-
if (cols.length === 0) return null;
|
|
28721
|
-
const widths = [];
|
|
28722
|
-
for (let col = rect.left; col < rect.right; col += 1) {
|
|
28723
|
-
const colElement = cols[col];
|
|
28724
|
-
if (!colElement) return null;
|
|
28725
|
-
const width = parsePixelWidth(colElement.style.width) ?? parsePixelWidth(colElement.getAttribute("width")) ?? Math.round(colElement.getBoundingClientRect().width);
|
|
28726
|
-
if (!Number.isFinite(width) || width <= 0) return null;
|
|
28727
|
-
widths.push(width);
|
|
28728
|
-
}
|
|
28729
|
-
return widths.length > 0 ? widths : null;
|
|
28730
|
-
}
|
|
28731
|
-
function getNodeColumnWidths(rect) {
|
|
28732
|
-
const widths = [];
|
|
28733
|
-
for (let col = rect.left; col < rect.right; col += 1) {
|
|
28734
|
-
let width = null;
|
|
28735
|
-
const seen = /* @__PURE__ */ new Set();
|
|
28736
|
-
for (let row = 0; row < rect.map.height && width == null; row += 1) {
|
|
28737
|
-
const cellPos = rect.map.map[row * rect.map.width + col];
|
|
28738
|
-
if (seen.has(cellPos)) continue;
|
|
28739
|
-
seen.add(cellPos);
|
|
28740
|
-
const cell = rect.table.nodeAt(cellPos);
|
|
28741
|
-
const colwidth = cell?.attrs.colwidth;
|
|
28742
|
-
if (!Array.isArray(colwidth)) continue;
|
|
28743
|
-
const cellLeft = rect.map.colCount(cellPos);
|
|
28744
|
-
const widthIndex = col - cellLeft;
|
|
28745
|
-
const candidate = colwidth[widthIndex];
|
|
28746
|
-
if (typeof candidate === "number" && candidate > 0) {
|
|
28747
|
-
width = candidate;
|
|
28748
|
-
}
|
|
28749
|
-
}
|
|
28750
|
-
if (width == null) return null;
|
|
28751
|
-
widths.push(width);
|
|
28752
|
-
}
|
|
28753
|
-
return widths.length > 0 ? widths : null;
|
|
28754
|
-
}
|
|
28755
|
-
function getSelectedColumnWidths(editor, rect) {
|
|
28756
|
-
return getDomColumnWidths(editor, rect) ?? getNodeColumnWidths(rect);
|
|
28757
|
-
}
|
|
28758
|
-
function dispatchTableLayoutChange(editor) {
|
|
28759
|
-
editor.view.dom.dispatchEvent(new CustomEvent(UEDITOR_TABLE_LAYOUT_CHANGE_EVENT, { bubbles: true }));
|
|
28760
|
-
}
|
|
28761
|
-
function mergeTableCellsPreservingColumnWidths(editor) {
|
|
28762
|
-
const rect = getSelectedTableRect(editor);
|
|
28763
|
-
const widths = getSelectedColumnWidths(editor, rect);
|
|
28764
|
-
const merged = editor.chain().focus().mergeCells().run();
|
|
28765
|
-
if (!merged) return merged;
|
|
28766
|
-
if (!widths) {
|
|
28767
|
-
dispatchTableLayoutChange(editor);
|
|
28768
|
-
return merged;
|
|
28769
|
-
}
|
|
28770
|
-
const nextRect = getSelectedTableRect(editor);
|
|
28771
|
-
const cellPos = nextRect.map.map[nextRect.top * nextRect.map.width + nextRect.left];
|
|
28772
|
-
const absolutePos = nextRect.tableStart + cellPos;
|
|
28773
|
-
const node = editor.state.doc.nodeAt(absolutePos);
|
|
28774
|
-
if (!node) return merged;
|
|
28775
|
-
editor.view.dispatch(
|
|
28776
|
-
editor.state.tr.setNodeMarkup(absolutePos, node.type, {
|
|
28777
|
-
...node.attrs,
|
|
28778
|
-
colwidth: widths
|
|
28779
|
-
})
|
|
28780
|
-
);
|
|
28781
|
-
dispatchTableLayoutChange(editor);
|
|
28782
|
-
return true;
|
|
28783
|
-
}
|
|
28784
|
-
function runTableCommandAtCellPos(editor, cellPos, command) {
|
|
28785
|
-
if (cellPos == null) return false;
|
|
28786
|
-
focusCell(editor, cellPos);
|
|
28787
|
-
return command(editor.chain().focus(null, { scrollIntoView: false })).run();
|
|
28788
|
-
}
|
|
28789
|
-
function getTableCornerCellPos(editor, activePos) {
|
|
28790
|
-
const tableInfo = findTableInfoFromCellPos(editor, activePos);
|
|
28791
|
-
if (!tableInfo) return null;
|
|
28792
|
-
const map = TableMap.get(tableInfo.table);
|
|
28793
|
-
return tableInfo.tableStart + map.positionAt(map.height - 1, map.width - 1, tableInfo.table);
|
|
28794
|
-
}
|
|
28795
|
-
function replaceTableAtCellPos(editor, cellPos, updateTable) {
|
|
28796
|
-
if (cellPos == null) return false;
|
|
28797
|
-
const tableInfo = findTableInfoFromCellPos(editor, cellPos);
|
|
28798
|
-
if (!tableInfo) return false;
|
|
28799
|
-
const nextTable = updateTable(tableInfo.table);
|
|
28800
|
-
if (!nextTable) return false;
|
|
28801
|
-
editor.view.dispatch(editor.state.tr.replaceWith(tableInfo.tablePos, tableInfo.tablePos + tableInfo.table.nodeSize, nextTable));
|
|
28802
|
-
dispatchTableLayoutChange(editor);
|
|
28803
|
-
return true;
|
|
28804
|
-
}
|
|
28805
|
-
function duplicateTableRowAt(editor, rowIndex, cellPos) {
|
|
28806
|
-
return replaceTableAtCellPos(editor, cellPos, (tableNode) => {
|
|
28807
|
-
const rows = collectChildren(tableNode);
|
|
28808
|
-
const rowNode = rows[rowIndex];
|
|
28809
|
-
if (!rowNode) return null;
|
|
28810
|
-
rows.splice(rowIndex + 1, 0, rowNode.copy(rowNode.content));
|
|
28811
|
-
return tableNode.type.create(tableNode.attrs, rows);
|
|
28812
|
-
});
|
|
28813
|
-
}
|
|
28814
|
-
function clearTableRowAt(editor, rowIndex, cellPos) {
|
|
28815
|
-
return replaceTableAtCellPos(editor, cellPos, (tableNode) => {
|
|
28816
|
-
const rows = collectChildren(tableNode);
|
|
28817
|
-
const rowNode = rows[rowIndex];
|
|
28818
|
-
if (!rowNode) return null;
|
|
28819
|
-
const cells = collectChildren(rowNode).map((cellNode) => createEmptyCellNode(cellNode));
|
|
28820
|
-
rows[rowIndex] = rowNode.type.create(rowNode.attrs, cells);
|
|
28821
|
-
return tableNode.type.create(tableNode.attrs, rows);
|
|
28822
|
-
});
|
|
28823
|
-
}
|
|
28824
|
-
function duplicateTableColumnAt(editor, columnIndex, cellPos) {
|
|
28825
|
-
return replaceTableAtCellPos(editor, cellPos, (tableNode) => {
|
|
28826
|
-
const rows = collectChildren(tableNode).map((rowNode) => {
|
|
28827
|
-
const cells = collectChildren(rowNode);
|
|
28828
|
-
const cellNode = cells[columnIndex];
|
|
28829
|
-
if (!cellNode) return rowNode;
|
|
28830
|
-
cells.splice(columnIndex + 1, 0, cellNode.copy(cellNode.content));
|
|
28831
|
-
return rowNode.type.create(rowNode.attrs, cells);
|
|
28832
|
-
});
|
|
28833
|
-
return tableNode.type.create(tableNode.attrs, rows);
|
|
28834
|
-
});
|
|
28835
|
-
}
|
|
28836
|
-
function clearTableColumnAt(editor, columnIndex, cellPos) {
|
|
28837
|
-
return replaceTableAtCellPos(editor, cellPos, (tableNode) => {
|
|
28838
|
-
const rows = collectChildren(tableNode).map((rowNode) => {
|
|
28839
|
-
const cells = collectChildren(rowNode);
|
|
28840
|
-
const cellNode = cells[columnIndex];
|
|
28841
|
-
if (!cellNode) return rowNode;
|
|
28842
|
-
cells[columnIndex] = createEmptyCellNode(cellNode);
|
|
28843
|
-
return rowNode.type.create(rowNode.attrs, cells);
|
|
28844
|
-
});
|
|
28845
|
-
return tableNode.type.create(tableNode.attrs, rows);
|
|
28846
|
-
});
|
|
28847
|
-
}
|
|
28848
|
-
function expandTableFromCell(editor, activeCellPos, rows, columns) {
|
|
28849
|
-
let cornerCellPos = getTableCornerCellPos(editor, activeCellPos);
|
|
28850
|
-
if (cornerCellPos == null) return false;
|
|
28851
|
-
for (let index = 0; index < rows; index += 1) {
|
|
28852
|
-
const ok = runTableCommandAtCellPos(editor, cornerCellPos, (chain) => chain.addRowAfter());
|
|
28853
|
-
if (!ok) return false;
|
|
28854
|
-
cornerCellPos = getTableCornerCellPos(editor, cornerCellPos);
|
|
28855
|
-
if (cornerCellPos == null) return false;
|
|
28856
|
-
}
|
|
28857
|
-
for (let index = 0; index < columns; index += 1) {
|
|
28858
|
-
const ok = runTableCommandAtCellPos(editor, cornerCellPos, (chain) => chain.addColumnAfter());
|
|
28859
|
-
if (!ok) return false;
|
|
28860
|
-
cornerCellPos = getTableCornerCellPos(editor, cornerCellPos);
|
|
28861
|
-
if (cornerCellPos == null) return false;
|
|
28862
|
-
}
|
|
28863
|
-
dispatchTableLayoutChange(editor);
|
|
28864
|
-
return true;
|
|
28865
|
-
}
|
|
28866
|
-
|
|
28867
|
-
// src/components/UEditor/menus.tsx
|
|
28868
28986
|
import { Fragment as Fragment29, jsx as jsx86, jsxs as jsxs72 } from "react/jsx-runtime";
|
|
28869
28987
|
var FloatingSlashCommandMenu = ({ editor, onClose }) => {
|
|
28870
28988
|
const t = useSmartTranslations("UEditor");
|
|
@@ -29401,7 +29519,7 @@ var BubbleMenuContent = ({
|
|
|
29401
29519
|
active: canSplitCell,
|
|
29402
29520
|
disabled: !canMergeCells && !canSplitCell,
|
|
29403
29521
|
title: canSplitCell ? t("tableMenu.splitCell") || "Split cell" : t("tableMenu.mergeCells") || "Merge cells",
|
|
29404
|
-
children: /* @__PURE__ */ jsx86(
|
|
29522
|
+
children: /* @__PURE__ */ jsx86(TableCellsMerge2, { className: "w-4 h-4" })
|
|
29405
29523
|
}
|
|
29406
29524
|
)
|
|
29407
29525
|
] }),
|
|
@@ -29465,10 +29583,22 @@ var CustomBubbleMenu = ({
|
|
|
29465
29583
|
setIsVisible(false);
|
|
29466
29584
|
return;
|
|
29467
29585
|
}
|
|
29468
|
-
|
|
29469
|
-
|
|
29470
|
-
|
|
29471
|
-
|
|
29586
|
+
let start;
|
|
29587
|
+
let end;
|
|
29588
|
+
try {
|
|
29589
|
+
start = view.coordsAtPos(from);
|
|
29590
|
+
end = view.coordsAtPos(to);
|
|
29591
|
+
} catch {
|
|
29592
|
+
clearShowTimeout();
|
|
29593
|
+
setIsVisible(false);
|
|
29594
|
+
return;
|
|
29595
|
+
}
|
|
29596
|
+
const viewportPadding = 8;
|
|
29597
|
+
const left = Math.min(
|
|
29598
|
+
window.innerWidth - viewportPadding,
|
|
29599
|
+
Math.max(viewportPadding, (start.left + end.left) / 2)
|
|
29600
|
+
);
|
|
29601
|
+
const top = Math.max(viewportPadding, start.top - BUBBLE_MENU_OFFSET);
|
|
29472
29602
|
setPosition({ top, left });
|
|
29473
29603
|
if (keepOpenRef.current) {
|
|
29474
29604
|
clearShowTimeout();
|
|
@@ -29490,11 +29620,17 @@ var CustomBubbleMenu = ({
|
|
|
29490
29620
|
editor.on("selectionUpdate", updatePosition);
|
|
29491
29621
|
editor.on("focus", updatePosition);
|
|
29492
29622
|
editor.on("blur", handleBlur);
|
|
29623
|
+
editor.on("transaction", updatePosition);
|
|
29624
|
+
editor.on("update", updatePosition);
|
|
29625
|
+
const animationFrameId = requestAnimationFrame(updatePosition);
|
|
29493
29626
|
return () => {
|
|
29627
|
+
cancelAnimationFrame(animationFrameId);
|
|
29494
29628
|
clearShowTimeout();
|
|
29495
29629
|
editor.off("selectionUpdate", updatePosition);
|
|
29496
29630
|
editor.off("focus", updatePosition);
|
|
29497
29631
|
editor.off("blur", handleBlur);
|
|
29632
|
+
editor.off("transaction", updatePosition);
|
|
29633
|
+
editor.off("update", updatePosition);
|
|
29498
29634
|
};
|
|
29499
29635
|
}, [editor]);
|
|
29500
29636
|
if (!isVisible) return null;
|
|
@@ -29504,7 +29640,7 @@ var CustomBubbleMenu = ({
|
|
|
29504
29640
|
{
|
|
29505
29641
|
ref: menuRef,
|
|
29506
29642
|
"data-popover": true,
|
|
29507
|
-
className: "fixed z-99999 flex rounded-xl border border-border/40 bg-card text-card-foreground shadow-lg backdrop-blur-sm overflow-hidden animate-in fade-in-0 zoom-in-95",
|
|
29643
|
+
className: "fixed z-[99999] flex rounded-xl border border-border/40 bg-card text-card-foreground shadow-lg backdrop-blur-sm overflow-hidden animate-in fade-in-0 zoom-in-95",
|
|
29508
29644
|
style: {
|
|
29509
29645
|
top: `${position.top}px`,
|
|
29510
29646
|
left: `${position.left}px`,
|
|
@@ -35427,6 +35563,17 @@ var UEDITOR_PROSEMIRROR_CLASS_NAME = cn(
|
|
|
35427
35563
|
"[&_.is-editor-empty]:before:float-left",
|
|
35428
35564
|
"[&_.is-editor-empty]:before:pointer-events-none",
|
|
35429
35565
|
"[&_.is-editor-empty]:before:h-0",
|
|
35566
|
+
"[&_.ProseMirror-gapcursor]:pointer-events-none",
|
|
35567
|
+
"[&_.ProseMirror-gapcursor]:absolute",
|
|
35568
|
+
"[&_.ProseMirror-gapcursor]:hidden",
|
|
35569
|
+
"[&_.ProseMirror-gapcursor:after]:content-['']",
|
|
35570
|
+
"[&_.ProseMirror-gapcursor:after]:block",
|
|
35571
|
+
"[&_.ProseMirror-gapcursor:after]:absolute",
|
|
35572
|
+
"[&_.ProseMirror-gapcursor:after]:top-[-2px]",
|
|
35573
|
+
"[&_.ProseMirror-gapcursor:after]:w-8",
|
|
35574
|
+
"[&_.ProseMirror-gapcursor:after]:border-t-2",
|
|
35575
|
+
"[&_.ProseMirror-gapcursor:after]:border-primary",
|
|
35576
|
+
"[&.ProseMirror-focused_.ProseMirror-gapcursor]:block",
|
|
35430
35577
|
"[&_ul[data-type='taskList']]:list-none",
|
|
35431
35578
|
"[&_ul[data-type='taskList']]:pl-0",
|
|
35432
35579
|
"[&_ul[data-type='taskList']_li]:flex",
|
|
@@ -35459,6 +35606,7 @@ var UEDITOR_PROSEMIRROR_CLASS_NAME = cn(
|
|
|
35459
35606
|
"[&_.tableWrapper::-webkit-scrollbar-thumb]:border-transparent",
|
|
35460
35607
|
"[&_.tableWrapper::-webkit-scrollbar-thumb]:bg-border/70",
|
|
35461
35608
|
"[&_.tableWrapper::-webkit-scrollbar-thumb:hover]:bg-muted-foreground/45",
|
|
35609
|
+
"[&_table]:w-auto",
|
|
35462
35610
|
"[&_table]:table-fixed",
|
|
35463
35611
|
"[&_table]:overflow-hidden",
|
|
35464
35612
|
"[&_table]:select-text",
|
|
@@ -36741,7 +36889,7 @@ var MenuBar = ({
|
|
|
36741
36889
|
"div",
|
|
36742
36890
|
{
|
|
36743
36891
|
"data-testid": "preview-content",
|
|
36744
|
-
className:
|
|
36892
|
+
className: UEDITOR_PROSEMIRROR_CLASS_NAME,
|
|
36745
36893
|
dangerouslySetInnerHTML: { __html: editor.getHTML() }
|
|
36746
36894
|
}
|
|
36747
36895
|
)
|