@underverse-ui/underverse 1.0.125 → 1.0.126

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
@@ -874,6 +874,9 @@ var en_default = {
874
874
  accent: "Accent",
875
875
  textColor: "Text Color",
876
876
  highlight: "Highlight",
877
+ automatic: "Automatic",
878
+ moreColors: "More Colors...",
879
+ color: "Color",
877
880
  done: "Done"
878
881
  },
879
882
  toolbar: {
@@ -888,6 +891,7 @@ var en_default = {
888
891
  subscript: "Subscript",
889
892
  superscript: "Superscript",
890
893
  link: "Link",
894
+ removeLink: "Remove Link",
891
895
  image: "Insert Image",
892
896
  table: "Insert Table",
893
897
  alignment: "Alignment",
@@ -1139,6 +1143,9 @@ var vi_default = {
1139
1143
  accent: "Nh\u1EA5n",
1140
1144
  textColor: "M\xE0u ch\u1EEF",
1141
1145
  highlight: "N\u1ED5i b\u1EADt",
1146
+ automatic: "T\u1EF1 \u0111\u1ED9ng",
1147
+ moreColors: "Th\xEAm m\xE0u...",
1148
+ color: "M\xE0u",
1142
1149
  done: "Xong"
1143
1150
  },
1144
1151
  toolbar: {
@@ -1153,6 +1160,7 @@ var vi_default = {
1153
1160
  subscript: "Ch\u1EC9 s\u1ED1 d\u01B0\u1EDBi",
1154
1161
  superscript: "Ch\u1EC9 s\u1ED1 tr\xEAn",
1155
1162
  link: "Li\xEAn k\u1EBFt",
1163
+ removeLink: "G\u1EE1 li\xEAn k\u1EBFt",
1156
1164
  image: "Ch\xE8n \u1EA3nh",
1157
1165
  table: "Ch\xE8n b\u1EA3ng",
1158
1166
  alignment: "C\u0103n ch\u1EC9nh",
@@ -1404,6 +1412,9 @@ var ko_default = {
1404
1412
  accent: "\uAC15\uC870",
1405
1413
  textColor: "\uD14D\uC2A4\uD2B8 \uC0C9\uC0C1",
1406
1414
  highlight: "\uD615\uAD11\uD39C",
1415
+ automatic: "\uC790\uB3D9",
1416
+ moreColors: "\uB2E4\uB978 \uC0C9...",
1417
+ color: "\uC0C9\uC0C1",
1407
1418
  done: "\uC644\uB8CC"
1408
1419
  },
1409
1420
  toolbar: {
@@ -1418,6 +1429,7 @@ var ko_default = {
1418
1429
  subscript: "\uC544\uB798 \uCCA8\uC790",
1419
1430
  superscript: "\uC704 \uCCA8\uC790",
1420
1431
  link: "\uB9C1\uD06C",
1432
+ removeLink: "\uB9C1\uD06C \uC81C\uAC70",
1421
1433
  image: "\uC774\uBBF8\uC9C0",
1422
1434
  table: "\uD45C",
1423
1435
  alignment: "\uC815\uB82C",
@@ -1668,6 +1680,9 @@ var ja_default = {
1668
1680
  accent: "\u30A2\u30AF\u30BB\u30F3\u30C8",
1669
1681
  textColor: "\u30C6\u30AD\u30B9\u30C8\u8272",
1670
1682
  highlight: "\u30CF\u30A4\u30E9\u30A4\u30C8",
1683
+ automatic: "\u81EA\u52D5",
1684
+ moreColors: "\u305D\u306E\u4ED6\u306E\u8272...",
1685
+ color: "\u8272",
1671
1686
  done: "\u5B8C\u4E86"
1672
1687
  },
1673
1688
  toolbar: {
@@ -1682,6 +1697,7 @@ var ja_default = {
1682
1697
  subscript: "\u4E0B\u4ED8\u304D",
1683
1698
  superscript: "\u4E0A\u4ED8\u304D",
1684
1699
  link: "\u30EA\u30F3\u30AF",
1700
+ removeLink: "\u30EA\u30F3\u30AF\u3092\u89E3\u9664",
1685
1701
  image: "\u753B\u50CF",
1686
1702
  table: "\u8868",
1687
1703
  alignment: "\u914D\u7F6E",
@@ -23986,8 +24002,8 @@ function useLocale2() {
23986
24002
  }
23987
24003
 
23988
24004
  // src/components/UEditor/UEditor.tsx
23989
- var import_react54 = __toESM(require("react"), 1);
23990
- var import_react55 = require("@tiptap/react");
24005
+ var import_react56 = __toESM(require("react"), 1);
24006
+ var import_react57 = require("@tiptap/react");
23991
24007
 
23992
24008
  // src/components/UEditor/extensions.ts
23993
24009
  var import_extension_document = __toESM(require("@tiptap/extension-document"), 1);
@@ -25440,12 +25456,113 @@ function buildUEditorExtensions({
25440
25456
 
25441
25457
  // src/components/UEditor/toolbar.tsx
25442
25458
  var import_react49 = __toESM(require("react"), 1);
25459
+ var import_react_dom8 = require("react-dom");
25460
+ var import_react50 = require("@tiptap/react");
25443
25461
  var import_lucide_react44 = require("lucide-react");
25444
25462
 
25445
25463
  // src/components/UEditor/colors.tsx
25446
25464
  var import_react47 = require("react");
25447
25465
  var import_lucide_react42 = require("lucide-react");
25448
25466
  var import_jsx_runtime78 = require("react/jsx-runtime");
25467
+ var TextColorIcon = ({ color }) => {
25468
+ const underlineColor = color && color !== "inherit" ? color : "currentColor";
25469
+ return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("span", { className: "relative flex h-5 w-5 items-center justify-center leading-none", children: [
25470
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "text-[15px] font-semibold leading-none", children: "A" }),
25471
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
25472
+ "span",
25473
+ {
25474
+ "aria-hidden": "true",
25475
+ className: "absolute bottom-0 left-1/2 h-0.5 w-4 -translate-x-1/2 rounded-full",
25476
+ style: { backgroundColor: underlineColor }
25477
+ }
25478
+ )
25479
+ ] });
25480
+ };
25481
+ var HighlightColorIcon = ({ color }) => {
25482
+ const underlineColor = color || "currentColor";
25483
+ return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("span", { className: "relative flex h-5 w-5 items-center justify-center leading-none", children: [
25484
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_lucide_react42.Highlighter, { className: "h-4 w-4" }),
25485
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
25486
+ "span",
25487
+ {
25488
+ "aria-hidden": "true",
25489
+ className: "absolute bottom-0 left-1/2 h-0.5 w-4 -translate-x-1/2 rounded-full",
25490
+ style: { backgroundColor: underlineColor }
25491
+ }
25492
+ )
25493
+ ] });
25494
+ };
25495
+ var EDITOR_COLOR_SWATCHES = [
25496
+ "#000000",
25497
+ "#3f3f46",
25498
+ "#713f12",
25499
+ "#14532d",
25500
+ "#164e63",
25501
+ "#1e3a8a",
25502
+ "#3730a3",
25503
+ "#404040",
25504
+ "#b91c1c",
25505
+ "#c2410c",
25506
+ "#a16207",
25507
+ "#15803d",
25508
+ "#0f766e",
25509
+ "#2563eb",
25510
+ "#4f46e5",
25511
+ "#737373",
25512
+ "#ef4444",
25513
+ "#f97316",
25514
+ "#eab308",
25515
+ "#22c55e",
25516
+ "#14b8a6",
25517
+ "#3b82f6",
25518
+ "#7c3aed",
25519
+ "#a3a3a3",
25520
+ "#f43f5e",
25521
+ "#f59e0b",
25522
+ "#facc15",
25523
+ "#00e676",
25524
+ "#22d3ee",
25525
+ "#06b6d4",
25526
+ "#be185d",
25527
+ "#bdbdbd",
25528
+ "#f9a8d4",
25529
+ "#fecaca",
25530
+ "#fde68a",
25531
+ "#bbf7d0",
25532
+ "#a7f3d0",
25533
+ "#bae6fd",
25534
+ "#c4b5fd",
25535
+ "#f5f5f5"
25536
+ ];
25537
+ var HIGHLIGHT_COLOR_SWATCHES = [
25538
+ "#fef08a",
25539
+ "#fde68a",
25540
+ "#fed7aa",
25541
+ "#fecaca",
25542
+ "#fbcfe8",
25543
+ "#e9d5ff",
25544
+ "#c7d2fe",
25545
+ "#bfdbfe",
25546
+ "#bae6fd",
25547
+ "#ccfbf1",
25548
+ "#bbf7d0",
25549
+ "#d9f99d",
25550
+ "#e5e7eb",
25551
+ "#fca5a5",
25552
+ "#fdba74",
25553
+ "#facc15",
25554
+ "#86efac",
25555
+ "#5eead4",
25556
+ "#7dd3fc",
25557
+ "#a5b4fc",
25558
+ "#d8b4fe",
25559
+ "#f0abfc",
25560
+ "#f9a8d4",
25561
+ "#d4d4d4"
25562
+ ];
25563
+ function buildColorOptions(colors, prefix) {
25564
+ return colors.map((color, index) => ({ name: `${prefix} ${index + 1}`, color }));
25565
+ }
25449
25566
  var useEditorColors = () => {
25450
25567
  const t = useSmartTranslations("UEditor");
25451
25568
  const textColors = (0, import_react47.useMemo)(
@@ -25457,7 +25574,8 @@ var useEditorColors = () => {
25457
25574
  { name: t("colors.success"), color: "var(--success)", cssClass: "text-success" },
25458
25575
  { name: t("colors.warning"), color: "var(--warning)", cssClass: "text-warning" },
25459
25576
  { name: t("colors.destructive"), color: "var(--destructive)", cssClass: "text-destructive" },
25460
- { name: t("colors.info"), color: "var(--info)", cssClass: "text-info" }
25577
+ { name: t("colors.info"), color: "var(--info)", cssClass: "text-info" },
25578
+ ...buildColorOptions(EDITOR_COLOR_SWATCHES, t("colors.color"))
25461
25579
  ],
25462
25580
  [t]
25463
25581
  );
@@ -25471,7 +25589,8 @@ var useEditorColors = () => {
25471
25589
  { name: t("colors.warning"), color: "color-mix(in oklch, var(--warning) 20%, transparent)", cssClass: "bg-warning/20" },
25472
25590
  { name: t("colors.destructive"), color: "color-mix(in oklch, var(--destructive) 20%, transparent)", cssClass: "bg-destructive/20" },
25473
25591
  { name: t("colors.info"), color: "color-mix(in oklch, var(--info) 20%, transparent)", cssClass: "bg-info/20" },
25474
- { name: t("colors.accent"), color: "var(--accent)", cssClass: "bg-accent" }
25592
+ { name: t("colors.accent"), color: "var(--accent)", cssClass: "bg-accent" },
25593
+ ...buildColorOptions(HIGHLIGHT_COLOR_SWATCHES, t("colors.color"))
25475
25594
  ],
25476
25595
  [t]
25477
25596
  );
@@ -25482,26 +25601,81 @@ var EditorColorPalette = ({
25482
25601
  currentColor,
25483
25602
  onSelect,
25484
25603
  label
25485
- }) => /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "p-2", children: [
25486
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider px-2", children: label }),
25487
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "grid grid-cols-4 gap-1.5 mt-2", children: colors.map((c) => /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(Tooltip, { placement: "top", content: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "text-xs font-medium", children: c.name }), children: /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(
25488
- "button",
25489
- {
25490
- type: "button",
25491
- onMouseDown: (e) => e.preventDefault(),
25492
- onClick: () => onSelect(c.color),
25493
- className: cn(
25494
- "flex items-center justify-center w-9 h-9 rounded-lg border-2 transition-all hover:scale-105",
25495
- currentColor === c.color ? "border-primary ring-2 ring-primary/20" : "border-border/50 hover:border-primary/50"
25496
- ),
25497
- style: { backgroundColor: c.color || "transparent" },
25498
- children: [
25499
- c.color === "" && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_lucide_react42.X, { className: "w-4 h-4 text-muted-foreground" }),
25500
- c.color === "inherit" && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "text-xs font-medium", children: "A" })
25501
- ]
25502
- }
25503
- ) }, c.name)) })
25504
- ] });
25604
+ }) => {
25605
+ const t = useSmartTranslations("UEditor");
25606
+ const colorInputRef = (0, import_react47.useRef)(null);
25607
+ const automaticColor = colors[0]?.color ?? "";
25608
+ const paletteColors = colors.slice(1);
25609
+ return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "w-56 p-2", children: [
25610
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "px-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: label }),
25611
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(
25612
+ "button",
25613
+ {
25614
+ type: "button",
25615
+ onMouseDown: (e) => e.preventDefault(),
25616
+ onClick: () => onSelect(automaticColor),
25617
+ className: cn(
25618
+ "mt-2 flex h-9 w-full items-center gap-3 rounded-md border px-2 text-sm transition-colors",
25619
+ "bg-muted/50 hover:bg-muted",
25620
+ currentColor === automaticColor ? "border-primary text-primary" : "border-transparent text-foreground"
25621
+ ),
25622
+ children: [
25623
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "flex h-5 w-5 items-center justify-center rounded border border-border bg-background", children: currentColor === automaticColor && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_lucide_react42.Check, { className: "h-3.5 w-3.5" }) }),
25624
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "flex-1 text-center", children: t("colors.automatic") })
25625
+ ]
25626
+ }
25627
+ ),
25628
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "mt-2 grid grid-cols-8 gap-1", children: paletteColors.map((c) => /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(Tooltip, { placement: "top", content: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "text-xs font-medium", children: c.name }), children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
25629
+ "button",
25630
+ {
25631
+ type: "button",
25632
+ "aria-label": c.name,
25633
+ onMouseDown: (e) => e.preventDefault(),
25634
+ onClick: () => onSelect(c.color),
25635
+ className: cn(
25636
+ "relative h-5 w-5 rounded-[3px] border transition-transform hover:scale-110",
25637
+ currentColor === c.color ? "border-primary ring-2 ring-primary/25" : "border-border/70"
25638
+ ),
25639
+ style: { backgroundColor: c.color || "transparent" },
25640
+ children: currentColor === c.color && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_lucide_react42.Check, { className: "h-3.5 w-3.5 text-white drop-shadow-[0_1px_1px_rgba(0,0,0,0.8)]" }) })
25641
+ }
25642
+ ) }, `${c.name}-${c.color}`)) }),
25643
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(
25644
+ "button",
25645
+ {
25646
+ type: "button",
25647
+ onMouseDown: (e) => e.preventDefault(),
25648
+ onClick: () => colorInputRef.current?.click(),
25649
+ className: "mt-3 flex h-9 w-full items-center gap-3 rounded-md px-2 text-sm text-foreground transition-colors hover:bg-muted",
25650
+ children: [
25651
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
25652
+ "span",
25653
+ {
25654
+ "aria-hidden": "true",
25655
+ className: "h-5 w-5 rounded border border-border",
25656
+ style: {
25657
+ background: "linear-gradient(135deg, #ff004c 0%, #fffb00 22%, #00ff66 42%, #00d5ff 62%, #2446ff 78%, #ff00d4 100%)"
25658
+ }
25659
+ }
25660
+ ),
25661
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "flex-1 text-center", children: t("colors.moreColors") }),
25662
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_lucide_react42.Palette, { className: "h-4 w-4 text-muted-foreground" }),
25663
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
25664
+ "input",
25665
+ {
25666
+ ref: colorInputRef,
25667
+ type: "color",
25668
+ value: currentColor.startsWith("#") ? currentColor : "#000000",
25669
+ onChange: (event) => onSelect(event.target.value),
25670
+ className: "sr-only",
25671
+ tabIndex: -1
25672
+ }
25673
+ )
25674
+ ]
25675
+ }
25676
+ )
25677
+ ] });
25678
+ };
25505
25679
 
