@underverse-ui/underverse 1.0.127 → 1.0.129

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
@@ -1014,7 +1014,8 @@ var en_default = {
1014
1014
  dragColumn: "Drag Column",
1015
1015
  alignLeft: "Align Table Left",
1016
1016
  alignCenter: "Align Table Center",
1017
- alignRight: "Align Table Right"
1017
+ alignRight: "Align Table Right",
1018
+ cellBackground: "Cell Background"
1018
1019
  }
1019
1020
  }
1020
1021
  };
@@ -1283,7 +1284,8 @@ var vi_default = {
1283
1284
  dragColumn: "K\xE9o c\u1ED9t",
1284
1285
  alignLeft: "C\u0103n b\u1EA3ng tr\xE1i",
1285
1286
  alignCenter: "C\u0103n b\u1EA3ng gi\u1EEFa",
1286
- alignRight: "C\u0103n b\u1EA3ng ph\u1EA3i"
1287
+ alignRight: "C\u0103n b\u1EA3ng ph\u1EA3i",
1288
+ cellBackground: "M\xE0u n\u1EC1n \xF4"
1287
1289
  }
1288
1290
  }
1289
1291
  };
@@ -1551,7 +1553,8 @@ var ko_default = {
1551
1553
  dragColumn: "\uC5F4 \uB4DC\uB798\uADF8",
1552
1554
  alignLeft: "\uD45C \uC67C\uCABD \uC815\uB82C",
1553
1555
  alignCenter: "\uD45C \uAC00\uC6B4\uB370 \uC815\uB82C",
1554
- alignRight: "\uD45C \uC624\uB978\uCABD \uC815\uB82C"
1556
+ alignRight: "\uD45C \uC624\uB978\uCABD \uC815\uB82C",
1557
+ cellBackground: "\uC140 \uBC30\uACBD\uC0C9"
1555
1558
  }
1556
1559
  }
1557
1560
  };
@@ -1819,7 +1822,8 @@ var ja_default = {
1819
1822
  dragColumn: "\u5217\u3092\u30C9\u30E9\u30C3\u30B0",
1820
1823
  alignLeft: "\u8868\u3092\u5DE6\u5BC4\u305B",
1821
1824
  alignCenter: "\u8868\u3092\u4E2D\u592E\u63C3\u3048",
1822
- alignRight: "\u8868\u3092\u53F3\u5BC4\u305B"
1825
+ alignRight: "\u8868\u3092\u53F3\u5BC4\u305B",
1826
+ cellBackground: "\u30BB\u30EB\u80CC\u666F\u8272"
1823
1827
  }
1824
1828
  }
1825
1829
  };
