@underverse-ui/underverse 1.0.211 → 2.0.1

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.
Files changed (30) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/LICENSE +21 -0
  3. package/README.md +243 -706
  4. package/api-reference.json +1 -1
  5. package/dist/{EmojiPicker-FEJJDAWZ.js → EmojiPicker-34YATB7Z.js} +4 -4
  6. package/dist/{chunk-F6A7HJE4.js → chunk-A7XL4RDV.js} +3 -3
  7. package/dist/{chunk-CYCBSKWI.js → chunk-KGNYK5YF.js} +2 -2
  8. package/dist/{chunk-BRDGIALS.js → chunk-PLHJWXCW.js} +24 -30
  9. package/dist/{chunk-BRDGIALS.js.map → chunk-PLHJWXCW.js.map} +1 -1
  10. package/dist/{chunk-GKY5DHGR.js → chunk-UNDGI6ZI.js} +3 -3
  11. package/dist/{chunk-4E43DRP2.js → chunk-Y7SQKJ7X.js} +95 -31
  12. package/dist/chunk-Y7SQKJ7X.js.map +1 -0
  13. package/dist/{chunk-AMAILXHP.js → chunk-Z6WE65J2.js} +44 -18
  14. package/dist/chunk-Z6WE65J2.js.map +1 -0
  15. package/dist/index.cjs +280 -159
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.js +140 -103
  18. package/dist/index.js.map +1 -1
  19. package/dist/{menu-bar-6GS5LLTD.js → menu-bar-AAD3LQTN.js} +4 -4
  20. package/dist/ueditor.cjs +132 -42
  21. package/dist/ueditor.cjs.map +1 -1
  22. package/dist/ueditor.js +4 -4
  23. package/package.json +3 -1
  24. package/dist/chunk-4E43DRP2.js.map +0 -1
  25. package/dist/chunk-AMAILXHP.js.map +0 -1
  26. /package/dist/{EmojiPicker-FEJJDAWZ.js.map → EmojiPicker-34YATB7Z.js.map} +0 -0
  27. /package/dist/{chunk-F6A7HJE4.js.map → chunk-A7XL4RDV.js.map} +0 -0
  28. /package/dist/{chunk-CYCBSKWI.js.map → chunk-KGNYK5YF.js.map} +0 -0
  29. /package/dist/{chunk-GKY5DHGR.js.map → chunk-UNDGI6ZI.js.map} +0 -0
  30. /package/dist/{menu-bar-6GS5LLTD.js.map → menu-bar-AAD3LQTN.js.map} +0 -0
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  getPanelBorderRadiusClass,
3
3
  useUnderverseUIConfig
4
- } from "./chunk-AMAILXHP.js";
4
+ } from "./chunk-Z6WE65J2.js";
5
5
  import {
6
6
  cn,
7
7
  useGlobalI18n
8
- } from "./chunk-BRDGIALS.js";
8
+ } from "./chunk-PLHJWXCW.js";
9
9
 
10
10
  // src/components/Modal.tsx
11
11
  import * as React from "react";
@@ -196,4 +196,4 @@ var Modal_default = Modal;
196
196
  export {
197
197
  Modal_default
198
198
  };
199
- //# sourceMappingURL=chunk-GKY5DHGR.js.map
199
+ //# sourceMappingURL=chunk-UNDGI6ZI.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  EmojiGridButton,
3
3
  formatEmojiCountLabel
4
- } from "./chunk-CYCBSKWI.js";
4
+ } from "./chunk-KGNYK5YF.js";
5
5
  import {
6
6
  COLUMN_RESIZE_LINE_THICKNESS,
7
7
  CellBgColorIcon,
@@ -53,12 +53,12 @@ import {
53
53
  sanitizeUEditorUrl,
54
54
  useEditorColors,
55
55
  useSharedEditorUiRenderState
56
- } from "./chunk-AMAILXHP.js";
56
+ } from "./chunk-Z6WE65J2.js";
57
57
  import {
58
58
  Tooltip,
59
59
  cn,
60
60
  useSmartTranslations
61
- } from "./chunk-BRDGIALS.js";
61
+ } from "./chunk-PLHJWXCW.js";
62
62
 
63
63
  // src/components/UEditor/prepare-content-for-save.ts