25506
25680
  // src/components/UEditor/image-commands.ts
25507
25681
  var import_state4 = require("@tiptap/pm/state");
@@ -25713,12 +25887,23 @@ function getDefaultFontFamilies(t) {
25713
25887
  }
25714
25888
  function getDefaultFontSizes() {
25715
25889
  return [
25890
+ { label: "8", value: "8px" },
25891
+ { label: "9", value: "9px" },
25892
+ { label: "10", value: "10px" },
25893
+ { label: "11", value: "11px" },
25716
25894
  { label: "12", value: "12px" },
25717
25895
  { label: "14", value: "14px" },
25718
25896
  { label: "16", value: "16px" },
25719
25897
  { label: "18", value: "18px" },
25898
+ { label: "20", value: "20px" },
25899
+ { label: "22", value: "22px" },
25720
25900
  { label: "24", value: "24px" },
25721
- { label: "32", value: "32px" }
25901
+ { label: "26", value: "26px" },
25902
+ { label: "28", value: "28px" },
25903
+ { label: "36", value: "36px" },
25904
+ { label: "48", value: "48px" },
25905
+ { label: "72", value: "72px" },
25906
+ { label: "96", value: "96px" }
25722
25907
  ];
25723
25908
  }
25724
25909
  function getDefaultLineHeights() {
@@ -25766,10 +25951,11 @@ var ToolbarButton = import_react49.default.forwardRef(({ onClick, onMouseDown, a
25766
25951
  onClick,
25767
25952
  disabled,
25768
25953
  className: cn(
25769
- "flex items-center justify-center w-8 h-8 rounded-lg transition-all duration-200",
25770
- "hover:bg-accent hover:scale-105",
25954
+ "flex items-center justify-center w-8 h-8 rounded-md transition-colors duration-150",
25955
+ "gap-0.5 [&_svg+svg]:-ml-1",
25956
+ "hover:bg-accent",
25771
25957
  "focus:outline-none focus:ring-2 focus:ring-primary/20",
25772
- "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:scale-100",
25958
+ "disabled:opacity-40 disabled:cursor-not-allowed",
25773
25959
  active ? "bg-primary/10 text-primary shadow-sm" : "text-muted-foreground hover:text-foreground",
25774
25960
  className
25775
25961
  ),
@@ -25782,7 +25968,7 @@ var ToolbarButton = import_react49.default.forwardRef(({ onClick, onMouseDown, a
25782
25968
  return button;
25783
25969
  });
25784
25970
  ToolbarButton.displayName = "ToolbarButton";
25785
- var ToolbarDivider = () => /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "w-px h-6 bg-border/50 mx-1" });
25971
+ var ToolbarDivider = () => /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "mx-0.5 h-5 w-px bg-border/60" });
25786
25972
  var TableInsertGrid = ({
25787
25973
  insertLabel,
25788
25974
  previewTemplate,
@@ -25793,36 +25979,29 @@ var TableInsertGrid = ({
25793
25979
  const maxCols = 8;
25794
25980
  return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: "mb-2 rounded-xl border border-border/60 bg-muted/20 p-2", children: [
25795
25981
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "mb-2 text-sm font-medium text-foreground", children: formatTableInsertLabel(previewTemplate, selection.rows, selection.cols) }),
25796
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
25797
- "div",
25798
- {
25799
- className: "grid grid-cols-8 gap-1",
25800
- onMouseLeave: () => setSelection((prev) => prev),
25801
- children: Array.from({ length: maxRows }).map(
25802
- (_, rowIndex) => Array.from({ length: maxCols }).map((__, colIndex) => {
25803
- const rows = rowIndex + 1;
25804
- const cols = colIndex + 1;
25805
- const active = rows <= selection.rows && cols <= selection.cols;
25806
- return /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
25807
- "button",
25808
- {
25809
- type: "button",
25810
- "aria-label": formatTableInsertLabel(previewTemplate, rows, cols),
25811
- onMouseDown: (e) => e.preventDefault(),
25812
- onMouseEnter: () => setSelection({ rows, cols }),
25813
- onFocus: () => setSelection({ rows, cols }),
25814
- onClick: () => onInsert(rows, cols),
25815
- className: cn(
25816
- "h-5 w-5 rounded-sm border transition-colors",
25817
- active ? "border-primary bg-primary/20" : "border-border/70 bg-background hover:border-primary/60 hover:bg-primary/10"
25818
- )
25819
- },
25820
- `${rows}-${cols}`
25821
- );
25822
- })
25823
- )
25824
- }
25825
- ),
25982
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "grid grid-cols-8 gap-1", onMouseLeave: () => setSelection((prev) => prev), children: Array.from({ length: maxRows }).map(
25983
+ (_, rowIndex) => Array.from({ length: maxCols }).map((__, colIndex) => {
25984
+ const rows = rowIndex + 1;
25985
+ const cols = colIndex + 1;
25986
+ const active = rows <= selection.rows && cols <= selection.cols;
25987
+ return /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
25988
+ "button",
25989
+ {
25990
+ type: "button",
25991
+ "aria-label": formatTableInsertLabel(previewTemplate, rows, cols),
25992
+ onMouseDown: (e) => e.preventDefault(),
25993
+ onMouseEnter: () => setSelection({ rows, cols }),
25994
+ onFocus: () => setSelection({ rows, cols }),
25995
+ onClick: () => onInsert(rows, cols),
25996
+ className: cn(
25997
+ "h-5 w-5 rounded-sm border transition-colors",
25998
+ active ? "border-primary bg-primary/20" : "border-border/70 bg-background hover:border-primary/60 hover:bg-primary/10"
25999
+ )
26000
+ },
26001
+ `${rows}-${cols}`
26002
+ );
26003
+ })
26004
+ ) }),
25826
26005
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "mt-2 text-xs text-muted-foreground", children: insertLabel })
25827
26006
  ] });
25828
26007
  };
@@ -25839,14 +26018,23 @@ var EditorToolbar = ({
25839
26018
  letterSpacings
25840
26019
  }) => {
25841
26020
  const t = useSmartTranslations("UEditor");
26021
+ (0, import_react50.useEditorState)({
26022
+ editor,
26023
+ selector: ({ transactionNumber }) => transactionNumber
26024
+ });
25842
26025
  const { textColors, highlightColors } = useEditorColors();
25843
26026
  const [showImageInput, setShowImageInput] = (0, import_react49.useState)(false);
26027
+ const [showLinkInput, setShowLinkInput] = (0, import_react49.useState)(false);
25844
26028
  const [isTableMenuOpen, setIsTableMenuOpen] = (0, import_react49.useState)(false);
25845
26029
  const tableCommandAnchorPosRef = (0, import_react49.useRef)(null);
25846
26030
  const fileInputRef = (0, import_react49.useRef)(null);
25847
26031
  const [isUploadingImage, setIsUploadingImage] = (0, import_react49.useState)(false);
25848
26032
  const [imageUploadError, setImageUploadError] = (0, import_react49.useState)(null);
25849
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);
25850
26038
  const isImageSelected = editor.isActive("image");
25851
26039
  const imageAttrs = editor.getAttributes("image");
25852
26040
  const tableAttrs = editor.getAttributes("table");
