@underverse-ui/underverse 1.0.71 → 1.0.72
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 +336 -107
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +336 -107
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -28946,6 +28946,19 @@ import {
|
|
|
28946
28946
|
import { Fragment as Fragment27, jsx as jsx81, jsxs as jsxs71 } from "react/jsx-runtime";
|
|
28947
28947
|
var FALLBACK_TABLE_ROW_HEIGHT = 44;
|
|
28948
28948
|
var FALLBACK_TABLE_COLUMN_WIDTH = 160;
|
|
28949
|
+
var MENU_HOVER_PADDING = 18;
|
|
28950
|
+
var ROW_HANDLE_HOVER_WIDTH = 28;
|
|
28951
|
+
var COLUMN_HANDLE_HOVER_HEIGHT = 28;
|
|
28952
|
+
var ADD_COLUMN_HOVER_WIDTH = 24;
|
|
28953
|
+
var ADD_ROW_HOVER_HEIGHT = 24;
|
|
28954
|
+
var HANDLE_HOVER_RADIUS = 14;
|
|
28955
|
+
var DEFAULT_HOVER_STATE = {
|
|
28956
|
+
menuVisible: false,
|
|
28957
|
+
addColumnVisible: false,
|
|
28958
|
+
addRowVisible: false,
|
|
28959
|
+
rowHandleIndex: null,
|
|
28960
|
+
columnHandleIndex: null
|
|
28961
|
+
};
|
|
28949
28962
|
function resolveElement(target) {
|
|
28950
28963
|
if (target instanceof Element) return target;
|
|
28951
28964
|
if (target instanceof Node) return target.parentElement;
|
|
@@ -29071,6 +29084,12 @@ function buildLayout(editor, surface, cell) {
|
|
|
29071
29084
|
};
|
|
29072
29085
|
}
|
|
29073
29086
|
function getSelectedCell(editor) {
|
|
29087
|
+
const browserSelection = window.getSelection();
|
|
29088
|
+
const anchorElement = resolveElement(browserSelection?.anchorNode ?? null);
|
|
29089
|
+
const anchorCell = anchorElement?.closest?.("th,td");
|
|
29090
|
+
if (anchorCell instanceof HTMLTableCellElement) {
|
|
29091
|
+
return anchorCell;
|
|
29092
|
+
}
|
|
29074
29093
|
const domAtPos = editor.view.domAtPos(editor.state.selection.from);
|
|
29075
29094
|
return getCellFromTarget(domAtPos.node);
|
|
29076
29095
|
}
|
|
@@ -29099,6 +29118,7 @@ function TableControls({ editor, containerRef }) {
|
|
|
29099
29118
|
const t = useSmartTranslations("UEditor");
|
|
29100
29119
|
const [layout, setLayout] = React74.useState(null);
|
|
29101
29120
|
const [dragPreview, setDragPreview] = React74.useState(null);
|
|
29121
|
+
const [hoverState, setHoverState] = React74.useState(DEFAULT_HOVER_STATE);
|
|
29102
29122
|
const layoutRef = React74.useRef(null);
|
|
29103
29123
|
const dragStateRef = React74.useRef(null);
|
|
29104
29124
|
React74.useEffect(() => {
|
|
@@ -29130,17 +29150,50 @@ function TableControls({ editor, containerRef }) {
|
|
|
29130
29150
|
setDragPreview(null);
|
|
29131
29151
|
document.body.style.cursor = "";
|
|
29132
29152
|
}, []);
|
|
29153
|
+
const updateHoverState = React74.useCallback((event) => {
|
|
29154
|
+
const activeLayout = layoutRef.current;
|
|
29155
|
+
const surface = containerRef.current;
|
|
29156
|
+
if (!activeLayout || !surface || dragStateRef.current) {
|
|
29157
|
+
setHoverState(DEFAULT_HOVER_STATE);
|
|
29158
|
+
return;
|
|
29159
|
+
}
|
|
29160
|
+
const surfaceRect = surface.getBoundingClientRect();
|
|
29161
|
+
const relativeX = event.clientX - surfaceRect.left + surface.scrollLeft;
|
|
29162
|
+
const relativeY = event.clientY - surfaceRect.top + surface.scrollTop;
|
|
29163
|
+
const rowHandleIndex = activeLayout.rowHandles.find((rowHandle) => relativeX >= activeLayout.tableLeft - ROW_HANDLE_HOVER_WIDTH && relativeX <= activeLayout.tableLeft && Math.abs(relativeY - rowHandle.center) <= HANDLE_HOVER_RADIUS)?.index ?? null;
|
|
29164
|
+
const columnHandleIndex = activeLayout.columnHandles.find((columnHandle) => relativeY >= activeLayout.tableTop - COLUMN_HANDLE_HOVER_HEIGHT && relativeY <= activeLayout.tableTop && Math.abs(relativeX - columnHandle.center) <= HANDLE_HOVER_RADIUS)?.index ?? null;
|
|
29165
|
+
const menuVisible = relativeX >= activeLayout.tableLeft - MENU_HOVER_PADDING && relativeX <= activeLayout.tableLeft + 42 && relativeY >= activeLayout.tableTop - COLUMN_HANDLE_HOVER_HEIGHT && relativeY <= activeLayout.tableTop + MENU_HOVER_PADDING;
|
|
29166
|
+
const addColumnVisible = relativeX >= activeLayout.tableLeft + activeLayout.tableWidth && relativeX <= activeLayout.tableLeft + activeLayout.tableWidth + ADD_COLUMN_HOVER_WIDTH && relativeY >= activeLayout.tableTop && relativeY <= activeLayout.tableTop + activeLayout.tableHeight;
|
|
29167
|
+
const addRowVisible = relativeY >= activeLayout.tableTop + activeLayout.tableHeight && relativeY <= activeLayout.tableTop + activeLayout.tableHeight + ADD_ROW_HOVER_HEIGHT && relativeX >= activeLayout.tableLeft && relativeX <= activeLayout.tableLeft + activeLayout.tableWidth;
|
|
29168
|
+
setHoverState((prev) => {
|
|
29169
|
+
if (prev.menuVisible === menuVisible && prev.addColumnVisible === addColumnVisible && prev.addRowVisible === addRowVisible && prev.rowHandleIndex === rowHandleIndex && prev.columnHandleIndex === columnHandleIndex) {
|
|
29170
|
+
return prev;
|
|
29171
|
+
}
|
|
29172
|
+
return {
|
|
29173
|
+
menuVisible,
|
|
29174
|
+
addColumnVisible,
|
|
29175
|
+
addRowVisible,
|
|
29176
|
+
rowHandleIndex,
|
|
29177
|
+
columnHandleIndex
|
|
29178
|
+
};
|
|
29179
|
+
});
|
|
29180
|
+
}, [containerRef]);
|
|
29133
29181
|
React74.useEffect(() => {
|
|
29134
29182
|
const proseMirror = editor.view.dom;
|
|
29135
29183
|
const surface = containerRef.current;
|
|
29136
29184
|
if (!surface) return void 0;
|
|
29137
29185
|
const handleMouseOver = (event) => {
|
|
29138
29186
|
if (dragStateRef.current) return;
|
|
29139
|
-
|
|
29187
|
+
const cell = getCellFromTarget(event.target);
|
|
29188
|
+
if (!cell) return;
|
|
29189
|
+
syncFromCell(cell);
|
|
29190
|
+
};
|
|
29191
|
+
const handleSurfaceMouseMove = (event) => {
|
|
29192
|
+
updateHoverState(event);
|
|
29140
29193
|
};
|
|
29141
29194
|
const handleMouseLeave = () => {
|
|
29142
29195
|
if (dragStateRef.current) return;
|
|
29143
|
-
|
|
29196
|
+
setHoverState(DEFAULT_HOVER_STATE);
|
|
29144
29197
|
};
|
|
29145
29198
|
const handleFocusIn = () => {
|
|
29146
29199
|
if (dragStateRef.current) return;
|
|
@@ -29149,6 +29202,7 @@ function TableControls({ editor, containerRef }) {
|
|
|
29149
29202
|
proseMirror.addEventListener("mouseover", handleMouseOver);
|
|
29150
29203
|
proseMirror.addEventListener("mouseleave", handleMouseLeave);
|
|
29151
29204
|
proseMirror.addEventListener("focusin", handleFocusIn);
|
|
29205
|
+
surface.addEventListener("mousemove", handleSurfaceMouseMove);
|
|
29152
29206
|
surface.addEventListener("scroll", refreshCurrentLayout, { passive: true });
|
|
29153
29207
|
window.addEventListener("resize", refreshCurrentLayout);
|
|
29154
29208
|
editor.on("selectionUpdate", syncFromSelection);
|
|
@@ -29158,12 +29212,13 @@ function TableControls({ editor, containerRef }) {
|
|
|
29158
29212
|
proseMirror.removeEventListener("mouseover", handleMouseOver);
|
|
29159
29213
|
proseMirror.removeEventListener("mouseleave", handleMouseLeave);
|
|
29160
29214
|
proseMirror.removeEventListener("focusin", handleFocusIn);
|
|
29215
|
+
surface.removeEventListener("mousemove", handleSurfaceMouseMove);
|
|
29161
29216
|
surface.removeEventListener("scroll", refreshCurrentLayout);
|
|
29162
29217
|
window.removeEventListener("resize", refreshCurrentLayout);
|
|
29163
29218
|
editor.off("selectionUpdate", syncFromSelection);
|
|
29164
29219
|
editor.off("update", refreshCurrentLayout);
|
|
29165
29220
|
};
|
|
29166
|
-
}, [clearDrag, containerRef, editor, refreshCurrentLayout, syncFromCell, syncFromSelection]);
|
|
29221
|
+
}, [clearDrag, containerRef, editor, refreshCurrentLayout, syncFromCell, syncFromSelection, updateHoverState]);
|
|
29167
29222
|
const runAtCellPos = React74.useCallback((cellPos, command, options) => {
|
|
29168
29223
|
if (cellPos == null) return false;
|
|
29169
29224
|
focusCell(editor, cellPos);
|
|
@@ -29253,6 +29308,7 @@ function TableControls({ editor, containerRef }) {
|
|
|
29253
29308
|
return true;
|
|
29254
29309
|
}, [runAtCornerCell, syncFromSelection]);
|
|
29255
29310
|
const canExpandTable = Boolean(layout);
|
|
29311
|
+
const controlsVisible = dragPreview !== null;
|
|
29256
29312
|
React74.useEffect(() => {
|
|
29257
29313
|
const handleMouseMove = (event) => {
|
|
29258
29314
|
const dragState = dragStateRef.current;
|
|
@@ -29464,107 +29520,147 @@ function TableControls({ editor, containerRef }) {
|
|
|
29464
29520
|
const expandPreviewHeight = dragPreview?.kind === "add-row" ? layout.tableHeight + dragPreview.previewRows * layout.avgRowHeight : layout.tableHeight;
|
|
29465
29521
|
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;
|
|
29466
29522
|
return /* @__PURE__ */ jsxs71(Fragment27, { children: [
|
|
29467
|
-
layout.rowHandles.map((rowHandle) =>
|
|
29468
|
-
|
|
29469
|
-
|
|
29470
|
-
|
|
29471
|
-
|
|
29472
|
-
|
|
29473
|
-
"
|
|
29474
|
-
{
|
|
29475
|
-
|
|
29476
|
-
|
|
29477
|
-
|
|
29478
|
-
|
|
29479
|
-
|
|
29480
|
-
|
|
29481
|
-
|
|
29482
|
-
|
|
29483
|
-
|
|
29484
|
-
|
|
29485
|
-
|
|
29486
|
-
|
|
29487
|
-
|
|
29488
|
-
|
|
29489
|
-
|
|
29490
|
-
|
|
29491
|
-
|
|
29492
|
-
|
|
29493
|
-
|
|
29494
|
-
|
|
29495
|
-
|
|
29496
|
-
|
|
29497
|
-
|
|
29498
|
-
|
|
29499
|
-
|
|
29500
|
-
|
|
29501
|
-
|
|
29502
|
-
|
|
29503
|
-
|
|
29504
|
-
|
|
29505
|
-
|
|
29506
|
-
|
|
29507
|
-
|
|
29508
|
-
|
|
29509
|
-
|
|
29510
|
-
|
|
29511
|
-
|
|
29512
|
-
|
|
29513
|
-
|
|
29514
|
-
|
|
29515
|
-
|
|
29516
|
-
|
|
29517
|
-
|
|
29518
|
-
|
|
29519
|
-
|
|
29520
|
-
|
|
29521
|
-
|
|
29522
|
-
|
|
29523
|
-
|
|
29524
|
-
|
|
29525
|
-
|
|
29526
|
-
|
|
29527
|
-
|
|
29528
|
-
|
|
29529
|
-
|
|
29530
|
-
|
|
29531
|
-
|
|
29532
|
-
|
|
29533
|
-
|
|
29534
|
-
|
|
29535
|
-
|
|
29536
|
-
|
|
29537
|
-
|
|
29538
|
-
|
|
29539
|
-
|
|
29540
|
-
|
|
29541
|
-
|
|
29542
|
-
|
|
29543
|
-
|
|
29544
|
-
|
|
29545
|
-
|
|
29546
|
-
|
|
29523
|
+
layout.rowHandles.map((rowHandle) => {
|
|
29524
|
+
const visible = controlsVisible || hoverState.rowHandleIndex === rowHandle.index;
|
|
29525
|
+
if (!visible) return null;
|
|
29526
|
+
return /* @__PURE__ */ jsx81(
|
|
29527
|
+
"div",
|
|
29528
|
+
{
|
|
29529
|
+
className: "absolute z-30",
|
|
29530
|
+
style: {
|
|
29531
|
+
top: Math.max(8, rowHandle.center - 12),
|
|
29532
|
+
left: rowHandleLeft
|
|
29533
|
+
},
|
|
29534
|
+
children: /* @__PURE__ */ jsx81(
|
|
29535
|
+
DropdownMenu,
|
|
29536
|
+
{
|
|
29537
|
+
placement: "right",
|
|
29538
|
+
items: getRowHandleMenuItems(rowHandle),
|
|
29539
|
+
trigger: /* @__PURE__ */ jsx81(
|
|
29540
|
+
"button",
|
|
29541
|
+
{
|
|
29542
|
+
type: "button",
|
|
29543
|
+
"aria-label": `${t("tableMenu.dragRow")} ${rowHandle.index + 1}`,
|
|
29544
|
+
title: `${t("tableMenu.dragRow")} ${rowHandle.index + 1}`,
|
|
29545
|
+
onMouseDown: (event) => {
|
|
29546
|
+
event.preventDefault();
|
|
29547
|
+
event.stopPropagation();
|
|
29548
|
+
dragStateRef.current = {
|
|
29549
|
+
kind: "row",
|
|
29550
|
+
originIndex: rowHandle.index,
|
|
29551
|
+
targetIndex: rowHandle.index,
|
|
29552
|
+
anchorPos: rowHandle.cellPos
|
|
29553
|
+
};
|
|
29554
|
+
setDragPreview({
|
|
29555
|
+
kind: "row",
|
|
29556
|
+
originIndex: rowHandle.index,
|
|
29557
|
+
targetIndex: rowHandle.index,
|
|
29558
|
+
targetStart: rowHandle.start,
|
|
29559
|
+
targetSize: rowHandle.size
|
|
29560
|
+
});
|
|
29561
|
+
document.body.style.cursor = "grabbing";
|
|
29562
|
+
},
|
|
29563
|
+
className: cn(
|
|
29564
|
+
"inline-flex h-6 w-6 items-center justify-center rounded-full",
|
|
29565
|
+
"border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
|
|
29566
|
+
"transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
|
|
29567
|
+
),
|
|
29568
|
+
children: /* @__PURE__ */ jsx81(GripVertical3, { className: "h-3.5 w-3.5" })
|
|
29569
|
+
}
|
|
29570
|
+
)
|
|
29571
|
+
}
|
|
29572
|
+
)
|
|
29573
|
+
},
|
|
29574
|
+
`row-handle-${rowHandle.index}`
|
|
29575
|
+
);
|
|
29576
|
+
}),
|
|
29577
|
+
layout.columnHandles.map((columnHandle) => {
|
|
29578
|
+
const visible = controlsVisible || hoverState.columnHandleIndex === columnHandle.index;
|
|
29579
|
+
if (!visible) return null;
|
|
29580
|
+
return /* @__PURE__ */ jsx81(
|
|
29581
|
+
"div",
|
|
29582
|
+
{
|
|
29583
|
+
className: "absolute z-30",
|
|
29584
|
+
style: {
|
|
29585
|
+
top: columnHandleTop,
|
|
29586
|
+
left: Math.max(8, columnHandle.center - 12)
|
|
29587
|
+
},
|
|
29588
|
+
children: /* @__PURE__ */ jsx81(
|
|
29589
|
+
DropdownMenu,
|
|
29590
|
+
{
|
|
29591
|
+
placement: "bottom-start",
|
|
29592
|
+
items: getColumnHandleMenuItems(columnHandle),
|
|
29593
|
+
trigger: /* @__PURE__ */ jsx81(
|
|
29594
|
+
"button",
|
|
29595
|
+
{
|
|
29596
|
+
type: "button",
|
|
29597
|
+
"aria-label": `${t("tableMenu.dragColumn")} ${columnHandle.index + 1}`,
|
|
29598
|
+
title: `${t("tableMenu.dragColumn")} ${columnHandle.index + 1}`,
|
|
29599
|
+
onMouseDown: (event) => {
|
|
29600
|
+
event.preventDefault();
|
|
29601
|
+
event.stopPropagation();
|
|
29602
|
+
dragStateRef.current = {
|
|
29603
|
+
kind: "column",
|
|
29604
|
+
originIndex: columnHandle.index,
|
|
29605
|
+
targetIndex: columnHandle.index,
|
|
29606
|
+
anchorPos: columnHandle.cellPos
|
|
29607
|
+
};
|
|
29608
|
+
setDragPreview({
|
|
29609
|
+
kind: "column",
|
|
29610
|
+
originIndex: columnHandle.index,
|
|
29611
|
+
targetIndex: columnHandle.index,
|
|
29612
|
+
targetStart: columnHandle.start,
|
|
29613
|
+
targetSize: columnHandle.size
|
|
29614
|
+
});
|
|
29615
|
+
document.body.style.cursor = "grabbing";
|
|
29616
|
+
},
|
|
29617
|
+
className: cn(
|
|
29618
|
+
"inline-flex h-6 w-6 items-center justify-center rounded-full",
|
|
29619
|
+
"border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
|
|
29620
|
+
"transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
|
|
29621
|
+
),
|
|
29622
|
+
children: /* @__PURE__ */ jsx81(GripHorizontal, { className: "h-3.5 w-3.5" })
|
|
29623
|
+
}
|
|
29624
|
+
)
|
|
29625
|
+
}
|
|
29626
|
+
)
|
|
29627
|
+
},
|
|
29628
|
+
`column-handle-${columnHandle.index}`
|
|
29629
|
+
);
|
|
29630
|
+
}),
|
|
29631
|
+
(controlsVisible || hoverState.menuVisible) && /* @__PURE__ */ jsx81(
|
|
29632
|
+
"div",
|
|
29547
29633
|
{
|
|
29548
|
-
|
|
29549
|
-
|
|
29550
|
-
|
|
29551
|
-
|
|
29634
|
+
className: "absolute z-30",
|
|
29635
|
+
style: {
|
|
29636
|
+
top: menuTop,
|
|
29637
|
+
left: menuLeft
|
|
29638
|
+
},
|
|
29639
|
+
children: /* @__PURE__ */ jsx81(
|
|
29640
|
+
DropdownMenu,
|
|
29552
29641
|
{
|
|
29553
|
-
|
|
29554
|
-
|
|
29555
|
-
|
|
29556
|
-
|
|
29557
|
-
|
|
29558
|
-
|
|
29559
|
-
|
|
29560
|
-
|
|
29561
|
-
|
|
29562
|
-
|
|
29642
|
+
placement: "bottom-start",
|
|
29643
|
+
items: menuItems,
|
|
29644
|
+
trigger: /* @__PURE__ */ jsx81(
|
|
29645
|
+
"button",
|
|
29646
|
+
{
|
|
29647
|
+
type: "button",
|
|
29648
|
+
"aria-label": t("tableMenu.openControls"),
|
|
29649
|
+
title: t("tableMenu.openControls"),
|
|
29650
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
29651
|
+
className: cn(
|
|
29652
|
+
"pointer-events-auto inline-flex h-7 w-7 items-center justify-center rounded-full",
|
|
29653
|
+
"border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
|
|
29654
|
+
"transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
|
|
29655
|
+
),
|
|
29656
|
+
children: /* @__PURE__ */ jsx81(MoreHorizontal2, { className: "h-4 w-4" })
|
|
29657
|
+
}
|
|
29658
|
+
)
|
|
29563
29659
|
}
|
|
29564
29660
|
)
|
|
29565
29661
|
}
|
|
29566
|
-
)
|
|
29567
|
-
/* @__PURE__ */ jsx81(
|
|
29662
|
+
),
|
|
29663
|
+
(controlsVisible || hoverState.addColumnVisible) && /* @__PURE__ */ jsx81(
|
|
29568
29664
|
"button",
|
|
29569
29665
|
{
|
|
29570
29666
|
type: "button",
|
|
@@ -29582,13 +29678,18 @@ function TableControls({ editor, containerRef }) {
|
|
|
29582
29678
|
className: cn(
|
|
29583
29679
|
"absolute z-30 inline-flex items-center justify-center rounded-md",
|
|
29584
29680
|
"border border-border/70 bg-muted/40 text-muted-foreground shadow-sm backdrop-blur",
|
|
29585
|
-
"transition-colors hover:bg-accent hover:text-foreground disabled:opacity-50 disabled:cursor-not-allowed"
|
|
29681
|
+
"transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground disabled:opacity-50 disabled:cursor-not-allowed"
|
|
29586
29682
|
),
|
|
29587
|
-
style: {
|
|
29683
|
+
style: {
|
|
29684
|
+
top: columnRailTop,
|
|
29685
|
+
left: columnRailLeft,
|
|
29686
|
+
width: 18,
|
|
29687
|
+
height: layout.tableHeight
|
|
29688
|
+
},
|
|
29588
29689
|
children: /* @__PURE__ */ jsx81("span", { className: "text-sm font-medium leading-none", children: "+" })
|
|
29589
29690
|
}
|
|
29590
29691
|
),
|
|
29591
|
-
/* @__PURE__ */ jsx81(
|
|
29692
|
+
(controlsVisible || hoverState.addRowVisible) && /* @__PURE__ */ jsx81(
|
|
29592
29693
|
"button",
|
|
29593
29694
|
{
|
|
29594
29695
|
type: "button",
|
|
@@ -29606,9 +29707,14 @@ function TableControls({ editor, containerRef }) {
|
|
|
29606
29707
|
className: cn(
|
|
29607
29708
|
"absolute z-30 inline-flex items-center justify-center rounded-md",
|
|
29608
29709
|
"border border-border/70 bg-muted/40 text-muted-foreground shadow-sm backdrop-blur",
|
|
29609
|
-
"transition-colors hover:bg-accent hover:text-foreground disabled:opacity-50 disabled:cursor-not-allowed"
|
|
29710
|
+
"transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground disabled:opacity-50 disabled:cursor-not-allowed"
|
|
29610
29711
|
),
|
|
29611
|
-
style: {
|
|
29712
|
+
style: {
|
|
29713
|
+
top: rowRailTop,
|
|
29714
|
+
left: rowRailLeft,
|
|
29715
|
+
width: layout.tableWidth,
|
|
29716
|
+
height: 16
|
|
29717
|
+
},
|
|
29612
29718
|
children: /* @__PURE__ */ jsx81("span", { className: "text-sm font-medium leading-none", children: "+" })
|
|
29613
29719
|
}
|
|
29614
29720
|
),
|
|
@@ -29743,6 +29849,19 @@ function resolveEventElement(target) {
|
|
|
29743
29849
|
if (target instanceof Node) return target.parentElement;
|
|
29744
29850
|
return null;
|
|
29745
29851
|
}
|
|
29852
|
+
function getSelectionTableCell(view) {
|
|
29853
|
+
const browserSelection = window.getSelection();
|
|
29854
|
+
const anchorElement = resolveEventElement(browserSelection?.anchorNode ?? null);
|
|
29855
|
+
const anchorCell = anchorElement?.closest?.("th,td");
|
|
29856
|
+
if (anchorCell instanceof HTMLElement) {
|
|
29857
|
+
return anchorCell;
|
|
29858
|
+
}
|
|
29859
|
+
const { from } = view.state.selection;
|
|
29860
|
+
const domAtPos = view.domAtPos(from);
|
|
29861
|
+
const element = resolveEventElement(domAtPos.node);
|
|
29862
|
+
const cell = element?.closest?.("th,td");
|
|
29863
|
+
return cell instanceof HTMLElement ? cell : null;
|
|
29864
|
+
}
|
|
29746
29865
|
function isRowResizeHotspot(cell, clientX, clientY) {
|
|
29747
29866
|
const rect = cell.getBoundingClientRect();
|
|
29748
29867
|
const nearBottom = rect.bottom - clientY <= TABLE_RESIZE_HIT_ZONE;
|
|
@@ -29769,6 +29888,16 @@ function getRelativeBoundaryMetrics(surface, table, row, cell) {
|
|
|
29769
29888
|
columnRight: cellRect.right - surfaceRect.left + surface.scrollLeft
|
|
29770
29889
|
};
|
|
29771
29890
|
}
|
|
29891
|
+
function getRelativeCellMetrics(surface, cell) {
|
|
29892
|
+
const surfaceRect = surface.getBoundingClientRect();
|
|
29893
|
+
const cellRect = cell.getBoundingClientRect();
|
|
29894
|
+
return {
|
|
29895
|
+
left: cellRect.left - surfaceRect.left + surface.scrollLeft,
|
|
29896
|
+
top: cellRect.top - surfaceRect.top + surface.scrollTop,
|
|
29897
|
+
width: cellRect.width,
|
|
29898
|
+
height: cellRect.height
|
|
29899
|
+
};
|
|
29900
|
+
}
|
|
29772
29901
|
var UEditor = React75.forwardRef(({
|
|
29773
29902
|
content = "",
|
|
29774
29903
|
onChange,
|
|
@@ -29796,6 +29925,9 @@ var UEditor = React75.forwardRef(({
|
|
|
29796
29925
|
const editorContentRef = useRef32(null);
|
|
29797
29926
|
const tableColumnGuideRef = useRef32(null);
|
|
29798
29927
|
const tableRowGuideRef = useRef32(null);
|
|
29928
|
+
const activeTableCellHighlightRef = useRef32(null);
|
|
29929
|
+
const hoveredTableCellRef = useRef32(null);
|
|
29930
|
+
const activeTableCellRef = useRef32(null);
|
|
29799
29931
|
const rowResizeStateRef = useRef32(null);
|
|
29800
29932
|
const setEditorResizeCursor = React75.useCallback((cursor) => {
|
|
29801
29933
|
const proseMirror = editorContentRef.current?.querySelector(".ProseMirror");
|
|
@@ -29822,6 +29954,36 @@ var UEditor = React75.forwardRef(({
|
|
|
29822
29954
|
hideColumnGuide();
|
|
29823
29955
|
hideRowGuide();
|
|
29824
29956
|
}, [hideColumnGuide, hideRowGuide, setEditorResizeCursor]);
|
|
29957
|
+
const updateActiveCellHighlight = React75.useCallback((cell) => {
|
|
29958
|
+
const surface = editorContentRef.current;
|
|
29959
|
+
const highlight = activeTableCellHighlightRef.current;
|
|
29960
|
+
if (!highlight) return;
|
|
29961
|
+
if (!surface || !cell) {
|
|
29962
|
+
highlight.style.display = "none";
|
|
29963
|
+
return;
|
|
29964
|
+
}
|
|
29965
|
+
const metrics = getRelativeCellMetrics(surface, cell);
|
|
29966
|
+
highlight.style.display = "block";
|
|
29967
|
+
highlight.style.left = `${metrics.left}px`;
|
|
29968
|
+
highlight.style.top = `${metrics.top}px`;
|
|
29969
|
+
highlight.style.width = `${metrics.width}px`;
|
|
29970
|
+
highlight.style.height = `${metrics.height}px`;
|
|
29971
|
+
}, []);
|
|
29972
|
+
const setActiveTableCell = React75.useCallback((cell) => {
|
|
29973
|
+
if (activeTableCellRef.current === cell) return;
|
|
29974
|
+
activeTableCellRef.current = cell;
|
|
29975
|
+
updateActiveCellHighlight(activeTableCellRef.current);
|
|
29976
|
+
}, [updateActiveCellHighlight]);
|
|
29977
|
+
const clearActiveTableCell = React75.useCallback(() => {
|
|
29978
|
+
activeTableCellRef.current = null;
|
|
29979
|
+
updateActiveCellHighlight(null);
|
|
29980
|
+
}, [updateActiveCellHighlight]);
|
|
29981
|
+
const setHoveredTableCell = React75.useCallback((cell) => {
|
|
29982
|
+
hoveredTableCellRef.current = cell;
|
|
29983
|
+
}, []);
|
|
29984
|
+
const clearHoveredTableCell = React75.useCallback(() => {
|
|
29985
|
+
hoveredTableCellRef.current = null;
|
|
29986
|
+
}, []);
|
|
29825
29987
|
const showColumnGuide = React75.useCallback((table, row, cell) => {
|
|
29826
29988
|
const surface = editorContentRef.current;
|
|
29827
29989
|
const guide = tableColumnGuideRef.current;
|
|
@@ -30003,6 +30165,10 @@ var UEditor = React75.forwardRef(({
|
|
|
30003
30165
|
onJsonChange?.(editor2.getJSON());
|
|
30004
30166
|
}
|
|
30005
30167
|
});
|
|
30168
|
+
const syncActiveTableCellFromSelection = React75.useCallback(() => {
|
|
30169
|
+
if (!editor) return;
|
|
30170
|
+
setActiveTableCell(getSelectionTableCell(editor.view));
|
|
30171
|
+
}, [editor, setActiveTableCell]);
|
|
30006
30172
|
useImperativeHandle3(
|
|
30007
30173
|
ref,
|
|
30008
30174
|
() => ({
|
|
@@ -30035,9 +30201,27 @@ var UEditor = React75.forwardRef(({
|
|
|
30035
30201
|
useEffect35(() => {
|
|
30036
30202
|
if (!editor) return void 0;
|
|
30037
30203
|
const proseMirror = editor.view.dom;
|
|
30204
|
+
const surface = editorContentRef.current;
|
|
30205
|
+
let selectionSyncTimeoutId = 0;
|
|
30206
|
+
const scheduleActiveCellSync = (fallbackCell = null) => {
|
|
30207
|
+
requestAnimationFrame(() => {
|
|
30208
|
+
setActiveTableCell(getSelectionTableCell(editor.view) ?? fallbackCell);
|
|
30209
|
+
});
|
|
30210
|
+
window.clearTimeout(selectionSyncTimeoutId);
|
|
30211
|
+
selectionSyncTimeoutId = window.setTimeout(() => {
|
|
30212
|
+
setActiveTableCell(getSelectionTableCell(editor.view) ?? fallbackCell);
|
|
30213
|
+
}, 0);
|
|
30214
|
+
};
|
|
30215
|
+
const handleSelectionChange = () => {
|
|
30216
|
+
scheduleActiveCellSync();
|
|
30217
|
+
};
|
|
30218
|
+
const handleActiveCellLayoutChange = () => {
|
|
30219
|
+
updateActiveCellHighlight(activeTableCellRef.current);
|
|
30220
|
+
};
|
|
30038
30221
|
const handleEditorMouseMove = (event) => {
|
|
30039
30222
|
const activeRowResize = rowResizeStateRef.current;
|
|
30040
30223
|
if (activeRowResize) {
|
|
30224
|
+
setHoveredTableCell(activeRowResize.cellElement);
|
|
30041
30225
|
showRowGuide(activeRowResize.tableElement, activeRowResize.rowElement, activeRowResize.cellElement);
|
|
30042
30226
|
return;
|
|
30043
30227
|
}
|
|
@@ -30048,12 +30232,15 @@ var UEditor = React75.forwardRef(({
|
|
|
30048
30232
|
}
|
|
30049
30233
|
const cell = target.closest("th,td");
|
|
30050
30234
|
if (!(cell instanceof HTMLElement)) {
|
|
30235
|
+
clearHoveredTableCell();
|
|
30051
30236
|
clearAllTableResizeHover();
|
|
30052
30237
|
return;
|
|
30053
30238
|
}
|
|
30239
|
+
setHoveredTableCell(cell);
|
|
30054
30240
|
const row = cell.closest("tr");
|
|
30055
30241
|
const table = cell.closest("table");
|
|
30056
30242
|
if (!(row instanceof HTMLTableRowElement) || !(table instanceof HTMLTableElement)) {
|
|
30243
|
+
clearHoveredTableCell();
|
|
30057
30244
|
clearAllTableResizeHover();
|
|
30058
30245
|
return;
|
|
30059
30246
|
}
|
|
@@ -30072,6 +30259,7 @@ var UEditor = React75.forwardRef(({
|
|
|
30072
30259
|
clearAllTableResizeHover();
|
|
30073
30260
|
};
|
|
30074
30261
|
const handleEditorMouseLeave = () => {
|
|
30262
|
+
clearHoveredTableCell();
|
|
30075
30263
|
if (!rowResizeStateRef.current) {
|
|
30076
30264
|
clearAllTableResizeHover();
|
|
30077
30265
|
}
|
|
@@ -30079,15 +30267,24 @@ var UEditor = React75.forwardRef(({
|
|
|
30079
30267
|
const handleEditorMouseDown = (event) => {
|
|
30080
30268
|
if (event.button !== 0) return;
|
|
30081
30269
|
const target = resolveEventElement(event.target);
|
|
30082
|
-
if (!(target instanceof Element))
|
|
30270
|
+
if (!(target instanceof Element)) {
|
|
30271
|
+
clearActiveTableCell();
|
|
30272
|
+
return;
|
|
30273
|
+
}
|
|
30083
30274
|
const cell = target.closest("th,td");
|
|
30084
|
-
if (!(cell instanceof HTMLTableCellElement))
|
|
30275
|
+
if (!(cell instanceof HTMLTableCellElement)) {
|
|
30276
|
+
clearActiveTableCell();
|
|
30277
|
+
return;
|
|
30278
|
+
}
|
|
30279
|
+
setActiveTableCell(cell);
|
|
30280
|
+
scheduleActiveCellSync(cell);
|
|
30085
30281
|
const row = cell.closest("tr");
|
|
30086
30282
|
const table = cell.closest("table");
|
|
30087
30283
|
if (!(row instanceof HTMLTableRowElement) || !(table instanceof HTMLTableElement)) return;
|
|
30088
30284
|
if (!isRowResizeHotspot(cell, event.clientX, event.clientY)) {
|
|
30089
30285
|
return;
|
|
30090
30286
|
}
|
|
30287
|
+
setHoveredTableCell(cell);
|
|
30091
30288
|
const rowInfo = findTableRowNodeInfo(editor.view, row);
|
|
30092
30289
|
if (!rowInfo) return;
|
|
30093
30290
|
rowResizeStateRef.current = {
|
|
@@ -30148,6 +30345,7 @@ var UEditor = React75.forwardRef(({
|
|
|
30148
30345
|
clearPreviewRowHeight(state.rowElement);
|
|
30149
30346
|
rowResizeStateRef.current = null;
|
|
30150
30347
|
document.body.style.cursor = "";
|
|
30348
|
+
clearHoveredTableCell();
|
|
30151
30349
|
clearAllTableResizeHover();
|
|
30152
30350
|
};
|
|
30153
30351
|
const handleWindowBlur = () => {
|
|
@@ -30156,30 +30354,53 @@ var UEditor = React75.forwardRef(({
|
|
|
30156
30354
|
clearPreviewRowHeight(state.rowElement);
|
|
30157
30355
|
rowResizeStateRef.current = null;
|
|
30158
30356
|
document.body.style.cursor = "";
|
|
30357
|
+
clearHoveredTableCell();
|
|
30159
30358
|
clearAllTableResizeHover();
|
|
30160
30359
|
};
|
|
30161
30360
|
proseMirror.addEventListener("mousemove", handleEditorMouseMove);
|
|
30162
30361
|
proseMirror.addEventListener("mouseleave", handleEditorMouseLeave);
|
|
30163
30362
|
proseMirror.addEventListener("mousedown", handleEditorMouseDown);
|
|
30363
|
+
proseMirror.addEventListener("click", handleSelectionChange);
|
|
30364
|
+
proseMirror.addEventListener("mouseup", handleSelectionChange);
|
|
30365
|
+
proseMirror.addEventListener("keyup", handleSelectionChange);
|
|
30366
|
+
proseMirror.addEventListener("focusin", handleSelectionChange);
|
|
30367
|
+
document.addEventListener("selectionchange", handleSelectionChange);
|
|
30368
|
+
surface?.addEventListener("scroll", handleActiveCellLayoutChange, { passive: true });
|
|
30369
|
+
window.addEventListener("resize", handleActiveCellLayoutChange);
|
|
30164
30370
|
window.addEventListener("mousemove", handlePointerMove);
|
|
30165
30371
|
document.addEventListener("pointermove", handlePointerMove);
|
|
30166
30372
|
window.addEventListener("mouseup", handlePointerUp);
|
|
30167
30373
|
document.addEventListener("pointerup", handlePointerUp);
|
|
30168
30374
|
window.addEventListener("blur", handleWindowBlur);
|
|
30375
|
+
editor.on("selectionUpdate", syncActiveTableCellFromSelection);
|
|
30376
|
+
editor.on("focus", syncActiveTableCellFromSelection);
|
|
30377
|
+
syncActiveTableCellFromSelection();
|
|
30169
30378
|
return () => {
|
|
30170
30379
|
proseMirror.removeEventListener("mousemove", handleEditorMouseMove);
|
|
30171
30380
|
proseMirror.removeEventListener("mouseleave", handleEditorMouseLeave);
|
|
30172
30381
|
proseMirror.removeEventListener("mousedown", handleEditorMouseDown);
|
|
30382
|
+
proseMirror.removeEventListener("click", handleSelectionChange);
|
|
30383
|
+
proseMirror.removeEventListener("mouseup", handleSelectionChange);
|
|
30384
|
+
proseMirror.removeEventListener("keyup", handleSelectionChange);
|
|
30385
|
+
proseMirror.removeEventListener("focusin", handleSelectionChange);
|
|
30386
|
+
document.removeEventListener("selectionchange", handleSelectionChange);
|
|
30387
|
+
surface?.removeEventListener("scroll", handleActiveCellLayoutChange);
|
|
30388
|
+
window.removeEventListener("resize", handleActiveCellLayoutChange);
|
|
30173
30389
|
window.removeEventListener("mousemove", handlePointerMove);
|
|
30174
30390
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
30175
30391
|
window.removeEventListener("mouseup", handlePointerUp);
|
|
30176
30392
|
document.removeEventListener("pointerup", handlePointerUp);
|
|
30177
30393
|
window.removeEventListener("blur", handleWindowBlur);
|
|
30394
|
+
editor.off("selectionUpdate", syncActiveTableCellFromSelection);
|
|
30395
|
+
editor.off("focus", syncActiveTableCellFromSelection);
|
|
30396
|
+
window.clearTimeout(selectionSyncTimeoutId);
|
|
30178
30397
|
document.body.style.cursor = "";
|
|
30398
|
+
clearActiveTableCell();
|
|
30399
|
+
clearHoveredTableCell();
|
|
30179
30400
|
clearAllTableResizeHover();
|
|
30180
30401
|
rowResizeStateRef.current = null;
|
|
30181
30402
|
};
|
|
30182
|
-
}, [clearAllTableResizeHover, editor, hideColumnGuide, hideRowGuide, showColumnGuide, showRowGuide]);
|
|
30403
|
+
}, [clearActiveTableCell, clearAllTableResizeHover, clearHoveredTableCell, editor, hideColumnGuide, hideRowGuide, setHoveredTableCell, showColumnGuide, showRowGuide, syncActiveTableCellFromSelection, updateActiveCellHighlight]);
|
|
30183
30404
|
if (!editor) {
|
|
30184
30405
|
return /* @__PURE__ */ jsx82(
|
|
30185
30406
|
"div",
|
|
@@ -30231,6 +30452,14 @@ var UEditor = React75.forwardRef(({
|
|
|
30231
30452
|
className: "pointer-events-none absolute z-20 bg-primary opacity-0 transition-opacity duration-100"
|
|
30232
30453
|
}
|
|
30233
30454
|
),
|
|
30455
|
+
/* @__PURE__ */ jsx82(
|
|
30456
|
+
"span",
|
|
30457
|
+
{
|
|
30458
|
+
ref: activeTableCellHighlightRef,
|
|
30459
|
+
"aria-hidden": "true",
|
|
30460
|
+
className: "pointer-events-none hidden absolute z-20 rounded-[2px] border-2 border-[#2383e2] bg-[#2383e2]/[0.06] transition-[left,top,width,height] duration-100"
|
|
30461
|
+
}
|
|
30462
|
+
),
|
|
30234
30463
|
editable && /* @__PURE__ */ jsx82(TableControls, { editor, containerRef: editorContentRef }),
|
|
30235
30464
|
/* @__PURE__ */ jsx82(
|
|
30236
30465
|
EditorContent,
|