@underverse-ui/underverse 1.0.71 → 1.0.73

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/dist/index.cjs CHANGED
@@ -20506,46 +20506,52 @@ function DataTableHeader({
20506
20506
  const titleContent = /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "flex items-center gap-1", children: [
20507
20507
  /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: cn("font-medium whitespace-nowrap select-text", headerTitleClass), children: col.title }),
20508
20508
  col.sortable && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
20509
- "button",
20509
+ Tooltip,
20510
20510
  {
20511
- className: cn(
20512
- "p-1 rounded-lg transition-all duration-200 hover:bg-accent",
20513
- sort?.key === col.key ? "opacity-100 bg-accent" : "opacity-60 hover:opacity-100"
20514
- ),
20515
- onClick: () => {
20516
- setCurPage(1);
20517
- setSort((current) => {
20518
- if (!current || current.key !== col.key) return { key: col.key, order: "asc" };
20519
- if (current.order === "asc") return { key: col.key, order: "desc" };
20520
- return null;
20521
- });
20522
- },
20523
- "aria-label": "Sort",
20524
- title: `Sort by ${String(col.title)}`,
20525
- children: /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("svg", { viewBox: "0 0 20 20", fill: "none", className: cn("inline-block", sortIconClass), children: [
20526
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
20527
- "path",
20528
- {
20529
- d: "M7 8l3-3 3 3",
20530
- stroke: "currentColor",
20531
- strokeWidth: "1.5",
20532
- strokeLinecap: "round",
20533
- strokeLinejoin: "round",
20534
- opacity: sort?.key === col.key && sort.order === "asc" ? 1 : 0.4
20535
- }
20536
- ),
20537
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
20538
- "path",
20539
- {
20540
- d: "M7 12l3 3 3-3",
20541
- stroke: "currentColor",
20542
- strokeWidth: "1.5",
20543
- strokeLinecap: "round",
20544
- strokeLinejoin: "round",
20545
- opacity: sort?.key === col.key && sort.order === "desc" ? 1 : 0.4
20546
- }
20547
- )
20548
- ] })
20511
+ placement: "top",
20512
+ content: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "text-xs font-medium", children: `Sort by ${String(col.title)}` }),
20513
+ children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
20514
+ "button",
20515
+ {
20516
+ className: cn(
20517
+ "p-1 rounded-lg transition-all duration-200 hover:bg-accent",
20518
+ sort?.key === col.key ? "opacity-100 bg-accent" : "opacity-60 hover:opacity-100"
20519
+ ),
20520
+ onClick: () => {
20521
+ setCurPage(1);
20522
+ setSort((current) => {
20523
+ if (!current || current.key !== col.key) return { key: col.key, order: "asc" };
20524
+ if (current.order === "asc") return { key: col.key, order: "desc" };
20525
+ return null;
20526
+ });
20527
+ },
20528
+ "aria-label": "Sort",
20529
+ children: /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("svg", { viewBox: "0 0 20 20", fill: "none", className: cn("inline-block", sortIconClass), children: [
20530
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
20531
+ "path",
20532
+ {
20533
+ d: "M7 8l3-3 3 3",
20534
+ stroke: "currentColor",
20535
+ strokeWidth: "1.5",
20536
+ strokeLinecap: "round",
20537
+ strokeLinejoin: "round",
20538
+ opacity: sort?.key === col.key && sort.order === "asc" ? 1 : 0.4
20539
+ }
20540
+ ),
20541
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
20542
+ "path",
20543
+ {
20544
+ d: "M7 12l3 3 3-3",
20545
+ stroke: "currentColor",
20546
+ strokeWidth: "1.5",
20547
+ strokeLinecap: "round",
20548
+ strokeLinejoin: "round",
20549
+ opacity: sort?.key === col.key && sort.order === "desc" ? 1 : 0.4
20550
+ }
20551
+ )
20552
+ ] })
20553
+ }
20554
+ )
20549
20555
  }
20550
20556
  )
20551
20557
  ] });
@@ -20553,18 +20559,24 @@ function DataTableHeader({
20553
20559
  Popover,
20554
20560
  {
20555
20561
  placement: "bottom-start",
20556
- trigger: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
20557
- "button",
20562
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "inline-flex", children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
20563
+ Tooltip,
20558
20564
  {
20559
- className: cn(
20560
- "p-1.5 rounded-lg transition-all duration-200 hover:bg-accent",
20561
- filters[col.key] ? "bg-accent text-primary" : "text-muted-foreground"
20562
- ),
20563
- "aria-label": "Filter",
20564
- title: `Filter by ${String(col.title)}`,
20565
- children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_lucide_react35.Filter, { className: "w-4 h-4" })
20565
+ placement: "top",
20566
+ content: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "text-xs font-medium", children: `Filter by ${String(col.title)}` }),
20567
+ children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
20568
+ "button",
20569
+ {
20570
+ className: cn(
20571
+ "p-1.5 rounded-lg transition-all duration-200 hover:bg-accent",
20572
+ filters[col.key] ? "bg-accent text-primary" : "text-muted-foreground"
20573
+ ),
20574
+ "aria-label": "Filter",
20575
+ children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_lucide_react35.Filter, { className: "w-4 h-4" })
20576
+ }
20577
+ )
20566
20578
  }
20567
- ),
20579
+ ) }),
20568
20580
  children: /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "p-3 w-64 space-y-3", children: [
20569
20581
  /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "flex items-center justify-between", children: [
20570
20582
  /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "text-sm font-medium", children: col.title }),
@@ -29039,6 +29051,19 @@ var import_lucide_react47 = require("lucide-react");
29039
29051
  var import_jsx_runtime82 = require("react/jsx-runtime");