64
64
  var MIME_EXTENSION_MAP = {
@@ -508,7 +508,7 @@ import { NodeViewWrapper, NodeViewContent } from "@tiptap/react";
508
508
  import React from "react";
509
509
  import { jsx } from "react/jsx-runtime";
510
510
  var LazyBaseEmojiPicker = React.lazy(async () => {
511
- const { EmojiPicker: EmojiPicker2 } = await import("./EmojiPicker-FEJJDAWZ.js");
511
+ const { EmojiPicker: EmojiPicker2 } = await import("./EmojiPicker-34YATB7Z.js");
512
512
  return { default: EmojiPicker2 };
513
513
  });
514
514
  var EmojiPicker = ({ onSelect }) => {
@@ -5928,15 +5928,18 @@ var FloatingMenuContent = ({ editor }) => {
5928
5928
  }
5929
5929
  );
5930
5930
  };
5931
- function applyTableCellBackground(editor, color) {
5931
+ function applyTableCellBackground(editor, color, options = {}) {
5932
+ const shouldFocus = options.focus ?? true;
5932
5933
  const value = color || null;
5933
5934
  const { state, view } = editor;
5934
5935
  const applied = setCellAttr2("backgroundColor", value)(state, view.dispatch.bind(view));
5935
5936
  if (applied) {
5936
- view.focus();
5937
+ if (shouldFocus) view.focus();
5937
5938
  return;
5938
5939
  }
5939
- editor.chain().focus().setCellAttribute("backgroundColor", value).run();
5940
+ const chain = editor.chain();
5941
+ if (shouldFocus) chain.focus();
5942
+ chain.setCellAttribute("backgroundColor", value).run();
5940
5943
  }
5941
5944
  function applyTableCellAttribute(editor, name, value, options = {}) {
5942
5945
  const shouldFocus = options.focus ?? true;
@@ -5994,6 +5997,30 @@ function BorderPositionPreviewIcon({ position }) {
5994
5997
  showVertical && /* @__PURE__ */ jsx12("path", { d: "M10 2V18", strokeWidth: "2" })
5995
5998
  ] });
5996
5999
  }
