@underverse-ui/underverse 1.0.72 → 1.0.74

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 }),
@@ -22632,16 +22644,22 @@ var EmojiList = (0, import_react44.forwardRef)((props, ref) => {
22632
22644
  ] }) }),
22633
22645
  /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "p-3", children: [
22634
22646
  /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "grid grid-cols-8 gap-1", children: props.items.slice(0, 64).map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
22635
- "button",
22647
+ Tooltip,
22636
22648
  {
22637
- type: "button",
22638
- onClick: () => props.command(item),
22639
- className: cn(
22640
- "w-9 h-9 flex items-center justify-center rounded-lg text-xl transition-colors",
22641
- selectedIndex === index ? "bg-primary/10 ring-2 ring-primary/30" : "hover:bg-accent"
22642
- ),
22643
- title: item.name.replace(/_/g, " "),
22644
- children: item.emoji
22649
+ placement: "top",
22650
+ content: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("span", { className: "text-xs font-medium", children: item.name.replace(/_/g, " ") }),
22651
+ children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
22652
+ "button",
22653
+ {
22654
+ type: "button",
22655
+ onClick: () => props.command(item),
22656
+ className: cn(
22657
+ "w-9 h-9 flex items-center justify-center rounded-lg text-xl transition-colors",
22658
+ selectedIndex === index ? "bg-primary/10 ring-2 ring-primary/30" : "hover:bg-accent"
22659
+ ),
22660
+ children: item.emoji
22661
+ }
22662
+ )
22645
22663
  },
22646
22664
  item.name
22647
22665
  )) }),
@@ -23267,7 +23285,7 @@ var EditorColorPalette = ({
23267
23285
  label
23268
23286
  }) => /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "p-2", children: [
23269
23287
  /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider px-2", children: label }),
23270
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "grid grid-cols-4 gap-1.5 mt-2", children: colors.map((c) => /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
23288
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "grid grid-cols-4 gap-1.5 mt-2", children: colors.map((c) => /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(Tooltip, { placement: "top", content: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "text-xs font-medium", children: c.name }), children: /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
23271
23289
  "button",
23272
23290
  {
23273
23291
  type: "button",
@@ -23278,14 +23296,12 @@ var EditorColorPalette = ({
23278
23296
  currentColor === c.color ? "border-primary ring-2 ring-primary/20" : "border-border/50 hover:border-primary/50"
23279
23297
  ),
23280
23298
  style: { backgroundColor: c.color || "transparent" },
23281
- title: c.name,
23282
23299
  children: [
23283
23300
  c.color === "" && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(import_lucide_react42.X, { className: "w-4 h-4 text-muted-foreground" }),
23284
23301
  c.color === "inherit" && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "text-xs font-medium", children: "A" })
23285
23302
  ]
23286
- },
23287
- c.name
23288
- )) })
23303
+ }
23304
+ ) }, c.name)) })
23289
23305
  ] });
23290
23306
 
23291
23307
  // src/components/UEditor/image-commands.ts
@@ -23480,17 +23496,17 @@ var ImageInput = ({ onSubmit, onCancel }) => {
23480
23496
  };
23481
23497
 
23482
23498
  // src/components/UEditor/emoji-picker.tsx
23483
- var import_react49 = require("react");
23484
23499
  var import_lucide_react44 = require("lucide-react");
23500
+ var import_react49 = require("react");
23485
23501
  var import_jsx_runtime78 = require("react/jsx-runtime");
23486
23502
  var CATEGORY_ICONS2 = {
23487
- "smileys_people": import_lucide_react44.Smile,
23488
- "animals_nature": import_lucide_react44.Leaf,
23489
- "food_drink": import_lucide_react44.Utensils,
23490
- "activity": import_lucide_react44.Dumbbell,
23491
- "objects": import_lucide_react44.Lightbulb,
23492
- "symbols": import_lucide_react44.Hash,
23493
- "flags": import_lucide_react44.Flag
23503
+ smileys_people: import_lucide_react44.Smile,
23504
+ animals_nature: import_lucide_react44.Leaf,
23505
+ food_drink: import_lucide_react44.Utensils,
23506
+ activity: import_lucide_react44.Dumbbell,
23507
+ objects: import_lucide_react44.Lightbulb,
23508
+ symbols: import_lucide_react44.Hash,
23509
+ flags: import_lucide_react44.Flag
23494
23510
  };
23495
23511
  var EmojiPicker2 = ({ onSelect, onClose }) => {
23496
23512
  const t = useSmartTranslations("UEditor");
@@ -23504,9 +23520,7 @@ var EmojiPicker2 = ({ onSelect, onClose }) => {
23504
23520
  const query = search.toLowerCase();
23505
23521
  return EMOJI_LIST.map((category) => ({
23506
23522
  ...category,
23507
- emojis: category.emojis.filter(
23508
- (emoji) => emoji.name.toLowerCase().includes(query) || emoji.emoji.includes(search)
23509
- )
23523
+ emojis: category.emojis.filter((emoji) => emoji.name.toLowerCase().includes(query) || emoji.emoji.includes(search))
23510
23524
  })).filter((category) => category.emojis.length > 0);
23511
23525
  }, [search]);
23512
23526
  const handleEmojiClick = (emoji) => {
@@ -23574,26 +23588,40 @@ var EmojiPicker2 = ({ onSelect, onClose }) => {
23574
23588
  )
23575
23589
  }
