@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.js CHANGED
@@ -688,6 +688,9 @@ var en_default = {
688
688
  accent: "Accent",
689
689
  textColor: "Text Color",
690
690
  highlight: "Highlight",
691
+ automatic: "Automatic",
692
+ moreColors: "More Colors...",
693
+ color: "Color",
691
694
  done: "Done"
692
695
  },
693
696
  toolbar: {
@@ -702,6 +705,7 @@ var en_default = {
702
705
  subscript: "Subscript",
703
706
  superscript: "Superscript",
704
707
  link: "Link",
708
+ removeLink: "Remove Link",
705
709
  image: "Insert Image",
706
710
  table: "Insert Table",
707
711
  alignment: "Alignment",
@@ -953,6 +957,9 @@ var vi_default = {
953
957
  accent: "Nh\u1EA5n",
954
958
  textColor: "M\xE0u ch\u1EEF",
955
959
  highlight: "N\u1ED5i b\u1EADt",
960
+ automatic: "T\u1EF1 \u0111\u1ED9ng",
961
+ moreColors: "Th\xEAm m\xE0u...",
962
+ color: "M\xE0u",
956
963
  done: "Xong"
957
964
  },
958
965
  toolbar: {
@@ -967,6 +974,7 @@ var vi_default = {
967
974
  subscript: "Ch\u1EC9 s\u1ED1 d\u01B0\u1EDBi",
968
975
  superscript: "Ch\u1EC9 s\u1ED1 tr\xEAn",
969
976
  link: "Li\xEAn k\u1EBFt",
977
+ removeLink: "G\u1EE1 li\xEAn k\u1EBFt",
970
978
  image: "Ch\xE8n \u1EA3nh",
971
979
  table: "Ch\xE8n b\u1EA3ng",
972
980
  alignment: "C\u0103n ch\u1EC9nh",
@@ -1218,6 +1226,9 @@ var ko_default = {
1218
1226
  accent: "\uAC15\uC870",
1219
1227
  textColor: "\uD14D\uC2A4\uD2B8 \uC0C9\uC0C1",
1220
1228
  highlight: "\uD615\uAD11\uD39C",
1229
+ automatic: "\uC790\uB3D9",
1230
+ moreColors: "\uB2E4\uB978 \uC0C9...",
1231
+ color: "\uC0C9\uC0C1",
1221
1232
  done: "\uC644\uB8CC"
1222
1233
  },
1223
1234
  toolbar: {
@@ -1232,6 +1243,7 @@ var ko_default = {
1232
1243
  subscript: "\uC544\uB798 \uCCA8\uC790",
1233
1244
  superscript: "\uC704 \uCCA8\uC790",
1234
1245
  link: "\uB9C1\uD06C",
1246
+ removeLink: "\uB9C1\uD06C \uC81C\uAC70",
1235
1247
  image: "\uC774\uBBF8\uC9C0",
1236
1248
  table: "\uD45C",
1237
1249
  alignment: "\uC815\uB82C",
@@ -1482,6 +1494,9 @@ var ja_default = {
1482
1494
  accent: "\u30A2\u30AF\u30BB\u30F3\u30C8",
1483
1495
  textColor: "\u30C6\u30AD\u30B9\u30C8\u8272",
1484
1496
  highlight: "\u30CF\u30A4\u30E9\u30A4\u30C8",
1497
+ automatic: "\u81EA\u52D5",
1498
+ moreColors: "\u305D\u306E\u4ED6\u306E\u8272...",
1499
+ color: "\u8272",
1485
1500
  done: "\u5B8C\u4E86"
1486
1501
  },
1487
1502
  toolbar: {
@@ -1496,6 +1511,7 @@ var ja_default = {
1496
1511
  subscript: "\u4E0B\u4ED8\u304D",
1497
1512
  superscript: "\u4E0A\u4ED8\u304D",
1498
1513
  link: "\u30EA\u30F3\u30AF",
1514
+ removeLink: "\u30EA\u30F3\u30AF\u3092\u89E3\u9664",
1499
1515
  image: "\u753B\u50CF",
1500
1516
  table: "\u8868",
1501
1517
  alignment: "\u914D\u7F6E",
@@ -23816,7 +23832,7 @@ function useLocale2() {
23816
23832
  }
23817
23833
 
23818
23834
  // src/components/UEditor/UEditor.tsx
23819
- import React78, { useEffect as useEffect36, useImperativeHandle as useImperativeHandle3, useMemo as useMemo24, useRef as useRef34 } from "react";
23835
+ import React78, { useEffect as useEffect36, useImperativeHandle as useImperativeHandle3, useMemo as useMemo24, useRef as useRef35 } from "react";
23820
23836
  import { useEditor, EditorContent } from "@tiptap/react";
23821
23837
 
23822
23838
  // src/components/UEditor/extensions.ts
@@ -25281,7 +25297,9 @@ function buildUEditorExtensions({
25281
25297
  }
25282
25298
 
25283
25299
  // src/components/UEditor/toolbar.tsx
25284
- import React73, { useRef as useRef30, useState as useState44 } from "react";
25300
+ import React73, { useRef as useRef31, useState as useState44 } from "react";
25301
+ import { createPortal as createPortal8 } from "react-dom";
25302
+ import { useEditorState } from "@tiptap/react";
25285
25303
  import {
25286
25304
  AlignCenter,
25287
25305
  AlignJustify,
@@ -25298,14 +25316,12 @@ import {
25298
25316
  Heading1 as Heading1Icon,
25299
25317
  Heading2 as Heading2Icon,
25300
25318
  Heading3 as Heading3Icon,
25301
- Highlighter,
25302
25319
  Image as ImageIcon2,
25303
25320
  Italic as ItalicIcon,
25304
25321
  Link as LinkIcon,
25305
25322
  List as ListIcon,
25306
25323
  ListOrdered as ListOrderedIcon,
25307
25324
  ListTodo as ListTodo2,
25308
- Palette as Palette2,
25309
25325
  Quote as QuoteIcon,
25310
25326
  Redo as RedoIcon,
25311
25327
  RotateCcw as RotateCcw2,
@@ -25322,9 +25338,108 @@ import {
25322
25338
  } from "lucide-react";
25323
25339
 
25324
25340
  // src/components/UEditor/colors.tsx
25325
- import { useMemo as useMemo22 } from "react";
25326
- import { X as X18 } from "lucide-react";
25341
+ import { useMemo as useMemo22, useRef as useRef29 } from "react";
25342
+ import { Check as Check10, Highlighter, Palette as Palette2 } from "lucide-react";
25327
25343
  import { jsx as jsx78, jsxs as jsxs65 } from "react/jsx-runtime";
25344
+ var TextColorIcon = ({ color }) => {
25345
+ const underlineColor = color && color !== "inherit" ? color : "currentColor";
25346
+ return /* @__PURE__ */ jsxs65("span", { className: "relative flex h-5 w-5 items-center justify-center leading-none", children: [
25347
+ /* @__PURE__ */ jsx78("span", { className: "text-[15px] font-semibold leading-none", children: "A" }),
25348
+ /* @__PURE__ */ jsx78(
25349
+ "span",
25350
+ {
25351
+ "aria-hidden": "true",
25352
+ className: "absolute bottom-0 left-1/2 h-0.5 w-4 -translate-x-1/2 rounded-full",
25353
+ style: { backgroundColor: underlineColor }
25354
+ }
25355
+ )
25356
+ ] });
25357
+ };
25358
+ var HighlightColorIcon = ({ color }) => {
25359
+ const underlineColor = color || "currentColor";
25360
+ return /* @__PURE__ */ jsxs65("span", { className: "relative flex h-5 w-5 items-center justify-center leading-none", children: [
25361
+ /* @__PURE__ */ jsx78(Highlighter, { className: "h-4 w-4" }),
25362
+ /* @__PURE__ */ jsx78(
25363
+ "span",
25364
+ {
25365
+ "aria-hidden": "true",
25366
+ className: "absolute bottom-0 left-1/2 h-0.5 w-4 -translate-x-1/2 rounded-full",
25367
+ style: { backgroundColor: underlineColor }
25368
+ }
25369
+ )
25370
+ ] });
25371
+ };
25372
+ var EDITOR_COLOR_SWATCHES = [
25373
+ "#000000",
25374
+ "#3f3f46",
25375
+ "#713f12",
25376
+ "#14532d",
25377
+ "#164e63",
25378
+ "#1e3a8a",
25379
+ "#3730a3",
25380
+ "#404040",
25381
+ "#b91c1c",
25382
+ "#c2410c",
25383
+ "#a16207",
25384
+ "#15803d",
25385
+ "#0f766e",
25386
+ "#2563eb",
25387
+ "#4f46e5",
25388
+ "#737373",
25389
+ "#ef4444",
25390
+ "#f97316",
25391
+ "#eab308",
25392
+ "#22c55e",
25393
+ "#14b8a6",
25394
+ "#3b82f6",
25395
+ "#7c3aed",
25396
+ "#a3a3a3",
25397
+ "#f43f5e",
25398
+ "#f59e0b",
25399
+ "#facc15",
25400
+ "#00e676",
25401
+ "#22d3ee",
25402
+ "#06b6d4",
25403
+ "#be185d",
25404
+ "#bdbdbd",
25405
+ "#f9a8d4",
25406
+ "#fecaca",
25407
+ "#fde68a",
25408
+ "#bbf7d0",
25409
+ "#a7f3d0",
25410
+ "#bae6fd",
25411
+ "#c4b5fd",
25412
+ "#f5f5f5"
25413
+ ];
25414
+ var HIGHLIGHT_COLOR_SWATCHES = [
25415
+ "#fef08a",
25416
+ "#fde68a",
25417
+ "#fed7aa",
25418
+ "#fecaca",
25419
+ "#fbcfe8",
25420
+ "#e9d5ff",
25421
+ "#c7d2fe",
25422
+ "#bfdbfe",
25423
+ "#bae6fd",
25424
+ "#ccfbf1",
25425
+ "#bbf7d0",
25426
+ "#d9f99d",
25427
+ "#e5e7eb",
25428
+ "#fca5a5",
25429
+ "#fdba74",
25430
+ "#facc15",
25431
+ "#86efac",
25432
+ "#5eead4",
25433
+ "#7dd3fc",
25434
+ "#a5b4fc",
25435
+ "#d8b4fe",
25436
+ "#f0abfc",
25437
+ "#f9a8d4",
25438
+ "#d4d4d4"
25439
+ ];
25440
+ function buildColorOptions(colors, prefix) {
25441
+ return colors.map((color, index) => ({ name: `${prefix} ${index + 1}`, color }));
25442
+ }
25328
25443
  var useEditorColors = () => {
25329
25444
  const t = useSmartTranslations("UEditor");
25330
25445
  const textColors = useMemo22(
@@ -25336,7 +25451,8 @@ var useEditorColors = () => {
25336
25451
  { name: t("colors.success"), color: "var(--success)", cssClass: "text-success" },
25337
25452
  { name: t("colors.warning"), color: "var(--warning)", cssClass: "text-warning" },
25338
25453
  { name: t("colors.destructive"), color: "var(--destructive)", cssClass: "text-destructive" },
25339
- { name: t("colors.info"), color: "var(--info)", cssClass: "text-info" }
25454
+ { name: t("colors.info"), color: "var(--info)", cssClass: "text-info" },
25455
+ ...buildColorOptions(EDITOR_COLOR_SWATCHES, t("colors.color"))
25340
25456
  ],
25341
25457
  [t]
25342
25458
  );
@@ -25350,7 +25466,8 @@ var useEditorColors = () => {
25350
25466
  { name: t("colors.warning"), color: "color-mix(in oklch, var(--warning) 20%, transparent)", cssClass: "bg-warning/20" },
25351
25467
  { name: t("colors.destructive"), color: "color-mix(in oklch, var(--destructive) 20%, transparent)", cssClass: "bg-destructive/20" },
25352
25468
  { name: t("colors.info"), color: "color-mix(in oklch, var(--info) 20%, transparent)", cssClass: "bg-info/20" },
25353
- { name: t("colors.accent"), color: "var(--accent)", cssClass: "bg-accent" }
25469
+ { name: t("colors.accent"), color: "var(--accent)", cssClass: "bg-accent" },
25470
+ ...buildColorOptions(HIGHLIGHT_COLOR_SWATCHES, t("colors.color"))
25354
25471
  ],
25355
25472
  [t]
25356
25473
  );
@@ -25361,26 +25478,81 @@ var EditorColorPalette = ({
25361
25478
  currentColor,
25362
25479
  onSelect,
25363
25480
  label
25364
- }) => /* @__PURE__ */ jsxs65("div", { className: "p-2", children: [
25365
- /* @__PURE__ */ jsx78("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider px-2", children: label }),
25366
- /* @__PURE__ */ jsx78("div", { className: "grid grid-cols-4 gap-1.5 mt-2", children: colors.map((c) => /* @__PURE__ */ jsx78(Tooltip, { placement: "top", content: /* @__PURE__ */ jsx78("span", { className: "text-xs font-medium", children: c.name }), children: /* @__PURE__ */ jsxs65(
25367
- "button",
25368
- {
25369
- type: "button",
25370
- onMouseDown: (e) => e.preventDefault(),
25371
- onClick: () => onSelect(c.color),
25372
- className: cn(
25373
- "flex items-center justify-center w-9 h-9 rounded-lg border-2 transition-all hover:scale-105",
25374
- currentColor === c.color ? "border-primary ring-2 ring-primary/20" : "border-border/50 hover:border-primary/50"
25375
- ),
25376
- style: { backgroundColor: c.color || "transparent" },
25377
- children: [
25378
- c.color === "" && /* @__PURE__ */ jsx78(X18, { className: "w-4 h-4 text-muted-foreground" }),
25379
- c.color === "inherit" && /* @__PURE__ */ jsx78("span", { className: "text-xs font-medium", children: "A" })
25380
- ]
25381
- }
25382
- ) }, c.name)) })
25383
- ] });
25481
+ }) => {
25482
+ const t = useSmartTranslations("UEditor");
25483
+ const colorInputRef = useRef29(null);
25484
+ const automaticColor = colors[0]?.color ?? "";
25485
+ const paletteColors = colors.slice(1);
25486
+ return /* @__PURE__ */ jsxs65("div", { className: "w-56 p-2", children: [
25487
+ /* @__PURE__ */ jsx78("span", { className: "px-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: label }),
25488
+ /* @__PURE__ */ jsxs65(
25489
+ "button",
25490
+ {
25491
+ type: "button",
25492
+ onMouseDown: (e) => e.preventDefault(),
25493
+ onClick: () => onSelect(automaticColor),
25494
+ className: cn(
25495
+ "mt-2 flex h-9 w-full items-center gap-3 rounded-md border px-2 text-sm transition-colors",
25496
+ "bg-muted/50 hover:bg-muted",
25497
+ currentColor === automaticColor ? "border-primary text-primary" : "border-transparent text-foreground"
25498
+ ),
25499
+ children: [
25500
+ /* @__PURE__ */ jsx78("span", { className: "flex h-5 w-5 items-center justify-center rounded border border-border bg-background", children: currentColor === automaticColor && /* @__PURE__ */ jsx78(Check10, { className: "h-3.5 w-3.5" }) }),
25501
+ /* @__PURE__ */ jsx78("span", { className: "flex-1 text-center", children: t("colors.automatic") })
25502
+ ]
25503
+ }
25504
+ ),
25505
+ /* @__PURE__ */ jsx78("div", { className: "mt-2 grid grid-cols-8 gap-1", children: paletteColors.map((c) => /* @__PURE__ */ jsx78(Tooltip, { placement: "top", content: /* @__PURE__ */ jsx78("span", { className: "text-xs font-medium", children: c.name }), children: /* @__PURE__ */ jsx78(
25506
+ "button",
25507
+ {
25508
+ type: "button",
25509
+ "aria-label": c.name,
25510
+ onMouseDown: (e) => e.preventDefault(),
25511
+ onClick: () => onSelect(c.color),
25512
+ className: cn(
25513
+ "relative h-5 w-5 rounded-[3px] border transition-transform hover:scale-110",
25514
+ currentColor === c.color ? "border-primary ring-2 ring-primary/25" : "border-border/70"
25515
+ ),
25516
+ style: { backgroundColor: c.color || "transparent" },
25517
+ children: currentColor === c.color && /* @__PURE__ */ jsx78("span", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx78(Check10, { className: "h-3.5 w-3.5 text-white drop-shadow-[0_1px_1px_rgba(0,0,0,0.8)]" }) })
25518
+ }
25519
+ ) }, `${c.name}-${c.color}`)) }),
25520
+ /* @__PURE__ */ jsxs65(
25521
+ "button",
25522
+ {
25523
+ type: "button",
25524
+ onMouseDown: (e) => e.preventDefault(),
25525
+ onClick: () => colorInputRef.current?.click(),
25526
+ 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",
25527
+ children: [
25528
+ /* @__PURE__ */ jsx78(
25529
+ "span",
25530
+ {
25531
+ "aria-hidden": "true",
25532
+ className: "h-5 w-5 rounded border border-border",
25533
+ style: {
25534
+ background: "linear-gradient(135deg, #ff004c 0%, #fffb00 22%, #00ff66 42%, #00d5ff 62%, #2446ff 78%, #ff00d4 100%)"
25535
+ }
25536
+ }
25537
+ ),
25538
+ /* @__PURE__ */ jsx78("span", { className: "flex-1 text-center", children: t("colors.moreColors") }),
25539
+ /* @__PURE__ */ jsx78(Palette2, { className: "h-4 w-4 text-muted-foreground" }),
25540
+ /* @__PURE__ */ jsx78(
25541
+ "input",
25542
+ {
25543
+ ref: colorInputRef,
25544
+ type: "color",
25545
+ value: currentColor.startsWith("#") ? currentColor : "#000000",
25546
+ onChange: (event) => onSelect(event.target.value),
25547
+ className: "sr-only",
25548
+ tabIndex: -1
25549
+ }
25550
+ )
25551
+ ]
25552
+ }
25553
+ )
25554
+ ] });
25555
+ };
25384
25556
 
25385
25557
  // src/components/UEditor/image-commands.ts
25386
25558
  import { NodeSelection, TextSelection } from "@tiptap/pm/state";
@@ -25473,8 +25645,8 @@ function deleteSelectedImage(editor) {
25473
25645
  }
25474
25646
 
25475
25647
  // src/components/UEditor/inputs.tsx
25476
- import { useEffect as useEffect33, useRef as useRef29, useState as useState43 } from "react";
25477
- import { Check as Check10, X as X19 } from "lucide-react";
25648
+ import { useEffect as useEffect33, useRef as useRef30, useState as useState43 } from "react";
25649
+ import { Check as Check11, X as X18 } from "lucide-react";
25478
25650
  import { jsx as jsx79, jsxs as jsxs66 } from "react/jsx-runtime";
25479
25651
  function normalizeUrl(raw) {
25480
25652
  return sanitizeUEditorUrl(raw, "link");
@@ -25486,7 +25658,7 @@ var LinkInput = ({
25486
25658
  }) => {
25487
25659
  const t = useSmartTranslations("UEditor");
25488
25660
  const [url, setUrl] = useState43(initialUrl);
25489
- const inputRef = useRef29(null);
25661
+ const inputRef = useRef30(null);
25490
25662
  useEffect33(() => {
25491
25663
  inputRef.current?.focus();
25492
25664
  inputRef.current?.select();
@@ -25508,15 +25680,15 @@ var LinkInput = ({
25508
25680
  className: "flex-1 px-3 py-2 text-sm bg-muted/50 border-0 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/20"
25509
25681
  }
25510
25682
  ),
25511
- /* @__PURE__ */ jsx79("button", { type: "submit", className: "p-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 transition-colors", children: /* @__PURE__ */ jsx79(Check10, { className: "w-4 h-4" }) }),
25512
- /* @__PURE__ */ jsx79("button", { type: "button", onClick: onCancel, className: "p-2 rounded-lg hover:bg-muted transition-colors text-muted-foreground", children: /* @__PURE__ */ jsx79(X19, { className: "w-4 h-4" }) })
25683
+ /* @__PURE__ */ jsx79("button", { type: "submit", className: "p-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 transition-colors", children: /* @__PURE__ */ jsx79(Check11, { className: "w-4 h-4" }) }),
25684
+ /* @__PURE__ */ jsx79("button", { type: "button", onClick: onCancel, className: "p-2 rounded-lg hover:bg-muted transition-colors text-muted-foreground", children: /* @__PURE__ */ jsx79(X18, { className: "w-4 h-4" }) })
25513
25685
  ] });
25514
25686
  };
25515
25687
  var ImageInput = ({ onSubmit, onCancel }) => {
25516
25688
  const t = useSmartTranslations("UEditor");
25517
25689
  const [url, setUrl] = useState43("");
25518
25690
  const [alt, setAlt] = useState43("");
25519
- const inputRef = useRef29(null);
25691
+ const inputRef = useRef30(null);
25520
25692
  useEffect33(() => {
25521
25693
  inputRef.current?.focus();
25522
25694
  }, []);
@@ -25592,12 +25764,23 @@ function getDefaultFontFamilies(t) {
25592
25764
  }
25593
25765
  function getDefaultFontSizes() {
25594
25766
  return [
25767
+ { label: "8", value: "8px" },
25768
+ { label: "9", value: "9px" },
25769
+ { label: "10", value: "10px" },
25770
+ { label: "11", value: "11px" },
25595
25771
  { label: "12", value: "12px" },
25596
25772
  { label: "14", value: "14px" },
25597
25773
  { label: "16", value: "16px" },
25598
25774
  { label: "18", value: "18px" },
25775
+ { label: "20", value: "20px" },
25776
+ { label: "22", value: "22px" },
25599
25777
  { label: "24", value: "24px" },
25600
- { label: "32", value: "32px" }
25778
+ { label: "26", value: "26px" },
25779
+ { label: "28", value: "28px" },
25780
+ { label: "36", value: "36px" },
25781
+ { label: "48", value: "48px" },
25782
+ { label: "72", value: "72px" },
25783
+ { label: "96", value: "96px" }
25601
25784
  ];
25602
25785
  }
25603
25786
  function getDefaultLineHeights() {
@@ -25645,10 +25828,11 @@ var ToolbarButton = React73.forwardRef(({ onClick, onMouseDown, active, disabled
25645
25828
  onClick,
25646
25829
  disabled,
25647
25830
  className: cn(
25648
- "flex items-center justify-center w-8 h-8 rounded-lg transition-all duration-200",
25649
- "hover:bg-accent hover:scale-105",
25831
+ "flex items-center justify-center w-8 h-8 rounded-md transition-colors duration-150",
25832
+ "gap-0.5 [&_svg+svg]:-ml-1",
25833
+ "hover:bg-accent",
25650
25834
  "focus:outline-none focus:ring-2 focus:ring-primary/20",
25651
- "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:scale-100",
25835
+ "disabled:opacity-40 disabled:cursor-not-allowed",
25652
25836
  active ? "bg-primary/10 text-primary shadow-sm" : "text-muted-foreground hover:text-foreground",
25653
25837
  className
25654
25838
  ),
@@ -25661,7 +25845,7 @@ var ToolbarButton = React73.forwardRef(({ onClick, onMouseDown, active, disabled
25661
25845
  return button;
25662
25846
  });
25663
25847
  ToolbarButton.displayName = "ToolbarButton";
25664
- var ToolbarDivider = () => /* @__PURE__ */ jsx81("div", { className: "w-px h-6 bg-border/50 mx-1" });
25848
+ var ToolbarDivider = () => /* @__PURE__ */ jsx81("div", { className: "mx-0.5 h-5 w-px bg-border/60" });
25665
25849
  var TableInsertGrid = ({
25666
25850
  insertLabel,
25667
25851
  previewTemplate,
@@ -25672,36 +25856,29 @@ var TableInsertGrid = ({
25672
25856
  const maxCols = 8;
25673
25857
  return /* @__PURE__ */ jsxs67("div", { className: "mb-2 rounded-xl border border-border/60 bg-muted/20 p-2", children: [
25674
25858
  /* @__PURE__ */ jsx81("div", { className: "mb-2 text-sm font-medium text-foreground", children: formatTableInsertLabel(previewTemplate, selection.rows, selection.cols) }),
25675
- /* @__PURE__ */ jsx81(
25676
- "div",
25677
- {
25678
- className: "grid grid-cols-8 gap-1",
25679
- onMouseLeave: () => setSelection((prev) => prev),
25680
- children: Array.from({ length: maxRows }).map(
25681
- (_, rowIndex) => Array.from({ length: maxCols }).map((__, colIndex) => {
25682
- const rows = rowIndex + 1;
25683
- const cols = colIndex + 1;
25684
- const active = rows <= selection.rows && cols <= selection.cols;
25685
- return /* @__PURE__ */ jsx81(
25686
- "button",
25687
- {
25688
- type: "button",
25689
- "aria-label": formatTableInsertLabel(previewTemplate, rows, cols),
25690
- onMouseDown: (e) => e.preventDefault(),
25691
- onMouseEnter: () => setSelection({ rows, cols }),
25692
- onFocus: () => setSelection({ rows, cols }),
25693
- onClick: () => onInsert(rows, cols),
25694
- className: cn(
25695
- "h-5 w-5 rounded-sm border transition-colors",
25696
- active ? "border-primary bg-primary/20" : "border-border/70 bg-background hover:border-primary/60 hover:bg-primary/10"
25697
- )
25698
- },
25699
- `${rows}-${cols}`
25700
- );
25701
- })
25702
- )
25703
- }
25704
- ),
25859
+ /* @__PURE__ */ jsx81("div", { className: "grid grid-cols-8 gap-1", onMouseLeave: () => setSelection((prev) => prev), children: Array.from({ length: maxRows }).map(
25860
+ (_, rowIndex) => Array.from({ length: maxCols }).map((__, colIndex) => {
25861
+ const rows = rowIndex + 1;
25862
+ const cols = colIndex + 1;
25863
+ const active = rows <= selection.rows && cols <= selection.cols;
25864
+ return /* @__PURE__ */ jsx81(
25865
+ "button",
25866
+ {
25867
+ type: "button",
25868
+ "aria-label": formatTableInsertLabel(previewTemplate, rows, cols),
25869
+ onMouseDown: (e) => e.preventDefault(),
25870
+ onMouseEnter: () => setSelection({ rows, cols }),
25871
+ onFocus: () => setSelection({ rows, cols }),
25872
+ onClick: () => onInsert(rows, cols),
25873
+ className: cn(
25874
+ "h-5 w-5 rounded-sm border transition-colors",
25875
+ active ? "border-primary bg-primary/20" : "border-border/70 bg-background hover:border-primary/60 hover:bg-primary/10"
25876
+ )
25877
+ },
25878
+ `${rows}-${cols}`
25879
+ );
25880
+ })
25881
+ ) }),
25705
25882
  /* @__PURE__ */ jsx81("div", { className: "mt-2 text-xs text-muted-foreground", children: insertLabel })
25706
25883
  ] });
25707
25884
  };
@@ -25718,14 +25895,23 @@ var EditorToolbar = ({
25718
25895
  letterSpacings
25719
25896
  }) => {
25720
25897
  const t = useSmartTranslations("UEditor");
25898
+ useEditorState({
25899
+ editor,
25900
+ selector: ({ transactionNumber }) => transactionNumber
25901
+ });
25721
25902
  const { textColors, highlightColors } = useEditorColors();
25722
25903
  const [showImageInput, setShowImageInput] = useState44(false);
25904
+ const [showLinkInput, setShowLinkInput] = useState44(false);
25723
25905
  const [isTableMenuOpen, setIsTableMenuOpen] = useState44(false);
25724
- const tableCommandAnchorPosRef = useRef30(null);
25725
- const fileInputRef = useRef30(null);
25906
+ const tableCommandAnchorPosRef = useRef31(null);
25907
+ const fileInputRef = useRef31(null);
25726
25908
  const [isUploadingImage, setIsUploadingImage] = useState44(false);
25727
25909
  const [imageUploadError, setImageUploadError] = useState44(null);
25728
25910
  const [fontSizeDraft, setFontSizeDraft] = useState44("");
25911
+ const [isFontSizeMenuOpen, setIsFontSizeMenuOpen] = useState44(false);
25912
+ const [fontSizeMenuPosition, setFontSizeMenuPosition] = useState44({ top: 0, left: 0 });
25913
+ const fontSizeControlRef = useRef31(null);
25914
+ const fontSizeMenuRef = useRef31(null);
25729
25915
  const isImageSelected = editor.isActive("image");
25730
25916
  const imageAttrs = editor.getAttributes("image");
25731
25917
  const tableAttrs = editor.getAttributes("table");
@@ -25737,30 +25923,23 @@ var EditorToolbar = ({
25737
25923
  const hasTableContext = isTableSelected || tableCommandAnchorPosRef.current !== null;
25738
25924
  const currentFontFamily = normalizeStyleValue(textStyleAttrs.fontFamily);
25739
25925
  const currentFontSize = normalizeStyleValue(textStyleAttrs.fontSize);
25926
+ const currentTextColor = normalizeStyleValue(textStyleAttrs.color) || "inherit";
25927
+ const currentHighlightColor = normalizeStyleValue(editor.getAttributes("highlight").color) || "";
25740
25928
  const currentLineHeight = normalizeStyleValue(textStyleAttrs.lineHeight);
25741
25929
  const currentLetterSpacing = normalizeStyleValue(textStyleAttrs.letterSpacing);
25742
- const availableFontFamilies = React73.useMemo(
25743
- () => fontFamilies ?? getDefaultFontFamilies(t),
25744
- [fontFamilies, t]
25745
- );
25746
- const availableFontSizes = React73.useMemo(
25747
- () => fontSizes ?? getDefaultFontSizes(),
25748
- [fontSizes]
25749
- );
25750
- const availableLineHeights = React73.useMemo(
25751
- () => lineHeights ?? getDefaultLineHeights(),
25752
- [lineHeights]
25753
- );
25754
- const availableLetterSpacings = React73.useMemo(
25755
- () => letterSpacings ?? getDefaultLetterSpacings(),
25756
- [letterSpacings]
25757
- );
25758
- const currentFontFamilyLabel = availableFontFamilies.find((option) => normalizeStyleValue(option.value) === currentFontFamily)?.label ?? t("toolbar.fontDefault");
25930
+ const availableFontFamilies = React73.useMemo(() => fontFamilies ?? getDefaultFontFamilies(t), [fontFamilies, t]);
25931
+ const availableFontSizes = React73.useMemo(() => fontSizes ?? getDefaultFontSizes(), [fontSizes]);
25932
+ const availableLineHeights = React73.useMemo(() => lineHeights ?? getDefaultLineHeights(), [lineHeights]);
25933
+ const availableLetterSpacings = React73.useMemo(() => letterSpacings ?? getDefaultLetterSpacings(), [letterSpacings]);
25934
+ const currentFontFamilyDisplayValue = currentFontFamily.split(",")[0]?.trim() ?? currentFontFamily;
25935
+ const currentFontFamilyLabel = availableFontFamilies.find((option) => normalizeStyleValue(option.value) === currentFontFamily)?.label ?? (currentFontFamilyDisplayValue || t("toolbar.fontDefault"));
25759
25936
  const currentFontSizeLabel = availableFontSizes.find((option) => normalizeStyleValue(option.value) === currentFontSize)?.label ?? t("toolbar.sizeDefault");
25760
25937
  const currentLineHeightLabel = availableLineHeights.find((option) => normalizeStyleValue(option.value) === currentLineHeight)?.label ?? t("toolbar.lineHeightDefault");
25761
25938
  const currentLetterSpacingLabel = availableLetterSpacings.find((option) => normalizeStyleValue(option.value) === currentLetterSpacing)?.label ?? t("toolbar.letterSpacingDefault");
25939
+ const displayedFontFamilyLabel = currentFontFamily ? currentFontFamilyLabel : availableFontFamilies[0]?.label ?? t("toolbar.fontDefault");
25762
25940
  React73.useEffect(() => {
25763
- setFontSizeDraft(currentFontSize.replace(/px$/i, ""));
25941
+ if (document.activeElement === fontSizeControlRef.current?.querySelector("input")) return;
25942
+ setFontSizeDraft(currentFontSize.replace(/px$/i, "") || "16");
25764
25943
  }, [currentFontSize]);
25765
25944
  const applyFontSizeDraft = () => {
25766
25945
  const normalized = fontSizeDraft.trim();
@@ -25772,7 +25951,39 @@ var EditorToolbar = ({
25772
25951
  if (!Number.isFinite(parsed) || parsed <= 0) return;
25773
25952
  const clamped = Math.min(96, Math.max(8, parsed));
25774
25953
  editor.chain().focus().setFontSize(`${clamped}px`).run();
25954
+ setFontSizeDraft(String(clamped));
25955
+ };
25956
+ const updateFontSizeMenuPosition = React73.useCallback(() => {
25957
+ const rect = fontSizeControlRef.current?.getBoundingClientRect();
25958
+ if (!rect) return;
25959
+ setFontSizeMenuPosition({
25960
+ top: Math.round(rect.bottom + 4),
25961
+ left: Math.round(rect.left)
25962
+ });
25963
+ }, []);
25964
+ const toggleFontSizeMenu = () => {
25965
+ updateFontSizeMenuPosition();
25966
+ setIsFontSizeMenuOpen((open) => !open);
25775
25967
  };
25968
+ React73.useEffect(() => {
25969
+ if (!isFontSizeMenuOpen) return;
25970
+ updateFontSizeMenuPosition();
25971
+ const handlePointerDown = (event) => {
25972
+ const target = event.target;
25973
+ if (fontSizeControlRef.current?.contains(target)) return;
25974
+ if (fontSizeMenuRef.current?.contains(target)) return;
25975
+ setIsFontSizeMenuOpen(false);
25976
+ };
25977
+ const handleLayoutChange = () => updateFontSizeMenuPosition();
25978
+ document.addEventListener("mousedown", handlePointerDown);
25979
+ window.addEventListener("resize", handleLayoutChange);
25980
+ window.addEventListener("scroll", handleLayoutChange, true);
25981
+ return () => {
25982
+ document.removeEventListener("mousedown", handlePointerDown);
25983
+ window.removeEventListener("resize", handleLayoutChange);
25984
+ window.removeEventListener("scroll", handleLayoutChange, true);
25985
+ };
25986
+ }, [isFontSizeMenuOpen, updateFontSizeMenuPosition]);
25776
25987
  const insertImageFiles = async (files) => {
25777
25988
  if (files.length === 0) return;
25778
25989
  setIsUploadingImage(true);
@@ -25794,7 +26005,7 @@ var EditorToolbar = ({
25794
26005
  setIsUploadingImage(false);
25795
26006
  };
25796
26007
  if (variant === "minimal") {
25797
- return /* @__PURE__ */ jsxs67("div", { className: "flex items-center gap-1 p-2 border-b bg-muted/30", children: [
26008
+ return /* @__PURE__ */ jsxs67("div", { className: "flex items-center gap-1 border-b border-border/35 bg-muted/30 p-2", children: [
25798
26009
  /* @__PURE__ */ jsx81(ToolbarButton, { onClick: () => editor.chain().focus().toggleBold().run(), active: editor.isActive("bold"), title: t("toolbar.bold"), children: /* @__PURE__ */ jsx81(BoldIcon, { className: "w-4 h-4" }) }),
25799
26010
  /* @__PURE__ */ jsx81(ToolbarButton, { onClick: () => editor.chain().focus().toggleItalic().run(), active: editor.isActive("italic"), title: t("toolbar.italic"), children: /* @__PURE__ */ jsx81(ItalicIcon, { className: "w-4 h-4" }) }),
25800
26011
  /* @__PURE__ */ jsx81(
@@ -25808,70 +26019,23 @@ var EditorToolbar = ({
25808
26019
  )
25809
26020
  ] });
25810
26021
  }
25811
- return /* @__PURE__ */ jsxs67("div", { className: "flex flex-wrap items-center gap-1 p-2 border-b bg-linear-to-r from-muted/30 to-transparent", children: [
25812
- /* @__PURE__ */ jsxs67(
25813
- DropdownMenu,
25814
- {
25815
- contentClassName: "p-2",
25816
- trigger: /* @__PURE__ */ jsxs67(ToolbarButton, { onClick: () => {
25817
- }, title: t("toolbar.textStyle"), className: "px-2 w-auto gap-1", children: [
25818
- /* @__PURE__ */ jsx81(Type2, { className: "w-4 h-4" }),
25819
- /* @__PURE__ */ jsx81(ChevronDown7, { className: "w-3 h-3" })
25820
- ] }),
25821
- children: [
25822
- /* @__PURE__ */ jsx81(
25823
- DropdownMenuItem,
25824
- {
25825
- icon: Type2,
25826
- label: t("toolbar.normal"),
25827
- onClick: () => editor.chain().focus().setParagraph().run(),
25828
- active: editor.isActive("paragraph")
25829
- }
25830
- ),
25831
- /* @__PURE__ */ jsx81(
25832
- DropdownMenuItem,
25833
- {
25834
- icon: Heading1Icon,
25835
- label: t("toolbar.heading1"),
25836
- onClick: () => editor.chain().focus().toggleHeading({ level: 1 }).run(),
25837
- active: editor.isActive("heading", { level: 1 }),
25838
- shortcut: "Ctrl+Alt+1"
25839
- }
25840
- ),
25841
- /* @__PURE__ */ jsx81(
25842
- DropdownMenuItem,
25843
- {
25844
- icon: Heading2Icon,
25845
- label: t("toolbar.heading2"),
25846
- onClick: () => editor.chain().focus().toggleHeading({ level: 2 }).run(),
25847
- active: editor.isActive("heading", { level: 2 }),
25848
- shortcut: "Ctrl+Alt+2"
25849
- }
25850
- ),
25851
- /* @__PURE__ */ jsx81(
25852
- DropdownMenuItem,
25853
- {
25854
- icon: Heading3Icon,
25855
- label: t("toolbar.heading3"),
25856
- onClick: () => editor.chain().focus().toggleHeading({ level: 3 }).run(),
25857
- active: editor.isActive("heading", { level: 3 }),
25858
- shortcut: "Ctrl+Alt+3"
25859
- }
25860
- )
25861
- ]
25862
- }
25863
- ),
26022
+ return /* @__PURE__ */ jsxs67("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: [
25864
26023
  /* @__PURE__ */ jsxs67(
25865
26024
  DropdownMenu,
25866
26025
  {
25867
- trigger: /* @__PURE__ */ jsx81(
25868
- ToolbarButton,
26026
+ trigger: /* @__PURE__ */ jsxs67(
26027
+ "button",
25869
26028
  {
25870
- onClick: () => {
25871
- },
25872
- title: t("toolbar.fontFamily"),
25873
- className: "relative",
25874
- children: /* @__PURE__ */ jsx81(Type2, { className: "w-4 h-4" })
26029
+ type: "button",
26030
+ "aria-label": t("toolbar.fontFamily"),
26031
+ className: cn(
26032
+ "flex h-8 min-w-34 max-w-42 items-center justify-between gap-2 rounded-full border border-border/60 bg-muted/30 px-2.5 text-xs text-foreground",
26033
+ "transition-colors hover:bg-accent focus:outline-none focus:ring-2 focus:ring-primary/20"
26034
+ ),
26035
+ children: [
26036
+ /* @__PURE__ */ jsx81("span", { className: "truncate", children: displayedFontFamilyLabel }),
26037
+ /* @__PURE__ */ jsx81(ChevronDown7, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" })
26038
+ ]
25875
26039
  }
25876
26040
  ),
25877
26041
  contentClassName: "max-h-80 overflow-y-auto min-w-56 p-2",
@@ -25891,30 +26055,24 @@ var EditorToolbar = ({
25891
26055
  label: option.label,
25892
26056
  onClick: () => editor.chain().focus().setFontFamily(option.value).run(),
25893
26057
  active: normalizeStyleValue(option.value) === currentFontFamily,
25894
- className: "font-medium"
26058
+ className: "font-medium "
25895
26059
  },
25896
26060
  option.value
25897
26061
  ))
25898
26062
  ]
25899
26063
  }
25900
26064
  ),
25901
- /* @__PURE__ */ jsxs67(
25902
- DropdownMenu,
25903
- {
25904
- closeOnSelect: false,
25905
- trigger: /* @__PURE__ */ jsx81(
25906
- ToolbarButton,
25907
- {
25908
- onClick: () => {
25909
- },
25910
- title: t("toolbar.fontSize"),
25911
- className: "px-2 w-auto min-w-9",
25912
- children: /* @__PURE__ */ jsx81("span", { className: "text-[10px] font-semibold leading-none", children: currentFontSize.replace(/px$/i, "") || "T" })
25913
- }
25914
- ),
25915
- contentClassName: "max-h-80 overflow-y-auto min-w-44 p-2",
25916
- children: [
25917
- /* @__PURE__ */ jsx81("div", { className: "mb-2 rounded-lg border border-border/60 bg-muted/30 p-2", children: /* @__PURE__ */ jsxs67("label", { className: "flex items-center gap-2", children: [
26065
+ /* @__PURE__ */ jsxs67(Fragment27, { children: [
26066
+ /* @__PURE__ */ jsxs67(
26067
+ "div",
26068
+ {
26069
+ ref: fontSizeControlRef,
26070
+ "aria-label": t("toolbar.fontSize"),
26071
+ className: cn(
26072
+ "flex h-8 min-w-16 items-center overflow-hidden rounded-full border border-border/60 bg-muted/30 text-xs font-semibold text-foreground",
26073
+ "transition-colors focus-within:ring-2 focus-within:ring-primary/20"
26074
+ ),
26075
+ children: [
25918
26076
  /* @__PURE__ */ jsx81(
25919
26077
  "input",
25920
26078
  {
@@ -25924,6 +26082,7 @@ var EditorToolbar = ({
25924
26082
  step: 1,
25925
26083
  value: fontSizeDraft,
25926
26084
  onChange: (e) => setFontSizeDraft(e.target.value),
26085
+ onBlur: applyFontSizeDraft,
25927
26086
  onMouseDown: (e) => e.stopPropagation(),
25928
26087
  onClick: (e) => e.stopPropagation(),
25929
26088
  onKeyDown: (e) => {
@@ -25934,48 +26093,116 @@ var EditorToolbar = ({
25934
26093
  }
25935
26094
  },
25936
26095
  "aria-label": t("toolbar.fontSize"),
25937
- 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"
26096
+ 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"
25938
26097
  }
25939
26098
  ),
25940
- /* @__PURE__ */ jsx81("span", { className: "text-xs text-muted-foreground", children: "px" })
25941
- ] }) }),
26099
+ /* @__PURE__ */ jsx81(
26100
+ "button",
26101
+ {
26102
+ type: "button",
26103
+ "aria-label": t("toolbar.fontSize"),
26104
+ "aria-expanded": isFontSizeMenuOpen,
26105
+ onClick: toggleFontSizeMenu,
26106
+ className: "flex h-full w-7 items-center justify-center border-l border-border/50 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
26107
+ children: /* @__PURE__ */ jsx81(ChevronDown7, { className: "h-3.5 w-3.5" })
26108
+ }
26109
+ )
26110
+ ]
26111
+ }
26112
+ ),
26113
+ isFontSizeMenuOpen && typeof document !== "undefined" && createPortal8(
26114
+ /* @__PURE__ */ jsx81(
26115
+ "div",
26116
+ {
26117
+ ref: fontSizeMenuRef,
26118
+ className: "fixed z-[10000] max-h-64 w-12 overflow-y-auto rounded-md border border-border/70 bg-popover p-0.5 text-popover-foreground shadow-md",
26119
+ style: { top: fontSizeMenuPosition.top, left: fontSizeMenuPosition.left },
26120
+ children: availableFontSizes.map((option) => {
26121
+ const active = normalizeStyleValue(option.value) === currentFontSize;
26122
+ return /* @__PURE__ */ jsx81(
26123
+ "button",
26124
+ {
26125
+ type: "button",
26126
+ onMouseDown: (e) => e.preventDefault(),
26127
+ onClick: () => {
26128
+ editor.chain().focus().setFontSize(option.value).run();
26129
+ setFontSizeDraft(option.label);
26130
+ setIsFontSizeMenuOpen(false);
26131
+ },
26132
+ className: cn(
26133
+ "flex h-6 w-full items-center justify-center rounded text-xs leading-none transition-colors",
26134
+ active ? "bg-primary/15 text-primary" : "text-foreground hover:bg-accent hover:text-accent-foreground"
26135
+ ),
26136
+ children: option.label
26137
+ },
26138
+ option.value
26139
+ );
26140
+ })
26141
+ }
26142
+ ),
26143
+ document.body
26144
+ )
26145
+ ] }),
26146
+ /* @__PURE__ */ jsxs67(
26147
+ DropdownMenu,
26148
+ {
26149
+ contentClassName: "p-2",
26150
+ trigger: /* @__PURE__ */ jsxs67(ToolbarButton, { onClick: () => {
26151
+ }, title: t("toolbar.textStyle"), className: "px-2 w-auto gap-1", children: [
26152
+ /* @__PURE__ */ jsx81(Type2, { className: "w-4 h-4" }),
26153
+ /* @__PURE__ */ jsx81(ChevronDown7, { className: "w-3 h-3" })
26154
+ ] }),
26155
+ children: [
25942
26156
  /* @__PURE__ */ jsx81(
25943
26157
  DropdownMenuItem,
25944
26158
  {
25945
26159
  icon: Type2,
25946
- label: t("toolbar.sizeDefault"),
25947
- onClick: () => editor.chain().focus().unsetFontSize().run(),
25948
- active: !currentFontSize
26160
+ label: t("toolbar.normal"),
26161
+ onClick: () => editor.chain().focus().setParagraph().run(),
26162
+ active: editor.isActive("paragraph")
25949
26163
  }
25950
26164
  ),
25951
- availableFontSizes.map((option) => /* @__PURE__ */ jsx81(
26165
+ /* @__PURE__ */ jsx81(
25952
26166
  DropdownMenuItem,
25953
26167
  {
25954
- label: option.label,
25955
- onClick: () => editor.chain().focus().setFontSize(option.value).run(),
25956
- active: normalizeStyleValue(option.value) === currentFontSize
25957
- },
25958
- option.value
25959
- ))
26168
+ icon: Heading1Icon,
26169
+ label: t("toolbar.heading1"),
26170
+ onClick: () => editor.chain().focus().toggleHeading({ level: 1 }).run(),
26171
+ active: editor.isActive("heading", { level: 1 }),
26172
+ shortcut: "Ctrl+Alt+1"
26173
+ }
26174
+ ),
26175
+ /* @__PURE__ */ jsx81(
26176
+ DropdownMenuItem,
26177
+ {
26178
+ icon: Heading2Icon,
26179
+ label: t("toolbar.heading2"),
26180
+ onClick: () => editor.chain().focus().toggleHeading({ level: 2 }).run(),
26181
+ active: editor.isActive("heading", { level: 2 }),
26182
+ shortcut: "Ctrl+Alt+2"
26183
+ }
26184
+ ),
26185
+ /* @__PURE__ */ jsx81(
26186
+ DropdownMenuItem,
26187
+ {
26188
+ icon: Heading3Icon,
26189
+ label: t("toolbar.heading3"),
26190
+ onClick: () => editor.chain().focus().toggleHeading({ level: 3 }).run(),
26191
+ active: editor.isActive("heading", { level: 3 }),
26192
+ shortcut: "Ctrl+Alt+3"
26193
+ }
26194
+ )
25960
26195
  ]
25961
26196
  }
25962
26197
  ),
25963
26198
  /* @__PURE__ */ jsxs67(
25964
26199
  DropdownMenu,
25965
26200
  {
25966
- trigger: /* @__PURE__ */ jsxs67(
25967
- ToolbarButton,
25968
- {
25969
- onClick: () => {
25970
- },
25971
- title: t("toolbar.lineHeight"),
25972
- className: "gap-0.5",
25973
- children: [
25974
- /* @__PURE__ */ jsx81(ArrowUp, { className: "w-3 h-3" }),
25975
- /* @__PURE__ */ jsx81(ArrowDown, { className: "w-3 h-3" })
25976
- ]
25977
- }
25978
- ),
26201
+ trigger: /* @__PURE__ */ jsxs67(ToolbarButton, { onClick: () => {
26202
+ }, title: t("toolbar.lineHeight"), className: "gap-0.5", children: [
26203
+ /* @__PURE__ */ jsx81(ArrowUp, { className: "w-3 h-3" }),
26204
+ /* @__PURE__ */ jsx81(ArrowDown, { className: "w-3 h-3" })
26205
+ ] }),
25979
26206
  contentClassName: "max-h-72 overflow-y-auto p-2",
25980
26207
  children: [
25981
26208
  /* @__PURE__ */ jsx81(
@@ -26002,19 +26229,11 @@ var EditorToolbar = ({
26002
26229
  /* @__PURE__ */ jsxs67(
26003
26230
  DropdownMenu,
26004
26231
  {
26005
- trigger: /* @__PURE__ */ jsxs67(
26006
- ToolbarButton,
26007
- {
26008
- onClick: () => {
26009
- },
26010
- title: t("toolbar.letterSpacing"),
26011
- className: "gap-0.5",
26012
- children: [
26013
- /* @__PURE__ */ jsx81(ArrowLeft, { className: "w-3 h-3" }),
26014
- /* @__PURE__ */ jsx81(ArrowRight, { className: "w-3 h-3" })
26015
- ]
26016
- }
26017
- ),
26232
+ trigger: /* @__PURE__ */ jsxs67(ToolbarButton, { onClick: () => {
26233
+ }, title: t("toolbar.letterSpacing"), className: "gap-0.5", children: [
26234
+ /* @__PURE__ */ jsx81(ArrowLeft, { className: "w-3 h-3" }),
26235
+ /* @__PURE__ */ jsx81(ArrowRight, { className: "w-3 h-3" })
26236
+ ] }),
26018
26237
  contentClassName: "max-h-72 overflow-y-auto p-2",
26019
26238
  children: [
26020
26239
  /* @__PURE__ */ jsx81(
@@ -26052,20 +26271,68 @@ var EditorToolbar = ({
26052
26271
  ),
26053
26272
  /* @__PURE__ */ jsx81(ToolbarButton, { onClick: () => editor.chain().focus().toggleStrike().run(), active: editor.isActive("strike"), title: t("toolbar.strike"), children: /* @__PURE__ */ jsx81(StrikethroughIcon, { className: "w-4 h-4" }) }),
26054
26273
  /* @__PURE__ */ jsx81(ToolbarButton, { onClick: () => editor.chain().focus().toggleCode().run(), active: editor.isActive("code"), title: t("toolbar.code"), children: /* @__PURE__ */ jsx81(CodeIcon, { className: "w-4 h-4" }) }),
26274
+ /* @__PURE__ */ jsx81(
26275
+ ToolbarButton,
26276
+ {
26277
+ onClick: () => editor.chain().focus().toggleSubscript().run(),
26278
+ active: editor.isActive("subscript"),
26279
+ title: t("toolbar.subscript"),
26280
+ children: /* @__PURE__ */ jsx81(SubscriptIcon, { className: "w-4 h-4" })
26281
+ }
26282
+ ),
26283
+ /* @__PURE__ */ jsx81(
26284
+ ToolbarButton,
26285
+ {
26286
+ onClick: () => editor.chain().focus().toggleSuperscript().run(),
26287
+ active: editor.isActive("superscript"),
26288
+ title: t("toolbar.superscript"),
26289
+ children: /* @__PURE__ */ jsx81(SuperscriptIcon, { className: "w-4 h-4" })
26290
+ }
26291
+ ),
26292
+ /* @__PURE__ */ jsx81(
26293
+ DropdownMenu,
26294
+ {
26295
+ contentClassName: "min-w-72",
26296
+ trigger: /* @__PURE__ */ jsx81(ToolbarButton, { onClick: () => setShowLinkInput(!editor.isActive("link")), active: editor.isActive("link"), title: t("toolbar.link"), children: /* @__PURE__ */ jsx81(LinkIcon, { className: "w-4 h-4" }) }),
26297
+ children: showLinkInput ? /* @__PURE__ */ jsx81(
26298
+ LinkInput,
26299
+ {
26300
+ initialUrl: String(editor.getAttributes("link").href ?? ""),
26301
+ onSubmit: (url) => {
26302
+ editor.chain().focus().extendMarkRange("link").setLink({ href: url }).run();
26303
+ setShowLinkInput(false);
26304
+ },
26305
+ onCancel: () => setShowLinkInput(false)
26306
+ }
26307
+ ) : /* @__PURE__ */ jsxs67(Fragment27, { children: [
26308
+ /* @__PURE__ */ jsx81(DropdownMenuItem, { icon: LinkIcon, label: t("toolbar.link"), onClick: () => setShowLinkInput(true), active: editor.isActive("link") }),
26309
+ /* @__PURE__ */ jsx81(
26310
+ DropdownMenuItem,
26311
+ {
26312
+ icon: Trash22,
26313
+ label: t("toolbar.removeLink"),
26314
+ onClick: () => editor.chain().focus().extendMarkRange("link").unsetLink().run(),
26315
+ disabled: !editor.isActive("link"),
26316
+ destructive: true
26317
+ }
26318
+ )
26319
+ ] })
26320
+ }
26321
+ ),
26055
26322
  /* @__PURE__ */ jsx81(ToolbarDivider, {}),
26056
26323
  /* @__PURE__ */ jsx81(
26057
26324
  DropdownMenu,
26058
26325
  {
26059
26326
  trigger: /* @__PURE__ */ jsxs67(ToolbarButton, { onClick: () => {
26060
26327
  }, title: t("colors.textColor"), children: [
26061
- /* @__PURE__ */ jsx81(Palette2, { className: "w-4 h-4" }),
26328
+ /* @__PURE__ */ jsx81(TextColorIcon, { color: currentTextColor }),
26062
26329
  /* @__PURE__ */ jsx81(ChevronDown7, { className: "w-3 h-3" })
26063
26330
  ] }),
26064
26331
  children: /* @__PURE__ */ jsx81(
26065
26332
  EditorColorPalette,
26066
26333
  {
26067
26334
  colors: textColors,
26068
- currentColor: editor.getAttributes("textStyle").color || "inherit",
26335
+ currentColor: currentTextColor,
26069
26336
  onSelect: (color) => {
26070
26337
  if (color === "inherit") {
26071
26338
  editor.chain().focus().unsetColor().run();
@@ -26083,14 +26350,14 @@ var EditorToolbar = ({
26083
26350
  {
26084
26351
  trigger: /* @__PURE__ */ jsxs67(ToolbarButton, { onClick: () => {
26085
26352
  }, active: editor.isActive("highlight"), title: t("colors.highlight"), children: [
26086
- /* @__PURE__ */ jsx81(Highlighter, { className: "w-4 h-4" }),
26353
+ /* @__PURE__ */ jsx81(HighlightColorIcon, { color: currentHighlightColor }),
26087
26354
  /* @__PURE__ */ jsx81(ChevronDown7, { className: "w-3 h-3" })
26088
26355
  ] }),
26089
26356
  children: /* @__PURE__ */ jsx81(
26090
26357
  EditorColorPalette,
26091
26358
  {
26092
26359
  colors: highlightColors,
26093
- currentColor: editor.getAttributes("highlight").color || "",
26360
+ currentColor: currentHighlightColor,
26094
26361
  onSelect: (color) => {
26095
26362
  if (color === "") {
26096
26363
  editor.chain().focus().unsetHighlight().run();
@@ -26515,47 +26782,30 @@ var EditorToolbar = ({
26515
26782
  }
26516
26783
  ),
26517
26784
  /* @__PURE__ */ jsx81(ToolbarDivider, {}),
26518
- /* @__PURE__ */ jsx81(
26519
- ToolbarButton,
26520
- {
26521
- onClick: () => editor.chain().focus().toggleSubscript().run(),
26522
- active: editor.isActive("subscript"),
26523
- title: t("toolbar.subscript"),
26524
- children: /* @__PURE__ */ jsx81(SubscriptIcon, { className: "w-4 h-4" })
26525
- }
26526
- ),
26527
- /* @__PURE__ */ jsx81(
26528
- ToolbarButton,
26529
- {
26530
- onClick: () => editor.chain().focus().toggleSuperscript().run(),
26531
- active: editor.isActive("superscript"),
26532
- title: t("toolbar.superscript"),
26533
- children: /* @__PURE__ */ jsx81(SuperscriptIcon, { className: "w-4 h-4" })
26534
- }
26535
- ),
26536
- /* @__PURE__ */ jsx81(ToolbarDivider, {}),
26537
26785
  /* @__PURE__ */ jsx81(ToolbarButton, { onClick: () => editor.chain().focus().undo().run(), disabled: !editor.can().undo(), title: t("toolbar.undo"), children: /* @__PURE__ */ jsx81(UndoIcon, { className: "w-4 h-4" }) }),
26538
26786
  /* @__PURE__ */ jsx81(ToolbarButton, { onClick: () => editor.chain().focus().redo().run(), disabled: !editor.can().redo(), title: t("toolbar.redo"), children: /* @__PURE__ */ jsx81(RedoIcon, { className: "w-4 h-4" }) })
26539
26787
  ] });
26540
26788
  };
26541
26789
 
26542
26790
  // src/components/UEditor/menus.tsx
26543
- import { useCallback as useCallback22, useEffect as useEffect34, useMemo as useMemo23, useRef as useRef31, useState as useState45 } from "react";
26544
- import { createPortal as createPortal8 } from "react-dom";
26791
+ import { useCallback as useCallback22, useEffect as useEffect34, useMemo as useMemo23, useRef as useRef32, useState as useState45 } from "react";
26792
+ import { useEditorState as useEditorState2 } from "@tiptap/react";
26793
+ import { createPortal as createPortal9 } from "react-dom";
26545
26794
  import {
26546
26795
  AlignCenter as AlignCenter2,
26547
26796
  AlignLeft as AlignLeft2,
26548
26797
  AlignRight as AlignRight2,
26549
26798
  Bold as BoldIcon2,
26799
+ ChevronDown as ChevronDown8,
26550
26800
  Code as CodeIcon2,
26551
26801
  Italic as ItalicIcon2,
26552
26802
  Link as LinkIcon2,
26553
- Palette as Palette3,
26554
26803
  Plus as Plus3,
26555
26804
  RotateCcw as RotateCcw3,
26556
26805
  Subscript as SubscriptIcon2,
26557
26806
  Superscript as SuperscriptIcon2,
26558
26807
  Trash2 as Trash23,
26808
+ Type as Type3,
26559
26809
  Underline as UnderlineIcon2,
26560
26810
  Strikethrough as StrikethroughIcon2
26561
26811
  } from "lucide-react";
@@ -26564,7 +26814,7 @@ var FloatingSlashCommandMenu = ({ editor, onClose }) => {
26564
26814
  const t = useSmartTranslations("UEditor");
26565
26815
  const messages = useMemo23(() => buildSlashCommandMessages(t), [t]);
26566
26816
  const items = useMemo23(() => buildSlashCommandItems({ query: "", messages }), [messages]);
26567
- const listRef = useRef31(null);
26817
+ const listRef = useRef32(null);
26568
26818
  useEffect34(() => {
26569
26819
  const handleKeyDown2 = (event) => {
26570
26820
  if (event.key === "Escape") {
@@ -26619,14 +26869,23 @@ var BubbleMenuContent = ({
26619
26869
  lineHeights
26620
26870
  }) => {
26621
26871
  const t = useSmartTranslations("UEditor");
26872
+ useEditorState2({
26873
+ editor,
26874
+ selector: ({ transactionNumber }) => transactionNumber
26875
+ });
26622
26876
  const { textColors, highlightColors } = useEditorColors();
26623
26877
  const [showLinkInput, setShowLinkInput] = useState45(false);
26624
- const [showEditorColorPalette, setShowEditorColorPalette] = useState45(false);
26878
+ const [activeColorPalette, setActiveColorPalette] = useState45(null);
26879
+ const [showTypographyPanel, setShowTypographyPanel] = useState45(false);
26880
+ const [showFontSizeOptions, setShowFontSizeOptions] = useState45(false);
26881
+ const [fontSizeDraft, setFontSizeDraft] = useState45("");
26625
26882
  const isImageSelected = editor.isActive("image");
26626
26883
  const imageAttrs = editor.getAttributes("image");
26627
26884
  const imageLayout = imageAttrs.imageLayout === "left" || imageAttrs.imageLayout === "right" ? imageAttrs.imageLayout : "block";
26628
26885
  const imageWidthPreset = imageAttrs.imageWidthPreset === "sm" || imageAttrs.imageWidthPreset === "md" || imageAttrs.imageWidthPreset === "lg" ? imageAttrs.imageWidthPreset : null;
26629
26886
  const textStyleAttrs = editor.getAttributes("textStyle");
26887
+ const currentTextColor = normalizeStyleValue(textStyleAttrs.color) || "inherit";
26888
+ const currentHighlightColor = normalizeStyleValue(editor.getAttributes("highlight").color) || "";
26630
26889
  const currentFontSize = normalizeStyleValue(textStyleAttrs.fontSize);
26631
26890
  const currentLineHeight = normalizeStyleValue(textStyleAttrs.lineHeight);
26632
26891
  const quickFontSizes = useMemo23(
@@ -26637,6 +26896,21 @@ var BubbleMenuContent = ({
26637
26896
  () => (lineHeights ?? getDefaultLineHeights()).filter((option) => ["1.2", "1.5", "1.75"].includes(option.value)),
26638
26897
  [lineHeights]
26639
26898
  );
26899
+ useEffect34(() => {
26900
+ setFontSizeDraft(currentFontSize.replace(/px$/i, ""));
26901
+ }, [currentFontSize]);
26902
+ const applyFontSizeDraft = () => {
26903
+ const normalized = fontSizeDraft.trim();
26904
+ if (!normalized) {
26905
+ editor.chain().focus().unsetFontSize().run();
26906
+ return;
26907
+ }
26908
+ const parsed = Number.parseFloat(normalized);
26909
+ if (!Number.isFinite(parsed) || parsed <= 0) return;
26910
+ const clamped = Math.min(96, Math.max(8, parsed));
26911
+ editor.chain().focus().setFontSize(`${clamped}px`).run();
26912
+ setFontSizeDraft(String(clamped));
26913
+ };
26640
26914
  useEffect34(() => {
26641
26915
  onKeepOpenChange?.(showLinkInput);
26642
26916
  }, [onKeepOpenChange, showLinkInput]);
@@ -26667,44 +26941,37 @@ var BubbleMenuContent = ({
26667
26941
  }
26668
26942
  );
26669
26943
  }
26670
- if (showEditorColorPalette) {
26671
- return /* @__PURE__ */ jsxs68("div", { className: "w-48", children: [
26672
- /* @__PURE__ */ jsx82(
26673
- EditorColorPalette,
26674
- {
26675
- colors: textColors,
26676
- currentColor: editor.getAttributes("textStyle").color || "inherit",
26677
- onSelect: (color) => {
26678
- if (color === "inherit") {
26679
- editor.chain().focus().unsetColor().run();
26680
- } else {
26681
- editor.chain().focus().setColor(color).run();
26682
- }
26683
- },
26684
- label: t("colors.textColor")
26685
- }
26686
- ),
26687
- /* @__PURE__ */ jsx82("div", { className: "border-t my-1" }),
26944
+ if (activeColorPalette) {
26945
+ const isTextPalette = activeColorPalette === "text";
26946
+ return /* @__PURE__ */ jsxs68("div", { className: "w-56", children: [
26688
26947
  /* @__PURE__ */ jsx82(
26689
26948
  EditorColorPalette,
26690
26949
  {
26691
- colors: highlightColors,
26692
- currentColor: editor.getAttributes("highlight").color || "",
26950
+ colors: isTextPalette ? textColors : highlightColors,
26951
+ currentColor: isTextPalette ? currentTextColor : currentHighlightColor,
26693
26952
  onSelect: (color) => {
26694
- if (color === "") {
26695
- editor.chain().focus().unsetHighlight().run();
26953
+ if (isTextPalette) {
26954
+ if (color === "inherit") {
26955
+ editor.chain().focus().unsetColor().run();
26956
+ } else {
26957
+ editor.chain().focus().setColor(color).run();
26958
+ }
26696
26959
  } else {
26697
- editor.chain().focus().toggleHighlight({ color }).run();
26960
+ if (color === "") {
26961
+ editor.chain().focus().unsetHighlight().run();
26962
+ } else {
26963
+ editor.chain().focus().toggleHighlight({ color }).run();
26964
+ }
26698
26965
  }
26699
26966
  },
26700
- label: t("colors.highlight")
26967
+ label: isTextPalette ? t("colors.textColor") : t("colors.highlight")
26701
26968
  }
26702
26969
  ),
26703
26970
  /* @__PURE__ */ jsx82("div", { className: "p-2 border-t", children: /* @__PURE__ */ jsx82(
26704
26971
  "button",
26705
26972
  {
26706
26973
  type: "button",
26707
- onClick: () => setShowEditorColorPalette(false),
26974
+ onClick: () => setActiveColorPalette(null),
26708
26975
  className: "w-full py-1.5 text-sm rounded-lg hover:bg-muted transition-colors",
26709
26976
  children: t("colors.done")
26710
26977
  }
@@ -26725,6 +26992,162 @@ var BubbleMenuContent = ({
26725
26992
  /* @__PURE__ */ jsx82(ToolbarButton, { onClick: () => deleteSelectedImage(editor), title: t("toolbar.imageDelete"), className: "text-destructive hover:text-destructive", children: /* @__PURE__ */ jsx82(Trash23, { className: "w-4 h-4" }) })
26726
26993
  ] });
26727
26994
  }
26995
+ if (showTypographyPanel) {
26996
+ return /* @__PURE__ */ jsxs68("div", { className: "w-72 p-2", children: [
26997
+ /* @__PURE__ */ jsxs68("div", { className: "mb-2 flex items-center justify-between gap-2", children: [
26998
+ /* @__PURE__ */ jsx82("span", { className: "px-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: t("toolbar.textStyle") }),
26999
+ /* @__PURE__ */ jsx82(
27000
+ "button",
27001
+ {
27002
+ type: "button",
27003
+ onClick: () => setShowTypographyPanel(false),
27004
+ className: "rounded-md px-2 py-1 text-xs text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
27005
+ children: t("colors.done")
27006
+ }
27007
+ )
27008
+ ] }),
27009
+ /* @__PURE__ */ jsxs68("div", { className: "space-y-2", children: [
27010
+ /* @__PURE__ */ jsxs68("div", { children: [
27011
+ /* @__PURE__ */ jsx82("div", { className: "mb-1 px-1 text-[11px] font-medium text-muted-foreground", children: t("toolbar.fontSize") }),
27012
+ /* @__PURE__ */ jsxs68("div", { className: "flex h-9 items-center overflow-hidden rounded-md border border-border/60 bg-muted/40", children: [
27013
+ /* @__PURE__ */ jsx82(
27014
+ "input",
27015
+ {
27016
+ type: "number",
27017
+ min: 8,
27018
+ max: 96,
27019
+ step: 1,
27020
+ value: fontSizeDraft,
27021
+ onChange: (event) => setFontSizeDraft(event.target.value),
27022
+ onBlur: applyFontSizeDraft,
27023
+ onMouseDown: (event) => event.stopPropagation(),
27024
+ onClick: (event) => event.stopPropagation(),
27025
+ onKeyDown: (event) => {
27026
+ event.stopPropagation();
27027
+ if (event.key === "Enter") {
27028
+ event.preventDefault();
27029
+ applyFontSizeDraft();
27030
+ }
27031
+ },
27032
+ "aria-label": t("toolbar.fontSize"),
27033
+ placeholder: "A",
27034
+ 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"
27035
+ }
27036
+ ),
27037
+ /* @__PURE__ */ jsx82("span", { className: "border-l border-border/50 px-2 text-[11px] text-muted-foreground", children: "px" }),
27038
+ /* @__PURE__ */ jsx82(
27039
+ "button",
27040
+ {
27041
+ type: "button",
27042
+ "aria-label": t("toolbar.fontSize"),
27043
+ onClick: () => setShowFontSizeOptions((open) => !open),
27044
+ className: cn(
27045
+ "flex h-full w-9 items-center justify-center border-l border-border/50 transition-colors hover:bg-muted",
27046
+ showFontSizeOptions && "bg-primary/10 text-primary"
27047
+ ),
27048
+ children: /* @__PURE__ */ jsx82(ChevronDown8, { className: "h-4 w-4" })
27049
+ }
27050
+ )
27051
+ ] }),
27052
+ showFontSizeOptions && /* @__PURE__ */ jsxs68("div", { className: "mt-1 grid grid-cols-4 gap-1", children: [
27053
+ /* @__PURE__ */ jsx82(
27054
+ "button",
27055
+ {
27056
+ type: "button",
27057
+ onClick: () => {
27058
+ editor.chain().focus().unsetFontSize().run();
27059
+ setShowFontSizeOptions(false);
27060
+ },
27061
+ className: cn(
27062
+ "h-8 rounded-md text-xs font-semibold transition-colors hover:bg-muted",
27063
+ !currentFontSize ? "bg-primary/10 text-primary" : "bg-muted/40 text-foreground"
27064
+ ),
27065
+ children: "A"
27066
+ }
27067
+ ),
27068
+ quickFontSizes.map((option) => /* @__PURE__ */ jsx82(
27069
+ "button",
27070
+ {
27071
+ type: "button",
27072
+ onClick: () => {
27073
+ editor.chain().focus().setFontSize(option.value).run();
27074
+ setShowFontSizeOptions(false);
27075
+ },
27076
+ className: cn(
27077
+ "h-8 rounded-md text-xs font-semibold transition-colors hover:bg-muted",
27078
+ normalizeStyleValue(option.value) === currentFontSize ? "bg-primary/10 text-primary" : "bg-muted/40 text-foreground"
27079
+ ),
27080
+ children: option.label
27081
+ },
27082
+ option.value
27083
+ ))
27084
+ ] })
27085
+ ] }),
27086
+ /* @__PURE__ */ jsxs68("div", { children: [
27087
+ /* @__PURE__ */ jsx82("div", { className: "mb-1 px-1 text-[11px] font-medium text-muted-foreground", children: t("toolbar.lineHeight") }),
27088
+ /* @__PURE__ */ jsxs68("div", { className: "grid grid-cols-4 gap-1", children: [
27089
+ /* @__PURE__ */ jsx82(
27090
+ "button",
27091
+ {
27092
+ type: "button",
27093
+ onClick: () => editor.chain().focus().unsetLineHeight().run(),
27094
+ className: cn(
27095
+ "h-8 rounded-md text-xs font-semibold transition-colors hover:bg-muted",
27096
+ !currentLineHeight ? "bg-primary/10 text-primary" : "bg-muted/40 text-foreground"
27097
+ ),
27098
+ children: "LH"
27099
+ }
27100
+ ),
27101
+ quickLineHeights.map((option) => /* @__PURE__ */ jsx82(
27102
+ "button",
27103
+ {
27104
+ type: "button",
27105
+ onClick: () => editor.chain().focus().setLineHeight(option.value).run(),
27106
+ className: cn(
27107
+ "h-8 rounded-md text-xs font-semibold transition-colors hover:bg-muted",
27108
+ normalizeStyleValue(option.value) === currentLineHeight ? "bg-primary/10 text-primary" : "bg-muted/40 text-foreground"
27109
+ ),
27110
+ children: option.label
27111
+ },
27112
+ option.value
27113
+ ))
27114
+ ] })
27115
+ ] }),
27116
+ /* @__PURE__ */ jsxs68("div", { className: "grid grid-cols-2 gap-1 border-t border-border/40 pt-2", children: [
27117
+ /* @__PURE__ */ jsxs68(
27118
+ "button",
27119
+ {
27120
+ type: "button",
27121
+ onClick: () => editor.chain().focus().toggleSubscript().run(),
27122
+ className: cn(
27123
+ "flex h-8 items-center justify-center gap-2 rounded-md text-xs font-semibold transition-colors hover:bg-muted",
27124
+ editor.isActive("subscript") ? "bg-primary/10 text-primary" : "bg-muted/40 text-foreground"
27125
+ ),
27126
+ children: [
27127
+ /* @__PURE__ */ jsx82(SubscriptIcon2, { className: "h-4 w-4" }),
27128
+ t("toolbar.subscript")
27129
+ ]
27130
+ }
27131
+ ),
27132
+ /* @__PURE__ */ jsxs68(
27133
+ "button",
27134
+ {
27135
+ type: "button",
27136
+ onClick: () => editor.chain().focus().toggleSuperscript().run(),
27137
+ className: cn(
27138
+ "flex h-8 items-center justify-center gap-2 rounded-md text-xs font-semibold transition-colors hover:bg-muted",
27139
+ editor.isActive("superscript") ? "bg-primary/10 text-primary" : "bg-muted/40 text-foreground"
27140
+ ),
27141
+ children: [
27142
+ /* @__PURE__ */ jsx82(SuperscriptIcon2, { className: "h-4 w-4" }),
27143
+ t("toolbar.superscript")
27144
+ ]
27145
+ }
27146
+ )
27147
+ ] })
27148
+ ] })
27149
+ ] });
27150
+ }
26728
27151
  return /* @__PURE__ */ jsxs68("div", { className: "flex items-center gap-0.5 p-1", children: [
26729
27152
  /* @__PURE__ */ jsx82(ToolbarButton, { onClick: () => editor.chain().focus().toggleBold().run(), active: editor.isActive("bold"), title: t("toolbar.bold"), children: /* @__PURE__ */ jsx82(BoldIcon2, { className: "w-4 h-4" }) }),
26730
27153
  /* @__PURE__ */ jsx82(ToolbarButton, { onClick: () => editor.chain().focus().toggleItalic().run(), active: editor.isActive("italic"), title: t("toolbar.italic"), children: /* @__PURE__ */ jsx82(ItalicIcon2, { className: "w-4 h-4" }) }),
@@ -26754,68 +27177,16 @@ var BubbleMenuContent = ({
26754
27177
  children: /* @__PURE__ */ jsx82(LinkIcon2, { className: "w-4 h-4" })
26755
27178
  }
26756
27179
  ),
26757
- /* @__PURE__ */ jsx82(ToolbarButton, { onClick: () => setShowEditorColorPalette(true), title: t("colors.textColor"), children: /* @__PURE__ */ jsx82(Palette3, { className: "w-4 h-4" }) }),
26758
- /* @__PURE__ */ jsx82("div", { className: "w-px h-6 bg-border/50 mx-1" }),
26759
- /* @__PURE__ */ jsx82(
26760
- ToolbarButton,
26761
- {
26762
- onClick: () => editor.chain().focus().unsetFontSize().run(),
26763
- active: !currentFontSize,
26764
- title: t("toolbar.sizeDefault"),
26765
- className: "px-2 w-auto",
26766
- children: /* @__PURE__ */ jsx82("span", { className: "text-[10px] font-semibold", children: "A" })
26767
- }
26768
- ),
26769
- quickFontSizes.map((option) => /* @__PURE__ */ jsx82(
26770
- ToolbarButton,
26771
- {
26772
- onClick: () => editor.chain().focus().setFontSize(option.value).run(),
26773
- active: normalizeStyleValue(option.value) === currentFontSize,
26774
- title: `${t("toolbar.fontSize")} ${option.label}`,
26775
- className: "px-2 w-auto",
26776
- children: /* @__PURE__ */ jsx82("span", { className: "text-[10px] font-semibold", children: option.label })
26777
- },
26778
- option.value
26779
- )),
26780
- /* @__PURE__ */ jsx82("div", { className: "w-px h-6 bg-border/50 mx-1" }),
26781
- /* @__PURE__ */ jsx82(
26782
- ToolbarButton,
26783
- {
26784
- onClick: () => editor.chain().focus().unsetLineHeight().run(),
26785
- active: !currentLineHeight,
26786
- title: t("toolbar.lineHeightDefault"),
26787
- className: "px-2 w-auto",
26788
- children: /* @__PURE__ */ jsx82("span", { className: "text-[10px] font-semibold leading-none", children: "LH" })
26789
- }
26790
- ),
26791
- quickLineHeights.map((option) => /* @__PURE__ */ jsx82(
26792
- ToolbarButton,
26793
- {
26794
- onClick: () => editor.chain().focus().setLineHeight(option.value).run(),
26795
- active: normalizeStyleValue(option.value) === currentLineHeight,
26796
- title: `${t("toolbar.lineHeight")} ${option.label}`,
26797
- className: "px-2 w-auto",
26798
- children: /* @__PURE__ */ jsx82("span", { className: "text-[10px] font-semibold", children: option.label })
26799
- },
26800
- option.value
26801
- )),
27180
+ /* @__PURE__ */ jsx82(ToolbarButton, { onClick: () => setActiveColorPalette("text"), title: t("colors.textColor"), children: /* @__PURE__ */ jsx82(TextColorIcon, { color: currentTextColor }) }),
27181
+ /* @__PURE__ */ jsx82(ToolbarButton, { onClick: () => setActiveColorPalette("highlight"), active: editor.isActive("highlight"), title: t("colors.highlight"), children: /* @__PURE__ */ jsx82(HighlightColorIcon, { color: currentHighlightColor }) }),
26802
27182
  /* @__PURE__ */ jsx82("div", { className: "w-px h-6 bg-border/50 mx-1" }),
26803
27183
  /* @__PURE__ */ jsx82(
26804
27184
  ToolbarButton,
26805
27185
  {
26806
- onClick: () => editor.chain().focus().toggleSubscript().run(),
26807
- active: editor.isActive("subscript"),
26808
- title: t("toolbar.subscript"),
26809
- children: /* @__PURE__ */ jsx82(SubscriptIcon2, { className: "w-4 h-4" })
26810
- }
26811
- ),
26812
- /* @__PURE__ */ jsx82(
26813
- ToolbarButton,
26814
- {
26815
- onClick: () => editor.chain().focus().toggleSuperscript().run(),
26816
- active: editor.isActive("superscript"),
26817
- title: t("toolbar.superscript"),
26818
- children: /* @__PURE__ */ jsx82(SuperscriptIcon2, { className: "w-4 h-4" })
27186
+ onClick: () => setShowTypographyPanel(true),
27187
+ active: Boolean(currentFontSize || currentLineHeight || editor.isActive("subscript") || editor.isActive("superscript")),
27188
+ title: t("toolbar.textStyle"),
27189
+ children: /* @__PURE__ */ jsx82(Type3, { className: "w-4 h-4" })
26819
27190
  }
26820
27191
  )
26821
27192
  ] });
@@ -26829,9 +27200,9 @@ var CustomBubbleMenu = ({
26829
27200
  const BUBBLE_MENU_OFFSET = 16;
26830
27201
  const [isVisible, setIsVisible] = useState45(false);
26831
27202
  const [position, setPosition] = useState45({ top: 0, left: 0 });
26832
- const menuRef = useRef31(null);
26833
- const keepOpenRef = useRef31(false);
26834
- const showTimeoutRef = useRef31(null);
27203
+ const menuRef = useRef32(null);
27204
+ const keepOpenRef = useRef32(false);
27205
+ const showTimeoutRef = useRef32(null);
26835
27206
  const setKeepOpen = useCallback22((next) => {
26836
27207
  keepOpenRef.current = next;
26837
27208
  if (next) setIsVisible(true);
@@ -26884,12 +27255,12 @@ var CustomBubbleMenu = ({
26884
27255
  };
26885
27256
  }, [editor]);
26886
27257
  if (!isVisible) return null;
26887
- return createPortal8(
27258
+ return createPortal9(
26888
27259
  /* @__PURE__ */ jsx82(
26889
27260
  "div",
26890
27261
  {
26891
27262
  ref: menuRef,
26892
- 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",
27263
+ 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",
26893
27264
  style: {
26894
27265
  top: `${position.top}px`,
26895
27266
  left: `${position.left}px`,
@@ -26940,7 +27311,7 @@ var CustomFloatingMenu = ({ editor }) => {
26940
27311
  };
26941
27312
  }, [editor]);
26942
27313
  if (!isVisible) return null;
26943
- return createPortal8(
27314
+ return createPortal9(
26944
27315
  /* @__PURE__ */ jsx82(
26945
27316
  "div",
26946
27317
  {
@@ -32672,10 +33043,10 @@ var UEDITOR_PROSEMIRROR_CLASS_NAME = cn(
32672
33043
  );
32673
33044
 
32674
33045
  // src/components/UEditor/use-table-interactions.ts
32675
- import React77, { useEffect as useEffect35, useRef as useRef33 } from "react";
33046
+ import React77, { useEffect as useEffect35, useRef as useRef34 } from "react";
32676
33047
 
32677
33048
  // src/components/UEditor/use-table-row-resize.ts
32678
- import React76, { useRef as useRef32 } from "react";
33049
+ import React76, { useRef as useRef33 } from "react";
32679
33050
  function useTableRowResize({
32680
33051
  editor,
32681
33052
  setHoveredTableCell,
@@ -32684,8 +33055,8 @@ function useTableRowResize({
32684
33055
  clearAllTableResizeHover,
32685
33056
  scheduleTableLayoutSync
32686
33057
  }) {
32687
- const commitFrameRef = useRef32(null);
32688
- const stateRef = useRef32(null);
33058
+ const commitFrameRef = useRef33(null);
33059
+ const stateRef = useRef33(null);
32689
33060
  const commitPreview = React76.useCallback(() => {
32690
33061
  if (!editor) return;
32691
33062
  const state = stateRef.current;
@@ -32841,14 +33212,14 @@ function useTableRowResize({
32841
33212
 
32842
33213
  // src/components/UEditor/use-table-interactions.ts
32843
33214
  function useUEditorTableInteractions(editor, editable = true) {
32844
- const editorContentRef = useRef33(null);
32845
- const tableColumnGuideRef = useRef33(null);
32846
- const tableRowGuideRef = useRef33(null);
32847
- const activeTableCellHighlightRef = useRef33(null);
32848
- const hoveredTableCellRef = useRef33(null);
32849
- const activeTableCellRef = useRef33(null);
32850
- const suppressActiveCellHighlightRef = useRef33(false);
32851
- const tableLayoutSyncFrameRef = useRef33(null);
33215
+ const editorContentRef = useRef34(null);
33216
+ const tableColumnGuideRef = useRef34(null);
33217
+ const tableRowGuideRef = useRef34(null);
33218
+ const activeTableCellHighlightRef = useRef34(null);
33219
+ const hoveredTableCellRef = useRef34(null);
33220
+ const activeTableCellRef = useRef34(null);
33221
+ const suppressActiveCellHighlightRef = useRef34(false);
33222
+ const tableLayoutSyncFrameRef = useRef34(null);
32852
33223
  const setEditorResizeCursor = React77.useCallback((cursor) => {
32853
33224
  const proseMirror = editorContentRef.current?.querySelector(".ProseMirror");
32854
33225
  if (proseMirror) {
@@ -33150,8 +33521,8 @@ var UEditor = React78.forwardRef(({
33150
33521
  }, ref) => {
33151
33522
  const t = useSmartTranslations("UEditor");
33152
33523
  const effectivePlaceholder = placeholder ?? t("placeholder");
33153
- const inFlightPrepareRef = useRef34(null);
33154
- const lastAppliedContentRef = useRef34(content ?? "");
33524
+ const inFlightPrepareRef = useRef35(null);
33525
+ const lastAppliedContentRef = useRef35(content ?? "");
33155
33526
  const extensions = useMemo24(
33156
33527
  () => buildUEditorExtensions({
33157
33528
  placeholder: effectivePlaceholder,