29040
29052
  var FALLBACK_TABLE_ROW_HEIGHT = 44;
29041
29053
  var FALLBACK_TABLE_COLUMN_WIDTH = 160;
29054
+ var MENU_HOVER_PADDING = 18;
29055
+ var ROW_HANDLE_HOVER_WIDTH = 28;
29056
+ var COLUMN_HANDLE_HOVER_HEIGHT = 28;
29057
+ var ADD_COLUMN_HOVER_WIDTH = 24;
29058
+ var ADD_ROW_HOVER_HEIGHT = 24;
29059
+ var HANDLE_HOVER_RADIUS = 14;
29060
+ var DEFAULT_HOVER_STATE = {
29061
+ menuVisible: false,
29062
+ addColumnVisible: false,
29063
+ addRowVisible: false,
29064
+ rowHandleIndex: null,
29065
+ columnHandleIndex: null
29066
+ };
29042
29067
  function resolveElement(target) {
29043
29068
  if (target instanceof Element) return target;
29044
29069
  if (target instanceof Node) return target.parentElement;
@@ -29164,6 +29189,12 @@ function buildLayout(editor, surface, cell) {
29164
29189
  };
29165
29190
  }
29166
29191
  function getSelectedCell(editor) {
29192
+ const browserSelection = window.getSelection();
29193
+ const anchorElement = resolveElement(browserSelection?.anchorNode ?? null);
29194
+ const anchorCell = anchorElement?.closest?.("th,td");
29195
+ if (anchorCell instanceof HTMLTableCellElement) {
29196
+ return anchorCell;
29197
+ }
29167
29198
  const domAtPos = editor.view.domAtPos(editor.state.selection.from);
29168
29199
  return getCellFromTarget(domAtPos.node);
29169
29200
  }