23576
23590
  ),
23577
- search && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
23578
- "button",
23579
- {
23580
- onClick: () => setSearch(""),
23581
- className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
23582
- children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_lucide_react44.X, { className: "w-4 h-4" })
23583
- }
23584
- )
23591
+ search && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("button", { onClick: () => setSearch(""), className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_lucide_react44.X, { className: "w-4 h-4" }) })
23585
23592
  ] }) }),
23586
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
23587
- "div",
23588
- {
23589
- ref: scrollContainerRef,
23590
- className: "overflow-y-auto px-3 py-2 shrink",
23591
- style: { height: "20rem" },
23592
- children: search ? (
23593
- // Search Results
23594
- filteredCategories.length > 0 ? filteredCategories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "mb-4", children: [
23595
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-2 sticky top-0 bg-card py-1", children: category.name }),
23596
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "grid grid-cols-9 gap-1", children: category.emojis.map((emoji) => /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
23593
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { ref: scrollContainerRef, className: "overflow-y-auto px-3 py-2 shrink", style: { height: "20rem" }, children: search ? (
23594
+ // Search Results
23595
+ filteredCategories.length > 0 ? filteredCategories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "mb-4", children: [
23596
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-2 sticky top-0 bg-card py-1", children: category.name }),
23597
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "grid grid-cols-9 gap-1", children: category.emojis.map((emoji) => /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(Tooltip, { placement: "top", content: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "text-xs font-medium", children: emoji.name.replace(/_/g, " ") }), children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
23598
+ "button",
23599
+ {
23600
+ onClick: () => handleEmojiClick(emoji.emoji),
23601
+ className: cn(
23602
+ "w-9 h-9 flex items-center justify-center rounded-lg",
23603
+ "text-2xl hover:bg-accent transition-colors",
23604
+ "focus:outline-none focus:ring-2 focus:ring-primary/20"
23605
+ ),
23606
+ children: emoji.emoji
23607
+ }
23608
+ ) }, emoji.name)) })
23609
+ ] }, category.id)) : /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "flex flex-col items-center justify-center h-full text-center", children: [
23610
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "text-4xl mb-2", children: "\u{1F50D}" }),
23611
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "text-sm font-medium text-muted-foreground", children: t("emojiPicker.noResults") }),
23612
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "text-xs text-muted-foreground mt-1", children: t("emojiPicker.tryDifferentSearch") })
23613
+ ] })
23614
+ ) : (
23615
+ // All Categories - Messenger Style
23616
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "space-y-4", children: EMOJI_LIST.map((category) => /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(
23617
+ "div",
23618
+ {
23619
+ ref: (el) => {
23620
+ categoryRefs.current[category.id] = el;
23621
+ },
23622
+ children: [
23623
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-2 sticky top-0 bg-card py-1 z-10", children: category.name }),
23624
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "grid grid-cols-9 gap-1", children: category.emojis.map((emoji) => /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(Tooltip, { placement: "top", content: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "text-xs font-medium", children: emoji.name.replace(/_/g, " ") }), children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
23597
23625
  "button",
23598
23626
  {
23599
23627
  onClick: () => handleEmojiClick(emoji.emoji),
@@ -23602,47 +23630,14 @@ var EmojiPicker2 = ({ onSelect, onClose }) => {
23602
23630
  "text-2xl hover:bg-accent transition-colors",
23603
23631
  "focus:outline-none focus:ring-2 focus:ring-primary/20"
23604
23632
  ),
23605
- title: emoji.name.replace(/_/g, " "),
23606
23633
  children: emoji.emoji
23607
- },
23608
- emoji.name
23609
- )) })
23610
- ] }, category.id)) : /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "flex flex-col items-center justify-center h-full text-center", children: [
23611
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "text-4xl mb-2", children: "\u{1F50D}" }),
23612
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "text-sm font-medium text-muted-foreground", children: t("emojiPicker.noResults") }),
23613
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "text-xs text-muted-foreground mt-1", children: t("emojiPicker.tryDifferentSearch") })
23614
- ] })
23615
- ) : (
23616
- // All Categories - Messenger Style
23617
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "space-y-4", children: EMOJI_LIST.map((category) => /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(
23618
- "div",
23619
- {
23620
- ref: (el) => {
23621
- categoryRefs.current[category.id] = el;
23622
- },
23623
- children: [
23624
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-2 sticky top-0 bg-card py-1 z-10", children: category.name }),
23625
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "grid grid-cols-9 gap-1", children: category.emojis.map((emoji) => /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
23626
- "button",
23627
- {
23628
- onClick: () => handleEmojiClick(emoji.emoji),
23629
- className: cn(
23630
- "w-9 h-9 flex items-center justify-center rounded-lg",
23631
- "text-2xl hover:bg-accent transition-colors",
23632
- "focus:outline-none focus:ring-2 focus:ring-primary/20"
23633
- ),
23634
- title: emoji.name.replace(/_/g, " "),
23635
- children: emoji.emoji
23636
- },
23637
- emoji.name
23638
- )) })
23639
- ]
23640
- },
23641
- category.id
23642
- )) })
23643
- )
23644
- }
23645
- ),
23634
+ }
23635
+ ) }, emoji.name)) })
23636
+ ]
23637
+ },
23638
+ category.id
23639
+ )) })
23640
+ ) }),
23646
23641
  !search && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "flex items-center justify-around px-2 py-2 border-t bg-muted/30 shrink-0", children: EMOJI_LIST.map((category) => {
23647
23642
  const IconComponent = CATEGORY_ICONS2[category.id] || import_lucide_react44.Smile;
23648
23643
  return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
@@ -23653,8 +23648,7 @@ var EmojiPicker2 = ({ onSelect, onClose }) => {
23653
23648
  "p-2 rounded-lg transition-colors",
23654
23649
  activeCategory === category.id ? "text-primary bg-primary/10" : "text-muted-foreground hover:text-foreground hover:bg-accent"
23655
23650
  ),
23656
- title: category.name,
23657
- children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(IconComponent, { className: "w-5 h-5" })
23651
+ children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(Tooltip, { placement: "top", content: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "text-xs font-medium", children: category.name }), children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "inline-flex", children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(IconComponent, { className: "w-5 h-5" }) }) })
23658
23652
  },
