@underverse-ui/underverse 1.0.142 → 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 +284 -228
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +287 -230
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -27147,7 +27147,7 @@ function buildUEditorExtensions({
|
|
|
27147
27147
|
handleWidth: 10,
|
|
27148
27148
|
allowTableNodeSelection: true,
|
|
27149
27149
|
HTMLAttributes: {
|
|
27150
|
-
class: "border-collapse
|
|
27150
|
+
class: "border-collapse my-4"
|
|
27151
27151
|
}
|
|
27152
27152
|
}),
|
|
27153
27153
|
table_row_default,
|
|
@@ -27230,6 +27230,7 @@ import {
|
|
|
27230
27230
|
Subscript as SubscriptIcon,
|
|
27231
27231
|
Superscript as SuperscriptIcon,
|
|
27232
27232
|
Table as TableIcon,
|
|
27233
|
+
TableCellsMerge,
|
|
27233
27234
|
Trash2 as Trash22,
|
|
27234
27235
|
Type as Type2,
|
|
27235
27236
|
Underline as UnderlineIcon,
|
|
@@ -27707,6 +27708,229 @@ var ImageInput = ({ onSubmit, onCancel }) => {
|
|
|
27707
27708
|
] });
|
|
27708
27709
|
};
|
|
27709
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
|
+
|
|
27710
27934
|
// src/components/UEditor/typography-options.ts
|
|
27711
27935
|
function normalizeStyleValue(value) {
|
|
27712
27936
|
return typeof value === "string" ? value.trim().replace(/^['"]|['"]$/g, "") : "";
|
|
@@ -27902,6 +28126,8 @@ var EditorToolbar = ({
|
|
|
27902
28126
|
const currentTableAlign = tableAlignAttr === "center" || tableAlignAttr === "right" ? tableAlignAttr : "left";
|
|
27903
28127
|
const isTableSelected = tableInfo !== null;
|
|
27904
28128
|
const hasTableContext = isTableSelected || tableCommandAnchorPosRef.current !== null;
|
|
28129
|
+
const canMergeCells = hasTableContext && editor.can().mergeCells();
|
|
28130
|
+
const canSplitCell = hasTableContext && editor.can().splitCell();
|
|
27905
28131
|
const currentFontFamily = normalizeStyleValue(textStyleAttrs.fontFamily);
|
|
27906
28132
|
const currentFontSize = normalizeStyleValue(textStyleAttrs.fontSize);
|
|
27907
28133
|
const currentTextColor = normalizeStyleValue(textStyleAttrs.color) || "inherit";
|
|
@@ -28671,7 +28897,62 @@ var EditorToolbar = ({
|
|
|
28671
28897
|
),
|
|
28672
28898
|
/* @__PURE__ */ jsx85(ToolbarDivider, {}),
|
|
28673
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" }) }),
|
|
28674
|
-
/* @__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" }) })
|
|
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
|
+
] })
|
|
28675
28956
|
] });
|
|
28676
28957
|
};
|
|
28677
28958
|
|
|
@@ -28693,7 +28974,7 @@ import {
|
|
|
28693
28974
|
RotateCcw as RotateCcw3,
|
|
28694
28975
|
Subscript as SubscriptIcon2,
|
|
28695
28976
|
Superscript as SuperscriptIcon2,
|
|
28696
|
-
TableCellsMerge,
|
|
28977
|
+
TableCellsMerge as TableCellsMerge2,
|
|
28697
28978
|
Trash2 as Trash23,
|
|
28698
28979
|
Type as Type3,
|
|
28699
28980
|
Underline as UnderlineIcon2,
|
|
@@ -28702,231 +28983,6 @@ import {
|
|
|
28702
28983
|
Unlink,
|
|
28703
28984
|
ExternalLink as ExternalLink3
|
|
28704
28985
|
} from "lucide-react";
|
|
28705
|
-
|
|
28706
|
-
// src/components/UEditor/table-cell-commands.ts
|
|
28707
|
-
import { TextSelection as TextSelection2 } from "@tiptap/pm/state";
|
|
28708
|
-
import { selectedRect, TableMap } from "@tiptap/pm/tables";
|
|
28709
|
-
function getCellSelectionPositions(selection) {
|
|
28710
|
-
const value = selection;
|
|
28711
|
-
const anchor = value.$anchorCell?.pos;
|
|
28712
|
-
const head = value.$headCell?.pos;
|
|
28713
|
-
return typeof anchor === "number" && typeof head === "number" ? { anchor, head } : null;
|
|
28714
|
-
}
|
|
28715
|
-
function findTableInfoFromCellPos(editor, cellPos) {
|
|
28716
|
-
const $pos = editor.state.doc.resolve(cellPos);
|
|
28717
|
-
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
28718
|
-
const node = $pos.node(depth);
|
|
28719
|
-
if (node.type.name === "table") {
|
|
28720
|
-
return {
|
|
28721
|
-
table: node,
|
|
28722
|
-
tablePos: $pos.before(depth),
|
|
28723
|
-
tableStart: $pos.start(depth)
|
|
28724
|
-
};
|
|
28725
|
-
}
|
|
28726
|
-
}
|
|
28727
|
-
return null;
|
|
28728
|
-
}
|
|
28729
|
-
function getFocusableCellPos(editor, cellPos) {
|
|
28730
|
-
const cellNode = editor.state.doc.nodeAt(cellPos);
|
|
28731
|
-
if (!cellNode) return cellPos + 1;
|
|
28732
|
-
let offset = cellPos + 1;
|
|
28733
|
-
let node = cellNode.firstChild ?? null;
|
|
28734
|
-
while (node && !node.isTextblock) {
|
|
28735
|
-
offset += 1;
|
|
28736
|
-
node = node.firstChild ?? null;
|
|
28737
|
-
}
|
|
28738
|
-
return node?.isTextblock ? offset + 1 : cellPos + 1;
|
|
28739
|
-
}
|
|
28740
|
-
function focusCell(editor, cellPos) {
|
|
28741
|
-
const selection = TextSelection2.near(editor.state.doc.resolve(getFocusableCellPos(editor, cellPos)));
|
|
28742
|
-
editor.view.dispatch(editor.state.tr.setSelection(selection));
|
|
28743
|
-
editor.view.focus();
|
|
28744
|
-
}
|
|
28745
|
-
function collectChildren(node) {
|
|
28746
|
-
const children = [];
|
|
28747
|
-
node.forEach((child) => children.push(child));
|
|
28748
|
-
return children;
|
|
28749
|
-
}
|
|
28750
|
-
function createEmptyCellNode(cellNode) {
|
|
28751
|
-
return cellNode.type.createAndFill(cellNode.attrs) ?? cellNode;
|
|
28752
|
-
}
|
|
28753
|
-
function getSelectedTableRect(editor) {
|
|
28754
|
-
const cellSelection = getCellSelectionPositions(editor.state.selection);
|
|
28755
|
-
if (cellSelection) {
|
|
28756
|
-
const tableInfo = findTableInfoFromCellPos(editor, cellSelection.anchor);
|
|
28757
|
-
if (tableInfo) {
|
|
28758
|
-
const map = TableMap.get(tableInfo.table);
|
|
28759
|
-
const rect = map.rectBetween(
|
|
28760
|
-
cellSelection.anchor - tableInfo.tableStart,
|
|
28761
|
-
cellSelection.head - tableInfo.tableStart
|
|
28762
|
-
);
|
|
28763
|
-
return {
|
|
28764
|
-
...rect,
|
|
28765
|
-
map,
|
|
28766
|
-
table: tableInfo.table,
|
|
28767
|
-
tableStart: tableInfo.tableStart
|
|
28768
|
-
};
|
|
28769
|
-
}
|
|
28770
|
-
}
|
|
28771
|
-
return selectedRect(editor.state);
|
|
28772
|
-
}
|
|
28773
|
-
function parsePixelWidth(value) {
|
|
28774
|
-
if (!value) return null;
|
|
28775
|
-
const parsed = Number.parseFloat(value);
|
|
28776
|
-
return Number.isFinite(parsed) && parsed > 0 ? Math.round(parsed) : null;
|
|
28777
|
-
}
|
|
28778
|
-
function getDomColumnWidths(editor, rect) {
|
|
28779
|
-
const tableDom = editor.view.nodeDOM(rect.tableStart - 1);
|
|
28780
|
-
if (!(tableDom instanceof HTMLTableElement)) return null;
|
|
28781
|
-
const cols = Array.from(tableDom.querySelectorAll("colgroup > col"));
|
|
28782
|
-
if (cols.length === 0) return null;
|
|
28783
|
-
const widths = [];
|
|
28784
|
-
for (let col = rect.left; col < rect.right; col += 1) {
|
|
28785
|
-
const colElement = cols[col];
|
|
28786
|
-
if (!colElement) return null;
|
|
28787
|
-
const width = parsePixelWidth(colElement.style.width) ?? parsePixelWidth(colElement.getAttribute("width")) ?? Math.round(colElement.getBoundingClientRect().width);
|
|
28788
|
-
if (!Number.isFinite(width) || width <= 0) return null;
|
|
28789
|
-
widths.push(width);
|
|
28790
|
-
}
|
|
28791
|
-
return widths.length > 0 ? widths : null;
|
|
28792
|
-
}
|
|
28793
|
-
function getNodeColumnWidths(rect) {
|
|
28794
|
-
const widths = [];
|
|
28795
|
-
for (let col = rect.left; col < rect.right; col += 1) {
|
|
28796
|
-
let width = null;
|
|
28797
|
-
const seen = /* @__PURE__ */ new Set();
|
|
28798
|
-
for (let row = 0; row < rect.map.height && width == null; row += 1) {
|
|
28799
|
-
const cellPos = rect.map.map[row * rect.map.width + col];
|
|
28800
|
-
if (seen.has(cellPos)) continue;
|
|
28801
|
-
seen.add(cellPos);
|
|
28802
|
-
const cell = rect.table.nodeAt(cellPos);
|
|
28803
|
-
const colwidth = cell?.attrs.colwidth;
|
|
28804
|
-
if (!Array.isArray(colwidth)) continue;
|
|
28805
|
-
const cellLeft = rect.map.colCount(cellPos);
|
|
28806
|
-
const widthIndex = col - cellLeft;
|
|
28807
|
-
const candidate = colwidth[widthIndex];
|
|
28808
|
-
if (typeof candidate === "number" && candidate > 0) {
|
|
28809
|
-
width = candidate;
|
|
28810
|
-
}
|
|
28811
|
-
}
|
|
28812
|
-
if (width == null) return null;
|
|
28813
|
-
widths.push(width);
|
|
28814
|
-
}
|
|
28815
|
-
return widths.length > 0 ? widths : null;
|
|
28816
|
-
}
|
|
28817
|
-
function getSelectedColumnWidths(editor, rect) {
|
|
28818
|
-
return getDomColumnWidths(editor, rect) ?? getNodeColumnWidths(rect);
|
|
28819
|
-
}
|
|
28820
|
-
function dispatchTableLayoutChange(editor) {
|
|
28821
|
-
editor.view.dom.dispatchEvent(new CustomEvent(UEDITOR_TABLE_LAYOUT_CHANGE_EVENT, { bubbles: true }));
|
|
28822
|
-
}
|
|
28823
|
-
function mergeTableCellsPreservingColumnWidths(editor) {
|
|
28824
|
-
const rect = getSelectedTableRect(editor);
|
|
28825
|
-
const widths = getSelectedColumnWidths(editor, rect);
|
|
28826
|
-
const merged = editor.chain().focus().mergeCells().run();
|
|
28827
|
-
if (!merged) return merged;
|
|
28828
|
-
if (!widths) {
|
|
28829
|
-
dispatchTableLayoutChange(editor);
|
|
28830
|
-
return merged;
|
|
28831
|
-
}
|
|
28832
|
-
const nextRect = getSelectedTableRect(editor);
|
|
28833
|
-
const cellPos = nextRect.map.map[nextRect.top * nextRect.map.width + nextRect.left];
|
|
28834
|
-
const absolutePos = nextRect.tableStart + cellPos;
|
|
28835
|
-
const node = editor.state.doc.nodeAt(absolutePos);
|
|
28836
|
-
if (!node) return merged;
|
|
28837
|
-
editor.view.dispatch(
|
|
28838
|
-
editor.state.tr.setNodeMarkup(absolutePos, node.type, {
|
|
28839
|
-
...node.attrs,
|
|
28840
|
-
colwidth: widths
|
|
28841
|
-
})
|
|
28842
|
-
);
|
|
28843
|
-
dispatchTableLayoutChange(editor);
|
|
28844
|
-
return true;
|
|
28845
|
-
}
|
|
28846
|
-
function runTableCommandAtCellPos(editor, cellPos, command) {
|
|
28847
|
-
if (cellPos == null) return false;
|
|
28848
|
-
focusCell(editor, cellPos);
|
|
28849
|
-
return command(editor.chain().focus(null, { scrollIntoView: false })).run();
|
|
28850
|
-
}
|
|
28851
|
-
function getTableCornerCellPos(editor, activePos) {
|
|
28852
|
-
const tableInfo = findTableInfoFromCellPos(editor, activePos);
|
|
28853
|
-
if (!tableInfo) return null;
|
|
28854
|
-
const map = TableMap.get(tableInfo.table);
|
|
28855
|
-
return tableInfo.tableStart + map.positionAt(map.height - 1, map.width - 1, tableInfo.table);
|
|
28856
|
-
}
|
|
28857
|
-
function replaceTableAtCellPos(editor, cellPos, updateTable) {
|
|
28858
|
-
if (cellPos == null) return false;
|
|
28859
|
-
const tableInfo = findTableInfoFromCellPos(editor, cellPos);
|
|
28860
|
-
if (!tableInfo) return false;
|
|
28861
|
-
const nextTable = updateTable(tableInfo.table);
|
|
28862
|
-
if (!nextTable) return false;
|
|
28863
|
-
editor.view.dispatch(editor.state.tr.replaceWith(tableInfo.tablePos, tableInfo.tablePos + tableInfo.table.nodeSize, nextTable));
|
|
28864
|
-
dispatchTableLayoutChange(editor);
|
|
28865
|
-
return true;
|
|
28866
|
-
}
|
|
28867
|
-
function duplicateTableRowAt(editor, rowIndex, cellPos) {
|
|
28868
|
-
return replaceTableAtCellPos(editor, cellPos, (tableNode) => {
|
|
28869
|
-
const rows = collectChildren(tableNode);
|
|
28870
|
-
const rowNode = rows[rowIndex];
|
|
28871
|
-
if (!rowNode) return null;
|
|
28872
|
-
rows.splice(rowIndex + 1, 0, rowNode.copy(rowNode.content));
|
|
28873
|
-
return tableNode.type.create(tableNode.attrs, rows);
|
|
28874
|
-
});
|
|
28875
|
-
}
|
|
28876
|
-
function clearTableRowAt(editor, rowIndex, cellPos) {
|
|
28877
|
-
return replaceTableAtCellPos(editor, cellPos, (tableNode) => {
|
|
28878
|
-
const rows = collectChildren(tableNode);
|
|
28879
|
-
const rowNode = rows[rowIndex];
|
|
28880
|
-
if (!rowNode) return null;
|
|
28881
|
-
const cells = collectChildren(rowNode).map((cellNode) => createEmptyCellNode(cellNode));
|
|
28882
|
-
rows[rowIndex] = rowNode.type.create(rowNode.attrs, cells);
|
|
28883
|
-
return tableNode.type.create(tableNode.attrs, rows);
|
|
28884
|
-
});
|
|
28885
|
-
}
|
|
28886
|
-
function duplicateTableColumnAt(editor, columnIndex, cellPos) {
|
|
28887
|
-
return replaceTableAtCellPos(editor, cellPos, (tableNode) => {
|
|
28888
|
-
const rows = collectChildren(tableNode).map((rowNode) => {
|
|
28889
|
-
const cells = collectChildren(rowNode);
|
|
28890
|
-
const cellNode = cells[columnIndex];
|
|
28891
|
-
if (!cellNode) return rowNode;
|
|
28892
|
-
cells.splice(columnIndex + 1, 0, cellNode.copy(cellNode.content));
|
|
28893
|
-
return rowNode.type.create(rowNode.attrs, cells);
|
|
28894
|
-
});
|
|
28895
|
-
return tableNode.type.create(tableNode.attrs, rows);
|
|
28896
|
-
});
|
|
28897
|
-
}
|
|
28898
|
-
function clearTableColumnAt(editor, columnIndex, cellPos) {
|
|
28899
|
-
return replaceTableAtCellPos(editor, cellPos, (tableNode) => {
|
|
28900
|
-
const rows = collectChildren(tableNode).map((rowNode) => {
|
|
28901
|
-
const cells = collectChildren(rowNode);
|
|
28902
|
-
const cellNode = cells[columnIndex];
|
|
28903
|
-
if (!cellNode) return rowNode;
|
|
28904
|
-
cells[columnIndex] = createEmptyCellNode(cellNode);
|
|
28905
|
-
return rowNode.type.create(rowNode.attrs, cells);
|
|
28906
|
-
});
|
|
28907
|
-
return tableNode.type.create(tableNode.attrs, rows);
|
|
28908
|
-
});
|
|
28909
|
-
}
|
|
28910
|
-
function expandTableFromCell(editor, activeCellPos, rows, columns) {
|
|
28911
|
-
let cornerCellPos = getTableCornerCellPos(editor, activeCellPos);
|
|
28912
|
-
if (cornerCellPos == null) return false;
|
|
28913
|
-
for (let index = 0; index < rows; index += 1) {
|
|
28914
|
-
const ok = runTableCommandAtCellPos(editor, cornerCellPos, (chain) => chain.addRowAfter());
|
|
28915
|
-
if (!ok) return false;
|
|
28916
|
-
cornerCellPos = getTableCornerCellPos(editor, cornerCellPos);
|
|
28917
|
-
if (cornerCellPos == null) return false;
|
|
28918
|
-
}
|
|
28919
|
-
for (let index = 0; index < columns; index += 1) {
|
|
28920
|
-
const ok = runTableCommandAtCellPos(editor, cornerCellPos, (chain) => chain.addColumnAfter());
|
|
28921
|
-
if (!ok) return false;
|
|
28922
|
-
cornerCellPos = getTableCornerCellPos(editor, cornerCellPos);
|
|
28923
|
-
if (cornerCellPos == null) return false;
|
|
28924
|
-
}
|
|
28925
|
-
dispatchTableLayoutChange(editor);
|
|
28926
|
-
return true;
|
|
28927
|
-
}
|
|
28928
|
-
|
|
28929
|
-
// src/components/UEditor/menus.tsx
|
|
28930
28986
|
import { Fragment as Fragment29, jsx as jsx86, jsxs as jsxs72 } from "react/jsx-runtime";
|
|
28931
28987
|
var FloatingSlashCommandMenu = ({ editor, onClose }) => {
|
|
28932
28988
|
const t = useSmartTranslations("UEditor");
|
|
@@ -29463,7 +29519,7 @@ var BubbleMenuContent = ({
|
|
|
29463
29519
|
active: canSplitCell,
|
|
29464
29520
|
disabled: !canMergeCells && !canSplitCell,
|
|
29465
29521
|
title: canSplitCell ? t("tableMenu.splitCell") || "Split cell" : t("tableMenu.mergeCells") || "Merge cells",
|
|
29466
|
-
children: /* @__PURE__ */ jsx86(
|
|
29522
|
+
children: /* @__PURE__ */ jsx86(TableCellsMerge2, { className: "w-4 h-4" })
|
|
29467
29523
|
}
|
|
29468
29524
|
)
|
|
29469
29525
|
] }),
|
|
@@ -35550,6 +35606,7 @@ var UEDITOR_PROSEMIRROR_CLASS_NAME = cn(
|
|
|
35550
35606
|
"[&_.tableWrapper::-webkit-scrollbar-thumb]:border-transparent",
|
|
35551
35607
|
"[&_.tableWrapper::-webkit-scrollbar-thumb]:bg-border/70",
|
|
35552
35608
|
"[&_.tableWrapper::-webkit-scrollbar-thumb:hover]:bg-muted-foreground/45",
|
|
35609
|
+
"[&_table]:w-auto",
|
|
35553
35610
|
"[&_table]:table-fixed",
|
|
35554
35611
|
"[&_table]:overflow-hidden",
|
|
35555
35612
|
"[&_table]:select-text",
|
|
@@ -36832,7 +36889,7 @@ var MenuBar = ({
|
|
|
36832
36889
|
"div",
|
|
36833
36890
|
{
|
|
36834
36891
|
"data-testid": "preview-content",
|
|
36835
|
-
className:
|
|
36892
|
+
className: UEDITOR_PROSEMIRROR_CLASS_NAME,
|
|
36836
36893
|
dangerouslySetInnerHTML: { __html: editor.getHTML() }
|
|
36837
36894
|
}
|
|
36838
36895
|
)
|