@@ -29192,6 +29223,8 @@ function TableControls({ editor, containerRef }) {
29192
29223
  const t = useSmartTranslations("UEditor");
29193
29224
  const [layout, setLayout] = import_react52.default.useState(null);
29194
29225
  const [dragPreview, setDragPreview] = import_react52.default.useState(null);
29226
+ const [hoverState, setHoverState] = import_react52.default.useState(DEFAULT_HOVER_STATE);
29227
+ const [openMenuKey, setOpenMenuKey] = import_react52.default.useState(null);
29195
29228
  const layoutRef = import_react52.default.useRef(null);
29196
29229
  const dragStateRef = import_react52.default.useRef(null);
29197
29230
  import_react52.default.useEffect(() => {
@@ -29223,17 +29256,58 @@ function TableControls({ editor, containerRef }) {
29223
29256
  setDragPreview(null);
29224
29257
  document.body.style.cursor = "";
29225
29258
  }, []);
29259
+ const updateHoverState = import_react52.default.useCallback((event) => {
29260
+ const activeLayout = layoutRef.current;
29261
+ const surface = containerRef.current;
29262
+ if (!activeLayout || !surface || dragStateRef.current) {
29263
+ setHoverState(DEFAULT_HOVER_STATE);
29264
+ return;
29265
+ }
29266
+ const surfaceRect = surface.getBoundingClientRect();
29267
+ const relativeX = event.clientX - surfaceRect.left + surface.scrollLeft;
29268
+ const relativeY = event.clientY - surfaceRect.top + surface.scrollTop;
29269
+ const targetElement = resolveElement(event.target);
29270
+ const directRowHandle = targetElement?.closest?.("[data-row-handle-index]");
29271
+ const directColumnHandle = targetElement?.closest?.("[data-column-handle-index]");
29272
+ const directTableMenu = targetElement?.closest?.("[data-table-control='table-menu']");
29273
+ const directAddColumn = targetElement?.closest?.("[data-table-control='add-column']");
29274
+ const directAddRow = targetElement?.closest?.("[data-table-control='add-row']");
29275
+ const directRowHandleIndex = directRowHandle instanceof HTMLElement ? Number.parseInt(directRowHandle.dataset.rowHandleIndex ?? "", 10) : Number.NaN;
29276
+ const directColumnHandleIndex = directColumnHandle instanceof HTMLElement ? Number.parseInt(directColumnHandle.dataset.columnHandleIndex ?? "", 10) : Number.NaN;
29277
+ 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;
29278
+ 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;
29279
+ const menuVisible = Boolean(directTableMenu) || relativeX >= activeLayout.tableLeft - MENU_HOVER_PADDING && relativeX <= activeLayout.tableLeft + 42 && relativeY >= activeLayout.tableTop - COLUMN_HANDLE_HOVER_HEIGHT && relativeY <= activeLayout.tableTop + MENU_HOVER_PADDING;
29280
+ const addColumnVisible = Boolean(directAddColumn) || relativeX >= activeLayout.tableLeft + activeLayout.tableWidth && relativeX <= activeLayout.tableLeft + activeLayout.tableWidth + ADD_COLUMN_HOVER_WIDTH && relativeY >= activeLayout.tableTop && relativeY <= activeLayout.tableTop + activeLayout.tableHeight;
29281
+ const addRowVisible = Boolean(directAddRow) || relativeY >= activeLayout.tableTop + activeLayout.tableHeight && relativeY <= activeLayout.tableTop + activeLayout.tableHeight + ADD_ROW_HOVER_HEIGHT && relativeX >= activeLayout.tableLeft && relativeX <= activeLayout.tableLeft + activeLayout.tableWidth;
29282
+ setHoverState((prev) => {
29283
+ if (prev.menuVisible === menuVisible && prev.addColumnVisible === addColumnVisible && prev.addRowVisible === addRowVisible && prev.rowHandleIndex === rowHandleIndex && prev.columnHandleIndex === columnHandleIndex) {
29284
+ return prev;
29285
+ }
29286
+ return {
29287
+ menuVisible,
29288
+ addColumnVisible,
29289
+ addRowVisible,
29290
+ rowHandleIndex,
29291
+ columnHandleIndex
29292
+ };
29293
+ });
29294
+ }, [containerRef]);
29226
29295
  import_react52.default.useEffect(() => {
29227
29296
  const proseMirror = editor.view.dom;
29228
29297
  const surface = containerRef.current;
29229
29298
  if (!surface) return void 0;
29230
29299
  const handleMouseOver = (event) => {
29231
29300
  if (dragStateRef.current) return;
29232
- syncFromCell(getCellFromTarget(event.target));
29301
+ const cell = getCellFromTarget(event.target);
29302
+ if (!cell) return;
29303
+ syncFromCell(cell);
29304
+ };
29305
+ const handleSurfaceMouseMove = (event) => {
29306
+ updateHoverState(event);
29233
29307
  };
29234
29308
  const handleMouseLeave = () => {
29235
29309
  if (dragStateRef.current) return;
29236
- syncFromSelection();
29310
+ setHoverState(DEFAULT_HOVER_STATE);
29237
29311
  };
29238
29312
  const handleFocusIn = () => {
29239
29313
  if (dragStateRef.current) return;
@@ -29242,6 +29316,8 @@ function TableControls({ editor, containerRef }) {
29242
29316
  proseMirror.addEventListener("mouseover", handleMouseOver);
29243
29317
  proseMirror.addEventListener("mouseleave", handleMouseLeave);
29244
29318
  proseMirror.addEventListener("focusin", handleFocusIn);
29319
+ surface.addEventListener("mouseover", handleSurfaceMouseMove);
29320
+ surface.addEventListener("mousemove", handleSurfaceMouseMove);
29245
29321
  surface.addEventListener("scroll", refreshCurrentLayout, { passive: true });
29246
29322
  window.addEventListener("resize", refreshCurrentLayout);
29247
29323
  editor.on("selectionUpdate", syncFromSelection);
@@ -29251,12 +29327,14 @@ function TableControls({ editor, containerRef }) {
29251
29327
  proseMirror.removeEventListener("mouseover", handleMouseOver);
29252
29328
  proseMirror.removeEventListener("mouseleave", handleMouseLeave);
29253
29329
  proseMirror.removeEventListener("focusin", handleFocusIn);
29330
+ surface.removeEventListener("mouseover", handleSurfaceMouseMove);
29331
+ surface.removeEventListener("mousemove", handleSurfaceMouseMove);
29254
29332
  surface.removeEventListener("scroll", refreshCurrentLayout);
29255
29333
  window.removeEventListener("resize", refreshCurrentLayout);
29256
29334
  editor.off("selectionUpdate", syncFromSelection);
29257
29335
  editor.off("update", refreshCurrentLayout);
29258
29336
  };
29259
- }, [clearDrag, containerRef, editor, refreshCurrentLayout, syncFromCell, syncFromSelection]);
29337
+ }, [clearDrag, containerRef, editor, refreshCurrentLayout, syncFromCell, syncFromSelection, updateHoverState]);
29260
29338
  const runAtCellPos = import_react52.default.useCallback((cellPos, command, options) => {
29261
29339
  if (cellPos == null) return false;
29262
29340
  focusCell(editor, cellPos);
@@ -29346,6 +29424,10 @@ function TableControls({ editor, containerRef }) {
29346
29424
  return true;
29347
29425
  }, [runAtCornerCell, syncFromSelection]);
29348
29426
  const canExpandTable = Boolean(layout);
29427
+ const controlsVisible = dragPreview !== null;
29428
+ const tableMenuOpen = openMenuKey === "table";
29429
+ const getRowMenuKey = import_react52.default.useCallback((index) => `row:${index}`, []);
29430
+ const getColumnMenuKey = import_react52.default.useCallback((index) => `column:${index}`, []);
29349
29431
  import_react52.default.useEffect(() => {
29350
29432
  const handleMouseMove = (event) => {
29351
29433
  const dragState = dragStateRef.current;
@@ -29557,115 +29639,176 @@ function TableControls({ editor, containerRef }) {
29557
29639
  const expandPreviewHeight = dragPreview?.kind === "add-row" ? layout.tableHeight + dragPreview.previewRows * layout.avgRowHeight : layout.tableHeight;
29558
29640
  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;
29559
29641
  return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(import_jsx_runtime82.Fragment, { children: [
29560
- layout.rowHandles.map((rowHandle) => /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "absolute z-30", style: { top: Math.max(8, rowHandle.center - 12), left: rowHandleLeft }, children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29561
- DropdownMenu,
29562
- {
29563
- placement: "right",
29564
- items: getRowHandleMenuItems(rowHandle),
29565
- trigger: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29566
- "button",
29567
- {
29568
- type: "button",
29569
- "aria-label": `${t("tableMenu.dragRow")} ${rowHandle.index + 1}`,
29570
- title: `${t("tableMenu.dragRow")} ${rowHandle.index + 1}`,
29571
- onMouseDown: (event) => {
29572
- event.preventDefault();
29573
- event.stopPropagation();
29574
- dragStateRef.current = {
29575
- kind: "row",
29576
- originIndex: rowHandle.index,
29577
- targetIndex: rowHandle.index,
29578
- anchorPos: rowHandle.cellPos
29579
- };
29580
- setDragPreview({
29581
- kind: "row",
29582
- originIndex: rowHandle.index,
29583
- targetIndex: rowHandle.index,
29584
- targetStart: rowHandle.start,
29585
- targetSize: rowHandle.size
29586
- });
29587
- document.body.style.cursor = "grabbing";
29588
- },
29589
- className: cn(
29590
- "inline-flex h-6 w-6 items-center justify-center rounded-full",
29591
- "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
29592
- "transition-colors hover:bg-accent hover:text-foreground"
29593
- ),
29594
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_lucide_react47.GripVertical, { className: "h-3.5 w-3.5" })
29595
- }
29596
- )
29597
- }
29598
- ) }, `row-handle-${rowHandle.index}`)),
29599
- layout.columnHandles.map((columnHandle) => /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "absolute z-30", style: { top: columnHandleTop, left: Math.max(8, columnHandle.center - 12) }, children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29600
- DropdownMenu,
29642
+ layout.rowHandles.map((rowHandle) => {
29643
+ const menuKey = getRowMenuKey(rowHandle.index);
29644
+ const visible = controlsVisible || hoverState.rowHandleIndex === rowHandle.index || openMenuKey === menuKey;
29645
+ if (!visible) return null;
29646
+ return /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29647
+ "div",
29648
+ {
29649
+ className: "absolute z-30",
29650
+ "data-row-handle-index": rowHandle.index,
29651
+ style: {
29652
+ top: Math.max(8, rowHandle.center - 12),
29653
+ left: rowHandleLeft
29654
+ },
29655
+ children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29656
+ DropdownMenu,
29657
+ {
29658
+ placement: "right",
29659
+ isOpen: openMenuKey === menuKey,
29660
+ onOpenChange: (open) => {
29661
+ setOpenMenuKey((prev) => open ? menuKey : prev === menuKey ? null : prev);
29662
+ },
29663
+ items: getRowHandleMenuItems(rowHandle),
29664
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29665
+ "button",
29666
+ {
29667
+ type: "button",
29668
+ "aria-label": `${t("tableMenu.dragRow")} ${rowHandle.index + 1}`,
29669
+ title: `${t("tableMenu.dragRow")} ${rowHandle.index + 1}`,
29670
+ onMouseDown: (event) => {
29671
+ event.preventDefault();
29672
+ event.stopPropagation();
29673
+ setOpenMenuKey(null);
29674
+ dragStateRef.current = {
29675
+ kind: "row",
29676
+ originIndex: rowHandle.index,
29677
+ targetIndex: rowHandle.index,
29678
+ anchorPos: rowHandle.cellPos
29679
+ };
29680
+ setDragPreview({
29681
+ kind: "row",
29682
+ originIndex: rowHandle.index,
29683
+ targetIndex: rowHandle.index,
29684
+ targetStart: rowHandle.start,
29685
+ targetSize: rowHandle.size
29686
+ });
29687
+ document.body.style.cursor = "grabbing";
29688
+ },
29689
+ className: cn(
29690
+ "inline-flex h-6 w-6 items-center justify-center rounded-full",
29691
+ "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
29692
+ "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
29693
+ ),
29694
+ children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_lucide_react47.GripVertical, { className: "h-3.5 w-3.5" })
29695
+ }
29696
+ )
29697
+ }
29698
+ )
29699
+ },
29700
+ `row-handle-${rowHandle.index}`
29701
+ );
29702
+ }),
29703
+ layout.columnHandles.map((columnHandle) => {
29704
+ const menuKey = getColumnMenuKey(columnHandle.index);
29705
+ const visible = controlsVisible || hoverState.columnHandleIndex === columnHandle.index || openMenuKey === menuKey;
29706
+ if (!visible) return null;
29707
+ return /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29708
+ "div",
29709
+ {
29710
+ className: "absolute z-30",
29711
+ "data-column-handle-index": columnHandle.index,
29712
+ style: {
29713
+ top: columnHandleTop,
29714
+ left: Math.max(8, columnHandle.center - 12)
29715
+ },
29716
+ children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29717
+ DropdownMenu,
29718
+ {
29719
+ placement: "bottom-start",
29720
+ isOpen: openMenuKey === menuKey,
29721
+ onOpenChange: (open) => {
29722
+ setOpenMenuKey((prev) => open ? menuKey : prev === menuKey ? null : prev);
29723
+ },
29724
+ items: getColumnHandleMenuItems(columnHandle),
29725
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29726
+ "button",
29727
+ {
29728
+ type: "button",
29729
+ "aria-label": `${t("tableMenu.dragColumn")} ${columnHandle.index + 1}`,
29730
+ title: `${t("tableMenu.dragColumn")} ${columnHandle.index + 1}`,
29731
+ onMouseDown: (event) => {
29732
+ event.preventDefault();
29733
+ event.stopPropagation();
29734
+ setOpenMenuKey(null);
29735
+ dragStateRef.current = {
29736
+ kind: "column",
29737
+ originIndex: columnHandle.index,
29738
+ targetIndex: columnHandle.index,
29739
+ anchorPos: columnHandle.cellPos
29740
+ };
29741
+ setDragPreview({
29742
+ kind: "column",
29743
+ originIndex: columnHandle.index,
29744
+ targetIndex: columnHandle.index,
29745
+ targetStart: columnHandle.start,
29746
+ targetSize: columnHandle.size
29747
+ });
29748
+ document.body.style.cursor = "grabbing";
29749
+ },
29750
+ className: cn(
29751
+ "inline-flex h-6 w-6 items-center justify-center rounded-full",
29752
+ "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
29753
+ "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
29754
+ ),
29755
+ children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_lucide_react47.GripHorizontal, { className: "h-3.5 w-3.5" })
29756
+ }
29757
+ )
29758
+ }
29759
+ )
29760
+ },
29761
+ `column-handle-${columnHandle.index}`
29762
+ );
29763
+ }),
29764
+ (controlsVisible || hoverState.menuVisible || tableMenuOpen) && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29765
+ "div",
29601
29766
  {
29602
- placement: "bottom-start",
29603
- items: getColumnHandleMenuItems(columnHandle),
29604
- trigger: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29605
- "button",
29767
+ className: "absolute z-30",
29768
+ "data-table-control": "table-menu",
29769
+ style: {
29770
+ top: menuTop,
29771
+ left: menuLeft
29772
+ },
29773
+ children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29774
+ DropdownMenu,
29606
29775
  {
29607
- type: "button",
29608
- "aria-label": `${t("tableMenu.dragColumn")} ${columnHandle.index + 1}`,
29609
- title: `${t("tableMenu.dragColumn")} ${columnHandle.index + 1}`,
29610
- onMouseDown: (event) => {
29611
- event.preventDefault();
29612
- event.stopPropagation();
29613
- dragStateRef.current = {
29614
- kind: "column",
29615
- originIndex: columnHandle.index,
29616
- targetIndex: columnHandle.index,
29617
- anchorPos: columnHandle.cellPos
29618
- };
29619
- setDragPreview({
29620
- kind: "column",
29621
- originIndex: columnHandle.index,
29622
- targetIndex: columnHandle.index,
29623
- targetStart: columnHandle.start,
29624
- targetSize: columnHandle.size
29625
- });
29626
- document.body.style.cursor = "grabbing";
29776
+ placement: "bottom-start",
29777
+ isOpen: tableMenuOpen,
29778
+ onOpenChange: (open) => {
29779
+ setOpenMenuKey((prev) => open ? "table" : prev === "table" ? null : prev);
29627
29780
  },
29628
- className: cn(
29629
- "inline-flex h-6 w-6 items-center justify-center rounded-full",
29630
- "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
29631
- "transition-colors hover:bg-accent hover:text-foreground"
29632
- ),
29633
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_lucide_react47.GripHorizontal, { className: "h-3.5 w-3.5" })
29634
- }
29635
- )
29636
- }
29637
- ) }, `column-handle-${columnHandle.index}`)),
29638
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "pointer-events-none absolute z-30", style: { top: menuTop, left: menuLeft }, children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29639
- DropdownMenu,
29640
- {
29641
- placement: "bottom-start",
29642
- items: menuItems,
29643
- trigger: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29644
- "button",
29645
- {
29646
- type: "button",
29647
- "aria-label": t("tableMenu.openControls"),
29648
- title: t("tableMenu.openControls"),
29649
- onMouseDown: (event) => event.preventDefault(),
29650
- className: cn(
29651
- "pointer-events-auto inline-flex h-7 w-7 items-center justify-center rounded-full",
29652
- "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
29653
- "transition-colors hover:bg-accent hover:text-foreground"
29654
- ),
29655
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_lucide_react47.MoreHorizontal, { className: "h-4 w-4" })
29781
+ items: menuItems,
29782
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29783
+ "button",
29784
+ {
29785
+ type: "button",
29786
+ "aria-label": t("tableMenu.openControls"),
29787
+ title: t("tableMenu.openControls"),
29788
+ onMouseDown: (event) => event.preventDefault(),
29789
+ className: cn(
29790
+ "pointer-events-auto inline-flex h-7 w-7 items-center justify-center rounded-full",
29791
+ "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
29792
+ "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
29793
+ ),
29794
+ children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_lucide_react47.MoreHorizontal, { className: "h-4 w-4" })
29795
+ }
29796
+ )
29656
29797
  }