23659
23653
  category.id
23660
23654
  );
@@ -29130,12 +29124,23 @@ function buildLayout(editor, surface, cell) {
29130
29124
  }
29131
29125
  const surfaceRect = surface.getBoundingClientRect();
29132
29126
  const tableRect = table.getBoundingClientRect();
29127
+ const wrapperElement = table.closest(".tableWrapper");
29128
+ const wrapper = wrapperElement instanceof HTMLElement ? wrapperElement : null;
29129
+ const wrapperRect = wrapper?.getBoundingClientRect() ?? tableRect;
29133
29130
  const tableLeft = tableRect.left - surfaceRect.left + surface.scrollLeft;
29134
29131
  const tableTop = tableRect.top - surfaceRect.top + surface.scrollTop;
29135
29132
  const avgRowHeight = metricOrFallback(tableRect.height / rows.length, FALLBACK_TABLE_ROW_HEIGHT);
29136
29133
  const avgColumnWidth = metricOrFallback(tableRect.width / referenceCells.length, FALLBACK_TABLE_COLUMN_WIDTH);
29137
29134
  const tableWidth = metricOrFallback(tableRect.width, avgColumnWidth * referenceCells.length);
29138
29135
  const tableHeight = metricOrFallback(tableRect.height, avgRowHeight * rows.length);
