@underverse-ui/underverse 1.0.135 → 1.0.137
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 +1311 -802
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +1287 -780
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1006,6 +1006,8 @@ var en_default = {
|
|
|
1006
1006
|
deleteTable: "Delete Table",
|
|
1007
1007
|
toggleHeaderRow: "Toggle Header Row",
|
|
1008
1008
|
toggleHeaderColumn: "Toggle Header Column",
|
|
1009
|
+
mergeCells: "Merge Cells",
|
|
1010
|
+
splitCell: "Split Cell",
|
|
1009
1011
|
openControls: "Open Table Controls",
|
|
1010
1012
|
quickAddColumnAfter: "Quick Add Column After",
|
|
1011
1013
|
quickAddRowAfter: "Quick Add Row After",
|
|
@@ -1276,6 +1278,8 @@ var vi_default = {
|
|
|
1276
1278
|
deleteTable: "X\xF3a b\u1EA3ng",
|
|
1277
1279
|
toggleHeaderRow: "B\u1EADt/t\u1EAFt h\xE0ng ti\xEAu \u0111\u1EC1",
|
|
1278
1280
|
toggleHeaderColumn: "B\u1EADt/t\u1EAFt c\u1ED9t ti\xEAu \u0111\u1EC1",
|
|
1281
|
+
mergeCells: "G\u1ED9p \xF4",
|
|
1282
|
+
splitCell: "T\xE1ch \xF4",
|
|
1279
1283
|
openControls: "M\u1EDF \u0111i\u1EC1u khi\u1EC3n b\u1EA3ng",
|
|
1280
1284
|
quickAddColumnAfter: "Th\xEAm nhanh c\u1ED9t sau",
|
|
1281
1285
|
quickAddRowAfter: "Th\xEAm nhanh h\xE0ng sau",
|
|
@@ -1545,6 +1549,8 @@ var ko_default = {
|
|
|
1545
1549
|
deleteTable: "\uD45C \uC0AD\uC81C",
|
|
1546
1550
|
toggleHeaderRow: "\uD5E4\uB354 \uD589 \uC804\uD658",
|
|
1547
1551
|
toggleHeaderColumn: "\uD5E4\uB354 \uC5F4 \uC804\uD658",
|
|
1552
|
+
mergeCells: "\uC140 \uBCD1\uD569",
|
|
1553
|
+
splitCell: "\uC140 \uBD84\uD560",
|
|
1548
1554
|
openControls: "\uD45C \uCEE8\uD2B8\uB864 \uC5F4\uAE30",
|
|
1549
1555
|
quickAddColumnAfter: "\uC624\uB978\uCABD \uC5F4 \uBE60\uB974\uAC8C \uCD94\uAC00",
|
|
1550
1556
|
quickAddRowAfter: "\uC544\uB798 \uD589 \uBE60\uB974\uAC8C \uCD94\uAC00",
|
|
@@ -1814,6 +1820,8 @@ var ja_default = {
|
|
|
1814
1820
|
deleteTable: "\u8868\u3092\u524A\u9664",
|
|
1815
1821
|
toggleHeaderRow: "\u30D8\u30C3\u30C0\u30FC\u884C\u3092\u5207\u308A\u66FF\u3048",
|
|
1816
1822
|
toggleHeaderColumn: "\u30D8\u30C3\u30C0\u30FC\u5217\u3092\u5207\u308A\u66FF\u3048",
|
|
1823
|
+
mergeCells: "\u30BB\u30EB\u3092\u7D50\u5408",
|
|
1824
|
+
splitCell: "\u30BB\u30EB\u3092\u5206\u5272",
|
|
1817
1825
|
openControls: "\u8868\u30B3\u30F3\u30C8\u30ED\u30FC\u30EB\u3092\u958B\u304F",
|
|
1818
1826
|
quickAddColumnAfter: "\u53F3\u5074\u306B\u5217\u3092\u3059\u3070\u3084\u304F\u8FFD\u52A0",
|
|
1819
1827
|
quickAddRowAfter: "\u4E0B\u306B\u884C\u3092\u3059\u3070\u3084\u304F\u8FFD\u52A0",
|
|
@@ -9343,6 +9351,7 @@ var DatePicker = ({
|
|
|
9343
9351
|
{
|
|
9344
9352
|
ref: inputRef,
|
|
9345
9353
|
type: "text",
|
|
9354
|
+
"aria-label": value ? formatDateDisplay(value) : placeholder || t("placeholder"),
|
|
9346
9355
|
disabled,
|
|
9347
9356
|
placeholder: placeholder || t("placeholder"),
|
|
9348
9357
|
value: isFocused ? inputValue : value ? formatDateDisplay(value) : "",
|
|
@@ -9360,8 +9369,7 @@ var DatePicker = ({
|
|
|
9360
9369
|
},
|
|
9361
9370
|
className: "w-full bg-transparent border-none outline-none focus:outline-none p-0 text-foreground font-medium placeholder-muted-foreground/60 min-w-0"
|
|
9362
9371
|
}
|
|
9363
|
-
)
|
|
9364
|
-
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "sr-only", children: value ? formatDateDisplay(value) : placeholder || t("placeholder") })
|
|
9372
|
+
)
|
|
9365
9373
|
] }),
|
|
9366
9374
|
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "flex items-center gap-1 shrink-0", children: [
|
|
9367
9375
|
value && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
@@ -10091,6 +10099,7 @@ var DateRangePicker = ({
|
|
|
10091
10099
|
{
|
|
10092
10100
|
ref: inputRef,
|
|
10093
10101
|
type: "text",
|
|
10102
|
+
"aria-label": tempStart ? displayLabel : placeholder,
|
|
10094
10103
|
disabled,
|
|
10095
10104
|
placeholder,
|
|
10096
10105
|
value: isFocused ? inputValue : tempStart ? displayLabel : "",
|
|
@@ -10108,8 +10117,7 @@ var DateRangePicker = ({
|
|
|
10108
10117
|
},
|
|
10109
10118
|
className: "w-full bg-transparent border-none outline-none focus:outline-none p-0 text-foreground font-medium placeholder-muted-foreground/60 min-w-0"
|
|
10110
10119
|
}
|
|
10111
|
-
)
|
|
10112
|
-
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "sr-only", children: tempStart ? displayLabel : placeholder })
|
|
10120
|
+
)
|
|
10113
10121
|
] }),
|
|
10114
10122
|
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: cn("transition-all duration-300 text-muted-foreground group-hover:text-foreground", isOpen && "rotate-180 text-primary"), children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("svg", { className: cn(sizeStyles8[size].navIcon), fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2.5, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) }) })
|
|
10115
10123
|
]
|
|
@@ -10787,12 +10795,12 @@ function MonthYearPicker({
|
|
|
10787
10795
|
className
|
|
10788
10796
|
),
|
|
10789
10797
|
children: [
|
|
10790
|
-
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex items-center gap-2.5", children: [
|
|
10798
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2.5", children: [
|
|
10791
10799
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
10792
10800
|
"div",
|
|
10793
10801
|
{
|
|
10794
10802
|
className: cn(
|
|
10795
|
-
"flex items-center justify-center transition-colors duration-300",
|
|
10803
|
+
"flex shrink-0 items-center justify-center transition-colors duration-300",
|
|
10796
10804
|
effectiveError ? "text-destructive" : success ? "text-success" : open ? "text-primary" : "text-muted-foreground group-hover:text-primary"
|
|
10797
10805
|
),
|
|
10798
10806
|
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react16.Calendar, { className: cn(sz.icon, "transition-transform duration-300", open && "rotate-12") })
|
|
@@ -10801,12 +10809,12 @@ function MonthYearPicker({
|
|
|
10801
10809
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
10802
10810
|
"span",
|
|
10803
10811
|
{
|
|
10804
|
-
className: cn("truncate font-medium transition-colors duration-200", !hasValue && "text-muted-foreground", hasValue && "text-foreground"),
|
|
10812
|
+
className: cn("min-w-0 truncate font-medium transition-colors duration-200", !hasValue && "text-muted-foreground", hasValue && "text-foreground"),
|
|
10805
10813
|
children: hasValue ? display : placeholder
|
|
10806
10814
|
}
|
|
10807
10815
|
)
|
|
10808
10816
|
] }),
|
|
10809
|
-
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: cn("ml-2 transition-all duration-300 text-muted-foreground group-hover:text-foreground", open && "rotate-180 text-primary"), children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react16.ChevronDown, { className: sz.icon }) })
|
|
10817
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: cn("ml-2 shrink-0 transition-all duration-300 text-muted-foreground group-hover:text-foreground", open && "rotate-180 text-primary"), children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react16.ChevronDown, { className: sz.icon }) })
|
|
10810
10818
|
]
|
|
10811
10819
|
}
|
|
10812
10820
|
);
|
|
@@ -12492,12 +12500,12 @@ function TimePicker({
|
|
|
12492
12500
|
className
|
|
12493
12501
|
),
|
|
12494
12502
|
children: [
|
|
12495
|
-
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-center gap-2.5", children: [
|
|
12503
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2.5", children: [
|
|
12496
12504
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
12497
12505
|
"div",
|
|
12498
12506
|
{
|
|
12499
12507
|
className: cn(
|
|
12500
|
-
"flex items-center justify-center transition-colors duration-300",
|
|
12508
|
+
"flex shrink-0 items-center justify-center transition-colors duration-300",
|
|
12501
12509
|
effectiveError ? "text-destructive" : success ? "text-success" : open ? "text-primary" : "text-muted-foreground group-hover:text-primary"
|
|
12502
12510
|
),
|
|
12503
12511
|
children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_lucide_react18.Clock, { className: cn(sz.icon, "transition-transform duration-300", open && "rotate-12") })
|
|
@@ -12507,7 +12515,7 @@ function TimePicker({
|
|
|
12507
12515
|
"span",
|
|
12508
12516
|
{
|
|
12509
12517
|
className: cn(
|
|
12510
|
-
"truncate font-medium transition-colors duration-200",
|
|
12518
|
+
"min-w-0 truncate font-medium transition-colors duration-200",
|
|
12511
12519
|
!hasCommittedValue && "text-muted-foreground",
|
|
12512
12520
|
hasCommittedValue ? "text-foreground" : ""
|
|
12513
12521
|
),
|
|
@@ -12515,7 +12523,7 @@ function TimePicker({
|
|
|
12515
12523
|
}
|
|
12516
12524
|
)
|
|
12517
12525
|
] }),
|
|
12518
|
-
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: cn("ml-2 transition-all duration-300 text-muted-foreground group-hover:text-foreground", open && "rotate-180 text-primary"), children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("svg", { className: sz.icon, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2.5, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) }) })
|
|
12526
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: cn("ml-2 shrink-0 transition-all duration-300 text-muted-foreground group-hover:text-foreground", open && "rotate-180 text-primary"), children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("svg", { className: sz.icon, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2.5, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) }) })
|
|
12519
12527
|
]
|
|
12520
12528
|
}
|
|
12521
12529
|
);
|
|
@@ -13145,8 +13153,8 @@ var DateTimePicker = ({
|
|
|
13145
13153
|
effectiveError && "border-destructive/60 bg-destructive/5"
|
|
13146
13154
|
),
|
|
13147
13155
|
children: [
|
|
13148
|
-
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "truncate", children: displayValue || placeholder || "Select date & time" }),
|
|
13149
|
-
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex items-center gap-2 text-muted-foreground", children: [
|
|
13156
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "min-w-0 flex-1 truncate text-left", children: displayValue || placeholder || "Select date & time" }),
|
|
13157
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex shrink-0 items-center gap-2 text-muted-foreground", children: [
|
|
13150
13158
|
value && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
13151
13159
|
"span",
|
|
13152
13160
|
{
|
|
@@ -25510,6 +25518,109 @@ var letter_spacing_default = LetterSpacing;
|
|
|
25510
25518
|
var import_extension_table = require("@tiptap/extension-table");
|
|
25511
25519
|
var import_state4 = require("@tiptap/pm/state");
|
|
25512
25520
|
|
|
25521
|
+
// src/components/UEditor/table-dom-utils.ts
|
|
25522
|
+
var MIN_TABLE_ROW_HEIGHT = 36;
|
|
25523
|
+
var COLUMN_RESIZE_LINE_THICKNESS = 2;
|
|
25524
|
+
var ROW_RESIZE_LINE_THICKNESS = 2;
|
|
25525
|
+
var UEDITOR_TABLE_LAYOUT_CHANGE_EVENT = "ueditor-table-layout-change";
|
|
25526
|
+
var TABLE_RESIZE_HIT_ZONE = 10;
|
|
25527
|
+
function findTableRowNodeInfo(view, rowElement) {
|
|
25528
|
+
const firstCell = rowElement.querySelector("th,td");
|
|
25529
|
+
if (!firstCell) return null;
|
|
25530
|
+
const cellPos = view.posAtDOM(firstCell, 0);
|
|
25531
|
+
const $pos = view.state.doc.resolve(cellPos);
|
|
25532
|
+
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
25533
|
+
const node = $pos.node(depth);
|
|
25534
|
+
if (node.type.name === "tableRow") {
|
|
25535
|
+
return {
|
|
25536
|
+
pos: $pos.before(depth),
|
|
25537
|
+
node
|
|
25538
|
+
};
|
|
25539
|
+
}
|
|
25540
|
+
}
|
|
25541
|
+
return null;
|
|
25542
|
+
}
|
|
25543
|
+
function resolveEventElement(target) {
|
|
25544
|
+
if (target instanceof Element) return target;
|
|
25545
|
+
if (target instanceof Node) return target.parentElement;
|
|
25546
|
+
return null;
|
|
25547
|
+
}
|
|
25548
|
+
function getSelectionTableCell(view) {
|
|
25549
|
+
const browserSelection = window.getSelection();
|
|
25550
|
+
const anchorElement = resolveEventElement(browserSelection?.anchorNode ?? null);
|
|
25551
|
+
const anchorCell = anchorElement?.closest?.("th,td");
|
|
25552
|
+
if (anchorCell instanceof HTMLElement) {
|
|
25553
|
+
return anchorCell;
|
|
25554
|
+
}
|
|
25555
|
+
const { from } = view.state.selection;
|
|
25556
|
+
const domAtPos = view.domAtPos(from);
|
|
25557
|
+
const element = resolveEventElement(domAtPos.node);
|
|
25558
|
+
const cell = element?.closest?.("th,td");
|
|
25559
|
+
return cell instanceof HTMLElement ? cell : null;
|
|
25560
|
+
}
|
|
25561
|
+
function isRowResizeHotspot(cell, clientX, clientY) {
|
|
25562
|
+
const rect = cell.getBoundingClientRect();
|
|
25563
|
+
const nearBottom = rect.bottom - clientY <= TABLE_RESIZE_HIT_ZONE;
|
|
25564
|
+
const nearRight = rect.right - clientX <= TABLE_RESIZE_HIT_ZONE;
|
|
25565
|
+
return nearBottom && !nearRight;
|
|
25566
|
+
}
|
|
25567
|
+
function isColumnResizeHotspot(cell, clientX, clientY) {
|
|
25568
|
+
const rect = cell.getBoundingClientRect();
|
|
25569
|
+
const nearRight = rect.right - clientX <= TABLE_RESIZE_HIT_ZONE;
|
|
25570
|
+
const nearBottom = rect.bottom - clientY <= TABLE_RESIZE_HIT_ZONE;
|
|
25571
|
+
return nearRight && !nearBottom;
|
|
25572
|
+
}
|
|
25573
|
+
function getRelativeBoundaryMetrics(surface, table, row, cell) {
|
|
25574
|
+
const surfaceRect = surface.getBoundingClientRect();
|
|
25575
|
+
const tableRect = table.getBoundingClientRect();
|
|
25576
|
+
const rowRect = row.getBoundingClientRect();
|
|
25577
|
+
const cellRect = cell.getBoundingClientRect();
|
|
25578
|
+
return {
|
|
25579
|
+
left: tableRect.left - surfaceRect.left + surface.scrollLeft,
|
|
25580
|
+
top: tableRect.top - surfaceRect.top + surface.scrollTop,
|
|
25581
|
+
width: tableRect.width,
|
|
25582
|
+
height: tableRect.height,
|
|
25583
|
+
rowBottom: rowRect.bottom - surfaceRect.top + surface.scrollTop,
|
|
25584
|
+
columnRight: cellRect.right - surfaceRect.left + surface.scrollLeft
|
|
25585
|
+
};
|
|
25586
|
+
}
|
|
25587
|
+
function getRelativeCellMetrics(surface, cell) {
|
|
25588
|
+
const surfaceRect = surface.getBoundingClientRect();
|
|
25589
|
+
const cellRect = cell.getBoundingClientRect();
|
|
25590
|
+
return {
|
|
25591
|
+
left: cellRect.left - surfaceRect.left + surface.scrollLeft,
|
|
25592
|
+
top: cellRect.top - surfaceRect.top + surface.scrollTop,
|
|
25593
|
+
width: cellRect.width,
|
|
25594
|
+
height: cellRect.height
|
|
25595
|
+
};
|
|
25596
|
+
}
|
|
25597
|
+
function getRelativeSelectedCellsMetrics(surface) {
|
|
25598
|
+
const selectedCells = Array.from(
|
|
25599
|
+
surface.querySelectorAll("td.selectedCell, th.selectedCell")
|
|
25600
|
+
);
|
|
25601
|
+
if (selectedCells.length === 0) {
|
|
25602
|
+
return null;
|
|
25603
|
+
}
|
|
25604
|
+
const surfaceRect = surface.getBoundingClientRect();
|
|
25605
|
+
let left = Number.POSITIVE_INFINITY;
|
|
25606
|
+
let top = Number.POSITIVE_INFINITY;
|
|
25607
|
+
let right = Number.NEGATIVE_INFINITY;
|
|
25608
|
+
let bottom = Number.NEGATIVE_INFINITY;
|
|
25609
|
+
selectedCells.forEach((cell) => {
|
|
25610
|
+
const rect = cell.getBoundingClientRect();
|
|
25611
|
+
left = Math.min(left, rect.left);
|
|
25612
|
+
top = Math.min(top, rect.top);
|
|
25613
|
+
right = Math.max(right, rect.right);
|
|
25614
|
+
bottom = Math.max(bottom, rect.bottom);
|
|
25615
|
+
});
|
|
25616
|
+
return {
|
|
25617
|
+
left: left - surfaceRect.left + surface.scrollLeft,
|
|
25618
|
+
top: top - surfaceRect.top + surface.scrollTop,
|
|
25619
|
+
width: right - left,
|
|
25620
|
+
height: bottom - top
|
|
25621
|
+
};
|
|
25622
|
+
}
|
|
25623
|
+
|
|
25513
25624
|
// src/components/UEditor/table-align-utils.ts
|
|
25514
25625
|
function findTableNodeInfoAtResolvedPos($pos) {
|
|
25515
25626
|
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
@@ -25537,11 +25648,13 @@ function applyTableAlignment(editor, tableAlign, anchorPos) {
|
|
|
25537
25648
|
editor.view.dispatch(
|
|
25538
25649
|
editor.state.tr.setNodeMarkup(tableInfo.pos, tableInfo.node.type, {
|
|
25539
25650
|
...tableInfo.node.attrs,
|
|
25540
|
-
tableAlign
|
|
25651
|
+
textAlign: tableAlign
|
|
25541
25652
|
})
|
|
25542
25653
|
);
|
|
25654
|
+
const domAtTable = editor.view.domAtPos(Math.min(tableInfo.pos + 1, editor.state.doc.content.size)).node;
|
|
25655
|
+
const domAtTableElement = resolveEventElement(domAtTable);
|
|
25543
25656
|
const tableDom = editor.view.nodeDOM(tableInfo.pos);
|
|
25544
|
-
const tableElement = tableDom instanceof HTMLTableElement ? tableDom : tableDom instanceof HTMLElement ? tableDom.querySelector("table") : null;
|
|
25657
|
+
const tableElement = domAtTableElement?.closest?.("table") ?? (tableDom instanceof HTMLTableElement ? tableDom : tableDom instanceof HTMLElement ? tableDom.querySelector("table") : null) ?? (editor.view.dom.querySelectorAll("table").length === 1 ? editor.view.dom.querySelector("table") : null);
|
|
25545
25658
|
if (tableElement instanceof HTMLTableElement) {
|
|
25546
25659
|
if (tableAlign) {
|
|
25547
25660
|
tableElement.setAttribute("data-table-align", tableAlign);
|
|
@@ -25590,25 +25703,30 @@ function renderTableAlignStyle(tableAlign) {
|
|
|
25590
25703
|
}
|
|
25591
25704
|
}
|
|
25592
25705
|
var UEditorTable = import_extension_table.Table.extend({
|
|
25593
|
-
|
|
25594
|
-
return
|
|
25595
|
-
...this.parent?.(),
|
|
25596
|
-
|
|
25597
|
-
|
|
25598
|
-
|
|
25599
|
-
|
|
25600
|
-
|
|
25601
|
-
|
|
25602
|
-
|
|
25603
|
-
|
|
25604
|
-
|
|
25605
|
-
|
|
25606
|
-
|
|
25607
|
-
|
|
25608
|
-
|
|
25706
|
+
addGlobalAttributes() {
|
|
25707
|
+
return [
|
|
25708
|
+
...this.parent?.() ?? [],
|
|
25709
|
+
{
|
|
25710
|
+
types: ["table"],
|
|
25711
|
+
attributes: {
|
|
25712
|
+
textAlign: {
|
|
25713
|
+
default: null,
|
|
25714
|
+
parseHTML: (element) => {
|
|
25715
|
+
if (!(element instanceof HTMLElement)) return null;
|
|
25716
|
+
return parseTableAlign(element);
|
|
25717
|
+
},
|
|
25718
|
+
renderHTML: (attributes) => {
|
|
25719
|
+
const tableAlign = normalizeTableAlign(attributes.textAlign);
|
|
25720
|
+
if (!tableAlign) return {};
|
|
25721
|
+
return {
|
|
25722
|
+
"data-table-align": tableAlign,
|
|
25723
|
+
style: renderTableAlignStyle(tableAlign)
|
|
25724
|
+
};
|
|
25725
|
+
}
|
|
25726
|
+
}
|
|
25609
25727
|
}
|
|
25610
25728
|
}
|
|
25611
|
-
|
|
25729
|
+
];
|
|
25612
25730
|
},
|
|
25613
25731
|
addCommands() {
|
|
25614
25732
|
return {
|
|
@@ -25619,7 +25737,7 @@ var UEditorTable = import_extension_table.Table.extend({
|
|
|
25619
25737
|
dispatch?.(
|
|
25620
25738
|
state.tr.setNodeMarkup(tableInfo.pos, tableInfo.node.type, {
|
|
25621
25739
|
...tableInfo.node.attrs,
|
|
25622
|
-
tableAlign
|
|
25740
|
+
textAlign: tableAlign
|
|
25623
25741
|
})
|
|
25624
25742
|
);
|
|
25625
25743
|
return true;
|
|
@@ -25630,7 +25748,7 @@ var UEditorTable = import_extension_table.Table.extend({
|
|
|
25630
25748
|
dispatch?.(
|
|
25631
25749
|
state.tr.setNodeMarkup(tableInfo.pos, tableInfo.node.type, {
|
|
25632
25750
|
...tableInfo.node.attrs,
|
|
25633
|
-
|
|
25751
|
+
textAlign: null
|
|
25634
25752
|
})
|
|
25635
25753
|
);
|
|
25636
25754
|
return true;
|
|
@@ -25639,6 +25757,7 @@ var UEditorTable = import_extension_table.Table.extend({
|
|
|
25639
25757
|
},
|
|
25640
25758
|
addProseMirrorPlugins() {
|
|
25641
25759
|
return [
|
|
25760
|
+
...this.parent?.() ?? [],
|
|
25642
25761
|
new import_state4.Plugin({
|
|
25643
25762
|
appendTransaction(_transactions, _oldState, newState) {
|
|
25644
25763
|
const { doc, schema } = newState;
|
|
@@ -26337,6 +26456,24 @@ function getDefaultLetterSpacings() {
|
|
|
26337
26456
|
|
|
26338
26457
|
// src/components/UEditor/toolbar.tsx
|
|
26339
26458
|
var import_jsx_runtime81 = require("react/jsx-runtime");
|
|
26459
|
+
function getTableAnchorPos(editor) {
|
|
26460
|
+
const tableInfo = findTableNodeInfoFromState(editor.state);
|
|
26461
|
+
if (tableInfo) return editor.state.selection.from;
|
|
26462
|
+
const selectionAnchor = resolveEventElement(window.getSelection()?.anchorNode ?? null);
|
|
26463
|
+
const selectionCell2 = selectionAnchor?.closest?.("th,td");
|
|
26464
|
+
if (selectionCell2 instanceof HTMLTableCellElement && editor.view.dom.contains(selectionCell2)) {
|
|
26465
|
+
return editor.view.posAtDOM(selectionCell2, 0) + 1;
|
|
26466
|
+
}
|
|
26467
|
+
const activeElement = document.activeElement instanceof Element ? document.activeElement : null;
|
|
26468
|
+
const activeCell = activeElement?.closest?.("th,td");
|
|
26469
|
+
if (activeCell instanceof HTMLTableCellElement && editor.view.dom.contains(activeCell)) {
|
|
26470
|
+
return editor.view.posAtDOM(activeCell, 0) + 1;
|
|
26471
|
+
}
|
|
26472
|
+
const tables = editor.view.dom.querySelectorAll("table");
|
|
26473
|
+
if (tables.length !== 1) return null;
|
|
26474
|
+
const firstCell = tables[0]?.querySelector("th,td");
|
|
26475
|
+
return firstCell instanceof HTMLTableCellElement ? editor.view.posAtDOM(firstCell, 0) + 1 : null;
|
|
26476
|
+
}
|
|
26340
26477
|
function fileToDataUrl2(file) {
|
|
26341
26478
|
return new Promise((resolve, reject) => {
|
|
26342
26479
|
const reader = new FileReader();
|
|
@@ -26443,12 +26580,15 @@ var EditorToolbar = ({
|
|
|
26443
26580
|
const [imageUploadError, setImageUploadError] = (0, import_react49.useState)(null);
|
|
26444
26581
|
const isImageSelected = editor.isActive("image");
|
|
26445
26582
|
const imageAttrs = editor.getAttributes("image");
|
|
26446
|
-
const
|
|
26583
|
+
const tableAnchorPos = getTableAnchorPos(editor);
|
|
26584
|
+
const tableInfo = tableAnchorPos == null ? null : findTableNodeInfoFromState(editor.state, tableAnchorPos);
|
|
26585
|
+
const tableAttrs = tableInfo?.node.attrs ?? editor.getAttributes("table");
|
|
26447
26586
|
const textStyleAttrs = editor.getAttributes("textStyle");
|
|
26448
26587
|
const imageLayout = imageAttrs.imageLayout === "left" || imageAttrs.imageLayout === "right" ? imageAttrs.imageLayout : "block";
|
|
26449
26588
|
const imageWidthPreset = imageAttrs.imageWidthPreset === "sm" || imageAttrs.imageWidthPreset === "md" || imageAttrs.imageWidthPreset === "lg" ? imageAttrs.imageWidthPreset : null;
|
|
26450
|
-
const
|
|
26451
|
-
const
|
|
26589
|
+
const tableAlignAttr = tableAttrs.tableAlign ?? tableAttrs.textAlign;
|
|
26590
|
+
const currentTableAlign = tableAlignAttr === "center" || tableAlignAttr === "right" ? tableAlignAttr : "left";
|
|
26591
|
+
const isTableSelected = tableInfo !== null;
|
|
26452
26592
|
const hasTableContext = isTableSelected || tableCommandAnchorPosRef.current !== null;
|
|
26453
26593
|
const currentFontFamily = normalizeStyleValue(textStyleAttrs.fontFamily);
|
|
26454
26594
|
const currentFontSize = normalizeStyleValue(textStyleAttrs.fontSize);
|
|
@@ -26466,6 +26606,7 @@ var EditorToolbar = ({
|
|
|
26466
26606
|
const currentLineHeightLabel = availableLineHeights.find((option) => normalizeStyleValue(option.value) === currentLineHeight)?.label ?? t("toolbar.lineHeightDefault");
|
|
26467
26607
|
const currentLetterSpacingLabel = availableLetterSpacings.find((option) => normalizeStyleValue(option.value) === currentLetterSpacing)?.label ?? t("toolbar.letterSpacingDefault");
|
|
26468
26608
|
const displayedFontFamilyLabel = currentFontFamily ? currentFontFamilyLabel : availableFontFamilies[0]?.label ?? t("toolbar.fontDefault");
|
|
26609
|
+
const tableCommandAnchorPos = tableCommandAnchorPosRef.current ?? tableAnchorPos ?? void 0;
|
|
26469
26610
|
const insertImageFiles = async (files) => {
|
|
26470
26611
|
if (files.length === 0) return;
|
|
26471
26612
|
setIsUploadingImage(true);
|
|
@@ -27068,7 +27209,7 @@ var EditorToolbar = ({
|
|
|
27068
27209
|
isOpen: isTableMenuOpen,
|
|
27069
27210
|
onOpenChange: (open) => {
|
|
27070
27211
|
setIsTableMenuOpen(open);
|
|
27071
|
-
tableCommandAnchorPosRef.current = open
|
|
27212
|
+
tableCommandAnchorPosRef.current = open ? getTableAnchorPos(editor) : null;
|
|
27072
27213
|
},
|
|
27073
27214
|
trigger: /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(ToolbarButton, { onClick: () => {
|
|
27074
27215
|
}, title: t("toolbar.table"), children: [
|
|
@@ -27094,7 +27235,7 @@ var EditorToolbar = ({
|
|
|
27094
27235
|
{
|
|
27095
27236
|
icon: import_lucide_react44.AlignLeft,
|
|
27096
27237
|
label: t("tableMenu.alignLeft"),
|
|
27097
|
-
onClick: () => applyTableAlignment(editor, "left",
|
|
27238
|
+
onClick: () => applyTableAlignment(editor, "left", tableCommandAnchorPos),
|
|
27098
27239
|
active: hasTableContext && currentTableAlign === "left",
|
|
27099
27240
|
disabled: !hasTableContext
|
|
27100
27241
|
}
|
|
@@ -27104,7 +27245,7 @@ var EditorToolbar = ({
|
|
|
27104
27245
|
{
|
|
27105
27246
|
icon: import_lucide_react44.AlignCenter,
|
|
27106
27247
|
label: t("tableMenu.alignCenter"),
|
|
27107
|
-
onClick: () => applyTableAlignment(editor, "center",
|
|
27248
|
+
onClick: () => applyTableAlignment(editor, "center", tableCommandAnchorPos),
|
|
27108
27249
|
active: hasTableContext && currentTableAlign === "center",
|
|
27109
27250
|
disabled: !hasTableContext
|
|
27110
27251
|
}
|
|
@@ -27114,7 +27255,7 @@ var EditorToolbar = ({
|
|
|
27114
27255
|
{
|
|
27115
27256
|
icon: import_lucide_react44.AlignRight,
|
|
27116
27257
|
label: t("tableMenu.alignRight"),
|
|
27117
|
-
onClick: () => applyTableAlignment(editor, "right",
|
|
27258
|
+
onClick: () => applyTableAlignment(editor, "right", tableCommandAnchorPos),
|
|
27118
27259
|
active: hasTableContext && currentTableAlign === "right",
|
|
27119
27260
|
disabled: !hasTableContext
|
|
27120
27261
|
}
|
|
@@ -27215,9 +27356,234 @@ var EditorToolbar = ({
|
|
|
27215
27356
|
// src/components/UEditor/menus.tsx
|
|
27216
27357
|
var import_react51 = require("react");
|
|
27217
27358
|
var import_react52 = require("@tiptap/react");
|
|
27218
|
-
var
|
|
27359
|
+
var import_tables2 = require("@tiptap/pm/tables");
|
|
27219
27360
|
var import_react_dom8 = require("react-dom");
|
|
27220
27361
|
var import_lucide_react45 = require("lucide-react");
|
|
27362
|
+
|
|
27363
|
+
// src/components/UEditor/table-cell-commands.ts
|
|
27364
|
+
var import_state6 = require("@tiptap/pm/state");
|
|
27365
|
+
var import_tables = require("@tiptap/pm/tables");
|
|
27366
|
+
function getCellSelectionPositions(selection) {
|
|
27367
|
+
const value = selection;
|
|
27368
|
+
const anchor = value.$anchorCell?.pos;
|
|
27369
|
+
const head = value.$headCell?.pos;
|
|
27370
|
+
return typeof anchor === "number" && typeof head === "number" ? { anchor, head } : null;
|
|
27371
|
+
}
|
|
27372
|
+
function findTableInfoFromCellPos(editor, cellPos) {
|
|
27373
|
+
const $pos = editor.state.doc.resolve(cellPos);
|
|
27374
|
+
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
27375
|
+
const node = $pos.node(depth);
|
|
27376
|
+
if (node.type.name === "table") {
|
|
27377
|
+
return {
|
|
27378
|
+
table: node,
|
|
27379
|
+
tablePos: $pos.before(depth),
|
|
27380
|
+
tableStart: $pos.start(depth)
|
|
27381
|
+
};
|
|
27382
|
+
}
|
|
27383
|
+
}
|
|
27384
|
+
return null;
|
|
27385
|
+
}
|
|
27386
|
+
function getFocusableCellPos(editor, cellPos) {
|
|
27387
|
+
const cellNode = editor.state.doc.nodeAt(cellPos);
|
|
27388
|
+
if (!cellNode) return cellPos + 1;
|
|
27389
|
+
let offset = cellPos + 1;
|
|
27390
|
+
let node = cellNode.firstChild ?? null;
|
|
27391
|
+
while (node && !node.isTextblock) {
|
|
27392
|
+
offset += 1;
|
|
27393
|
+
node = node.firstChild ?? null;
|
|
27394
|
+
}
|
|
27395
|
+
return node?.isTextblock ? offset + 1 : cellPos + 1;
|
|
27396
|
+
}
|
|
27397
|
+
function focusCell(editor, cellPos) {
|
|
27398
|
+
const selection = import_state6.TextSelection.near(editor.state.doc.resolve(getFocusableCellPos(editor, cellPos)));
|
|
27399
|
+
editor.view.dispatch(editor.state.tr.setSelection(selection));
|
|
27400
|
+
editor.view.focus();
|
|
27401
|
+
}
|
|
27402
|
+
function collectChildren(node) {
|
|
27403
|
+
const children = [];
|
|
27404
|
+
node.forEach((child) => children.push(child));
|
|
27405
|
+
return children;
|
|
27406
|
+
}
|
|
27407
|
+
function createEmptyCellNode(cellNode) {
|
|
27408
|
+
return cellNode.type.createAndFill(cellNode.attrs) ?? cellNode;
|
|
27409
|
+
}
|
|
27410
|
+
function getSelectedTableRect(editor) {
|
|
27411
|
+
const cellSelection = getCellSelectionPositions(editor.state.selection);
|
|
27412
|
+
if (cellSelection) {
|
|
27413
|
+
const tableInfo = findTableInfoFromCellPos(editor, cellSelection.anchor);
|
|
27414
|
+
if (tableInfo) {
|
|
27415
|
+
const map = import_tables.TableMap.get(tableInfo.table);
|
|
27416
|
+
const rect = map.rectBetween(
|
|
27417
|
+
cellSelection.anchor - tableInfo.tableStart,
|
|
27418
|
+
cellSelection.head - tableInfo.tableStart
|
|
27419
|
+
);
|
|
27420
|
+
return {
|
|
27421
|
+
...rect,
|
|
27422
|
+
map,
|
|
27423
|
+
table: tableInfo.table,
|
|
27424
|
+
tableStart: tableInfo.tableStart
|
|
27425
|
+
};
|
|
27426
|
+
}
|
|
27427
|
+
}
|
|
27428
|
+
return (0, import_tables.selectedRect)(editor.state);
|
|
27429
|
+
}
|
|
27430
|
+
function parsePixelWidth(value) {
|
|
27431
|
+
if (!value) return null;
|
|
27432
|
+
const parsed = Number.parseFloat(value);
|
|
27433
|
+
return Number.isFinite(parsed) && parsed > 0 ? Math.round(parsed) : null;
|
|
27434
|
+
}
|
|
27435
|
+
function getDomColumnWidths(editor, rect) {
|
|
27436
|
+
const tableDom = editor.view.nodeDOM(rect.tableStart - 1);
|
|
27437
|
+
if (!(tableDom instanceof HTMLTableElement)) return null;
|
|
27438
|
+
const cols = Array.from(tableDom.querySelectorAll("colgroup > col"));
|
|
27439
|
+
if (cols.length === 0) return null;
|
|
27440
|
+
const widths = [];
|
|
27441
|
+
for (let col = rect.left; col < rect.right; col += 1) {
|
|
27442
|
+
const colElement = cols[col];
|
|
27443
|
+
if (!colElement) return null;
|
|
27444
|
+
const width = parsePixelWidth(colElement.style.width) ?? parsePixelWidth(colElement.getAttribute("width")) ?? Math.round(colElement.getBoundingClientRect().width);
|
|
27445
|
+
if (!Number.isFinite(width) || width <= 0) return null;
|
|
27446
|
+
widths.push(width);
|
|
27447
|
+
}
|
|
27448
|
+
return widths.length > 0 ? widths : null;
|
|
27449
|
+
}
|
|
27450
|
+
function getNodeColumnWidths(rect) {
|
|
27451
|
+
const widths = [];
|
|
27452
|
+
for (let col = rect.left; col < rect.right; col += 1) {
|
|
27453
|
+
let width = null;
|
|
27454
|
+
const seen = /* @__PURE__ */ new Set();
|
|
27455
|
+
for (let row = 0; row < rect.map.height && width == null; row += 1) {
|
|
27456
|
+
const cellPos = rect.map.map[row * rect.map.width + col];
|
|
27457
|
+
if (seen.has(cellPos)) continue;
|
|
27458
|
+
seen.add(cellPos);
|
|
27459
|
+
const cell = rect.table.nodeAt(cellPos);
|
|
27460
|
+
const colwidth = cell?.attrs.colwidth;
|
|
27461
|
+
if (!Array.isArray(colwidth)) continue;
|
|
27462
|
+
const cellLeft = rect.map.colCount(cellPos);
|
|
27463
|
+
const widthIndex = col - cellLeft;
|
|
27464
|
+
const candidate = colwidth[widthIndex];
|
|
27465
|
+
if (typeof candidate === "number" && candidate > 0) {
|
|
27466
|
+
width = candidate;
|
|
27467
|
+
}
|
|
27468
|
+
}
|
|
27469
|
+
if (width == null) return null;
|
|
27470
|
+
widths.push(width);
|
|
27471
|
+
}
|
|
27472
|
+
return widths.length > 0 ? widths : null;
|
|
27473
|
+
}
|
|
27474
|
+
function getSelectedColumnWidths(editor, rect) {
|
|
27475
|
+
return getDomColumnWidths(editor, rect) ?? getNodeColumnWidths(rect);
|
|
27476
|
+
}
|
|
27477
|
+
function dispatchTableLayoutChange(editor) {
|
|
27478
|
+
editor.view.dom.dispatchEvent(new CustomEvent(UEDITOR_TABLE_LAYOUT_CHANGE_EVENT, { bubbles: true }));
|
|
27479
|
+
}
|
|
27480
|
+
function mergeTableCellsPreservingColumnWidths(editor) {
|
|
27481
|
+
const rect = getSelectedTableRect(editor);
|
|
27482
|
+
const widths = getSelectedColumnWidths(editor, rect);
|
|
27483
|
+
const merged = editor.chain().focus().mergeCells().run();
|
|
27484
|
+
if (!merged) return merged;
|
|
27485
|
+
if (!widths) {
|
|
27486
|
+
dispatchTableLayoutChange(editor);
|
|
27487
|
+
return merged;
|
|
27488
|
+
}
|
|
27489
|
+
const nextRect = getSelectedTableRect(editor);
|
|
27490
|
+
const cellPos = nextRect.map.map[nextRect.top * nextRect.map.width + nextRect.left];
|
|
27491
|
+
const absolutePos = nextRect.tableStart + cellPos;
|
|
27492
|
+
const node = editor.state.doc.nodeAt(absolutePos);
|
|
27493
|
+
if (!node) return merged;
|
|
27494
|
+
editor.view.dispatch(
|
|
27495
|
+
editor.state.tr.setNodeMarkup(absolutePos, node.type, {
|
|
27496
|
+
...node.attrs,
|
|
27497
|
+
colwidth: widths
|
|
27498
|
+
})
|
|
27499
|
+
);
|
|
27500
|
+
dispatchTableLayoutChange(editor);
|
|
27501
|
+
return true;
|
|
27502
|
+
}
|
|
27503
|
+
function runTableCommandAtCellPos(editor, cellPos, command) {
|
|
27504
|
+
if (cellPos == null) return false;
|
|
27505
|
+
focusCell(editor, cellPos);
|
|
27506
|
+
return command(editor.chain().focus(null, { scrollIntoView: false })).run();
|
|
27507
|
+
}
|
|
27508
|
+
function getTableCornerCellPos(editor, activePos) {
|
|
27509
|
+
const tableInfo = findTableInfoFromCellPos(editor, activePos);
|
|
27510
|
+
if (!tableInfo) return null;
|
|
27511
|
+
const map = import_tables.TableMap.get(tableInfo.table);
|
|
27512
|
+
return tableInfo.tableStart + map.positionAt(map.height - 1, map.width - 1, tableInfo.table);
|
|
27513
|
+
}
|
|
27514
|
+
function replaceTableAtCellPos(editor, cellPos, updateTable) {
|
|
27515
|
+
if (cellPos == null) return false;
|
|
27516
|
+
const tableInfo = findTableInfoFromCellPos(editor, cellPos);
|
|
27517
|
+
if (!tableInfo) return false;
|
|
27518
|
+
const nextTable = updateTable(tableInfo.table);
|
|
27519
|
+
if (!nextTable) return false;
|
|
27520
|
+
editor.view.dispatch(editor.state.tr.replaceWith(tableInfo.tablePos, tableInfo.tablePos + tableInfo.table.nodeSize, nextTable));
|
|
27521
|
+
dispatchTableLayoutChange(editor);
|
|
27522
|
+
return true;
|
|
27523
|
+
}
|
|
27524
|
+
function duplicateTableRowAt(editor, rowIndex, cellPos) {
|
|
27525
|
+
return replaceTableAtCellPos(editor, cellPos, (tableNode) => {
|
|
27526
|
+
const rows = collectChildren(tableNode);
|
|
27527
|
+
const rowNode = rows[rowIndex];
|
|
27528
|
+
if (!rowNode) return null;
|
|
27529
|
+
rows.splice(rowIndex + 1, 0, rowNode.copy(rowNode.content));
|
|
27530
|
+
return tableNode.type.create(tableNode.attrs, rows);
|
|
27531
|
+
});
|
|
27532
|
+
}
|
|
27533
|
+
function clearTableRowAt(editor, rowIndex, cellPos) {
|
|
27534
|
+
return replaceTableAtCellPos(editor, cellPos, (tableNode) => {
|
|
27535
|
+
const rows = collectChildren(tableNode);
|
|
27536
|
+
const rowNode = rows[rowIndex];
|
|
27537
|
+
if (!rowNode) return null;
|
|
27538
|
+
const cells = collectChildren(rowNode).map((cellNode) => createEmptyCellNode(cellNode));
|
|
27539
|
+
rows[rowIndex] = rowNode.type.create(rowNode.attrs, cells);
|
|
27540
|
+
return tableNode.type.create(tableNode.attrs, rows);
|
|
27541
|
+
});
|
|
27542
|
+
}
|
|
27543
|
+
function duplicateTableColumnAt(editor, columnIndex, cellPos) {
|
|
27544
|
+
return replaceTableAtCellPos(editor, cellPos, (tableNode) => {
|
|
27545
|
+
const rows = collectChildren(tableNode).map((rowNode) => {
|
|
27546
|
+
const cells = collectChildren(rowNode);
|
|
27547
|
+
const cellNode = cells[columnIndex];
|
|
27548
|
+
if (!cellNode) return rowNode;
|
|
27549
|
+
cells.splice(columnIndex + 1, 0, cellNode.copy(cellNode.content));
|
|
27550
|
+
return rowNode.type.create(rowNode.attrs, cells);
|
|
27551
|
+
});
|
|
27552
|
+
return tableNode.type.create(tableNode.attrs, rows);
|
|
27553
|
+
});
|
|
27554
|
+
}
|
|
27555
|
+
function clearTableColumnAt(editor, columnIndex, cellPos) {
|
|
27556
|
+
return replaceTableAtCellPos(editor, cellPos, (tableNode) => {
|
|
27557
|
+
const rows = collectChildren(tableNode).map((rowNode) => {
|
|
27558
|
+
const cells = collectChildren(rowNode);
|
|
27559
|
+
const cellNode = cells[columnIndex];
|
|
27560
|
+
if (!cellNode) return rowNode;
|
|
27561
|
+
cells[columnIndex] = createEmptyCellNode(cellNode);
|
|
27562
|
+
return rowNode.type.create(rowNode.attrs, cells);
|
|
27563
|
+
});
|
|
27564
|
+
return tableNode.type.create(tableNode.attrs, rows);
|
|
27565
|
+
});
|
|
27566
|
+
}
|
|
27567
|
+
function expandTableFromCell(editor, activeCellPos, rows, columns) {
|
|
27568
|
+
let cornerCellPos = getTableCornerCellPos(editor, activeCellPos);
|
|
27569
|
+
if (cornerCellPos == null) return false;
|
|
27570
|
+
for (let index = 0; index < rows; index += 1) {
|
|
27571
|
+
const ok = runTableCommandAtCellPos(editor, cornerCellPos, (chain) => chain.addRowAfter());
|
|
27572
|
+
if (!ok) return false;
|
|
27573
|
+
cornerCellPos = getTableCornerCellPos(editor, cornerCellPos);
|
|
27574
|
+
if (cornerCellPos == null) return false;
|
|
27575
|
+
}
|
|
27576
|
+
for (let index = 0; index < columns; index += 1) {
|
|
27577
|
+
const ok = runTableCommandAtCellPos(editor, cornerCellPos, (chain) => chain.addColumnAfter());
|
|
27578
|
+
if (!ok) return false;
|
|
27579
|
+
cornerCellPos = getTableCornerCellPos(editor, cornerCellPos);
|
|
27580
|
+
if (cornerCellPos == null) return false;
|
|
27581
|
+
}
|
|
27582
|
+
dispatchTableLayoutChange(editor);
|
|
27583
|
+
return true;
|
|
27584
|
+
}
|
|
27585
|
+
|
|
27586
|
+
// src/components/UEditor/menus.tsx
|
|
27221
27587
|
var import_jsx_runtime82 = require("react/jsx-runtime");
|
|
27222
27588
|
var FloatingSlashCommandMenu = ({ editor, onClose }) => {
|
|
27223
27589
|
const t = useSmartTranslations("UEditor");
|
|
@@ -27274,7 +27640,7 @@ var FloatingMenuContent = ({ editor }) => {
|
|
|
27274
27640
|
function applyTableCellBackground(editor, color) {
|
|
27275
27641
|
const value = color || null;
|
|
27276
27642
|
const { state, view } = editor;
|
|
27277
|
-
const applied = (0,
|
|
27643
|
+
const applied = (0, import_tables2.setCellAttr)("backgroundColor", value)(state, view.dispatch.bind(view));
|
|
27278
27644
|
if (applied) {
|
|
27279
27645
|
view.focus();
|
|
27280
27646
|
return;
|
|
@@ -27306,7 +27672,9 @@ var BubbleMenuContent = ({
|
|
|
27306
27672
|
const currentTextColor = normalizeStyleValue(textStyleAttrs.color) || "inherit";
|
|
27307
27673
|
const currentHighlightColor = normalizeStyleValue(editor.getAttributes("highlight").color) || "";
|
|
27308
27674
|
const currentCellBgColor = normalizeStyleValue(editor.getAttributes("tableCell").backgroundColor || editor.getAttributes("tableHeader").backgroundColor) || "";
|
|
27309
|
-
const isInTable2 = (0,
|
|
27675
|
+
const isInTable2 = (0, import_tables2.isInTable)(editor.state);
|
|
27676
|
+
const canMergeCells = isInTable2 && editor.can().mergeCells();
|
|
27677
|
+
const canSplitCell = isInTable2 && editor.can().splitCell();
|
|
27310
27678
|
const currentFontSize = normalizeStyleValue(textStyleAttrs.fontSize);
|
|
27311
27679
|
const currentLineHeight = normalizeStyleValue(textStyleAttrs.lineHeight);
|
|
27312
27680
|
const quickFontSizes = (0, import_react51.useMemo)(
|
|
@@ -27601,15 +27969,33 @@ var BubbleMenuContent = ({
|
|
|
27601
27969
|
),
|
|
27602
27970
|
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(ToolbarButton, { onClick: () => setActiveColorPalette("text"), title: t("colors.textColor"), children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(TextColorIcon, { color: currentTextColor }) }),
|
|
27603
27971
|
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(ToolbarButton, { onClick: () => setActiveColorPalette("highlight"), active: editor.isActive("highlight"), title: t("colors.highlight"), children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(HighlightColorIcon, { color: currentHighlightColor }) }),
|
|
27604
|
-
isInTable2 && /* @__PURE__ */ (0, import_jsx_runtime82.
|
|
27605
|
-
|
|
27606
|
-
|
|
27607
|
-
|
|
27608
|
-
|
|
27609
|
-
|
|
27610
|
-
|
|
27611
|
-
|
|
27612
|
-
|
|
27972
|
+
isInTable2 && /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(import_jsx_runtime82.Fragment, { children: [
|
|
27973
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
27974
|
+
ToolbarButton,
|
|
27975
|
+
{
|
|
27976
|
+
onClick: () => setActiveColorPalette("cell-bg"),
|
|
27977
|
+
active: Boolean(currentCellBgColor),
|
|
27978
|
+
title: t("tableMenu.cellBackground") || "Cell background",
|
|
27979
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(CellBgColorIcon, { color: currentCellBgColor })
|
|
27980
|
+
}
|
|
27981
|
+
),
|
|
27982
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
27983
|
+
ToolbarButton,
|
|
27984
|
+
{
|
|
27985
|
+
onClick: () => {
|
|
27986
|
+
if (canSplitCell) {
|
|
27987
|
+
editor.chain().focus().splitCell().run();
|
|
27988
|
+
return;
|
|
27989
|
+
}
|
|
27990
|
+
mergeTableCellsPreservingColumnWidths(editor);
|
|
27991
|
+
},
|
|
27992
|
+
active: canSplitCell,
|
|
27993
|
+
disabled: !canMergeCells && !canSplitCell,
|
|
27994
|
+
title: canSplitCell ? t("tableMenu.splitCell") || "Split cell" : t("tableMenu.mergeCells") || "Merge cells",
|
|
27995
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_lucide_react45.TableCellsMerge, { className: "w-4 h-4" })
|
|
27996
|
+
}
|
|
27997
|
+
)
|
|
27998
|
+
] }),
|
|
27613
27999
|
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
27614
28000
|
ToolbarButton,
|
|
27615
28001
|
{
|
|
@@ -28101,7 +28487,7 @@ function findDiffEnd(a, b, posA, posB) {
|
|
|
28101
28487
|
posB -= size;
|
|
28102
28488
|
}
|
|
28103
28489
|
}
|
|
28104
|
-
var
|
|
28490
|
+
var Fragment29 = class _Fragment {
|
|
28105
28491
|
/**
|
|
28106
28492
|
@internal
|
|
28107
28493
|
*/
|
|
@@ -28393,7 +28779,7 @@ var Fragment28 = class _Fragment {
|
|
|
28393
28779
|
throw new RangeError("Can not convert " + nodes + " to a Fragment" + (nodes.nodesBetween ? " (looks like multiple versions of prosemirror-model were loaded)" : ""));
|
|
28394
28780
|
}
|
|
28395
28781
|
};
|
|
28396
|
-
|
|
28782
|
+
Fragment29.empty = new Fragment29([], 0);
|
|
28397
28783
|
var found = { index: 0, offset: 0 };
|
|
28398
28784
|
function retIndex(index, offset) {
|
|
28399
28785
|
found.index = index;
|
|
@@ -28618,7 +29004,7 @@ var Slice = class _Slice {
|
|
|
28618
29004
|
let openStart = json.openStart || 0, openEnd = json.openEnd || 0;
|
|
28619
29005
|
if (typeof openStart != "number" || typeof openEnd != "number")
|
|
28620
29006
|
throw new RangeError("Invalid input for Slice.fromJSON");
|
|
28621
|
-
return new _Slice(
|
|
29007
|
+
return new _Slice(Fragment29.fromJSON(schema, json.content), openStart, openEnd);
|
|
28622
29008
|
}
|
|
28623
29009
|
/**
|
|
28624
29010
|
Create a slice from a fragment by taking the maximum possible
|
|
@@ -28633,7 +29019,7 @@ var Slice = class _Slice {
|
|
|
28633
29019
|
return new _Slice(fragment, openStart, openEnd);
|
|
28634
29020
|
}
|
|
28635
29021
|
};
|
|
28636
|
-
Slice.empty = new Slice(
|
|
29022
|
+
Slice.empty = new Slice(Fragment29.empty, 0, 0);
|
|
28637
29023
|
function removeRange(content, from, to) {
|
|
28638
29024
|
let { index, offset } = content.findIndex(from), child = content.maybeChild(index);
|
|
28639
29025
|
let { index: indexTo, offset: offsetTo } = content.findIndex(to);
|
|
@@ -28731,7 +29117,7 @@ function replaceThreeWay($from, $start, $end, $to, depth) {
|
|
|
28731
29117
|
addNode(close(openEnd, replaceTwoWay($end, $to, depth + 1)), content);
|
|
28732
29118
|
}
|
|
28733
29119
|
addRange($to, null, depth, content);
|
|
28734
|
-
return new
|
|
29120
|
+
return new Fragment29(content);
|
|
28735
29121
|
}
|
|
28736
29122
|
function replaceTwoWay($from, $to, depth) {
|
|
28737
29123
|
let content = [];
|
|
@@ -28741,13 +29127,13 @@ function replaceTwoWay($from, $to, depth) {
|
|
|
28741
29127
|
addNode(close(type, replaceTwoWay($from, $to, depth + 1)), content);
|
|
28742
29128
|
}
|
|
28743
29129
|
addRange($to, null, depth, content);
|
|
28744
|
-
return new
|
|
29130
|
+
return new Fragment29(content);
|
|
28745
29131
|
}
|
|
28746
29132
|
function prepareSliceForReplace(slice, $along) {
|
|
28747
29133
|
let extra = $along.depth - slice.openStart, parent = $along.node(extra);
|
|
28748
29134
|
let node = parent.copy(slice.content);
|
|
28749
29135
|
for (let i = extra - 1; i >= 0; i--)
|
|
28750
|
-
node = $along.node(i).copy(
|
|
29136
|
+
node = $along.node(i).copy(Fragment29.from(node));
|
|
28751
29137
|
return {
|
|
28752
29138
|
start: node.resolveNoCache(slice.openStart + extra),
|
|
28753
29139
|
end: node.resolveNoCache(node.content.size - slice.openEnd - extra)
|
|
@@ -29086,7 +29472,7 @@ var Node2 = class _Node {
|
|
|
29086
29472
|
this.type = type;
|
|
29087
29473
|
this.attrs = attrs;
|
|
29088
29474
|
this.marks = marks;
|
|
29089
|
-
this.content = content ||
|
|
29475
|
+
this.content = content || Fragment29.empty;
|
|
29090
29476
|
}
|
|
29091
29477
|
/**
|
|
29092
29478
|
The array of this node's child nodes.
|
|
@@ -29391,7 +29777,7 @@ var Node2 = class _Node {
|
|
|
29391
29777
|
can optionally pass `start` and `end` indices into the
|
|
29392
29778
|
replacement fragment.
|
|
29393
29779
|
*/
|
|
29394
|
-
canReplace(from, to, replacement =
|
|
29780
|
+
canReplace(from, to, replacement = Fragment29.empty, start = 0, end = replacement.childCount) {
|
|
29395
29781
|
let one = this.contentMatchAt(from).matchFragment(replacement, start, end);
|
|
29396
29782
|
let two = one && one.matchFragment(this.content, to);
|
|
29397
29783
|
if (!two || !two.validEnd)
|
|
@@ -29473,7 +29859,7 @@ var Node2 = class _Node {
|
|
|
29473
29859
|
throw new RangeError("Invalid text node in JSON");
|
|
29474
29860
|
return schema.text(json.text, marks);
|
|
29475
29861
|
}
|
|
29476
|
-
let content =
|
|
29862
|
+
let content = Fragment29.fromJSON(schema, json.content);
|
|
29477
29863
|
let node = schema.nodeType(json.type).create(json.attrs, content, marks);
|
|
29478
29864
|
node.type.checkAttrs(node.attrs);
|
|
29479
29865
|
return node;
|
|
@@ -29569,7 +29955,7 @@ var ContentMatch = class _ContentMatch {
|
|
|
29569
29955
|
function search(match, types) {
|
|
29570
29956
|
let finished = match.matchFragment(after, startIndex);
|
|
29571
29957
|
if (finished && (!toEnd || finished.validEnd))
|
|
29572
|
-
return
|
|
29958
|
+
return Fragment29.from(types.map((tp) => tp.createAndFill()));
|
|
29573
29959
|
for (let i = 0; i < match.next.length; i++) {
|
|
29574
29960
|
let { type, next } = match.next[i];
|
|
29575
29961
|
if (!(type.isText || type.hasRequiredAttrs()) && seen.indexOf(next) == -1) {
|
|
@@ -30137,7 +30523,7 @@ function mapFragment(fragment, f, parent) {
|
|
|
30137
30523
|
child = f(child, parent, i);
|
|
30138
30524
|
mapped.push(child);
|
|
30139
30525
|
}
|
|
30140
|
-
return
|
|
30526
|
+
return Fragment29.fromArray(mapped);
|
|
30141
30527
|
}
|
|
30142
30528
|
var AddMarkStep = class _AddMarkStep extends Step {
|
|
30143
30529
|
/**
|
|
@@ -30254,7 +30640,7 @@ var AddNodeMarkStep = class _AddNodeMarkStep extends Step {
|
|
|
30254
30640
|
if (!node)
|
|
30255
30641
|
return StepResult.fail("No node at mark step's position");
|
|
30256
30642
|
let updated = node.type.create(node.attrs, null, this.mark.addToSet(node.marks));
|
|
30257
|
-
return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(
|
|
30643
|
+
return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment29.from(updated), 0, node.isLeaf ? 0 : 1));
|
|
30258
30644
|
}
|
|
30259
30645
|
invert(doc) {
|
|
30260
30646
|
let node = doc.nodeAt(this.pos);
|
|
@@ -30300,7 +30686,7 @@ var RemoveNodeMarkStep = class _RemoveNodeMarkStep extends Step {
|
|
|
30300
30686
|
if (!node)
|
|
30301
30687
|
return StepResult.fail("No node at mark step's position");
|
|
30302
30688
|
let updated = node.type.create(node.attrs, null, this.mark.removeFromSet(node.marks));
|
|
30303
|
-
return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(
|
|
30689
|
+
return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment29.from(updated), 0, node.isLeaf ? 0 : 1));
|
|
30304
30690
|
}
|
|
30305
30691
|
invert(doc) {
|
|
30306
30692
|
let node = doc.nodeAt(this.pos);
|
|
@@ -30501,7 +30887,7 @@ var AttrStep = class _AttrStep extends Step {
|
|
|
30501
30887
|
attrs[name] = node.attrs[name];
|
|
30502
30888
|
attrs[this.attr] = this.value;
|
|
30503
30889
|
let updated = node.type.create(attrs, null, node.marks);
|
|
30504
|
-
return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(
|
|
30890
|
+
return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment29.from(updated), 0, node.isLeaf ? 0 : 1));
|
|
30505
30891
|
}
|
|
30506
30892
|
getMap() {
|
|
30507
30893
|
return StepMap.empty;
|
|
@@ -30678,7 +31064,7 @@ var Selection = class {
|
|
|
30678
31064
|
found.
|
|
30679
31065
|
*/
|
|
30680
31066
|
static findFrom($pos, dir, textOnly = false) {
|
|
30681
|
-
let inner = $pos.parent.inlineContent ? new
|
|
31067
|
+
let inner = $pos.parent.inlineContent ? new TextSelection3($pos) : findSelectionIn($pos.node(0), $pos.parent, $pos.pos, $pos.index(), dir, textOnly);
|
|
30682
31068
|
if (inner)
|
|
30683
31069
|
return inner;
|
|
30684
31070
|
for (let depth = $pos.depth - 1; depth >= 0; depth--) {
|
|
@@ -30747,7 +31133,7 @@ var Selection = class {
|
|
|
30747
31133
|
returns the bookmark for that.
|
|
30748
31134
|
*/
|
|
30749
31135
|
getBookmark() {
|
|
30750
|
-
return
|
|
31136
|
+
return TextSelection3.between(this.$anchor, this.$head).getBookmark();
|
|
30751
31137
|
}
|
|
30752
31138
|
};
|
|
30753
31139
|
Selection.prototype.visible = true;
|
|
@@ -30767,7 +31153,7 @@ function checkTextSelection($pos) {
|
|
|
30767
31153
|
console["warn"]("TextSelection endpoint not pointing into a node with inline content (" + $pos.parent.type.name + ")");
|
|
30768
31154
|
}
|
|
30769
31155
|
}
|
|
30770
|
-
var
|
|
31156
|
+
var TextSelection3 = class _TextSelection extends Selection {
|
|
30771
31157
|
/**
|
|
30772
31158
|
Construct a text selection between the given points.
|
|
30773
31159
|
*/
|
|
@@ -30853,7 +31239,7 @@ var TextSelection2 = class _TextSelection extends Selection {
|
|
|
30853
31239
|
return new _TextSelection($anchor, $head);
|
|
30854
31240
|
}
|
|
30855
31241
|
};
|
|
30856
|
-
Selection.jsonID("text",
|
|
31242
|
+
Selection.jsonID("text", TextSelection3);
|
|
30857
31243
|
var TextBookmark = class _TextBookmark {
|
|
30858
31244
|
constructor(anchor, head) {
|
|
30859
31245
|
this.anchor = anchor;
|
|
@@ -30863,7 +31249,7 @@ var TextBookmark = class _TextBookmark {
|
|
|
30863
31249
|
return new _TextBookmark(mapping.map(this.anchor), mapping.map(this.head));
|
|
30864
31250
|
}
|
|
30865
31251
|
resolve(doc) {
|
|
30866
|
-
return
|
|
31252
|
+
return TextSelection3.between(doc.resolve(this.anchor), doc.resolve(this.head));
|
|
30867
31253
|
}
|
|
30868
31254
|
};
|
|
30869
31255
|
var NodeSelection2 = class _NodeSelection extends Selection {
|
|
@@ -30885,7 +31271,7 @@ var NodeSelection2 = class _NodeSelection extends Selection {
|
|
|
30885
31271
|
return new _NodeSelection($pos);
|
|
30886
31272
|
}
|
|
30887
31273
|
content() {
|
|
30888
|
-
return new Slice(
|
|
31274
|
+
return new Slice(Fragment29.from(this.node), 0, 0);
|
|
30889
31275
|
}
|
|
30890
31276
|
eq(other) {
|
|
30891
31277
|
return other instanceof _NodeSelection && other.anchor == this.anchor;
|
|
@@ -30982,7 +31368,7 @@ var AllBookmark = {
|
|
|
30982
31368
|
};
|
|
30983
31369
|
function findSelectionIn(doc, node, pos, index, dir, text = false) {
|
|
30984
31370
|
if (node.inlineContent)
|
|
30985
|
-
return
|
|
31371
|
+
return TextSelection3.create(doc, pos);
|
|
30986
31372
|
for (let i = index - (dir > 0 ? 0 : 1); dir > 0 ? i < node.childCount : i >= 0; i += dir) {
|
|
30987
31373
|
let child = node.child(i);
|
|
30988
31374
|
if (!child.isAtom) {
|
|
@@ -31288,7 +31674,7 @@ if (typeof WeakMap != "undefined") {
|
|
|
31288
31674
|
return cache[cachePos++] = value;
|
|
31289
31675
|
};
|
|
31290
31676
|
}
|
|
31291
|
-
var
|
|
31677
|
+
var TableMap2 = class {
|
|
31292
31678
|
constructor(width, height, map, problems) {
|
|
31293
31679
|
this.width = width;
|
|
31294
31680
|
this.height = height;
|
|
@@ -31425,7 +31811,7 @@ function computeMap(table) {
|
|
|
31425
31811
|
pos++;
|
|
31426
31812
|
}
|
|
31427
31813
|
if (width === 0 || height === 0) (problems || (problems = [])).push({ type: "zero_sized" });
|
|
31428
|
-
const tableMap = new
|
|
31814
|
+
const tableMap = new TableMap2(width, height, map, problems);
|
|
31429
31815
|
let badWidths = false;
|
|
31430
31816
|
for (let i = 0; !badWidths && i < colWidths.length; i += 2) if (colWidths[i] != null && colWidths[i + 1] < height) badWidths = true;
|
|
31431
31817
|
if (badWidths) findBadColWidths(tableMap, colWidths, table);
|
|
@@ -31529,7 +31915,7 @@ function inSameTable($cellA, $cellB) {
|
|
|
31529
31915
|
}
|
|
31530
31916
|
function nextCell($pos, axis, dir) {
|
|
31531
31917
|
const table = $pos.node(-1);
|
|
31532
|
-
const map =
|
|
31918
|
+
const map = TableMap2.get(table);
|
|
31533
31919
|
const tableStart = $pos.start(-1);
|
|
31534
31920
|
const moved = map.nextCell($pos.pos - tableStart, axis, dir);
|
|
31535
31921
|
return moved == null ? null : $pos.node(0).resolve(tableStart + moved);
|
|
@@ -31549,7 +31935,7 @@ function removeColSpan(attrs, pos, n = 1) {
|
|
|
31549
31935
|
var CellSelection = class CellSelection2 extends Selection {
|
|
31550
31936
|
constructor($anchorCell, $headCell = $anchorCell) {
|
|
31551
31937
|
const table = $anchorCell.node(-1);
|
|
31552
|
-
const map =
|
|
31938
|
+
const map = TableMap2.get(table);
|
|
31553
31939
|
const tableStart = $anchorCell.start(-1);
|
|
31554
31940
|
const rect = map.rectBetween($anchorCell.pos - tableStart, $headCell.pos - tableStart);
|
|
31555
31941
|
const doc = $anchorCell.node(0);
|
|
@@ -31574,11 +31960,11 @@ var CellSelection = class CellSelection2 extends Selection {
|
|
|
31574
31960
|
else if (tableChanged && this.isColSelection()) return CellSelection2.colSelection($anchorCell, $headCell);
|
|
31575
31961
|
else return new CellSelection2($anchorCell, $headCell);
|
|
31576
31962
|
}
|
|
31577
|
-
return
|
|
31963
|
+
return TextSelection3.between($anchorCell, $headCell);
|
|
31578
31964
|
}
|
|
31579
31965
|
content() {
|
|
31580
31966
|
const table = this.$anchorCell.node(-1);
|
|
31581
|
-
const map =
|
|
31967
|
+
const map = TableMap2.get(table);
|
|
31582
31968
|
const tableStart = this.$anchorCell.start(-1);
|
|
31583
31969
|
const rect = map.rectBetween(this.$anchorCell.pos - tableStart, this.$headCell.pos - tableStart);
|
|
31584
31970
|
const seen = {};
|
|
@@ -31613,10 +31999,10 @@ var CellSelection = class CellSelection2 extends Selection {
|
|
|
31613
31999
|
}
|
|
31614
32000
|
rowContent.push(cell);
|
|
31615
32001
|
}
|
|
31616
|
-
rows.push(table.child(row).copy(
|
|
32002
|
+
rows.push(table.child(row).copy(Fragment29.from(rowContent)));
|
|
31617
32003
|
}
|
|
31618
32004
|
const fragment = this.isColSelection() && this.isRowSelection() ? table : rows;
|
|
31619
|
-
return new Slice(
|
|
32005
|
+
return new Slice(Fragment29.from(fragment), 1, 1);
|
|
31620
32006
|
}
|
|
31621
32007
|
replace(tr, content = Slice.empty) {
|
|
31622
32008
|
const mapFrom = tr.steps.length, ranges = this.ranges;
|
|
@@ -31628,11 +32014,11 @@ var CellSelection = class CellSelection2 extends Selection {
|
|
|
31628
32014
|
if (sel) tr.setSelection(sel);
|
|
31629
32015
|
}
|
|
31630
32016
|
replaceWith(tr, node) {
|
|
31631
|
-
this.replace(tr, new Slice(
|
|
32017
|
+
this.replace(tr, new Slice(Fragment29.from(node), 0, 0));
|
|
31632
32018
|
}
|
|
31633
32019
|
forEachCell(f) {
|
|
31634
32020
|
const table = this.$anchorCell.node(-1);
|
|
31635
|
-
const map =
|
|
32021
|
+
const map = TableMap2.get(table);
|
|
31636
32022
|
const tableStart = this.$anchorCell.start(-1);
|
|
31637
32023
|
const cells = map.cellsInRect(map.rectBetween(this.$anchorCell.pos - tableStart, this.$headCell.pos - tableStart));
|
|
31638
32024
|
for (let i = 0; i < cells.length; i++) f(table.nodeAt(cells[i]), tableStart + cells[i]);
|
|
@@ -31647,7 +32033,7 @@ var CellSelection = class CellSelection2 extends Selection {
|
|
|
31647
32033
|
}
|
|
31648
32034
|
static colSelection($anchorCell, $headCell = $anchorCell) {
|
|
31649
32035
|
const table = $anchorCell.node(-1);
|
|
31650
|
-
const map =
|
|
32036
|
+
const map = TableMap2.get(table);
|
|
31651
32037
|
const tableStart = $anchorCell.start(-1);
|
|
31652
32038
|
const anchorRect = map.findCell($anchorCell.pos - tableStart);
|
|
31653
32039
|
const headRect = map.findCell($headCell.pos - tableStart);
|
|
@@ -31663,7 +32049,7 @@ var CellSelection = class CellSelection2 extends Selection {
|
|
|
31663
32049
|
}
|
|
31664
32050
|
isRowSelection() {
|
|
31665
32051
|
const table = this.$anchorCell.node(-1);
|
|
31666
|
-
const map =
|
|
32052
|
+
const map = TableMap2.get(table);
|
|
31667
32053
|
const tableStart = this.$anchorCell.start(-1);
|
|
31668
32054
|
const anchorLeft = map.colCount(this.$anchorCell.pos - tableStart);
|
|
31669
32055
|
const headLeft = map.colCount(this.$headCell.pos - tableStart);
|
|
@@ -31677,7 +32063,7 @@ var CellSelection = class CellSelection2 extends Selection {
|
|
|
31677
32063
|
}
|
|
31678
32064
|
static rowSelection($anchorCell, $headCell = $anchorCell) {
|
|
31679
32065
|
const table = $anchorCell.node(-1);
|
|
31680
|
-
const map =
|
|
32066
|
+
const map = TableMap2.get(table);
|
|
31681
32067
|
const tableStart = $anchorCell.start(-1);
|
|
31682
32068
|
const anchorRect = map.findCell($anchorCell.pos - tableStart);
|
|
31683
32069
|
const headRect = map.findCell($headCell.pos - tableStart);
|
|
@@ -31726,7 +32112,7 @@ var CellBookmark = class CellBookmark2 {
|
|
|
31726
32112
|
};
|
|
31727
32113
|
var fixTablesKey = new PluginKey3("fix-tables");
|
|
31728
32114
|
function convertTableNodeToArrayOfRows(tableNode) {
|
|
31729
|
-
const map =
|
|
32115
|
+
const map = TableMap2.get(tableNode);
|
|
31730
32116
|
const rows = [];
|
|
31731
32117
|
const rowCount = map.height;
|
|
31732
32118
|
const colCount$1 = map.width;
|
|
@@ -31757,7 +32143,7 @@ function convertTableNodeToArrayOfRows(tableNode) {
|
|
|
31757
32143
|
}
|
|
31758
32144
|
function convertArrayOfRowsToTableNode(tableNode, arrayOfNodes) {
|
|
31759
32145
|
const newRows = [];
|
|
31760
|
-
const map =
|
|
32146
|
+
const map = TableMap2.get(tableNode);
|
|
31761
32147
|
const rowCount = map.height;
|
|
31762
32148
|
const colCount$1 = map.width;
|
|
31763
32149
|
for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {
|
|
@@ -31806,7 +32192,7 @@ function findParentNode(predicate, $pos) {
|
|
|
31806
32192
|
function getCellsInColumn(columnIndex, selection) {
|
|
31807
32193
|
const table = findTable(selection.$from);
|
|
31808
32194
|
if (!table) return;
|
|
31809
|
-
const map =
|
|
32195
|
+
const map = TableMap2.get(table.node);
|
|
31810
32196
|
if (columnIndex < 0 || columnIndex > map.width - 1) return;
|
|
31811
32197
|
return map.cellsInRect({
|
|
31812
32198
|
left: columnIndex,
|
|
@@ -31827,7 +32213,7 @@ function getCellsInColumn(columnIndex, selection) {
|
|
|
31827
32213
|
function getCellsInRow(rowIndex, selection) {
|
|
31828
32214
|
const table = findTable(selection.$from);
|
|
31829
32215
|
if (!table) return;
|
|
31830
|
-
const map =
|
|
32216
|
+
const map = TableMap2.get(table.node);
|
|
31831
32217
|
if (rowIndex < 0 || rowIndex > map.height - 1) return;
|
|
31832
32218
|
return map.cellsInRect({
|
|
31833
32219
|
left: 0,
|
|
@@ -31956,7 +32342,7 @@ function moveColumn(moveColParams) {
|
|
|
31956
32342
|
const newTable = moveTableColumn$1(table.node, indexesOriginColumn, indexesTargetColumn, 0);
|
|
31957
32343
|
tr.replaceWith(table.pos, table.pos + table.node.nodeSize, newTable);
|
|
31958
32344
|
if (!select) return true;
|
|
31959
|
-
const map =
|
|
32345
|
+
const map = TableMap2.get(newTable);
|
|
31960
32346
|
const start = table.start;
|
|
31961
32347
|
const index = targetIndex;
|
|
31962
32348
|
const lastCell = map.positionAt(map.height - 1, index, newTable);
|
|
@@ -31984,7 +32370,7 @@ function moveRow(moveRowParams) {
|
|
|
31984
32370
|
const newTable = moveTableRow$1(table.node, indexesOriginRow, indexesTargetRow, 0);
|
|
31985
32371
|
tr.replaceWith(table.pos, table.pos + table.node.nodeSize, newTable);
|
|
31986
32372
|
if (!select) return true;
|
|
31987
|
-
const map =
|
|
32373
|
+
const map = TableMap2.get(newTable);
|
|
31988
32374
|
const start = table.start;
|
|
31989
32375
|
const index = targetIndex;
|
|
31990
32376
|
const lastCell = map.positionAt(index, map.width - 1, newTable);
|
|
@@ -31999,12 +32385,12 @@ function moveTableRow$1(table, indexesOrigin, indexesTarget, direction) {
|
|
|
31999
32385
|
rows = moveRowInArrayOfRows(rows, indexesOrigin, indexesTarget, direction);
|
|
32000
32386
|
return convertArrayOfRowsToTableNode(table, rows);
|
|
32001
32387
|
}
|
|
32002
|
-
function
|
|
32388
|
+
function selectedRect2(state) {
|
|
32003
32389
|
const sel = state.selection;
|
|
32004
32390
|
const $pos = selectionCell(state);
|
|
32005
32391
|
const table = $pos.node(-1);
|
|
32006
32392
|
const tableStart = $pos.start(-1);
|
|
32007
|
-
const map =
|
|
32393
|
+
const map = TableMap2.get(table);
|
|
32008
32394
|
return {
|
|
32009
32395
|
...sel instanceof CellSelection ? map.rectBetween(sel.$anchorCell.pos - tableStart, sel.$headCell.pos - tableStart) : map.findCell($pos.pos - tableStart),
|
|
32010
32396
|
tableStart,
|
|
@@ -32017,7 +32403,7 @@ function deprecated_toggleHeader(type) {
|
|
|
32017
32403
|
if (!isInTable(state)) return false;
|
|
32018
32404
|
if (dispatch) {
|
|
32019
32405
|
const types = tableNodeTypes(state.schema);
|
|
32020
|
-
const rect =
|
|
32406
|
+
const rect = selectedRect2(state), tr = state.tr;
|
|
32021
32407
|
const cells = rect.map.cellsInRect(type == "column" ? {
|
|
32022
32408
|
left: rect.left,
|
|
32023
32409
|
top: 0,
|
|
@@ -32057,7 +32443,7 @@ function toggleHeader(type, options) {
|
|
|
32057
32443
|
if (!isInTable(state)) return false;
|
|
32058
32444
|
if (dispatch) {
|
|
32059
32445
|
const types = tableNodeTypes(state.schema);
|
|
32060
|
-
const rect =
|
|
32446
|
+
const rect = selectedRect2(state), tr = state.tr;
|
|
32061
32447
|
const isHeaderRowEnabled = isHeaderEnabledByType("row", rect, types);
|
|
32062
32448
|
const isHeaderColumnEnabled = isHeaderEnabledByType("column", rect, types);
|
|
32063
32449
|
const selectionStartsAt = (type === "column" ? isHeaderRowEnabled : type === "row" ? isHeaderColumnEnabled : false) ? 1 : 0;
|
|
@@ -32189,7 +32575,7 @@ function shiftArrow(axis, dir) {
|
|
|
32189
32575
|
};
|
|
32190
32576
|
}
|
|
32191
32577
|
function atEndOfCell(view, axis, dir) {
|
|
32192
|
-
if (!(view.state.selection instanceof
|
|
32578
|
+
if (!(view.state.selection instanceof TextSelection3)) return null;
|
|
32193
32579
|
const { $head } = view.state.selection;
|
|
32194
32580
|
for (let d = $head.depth - 1; d >= 0; d--) {
|
|
32195
32581
|
const parent = $head.node(d);
|
|
@@ -32205,152 +32591,482 @@ function atEndOfCell(view, axis, dir) {
|
|
|
32205
32591
|
var columnResizingPluginKey = new PluginKey3("tableColumnResizing");
|
|
32206
32592
|
|
|
32207
32593
|
// src/components/UEditor/table-controls.tsx
|
|
32208
|
-
var
|
|
32209
|
-
|
|
32210
|
-
// src/components/UEditor/table-dom-utils.ts
|
|
32211
|
-
var MIN_TABLE_ROW_HEIGHT = 36;
|
|
32212
|
-
var COLUMN_RESIZE_LINE_THICKNESS = 2;
|
|
32213
|
-
var ROW_RESIZE_LINE_THICKNESS = 2;
|
|
32214
|
-
var UEDITOR_TABLE_LAYOUT_CHANGE_EVENT = "ueditor-table-layout-change";
|
|
32215
|
-
var TABLE_RESIZE_HIT_ZONE = 10;
|
|
32216
|
-
function findTableRowNodeInfo(view, rowElement) {
|
|
32217
|
-
const firstCell = rowElement.querySelector("th,td");
|
|
32218
|
-
if (!firstCell) return null;
|
|
32219
|
-
const cellPos = view.posAtDOM(firstCell, 0);
|
|
32220
|
-
const $pos = view.state.doc.resolve(cellPos);
|
|
32221
|
-
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
32222
|
-
const node = $pos.node(depth);
|
|
32223
|
-
if (node.type.name === "tableRow") {
|
|
32224
|
-
return {
|
|
32225
|
-
pos: $pos.before(depth),
|
|
32226
|
-
node
|
|
32227
|
-
};
|
|
32228
|
-
}
|
|
32229
|
-
}
|
|
32230
|
-
return null;
|
|
32231
|
-
}
|
|
32232
|
-
function resolveEventElement(target) {
|
|
32233
|
-
if (target instanceof Element) return target;
|
|
32234
|
-
if (target instanceof Node) return target.parentElement;
|
|
32235
|
-
return null;
|
|
32236
|
-
}
|
|
32237
|
-
function getSelectionTableCell(view) {
|
|
32238
|
-
const browserSelection = window.getSelection();
|
|
32239
|
-
const anchorElement = resolveEventElement(browserSelection?.anchorNode ?? null);
|
|
32240
|
-
const anchorCell = anchorElement?.closest?.("th,td");
|
|
32241
|
-
if (anchorCell instanceof HTMLElement) {
|
|
32242
|
-
return anchorCell;
|
|
32243
|
-
}
|
|
32244
|
-
const { from } = view.state.selection;
|
|
32245
|
-
const domAtPos = view.domAtPos(from);
|
|
32246
|
-
const element = resolveEventElement(domAtPos.node);
|
|
32247
|
-
const cell = element?.closest?.("th,td");
|
|
32248
|
-
return cell instanceof HTMLElement ? cell : null;
|
|
32249
|
-
}
|
|
32250
|
-
function isRowResizeHotspot(cell, clientX, clientY) {
|
|
32251
|
-
const rect = cell.getBoundingClientRect();
|
|
32252
|
-
const nearBottom = rect.bottom - clientY <= TABLE_RESIZE_HIT_ZONE;
|
|
32253
|
-
const nearRight = rect.right - clientX <= TABLE_RESIZE_HIT_ZONE;
|
|
32254
|
-
return nearBottom && !nearRight;
|
|
32255
|
-
}
|
|
32256
|
-
function isColumnResizeHotspot(cell, clientX, clientY) {
|
|
32257
|
-
const rect = cell.getBoundingClientRect();
|
|
32258
|
-
const nearRight = rect.right - clientX <= TABLE_RESIZE_HIT_ZONE;
|
|
32259
|
-
const nearBottom = rect.bottom - clientY <= TABLE_RESIZE_HIT_ZONE;
|
|
32260
|
-
return nearRight && !nearBottom;
|
|
32261
|
-
}
|
|
32262
|
-
function getRelativeBoundaryMetrics(surface, table, row, cell) {
|
|
32263
|
-
const surfaceRect = surface.getBoundingClientRect();
|
|
32264
|
-
const tableRect = table.getBoundingClientRect();
|
|
32265
|
-
const rowRect = row.getBoundingClientRect();
|
|
32266
|
-
const cellRect = cell.getBoundingClientRect();
|
|
32267
|
-
return {
|
|
32268
|
-
left: tableRect.left - surfaceRect.left + surface.scrollLeft,
|
|
32269
|
-
top: tableRect.top - surfaceRect.top + surface.scrollTop,
|
|
32270
|
-
width: tableRect.width,
|
|
32271
|
-
height: tableRect.height,
|
|
32272
|
-
rowBottom: rowRect.bottom - surfaceRect.top + surface.scrollTop,
|
|
32273
|
-
columnRight: cellRect.right - surfaceRect.left + surface.scrollLeft
|
|
32274
|
-
};
|
|
32275
|
-
}
|
|
32276
|
-
function getRelativeCellMetrics(surface, cell) {
|
|
32277
|
-
const surfaceRect = surface.getBoundingClientRect();
|
|
32278
|
-
const cellRect = cell.getBoundingClientRect();
|
|
32279
|
-
return {
|
|
32280
|
-
left: cellRect.left - surfaceRect.left + surface.scrollLeft,
|
|
32281
|
-
top: cellRect.top - surfaceRect.top + surface.scrollTop,
|
|
32282
|
-
width: cellRect.width,
|
|
32283
|
-
height: cellRect.height
|
|
32284
|
-
};
|
|
32285
|
-
}
|
|
32286
|
-
function getRelativeSelectedCellsMetrics(surface) {
|
|
32287
|
-
const selectedCells = Array.from(
|
|
32288
|
-
surface.querySelectorAll("td.selectedCell, th.selectedCell")
|
|
32289
|
-
);
|
|
32290
|
-
if (selectedCells.length === 0) {
|
|
32291
|
-
return null;
|
|
32292
|
-
}
|
|
32293
|
-
const surfaceRect = surface.getBoundingClientRect();
|
|
32294
|
-
let left = Number.POSITIVE_INFINITY;
|
|
32295
|
-
let top = Number.POSITIVE_INFINITY;
|
|
32296
|
-
let right = Number.NEGATIVE_INFINITY;
|
|
32297
|
-
let bottom = Number.NEGATIVE_INFINITY;
|
|
32298
|
-
selectedCells.forEach((cell) => {
|
|
32299
|
-
const rect = cell.getBoundingClientRect();
|
|
32300
|
-
left = Math.min(left, rect.left);
|
|
32301
|
-
top = Math.min(top, rect.top);
|
|
32302
|
-
right = Math.max(right, rect.right);
|
|
32303
|
-
bottom = Math.max(bottom, rect.bottom);
|
|
32304
|
-
});
|
|
32305
|
-
return {
|
|
32306
|
-
left: left - surfaceRect.left + surface.scrollLeft,
|
|
32307
|
-
top: top - surfaceRect.top + surface.scrollTop,
|
|
32308
|
-
width: right - left,
|
|
32309
|
-
height: bottom - top
|
|
32310
|
-
};
|
|
32311
|
-
}
|
|
32594
|
+
var import_lucide_react48 = require("lucide-react");
|
|
32312
32595
|
|
|
32313
|
-
// src/components/UEditor/table-
|
|
32314
|
-
var import_jsx_runtime84 = require("react/jsx-runtime");
|
|
32315
|
-
var FALLBACK_TABLE_ROW_HEIGHT = 44;
|
|
32316
|
-
var FALLBACK_TABLE_COLUMN_WIDTH = 160;
|
|
32596
|
+
// src/components/UEditor/table-hover-state.ts
|
|
32317
32597
|
var MENU_HOVER_PADDING = 18;
|
|
32318
32598
|
var ROW_HANDLE_HOVER_WIDTH = 28;
|
|
32319
32599
|
var COLUMN_HANDLE_HOVER_HEIGHT = 28;
|
|
32320
|
-
var TABLE_MENU_TOP_OFFSET = 10;
|
|
32321
|
-
var ADD_COLUMN_RAIL_GAP = 4;
|
|
32322
|
-
var ADD_ROW_RAIL_GAP = 4;
|
|
32323
32600
|
var ADD_COLUMN_HOVER_WIDTH = 24;
|
|
32324
32601
|
var ADD_ROW_HOVER_HEIGHT = 24;
|
|
32325
32602
|
var HANDLE_HOVER_RADIUS = 14;
|
|
32326
|
-
var
|
|
32327
|
-
var DEFAULT_HOVER_STATE = {
|
|
32603
|
+
var DEFAULT_TABLE_HOVER_STATE = {
|
|
32328
32604
|
menuVisible: false,
|
|
32329
32605
|
addColumnVisible: false,
|
|
32330
32606
|
addRowVisible: false,
|
|
32331
32607
|
rowHandleIndex: null,
|
|
32332
32608
|
columnHandleIndex: null
|
|
32333
32609
|
};
|
|
32334
|
-
function
|
|
32335
|
-
|
|
32336
|
-
if (target instanceof Node) return target.parentElement;
|
|
32337
|
-
return null;
|
|
32610
|
+
function areTableHoverStatesEqual(left, right) {
|
|
32611
|
+
return left.menuVisible === right.menuVisible && left.addColumnVisible === right.addColumnVisible && left.addRowVisible === right.addRowVisible && left.rowHandleIndex === right.rowHandleIndex && left.columnHandleIndex === right.columnHandleIndex;
|
|
32338
32612
|
}
|
|
32339
|
-
function
|
|
32340
|
-
|
|
32341
|
-
|
|
32342
|
-
|
|
32343
|
-
|
|
32344
|
-
|
|
32345
|
-
|
|
32346
|
-
|
|
32613
|
+
function buildTableHoverState({
|
|
32614
|
+
event,
|
|
32615
|
+
layout,
|
|
32616
|
+
surface
|
|
32617
|
+
}) {
|
|
32618
|
+
const surfaceRect = surface.getBoundingClientRect();
|
|
32619
|
+
const relativeX = event.clientX - surfaceRect.left + surface.scrollLeft;
|
|
32620
|
+
const relativeY = event.clientY - surfaceRect.top + surface.scrollTop;
|
|
32621
|
+
const targetElement = resolveEventElement(event.target);
|
|
32622
|
+
const directRowHandle = targetElement?.closest?.("[data-row-handle-index]");
|
|
32623
|
+
const directColumnHandle = targetElement?.closest?.("[data-column-handle-index]");
|
|
32624
|
+
const directTableMenu = targetElement?.closest?.("[data-table-control='table-menu']");
|
|
32625
|
+
const directAddColumn = targetElement?.closest?.("[data-table-control='add-column']");
|
|
32626
|
+
const directAddRow = targetElement?.closest?.("[data-table-control='add-row']");
|
|
32627
|
+
const directRowHandleIndex = directRowHandle instanceof HTMLElement ? Number.parseInt(directRowHandle.dataset.rowHandleIndex ?? "", 10) : Number.NaN;
|
|
32628
|
+
const directColumnHandleIndex = directColumnHandle instanceof HTMLElement ? Number.parseInt(directColumnHandle.dataset.columnHandleIndex ?? "", 10) : Number.NaN;
|
|
32629
|
+
const visibleTableWidth = Math.min(layout.tableWidth, layout.viewportWidth);
|
|
32630
|
+
const visibleTableHeight = Math.min(layout.tableHeight, layout.viewportHeight);
|
|
32631
|
+
const isMouseInTable = relativeX >= layout.tableLeft && relativeX <= layout.tableLeft + layout.tableWidth && relativeY >= layout.tableTop && relativeY <= layout.tableTop + layout.tableHeight;
|
|
32632
|
+
const rowHandleIndex = Number.isFinite(directRowHandleIndex) ? directRowHandleIndex : layout.rowHandles.find((rowHandle) => relativeX >= layout.tableLeft - ROW_HANDLE_HOVER_WIDTH && relativeX <= layout.tableLeft && Math.abs(relativeY - rowHandle.center) <= HANDLE_HOVER_RADIUS)?.index ?? null;
|
|
32633
|
+
const columnHandleIndex = Number.isFinite(directColumnHandleIndex) ? directColumnHandleIndex : layout.columnHandles.find((columnHandle) => relativeY >= layout.tableTop - COLUMN_HANDLE_HOVER_HEIGHT && relativeY <= layout.tableTop && Math.abs(relativeX - columnHandle.center) <= HANDLE_HOVER_RADIUS)?.index ?? null;
|
|
32634
|
+
const menuVisible = Boolean(directTableMenu) || isMouseInTable || relativeX >= layout.tableLeft - MENU_HOVER_PADDING && relativeX <= layout.tableLeft + 42 && relativeY >= layout.tableTop - COLUMN_HANDLE_HOVER_HEIGHT && relativeY <= layout.tableTop + MENU_HOVER_PADDING;
|
|
32635
|
+
const lastRow = layout.rowHandles[layout.rowHandles.length - 1];
|
|
32636
|
+
const lastCol = layout.columnHandles[layout.columnHandles.length - 1];
|
|
32637
|
+
const isMouseInLastColumn = lastCol ? relativeX >= lastCol.start && relativeX <= lastCol.start + lastCol.size && relativeY >= layout.tableTop && relativeY <= layout.tableTop + visibleTableHeight : false;
|
|
32638
|
+
const addColumnVisible = Boolean(directAddColumn) || relativeX >= layout.tableLeft + visibleTableWidth && relativeX <= layout.tableLeft + visibleTableWidth + ADD_COLUMN_HOVER_WIDTH && relativeY >= layout.tableTop && relativeY <= layout.tableTop + visibleTableHeight || isMouseInLastColumn;
|
|
32639
|
+
const isMouseInLastRow = lastRow ? relativeY >= lastRow.start && relativeY <= lastRow.start + lastRow.size && relativeX >= layout.tableLeft && relativeX <= layout.tableLeft + visibleTableWidth : false;
|
|
32640
|
+
const addRowVisible = Boolean(directAddRow) || relativeY >= layout.tableTop + visibleTableHeight && relativeY <= layout.tableTop + visibleTableHeight + ADD_ROW_HOVER_HEIGHT && relativeX >= layout.tableLeft && relativeX <= layout.tableLeft + visibleTableWidth || isMouseInLastRow;
|
|
32641
|
+
return {
|
|
32642
|
+
menuVisible,
|
|
32643
|
+
addColumnVisible,
|
|
32644
|
+
addRowVisible,
|
|
32645
|
+
rowHandleIndex,
|
|
32646
|
+
columnHandleIndex
|
|
32647
|
+
};
|
|
32648
|
+
}
|
|
32649
|
+
|
|
32650
|
+
// src/components/UEditor/table-drag-preview.tsx
|
|
32651
|
+
var import_jsx_runtime84 = require("react/jsx-runtime");
|
|
32652
|
+
function TableDragPreview({
|
|
32653
|
+
columnDragLabel,
|
|
32654
|
+
dragPreview,
|
|
32655
|
+
layout,
|
|
32656
|
+
rowDragLabel
|
|
32657
|
+
}) {
|
|
32658
|
+
if (!dragPreview) return null;
|
|
32659
|
+
const expandPreviewWidth = dragPreview.kind === "add-column" ? layout.tableWidth + dragPreview.previewCols * layout.avgColumnWidth : layout.tableWidth;
|
|
32660
|
+
const expandPreviewHeight = dragPreview.kind === "add-row" ? layout.tableHeight + dragPreview.previewRows * layout.avgRowHeight : layout.tableHeight;
|
|
32661
|
+
const dragStatusText = dragPreview.kind === "row" ? `${rowDragLabel} ${dragPreview.originIndex + 1} -> ${dragPreview.targetIndex + 1}` : dragPreview.kind === "column" ? `${columnDragLabel} ${dragPreview.originIndex + 1} -> ${dragPreview.targetIndex + 1}` : dragPreview.kind === "add-row" ? `+${dragPreview.previewRows}R` : `+${dragPreview.previewCols}C`;
|
|
32662
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(import_jsx_runtime84.Fragment, { children: [
|
|
32663
|
+
dragPreview.kind === "row" && /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(import_jsx_runtime84.Fragment, { children: [
|
|
32664
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
32665
|
+
"div",
|
|
32666
|
+
{
|
|
32667
|
+
"aria-hidden": "true",
|
|
32668
|
+
className: "pointer-events-none absolute z-20 rounded-lg border border-primary/20 bg-primary/10",
|
|
32669
|
+
style: {
|
|
32670
|
+
top: dragPreview.targetStart,
|
|
32671
|
+
left: layout.tableLeft,
|
|
32672
|
+
width: layout.tableWidth,
|
|
32673
|
+
height: dragPreview.targetSize
|
|
32674
|
+
}
|
|
32675
|
+
}
|
|
32676
|
+
),
|
|
32677
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
32678
|
+
"div",
|
|
32679
|
+
{
|
|
32680
|
+
"aria-hidden": "true",
|
|
32681
|
+
className: "pointer-events-none absolute z-20 rounded-full bg-primary/80",
|
|
32682
|
+
style: {
|
|
32683
|
+
top: dragPreview.targetStart + dragPreview.targetSize / 2 - 1,
|
|
32684
|
+
left: layout.tableLeft,
|
|
32685
|
+
width: layout.tableWidth,
|
|
32686
|
+
height: 2
|
|
32687
|
+
}
|
|
32688
|
+
}
|
|
32689
|
+
)
|
|
32690
|
+
] }),
|
|
32691
|
+
dragPreview.kind === "column" && /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(import_jsx_runtime84.Fragment, { children: [
|
|
32692
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
32693
|
+
"div",
|
|
32694
|
+
{
|
|
32695
|
+
"aria-hidden": "true",
|
|
32696
|
+
className: "pointer-events-none absolute z-20 rounded-lg border border-primary/20 bg-primary/10",
|
|
32697
|
+
style: {
|
|
32698
|
+
top: layout.tableTop,
|
|
32699
|
+
left: dragPreview.targetStart,
|
|
32700
|
+
width: dragPreview.targetSize,
|
|
32701
|
+
height: layout.tableHeight
|
|
32702
|
+
}
|
|
32703
|
+
}
|
|
32704
|
+
),
|
|
32705
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
32706
|
+
"div",
|
|
32707
|
+
{
|
|
32708
|
+
"aria-hidden": "true",
|
|
32709
|
+
className: "pointer-events-none absolute z-20 rounded-full bg-primary/80",
|
|
32710
|
+
style: {
|
|
32711
|
+
top: layout.tableTop,
|
|
32712
|
+
left: dragPreview.targetStart + dragPreview.targetSize / 2 - 1,
|
|
32713
|
+
width: 2,
|
|
32714
|
+
height: layout.tableHeight
|
|
32715
|
+
}
|
|
32716
|
+
}
|
|
32717
|
+
)
|
|
32718
|
+
] }),
|
|
32719
|
+
(dragPreview.kind === "add-row" || dragPreview.kind === "add-column") && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
32720
|
+
"div",
|
|
32721
|
+
{
|
|
32722
|
+
"aria-hidden": "true",
|
|
32723
|
+
className: "pointer-events-none absolute z-20 rounded-xl border border-dashed border-primary/70 bg-primary/5",
|
|
32724
|
+
style: {
|
|
32725
|
+
top: layout.tableTop,
|
|
32726
|
+
left: layout.tableLeft,
|
|
32727
|
+
width: expandPreviewWidth,
|
|
32728
|
+
height: expandPreviewHeight
|
|
32729
|
+
}
|
|
32730
|
+
}
|
|
32731
|
+
),
|
|
32732
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
32733
|
+
"div",
|
|
32734
|
+
{
|
|
32735
|
+
role: "status",
|
|
32736
|
+
className: "pointer-events-none absolute z-30 rounded-full border border-primary/20 bg-background/95 px-2 py-1 text-[11px] font-medium text-foreground shadow-sm backdrop-blur",
|
|
32737
|
+
style: {
|
|
32738
|
+
top: dragPreview.kind === "add-row" || dragPreview.kind === "add-column" ? layout.tableTop + expandPreviewHeight + 8 : layout.tableTop - 40,
|
|
32739
|
+
left: dragPreview.kind === "add-row" || dragPreview.kind === "add-column" ? layout.tableLeft + Math.max(0, expandPreviewWidth - 84) : layout.tableLeft + Math.max(0, layout.tableWidth - 108)
|
|
32740
|
+
},
|
|
32741
|
+
children: dragStatusText
|
|
32742
|
+
}
|
|
32743
|
+
)
|
|
32744
|
+
] });
|
|
32745
|
+
}
|
|
32746
|
+
|
|
32747
|
+
// src/components/UEditor/table-add-rails.tsx
|
|
32748
|
+
var import_jsx_runtime85 = require("react/jsx-runtime");
|
|
32749
|
+
var ADD_COLUMN_RAIL_GAP = 4;
|
|
32750
|
+
var ADD_ROW_RAIL_GAP = 4;
|
|
32751
|
+
function TableAddRails({
|
|
32752
|
+
addColumnVisible,
|
|
32753
|
+
addRowVisible,
|
|
32754
|
+
canExpandTable,
|
|
32755
|
+
controlsVisible,
|
|
32756
|
+
layout,
|
|
32757
|
+
onStartAddColumn,
|
|
32758
|
+
onStartAddRow,
|
|
32759
|
+
quickAddColumnLabel,
|
|
32760
|
+
quickAddRowLabel
|
|
32761
|
+
}) {
|
|
32762
|
+
const visibleTableWidth = Math.min(layout.tableWidth, layout.viewportWidth);
|
|
32763
|
+
const visibleTableHeight = Math.min(layout.tableHeight, layout.viewportHeight);
|
|
32764
|
+
const columnRailTop = layout.tableTop;
|
|
32765
|
+
const columnRailLeft = layout.tableLeft + visibleTableWidth + ADD_COLUMN_RAIL_GAP;
|
|
32766
|
+
const rowRailTop = layout.tableTop + visibleTableHeight + ADD_ROW_RAIL_GAP;
|
|
32767
|
+
const rowRailLeft = layout.tableLeft;
|
|
32768
|
+
const showColumnRail = controlsVisible || addColumnVisible;
|
|
32769
|
+
const showRowRail = controlsVisible || addRowVisible;
|
|
32770
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(import_jsx_runtime85.Fragment, { children: [
|
|
32771
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
|
|
32772
|
+
Tooltip,
|
|
32773
|
+
{
|
|
32774
|
+
placement: "right",
|
|
32775
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "text-xs font-medium", children: quickAddColumnLabel }),
|
|
32776
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
|
|
32777
|
+
"button",
|
|
32778
|
+
{
|
|
32779
|
+
type: "button",
|
|
32780
|
+
"data-table-control": "add-column",
|
|
32781
|
+
"aria-label": quickAddColumnLabel,
|
|
32782
|
+
onMouseDown: (event) => {
|
|
32783
|
+
event.preventDefault();
|
|
32784
|
+
event.stopPropagation();
|
|
32785
|
+
if (!canExpandTable) return;
|
|
32786
|
+
onStartAddColumn();
|
|
32787
|
+
},
|
|
32788
|
+
disabled: !canExpandTable,
|
|
32789
|
+
className: cn(
|
|
32790
|
+
"absolute z-30 inline-flex items-center justify-center rounded-md",
|
|
32791
|
+
"border border-border/70 bg-muted/40 text-muted-foreground shadow-sm backdrop-blur",
|
|
32792
|
+
"transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground disabled:opacity-50 disabled:cursor-not-allowed"
|
|
32793
|
+
),
|
|
32794
|
+
style: {
|
|
32795
|
+
top: showColumnRail ? columnRailTop : columnRailTop + Math.max(0, visibleTableHeight / 2 - 24),
|
|
32796
|
+
left: columnRailLeft,
|
|
32797
|
+
width: showColumnRail ? 18 : 12,
|
|
32798
|
+
height: showColumnRail ? visibleTableHeight : 48,
|
|
32799
|
+
opacity: showColumnRail ? 1 : 0,
|
|
32800
|
+
transform: showColumnRail ? "scale(1)" : "scale(0.92)",
|
|
32801
|
+
pointerEvents: showColumnRail ? "auto" : "none"
|
|
32802
|
+
},
|
|
32803
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "text-sm font-medium leading-none", children: "+" })
|
|
32804
|
+
}
|
|
32805
|
+
)
|
|
32806
|
+
}
|
|
32807
|
+
),
|
|
32808
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
|
|
32809
|
+
Tooltip,
|
|
32810
|
+
{
|
|
32811
|
+
placement: "bottom",
|
|
32812
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "text-xs font-medium", children: quickAddRowLabel }),
|
|
32813
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
|
|
32814
|
+
"button",
|
|
32815
|
+
{
|
|
32816
|
+
type: "button",
|
|
32817
|
+
"data-table-control": "add-row",
|
|
32818
|
+
"aria-label": quickAddRowLabel,
|
|
32819
|
+
onMouseDown: (event) => {
|
|
32820
|
+
event.preventDefault();
|
|
32821
|
+
event.stopPropagation();
|
|
32822
|
+
if (!canExpandTable) return;
|
|
32823
|
+
onStartAddRow();
|
|
32824
|
+
},
|
|
32825
|
+
disabled: !canExpandTable,
|
|
32826
|
+
className: cn(
|
|
32827
|
+
"absolute z-30 inline-flex items-center justify-center rounded-md",
|
|
32828
|
+
"border border-border/70 bg-muted/40 text-muted-foreground shadow-sm backdrop-blur",
|
|
32829
|
+
"transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground disabled:opacity-50 disabled:cursor-not-allowed"
|
|
32830
|
+
),
|
|
32831
|
+
style: {
|
|
32832
|
+
top: rowRailTop,
|
|
32833
|
+
left: showRowRail ? rowRailLeft : rowRailLeft + Math.max(0, visibleTableWidth / 2 - 24),
|
|
32834
|
+
width: showRowRail ? visibleTableWidth : 48,
|
|
32835
|
+
height: showRowRail ? 16 : 12,
|
|
32836
|
+
opacity: showRowRail ? 1 : 0,
|
|
32837
|
+
transform: showRowRail ? "scale(1)" : "scale(0.92)",
|
|
32838
|
+
pointerEvents: showRowRail ? "auto" : "none"
|
|
32839
|
+
},
|
|
32840
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "text-sm font-medium leading-none", children: "+" })
|
|
32841
|
+
}
|
|
32842
|
+
)
|
|
32843
|
+
}
|
|
32844
|
+
)
|
|
32845
|
+
] });
|
|
32846
|
+
}
|
|
32847
|
+
|
|
32848
|
+
// src/components/UEditor/table-control-menu.tsx
|
|
32849
|
+
var import_lucide_react46 = require("lucide-react");
|
|
32850
|
+
var import_jsx_runtime86 = require("react/jsx-runtime");
|
|
32851
|
+
function TableControlMenu({
|
|
32852
|
+
controlsVisible,
|
|
32853
|
+
isOpen,
|
|
32854
|
+
items,
|
|
32855
|
+
label,
|
|
32856
|
+
left,
|
|
32857
|
+
menuVisible,
|
|
32858
|
+
onOpenChange,
|
|
32859
|
+
top
|
|
32860
|
+
}) {
|
|
32861
|
+
const shown = controlsVisible || menuVisible || isOpen;
|
|
32862
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
32863
|
+
"div",
|
|
32864
|
+
{
|
|
32865
|
+
className: "absolute z-30",
|
|
32866
|
+
"data-table-control": "table-menu",
|
|
32867
|
+
style: {
|
|
32868
|
+
top,
|
|
32869
|
+
left
|
|
32870
|
+
},
|
|
32871
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
32872
|
+
Tooltip,
|
|
32873
|
+
{
|
|
32874
|
+
placement: "top",
|
|
32875
|
+
disabled: isOpen,
|
|
32876
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "text-xs font-medium", children: label }),
|
|
32877
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "inline-flex", children: /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
32878
|
+
DropdownMenu,
|
|
32879
|
+
{
|
|
32880
|
+
placement: "bottom-start",
|
|
32881
|
+
isOpen,
|
|
32882
|
+
onOpenChange,
|
|
32883
|
+
contentClassName: "p-2",
|
|
32884
|
+
items,
|
|
32885
|
+
trigger: /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
32886
|
+
"button",
|
|
32887
|
+
{
|
|
32888
|
+
type: "button",
|
|
32889
|
+
"aria-label": label,
|
|
32890
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
32891
|
+
className: cn(
|
|
32892
|
+
"pointer-events-auto inline-flex h-7 w-7 items-center justify-center rounded-full",
|
|
32893
|
+
"border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
|
|
32894
|
+
"transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
|
|
32895
|
+
),
|
|
32896
|
+
style: {
|
|
32897
|
+
opacity: shown ? 1 : 0,
|
|
32898
|
+
transform: shown ? "scale(1)" : "scale(0.82)",
|
|
32899
|
+
pointerEvents: shown ? "auto" : "none"
|
|
32900
|
+
},
|
|
32901
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(import_lucide_react46.MoreHorizontal, { className: "h-4 w-4" })
|
|
32902
|
+
}
|
|
32903
|
+
)
|
|
32904
|
+
}
|
|
32905
|
+
) })
|
|
32906
|
+
}
|
|
32907
|
+
)
|
|
32347
32908
|
}
|
|
32348
|
-
|
|
32349
|
-
return bestIndex;
|
|
32909
|
+
);
|
|
32350
32910
|
}
|
|
32911
|
+
|
|
32912
|
+
// src/components/UEditor/table-axis-handles.tsx
|
|
32913
|
+
var import_lucide_react47 = require("lucide-react");
|
|
32914
|
+
var import_jsx_runtime87 = require("react/jsx-runtime");
|
|
32915
|
+
var IDLE_HANDLE_SCALE = "0.78";
|
|
32916
|
+
function TableRowHandles({
|
|
32917
|
+
activeRowIndex,
|
|
32918
|
+
controlsVisible,
|
|
32919
|
+
getMenuItems,
|
|
32920
|
+
hoverRowHandleIndex,
|
|
32921
|
+
onOpenMenuChange,
|
|
32922
|
+
onStartDrag,
|
|
32923
|
+
openMenuKey,
|
|
32924
|
+
rowDragLabel,
|
|
32925
|
+
rowHandleLeft,
|
|
32926
|
+
rowHandles
|
|
32927
|
+
}) {
|
|
32928
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(import_jsx_runtime87.Fragment, { children: rowHandles.map((rowHandle) => {
|
|
32929
|
+
const menuKey = `row:${rowHandle.index}`;
|
|
32930
|
+
const isActive = rowHandle.index === activeRowIndex;
|
|
32931
|
+
const visible = controlsVisible || hoverRowHandleIndex === rowHandle.index || openMenuKey === menuKey;
|
|
32932
|
+
const isShown = visible || isActive;
|
|
32933
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
32934
|
+
"div",
|
|
32935
|
+
{
|
|
32936
|
+
className: "absolute z-30",
|
|
32937
|
+
"data-row-handle-index": rowHandle.index,
|
|
32938
|
+
style: {
|
|
32939
|
+
top: Math.max(8, rowHandle.center - 12),
|
|
32940
|
+
left: rowHandleLeft
|
|
32941
|
+
},
|
|
32942
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
32943
|
+
Tooltip,
|
|
32944
|
+
{
|
|
32945
|
+
placement: "right",
|
|
32946
|
+
disabled: openMenuKey === menuKey || !visible && isActive,
|
|
32947
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { className: "text-xs font-medium", children: `${rowDragLabel} ${rowHandle.index + 1}` }),
|
|
32948
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { className: "inline-flex", children: /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
32949
|
+
DropdownMenu,
|
|
32950
|
+
{
|
|
32951
|
+
placement: "right",
|
|
32952
|
+
isOpen: openMenuKey === menuKey,
|
|
32953
|
+
onOpenChange: (open) => onOpenMenuChange(menuKey, open),
|
|
32954
|
+
contentClassName: "p-2",
|
|
32955
|
+
items: getMenuItems(rowHandle),
|
|
32956
|
+
trigger: /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
32957
|
+
"button",
|
|
32958
|
+
{
|
|
32959
|
+
type: "button",
|
|
32960
|
+
"aria-label": `${rowDragLabel} ${rowHandle.index + 1}`,
|
|
32961
|
+
onMouseDown: (event) => {
|
|
32962
|
+
event.preventDefault();
|
|
32963
|
+
event.stopPropagation();
|
|
32964
|
+
onStartDrag(rowHandle);
|
|
32965
|
+
},
|
|
32966
|
+
className: cn(
|
|
32967
|
+
"inline-flex h-6 w-6 items-center justify-center rounded-full transition-[opacity,transform,colors,border,background-color] duration-150",
|
|
32968
|
+
visible ? "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur hover:bg-accent hover:text-foreground cursor-grab active:cursor-grabbing" : "border-transparent bg-transparent cursor-pointer"
|
|
32969
|
+
),
|
|
32970
|
+
style: {
|
|
32971
|
+
opacity: isShown ? 1 : 0,
|
|
32972
|
+
transform: isShown ? "scale(1)" : `scale(${IDLE_HANDLE_SCALE})`,
|
|
32973
|
+
pointerEvents: isShown ? "auto" : "none"
|
|
32974
|
+
},
|
|
32975
|
+
children: visible ? /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(import_lucide_react47.GripVertical, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("div", { className: "h-3 w-1 rounded-full bg-muted-foreground/50 hover:bg-muted-foreground" })
|
|
32976
|
+
}
|
|
32977
|
+
)
|
|
32978
|
+
}
|
|
32979
|
+
) })
|
|
32980
|
+
}
|
|
32981
|
+
)
|
|
32982
|
+
},
|
|
32983
|
+
`row-handle-${rowHandle.index}`
|
|
32984
|
+
);
|
|
32985
|
+
}) });
|
|
32986
|
+
}
|
|
32987
|
+
function TableColumnHandles({
|
|
32988
|
+
activeColumnIndex,
|
|
32989
|
+
columnDragLabel,
|
|
32990
|
+
columnHandleTop,
|
|
32991
|
+
columnHandles,
|
|
32992
|
+
controlsVisible,
|
|
32993
|
+
getMenuItems,
|
|
32994
|
+
hoverColumnHandleIndex,
|
|
32995
|
+
onOpenMenuChange,
|
|
32996
|
+
onStartDrag,
|
|
32997
|
+
openMenuKey
|
|
32998
|
+
}) {
|
|
32999
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(import_jsx_runtime87.Fragment, { children: columnHandles.map((columnHandle) => {
|
|
33000
|
+
const menuKey = `column:${columnHandle.index}`;
|
|
33001
|
+
const isActive = columnHandle.index === activeColumnIndex;
|
|
33002
|
+
const visible = controlsVisible || hoverColumnHandleIndex === columnHandle.index || openMenuKey === menuKey;
|
|
33003
|
+
const isShown = visible || isActive;
|
|
33004
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
33005
|
+
"div",
|
|
33006
|
+
{
|
|
33007
|
+
className: "absolute z-30",
|
|
33008
|
+
"data-column-handle-index": columnHandle.index,
|
|
33009
|
+
style: {
|
|
33010
|
+
top: columnHandleTop,
|
|
33011
|
+
left: Math.max(8, columnHandle.center - 12)
|
|
33012
|
+
},
|
|
33013
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
33014
|
+
Tooltip,
|
|
33015
|
+
{
|
|
33016
|
+
placement: "top",
|
|
33017
|
+
disabled: openMenuKey === menuKey || !visible && isActive,
|
|
33018
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { className: "text-xs font-medium", children: `${columnDragLabel} ${columnHandle.index + 1}` }),
|
|
33019
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { className: "inline-flex", children: /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
33020
|
+
DropdownMenu,
|
|
33021
|
+
{
|
|
33022
|
+
placement: "bottom-start",
|
|
33023
|
+
isOpen: openMenuKey === menuKey,
|
|
33024
|
+
onOpenChange: (open) => onOpenMenuChange(menuKey, open),
|
|
33025
|
+
contentClassName: "p-2",
|
|
33026
|
+
items: getMenuItems(columnHandle),
|
|
33027
|
+
trigger: /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
33028
|
+
"button",
|
|
33029
|
+
{
|
|
33030
|
+
type: "button",
|
|
33031
|
+
"aria-label": `${columnDragLabel} ${columnHandle.index + 1}`,
|
|
33032
|
+
onMouseDown: (event) => {
|
|
33033
|
+
event.preventDefault();
|
|
33034
|
+
event.stopPropagation();
|
|
33035
|
+
onStartDrag(columnHandle);
|
|
33036
|
+
},
|
|
33037
|
+
className: cn(
|
|
33038
|
+
"inline-flex h-6 w-6 items-center justify-center rounded-full transition-[opacity,transform,colors,border,background-color] duration-150",
|
|
33039
|
+
visible ? "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur hover:bg-accent hover:text-foreground cursor-grab active:cursor-grabbing" : "border-transparent bg-transparent cursor-pointer"
|
|
33040
|
+
),
|
|
33041
|
+
style: {
|
|
33042
|
+
opacity: isShown ? 1 : 0,
|
|
33043
|
+
transform: isShown ? "scale(1)" : `scale(${IDLE_HANDLE_SCALE})`,
|
|
33044
|
+
pointerEvents: isShown ? "auto" : "none"
|
|
33045
|
+
},
|
|
33046
|
+
children: visible ? /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(import_lucide_react47.GripHorizontal, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("div", { className: "h-1 w-3 rounded-full bg-muted-foreground/50 hover:bg-muted-foreground" })
|
|
33047
|
+
}
|
|
33048
|
+
)
|
|
33049
|
+
}
|
|
33050
|
+
) })
|
|
33051
|
+
}
|
|
33052
|
+
)
|
|
33053
|
+
},
|
|
33054
|
+
`column-handle-${columnHandle.index}`
|
|
33055
|
+
);
|
|
33056
|
+
}) });
|
|
33057
|
+
}
|
|
33058
|
+
|
|
33059
|
+
// src/components/UEditor/table-layout-model.ts
|
|
33060
|
+
var FALLBACK_TABLE_ROW_HEIGHT = 44;
|
|
33061
|
+
var FALLBACK_TABLE_COLUMN_WIDTH = 160;
|
|
32351
33062
|
function metricOrFallback(value, fallback) {
|
|
32352
33063
|
return Number.isFinite(value) && value > 0 ? value : fallback;
|
|
32353
33064
|
}
|
|
33065
|
+
function parsePixelMetric(value) {
|
|
33066
|
+
if (!value) return null;
|
|
33067
|
+
const parsed = Number.parseFloat(value);
|
|
33068
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
|
|
33069
|
+
}
|
|
32354
33070
|
function getPrimaryCell(table) {
|
|
32355
33071
|
const cell = table.querySelector("th,td");
|
|
32356
33072
|
return cell instanceof HTMLTableCellElement ? cell : null;
|
|
@@ -32362,7 +33078,7 @@ function getLastCell(table) {
|
|
|
32362
33078
|
return cell instanceof HTMLTableCellElement ? cell : null;
|
|
32363
33079
|
}
|
|
32364
33080
|
function getCellFromTarget(target) {
|
|
32365
|
-
const element =
|
|
33081
|
+
const element = resolveEventElement(target);
|
|
32366
33082
|
if (!element) return null;
|
|
32367
33083
|
const directCell = element.closest("th,td");
|
|
32368
33084
|
if (directCell instanceof HTMLTableCellElement) {
|
|
@@ -32388,25 +33104,135 @@ function findTableInfo(editor, pos) {
|
|
|
32388
33104
|
}
|
|
32389
33105
|
return null;
|
|
32390
33106
|
}
|
|
32391
|
-
function
|
|
32392
|
-
const
|
|
32393
|
-
|
|
32394
|
-
const
|
|
32395
|
-
|
|
33107
|
+
function getCellRelativePosFromDomPos(map, tableStart, domPos) {
|
|
33108
|
+
const relativeDomPos = domPos - tableStart;
|
|
33109
|
+
const seen = /* @__PURE__ */ new Set();
|
|
33110
|
+
for (const relativeCellPos of map.map) {
|
|
33111
|
+
if (seen.has(relativeCellPos)) continue;
|
|
33112
|
+
seen.add(relativeCellPos);
|
|
33113
|
+
if (relativeDomPos === relativeCellPos || relativeDomPos === relativeCellPos + 1) {
|
|
33114
|
+
return relativeCellPos;
|
|
33115
|
+
}
|
|
33116
|
+
}
|
|
33117
|
+
return null;
|
|
33118
|
+
}
|
|
33119
|
+
function buildLogicalColumnMetrics({
|
|
33120
|
+
editor,
|
|
33121
|
+
surface,
|
|
33122
|
+
surfaceRect,
|
|
33123
|
+
tableElement,
|
|
33124
|
+
tableInfo,
|
|
33125
|
+
tableLeft,
|
|
33126
|
+
tableWidth
|
|
33127
|
+
}) {
|
|
33128
|
+
const map = TableMap2.get(tableInfo.node);
|
|
33129
|
+
const fallbackWidth = metricOrFallback(tableWidth / map.width, FALLBACK_TABLE_COLUMN_WIDTH);
|
|
33130
|
+
const firstRow = tableElement.rows.item(0);
|
|
33131
|
+
const visualColumns = [];
|
|
33132
|
+
if (firstRow) {
|
|
33133
|
+
for (const tableCell of Array.from(firstRow.cells)) {
|
|
33134
|
+
if (!(tableCell instanceof HTMLTableCellElement)) continue;
|
|
33135
|
+
const cellPos = editor.view.posAtDOM(tableCell, 0);
|
|
33136
|
+
const relativeCellPos = getCellRelativePosFromDomPos(map, tableInfo.start, cellPos);
|
|
33137
|
+
if (relativeCellPos == null) continue;
|
|
33138
|
+
const cellMapRect = map.findCell(relativeCellPos);
|
|
33139
|
+
const cellRect = tableCell.getBoundingClientRect();
|
|
33140
|
+
const cellStart = cellRect.width > 0 ? cellRect.left - surfaceRect.left + surface.scrollLeft : tableLeft + cellMapRect.left * fallbackWidth;
|
|
33141
|
+
const size = metricOrFallback(cellRect.width, fallbackWidth * Math.max(1, cellMapRect.right - cellMapRect.left));
|
|
33142
|
+
visualColumns.push({
|
|
33143
|
+
index: cellMapRect.left,
|
|
33144
|
+
cellPos: tableInfo.start + relativeCellPos,
|
|
33145
|
+
start: cellStart,
|
|
33146
|
+
size,
|
|
33147
|
+
center: cellStart + size / 2
|
|
33148
|
+
});
|
|
33149
|
+
}
|
|
33150
|
+
}
|
|
33151
|
+
if (visualColumns.length > 0) {
|
|
33152
|
+
return visualColumns.sort((a, b) => a.index - b.index);
|
|
33153
|
+
}
|
|
33154
|
+
const cols = Array.from(tableElement.querySelectorAll("colgroup > col"));
|
|
33155
|
+
const parsedWidths = cols.slice(0, map.width).map((col) => parsePixelMetric(col.style.width) ?? parsePixelMetric(col.getAttribute("width")));
|
|
33156
|
+
const hasCompleteColWidths = parsedWidths.length >= map.width && parsedWidths.every((width) => typeof width === "number");
|
|
33157
|
+
let cursor = tableLeft;
|
|
33158
|
+
return Array.from({ length: map.width }, (_, index) => {
|
|
33159
|
+
const size = hasCompleteColWidths ? parsedWidths[index] : fallbackWidth;
|
|
33160
|
+
const start = hasCompleteColWidths ? cursor : tableLeft + index * fallbackWidth;
|
|
33161
|
+
cursor += size;
|
|
33162
|
+
return {
|
|
33163
|
+
index,
|
|
33164
|
+
cellPos: tableInfo.start + map.positionAt(0, index, tableInfo.node),
|
|
33165
|
+
start,
|
|
33166
|
+
size,
|
|
33167
|
+
center: start + size / 2
|
|
33168
|
+
};
|
|
33169
|
+
});
|
|
33170
|
+
}
|
|
33171
|
+
function buildLogicalRowMetrics({
|
|
33172
|
+
editor,
|
|
33173
|
+
surface,
|
|
33174
|
+
surfaceRect,
|
|
33175
|
+
tableInfo,
|
|
33176
|
+
rows,
|
|
33177
|
+
tableTop,
|
|
33178
|
+
tableHeight,
|
|
33179
|
+
cornerCell
|
|
33180
|
+
}) {
|
|
33181
|
+
const map = TableMap2.get(tableInfo.node);
|
|
33182
|
+
const fallbackHeight = metricOrFallback(tableHeight / map.height, FALLBACK_TABLE_ROW_HEIGHT);
|
|
33183
|
+
const visualRows = [];
|
|
33184
|
+
const seenCellPositions = /* @__PURE__ */ new Set();
|
|
33185
|
+
for (let rowIndex = 0; rowIndex < map.height; rowIndex += 1) {
|
|
33186
|
+
const relativeCellPos = map.map[rowIndex * map.width];
|
|
33187
|
+
if (seenCellPositions.has(relativeCellPos)) continue;
|
|
33188
|
+
seenCellPositions.add(relativeCellPos);
|
|
33189
|
+
const cellMapRect = map.findCell(relativeCellPos);
|
|
33190
|
+
const cellDom = editor.view.nodeDOM(tableInfo.start + relativeCellPos);
|
|
33191
|
+
const tableCell = cellDom instanceof HTMLTableCellElement ? cellDom : null;
|
|
33192
|
+
if (tableCell) {
|
|
33193
|
+
const cellRect = tableCell.getBoundingClientRect();
|
|
33194
|
+
const start = cellRect.height > 0 ? cellRect.top - surfaceRect.top + surface.scrollTop : tableTop + cellMapRect.top * fallbackHeight;
|
|
33195
|
+
const size = metricOrFallback(cellRect.height, fallbackHeight * Math.max(1, cellMapRect.bottom - cellMapRect.top));
|
|
33196
|
+
visualRows.push({
|
|
33197
|
+
index: cellMapRect.top,
|
|
33198
|
+
cellPos: tableInfo.start + relativeCellPos,
|
|
33199
|
+
start,
|
|
33200
|
+
size,
|
|
33201
|
+
center: start + size / 2
|
|
33202
|
+
});
|
|
33203
|
+
}
|
|
33204
|
+
}
|
|
33205
|
+
if (visualRows.length > 0) {
|
|
33206
|
+
return visualRows.sort((a, b) => a.index - b.index);
|
|
33207
|
+
}
|
|
33208
|
+
return rows.map((tableRow, index) => {
|
|
33209
|
+
const rowRect = tableRow.getBoundingClientRect();
|
|
33210
|
+
const anchorCell = tableRow.cells.item(0) ?? cornerCell;
|
|
33211
|
+
const start = rowRect.height > 0 ? rowRect.top - surfaceRect.top + surface.scrollTop : tableTop + index * fallbackHeight;
|
|
33212
|
+
const size = metricOrFallback(rowRect.height, fallbackHeight);
|
|
33213
|
+
return {
|
|
33214
|
+
index,
|
|
33215
|
+
cellPos: editor.view.posAtDOM(anchorCell, 0),
|
|
33216
|
+
start,
|
|
33217
|
+
size,
|
|
33218
|
+
center: start + size / 2
|
|
33219
|
+
};
|
|
33220
|
+
});
|
|
32396
33221
|
}
|
|
32397
|
-
function
|
|
33222
|
+
function buildTableControlLayout(editor, surface, cell) {
|
|
32398
33223
|
const row = cell.closest("tr");
|
|
32399
33224
|
const table = cell.closest("table");
|
|
32400
33225
|
if (!(row instanceof HTMLTableRowElement) || !(table instanceof HTMLTableElement)) {
|
|
32401
33226
|
return null;
|
|
32402
33227
|
}
|
|
32403
33228
|
const rows = Array.from(table.rows).filter((item) => item instanceof HTMLTableRowElement);
|
|
32404
|
-
const referenceRow = rows[0];
|
|
32405
|
-
const referenceCells = Array.from(referenceRow?.cells ?? []).filter((item) => item instanceof HTMLTableCellElement);
|
|
32406
33229
|
const cornerCell = getLastCell(table);
|
|
32407
|
-
|
|
33230
|
+
const cellPos = editor.view.posAtDOM(cell, 0);
|
|
33231
|
+
const tableInfo = findTableInfo(editor, cellPos);
|
|
33232
|
+
if (rows.length === 0 || !tableInfo || !(cornerCell instanceof HTMLTableCellElement)) {
|
|
32408
33233
|
return null;
|
|
32409
33234
|
}
|
|
33235
|
+
const map = TableMap2.get(tableInfo.node);
|
|
32410
33236
|
const surfaceRect = surface.getBoundingClientRect();
|
|
32411
33237
|
const tableRect = table.getBoundingClientRect();
|
|
32412
33238
|
const wrapperElement = table.closest(".tableWrapper");
|
|
@@ -32415,8 +33241,8 @@ function buildLayout(editor, surface, cell) {
|
|
|
32415
33241
|
const tableLeft = tableRect.left - surfaceRect.left + surface.scrollLeft;
|
|
32416
33242
|
const tableTop = tableRect.top - surfaceRect.top + surface.scrollTop;
|
|
32417
33243
|
const avgRowHeight = metricOrFallback(tableRect.height / rows.length, FALLBACK_TABLE_ROW_HEIGHT);
|
|
32418
|
-
const avgColumnWidth = metricOrFallback(tableRect.width /
|
|
32419
|
-
const tableWidth = metricOrFallback(tableRect.width, avgColumnWidth *
|
|
33244
|
+
const avgColumnWidth = metricOrFallback(tableRect.width / map.width, FALLBACK_TABLE_COLUMN_WIDTH);
|
|
33245
|
+
const tableWidth = metricOrFallback(tableRect.width, avgColumnWidth * map.width);
|
|
32420
33246
|
const tableHeight = metricOrFallback(tableRect.height, avgRowHeight * rows.length);
|
|
32421
33247
|
const wrapperLeft = wrapperRect.left - surfaceRect.left + surface.scrollLeft;
|
|
32422
33248
|
const wrapperTop = wrapperRect.top - surfaceRect.top + surface.scrollTop;
|
|
@@ -32426,36 +33252,33 @@ function buildLayout(editor, surface, cell) {
|
|
|
32426
33252
|
const viewportHeight = metricOrFallback(wrapper?.clientHeight ?? wrapperRect.height, tableHeight);
|
|
32427
33253
|
const verticalScrollbarWidth = Math.max(0, Math.round(wrapperWidth - viewportWidth));
|
|
32428
33254
|
const horizontalScrollbarHeight = Math.max(0, Math.round(wrapperHeight - viewportHeight));
|
|
32429
|
-
const rowHandles =
|
|
32430
|
-
|
|
32431
|
-
|
|
32432
|
-
|
|
32433
|
-
|
|
32434
|
-
|
|
32435
|
-
|
|
32436
|
-
|
|
32437
|
-
|
|
32438
|
-
size,
|
|
32439
|
-
center: start + size / 2
|
|
32440
|
-
};
|
|
33255
|
+
const rowHandles = buildLogicalRowMetrics({
|
|
33256
|
+
editor,
|
|
33257
|
+
surface,
|
|
33258
|
+
surfaceRect,
|
|
33259
|
+
tableInfo,
|
|
33260
|
+
rows,
|
|
33261
|
+
tableTop,
|
|
33262
|
+
tableHeight,
|
|
33263
|
+
cornerCell
|
|
32441
33264
|
});
|
|
32442
|
-
const columnHandles =
|
|
32443
|
-
|
|
32444
|
-
|
|
32445
|
-
|
|
32446
|
-
|
|
32447
|
-
|
|
32448
|
-
|
|
32449
|
-
|
|
32450
|
-
size,
|
|
32451
|
-
center: start + size / 2
|
|
32452
|
-
};
|
|
33265
|
+
const columnHandles = buildLogicalColumnMetrics({
|
|
33266
|
+
editor,
|
|
33267
|
+
surface,
|
|
33268
|
+
surfaceRect,
|
|
33269
|
+
tableElement: table,
|
|
33270
|
+
tableInfo,
|
|
33271
|
+
tableLeft,
|
|
33272
|
+
tableWidth
|
|
32453
33273
|
});
|
|
33274
|
+
const activeCellRelativePos = getCellRelativePosFromDomPos(map, tableInfo.start, cellPos);
|
|
33275
|
+
const activeCellRect = activeCellRelativePos != null ? map.findCell(activeCellRelativePos) : { left: cell.cellIndex, top: row.rowIndex };
|
|
33276
|
+
const normalizedCellPos = activeCellRelativePos != null ? tableInfo.start + activeCellRelativePos : cellPos;
|
|
32454
33277
|
return {
|
|
32455
|
-
cellPos:
|
|
32456
|
-
cornerCellPos:
|
|
32457
|
-
activeRowIndex:
|
|
32458
|
-
activeColumnIndex:
|
|
33278
|
+
cellPos: normalizedCellPos,
|
|
33279
|
+
cornerCellPos: tableInfo.start + map.positionAt(map.height - 1, map.width - 1, tableInfo.node),
|
|
33280
|
+
activeRowIndex: activeCellRect.top,
|
|
33281
|
+
activeColumnIndex: activeCellRect.left,
|
|
32459
33282
|
tableLeft,
|
|
32460
33283
|
tableTop,
|
|
32461
33284
|
tableWidth,
|
|
@@ -32474,9 +33297,25 @@ function buildLayout(editor, surface, cell) {
|
|
|
32474
33297
|
columnHandles
|
|
32475
33298
|
};
|
|
32476
33299
|
}
|
|
33300
|
+
|
|
33301
|
+
// src/components/UEditor/table-controls.tsx
|
|
33302
|
+
var import_jsx_runtime88 = require("react/jsx-runtime");
|
|
33303
|
+
var TABLE_MENU_TOP_OFFSET = 10;
|
|
33304
|
+
function nearestIndex(centers, position) {
|
|
33305
|
+
let bestIndex = 0;
|
|
33306
|
+
let bestDistance = Number.POSITIVE_INFINITY;
|
|
33307
|
+
centers.forEach((center, index) => {
|
|
33308
|
+
const distance = Math.abs(center - position);
|
|
33309
|
+
if (distance < bestDistance) {
|
|
33310
|
+
bestDistance = distance;
|
|
33311
|
+
bestIndex = index;
|
|
33312
|
+
}
|
|
33313
|
+
});
|
|
33314
|
+
return bestIndex;
|
|
33315
|
+
}
|
|
32477
33316
|
function getSelectedCell(editor) {
|
|
32478
33317
|
const browserSelection = window.getSelection();
|
|
32479
|
-
const anchorElement =
|
|
33318
|
+
const anchorElement = resolveEventElement(browserSelection?.anchorNode ?? null);
|
|
32480
33319
|
const anchorCell = anchorElement?.closest?.("th,td");
|
|
32481
33320
|
if (anchorCell instanceof HTMLTableCellElement) {
|
|
32482
33321
|
return anchorCell;
|
|
@@ -32484,35 +33323,15 @@ function getSelectedCell(editor) {
|
|
|
32484
33323
|
const domAtPos = editor.view.domAtPos(editor.state.selection.from);
|
|
32485
33324
|
return getCellFromTarget(domAtPos.node);
|
|
32486
33325
|
}
|
|
32487
|
-
function getFocusableCellPos(editor, cellPos) {
|
|
32488
|
-
const cellNode = editor.state.doc.nodeAt(cellPos);
|
|
32489
|
-
if (!cellNode) return cellPos + 1;
|
|
32490
|
-
let offset = cellPos + 1;
|
|
32491
|
-
let node = cellNode.firstChild ?? null;
|
|
32492
|
-
while (node && !node.isTextblock) {
|
|
32493
|
-
offset += 1;
|
|
32494
|
-
node = node.firstChild ?? null;
|
|
32495
|
-
}
|
|
32496
|
-
return node?.isTextblock ? offset + 1 : cellPos + 1;
|
|
32497
|
-
}
|
|
32498
|
-
function focusCell(editor, cellPos) {
|
|
32499
|
-
const selection = TextSelection2.near(editor.state.doc.resolve(getFocusableCellPos(editor, cellPos)));
|
|
32500
|
-
editor.view.dispatch(editor.state.tr.setSelection(selection));
|
|
32501
|
-
editor.view.focus();
|
|
32502
|
-
}
|
|
32503
|
-
function collectChildren(node) {
|
|
32504
|
-
const children = [];
|
|
32505
|
-
node.forEach((child) => children.push(child));
|
|
32506
|
-
return children;
|
|
32507
|
-
}
|
|
32508
33326
|
function TableControls({ editor, containerRef }) {
|
|
32509
33327
|
const t = useSmartTranslations("UEditor");
|
|
32510
33328
|
const [layout, setLayout] = import_react53.default.useState(null);
|
|
32511
33329
|
const [dragPreview, setDragPreview] = import_react53.default.useState(null);
|
|
32512
|
-
const [hoverState, setHoverState] = import_react53.default.useState(
|
|
33330
|
+
const [hoverState, setHoverState] = import_react53.default.useState(DEFAULT_TABLE_HOVER_STATE);
|
|
32513
33331
|
const [openMenuKey, setOpenMenuKey] = import_react53.default.useState(null);
|
|
32514
33332
|
const layoutRef = import_react53.default.useRef(null);
|
|
32515
33333
|
const dragStateRef = import_react53.default.useRef(null);
|
|
33334
|
+
const syncFrameRef = import_react53.default.useRef(null);
|
|
32516
33335
|
import_react53.default.useEffect(() => {
|
|
32517
33336
|
layoutRef.current = layout;
|
|
32518
33337
|
}, [layout]);
|
|
@@ -32522,11 +33341,24 @@ function TableControls({ editor, containerRef }) {
|
|
|
32522
33341
|
setLayout(null);
|
|
32523
33342
|
return;
|
|
32524
33343
|
}
|
|
32525
|
-
setLayout(
|
|
33344
|
+
setLayout(buildTableControlLayout(editor, surface, cell));
|
|
32526
33345
|
}, [containerRef, editor]);
|
|
32527
33346
|
const syncFromSelection = import_react53.default.useCallback(() => {
|
|
32528
33347
|
syncFromCell(getSelectedCell(editor));
|
|
32529
33348
|
}, [editor, syncFromCell]);
|
|
33349
|
+
const scheduleSyncFromSelection = import_react53.default.useCallback(() => {
|
|
33350
|
+
if (syncFrameRef.current !== null) return;
|
|
33351
|
+
syncFrameRef.current = window.requestAnimationFrame(() => {
|
|
33352
|
+
syncFrameRef.current = null;
|
|
33353
|
+
syncFromSelection();
|
|
33354
|
+
});
|
|
33355
|
+
}, [syncFromSelection]);
|
|
33356
|
+
import_react53.default.useEffect(() => () => {
|
|
33357
|
+
if (syncFrameRef.current !== null) {
|
|
33358
|
+
window.cancelAnimationFrame(syncFrameRef.current);
|
|
33359
|
+
syncFrameRef.current = null;
|
|
33360
|
+
}
|
|
33361
|
+
}, []);
|
|
32530
33362
|
const refreshCurrentLayout = import_react53.default.useCallback(() => {
|
|
32531
33363
|
setLayout((prev) => {
|
|
32532
33364
|
if (!prev) return prev;
|
|
@@ -32534,7 +33366,7 @@ function TableControls({ editor, containerRef }) {
|
|
|
32534
33366
|
if (!surface) return null;
|
|
32535
33367
|
const node = editor.view.nodeDOM(prev.cellPos);
|
|
32536
33368
|
const cell = getCellFromTarget(node) ?? getSelectedCell(editor);
|
|
32537
|
-
return cell ?
|
|
33369
|
+
return cell ? buildTableControlLayout(editor, surface, cell) : null;
|
|
32538
33370
|
});
|
|
32539
33371
|
}, [containerRef, editor]);
|
|
32540
33372
|
const clearDrag = import_react53.default.useCallback(() => {
|
|
@@ -32546,43 +33378,16 @@ function TableControls({ editor, containerRef }) {
|
|
|
32546
33378
|
const activeLayout = layoutRef.current;
|
|
32547
33379
|
const surface = containerRef.current;
|
|
32548
33380
|
if (!activeLayout || !surface || dragStateRef.current) {
|
|
32549
|
-
setHoverState(
|
|
33381
|
+
setHoverState(DEFAULT_TABLE_HOVER_STATE);
|
|
32550
33382
|
return;
|
|
32551
33383
|
}
|
|
32552
|
-
const
|
|
32553
|
-
|
|
32554
|
-
|
|
32555
|
-
|
|
32556
|
-
|
|
32557
|
-
const directColumnHandle = targetElement?.closest?.("[data-column-handle-index]");
|
|
32558
|
-
const directTableMenu = targetElement?.closest?.("[data-table-control='table-menu']");
|
|
32559
|
-
const directAddColumn = targetElement?.closest?.("[data-table-control='add-column']");
|
|
32560
|
-
const directAddRow = targetElement?.closest?.("[data-table-control='add-row']");
|
|
32561
|
-
const directRowHandleIndex = directRowHandle instanceof HTMLElement ? Number.parseInt(directRowHandle.dataset.rowHandleIndex ?? "", 10) : Number.NaN;
|
|
32562
|
-
const directColumnHandleIndex = directColumnHandle instanceof HTMLElement ? Number.parseInt(directColumnHandle.dataset.columnHandleIndex ?? "", 10) : Number.NaN;
|
|
32563
|
-
const visibleTableWidth2 = Math.min(activeLayout.tableWidth, activeLayout.viewportWidth);
|
|
32564
|
-
const visibleTableHeight2 = Math.min(activeLayout.tableHeight, activeLayout.viewportHeight);
|
|
32565
|
-
const isMouseInTable = relativeX >= activeLayout.tableLeft && relativeX <= activeLayout.tableLeft + activeLayout.tableWidth && relativeY >= activeLayout.tableTop && relativeY <= activeLayout.tableTop + activeLayout.tableHeight;
|
|
32566
|
-
const rowHandleIndex = Number.isFinite(directRowHandleIndex) ? directRowHandleIndex : activeLayout.rowHandles.find((rowHandle) => relativeX >= activeLayout.tableLeft - ROW_HANDLE_HOVER_WIDTH && relativeX <= activeLayout.tableLeft && Math.abs(relativeY - rowHandle.center) <= HANDLE_HOVER_RADIUS)?.index ?? null;
|
|
32567
|
-
const columnHandleIndex = Number.isFinite(directColumnHandleIndex) ? directColumnHandleIndex : activeLayout.columnHandles.find((columnHandle) => relativeY >= activeLayout.tableTop - COLUMN_HANDLE_HOVER_HEIGHT && relativeY <= activeLayout.tableTop && Math.abs(relativeX - columnHandle.center) <= HANDLE_HOVER_RADIUS)?.index ?? null;
|
|
32568
|
-
const menuVisible = Boolean(directTableMenu) || isMouseInTable || relativeX >= activeLayout.tableLeft - MENU_HOVER_PADDING && relativeX <= activeLayout.tableLeft + 42 && relativeY >= activeLayout.tableTop - COLUMN_HANDLE_HOVER_HEIGHT && relativeY <= activeLayout.tableTop + MENU_HOVER_PADDING;
|
|
32569
|
-
const lastRow = activeLayout.rowHandles[activeLayout.rowHandles.length - 1];
|
|
32570
|
-
const lastCol = activeLayout.columnHandles[activeLayout.columnHandles.length - 1];
|
|
32571
|
-
const isMouseInLastColumn = lastCol ? relativeX >= lastCol.start && relativeX <= lastCol.start + lastCol.size && relativeY >= activeLayout.tableTop && relativeY <= activeLayout.tableTop + visibleTableHeight2 : false;
|
|
32572
|
-
const addColumnVisible = Boolean(directAddColumn) || relativeX >= activeLayout.tableLeft + visibleTableWidth2 && relativeX <= activeLayout.tableLeft + visibleTableWidth2 + ADD_COLUMN_HOVER_WIDTH && relativeY >= activeLayout.tableTop && relativeY <= activeLayout.tableTop + visibleTableHeight2 || isMouseInLastColumn;
|
|
32573
|
-
const isMouseInLastRow = lastRow ? relativeY >= lastRow.start && relativeY <= lastRow.start + lastRow.size && relativeX >= activeLayout.tableLeft && relativeX <= activeLayout.tableLeft + visibleTableWidth2 : false;
|
|
32574
|
-
const addRowVisible = Boolean(directAddRow) || relativeY >= activeLayout.tableTop + visibleTableHeight2 && relativeY <= activeLayout.tableTop + visibleTableHeight2 + ADD_ROW_HOVER_HEIGHT && relativeX >= activeLayout.tableLeft && relativeX <= activeLayout.tableLeft + visibleTableWidth2 || isMouseInLastRow;
|
|
33384
|
+
const nextState = buildTableHoverState({
|
|
33385
|
+
event,
|
|
33386
|
+
layout: activeLayout,
|
|
33387
|
+
surface
|
|
33388
|
+
});
|
|
32575
33389
|
setHoverState((prev) => {
|
|
32576
|
-
|
|
32577
|
-
return prev;
|
|
32578
|
-
}
|
|
32579
|
-
return {
|
|
32580
|
-
menuVisible,
|
|
32581
|
-
addColumnVisible,
|
|
32582
|
-
addRowVisible,
|
|
32583
|
-
rowHandleIndex,
|
|
32584
|
-
columnHandleIndex
|
|
32585
|
-
};
|
|
33390
|
+
return areTableHoverStatesEqual(prev, nextState) ? prev : nextState;
|
|
32586
33391
|
});
|
|
32587
33392
|
}, [containerRef]);
|
|
32588
33393
|
import_react53.default.useEffect(() => {
|
|
@@ -32600,14 +33405,17 @@ function TableControls({ editor, containerRef }) {
|
|
|
32600
33405
|
};
|
|
32601
33406
|
const handleMouseLeave = () => {
|
|
32602
33407
|
if (dragStateRef.current) return;
|
|
32603
|
-
setHoverState(
|
|
33408
|
+
setHoverState(DEFAULT_TABLE_HOVER_STATE);
|
|
32604
33409
|
};
|
|
32605
|
-
const handleFocusIn = () => {
|
|
33410
|
+
const handleFocusIn = (event) => {
|
|
32606
33411
|
if (dragStateRef.current) return;
|
|
32607
|
-
|
|
33412
|
+
const cell = event ? getCellFromTarget(event.target) : null;
|
|
33413
|
+
syncFromCell(cell ?? getSelectedCell(editor));
|
|
32608
33414
|
};
|
|
32609
33415
|
proseMirror.addEventListener("mouseover", handleMouseOver);
|
|
32610
33416
|
proseMirror.addEventListener("mouseleave", handleMouseLeave);
|
|
33417
|
+
proseMirror.addEventListener("click", handleFocusIn);
|
|
33418
|
+
proseMirror.addEventListener("mouseup", handleFocusIn);
|
|
32611
33419
|
proseMirror.addEventListener("focusin", handleFocusIn);
|
|
32612
33420
|
surface.addEventListener("mouseover", handleSurfaceMouseMove);
|
|
32613
33421
|
surface.addEventListener("mousemove", handleSurfaceMouseMove);
|
|
@@ -32620,6 +33428,8 @@ function TableControls({ editor, containerRef }) {
|
|
|
32620
33428
|
return () => {
|
|
32621
33429
|
proseMirror.removeEventListener("mouseover", handleMouseOver);
|
|
32622
33430
|
proseMirror.removeEventListener("mouseleave", handleMouseLeave);
|
|
33431
|
+
proseMirror.removeEventListener("click", handleFocusIn);
|
|
33432
|
+
proseMirror.removeEventListener("mouseup", handleFocusIn);
|
|
32623
33433
|
proseMirror.removeEventListener("focusin", handleFocusIn);
|
|
32624
33434
|
surface.removeEventListener("mouseover", handleSurfaceMouseMove);
|
|
32625
33435
|
surface.removeEventListener("mousemove", handleSurfaceMouseMove);
|
|
@@ -32631,98 +33441,90 @@ function TableControls({ editor, containerRef }) {
|
|
|
32631
33441
|
};
|
|
32632
33442
|
}, [clearDrag, containerRef, editor, refreshCurrentLayout, syncFromCell, syncFromSelection, updateHoverState]);
|
|
32633
33443
|
const runAtCellPos = import_react53.default.useCallback((cellPos, command, options) => {
|
|
32634
|
-
|
|
32635
|
-
focusCell(editor, cellPos);
|
|
32636
|
-
const result = command(editor.chain().focus(null, { scrollIntoView: false })).run();
|
|
33444
|
+
const result = runTableCommandAtCellPos(editor, cellPos, command);
|
|
32637
33445
|
if (options?.sync !== false) {
|
|
32638
|
-
|
|
33446
|
+
scheduleSyncFromSelection();
|
|
32639
33447
|
}
|
|
32640
33448
|
return result;
|
|
32641
|
-
}, [editor,
|
|
33449
|
+
}, [editor, scheduleSyncFromSelection]);
|
|
32642
33450
|
const runAtActiveCell = import_react53.default.useCallback((command, options) => {
|
|
32643
33451
|
return runAtCellPos(layoutRef.current?.cellPos ?? null, command, options);
|
|
32644
33452
|
}, [runAtCellPos]);
|
|
32645
|
-
const getCurrentCornerCellPos = import_react53.default.useCallback(() => {
|
|
32646
|
-
const activePos = layoutRef.current?.cellPos ?? editor.state.selection.from;
|
|
32647
|
-
return getLastCellPosFromState(editor, activePos);
|
|
32648
|
-
}, [editor]);
|
|
32649
|
-
const runAtCornerCell = import_react53.default.useCallback((command, options) => {
|
|
32650
|
-
return runAtCellPos(getCurrentCornerCellPos(), command, options);
|
|
32651
|
-
}, [getCurrentCornerCellPos, runAtCellPos]);
|
|
32652
|
-
const replaceTableAtCellPos = import_react53.default.useCallback((cellPos, updateTable) => {
|
|
32653
|
-
if (cellPos == null) return false;
|
|
32654
|
-
const tableInfo = findTableInfo(editor, cellPos);
|
|
32655
|
-
if (!tableInfo) return false;
|
|
32656
|
-
const nextTable = updateTable(tableInfo.node);
|
|
32657
|
-
if (!nextTable) return false;
|
|
32658
|
-
editor.view.dispatch(editor.state.tr.replaceWith(tableInfo.pos, tableInfo.pos + tableInfo.node.nodeSize, nextTable));
|
|
32659
|
-
requestAnimationFrame(syncFromSelection);
|
|
32660
|
-
return true;
|
|
32661
|
-
}, [editor, syncFromSelection]);
|
|
32662
|
-
const createEmptyCellNode = import_react53.default.useCallback((cellNode) => {
|
|
32663
|
-
return cellNode.type.createAndFill(cellNode.attrs) ?? cellNode;
|
|
32664
|
-
}, []);
|
|
32665
33453
|
const duplicateRowAt = import_react53.default.useCallback((rowIndex, cellPos) => {
|
|
32666
|
-
|
|
32667
|
-
|
|
32668
|
-
|
|
32669
|
-
|
|
32670
|
-
rows.splice(rowIndex + 1, 0, rowNode.copy(rowNode.content));
|
|
32671
|
-
return tableNode.type.create(tableNode.attrs, rows);
|
|
32672
|
-
});
|
|
32673
|
-
}, [replaceTableAtCellPos]);
|
|
33454
|
+
const result = duplicateTableRowAt(editor, rowIndex, cellPos);
|
|
33455
|
+
scheduleSyncFromSelection();
|
|
33456
|
+
return result;
|
|
33457
|
+
}, [editor, scheduleSyncFromSelection]);
|
|
32674
33458
|
const clearRowAt = import_react53.default.useCallback((rowIndex, cellPos) => {
|
|
32675
|
-
|
|
32676
|
-
|
|
32677
|
-
|
|
32678
|
-
|
|
32679
|
-
const cells = collectChildren(rowNode).map((cellNode) => createEmptyCellNode(cellNode));
|
|
32680
|
-
rows[rowIndex] = rowNode.type.create(rowNode.attrs, cells);
|
|
32681
|
-
return tableNode.type.create(tableNode.attrs, rows);
|
|
32682
|
-
});
|
|
32683
|
-
}, [createEmptyCellNode, replaceTableAtCellPos]);
|
|
33459
|
+
const result = clearTableRowAt(editor, rowIndex, cellPos);
|
|
33460
|
+
scheduleSyncFromSelection();
|
|
33461
|
+
return result;
|
|
33462
|
+
}, [editor, scheduleSyncFromSelection]);
|
|
32684
33463
|
const duplicateColumnAt = import_react53.default.useCallback((columnIndex, cellPos) => {
|
|
32685
|
-
|
|
32686
|
-
|
|
32687
|
-
|
|
32688
|
-
|
|
32689
|
-
if (!cellNode) return rowNode;
|
|
32690
|
-
cells.splice(columnIndex + 1, 0, cellNode.copy(cellNode.content));
|
|
32691
|
-
return rowNode.type.create(rowNode.attrs, cells);
|
|
32692
|
-
});
|
|
32693
|
-
return tableNode.type.create(tableNode.attrs, rows);
|
|
32694
|
-
});
|
|
32695
|
-
}, [replaceTableAtCellPos]);
|
|
33464
|
+
const result = duplicateTableColumnAt(editor, columnIndex, cellPos);
|
|
33465
|
+
scheduleSyncFromSelection();
|
|
33466
|
+
return result;
|
|
33467
|
+
}, [editor, scheduleSyncFromSelection]);
|
|
32696
33468
|
const clearColumnAt = import_react53.default.useCallback((columnIndex, cellPos) => {
|
|
32697
|
-
|
|
32698
|
-
|
|
32699
|
-
|
|
32700
|
-
|
|
32701
|
-
if (!cellNode) return rowNode;
|
|
32702
|
-
cells[columnIndex] = createEmptyCellNode(cellNode);
|
|
32703
|
-
return rowNode.type.create(rowNode.attrs, cells);
|
|
32704
|
-
});
|
|
32705
|
-
return tableNode.type.create(tableNode.attrs, rows);
|
|
32706
|
-
});
|
|
32707
|
-
}, [createEmptyCellNode, replaceTableAtCellPos]);
|
|
33469
|
+
const result = clearTableColumnAt(editor, columnIndex, cellPos);
|
|
33470
|
+
scheduleSyncFromSelection();
|
|
33471
|
+
return result;
|
|
33472
|
+
}, [editor, scheduleSyncFromSelection]);
|
|
32708
33473
|
const expandTableBy = import_react53.default.useCallback((rows, cols) => {
|
|
32709
|
-
|
|
32710
|
-
|
|
32711
|
-
|
|
32712
|
-
|
|
32713
|
-
|
|
32714
|
-
for (let index = 0; index < cols; index += 1) {
|
|
32715
|
-
ok = runAtCornerCell((chain) => chain.addColumnAfter(), { sync: false });
|
|
32716
|
-
if (!ok) return false;
|
|
32717
|
-
}
|
|
32718
|
-
requestAnimationFrame(syncFromSelection);
|
|
32719
|
-
return true;
|
|
32720
|
-
}, [runAtCornerCell, syncFromSelection]);
|
|
33474
|
+
const activeCellPos = layoutRef.current?.cellPos ?? editor.state.selection.from;
|
|
33475
|
+
const result = expandTableFromCell(editor, activeCellPos, rows, cols);
|
|
33476
|
+
scheduleSyncFromSelection();
|
|
33477
|
+
return result;
|
|
33478
|
+
}, [editor, scheduleSyncFromSelection]);
|
|
32721
33479
|
const canExpandTable = Boolean(layout);
|
|
32722
33480
|
const controlsVisible = dragPreview !== null;
|
|
32723
33481
|
const tableMenuOpen = openMenuKey === "table";
|
|
32724
|
-
const
|
|
32725
|
-
|
|
33482
|
+
const startAddColumnDrag = import_react53.default.useCallback(() => {
|
|
33483
|
+
setOpenMenuKey(null);
|
|
33484
|
+
dragStateRef.current = { kind: "add-column", previewCols: 1 };
|
|
33485
|
+
setDragPreview({ kind: "add-column", previewCols: 1 });
|
|
33486
|
+
document.body.style.cursor = "ew-resize";
|
|
33487
|
+
}, []);
|
|
33488
|
+
const startAddRowDrag = import_react53.default.useCallback(() => {
|
|
33489
|
+
setOpenMenuKey(null);
|
|
33490
|
+
dragStateRef.current = { kind: "add-row", previewRows: 1 };
|
|
33491
|
+
setDragPreview({ kind: "add-row", previewRows: 1 });
|
|
33492
|
+
document.body.style.cursor = "ns-resize";
|
|
33493
|
+
}, []);
|
|
33494
|
+
const startRowDrag = import_react53.default.useCallback((rowHandle) => {
|
|
33495
|
+
setOpenMenuKey(null);
|
|
33496
|
+
dragStateRef.current = {
|
|
33497
|
+
kind: "row",
|
|
33498
|
+
originIndex: rowHandle.index,
|
|
33499
|
+
targetIndex: rowHandle.index,
|
|
33500
|
+
anchorPos: rowHandle.cellPos
|
|
33501
|
+
};
|
|
33502
|
+
setDragPreview({
|
|
33503
|
+
kind: "row",
|
|
33504
|
+
originIndex: rowHandle.index,
|
|
33505
|
+
targetIndex: rowHandle.index,
|
|
33506
|
+
targetStart: rowHandle.start,
|
|
33507
|
+
targetSize: rowHandle.size
|
|
33508
|
+
});
|
|
33509
|
+
document.body.style.cursor = "grabbing";
|
|
33510
|
+
}, []);
|
|
33511
|
+
const startColumnDrag = import_react53.default.useCallback((columnHandle) => {
|
|
33512
|
+
setOpenMenuKey(null);
|
|
33513
|
+
dragStateRef.current = {
|
|
33514
|
+
kind: "column",
|
|
33515
|
+
originIndex: columnHandle.index,
|
|
33516
|
+
targetIndex: columnHandle.index,
|
|
33517
|
+
anchorPos: columnHandle.cellPos
|
|
33518
|
+
};
|
|
33519
|
+
setDragPreview({
|
|
33520
|
+
kind: "column",
|
|
33521
|
+
originIndex: columnHandle.index,
|
|
33522
|
+
targetIndex: columnHandle.index,
|
|
33523
|
+
targetStart: columnHandle.start,
|
|
33524
|
+
targetSize: columnHandle.size
|
|
33525
|
+
});
|
|
33526
|
+
document.body.style.cursor = "grabbing";
|
|
33527
|
+
}, []);
|
|
32726
33528
|
import_react53.default.useEffect(() => {
|
|
32727
33529
|
const handleMouseMove = (event) => {
|
|
32728
33530
|
const dragState = dragStateRef.current;
|
|
@@ -32733,9 +33535,10 @@ function TableControls({ editor, containerRef }) {
|
|
|
32733
33535
|
const relativeX = event.clientX - surfaceRect.left + surface.scrollLeft;
|
|
32734
33536
|
const relativeY = event.clientY - surfaceRect.top + surface.scrollTop;
|
|
32735
33537
|
if (dragState.kind === "row") {
|
|
32736
|
-
const
|
|
33538
|
+
const targetHandleIndex = nearestIndex(activeLayout.rowHandles.map((item) => item.center), relativeY);
|
|
33539
|
+
const targetRow = activeLayout.rowHandles[targetHandleIndex];
|
|
33540
|
+
const targetIndex = targetRow.index;
|
|
32737
33541
|
dragState.targetIndex = targetIndex;
|
|
32738
|
-
const targetRow = activeLayout.rowHandles[targetIndex];
|
|
32739
33542
|
setDragPreview({
|
|
32740
33543
|
kind: "row",
|
|
32741
33544
|
originIndex: dragState.originIndex,
|
|
@@ -32747,9 +33550,10 @@ function TableControls({ editor, containerRef }) {
|
|
|
32747
33550
|
return;
|
|
32748
33551
|
}
|
|
32749
33552
|
if (dragState.kind === "column") {
|
|
32750
|
-
const
|
|
33553
|
+
const targetHandleIndex = nearestIndex(activeLayout.columnHandles.map((item) => item.center), relativeX);
|
|
33554
|
+
const targetColumn = activeLayout.columnHandles[targetHandleIndex];
|
|
33555
|
+
const targetIndex = targetColumn.index;
|
|
32751
33556
|
dragState.targetIndex = targetIndex;
|
|
32752
|
-
const targetColumn = activeLayout.columnHandles[targetIndex];
|
|
32753
33557
|
setDragPreview({
|
|
32754
33558
|
kind: "column",
|
|
32755
33559
|
originIndex: dragState.originIndex,
|
|
@@ -32782,7 +33586,7 @@ function TableControls({ editor, containerRef }) {
|
|
|
32782
33586
|
pos: dragState.anchorPos,
|
|
32783
33587
|
select: true
|
|
32784
33588
|
})(editor.state, editor.view.dispatch);
|
|
32785
|
-
|
|
33589
|
+
scheduleSyncFromSelection();
|
|
32786
33590
|
}
|
|
32787
33591
|
if (dragState.kind === "column" && dragState.originIndex !== dragState.targetIndex) {
|
|
32788
33592
|
moveTableColumn({
|
|
@@ -32791,7 +33595,7 @@ function TableControls({ editor, containerRef }) {
|
|
|
32791
33595
|
pos: dragState.anchorPos,
|
|
32792
33596
|
select: true
|
|
32793
33597
|
})(editor.state, editor.view.dispatch);
|
|
32794
|
-
|
|
33598
|
+
scheduleSyncFromSelection();
|
|
32795
33599
|
}
|
|
32796
33600
|
if (dragState.kind === "add-row") {
|
|
32797
33601
|
expandTableBy(dragState.previewRows, 0);
|
|
@@ -32809,70 +33613,70 @@ function TableControls({ editor, containerRef }) {
|
|
|
32809
33613
|
window.removeEventListener("mouseup", handleMouseUp);
|
|
32810
33614
|
window.removeEventListener("blur", clearDrag);
|
|
32811
33615
|
};
|
|
32812
|
-
}, [clearDrag, containerRef, editor, expandTableBy,
|
|
33616
|
+
}, [clearDrag, containerRef, editor, expandTableBy, scheduleSyncFromSelection]);
|
|
32813
33617
|
const menuItems = import_react53.default.useMemo(() => {
|
|
32814
33618
|
if (!layout) return [];
|
|
32815
33619
|
return [
|
|
32816
33620
|
{
|
|
32817
33621
|
label: t("tableMenu.alignLeft"),
|
|
32818
|
-
icon:
|
|
33622
|
+
icon: import_lucide_react48.AlignLeft,
|
|
32819
33623
|
onClick: () => applyTableAlignment(editor, "left", layout.cellPos)
|
|
32820
33624
|
},
|
|
32821
33625
|
{
|
|
32822
33626
|
label: t("tableMenu.alignCenter"),
|
|
32823
|
-
icon:
|
|
33627
|
+
icon: import_lucide_react48.AlignCenter,
|
|
32824
33628
|
onClick: () => applyTableAlignment(editor, "center", layout.cellPos)
|
|
32825
33629
|
},
|
|
32826
33630
|
{
|
|
32827
33631
|
label: t("tableMenu.alignRight"),
|
|
32828
|
-
icon:
|
|
33632
|
+
icon: import_lucide_react48.AlignRight,
|
|
32829
33633
|
onClick: () => applyTableAlignment(editor, "right", layout.cellPos)
|
|
32830
33634
|
},
|
|
32831
33635
|
{
|
|
32832
33636
|
label: t("tableMenu.addColumnBefore"),
|
|
32833
|
-
icon:
|
|
33637
|
+
icon: import_lucide_react48.ArrowLeft,
|
|
32834
33638
|
onClick: () => runAtActiveCell((chain) => chain.addColumnBefore())
|
|
32835
33639
|
},
|
|
32836
33640
|
{
|
|
32837
33641
|
label: t("tableMenu.addColumnAfter"),
|
|
32838
|
-
icon:
|
|
33642
|
+
icon: import_lucide_react48.ArrowRight,
|
|
32839
33643
|
onClick: () => runAtActiveCell((chain) => chain.addColumnAfter())
|
|
32840
33644
|
},
|
|
32841
33645
|
{
|
|
32842
33646
|
label: t("tableMenu.addRowBefore"),
|
|
32843
|
-
icon:
|
|
33647
|
+
icon: import_lucide_react48.ArrowUp,
|
|
32844
33648
|
onClick: () => runAtActiveCell((chain) => chain.addRowBefore())
|
|
32845
33649
|
},
|
|
32846
33650
|
{
|
|
32847
33651
|
label: t("tableMenu.addRowAfter"),
|
|
32848
|
-
icon:
|
|
33652
|
+
icon: import_lucide_react48.ArrowDown,
|
|
32849
33653
|
onClick: () => runAtActiveCell((chain) => chain.addRowAfter())
|
|
32850
33654
|
},
|
|
32851
33655
|
{
|
|
32852
33656
|
label: t("tableMenu.toggleHeaderRow"),
|
|
32853
|
-
icon:
|
|
33657
|
+
icon: import_lucide_react48.Table,
|
|
32854
33658
|
onClick: () => runAtActiveCell((chain) => chain.toggleHeaderRow())
|
|
32855
33659
|
},
|
|
32856
33660
|
{
|
|
32857
33661
|
label: t("tableMenu.toggleHeaderColumn"),
|
|
32858
|
-
icon:
|
|
33662
|
+
icon: import_lucide_react48.Table,
|
|
32859
33663
|
onClick: () => runAtActiveCell((chain) => chain.toggleHeaderColumn())
|
|
32860
33664
|
},
|
|
32861
33665
|
{
|
|
32862
33666
|
label: t("tableMenu.deleteColumn"),
|
|
32863
|
-
icon:
|
|
33667
|
+
icon: import_lucide_react48.Trash2,
|
|
32864
33668
|
onClick: () => runAtActiveCell((chain) => chain.deleteColumn()),
|
|
32865
33669
|
destructive: true
|
|
32866
33670
|
},
|
|
32867
33671
|
{
|
|
32868
33672
|
label: t("tableMenu.deleteRow"),
|
|
32869
|
-
icon:
|
|
33673
|
+
icon: import_lucide_react48.Trash2,
|
|
32870
33674
|
onClick: () => runAtActiveCell((chain) => chain.deleteRow()),
|
|
32871
33675
|
destructive: true
|
|
32872
33676
|
},
|
|
32873
33677
|
{
|
|
32874
33678
|
label: t("tableMenu.deleteTable"),
|
|
32875
|
-
icon:
|
|
33679
|
+
icon: import_lucide_react48.Trash2,
|
|
32876
33680
|
onClick: () => runAtActiveCell((chain) => chain.deleteTable()),
|
|
32877
33681
|
destructive: true
|
|
32878
33682
|
}
|
|
@@ -32881,27 +33685,27 @@ function TableControls({ editor, containerRef }) {
|
|
|
32881
33685
|
const getRowHandleMenuItems = import_react53.default.useCallback((rowHandle) => [
|
|
32882
33686
|
{
|
|
32883
33687
|
label: t("tableMenu.addRowBefore"),
|
|
32884
|
-
icon:
|
|
33688
|
+
icon: import_lucide_react48.ArrowUp,
|
|
32885
33689
|
onClick: () => runAtCellPos(rowHandle.cellPos, (chain) => chain.addRowBefore())
|
|
32886
33690
|
},
|
|
32887
33691
|
{
|
|
32888
33692
|
label: t("tableMenu.addRowAfter"),
|
|
32889
|
-
icon:
|
|
33693
|
+
icon: import_lucide_react48.ArrowDown,
|
|
32890
33694
|
onClick: () => runAtCellPos(rowHandle.cellPos, (chain) => chain.addRowAfter())
|
|
32891
33695
|
},
|
|
32892
33696
|
{
|
|
32893
33697
|
label: t("tableMenu.duplicateRow"),
|
|
32894
|
-
icon:
|
|
33698
|
+
icon: import_lucide_react48.Copy,
|
|
32895
33699
|
onClick: () => duplicateRowAt(rowHandle.index, rowHandle.cellPos)
|
|
32896
33700
|
},
|
|
32897
33701
|
{
|
|
32898
33702
|
label: t("tableMenu.clearRowContents"),
|
|
32899
|
-
icon:
|
|
33703
|
+
icon: import_lucide_react48.Table,
|
|
32900
33704
|
onClick: () => clearRowAt(rowHandle.index, rowHandle.cellPos)
|
|
32901
33705
|
},
|
|
32902
33706
|
{
|
|
32903
33707
|
label: t("tableMenu.deleteRow"),
|
|
32904
|
-
icon:
|
|
33708
|
+
icon: import_lucide_react48.Trash2,
|
|
32905
33709
|
onClick: () => runAtCellPos(rowHandle.cellPos, (chain) => chain.deleteRow()),
|
|
32906
33710
|
destructive: true
|
|
32907
33711
|
}
|
|
@@ -32909,27 +33713,27 @@ function TableControls({ editor, containerRef }) {
|
|
|
32909
33713
|
const getColumnHandleMenuItems = import_react53.default.useCallback((columnHandle) => [
|
|
32910
33714
|
{
|
|
32911
33715
|
label: t("tableMenu.addColumnBefore"),
|
|
32912
|
-
icon:
|
|
33716
|
+
icon: import_lucide_react48.ArrowLeft,
|
|
32913
33717
|
onClick: () => runAtCellPos(columnHandle.cellPos, (chain) => chain.addColumnBefore())
|
|
32914
33718
|
},
|
|
32915
33719
|
{
|
|
32916
33720
|
label: t("tableMenu.addColumnAfter"),
|
|
32917
|
-
icon:
|
|
33721
|
+
icon: import_lucide_react48.ArrowRight,
|
|
32918
33722
|
onClick: () => runAtCellPos(columnHandle.cellPos, (chain) => chain.addColumnAfter())
|
|
32919
33723
|
},
|
|
32920
33724
|
{
|
|
32921
33725
|
label: t("tableMenu.duplicateColumn"),
|
|
32922
|
-
icon:
|
|
33726
|
+
icon: import_lucide_react48.Copy,
|
|
32923
33727
|
onClick: () => duplicateColumnAt(columnHandle.index, columnHandle.cellPos)
|
|
32924
33728
|
},
|
|
32925
33729
|
{
|
|
32926
33730
|
label: t("tableMenu.clearColumnContents"),
|
|
32927
|
-
icon:
|
|
33731
|
+
icon: import_lucide_react48.Table,
|
|
32928
33732
|
onClick: () => clearColumnAt(columnHandle.index, columnHandle.cellPos)
|
|
32929
33733
|
},
|
|
32930
33734
|
{
|
|
32931
33735
|
label: t("tableMenu.deleteColumn"),
|
|
32932
|
-
icon:
|
|
33736
|
+
icon: import_lucide_react48.Trash2,
|
|
32933
33737
|
onClick: () => runAtCellPos(columnHandle.cellPos, (chain) => chain.deleteColumn()),
|
|
32934
33738
|
destructive: true
|
|
32935
33739
|
}
|
|
@@ -32941,373 +33745,77 @@ function TableControls({ editor, containerRef }) {
|
|
|
32941
33745
|
const menuLeft = Math.max(8, layout.tableLeft);
|
|
32942
33746
|
const rowHandleLeft = layout.tableLeft - 12;
|
|
32943
33747
|
const columnHandleTop = layout.tableTop - 12;
|
|
32944
|
-
|
|
32945
|
-
|
|
32946
|
-
|
|
32947
|
-
const columnRailLeft = layout.tableLeft + visibleTableWidth + ADD_COLUMN_RAIL_GAP;
|
|
32948
|
-
const rowRailTop = layout.tableTop + visibleTableHeight + ADD_ROW_RAIL_GAP;
|
|
32949
|
-
const rowRailLeft = layout.tableLeft;
|
|
32950
|
-
const expandPreviewWidth = dragPreview?.kind === "add-column" ? layout.tableWidth + dragPreview.previewCols * layout.avgColumnWidth : layout.tableWidth;
|
|
32951
|
-
const expandPreviewHeight = dragPreview?.kind === "add-row" ? layout.tableHeight + dragPreview.previewRows * layout.avgRowHeight : layout.tableHeight;
|
|
32952
|
-
const dragStatusText = dragPreview?.kind === "row" ? `${t("tableMenu.dragRow")} ${dragPreview.originIndex + 1} -> ${dragPreview.targetIndex + 1}` : dragPreview?.kind === "column" ? `${t("tableMenu.dragColumn")} ${dragPreview.originIndex + 1} -> ${dragPreview.targetIndex + 1}` : dragPreview?.kind === "add-row" ? `+${dragPreview.previewRows}R` : dragPreview?.kind === "add-column" ? `+${dragPreview.previewCols}C` : null;
|
|
32953
|
-
return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(import_jsx_runtime84.Fragment, { children: [
|
|
32954
|
-
layout.rowHandles.map((rowHandle) => {
|
|
32955
|
-
const menuKey = getRowMenuKey(rowHandle.index);
|
|
32956
|
-
const isActive = rowHandle.index === layout.activeRowIndex;
|
|
32957
|
-
const visible = controlsVisible || hoverState.rowHandleIndex === rowHandle.index || openMenuKey === menuKey;
|
|
32958
|
-
const isShown = visible || isActive;
|
|
32959
|
-
return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
32960
|
-
"div",
|
|
32961
|
-
{
|
|
32962
|
-
className: "absolute z-30",
|
|
32963
|
-
"data-row-handle-index": rowHandle.index,
|
|
32964
|
-
style: {
|
|
32965
|
-
top: Math.max(8, rowHandle.center - 12),
|
|
32966
|
-
left: rowHandleLeft
|
|
32967
|
-
},
|
|
32968
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
32969
|
-
Tooltip,
|
|
32970
|
-
{
|
|
32971
|
-
placement: "right",
|
|
32972
|
-
disabled: openMenuKey === menuKey || !visible && isActive,
|
|
32973
|
-
content: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "text-xs font-medium", children: `${t("tableMenu.dragRow")} ${rowHandle.index + 1}` }),
|
|
32974
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "inline-flex", children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
32975
|
-
DropdownMenu,
|
|
32976
|
-
{
|
|
32977
|
-
placement: "right",
|
|
32978
|
-
isOpen: openMenuKey === menuKey,
|
|
32979
|
-
onOpenChange: (open) => {
|
|
32980
|
-
setOpenMenuKey((prev) => open ? menuKey : prev === menuKey ? null : prev);
|
|
32981
|
-
},
|
|
32982
|
-
contentClassName: "p-2",
|
|
32983
|
-
items: getRowHandleMenuItems(rowHandle),
|
|
32984
|
-
trigger: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
32985
|
-
"button",
|
|
32986
|
-
{
|
|
32987
|
-
type: "button",
|
|
32988
|
-
"aria-label": `${t("tableMenu.dragRow")} ${rowHandle.index + 1}`,
|
|
32989
|
-
onMouseDown: (event) => {
|
|
32990
|
-
event.preventDefault();
|
|
32991
|
-
event.stopPropagation();
|
|
32992
|
-
setOpenMenuKey(null);
|
|
32993
|
-
dragStateRef.current = {
|
|
32994
|
-
kind: "row",
|
|
32995
|
-
originIndex: rowHandle.index,
|
|
32996
|
-
targetIndex: rowHandle.index,
|
|
32997
|
-
anchorPos: rowHandle.cellPos
|
|
32998
|
-
};
|
|
32999
|
-
setDragPreview({
|
|
33000
|
-
kind: "row",
|
|
33001
|
-
originIndex: rowHandle.index,
|
|
33002
|
-
targetIndex: rowHandle.index,
|
|
33003
|
-
targetStart: rowHandle.start,
|
|
33004
|
-
targetSize: rowHandle.size
|
|
33005
|
-
});
|
|
33006
|
-
document.body.style.cursor = "grabbing";
|
|
33007
|
-
},
|
|
33008
|
-
className: cn(
|
|
33009
|
-
"inline-flex h-6 w-6 items-center justify-center rounded-full transition-[opacity,transform,colors,border,background-color] duration-150",
|
|
33010
|
-
visible ? "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur hover:bg-accent hover:text-foreground cursor-grab active:cursor-grabbing" : "border-transparent bg-transparent cursor-pointer"
|
|
33011
|
-
),
|
|
33012
|
-
style: {
|
|
33013
|
-
opacity: isShown ? 1 : 0,
|
|
33014
|
-
transform: isShown ? "scale(1)" : `scale(${IDLE_HANDLE_SCALE})`,
|
|
33015
|
-
pointerEvents: isShown ? "auto" : "none"
|
|
33016
|
-
},
|
|
33017
|
-
children: visible ? /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_lucide_react46.GripVertical, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "h-3 w-1 rounded-full bg-muted-foreground/50 hover:bg-muted-foreground" })
|
|
33018
|
-
}
|
|
33019
|
-
)
|
|
33020
|
-
}
|
|
33021
|
-
) })
|
|
33022
|
-
}
|
|
33023
|
-
)
|
|
33024
|
-
},
|
|
33025
|
-
`row-handle-${rowHandle.index}`
|
|
33026
|
-
);
|
|
33027
|
-
}),
|
|
33028
|
-
layout.columnHandles.map((columnHandle) => {
|
|
33029
|
-
const menuKey = getColumnMenuKey(columnHandle.index);
|
|
33030
|
-
const isActive = columnHandle.index === layout.activeColumnIndex;
|
|
33031
|
-
const visible = controlsVisible || hoverState.columnHandleIndex === columnHandle.index || openMenuKey === menuKey;
|
|
33032
|
-
const isShown = visible || isActive;
|
|
33033
|
-
return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
33034
|
-
"div",
|
|
33035
|
-
{
|
|
33036
|
-
className: "absolute z-30",
|
|
33037
|
-
"data-column-handle-index": columnHandle.index,
|
|
33038
|
-
style: {
|
|
33039
|
-
top: columnHandleTop,
|
|
33040
|
-
left: Math.max(8, columnHandle.center - 12)
|
|
33041
|
-
},
|
|
33042
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
33043
|
-
Tooltip,
|
|
33044
|
-
{
|
|
33045
|
-
placement: "top",
|
|
33046
|
-
disabled: openMenuKey === menuKey || !visible && isActive,
|
|
33047
|
-
content: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "text-xs font-medium", children: `${t("tableMenu.dragColumn")} ${columnHandle.index + 1}` }),
|
|
33048
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "inline-flex", children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
33049
|
-
DropdownMenu,
|
|
33050
|
-
{
|
|
33051
|
-
placement: "bottom-start",
|
|
33052
|
-
isOpen: openMenuKey === menuKey,
|
|
33053
|
-
onOpenChange: (open) => {
|
|
33054
|
-
setOpenMenuKey((prev) => open ? menuKey : prev === menuKey ? null : prev);
|
|
33055
|
-
},
|
|
33056
|
-
contentClassName: "p-2",
|
|
33057
|
-
items: getColumnHandleMenuItems(columnHandle),
|
|
33058
|
-
trigger: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
33059
|
-
"button",
|
|
33060
|
-
{
|
|
33061
|
-
type: "button",
|
|
33062
|
-
"aria-label": `${t("tableMenu.dragColumn")} ${columnHandle.index + 1}`,
|
|
33063
|
-
onMouseDown: (event) => {
|
|
33064
|
-
event.preventDefault();
|
|
33065
|
-
event.stopPropagation();
|
|
33066
|
-
setOpenMenuKey(null);
|
|
33067
|
-
dragStateRef.current = {
|
|
33068
|
-
kind: "column",
|
|
33069
|
-
originIndex: columnHandle.index,
|
|
33070
|
-
targetIndex: columnHandle.index,
|
|
33071
|
-
anchorPos: columnHandle.cellPos
|
|
33072
|
-
};
|
|
33073
|
-
setDragPreview({
|
|
33074
|
-
kind: "column",
|
|
33075
|
-
originIndex: columnHandle.index,
|
|
33076
|
-
targetIndex: columnHandle.index,
|
|
33077
|
-
targetStart: columnHandle.start,
|
|
33078
|
-
targetSize: columnHandle.size
|
|
33079
|
-
});
|
|
33080
|
-
document.body.style.cursor = "grabbing";
|
|
33081
|
-
},
|
|
33082
|
-
className: cn(
|
|
33083
|
-
"inline-flex h-6 w-6 items-center justify-center rounded-full transition-[opacity,transform,colors,border,background-color] duration-150",
|
|
33084
|
-
visible ? "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur hover:bg-accent hover:text-foreground cursor-grab active:cursor-grabbing" : "border-transparent bg-transparent cursor-pointer"
|
|
33085
|
-
),
|
|
33086
|
-
style: {
|
|
33087
|
-
opacity: isShown ? 1 : 0,
|
|
33088
|
-
transform: isShown ? "scale(1)" : `scale(${IDLE_HANDLE_SCALE})`,
|
|
33089
|
-
pointerEvents: isShown ? "auto" : "none"
|
|
33090
|
-
},
|
|
33091
|
-
children: visible ? /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_lucide_react46.GripHorizontal, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "h-1 w-3 rounded-full bg-muted-foreground/50 hover:bg-muted-foreground" })
|
|
33092
|
-
}
|
|
33093
|
-
)
|
|
33094
|
-
}
|
|
33095
|
-
) })
|
|
33096
|
-
}
|
|
33097
|
-
)
|
|
33098
|
-
},
|
|
33099
|
-
`column-handle-${columnHandle.index}`
|
|
33100
|
-
);
|
|
33101
|
-
}),
|
|
33102
|
-
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
33103
|
-
"div",
|
|
33748
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(import_jsx_runtime88.Fragment, { children: [
|
|
33749
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
33750
|
+
TableRowHandles,
|
|
33104
33751
|
{
|
|
33105
|
-
|
|
33106
|
-
|
|
33107
|
-
|
|
33108
|
-
|
|
33109
|
-
|
|
33752
|
+
activeRowIndex: layout.activeRowIndex,
|
|
33753
|
+
controlsVisible,
|
|
33754
|
+
getMenuItems: getRowHandleMenuItems,
|
|
33755
|
+
hoverRowHandleIndex: hoverState.rowHandleIndex,
|
|
33756
|
+
onOpenMenuChange: (menuKey, open) => {
|
|
33757
|
+
setOpenMenuKey((prev) => open ? menuKey : prev === menuKey ? null : prev);
|
|
33110
33758
|
},
|
|
33111
|
-
|
|
33112
|
-
|
|
33113
|
-
|
|
33114
|
-
|
|
33115
|
-
|
|
33116
|
-
content: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "text-xs font-medium", children: t("tableMenu.openControls") }),
|
|
33117
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "inline-flex", children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
33118
|
-
DropdownMenu,
|
|
33119
|
-
{
|
|
33120
|
-
placement: "bottom-start",
|
|
33121
|
-
isOpen: tableMenuOpen,
|
|
33122
|
-
onOpenChange: (open) => {
|
|
33123
|
-
setOpenMenuKey((prev) => open ? "table" : prev === "table" ? null : prev);
|
|
33124
|
-
},
|
|
33125
|
-
contentClassName: "p-2",
|
|
33126
|
-
items: menuItems,
|
|
33127
|
-
trigger: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
33128
|
-
"button",
|
|
33129
|
-
{
|
|
33130
|
-
type: "button",
|
|
33131
|
-
"aria-label": t("tableMenu.openControls"),
|
|
33132
|
-
onMouseDown: (event) => event.preventDefault(),
|
|
33133
|
-
className: cn(
|
|
33134
|
-
"pointer-events-auto inline-flex h-7 w-7 items-center justify-center rounded-full",
|
|
33135
|
-
"border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
|
|
33136
|
-
"transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
|
|
33137
|
-
),
|
|
33138
|
-
style: {
|
|
33139
|
-
opacity: controlsVisible || hoverState.menuVisible || tableMenuOpen ? 1 : 0,
|
|
33140
|
-
transform: controlsVisible || hoverState.menuVisible || tableMenuOpen ? "scale(1)" : "scale(0.82)",
|
|
33141
|
-
pointerEvents: controlsVisible || hoverState.menuVisible || tableMenuOpen ? "auto" : "none"
|
|
33142
|
-
},
|
|
33143
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_lucide_react46.MoreHorizontal, { className: "h-4 w-4" })
|
|
33144
|
-
}
|
|
33145
|
-
)
|
|
33146
|
-
}
|
|
33147
|
-
) })
|
|
33148
|
-
}
|
|
33149
|
-
)
|
|
33759
|
+
onStartDrag: startRowDrag,
|
|
33760
|
+
openMenuKey,
|
|
33761
|
+
rowDragLabel: t("tableMenu.dragRow"),
|
|
33762
|
+
rowHandleLeft,
|
|
33763
|
+
rowHandles: layout.rowHandles
|
|
33150
33764
|
}
|
|
33151
33765
|
),
|
|
33152
|
-
/* @__PURE__ */ (0,
|
|
33153
|
-
|
|
33766
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
33767
|
+
TableColumnHandles,
|
|
33154
33768
|
{
|
|
33155
|
-
|
|
33156
|
-
|
|
33157
|
-
|
|
33158
|
-
|
|
33159
|
-
|
|
33160
|
-
|
|
33161
|
-
|
|
33162
|
-
|
|
33163
|
-
|
|
33164
|
-
|
|
33165
|
-
|
|
33166
|
-
|
|
33167
|
-
if (!canExpandTable) return;
|
|
33168
|
-
dragStateRef.current = { kind: "add-column", previewCols: 1 };
|
|
33169
|
-
setDragPreview({ kind: "add-column", previewCols: 1 });
|
|
33170
|
-
document.body.style.cursor = "ew-resize";
|
|
33171
|
-
},
|
|
33172
|
-
disabled: !canExpandTable,
|
|
33173
|
-
className: cn(
|
|
33174
|
-
"absolute z-30 inline-flex items-center justify-center rounded-md",
|
|
33175
|
-
"border border-border/70 bg-muted/40 text-muted-foreground shadow-sm backdrop-blur",
|
|
33176
|
-
"transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground disabled:opacity-50 disabled:cursor-not-allowed"
|
|
33177
|
-
),
|
|
33178
|
-
style: {
|
|
33179
|
-
top: controlsVisible || hoverState.addColumnVisible ? columnRailTop : columnRailTop + Math.max(0, visibleTableHeight / 2 - 24),
|
|
33180
|
-
left: columnRailLeft,
|
|
33181
|
-
width: controlsVisible || hoverState.addColumnVisible ? 18 : 12,
|
|
33182
|
-
height: controlsVisible || hoverState.addColumnVisible ? visibleTableHeight : 48,
|
|
33183
|
-
opacity: controlsVisible || hoverState.addColumnVisible ? 1 : 0,
|
|
33184
|
-
transform: controlsVisible || hoverState.addColumnVisible ? "scale(1)" : "scale(0.92)",
|
|
33185
|
-
pointerEvents: controlsVisible || hoverState.addColumnVisible ? "auto" : "none"
|
|
33186
|
-
},
|
|
33187
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "text-sm font-medium leading-none", children: "+" })
|
|
33188
|
-
}
|
|
33189
|
-
)
|
|
33769
|
+
activeColumnIndex: layout.activeColumnIndex,
|
|
33770
|
+
columnDragLabel: t("tableMenu.dragColumn"),
|
|
33771
|
+
columnHandleTop,
|
|
33772
|
+
columnHandles: layout.columnHandles,
|
|
33773
|
+
controlsVisible,
|
|
33774
|
+
getMenuItems: getColumnHandleMenuItems,
|
|
33775
|
+
hoverColumnHandleIndex: hoverState.columnHandleIndex,
|
|
33776
|
+
onOpenMenuChange: (menuKey, open) => {
|
|
33777
|
+
setOpenMenuKey((prev) => open ? menuKey : prev === menuKey ? null : prev);
|
|
33778
|
+
},
|
|
33779
|
+
onStartDrag: startColumnDrag,
|
|
33780
|
+
openMenuKey
|
|
33190
33781
|
}
|
|
33191
33782
|
),
|
|
33192
|
-
/* @__PURE__ */ (0,
|
|
33193
|
-
|
|
33783
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
33784
|
+
TableControlMenu,
|
|
33194
33785
|
{
|
|
33195
|
-
|
|
33196
|
-
|
|
33197
|
-
|
|
33198
|
-
|
|
33199
|
-
|
|
33200
|
-
|
|
33201
|
-
|
|
33202
|
-
|
|
33203
|
-
|
|
33204
|
-
|
|
33205
|
-
event.stopPropagation();
|
|
33206
|
-
setOpenMenuKey(null);
|
|
33207
|
-
if (!canExpandTable) return;
|
|
33208
|
-
dragStateRef.current = { kind: "add-row", previewRows: 1 };
|
|
33209
|
-
setDragPreview({ kind: "add-row", previewRows: 1 });
|
|
33210
|
-
document.body.style.cursor = "ns-resize";
|
|
33211
|
-
},
|
|
33212
|
-
disabled: !canExpandTable,
|
|
33213
|
-
className: cn(
|
|
33214
|
-
"absolute z-30 inline-flex items-center justify-center rounded-md",
|
|
33215
|
-
"border border-border/70 bg-muted/40 text-muted-foreground shadow-sm backdrop-blur",
|
|
33216
|
-
"transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground disabled:opacity-50 disabled:cursor-not-allowed"
|
|
33217
|
-
),
|
|
33218
|
-
style: {
|
|
33219
|
-
top: rowRailTop,
|
|
33220
|
-
left: controlsVisible || hoverState.addRowVisible ? rowRailLeft : rowRailLeft + Math.max(0, visibleTableWidth / 2 - 24),
|
|
33221
|
-
width: controlsVisible || hoverState.addRowVisible ? visibleTableWidth : 48,
|
|
33222
|
-
height: controlsVisible || hoverState.addRowVisible ? 16 : 12,
|
|
33223
|
-
opacity: controlsVisible || hoverState.addRowVisible ? 1 : 0,
|
|
33224
|
-
transform: controlsVisible || hoverState.addRowVisible ? "scale(1)" : "scale(0.92)",
|
|
33225
|
-
pointerEvents: controlsVisible || hoverState.addRowVisible ? "auto" : "none"
|
|
33226
|
-
},
|
|
33227
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "text-sm font-medium leading-none", children: "+" })
|
|
33228
|
-
}
|
|
33229
|
-
)
|
|
33786
|
+
controlsVisible,
|
|
33787
|
+
isOpen: tableMenuOpen,
|
|
33788
|
+
items: menuItems,
|
|
33789
|
+
label: t("tableMenu.openControls"),
|
|
33790
|
+
left: menuLeft,
|
|
33791
|
+
menuVisible: hoverState.menuVisible,
|
|
33792
|
+
onOpenChange: (open) => {
|
|
33793
|
+
setOpenMenuKey((prev) => open ? "table" : prev === "table" ? null : prev);
|
|
33794
|
+
},
|
|
33795
|
+
top: menuTop
|
|
33230
33796
|
}
|
|
33231
33797
|
),
|
|
33232
|
-
|
|
33233
|
-
|
|
33234
|
-
"div",
|
|
33235
|
-
{
|
|
33236
|
-
"aria-hidden": "true",
|
|
33237
|
-
className: "pointer-events-none absolute z-20 rounded-lg border border-primary/20 bg-primary/10",
|
|
33238
|
-
style: {
|
|
33239
|
-
top: dragPreview.targetStart,
|
|
33240
|
-
left: layout.tableLeft,
|
|
33241
|
-
width: layout.tableWidth,
|
|
33242
|
-
height: dragPreview.targetSize
|
|
33243
|
-
}
|
|
33244
|
-
}
|
|
33245
|
-
),
|
|
33246
|
-
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
33247
|
-
"div",
|
|
33248
|
-
{
|
|
33249
|
-
"aria-hidden": "true",
|
|
33250
|
-
className: "pointer-events-none absolute z-20 rounded-full bg-primary/80",
|
|
33251
|
-
style: {
|
|
33252
|
-
top: dragPreview.targetStart + dragPreview.targetSize / 2 - 1,
|
|
33253
|
-
left: layout.tableLeft,
|
|
33254
|
-
width: layout.tableWidth,
|
|
33255
|
-
height: 2
|
|
33256
|
-
}
|
|
33257
|
-
}
|
|
33258
|
-
)
|
|
33259
|
-
] }),
|
|
33260
|
-
dragPreview?.kind === "column" && /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(import_jsx_runtime84.Fragment, { children: [
|
|
33261
|
-
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
33262
|
-
"div",
|
|
33263
|
-
{
|
|
33264
|
-
"aria-hidden": "true",
|
|
33265
|
-
className: "pointer-events-none absolute z-20 rounded-lg border border-primary/20 bg-primary/10",
|
|
33266
|
-
style: {
|
|
33267
|
-
top: layout.tableTop,
|
|
33268
|
-
left: dragPreview.targetStart,
|
|
33269
|
-
width: dragPreview.targetSize,
|
|
33270
|
-
height: layout.tableHeight
|
|
33271
|
-
}
|
|
33272
|
-
}
|
|
33273
|
-
),
|
|
33274
|
-
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
33275
|
-
"div",
|
|
33276
|
-
{
|
|
33277
|
-
"aria-hidden": "true",
|
|
33278
|
-
className: "pointer-events-none absolute z-20 rounded-full bg-primary/80",
|
|
33279
|
-
style: {
|
|
33280
|
-
top: layout.tableTop,
|
|
33281
|
-
left: dragPreview.targetStart + dragPreview.targetSize / 2 - 1,
|
|
33282
|
-
width: 2,
|
|
33283
|
-
height: layout.tableHeight
|
|
33284
|
-
}
|
|
33285
|
-
}
|
|
33286
|
-
)
|
|
33287
|
-
] }),
|
|
33288
|
-
(dragPreview?.kind === "add-row" || dragPreview?.kind === "add-column") && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_jsx_runtime84.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
33289
|
-
"div",
|
|
33798
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
33799
|
+
TableAddRails,
|
|
33290
33800
|
{
|
|
33291
|
-
|
|
33292
|
-
|
|
33293
|
-
|
|
33294
|
-
|
|
33295
|
-
|
|
33296
|
-
|
|
33297
|
-
|
|
33298
|
-
|
|
33801
|
+
addColumnVisible: hoverState.addColumnVisible,
|
|
33802
|
+
addRowVisible: hoverState.addRowVisible,
|
|
33803
|
+
canExpandTable,
|
|
33804
|
+
controlsVisible,
|
|
33805
|
+
layout,
|
|
33806
|
+
onStartAddColumn: startAddColumnDrag,
|
|
33807
|
+
onStartAddRow: startAddRowDrag,
|
|
33808
|
+
quickAddColumnLabel: t("tableMenu.quickAddColumnAfter"),
|
|
33809
|
+
quickAddRowLabel: t("tableMenu.quickAddRowAfter")
|
|
33299
33810
|
}
|
|
33300
|
-
)
|
|
33301
|
-
|
|
33302
|
-
|
|
33811
|
+
),
|
|
33812
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
33813
|
+
TableDragPreview,
|
|
33303
33814
|
{
|
|
33304
|
-
|
|
33305
|
-
|
|
33306
|
-
|
|
33307
|
-
|
|
33308
|
-
left: dragPreview?.kind === "add-row" || dragPreview?.kind === "add-column" ? layout.tableLeft + Math.max(0, expandPreviewWidth - 84) : layout.tableLeft + Math.max(0, layout.tableWidth - 108)
|
|
33309
|
-
},
|
|
33310
|
-
children: dragStatusText
|
|
33815
|
+
columnDragLabel: t("tableMenu.dragColumn"),
|
|
33816
|
+
dragPreview,
|
|
33817
|
+
layout,
|
|
33818
|
+
rowDragLabel: t("tableMenu.dragRow")
|
|
33311
33819
|
}
|
|
33312
33820
|
)
|
|
33313
33821
|
] });
|
|
@@ -33906,7 +34414,7 @@ function useUEditorTableInteractions(editor, editable = true) {
|
|
|
33906
34414
|
}
|
|
33907
34415
|
|
|
33908
34416
|
// src/components/UEditor/UEditor.tsx
|
|
33909
|
-
var
|
|
34417
|
+
var import_jsx_runtime89 = require("react/jsx-runtime");
|
|
33910
34418
|
var UEditor = import_react56.default.forwardRef(({
|
|
33911
34419
|
content = "",
|
|
33912
34420
|
onChange,
|
|
@@ -34003,6 +34511,7 @@ var UEditor = import_react56.default.forwardRef(({
|
|
|
34003
34511
|
(0, import_react56.useImperativeHandle)(
|
|
34004
34512
|
ref,
|
|
34005
34513
|
() => ({
|
|
34514
|
+
editor,
|
|
34006
34515
|
prepareContentForSave: async ({ throwOnError = false } = {}) => {
|
|
34007
34516
|
if (!inFlightPrepareRef.current) {
|
|
34008
34517
|
const htmlSnapshot = editor?.getHTML() ?? content ?? "";
|
|
@@ -34033,7 +34542,7 @@ var UEditor = import_react56.default.forwardRef(({
|
|
|
34033
34542
|
}
|
|
34034
34543
|
}, [content, editor]);
|
|
34035
34544
|
if (!editor) {
|
|
34036
|
-
return /* @__PURE__ */ (0,
|
|
34545
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
34037
34546
|
"div",
|
|
34038
34547
|
{
|
|
34039
34548
|
className: cn("w-full rounded-lg border bg-background flex items-center justify-center text-muted-foreground", className),
|
|
@@ -34042,7 +34551,7 @@ var UEditor = import_react56.default.forwardRef(({
|
|
|
34042
34551
|
}
|
|
34043
34552
|
);
|
|
34044
34553
|
}
|
|
34045
|
-
return /* @__PURE__ */ (0,
|
|
34554
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(
|
|
34046
34555
|
"div",
|
|
34047
34556
|
{
|
|
34048
34557
|
className: cn(
|
|
@@ -34057,7 +34566,7 @@ var UEditor = import_react56.default.forwardRef(({
|
|
|
34057
34566
|
className
|
|
34058
34567
|
),
|
|
34059
34568
|
children: [
|
|
34060
|
-
editable && showToolbar && /* @__PURE__ */ (0,
|
|
34569
|
+
editable && showToolbar && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
34061
34570
|
EditorToolbar,
|
|
34062
34571
|
{
|
|
34063
34572
|
editor,
|
|
@@ -34072,7 +34581,7 @@ var UEditor = import_react56.default.forwardRef(({
|
|
|
34072
34581
|
letterSpacings
|
|
34073
34582
|
}
|
|
34074
34583
|
),
|
|
34075
|
-
editable && showBubbleMenu && /* @__PURE__ */ (0,
|
|
34584
|
+
editable && showBubbleMenu && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
34076
34585
|
CustomBubbleMenu,
|
|
34077
34586
|
{
|
|
34078
34587
|
editor,
|
|
@@ -34080,8 +34589,8 @@ var UEditor = import_react56.default.forwardRef(({
|
|
|
34080
34589
|
lineHeights
|
|
34081
34590
|
}
|
|
34082
34591
|
),
|
|
34083
|
-
editable && showFloatingMenu && /* @__PURE__ */ (0,
|
|
34084
|
-
/* @__PURE__ */ (0,
|
|
34592
|
+
editable && showFloatingMenu && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(CustomFloatingMenu, { editor }),
|
|
34593
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(
|
|
34085
34594
|
"div",
|
|
34086
34595
|
{
|
|
34087
34596
|
ref: editorContentRef,
|
|
@@ -34091,7 +34600,7 @@ var UEditor = import_react56.default.forwardRef(({
|
|
|
34091
34600
|
maxHeight
|
|
34092
34601
|
},
|
|
34093
34602
|
children: [
|
|
34094
|
-
/* @__PURE__ */ (0,
|
|
34603
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
34095
34604
|
"span",
|
|
34096
34605
|
{
|
|
34097
34606
|
ref: tableColumnGuideRef,
|
|
@@ -34099,7 +34608,7 @@ var UEditor = import_react56.default.forwardRef(({
|
|
|
34099
34608
|
className: "pointer-events-none absolute z-20 bg-primary opacity-0 transition-opacity duration-100"
|
|
34100
34609
|
}
|
|
34101
34610
|
),
|
|
34102
|
-
/* @__PURE__ */ (0,
|
|
34611
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
34103
34612
|
"span",
|
|
34104
34613
|
{
|
|
34105
34614
|
ref: tableRowGuideRef,
|
|
@@ -34107,7 +34616,7 @@ var UEditor = import_react56.default.forwardRef(({
|
|
|
34107
34616
|
className: "pointer-events-none absolute z-20 bg-primary opacity-0 transition-opacity duration-100"
|
|
34108
34617
|
}
|
|
34109
34618
|
),
|
|
34110
|
-
/* @__PURE__ */ (0,
|
|
34619
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
34111
34620
|
"span",
|
|
34112
34621
|
{
|
|
34113
34622
|
ref: activeTableCellHighlightRef,
|
|
@@ -34116,8 +34625,8 @@ var UEditor = import_react56.default.forwardRef(({
|
|
|
34116
34625
|
className: "pointer-events-none hidden absolute z-20 rounded-[2px] border-2 border-primary bg-primary/10 transition-[left,top,width,height] duration-100"
|
|
34117
34626
|
}
|
|
34118
34627
|
),
|
|
34119
|
-
editable && /* @__PURE__ */ (0,
|
|
34120
|
-
/* @__PURE__ */ (0,
|
|
34628
|
+
editable && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(TableControls, { editor, containerRef: editorContentRef }),
|
|
34629
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
34121
34630
|
import_react57.EditorContent,
|
|
34122
34631
|
{
|
|
34123
34632
|
editor,
|
|
@@ -34127,7 +34636,7 @@ var UEditor = import_react56.default.forwardRef(({
|
|
|
34127
34636
|
]
|
|
34128
34637
|
}
|
|
34129
34638
|
),
|
|
34130
|
-
showCharacterCount && /* @__PURE__ */ (0,
|
|
34639
|
+
showCharacterCount && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(CharacterCountDisplay, { editor, maxCharacters })
|
|
34131
34640
|
]
|
|
34132
34641
|
}
|
|
34133
34642
|
);
|