29657
29798
  )
29658
29799
  }
29659
- ) }),
29660
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29800
+ ),
29801
+ (controlsVisible || hoverState.addColumnVisible) && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29661
29802
  "button",
29662
29803
  {
29663
29804
  type: "button",
29805
+ "data-table-control": "add-column",
29664
29806
  "aria-label": t("tableMenu.quickAddColumnAfter"),
29665
29807
  title: t("tableMenu.quickAddColumnAfter"),
29666
29808
  onMouseDown: (event) => {
29667
29809
  event.preventDefault();
29668
29810
  event.stopPropagation();
29811
+ setOpenMenuKey(null);
29669
29812
  if (!canExpandTable) return;
29670
29813
  dragStateRef.current = { kind: "add-column", previewCols: 1 };
29671
29814
  setDragPreview({ kind: "add-column", previewCols: 1 });
@@ -29675,21 +29818,28 @@ function TableControls({ editor, containerRef }) {
29675
29818
  className: cn(
29676
29819
  "absolute z-30 inline-flex items-center justify-center rounded-md",
29677
29820
  "border border-border/70 bg-muted/40 text-muted-foreground shadow-sm backdrop-blur",
29678
- "transition-colors hover:bg-accent hover:text-foreground disabled:opacity-50 disabled:cursor-not-allowed"
29821
+ "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground disabled:opacity-50 disabled:cursor-not-allowed"
29679
29822
  ),
29680
- style: { top: columnRailTop, left: columnRailLeft, width: 18, height: layout.tableHeight },
29823
+ style: {
29824
+ top: columnRailTop,
29825
+ left: columnRailLeft,
29826
+ width: 18,
29827
+ height: layout.tableHeight
29828
+ },
29681
29829
  children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "text-sm font-medium leading-none", children: "+" })
29682
29830
  }