29136
+ const wrapperLeft = wrapperRect.left - surfaceRect.left + surface.scrollLeft;
29137
+ const wrapperTop = wrapperRect.top - surfaceRect.top + surface.scrollTop;
29138
+ const wrapperWidth = metricOrFallback(wrapperRect.width, tableWidth);
29139
+ const wrapperHeight = metricOrFallback(wrapperRect.height, tableHeight);
29140
+ const viewportWidth = metricOrFallback(wrapper?.clientWidth ?? wrapperRect.width, tableWidth);
29141
+ const viewportHeight = metricOrFallback(wrapper?.clientHeight ?? wrapperRect.height, tableHeight);
29142
+ const verticalScrollbarWidth = Math.max(0, Math.round(wrapperWidth - viewportWidth));
29143
+ const horizontalScrollbarHeight = Math.max(0, Math.round(wrapperHeight - viewportHeight));
29139
29144
  const rowHandles = rows.map((tableRow, index) => {
29140
29145
  const rowRect = tableRow.getBoundingClientRect();
29141
29146
  const anchorCell = tableRow.cells.item(0) ?? cornerCell;
@@ -29170,6 +29175,14 @@ function buildLayout(editor, surface, cell) {
29170
29175
  tableTop,
29171
29176
  tableWidth,
29172
29177
  tableHeight,
29178
+ wrapperLeft,
29179
+ wrapperTop,
29180
+ wrapperWidth,
29181
+ wrapperHeight,
29182
+ viewportWidth,
29183
+ viewportHeight,
29184
+ horizontalScrollbarHeight,
29185
+ verticalScrollbarWidth,
29173
29186
  avgRowHeight,
29174
29187
  avgColumnWidth,
29175
29188
  rowHandles,
@@ -29212,6 +29225,7 @@ function TableControls({ editor, containerRef }) {
29212
29225
  const [layout, setLayout] = import_react52.default.useState(null);
29213
29226
  const [dragPreview, setDragPreview] = import_react52.default.useState(null);
29214
29227
  const [hoverState, setHoverState] = import_react52.default.useState(DEFAULT_HOVER_STATE);
29228
+ const [openMenuKey, setOpenMenuKey] = import_react52.default.useState(null);
29215
29229
  const layoutRef = import_react52.default.useRef(null);
29216
29230
  const dragStateRef = import_react52.default.useRef(null);
29217
29231
  import_react52.default.useEffect(() => {
@@ -29253,11 +29267,21 @@ function TableControls({ editor, containerRef }) {
29253
29267
  const surfaceRect = surface.getBoundingClientRect();
29254
29268
  const relativeX = event.clientX - surfaceRect.left + surface.scrollLeft;
29255
29269
  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;
29270
+ const targetElement = resolveElement(event.target);
29271
+ const directRowHandle = targetElement?.closest?.("[data-row-handle-index]");
29272
+ const directColumnHandle = targetElement?.closest?.("[data-column-handle-index]");
29273
+ const directTableMenu = targetElement?.closest?.("[data-table-control='table-menu']");
29274
+ const directAddColumn = targetElement?.closest?.("[data-table-control='add-column']");
29275
+ const directAddRow = targetElement?.closest?.("[data-table-control='add-row']");
29276
+ const directRowHandleIndex = directRowHandle instanceof HTMLElement ? Number.parseInt(directRowHandle.dataset.rowHandleIndex ?? "", 10) : Number.NaN;
29277
+ const directColumnHandleIndex = directColumnHandle instanceof HTMLElement ? Number.parseInt(directColumnHandle.dataset.columnHandleIndex ?? "", 10) : Number.NaN;
29278
+ const visibleTableWidth2 = Math.min(activeLayout.tableWidth, activeLayout.viewportWidth);
29279
+ const visibleTableHeight2 = Math.min(activeLayout.tableHeight, activeLayout.viewportHeight);
29280
+ 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;
29281
+ 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;
29282
+ 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;
29283
+ const addColumnVisible = Boolean(directAddColumn) || relativeX >= activeLayout.wrapperLeft + visibleTableWidth2 && relativeX <= activeLayout.wrapperLeft + visibleTableWidth2 + ADD_COLUMN_HOVER_WIDTH && relativeY >= activeLayout.wrapperTop && relativeY <= activeLayout.wrapperTop + visibleTableHeight2;
29284
+ const addRowVisible = Boolean(directAddRow) || relativeY >= activeLayout.wrapperTop + activeLayout.wrapperHeight && relativeY <= activeLayout.wrapperTop + activeLayout.wrapperHeight + ADD_ROW_HOVER_HEIGHT && relativeX >= activeLayout.wrapperLeft && relativeX <= activeLayout.wrapperLeft + visibleTableWidth2;
29261
29285
  setHoverState((prev) => {
29262
29286
  if (prev.menuVisible === menuVisible && prev.addColumnVisible === addColumnVisible && prev.addRowVisible === addRowVisible && prev.rowHandleIndex === rowHandleIndex && prev.columnHandleIndex === columnHandleIndex) {
29263
29287
  return prev;
@@ -29295,6 +29319,7 @@ function TableControls({ editor, containerRef }) {
29295
29319
  proseMirror.addEventListener("mouseover", handleMouseOver);
29296
29320
  proseMirror.addEventListener("mouseleave", handleMouseLeave);
29297
29321
  proseMirror.addEventListener("focusin", handleFocusIn);
29322
+ surface.addEventListener("mouseover", handleSurfaceMouseMove);
29298
29323
  surface.addEventListener("mousemove", handleSurfaceMouseMove);
29299
29324
  surface.addEventListener("scroll", refreshCurrentLayout, { passive: true });
29300
29325
  window.addEventListener("resize", refreshCurrentLayout);
@@ -29305,6 +29330,7 @@ function TableControls({ editor, containerRef }) {
29305
29330
  proseMirror.removeEventListener("mouseover", handleMouseOver);
29306
29331
  proseMirror.removeEventListener("mouseleave", handleMouseLeave);
29307
29332
  proseMirror.removeEventListener("focusin", handleFocusIn);
29333
+ surface.removeEventListener("mouseover", handleSurfaceMouseMove);
29308
29334
  surface.removeEventListener("mousemove", handleSurfaceMouseMove);
29309
29335
  surface.removeEventListener("scroll", refreshCurrentLayout);
29310
29336
  window.removeEventListener("resize", refreshCurrentLayout);
@@ -29402,6 +29428,9 @@ function TableControls({ editor, containerRef }) {
29402
29428
  }, [runAtCornerCell, syncFromSelection]);
29403
29429
  const canExpandTable = Boolean(layout);
29404
29430
  const controlsVisible = dragPreview !== null;
29431
+ const tableMenuOpen = openMenuKey === "table";
29432
+ const getRowMenuKey = import_react52.default.useCallback((index) => `row:${index}`, []);
29433
+ const getColumnMenuKey = import_react52.default.useCallback((index) => `column:${index}`, []);
29405
29434
  import_react52.default.useEffect(() => {
29406
29435
  const handleMouseMove = (event) => {
29407
29436
  const dragState = dragStateRef.current;
@@ -29605,62 +29634,77 @@ function TableControls({ editor, containerRef }) {
29605
29634
  const menuLeft = Math.max(8, layout.tableLeft);
29606
29635
  const rowHandleLeft = Math.max(8, layout.tableLeft - 66);
29607
29636
  const columnHandleTop = Math.max(8, layout.tableTop - 14);
29608
- const columnRailTop = layout.tableTop;
29609
- const columnRailLeft = layout.tableLeft + layout.tableWidth + 8;
29610
- const rowRailTop = layout.tableTop + layout.tableHeight + 8;
29611
- const rowRailLeft = layout.tableLeft;
29637
+ const visibleTableWidth = Math.min(layout.tableWidth, layout.viewportWidth);
29638
+ const visibleTableHeight = Math.min(layout.tableHeight, layout.viewportHeight);
29639
+ const columnRailTop = layout.wrapperTop;
29640
+ const columnRailLeft = layout.wrapperLeft + visibleTableWidth + 8;
29641
+ const rowRailTop = layout.wrapperTop + layout.wrapperHeight + 8;
29642
+ const rowRailLeft = layout.wrapperLeft;
29612
29643
  const expandPreviewWidth = dragPreview?.kind === "add-column" ? layout.tableWidth + dragPreview.previewCols * layout.avgColumnWidth : layout.tableWidth;
29613
29644
  const expandPreviewHeight = dragPreview?.kind === "add-row" ? layout.tableHeight + dragPreview.previewRows * layout.avgRowHeight : layout.tableHeight;
29614
29645
  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
29646
  return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(import_jsx_runtime82.Fragment, { children: [
29616
29647
  layout.rowHandles.map((rowHandle) => {
29617
- const visible = controlsVisible || hoverState.rowHandleIndex === rowHandle.index;
29648
+ const menuKey = getRowMenuKey(rowHandle.index);
29649
+ const visible = controlsVisible || hoverState.rowHandleIndex === rowHandle.index || openMenuKey === menuKey;
29618
29650
  if (!visible) return null;
29619
29651
  return /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29620
29652
  "div",
29621
29653
  {
29622
29654
  className: "absolute z-30",
29655
+ "data-row-handle-index": rowHandle.index,
29623
29656
  style: {
29624
29657
  top: Math.max(8, rowHandle.center - 12),
29625
29658
  left: rowHandleLeft
29626
29659
  },
29627
29660
  children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29628
- DropdownMenu,
29661
+ Tooltip,
29629
29662
  {
29630
29663
  placement: "right",
29631
- items: getRowHandleMenuItems(rowHandle),
29632
- trigger: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29633
- "button",
29664
+ content: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "text-xs font-medium", children: `${t("tableMenu.dragRow")} ${rowHandle.index + 1}` }),
29665
+ children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "inline-flex", children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29666
+ DropdownMenu,
29634
29667
  {
29635
- type: "button",
29636
- "aria-label": `${t("tableMenu.dragRow")} ${rowHandle.index + 1}`,
29637
- title: `${t("tableMenu.dragRow")} ${rowHandle.index + 1}`,
29638
- onMouseDown: (event) => {
29639
- event.preventDefault();
29640
- event.stopPropagation();
29641
- dragStateRef.current = {
29642
- kind: "row",
29643
- originIndex: rowHandle.index,
29644
- targetIndex: rowHandle.index,
29645
- anchorPos: rowHandle.cellPos
29646
- };
29647
- setDragPreview({
29648
- kind: "row",
29649
- originIndex: rowHandle.index,
29650
- targetIndex: rowHandle.index,
29651
- targetStart: rowHandle.start,
29652
- targetSize: rowHandle.size
29653
- });
29654
- document.body.style.cursor = "grabbing";
29668
+ placement: "right",
29669
+ isOpen: openMenuKey === menuKey,
29670
+ onOpenChange: (open) => {
29671
+ setOpenMenuKey((prev) => open ? menuKey : prev === menuKey ? null : prev);
29655
29672
  },
29656
- className: cn(
29657
- "inline-flex h-6 w-6 items-center justify-center rounded-full",
29658
- "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
29659
- "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
29660
- ),
29661
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_lucide_react47.GripVertical, { className: "h-3.5 w-3.5" })
29673
+ items: getRowHandleMenuItems(rowHandle),
29674
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29675
+ "button",
29676
+ {
29677
+ type: "button",
29678
+ "aria-label": `${t("tableMenu.dragRow")} ${rowHandle.index + 1}`,
29679
+ onMouseDown: (event) => {
29680
+ event.preventDefault();
29681
+ event.stopPropagation();
29682
+ setOpenMenuKey(null);
29683
+ dragStateRef.current = {
29684
+ kind: "row",
29685
+ originIndex: rowHandle.index,
29686
+ targetIndex: rowHandle.index,
29687
+ anchorPos: rowHandle.cellPos
29688
+ };
29689
+ setDragPreview({
29690
+ kind: "row",
29691
+ originIndex: rowHandle.index,
29692
+ targetIndex: rowHandle.index,
29693
+ targetStart: rowHandle.start,
29694
+ targetSize: rowHandle.size
29695
+ });
29696
+ document.body.style.cursor = "grabbing";
29697
+ },
29698
+ className: cn(
29699
+ "inline-flex h-6 w-6 items-center justify-center rounded-full",
29700
+ "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
29701
+ "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
29702
+ ),
29703
+ children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_lucide_react47.GripVertical, { className: "h-3.5 w-3.5" })
29704
+ }
29705
+ )
29662
29706
  }
29663
- )
29707
+ ) })
29664
29708
  }
29665
29709
  )
29666
29710
  },
@@ -29668,147 +29712,187 @@ function TableControls({ editor, containerRef }) {
29668
29712
  );
29669
29713
  }),
29670
29714
  layout.columnHandles.map((columnHandle) => {
29671
- const visible = controlsVisible || hoverState.columnHandleIndex === columnHandle.index;
29715
+ const menuKey = getColumnMenuKey(columnHandle.index);
29716
+ const visible = controlsVisible || hoverState.columnHandleIndex === columnHandle.index || openMenuKey === menuKey;
29672
29717
  if (!visible) return null;
29673
29718
  return /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29674
29719
  "div",
29675
29720
  {
29676
29721
  className: "absolute z-30",
29722
+ "data-column-handle-index": columnHandle.index,
29677
29723
  style: {
29678
29724
  top: columnHandleTop,
29679
29725
  left: Math.max(8, columnHandle.center - 12)
29680
29726
  },
29681
29727
  children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29682
- DropdownMenu,
29728
+ Tooltip,
29683
29729
  {
29684
- placement: "bottom-start",
29685
- items: getColumnHandleMenuItems(columnHandle),
29686
- trigger: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29687
- "button",
29730
+ placement: "top",
29731
+ content: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "text-xs font-medium", children: `${t("tableMenu.dragColumn")} ${columnHandle.index + 1}` }),
29732
+ children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "inline-flex", children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29733
+ DropdownMenu,
29688
29734
  {
29689
- type: "button",
29690
- "aria-label": `${t("tableMenu.dragColumn")} ${columnHandle.index + 1}`,
29691
- title: `${t("tableMenu.dragColumn")} ${columnHandle.index + 1}`,
29692
- onMouseDown: (event) => {
29693
- event.preventDefault();
29694
- event.stopPropagation();
29695
- dragStateRef.current = {
29696
- kind: "column",
29697
- originIndex: columnHandle.index,
29698
- targetIndex: columnHandle.index,
29699
- anchorPos: columnHandle.cellPos
29700
- };
29701
- setDragPreview({
29702
- kind: "column",
29703
- originIndex: columnHandle.index,
29704
- targetIndex: columnHandle.index,
29705
- targetStart: columnHandle.start,
29706
- targetSize: columnHandle.size
29707
- });
29708
- document.body.style.cursor = "grabbing";
29735
+ placement: "bottom-start",
29736
+ isOpen: openMenuKey === menuKey,
29737
+ onOpenChange: (open) => {
29738
+ setOpenMenuKey((prev) => open ? menuKey : prev === menuKey ? null : prev);
29709
29739
  },
29710
- className: cn(
29711
- "inline-flex h-6 w-6 items-center justify-center rounded-full",
29712
- "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
29713
- "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
29714
- ),
29715
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_lucide_react47.GripHorizontal, { className: "h-3.5 w-3.5" })
29740
+ items: getColumnHandleMenuItems(columnHandle),
29741
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29742
+ "button",
29743
+ {
29744
+ type: "button",
29745
+ "aria-label": `${t("tableMenu.dragColumn")} ${columnHandle.index + 1}`,
29746
+ onMouseDown: (event) => {
29747
+ event.preventDefault();
29748
+ event.stopPropagation();
29749
+ setOpenMenuKey(null);
29750
+ dragStateRef.current = {
29751
+ kind: "column",
29752
+ originIndex: columnHandle.index,
29753
+ targetIndex: columnHandle.index,
29754
+ anchorPos: columnHandle.cellPos
29755
+ };
29756
+ setDragPreview({
29757
+ kind: "column",
29758
+ originIndex: columnHandle.index,
29759
+ targetIndex: columnHandle.index,
29760
+ targetStart: columnHandle.start,
29761
+ targetSize: columnHandle.size
29762
+ });
29763
+ document.body.style.cursor = "grabbing";
29764
+ },
29765
+ className: cn(
29766
+ "inline-flex h-6 w-6 items-center justify-center rounded-full",
29767
+ "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
29768
+ "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
29769
+ ),
29770
+ children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_lucide_react47.GripHorizontal, { className: "h-3.5 w-3.5" })
29771
+ }
29772
+ )
29716
29773
  }
29717
- )
29774
+ ) })
29718
29775
  }
29719
29776
  )
29720
29777
  },
29721
29778
  `column-handle-${columnHandle.index}`
29722
29779
  );
29723
29780
  }),
