@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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "@underverse-ui/underverse",
3
- "version": "1.0.72",
3
+ "version": "1.0.73",
4
4
  "sourceEntry": "src/index.ts",
5
5
  "totalExports": 221,
6
6
  "exports": [
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 }),
@@ -29212,6 +29224,7 @@ function TableControls({ editor, containerRef }) {
29212
29224
  const [layout, setLayout] = import_react52.default.useState(null);
29213
29225
  const [dragPreview, setDragPreview] = import_react52.default.useState(null);
29214
29226
  const [hoverState, setHoverState] = import_react52.default.useState(DEFAULT_HOVER_STATE);
29227
+ const [openMenuKey, setOpenMenuKey] = import_react52.default.useState(null);
29215
29228
  const layoutRef = import_react52.default.useRef(null);
29216
29229
  const dragStateRef = import_react52.default.useRef(null);
29217
29230
  import_react52.default.useEffect(() => {
@@ -29253,11 +29266,19 @@ function TableControls({ editor, containerRef }) {
29253
29266
  const surfaceRect = surface.getBoundingClientRect();
29254
29267
  const relativeX = event.clientX - surfaceRect.left + surface.scrollLeft;
29255
29268
  const relativeY = event.clientY - surfaceRect.top + surface.scrollTop;
29256
- 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;
29257
- 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;
29258
- 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;
29259
- const addColumnVisible = relativeX >= activeLayout.tableLeft + activeLayout.tableWidth && relativeX <= activeLayout.tableLeft + activeLayout.tableWidth + ADD_COLUMN_HOVER_WIDTH && relativeY >= activeLayout.tableTop && relativeY <= activeLayout.tableTop + activeLayout.tableHeight;
29260
- const addRowVisible = relativeY >= activeLayout.tableTop + activeLayout.tableHeight && relativeY <= activeLayout.tableTop + activeLayout.tableHeight + ADD_ROW_HOVER_HEIGHT && relativeX >= activeLayout.tableLeft && relativeX <= activeLayout.tableLeft + activeLayout.tableWidth;
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;
29261
29282
  setHoverState((prev) => {
29262
29283
  if (prev.menuVisible === menuVisible && prev.addColumnVisible === addColumnVisible && prev.addRowVisible === addRowVisible && prev.rowHandleIndex === rowHandleIndex && prev.columnHandleIndex === columnHandleIndex) {
29263
29284
  return prev;
@@ -29295,6 +29316,7 @@ function TableControls({ editor, containerRef }) {
29295
29316
  proseMirror.addEventListener("mouseover", handleMouseOver);
29296
29317
  proseMirror.addEventListener("mouseleave", handleMouseLeave);
29297
29318
  proseMirror.addEventListener("focusin", handleFocusIn);
29319
+ surface.addEventListener("mouseover", handleSurfaceMouseMove);
29298
29320
  surface.addEventListener("mousemove", handleSurfaceMouseMove);
29299
29321
  surface.addEventListener("scroll", refreshCurrentLayout, { passive: true });
29300
29322
  window.addEventListener("resize", refreshCurrentLayout);
@@ -29305,6 +29327,7 @@ function TableControls({ editor, containerRef }) {
29305
29327
  proseMirror.removeEventListener("mouseover", handleMouseOver);
29306
29328
  proseMirror.removeEventListener("mouseleave", handleMouseLeave);
29307
29329
  proseMirror.removeEventListener("focusin", handleFocusIn);
29330
+ surface.removeEventListener("mouseover", handleSurfaceMouseMove);
29308
29331
  surface.removeEventListener("mousemove", handleSurfaceMouseMove);
29309
29332
  surface.removeEventListener("scroll", refreshCurrentLayout);
29310
29333
  window.removeEventListener("resize", refreshCurrentLayout);
@@ -29402,6 +29425,9 @@ function TableControls({ editor, containerRef }) {
29402
29425
  }, [runAtCornerCell, syncFromSelection]);
29403
29426
  const canExpandTable = Boolean(layout);
29404
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}`, []);
29405
29431
  import_react52.default.useEffect(() => {
29406
29432
  const handleMouseMove = (event) => {
29407
29433
  const dragState = dragStateRef.current;
@@ -29614,12 +29640,14 @@ function TableControls({ editor, containerRef }) {
29614
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;
29615
29641
  return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(import_jsx_runtime82.Fragment, { children: [
29616
29642
  layout.rowHandles.map((rowHandle) => {
29617
- const visible = controlsVisible || hoverState.rowHandleIndex === rowHandle.index;
29643
+ const menuKey = getRowMenuKey(rowHandle.index);
29644
+ const visible = controlsVisible || hoverState.rowHandleIndex === rowHandle.index || openMenuKey === menuKey;
29618
29645
  if (!visible) return null;
29619
29646
  return /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29620
29647
  "div",
29621
29648
  {
29622
29649
  className: "absolute z-30",
29650
+ "data-row-handle-index": rowHandle.index,
29623
29651
  style: {
29624
29652
  top: Math.max(8, rowHandle.center - 12),
29625
29653
  left: rowHandleLeft
@@ -29628,6 +29656,10 @@ function TableControls({ editor, containerRef }) {
29628
29656
  DropdownMenu,
29629
29657
  {
29630
29658
  placement: "right",
29659
+ isOpen: openMenuKey === menuKey,
29660
+ onOpenChange: (open) => {
29661
+ setOpenMenuKey((prev) => open ? menuKey : prev === menuKey ? null : prev);
29662
+ },
29631
29663
  items: getRowHandleMenuItems(rowHandle),
29632
29664
  trigger: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29633
29665
  "button",
@@ -29638,6 +29670,7 @@ function TableControls({ editor, containerRef }) {
29638
29670
  onMouseDown: (event) => {
29639
29671
  event.preventDefault();
29640
29672
  event.stopPropagation();
29673
+ setOpenMenuKey(null);
29641
29674
  dragStateRef.current = {
29642
29675
  kind: "row",
29643
29676
  originIndex: rowHandle.index,
@@ -29668,12 +29701,14 @@ function TableControls({ editor, containerRef }) {
29668
29701
  );
29669
29702
  }),
29670
29703
  layout.columnHandles.map((columnHandle) => {
29671
- const visible = controlsVisible || hoverState.columnHandleIndex === columnHandle.index;
29704
+ const menuKey = getColumnMenuKey(columnHandle.index);
29705
+ const visible = controlsVisible || hoverState.columnHandleIndex === columnHandle.index || openMenuKey === menuKey;
29672
29706
  if (!visible) return null;
29673
29707
  return /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29674
29708
  "div",
29675
29709
  {
29676
29710
  className: "absolute z-30",
29711
+ "data-column-handle-index": columnHandle.index,
29677
29712
  style: {
29678
29713
  top: columnHandleTop,
29679
29714
  left: Math.max(8, columnHandle.center - 12)
@@ -29682,6 +29717,10 @@ function TableControls({ editor, containerRef }) {
29682
29717
  DropdownMenu,
29683
29718
  {
29684
29719
  placement: "bottom-start",
29720
+ isOpen: openMenuKey === menuKey,
29721
+ onOpenChange: (open) => {
29722
+ setOpenMenuKey((prev) => open ? menuKey : prev === menuKey ? null : prev);
29723
+ },
29685
29724
  items: getColumnHandleMenuItems(columnHandle),
29686
29725
  trigger: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29687
29726
  "button",
@@ -29692,6 +29731,7 @@ function TableControls({ editor, containerRef }) {
29692
29731
  onMouseDown: (event) => {
29693
29732
  event.preventDefault();
29694
29733
  event.stopPropagation();
29734
+ setOpenMenuKey(null);
29695
29735
  dragStateRef.current = {
29696
29736
  kind: "column",
29697
29737
  originIndex: columnHandle.index,
@@ -29721,10 +29761,11 @@ function TableControls({ editor, containerRef }) {
29721
29761
  `column-handle-${columnHandle.index}`
29722
29762
  );
29723
29763
  }),
29724
- (controlsVisible || hoverState.menuVisible) && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29764
+ (controlsVisible || hoverState.menuVisible || tableMenuOpen) && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29725
29765
  "div",
29726
29766
  {
29727
29767
  className: "absolute z-30",
29768
+ "data-table-control": "table-menu",
29728
29769
  style: {
29729
29770
  top: menuTop,
29730
29771
  left: menuLeft
@@ -29733,6 +29774,10 @@ function TableControls({ editor, containerRef }) {
29733
29774
  DropdownMenu,
29734
29775
  {
29735
29776
  placement: "bottom-start",
29777
+ isOpen: tableMenuOpen,
29778
+ onOpenChange: (open) => {
29779
+ setOpenMenuKey((prev) => open ? "table" : prev === "table" ? null : prev);
29780
+ },
29736
29781
  items: menuItems,
29737
29782
  trigger: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29738
29783
  "button",
@@ -29757,11 +29802,13 @@ function TableControls({ editor, containerRef }) {
29757
29802
  "button",
29758
29803
  {
29759
29804
  type: "button",
29805
+ "data-table-control": "add-column",
29760
29806
  "aria-label": t("tableMenu.quickAddColumnAfter"),
29761
29807
  title: t("tableMenu.quickAddColumnAfter"),
29762
29808
  onMouseDown: (event) => {
29763
29809
  event.preventDefault();
29764
29810
  event.stopPropagation();
29811
+ setOpenMenuKey(null);
29765
29812
  if (!canExpandTable) return;
29766
29813
  dragStateRef.current = { kind: "add-column", previewCols: 1 };
29767
29814
  setDragPreview({ kind: "add-column", previewCols: 1 });
@@ -29786,11 +29833,13 @@ function TableControls({ editor, containerRef }) {
29786
29833
  "button",
29787
29834
  {
29788
29835
  type: "button",
29836
+ "data-table-control": "add-row",
29789
29837
  "aria-label": t("tableMenu.quickAddRowAfter"),
29790
29838
  title: t("tableMenu.quickAddRowAfter"),
29791
29839
  onMouseDown: (event) => {
29792
29840
  event.preventDefault();
29793
29841
  event.stopPropagation();
29842
+ setOpenMenuKey(null);
29794
29843
  if (!canExpandTable) return;
29795
29844
  dragStateRef.current = { kind: "add-row", previewRows: 1 };
29796
29845
  setDragPreview({ kind: "add-row", previewRows: 1 });
@@ -30182,8 +30231,13 @@ var UEditor = import_react53.default.forwardRef(({
30182
30231
  "[&_.selectedCell]:after:pointer-events-none",
30183
30232
  "[&_.column-resize-handle]:pointer-events-auto",
30184
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",
30185
30239
  "[&_.column-resize-handle]:bg-primary/65",
30186
- "[&_.column-resize-handle]:w-2",
30240
+ "[&_.column-resize-handle]:w-2.5",
30187
30241
  "[&_.column-resize-handle]:rounded-full",
30188
30242
  "[&_.column-resize-handle]:opacity-0",
30189
30243
  "[&_.column-resize-handle]:shadow-sm",