@underverse-ui/underverse 1.0.191 → 1.0.193

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
@@ -910,6 +910,19 @@ var en_default = {
910
910
  borderStyle: "Border Style",
911
911
  borderWidth: "Border Width",
912
912
  borderColor: "Border Color",
913
+ borderPosition: "Border placement",
914
+ borderMode: "Border mode",
915
+ borderDraw: "Draw borders",
916
+ borderErase: "Hide borders",
917
+ borderAll: "All borders",
918
+ borderOuter: "Outer borders",
919
+ borderInner: "Inner borders",
920
+ borderHorizontal: "Inner horizontal borders",
921
+ borderVertical: "Inner vertical borders",
922
+ borderTop: "Top border",
923
+ borderRight: "Right border",
924
+ borderBottom: "Bottom border",
925
+ borderLeft: "Left border",
913
926
  clearBorder: "Clear Border",
914
927
  formula: "Formula",
915
928
  formulaBar: "Formula bar",
@@ -1343,6 +1356,19 @@ var vi_default = {
1343
1356
  borderStyle: "Ki\u1EC3u vi\u1EC1n",
1344
1357
  borderWidth: "\u0110\u1ED9 d\xE0y vi\u1EC1n",
1345
1358
  borderColor: "M\xE0u vi\u1EC1n",
1359
+ borderPosition: "V\u1ECB tr\xED vi\u1EC1n",
1360
+ borderMode: "Ch\u1EBF \u0111\u1ED9 vi\u1EC1n",
1361
+ borderDraw: "V\u1EBD vi\u1EC1n",
1362
+ borderErase: "\u1EA8n c\u1EA1nh",
1363
+ borderAll: "T\u1EA5t c\u1EA3 vi\u1EC1n",
1364
+ borderOuter: "Vi\u1EC1n ngo\xE0i",
1365
+ borderInner: "Vi\u1EC1n trong",
1366
+ borderHorizontal: "Vi\u1EC1n ngang b\xEAn trong",
1367
+ borderVertical: "Vi\u1EC1n d\u1ECDc b\xEAn trong",
1368
+ borderTop: "Vi\u1EC1n tr\xEAn",
1369
+ borderRight: "Vi\u1EC1n ph\u1EA3i",
1370
+ borderBottom: "Vi\u1EC1n d\u01B0\u1EDBi",
1371
+ borderLeft: "Vi\u1EC1n tr\xE1i",
1346
1372
  clearBorder: "X\xF3a vi\u1EC1n",
1347
1373
  formula: "C\xF4ng th\u1EE9c",
1348
1374
  formulaBar: "Thanh c\xF4ng th\u1EE9c",
@@ -1776,6 +1802,19 @@ var ko_default = {
1776
1802
  borderStyle: "\uD14C\uB450\uB9AC \uC2A4\uD0C0\uC77C",
1777
1803
  borderWidth: "\uD14C\uB450\uB9AC \uB450\uAED8",
1778
1804
  borderColor: "\uD14C\uB450\uB9AC \uC0C9\uC0C1",
1805
+ borderPosition: "\uD14C\uB450\uB9AC \uC704\uCE58",
1806
+ borderMode: "\uD14C\uB450\uB9AC \uBAA8\uB4DC",
1807
+ borderDraw: "\uD14C\uB450\uB9AC \uADF8\uB9AC\uAE30",
1808
+ borderErase: "\uD14C\uB450\uB9AC \uC228\uAE30\uAE30",
1809
+ borderAll: "\uBAA8\uB4E0 \uD14C\uB450\uB9AC",
1810
+ borderOuter: "\uBC14\uAE65\uCABD \uD14C\uB450\uB9AC",
1811
+ borderInner: "\uC548\uCABD \uD14C\uB450\uB9AC",
1812
+ borderHorizontal: "\uC548\uCABD \uAC00\uB85C \uD14C\uB450\uB9AC",
1813
+ borderVertical: "\uC548\uCABD \uC138\uB85C \uD14C\uB450\uB9AC",
1814
+ borderTop: "\uC704\uCABD \uD14C\uB450\uB9AC",
1815
+ borderRight: "\uC624\uB978\uCABD \uD14C\uB450\uB9AC",
1816
+ borderBottom: "\uC544\uB798\uCABD \uD14C\uB450\uB9AC",
1817
+ borderLeft: "\uC67C\uCABD \uD14C\uB450\uB9AC",
1779
1818
  clearBorder: "\uD14C\uB450\uB9AC \uC9C0\uC6B0\uAE30",
1780
1819
  formula: "\uC218\uC2DD",
1781
1820
  formulaBar: "\uC218\uC2DD \uC785\uB825\uC904",
@@ -2209,6 +2248,19 @@ var ja_default = {
2209
2248
  borderStyle: "\u67A0\u7DDA\u30B9\u30BF\u30A4\u30EB",
2210
2249
  borderWidth: "\u67A0\u7DDA\u306E\u592A\u3055",
2211
2250
  borderColor: "\u67A0\u7DDA\u306E\u8272",
2251
+ borderPosition: "\u67A0\u7DDA\u306E\u4F4D\u7F6E",
2252
+ borderMode: "\u67A0\u7DDA\u30E2\u30FC\u30C9",
2253
+ borderDraw: "\u67A0\u7DDA\u3092\u5F15\u304F",
2254
+ borderErase: "\u67A0\u7DDA\u3092\u975E\u8868\u793A",
2255
+ borderAll: "\u3059\u3079\u3066\u306E\u67A0\u7DDA",
2256
+ borderOuter: "\u5916\u67A0",
2257
+ borderInner: "\u5185\u5074\u306E\u67A0\u7DDA",
2258
+ borderHorizontal: "\u5185\u5074\u306E\u6A2A\u7F6B\u7DDA",
2259
+ borderVertical: "\u5185\u5074\u306E\u7E26\u7F6B\u7DDA",
2260
+ borderTop: "\u4E0A\u7F6B\u7DDA",
2261
+ borderRight: "\u53F3\u7F6B\u7DDA",
2262
+ borderBottom: "\u4E0B\u7F6B\u7DDA",
2263
+ borderLeft: "\u5DE6\u7F6B\u7DDA",
2212
2264
  clearBorder: "\u67A0\u7DDA\u3092\u30AF\u30EA\u30A2",
2213
2265
  formula: "\u6570\u5F0F",
2214
2266
  formulaBar: "\u6570\u5F0F\u30D0\u30FC",
@@ -3365,7 +3417,7 @@ var Textarea = forwardRef3(
3365
3417
  required,
3366
3418
  value,
3367
3419
  maxLength,
3368
- borderMode = "2xl",
3420
+ borderMode,
3369
3421
  ...props
3370
3422
  }, ref) => {
3371
3423
  const [isFocused, setIsFocused] = useState4(false);
@@ -6774,9 +6826,12 @@ var Modal = ({
6774
6826
  noPadding = false,
6775
6827
  fullWidth = false,
6776
6828
  width,
6777
- height
6829
+ height,
6830
+ borderMode
6778
6831
  }) => {
6779
6832
  const gi18n = useGlobalI18n();
6833
+ const globalConfig = useUnderverseUIConfig();
6834
+ const resolvedBorderMode = borderMode ?? globalConfig.borderMode;
6780
6835
  const [isMounted, setIsMounted] = React22.useState(false);
6781
6836
  const [isVisible, setIsVisible] = React22.useState(false);
6782
6837
  const [isAnimating, setIsAnimating] = React22.useState(true);
@@ -6882,7 +6937,8 @@ var Modal = ({
6882
6937
  {
6883
6938
  ref: modalContentRef,
6884
6939
  className: cn(
6885
- "relative w-full rounded-2xl md:rounded-3xl border border-border/40 bg-card text-card-foreground shadow-xl",
6940
+ "relative w-full border border-border/40 bg-card text-card-foreground shadow-xl",
6941
+ resolvedBorderMode ? getBorderRadiusClass(resolvedBorderMode) : "rounded-2xl md:rounded-3xl",
6886
6942
  "transition-all duration-200 ease-out",
6887
6943
  maxWidthClass,
6888
6944
  fullWidth && "mx-0",
@@ -7390,7 +7446,8 @@ var Popover = ({
7390
7446
  open,
7391
7447
  onOpenChange,
7392
7448
  matchTriggerWidth = false,
7393
- contentWidth
7449
+ contentWidth,
7450
+ borderMode
7394
7451
  }) => {
7395
7452
  const isControlled = open !== void 0;
7396
7453
  const [internalOpen, setInternalOpen] = React24.useState(false);
@@ -7399,6 +7456,8 @@ var Popover = ({
7399
7456
  const panelRef = React24.useRef(null);
7400
7457
  const lastAppliedRef = React24.useRef(null);
7401
7458
  useShadCNAnimations();
7459
+ const globalConfig = useUnderverseUIConfig();
7460
+ const resolvedBorderMode = borderMode ?? globalConfig.popover?.borderMode ?? globalConfig.borderMode;
7402
7461
  const isOpen = isControlled ? open : internalOpen;
7403
7462
  const setIsOpen = React24.useCallback(
7404
7463
  (next) => {
@@ -7579,7 +7638,8 @@ var Popover = ({
7579
7638
  {
7580
7639
  ...contentProps,
7581
7640
  className: cn(
7582
- "rounded-2xl md:rounded-3xl border bg-popover text-popover-foreground shadow-md",
7641
+ resolvedBorderMode ? getBorderRadiusClass(resolvedBorderMode) : "rounded-2xl md:rounded-3xl",
7642
+ "border bg-popover text-popover-foreground shadow-md",
7583
7643
  "backdrop-blur-sm bg-popover/95 border-border/60 p-4",
7584
7644
  contentProps?.className,
7585
7645
  contentClassName
@@ -7918,7 +7978,9 @@ var SlideOver = (props) => {
7918
7978
  return /* @__PURE__ */ jsx27(Sheet, { ...props, side: "right", variant: "overlay", size: "lg" });
7919
7979
  };
7920
7980
  var BottomSheet = ({ snapPoints = ["25%", "50%", "90%"], defaultSnap = 1, ...props }) => {
7921
- return /* @__PURE__ */ jsx27(Sheet, { ...props, side: "bottom", variant: "overlay", className: cn("rounded-t-3xl", props.className) });
7981
+ const globalConfig = useUnderverseUIConfig();
7982
+ const isSquare = globalConfig.borderMode === "daewoo" || globalConfig.borderMode === "none";
7983
+ return /* @__PURE__ */ jsx27(Sheet, { ...props, side: "bottom", variant: "overlay", className: cn(isSquare ? "" : "rounded-t-3xl", props.className) });
7922
7984
  };
7923
7985
  var SidebarSheet = ({ navigation, children, ...props }) => {
7924
7986
  return /* @__PURE__ */ jsxs17(Sheet, { ...props, side: "left", variant: "push", size: "md", children: [
@@ -8590,7 +8652,8 @@ var DropdownMenu = ({
8590
8652
  disabled = false,
8591
8653
  isOpen,
8592
8654
  onOpenChange,
8593
- items
8655
+ items,
8656
+ borderMode
8594
8657
  }) => {
8595
8658
  const [internalOpen, setInternalOpen] = useState18(false);
8596
8659
  const open = isOpen !== void 0 ? isOpen : internalOpen;
@@ -8626,6 +8689,8 @@ var DropdownMenu = ({
8626
8689
  item.scrollIntoView({ block: "nearest" });
8627
8690
  }, [getEnabledMenuItems, setActiveIndex]);
8628
8691
  useShadCNAnimations();
8692
+ const globalConfig = useUnderverseUIConfig();
8693
+ const resolvedBorderMode = borderMode ?? globalConfig.dropdownMenu?.borderMode ?? globalConfig.borderMode;
8629
8694
  React29.useEffect(() => {
8630
8695
  if (!open) return;
8631
8696
  const handleKeyNav = (e) => {
@@ -8693,7 +8758,8 @@ var DropdownMenu = ({
8693
8758
  animationDelay: open ? `${Math.min(index * 20, 200)}ms` : "0ms"
8694
8759
  },
8695
8760
  className: cn(
8696
- "dropdown-item flex w-full items-center gap-2 px-2.5 py-1.5 text-sm rounded-lg",
8761
+ "dropdown-item flex w-full items-center gap-2 px-2.5 py-1.5 text-sm",
8762
+ resolvedBorderMode ? getBorderRadiusClass(resolvedBorderMode) : "rounded-lg",
8697
8763
  "outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
8698
8764
  "hover:bg-accent hover:text-accent-foreground",
8699
8765
  "focus:bg-accent focus:text-accent-foreground",
@@ -8749,6 +8815,7 @@ var DropdownMenu = ({
8749
8815
  trigger: enhancedTrigger,
8750
8816
  placement,
8751
8817
  disabled,
8818
+ borderMode: resolvedBorderMode,
8752
8819
  contentClassName: cn("p-1", contentClassName),
8753
8820
  children: menuBody
8754
8821
  }
@@ -8765,10 +8832,13 @@ var DropdownMenuItem = ({
8765
8832
  active,
8766
8833
  shortcut,
8767
8834
  className,
8768
- closeOnSelect
8835
+ closeOnSelect,
8836
+ borderMode
8769
8837
  }) => {
8770
8838
  const menu = React29.useContext(DropdownMenuContext);
8771
8839
  const shouldCloseOnSelect = closeOnSelect ?? menu?.closeOnSelect ?? false;
8840
+ const globalConfig = useUnderverseUIConfig();
8841
+ const resolvedBorderMode = borderMode ?? globalConfig.dropdownMenu?.borderMode ?? globalConfig.borderMode;
8772
8842
  return /* @__PURE__ */ jsxs22(
8773
8843
  "button",
8774
8844
  {
@@ -8783,7 +8853,8 @@ var DropdownMenuItem = ({
8783
8853
  "data-dropdown-menu-item": "",
8784
8854
  tabIndex: -1,
8785
8855
  className: cn(
8786
- "flex w-full items-center gap-2 px-3 py-2 text-sm rounded-lg transition-colors group cursor-pointer",
8856
+ "flex w-full items-center gap-2 px-3 py-2 text-sm transition-colors group cursor-pointer",
8857
+ resolvedBorderMode ? getBorderRadiusClass(resolvedBorderMode) : "rounded-lg",
8787
8858
  "hover:bg-accent hover:text-accent-foreground",
8788
8859
  "focus:bg-accent focus:text-accent-foreground focus:outline-none",
8789
8860
  "disabled:opacity-50 disabled:cursor-not-allowed",
@@ -8805,56 +8876,67 @@ var DropdownMenuItem = ({
8805
8876
  );
8806
8877
  };
8807
8878
  var DropdownMenuSeparator = ({ className }) => /* @__PURE__ */ jsx32("div", { className: cn("h-px bg-border my-1", className) });
8808
- var DropdownMenuSub = ({ label, icon: Icon, disabled, children }) => /* @__PURE__ */ jsx32(
8809
- DropdownMenu,
8810
- {
8811
- trigger: /* @__PURE__ */ jsxs22(
8812
- "button",
8813
- {
8814
- type: "button",
8815
- disabled,
8816
- onMouseDown: (e) => e.preventDefault(),
8817
- className: cn(
8818
- "flex w-full items-center gap-2 px-3 py-2 text-sm rounded-lg transition-colors cursor-pointer",
8819
- "hover:bg-accent hover:text-accent-foreground",
8820
- "focus:bg-accent focus:text-accent-foreground focus:outline-none",
8821
- "disabled:opacity-50 disabled:cursor-not-allowed"
8822
- ),
8823
- children: [
8824
- Icon && /* @__PURE__ */ jsx32(Icon, { className: "w-4 h-4 shrink-0 opacity-60" }),
8825
- /* @__PURE__ */ jsx32("span", { className: "flex-1 text-left", children: label }),
8826
- /* @__PURE__ */ jsx32(ChevronRight2, { className: "w-3 h-3 opacity-50" })
8827
- ]
8828
- }
8829
- ),
8830
- placement: "right",
8831
- children
8832
- }
8833
- );
8834
- var SelectDropdown = ({ options, value, onChange, placeholder = "Select...", className }) => /* @__PURE__ */ jsx32(
8835
- DropdownMenu,
8836
- {
8837
- trigger: /* @__PURE__ */ jsxs22(
8838
- "button",
8839
- {
8840
- className: cn(
8841
- "inline-flex items-center justify-between gap-2 px-3 py-2 text-sm rounded-2xl border bg-background border-border/60",
8842
- "hover:bg-accent/50",
8843
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
8844
- className
8845
- ),
8846
- children: [
8847
- /* @__PURE__ */ jsx32("span", { className: "truncate max-w-64 text-foreground/90", children: value || placeholder }),
8848
- /* @__PURE__ */ jsx32("svg", { width: "16", height: "16", viewBox: "0 0 20 20", fill: "none", className: "opacity-70", children: /* @__PURE__ */ jsx32("path", { d: "M6 8l4 4 4-4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
8849
- ]
8850
- }
8851
- ),
8852
- items: options.map((option) => ({
8853
- label: option,
8854
- onClick: () => onChange(option)
8855
- }))
8856
- }
8857
- );
8879
+ var DropdownMenuSub = ({ label, icon: Icon, disabled, borderMode, children }) => {
8880
+ const globalConfig = useUnderverseUIConfig();
8881
+ const resolvedBorderMode = borderMode ?? globalConfig.dropdownMenu?.borderMode ?? globalConfig.borderMode;
8882
+ return /* @__PURE__ */ jsx32(
8883
+ DropdownMenu,
8884
+ {
8885
+ trigger: /* @__PURE__ */ jsxs22(
8886
+ "button",
8887
+ {
8888
+ type: "button",
8889
+ disabled,
8890
+ onMouseDown: (e) => e.preventDefault(),
8891
+ className: cn(
8892
+ "flex w-full items-center gap-2 px-3 py-2 text-sm transition-colors cursor-pointer",
8893
+ resolvedBorderMode ? getBorderRadiusClass(resolvedBorderMode) : "rounded-lg",
8894
+ "hover:bg-accent hover:text-accent-foreground",
8895
+ "focus:bg-accent focus:text-accent-foreground focus:outline-none",
8896
+ "disabled:opacity-50 disabled:cursor-not-allowed"
8897
+ ),
8898
+ children: [
8899
+ Icon && /* @__PURE__ */ jsx32(Icon, { className: "w-4 h-4 shrink-0 opacity-60" }),
8900
+ /* @__PURE__ */ jsx32("span", { className: "flex-1 text-left", children: label }),
8901
+ /* @__PURE__ */ jsx32(ChevronRight2, { className: "w-3 h-3 opacity-50" })
8902
+ ]
8903
+ }
8904
+ ),
8905
+ placement: "right",
8906
+ children
8907
+ }
8908
+ );
8909
+ };
8910
+ var SelectDropdown = ({ options, value, onChange, placeholder = "Select...", className, borderMode }) => {
8911
+ const globalConfig = useUnderverseUIConfig();
8912
+ const resolvedBorderMode = borderMode ?? globalConfig.dropdownMenu?.borderMode ?? globalConfig.borderMode;
8913
+ return /* @__PURE__ */ jsx32(
8914
+ DropdownMenu,
8915
+ {
8916
+ trigger: /* @__PURE__ */ jsxs22(
8917
+ "button",
8918
+ {
8919
+ className: cn(
8920
+ "inline-flex items-center justify-between gap-2 px-3 py-2 text-sm border bg-background border-border/60",
8921
+ resolvedBorderMode ? getBorderRadiusClass(resolvedBorderMode) : "rounded-2xl",
8922
+ "hover:bg-accent/50",
8923
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
8924
+ className
8925
+ ),
8926
+ children: [
8927
+ /* @__PURE__ */ jsx32("span", { className: "truncate max-w-64 text-foreground/90", children: value || placeholder }),
8928
+ /* @__PURE__ */ jsx32("svg", { width: "16", height: "16", viewBox: "0 0 20 20", fill: "none", className: "opacity-70", children: /* @__PURE__ */ jsx32("path", { d: "M6 8l4 4 4-4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
8929
+ ]
8930
+ }
8931
+ ),
8932
+ items: options.map((option) => ({
8933
+ label: option,
8934
+ onClick: () => onChange(option)
8935
+ })),
8936
+ borderMode: resolvedBorderMode
8937
+ }
8938
+ );
8939
+ };
8858
8940
  var DropdownMenu_default = DropdownMenu;
8859
8941
 
8860
8942
  // src/components/Pagination.tsx
@@ -8939,6 +9021,9 @@ var Combobox = ({
8939
9021
  maxInitialOptions,
8940
9022
  showSearchPromptWhenEmptyQuery = false
8941
9023
  }) => {
9024
+ const globalConfig = useUnderverseUIConfig();
9025
+ const resolvedBorderMode = borderMode ?? globalConfig.borderMode ?? "full";
9026
+ const radiusClass = getBorderRadiusClass(resolvedBorderMode);
8942
9027
  const tv = useSmartTranslations("ValidationInput");
8943
9028
  const gi18n = useGlobalI18n();
8944
9029
  const placeholder = placeholderProp ?? gi18n.selectPlaceholder ?? "Select\u2026";
@@ -9148,7 +9233,7 @@ var Combobox = ({
9148
9233
  {
9149
9234
  "data-combobox-dropdown": true,
9150
9235
  "data-state": open ? "open" : "closed",
9151
- className: "w-full rounded-2xl md:rounded-3xl overflow-hidden",
9236
+ className: cn("w-full overflow-hidden", getBorderRadiusClass(resolvedBorderMode)),
9152
9237
  children: [
9153
9238
  enableSearch && /* @__PURE__ */ jsx33("div", { className: cn("relative border-b border-border/30", size === "sm" ? "p-2" : size === "lg" ? "p-3" : "p-2.5"), children: /* @__PURE__ */ jsxs23("div", { className: "relative", children: [
9154
9239
  /* @__PURE__ */ jsx33(
@@ -9290,9 +9375,6 @@ var Combobox = ({
9290
9375
  filled: "border-0 bg-muted/50 hover:bg-muted/80"
9291
9376
  };
9292
9377
  const labelSize = size === "sm" ? "text-xs" : size === "lg" ? "text-base" : "text-sm";
9293
- const globalConfig = useUnderverseUIConfig();
9294
- const resolvedBorderMode = borderMode ?? globalConfig.borderMode ?? "full";
9295
- const radiusClass = getBorderRadiusClass(resolvedBorderMode);
9296
9378
  const verticalGap = size === "sm" ? "space-y-1.5" : "space-y-2";
9297
9379
  const triggerButtonBaseProps = {
9298
9380
  ref: triggerRef,
@@ -9423,12 +9505,13 @@ var Combobox = ({
9423
9505
  placement: "bottom-start",
9424
9506
  matchTriggerWidth: true,
9425
9507
  className: "z-9999",
9426
- contentClassName: "p-0 overflow-hidden rounded-2xl md:rounded-3xl",
9508
+ borderMode: resolvedBorderMode,
9509
+ contentClassName: "p-0 overflow-hidden",
9427
9510
  children: dropdownBody
9428
9511
  }
9429
9512
  ) : /* @__PURE__ */ jsxs23("div", { className: "relative", children: [
9430
9513
  triggerButtonInline,
9431
- open && /* @__PURE__ */ jsx33("div", { className: "absolute left-0 top-full mt-1 z-50 w-full", children: /* @__PURE__ */ jsx33("div", { className: "rounded-2xl md:rounded-3xl overflow-hidden border text-popover-foreground shadow-md backdrop-blur-sm bg-popover/95 border-border/60", children: dropdownBody }) })
9514
+ open && /* @__PURE__ */ jsx33("div", { className: "absolute left-0 top-full mt-1 z-50 w-full", children: /* @__PURE__ */ jsx33("div", { className: cn("overflow-hidden border text-popover-foreground shadow-md backdrop-blur-sm bg-popover/95 border-border/60", getBorderRadiusClass(resolvedBorderMode)), children: dropdownBody }) })
9432
9515
  ] }),
9433
9516
  (helperText || effectiveError) && /* @__PURE__ */ jsxs23(
9434
9517
  "p",
@@ -10702,10 +10785,10 @@ var DatePicker = ({
10702
10785
  placement: "bottom-start",
10703
10786
  disabled,
10704
10787
  contentWidth: sizeStyles8[size].contentWidth,
10788
+ borderMode: resolvedBorderMode,
10705
10789
  contentClassName: cn(
10706
10790
  "p-0",
10707
10791
  "backdrop-blur-xl bg-popover/95 border-border/40 shadow-2xl",
10708
- "rounded-2xl md:rounded-3xl",
10709
10792
  // Keep usable on small viewports (wheel scroll should stay within the popover if it overflows)
10710
10793
  "max-w-[calc(100vw-1rem)] max-h-[calc(100vh-6rem)] overflow-auto overscroll-contain",
10711
10794
  sizeStyles8[size].contentPadding,
@@ -11457,10 +11540,10 @@ var DateRangePicker = ({
11457
11540
  placement: "bottom-start",
11458
11541
  disabled,
11459
11542
  contentWidth: sizeStyles8[size].contentWidth,
11543
+ borderMode: resolvedBorderMode,
11460
11544
  contentClassName: cn(
11461
11545
  "p-0",
11462
11546
  "backdrop-blur-xl bg-popover/95 border-border/40 shadow-2xl",
11463
- "rounded-2xl md:rounded-3xl",
11464
11547
  "max-w-[calc(100vw-1rem)] max-h-[calc(100vh-6rem)] overflow-auto overscroll-contain",
11465
11548
  sizeStyles8[size].contentPadding,
11466
11549
  "animate-in fade-in-0 zoom-in-95 slide-in-from-top-2 duration-300"
@@ -11860,6 +11943,8 @@ var LunarDatePicker = ({
11860
11943
  maxDate,
11861
11944
  borderMode
11862
11945
  }) => {
11946
+ const globalConfig = useUnderverseUIConfig();
11947
+ const resolvedBorderMode = borderMode ?? globalConfig.input?.borderMode ?? globalConfig.borderMode ?? "full";
11863
11948
  const t = useSmartTranslations("DatePicker");
11864
11949
  const tv = useSmartTranslations("ValidationInput");
11865
11950
  const locale = useSmartLocale();
@@ -12384,12 +12469,12 @@ var LunarDatePicker = ({
12384
12469
  open: isOpen,
12385
12470
  onOpenChange: setIsOpen,
12386
12471
  placement: "bottom-start",
12472
+ borderMode: resolvedBorderMode,
12387
12473
  disabled,
12388
12474
  contentWidth: sizeStyles8[size].contentWidth,
12389
12475
  contentClassName: cn(
12390
12476
  "p-0",
12391
12477
  "backdrop-blur-xl bg-popover/95 border-border/40 shadow-2xl",
12392
- "rounded-2xl md:rounded-3xl",
12393
12478
  // Keep usable on small viewports (wheel scroll should stay within the popover if it overflows)
12394
12479
  "max-w-[calc(100vw-1rem)] max-h-[calc(100vh-6rem)] overflow-auto overscroll-contain",
12395
12480
  sizeStyles8[size].contentPadding,
@@ -12407,7 +12492,7 @@ var LunarDatePicker = ({
12407
12492
  "aria-invalid": !!effectiveError,
12408
12493
  className: cn(
12409
12494
  "group flex w-full items-center justify-between border bg-background/80 backdrop-blur-sm",
12410
- getBorderRadiusClass(borderMode ?? "full"),
12495
+ getBorderRadiusClass(resolvedBorderMode),
12411
12496
  sizeStyles8[size].trigger,
12412
12497
  disabled ? "border-border/40 opacity-50 cursor-not-allowed" : [
12413
12498
  "border-border/60 hover:border-primary/40",
@@ -13550,6 +13635,8 @@ function MonthYearPicker({
13550
13635
  borderMode,
13551
13636
  ...rest
13552
13637
  }) {
13638
+ const globalConfig = useUnderverseUIConfig();
13639
+ const resolvedBorderMode = borderMode ?? globalConfig.input?.borderMode ?? globalConfig.borderMode ?? "full";
13553
13640
  const gi18n = useGlobalI18n();
13554
13641
  const tv = useSmartTranslations("ValidationInput");
13555
13642
  const now = /* @__PURE__ */ new Date();
@@ -13708,7 +13795,7 @@ function MonthYearPicker({
13708
13795
  "aria-invalid": !!effectiveError,
13709
13796
  className: cn(
13710
13797
  "group flex w-full items-center justify-between border bg-background/80 backdrop-blur-sm",
13711
- getBorderRadiusClass(borderMode ?? "full"),
13798
+ getBorderRadiusClass(resolvedBorderMode),
13712
13799
  sz.height,
13713
13800
  sz.padding,
13714
13801
  sz.text,
@@ -13890,7 +13977,8 @@ function MonthYearPicker({
13890
13977
  {
13891
13978
  className: cn(
13892
13979
  panelSz.contentPadding,
13893
- "rounded-2xl border bg-background/80 backdrop-blur-sm",
13980
+ resolvedBorderMode ? getBorderRadiusClass(resolvedBorderMode) : "rounded-2xl md:rounded-3xl",
13981
+ "border bg-background/80 backdrop-blur-sm",
13894
13982
  effectiveError ? "border-destructive/60 bg-destructive/5" : "border-border/50"
13895
13983
  ),
13896
13984
  children: pickerContent
@@ -13931,7 +14019,8 @@ function MonthYearPicker({
13931
14019
  contentWidth,
13932
14020
  matchTriggerWidth,
13933
14021
  disabled,
13934
- contentClassName: cn(panelSz.contentPadding, compactPanel && "max-w-[calc(100vw-2rem)] p-4 rounded-2xl", "rounded-2xl"),
14022
+ borderMode: resolvedBorderMode,
14023
+ contentClassName: cn(panelSz.contentPadding, compactPanel && "max-w-[calc(100vw-2rem)] p-4"),
13935
14024
  children: pickerContent
13936
14025
  }
13937
14026
  ),
@@ -15078,6 +15167,8 @@ function TimePicker({
15078
15167
  }) {
15079
15168
  const tv = useSmartTranslations("ValidationInput");
15080
15169
  const gi18n = useGlobalI18n();
15170
+ const globalConfig = useUnderverseUIConfig();
15171
+ const resolvedBorderMode = borderMode ?? globalConfig.input?.borderMode ?? globalConfig.borderMode ?? "full";
15081
15172
  const autoId = React38.useId();
15082
15173
  const isControlled = value !== void 0;
15083
15174
  const now = /* @__PURE__ */ new Date();
@@ -15415,7 +15506,7 @@ function TimePicker({
15415
15506
  "aria-invalid": !!effectiveError,
15416
15507
  className: cn(
15417
15508
  "group flex w-full items-center justify-between border bg-background/80 backdrop-blur-sm",
15418
- getBorderRadiusClass(borderMode ?? "full"),
15509
+ getBorderRadiusClass(resolvedBorderMode),
15419
15510
  sz.height,
15420
15511
  sz.padding,
15421
15512
  sz.text,
@@ -15796,7 +15887,8 @@ function TimePicker({
15796
15887
  {
15797
15888
  className: cn(
15798
15889
  panelSz.contentPadding,
15799
- "rounded-2xl md:rounded-3xl border bg-card/95 backdrop-blur-sm shadow-xl",
15890
+ resolvedBorderMode ? getBorderRadiusClass(resolvedBorderMode) : "rounded-2xl md:rounded-3xl",
15891
+ "border bg-card/95 backdrop-blur-sm shadow-xl",
15800
15892
  effectiveError ? "border-destructive/60 bg-destructive/5" : "border-border/60",
15801
15893
  className
15802
15894
  ),
@@ -15852,10 +15944,11 @@ function TimePicker({
15852
15944
  placement: "bottom-start",
15853
15945
  matchTriggerWidth: shouldMatchTriggerWidth,
15854
15946
  contentWidth: shouldMatchTriggerWidth ? void 0 : contentWidth,
15947
+ borderMode: resolvedBorderMode,
15855
15948
  contentClassName: cn(
15856
15949
  panelSz.contentPadding,
15857
- compactPanel && "max-w-[calc(100vw-2rem)] p-4 rounded-2xl",
15858
- "rounded-2xl md:rounded-3xl border bg-popover/98 backdrop-blur-md shadow-2xl",
15950
+ compactPanel && "max-w-[calc(100vw-2rem)] p-4",
15951
+ "border bg-popover/98 backdrop-blur-md shadow-2xl",
15859
15952
  effectiveError && "border-destructive/40",
15860
15953
  success && !effectiveError && "border-success/40",
15861
15954
  !effectiveError && !success && "border-border/60",
@@ -15898,6 +15991,8 @@ var DateTimePicker = ({
15898
15991
  size = "md",
15899
15992
  borderMode
15900
15993
  }) => {
15994
+ const globalConfig = useUnderverseUIConfig();
15995
+ const resolvedBorderMode = borderMode ?? globalConfig.input?.borderMode ?? globalConfig.borderMode ?? "full";
15901
15996
  const t = useSmartTranslations("DateTimePicker");
15902
15997
  const tv = useSmartTranslations("ValidationInput");
15903
15998
  const locale = useSmartLocale();
@@ -16077,7 +16172,7 @@ var DateTimePicker = ({
16077
16172
  "aria-invalid": !!effectiveError,
16078
16173
  className: cn(
16079
16174
  "flex w-full items-center justify-between border border-input bg-background",
16080
- getBorderRadiusClass(borderMode ?? "full"),
16175
+ getBorderRadiusClass(resolvedBorderMode),
16081
16176
  sizeStyles8[size].trigger,
16082
16177
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
16083
16178
  disabled && "opacity-50 cursor-not-allowed",
@@ -16106,12 +16201,9 @@ var DateTimePicker = ({
16106
16201
  ]
16107
16202
  }
16108
16203
  ),
16109
- contentClassName: cn(
16110
- "w-auto p-0 rounded-2xl md:rounded-3xl",
16111
- // Keep the popover usable on small viewports
16112
- "max-w-[calc(100vw-1rem)] max-h-[calc(100vh-6rem)] overflow-auto"
16113
- ),
16114
- placement: "bottom-end",
16204
+ placement: "bottom-start",
16205
+ borderMode: resolvedBorderMode,
16206
+ contentClassName: "p-0 overflow-hidden w-auto flex flex-col md:flex-row max-w-[calc(100vw-1rem)] max-h-[calc(100vh-6rem)] overflow-auto",
16115
16207
  children: [
16116
16208
  /* @__PURE__ */ jsxs30("div", { className: "flex flex-col lg:flex-row divide-y lg:divide-y-0 lg:divide-x divide-border", children: [
16117
16209
  /* @__PURE__ */ jsx43("div", { className: sizeStyles8[size].padding, children: /* @__PURE__ */ jsx43(
@@ -19143,6 +19235,8 @@ var MultiCombobox = ({
19143
19235
  maxInitialOptions,
19144
19236
  showSearchPromptWhenEmptyQuery = false
19145
19237
  }) => {
19238
+ const globalConfig = useUnderverseUIConfig();
19239
+ const resolvedBorderMode = borderMode ?? globalConfig.borderMode ?? "full";
19146
19240
  const tv = useSmartTranslations("ValidationInput");
19147
19241
  const gi18n = useGlobalI18n();
19148
19242
  const placeholder = placeholderProp ?? gi18n.selectPlaceholder ?? "Select...";
@@ -19403,7 +19497,7 @@ var MultiCombobox = ({
19403
19497
  item.value
19404
19498
  );
19405
19499
  };
19406
- const dropdownBody = /* @__PURE__ */ jsxs37("div", { "data-combobox-dropdown": true, "data-state": open ? "open" : "closed", className: "w-full rounded-2xl md:rounded-3xl overflow-hidden", children: [
19500
+ const dropdownBody = /* @__PURE__ */ jsxs37("div", { "data-combobox-dropdown": true, "data-state": open ? "open" : "closed", className: cn("w-full overflow-hidden", getBorderRadiusClass(resolvedBorderMode)), children: [
19407
19501
  value.length > 0 && /* @__PURE__ */ jsxs37("div", { className: "px-3 py-2 border-b border-border/40 flex items-center justify-between bg-muted/30", children: [
19408
19502
  /* @__PURE__ */ jsx50("span", { className: "text-xs font-medium text-muted-foreground", children: maxSelected ? gi18n.selectedCountWithMax ? gi18n.selectedCountWithMax(value.length, maxSelected) : `${value.length} / ${maxSelected} max` : gi18n.itemSelectedCount ? gi18n.itemSelectedCount(value.length) : `${value.length} selected` }),
19409
19503
  showClear && /* @__PURE__ */ jsxs37(
@@ -19521,8 +19615,6 @@ var MultiCombobox = ({
19521
19615
  const selectedOptions = value.map((v) => normalizedOptions.find((o) => o.value === v) ?? selectedOptionFallbackMap.get(v)).filter(Boolean);
19522
19616
  const visibleTags = maxTagsVisible ? selectedOptions.slice(0, maxTagsVisible) : selectedOptions;
19523
19617
  const hiddenCount = maxTagsVisible ? Math.max(0, selectedOptions.length - maxTagsVisible) : 0;
19524
- const globalConfig = useUnderverseUIConfig();
19525
- const resolvedBorderMode = borderMode ?? globalConfig.borderMode ?? "full";
19526
19618
  const triggerButton = /* @__PURE__ */ jsxs37(
19527
19619
  "button",
19528
19620
  {
@@ -19685,7 +19777,8 @@ var MultiCombobox = ({
19685
19777
  placement: "bottom-start",
19686
19778
  matchTriggerWidth: true,
19687
19779
  className: "z-9999",
19688
- contentClassName: "p-0 overflow-hidden rounded-2xl md:rounded-3xl",
19780
+ borderMode: resolvedBorderMode,
19781
+ contentClassName: "p-0 overflow-hidden",
19689
19782
  children: dropdownBody
19690
19783
  }
19691
19784
  ),
@@ -19740,6 +19833,8 @@ var RadioGroup = React47.forwardRef(
19740
19833
  error = false,
19741
19834
  errorMessage
19742
19835
  }, ref) => {
19836
+ const globalConfig = useUnderverseUIConfig();
19837
+ const resolvedBorderMode = borderMode ?? globalConfig.input?.borderMode ?? globalConfig.borderMode ?? "full";
19743
19838
  const [internalValue, setInternalValue] = React47.useState(defaultValue || "");
19744
19839
  const isControlled = value !== void 0;
19745
19840
  const currentValue = isControlled ? value : internalValue;
@@ -19763,7 +19858,7 @@ var RadioGroup = React47.forwardRef(
19763
19858
  disabled,
19764
19859
  size,
19765
19860
  variant,
19766
- borderMode
19861
+ borderMode: resolvedBorderMode
19767
19862
  },
19768
19863
  children: /* @__PURE__ */ jsxs38("div", { className: "space-y-2", children: [
19769
19864
  /* @__PURE__ */ jsx51(
@@ -21017,6 +21112,8 @@ function CategoryTreeSelect(props) {
21017
21112
  singleSelect = false,
21018
21113
  borderMode
21019
21114
  } = props;
21115
+ const globalConfig = useUnderverseUIConfig();
21116
+ const resolvedBorderMode = borderMode ?? globalConfig.input?.borderMode ?? globalConfig.borderMode ?? "full";
21020
21117
  const [isOpen, setIsOpen] = useState33(false);
21021
21118
  const [expandedNodes, setExpandedNodes] = useState33(
21022
21119
  () => getInitialExpandedNodes(categories, { defaultExpanded, defaultExpandedIds, expandToId, viewOnly, inline })
@@ -21674,10 +21771,11 @@ function CategoryTreeSelect(props) {
21674
21771
  matchTriggerWidth: true,
21675
21772
  className: "z-9999",
21676
21773
  contentClassName: cn(
21677
- "p-0 overflow-hidden rounded-2xl md:rounded-3xl",
21774
+ "p-0 overflow-hidden",
21678
21775
  "border-border/40 bg-popover/95 text-popover-foreground",
21679
21776
  "shadow-2xl backdrop-blur-xl"
21680
21777
  ),
21778
+ borderMode: resolvedBorderMode,
21681
21779
  trigger: /* @__PURE__ */ jsxs41(
21682
21780
  "div",
21683
21781
  {
@@ -21704,7 +21802,7 @@ function CategoryTreeSelect(props) {
21704
21802
  },
21705
21803
  className: cn(
21706
21804
  "group flex w-full items-center justify-between transition-all duration-200",
21707
- getBorderRadiusClass(borderMode ?? "full"),
21805
+ getBorderRadiusClass(resolvedBorderMode ?? "full"),
21708
21806
  "backdrop-blur-sm",
21709
21807
  triggerSizeStyles[size].button,
21710
21808
  triggerVariantStyles[variant],
@@ -24311,6 +24409,8 @@ function ColorPicker({
24311
24409
  borderMode,
24312
24410
  ...rest
24313
24411
  }) {
24412
+ const globalConfig = useUnderverseUIConfig();
24413
+ const resolvedBorderMode = borderMode ?? globalConfig.input?.borderMode ?? globalConfig.borderMode ?? "full";
24314
24414
  const gi18n = useGlobalI18n();
24315
24415
  const isControlled = value !== void 0;
24316
24416
  const initial = parseAnyColor(isControlled ? value : defaultValue) || { r: 79, g: 70, b: 229, a: 1 };
@@ -24408,7 +24508,7 @@ function ColorPicker({
24408
24508
  disabled,
24409
24509
  className: cn(
24410
24510
  "w-full px-3 border border-input bg-background flex items-center justify-between",
24411
- getBorderRadiusClass(borderMode ?? "full"),
24511
+ getBorderRadiusClass(resolvedBorderMode),
24412
24512
  sizeClasses2[size],
24413
24513
  "hover:border-accent-foreground/30 transition-colors",
24414
24514
  disabled && "opacity-50 cursor-not-allowed",
@@ -24444,8 +24544,9 @@ function ColorPicker({
24444
24544
  onOpenChange: setOpen,
24445
24545
  placement: "bottom-start",
24446
24546
  matchTriggerWidth: variant === "minimal",
24547
+ borderMode: resolvedBorderMode,
24447
24548
  contentWidth: contentWidthByVariant[variant],
24448
- contentClassName: cn("p-3 rounded-2xl md:rounded-3xl border border-border/50 bg-card shadow-lg", contentClassName),
24549
+ contentClassName: cn("p-3 border border-border/50 bg-card shadow-lg", contentClassName),
24449
24550
  children: /* @__PURE__ */ jsxs49("div", { className: "space-y-3", children: [
24450
24551
  variant !== "minimal" && /* @__PURE__ */ jsxs49("div", { className: "flex items-center gap-2", children: [
24451
24552
  /* @__PURE__ */ jsx62(
@@ -31767,7 +31868,7 @@ var CustomTableCell = TableCell2.extend({
31767
31868
  },
31768
31869
  textDirection: {
31769
31870
  default: null,
31770
- parseHTML: (element) => element.getAttribute("data-text-direction") === "vertical" || element.style.writingMode === "vertical-rl" ? "vertical" : null,
31871
+ parseHTML: (element) => element.getAttribute("data-text-direction") === "vertical" || ["sideways-lr", "vertical-lr", "vertical-rl"].includes(element.style.writingMode) ? "vertical" : null,
31771
31872
  renderHTML: (attributes) => attributes.textDirection === "vertical" ? { "data-text-direction": "vertical" } : {}
31772
31873
  }
31773
31874
  };
@@ -31786,7 +31887,7 @@ var CustomTableCell = TableCell2.extend({
31786
31887
  if (borderStyle) mergedStyle += `; border-style: ${borderStyle}`;
31787
31888
  if (borderWidth) mergedStyle += `; border-width: ${borderWidth}`;
31788
31889
  if (verticalAlign) mergedStyle += `; vertical-align: ${verticalAlign}`;
31789
- if (textDirection === "vertical") mergedStyle += "; writing-mode: vertical-rl; text-orientation: mixed";
31890
+ if (textDirection === "vertical") mergedStyle += "; writing-mode: sideways-lr; text-orientation: mixed";
31790
31891
  mergedStyle = mergedStyle.replace(/^;/, "").trim();
31791
31892
  return [
31792
31893
  "td",
@@ -31893,7 +31994,7 @@ var CustomTableHeader = TableHeader2.extend({
31893
31994
  },
31894
31995
  textDirection: {
31895
31996
  default: null,
31896
- parseHTML: (element) => element.getAttribute("data-text-direction") === "vertical" || element.style.writingMode === "vertical-rl" ? "vertical" : null,
31997
+ parseHTML: (element) => element.getAttribute("data-text-direction") === "vertical" || ["sideways-lr", "vertical-lr", "vertical-rl"].includes(element.style.writingMode) ? "vertical" : null,
31897
31998
  renderHTML: (attributes) => attributes.textDirection === "vertical" ? { "data-text-direction": "vertical" } : {}
31898
31999
  }
31899
32000
  };
@@ -31912,7 +32013,7 @@ var CustomTableHeader = TableHeader2.extend({
31912
32013
  if (borderStyle) mergedStyle += `; border-style: ${borderStyle}`;
31913
32014
  if (borderWidth) mergedStyle += `; border-width: ${borderWidth}`;
31914
32015
  if (verticalAlign) mergedStyle += `; vertical-align: ${verticalAlign}`;
31915
- if (textDirection === "vertical") mergedStyle += "; writing-mode: vertical-rl; text-orientation: mixed";
32016
+ if (textDirection === "vertical") mergedStyle += "; writing-mode: sideways-lr; text-orientation: mixed";
31916
32017
  mergedStyle = mergedStyle.replace(/^;/, "").trim();
31917
32018
  return [
31918
32019
  "th",
@@ -34165,6 +34266,7 @@ import {
34165
34266
  Underline as UnderlineIcon2,
34166
34267
  Strikethrough as StrikethroughIcon2,
34167
34268
  Edit2,
34269
+ Eraser,
34168
34270
  Unlink,
34169
34271
  ExternalLink as ExternalLink3,
34170
34272
  Sigma as Sigma2,
@@ -34175,9 +34277,137 @@ import {
34175
34277
  ArrowRight as ArrowRight2
34176
34278
  } from "lucide-react";
34177
34279
 
34280
+ // src/components/UEditor/table-border-commands.ts
34281
+ import { selectedRect as selectedRect2 } from "@tiptap/pm/tables";
34282
+ var SIDES = ["top", "right", "bottom", "left"];
34283
+ var OPPOSITE_SIDE = {
34284
+ top: "bottom",
34285
+ right: "left",
34286
+ bottom: "top",
34287
+ left: "right"
34288
+ };
34289
+ function splitCssValues(value) {
34290
+ const values = [];
34291
+ let token = "";
34292
+ let parentheses = 0;
34293
+ for (const character of value.trim()) {
34294
+ if (/\s/.test(character) && parentheses === 0) {
34295
+ if (token) values.push(token);
34296
+ token = "";
34297
+ continue;
34298
+ }
34299
+ if (character === "(") parentheses += 1;
34300
+ if (character === ")") parentheses = Math.max(0, parentheses - 1);
34301
+ token += character;
34302
+ }
34303
+ if (token) values.push(token);
34304
+ return values;
34305
+ }
34306
+ function expandCssQuad(value, fallback) {
34307
+ const values = typeof value === "string" ? splitCssValues(value) : [];
34308
+ const [top = fallback, right = top, bottom = top, left = right] = values;
34309
+ return { top, right, bottom, left };
34310
+ }
34311
+ function serializeCssQuad({ top, right, bottom, left }) {
34312
+ if (top === right && top === bottom && top === left) return top;
34313
+ if (top === bottom && right === left) return `${top} ${right}`;
34314
+ if (right === left) return `${top} ${right} ${bottom}`;
34315
+ return `${top} ${right} ${bottom} ${left}`;
34316
+ }
34317
+ function getAppliedSides(position, cell, selection) {
34318
+ const outer = {
34319
+ top: cell.top === selection.top,
34320
+ right: cell.right === selection.right,
34321
+ bottom: cell.bottom === selection.bottom,
34322
+ left: cell.left === selection.left
34323
+ };
34324
+ const inner = {
34325
+ top: cell.top > selection.top,
34326
+ right: cell.right < selection.right,
34327
+ bottom: cell.bottom < selection.bottom,
34328
+ left: cell.left > selection.left
34329
+ };
34330
+ switch (position) {
34331
+ case "all":
34332
+ return { top: true, right: true, bottom: true, left: true };
34333
+ case "outer":
34334
+ return outer;
34335
+ case "inner":
34336
+ return inner;
34337
+ case "horizontal":
34338
+ return { top: inner.top, right: false, bottom: inner.bottom, left: false };
34339
+ case "vertical":
34340
+ return { top: false, right: inner.right, bottom: false, left: inner.left };
34341
+ default:
34342
+ return {
34343
+ top: position === "top" && outer.top,
34344
+ right: position === "right" && outer.right,
34345
+ bottom: position === "bottom" && outer.bottom,
34346
+ left: position === "left" && outer.left
34347
+ };
34348
+ }
34349
+ }
34350
+ function applyTableCellBorders(editor, position, format, options = {}) {
34351
+ const { state, view } = editor;
34352
+ const selection = selectedRect2(state);
34353
+ const transaction = state.tr;
34354
+ const cellPositions = new Set(selection.map.cellsInRect(selection));
34355
+ const sidesByCell = /* @__PURE__ */ new Map();
34356
+ const addSide = (cellPos, side) => {
34357
+ const sides = sidesByCell.get(cellPos) ?? /* @__PURE__ */ new Set();
34358
+ sides.add(side);
34359
+ sidesByCell.set(cellPos, sides);
34360
+ };
34361
+ const addAdjacentSides = (cell, side) => {
34362
+ const adjacentPositions = /* @__PURE__ */ new Set();
34363
+ if (side === "top" && cell.top > 0) {
34364
+ for (let col = cell.left; col < cell.right; col += 1) adjacentPositions.add(selection.map.map[(cell.top - 1) * selection.map.width + col]);
34365
+ } else if (side === "bottom" && cell.bottom < selection.map.height) {
34366
+ for (let col = cell.left; col < cell.right; col += 1) adjacentPositions.add(selection.map.map[cell.bottom * selection.map.width + col]);
34367
+ } else if (side === "left" && cell.left > 0) {
34368
+ for (let row = cell.top; row < cell.bottom; row += 1) adjacentPositions.add(selection.map.map[row * selection.map.width + cell.left - 1]);
34369
+ } else if (side === "right" && cell.right < selection.map.width) {
34370
+ for (let row = cell.top; row < cell.bottom; row += 1) adjacentPositions.add(selection.map.map[row * selection.map.width + cell.right]);
34371
+ }
34372
+ for (const adjacentPos of adjacentPositions) addSide(adjacentPos, OPPOSITE_SIDE[side]);
34373
+ };
34374
+ for (const relativePos of cellPositions) {
34375
+ const cell = selection.map.findCell(relativePos);
34376
+ const appliedSides = getAppliedSides(position, cell, selection);
34377
+ for (const side of SIDES) {
34378
+ if (!appliedSides[side]) continue;
34379
+ addSide(relativePos, side);
34380
+ addAdjacentSides(cell, side);
34381
+ }
34382
+ }
34383
+ for (const [relativePos, appliedSides] of sidesByCell) {
34384
+ const absolutePos = selection.tableStart + relativePos;
34385
+ const node = state.doc.nodeAt(absolutePos);
34386
+ if (!node) continue;
34387
+ const styles = expandCssQuad(node.attrs.borderStyle, "solid");
34388
+ const widths = expandCssQuad(node.attrs.borderWidth, "1px");
34389
+ const colors = expandCssQuad(node.attrs.borderColor, "#000000");
34390
+ for (const side of SIDES) {
34391
+ if (!appliedSides.has(side)) continue;
34392
+ styles[side] = format.style;
34393
+ widths[side] = format.width;
34394
+ colors[side] = format.color || "currentColor";
34395
+ }
34396
+ transaction.setNodeMarkup(absolutePos, void 0, {
34397
+ ...node.attrs,
34398
+ borderStyle: serializeCssQuad(styles),
34399
+ borderWidth: serializeCssQuad(widths),
34400
+ borderColor: serializeCssQuad(colors)
34401
+ });
34402
+ }
34403
+ if (transaction.docChanged) view.dispatch(transaction);
34404
+ if (options.focus ?? true) view.focus();
34405
+ return transaction.docChanged;
34406
+ }
34407
+
34178
34408
  // src/components/UEditor/table-formula-commands.ts
34179
34409
  import { TextSelection as TextSelection4 } from "@tiptap/pm/state";
34180
- import { selectedRect as selectedRect2, setCellAttr as setCellAttr2, TableMap as TableMap3 } from "@tiptap/pm/tables";
34410
+ import { selectedRect as selectedRect3, setCellAttr as setCellAttr2, TableMap as TableMap3 } from "@tiptap/pm/tables";
34181
34411
 
34182
34412
  // src/components/UEditor/table-formula.ts
34183
34413
  var CELL_ADDRESS_RE = /^([A-Z]+)([1-9]\d*)$/i;
@@ -35066,7 +35296,7 @@ function recalculateTableNode(tableNode, options) {
35066
35296
  return tableNode.type.create(tableNode.attrs, rows);
35067
35297
  }
35068
35298
  function recalculateSelectedTable(editor) {
35069
- const rect = selectedRect2(editor.state);
35299
+ const rect = selectedRect3(editor.state);
35070
35300
  const tableNode = rect.table;
35071
35301
  const nextTable = recalculateTableNode(tableNode);
35072
35302
  if (!nextTable) return false;
@@ -35210,6 +35440,32 @@ function BorderStylePreviewIcon({ style }) {
35210
35440
  }
35211
35441
  );
35212
35442
  }
35443
+ function BorderPositionPreviewIcon({ position }) {
35444
+ const showTop = position === "all" || position === "outer" || position === "top";
35445
+ const showRight = position === "all" || position === "outer" || position === "right";
35446
+ const showBottom = position === "all" || position === "outer" || position === "bottom";
35447
+ const showLeft = position === "all" || position === "outer" || position === "left";
35448
+ const showHorizontal = position === "all" || position === "inner" || position === "horizontal";
35449
+ const showVertical = position === "all" || position === "inner" || position === "vertical";
35450
+ return /* @__PURE__ */ jsxs76("svg", { "aria-hidden": "true", viewBox: "0 0 20 20", className: "h-5 w-5 fill-none stroke-current", children: [
35451
+ /* @__PURE__ */ jsx93(
35452
+ "path",
35453
+ {
35454
+ d: "M2 2H18V18H2Z M2 10H18 M10 2V18",
35455
+ className: "text-foreground opacity-70",
35456
+ stroke: "currentColor",
35457
+ strokeDasharray: "2 1.5",
35458
+ strokeWidth: "1.25"
35459
+ }
35460
+ ),
35461
+ showTop && /* @__PURE__ */ jsx93("path", { d: "M2 2H18", strokeWidth: "2" }),
35462
+ showRight && /* @__PURE__ */ jsx93("path", { d: "M18 2V18", strokeWidth: "2" }),
35463
+ showBottom && /* @__PURE__ */ jsx93("path", { d: "M2 18H18", strokeWidth: "2" }),
35464
+ showLeft && /* @__PURE__ */ jsx93("path", { d: "M2 2V18", strokeWidth: "2" }),
35465
+ showHorizontal && /* @__PURE__ */ jsx93("path", { d: "M2 10H18", strokeWidth: "2" }),
35466
+ showVertical && /* @__PURE__ */ jsx93("path", { d: "M10 2V18", strokeWidth: "2" })
35467
+ ] });
35468
+ }
35213
35469
  var BubbleMenuContent = ({
35214
35470
  editor,
35215
35471
  onKeepOpenChange,
@@ -35217,7 +35473,8 @@ var BubbleMenuContent = ({
35217
35473
  onRequestClose,
35218
35474
  fontSizes,
35219
35475
  lineHeights,
35220
- initialShowLinkInput = false
35476
+ initialShowLinkInput = false,
35477
+ cellBorderOpenRequest = 0
35221
35478
  }) => {
35222
35479
  const t = useSmartTranslations("UEditor");
35223
35480
  useEditorState2({
@@ -35230,6 +35487,11 @@ var BubbleMenuContent = ({
35230
35487
  useEffect37(() => {
35231
35488
  setShowLinkInput(initialShowLinkInput);
35232
35489
  }, [initialShowLinkInput]);
35490
+ useEffect37(() => {
35491
+ if (!cellBorderOpenRequest) return;
35492
+ setActiveColorPalette("cell-border");
35493
+ onKeepOpenChange?.(true);
35494
+ }, [cellBorderOpenRequest, onKeepOpenChange]);
35233
35495
  const [showTypographyPanel, setShowTypographyPanel] = useState50(false);
35234
35496
  const [showFormulaPanel, setShowFormulaPanel] = useState50(false);
35235
35497
  const [formulaDraft, setFormulaDraft] = useState50("");
@@ -35247,6 +35509,14 @@ var BubbleMenuContent = ({
35247
35509
  const currentCellNumberFormat = normalizeStyleValue(editor.getAttributes("tableCell").numberFormat || editor.getAttributes("tableHeader").numberFormat) || "text";
35248
35510
  const currentCellBorderStyle = editor.getAttributes("tableCell").borderStyle || editor.getAttributes("tableHeader").borderStyle || "solid";
35249
35511
  const currentCellBorderWidth = editor.getAttributes("tableCell").borderWidth || editor.getAttributes("tableHeader").borderWidth || "1px";
35512
+ const currentCellBorderColor = normalizeStyleValue(editor.getAttributes("tableCell").borderColor || editor.getAttributes("tableHeader").borderColor) || "#000000";
35513
+ const [borderStyleDraft, setBorderStyleDraft] = useState50(
35514
+ ["solid", "dashed", "dotted", "double"].includes(currentCellBorderStyle) ? currentCellBorderStyle : "solid"
35515
+ );
35516
+ const [borderWidthDraft, setBorderWidthDraft] = useState50(currentCellBorderWidth);
35517
+ const [borderColorDraft, setBorderColorDraft] = useState50(currentCellBorderColor);
35518
+ const [borderEditMode, setBorderEditMode] = useState50("draw");
35519
+ const [activeBorderPosition, setActiveBorderPosition] = useState50("all");
35250
35520
  const currentCellVerticalAlign = normalizeStyleValue(editor.getAttributes("tableCell").verticalAlign || editor.getAttributes("tableHeader").verticalAlign) || "";
35251
35521
  const currentCellTextDirection = normalizeStyleValue(editor.getAttributes("tableCell").textDirection || editor.getAttributes("tableHeader").textDirection) || "horizontal";
35252
35522
  const isInTable2 = isSelectionInTable(editor.state);
@@ -35303,21 +35573,60 @@ var BubbleMenuContent = ({
35303
35573
  onLinkInputOpenChange?.(false);
35304
35574
  onRequestClose?.();
35305
35575
  }, [onKeepOpenChange, onLinkInputOpenChange, onRequestClose]);
35306
- const applyTableCellAttributeAndClose = useCallback23((name, value) => {
35307
- applyTableCellAttribute2(editor, name, value, { focus: false });
35308
- closeTransientPanels();
35309
- }, [closeTransientPanels, editor]);
35310
- const clearTableCellBorderAndClose = useCallback23(() => {
35311
- applyTableCellAttribute2(editor, "borderColor", null, { focus: false });
35312
- applyTableCellAttribute2(editor, "borderStyle", null, { focus: false });
35313
- applyTableCellAttribute2(editor, "borderWidth", null, { focus: false });
35314
- closeTransientPanels();
35315
- }, [closeTransientPanels, editor]);
35316
- const applyTableCellBorderColorAndClose = useCallback23((color) => {
35317
- const value = color || null;
35318
- applyTableCellAttribute2(editor, "borderColor", value, { focus: false });
35319
- closeTransientPanels();
35320
- }, [closeTransientPanels, editor]);
35576
+ const selectTableCellBorderColor = useCallback23((color) => {
35577
+ const value = color || "currentColor";
35578
+ setBorderColorDraft(value);
35579
+ setBorderEditMode("draw");
35580
+ setActiveBorderPosition("all");
35581
+ applyTableCellBorders(editor, "all", {
35582
+ color: value,
35583
+ style: borderStyleDraft,
35584
+ width: borderWidthDraft
35585
+ }, { focus: false });
35586
+ setActiveColorPalette("cell-border");
35587
+ onKeepOpenChange?.(true);
35588
+ }, [borderStyleDraft, borderWidthDraft, editor, onKeepOpenChange]);
35589
+ const applyTableCellBorderPosition = useCallback23((position) => {
35590
+ setActiveBorderPosition(position);
35591
+ applyTableCellBorders(editor, position, {
35592
+ color: borderColorDraft,
35593
+ style: borderEditMode === "erase" ? "none" : borderStyleDraft,
35594
+ width: borderWidthDraft
35595
+ }, { focus: false });
35596
+ onKeepOpenChange?.(true);
35597
+ }, [borderColorDraft, borderEditMode, borderStyleDraft, borderWidthDraft, editor, onKeepOpenChange]);
35598
+ const applyTableCellBorderStyle = useCallback23((style) => {
35599
+ setBorderStyleDraft(style);
35600
+ setBorderEditMode("draw");
35601
+ setActiveBorderPosition("all");
35602
+ applyTableCellBorders(editor, "all", {
35603
+ color: borderColorDraft,
35604
+ style,
35605
+ width: borderWidthDraft
35606
+ }, { focus: false });
35607
+ onKeepOpenChange?.(true);
35608
+ }, [borderColorDraft, borderWidthDraft, editor, onKeepOpenChange]);
35609
+ const applyTableCellBorderWidth = useCallback23((width) => {
35610
+ setBorderWidthDraft(width);
35611
+ setBorderEditMode("draw");
35612
+ setActiveBorderPosition("all");
35613
+ applyTableCellBorders(editor, "all", {
35614
+ color: borderColorDraft,
35615
+ style: borderStyleDraft,
35616
+ width
35617
+ }, { focus: false });
35618
+ onKeepOpenChange?.(true);
35619
+ }, [borderColorDraft, borderStyleDraft, editor, onKeepOpenChange]);
35620
+ const clearTableCellBorders = useCallback23(() => {
35621
+ setActiveBorderPosition("all");
35622
+ setBorderEditMode("erase");
35623
+ applyTableCellBorders(editor, "all", {
35624
+ color: borderColorDraft,
35625
+ style: "none",
35626
+ width: borderWidthDraft
35627
+ }, { focus: false });
35628
+ onKeepOpenChange?.(true);
35629
+ }, [borderColorDraft, borderWidthDraft, editor, onKeepOpenChange]);
35321
35630
  const closeColorPalette = useCallback23(() => {
35322
35631
  setActiveColorPalette(null);
35323
35632
  onKeepOpenChange?.(false);
@@ -35371,27 +35680,104 @@ var BubbleMenuContent = ({
35371
35680
  const isTextPalette = activeColorPalette === "text";
35372
35681
  const isHighlightPalette = activeColorPalette === "highlight";
35373
35682
  if (activeColorPalette === "cell-border") {
35374
- const currentBorderColor = editor.getAttributes("tableCell").borderColor || editor.getAttributes("tableHeader").borderColor || "currentColor";
35375
- return /* @__PURE__ */ jsxs76("div", { className: "flex flex-col gap-2 p-2 w-56 text-sm", "data-ueditor-keep-open": true, children: [
35683
+ return /* @__PURE__ */ jsxs76("div", { className: "flex w-72 flex-col gap-2 p-2 text-sm", "data-ueditor-keep-open": true, children: [
35376
35684
  /* @__PURE__ */ jsx93("div", { className: "font-semibold text-xs text-muted-foreground uppercase tracking-wider mb-1", children: t("tableMenu.cellBorder") || "Cell Borders" }),
35685
+ /* @__PURE__ */ jsxs76("div", { className: "flex gap-2", children: [
35686
+ /* @__PURE__ */ jsxs76("div", { className: "min-w-0 flex-1", children: [
35687
+ /* @__PURE__ */ jsx93("label", { className: "mb-1 block text-xs text-muted-foreground", children: t("tableMenu.borderPosition") || "Border placement" }),
35688
+ /* @__PURE__ */ jsxs76("div", { className: "grid grid-cols-5 gap-1", role: "group", "aria-label": t("tableMenu.borderPosition") || "Border placement", children: [
35689
+ [
35690
+ ["all", "borderAll"],
35691
+ ["outer", "borderOuter"],
35692
+ ["inner", "borderInner"],
35693
+ ["horizontal", "borderHorizontal"],
35694
+ ["vertical", "borderVertical"],
35695
+ ["top", "borderTop"],
35696
+ ["right", "borderRight"],
35697
+ ["bottom", "borderBottom"],
35698
+ ["left", "borderLeft"]
35699
+ ].map(([position, labelKey]) => {
35700
+ const label = t(`tableMenu.${labelKey}`) || position;
35701
+ return /* @__PURE__ */ jsx93(
35702
+ "button",
35703
+ {
35704
+ type: "button",
35705
+ "aria-label": label,
35706
+ title: label,
35707
+ onMouseDown: (event) => event.preventDefault(),
35708
+ onClick: () => applyTableCellBorderPosition(position),
35709
+ className: cn(
35710
+ "inline-flex h-8 items-center justify-center rounded-md text-foreground transition-colors hover:bg-muted hover:text-primary",
35711
+ activeBorderPosition === position ? "bg-primary/10 text-primary" : "bg-muted/40"
35712
+ ),
35713
+ children: /* @__PURE__ */ jsx93(BorderPositionPreviewIcon, { position })
35714
+ },
35715
+ position
35716
+ );
35717
+ }),
35718
+ /* @__PURE__ */ jsx93(
35719
+ "button",
35720
+ {
35721
+ type: "button",
35722
+ "aria-label": t("tableMenu.clearBorder") || "Clear borders",
35723
+ title: t("tableMenu.clearBorder") || "Clear borders",
35724
+ onMouseDown: (event) => event.preventDefault(),
35725
+ onClick: clearTableCellBorders,
35726
+ className: "inline-flex h-8 items-center justify-center rounded-md bg-muted/40 text-destructive transition-colors hover:bg-destructive/10",
35727
+ children: /* @__PURE__ */ jsx93(BorderStylePreviewIcon, { style: "none" })
35728
+ }
35729
+ )
35730
+ ] })
35731
+ ] }),
35732
+ /* @__PURE__ */ jsxs76("div", { className: "flex flex-col gap-1 border-l border-border pl-2 pt-5", role: "group", "aria-label": t("tableMenu.borderMode") || "Border mode", children: [
35733
+ /* @__PURE__ */ jsx93(
35734
+ "button",
35735
+ {
35736
+ type: "button",
35737
+ "aria-label": t("tableMenu.borderDraw") || "Draw borders",
35738
+ title: t("tableMenu.borderDraw") || "Draw borders",
35739
+ onMouseDown: (event) => event.preventDefault(),
35740
+ onClick: () => setBorderEditMode("draw"),
35741
+ className: cn(
35742
+ "inline-flex h-8 w-8 items-center justify-center rounded-md transition-colors hover:bg-muted",
35743
+ borderEditMode === "draw" ? "bg-primary/10 text-primary" : "text-muted-foreground"
35744
+ ),
35745
+ children: /* @__PURE__ */ jsx93(Edit2, { className: "h-4 w-4" })
35746
+ }
35747
+ ),
35748
+ /* @__PURE__ */ jsx93(
35749
+ "button",
35750
+ {
35751
+ type: "button",
35752
+ "aria-label": t("tableMenu.borderErase") || "Hide borders",
35753
+ title: t("tableMenu.borderErase") || "Hide borders",
35754
+ onMouseDown: (event) => event.preventDefault(),
35755
+ onClick: () => setBorderEditMode("erase"),
35756
+ className: cn(
35757
+ "inline-flex h-8 w-8 items-center justify-center rounded-md transition-colors hover:bg-muted",
35758
+ borderEditMode === "erase" ? "bg-destructive/10 text-destructive" : "text-muted-foreground"
35759
+ ),
35760
+ children: /* @__PURE__ */ jsx93(Eraser, { className: "h-4 w-4" })
35761
+ }
35762
+ )
35763
+ ] })
35764
+ ] }),
35377
35765
  /* @__PURE__ */ jsxs76("div", { className: "flex flex-col gap-1", children: [
35378
35766
  /* @__PURE__ */ jsx93("label", { className: "text-xs text-muted-foreground", children: t("tableMenu.borderStyle") || "Border Style" }),
35379
- /* @__PURE__ */ jsx93("div", { className: "grid grid-cols-3 gap-1", role: "group", "aria-label": t("tableMenu.borderStyle") || "Border Style", children: [
35767
+ /* @__PURE__ */ jsx93("div", { className: "grid grid-cols-4 gap-1.5", role: "group", "aria-label": t("tableMenu.borderStyle") || "Border Style", children: [
35380
35768
  ["solid", "Solid"],
35381
35769
  ["dashed", "Dashed"],
35382
35770
  ["dotted", "Dotted"],
35383
- ["double", "Double"],
35384
- ["none", "None"]
35771
+ ["double", "Double"]
35385
35772
  ].map(([style, label]) => /* @__PURE__ */ jsxs76(
35386
35773
  "button",
35387
35774
  {
35388
35775
  type: "button",
35389
- "data-ueditor-close-on-select": true,
35390
35776
  onMouseDown: (event) => event.preventDefault(),
35391
- onClick: () => applyTableCellAttributeAndClose("borderStyle", style),
35777
+ onClick: () => applyTableCellBorderStyle(style),
35392
35778
  className: cn(
35393
- "inline-flex h-8 items-center justify-center gap-1.5 rounded-md px-2 text-xs font-medium transition-colors hover:bg-muted",
35394
- currentCellBorderStyle === style ? "bg-primary/10 text-primary" : "bg-muted/40 text-foreground"
35779
+ "inline-flex h-8 min-w-0 items-center justify-center gap-1.5 rounded-md px-2.5 text-xs font-medium transition-colors hover:bg-muted",
35780
+ borderStyleDraft === style ? "bg-primary/10 text-primary" : "bg-muted/40 text-foreground"
35395
35781
  ),
35396
35782
  children: [
35397
35783
  /* @__PURE__ */ jsx93(BorderStylePreviewIcon, { style }),
@@ -35407,12 +35793,11 @@ var BubbleMenuContent = ({
35407
35793
  "button",
35408
35794
  {
35409
35795
  type: "button",
35410
- "data-ueditor-close-on-select": true,
35411
35796
  onMouseDown: (event) => event.preventDefault(),
35412
- onClick: () => applyTableCellAttributeAndClose("borderWidth", width),
35797
+ onClick: () => applyTableCellBorderWidth(width),
35413
35798
  className: cn(
35414
35799
  "h-8 rounded-md px-2 text-xs font-medium transition-colors hover:bg-muted",
35415
- currentCellBorderWidth === width ? "bg-primary/10 text-primary" : "bg-muted/40 text-foreground"
35800
+ borderWidthDraft === width ? "bg-primary/10 text-primary" : "bg-muted/40 text-foreground"
35416
35801
  ),
35417
35802
  children: width
35418
35803
  },
@@ -35432,33 +35817,22 @@ var BubbleMenuContent = ({
35432
35817
  {
35433
35818
  className: "w-4 h-4 rounded-full border border-border",
35434
35819
  style: {
35435
- backgroundColor: currentBorderColor
35820
+ backgroundColor: borderColorDraft
35436
35821
  }
35437
35822
  }
35438
35823
  )
35439
35824
  ]
35440
35825
  }
35441
- ),
35442
- /* @__PURE__ */ jsx93("div", { className: "flex items-center justify-between gap-2 mt-2 pt-2 border-t border-border", children: /* @__PURE__ */ jsx93(
35443
- "button",
35444
- {
35445
- type: "button",
35446
- "data-ueditor-close-on-select": true,
35447
- onClick: clearTableCellBorderAndClose,
35448
- className: "text-xs text-destructive hover:underline",
35449
- children: t("tableMenu.clearBorder") || "Clear Border"
35450
- }
35451
- ) })
35826
+ )
35452
35827
  ] });
35453
35828
  }
35454
35829
  if (activeColorPalette === "cell-border-color") {
35455
- const currentBorderColor = normalizeStyleValue(editor.getAttributes("tableCell").borderColor || editor.getAttributes("tableHeader").borderColor) || "";
35456
35830
  return /* @__PURE__ */ jsx93("div", { className: "w-56", "data-ueditor-keep-open": true, children: /* @__PURE__ */ jsx93(
35457
35831
  EditorColorPalette,
35458
35832
  {
35459
35833
  colors: borderColors,
35460
- currentColor: currentBorderColor,
35461
- onSelect: applyTableCellBorderColorAndClose,
35834
+ currentColor: borderColorDraft,
35835
+ onSelect: selectTableCellBorderColor,
35462
35836
  label: t("tableMenu.borderColor") || "Border Color"
35463
35837
  }
35464
35838
  ) });
@@ -35976,6 +36350,7 @@ var CustomBubbleMenu = ({
35976
36350
  const BUBBLE_MENU_ESTIMATED_HEIGHT = 44;
35977
36351
  const [isVisible, setIsVisible] = useState50(false);
35978
36352
  const [linkInputOpen, setLinkInputOpen] = useState50(false);
36353
+ const [cellBorderOpenRequest, setCellBorderOpenRequest] = useState50(0);
35979
36354
  const [position, setPosition2] = useState50({
35980
36355
  top: 0,
35981
36356
  left: 0,
@@ -35992,8 +36367,8 @@ var CustomBubbleMenu = ({
35992
36367
  if (!next) setLinkInputOpen(false);
35993
36368
  if (next) setIsVisible(true);
35994
36369
  }, []);
35995
- const closeBubbleMenu = useCallback23(() => {
35996
- suppressShowUntilRef.current = Date.now() + 1e3;
36370
+ const closeBubbleMenu = useCallback23((suppressShow = true) => {
36371
+ suppressShowUntilRef.current = suppressShow ? Date.now() + 1e3 : 0;
35997
36372
  keepOpenRef.current = false;
35998
36373
  setKeepOpenState(false);
35999
36374
  setLinkInputOpen(false);
@@ -36085,6 +36460,41 @@ var CustomBubbleMenu = ({
36085
36460
  editor.off("update", updatePosition);
36086
36461
  };
36087
36462
  }, [editor]);
36463
+ useEffect37(() => {
36464
+ if (!isVisible) return;
36465
+ const handlePointerDown = (event) => {
36466
+ const target = event.target;
36467
+ if (target && (menuRef.current?.contains(target) || target.closest("[data-ueditor-keep-open]"))) return;
36468
+ const table = target?.closest("table");
36469
+ if (table && editor.view.dom.contains(table)) return;
36470
+ closeBubbleMenu(false);
36471
+ };
36472
+ const handleKeyDown2 = (event) => {
36473
+ if (event.key === "Escape") closeBubbleMenu();
36474
+ };
36475
+ document.addEventListener("pointerdown", handlePointerDown, true);
36476
+ document.addEventListener("keydown", handleKeyDown2);
36477
+ return () => {
36478
+ document.removeEventListener("pointerdown", handlePointerDown, true);
36479
+ document.removeEventListener("keydown", handleKeyDown2);
36480
+ };
36481
+ }, [closeBubbleMenu, editor, isVisible]);
36482
+ useEffect37(() => {
36483
+ const handleTableDoubleClick = (event) => {
36484
+ const target = event.target;
36485
+ const cell = target?.closest("td,th");
36486
+ if (!cell || !editor.view.dom.contains(cell)) return;
36487
+ suppressShowUntilRef.current = 0;
36488
+ keepOpenRef.current = true;
36489
+ setKeepOpenState(true);
36490
+ setLinkInputOpen(false);
36491
+ setCellBorderOpenRequest((request) => request + 1);
36492
+ setIsVisible(true);
36493
+ requestAnimationFrame(() => editor.view.focus());
36494
+ };
36495
+ editor.view.dom.addEventListener("dblclick", handleTableDoubleClick);
36496
+ return () => editor.view.dom.removeEventListener("dblclick", handleTableDoubleClick);
36497
+ }, [editor]);
36088
36498
  if (!isVisible) return null;
36089
36499
  return createPortal8(
36090
36500
  /* @__PURE__ */ jsx93(
@@ -36125,7 +36535,8 @@ var CustomBubbleMenu = ({
36125
36535
  onRequestClose: closeBubbleMenu,
36126
36536
  fontSizes,
36127
36537
  lineHeights,
36128
- initialShowLinkInput: linkInputOpen
36538
+ initialShowLinkInput: linkInputOpen,
36539
+ cellBorderOpenRequest
36129
36540
  }
36130
36541
  )
36131
36542
  }
@@ -40577,7 +40988,7 @@ function moveTableRow$1(table, indexesOrigin, indexesTarget, direction) {
40577
40988
  rows = moveRowInArrayOfRows(rows, indexesOrigin, indexesTarget, direction);
40578
40989
  return convertArrayOfRowsToTableNode(table, rows);
40579
40990
  }
40580
- function selectedRect3(state) {
40991
+ function selectedRect4(state) {
40581
40992
  const sel = state.selection;
40582
40993
  const $pos = selectionCell(state);
40583
40994
  const table = $pos.node(-1);
@@ -40595,7 +41006,7 @@ function deprecated_toggleHeader(type) {
40595
41006
  if (!isInTable(state)) return false;
40596
41007
  if (dispatch) {
40597
41008
  const types = tableNodeTypes2(state.schema);
40598
- const rect = selectedRect3(state), tr = state.tr;
41009
+ const rect = selectedRect4(state), tr = state.tr;
40599
41010
  const cells = rect.map.cellsInRect(type == "column" ? {
40600
41011
  left: rect.left,
40601
41012
  top: 0,
@@ -40635,7 +41046,7 @@ function toggleHeader(type, options) {
40635
41046
  if (!isInTable(state)) return false;
40636
41047
  if (dispatch) {
40637
41048
  const types = tableNodeTypes2(state.schema);
40638
- const rect = selectedRect3(state), tr = state.tr;
41049
+ const rect = selectedRect4(state), tr = state.tr;
40639
41050
  const isHeaderRowEnabled = isHeaderEnabledByType("row", rect, types);
40640
41051
  const isHeaderColumnEnabled = isHeaderEnabledByType("column", rect, types);
40641
41052
  const selectionStartsAt = (type === "column" ? isHeaderRowEnabled : type === "row" ? isHeaderColumnEnabled : false) ? 1 : 0;