29683
29831
  ),
29684
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29832
+ (controlsVisible || hoverState.addRowVisible) && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29685
29833
  "button",
29686
29834
  {
29687
29835
  type: "button",
29836
+ "data-table-control": "add-row",
29688
29837
  "aria-label": t("tableMenu.quickAddRowAfter"),
29689
29838
  title: t("tableMenu.quickAddRowAfter"),
29690
29839
  onMouseDown: (event) => {
29691
29840
  event.preventDefault();
29692
29841
  event.stopPropagation();
29842
+ setOpenMenuKey(null);
29693
29843
  if (!canExpandTable) return;
29694
29844
  dragStateRef.current = { kind: "add-row", previewRows: 1 };
29695
29845
  setDragPreview({ kind: "add-row", previewRows: 1 });
@@ -29699,9 +29849,14 @@ function TableControls({ editor, containerRef }) {
29699
29849
  className: cn(
29700
29850
  "absolute z-30 inline-flex items-center justify-center rounded-md",
29701
29851
  "border border-border/70 bg-muted/40 text-muted-foreground shadow-sm backdrop-blur",
29702
- "transition-colors hover:bg-accent hover:text-foreground disabled:opacity-50 disabled:cursor-not-allowed"
29852
+ "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground disabled:opacity-50 disabled:cursor-not-allowed"
29703
29853
  ),
29704
- style: { top: rowRailTop, left: rowRailLeft, width: layout.tableWidth, height: 16 },
29854
+ style: {
29855
+ top: rowRailTop,
29856
+ left: rowRailLeft,
29857
+ width: layout.tableWidth,
29858
+ height: 16
29859
+ },
29705
29860
  children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "text-sm font-medium leading-none", children: "+" })
29706
29861
  }