29724
- (controlsVisible || hoverState.menuVisible) && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29781
+ (controlsVisible || hoverState.menuVisible || tableMenuOpen) && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29725
29782
  "div",
29726
29783
  {
29727
29784
  className: "absolute z-30",
29785
+ "data-table-control": "table-menu",
29728
29786
  style: {
29729
29787
  top: menuTop,
29730
29788
  left: menuLeft
29731
29789
  },
29732
29790
  children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29733
- DropdownMenu,
29791
+ Tooltip,
29734
29792
  {
29735
- placement: "bottom-start",
29736
- items: menuItems,
29737
- trigger: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29738
- "button",
29793
+ placement: "top",
29794
+ content: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "text-xs font-medium", children: t("tableMenu.openControls") }),
29795
+ children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "inline-flex", children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29796
+ DropdownMenu,
29739
29797
  {
29740
- type: "button",
29741
- "aria-label": t("tableMenu.openControls"),
29742
- title: t("tableMenu.openControls"),
29743
- onMouseDown: (event) => event.preventDefault(),
29744
- className: cn(
29745
- "pointer-events-auto inline-flex h-7 w-7 items-center justify-center rounded-full",
29746
- "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
29747
- "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
29748
- ),
29749
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_lucide_react47.MoreHorizontal, { className: "h-4 w-4" })
29798
+ placement: "bottom-start",
29799
+ isOpen: tableMenuOpen,
29800
+ onOpenChange: (open) => {
29801
+ setOpenMenuKey((prev) => open ? "table" : prev === "table" ? null : prev);
29802
+ },
29803
+ items: menuItems,
29804
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29805
+ "button",
29806
+ {
29807
+ type: "button",
29808
+ "aria-label": t("tableMenu.openControls"),
29809
+ onMouseDown: (event) => event.preventDefault(),
29810
+ className: cn(
29811
+ "pointer-events-auto inline-flex h-7 w-7 items-center justify-center rounded-full",
29812
+ "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
29813
+ "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
29814
+ ),
29815
+ children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_lucide_react47.MoreHorizontal, { className: "h-4 w-4" })
29816
+ }
29817
+ )
29750
29818
  }