@@ -7404,7 +7408,7 @@ var DropdownMenuItem = ({
7404
7408
  disabled,
7405
7409
  onMouseDown: (e) => e.preventDefault(),
7406
7410
  className: cn(
7407
- "flex w-full items-center gap-2 px-3 py-2 text-sm rounded-lg transition-colors group",
7411
+ "flex w-full items-center gap-2 px-3 py-2 text-sm rounded-lg transition-colors group cursor-pointer",
7408
7412
  "hover:bg-accent hover:text-accent-foreground",
7409
7413
  "focus:bg-accent focus:text-accent-foreground focus:outline-none",
7410
7414
  "disabled:opacity-50 disabled:cursor-not-allowed",
@@ -24006,6 +24010,7 @@ var import_react56 = __toESM(require("react"), 1);
24006
24010
  var import_react57 = require("@tiptap/react");
24007
24011
 
24008
24012
  // src/components/UEditor/extensions.ts
24013
+ var import_core10 = require("@tiptap/core");
24009
24014
  var import_extension_document = __toESM(require("@tiptap/extension-document"), 1);
24010
24015
  var import_extension_paragraph = __toESM(require("@tiptap/extension-paragraph"), 1);
24011
24016
  var import_extension_text = __toESM(require("@tiptap/extension-text"), 1);
@@ -25319,6 +25324,64 @@ var UEditorTable = import_extension_table.Table.extend({
25319
25324
  var table_align_default = UEditorTable;
25320
25325
 
25321
25326
  // src/components/UEditor/extensions.ts
25327
+ var CustomTableCell = import_extension_table_cell.default.extend({
25328
+ addAttributes() {
25329
+ return {
25330
+ ...this.parent?.(),
25331
+ backgroundColor: {
25332
+ default: null,
25333
+ parseHTML: (element) => element.style.backgroundColor || element.getAttribute("data-background-color") || null,
25334
+ renderHTML: (attributes) => {
25335
+ if (!attributes.backgroundColor) {
25336
+ return {};
25337
+ }
25338
+ return {
25339
+ "data-background-color": attributes.backgroundColor
25340
+ };
25341
+ }
25342
+ }
25343
+ };
25344
+ },
25345
+ renderHTML({ HTMLAttributes }) {
25346
+ const style = HTMLAttributes.style || "";
25347
+ const bg = HTMLAttributes["data-background-color"];
25348
+ const mergedStyle = bg ? `${style}; background-color: ${bg}`.replace(/^;/, "") : style;
25349
+ return [
25350
+ "td",
25351
+ (0, import_core10.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, mergedStyle ? { style: mergedStyle } : {}),
25352
+ 0
25353
+ ];
25354
+ }
25355
+ });
25356
+ var CustomTableHeader = import_extension_table_header.default.extend({
25357
+ addAttributes() {
25358
+ return {
25359
+ ...this.parent?.(),
25360
+ backgroundColor: {
25361
+ default: null,
25362
+ parseHTML: (element) => element.style.backgroundColor || element.getAttribute("data-background-color") || null,
25363
+ renderHTML: (attributes) => {
25364
+ if (!attributes.backgroundColor) {
25365
+ return {};
25366
+ }
25367
+ return {
25368
+ "data-background-color": attributes.backgroundColor
25369
+ };
25370
+ }
25371
+ }
25372
+ };
25373
+ },
25374
+ renderHTML({ HTMLAttributes }) {
25375
+ const style = HTMLAttributes.style || "";
25376
+ const bg = HTMLAttributes["data-background-color"];
25377
+ const mergedStyle = bg ? `${style}; background-color: ${bg}`.replace(/^;/, "") : style;
25378
+ return [
25379
+ "th",
25380
+ (0, import_core10.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, mergedStyle ? { style: mergedStyle } : {}),
25381
+ 0
25382
+ ];
25383
+ }
25384
+ });
25322
25385
  var lowlight = (0, import_lowlight.createLowlight)(import_lowlight.common);
25323
25386
  function buildUEditorExtensions({
25324
25387
  placeholder,
@@ -25417,12 +25480,12 @@ function buildUEditorExtensions({
25417
25480
  }
25418
25481
  }),
25419
25482
  table_row_default,
25420
- import_extension_table_cell.default.configure({
25483
+ CustomTableCell.configure({
25421
25484
  HTMLAttributes: {
25422
25485
  class: "border border-border p-2 min-w-25"
25423
25486
  }
25424
25487
  }),
25425
- import_extension_table_header.default.configure({
25488
+ CustomTableHeader.configure({
25426
25489
  HTMLAttributes: {
25427
25490
  class: "border border-border p-2 bg-muted font-semibold min-w-25"
25428
25491
  }
@@ -25456,7 +25519,6 @@ function buildUEditorExtensions({
25456
25519
 
25457
25520
  // src/components/UEditor/toolbar.tsx
25458
25521
  var import_react49 = __toESM(require("react"), 1);
25459
- var import_react_dom8 = require("react-dom");
25460
25522
  var import_react50 = require("@tiptap/react");
25461
25523
  var import_lucide_react44 = require("lucide-react");
25462
25524
 
@@ -25492,6 +25554,20 @@ var HighlightColorIcon = ({ color }) => {
25492
25554
  )
25493
25555
  ] });
25494
25556
  };
25557
+ var CellBgColorIcon = ({ color }) => {
25558
+ const underlineColor = color && color !== "inherit" ? color : "currentColor";
25559
+ return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("span", { className: "relative flex h-5 w-5 items-center justify-center leading-none", children: [
25560
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_lucide_react42.Paintbrush, { className: "h-4 w-4" }),
25561
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
25562
+ "span",
25563
+ {
25564
+ "aria-hidden": "true",
25565
+ className: "absolute bottom-0 left-1/2 h-0.5 w-4 -translate-x-1/2 rounded-full",
25566
+ style: { backgroundColor: underlineColor }
25567
+ }
25568
+ )
25569
+ ] });
25570
+ };
25495
25571
  var EDITOR_COLOR_SWATCHES = [
25496
25572
  "#000000",
25497
25573
  "#3f3f46",
@@ -25951,7 +26027,7 @@ var ToolbarButton = import_react49.default.forwardRef(({ onClick, onMouseDown, a
25951
26027
  onClick,
25952
26028
  disabled,
25953
26029
  className: cn(
25954
- "flex items-center justify-center w-8 h-8 rounded-md transition-colors duration-150",
26030
+ "flex items-center justify-center w-7 h-7 rounded-md transition-colors duration-150 cursor-pointer",
25955
26031
  "gap-0.5 [&_svg+svg]:-ml-1",
25956
26032
  "hover:bg-accent",
25957
26033
  "focus:outline-none focus:ring-2 focus:ring-primary/20",
@@ -26030,11 +26106,6 @@ var EditorToolbar = ({
26030
26106
  const fileInputRef = (0, import_react49.useRef)(null);
26031
26107
  const [isUploadingImage, setIsUploadingImage] = (0, import_react49.useState)(false);
26032
26108
  const [imageUploadError, setImageUploadError] = (0, import_react49.useState)(null);
26033
- const [fontSizeDraft, setFontSizeDraft] = (0, import_react49.useState)("");
26034
- const [isFontSizeMenuOpen, setIsFontSizeMenuOpen] = (0, import_react49.useState)(false);
26035
- const [fontSizeMenuPosition, setFontSizeMenuPosition] = (0, import_react49.useState)({ top: 0, left: 0 });
26036
- const fontSizeControlRef = (0, import_react49.useRef)(null);
26037
- const fontSizeMenuRef = (0, import_react49.useRef)(null);
26038
26109
  const isImageSelected = editor.isActive("image");
26039
26110
  const imageAttrs = editor.getAttributes("image");
26040
26111
  const tableAttrs = editor.getAttributes("table");
@@ -26060,53 +26131,6 @@ var EditorToolbar = ({
26060
26131
  const currentLineHeightLabel = availableLineHeights.find((option) => normalizeStyleValue(option.value) === currentLineHeight)?.label ?? t("toolbar.lineHeightDefault");
26061
26132
  const currentLetterSpacingLabel = availableLetterSpacings.find((option) => normalizeStyleValue(option.value) === currentLetterSpacing)?.label ?? t("toolbar.letterSpacingDefault");
26062
26133
  const displayedFontFamilyLabel = currentFontFamily ? currentFontFamilyLabel : availableFontFamilies[0]?.label ?? t("toolbar.fontDefault");
26063
- import_react49.default.useEffect(() => {
26064
- if (document.activeElement === fontSizeControlRef.current?.querySelector("input")) return;
26065
- setFontSizeDraft(currentFontSize.replace(/px$/i, "") || "16");
26066
- }, [currentFontSize]);
26067
- const applyFontSizeDraft = () => {
26068
- const normalized = fontSizeDraft.trim();
26069
- if (!normalized) {
26070
- editor.chain().focus().unsetFontSize().run();
26071
- return;
26072
- }
26073
- const parsed = Number.parseFloat(normalized);
26074
- if (!Number.isFinite(parsed) || parsed <= 0) return;
26075
- const clamped = Math.min(96, Math.max(8, parsed));
26076
- editor.chain().focus().setFontSize(`${clamped}px`).run();
26077
- setFontSizeDraft(String(clamped));
26078
- };
26079
- const updateFontSizeMenuPosition = import_react49.default.useCallback(() => {
26080
- const rect = fontSizeControlRef.current?.getBoundingClientRect();
26081
- if (!rect) return;
26082
- setFontSizeMenuPosition({
26083
- top: Math.round(rect.bottom + 4),
26084
- left: Math.round(rect.left)
26085
- });
26086
- }, []);
26087
- const toggleFontSizeMenu = () => {
26088
- updateFontSizeMenuPosition();
26089
- setIsFontSizeMenuOpen((open) => !open);
26090
- };
26091
- import_react49.default.useEffect(() => {
26092
- if (!isFontSizeMenuOpen) return;
26093
- updateFontSizeMenuPosition();
26094
- const handlePointerDown = (event) => {
26095
- const target = event.target;
26096
- if (fontSizeControlRef.current?.contains(target)) return;
26097
- if (fontSizeMenuRef.current?.contains(target)) return;
26098
- setIsFontSizeMenuOpen(false);
26099
- };
26100
- const handleLayoutChange = () => updateFontSizeMenuPosition();
26101
- document.addEventListener("mousedown", handlePointerDown);
26102
- window.addEventListener("resize", handleLayoutChange);
26103
- window.addEventListener("scroll", handleLayoutChange, true);
26104
- return () => {
26105
- document.removeEventListener("mousedown", handlePointerDown);
26106
- window.removeEventListener("resize", handleLayoutChange);
26107
- window.removeEventListener("scroll", handleLayoutChange, true);
26108
- };
26109
- }, [isFontSizeMenuOpen, updateFontSizeMenuPosition]);
26110
26134
  const insertImageFiles = async (files) => {
26111
26135
  if (files.length === 0) return;
26112
26136
  setIsUploadingImage(true);
@@ -26146,21 +26170,11 @@ var EditorToolbar = ({
26146
26170
  /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
26147
26171
  DropdownMenu,
26148
26172
  {
26149
- trigger: /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
26150
- "button",
26151
- {
26152
- type: "button",
26153
- "aria-label": t("toolbar.fontFamily"),
26154
- className: cn(
26155
- "flex h-8 min-w-34 max-w-42 items-center justify-between gap-2 rounded-full border border-border/60 bg-muted/30 px-2.5 text-xs text-foreground",
26156
- "transition-colors hover:bg-accent focus:outline-none focus:ring-2 focus:ring-primary/20"
26157
- ),
26158
- children: [
26159
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("span", { className: "truncate", children: displayedFontFamilyLabel }),
26160
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.ChevronDown, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" })
26161
- ]
26162
- }
26163
- ),
26173
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(ToolbarButton, { onClick: () => {
26174
+ }, title: t("toolbar.fontFamily"), className: "px-1.5 w-auto gap-0.5", children: [
26175
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.Baseline, { className: "w-4 h-4" }),
26176
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.ChevronDown, { className: "h-3 w-3 text-muted-foreground" })
26177
+ ] }),
26164
26178
  contentClassName: "max-h-80 overflow-y-auto min-w-56 p-2",
26165
26179
  children: [
26166
26180
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
@@ -26178,102 +26192,55 @@ var EditorToolbar = ({
26178
26192
  label: option.label,
26179
26193
  onClick: () => editor.chain().focus().setFontFamily(option.value).run(),
26180
26194
  active: normalizeStyleValue(option.value) === currentFontFamily,
26181
- className: "font-medium "
26195
+ className: "font-medium"
26182
26196
  },
26183
26197
  option.value
26184
26198
  ))
26185
26199
  ]
26186
26200
  }
26187
26201
  ),
26188
- /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(import_jsx_runtime81.Fragment, { children: [
26189
- /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
26190
- "div",
26191
- {
26192
- ref: fontSizeControlRef,
26193
- "aria-label": t("toolbar.fontSize"),
26194
- className: cn(
26195
- "flex h-8 min-w-14 items-center overflow-hidden rounded-full border border-border/60 bg-muted/30 text-xs font-semibold text-foreground",
26196
- "transition-colors focus-within:ring-2 focus-within:ring-primary/20"
26202
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
26203
+ DropdownMenu,
26204
+ {
26205
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(ToolbarButton, { onClick: () => {
26206
+ }, title: t("toolbar.fontSize"), className: "px-1.5 w-auto gap-0.5", children: [
26207
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: "flex items-center gap-0.5", children: [
26208
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.ChevronsUpDown, { className: "h-3 w-3 text-muted-foreground", strokeWidth: 2.5 }),
26209
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("span", { className: "text-xs font-bold leading-none", children: "A" })
26210
+ ] }),
26211
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.ChevronDown, { className: "h-3 w-3 text-muted-foreground" })
26212
+ ] }),
26213
+ contentClassName: "max-h-80 overflow-y-auto min-w-32 p-2",
26214
+ children: [
26215
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26216
+ DropdownMenuItem,
26217
+ {
26218
+ icon: import_lucide_react44.Type,
26219
+ label: t("toolbar.sizeDefault"),
26220
+ onClick: () => editor.chain().focus().unsetFontSize().run(),
26221
+ active: !currentFontSize
26222
+ }
26197
26223
  ),
26198
- children: [
26199
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26200
- "input",
26201
- {
26202
- type: "number",
26203
- min: 8,
26204
- max: 96,
26205
- step: 1,
26206
- value: fontSizeDraft,
26207
- onChange: (e) => setFontSizeDraft(e.target.value),
26208
- onBlur: applyFontSizeDraft,
26209
- onMouseDown: (e) => e.stopPropagation(),
26210
- onClick: (e) => e.stopPropagation(),
26211
- onKeyDown: (e) => {
26212
- e.stopPropagation();
26213
- if (e.key === "Enter") {
26214
- e.preventDefault();
26215
- applyFontSizeDraft();
26216
- }
26217
- },
26218
- "aria-label": t("toolbar.fontSize"),
26219
- className: "h-full w-8 bg-transparent px-0.5 text-center text-xs font-semibold outline-none [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
26220
- }
26221
- ),
26222
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26223
- "button",
26224
- {
26225
- type: "button",
26226
- "aria-label": t("toolbar.fontSize"),
26227
- "aria-expanded": isFontSizeMenuOpen,
26228
- onClick: toggleFontSizeMenu,
26229
- className: "flex h-full w-5 items-center justify-center text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
26230
- children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.ChevronDown, { className: "h-3.5 w-3.5" })
26231
- }
26232
- )
26233
- ]
26234
- }
26235
- ),
26236
- isFontSizeMenuOpen && typeof document !== "undefined" && (0, import_react_dom8.createPortal)(
26237
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26238
- "div",
26239
- {
26240
- ref: fontSizeMenuRef,
26241
- className: "fixed z-[10000] max-h-64 w-12 overflow-y-auto rounded-md border border-border/70 bg-popover p-0.5 text-popover-foreground shadow-md",
26242
- style: { top: fontSizeMenuPosition.top, left: fontSizeMenuPosition.left },
26243
- children: availableFontSizes.map((option) => {
26244
- const active = normalizeStyleValue(option.value) === currentFontSize;
26245
- return /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26246
- "button",
26247
- {
26248
- type: "button",
26249
- onMouseDown: (e) => e.preventDefault(),
26250
- onClick: () => {
26251
- editor.chain().focus().setFontSize(option.value).run();
26252
- setFontSizeDraft(option.label);
26253
- setIsFontSizeMenuOpen(false);
26254
- },
26255
- className: cn(
26256
- "flex h-6 w-full items-center justify-center rounded text-xs leading-none transition-colors",
26257
- active ? "bg-primary/15 text-primary" : "text-foreground hover:bg-accent hover:text-accent-foreground"
26258
- ),
26259
- children: option.label
26260
- },
26261
- option.value
26262
- );
26263
- })
26264
- }
26265
- ),
26266
- document.body
26267
- )
26268
- ] }),
26224
+ availableFontSizes.map((option) => /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26225
+ DropdownMenuItem,
26226
+ {
26227
+ label: option.label,
26228
+ onClick: () => editor.chain().focus().setFontSize(option.value).run(),
26229
+ active: normalizeStyleValue(option.value) === currentFontSize
26230
+ },
26231
+ option.value
26232
+ ))
26233
+ ]
26234
+ }
26235
+ ),
26269
26236
  /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
26270
26237
  DropdownMenu,
26271
26238
  {
26272
- contentClassName: "p-2",
26239
+ contentClassName: "p-1",
26273
26240
  trigger: /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(ToolbarButton, { onClick: () => {
26274
- }, title: t("toolbar.textStyle"), className: "px-2 w-auto gap-1", children: [
26241
+ }, title: t("toolbar.textStyle"), className: "px-1.5 w-auto gap-0.5", children: [
26275
26242
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.Type, { className: "w-4 h-4" }),
26276
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.ChevronDown, { className: "w-3 h-3" })
26243
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.ChevronDown, { className: "h-3 w-3 text-muted-foreground" })
26277
26244
  ] }),
26278
26245
  children: [
26279
26246
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
@@ -26326,7 +26293,7 @@ var EditorToolbar = ({
26326
26293
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.ArrowUp, { className: "w-3 h-3" }),
26327
26294
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.ArrowDown, { className: "w-3 h-3" })
26328
26295
  ] }),