@@ -25858,30 +26046,23 @@ var EditorToolbar = ({
25858
26046
  const hasTableContext = isTableSelected || tableCommandAnchorPosRef.current !== null;
25859
26047
  const currentFontFamily = normalizeStyleValue(textStyleAttrs.fontFamily);
25860
26048
  const currentFontSize = normalizeStyleValue(textStyleAttrs.fontSize);
26049
+ const currentTextColor = normalizeStyleValue(textStyleAttrs.color) || "inherit";
26050
+ const currentHighlightColor = normalizeStyleValue(editor.getAttributes("highlight").color) || "";
25861
26051
  const currentLineHeight = normalizeStyleValue(textStyleAttrs.lineHeight);
25862
26052
  const currentLetterSpacing = normalizeStyleValue(textStyleAttrs.letterSpacing);
25863
- const availableFontFamilies = import_react49.default.useMemo(
25864
- () => fontFamilies ?? getDefaultFontFamilies(t),
25865
- [fontFamilies, t]
25866
- );
25867
- const availableFontSizes = import_react49.default.useMemo(
25868
- () => fontSizes ?? getDefaultFontSizes(),
25869
- [fontSizes]
25870
- );
25871
- const availableLineHeights = import_react49.default.useMemo(
25872
- () => lineHeights ?? getDefaultLineHeights(),
25873
- [lineHeights]
25874
- );
25875
- const availableLetterSpacings = import_react49.default.useMemo(
25876
- () => letterSpacings ?? getDefaultLetterSpacings(),
25877
- [letterSpacings]
25878
- );
25879
- const currentFontFamilyLabel = availableFontFamilies.find((option) => normalizeStyleValue(option.value) === currentFontFamily)?.label ?? t("toolbar.fontDefault");
26053
+ const availableFontFamilies = import_react49.default.useMemo(() => fontFamilies ?? getDefaultFontFamilies(t), [fontFamilies, t]);
26054
+ const availableFontSizes = import_react49.default.useMemo(() => fontSizes ?? getDefaultFontSizes(), [fontSizes]);
26055
+ const availableLineHeights = import_react49.default.useMemo(() => lineHeights ?? getDefaultLineHeights(), [lineHeights]);
26056
+ const availableLetterSpacings = import_react49.default.useMemo(() => letterSpacings ?? getDefaultLetterSpacings(), [letterSpacings]);
26057
+ const currentFontFamilyDisplayValue = currentFontFamily.split(",")[0]?.trim() ?? currentFontFamily;
26058
+ const currentFontFamilyLabel = availableFontFamilies.find((option) => normalizeStyleValue(option.value) === currentFontFamily)?.label ?? (currentFontFamilyDisplayValue || t("toolbar.fontDefault"));
25880
26059
  const currentFontSizeLabel = availableFontSizes.find((option) => normalizeStyleValue(option.value) === currentFontSize)?.label ?? t("toolbar.sizeDefault");
25881
26060
  const currentLineHeightLabel = availableLineHeights.find((option) => normalizeStyleValue(option.value) === currentLineHeight)?.label ?? t("toolbar.lineHeightDefault");
25882
26061
  const currentLetterSpacingLabel = availableLetterSpacings.find((option) => normalizeStyleValue(option.value) === currentLetterSpacing)?.label ?? t("toolbar.letterSpacingDefault");
26062
+ const displayedFontFamilyLabel = currentFontFamily ? currentFontFamilyLabel : availableFontFamilies[0]?.label ?? t("toolbar.fontDefault");
25883
26063
  import_react49.default.useEffect(() => {
25884
- setFontSizeDraft(currentFontSize.replace(/px$/i, ""));
26064
+ if (document.activeElement === fontSizeControlRef.current?.querySelector("input")) return;
26065
+ setFontSizeDraft(currentFontSize.replace(/px$/i, "") || "16");
25885
26066
  }, [currentFontSize]);
25886
26067
  const applyFontSizeDraft = () => {
25887
26068
  const normalized = fontSizeDraft.trim();
@@ -25893,7 +26074,39 @@ var EditorToolbar = ({
25893
26074
  if (!Number.isFinite(parsed) || parsed <= 0) return;
25894
26075
  const clamped = Math.min(96, Math.max(8, parsed));
25895
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);
25896
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]);
25897
26110
  const insertImageFiles = async (files) => {
25898
26111
  if (files.length === 0) return;
25899
26112
  setIsUploadingImage(true);
@@ -25915,7 +26128,7 @@ var EditorToolbar = ({
25915
26128
  setIsUploadingImage(false);
25916
26129
  };
25917
26130
  if (variant === "minimal") {
25918
- return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: "flex items-center gap-1 p-2 border-b bg-muted/30", children: [
26131
+ return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: "flex items-center gap-1 border-b border-border/35 bg-muted/30 p-2", children: [
25919
26132
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(ToolbarButton, { onClick: () => editor.chain().focus().toggleBold().run(), active: editor.isActive("bold"), title: t("toolbar.bold"), children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.Bold, { className: "w-4 h-4" }) }),
25920
26133
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(ToolbarButton, { onClick: () => editor.chain().focus().toggleItalic().run(), active: editor.isActive("italic"), title: t("toolbar.italic"), children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.Italic, { className: "w-4 h-4" }) }),
25921
26134
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
@@ -25929,70 +26142,23 @@ var EditorToolbar = ({
25929
26142
  )
25930
26143
  ] });
25931
26144
  }
25932
- return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: "flex flex-wrap items-center gap-1 p-2 border-b bg-linear-to-r from-muted/30 to-transparent", children: [
25933
- /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
25934
- DropdownMenu,
25935
- {
25936
- contentClassName: "p-2",
25937
- trigger: /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(ToolbarButton, { onClick: () => {
25938
- }, title: t("toolbar.textStyle"), className: "px-2 w-auto gap-1", children: [
25939
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.Type, { className: "w-4 h-4" }),
25940
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.ChevronDown, { className: "w-3 h-3" })
25941
- ] }),
25942
- children: [
25943
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
25944
- DropdownMenuItem,
25945
- {
25946
- icon: import_lucide_react44.Type,
25947
- label: t("toolbar.normal"),
25948
- onClick: () => editor.chain().focus().setParagraph().run(),
25949
- active: editor.isActive("paragraph")
25950
- }
25951
- ),
25952
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
25953
- DropdownMenuItem,
25954
- {
25955
- icon: import_lucide_react44.Heading1,
25956
- label: t("toolbar.heading1"),
25957
- onClick: () => editor.chain().focus().toggleHeading({ level: 1 }).run(),
25958
- active: editor.isActive("heading", { level: 1 }),
25959
- shortcut: "Ctrl+Alt+1"
25960
- }
25961
- ),
25962
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
25963
- DropdownMenuItem,
25964
- {
25965
- icon: import_lucide_react44.Heading2,
25966
- label: t("toolbar.heading2"),
25967
- onClick: () => editor.chain().focus().toggleHeading({ level: 2 }).run(),
25968
- active: editor.isActive("heading", { level: 2 }),
25969
- shortcut: "Ctrl+Alt+2"
25970
- }
25971
- ),
25972
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
25973
- DropdownMenuItem,
25974
- {
25975
- icon: import_lucide_react44.Heading3,
25976
- label: t("toolbar.heading3"),
25977
- onClick: () => editor.chain().focus().toggleHeading({ level: 3 }).run(),
25978
- active: editor.isActive("heading", { level: 3 }),
25979
- shortcut: "Ctrl+Alt+3"
25980
- }
25981
- )
25982
- ]
25983
- }
25984
- ),
26145
+ return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: "flex flex-wrap items-center gap-0.5 border-b border-border/35 bg-linear-to-r from-muted/25 to-transparent p-1.5", children: [
25985
26146
  /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
25986
26147
  DropdownMenu,
25987
26148
  {
25988
- trigger: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
25989
- ToolbarButton,
26149
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
26150
+ "button",
25990
26151
  {
25991
- onClick: () => {
25992
- },
25993
- title: t("toolbar.fontFamily"),
25994
- className: "relative",
25995
- children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.Type, { className: "w-4 h-4" })
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
+ ]
25996
26162
  }
25997
26163
  ),
25998
26164
  contentClassName: "max-h-80 overflow-y-auto min-w-56 p-2",
@@ -26012,30 +26178,24 @@ var EditorToolbar = ({
26012
26178
  label: option.label,
26013
26179
  onClick: () => editor.chain().focus().setFontFamily(option.value).run(),
26014
26180
  active: normalizeStyleValue(option.value) === currentFontFamily,
26015
- className: "font-medium"
26181
+ className: "font-medium "
26016
26182
  },
26017
26183
  option.value
26018
26184
  ))
26019
26185
  ]
26020
26186
  }
26021
26187
  ),