29751
- )
29819
+ ) })
29752
29820
  }
29753
29821
  )
29754
29822
  }
29755
29823
  ),
29756
29824
  (controlsVisible || hoverState.addColumnVisible) && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29757
- "button",
29825
+ Tooltip,
29758
29826
  {
29759
- type: "button",
29760
- "aria-label": t("tableMenu.quickAddColumnAfter"),
29761
- title: t("tableMenu.quickAddColumnAfter"),
29762
- onMouseDown: (event) => {
29763
- event.preventDefault();
29764
- event.stopPropagation();
29765
- if (!canExpandTable) return;
29766
- dragStateRef.current = { kind: "add-column", previewCols: 1 };
29767
- setDragPreview({ kind: "add-column", previewCols: 1 });
29768
- document.body.style.cursor = "ew-resize";
29769
- },
29770
- disabled: !canExpandTable,
29771
- className: cn(
29772
- "absolute z-30 inline-flex items-center justify-center rounded-md",
29773
- "border border-border/70 bg-muted/40 text-muted-foreground shadow-sm backdrop-blur",
29774
- "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground disabled:opacity-50 disabled:cursor-not-allowed"
29775
- ),
29776
- style: {
29777
- top: columnRailTop,
29778
- left: columnRailLeft,
29779
- width: 18,
29780
- height: layout.tableHeight
29781
- },
29782
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "text-sm font-medium leading-none", children: "+" })
29827
+ placement: "right",
29828
+ content: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "text-xs font-medium", children: t("tableMenu.quickAddColumnAfter") }),
29829
+ children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29830
+ "button",
29831
+ {
29832
+ type: "button",
29833
+ "data-table-control": "add-column",
29834
+ "aria-label": t("tableMenu.quickAddColumnAfter"),
29835
+ onMouseDown: (event) => {
29836
+ event.preventDefault();
29837
+ event.stopPropagation();
29838
+ setOpenMenuKey(null);
29839
+ if (!canExpandTable) return;
29840
+ dragStateRef.current = { kind: "add-column", previewCols: 1 };
29841
+ setDragPreview({ kind: "add-column", previewCols: 1 });
29842
+ document.body.style.cursor = "ew-resize";
29843
+ },
29844
+ disabled: !canExpandTable,
29845
+ className: cn(
29846
+ "absolute z-30 inline-flex items-center justify-center rounded-md",
29847
+ "border border-border/70 bg-muted/40 text-muted-foreground shadow-sm backdrop-blur",
29848
+ "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground disabled:opacity-50 disabled:cursor-not-allowed"
29849
+ ),
29850
+ style: {
29851
+ top: columnRailTop,
29852
+ left: columnRailLeft,
29853
+ width: 18,
29854
+ height: visibleTableHeight
29855
+ },
29856
+ children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "text-sm font-medium leading-none", children: "+" })
29857
+ }
29858
+ )
29783
29859
  }
