@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.js CHANGED
@@ -828,7 +828,8 @@ var en_default = {
828
828
  dragColumn: "Drag Column",
829
829
  alignLeft: "Align Table Left",
830
830
  alignCenter: "Align Table Center",
831
- alignRight: "Align Table Right"
831
+ alignRight: "Align Table Right",
832
+ cellBackground: "Cell Background"
832
833
  }
833
834
  }
834
835
  };
@@ -1097,7 +1098,8 @@ var vi_default = {
1097
1098
  dragColumn: "K\xE9o c\u1ED9t",
1098
1099
  alignLeft: "C\u0103n b\u1EA3ng tr\xE1i",
1099
1100
  alignCenter: "C\u0103n b\u1EA3ng gi\u1EEFa",
1100
- alignRight: "C\u0103n b\u1EA3ng ph\u1EA3i"
1101
+ alignRight: "C\u0103n b\u1EA3ng ph\u1EA3i",
1102
+ cellBackground: "M\xE0u n\u1EC1n \xF4"
1101
1103
  }
1102
1104
  }
1103
1105
  };
@@ -1365,7 +1367,8 @@ var ko_default = {
1365
1367
  dragColumn: "\uC5F4 \uB4DC\uB798\uADF8",
1366
1368
  alignLeft: "\uD45C \uC67C\uCABD \uC815\uB82C",
1367
1369
  alignCenter: "\uD45C \uAC00\uC6B4\uB370 \uC815\uB82C",
1368
- alignRight: "\uD45C \uC624\uB978\uCABD \uC815\uB82C"
1370
+ alignRight: "\uD45C \uC624\uB978\uCABD \uC815\uB82C",
1371
+ cellBackground: "\uC140 \uBC30\uACBD\uC0C9"
1369
1372
  }
1370
1373
  }
1371
1374
  };
@@ -1633,7 +1636,8 @@ var ja_default = {
1633
1636
  dragColumn: "\u5217\u3092\u30C9\u30E9\u30C3\u30B0",
1634
1637
  alignLeft: "\u8868\u3092\u5DE6\u5BC4\u305B",
1635
1638
  alignCenter: "\u8868\u3092\u4E2D\u592E\u63C3\u3048",
1636
- alignRight: "\u8868\u3092\u53F3\u5BC4\u305B"
1639
+ alignRight: "\u8868\u3092\u53F3\u5BC4\u305B",
1640
+ cellBackground: "\u30BB\u30EB\u80CC\u666F\u8272"
1637
1641
  }
1638
1642
  }
1639
1643
  };