29707
29862
  ),
@@ -29836,6 +29991,19 @@ function resolveEventElement(target) {
29836
29991
  if (target instanceof Node) return target.parentElement;
29837
29992
  return null;
29838
29993
  }
29994
+ function getSelectionTableCell(view) {
29995
+ const browserSelection = window.getSelection();
29996
+ const anchorElement = resolveEventElement(browserSelection?.anchorNode ?? null);
29997
+ const anchorCell = anchorElement?.closest?.("th,td");
29998
+ if (anchorCell instanceof HTMLElement) {
29999
+ return anchorCell;
30000
+ }
30001
+ const { from } = view.state.selection;
30002
+ const domAtPos = view.domAtPos(from);
30003
+ const element = resolveEventElement(domAtPos.node);
30004
+ const cell = element?.closest?.("th,td");
30005
+ return cell instanceof HTMLElement ? cell : null;
30006
+ }
29839
30007
  function isRowResizeHotspot(cell, clientX, clientY) {
29840
30008
  const rect = cell.getBoundingClientRect();
29841
30009
  const nearBottom = rect.bottom - clientY <= TABLE_RESIZE_HIT_ZONE;
@@ -29862,6 +30030,16 @@ function getRelativeBoundaryMetrics(surface, table, row, cell) {
29862
30030
  columnRight: cellRect.right - surfaceRect.left + surface.scrollLeft
29863
30031
  };
29864
30032
  }