29784
29860
  ),
29785
29861
  (controlsVisible || hoverState.addRowVisible) && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29786
- "button",
29862
+ Tooltip,
29787
29863
  {
29788
- type: "button",
29789
- "aria-label": t("tableMenu.quickAddRowAfter"),
29790
- title: t("tableMenu.quickAddRowAfter"),
29791
- onMouseDown: (event) => {
29792
- event.preventDefault();
29793
- event.stopPropagation();
29794
- if (!canExpandTable) return;
29795
- dragStateRef.current = { kind: "add-row", previewRows: 1 };
29796
- setDragPreview({ kind: "add-row", previewRows: 1 });
29797
- document.body.style.cursor = "ns-resize";
29798
- },
29799
- disabled: !canExpandTable,
29800
- className: cn(
29801
- "absolute z-30 inline-flex items-center justify-center rounded-md",
29802
- "border border-border/70 bg-muted/40 text-muted-foreground shadow-sm backdrop-blur",
29803
- "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground disabled:opacity-50 disabled:cursor-not-allowed"
29804
- ),
29805
- style: {
29806
- top: rowRailTop,
29807
- left: rowRailLeft,
29808
- width: layout.tableWidth,
29809
- height: 16
29810
- },
29811
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "text-sm font-medium leading-none", children: "+" })
29864
+ placement: "bottom",
29865
+ content: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "text-xs font-medium", children: t("tableMenu.quickAddRowAfter") }),
29866
+ children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
29867
+ "button",
29868
+ {
29869
+ type: "button",
29870
+ "data-table-control": "add-row",
29871
+ "aria-label": t("tableMenu.quickAddRowAfter"),
29872
+ onMouseDown: (event) => {
29873
+ event.preventDefault();
29874
+ event.stopPropagation();
29875
+ setOpenMenuKey(null);
29876
+ if (!canExpandTable) return;
29877
+ dragStateRef.current = { kind: "add-row", previewRows: 1 };
29878
+ setDragPreview({ kind: "add-row", previewRows: 1 });
29879
+ document.body.style.cursor = "ns-resize";
29880
+ },
29881
+ disabled: !canExpandTable,
29882
+ className: cn(
29883
+ "absolute z-30 inline-flex items-center justify-center rounded-md",
29884
+ "border border-border/70 bg-muted/40 text-muted-foreground shadow-sm backdrop-blur",
29885
+ "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground disabled:opacity-50 disabled:cursor-not-allowed"
29886
+ ),
29887
+ style: {
29888
+ top: rowRailTop,
29889
+ left: rowRailLeft,
29890
+ width: visibleTableWidth,
29891
+ height: 16
29892
+ },
29893
+ children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "text-sm font-medium leading-none", children: "+" })
29894
+ }
29895
+ )
29812
29896
  }