6000
+ function getBubbleMenuPosition({
6001
+ start,
6002
+ end,
6003
+ menuSize,
6004
+ viewport,
6005
+ offset = 16,
6006
+ padding = 8
6007
+ }) {
6008
+ const selectionTop = Math.min(start.top, end.top);
6009
+ const selectionBottom = Math.max(start.bottom, end.bottom);
6010
+ const spaceAbove = selectionTop - offset - padding;
6011
+ const spaceBelow = viewport.height - padding - selectionBottom - offset;
6012
+ const placement = menuSize.height <= spaceAbove || spaceAbove >= spaceBelow ? "top" : "bottom";
6013
+ const halfWidth = menuSize.width / 2;
6014
+ const minLeft = padding + halfWidth;
6015
+ const maxLeft = viewport.width - padding - halfWidth;
6016
+ const selectionCenter = (start.left + end.left) / 2;
6017
+ const left = maxLeft >= minLeft ? Math.min(maxLeft, Math.max(minLeft, selectionCenter)) : viewport.width / 2;
6018
+ const requestedTop = placement === "top" ? selectionTop - offset : selectionBottom + offset;
6019
+ const minTop = placement === "top" ? padding + menuSize.height : padding;
6020
+ const maxTop = placement === "top" ? viewport.height - padding : viewport.height - padding - menuSize.height;
6021
+ const top = maxTop >= minTop ? Math.min(maxTop, Math.max(minTop, requestedTop)) : Math.max(padding, requestedTop);
6022
+ return { top, left, placement };
6023
+ }
5997
6024
  function getBubbleMenuContext(editor) {
5998
6025
  const { selection } = editor.state;
5999
6026
  if (editor.isActive("image")) return "image";
@@ -6159,24 +6186,34 @@ var BubbleMenuContent = ({
6159
6186
  setActiveColorPalette(null);
6160
6187
  onKeepOpenChange?.(false);
6161
6188
  }, [onKeepOpenChange]);
6162
- const applyInlineColorAndClose = useCallback((color) => {
6189
+ const applyInlineColor = useCallback((color, focus) => {
6163
6190
  if (activeColorPalette === "text") {
6191
+ const chain = editor.chain();
6192
+ if (focus) chain.focus();
6164
6193
  if (color === "inherit") {
6165
- editor.chain().focus().unsetColor().run();
6194
+ chain.unsetColor().run();
6166
6195
  } else {
6167
- editor.chain().focus().setColor(color).run();
6196
+ chain.setColor(color).run();
6168
6197
  }
6169
6198
  } else if (activeColorPalette === "highlight") {
6199
+ const chain = editor.chain();
6200
+ if (focus) chain.focus();
6170
6201
  if (color === "") {
6171
- editor.chain().focus().unsetHighlight().run();
6202
+ chain.unsetHighlight().run();
6172
6203
  } else {
6173
- editor.chain().focus().toggleHighlight({ color }).run();
6204
+ chain.toggleHighlight({ color }).run();
6174
6205
  }
6175
6206
  } else {
6176
- applyTableCellBackground(editor, color);
6207
+ applyTableCellBackground(editor, color, { focus });
6177
6208
  }
6209
+ }, [activeColorPalette, editor]);
6210
+ const applyInlineColorAndClose = useCallback((color) => {
6211
+ applyInlineColor(color, true);
6178
6212
  closeColorPalette();
6179
- }, [activeColorPalette, closeColorPalette, editor]);
6213
+ }, [applyInlineColor, closeColorPalette]);
6214
+ const applyCustomColor = useCallback((color) => {
6215
+ applyInlineColor(color, false);
6216
+ }, [applyInlineColor]);
6180
6217
  useEffect5(() => {
6181
6218
  if (!showLinkInput) return;
6182
6219
  const close2 = () => setShowLinkInput(false);
@@ -6371,6 +6408,7 @@ var BubbleMenuContent = ({
6371
6408
  colors: isTextPalette ? textColors : highlightColors,
6372
6409
  currentColor: isTextPalette ? currentTextColor : isHighlightPalette ? currentHighlightColor : currentCellBgColor,
6373
6410
  onSelect: applyInlineColorAndClose,
6411
+ onCustomColorSelect: applyCustomColor,
6374
6412
  label: isTextPalette ? t("colors.textColor") : isHighlightPalette ? t("colors.highlight") : t("tableMenu.cellBackground") || "Cell background"
6375
6413
  }
6376
6414
  ) });
@@ -6657,6 +6695,7 @@ var BubbleMenuContent = ({
6657
6695
  /* @__PURE__ */ jsx12(
6658
6696
  ToolbarButton,
6659
6697
  {
6698
+ onMouseDown: () => onKeepOpenChange?.(true),
6660
6699
  onClick: () => setActiveColorPalette("cell-bg"),
6661
6700
  active: Boolean(currentCellBgColor),
6662
6701
  title: t("tableMenu.cellBackground") || "Cell background",
@@ -6888,6 +6927,8 @@ var CustomBubbleMenu = ({
6888
6927
  placement: "top"
6889
6928
  });
6890
6929
  const menuRef = useRef4(null);
6930
+ const updatePositionRef = useRef4(() => {
6931
+ });
6891
6932
  const keepOpenRef = useRef4(false);
6892
6933
  const [keepOpen, setKeepOpenState] = useState5(false);
6893
6934
  const showTimeoutRef = useRef4(null);
@@ -6945,19 +6986,15 @@ var CustomBubbleMenu = ({
6945
6986
  setIsVisible(false);
6946
6987
  return;
6947
6988
  }
6948
- const viewportPadding = 8;
6949
6989
  const menuHeight = menuRef.current?.getBoundingClientRect().height || BUBBLE_MENU_ESTIMATED_HEIGHT;
6950
- const editorTop = view.dom.getBoundingClientRect().top;
6951
- const selectionTop = Math.min(start.top, end.top);
6952
- const selectionBottom = Math.max(start.bottom, end.bottom);
6953
- const hasRoomAboveEditor = selectionTop - BUBBLE_MENU_OFFSET - menuHeight >= editorTop + viewportPadding;
6954
- const placement = hasRoomAboveEditor ? "top" : "bottom";
6955
- const left = Math.min(
6956
- window.innerWidth - viewportPadding,
6957
- Math.max(viewportPadding, (start.left + end.left) / 2)
6958
- );
6959
- const top = placement === "top" ? Math.max(viewportPadding, selectionTop - BUBBLE_MENU_OFFSET) : Math.min(window.innerHeight - viewportPadding, selectionBottom + BUBBLE_MENU_OFFSET);
6960
- setPosition2({ top, left, placement });
6990
+ const menuWidth = menuRef.current?.getBoundingClientRect().width || 0;
6991
+ setPosition2(getBubbleMenuPosition({
6992
+ start,
6993
+ end,
6994
+ menuSize: { width: menuWidth, height: menuHeight },
6995
+ viewport: { width: window.innerWidth, height: window.innerHeight },
6996
+ offset: BUBBLE_MENU_OFFSET
6997
+ }));
6961
6998
  if (keepOpenRef.current) {
6962
6999
  clearShowTimeout();
6963
7000
  setIsVisible(true);
@@ -6986,8 +7023,11 @@ var CustomBubbleMenu = ({
6986
7023
  editor.on("transaction", schedulePositionUpdate);
6987
7024
  editor.on("focus", schedulePositionUpdate);
6988
7025
  editor.on("blur", handleBlur);
7026
+ updatePositionRef.current = updatePosition;
6989
7027
  schedulePositionUpdate();
6990
7028
  return () => {
7029
+ updatePositionRef.current = () => {
7030
+ };
6991
7031
  if (animationFrameId !== null) cancelAnimationFrame(animationFrameId);
6992
7032
  clearShowTimeout();
6993
7033
  editor.off("transaction", schedulePositionUpdate);
@@ -6995,6 +7035,24 @@ var CustomBubbleMenu = ({
6995
7035
  editor.off("blur", handleBlur);
6996
7036
  };
6997
7037
  }, [editor]);
7038
+ useEffect5(() => {
7039
+ if (!isVisible || typeof ResizeObserver === "undefined") return;
7040
+ const menu = menuRef.current;
7041
+ if (!menu) return;
7042
+ let animationFrameId = null;
7043
+ const observer = new ResizeObserver(() => {
7044
+ if (animationFrameId !== null) cancelAnimationFrame(animationFrameId);
7045
+ animationFrameId = requestAnimationFrame(() => {
7046
+ animationFrameId = null;
7047
+ updatePositionRef.current();
7048
+ });
7049
+ });
7050
+ observer.observe(menu);
7051
+ return () => {
7052
+ if (animationFrameId !== null) cancelAnimationFrame(animationFrameId);
7053
+ observer.disconnect();
7054
+ };
7055
+ }, [isVisible]);
6998
7056
  useEffect5(() => {
6999
7057
  if (!isVisible) return;
7000
7058
  const handlePointerDown = (event) => {
@@ -12131,7 +12189,7 @@ function TableResizeHandles({
12131
12189
  "data-resizing": active ? "true" : "false",
12132
12190
  className: cn(
12133
12191
  "pointer-events-none absolute z-[38] box-border border border-primary/55",
12134
- active && "border-primary bg-primary/[0.03]"
12192
+ active && "border-primary bg-primary/3"
12135
12193
  ),
12136
12194
  style: {
12137
12195
  left: layout.tableLeft,
@@ -14180,11 +14238,17 @@ function useUEditorOutput({
14180
14238
  onJsonChange,
14181
14239
  outputDebounceMs
14182
14240
  }) {
14183
- const callbacksRef = React14.useRef({});
14241
+ const callbacksRef = React14.useRef({
14242
+ onChange,
14243
+ onHtmlChange,
14244
+ onJsonChange
14245
+ });
14184
14246
  const pendingEditorRef = React14.useRef(null);
14185
14247
  const timeoutRef = React14.useRef(null);
14186
14248
  const debounceMs = normalizeDebounceMs(outputDebounceMs);
14187
- callbacksRef.current = { onChange, onHtmlChange, onJsonChange };
14249
+ React14.useLayoutEffect(() => {
14250
+ callbacksRef.current = { onChange, onHtmlChange, onJsonChange };
14251
+ }, [onChange, onHtmlChange, onJsonChange]);
14188
14252
  const flushOutputUpdates = React14.useCallback(() => {
14189
14253
  if (timeoutRef.current !== null) {
14190
14254
  clearTimeout(timeoutRef.current);
@@ -14239,7 +14303,7 @@ function useUEditorOutput({
14239
14303
  // src/components/UEditor/UEditor.tsx
14240
14304
  import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
14241
14305
  var LazyMenuBar = React15.lazy(async () => {
14242
- const { MenuBar } = await import("./menu-bar-6GS5LLTD.js");
14306
+ const { MenuBar } = await import("./menu-bar-AAD3LQTN.js");
14243
14307
  return { default: MenuBar };
14244
14308
  });
14245
14309
  var UEditor = React15.forwardRef(({
@@ -14689,4 +14753,4 @@ export {
14689
14753
  prepareUEditorContentForSave,
14690
14754
  UEditor_default
14691
14755
  };
14692
- //# sourceMappingURL=chunk-4E43DRP2.js.map
14756
+ //# sourceMappingURL=chunk-Y7SQKJ7X.js.map