@@ -7218,7 +7222,7 @@ var DropdownMenuItem = ({
7218
7222
  disabled,
7219
7223
  onMouseDown: (e) => e.preventDefault(),
7220
7224
  className: cn(
7221
- "flex w-full items-center gap-2 px-3 py-2 text-sm rounded-lg transition-colors group",
7225
+ "flex w-full items-center gap-2 px-3 py-2 text-sm rounded-lg transition-colors group cursor-pointer",
7222
7226
  "hover:bg-accent hover:text-accent-foreground",
7223
7227
  "focus:bg-accent focus:text-accent-foreground focus:outline-none",
7224
7228
  "disabled:opacity-50 disabled:cursor-not-allowed",
@@ -23836,6 +23840,7 @@ import React78, { useEffect as useEffect36, useImperativeHandle as useImperative
23836
23840
  import { useEditor, EditorContent } from "@tiptap/react";
23837
23841
 
23838
23842
  // src/components/UEditor/extensions.ts
23843
+ import { mergeAttributes as mergeAttributes2 } from "@tiptap/core";
23839
23844
  import Document from "@tiptap/extension-document";
23840
23845
  import Paragraph from "@tiptap/extension-paragraph";
23841
23846
  import Text from "@tiptap/extension-text";
@@ -25161,6 +25166,64 @@ var UEditorTable = Table3.extend({
25161
25166
  var table_align_default = UEditorTable;
25162
25167
 
25163
25168
  // src/components/UEditor/extensions.ts
25169
+ var CustomTableCell = TableCell2.extend({
25170
+ addAttributes() {
25171
+ return {
25172
+ ...this.parent?.(),
25173
+ backgroundColor: {
25174
+ default: null,
25175
+ parseHTML: (element) => element.style.backgroundColor || element.getAttribute("data-background-color") || null,
25176
+ renderHTML: (attributes) => {
25177
+ if (!attributes.backgroundColor) {
25178
+ return {};
25179
+ }
25180
+ return {
25181
+ "data-background-color": attributes.backgroundColor
25182
+ };
25183
+ }
25184
+ }
25185
+ };
25186
+ },
25187
+ renderHTML({ HTMLAttributes }) {
25188
+ const style = HTMLAttributes.style || "";
25189
+ const bg = HTMLAttributes["data-background-color"];
25190
+ const mergedStyle = bg ? `${style}; background-color: ${bg}`.replace(/^;/, "") : style;
25191
+ return [
25192
+ "td",
25193
+ mergeAttributes2(this.options.HTMLAttributes, HTMLAttributes, mergedStyle ? { style: mergedStyle } : {}),
25194
+ 0
25195
+ ];
25196
+ }
25197
+ });
25198
+ var CustomTableHeader = TableHeader2.extend({
25199
+ addAttributes() {
25200
+ return {
25201
+ ...this.parent?.(),
25202
+ backgroundColor: {
25203
+ default: null,
25204
+ parseHTML: (element) => element.style.backgroundColor || element.getAttribute("data-background-color") || null,
25205
+ renderHTML: (attributes) => {
25206
+ if (!attributes.backgroundColor) {
25207
+ return {};
25208
+ }
25209
+ return {
25210
+ "data-background-color": attributes.backgroundColor
25211
+ };
25212
+ }
25213
+ }
25214
+ };
25215
+ },
25216
+ renderHTML({ HTMLAttributes }) {
25217
+ const style = HTMLAttributes.style || "";
25218
+ const bg = HTMLAttributes["data-background-color"];
25219
+ const mergedStyle = bg ? `${style}; background-color: ${bg}`.replace(/^;/, "") : style;
25220
+ return [
25221
+ "th",
25222
+ mergeAttributes2(this.options.HTMLAttributes, HTMLAttributes, mergedStyle ? { style: mergedStyle } : {}),
25223
+ 0
25224
+ ];
25225
+ }
25226
+ });
25164
25227
  var lowlight = createLowlight(common);
25165
25228
  function buildUEditorExtensions({
25166
25229
  placeholder,
@@ -25259,12 +25322,12 @@ function buildUEditorExtensions({
25259
25322
  }
25260
25323
  }),
25261
25324
  table_row_default,
25262
- TableCell2.configure({
25325
+ CustomTableCell.configure({
25263
25326
  HTMLAttributes: {
25264
25327
  class: "border border-border p-2 min-w-25"
25265
25328
  }
25266
25329
  }),
25267
- TableHeader2.configure({
25330
+ CustomTableHeader.configure({
25268
25331
  HTMLAttributes: {
25269
25332
  class: "border border-border p-2 bg-muted font-semibold min-w-25"
25270
25333
  }
@@ -25298,7 +25361,6 @@ function buildUEditorExtensions({
25298
25361
 
25299
25362
  // src/components/UEditor/toolbar.tsx
25300
25363
  import React73, { useRef as useRef31, useState as useState44 } from "react";
25301
- import { createPortal as createPortal8 } from "react-dom";
25302
25364
  import { useEditorState } from "@tiptap/react";
25303
25365
  import {
25304
25366
  AlignCenter,
@@ -25309,8 +25371,10 @@ import {
25309
25371
  ArrowLeft,
25310
25372
  ArrowRight,
25311
25373
  ArrowUp,
25374
+ Baseline,
25312
25375
  Bold as BoldIcon,
25313
25376
  ChevronDown as ChevronDown7,
25377
+ ChevronsUpDown,
25314
25378
  Code as CodeIcon,
25315
25379
  FileCode as FileCode3,
25316
25380
  Heading1 as Heading1Icon,
@@ -25339,7 +25403,7 @@ import {
25339
25403
 
25340
25404
  // src/components/UEditor/colors.tsx
25341
25405
  import { useMemo as useMemo22, useRef as useRef29 } from "react";
25342
- import { Check as Check10, Highlighter, Palette as Palette2 } from "lucide-react";
25406
+ import { Check as Check10, Highlighter, Palette as Palette2, Paintbrush } from "lucide-react";
25343
25407
  import { jsx as jsx78, jsxs as jsxs65 } from "react/jsx-runtime";
25344
25408
  var TextColorIcon = ({ color }) => {
25345
25409
  const underlineColor = color && color !== "inherit" ? color : "currentColor";
@@ -25369,6 +25433,20 @@ var HighlightColorIcon = ({ color }) => {
25369
25433
  )
25370
25434
  ] });
25371
25435
  };
25436
+ var CellBgColorIcon = ({ color }) => {
25437
+ const underlineColor = color && color !== "inherit" ? color : "currentColor";
25438
+ return /* @__PURE__ */ jsxs65("span", { className: "relative flex h-5 w-5 items-center justify-center leading-none", children: [
25439
+ /* @__PURE__ */ jsx78(Paintbrush, { className: "h-4 w-4" }),
25440
+ /* @__PURE__ */ jsx78(
25441
+ "span",
25442
+ {
25443
+ "aria-hidden": "true",
25444
+ className: "absolute bottom-0 left-1/2 h-0.5 w-4 -translate-x-1/2 rounded-full",
25445
+ style: { backgroundColor: underlineColor }
25446
+ }
25447
+ )
25448
+ ] });
25449
+ };
25372
25450
  var EDITOR_COLOR_SWATCHES = [
25373
25451
  "#000000",
25374
25452
  "#3f3f46",
@@ -25828,7 +25906,7 @@ var ToolbarButton = React73.forwardRef(({ onClick, onMouseDown, active, disabled
25828
25906
  onClick,
25829
25907
  disabled,
25830
25908
  className: cn(
25831
- "flex items-center justify-center w-8 h-8 rounded-md transition-colors duration-150",
25909
+ "flex items-center justify-center w-7 h-7 rounded-md transition-colors duration-150 cursor-pointer",
25832
25910
  "gap-0.5 [&_svg+svg]:-ml-1",
25833
25911
  "hover:bg-accent",
25834
25912
  "focus:outline-none focus:ring-2 focus:ring-primary/20",
@@ -25907,11 +25985,6 @@ var EditorToolbar = ({
25907
25985
  const fileInputRef = useRef31(null);
25908
25986
  const [isUploadingImage, setIsUploadingImage] = useState44(false);
25909
25987
  const [imageUploadError, setImageUploadError] = useState44(null);
25910
- const [fontSizeDraft, setFontSizeDraft] = useState44("");
25911
- const [isFontSizeMenuOpen, setIsFontSizeMenuOpen] = useState44(false);
25912
- const [fontSizeMenuPosition, setFontSizeMenuPosition] = useState44({ top: 0, left: 0 });
25913
- const fontSizeControlRef = useRef31(null);
25914
- const fontSizeMenuRef = useRef31(null);
25915
25988
  const isImageSelected = editor.isActive("image");
25916
25989
  const imageAttrs = editor.getAttributes("image");
25917
25990
  const tableAttrs = editor.getAttributes("table");
@@ -25937,53 +26010,6 @@ var EditorToolbar = ({
25937
26010
  const currentLineHeightLabel = availableLineHeights.find((option) => normalizeStyleValue(option.value) === currentLineHeight)?.label ?? t("toolbar.lineHeightDefault");
25938
26011
  const currentLetterSpacingLabel = availableLetterSpacings.find((option) => normalizeStyleValue(option.value) === currentLetterSpacing)?.label ?? t("toolbar.letterSpacingDefault");
25939
26012
  const displayedFontFamilyLabel = currentFontFamily ? currentFontFamilyLabel : availableFontFamilies[0]?.label ?? t("toolbar.fontDefault");
25940
- React73.useEffect(() => {
25941
- if (document.activeElement === fontSizeControlRef.current?.querySelector("input")) return;
25942
- setFontSizeDraft(currentFontSize.replace(/px$/i, "") || "16");
25943
- }, [currentFontSize]);
25944
- const applyFontSizeDraft = () => {
25945
- const normalized = fontSizeDraft.trim();
25946
- if (!normalized) {
25947
- editor.chain().focus().unsetFontSize().run();
25948
- return;
25949
- }
25950
- const parsed = Number.parseFloat(normalized);
25951
- if (!Number.isFinite(parsed) || parsed <= 0) return;
25952
- const clamped = Math.min(96, Math.max(8, parsed));
25953
- editor.chain().focus().setFontSize(`${clamped}px`).run();
25954
- setFontSizeDraft(String(clamped));
25955
- };
25956
- const updateFontSizeMenuPosition = React73.useCallback(() => {
25957
- const rect = fontSizeControlRef.current?.getBoundingClientRect();
25958
- if (!rect) return;
25959
- setFontSizeMenuPosition({
25960
- top: Math.round(rect.bottom + 4),
25961
- left: Math.round(rect.left)
25962
- });
25963
- }, []);
25964
- const toggleFontSizeMenu = () => {
25965
- updateFontSizeMenuPosition();
25966
- setIsFontSizeMenuOpen((open) => !open);
25967
- };
25968
- React73.useEffect(() => {
25969
- if (!isFontSizeMenuOpen) return;
25970
- updateFontSizeMenuPosition();
25971
- const handlePointerDown = (event) => {
25972
- const target = event.target;
25973
- if (fontSizeControlRef.current?.contains(target)) return;
25974
- if (fontSizeMenuRef.current?.contains(target)) return;
25975
- setIsFontSizeMenuOpen(false);
25976
- };
25977
- const handleLayoutChange = () => updateFontSizeMenuPosition();
25978
- document.addEventListener("mousedown", handlePointerDown);
25979
- window.addEventListener("resize", handleLayoutChange);
25980
- window.addEventListener("scroll", handleLayoutChange, true);
25981
- return () => {
25982
- document.removeEventListener("mousedown", handlePointerDown);
25983
- window.removeEventListener("resize", handleLayoutChange);
25984
- window.removeEventListener("scroll", handleLayoutChange, true);
25985
- };
25986
- }, [isFontSizeMenuOpen, updateFontSizeMenuPosition]);
25987
26013
  const insertImageFiles = async (files) => {
25988
26014
  if (files.length === 0) return;
25989
26015
  setIsUploadingImage(true);
@@ -26023,21 +26049,11 @@ var EditorToolbar = ({
26023
26049
  /* @__PURE__ */ jsxs67(
26024
26050
  DropdownMenu,
26025
26051
  {
26026
- trigger: /* @__PURE__ */ jsxs67(
26027
- "button",
26028
- {
26029
- type: "button",
26030
- "aria-label": t("toolbar.fontFamily"),
26031
- className: cn(
26032
- "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",
26033
- "transition-colors hover:bg-accent focus:outline-none focus:ring-2 focus:ring-primary/20"
26034
- ),
26035
- children: [
26036
- /* @__PURE__ */ jsx81("span", { className: "truncate", children: displayedFontFamilyLabel }),
26037
- /* @__PURE__ */ jsx81(ChevronDown7, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" })
26038
- ]
26039
- }
26040
- ),
26052
+ trigger: /* @__PURE__ */ jsxs67(ToolbarButton, { onClick: () => {
26053
+ }, title: t("toolbar.fontFamily"), className: "px-1.5 w-auto gap-0.5", children: [
26054
+ /* @__PURE__ */ jsx81(Baseline, { className: "w-4 h-4" }),
26055
+ /* @__PURE__ */ jsx81(ChevronDown7, { className: "h-3 w-3 text-muted-foreground" })
26056
+ ] }),
26041
26057
  contentClassName: "max-h-80 overflow-y-auto min-w-56 p-2",
26042
26058
  children: [
26043
26059
  /* @__PURE__ */ jsx81(
@@ -26055,102 +26071,55 @@ var EditorToolbar = ({
26055
26071
  label: option.label,
26056
26072
  onClick: () => editor.chain().focus().setFontFamily(option.value).run(),
26057
26073
  active: normalizeStyleValue(option.value) === currentFontFamily,
26058
- className: "font-medium "
26074
+ className: "font-medium"
26059
26075
  },
26060
26076
  option.value
26061
26077
  ))
26062
26078
  ]
26063
26079
  }
26064
26080
  ),
26065
- /* @__PURE__ */ jsxs67(Fragment27, { children: [
26066
- /* @__PURE__ */ jsxs67(
26067
- "div",
26068
- {
26069
- ref: fontSizeControlRef,
26070
- "aria-label": t("toolbar.fontSize"),
26071
- className: cn(
26072
- "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",
26073
- "transition-colors focus-within:ring-2 focus-within:ring-primary/20"
26081
+ /* @__PURE__ */ jsxs67(
26082
+ DropdownMenu,
26083
+ {
26084
+ trigger: /* @__PURE__ */ jsxs67(ToolbarButton, { onClick: () => {
26085
+ }, title: t("toolbar.fontSize"), className: "px-1.5 w-auto gap-0.5", children: [
26086
+ /* @__PURE__ */ jsxs67("div", { className: "flex items-center gap-0.5", children: [
26087
+ /* @__PURE__ */ jsx81(ChevronsUpDown, { className: "h-3 w-3 text-muted-foreground", strokeWidth: 2.5 }),
26088
+ /* @__PURE__ */ jsx81("span", { className: "text-xs font-bold leading-none", children: "A" })
26089
+ ] }),
26090
+ /* @__PURE__ */ jsx81(ChevronDown7, { className: "h-3 w-3 text-muted-foreground" })
26091
+ ] }),
26092
+ contentClassName: "max-h-80 overflow-y-auto min-w-32 p-2",
26093
+ children: [
26094
+ /* @__PURE__ */ jsx81(
26095
+ DropdownMenuItem,
26096
+ {
26097
+ icon: Type2,
26098
+ label: t("toolbar.sizeDefault"),
26099
+ onClick: () => editor.chain().focus().unsetFontSize().run(),
26100
+ active: !currentFontSize
26101
+ }
26074
26102
  ),
26075
- children: [
26076
- /* @__PURE__ */ jsx81(
26077
- "input",
26078
- {
26079
- type: "number",
26080
- min: 8,
26081
- max: 96,
26082
- step: 1,
26083
- value: fontSizeDraft,
26084
- onChange: (e) => setFontSizeDraft(e.target.value),
26085
- onBlur: applyFontSizeDraft,
26086
- onMouseDown: (e) => e.stopPropagation(),
26087
- onClick: (e) => e.stopPropagation(),
26088
- onKeyDown: (e) => {
26089
- e.stopPropagation();
26090
- if (e.key === "Enter") {
26091
- e.preventDefault();
26092
- applyFontSizeDraft();
26093
- }
26094
- },
26095
- "aria-label": t("toolbar.fontSize"),
26096
- 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"
26097
- }
26098
- ),
26099
- /* @__PURE__ */ jsx81(
26100
- "button",
26101
- {
26102
- type: "button",
26103
- "aria-label": t("toolbar.fontSize"),
26104
- "aria-expanded": isFontSizeMenuOpen,
26105
- onClick: toggleFontSizeMenu,
26106
- className: "flex h-full w-5 items-center justify-center text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
26107
- children: /* @__PURE__ */ jsx81(ChevronDown7, { className: "h-3.5 w-3.5" })
26108
- }
26109
- )
26110
- ]
26111
- }
26112
- ),
26113
- isFontSizeMenuOpen && typeof document !== "undefined" && createPortal8(
26114
- /* @__PURE__ */ jsx81(
26115
- "div",
26116
- {
26117
- ref: fontSizeMenuRef,
26118
- 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",
26119
- style: { top: fontSizeMenuPosition.top, left: fontSizeMenuPosition.left },
26120
- children: availableFontSizes.map((option) => {
26121
- const active = normalizeStyleValue(option.value) === currentFontSize;
26122
- return /* @__PURE__ */ jsx81(
26123
- "button",
26124
- {
26125
- type: "button",
26126
- onMouseDown: (e) => e.preventDefault(),
26127
- onClick: () => {
26128
- editor.chain().focus().setFontSize(option.value).run();
26129
- setFontSizeDraft(option.label);
26130
- setIsFontSizeMenuOpen(false);
26131
- },
26132
- className: cn(
26133
- "flex h-6 w-full items-center justify-center rounded text-xs leading-none transition-colors",
26134
- active ? "bg-primary/15 text-primary" : "text-foreground hover:bg-accent hover:text-accent-foreground"
26135
- ),
26136
- children: option.label
26137
- },
26138
- option.value
26139
- );
26140
- })
26141
- }
26142
- ),
26143
- document.body
26144
- )
26145
- ] }),
26103
+ availableFontSizes.map((option) => /* @__PURE__ */ jsx81(
26104
+ DropdownMenuItem,
26105
+ {
26106
+ label: option.label,
26107
+ onClick: () => editor.chain().focus().setFontSize(option.value).run(),
26108
+ active: normalizeStyleValue(option.value) === currentFontSize
26109
+ },
26110
+ option.value
26111
+ ))
26112
+ ]
26113
+ }
26114
+ ),
26146
26115
  /* @__PURE__ */ jsxs67(
26147
26116
  DropdownMenu,
26148
26117
  {
26149
- contentClassName: "p-2",
26118
+ contentClassName: "p-1",
26150
26119
  trigger: /* @__PURE__ */ jsxs67(ToolbarButton, { onClick: () => {
26151
- }, title: t("toolbar.textStyle"), className: "px-2 w-auto gap-1", children: [
26120
+ }, title: t("toolbar.textStyle"), className: "px-1.5 w-auto gap-0.5", children: [
26152
26121
  /* @__PURE__ */ jsx81(Type2, { className: "w-4 h-4" }),
26153
- /* @__PURE__ */ jsx81(ChevronDown7, { className: "w-3 h-3" })
26122
+ /* @__PURE__ */ jsx81(ChevronDown7, { className: "h-3 w-3 text-muted-foreground" })
26154
26123
  ] }),
26155
26124
  children: [
26156
26125
  /* @__PURE__ */ jsx81(
@@ -26203,7 +26172,7 @@ var EditorToolbar = ({
26203
26172
  /* @__PURE__ */ jsx81(ArrowUp, { className: "w-3 h-3" }),
26204
26173
  /* @__PURE__ */ jsx81(ArrowDown, { className: "w-3 h-3" })
26205
26174
  ] }),
26206
- contentClassName: "max-h-72 overflow-y-auto p-2",
26175
+ contentClassName: "max-h-72 overflow-y-auto p-1",
26207
26176
  children: [
26208
26177
  /* @__PURE__ */ jsx81(
26209
26178
  DropdownMenuItem,
@@ -26234,7 +26203,7 @@ var EditorToolbar = ({
26234
26203
  /* @__PURE__ */ jsx81(ArrowLeft, { className: "w-3 h-3" }),
26235
26204
  /* @__PURE__ */ jsx81(ArrowRight, { className: "w-3 h-3" })
26236
26205
  ] }),
26237
- contentClassName: "max-h-72 overflow-y-auto p-2",
26206
+ contentClassName: "max-h-72 overflow-y-auto p-1",
26238
26207
  children: [
26239
26208
  /* @__PURE__ */ jsx81(
26240
26209
  DropdownMenuItem,
@@ -26790,7 +26759,8 @@ var EditorToolbar = ({
26790
26759
  // src/components/UEditor/menus.tsx
26791
26760
  import { useCallback as useCallback22, useEffect as useEffect34, useMemo as useMemo23, useRef as useRef32, useState as useState45 } from "react";
26792
26761
  import { useEditorState as useEditorState2 } from "@tiptap/react";
26793
- import { createPortal as createPortal9 } from "react-dom";
26762
+ import { isInTable as isSelectionInTable, setCellAttr } from "@tiptap/pm/tables";
26763
+ import { createPortal as createPortal8 } from "react-dom";
26794
26764
  import {
26795
26765
  AlignCenter as AlignCenter2,
26796
26766
  AlignLeft as AlignLeft2,
@@ -26862,6 +26832,16 @@ var FloatingMenuContent = ({ editor }) => {
26862
26832
  }
26863
26833
  );
26864
26834
  };
26835
+ function applyTableCellBackground(editor, color) {
26836
+ const value = color || null;
26837
+ const { state, view } = editor;
26838
+ const applied = setCellAttr("backgroundColor", value)(state, view.dispatch.bind(view));
26839
+ if (applied) {
26840
+ view.focus();
26841
+ return;
26842
+ }
26843
+ editor.chain().focus().setCellAttribute("backgroundColor", value).run();
26844
+ }
26865
26845
  var BubbleMenuContent = ({
26866
26846
  editor,
26867
26847
  onKeepOpenChange,
@@ -26886,6 +26866,8 @@ var BubbleMenuContent = ({
26886
26866
  const textStyleAttrs = editor.getAttributes("textStyle");
26887
26867
  const currentTextColor = normalizeStyleValue(textStyleAttrs.color) || "inherit";
26888
26868
  const currentHighlightColor = normalizeStyleValue(editor.getAttributes("highlight").color) || "";
26869
+ const currentCellBgColor = normalizeStyleValue(editor.getAttributes("tableCell").backgroundColor || editor.getAttributes("tableHeader").backgroundColor) || "";
26870
+ const isInTable2 = isSelectionInTable(editor.state);
26889
26871
  const currentFontSize = normalizeStyleValue(textStyleAttrs.fontSize);
26890
26872
  const currentLineHeight = normalizeStyleValue(textStyleAttrs.lineHeight);
26891
26873
  const quickFontSizes = useMemo23(
@@ -26943,12 +26925,13 @@ var BubbleMenuContent = ({
26943
26925
  }
26944
26926
  if (activeColorPalette) {
26945
26927
  const isTextPalette = activeColorPalette === "text";
26928
+ const isHighlightPalette = activeColorPalette === "highlight";
26946
26929
  return /* @__PURE__ */ jsxs68("div", { className: "w-56", children: [
26947
26930
  /* @__PURE__ */ jsx82(
26948
26931
  EditorColorPalette,
26949
26932
  {
26950
26933
  colors: isTextPalette ? textColors : highlightColors,
26951
- currentColor: isTextPalette ? currentTextColor : currentHighlightColor,
26934
+ currentColor: isTextPalette ? currentTextColor : isHighlightPalette ? currentHighlightColor : currentCellBgColor,
26952
26935
  onSelect: (color) => {
26953
26936
  if (isTextPalette) {
26954
26937
  if (color === "inherit") {
@@ -26956,15 +26939,17 @@ var BubbleMenuContent = ({
26956
26939
  } else {
26957
26940
  editor.chain().focus().setColor(color).run();
26958
26941
  }
26959
- } else {
26942
+ } else if (isHighlightPalette) {
26960
26943
  if (color === "") {
26961
26944
  editor.chain().focus().unsetHighlight().run();
26962
26945
  } else {
26963
26946
  editor.chain().focus().toggleHighlight({ color }).run();
26964
26947
  }
26948
+ } else {
26949
+ applyTableCellBackground(editor, color);
26965
26950
  }
26966
26951
  },
26967
- label: isTextPalette ? t("colors.textColor") : t("colors.highlight")
26952
+ label: isTextPalette ? t("colors.textColor") : isHighlightPalette ? t("colors.highlight") : t("tableMenu.cellBackground") || "Cell background"
26968
26953
  }
26969
26954
  ),
26970
26955
  /* @__PURE__ */ jsx82("div", { className: "p-2 border-t", children: /* @__PURE__ */ jsx82(
@@ -27179,7 +27164,7 @@ var BubbleMenuContent = ({
27179
27164
  ),
27180
27165
  /* @__PURE__ */ jsx82(ToolbarButton, { onClick: () => setActiveColorPalette("text"), title: t("colors.textColor"), children: /* @__PURE__ */ jsx82(TextColorIcon, { color: currentTextColor }) }),
27181
27166
  /* @__PURE__ */ jsx82(ToolbarButton, { onClick: () => setActiveColorPalette("highlight"), active: editor.isActive("highlight"), title: t("colors.highlight"), children: /* @__PURE__ */ jsx82(HighlightColorIcon, { color: currentHighlightColor }) }),
27182
- /* @__PURE__ */ jsx82("div", { className: "w-px h-6 bg-border/50 mx-1" }),
27167
+ isInTable2 && /* @__PURE__ */ jsx82(ToolbarButton, { onClick: () => setActiveColorPalette("cell-bg"), active: Boolean(currentCellBgColor), title: t("tableMenu.cellBackground") || "Cell background", children: /* @__PURE__ */ jsx82(CellBgColorIcon, { color: currentCellBgColor }) }),
27183
27168
  /* @__PURE__ */ jsx82(
27184
27169
  ToolbarButton,
27185
27170
  {
@@ -27255,7 +27240,7 @@ var CustomBubbleMenu = ({
27255
27240
  };
27256
27241
  }, [editor]);
27257
27242
  if (!isVisible) return null;
27258
- return createPortal9(
27243
+ return createPortal8(
27259
27244
  /* @__PURE__ */ jsx82(
27260
27245
  "div",
27261
27246
  {
@@ -27311,7 +27296,7 @@ var CustomFloatingMenu = ({ editor }) => {
27311
27296
  };
27312
27297
  }, [editor]);
27313
27298
  if (!isVisible) return null;
27314
- return createPortal9(
27299
+ return createPortal8(
27315
27300
  /* @__PURE__ */ jsx82(
27316
27301
  "div",
27317
27302
  {
@@ -31907,15 +31892,12 @@ var FALLBACK_TABLE_COLUMN_WIDTH = 160;
31907
31892
  var MENU_HOVER_PADDING = 18;
31908
31893
  var ROW_HANDLE_HOVER_WIDTH = 28;
31909
31894
  var COLUMN_HANDLE_HOVER_HEIGHT = 28;
31910
- var ROW_HANDLE_GUTTER = 20;
31911
31895
  var TABLE_MENU_TOP_OFFSET = 10;
31912
- var COLUMN_HANDLE_TOP_OFFSET = 8;
31913
31896
  var ADD_COLUMN_RAIL_GAP = 4;
31914
31897
  var ADD_ROW_RAIL_GAP = 4;
31915
31898
  var ADD_COLUMN_HOVER_WIDTH = 24;
31916
31899
  var ADD_ROW_HOVER_HEIGHT = 24;
31917
31900
  var HANDLE_HOVER_RADIUS = 14;
31918
- var IDLE_HANDLE_OPACITY = "0.4";
31919
31901
  var IDLE_HANDLE_SCALE = "0.78";
31920
31902
  var DEFAULT_HOVER_STATE = {
31921
31903
  menuVisible: false,
@@ -32155,11 +32137,16 @@ function TableControls({ editor, containerRef }) {
32155
32137
  const directColumnHandleIndex = directColumnHandle instanceof HTMLElement ? Number.parseInt(directColumnHandle.dataset.columnHandleIndex ?? "", 10) : Number.NaN;
32156
32138
  const visibleTableWidth2 = Math.min(activeLayout.tableWidth, activeLayout.viewportWidth);
32157
32139
  const visibleTableHeight2 = Math.min(activeLayout.tableHeight, activeLayout.viewportHeight);
32140
+ const isMouseInTable = relativeX >= activeLayout.tableLeft && relativeX <= activeLayout.tableLeft + activeLayout.tableWidth && relativeY >= activeLayout.tableTop && relativeY <= activeLayout.tableTop + activeLayout.tableHeight;
32158
32141
  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;
32159
32142
  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;
32160
- 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;
32161
- const addColumnVisible = Boolean(directAddColumn) || relativeX >= activeLayout.tableLeft + visibleTableWidth2 && relativeX <= activeLayout.tableLeft + visibleTableWidth2 + ADD_COLUMN_HOVER_WIDTH && relativeY >= activeLayout.tableTop && relativeY <= activeLayout.tableTop + visibleTableHeight2;
32162
- const addRowVisible = Boolean(directAddRow) || relativeY >= activeLayout.tableTop + visibleTableHeight2 && relativeY <= activeLayout.tableTop + visibleTableHeight2 + ADD_ROW_HOVER_HEIGHT && relativeX >= activeLayout.tableLeft && relativeX <= activeLayout.tableLeft + visibleTableWidth2;
32143
+ 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;
32144
+ const lastRow = activeLayout.rowHandles[activeLayout.rowHandles.length - 1];
32145
+ const lastCol = activeLayout.columnHandles[activeLayout.columnHandles.length - 1];
32146
+ const isMouseInLastColumn = lastCol ? relativeX >= lastCol.start && relativeX <= lastCol.start + lastCol.size && relativeY >= activeLayout.tableTop && relativeY <= activeLayout.tableTop + visibleTableHeight2 : false;
32147
+ const addColumnVisible = Boolean(directAddColumn) || relativeX >= activeLayout.tableLeft + visibleTableWidth2 && relativeX <= activeLayout.tableLeft + visibleTableWidth2 + ADD_COLUMN_HOVER_WIDTH && relativeY >= activeLayout.tableTop && relativeY <= activeLayout.tableTop + visibleTableHeight2 || isMouseInLastColumn;
32148
+ const isMouseInLastRow = lastRow ? relativeY >= lastRow.start && relativeY <= lastRow.start + lastRow.size && relativeX >= activeLayout.tableLeft && relativeX <= activeLayout.tableLeft + visibleTableWidth2 : false;
32149
+ const addRowVisible = Boolean(directAddRow) || relativeY >= activeLayout.tableTop + visibleTableHeight2 && relativeY <= activeLayout.tableTop + visibleTableHeight2 + ADD_ROW_HOVER_HEIGHT && relativeX >= activeLayout.tableLeft && relativeX <= activeLayout.tableLeft + visibleTableWidth2 || isMouseInLastRow;
32163
32150
  setHoverState((prev) => {
32164
32151
  if (prev.menuVisible === menuVisible && prev.addColumnVisible === addColumnVisible && prev.addRowVisible === addRowVisible && prev.rowHandleIndex === rowHandleIndex && prev.columnHandleIndex === columnHandleIndex) {
32165
32152
  return prev;
@@ -32527,8 +32514,8 @@ function TableControls({ editor, containerRef }) {
32527
32514
  }
32528
32515
  const menuTop = Math.max(8, layout.tableTop - TABLE_MENU_TOP_OFFSET);
32529
32516
  const menuLeft = Math.max(8, layout.tableLeft);
32530
- const rowHandleLeft = Math.max(8, layout.tableLeft - ROW_HANDLE_GUTTER);
32531
- const columnHandleTop = Math.max(8, layout.tableTop - COLUMN_HANDLE_TOP_OFFSET);
32517
+ const rowHandleLeft = layout.tableLeft - 12;
32518
+ const columnHandleTop = layout.tableTop - 12;
32532
32519
  const visibleTableWidth = Math.min(layout.tableWidth, layout.viewportWidth);
32533
32520
  const visibleTableHeight = Math.min(layout.tableHeight, layout.viewportHeight);
32534
32521
  const columnRailTop = layout.tableTop;
@@ -32541,7 +32528,9 @@ function TableControls({ editor, containerRef }) {
32541
32528
  return /* @__PURE__ */ jsxs70(Fragment29, { children: [
32542
32529
  layout.rowHandles.map((rowHandle) => {
32543
32530
  const menuKey = getRowMenuKey(rowHandle.index);
32531
+ const isActive = rowHandle.index === layout.activeRowIndex;
32544
32532
  const visible = controlsVisible || hoverState.rowHandleIndex === rowHandle.index || openMenuKey === menuKey;
32533
+ const isShown = visible || isActive;
32545
32534
  return /* @__PURE__ */ jsx83(
32546
32535
  "div",
32547
32536
  {
@@ -32555,7 +32544,7 @@ function TableControls({ editor, containerRef }) {
32555
32544
  Tooltip,
32556
32545
  {
32557
32546
  placement: "right",
32558
- disabled: openMenuKey === menuKey,
32547
+ disabled: openMenuKey === menuKey || !visible && isActive,
32559
32548
  content: /* @__PURE__ */ jsx83("span", { className: "text-xs font-medium", children: `${t("tableMenu.dragRow")} ${rowHandle.index + 1}` }),
32560
32549
  children: /* @__PURE__ */ jsx83("span", { className: "inline-flex", children: /* @__PURE__ */ jsx83(
32561
32550
  DropdownMenu,
@@ -32592,16 +32581,15 @@ function TableControls({ editor, containerRef }) {
32592
32581
  document.body.style.cursor = "grabbing";
32593
32582
  },
32594
32583
  className: cn(
32595
- "inline-flex h-6 w-6 items-center justify-center rounded-full",
32596
- "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
32597
- "cursor-grab active:cursor-grabbing",
32598
- "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
32584
+ "inline-flex h-6 w-6 items-center justify-center rounded-full transition-[opacity,transform,colors,border,background-color] duration-150",
32585
+ 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"
32599
32586
  ),
32600
32587
  style: {
32601
- opacity: visible ? 1 : Number(IDLE_HANDLE_OPACITY),
32602
- transform: visible ? "scale(1)" : `scale(${IDLE_HANDLE_SCALE})`
32588
+ opacity: isShown ? 1 : 0,
32589
+ transform: isShown ? "scale(1)" : `scale(${IDLE_HANDLE_SCALE})`,
32590
+ pointerEvents: isShown ? "auto" : "none"
32603
32591
  },
32604
- children: /* @__PURE__ */ jsx83(GripVertical3, { className: "h-3.5 w-3.5" })
32592
+ children: visible ? /* @__PURE__ */ jsx83(GripVertical3, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx83("div", { className: "h-3 w-1 rounded-full bg-muted-foreground/50 hover:bg-muted-foreground" })
32605
32593
  }
32606
32594
  )
32607
32595
  }
@@ -32614,7 +32602,9 @@ function TableControls({ editor, containerRef }) {
32614
32602
  }),
32615
32603
  layout.columnHandles.map((columnHandle) => {
32616
32604
  const menuKey = getColumnMenuKey(columnHandle.index);
32605
+ const isActive = columnHandle.index === layout.activeColumnIndex;
32617
32606
  const visible = controlsVisible || hoverState.columnHandleIndex === columnHandle.index || openMenuKey === menuKey;
32607
+ const isShown = visible || isActive;
32618
32608
  return /* @__PURE__ */ jsx83(
32619
32609
  "div",
32620
32610
  {
@@ -32628,7 +32618,7 @@ function TableControls({ editor, containerRef }) {
32628
32618
  Tooltip,
32629
32619
  {
32630
32620
  placement: "top",
32631
- disabled: openMenuKey === menuKey,
32621
+ disabled: openMenuKey === menuKey || !visible && isActive,
32632
32622
  content: /* @__PURE__ */ jsx83("span", { className: "text-xs font-medium", children: `${t("tableMenu.dragColumn")} ${columnHandle.index + 1}` }),
32633
32623
  children: /* @__PURE__ */ jsx83("span", { className: "inline-flex", children: /* @__PURE__ */ jsx83(
32634
32624
  DropdownMenu,
@@ -32665,16 +32655,15 @@ function TableControls({ editor, containerRef }) {
32665
32655
  document.body.style.cursor = "grabbing";
32666
32656
  },
32667
32657
  className: cn(
32668
- "inline-flex h-6 w-6 items-center justify-center rounded-full",
32669
- "border border-border/70 bg-background/95 text-muted-foreground shadow-sm backdrop-blur",
32670
- "cursor-grab active:cursor-grabbing",
32671
- "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
32658
+ "inline-flex h-6 w-6 items-center justify-center rounded-full transition-[opacity,transform,colors,border,background-color] duration-150",
32659
+ 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"
32672
32660
  ),
32673
32661
  style: {
32674
- opacity: visible ? 1 : Number(IDLE_HANDLE_OPACITY),
32675
- transform: visible ? "scale(1)" : `scale(${IDLE_HANDLE_SCALE})`
32662
+ opacity: isShown ? 1 : 0,
32663
+ transform: isShown ? "scale(1)" : `scale(${IDLE_HANDLE_SCALE})`,
32664
+ pointerEvents: isShown ? "auto" : "none"
32676
32665
  },
32677
- children: /* @__PURE__ */ jsx83(GripHorizontal, { className: "h-3.5 w-3.5" })
32666
+ children: visible ? /* @__PURE__ */ jsx83(GripHorizontal, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx83("div", { className: "h-1 w-3 rounded-full bg-muted-foreground/50 hover:bg-muted-foreground" })
32678
32667
  }
32679
32668
  )
32680
32669
  }
@@ -32722,8 +32711,9 @@ function TableControls({ editor, containerRef }) {
32722
32711
  "transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground"
32723
32712
  ),
32724
32713
  style: {
32725
- opacity: controlsVisible || hoverState.menuVisible || tableMenuOpen ? 1 : 0.5,
32726
- transform: controlsVisible || hoverState.menuVisible || tableMenuOpen ? "scale(1)" : "scale(0.82)"
32714
+ opacity: controlsVisible || hoverState.menuVisible || tableMenuOpen ? 1 : 0,
32715
+ transform: controlsVisible || hoverState.menuVisible || tableMenuOpen ? "scale(1)" : "scale(0.82)",
32716
+ pointerEvents: controlsVisible || hoverState.menuVisible || tableMenuOpen ? "auto" : "none"
32727
32717
  },
32728
32718
  children: /* @__PURE__ */ jsx83(MoreHorizontal2, { className: "h-4 w-4" })
32729
32719
  }
@@ -32765,8 +32755,9 @@ function TableControls({ editor, containerRef }) {
32765
32755
  left: columnRailLeft,
32766
32756
  width: controlsVisible || hoverState.addColumnVisible ? 18 : 12,
32767
32757
  height: controlsVisible || hoverState.addColumnVisible ? visibleTableHeight : 48,
32768
- opacity: controlsVisible || hoverState.addColumnVisible ? 1 : 0.45,
32769
- transform: controlsVisible || hoverState.addColumnVisible ? "scale(1)" : "scale(0.92)"
32758
+ opacity: controlsVisible || hoverState.addColumnVisible ? 1 : 0,
32759
+ transform: controlsVisible || hoverState.addColumnVisible ? "scale(1)" : "scale(0.92)",
32760
+ pointerEvents: controlsVisible || hoverState.addColumnVisible ? "auto" : "none"
32770
32761
  },
32771
32762
  children: /* @__PURE__ */ jsx83("span", { className: "text-sm font-medium leading-none", children: "+" })
32772
32763
  }
@@ -32804,8 +32795,9 @@ function TableControls({ editor, containerRef }) {
32804
32795
  left: controlsVisible || hoverState.addRowVisible ? rowRailLeft : rowRailLeft + Math.max(0, visibleTableWidth / 2 - 24),
32805
32796
  width: controlsVisible || hoverState.addRowVisible ? visibleTableWidth : 48,
32806
32797
  height: controlsVisible || hoverState.addRowVisible ? 16 : 12,
32807
- opacity: controlsVisible || hoverState.addRowVisible ? 1 : 0.45,
32808
- transform: controlsVisible || hoverState.addRowVisible ? "scale(1)" : "scale(0.92)"
32798
+ opacity: controlsVisible || hoverState.addRowVisible ? 1 : 0,
32799
+ transform: controlsVisible || hoverState.addRowVisible ? "scale(1)" : "scale(0.92)",
32800
+ pointerEvents: controlsVisible || hoverState.addRowVisible ? "auto" : "none"
32809
32801
  },
32810
32802
  children: /* @__PURE__ */ jsx83("span", { className: "text-sm font-medium leading-none", children: "+" })
32811
32803
  }