29813
29897
  ),
29814
29898
  dragPreview?.kind === "row" && /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(import_jsx_runtime82.Fragment, { children: [
@@ -30162,7 +30246,20 @@ var UEditor = import_react53.default.forwardRef(({
30162
30246
  "[&_pre]:text-[#d4d4d4]!",
30163
30247
  "[&_pre_code]:bg-transparent!",
30164
30248
  "[&_.tableWrapper]:overflow-x-auto",
30249
+ "[&_.tableWrapper]:pb-1.5",
30165
30250
  "[&_.tableWrapper]:select-text",
30251
+ "[&_.tableWrapper]:[scrollbar-width:thin]",
30252
+ "[&_.tableWrapper]:[scrollbar-color:hsl(var(--border))_transparent]",
30253
+ "[&_.tableWrapper::-webkit-scrollbar]:h-2",
30254
+ "[&_.tableWrapper::-webkit-scrollbar]:w-2",
30255
+ "[&_.tableWrapper::-webkit-scrollbar-track]:rounded-full",
30256
+ "[&_.tableWrapper::-webkit-scrollbar-track]:bg-transparent",
30257
+ "[&_.tableWrapper::-webkit-scrollbar-thumb]:rounded-full",
30258
+ "[&_.tableWrapper::-webkit-scrollbar-thumb]:border",
30259
+ "[&_.tableWrapper::-webkit-scrollbar-thumb]:border-solid",
30260
+ "[&_.tableWrapper::-webkit-scrollbar-thumb]:border-transparent",
30261
+ "[&_.tableWrapper::-webkit-scrollbar-thumb]:bg-border/70",
30262
+ "[&_.tableWrapper::-webkit-scrollbar-thumb:hover]:bg-muted-foreground/45",
30166
30263
  "[&_table]:table-fixed",
30167
30264
  "[&_table]:overflow-hidden",
30168
30265
  "[&_table]:select-text",
@@ -30182,15 +30279,27 @@ var UEditor = import_react53.default.forwardRef(({
30182
30279
  "[&_.selectedCell]:after:pointer-events-none",
30183
30280
  "[&_.column-resize-handle]:pointer-events-auto",
30184
30281
  "[&_.column-resize-handle]:cursor-col-resize",
30185
- "[&_.column-resize-handle]:bg-primary/65",
30186
- "[&_.column-resize-handle]:w-2",
30187
- "[&_.column-resize-handle]:rounded-full",
30282
+ "[&_.column-resize-handle]:absolute",
30283
+ "[&_.column-resize-handle]:top-[-1px]",
30284
+ "[&_.column-resize-handle]:bottom-[-1px]",
30285
+ "[&_.column-resize-handle]:right-[-5px]",
30286
+ "[&_.column-resize-handle]:z-10",
30287
+ "[&_.column-resize-handle]:w-2.5",
30288
+ "[&_.column-resize-handle]:bg-transparent",
30289
+ "[&_.column-resize-handle]:rounded-none",
30188
30290
  "[&_.column-resize-handle]:opacity-0",
30189
- "[&_.column-resize-handle]:shadow-sm",
30190
- "[&_.column-resize-handle]:transition-[opacity,background-color,box-shadow]",
30291
+ "[&_.column-resize-handle]:transition-opacity",
30292
+ "[&_.column-resize-handle]:after:absolute",
30293
+ "[&_.column-resize-handle]:after:top-0",
30294
+ "[&_.column-resize-handle]:after:bottom-0",
30295
+ "[&_.column-resize-handle]:after:left-1/2",
30296
+ "[&_.column-resize-handle]:after:w-0.5",
30297
+ "[&_.column-resize-handle]:after:-translate-x-1/2",
30298
+ "[&_.column-resize-handle]:after:rounded-full",
30299
+ "[&_.column-resize-handle]:after:bg-primary/75",
30300
+ "[&_.column-resize-handle]:after:content-['']",
30191
30301
  "[&.resize-cursor_.column-resize-handle]:opacity-100",
30192
- "[&.resize-cursor_.column-resize-handle]:bg-primary",
30193
- "[&.resize-cursor_.column-resize-handle]:shadow-md",
30302
+ "[&.resize-cursor_.column-resize-handle]:after:bg-primary",
30194
30303
  "[&.resize-cursor]:cursor-col-resize",
30195
30304
  "[&.resize-row-cursor]:cursor-row-resize",
30196
30305
  "[&_img.ProseMirror-selectednode]:ring-2",