26329
- contentClassName: "max-h-72 overflow-y-auto p-2",
26296
+ contentClassName: "max-h-72 overflow-y-auto p-1",
26330
26297
  children: [
26331
26298
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26332
26299
  DropdownMenuItem,
@@ -26357,7 +26324,7 @@ var EditorToolbar = ({
26357
26324
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.ArrowLeft, { className: "w-3 h-3" }),
26358
26325
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.ArrowRight, { className: "w-3 h-3" })
26359
26326
  ] }),
26360
- contentClassName: "max-h-72 overflow-y-auto p-2",
26327
+ contentClassName: "max-h-72 overflow-y-auto p-1",
26361
26328
  children: [
26362
26329
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26363
26330
  DropdownMenuItem,
@@ -26913,7 +26880,8 @@ var EditorToolbar = ({
26913
26880
  // src/components/UEditor/menus.tsx
26914
26881
  var import_react51 = require("react");
26915
26882
  var import_react52 = require("@tiptap/react");
26916
- var import_react_dom9 = require("react-dom");
26883
+ var import_tables = require("@tiptap/pm/tables");
26884
+ var import_react_dom8 = require("react-dom");
26917
26885
  var import_lucide_react45 = require("lucide-react");
26918
26886
  var import_jsx_runtime82 = require("react/jsx-runtime");
26919
26887
  var FloatingSlashCommandMenu = ({ editor, onClose }) => {
@@ -26968,6 +26936,16 @@ var FloatingMenuContent = ({ editor }) => {
26968
26936
  }
26969
26937
  );
26970
26938
  };
26939
+ function applyTableCellBackground(editor, color) {
26940
+ const value = color || null;
26941
+ const { state, view } = editor;
26942
+ const applied = (0, import_tables.setCellAttr)("backgroundColor", value)(state, view.dispatch.bind(view));
26943
+ if (applied) {
26944
+ view.focus();
26945
+ return;
26946
+ }
26947
+ editor.chain().focus().setCellAttribute("backgroundColor", value).run();
26948
+ }
26971
26949
  var BubbleMenuContent = ({
26972
26950
  editor,
26973
26951
  onKeepOpenChange,
@@ -26992,6 +26970,8 @@ var BubbleMenuContent = ({
26992
26970
  const textStyleAttrs = editor.getAttributes("textStyle");
26993
26971
  const currentTextColor = normalizeStyleValue(textStyleAttrs.color) || "inherit";
26994
26972
  const currentHighlightColor = normalizeStyleValue(editor.getAttributes("highlight").color) || "";
26973
+ const currentCellBgColor = normalizeStyleValue(editor.getAttributes("tableCell").backgroundColor || editor.getAttributes("tableHeader").backgroundColor) || "";
26974
+ const isInTable2 = (0, import_tables.isInTable)(editor.state);
26995
26975
  const currentFontSize = normalizeStyleValue(textStyleAttrs.fontSize);
26996
26976
  const currentLineHeight = normalizeStyleValue(textStyleAttrs.lineHeight);
26997
26977
  const quickFontSizes = (0, import_react51.useMemo)(
@@ -27049,12 +27029,13 @@ var BubbleMenuContent = ({
27049
27029
  }
27050
27030
  if (activeColorPalette) {
27051
27031
  const isTextPalette = activeColorPalette === "text";
27032
+ const isHighlightPalette = activeColorPalette === "highlight";
27052
27033
  return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "w-56", children: [
27053
27034
  /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
27054
27035
  EditorColorPalette,
27055
27036
  {
27056
27037
  colors: isTextPalette ? textColors : highlightColors,
27057
- currentColor: isTextPalette ? currentTextColor : currentHighlightColor,
27038
+ currentColor: isTextPalette ? currentTextColor : isHighlightPalette ? currentHighlightColor : currentCellBgColor,
27058
27039
  onSelect: (color) => {
27059
27040
  if (isTextPalette) {
27060
27041
  if (color === "inherit") {
@@ -27062,15 +27043,17 @@ var BubbleMenuContent = ({
27062
27043
  } else {
27063
27044
  editor.chain().focus().setColor(color).run();
27064
27045
  }
27065
- } else {
27046
+ } else if (isHighlightPalette) {
27066
27047
  if (color === "") {
27067
27048
  editor.chain().focus().unsetHighlight().run();
27068
27049
  } else {
27069
27050
  editor.chain().focus().toggleHighlight({ color }).run();
27070
27051
  }
27052
+ } else {
27053
+ applyTableCellBackground(editor, color);
27071
27054
  }
27072
27055
  },
27073
- label: isTextPalette ? t("colors.textColor") : t("colors.highlight")
27056
+ label: isTextPalette ? t("colors.textColor") : isHighlightPalette ? t("colors.highlight") : t("tableMenu.cellBackground") || "Cell background"
27074
27057
  }
27075
27058
  ),
27076
27059
  /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "p-2 border-t", children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
@@ -27285,7 +27268,7 @@ var BubbleMenuContent = ({
27285
27268
  ),
27286
27269
  /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(ToolbarButton, { onClick: () => setActiveColorPalette("text"), title: t("colors.textColor"), children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(TextColorIcon, { color: currentTextColor }) }),
27287
27270
  /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(ToolbarButton, { onClick: () => setActiveColorPalette("highlight"), active: editor.isActive("highlight"), title: t("colors.highlight"), children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(HighlightColorIcon, { color: currentHighlightColor }) }),
27288
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "w-px h-6 bg-border/50 mx-1" }),
27271
+ isInTable2 && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(ToolbarButton, { onClick: () => setActiveColorPalette("cell-bg"), active: Boolean(currentCellBgColor), title: t("tableMenu.cellBackground") || "Cell background", children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(CellBgColorIcon, { color: currentCellBgColor }) }),
27289
27272
  /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
27290
27273
  ToolbarButton,
27291
27274
  {
@@ -27361,7 +27344,7 @@ var CustomBubbleMenu = ({
27361
27344
  };
27362
27345
  }, [editor]);
27363
27346
  if (!isVisible) return null;
27364
- return (0, import_react_dom9.createPortal)(
27347
+ return (0, import_react_dom8.createPortal)(
27365
27348
  /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
27366
27349
  "div",
27367
27350
  {
@@ -27417,7 +27400,7 @@ var CustomFloatingMenu = ({ editor }) => {
27417
27400
  };
27418
27401
  }, [editor]);
27419
27402
  if (!isVisible) return null;
27420
- return (0, import_react_dom9.createPortal)(
27403
+ return (0, import_react_dom8.createPortal)(
27421
27404
  /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
27422
27405
  "div",
27423
27406
  {
@@ -31999,15 +31982,12 @@ var FALLBACK_TABLE_COLUMN_WIDTH = 160;
31999
31982
  var MENU_HOVER_PADDING = 18;
32000
31983
  var ROW_HANDLE_HOVER_WIDTH = 28;
32001
31984
  var COLUMN_HANDLE_HOVER_HEIGHT = 28;
32002
- var ROW_HANDLE_GUTTER = 20;
32003
31985
  var TABLE_MENU_TOP_OFFSET = 10;
32004
- var COLUMN_HANDLE_TOP_OFFSET = 8;
32005
31986
  var ADD_COLUMN_RAIL_GAP = 4;
32006
31987
  var ADD_ROW_RAIL_GAP = 4;
32007
31988
  var ADD_COLUMN_HOVER_WIDTH = 24;
32008
31989
  var ADD_ROW_HOVER_HEIGHT = 24;
32009
31990
  var HANDLE_HOVER_RADIUS = 14;
32010
- var IDLE_HANDLE_OPACITY = "0.4";
32011
31991
  var IDLE_HANDLE_SCALE = "0.78";
32012
31992
  var DEFAULT_HOVER_STATE = {
32013
31993
  menuVisible: false,
@@ -32247,11 +32227,16 @@ function TableControls({ editor, containerRef }) {
32247
32227
  const directColumnHandleIndex = directColumnHandle instanceof HTMLElement ? Number.parseInt(directColumnHandle.dataset.columnHandleIndex ?? "", 10) : Number.NaN;
32248
32228
  const visibleTableWidth2 = Math.min(activeLayout.tableWidth, activeLayout.viewportWidth);
32249
32229
  const visibleTableHeight2 = Math.min(activeLayout.tableHeight, activeLayout.viewportHeight);
32230
+ const isMouseInTable = relativeX >= activeLayout.tableLeft && relativeX <= activeLayout.tableLeft + activeLayout.tableWidth && relativeY >= activeLayout.tableTop && relativeY <= activeLayout.tableTop + activeLayout.tableHeight;
32250
32231
  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;
32251
32232
  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;
32252
- 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;
32253
- const addColumnVisible = Boolean(directAddColumn) || relativeX >= activeLayout.tableLeft + visibleTableWidth2 && relativeX <= activeLayout.tableLeft + visibleTableWidth2 + ADD_COLUMN_HOVER_WIDTH && relativeY >= activeLayout.tableTop && relativeY <= activeLayout.tableTop + visibleTableHeight2;
32254
- const addRowVisible = Boolean(directAddRow) || relativeY >= activeLayout.tableTop + visibleTableHeight2 && relativeY <= activeLayout.tableTop + visibleTableHeight2 + ADD_ROW_HOVER_HEIGHT && relativeX >= activeLayout.tableLeft && relativeX <= activeLayout.tableLeft + visibleTableWidth2;
32233
+ const menuVisible = Boolean(directTableMenu) || isMouseInTable || relativeX >= activeLayout.tableLeft - MENU_HOVER_PADDING && relativeX <= activeLayout.tableLeft + 42 && relativeY >= activeLayout.tableTop - COLUMN_HANDLE_HOVER_HEIGHT && relativeY <= activeLayout.tableTop + MENU_HOVER_PADDING;
32234
+ const lastRow = activeLayout.rowHandles[activeLayout.rowHandles.length - 1];
32235
+ const lastCol = activeLayout.columnHandles[activeLayout.columnHandles.length - 1];
32236
+ const isMouseInLastColumn = lastCol ? relativeX >= lastCol.start && relativeX <= lastCol.start + lastCol.size && relativeY >= activeLayout.tableTop && relativeY <= activeLayout.tableTop + visibleTableHeight2 : false;
32237
+ const addColumnVisible = Boolean(directAddColumn) || relativeX >= activeLayout.tableLeft + visibleTableWidth2 && relativeX <= activeLayout.tableLeft + visibleTableWidth2 + ADD_COLUMN_HOVER_WIDTH && relativeY >= activeLayout.tableTop && relativeY <= activeLayout.tableTop + visibleTableHeight2 || isMouseInLastColumn;
32238
+ const isMouseInLastRow = lastRow ? relativeY >= lastRow.start && relativeY <= lastRow.start + lastRow.size && relativeX >= activeLayout.tableLeft && relativeX <= activeLayout.tableLeft + visibleTableWidth2 : false;
32239
+ const addRowVisible = Boolean(directAddRow) || relativeY >= activeLayout.tableTop + visibleTableHeight2 && relativeY <= activeLayout.tableTop + visibleTableHeight2 + ADD_ROW_HOVER_HEIGHT && relativeX >= activeLayout.tableLeft && relativeX <= activeLayout.tableLeft + visibleTableWidth2 || isMouseInLastRow;
32255
32240
  setHoverState((prev) => {
32256
32241
  if (prev.menuVisible === menuVisible && prev.addColumnVisible === addColumnVisible && prev.addRowVisible === addRowVisible && prev.rowHandleIndex === rowHandleIndex && prev.columnHandleIndex === columnHandleIndex) {
32257
32242
  return prev;
@@ -32619,8 +32604,8 @@ function TableControls({ editor, containerRef }) {
32619
32604
  }
32620
32605
  const menuTop = Math.max(8, layout.tableTop - TABLE_MENU_TOP_OFFSET);
32621
32606
  const menuLeft = Math.max(8, layout.tableLeft);
32622
- const rowHandleLeft = Math.max(8, layout.tableLeft - ROW_HANDLE_GUTTER);
32623
- const columnHandleTop = Math.max(8, layout.tableTop - COLUMN_HANDLE_TOP_OFFSET);
32607
+ const rowHandleLeft = layout.tableLeft - 12;
32608
+ const columnHandleTop = layout.tableTop - 12;
32624
32609
  const visibleTableWidth = Math.min(layout.tableWidth, layout.viewportWidth);
32625
32610
  const visibleTableHeight = Math.min(layout.tableHeight, layout.viewportHeight);
32626
32611
  const columnRailTop = layout.tableTop;
@@ -32633,7 +32618,9 @@ function TableControls({ editor, containerRef }) {
32633
32618
  return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(import_jsx_runtime84.Fragment, { children: [
32634
32619
  layout.rowHandles.map((rowHandle) => {
32635
32620
  const menuKey = getRowMenuKey(rowHandle.index);
32621
+ const isActive = rowHandle.index === layout.activeRowIndex;
32636
32622
  const visible = controlsVisible || hoverState.rowHandleIndex === rowHandle.index || openMenuKey === menuKey;
32623
+ const isShown = visible || isActive;
32637
32624
  return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
32638
32625
  "div",
32639
32626
  {
@@ -32647,7 +32634,7 @@ function TableControls({ editor, containerRef }) {
32647
32634
  Tooltip,
32648
32635
  {
32649
32636
  placement: "right",
32650
- disabled: openMenuKey === menuKey,
32637
+ disabled: openMenuKey === menuKey || !visible && isActive,
32651
32638
  content: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "text-xs font-medium", children: `${t("tableMenu.dragRow")} ${rowHandle.index + 1}` }),
32652
32639
  children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "inline-flex", children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
32653
32640
  DropdownMenu,
@@ -32684,16 +32671,15 @@ function TableControls({ editor, containerRef }) {
32684
32671
  document.body.style.cursor = "grabbing";
32685
32672
  },
32686
32673
  className: cn(
32687
- "inline-flex h-6 w-6 items-center justify-center rounded-full",
32688
- "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
32689
- "cursor-grab active:cursor-grabbing",
32690
- "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
32674
+ "inline-flex h-6 w-6 items-center justify-center rounded-full transition-[opacity,transform,colors,border,background-color] duration-150",
32675
+ visible ? "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur hover:bg-accent hover:text-foreground cursor-grab active:cursor-grabbing" : "border-transparent bg-transparent cursor-pointer"
32691
32676
  ),
32692
32677
  style: {
32693
- opacity: visible ? 1 : Number(IDLE_HANDLE_OPACITY),
32694
- transform: visible ? "scale(1)" : `scale(${IDLE_HANDLE_SCALE})`
32678
+ opacity: isShown ? 1 : 0,
32679
+ transform: isShown ? "scale(1)" : `scale(${IDLE_HANDLE_SCALE})`,
32680
+ pointerEvents: isShown ? "auto" : "none"
32695
32681
  },
32696
- children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_lucide_react46.GripVertical, { className: "h-3.5 w-3.5" })
32682
+ children: visible ? /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_lucide_react46.GripVertical, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "h-3 w-1 rounded-full bg-muted-foreground/50 hover:bg-muted-foreground" })
32697
32683
  }
32698
32684
  )
32699
32685
  }
@@ -32706,7 +32692,9 @@ function TableControls({ editor, containerRef }) {
32706
32692
  }),
32707
32693
  layout.columnHandles.map((columnHandle) => {
32708
32694
  const menuKey = getColumnMenuKey(columnHandle.index);
32695
+ const isActive = columnHandle.index === layout.activeColumnIndex;
32709
32696
  const visible = controlsVisible || hoverState.columnHandleIndex === columnHandle.index || openMenuKey === menuKey;
32697
+ const isShown = visible || isActive;
32710
32698
  return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
32711
32699
  "div",
32712
32700
  {
@@ -32720,7 +32708,7 @@ function TableControls({ editor, containerRef }) {
32720
32708
  Tooltip,
32721
32709
  {
32722
32710
  placement: "top",
32723
- disabled: openMenuKey === menuKey,
32711
+ disabled: openMenuKey === menuKey || !visible && isActive,
32724
32712
  content: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "text-xs font-medium", children: `${t("tableMenu.dragColumn")} ${columnHandle.index + 1}` }),
32725
32713
  children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "inline-flex", children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
32726
32714
  DropdownMenu,
@@ -32757,16 +32745,15 @@ function TableControls({ editor, containerRef }) {
32757
32745
  document.body.style.cursor = "grabbing";
32758
32746
  },
32759
32747
  className: cn(
32760
- "inline-flex h-6 w-6 items-center justify-center rounded-full",
32761
- "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
32762
- "cursor-grab active:cursor-grabbing",
32763
- "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
32748
+ "inline-flex h-6 w-6 items-center justify-center rounded-full transition-[opacity,transform,colors,border,background-color] duration-150",
32749
+ visible ? "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur hover:bg-accent hover:text-foreground cursor-grab active:cursor-grabbing" : "border-transparent bg-transparent cursor-pointer"
32764
32750
  ),
32765
32751
  style: {
32766
- opacity: visible ? 1 : Number(IDLE_HANDLE_OPACITY),
32767
- transform: visible ? "scale(1)" : `scale(${IDLE_HANDLE_SCALE})`
32752
+ opacity: isShown ? 1 : 0,
32753
+ transform: isShown ? "scale(1)" : `scale(${IDLE_HANDLE_SCALE})`,
32754
+ pointerEvents: isShown ? "auto" : "none"
32768
32755
  },
32769
- children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_lucide_react46.GripHorizontal, { className: "h-3.5 w-3.5" })
32756
+ children: visible ? /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_lucide_react46.GripHorizontal, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "h-1 w-3 rounded-full bg-muted-foreground/50 hover:bg-muted-foreground" })
32770
32757
  }
32771
32758
  )
32772
32759
  }
@@ -32814,8 +32801,9 @@ function TableControls({ editor, containerRef }) {
32814
32801
  "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
32815
32802
  ),
32816
32803
  style: {
32817
- opacity: controlsVisible || hoverState.menuVisible || tableMenuOpen ? 1 : 0.5,
32818
- transform: controlsVisible || hoverState.menuVisible || tableMenuOpen ? "scale(1)" : "scale(0.82)"
32804
+ opacity: controlsVisible || hoverState.menuVisible || tableMenuOpen ? 1 : 0,
32805
+ transform: controlsVisible || hoverState.menuVisible || tableMenuOpen ? "scale(1)" : "scale(0.82)",
32806
+ pointerEvents: controlsVisible || hoverState.menuVisible || tableMenuOpen ? "auto" : "none"
32819
32807
  },
32820
32808
  children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_lucide_react46.MoreHorizontal, { className: "h-4 w-4" })
32821
32809
  }
@@ -32857,8 +32845,9 @@ function TableControls({ editor, containerRef }) {
32857
32845
  left: columnRailLeft,
32858
32846
  width: controlsVisible || hoverState.addColumnVisible ? 18 : 12,
32859
32847
  height: controlsVisible || hoverState.addColumnVisible ? visibleTableHeight : 48,
32860
- opacity: controlsVisible || hoverState.addColumnVisible ? 1 : 0.45,
32861
- transform: controlsVisible || hoverState.addColumnVisible ? "scale(1)" : "scale(0.92)"
32848
+ opacity: controlsVisible || hoverState.addColumnVisible ? 1 : 0,
32849
+ transform: controlsVisible || hoverState.addColumnVisible ? "scale(1)" : "scale(0.92)",
32850
+ pointerEvents: controlsVisible || hoverState.addColumnVisible ? "auto" : "none"
32862
32851
  },
32863
32852
  children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "text-sm font-medium leading-none", children: "+" })
32864
32853
  }
@@ -32896,8 +32885,9 @@ function TableControls({ editor, containerRef }) {
32896
32885
  left: controlsVisible || hoverState.addRowVisible ? rowRailLeft : rowRailLeft + Math.max(0, visibleTableWidth / 2 - 24),
32897
32886
  width: controlsVisible || hoverState.addRowVisible ? visibleTableWidth : 48,
32898
32887
  height: controlsVisible || hoverState.addRowVisible ? 16 : 12,
32899
- opacity: controlsVisible || hoverState.addRowVisible ? 1 : 0.45,
32900
- transform: controlsVisible || hoverState.addRowVisible ? "scale(1)" : "scale(0.92)"
32888
+ opacity: controlsVisible || hoverState.addRowVisible ? 1 : 0,
32889
+ transform: controlsVisible || hoverState.addRowVisible ? "scale(1)" : "scale(0.92)",
32890
+ pointerEvents: controlsVisible || hoverState.addRowVisible ? "auto" : "none"
32901
32891
  },
32902
32892
  children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "text-sm font-medium leading-none", children: "+" })
32903
32893
  }