30033
+ function getRelativeCellMetrics(surface, cell) {
30034
+ const surfaceRect = surface.getBoundingClientRect();
30035
+ const cellRect = cell.getBoundingClientRect();
30036
+ return {
30037
+ left: cellRect.left - surfaceRect.left + surface.scrollLeft,
30038
+ top: cellRect.top - surfaceRect.top + surface.scrollTop,
30039
+ width: cellRect.width,
30040
+ height: cellRect.height
30041
+ };
30042
+ }
29865
30043
  var UEditor = import_react53.default.forwardRef(({
29866
30044
  content = "",
29867
30045
  onChange,
@@ -29889,6 +30067,9 @@ var UEditor = import_react53.default.forwardRef(({
29889
30067
  const editorContentRef = (0, import_react53.useRef)(null);
29890
30068
  const tableColumnGuideRef = (0, import_react53.useRef)(null);
29891
30069
  const tableRowGuideRef = (0, import_react53.useRef)(null);
30070
+ const activeTableCellHighlightRef = (0, import_react53.useRef)(null);
30071
+ const hoveredTableCellRef = (0, import_react53.useRef)(null);
30072
+ const activeTableCellRef = (0, import_react53.useRef)(null);
29892
30073
  const rowResizeStateRef = (0, import_react53.useRef)(null);
29893
30074
  const setEditorResizeCursor = import_react53.default.useCallback((cursor) => {
29894
30075
  const proseMirror = editorContentRef.current?.querySelector(".ProseMirror");
@@ -29915,6 +30096,36 @@ var UEditor = import_react53.default.forwardRef(({
29915
30096
  hideColumnGuide();
29916
30097
  hideRowGuide();
29917
30098
  }, [hideColumnGuide, hideRowGuide, setEditorResizeCursor]);
30099
+ const updateActiveCellHighlight = import_react53.default.useCallback((cell) => {
30100
+ const surface = editorContentRef.current;
30101
+ const highlight = activeTableCellHighlightRef.current;
30102
+ if (!highlight) return;
30103
+ if (!surface || !cell) {
30104
+ highlight.style.display = "none";
30105
+ return;
30106
+ }
30107
+ const metrics = getRelativeCellMetrics(surface, cell);
30108
+ highlight.style.display = "block";
30109
+ highlight.style.left = `${metrics.left}px`;
30110
+ highlight.style.top = `${metrics.top}px`;
30111
+ highlight.style.width = `${metrics.width}px`;
30112
+ highlight.style.height = `${metrics.height}px`;
30113
+ }, []);
30114
+ const setActiveTableCell = import_react53.default.useCallback((cell) => {
30115
+ if (activeTableCellRef.current === cell) return;
30116
+ activeTableCellRef.current = cell;
30117
+ updateActiveCellHighlight(activeTableCellRef.current);
30118
+ }, [updateActiveCellHighlight]);
30119
+ const clearActiveTableCell = import_react53.default.useCallback(() => {
30120
+ activeTableCellRef.current = null;
30121
+ updateActiveCellHighlight(null);
30122
+ }, [updateActiveCellHighlight]);
30123
+ const setHoveredTableCell = import_react53.default.useCallback((cell) => {
30124
+ hoveredTableCellRef.current = cell;
30125
+ }, []);
30126
+ const clearHoveredTableCell = import_react53.default.useCallback(() => {
30127
+ hoveredTableCellRef.current = null;
30128
+ }, []);
29918
30129
  const showColumnGuide = import_react53.default.useCallback((table, row, cell) => {
29919
30130
  const surface = editorContentRef.current;
29920
30131
  const guide = tableColumnGuideRef.current;
@@ -30020,8 +30231,13 @@ var UEditor = import_react53.default.forwardRef(({
30020
30231
  "[&_.selectedCell]:after:pointer-events-none",
30021
30232
  "[&_.column-resize-handle]:pointer-events-auto",
30022
30233
  "[&_.column-resize-handle]:cursor-col-resize",
30234
+ "[&_.column-resize-handle]:absolute",
30235
+ "[&_.column-resize-handle]:top-[-1px]",
30236
+ "[&_.column-resize-handle]:bottom-[-1px]",
30237
+ "[&_.column-resize-handle]:right-[-5px]",
30238
+ "[&_.column-resize-handle]:z-10",
30023
30239
  "[&_.column-resize-handle]:bg-primary/65",
30024
- "[&_.column-resize-handle]:w-2",
30240
+ "[&_.column-resize-handle]:w-2.5",
30025
30241
  "[&_.column-resize-handle]:rounded-full",
30026
30242
  "[&_.column-resize-handle]:opacity-0",
30027
30243
  "[&_.column-resize-handle]:shadow-sm",
@@ -30096,6 +30312,10 @@ var UEditor = import_react53.default.forwardRef(({
30096
30312
  onJsonChange?.(editor2.getJSON());
30097
30313
  }
30098
30314
  });
30315
+ const syncActiveTableCellFromSelection = import_react53.default.useCallback(() => {
30316
+ if (!editor) return;
30317
+ setActiveTableCell(getSelectionTableCell(editor.view));
30318
+ }, [editor, setActiveTableCell]);
30099
30319
  (0, import_react53.useImperativeHandle)(
30100
30320
  ref,
30101
30321
  () => ({
@@ -30128,9 +30348,27 @@ var UEditor = import_react53.default.forwardRef(({
30128
30348
  (0, import_react53.useEffect)(() => {
30129
30349
  if (!editor) return void 0;
30130
30350
  const proseMirror = editor.view.dom;
30351
+ const surface = editorContentRef.current;
30352
+ let selectionSyncTimeoutId = 0;
30353
+ const scheduleActiveCellSync = (fallbackCell = null) => {
30354
+ requestAnimationFrame(() => {
30355
+ setActiveTableCell(getSelectionTableCell(editor.view) ?? fallbackCell);
30356
+ });
30357
+ window.clearTimeout(selectionSyncTimeoutId);
30358
+ selectionSyncTimeoutId = window.setTimeout(() => {
30359
+ setActiveTableCell(getSelectionTableCell(editor.view) ?? fallbackCell);
30360
+ }, 0);
30361
+ };
30362
+ const handleSelectionChange = () => {
30363
+ scheduleActiveCellSync();
30364
+ };
30365
+ const handleActiveCellLayoutChange = () => {
30366
+ updateActiveCellHighlight(activeTableCellRef.current);
30367
+ };
30131
30368
  const handleEditorMouseMove = (event) => {
30132
30369
  const activeRowResize = rowResizeStateRef.current;
30133
30370
  if (activeRowResize) {
30371
+ setHoveredTableCell(activeRowResize.cellElement);
30134
30372
  showRowGuide(activeRowResize.tableElement, activeRowResize.rowElement, activeRowResize.cellElement);
30135
30373
  return;
30136
30374
  }
@@ -30141,12 +30379,15 @@ var UEditor = import_react53.default.forwardRef(({
30141
30379
  }
30142
30380
  const cell = target.closest("th,td");
30143
30381
  if (!(cell instanceof HTMLElement)) {
30382
+ clearHoveredTableCell();
30144
30383
  clearAllTableResizeHover();
30145
30384
  return;
30146
30385
  }
30386
+ setHoveredTableCell(cell);
30147
30387
  const row = cell.closest("tr");
30148
30388
  const table = cell.closest("table");
30149
30389
  if (!(row instanceof HTMLTableRowElement) || !(table instanceof HTMLTableElement)) {
30390
+ clearHoveredTableCell();
30150
30391
  clearAllTableResizeHover();
30151
30392
  return;
30152
30393
  }
@@ -30165,6 +30406,7 @@ var UEditor = import_react53.default.forwardRef(({
30165
30406
  clearAllTableResizeHover();
30166
30407
  };
30167
30408
  const handleEditorMouseLeave = () => {
30409
+ clearHoveredTableCell();
30168
30410
  if (!rowResizeStateRef.current) {
30169
30411
  clearAllTableResizeHover();
30170
30412
  }
@@ -30172,15 +30414,24 @@ var UEditor = import_react53.default.forwardRef(({
30172
30414
  const handleEditorMouseDown = (event) => {
30173
30415
  if (event.button !== 0) return;
30174
30416
  const target = resolveEventElement(event.target);
30175
- if (!(target instanceof Element)) return;
30417
+ if (!(target instanceof Element)) {
30418
+ clearActiveTableCell();
30419
+ return;
30420
+ }
30176
30421
  const cell = target.closest("th,td");
30177
- if (!(cell instanceof HTMLTableCellElement)) return;
30422
+ if (!(cell instanceof HTMLTableCellElement)) {
30423
+ clearActiveTableCell();
30424
+ return;
30425
+ }
30426
+ setActiveTableCell(cell);
30427
+ scheduleActiveCellSync(cell);
30178
30428
  const row = cell.closest("tr");
30179
30429
  const table = cell.closest("table");
30180
30430
  if (!(row instanceof HTMLTableRowElement) || !(table instanceof HTMLTableElement)) return;
30181
30431
  if (!isRowResizeHotspot(cell, event.clientX, event.clientY)) {
30182
30432
  return;
30183
30433
  }
30434
+ setHoveredTableCell(cell);
30184
30435
  const rowInfo = findTableRowNodeInfo(editor.view, row);
30185
30436
  if (!rowInfo) return;
30186
30437
  rowResizeStateRef.current = {
@@ -30241,6 +30492,7 @@ var UEditor = import_react53.default.forwardRef(({
30241
30492
  clearPreviewRowHeight(state.rowElement);
30242
30493
  rowResizeStateRef.current = null;
30243
30494
  document.body.style.cursor = "";
30495
+ clearHoveredTableCell();
30244
30496
  clearAllTableResizeHover();
30245
30497
  };
30246
30498
  const handleWindowBlur = () => {
@@ -30249,30 +30501,53 @@ var UEditor = import_react53.default.forwardRef(({
30249
30501
  clearPreviewRowHeight(state.rowElement);
30250
30502
  rowResizeStateRef.current = null;
30251
30503
  document.body.style.cursor = "";
30504
+ clearHoveredTableCell();
30252
30505
  clearAllTableResizeHover();
30253
30506
  };
30254
30507
  proseMirror.addEventListener("mousemove", handleEditorMouseMove);
30255
30508
  proseMirror.addEventListener("mouseleave", handleEditorMouseLeave);
30256
30509
  proseMirror.addEventListener("mousedown", handleEditorMouseDown);
30510
+ proseMirror.addEventListener("click", handleSelectionChange);
30511
+ proseMirror.addEventListener("mouseup", handleSelectionChange);
30512
+ proseMirror.addEventListener("keyup", handleSelectionChange);
30513
+ proseMirror.addEventListener("focusin", handleSelectionChange);
30514
+ document.addEventListener("selectionchange", handleSelectionChange);
30515
+ surface?.addEventListener("scroll", handleActiveCellLayoutChange, { passive: true });
30516
+ window.addEventListener("resize", handleActiveCellLayoutChange);
30257
30517
  window.addEventListener("mousemove", handlePointerMove);
30258
30518
  document.addEventListener("pointermove", handlePointerMove);
30259
30519
  window.addEventListener("mouseup", handlePointerUp);
30260
30520
  document.addEventListener("pointerup", handlePointerUp);
30261
30521
  window.addEventListener("blur", handleWindowBlur);
30522
+ editor.on("selectionUpdate", syncActiveTableCellFromSelection);
30523
+ editor.on("focus", syncActiveTableCellFromSelection);
30524
+ syncActiveTableCellFromSelection();
30262
30525
  return () => {
30263
30526
  proseMirror.removeEventListener("mousemove", handleEditorMouseMove);
30264
30527
  proseMirror.removeEventListener("mouseleave", handleEditorMouseLeave);
30265
30528
  proseMirror.removeEventListener("mousedown", handleEditorMouseDown);
30529
+ proseMirror.removeEventListener("click", handleSelectionChange);
30530
+ proseMirror.removeEventListener("mouseup", handleSelectionChange);
30531
+ proseMirror.removeEventListener("keyup", handleSelectionChange);
30532
+ proseMirror.removeEventListener("focusin", handleSelectionChange);
30533
+ document.removeEventListener("selectionchange", handleSelectionChange);
30534
+ surface?.removeEventListener("scroll", handleActiveCellLayoutChange);
30535
+ window.removeEventListener("resize", handleActiveCellLayoutChange);
30266
30536
  window.removeEventListener("mousemove", handlePointerMove);
30267
30537
  document.removeEventListener("pointermove", handlePointerMove);
30268
30538
  window.removeEventListener("mouseup", handlePointerUp);
30269
30539
  document.removeEventListener("pointerup", handlePointerUp);
30270
30540
  window.removeEventListener("blur", handleWindowBlur);
30541
+ editor.off("selectionUpdate", syncActiveTableCellFromSelection);
30542
+ editor.off("focus", syncActiveTableCellFromSelection);
30543
+ window.clearTimeout(selectionSyncTimeoutId);
30271
30544
  document.body.style.cursor = "";
30545
+ clearActiveTableCell();
30546
+ clearHoveredTableCell();
30272
30547
  clearAllTableResizeHover();
30273
30548
  rowResizeStateRef.current = null;
30274
30549
  };
30275
- }, [clearAllTableResizeHover, editor, hideColumnGuide, hideRowGuide, showColumnGuide, showRowGuide]);
30550
+ }, [clearActiveTableCell, clearAllTableResizeHover, clearHoveredTableCell, editor, hideColumnGuide, hideRowGuide, setHoveredTableCell, showColumnGuide, showRowGuide, syncActiveTableCellFromSelection, updateActiveCellHighlight]);
30276
30551
  if (!editor) {
30277
30552
  return /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
30278
30553
  "div",
@@ -30324,6 +30599,14 @@ var UEditor = import_react53.default.forwardRef(({
30324
30599
  className: "pointer-events-none absolute z-20 bg-primary opacity-0 transition-opacity duration-100"
30325
30600
  }
30326
30601
  ),
30602
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
30603
+ "span",
30604
+ {
30605
+ ref: activeTableCellHighlightRef,
30606
+ "aria-hidden": "true",
30607
+ 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"
30608
+ }
30609
+ ),
30327
30610
  editable && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(TableControls, { editor, containerRef: editorContentRef }),
30328
30611
  /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
30329
30612
  import_react54.EditorContent,