@underverse-ui/underverse 1.0.186 → 1.0.188

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
@@ -808,6 +808,8 @@ var en_default = {
808
808
  fileCardDesc: "Upload a file card attachment",
809
809
  formCheckbox: "Form Checkbox",
810
810
  formCheckboxDesc: "Insert an interactive checkbox field",
811
+ roundCheckbox: "Round Checkbox",
812
+ roundCheckboxDesc: "Insert a circular interactive checkbox",
811
813
  formRadio: "Form Radio Button",
812
814
  formRadioDesc: "Insert an interactive radio button field"
813
815
  },
@@ -815,7 +817,8 @@ var en_default = {
815
817
  addBlock: "Add block"
816
818
  },
817
819
  linkInput: {
818
- placeholder: "Paste or type a link..."
820
+ placeholder: "Paste or type a link...",
821
+ invalid: "Enter a valid link, such as https://example.com."
819
822
  },
820
823
  imageInput: {
821
824
  urlTab: "URL",
@@ -906,7 +909,10 @@ var en_default = {
906
909
  alignVertical: "Vertical Alignment",
907
910
  alignVerticalTop: "Top Align",
908
911
  alignVerticalMiddle: "Middle Align",
909
- alignVerticalBottom: "Bottom Align"
912
+ alignVerticalBottom: "Bottom Align",
913
+ textDirection: "Text Direction",
914
+ horizontalText: "Horizontal Text",
915
+ verticalText: "Vertical Text"
910
916
  },
911
917
  callout: {
912
918
  selectEmoji: "Select Emoji",
@@ -1235,6 +1241,8 @@ var vi_default = {
1235
1241
  fileCardDesc: "T\u1EA3i l\xEAn t\u1EC7p tin \u0111\xEDnh k\xE8m",
1236
1242
  formCheckbox: "Checkbox bi\u1EC3u m\u1EABu",
1237
1243
  formCheckboxDesc: "Th\xEAm \xF4 checkbox bi\u1EC3u m\u1EABu",
1244
+ roundCheckbox: "Checkbox tr\xF2n",
1245
+ roundCheckboxDesc: "Th\xEAm checkbox t\u01B0\u01A1ng t\xE1c h\xECnh tr\xF2n",
1238
1246
  formRadio: "Radio bi\u1EC3u m\u1EABu",
1239
1247
  formRadioDesc: "Th\xEAm n\xFAt ch\u1ECDn m\u1ED9t (Radio) bi\u1EC3u m\u1EABu"
1240
1248
  },
@@ -1242,7 +1250,8 @@ var vi_default = {
1242
1250
  addBlock: "Th\xEAm kh\u1ED1i"
1243
1251
  },
1244
1252
  linkInput: {
1245
- placeholder: "D\xE1n ho\u1EB7c nh\u1EADp li\xEAn k\u1EBFt..."
1253
+ placeholder: "D\xE1n ho\u1EB7c nh\u1EADp li\xEAn k\u1EBFt...",
1254
+ invalid: "Vui l\xF2ng nh\u1EADp li\xEAn k\u1EBFt h\u1EE3p l\u1EC7, v\xED d\u1EE5: https://example.com."
1246
1255
  },
1247
1256
  imageInput: {
1248
1257
  urlTab: "URL",
@@ -1333,7 +1342,10 @@ var vi_default = {
1333
1342
  alignVertical: "C\u0103n l\u1EC1 d\u1ECDc",
1334
1343
  alignVerticalTop: "C\u0103n tr\xEAn",
1335
1344
  alignVerticalMiddle: "C\u0103n gi\u1EEFa",
1336
- alignVerticalBottom: "C\u0103n d\u01B0\u1EDBi"
1345
+ alignVerticalBottom: "C\u0103n d\u01B0\u1EDBi",
1346
+ textDirection: "H\u01B0\u1EDBng ch\u1EEF",
1347
+ horizontalText: "Ch\u1EEF ngang",
1348
+ verticalText: "Ch\u1EEF d\u1ECDc"
1337
1349
  },
1338
1350
  callout: {
1339
1351
  selectEmoji: "Ch\u1ECDn Bi\u1EC3u t\u01B0\u1EE3ng",
@@ -1662,6 +1674,8 @@ var ko_default = {
1662
1674
  fileCardDesc: "\uD30C\uC77C \uCE74\uB4DC \uCCA8\uBD80 \uD30C\uC77C\uC744 \uC5C5\uB85C\uB4DC\uD569\uB2C8\uB2E4",
1663
1675
  formCheckbox: "\uC591\uC2DD \uCCB4\uD06C\uBC15\uC2A4",
1664
1676
  formCheckboxDesc: "\uB300\uD654\uD615 \uCCB4\uD06C\uBC15\uC2A4 \uD544\uB4DC \uC0BD\uC785",
1677
+ roundCheckbox: "\uC6D0\uD615 \uCCB4\uD06C\uBC15\uC2A4",
1678
+ roundCheckboxDesc: "\uC6D0\uD615 \uB300\uD654\uD615 \uCCB4\uD06C\uBC15\uC2A4 \uC0BD\uC785",
1665
1679
  formRadio: "\uC591\uC2DD \uB77C\uB514\uC624 \uBC84\uD2BC",
1666
1680
  formRadioDesc: "\uB300\uD654\uD615 \uB77C\uB514\uC624 \uBC84\uD2BC \uD544\uB4DC \uC0BD\uC785"
1667
1681
  },
@@ -1669,7 +1683,8 @@ var ko_default = {
1669
1683
  addBlock: "\uBE14\uB85D \uCD94\uAC00"
1670
1684
  },
1671
1685
  linkInput: {
1672
- placeholder: "\uB9C1\uD06C \uBD99\uC5EC\uB123\uAE30 \uB610\uB294 \uC785\uB825..."
1686
+ placeholder: "\uB9C1\uD06C \uBD99\uC5EC\uB123\uAE30 \uB610\uB294 \uC785\uB825...",
1687
+ invalid: "https://example.com\uACFC \uAC19\uC740 \uC62C\uBC14\uB978 \uB9C1\uD06C\uB97C \uC785\uB825\uD574 \uC8FC\uC138\uC694."
1673
1688
  },
1674
1689
  imageInput: {
1675
1690
  urlTab: "URL",
@@ -1760,7 +1775,10 @@ var ko_default = {
1760
1775
  alignVertical: "\uC138\uB85C \uB9DE\uCDA4",
1761
1776
  alignVerticalTop: "\uC704\uCABD \uB9DE\uCDA4",
1762
1777
  alignVerticalMiddle: "\uAC00\uC6B4\uB370 \uB9DE\uCDA4",
1763
- alignVerticalBottom: "\uC544\uB798\uCABD \uB9DE\uCDA4"
1778
+ alignVerticalBottom: "\uC544\uB798\uCABD \uB9DE\uCDA4",
1779
+ textDirection: "\uD14D\uC2A4\uD2B8 \uBC29\uD5A5",
1780
+ horizontalText: "\uAC00\uB85C\uC4F0\uAE30",
1781
+ verticalText: "\uC138\uB85C\uC4F0\uAE30"
1764
1782
  },
1765
1783
  callout: {
1766
1784
  selectEmoji: "\uC774\uBAA8\uC9C0 \uC120\uD0DD",
@@ -2089,6 +2107,8 @@ var ja_default = {
2089
2107
  fileCardDesc: "\u30D5\u30A1\u30A4\u30EB\u30AB\u30FC\u30C9\u306E\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u3092\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u3057\u307E\u3059",
2090
2108
  formCheckbox: "\u30D5\u30A9\u30FC\u30E0\u30C1\u30A7\u30C3\u30AF\u30DC\u30C3\u30AF\u30B9",
2091
2109
  formCheckboxDesc: "\u30A4\u30F3\u30BF\u30E9\u30AF\u30C6\u30A3\u30D6\u306A\u30C1\u30A7\u30C3\u30AF\u30DC\u30C3\u30AF\u30B9\u3092\u633F\u5165\u3057\u307E\u3059",
2110
+ roundCheckbox: "\u4E38\u578B\u30C1\u30A7\u30C3\u30AF\u30DC\u30C3\u30AF\u30B9",
2111
+ roundCheckboxDesc: "\u4E38\u578B\u306E\u30A4\u30F3\u30BF\u30E9\u30AF\u30C6\u30A3\u30D6\u306A\u30C1\u30A7\u30C3\u30AF\u30DC\u30C3\u30AF\u30B9\u3092\u633F\u5165\u3057\u307E\u3059",
2092
2112
  formRadio: "\u30D5\u30A9\u30FC\u30E0\u30E9\u30B8\u30AA\u30DC\u30BF\u30F3",
2093
2113
  formRadioDesc: "\u30A4\u30F3\u30BF\u30E9\u30AF\u30C6\u30A3\u30D6\u306A\u30E9\u30B8\u30AA\u30DC\u30BF\u30F3\u3092\u633F\u5165\u3057\u307E\u3059"
2094
2114
  },
@@ -2096,7 +2116,8 @@ var ja_default = {
2096
2116
  addBlock: "\u30D6\u30ED\u30C3\u30AF\u3092\u8FFD\u52A0"
2097
2117
  },
2098
2118
  linkInput: {
2099
- placeholder: "\u30EA\u30F3\u30AF\u3092\u8CBC\u308A\u4ED8\u3051\u307E\u305F\u306F\u5165\u529B..."
2119
+ placeholder: "\u30EA\u30F3\u30AF\u3092\u8CBC\u308A\u4ED8\u3051\u307E\u305F\u306F\u5165\u529B...",
2120
+ invalid: "https://example.com \u306E\u3088\u3046\u306A\u6709\u52B9\u306A\u30EA\u30F3\u30AF\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\u3002"
2100
2121
  },
2101
2122
  imageInput: {
2102
2123
  urlTab: "URL",
@@ -2187,7 +2208,10 @@ var ja_default = {
2187
2208
  alignVertical: "\u5782\u76F4\u63C3\u3048",
2188
2209
  alignVerticalTop: "\u4E0A\u63C3\u3048",
2189
2210
  alignVerticalMiddle: "\u4E0A\u4E0B\u4E2D\u592E\u63C3\u3048",
2190
- alignVerticalBottom: "\u4E0B\u63C3\u3048"
2211
+ alignVerticalBottom: "\u4E0B\u63C3\u3048",
2212
+ textDirection: "\u6587\u5B57\u65B9\u5411",
2213
+ horizontalText: "\u6A2A\u66F8\u304D",
2214
+ verticalText: "\u7E26\u66F8\u304D"
2191
2215
  },
2192
2216
  callout: {
2193
2217
  selectEmoji: "\u7D75\u6587\u5B57\u3092\u9078\u629E",
@@ -27566,6 +27590,32 @@ function isProtocolRelativeUrl(value) {
27566
27590
  function isRelativeUrl(value) {
27567
27591
  return value.startsWith("/") || value.startsWith("./") || value.startsWith("../") || value.startsWith("#");
27568
27592
  }
27593
+ function isValidIpv4Hostname(hostname) {
27594
+ const parts = hostname.split(".");
27595
+ return parts.length === 4 && parts.every((part) => /^\d{1,3}$/.test(part) && Number(part) <= 255);
27596
+ }
27597
+ function isValidWebHostname(hostname) {
27598
+ const normalized = hostname.toLowerCase();
27599
+ if (normalized === "localhost" || isValidIpv4Hostname(normalized)) return true;
27600
+ if (normalized.startsWith("[") && normalized.endsWith("]") && normalized.includes(":")) return true;
27601
+ const labels = normalized.split(".");
27602
+ if (labels.length < 2) return false;
27603
+ const validLabel = /^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)$/;
27604
+ return labels.every((label) => validLabel.test(label)) && /[a-z]/.test(labels.at(-1) ?? "");
27605
+ }
27606
+ function isValidLinkUrl(parsed) {
27607
+ if (parsed.protocol === "http:" || parsed.protocol === "https:") {
27608
+ return isValidWebHostname(parsed.hostname);
27609
+ }
27610
+ if (parsed.protocol === "mailto:") {
27611
+ return /^[^@]+@[^@]+\.[^@]+$/.test(decodeURIComponent(parsed.pathname));
27612
+ }
27613
+ if (parsed.protocol === "tel:") {
27614
+ const number = decodeURIComponent(parsed.pathname);
27615
+ return /^\+?[\d().-]+$/.test(number) && (number.match(/\d/g)?.length ?? 0) >= 3;
27616
+ }
27617
+ return false;
27618
+ }
27569
27619
  function isDataImageUrl(value) {
27570
27620
  return /^data:image\/(?:png|jpe?g|gif|webp|svg\+xml|bmp|x-icon|avif);base64,/i.test(value);
27571
27621
  }
@@ -27583,7 +27633,7 @@ function isSafeUEditorUrl(raw, kind) {
27583
27633
  const parsed = new URL(value);
27584
27634
  if (kind === "image") return IMAGE_PROTOCOLS.has(parsed.protocol);
27585
27635
  if (kind === "file") return FILE_PROTOCOLS.has(parsed.protocol);
27586
- return LINK_PROTOCOLS.has(parsed.protocol);
27636
+ return LINK_PROTOCOLS.has(parsed.protocol) && isValidLinkUrl(parsed);
27587
27637
  } catch {
27588
27638
  return false;
27589
27639
  }
@@ -28170,6 +28220,7 @@ import { Check as Check10 } from "lucide-react";
28170
28220
  import { jsx as jsx82 } from "react/jsx-runtime";
28171
28221
  var FormCheckboxView = ({ node, updateAttributes, editor, selected }) => {
28172
28222
  const isChecked = !!node.attrs.checked;
28223
+ const isCircle = node.attrs.variant === "circle";
28173
28224
  const isEditable = editor.isEditable;
28174
28225
  const handleToggle = (e) => {
28175
28226
  if (!isEditable) return;
@@ -28199,7 +28250,8 @@ var FormCheckboxView = ({ node, updateAttributes, editor, selected }) => {
28199
28250
  onClick: handleToggle,
28200
28251
  onKeyDown: handleKeyDown2,
28201
28252
  className: cn(
28202
- "flex items-center justify-center w-5 h-5 rounded-md border text-primary-foreground transition-all duration-200 outline-none",
28253
+ "flex items-center justify-center w-5 h-5 border text-primary-foreground transition-all duration-200 outline-none",
28254
+ isCircle ? "rounded-full" : "rounded-md",
28203
28255
  isChecked ? "bg-primary border-primary scale-100" : "bg-background border-border/70 hover:border-primary/50",
28204
28256
  selected && "ring-2 ring-primary/30 ring-offset-1",
28205
28257
  isEditable && "focus-visible:ring-2 focus-visible:ring-primary/45 focus-visible:ring-offset-1 focus-visible:border-primary"
@@ -28271,6 +28323,11 @@ var FormCheckbox2 = Node5.create({
28271
28323
  name: attributes.name
28272
28324
  };
28273
28325
  }
28326
+ },
28327
+ variant: {
28328
+ default: "square",
28329
+ parseHTML: (element) => element.getAttribute("data-variant") === "circle" ? "circle" : "square",
28330
+ renderHTML: (attributes) => attributes.variant === "circle" ? { "data-variant": "circle" } : {}
28274
28331
  }
28275
28332
  };
28276
28333
  },
@@ -28563,6 +28620,7 @@ import {
28563
28620
  Bookmark as BookmarkIcon,
28564
28621
  Paperclip,
28565
28622
  CheckSquare,
28623
+ CircleCheckBig,
28566
28624
  CircleDot
28567
28625
  } from "lucide-react";
28568
28626
 
@@ -28624,6 +28682,8 @@ var DEFAULT_MESSAGES = {
28624
28682
  fileCardDesc: "Upload a file card attachment",
28625
28683
  formCheckbox: "Form Checkbox",
28626
28684
  formCheckboxDesc: "Insert an interactive checkbox field",
28685
+ roundCheckbox: "Round Checkbox",
28686
+ roundCheckboxDesc: "Insert a circular interactive checkbox",
28627
28687
  formRadio: "Form Radio Button",
28628
28688
  formRadioDesc: "Insert an interactive radio button field"
28629
28689
  };
@@ -28679,6 +28739,8 @@ function buildSlashCommandMessages(translate) {
28679
28739
  fileCardDesc: translate("slashCommand.fileCardDesc") || "Upload a file card attachment",
28680
28740
  formCheckbox: translate("slashCommand.formCheckbox") || "Form Checkbox",
28681
28741
  formCheckboxDesc: translate("slashCommand.formCheckboxDesc") || "Insert an interactive checkbox field",
28742
+ roundCheckbox: translate("slashCommand.roundCheckbox") || "Round Checkbox",
28743
+ roundCheckboxDesc: translate("slashCommand.roundCheckboxDesc") || "Insert a circular interactive checkbox",
28682
28744
  formRadio: translate("slashCommand.formRadio") || "Form Radio Button",
28683
28745
  formRadioDesc: translate("slashCommand.formRadioDesc") || "Insert an interactive radio button field"
28684
28746
  };
@@ -28825,10 +28887,20 @@ function buildSlashCommandItems({
28825
28887
  icon: CheckSquare,
28826
28888
  title: messages.formCheckbox,
28827
28889
  description: messages.formCheckboxDesc,
28890
+ searchTerms: ["checkbox", "square checkbox"],
28828
28891
  command: run(({ editor, range }) => {
28829
28892
  getCommandChain(editor, range).setFormCheckbox().run();
28830
28893
  })
28831
28894
  },
28895
+ {
28896
+ icon: CircleCheckBig,
28897
+ title: messages.roundCheckbox,
28898
+ description: messages.roundCheckboxDesc,
28899
+ searchTerms: ["roundcheckbox", "round checkbox", "circle checkbox"],
28900
+ command: run(({ editor, range }) => {
28901
+ getCommandChain(editor, range).setFormCheckbox({ variant: "circle" }).run();
28902
+ })
28903
+ },
28832
28904
  {
28833
28905
  icon: CircleDot,
28834
28906
  title: messages.formRadio,
@@ -28837,7 +28909,11 @@ function buildSlashCommandItems({
28837
28909
  getCommandChain(editor, range).setFormRadio({ name: `radio-group-${Math.random().toString(36).substring(2, 6)}` }).run();
28838
28910
  })
28839
28911
  }
28840
- ].filter((item) => item.title.toLowerCase().includes(query.toLowerCase()));
28912
+ ].filter((item) => {
28913
+ const normalizedQuery = query.trim().toLowerCase();
28914
+ if (!normalizedQuery) return true;
28915
+ return [item.title, item.description, ...item.searchTerms ?? []].some((value) => value.toLowerCase().includes(normalizedQuery));
28916
+ });
28841
28917
  }
28842
28918
  var SlashCommandList = forwardRef14((props, ref) => {
28843
28919
  const [selectedIndex, setSelectedIndex] = useResettingIndex2(props.items);
@@ -31644,6 +31720,11 @@ var CustomTableCell = TableCell2.extend({
31644
31720
  "data-vertical-align": attributes.verticalAlign
31645
31721
  };
31646
31722
  }
31723
+ },
31724
+ textDirection: {
31725
+ default: null,
31726
+ parseHTML: (element) => element.getAttribute("data-text-direction") === "vertical" || element.style.writingMode === "vertical-rl" ? "vertical" : null,
31727
+ renderHTML: (attributes) => attributes.textDirection === "vertical" ? { "data-text-direction": "vertical" } : {}
31647
31728
  }
31648
31729
  };
31649
31730
  },
@@ -31654,12 +31735,14 @@ var CustomTableCell = TableCell2.extend({
31654
31735
  const borderStyle = HTMLAttributes["data-border-style"];
31655
31736
  const borderWidth = HTMLAttributes["data-border-width"];
31656
31737
  const verticalAlign = HTMLAttributes["data-vertical-align"];
31738
+ const textDirection = HTMLAttributes["data-text-direction"];
31657
31739
  let mergedStyle = style;
31658
31740
  if (bg) mergedStyle += `; background-color: ${bg}`;
31659
31741
  if (borderColor) mergedStyle += `; border-color: ${borderColor}`;
31660
31742
  if (borderStyle) mergedStyle += `; border-style: ${borderStyle}`;
31661
31743
  if (borderWidth) mergedStyle += `; border-width: ${borderWidth}`;
31662
31744
  if (verticalAlign) mergedStyle += `; vertical-align: ${verticalAlign}`;
31745
+ if (textDirection === "vertical") mergedStyle += "; writing-mode: vertical-rl; text-orientation: mixed";
31663
31746
  mergedStyle = mergedStyle.replace(/^;/, "").trim();
31664
31747
  return [
31665
31748
  "td",
@@ -31763,6 +31846,11 @@ var CustomTableHeader = TableHeader2.extend({
31763
31846
  "data-vertical-align": attributes.verticalAlign
31764
31847
  };
31765
31848
  }
31849
+ },
31850
+ textDirection: {
31851
+ default: null,
31852
+ parseHTML: (element) => element.getAttribute("data-text-direction") === "vertical" || element.style.writingMode === "vertical-rl" ? "vertical" : null,
31853
+ renderHTML: (attributes) => attributes.textDirection === "vertical" ? { "data-text-direction": "vertical" } : {}
31766
31854
  }
31767
31855
  };
31768
31856
  },
@@ -31773,12 +31861,14 @@ var CustomTableHeader = TableHeader2.extend({
31773
31861
  const borderStyle = HTMLAttributes["data-border-style"];
31774
31862
  const borderWidth = HTMLAttributes["data-border-width"];
31775
31863
  const verticalAlign = HTMLAttributes["data-vertical-align"];
31864
+ const textDirection = HTMLAttributes["data-text-direction"];
31776
31865
  let mergedStyle = style;
31777
31866
  if (bg) mergedStyle += `; background-color: ${bg}`;
31778
31867
  if (borderColor) mergedStyle += `; border-color: ${borderColor}`;
31779
31868
  if (borderStyle) mergedStyle += `; border-style: ${borderStyle}`;
31780
31869
  if (borderWidth) mergedStyle += `; border-width: ${borderWidth}`;
31781
31870
  if (verticalAlign) mergedStyle += `; vertical-align: ${verticalAlign}`;
31871
+ if (textDirection === "vertical") mergedStyle += "; writing-mode: vertical-rl; text-orientation: mixed";
31782
31872
  mergedStyle = mergedStyle.replace(/^;/, "").trim();
31783
31873
  return [
31784
31874
  "th",
@@ -31972,6 +32062,7 @@ import {
31972
32062
  Bold as BoldIcon,
31973
32063
  ChevronDown as ChevronDown8,
31974
32064
  ChevronsUpDown,
32065
+ CircleCheckBig as CircleCheckBig2,
31975
32066
  Code as CodeIcon,
31976
32067
  FileCode as FileCode3,
31977
32068
  Heading1 as Heading1Icon,
@@ -31987,6 +32078,7 @@ import {
31987
32078
  Redo as RedoIcon,
31988
32079
  RotateCcw as RotateCcw2,
31989
32080
  Smile as Smile3,
32081
+ SquareCheckBig,
31990
32082
  Strikethrough as StrikethroughIcon,
31991
32083
  Subscript as SubscriptIcon,
31992
32084
  Superscript as SuperscriptIcon,
@@ -32379,7 +32471,7 @@ function deleteSelectedImage(editor) {
32379
32471
  }
32380
32472
 
32381
32473
  // src/components/UEditor/inputs.tsx
32382
- import { useEffect as useEffect36, useRef as useRef32, useState as useState48 } from "react";
32474
+ import { useEffect as useEffect36, useId as useId15, useRef as useRef32, useState as useState48 } from "react";
32383
32475
  import { Check as Check13, X as X19 } from "lucide-react";
32384
32476
  import { jsx as jsx90, jsxs as jsxs74 } from "react/jsx-runtime";
32385
32477
  function normalizeUrl(raw) {
@@ -32392,7 +32484,9 @@ var LinkInput = ({
32392
32484
  }) => {
32393
32485
  const t = useSmartTranslations("UEditor");
32394
32486
  const [url, setUrl] = useState48(initialUrl);
32487
+ const [error, setError] = useState48("");
32395
32488
  const inputRef = useRef32(null);
32489
+ const errorId = useId15();
32396
32490
  useEffect36(() => {
32397
32491
  inputRef.current?.focus();
32398
32492
  inputRef.current?.select();
@@ -32400,22 +32494,35 @@ var LinkInput = ({
32400
32494
  const handleSubmit = (e) => {
32401
32495
  e.preventDefault();
32402
32496
  const normalized = normalizeUrl(url);
32403
- if (normalized) onSubmit(normalized);
32497
+ if (!normalized) {
32498
+ setError(t("linkInput.invalid"));
32499
+ return;
32500
+ }
32501
+ setError("");
32502
+ onSubmit(normalized);
32404
32503
  };
32405
- return /* @__PURE__ */ jsxs74("form", { onSubmit: handleSubmit, className: "flex items-center gap-2 p-2", children: [
32406
- /* @__PURE__ */ jsx90(
32407
- "input",
32408
- {
32409
- ref: inputRef,
32410
- type: "text",
32411
- value: url,
32412
- onChange: (e) => setUrl(e.target.value),
32413
- placeholder: t("linkInput.placeholder"),
32414
- 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"
32415
- }
32416
- ),
32417
- /* @__PURE__ */ jsx90("button", { type: "submit", className: "p-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 transition-colors", children: /* @__PURE__ */ jsx90(Check13, { className: "w-4 h-4" }) }),
32418
- /* @__PURE__ */ jsx90("button", { type: "button", onClick: onCancel, className: "p-2 rounded-lg hover:bg-muted transition-colors text-muted-foreground", children: /* @__PURE__ */ jsx90(X19, { className: "w-4 h-4" }) })
32504
+ return /* @__PURE__ */ jsxs74("form", { onSubmit: handleSubmit, className: "p-2", children: [
32505
+ /* @__PURE__ */ jsxs74("div", { className: "flex items-center gap-2", children: [
32506
+ /* @__PURE__ */ jsx90(
32507
+ "input",
32508
+ {
32509
+ ref: inputRef,
32510
+ type: "text",
32511
+ value: url,
32512
+ onChange: (e) => {
32513
+ setUrl(e.target.value);
32514
+ if (error) setError("");
32515
+ },
32516
+ placeholder: t("linkInput.placeholder"),
32517
+ "aria-invalid": Boolean(error),
32518
+ "aria-describedby": error ? errorId : void 0,
32519
+ 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 aria-invalid:ring-2 aria-invalid:ring-destructive/40"
32520
+ }
32521
+ ),
32522
+ /* @__PURE__ */ jsx90("button", { type: "submit", className: "p-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 transition-colors", children: /* @__PURE__ */ jsx90(Check13, { className: "w-4 h-4" }) }),
32523
+ /* @__PURE__ */ jsx90("button", { type: "button", onClick: onCancel, className: "p-2 rounded-lg hover:bg-muted transition-colors text-muted-foreground", children: /* @__PURE__ */ jsx90(X19, { className: "w-4 h-4" }) })
32524
+ ] }),
32525
+ error ? /* @__PURE__ */ jsx90("p", { id: errorId, role: "alert", className: "mt-1.5 px-1 text-xs text-destructive", children: error }) : null
32419
32526
  ] });
32420
32527
  };
32421
32528
  var ImageInput = ({ onSubmit, onCancel }) => {
@@ -32476,8 +32583,28 @@ var ImageInput = ({ onSubmit, onCancel }) => {
32476
32583
  ] });
32477
32584
  };
32478
32585
 
32479
- // src/components/UEditor/table-cell-commands.ts
32586
+ // src/components/UEditor/link-commands.ts
32480
32587
  import { TextSelection as TextSelection2 } from "@tiptap/pm/state";
32588
+ function applyEditorLink(editor, href) {
32589
+ const isEditingLink = editor.isActive("link");
32590
+ const hasSelectedText = !editor.state.selection.empty;
32591
+ const chain = editor.chain().focus();
32592
+ if (isEditingLink) {
32593
+ chain.extendMarkRange("link");
32594
+ }
32595
+ chain.setLink({ href });
32596
+ if (!hasSelectedText && !isEditingLink) {
32597
+ chain.insertContent(href);
32598
+ }
32599
+ return chain.command(({ tr }) => {
32600
+ tr.setSelection(TextSelection2.create(tr.doc, tr.selection.to));
32601
+ tr.removeStoredMark(editor.schema.marks.link);
32602
+ return true;
32603
+ }).run();
32604
+ }
32605
+
32606
+ // src/components/UEditor/table-cell-commands.ts
32607
+ import { TextSelection as TextSelection3 } from "@tiptap/pm/state";
32481
32608
  import { selectedRect, TableMap as TableMap2 } from "@tiptap/pm/tables";
32482
32609
  function getCellSelectionPositions(selection) {
32483
32610
  const value = selection;
@@ -32511,7 +32638,7 @@ function getFocusableCellPos(editor, cellPos) {
32511
32638
  return node?.isTextblock ? offset + 1 : cellPos + 1;
32512
32639
  }
32513
32640
  function focusCell(editor, cellPos) {
32514
- const selection = TextSelection2.near(editor.state.doc.resolve(getFocusableCellPos(editor, cellPos)));
32641
+ const selection = TextSelection3.near(editor.state.doc.resolve(getFocusableCellPos(editor, cellPos)));
32515
32642
  editor.view.dispatch(editor.state.tr.setSelection(selection));
32516
32643
  editor.view.focus();
32517
32644
  }
@@ -32986,6 +33113,7 @@ var EditorToolbar = ({
32986
33113
  const canMergeCells = hasTableContext && editor.can().mergeCells();
32987
33114
  const canSplitCell = hasTableContext && editor.can().splitCell();
32988
33115
  const currentCellVerticalAlign = normalizeStyleValue(editor.getAttributes("tableCell").verticalAlign || editor.getAttributes("tableHeader").verticalAlign) || "";
33116
+ const currentCellTextDirection = normalizeStyleValue(editor.getAttributes("tableCell").textDirection || editor.getAttributes("tableHeader").textDirection) || "horizontal";
32989
33117
  const currentFontFamily = normalizeStyleValue(textStyleAttrs.fontFamily);
32990
33118
  const currentFontSize = normalizeStyleValue(textStyleAttrs.fontSize);
32991
33119
  const currentTextColor = normalizeStyleValue(textStyleAttrs.color) || "inherit";
@@ -33047,6 +33175,34 @@ var EditorToolbar = ({
33047
33175
  children: /* @__PURE__ */ jsx91(ListIcon, { className: "w-4 h-4" })
33048
33176
  }
33049
33177
  ),
33178
+ /* @__PURE__ */ jsxs75(
33179
+ DropdownMenu,
33180
+ {
33181
+ trigger: /* @__PURE__ */ jsxs75(ToolbarButton, { onClick: () => {
33182
+ }, active: editor.isActive("formCheckbox"), title: t("slashCommand.formCheckbox"), children: [
33183
+ /* @__PURE__ */ jsx91(SquareCheckBig, { className: "w-4 h-4" }),
33184
+ /* @__PURE__ */ jsx91(ChevronDown8, { className: "w-3 h-3" })
33185
+ ] }),
33186
+ children: [
33187
+ /* @__PURE__ */ jsx91(
33188
+ DropdownMenuItem,
33189
+ {
33190
+ icon: SquareCheckBig,
33191
+ label: t("slashCommand.formCheckbox"),
33192
+ onClick: () => editor.chain().focus().setFormCheckbox().run()
33193
+ }
33194
+ ),
33195
+ /* @__PURE__ */ jsx91(
33196
+ DropdownMenuItem,
33197
+ {
33198
+ icon: CircleCheckBig2,
33199
+ label: t("slashCommand.roundCheckbox"),
33200
+ onClick: () => editor.chain().focus().setFormCheckbox({ variant: "circle" }).run()
33201
+ }
33202
+ )
33203
+ ]
33204
+ }
33205
+ ),
33050
33206
  /* @__PURE__ */ jsx91(
33051
33207
  DropdownMenu,
33052
33208
  {
@@ -33057,7 +33213,7 @@ var EditorToolbar = ({
33057
33213
  {
33058
33214
  initialUrl: String(editor.getAttributes("link").href ?? ""),
33059
33215
  onSubmit: (url) => {
33060
- editor.chain().focus().extendMarkRange("link").setLink({ href: url }).run();
33216
+ applyEditorLink(editor, url);
33061
33217
  setShowLinkInput(false);
33062
33218
  },
33063
33219
  onCancel: () => setShowLinkInput(false)
@@ -33294,7 +33450,7 @@ var EditorToolbar = ({
33294
33450
  {
33295
33451
  initialUrl: String(editor.getAttributes("link").href ?? ""),
33296
33452
  onSubmit: (url) => {
33297
- editor.chain().focus().extendMarkRange("link").setLink({ href: url }).run();
33453
+ applyEditorLink(editor, url);
33298
33454
  setShowLinkInput(false);
33299
33455
  },
33300
33456
  onCancel: () => setShowLinkInput(false)
@@ -33472,6 +33628,36 @@ var EditorToolbar = ({
33472
33628
  ] })
33473
33629
  ]
33474
33630
  }
33631
+ ),
33632
+ hasTableContext && /* @__PURE__ */ jsxs75(
33633
+ DropdownMenu,
33634
+ {
33635
+ trigger: /* @__PURE__ */ jsxs75(ToolbarButton, { onClick: () => {
33636
+ }, title: t("tableMenu.textDirection"), children: [
33637
+ currentCellTextDirection === "vertical" ? /* @__PURE__ */ jsx91(ArrowDown, { className: "w-4 h-4" }) : /* @__PURE__ */ jsx91(ArrowRight, { className: "w-4 h-4" }),
33638
+ /* @__PURE__ */ jsx91(ChevronDown8, { className: "w-3 h-3" })
33639
+ ] }),
33640
+ children: [
33641
+ /* @__PURE__ */ jsx91(
33642
+ DropdownMenuItem,
33643
+ {
33644
+ icon: ArrowRight,
33645
+ label: t("tableMenu.horizontalText"),
33646
+ onClick: () => applyTableCellAttribute(editor, "textDirection", null),
33647
+ active: currentCellTextDirection === "horizontal"
33648
+ }
33649
+ ),
33650
+ /* @__PURE__ */ jsx91(
33651
+ DropdownMenuItem,
33652
+ {
33653
+ icon: ArrowDown,
33654
+ label: t("tableMenu.verticalText"),
33655
+ onClick: () => applyTableCellAttribute(editor, "textDirection", "vertical"),
33656
+ active: currentCellTextDirection === "vertical"
33657
+ }
33658
+ )
33659
+ ]
33660
+ }
33475
33661
  )
33476
33662
  ] }),
33477
33663
  /* @__PURE__ */ jsx91(ToolbarDivider, {}),
@@ -33517,6 +33703,34 @@ var EditorToolbar = ({
33517
33703
  ]
33518
33704
  }
33519
33705
  ),
33706
+ /* @__PURE__ */ jsxs75(
33707
+ DropdownMenu,
33708
+ {
33709
+ trigger: /* @__PURE__ */ jsxs75(ToolbarButton, { onClick: () => {
33710
+ }, active: editor.isActive("formCheckbox"), title: t("slashCommand.formCheckbox"), children: [
33711
+ /* @__PURE__ */ jsx91(SquareCheckBig, { className: "w-4 h-4" }),
33712
+ /* @__PURE__ */ jsx91(ChevronDown8, { className: "w-3 h-3" })
33713
+ ] }),
33714
+ children: [
33715
+ /* @__PURE__ */ jsx91(
33716
+ DropdownMenuItem,
33717
+ {
33718
+ icon: SquareCheckBig,
33719
+ label: t("slashCommand.formCheckbox"),
33720
+ onClick: () => editor.chain().focus().setFormCheckbox().run()
33721
+ }
33722
+ ),
33723
+ /* @__PURE__ */ jsx91(
33724
+ DropdownMenuItem,
33725
+ {
33726
+ icon: CircleCheckBig2,
33727
+ label: t("slashCommand.roundCheckbox"),
33728
+ onClick: () => editor.chain().focus().setFormCheckbox({ variant: "circle" }).run()
33729
+ }
33730
+ )
33731
+ ]
33732
+ }
33733
+ ),
33520
33734
  isMediumFull && /* @__PURE__ */ jsx91(ToolbarButton, { onClick: () => editor.chain().focus().toggleBlockquote().run(), active: editor.isActive("blockquote"), title: t("toolbar.quote"), children: /* @__PURE__ */ jsx91(QuoteIcon, { className: "w-4 h-4" }) }),
33521
33735
  isFull && /* @__PURE__ */ jsxs75(
33522
33736
  DropdownMenu,
@@ -33912,11 +34126,13 @@ import {
33912
34126
  Sigma as Sigma2,
33913
34127
  AlignStartVertical as AlignStartVertical2,
33914
34128
  AlignCenterVertical as AlignCenterVertical2,
33915
- AlignEndVertical as AlignEndVertical2
34129
+ AlignEndVertical as AlignEndVertical2,
34130
+ ArrowDown as ArrowDown2,
34131
+ ArrowRight as ArrowRight2
33916
34132
  } from "lucide-react";
33917
34133
 
33918
34134
  // src/components/UEditor/table-formula-commands.ts
33919
- import { TextSelection as TextSelection3 } from "@tiptap/pm/state";
34135
+ import { TextSelection as TextSelection4 } from "@tiptap/pm/state";
33920
34136
  import { selectedRect as selectedRect2, setCellAttr as setCellAttr2, TableMap as TableMap3 } from "@tiptap/pm/tables";
33921
34137
 
33922
34138
  // src/components/UEditor/table-formula.ts
@@ -34532,7 +34748,7 @@ function restoreSelectionAtTableCell(editor, anchor) {
34532
34748
  if (!cellNode || cellNode.type.name !== "tableCell" && cellNode.type.name !== "tableHeader") return false;
34533
34749
  const selectionPos = Math.min(cellPos + 2, editor.state.doc.content.size);
34534
34750
  editor.view.dispatch(
34535
- editor.state.tr.setSelection(TextSelection3.near(editor.state.doc.resolve(selectionPos))).setMeta("addToHistory", false)
34751
+ editor.state.tr.setSelection(TextSelection4.near(editor.state.doc.resolve(selectionPos))).setMeta("addToHistory", false)
34536
34752
  );
34537
34753
  return true;
34538
34754
  }
@@ -34609,7 +34825,7 @@ function removeSelectedTableCellFormula(editor, clearContent) {
34609
34825
  );
34610
34826
  let transaction = editor.state.tr.replaceWith(selectedCell.cellPos, selectedCell.cellPos + selectedCell.node.nodeSize, nextCell2).setMeta(UEDITOR_TABLE_FORMULA_RECALCULATE_META, true);
34611
34827
  const selectionPos = Math.min(selectedCell.cellPos + 2, transaction.doc.content.size);
34612
- transaction = transaction.setSelection(TextSelection3.near(transaction.doc.resolve(selectionPos)));
34828
+ transaction = transaction.setSelection(TextSelection4.near(transaction.doc.resolve(selectionPos)));
34613
34829
  editor.view.dispatch(transaction);
34614
34830
  recalculateActiveTableFormulas(editor);
34615
34831
  restoreSelectionAtTableCell(editor, selectedCell);
@@ -34988,6 +35204,7 @@ var BubbleMenuContent = ({
34988
35204
  const currentCellBorderStyle = editor.getAttributes("tableCell").borderStyle || editor.getAttributes("tableHeader").borderStyle || "solid";
34989
35205
  const currentCellBorderWidth = editor.getAttributes("tableCell").borderWidth || editor.getAttributes("tableHeader").borderWidth || "1px";
34990
35206
  const currentCellVerticalAlign = normalizeStyleValue(editor.getAttributes("tableCell").verticalAlign || editor.getAttributes("tableHeader").verticalAlign) || "";
35207
+ const currentCellTextDirection = normalizeStyleValue(editor.getAttributes("tableCell").textDirection || editor.getAttributes("tableHeader").textDirection) || "horizontal";
34991
35208
  const isInTable2 = isSelectionInTable(editor.state);
34992
35209
  const canMergeCells = isInTable2 && editor.can().mergeCells();
34993
35210
  const canSplitCell = isInTable2 && editor.can().splitCell();
@@ -35095,7 +35312,7 @@ var BubbleMenuContent = ({
35095
35312
  {
35096
35313
  initialUrl: editor.getAttributes("link").href || "",
35097
35314
  onSubmit: (url) => {
35098
- editor.chain().focus().extendMarkRange("link").setLink({ href: url }).run();
35315
+ applyEditorLink(editor, url);
35099
35316
  setShowLinkInput(false);
35100
35317
  requestAnimationFrame(() => editor.commands.focus());
35101
35318
  },
@@ -35631,6 +35848,49 @@ var BubbleMenuContent = ({
35631
35848
  )
35632
35849
  ]
35633
35850
  }
35851
+ ),
35852
+ /* @__PURE__ */ jsxs76(
35853
+ DropdownMenu,
35854
+ {
35855
+ onOpenChange: (open) => {
35856
+ onKeepOpenChange?.(open);
35857
+ },
35858
+ trigger: /* @__PURE__ */ jsxs76(
35859
+ ToolbarButton,
35860
+ {
35861
+ onMouseDown: () => {
35862
+ onKeepOpenChange?.(true);
35863
+ },
35864
+ onClick: () => {
35865
+ },
35866
+ title: t("tableMenu.textDirection"),
35867
+ children: [
35868
+ currentCellTextDirection === "vertical" ? /* @__PURE__ */ jsx92(ArrowDown2, { className: "w-4 h-4" }) : /* @__PURE__ */ jsx92(ArrowRight2, { className: "w-4 h-4" }),
35869
+ /* @__PURE__ */ jsx92(ChevronDown9, { className: "w-3 h-3" })
35870
+ ]
35871
+ }
35872
+ ),
35873
+ children: [
35874
+ /* @__PURE__ */ jsx92(
35875
+ DropdownMenuItem,
35876
+ {
35877
+ icon: ArrowRight2,
35878
+ label: t("tableMenu.horizontalText"),
35879
+ onClick: () => applyTableCellAttribute2(editor, "textDirection", null, { focus: false }),
35880
+ active: currentCellTextDirection === "horizontal"
35881
+ }
35882
+ ),
35883
+ /* @__PURE__ */ jsx92(
35884
+ DropdownMenuItem,
35885
+ {
35886
+ icon: ArrowDown2,
35887
+ label: t("tableMenu.verticalText"),
35888
+ onClick: () => applyTableCellAttribute2(editor, "textDirection", "vertical", { focus: false }),
35889
+ active: currentCellTextDirection === "vertical"
35890
+ }
35891
+ )
35892
+ ]
35893
+ }
35634
35894
  )
35635
35895
  ] }),
35636
35896
  /* @__PURE__ */ jsx92(
@@ -38952,7 +39212,7 @@ var Selection = class {
38952
39212
  found.
38953
39213
  */
38954
39214
  static findFrom($pos, dir, textOnly = false) {
38955
- let inner = $pos.parent.inlineContent ? new TextSelection4($pos) : findSelectionIn($pos.node(0), $pos.parent, $pos.pos, $pos.index(), dir, textOnly);
39215
+ let inner = $pos.parent.inlineContent ? new TextSelection5($pos) : findSelectionIn($pos.node(0), $pos.parent, $pos.pos, $pos.index(), dir, textOnly);
38956
39216
  if (inner)
38957
39217
  return inner;
38958
39218
  for (let depth = $pos.depth - 1; depth >= 0; depth--) {
@@ -39021,7 +39281,7 @@ var Selection = class {
39021
39281
  returns the bookmark for that.
39022
39282
  */
39023
39283
  getBookmark() {
39024
- return TextSelection4.between(this.$anchor, this.$head).getBookmark();
39284
+ return TextSelection5.between(this.$anchor, this.$head).getBookmark();
39025
39285
  }
39026
39286
  };
39027
39287
  Selection.prototype.visible = true;
@@ -39041,7 +39301,7 @@ function checkTextSelection($pos) {
39041
39301
  console["warn"]("TextSelection endpoint not pointing into a node with inline content (" + $pos.parent.type.name + ")");
39042
39302
  }
39043
39303
  }
39044
- var TextSelection4 = class _TextSelection extends Selection {
39304
+ var TextSelection5 = class _TextSelection extends Selection {
39045
39305
  /**
39046
39306
  Construct a text selection between the given points.
39047
39307
  */
@@ -39127,7 +39387,7 @@ var TextSelection4 = class _TextSelection extends Selection {
39127
39387
  return new _TextSelection($anchor, $head);
39128
39388
  }
39129
39389
  };
39130
- Selection.jsonID("text", TextSelection4);
39390
+ Selection.jsonID("text", TextSelection5);
39131
39391
  var TextBookmark = class _TextBookmark {
39132
39392
  constructor(anchor, head) {
39133
39393
  this.anchor = anchor;
@@ -39137,7 +39397,7 @@ var TextBookmark = class _TextBookmark {
39137
39397
  return new _TextBookmark(mapping.map(this.anchor), mapping.map(this.head));
39138
39398
  }
39139
39399
  resolve(doc) {
39140
- return TextSelection4.between(doc.resolve(this.anchor), doc.resolve(this.head));
39400
+ return TextSelection5.between(doc.resolve(this.anchor), doc.resolve(this.head));
39141
39401
  }
39142
39402
  };
39143
39403
  var NodeSelection2 = class _NodeSelection extends Selection {
@@ -39256,7 +39516,7 @@ var AllBookmark = {
39256
39516
  };
39257
39517
  function findSelectionIn(doc, node, pos, index, dir, text = false) {
39258
39518
  if (node.inlineContent)
39259
- return TextSelection4.create(doc, pos);
39519
+ return TextSelection5.create(doc, pos);
39260
39520
  for (let i = index - (dir > 0 ? 0 : 1); dir > 0 ? i < node.childCount : i >= 0; i += dir) {
39261
39521
  let child = node.child(i);
39262
39522
  if (!child.isAtom) {
@@ -39848,7 +40108,7 @@ var CellSelection = class CellSelection2 extends Selection {
39848
40108
  else if (tableChanged && this.isColSelection()) return CellSelection2.colSelection($anchorCell, $headCell);
39849
40109
  else return new CellSelection2($anchorCell, $headCell);
39850
40110
  }
39851
- return TextSelection4.between($anchorCell, $headCell);
40111
+ return TextSelection5.between($anchorCell, $headCell);
39852
40112
  }
39853
40113
  content() {
39854
40114
  const table = this.$anchorCell.node(-1);
@@ -40463,7 +40723,7 @@ function shiftArrow(axis, dir) {
40463
40723
  };
40464
40724
  }
40465
40725
  function atEndOfCell(view, axis, dir) {
40466
- if (!(view.state.selection instanceof TextSelection4)) return null;
40726
+ if (!(view.state.selection instanceof TextSelection5)) return null;
40467
40727
  const { $head } = view.state.selection;
40468
40728
  for (let d = $head.depth - 1; d >= 0; d--) {
40469
40729
  const parent = $head.node(d);
@@ -40483,9 +40743,9 @@ import {
40483
40743
  AlignCenter as AlignCenter3,
40484
40744
  AlignLeft as AlignLeft3,
40485
40745
  AlignRight as AlignRight3,
40486
- ArrowDown as ArrowDown2,
40746
+ ArrowDown as ArrowDown3,
40487
40747
  ArrowLeft as ArrowLeft2,
40488
- ArrowRight as ArrowRight2,
40748
+ ArrowRight as ArrowRight3,
40489
40749
  ArrowUp as ArrowUp2,
40490
40750
  Copy as Copy3,
40491
40751
  Table as TableIcon2,
@@ -41552,7 +41812,7 @@ function TableControls({ editor, containerRef }) {
41552
41812
  },
41553
41813
  {
41554
41814
  label: t("tableMenu.addColumnAfter"),
41555
- icon: ArrowRight2,
41815
+ icon: ArrowRight3,
41556
41816
  onClick: () => runAtActiveCell((chain) => chain.addColumnAfter())
41557
41817
  },
41558
41818
  {
@@ -41562,7 +41822,7 @@ function TableControls({ editor, containerRef }) {
41562
41822
  },
41563
41823
  {
41564
41824
  label: t("tableMenu.addRowAfter"),
41565
- icon: ArrowDown2,
41825
+ icon: ArrowDown3,
41566
41826
  onClick: () => runAtActiveCell((chain) => chain.addRowAfter())
41567
41827
  },
41568
41828
  {
@@ -41603,7 +41863,7 @@ function TableControls({ editor, containerRef }) {
41603
41863
  },
41604
41864
  {
41605
41865
  label: t("tableMenu.addRowAfter"),
41606
- icon: ArrowDown2,
41866
+ icon: ArrowDown3,
41607
41867
  onClick: () => runAtCellPos(rowHandle.cellPos, (chain) => chain.addRowAfter())
41608
41868
  },
41609
41869
  {
@@ -41631,7 +41891,7 @@ function TableControls({ editor, containerRef }) {
41631
41891
  },
41632
41892
  {
41633
41893
  label: t("tableMenu.addColumnAfter"),
41634
- icon: ArrowRight2,
41894
+ icon: ArrowRight3,
41635
41895
  onClick: () => runAtCellPos(columnHandle.cellPos, (chain) => chain.addColumnAfter())
41636
41896
  },
41637
41897
  {
@@ -42365,7 +42625,7 @@ import { useEffect as useEffect39, useRef as useRef37 } from "react";
42365
42625
  import { TableMap as TableMap6 } from "@tiptap/pm/tables";
42366
42626
 
42367
42627
  // src/components/UEditor/table-formula-range-picker.ts
42368
- import { TextSelection as TextSelection5 } from "@tiptap/pm/state";
42628
+ import { TextSelection as TextSelection6 } from "@tiptap/pm/state";
42369
42629
  import { TableMap as TableMap5 } from "@tiptap/pm/tables";
42370
42630
  function getCellText2(cellNode) {
42371
42631
  return cellNode.textBetween(0, cellNode.content.size, "\n").trim();
@@ -42443,7 +42703,7 @@ function cancelFormulaEditing(view) {
42443
42703
  if (!context) return false;
42444
42704
  let tr = view.state.tr.delete(context.cellContentStart, context.cellContentEnd);
42445
42705
  const selectionPos = Math.min(context.cellContentStart, tr.doc.content.size);
42446
- tr = tr.setSelection(TextSelection5.near(tr.doc.resolve(selectionPos)));
42706
+ tr = tr.setSelection(TextSelection6.near(tr.doc.resolve(selectionPos)));
42447
42707
  view.dispatch(tr);
42448
42708
  view.focus();
42449
42709
  return true;
@@ -42520,7 +42780,7 @@ function replacePickedLabel(view, pickState, nextLabel, currentCell) {
42520
42780
  }
42521
42781
  let tr = view.state.tr.insertText(nextLabel, pickState.insertedFrom, pickState.insertedTo);
42522
42782
  const nextTo = pickState.insertedFrom + nextLabel.length;
42523
- tr = tr.setSelection(TextSelection5.create(tr.doc, nextTo));
42783
+ tr = tr.setSelection(TextSelection6.create(tr.doc, nextTo));
42524
42784
  view.dispatch(tr);
42525
42785
  return {
42526
42786
  ...pickState,
@@ -42557,7 +42817,7 @@ function beginFormulaRangePick(view, event) {
42557
42817
  const insertedText = `${prefix}${picked.label}`;
42558
42818
  const insertedFrom = from + prefix.length;
42559
42819
  let tr = view.state.tr.insertText(insertedText, from, to);
42560
- tr = tr.setSelection(TextSelection5.create(tr.doc, from + insertedText.length));
42820
+ tr = tr.setSelection(TextSelection6.create(tr.doc, from + insertedText.length));
42561
42821
  view.dispatch(tr);
42562
42822
  view.focus();
42563
42823
  event.preventDefault();
@@ -42870,6 +43130,7 @@ import {
42870
43130
  Undo as UndoIcon2,
42871
43131
  Square,
42872
43132
  CircleDot as CircleDot2,
43133
+ CircleCheckBig as CircleCheckBig3,
42873
43134
  Upload as Upload4
42874
43135
  } from "lucide-react";
42875
43136
 
@@ -43524,7 +43785,7 @@ var MenuBar = ({
43524
43785
  closeInsertMenu();
43525
43786
  };
43526
43787
  const handleLinkSubmit = (url) => {
43527
- editor.chain().focus().setLink({ href: url }).run();
43788
+ applyEditorLink(editor, url);
43528
43789
  closeInsertMenu();
43529
43790
  };
43530
43791
  const insertMenuItems = [
@@ -43591,6 +43852,12 @@ var MenuBar = ({
43591
43852
  icon: Square,
43592
43853
  onClick: () => editor.chain().focus().setFormCheckbox().run()
43593
43854
  },
43855
+ {
43856
+ type: "action",
43857
+ label: t("slashCommand.roundCheckbox") || "Round Checkbox",
43858
+ icon: CircleCheckBig3,
43859
+ onClick: () => editor.chain().focus().setFormCheckbox({ variant: "circle" }).run()
43860
+ },
43594
43861
  {
43595
43862
  type: "action",
43596
43863
  label: t("menubar.formRadio") || "Form Radio Button",