@underverse-ui/underverse 1.0.72 → 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.js CHANGED
@@ -20337,46 +20337,52 @@ function DataTableHeader({
20337
20337
  const titleContent = /* @__PURE__ */ jsxs53("div", { className: "flex items-center gap-1", children: [
20338
20338
  /* @__PURE__ */ jsx63("span", { className: cn("font-medium whitespace-nowrap select-text", headerTitleClass), children: col.title }),
20339
20339
  col.sortable && /* @__PURE__ */ jsx63(
20340
- "button",
20340
+ Tooltip,
20341
20341
  {
20342
- className: cn(
20343
- "p-1 rounded-lg transition-all duration-200 hover:bg-accent",
20344
- sort?.key === col.key ? "opacity-100 bg-accent" : "opacity-60 hover:opacity-100"
20345
- ),
20346
- onClick: () => {
20347
- setCurPage(1);
20348
- setSort((current) => {
20349
- if (!current || current.key !== col.key) return { key: col.key, order: "asc" };
20350
- if (current.order === "asc") return { key: col.key, order: "desc" };
20351
- return null;
20352
- });
20353
- },
20354
- "aria-label": "Sort",
20355
- title: `Sort by ${String(col.title)}`,
20356
- children: /* @__PURE__ */ jsxs53("svg", { viewBox: "0 0 20 20", fill: "none", className: cn("inline-block", sortIconClass), children: [
20357
- /* @__PURE__ */ jsx63(
20358
- "path",
20359
- {
20360
- d: "M7 8l3-3 3 3",
20361
- stroke: "currentColor",
20362
- strokeWidth: "1.5",
20363
- strokeLinecap: "round",
20364
- strokeLinejoin: "round",
20365
- opacity: sort?.key === col.key && sort.order === "asc" ? 1 : 0.4
20366
- }
20367
- ),
20368
- /* @__PURE__ */ jsx63(
20369
- "path",
20370
- {
20371
- d: "M7 12l3 3 3-3",
20372
- stroke: "currentColor",
20373
- strokeWidth: "1.5",
20374
- strokeLinecap: "round",
20375
- strokeLinejoin: "round",
20376
- opacity: sort?.key === col.key && sort.order === "desc" ? 1 : 0.4
20377
- }
20378
- )
20379
- ] })
20342
+ placement: "top",
20343
+ content: /* @__PURE__ */ jsx63("span", { className: "text-xs font-medium", children: `Sort by ${String(col.title)}` }),
20344
+ children: /* @__PURE__ */ jsx63(
20345
+ "button",
20346
+ {
20347
+ className: cn(
20348
+ "p-1 rounded-lg transition-all duration-200 hover:bg-accent",
20349
+ sort?.key === col.key ? "opacity-100 bg-accent" : "opacity-60 hover:opacity-100"
20350
+ ),
20351
+ onClick: () => {
20352
+ setCurPage(1);
20353
+ setSort((current) => {
20354
+ if (!current || current.key !== col.key) return { key: col.key, order: "asc" };
20355
+ if (current.order === "asc") return { key: col.key, order: "desc" };
20356
+ return null;
20357
+ });
20358
+ },
20359
+ "aria-label": "Sort",
20360
+ children: /* @__PURE__ */ jsxs53("svg", { viewBox: "0 0 20 20", fill: "none", className: cn("inline-block", sortIconClass), children: [
20361
+ /* @__PURE__ */ jsx63(
20362
+ "path",
20363
+ {
20364
+ d: "M7 8l3-3 3 3",
20365
+ stroke: "currentColor",
20366
+ strokeWidth: "1.5",
20367
+ strokeLinecap: "round",
20368
+ strokeLinejoin: "round",
20369
+ opacity: sort?.key === col.key && sort.order === "asc" ? 1 : 0.4
20370
+ }
20371
+ ),
20372
+ /* @__PURE__ */ jsx63(
20373
+ "path",
20374
+ {
20375
+ d: "M7 12l3 3 3-3",
20376
+ stroke: "currentColor",
20377
+ strokeWidth: "1.5",
20378
+ strokeLinecap: "round",
20379
+ strokeLinejoin: "round",
20380
+ opacity: sort?.key === col.key && sort.order === "desc" ? 1 : 0.4
20381
+ }
20382
+ )
20383
+ ] })
20384
+ }
20385
+ )
20380
20386
  }
20381
20387
  )
20382
20388
  ] });
@@ -20384,18 +20390,24 @@ function DataTableHeader({
20384
20390
  Popover,
20385
20391
  {
20386
20392
  placement: "bottom-start",
20387
- trigger: /* @__PURE__ */ jsx63(
20388
- "button",
20393
+ trigger: /* @__PURE__ */ jsx63("span", { className: "inline-flex", children: /* @__PURE__ */ jsx63(
20394
+ Tooltip,
20389
20395
  {
20390
- className: cn(
20391
- "p-1.5 rounded-lg transition-all duration-200 hover:bg-accent",
20392
- filters[col.key] ? "bg-accent text-primary" : "text-muted-foreground"
20393
- ),
20394
- "aria-label": "Filter",
20395
- title: `Filter by ${String(col.title)}`,
20396
- children: /* @__PURE__ */ jsx63(FilterIcon, { className: "w-4 h-4" })
20396
+ placement: "top",
20397
+ content: /* @__PURE__ */ jsx63("span", { className: "text-xs font-medium", children: `Filter by ${String(col.title)}` }),
20398
+ children: /* @__PURE__ */ jsx63(
20399
+ "button",
20400
+ {
20401
+ className: cn(
20402
+ "p-1.5 rounded-lg transition-all duration-200 hover:bg-accent",
20403
+ filters[col.key] ? "bg-accent text-primary" : "text-muted-foreground"
20404
+ ),
20405
+ "aria-label": "Filter",
20406
+ children: /* @__PURE__ */ jsx63(FilterIcon, { className: "w-4 h-4" })
20407
+ }
20408
+ )
20397
20409
  }
20398
- ),
20410
+ ) }),
20399
20411
  children: /* @__PURE__ */ jsxs53("div", { className: "p-3 w-64 space-y-3", children: [
20400
20412
  /* @__PURE__ */ jsxs53("div", { className: "flex items-center justify-between", children: [
20401
20413
  /* @__PURE__ */ jsx63("div", { className: "text-sm font-medium", children: col.title }),
@@ -29119,6 +29131,7 @@ function TableControls({ editor, containerRef }) {
29119
29131
  const [layout, setLayout] = React74.useState(null);
29120
29132
  const [dragPreview, setDragPreview] = React74.useState(null);
29121
29133
  const [hoverState, setHoverState] = React74.useState(DEFAULT_HOVER_STATE);
29134
+ const [openMenuKey, setOpenMenuKey] = React74.useState(null);
29122
29135
  const layoutRef = React74.useRef(null);
29123
29136
  const dragStateRef = React74.useRef(null);
29124
29137
  React74.useEffect(() => {
@@ -29160,11 +29173,19 @@ function TableControls({ editor, containerRef }) {
29160
29173
  const surfaceRect = surface.getBoundingClientRect();
29161
29174
  const relativeX = event.clientX - surfaceRect.left + surface.scrollLeft;
29162
29175
  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;
29176
+ const targetElement = resolveElement(event.target);
29177
+ const directRowHandle = targetElement?.closest?.("[data-row-handle-index]");
29178
+ const directColumnHandle = targetElement?.closest?.("[data-column-handle-index]");
29179
+ const directTableMenu = targetElement?.closest?.("[data-table-control='table-menu']");
29180
+ const directAddColumn = targetElement?.closest?.("[data-table-control='add-column']");
29181
+ const directAddRow = targetElement?.closest?.("[data-table-control='add-row']");
29182
+ const directRowHandleIndex = directRowHandle instanceof HTMLElement ? Number.parseInt(directRowHandle.dataset.rowHandleIndex ?? "", 10) : Number.NaN;
29183
+ const directColumnHandleIndex = directColumnHandle instanceof HTMLElement ? Number.parseInt(directColumnHandle.dataset.columnHandleIndex ?? "", 10) : Number.NaN;
29184
+ 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;
29185
+ 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;
29186
+ 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;
29187
+ 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;
29188
+ 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;
29168
29189
  setHoverState((prev) => {
29169
29190
  if (prev.menuVisible === menuVisible && prev.addColumnVisible === addColumnVisible && prev.addRowVisible === addRowVisible && prev.rowHandleIndex === rowHandleIndex && prev.columnHandleIndex === columnHandleIndex) {
29170
29191
  return prev;
@@ -29202,6 +29223,7 @@ function TableControls({ editor, containerRef }) {
29202
29223
  proseMirror.addEventListener("mouseover", handleMouseOver);
29203
29224
  proseMirror.addEventListener("mouseleave", handleMouseLeave);
29204
29225
  proseMirror.addEventListener("focusin", handleFocusIn);
29226
+ surface.addEventListener("mouseover", handleSurfaceMouseMove);
29205
29227
  surface.addEventListener("mousemove", handleSurfaceMouseMove);
29206
29228
  surface.addEventListener("scroll", refreshCurrentLayout, { passive: true });
29207
29229
  window.addEventListener("resize", refreshCurrentLayout);
@@ -29212,6 +29234,7 @@ function TableControls({ editor, containerRef }) {
29212
29234
  proseMirror.removeEventListener("mouseover", handleMouseOver);
29213
29235
  proseMirror.removeEventListener("mouseleave", handleMouseLeave);
29214
29236
  proseMirror.removeEventListener("focusin", handleFocusIn);
29237
+ surface.removeEventListener("mouseover", handleSurfaceMouseMove);
29215
29238
  surface.removeEventListener("mousemove", handleSurfaceMouseMove);
29216
29239
  surface.removeEventListener("scroll", refreshCurrentLayout);
29217
29240
  window.removeEventListener("resize", refreshCurrentLayout);
@@ -29309,6 +29332,9 @@ function TableControls({ editor, containerRef }) {
29309
29332
  }, [runAtCornerCell, syncFromSelection]);
29310
29333
  const canExpandTable = Boolean(layout);
29311
29334
  const controlsVisible = dragPreview !== null;
29335
+ const tableMenuOpen = openMenuKey === "table";
29336
+ const getRowMenuKey = React74.useCallback((index) => `row:${index}`, []);
29337
+ const getColumnMenuKey = React74.useCallback((index) => `column:${index}`, []);
29312
29338
  React74.useEffect(() => {
29313
29339
  const handleMouseMove = (event) => {
29314
29340
  const dragState = dragStateRef.current;
@@ -29521,12 +29547,14 @@ function TableControls({ editor, containerRef }) {
29521
29547
  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;
29522
29548
  return /* @__PURE__ */ jsxs71(Fragment27, { children: [
29523
29549
  layout.rowHandles.map((rowHandle) => {
29524
- const visible = controlsVisible || hoverState.rowHandleIndex === rowHandle.index;
29550
+ const menuKey = getRowMenuKey(rowHandle.index);
29551
+ const visible = controlsVisible || hoverState.rowHandleIndex === rowHandle.index || openMenuKey === menuKey;
29525
29552
  if (!visible) return null;
29526
29553
  return /* @__PURE__ */ jsx81(
29527
29554
  "div",
29528
29555
  {
29529
29556
  className: "absolute z-30",
29557
+ "data-row-handle-index": rowHandle.index,
29530
29558
  style: {
29531
29559
  top: Math.max(8, rowHandle.center - 12),
29532
29560
  left: rowHandleLeft
@@ -29535,6 +29563,10 @@ function TableControls({ editor, containerRef }) {
29535
29563
  DropdownMenu,
29536
29564
  {
29537
29565
  placement: "right",
29566
+ isOpen: openMenuKey === menuKey,
29567
+ onOpenChange: (open) => {
29568
+ setOpenMenuKey((prev) => open ? menuKey : prev === menuKey ? null : prev);
29569
+ },
29538
29570
  items: getRowHandleMenuItems(rowHandle),
29539
29571
  trigger: /* @__PURE__ */ jsx81(
29540
29572
  "button",
@@ -29545,6 +29577,7 @@ function TableControls({ editor, containerRef }) {
29545
29577
  onMouseDown: (event) => {
29546
29578
  event.preventDefault();
29547
29579
  event.stopPropagation();
29580
+ setOpenMenuKey(null);
29548
29581
  dragStateRef.current = {
29549
29582
  kind: "row",
29550
29583
  originIndex: rowHandle.index,
@@ -29575,12 +29608,14 @@ function TableControls({ editor, containerRef }) {
29575
29608
  );
29576
29609
  }),
29577
29610
  layout.columnHandles.map((columnHandle) => {
29578
- const visible = controlsVisible || hoverState.columnHandleIndex === columnHandle.index;
29611
+ const menuKey = getColumnMenuKey(columnHandle.index);
29612
+ const visible = controlsVisible || hoverState.columnHandleIndex === columnHandle.index || openMenuKey === menuKey;
29579
29613
  if (!visible) return null;
29580
29614
  return /* @__PURE__ */ jsx81(
29581
29615
  "div",
29582
29616
  {
29583
29617
  className: "absolute z-30",
29618
+ "data-column-handle-index": columnHandle.index,
29584
29619
  style: {
29585
29620
  top: columnHandleTop,
29586
29621
  left: Math.max(8, columnHandle.center - 12)
@@ -29589,6 +29624,10 @@ function TableControls({ editor, containerRef }) {
29589
29624
  DropdownMenu,
29590
29625
  {
29591
29626
  placement: "bottom-start",
29627
+ isOpen: openMenuKey === menuKey,
29628
+ onOpenChange: (open) => {
29629
+ setOpenMenuKey((prev) => open ? menuKey : prev === menuKey ? null : prev);
29630
+ },
29592
29631
  items: getColumnHandleMenuItems(columnHandle),
29593
29632
  trigger: /* @__PURE__ */ jsx81(
29594
29633
  "button",
@@ -29599,6 +29638,7 @@ function TableControls({ editor, containerRef }) {
29599
29638
  onMouseDown: (event) => {
29600
29639
  event.preventDefault();
29601
29640
  event.stopPropagation();
29641
+ setOpenMenuKey(null);
29602
29642
  dragStateRef.current = {
29603
29643
  kind: "column",
29604
29644
  originIndex: columnHandle.index,
@@ -29628,10 +29668,11 @@ function TableControls({ editor, containerRef }) {
29628
29668
  `column-handle-${columnHandle.index}`
29629
29669
  );
29630
29670
  }),
29631
- (controlsVisible || hoverState.menuVisible) && /* @__PURE__ */ jsx81(
29671
+ (controlsVisible || hoverState.menuVisible || tableMenuOpen) && /* @__PURE__ */ jsx81(
29632
29672
  "div",
29633
29673
  {
29634
29674
  className: "absolute z-30",
29675
+ "data-table-control": "table-menu",
29635
29676
  style: {
29636
29677
  top: menuTop,
29637
29678
  left: menuLeft
@@ -29640,6 +29681,10 @@ function TableControls({ editor, containerRef }) {
29640
29681
  DropdownMenu,
29641
29682
  {
29642
29683
  placement: "bottom-start",
29684
+ isOpen: tableMenuOpen,
29685
+ onOpenChange: (open) => {
29686
+ setOpenMenuKey((prev) => open ? "table" : prev === "table" ? null : prev);
29687
+ },
29643
29688
  items: menuItems,
29644
29689
  trigger: /* @__PURE__ */ jsx81(
29645
29690
  "button",
@@ -29664,11 +29709,13 @@ function TableControls({ editor, containerRef }) {
29664
29709
  "button",
29665
29710
  {
29666
29711
  type: "button",
29712
+ "data-table-control": "add-column",
29667
29713
  "aria-label": t("tableMenu.quickAddColumnAfter"),
29668
29714
  title: t("tableMenu.quickAddColumnAfter"),
29669
29715
  onMouseDown: (event) => {
29670
29716
  event.preventDefault();
29671
29717
  event.stopPropagation();
29718
+ setOpenMenuKey(null);
29672
29719
  if (!canExpandTable) return;
29673
29720
  dragStateRef.current = { kind: "add-column", previewCols: 1 };
29674
29721
  setDragPreview({ kind: "add-column", previewCols: 1 });
@@ -29693,11 +29740,13 @@ function TableControls({ editor, containerRef }) {
29693
29740
  "button",
29694
29741
  {
29695
29742
  type: "button",
29743
+ "data-table-control": "add-row",
29696
29744
  "aria-label": t("tableMenu.quickAddRowAfter"),
29697
29745
  title: t("tableMenu.quickAddRowAfter"),
29698
29746
  onMouseDown: (event) => {
29699
29747
  event.preventDefault();
29700
29748
  event.stopPropagation();
29749
+ setOpenMenuKey(null);
29701
29750
  if (!canExpandTable) return;
29702
29751
  dragStateRef.current = { kind: "add-row", previewRows: 1 };
29703
29752
  setDragPreview({ kind: "add-row", previewRows: 1 });
@@ -30089,8 +30138,13 @@ var UEditor = React75.forwardRef(({
30089
30138
  "[&_.selectedCell]:after:pointer-events-none",
30090
30139
  "[&_.column-resize-handle]:pointer-events-auto",
30091
30140
  "[&_.column-resize-handle]:cursor-col-resize",
30141
+ "[&_.column-resize-handle]:absolute",
30142
+ "[&_.column-resize-handle]:top-[-1px]",
30143
+ "[&_.column-resize-handle]:bottom-[-1px]",
30144
+ "[&_.column-resize-handle]:right-[-5px]",
30145
+ "[&_.column-resize-handle]:z-10",
30092
30146
  "[&_.column-resize-handle]:bg-primary/65",
30093
- "[&_.column-resize-handle]:w-2",
30147
+ "[&_.column-resize-handle]:w-2.5",
30094
30148
  "[&_.column-resize-handle]:rounded-full",
30095
30149
  "[&_.column-resize-handle]:opacity-0",
30096
30150
  "[&_.column-resize-handle]:shadow-sm",