26022
- /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
26023
- DropdownMenu,
26024
- {
26025
- closeOnSelect: false,
26026
- trigger: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26027
- ToolbarButton,
26028
- {
26029
- onClick: () => {
26030
- },
26031
- title: t("toolbar.fontSize"),
26032
- className: "px-2 w-auto min-w-9",
26033
- children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("span", { className: "text-[10px] font-semibold leading-none", children: currentFontSize.replace(/px$/i, "") || "T" })
26034
- }
26035
- ),
26036
- contentClassName: "max-h-80 overflow-y-auto min-w-44 p-2",
26037
- children: [
26038
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "mb-2 rounded-lg border border-border/60 bg-muted/30 p-2", children: /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("label", { className: "flex items-center gap-2", children: [
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-16 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"
26197
+ ),
26198
+ children: [
26039
26199
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26040
26200
  "input",
26041
26201
  {
@@ -26045,6 +26205,7 @@ var EditorToolbar = ({
26045
26205
  step: 1,
26046
26206
  value: fontSizeDraft,
26047
26207
  onChange: (e) => setFontSizeDraft(e.target.value),
26208
+ onBlur: applyFontSizeDraft,
26048
26209
  onMouseDown: (e) => e.stopPropagation(),
26049
26210
  onClick: (e) => e.stopPropagation(),
26050
26211
  onKeyDown: (e) => {
@@ -26055,48 +26216,116 @@ var EditorToolbar = ({
26055
26216
  }
26056
26217
  },
26057
26218
  "aria-label": t("toolbar.fontSize"),
26058
- className: "h-8 w-full rounded-md border border-border bg-background px-2 text-sm outline-none focus:ring-2 focus:ring-primary/20"
26219
+ className: "h-full w-10 bg-transparent px-1 text-center text-xs font-semibold outline-none [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
26059
26220
  }
26060
26221
  ),
26061
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("span", { className: "text-xs text-muted-foreground", children: "px" })
26062
- ] }) }),
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-7 items-center justify-center border-l border-border/50 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
+ ] }),
26269
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
26270
+ DropdownMenu,
26271
+ {
26272
+ contentClassName: "p-2",
26273
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(ToolbarButton, { onClick: () => {
26274
+ }, title: t("toolbar.textStyle"), className: "px-2 w-auto gap-1", children: [
26275
+ /* @__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" })
26277
+ ] }),
26278
+ children: [
26063
26279
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26064
26280
  DropdownMenuItem,
26065
26281
  {
26066
26282
  icon: import_lucide_react44.Type,
26067
- label: t("toolbar.sizeDefault"),
26068
- onClick: () => editor.chain().focus().unsetFontSize().run(),
26069
- active: !currentFontSize
26283
+ label: t("toolbar.normal"),
26284
+ onClick: () => editor.chain().focus().setParagraph().run(),
26285
+ active: editor.isActive("paragraph")
26070
26286
  }
26071
26287
  ),
26072
- availableFontSizes.map((option) => /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26288
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26073
26289
  DropdownMenuItem,
26074
26290
  {
26075
- label: option.label,
26076
- onClick: () => editor.chain().focus().setFontSize(option.value).run(),
26077
- active: normalizeStyleValue(option.value) === currentFontSize
26078
- },
26079
- option.value
26080
- ))
26291
+ icon: import_lucide_react44.Heading1,
26292
+ label: t("toolbar.heading1"),
26293
+ onClick: () => editor.chain().focus().toggleHeading({ level: 1 }).run(),
26294
+ active: editor.isActive("heading", { level: 1 }),
26295
+ shortcut: "Ctrl+Alt+1"
26296
+ }
26297
+ ),
26298
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26299
+ DropdownMenuItem,
26300
+ {
26301
+ icon: import_lucide_react44.Heading2,
26302
+ label: t("toolbar.heading2"),
26303
+ onClick: () => editor.chain().focus().toggleHeading({ level: 2 }).run(),
26304
+ active: editor.isActive("heading", { level: 2 }),
26305
+ shortcut: "Ctrl+Alt+2"
26306
+ }
26307
+ ),
26308
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26309
+ DropdownMenuItem,
26310
+ {
26311
+ icon: import_lucide_react44.Heading3,
26312
+ label: t("toolbar.heading3"),
26313
+ onClick: () => editor.chain().focus().toggleHeading({ level: 3 }).run(),
26314
+ active: editor.isActive("heading", { level: 3 }),
26315
+ shortcut: "Ctrl+Alt+3"
26316
+ }
26317
+ )
26081
26318
  ]
26082
26319
  }
26083
26320
  ),
26084
26321
  /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
26085
26322
  DropdownMenu,
26086
26323
  {
26087
- trigger: /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
26088
- ToolbarButton,
26089
- {
26090
- onClick: () => {
26091
- },
26092
- title: t("toolbar.lineHeight"),
26093
- className: "gap-0.5",
26094
- children: [
26095
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.ArrowUp, { className: "w-3 h-3" }),
26096
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.ArrowDown, { className: "w-3 h-3" })
26097
- ]
26098
- }
26099
- ),
26324
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(ToolbarButton, { onClick: () => {
26325
+ }, title: t("toolbar.lineHeight"), className: "gap-0.5", children: [
26326
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.ArrowUp, { className: "w-3 h-3" }),
26327
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.ArrowDown, { className: "w-3 h-3" })
26328
+ ] }),
26100
26329
  contentClassName: "max-h-72 overflow-y-auto p-2",
26101
26330
  children: [
26102
26331
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
@@ -26123,19 +26352,11 @@ var EditorToolbar = ({
26123
26352
  /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
26124
26353
  DropdownMenu,
26125
26354
  {
26126
- trigger: /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
26127
- ToolbarButton,
26128
- {
26129
- onClick: () => {
26130
- },
26131
- title: t("toolbar.letterSpacing"),
26132
- className: "gap-0.5",
26133
- children: [
26134
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.ArrowLeft, { className: "w-3 h-3" }),
26135
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.ArrowRight, { className: "w-3 h-3" })
26136
- ]
26137
- }
26138
- ),
26355
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(ToolbarButton, { onClick: () => {
26356
+ }, title: t("toolbar.letterSpacing"), className: "gap-0.5", children: [
26357
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.ArrowLeft, { className: "w-3 h-3" }),
26358
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.ArrowRight, { className: "w-3 h-3" })
26359
+ ] }),
26139
26360
  contentClassName: "max-h-72 overflow-y-auto p-2",
26140
26361
  children: [
26141
26362
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
@@ -26173,20 +26394,68 @@ var EditorToolbar = ({
26173
26394
  ),
26174
26395
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(ToolbarButton, { onClick: () => editor.chain().focus().toggleStrike().run(), active: editor.isActive("strike"), title: t("toolbar.strike"), children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.Strikethrough, { className: "w-4 h-4" }) }),
26175
26396
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(ToolbarButton, { onClick: () => editor.chain().focus().toggleCode().run(), active: editor.isActive("code"), title: t("toolbar.code"), children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.Code, { className: "w-4 h-4" }) }),
26397
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26398
+ ToolbarButton,
26399
+ {
26400
+ onClick: () => editor.chain().focus().toggleSubscript().run(),
26401
+ active: editor.isActive("subscript"),
26402
+ title: t("toolbar.subscript"),
26403
+ children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.Subscript, { className: "w-4 h-4" })
26404
+ }
26405
+ ),
26406
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26407
+ ToolbarButton,
26408
+ {
26409
+ onClick: () => editor.chain().focus().toggleSuperscript().run(),
26410
+ active: editor.isActive("superscript"),
26411
+ title: t("toolbar.superscript"),
26412
+ children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.Superscript, { className: "w-4 h-4" })
26413
+ }
26414
+ ),
26415
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26416
+ DropdownMenu,
26417
+ {
26418
+ contentClassName: "min-w-72",
26419
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(ToolbarButton, { onClick: () => setShowLinkInput(!editor.isActive("link")), active: editor.isActive("link"), title: t("toolbar.link"), children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.Link, { className: "w-4 h-4" }) }),
26420
+ children: showLinkInput ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26421
+ LinkInput,
26422
+ {
26423
+ initialUrl: String(editor.getAttributes("link").href ?? ""),
26424
+ onSubmit: (url) => {
26425
+ editor.chain().focus().extendMarkRange("link").setLink({ href: url }).run();
26426
+ setShowLinkInput(false);
26427
+ },
26428
+ onCancel: () => setShowLinkInput(false)
26429
+ }
26430
+ ) : /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(import_jsx_runtime81.Fragment, { children: [
26431
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(DropdownMenuItem, { icon: import_lucide_react44.Link, label: t("toolbar.link"), onClick: () => setShowLinkInput(true), active: editor.isActive("link") }),
26432
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26433
+ DropdownMenuItem,
26434
+ {
26435
+ icon: import_lucide_react44.Trash2,
26436
+ label: t("toolbar.removeLink"),
26437
+ onClick: () => editor.chain().focus().extendMarkRange("link").unsetLink().run(),
26438
+ disabled: !editor.isActive("link"),
26439
+ destructive: true
26440
+ }
26441
+ )
26442
+ ] })
26443
+ }
26444
+ ),
26176
26445
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(ToolbarDivider, {}),
26177
26446
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26178
26447
  DropdownMenu,
26179
26448
  {
26180
26449
  trigger: /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(ToolbarButton, { onClick: () => {
26181
26450
  }, title: t("colors.textColor"), children: [
26182
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.Palette, { className: "w-4 h-4" }),
26451
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(TextColorIcon, { color: currentTextColor }),
26183
26452
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.ChevronDown, { className: "w-3 h-3" })
26184
26453
  ] }),
26185
26454
  children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26186
26455
  EditorColorPalette,
26187
26456
  {
26188
26457
  colors: textColors,
26189
- currentColor: editor.getAttributes("textStyle").color || "inherit",
26458
+ currentColor: currentTextColor,
26190
26459
  onSelect: (color) => {
26191
26460
  if (color === "inherit") {
26192
26461
  editor.chain().focus().unsetColor().run();
@@ -26204,14 +26473,14 @@ var EditorToolbar = ({
26204
26473
  {
26205
26474
  trigger: /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(ToolbarButton, { onClick: () => {
26206
26475
  }, active: editor.isActive("highlight"), title: t("colors.highlight"), children: [
26207
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.Highlighter, { className: "w-4 h-4" }),
26476
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(HighlightColorIcon, { color: currentHighlightColor }),
26208
26477
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.ChevronDown, { className: "w-3 h-3" })
26209
26478
  ] }),
26210
26479
  children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26211
26480
  EditorColorPalette,
26212
26481
  {
26213
26482
  colors: highlightColors,
26214
- currentColor: editor.getAttributes("highlight").color || "",
26483
+ currentColor: currentHighlightColor,
26215
26484
  onSelect: (color) => {
26216
26485
  if (color === "") {
26217
26486
  editor.chain().focus().unsetHighlight().run();
@@ -26636,41 +26905,23 @@ var EditorToolbar = ({
26636
26905
  }
26637
26906
  ),
26638
26907
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(ToolbarDivider, {}),
26639
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26640
- ToolbarButton,
26641
- {
26642
- onClick: () => editor.chain().focus().toggleSubscript().run(),
26643
- active: editor.isActive("subscript"),
26644
- title: t("toolbar.subscript"),
26645
- children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.Subscript, { className: "w-4 h-4" })
26646
- }
26647
- ),
26648
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
26649
- ToolbarButton,
26650
- {
26651
- onClick: () => editor.chain().focus().toggleSuperscript().run(),
26652
- active: editor.isActive("superscript"),
26653
- title: t("toolbar.superscript"),
26654
- children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.Superscript, { className: "w-4 h-4" })
26655
- }
26656
- ),
26657
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(ToolbarDivider, {}),
26658
26908
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(ToolbarButton, { onClick: () => editor.chain().focus().undo().run(), disabled: !editor.can().undo(), title: t("toolbar.undo"), children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.Undo, { className: "w-4 h-4" }) }),
26659
26909
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(ToolbarButton, { onClick: () => editor.chain().focus().redo().run(), disabled: !editor.can().redo(), title: t("toolbar.redo"), children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_lucide_react44.Redo, { className: "w-4 h-4" }) })
26660
26910
  ] });
26661
26911
  };
26662
26912
 
26663
26913
  // src/components/UEditor/menus.tsx
26664
- var import_react50 = require("react");
26665
- var import_react_dom8 = require("react-dom");
26914
+ var import_react51 = require("react");
26915
+ var import_react52 = require("@tiptap/react");
26916
+ var import_react_dom9 = require("react-dom");
26666
26917
  var import_lucide_react45 = require("lucide-react");
26667
26918
  var import_jsx_runtime82 = require("react/jsx-runtime");
26668
26919
  var FloatingSlashCommandMenu = ({ editor, onClose }) => {
26669
26920
  const t = useSmartTranslations("UEditor");
26670
- const messages = (0, import_react50.useMemo)(() => buildSlashCommandMessages(t), [t]);
26671
- const items = (0, import_react50.useMemo)(() => buildSlashCommandItems({ query: "", messages }), [messages]);
26672
- const listRef = (0, import_react50.useRef)(null);
26673
- (0, import_react50.useEffect)(() => {
26921
+ const messages = (0, import_react51.useMemo)(() => buildSlashCommandMessages(t), [t]);
26922
+ const items = (0, import_react51.useMemo)(() => buildSlashCommandItems({ query: "", messages }), [messages]);
26923
+ const listRef = (0, import_react51.useRef)(null);
26924
+ (0, import_react51.useEffect)(() => {
26674
26925
  const handleKeyDown2 = (event) => {
26675
26926
  if (event.key === "Escape") {
26676
26927
  event.preventDefault();
@@ -26700,7 +26951,7 @@ var FloatingSlashCommandMenu = ({ editor, onClose }) => {
26700
26951
  };
26701
26952
  var FloatingMenuContent = ({ editor }) => {
26702
26953
  const t = useSmartTranslations("UEditor");
26703
- const [showCommands, setShowCommands] = (0, import_react50.useState)(false);
26954
+ const [showCommands, setShowCommands] = (0, import_react51.useState)(false);
26704
26955
  if (showCommands) {
26705
26956
  return /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(FloatingSlashCommandMenu, { editor, onClose: () => setShowCommands(false) });
26706
26957
  }
@@ -26724,28 +26975,52 @@ var BubbleMenuContent = ({
26724
26975
  lineHeights
26725
26976
  }) => {
26726
26977
  const t = useSmartTranslations("UEditor");
26978
+ (0, import_react52.useEditorState)({
26979
+ editor,
26980
+ selector: ({ transactionNumber }) => transactionNumber
26981
+ });
26727
26982
  const { textColors, highlightColors } = useEditorColors();
26728
- const [showLinkInput, setShowLinkInput] = (0, import_react50.useState)(false);
26729
- const [showEditorColorPalette, setShowEditorColorPalette] = (0, import_react50.useState)(false);
26983
+ const [showLinkInput, setShowLinkInput] = (0, import_react51.useState)(false);
26984
+ const [activeColorPalette, setActiveColorPalette] = (0, import_react51.useState)(null);
26985
+ const [showTypographyPanel, setShowTypographyPanel] = (0, import_react51.useState)(false);
26986
+ const [showFontSizeOptions, setShowFontSizeOptions] = (0, import_react51.useState)(false);
26987
+ const [fontSizeDraft, setFontSizeDraft] = (0, import_react51.useState)("");
26730
26988
  const isImageSelected = editor.isActive("image");
26731
26989
  const imageAttrs = editor.getAttributes("image");
26732
26990
  const imageLayout = imageAttrs.imageLayout === "left" || imageAttrs.imageLayout === "right" ? imageAttrs.imageLayout : "block";
26733
26991
  const imageWidthPreset = imageAttrs.imageWidthPreset === "sm" || imageAttrs.imageWidthPreset === "md" || imageAttrs.imageWidthPreset === "lg" ? imageAttrs.imageWidthPreset : null;
26734
26992
  const textStyleAttrs = editor.getAttributes("textStyle");
26993
+ const currentTextColor = normalizeStyleValue(textStyleAttrs.color) || "inherit";
26994
+ const currentHighlightColor = normalizeStyleValue(editor.getAttributes("highlight").color) || "";
26735
26995
  const currentFontSize = normalizeStyleValue(textStyleAttrs.fontSize);
26736
26996
  const currentLineHeight = normalizeStyleValue(textStyleAttrs.lineHeight);
26737
- const quickFontSizes = (0, import_react50.useMemo)(
26997
+ const quickFontSizes = (0, import_react51.useMemo)(
26738
26998
  () => (fontSizes ?? getDefaultFontSizes()).filter((option) => ["14px", "16px", "24px"].includes(option.value)),
26739
26999
  [fontSizes]
26740
27000
  );
26741
- const quickLineHeights = (0, import_react50.useMemo)(
27001
+ const quickLineHeights = (0, import_react51.useMemo)(
26742
27002
  () => (lineHeights ?? getDefaultLineHeights()).filter((option) => ["1.2", "1.5", "1.75"].includes(option.value)),
26743
27003
  [lineHeights]
26744
27004
  );
26745
- (0, import_react50.useEffect)(() => {
27005
+ (0, import_react51.useEffect)(() => {
27006
+ setFontSizeDraft(currentFontSize.replace(/px$/i, ""));
27007
+ }, [currentFontSize]);
27008
+ const applyFontSizeDraft = () => {
27009
+ const normalized = fontSizeDraft.trim();
27010
+ if (!normalized) {
27011
+ editor.chain().focus().unsetFontSize().run();
27012
+ return;
27013
+ }
27014
+ const parsed = Number.parseFloat(normalized);
27015
+ if (!Number.isFinite(parsed) || parsed <= 0) return;
27016
+ const clamped = Math.min(96, Math.max(8, parsed));
27017
+ editor.chain().focus().setFontSize(`${clamped}px`).run();
27018
+ setFontSizeDraft(String(clamped));
27019
+ };
27020
+ (0, import_react51.useEffect)(() => {
26746
27021
  onKeepOpenChange?.(showLinkInput);
26747
27022
  }, [onKeepOpenChange, showLinkInput]);
26748
- (0, import_react50.useEffect)(() => {
27023
+ (0, import_react51.useEffect)(() => {
26749
27024
  if (!showLinkInput) return;
26750
27025
  const close2 = () => setShowLinkInput(false);
26751
27026
  editor.on("selectionUpdate", close2);
@@ -26772,44 +27047,37 @@ var BubbleMenuContent = ({
26772
27047
  }
26773
27048
  );
26774
27049
  }
26775
- if (showEditorColorPalette) {
26776
- return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "w-48", children: [
26777
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
26778
- EditorColorPalette,
26779
- {
26780
- colors: textColors,
26781
- currentColor: editor.getAttributes("textStyle").color || "inherit",
26782
- onSelect: (color) => {
26783
- if (color === "inherit") {
26784
- editor.chain().focus().unsetColor().run();
26785
- } else {
26786
- editor.chain().focus().setColor(color).run();
26787
- }
26788
- },
26789
- label: t("colors.textColor")
26790
- }
26791
- ),
26792
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "border-t my-1" }),
27050
+ if (activeColorPalette) {
27051
+ const isTextPalette = activeColorPalette === "text";
27052
+ return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "w-56", children: [
26793
27053
  /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
26794
27054
  EditorColorPalette,
26795
27055
  {
26796
- colors: highlightColors,
26797
- currentColor: editor.getAttributes("highlight").color || "",
27056
+ colors: isTextPalette ? textColors : highlightColors,
27057
+ currentColor: isTextPalette ? currentTextColor : currentHighlightColor,
26798
27058
  onSelect: (color) => {
26799
- if (color === "") {
26800
- editor.chain().focus().unsetHighlight().run();
27059
+ if (isTextPalette) {
27060
+ if (color === "inherit") {
27061
+ editor.chain().focus().unsetColor().run();
27062
+ } else {
27063
+ editor.chain().focus().setColor(color).run();
27064
+ }
26801
27065
  } else {
26802
- editor.chain().focus().toggleHighlight({ color }).run();
27066
+ if (color === "") {
27067
+ editor.chain().focus().unsetHighlight().run();
27068
+ } else {
27069
+ editor.chain().focus().toggleHighlight({ color }).run();
27070
+ }
26803
27071
  }
26804
27072
  },
26805
- label: t("colors.highlight")
27073
+ label: isTextPalette ? t("colors.textColor") : t("colors.highlight")
26806
27074
  }
26807
27075
  ),
26808
27076
  /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "p-2 border-t", children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
26809
27077
  "button",
26810
27078
  {
26811
27079
  type: "button",
26812
- onClick: () => setShowEditorColorPalette(false),
27080
+ onClick: () => setActiveColorPalette(null),
26813
27081
  className: "w-full py-1.5 text-sm rounded-lg hover:bg-muted transition-colors",
26814
27082
  children: t("colors.done")
26815
27083
  }
@@ -26830,6 +27098,162 @@ var BubbleMenuContent = ({
26830
27098
  /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(ToolbarButton, { onClick: () => deleteSelectedImage(editor), title: t("toolbar.imageDelete"), className: "text-destructive hover:text-destructive", children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_lucide_react45.Trash2, { className: "w-4 h-4" }) })
26831
27099
  ] });
26832
27100
  }
27101
+ if (showTypographyPanel) {
27102
+ return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "w-72 p-2", children: [
27103
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "mb-2 flex items-center justify-between gap-2", children: [
27104
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "px-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: t("toolbar.textStyle") }),
27105
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
27106
+ "button",
27107
+ {
27108
+ type: "button",
27109
+ onClick: () => setShowTypographyPanel(false),
27110
+ className: "rounded-md px-2 py-1 text-xs text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
27111
+ children: t("colors.done")
27112
+ }
27113
+ )
27114
+ ] }),
27115
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "space-y-2", children: [
27116
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { children: [
27117
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "mb-1 px-1 text-[11px] font-medium text-muted-foreground", children: t("toolbar.fontSize") }),
27118
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "flex h-9 items-center overflow-hidden rounded-md border border-border/60 bg-muted/40", children: [
27119
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
27120
+ "input",
27121
+ {
27122
+ type: "number",
27123
+ min: 8,
27124
+ max: 96,
27125
+ step: 1,
27126
+ value: fontSizeDraft,
27127
+ onChange: (event) => setFontSizeDraft(event.target.value),
27128
+ onBlur: applyFontSizeDraft,
27129
+ onMouseDown: (event) => event.stopPropagation(),
27130
+ onClick: (event) => event.stopPropagation(),
27131
+ onKeyDown: (event) => {
27132
+ event.stopPropagation();
27133
+ if (event.key === "Enter") {
27134
+ event.preventDefault();
27135
+ applyFontSizeDraft();
27136
+ }
27137
+ },
27138
+ "aria-label": t("toolbar.fontSize"),
27139
+ placeholder: "A",
27140
+ className: "h-full min-w-0 flex-1 bg-transparent px-2 text-center text-sm font-semibold text-foreground outline-none [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
27141
+ }
27142
+ ),
27143
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "border-l border-border/50 px-2 text-[11px] text-muted-foreground", children: "px" }),
27144
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
27145
+ "button",
27146
+ {
27147
+ type: "button",
27148
+ "aria-label": t("toolbar.fontSize"),
27149
+ onClick: () => setShowFontSizeOptions((open) => !open),
27150
+ className: cn(
27151
+ "flex h-full w-9 items-center justify-center border-l border-border/50 transition-colors hover:bg-muted",
27152
+ showFontSizeOptions && "bg-primary/10 text-primary"
27153
+ ),
27154
+ children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_lucide_react45.ChevronDown, { className: "h-4 w-4" })
27155
+ }
27156
+ )
27157
+ ] }),
27158
+ showFontSizeOptions && /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "mt-1 grid grid-cols-4 gap-1", children: [
27159
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
27160
+ "button",
27161
+ {
27162
+ type: "button",
27163
+ onClick: () => {
27164
+ editor.chain().focus().unsetFontSize().run();
27165
+ setShowFontSizeOptions(false);
27166
+ },
27167
+ className: cn(
27168
+ "h-8 rounded-md text-xs font-semibold transition-colors hover:bg-muted",
27169
+ !currentFontSize ? "bg-primary/10 text-primary" : "bg-muted/40 text-foreground"
27170
+ ),
27171
+ children: "A"
27172
+ }
27173
+ ),
27174
+ quickFontSizes.map((option) => /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
27175
+ "button",
27176
+ {
27177
+ type: "button",
27178
+ onClick: () => {
27179
+ editor.chain().focus().setFontSize(option.value).run();
27180
+ setShowFontSizeOptions(false);
27181
+ },
27182
+ className: cn(
27183
+ "h-8 rounded-md text-xs font-semibold transition-colors hover:bg-muted",
27184
+ normalizeStyleValue(option.value) === currentFontSize ? "bg-primary/10 text-primary" : "bg-muted/40 text-foreground"
27185
+ ),
27186
+ children: option.label
27187
+ },
27188
+ option.value
27189
+ ))
27190
+ ] })
27191
+ ] }),
27192
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { children: [
27193
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "mb-1 px-1 text-[11px] font-medium text-muted-foreground", children: t("toolbar.lineHeight") }),
27194
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "grid grid-cols-4 gap-1", children: [
27195
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
27196
+ "button",
27197
+ {
27198
+ type: "button",
27199
+ onClick: () => editor.chain().focus().unsetLineHeight().run(),
27200
+ className: cn(
27201
+ "h-8 rounded-md text-xs font-semibold transition-colors hover:bg-muted",
27202
+ !currentLineHeight ? "bg-primary/10 text-primary" : "bg-muted/40 text-foreground"
27203
+ ),
27204
+ children: "LH"
27205
+ }
27206
+ ),
27207
+ quickLineHeights.map((option) => /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
27208
+ "button",
27209
+ {
27210
+ type: "button",
27211
+ onClick: () => editor.chain().focus().setLineHeight(option.value).run(),
27212
+ className: cn(
27213
+ "h-8 rounded-md text-xs font-semibold transition-colors hover:bg-muted",
27214
+ normalizeStyleValue(option.value) === currentLineHeight ? "bg-primary/10 text-primary" : "bg-muted/40 text-foreground"
27215
+ ),
27216
+ children: option.label
27217
+ },
27218
+ option.value
27219
+ ))
27220
+ ] })
27221
+ ] }),
27222
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "grid grid-cols-2 gap-1 border-t border-border/40 pt-2", children: [
27223
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(
27224
+ "button",
27225
+ {
27226
+ type: "button",
27227
+ onClick: () => editor.chain().focus().toggleSubscript().run(),
27228
+ className: cn(
27229
+ "flex h-8 items-center justify-center gap-2 rounded-md text-xs font-semibold transition-colors hover:bg-muted",
27230
+ editor.isActive("subscript") ? "bg-primary/10 text-primary" : "bg-muted/40 text-foreground"
27231
+ ),
27232
+ children: [
27233
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_lucide_react45.Subscript, { className: "h-4 w-4" }),
27234
+ t("toolbar.subscript")
27235
+ ]
27236
+ }
27237
+ ),
27238
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(
27239
+ "button",
27240
+ {
27241
+ type: "button",
27242
+ onClick: () => editor.chain().focus().toggleSuperscript().run(),
27243
+ className: cn(
27244
+ "flex h-8 items-center justify-center gap-2 rounded-md text-xs font-semibold transition-colors hover:bg-muted",
27245
+ editor.isActive("superscript") ? "bg-primary/10 text-primary" : "bg-muted/40 text-foreground"
27246
+ ),
27247
+ children: [
27248
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_lucide_react45.Superscript, { className: "h-4 w-4" }),
27249
+ t("toolbar.superscript")
27250
+ ]
27251
+ }
27252
+ )
27253
+ ] })
27254
+ ] })
27255
+ ] });
27256
+ }
26833
27257
  return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "flex items-center gap-0.5 p-1", children: [
26834
27258
  /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(ToolbarButton, { onClick: () => editor.chain().focus().toggleBold().run(), active: editor.isActive("bold"), title: t("toolbar.bold"), children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_lucide_react45.Bold, { className: "w-4 h-4" }) }),
26835
27259
  /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(ToolbarButton, { onClick: () => editor.chain().focus().toggleItalic().run(), active: editor.isActive("italic"), title: t("toolbar.italic"), children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_lucide_react45.Italic, { className: "w-4 h-4" }) }),
@@ -26859,68 +27283,16 @@ var BubbleMenuContent = ({
26859
27283
  children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_lucide_react45.Link, { className: "w-4 h-4" })
26860
27284
  }
26861
27285
  ),
26862
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(ToolbarButton, { onClick: () => setShowEditorColorPalette(true), title: t("colors.textColor"), children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_lucide_react45.Palette, { className: "w-4 h-4" }) }),
26863
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "w-px h-6 bg-border/50 mx-1" }),
26864
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
26865
- ToolbarButton,
26866
- {
26867
- onClick: () => editor.chain().focus().unsetFontSize().run(),
26868
- active: !currentFontSize,
26869
- title: t("toolbar.sizeDefault"),
26870
- className: "px-2 w-auto",
26871
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "text-[10px] font-semibold", children: "A" })
26872
- }
26873
- ),
26874
- quickFontSizes.map((option) => /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
26875
- ToolbarButton,
26876
- {
26877
- onClick: () => editor.chain().focus().setFontSize(option.value).run(),
26878
- active: normalizeStyleValue(option.value) === currentFontSize,
26879
- title: `${t("toolbar.fontSize")} ${option.label}`,
26880
- className: "px-2 w-auto",
26881
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "text-[10px] font-semibold", children: option.label })
26882
- },
26883
- option.value
26884
- )),
26885
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "w-px h-6 bg-border/50 mx-1" }),
26886
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
26887
- ToolbarButton,
26888
- {
26889
- onClick: () => editor.chain().focus().unsetLineHeight().run(),
26890
- active: !currentLineHeight,
26891
- title: t("toolbar.lineHeightDefault"),
26892
- className: "px-2 w-auto",
26893
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "text-[10px] font-semibold leading-none", children: "LH" })
26894
- }
26895
- ),
26896
- quickLineHeights.map((option) => /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
26897
- ToolbarButton,
26898
- {
26899
- onClick: () => editor.chain().focus().setLineHeight(option.value).run(),
26900
- active: normalizeStyleValue(option.value) === currentLineHeight,
26901
- title: `${t("toolbar.lineHeight")} ${option.label}`,
26902
- className: "px-2 w-auto",
26903
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "text-[10px] font-semibold", children: option.label })
26904
- },
26905
- option.value
26906
- )),
27286
+ /* @__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
+ /* @__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 }) }),
26907
27288
  /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "w-px h-6 bg-border/50 mx-1" }),
26908
27289
  /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
26909
27290
  ToolbarButton,
26910
27291
  {
26911
- onClick: () => editor.chain().focus().toggleSubscript().run(),
26912
- active: editor.isActive("subscript"),
26913
- title: t("toolbar.subscript"),
26914
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_lucide_react45.Subscript, { className: "w-4 h-4" })
26915
- }
26916
- ),
26917
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
26918
- ToolbarButton,
26919
- {
26920
- onClick: () => editor.chain().focus().toggleSuperscript().run(),
26921
- active: editor.isActive("superscript"),
26922
- title: t("toolbar.superscript"),
26923
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_lucide_react45.Superscript, { className: "w-4 h-4" })
27292
+ onClick: () => setShowTypographyPanel(true),
27293
+ active: Boolean(currentFontSize || currentLineHeight || editor.isActive("subscript") || editor.isActive("superscript")),
27294
+ title: t("toolbar.textStyle"),
27295
+ children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_lucide_react45.Type, { className: "w-4 h-4" })
26924
27296
  }
26925
27297
  )
26926
27298
  ] });
@@ -26932,16 +27304,16 @@ var CustomBubbleMenu = ({
26932
27304
  }) => {
26933
27305
  const SHOW_DELAY_MS = 180;
26934
27306
  const BUBBLE_MENU_OFFSET = 16;
26935
- const [isVisible, setIsVisible] = (0, import_react50.useState)(false);
26936
- const [position, setPosition] = (0, import_react50.useState)({ top: 0, left: 0 });
26937
- const menuRef = (0, import_react50.useRef)(null);
26938
- const keepOpenRef = (0, import_react50.useRef)(false);
26939
- const showTimeoutRef = (0, import_react50.useRef)(null);
26940
- const setKeepOpen = (0, import_react50.useCallback)((next) => {
27307
+ const [isVisible, setIsVisible] = (0, import_react51.useState)(false);
27308
+ const [position, setPosition] = (0, import_react51.useState)({ top: 0, left: 0 });
27309
+ const menuRef = (0, import_react51.useRef)(null);
27310
+ const keepOpenRef = (0, import_react51.useRef)(false);
27311
+ const showTimeoutRef = (0, import_react51.useRef)(null);
27312
+ const setKeepOpen = (0, import_react51.useCallback)((next) => {
26941
27313
  keepOpenRef.current = next;
26942
27314
  if (next) setIsVisible(true);
26943
27315
  }, []);
26944
- (0, import_react50.useEffect)(() => {
27316
+ (0, import_react51.useEffect)(() => {
26945
27317
  const clearShowTimeout = () => {
26946
27318
  if (showTimeoutRef.current) {
26947
27319
  clearTimeout(showTimeoutRef.current);
@@ -26989,12 +27361,12 @@ var CustomBubbleMenu = ({
26989
27361
  };
26990
27362
  }, [editor]);
26991
27363
  if (!isVisible) return null;
26992
- return (0, import_react_dom8.createPortal)(
27364
+ return (0, import_react_dom9.createPortal)(
26993
27365
  /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
26994
27366
  "div",
26995
27367
  {
26996
27368
  ref: menuRef,
26997
- className: "fixed z-50 flex rounded-2xl border border-border/50 bg-card text-card-foreground shadow-lg backdrop-blur-sm overflow-hidden animate-in fade-in-0 zoom-in-95",
27369
+ className: "fixed z-50 flex rounded-xl border border-border/40 bg-card text-card-foreground shadow-lg backdrop-blur-sm overflow-hidden animate-in fade-in-0 zoom-in-95",
26998
27370
  style: {
26999
27371
  top: `${position.top}px`,
27000
27372
  left: `${position.left}px`,
@@ -27017,9 +27389,9 @@ var CustomBubbleMenu = ({
27017
27389
  };
27018
27390
  var CustomFloatingMenu = ({ editor }) => {
27019
27391
  const FLOATING_MENU_OFFSET = 16;
27020
- const [isVisible, setIsVisible] = (0, import_react50.useState)(false);
27021
- const [position, setPosition] = (0, import_react50.useState)({ top: 0, left: 0 });
27022
- (0, import_react50.useEffect)(() => {
27392
+ const [isVisible, setIsVisible] = (0, import_react51.useState)(false);
27393
+ const [position, setPosition] = (0, import_react51.useState)({ top: 0, left: 0 });
27394
+ (0, import_react51.useEffect)(() => {
27023
27395
  const updatePosition = () => {
27024
27396
  const { state, view } = editor;
27025
27397
  const { $from, empty } = state.selection;
@@ -27045,7 +27417,7 @@ var CustomFloatingMenu = ({ editor }) => {
27045
27417
  };
27046
27418
  }, [editor]);
27047
27419
  if (!isVisible) return null;
27048
- return (0, import_react_dom8.createPortal)(
27420
+ return (0, import_react_dom9.createPortal)(
27049
27421
  /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
27050
27422
  "div",
27051
27423
  {
@@ -27354,7 +27726,7 @@ async function prepareUEditorContentForSave({
27354
27726
  }
27355
27727
 
27356
27728
  // src/components/UEditor/table-controls.tsx
27357
- var import_react51 = __toESM(require("react"), 1);
27729
+ var import_react53 = __toESM(require("react"), 1);
27358
27730
 
27359
27731
  // node_modules/prosemirror-model/dist/index.js
27360
27732
  function findDiffStart(a, b, pos) {
@@ -31820,16 +32192,16 @@ function collectChildren(node) {
31820
32192
  }
31821
32193
  function TableControls({ editor, containerRef }) {
31822
32194
  const t = useSmartTranslations("UEditor");
31823
- const [layout, setLayout] = import_react51.default.useState(null);
31824
- const [dragPreview, setDragPreview] = import_react51.default.useState(null);
31825
- const [hoverState, setHoverState] = import_react51.default.useState(DEFAULT_HOVER_STATE);
31826
- const [openMenuKey, setOpenMenuKey] = import_react51.default.useState(null);
31827
- const layoutRef = import_react51.default.useRef(null);
31828
- const dragStateRef = import_react51.default.useRef(null);
31829
- import_react51.default.useEffect(() => {
32195
+ const [layout, setLayout] = import_react53.default.useState(null);
32196
+ const [dragPreview, setDragPreview] = import_react53.default.useState(null);
32197
+ const [hoverState, setHoverState] = import_react53.default.useState(DEFAULT_HOVER_STATE);
32198
+ const [openMenuKey, setOpenMenuKey] = import_react53.default.useState(null);
32199
+ const layoutRef = import_react53.default.useRef(null);
32200
+ const dragStateRef = import_react53.default.useRef(null);
32201
+ import_react53.default.useEffect(() => {
31830
32202
  layoutRef.current = layout;
31831
32203
  }, [layout]);
31832
- const syncFromCell = import_react51.default.useCallback((cell) => {
32204
+ const syncFromCell = import_react53.default.useCallback((cell) => {
31833
32205
  const surface = containerRef.current;
31834
32206
  if (!surface || !cell) {
31835
32207
  setLayout(null);
@@ -31837,10 +32209,10 @@ function TableControls({ editor, containerRef }) {
31837
32209
  }
31838
32210
  setLayout(buildLayout(editor, surface, cell));
31839
32211
  }, [containerRef, editor]);
31840
- const syncFromSelection = import_react51.default.useCallback(() => {
32212
+ const syncFromSelection = import_react53.default.useCallback(() => {
31841
32213
  syncFromCell(getSelectedCell(editor));
31842
32214
  }, [editor, syncFromCell]);
31843
- const refreshCurrentLayout = import_react51.default.useCallback(() => {
32215
+ const refreshCurrentLayout = import_react53.default.useCallback(() => {
31844
32216
  setLayout((prev) => {
31845
32217
  if (!prev) return prev;
31846
32218
  const surface = containerRef.current;
@@ -31850,12 +32222,12 @@ function TableControls({ editor, containerRef }) {
31850
32222
  return cell ? buildLayout(editor, surface, cell) : null;
31851
32223
  });
31852
32224
  }, [containerRef, editor]);
31853
- const clearDrag = import_react51.default.useCallback(() => {
32225
+ const clearDrag = import_react53.default.useCallback(() => {
31854
32226
  dragStateRef.current = null;
31855
32227
  setDragPreview(null);
31856
32228
  document.body.style.cursor = "";
31857
32229
  }, []);
31858
- const updateHoverState = import_react51.default.useCallback((event) => {
32230
+ const updateHoverState = import_react53.default.useCallback((event) => {
31859
32231
  const activeLayout = layoutRef.current;
31860
32232
  const surface = containerRef.current;
31861
32233
  if (!activeLayout || !surface || dragStateRef.current) {
@@ -31893,7 +32265,7 @@ function TableControls({ editor, containerRef }) {
31893
32265
  };
31894
32266
  });
31895
32267
  }, [containerRef]);
31896
- import_react51.default.useEffect(() => {
32268
+ import_react53.default.useEffect(() => {
31897
32269
  const proseMirror = editor.view.dom;
31898
32270
  const surface = containerRef.current;
31899
32271
  if (!surface) return void 0;
@@ -31938,7 +32310,7 @@ function TableControls({ editor, containerRef }) {
31938
32310
  editor.off("update", refreshCurrentLayout);
31939
32311
  };
31940
32312
  }, [clearDrag, containerRef, editor, refreshCurrentLayout, syncFromCell, syncFromSelection, updateHoverState]);
31941
- const runAtCellPos = import_react51.default.useCallback((cellPos, command, options) => {
32313
+ const runAtCellPos = import_react53.default.useCallback((cellPos, command, options) => {
31942
32314
  if (cellPos == null) return false;
31943
32315
  focusCell(editor, cellPos);
31944
32316
  const result = command(editor.chain().focus(null, { scrollIntoView: false })).run();
@@ -31947,17 +32319,17 @@ function TableControls({ editor, containerRef }) {
31947
32319
  }
31948
32320
  return result;
31949
32321
  }, [editor, syncFromSelection]);
31950
- const runAtActiveCell = import_react51.default.useCallback((command, options) => {
32322
+ const runAtActiveCell = import_react53.default.useCallback((command, options) => {
31951
32323
  return runAtCellPos(layoutRef.current?.cellPos ?? null, command, options);
31952
32324
  }, [runAtCellPos]);
31953
- const getCurrentCornerCellPos = import_react51.default.useCallback(() => {
32325
+ const getCurrentCornerCellPos = import_react53.default.useCallback(() => {
31954
32326
  const activePos = layoutRef.current?.cellPos ?? editor.state.selection.from;
31955
32327
  return getLastCellPosFromState(editor, activePos);
31956
32328
  }, [editor]);
31957
- const runAtCornerCell = import_react51.default.useCallback((command, options) => {
32329
+ const runAtCornerCell = import_react53.default.useCallback((command, options) => {
31958
32330
  return runAtCellPos(getCurrentCornerCellPos(), command, options);
31959
32331
  }, [getCurrentCornerCellPos, runAtCellPos]);
31960
- const replaceTableAtCellPos = import_react51.default.useCallback((cellPos, updateTable) => {
32332
+ const replaceTableAtCellPos = import_react53.default.useCallback((cellPos, updateTable) => {
31961
32333
  if (cellPos == null) return false;
31962
32334
  const tableInfo = findTableInfo(editor, cellPos);
31963
32335
  if (!tableInfo) return false;
@@ -31967,10 +32339,10 @@ function TableControls({ editor, containerRef }) {
31967
32339
  requestAnimationFrame(syncFromSelection);
31968
32340
  return true;
31969
32341
  }, [editor, syncFromSelection]);
31970
- const createEmptyCellNode = import_react51.default.useCallback((cellNode) => {
32342
+ const createEmptyCellNode = import_react53.default.useCallback((cellNode) => {
31971
32343
  return cellNode.type.createAndFill(cellNode.attrs) ?? cellNode;
31972
32344
  }, []);
31973
- const duplicateRowAt = import_react51.default.useCallback((rowIndex, cellPos) => {
32345
+ const duplicateRowAt = import_react53.default.useCallback((rowIndex, cellPos) => {
31974
32346
  return replaceTableAtCellPos(cellPos, (tableNode) => {
31975
32347
  const rows = collectChildren(tableNode);
31976
32348
  const rowNode = rows[rowIndex];
@@ -31979,7 +32351,7 @@ function TableControls({ editor, containerRef }) {
31979
32351
  return tableNode.type.create(tableNode.attrs, rows);
31980
32352
  });
31981
32353
  }, [replaceTableAtCellPos]);
31982
- const clearRowAt = import_react51.default.useCallback((rowIndex, cellPos) => {
32354
+ const clearRowAt = import_react53.default.useCallback((rowIndex, cellPos) => {
31983
32355
  return replaceTableAtCellPos(cellPos, (tableNode) => {
31984
32356
  const rows = collectChildren(tableNode);
31985
32357
  const rowNode = rows[rowIndex];
@@ -31989,7 +32361,7 @@ function TableControls({ editor, containerRef }) {
31989
32361
  return tableNode.type.create(tableNode.attrs, rows);
31990
32362
  });
31991
32363
  }, [createEmptyCellNode, replaceTableAtCellPos]);
31992
- const duplicateColumnAt = import_react51.default.useCallback((columnIndex, cellPos) => {
32364
+ const duplicateColumnAt = import_react53.default.useCallback((columnIndex, cellPos) => {
31993
32365
  return replaceTableAtCellPos(cellPos, (tableNode) => {
31994
32366
  const rows = collectChildren(tableNode).map((rowNode) => {
31995
32367
  const cells = collectChildren(rowNode);
@@ -32001,7 +32373,7 @@ function TableControls({ editor, containerRef }) {
32001
32373
  return tableNode.type.create(tableNode.attrs, rows);
32002
32374
  });
32003
32375
  }, [replaceTableAtCellPos]);
32004
- const clearColumnAt = import_react51.default.useCallback((columnIndex, cellPos) => {
32376
+ const clearColumnAt = import_react53.default.useCallback((columnIndex, cellPos) => {
32005
32377
  return replaceTableAtCellPos(cellPos, (tableNode) => {
32006
32378
  const rows = collectChildren(tableNode).map((rowNode) => {
32007
32379
  const cells = collectChildren(rowNode);
@@ -32013,7 +32385,7 @@ function TableControls({ editor, containerRef }) {
32013
32385
  return tableNode.type.create(tableNode.attrs, rows);
32014
32386
  });
32015
32387
  }, [createEmptyCellNode, replaceTableAtCellPos]);
32016
- const expandTableBy = import_react51.default.useCallback((rows, cols) => {
32388
+ const expandTableBy = import_react53.default.useCallback((rows, cols) => {
32017
32389
  let ok = true;
32018
32390
  for (let index = 0; index < rows; index += 1) {
32019
32391
  ok = runAtCornerCell((chain) => chain.addRowAfter(), { sync: false });
@@ -32029,9 +32401,9 @@ function TableControls({ editor, containerRef }) {
32029
32401
  const canExpandTable = Boolean(layout);
32030
32402
  const controlsVisible = dragPreview !== null;
32031
32403
  const tableMenuOpen = openMenuKey === "table";
32032
- const getRowMenuKey = import_react51.default.useCallback((index) => `row:${index}`, []);
32033
- const getColumnMenuKey = import_react51.default.useCallback((index) => `column:${index}`, []);
32034
- import_react51.default.useEffect(() => {
32404
+ const getRowMenuKey = import_react53.default.useCallback((index) => `row:${index}`, []);
32405
+ const getColumnMenuKey = import_react53.default.useCallback((index) => `column:${index}`, []);
32406
+ import_react53.default.useEffect(() => {
32035
32407
  const handleMouseMove = (event) => {
32036
32408
  const dragState = dragStateRef.current;
32037
32409
  const activeLayout = layoutRef.current;
@@ -32118,7 +32490,7 @@ function TableControls({ editor, containerRef }) {
32118
32490
  window.removeEventListener("blur", clearDrag);
32119
32491
  };
32120
32492
  }, [clearDrag, containerRef, editor, expandTableBy, syncFromSelection]);
32121
- const menuItems = import_react51.default.useMemo(() => {
32493
+ const menuItems = import_react53.default.useMemo(() => {
32122
32494
  if (!layout) return [];
32123
32495
  return [
32124
32496
  {
@@ -32186,7 +32558,7 @@ function TableControls({ editor, containerRef }) {
32186
32558
  }
32187
32559
  ];
32188
32560
  }, [layout, runAtActiveCell, t]);
32189
- const getRowHandleMenuItems = import_react51.default.useCallback((rowHandle) => [
32561
+ const getRowHandleMenuItems = import_react53.default.useCallback((rowHandle) => [
32190
32562
  {
32191
32563
  label: t("tableMenu.addRowBefore"),
32192
32564
  icon: import_lucide_react46.ArrowUp,
@@ -32214,7 +32586,7 @@ function TableControls({ editor, containerRef }) {
32214
32586
  destructive: true
32215
32587
  }
32216
32588
  ], [clearRowAt, duplicateRowAt, runAtCellPos, t]);
32217
- const getColumnHandleMenuItems = import_react51.default.useCallback((columnHandle) => [
32589
+ const getColumnHandleMenuItems = import_react53.default.useCallback((columnHandle) => [
32218
32590
  {
32219
32591
  label: t("tableMenu.addColumnBefore"),
32220
32592
  icon: import_lucide_react46.ArrowLeft,
@@ -32763,10 +33135,10 @@ var UEDITOR_PROSEMIRROR_CLASS_NAME = cn(
32763
33135
  );
32764
33136
 
32765
33137
  // src/components/UEditor/use-table-interactions.ts
32766
- var import_react53 = __toESM(require("react"), 1);
33138
+ var import_react55 = __toESM(require("react"), 1);
32767
33139
 
32768
33140
  // src/components/UEditor/use-table-row-resize.ts
32769
- var import_react52 = __toESM(require("react"), 1);
33141
+ var import_react54 = __toESM(require("react"), 1);
32770
33142
  function useTableRowResize({
32771
33143
  editor,
32772
33144
  setHoveredTableCell,
@@ -32775,9 +33147,9 @@ function useTableRowResize({
32775
33147
  clearAllTableResizeHover,
32776
33148
  scheduleTableLayoutSync
32777
33149
  }) {
32778
- const commitFrameRef = (0, import_react52.useRef)(null);
32779
- const stateRef = (0, import_react52.useRef)(null);
32780
- const commitPreview = import_react52.default.useCallback(() => {
33150
+ const commitFrameRef = (0, import_react54.useRef)(null);
33151
+ const stateRef = (0, import_react54.useRef)(null);
33152
+ const commitPreview = import_react54.default.useCallback(() => {
32781
33153
  if (!editor) return;
32782
33154
  const state = stateRef.current;
32783
33155
  if (!state) return;
@@ -32812,22 +33184,22 @@ function useTableRowResize({
32812
33184
  showRowGuide(state.tableElement, state.rowElement, state.cellElement);
32813
33185
  scheduleTableLayoutSync();
32814
33186
  }, [editor, scheduleTableLayoutSync, showRowGuide]);
32815
- const scheduleCommit = import_react52.default.useCallback(() => {
33187
+ const scheduleCommit = import_react54.default.useCallback(() => {
32816
33188
  if (commitFrameRef.current !== null) return;
32817
33189
  commitFrameRef.current = window.requestAnimationFrame(() => {
32818
33190
  commitFrameRef.current = null;
32819
33191
  commitPreview();
32820
33192
  });
32821
33193
  }, [commitPreview]);
32822
- const syncActiveGuide = import_react52.default.useCallback(() => {
33194
+ const syncActiveGuide = import_react54.default.useCallback(() => {
32823
33195
  const state = stateRef.current;
32824
33196
  if (!state) return false;
32825
33197
  setHoveredTableCell(state.cellElement);
32826
33198
  showRowGuide(state.tableElement, state.rowElement, state.cellElement);
32827
33199
  return true;
32828
33200
  }, [setHoveredTableCell, showRowGuide]);
32829
- const isResizing = import_react52.default.useCallback(() => stateRef.current !== null, []);
32830
- const beginResize = import_react52.default.useCallback((event, table, row, cell) => {
33201
+ const isResizing = import_react54.default.useCallback(() => stateRef.current !== null, []);
33202
+ const beginResize = import_react54.default.useCallback((event, table, row, cell) => {
32831
33203
  if (!editor || !isRowResizeHotspot(cell, event.clientX, event.clientY)) {
32832
33204
  return false;
32833
33205
  }
@@ -32853,7 +33225,7 @@ function useTableRowResize({
32853
33225
  event.stopPropagation();
32854
33226
  return true;
32855
33227
  }, [editor, setHoveredTableCell, showRowGuide]);
32856
- const handlePointerMove = import_react52.default.useCallback((event) => {
33228
+ const handlePointerMove = import_react54.default.useCallback((event) => {
32857
33229
  const state = stateRef.current;
32858
33230
  if (!state) return;
32859
33231
  const nextHeight = Math.max(
@@ -32869,7 +33241,7 @@ function useTableRowResize({
32869
33241
  document.body.style.cursor = "row-resize";
32870
33242
  scheduleCommit();
32871
33243
  }, [scheduleCommit, showRowGuide]);
32872
- const handlePointerUp = import_react52.default.useCallback((event) => {
33244
+ const handlePointerUp = import_react54.default.useCallback((event) => {
32873
33245
  if (!editor) return;
32874
33246
  const state = stateRef.current;
32875
33247
  if (!state) return;
@@ -32899,7 +33271,7 @@ function useTableRowResize({
32899
33271
  clearAllTableResizeHover();
32900
33272
  scheduleTableLayoutSync();
32901
33273
  }, [clearAllTableResizeHover, clearHoveredTableCell, commitPreview, editor, scheduleTableLayoutSync]);
32902
- const cancelResize = import_react52.default.useCallback(() => {
33274
+ const cancelResize = import_react54.default.useCallback(() => {
32903
33275
  if (!stateRef.current) return;
32904
33276
  if (commitFrameRef.current !== null) {
32905
33277
  window.cancelAnimationFrame(commitFrameRef.current);
@@ -32911,7 +33283,7 @@ function useTableRowResize({
32911
33283
  clearAllTableResizeHover();
32912
33284
  scheduleTableLayoutSync();
32913
33285
  }, [clearAllTableResizeHover, clearHoveredTableCell, scheduleTableLayoutSync]);
32914
- const cleanup = import_react52.default.useCallback(() => {
33286
+ const cleanup = import_react54.default.useCallback(() => {
32915
33287
  if (commitFrameRef.current !== null) {
32916
33288
  window.cancelAnimationFrame(commitFrameRef.current);
32917
33289
  commitFrameRef.current = null;
@@ -32932,40 +33304,40 @@ function useTableRowResize({
32932
33304
 
32933
33305
  // src/components/UEditor/use-table-interactions.ts
32934
33306
  function useUEditorTableInteractions(editor, editable = true) {
32935
- const editorContentRef = (0, import_react53.useRef)(null);
32936
- const tableColumnGuideRef = (0, import_react53.useRef)(null);
32937
- const tableRowGuideRef = (0, import_react53.useRef)(null);
32938
- const activeTableCellHighlightRef = (0, import_react53.useRef)(null);
32939
- const hoveredTableCellRef = (0, import_react53.useRef)(null);
32940
- const activeTableCellRef = (0, import_react53.useRef)(null);
32941
- const suppressActiveCellHighlightRef = (0, import_react53.useRef)(false);
32942
- const tableLayoutSyncFrameRef = (0, import_react53.useRef)(null);
32943
- const setEditorResizeCursor = import_react53.default.useCallback((cursor) => {
33307
+ const editorContentRef = (0, import_react55.useRef)(null);
33308
+ const tableColumnGuideRef = (0, import_react55.useRef)(null);
33309
+ const tableRowGuideRef = (0, import_react55.useRef)(null);
33310
+ const activeTableCellHighlightRef = (0, import_react55.useRef)(null);
33311
+ const hoveredTableCellRef = (0, import_react55.useRef)(null);
33312
+ const activeTableCellRef = (0, import_react55.useRef)(null);
33313
+ const suppressActiveCellHighlightRef = (0, import_react55.useRef)(false);
33314
+ const tableLayoutSyncFrameRef = (0, import_react55.useRef)(null);
33315
+ const setEditorResizeCursor = import_react55.default.useCallback((cursor) => {
32944
33316
  const proseMirror = editorContentRef.current?.querySelector(".ProseMirror");
32945
33317
  if (proseMirror) {
32946
33318
  proseMirror.style.cursor = cursor;
32947
33319
  }
32948
33320
  }, []);
32949
- const hideColumnGuide = import_react53.default.useCallback(() => {
33321
+ const hideColumnGuide = import_react55.default.useCallback(() => {
32950
33322
  editorContentRef.current?.classList.remove("resize-cursor");
32951
33323
  const guide = tableColumnGuideRef.current;
32952
33324
  if (guide) {
32953
33325
  guide.style.opacity = "0";
32954
33326
  }
32955
33327
  }, []);
32956
- const hideRowGuide = import_react53.default.useCallback(() => {
33328
+ const hideRowGuide = import_react55.default.useCallback(() => {
32957
33329
  editorContentRef.current?.classList.remove("resize-row-cursor");
32958
33330
  const guide = tableRowGuideRef.current;
32959
33331
  if (guide) {
32960
33332
  guide.style.opacity = "0";
32961
33333
  }
32962
33334
  }, []);
32963
- const clearAllTableResizeHover = import_react53.default.useCallback(() => {
33335
+ const clearAllTableResizeHover = import_react55.default.useCallback(() => {
32964
33336
  setEditorResizeCursor("");
32965
33337
  hideColumnGuide();
32966
33338
  hideRowGuide();
32967
33339
  }, [hideColumnGuide, hideRowGuide, setEditorResizeCursor]);
32968
- const updateActiveCellHighlight = import_react53.default.useCallback((cell) => {
33340
+ const updateActiveCellHighlight = import_react55.default.useCallback((cell) => {
32969
33341
  const surface = editorContentRef.current;
32970
33342
  const highlight = activeTableCellHighlightRef.current;
32971
33343
  if (!highlight) return;
@@ -32980,7 +33352,7 @@ function useUEditorTableInteractions(editor, editable = true) {
32980
33352
  highlight.style.width = `${metrics.width}px`;
32981
33353
  highlight.style.height = `${metrics.height}px`;
32982
33354
  }, []);
32983
- const scheduleTableLayoutSync = import_react53.default.useCallback(() => {
33355
+ const scheduleTableLayoutSync = import_react55.default.useCallback(() => {
32984
33356
  if (tableLayoutSyncFrameRef.current !== null) return;
32985
33357
  tableLayoutSyncFrameRef.current = window.requestAnimationFrame(() => {
32986
33358
  tableLayoutSyncFrameRef.current = null;
@@ -32988,22 +33360,22 @@ function useUEditorTableInteractions(editor, editable = true) {
32988
33360
  editorContentRef.current?.dispatchEvent(new CustomEvent(UEDITOR_TABLE_LAYOUT_CHANGE_EVENT));
32989
33361
  });
32990
33362
  }, [updateActiveCellHighlight]);
32991
- const setActiveTableCell = import_react53.default.useCallback((cell) => {
33363
+ const setActiveTableCell = import_react55.default.useCallback((cell) => {
32992
33364
  if (activeTableCellRef.current === cell) return;
32993
33365
  activeTableCellRef.current = cell;
32994
33366
  updateActiveCellHighlight(activeTableCellRef.current);
32995
33367
  }, [updateActiveCellHighlight]);
32996
- const clearActiveTableCell = import_react53.default.useCallback(() => {
33368
+ const clearActiveTableCell = import_react55.default.useCallback(() => {
32997
33369
  activeTableCellRef.current = null;
32998
33370
  updateActiveCellHighlight(null);
32999
33371
  }, [updateActiveCellHighlight]);
33000
- const setHoveredTableCell = import_react53.default.useCallback((cell) => {
33372
+ const setHoveredTableCell = import_react55.default.useCallback((cell) => {
33001
33373
  hoveredTableCellRef.current = cell;
33002
33374
  }, []);
33003
- const clearHoveredTableCell = import_react53.default.useCallback(() => {
33375
+ const clearHoveredTableCell = import_react55.default.useCallback(() => {
33004
33376
  hoveredTableCellRef.current = null;
33005
33377
  }, []);
33006
- const showColumnGuide = import_react53.default.useCallback((table, row, cell) => {
33378
+ const showColumnGuide = import_react55.default.useCallback((table, row, cell) => {
33007
33379
  const surface = editorContentRef.current;
33008
33380
  const guide = tableColumnGuideRef.current;
33009
33381
  if (!surface || !guide) return;
@@ -33016,7 +33388,7 @@ function useUEditorTableInteractions(editor, editable = true) {
33016
33388
  surface.classList.add("resize-cursor");
33017
33389
  setEditorResizeCursor("col-resize");
33018
33390
  }, [setEditorResizeCursor]);
33019
- const showRowGuide = import_react53.default.useCallback((table, row, cell) => {
33391
+ const showRowGuide = import_react55.default.useCallback((table, row, cell) => {
33020
33392
  const surface = editorContentRef.current;
33021
33393
  const guide = tableRowGuideRef.current;
33022
33394
  if (!surface || !guide) return;
@@ -33045,11 +33417,11 @@ function useUEditorTableInteractions(editor, editable = true) {
33045
33417
  clearAllTableResizeHover,
33046
33418
  scheduleTableLayoutSync
33047
33419
  });
33048
- const syncActiveTableCellFromSelection = import_react53.default.useCallback(() => {
33420
+ const syncActiveTableCellFromSelection = import_react55.default.useCallback(() => {
33049
33421
  if (!editor) return;
33050
33422
  setActiveTableCell(getSelectionTableCell(editor.view));
33051
33423
  }, [editor, setActiveTableCell]);
33052
- (0, import_react53.useEffect)(() => {
33424
+ (0, import_react55.useEffect)(() => {
33053
33425
  if (!editor || !editable) return void 0;
33054
33426
  const proseMirror = editor.view.dom;
33055
33427
  const surface = editorContentRef.current;
@@ -33210,7 +33582,7 @@ function useUEditorTableInteractions(editor, editable = true) {
33210
33582
 
33211
33583
  // src/components/UEditor/UEditor.tsx
33212
33584
  var import_jsx_runtime85 = require("react/jsx-runtime");
33213
- var UEditor = import_react54.default.forwardRef(({
33585
+ var UEditor = import_react56.default.forwardRef(({
33214
33586
  content = "",
33215
33587
  onChange,
33216
33588
  onHtmlChange,
@@ -33241,9 +33613,9 @@ var UEditor = import_react54.default.forwardRef(({
33241
33613
  }, ref) => {
33242
33614
  const t = useSmartTranslations("UEditor");
33243
33615
  const effectivePlaceholder = placeholder ?? t("placeholder");
33244
- const inFlightPrepareRef = (0, import_react54.useRef)(null);
33245
- const lastAppliedContentRef = (0, import_react54.useRef)(content ?? "");
33246
- const extensions = (0, import_react54.useMemo)(
33616
+ const inFlightPrepareRef = (0, import_react56.useRef)(null);
33617
+ const lastAppliedContentRef = (0, import_react56.useRef)(content ?? "");
33618
+ const extensions = (0, import_react56.useMemo)(
33247
33619
  () => buildUEditorExtensions({
33248
33620
  placeholder: effectivePlaceholder,
33249
33621
  translate: t,
@@ -33257,7 +33629,7 @@ var UEditor = import_react54.default.forwardRef(({
33257
33629
  }),
33258
33630
  [effectivePlaceholder, t, maxCharacters, uploadImage, imageInsertMode, maxImageFileSize, allowedImageMimeTypes, fallbackToDataUrl, editable]
33259
33631
  );
33260
- const editor = (0, import_react55.useEditor)({
33632
+ const editor = (0, import_react57.useEditor)({
33261
33633
  immediatelyRender: false,
33262
33634
  extensions,
33263
33635
  content,
@@ -33303,7 +33675,7 @@ var UEditor = import_react54.default.forwardRef(({
33303
33675
  tableRowGuideRef,
33304
33676
  activeTableCellHighlightRef
33305
33677
  } = useUEditorTableInteractions(editor, editable);
33306
- (0, import_react54.useImperativeHandle)(
33678
+ (0, import_react56.useImperativeHandle)(
33307
33679
  ref,
33308
33680
  () => ({
33309
33681
  prepareContentForSave: async ({ throwOnError = false } = {}) => {
@@ -33326,7 +33698,7 @@ var UEditor = import_react54.default.forwardRef(({
33326
33698
  }),
33327
33699
  [content, editor, uploadImageForSave, uploadImageConcurrency]
33328
33700
  );
33329
- (0, import_react54.useEffect)(() => {
33701
+ (0, import_react56.useEffect)(() => {
33330
33702
  if (!editor) return;
33331
33703
  const nextContent = content ?? "";
33332
33704
  if (lastAppliedContentRef.current === nextContent) return;
@@ -33421,7 +33793,7 @@ var UEditor = import_react54.default.forwardRef(({
33421
33793
  ),
33422
33794
  editable && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(TableControls, { editor, containerRef: editorContentRef }),
33423
33795
  /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
33424
- import_react55.EditorContent,
33796
+ import_react57.EditorContent,
33425
33797
  {
33426
33798
  editor,
33427
33799
  className: "min-h-full"