@underverse-ui/underverse 1.0.143 → 1.0.145

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
@@ -25741,6 +25741,99 @@ function getImageFiles(dataTransfer) {
25741
25741
  }
25742
25742
  return Array.from(byKey.values());
25743
25743
  }
25744
+ function getClipboardData(dataTransfer, type) {
25745
+ try {
25746
+ return dataTransfer.getData(type) ?? "";
25747
+ } catch {
25748
+ return "";
25749
+ }
25750
+ }
25751
+ function extractClipboardHtmlFragment(html) {
25752
+ const startMarker = "<!--StartFragment-->";
25753
+ const endMarker = "<!--EndFragment-->";
25754
+ const start = html.indexOf(startMarker);
25755
+ const end = html.indexOf(endMarker);
25756
+ if (start >= 0 && end > start) {
25757
+ return html.slice(start + startMarker.length, end);
25758
+ }
25759
+ return html;
25760
+ }
25761
+ function getClipboardTableHtml(dataTransfer) {
25762
+ const html = getClipboardData(dataTransfer, "text/html");
25763
+ if (!/<table(?:\s|>)/i.test(html)) return "";
25764
+ const fragment = extractClipboardHtmlFragment(html);
25765
+ if (typeof DOMParser !== "undefined") {
25766
+ const doc = new DOMParser().parseFromString(fragment, "text/html");
25767
+ const table = doc.querySelector("table");
25768
+ if (table) return table.outerHTML;
25769
+ }
25770
+ return fragment;
25771
+ }
25772
+ function escapeHtml(value) {
25773
+ return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
25774
+ }
25775
+ function renderCellHtml(value) {
25776
+ const lines = value.split("\n");
25777
+ return lines.map((line) => `<p>${escapeHtml(line)}</p>`).join("");
25778
+ }
25779
+ function parseTsvRows(text) {
25780
+ const rows = [];
25781
+ let row = [];
25782
+ let field = "";
25783
+ let inQuotes = false;
25784
+ const pushField = () => {
25785
+ row.push(field);
25786
+ field = "";
25787
+ };
25788
+ const pushRow = () => {
25789
+ pushField();
25790
+ rows.push(row);
25791
+ row = [];
25792
+ };
25793
+ for (let index = 0; index < text.length; index += 1) {
25794
+ const char = text[index];
25795
+ const next = text[index + 1];
25796
+ if (inQuotes) {
25797
+ if (char === '"' && next === '"') {
25798
+ field += '"';
25799
+ index += 1;
25800
+ continue;
25801
+ }
25802
+ if (char === '"') {
25803
+ inQuotes = false;
25804
+ continue;
25805
+ }
25806
+ field += char;
25807
+ continue;
25808
+ }
25809
+ if (char === '"' && field.length === 0) {
25810
+ inQuotes = true;
25811
+ continue;
25812
+ }
25813
+ if (char === " ") {
25814
+ pushField();
25815
+ continue;
25816
+ }
25817
+ if (char === "\n") {
25818
+ pushRow();
25819
+ continue;
25820
+ }
25821
+ field += char;
25822
+ }
25823
+ pushRow();
25824
+ while (rows.length > 0 && rows[rows.length - 1].every((cell) => cell === "")) {
25825
+ rows.pop();
25826
+ }
25827
+ return rows;
25828
+ }
25829
+ function getClipboardTsvTableHtml(dataTransfer) {
25830
+ const text = getClipboardData(dataTransfer, "text/plain").replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\n+$/, "");
25831
+ if (!text.includes(" ")) return "";
25832
+ const rows = parseTsvRows(text);
25833
+ if (rows.length === 0 || rows.every((row) => row.length < 2)) return "";
25834
+ const body = rows.map((row) => `<tr>${row.map((cell) => `<td>${renderCellHtml(cell)}</td>`).join("")}</tr>`).join("");
25835
+ return `<table><tbody>${body}</tbody></table>`;
25836
+ }
25744
25837
  function fileToDataUrl(file) {
25745
25838
  return new Promise((resolve, reject) => {
25746
25839
  const reader = new FileReader();
@@ -25795,6 +25888,18 @@ var ClipboardImages = Extension2.create({
25795
25888
  props: {
25796
25889
  handlePaste: (_view, event) => {
25797
25890
  if (!event || !event.clipboardData) return false;
25891
+ const tableHtml = getClipboardTableHtml(event.clipboardData);
25892
+ if (tableHtml) {
25893
+ event.preventDefault();
25894
+ editor.chain().focus().insertContent(tableHtml).run();
25895
+ return true;
25896
+ }
25897
+ const tsvTableHtml = getClipboardTsvTableHtml(event.clipboardData);
25898
+ if (tsvTableHtml) {
25899
+ event.preventDefault();
25900
+ editor.chain().focus().insertContent(tsvTableHtml).run();
25901
+ return true;
25902
+ }
25798
25903
  const files = getImageFiles(event.clipboardData);
25799
25904
  if (files.length === 0) return false;
25800
25905
  event.preventDefault();
@@ -28984,58 +29089,6 @@ import {
28984
29089
  ExternalLink as ExternalLink3
28985
29090
  } from "lucide-react";
28986
29091
  import { Fragment as Fragment29, jsx as jsx86, jsxs as jsxs72 } from "react/jsx-runtime";
28987
- var FloatingSlashCommandMenu = ({ editor, onClose }) => {
28988
- const t = useSmartTranslations("UEditor");
28989
- const messages = useMemo23(() => buildSlashCommandMessages(t), [t]);
28990
- const items = useMemo23(() => buildSlashCommandItems({ query: "", messages }), [messages]);
28991
- const listRef = useRef33(null);
28992
- useEffect36(() => {
28993
- const handleKeyDown2 = (event) => {
28994
- if (event.key === "Escape") {
28995
- event.preventDefault();
28996
- onClose();
28997
- return;
28998
- }
28999
- const handled = listRef.current?.onKeyDown({ event }) ?? false;
29000
- if (handled) {
29001
- event.preventDefault();
29002
- }
29003
- };
29004
- document.addEventListener("keydown", handleKeyDown2);
29005
- return () => document.removeEventListener("keydown", handleKeyDown2);
29006
- }, [onClose]);
29007
- return /* @__PURE__ */ jsx86(
29008
- SlashCommandList,
29009
- {
29010
- ref: listRef,
29011
- items,
29012
- messages,
29013
- command: (item) => {
29014
- item.command({ editor });
29015
- onClose();
29016
- }
29017
- }
29018
- );
29019
- };
29020
- var FloatingMenuContent = ({ editor }) => {
29021
- const t = useSmartTranslations("UEditor");
29022
- const [showCommands, setShowCommands] = useState48(false);
29023
- if (showCommands) {
29024
- return /* @__PURE__ */ jsx86(FloatingSlashCommandMenu, { editor, onClose: () => setShowCommands(false) });
29025
- }
29026
- return /* @__PURE__ */ jsxs72(
29027
- "button",
29028
- {
29029
- type: "button",
29030
- onClick: () => setShowCommands(true),
29031
- className: "flex items-center gap-1 px-2 py-1.5 rounded-lg hover:bg-accent transition-all group",
29032
- children: [
29033
- /* @__PURE__ */ jsx86(Plus3, { className: "w-4 h-4 text-muted-foreground group-hover:text-foreground" }),
29034
- /* @__PURE__ */ jsx86("span", { className: "text-sm text-muted-foreground group-hover:text-foreground", children: t("floatingMenu.addBlock") })
29035
- ]
29036
- }
29037
- );
29038
- };
29039
29092
  function applyTableCellBackground(editor, color) {
29040
29093
  const value = color || null;
29041
29094
  const { state, view } = editor;
@@ -29662,54 +29715,6 @@ var CustomBubbleMenu = ({
29662
29715
  document.body
29663
29716
  );
29664
29717
  };
29665
- var CustomFloatingMenu = ({ editor }) => {
29666
- const FLOATING_MENU_OFFSET = 16;
29667
- const [isVisible, setIsVisible] = useState48(false);
29668
- const [position, setPosition] = useState48({ top: 0, left: 0 });
29669
- useEffect36(() => {
29670
- const updatePosition = () => {
29671
- const { state, view } = editor;
29672
- const { $from, empty } = state.selection;
29673
- const isEmptyTextBlock = $from.parent.isTextblock && $from.parent.type.name === "paragraph" && $from.parent.textContent === "" && empty;
29674
- if (!isEmptyTextBlock || !view.hasFocus()) {
29675
- setIsVisible(false);
29676
- return;
29677
- }
29678
- const coords = view.coordsAtPos($from.pos);
29679
- setPosition({ top: coords.top - FLOATING_MENU_OFFSET, left: coords.left });
29680
- setIsVisible(true);
29681
- };
29682
- const handleBlur = () => setIsVisible(false);
29683
- editor.on("selectionUpdate", updatePosition);
29684
- editor.on("focus", updatePosition);
29685
- editor.on("blur", handleBlur);
29686
- editor.on("update", updatePosition);
29687
- return () => {
29688
- editor.off("selectionUpdate", updatePosition);
29689
- editor.off("focus", updatePosition);
29690
- editor.off("blur", handleBlur);
29691
- editor.off("update", updatePosition);
29692
- };
29693
- }, [editor]);
29694
- if (!isVisible) return null;
29695
- return createPortal8(
29696
- /* @__PURE__ */ jsx86(
29697
- "div",
29698
- {
29699
- "data-popover": true,
29700
- className: "fixed z-99999 rounded-2xl border border-border/50 bg-card text-card-foreground shadow-lg backdrop-blur-sm overflow-hidden animate-in fade-in-0 slide-in-from-bottom-2",
29701
- style: {
29702
- top: `${position.top}px`,
29703
- left: `${position.left}px`,
29704
- transform: "translate(-50%, -100%)"
29705
- },
29706
- onMouseDown: (e) => e.preventDefault(),
29707
- children: /* @__PURE__ */ jsx86(FloatingMenuContent, { editor })
29708
- }
29709
- ),
29710
- document.body
29711
- );
29712
- };
29713
29718
 
29714
29719
  // src/components/UEditor/CharacterCount.tsx
29715
29720
  import { jsxs as jsxs73 } from "react/jsx-runtime";
@@ -34495,8 +34500,8 @@ function TableAddRails({
34495
34500
  const visibleTableHeight = Math.min(layout.tableHeight, layout.viewportHeight);
34496
34501
  const columnRailTop = layout.tableTop;
34497
34502
  const columnRailLeft = layout.tableLeft + visibleTableWidth + ADD_COLUMN_RAIL_GAP;
34498
- const rowRailTop = layout.tableTop + visibleTableHeight + ADD_ROW_RAIL_GAP;
34499
- const rowRailLeft = layout.tableLeft;
34503
+ const rowRailTop = layout.wrapperTop + layout.wrapperHeight + ADD_ROW_RAIL_GAP;
34504
+ const rowRailLeft = Math.max(layout.tableLeft, layout.wrapperLeft);
34500
34505
  const showColumnRail = controlsVisible || addColumnVisible;
34501
34506
  const showRowRail = controlsVisible || addRowVisible;
34502
34507
  return /* @__PURE__ */ jsxs75(Fragment32, { children: [
@@ -35126,6 +35131,7 @@ function TableControls({ editor, containerRef }) {
35126
35131
  const proseMirror = editor.view.dom;
35127
35132
  const surface = containerRef.current;
35128
35133
  if (!surface) return void 0;
35134
+ const scrollListenerOptions = { passive: true, capture: true };
35129
35135
  const handleMouseOver = (event) => {
35130
35136
  if (dragStateRef.current) return;
35131
35137
  const cell = getCellFromTarget(event.target);
@@ -35151,7 +35157,7 @@ function TableControls({ editor, containerRef }) {
35151
35157
  proseMirror.addEventListener("focusin", handleFocusIn);
35152
35158
  surface.addEventListener("mouseover", handleSurfaceMouseMove);
35153
35159
  surface.addEventListener("mousemove", handleSurfaceMouseMove);
35154
- surface.addEventListener("scroll", refreshCurrentLayout, { passive: true });
35160
+ surface.addEventListener("scroll", refreshCurrentLayout, scrollListenerOptions);
35155
35161
  surface.addEventListener(UEDITOR_TABLE_LAYOUT_CHANGE_EVENT, refreshCurrentLayout);
35156
35162
  window.addEventListener("resize", refreshCurrentLayout);
35157
35163
  editor.on("selectionUpdate", syncFromSelection);
@@ -35165,7 +35171,7 @@ function TableControls({ editor, containerRef }) {
35165
35171
  proseMirror.removeEventListener("focusin", handleFocusIn);
35166
35172
  surface.removeEventListener("mouseover", handleSurfaceMouseMove);
35167
35173
  surface.removeEventListener("mousemove", handleSurfaceMouseMove);
35168
- surface.removeEventListener("scroll", refreshCurrentLayout);
35174
+ surface.removeEventListener("scroll", refreshCurrentLayout, scrollListenerOptions);
35169
35175
  surface.removeEventListener(UEDITOR_TABLE_LAYOUT_CHANGE_EVENT, refreshCurrentLayout);
35170
35176
  window.removeEventListener("resize", refreshCurrentLayout);
35171
35177
  editor.off("selectionUpdate", syncFromSelection);
@@ -35635,7 +35641,7 @@ var UEDITOR_PROSEMIRROR_CLASS_NAME = cn(
35635
35641
  "[&_.column-resize-handle]:top-[-1px]",
35636
35642
  "[&_.column-resize-handle]:bottom-[-1px]",
35637
35643
  "[&_.column-resize-handle]:right-[-5px]",
35638
- "[&_.column-resize-handle]:z-10",
35644
+ "[&_.column-resize-handle]:z-30",
35639
35645
  "[&_.column-resize-handle]:w-2.5",
35640
35646
  "[&_.column-resize-handle]:bg-transparent",
35641
35647
  "[&_.column-resize-handle]:rounded-none",
@@ -35889,26 +35895,31 @@ function useUEditorTableInteractions(editor, editable = true) {
35889
35895
  const activeTableCellRef = useRef35(null);
35890
35896
  const suppressActiveCellHighlightRef = useRef35(false);
35891
35897
  const tableLayoutSyncFrameRef = useRef35(null);
35898
+ const getProseMirrorElement = React80.useCallback(() => {
35899
+ return editorContentRef.current?.querySelector(".ProseMirror");
35900
+ }, []);
35892
35901
  const setEditorResizeCursor = React80.useCallback((cursor) => {
35893
- const proseMirror = editorContentRef.current?.querySelector(".ProseMirror");
35902
+ const proseMirror = getProseMirrorElement();
35894
35903
  if (proseMirror) {
35895
35904
  proseMirror.style.cursor = cursor;
35896
35905
  }
35897
- }, []);
35906
+ }, [getProseMirrorElement]);
35898
35907
  const hideColumnGuide = React80.useCallback(() => {
35899
35908
  editorContentRef.current?.classList.remove("resize-cursor");
35909
+ getProseMirrorElement()?.classList.remove("resize-cursor");
35900
35910
  const guide = tableColumnGuideRef.current;
35901
35911
  if (guide) {
35902
35912
  guide.style.opacity = "0";
35903
35913
  }
35904
- }, []);
35914
+ }, [getProseMirrorElement]);
35905
35915
  const hideRowGuide = React80.useCallback(() => {
35906
35916
  editorContentRef.current?.classList.remove("resize-row-cursor");
35917
+ getProseMirrorElement()?.classList.remove("resize-row-cursor");
35907
35918
  const guide = tableRowGuideRef.current;
35908
35919
  if (guide) {
35909
35920
  guide.style.opacity = "0";
35910
35921
  }
35911
- }, []);
35922
+ }, [getProseMirrorElement]);
35912
35923
  const clearAllTableResizeHover = React80.useCallback(() => {
35913
35924
  setEditorResizeCursor("");
35914
35925
  hideColumnGuide();
@@ -35938,7 +35949,10 @@ function useUEditorTableInteractions(editor, editable = true) {
35938
35949
  });
35939
35950
  }, [updateActiveCellHighlight]);
35940
35951
  const setActiveTableCell = React80.useCallback((cell) => {
35941
- if (activeTableCellRef.current === cell) return;
35952
+ if (activeTableCellRef.current === cell) {
35953
+ updateActiveCellHighlight(cell);
35954
+ return;
35955
+ }
35942
35956
  activeTableCellRef.current = cell;
35943
35957
  updateActiveCellHighlight(activeTableCellRef.current);
35944
35958
  }, [updateActiveCellHighlight]);
@@ -35963,8 +35977,9 @@ function useUEditorTableInteractions(editor, editable = true) {
35963
35977
  guide.style.height = `${metrics.height}px`;
35964
35978
  guide.style.opacity = "1";
35965
35979
  surface.classList.add("resize-cursor");
35980
+ getProseMirrorElement()?.classList.add("resize-cursor");
35966
35981
  setEditorResizeCursor("col-resize");
35967
- }, [setEditorResizeCursor]);
35982
+ }, [getProseMirrorElement, setEditorResizeCursor]);
35968
35983
  const showRowGuide = React80.useCallback((table, row, cell) => {
35969
35984
  const surface = editorContentRef.current;
35970
35985
  const guide = tableRowGuideRef.current;
@@ -35976,8 +35991,9 @@ function useUEditorTableInteractions(editor, editable = true) {
35976
35991
  guide.style.height = `${ROW_RESIZE_LINE_THICKNESS}px`;
35977
35992
  guide.style.opacity = "1";
35978
35993
  surface.classList.add("resize-row-cursor");
35994
+ getProseMirrorElement()?.classList.add("resize-row-cursor");
35979
35995
  setEditorResizeCursor("row-resize");
35980
- }, [setEditorResizeCursor]);
35996
+ }, [getProseMirrorElement, setEditorResizeCursor]);
35981
35997
  const {
35982
35998
  beginResize,
35983
35999
  cancelResize,
@@ -35996,19 +36012,32 @@ function useUEditorTableInteractions(editor, editable = true) {
35996
36012
  });
35997
36013
  const syncActiveTableCellFromSelection = React80.useCallback(() => {
35998
36014
  if (!editor) return;
36015
+ if (!editor.isFocused) {
36016
+ clearActiveTableCell();
36017
+ return;
36018
+ }
35999
36019
  setActiveTableCell(getSelectionTableCell(editor.view));
36000
- }, [editor, setActiveTableCell]);
36020
+ }, [clearActiveTableCell, editor, setActiveTableCell]);
36001
36021
  useEffect37(() => {
36002
36022
  if (!editor || !editable) return void 0;
36003
36023
  const proseMirror = editor.view.dom;
36004
36024
  const surface = editorContentRef.current;
36005
36025
  let selectionSyncTimeoutId = 0;
36026
+ const scrollListenerOptions = { passive: true, capture: true };
36006
36027
  const scheduleActiveCellSync = (fallbackCell = null) => {
36007
36028
  requestAnimationFrame(() => {
36029
+ if (!editor.isFocused) {
36030
+ clearActiveTableCell();
36031
+ return;
36032
+ }
36008
36033
  setActiveTableCell(getSelectionTableCell(editor.view) ?? fallbackCell);
36009
36034
  });
36010
36035
  window.clearTimeout(selectionSyncTimeoutId);
36011
36036
  selectionSyncTimeoutId = window.setTimeout(() => {
36037
+ if (!editor.isFocused) {
36038
+ clearActiveTableCell();
36039
+ return;
36040
+ }
36012
36041
  setActiveTableCell(getSelectionTableCell(editor.view) ?? fallbackCell);
36013
36042
  }, 0);
36014
36043
  };
@@ -36112,13 +36141,15 @@ function useUEditorTableInteractions(editor, editable = true) {
36112
36141
  proseMirror.addEventListener("keyup", handleSelectionChange);
36113
36142
  proseMirror.addEventListener("focusin", handleSelectionChange);
36114
36143
  document.addEventListener("selectionchange", handleSelectionChange);
36115
- surface?.addEventListener("scroll", handleActiveCellLayoutChange, { passive: true });
36144
+ surface?.addEventListener("scroll", handleActiveCellLayoutChange, scrollListenerOptions);
36116
36145
  window.addEventListener("resize", handleActiveCellLayoutChange);
36117
36146
  document.addEventListener("pointermove", handlePointerMove);
36118
36147
  document.addEventListener("pointerup", handlePointerUp);
36119
36148
  window.addEventListener("blur", handleWindowBlur);
36120
36149
  editor.on("selectionUpdate", syncActiveTableCellFromSelection);
36121
36150
  editor.on("focus", syncActiveTableCellFromSelection);
36151
+ editor.on("blur", clearActiveTableCell);
36152
+ editor.on("update", scheduleTableLayoutSync);
36122
36153
  syncActiveTableCellFromSelection();
36123
36154
  return () => {
36124
36155
  proseMirror.removeEventListener("mousemove", handleEditorMouseMove);
@@ -36129,13 +36160,15 @@ function useUEditorTableInteractions(editor, editable = true) {
36129
36160
  proseMirror.removeEventListener("keyup", handleSelectionChange);
36130
36161
  proseMirror.removeEventListener("focusin", handleSelectionChange);
36131
36162
  document.removeEventListener("selectionchange", handleSelectionChange);
36132
- surface?.removeEventListener("scroll", handleActiveCellLayoutChange);
36163
+ surface?.removeEventListener("scroll", handleActiveCellLayoutChange, scrollListenerOptions);
36133
36164
  window.removeEventListener("resize", handleActiveCellLayoutChange);
36134
36165
  document.removeEventListener("pointermove", handlePointerMove);
36135
36166
  document.removeEventListener("pointerup", handlePointerUp);
36136
36167
  window.removeEventListener("blur", handleWindowBlur);
36137
36168
  editor.off("selectionUpdate", syncActiveTableCellFromSelection);
36138
36169
  editor.off("focus", syncActiveTableCellFromSelection);
36170
+ editor.off("blur", clearActiveTableCell);
36171
+ editor.off("update", scheduleTableLayoutSync);
36139
36172
  window.clearTimeout(selectionSyncTimeoutId);
36140
36173
  if (tableLayoutSyncFrameRef.current !== null) {
36141
36174
  window.cancelAnimationFrame(tableLayoutSyncFrameRef.current);
@@ -36148,7 +36181,7 @@ function useUEditorTableInteractions(editor, editable = true) {
36148
36181
  clearHoveredTableCell();
36149
36182
  clearAllTableResizeHover();
36150
36183
  };
36151
- }, [beginResize, cancelResize, cleanupRowResize, clearActiveTableCell, clearAllTableResizeHover, clearHoveredTableCell, editable, editor, handleRowResizePointerMove, handleRowResizePointerUp, hideColumnGuide, hideRowGuide, isRowResizing, showColumnGuide, showRowGuide, syncActiveRowResizeGuide, syncActiveTableCellFromSelection, updateActiveCellHighlight]);
36184
+ }, [beginResize, cancelResize, cleanupRowResize, clearActiveTableCell, clearAllTableResizeHover, clearHoveredTableCell, editable, editor, handleRowResizePointerMove, handleRowResizePointerUp, hideColumnGuide, hideRowGuide, isRowResizing, scheduleTableLayoutSync, showColumnGuide, showRowGuide, syncActiveRowResizeGuide, syncActiveTableCellFromSelection, updateActiveCellHighlight]);
36152
36185
  return {
36153
36186
  editorContentRef,
36154
36187
  tableColumnGuideRef,
@@ -36167,6 +36200,7 @@ import {
36167
36200
  AlignRight as AlignRight4,
36168
36201
  Bold as BoldIcon3,
36169
36202
  Code as CodeIcon3,
36203
+ Eye as Eye3,
36170
36204
  FileCode as FileCode4,
36171
36205
  Heading1 as Heading1Icon2,
36172
36206
  Heading2 as Heading2Icon2,
@@ -36186,7 +36220,8 @@ import {
36186
36220
  Trash2 as Trash25,
36187
36221
  Underline as UnderlineIcon3,
36188
36222
  Undo as UndoIcon2,
36189
- Upload as Upload4
36223
+ Upload as Upload4,
36224
+ X as X19
36190
36225
  } from "lucide-react";
36191
36226
  import { Fragment as Fragment35, jsx as jsx92, jsxs as jsxs77 } from "react/jsx-runtime";
36192
36227
  function MenuTableInsertGrid({
@@ -36677,6 +36712,21 @@ var MenuBar = ({
36677
36712
  const openPreviewDialog = () => {
36678
36713
  setShowPreviewDialog(true);
36679
36714
  };
36715
+ const handlePreview = () => {
36716
+ if (onPreview) {
36717
+ onPreview();
36718
+ return;
36719
+ }
36720
+ openPreviewDialog();
36721
+ };
36722
+ React81.useEffect(() => {
36723
+ if (!showPreviewDialog) return void 0;
36724
+ const previousOverflow = document.body.style.overflow;
36725
+ document.body.style.overflow = "hidden";
36726
+ return () => {
36727
+ document.body.style.overflow = previousOverflow;
36728
+ };
36729
+ }, [showPreviewDialog]);
36680
36730
  const applySourceHtml = () => {
36681
36731
  editor.chain().focus().setContent(sourceHtml).run();
36682
36732
  setShowSourceDialog(false);
@@ -36788,7 +36838,7 @@ var MenuBar = ({
36788
36838
  { label: t("menubar.edit"), items: buildEditMenuItems(t, editor), open: void 0, onOpenChange: void 0 },
36789
36839
  {
36790
36840
  label: t("menubar.view"),
36791
- items: buildViewMenuItems(t, { containerRef, onSourceCode, openSourceDialog, onPreview, openPreviewDialog }),
36841
+ items: buildViewMenuItems(t, { containerRef, onSourceCode, openSourceDialog, onPreview: handlePreview, openPreviewDialog }),
36792
36842
  open: void 0,
36793
36843
  onOpenChange: void 0
36794
36844
  },
@@ -36825,17 +36875,33 @@ var MenuBar = ({
36825
36875
  onChange: (e) => handleImageFiles(e.target.files)
36826
36876
  }
36827
36877
  ),
36828
- /* @__PURE__ */ jsx92("div", { className: "flex items-center gap-0.5 border-b border-border/35 bg-muted/20 px-1.5 py-0.5", children: menus.map(({ label, items, open, onOpenChange }) => /* @__PURE__ */ jsx92(
36829
- DropdownMenu,
36830
- {
36831
- trigger: /* @__PURE__ */ jsx92(MenuBarTrigger, { children: label }),
36832
- placement: "bottom-start",
36833
- isOpen: open,
36834
- onOpenChange,
36835
- children: renderMenuItems(items)
36836
- },
36837
- label
36838
- )) }),
36878
+ /* @__PURE__ */ jsxs77("div", { className: "flex items-center gap-0.5 border-b border-border/35 bg-muted/20 px-1.5 py-0.5", children: [
36879
+ menus.map(({ label, items, open, onOpenChange }) => /* @__PURE__ */ jsx92(
36880
+ DropdownMenu,
36881
+ {
36882
+ trigger: /* @__PURE__ */ jsx92(MenuBarTrigger, { children: label }),
36883
+ placement: "bottom-start",
36884
+ isOpen: open,
36885
+ onOpenChange,
36886
+ children: renderMenuItems(items)
36887
+ },
36888
+ label
36889
+ )),
36890
+ /* @__PURE__ */ jsx92(
36891
+ "button",
36892
+ {
36893
+ type: "button",
36894
+ onClick: handlePreview,
36895
+ "aria-label": t("menubar.preview"),
36896
+ title: t("menubar.preview"),
36897
+ className: cn(
36898
+ "ml-auto inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground transition-colors",
36899
+ "hover:bg-accent hover:text-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-1"
36900
+ ),
36901
+ children: /* @__PURE__ */ jsx92(Eye3, { className: "h-4 w-4", "aria-hidden": "true" })
36902
+ }
36903
+ )
36904
+ ] }),
36839
36905
  /* @__PURE__ */ jsx92(
36840
36906
  Modal_default,
36841
36907
  {
@@ -36878,23 +36944,38 @@ var MenuBar = ({
36878
36944
  ] })
36879
36945
  }
36880
36946
  ),
36881
- /* @__PURE__ */ jsx92(
36882
- Modal_default,
36883
- {
36884
- isOpen: showPreviewDialog,
36885
- onClose: () => setShowPreviewDialog(false),
36886
- title: t("menubar.preview"),
36887
- size: "lg",
36888
- children: editor.isEmpty ? /* @__PURE__ */ jsx92("p", { className: "text-muted-foreground text-sm", children: t("menubar.previewEmpty") }) : /* @__PURE__ */ jsx92(
36889
- "div",
36947
+ showPreviewDialog && /* @__PURE__ */ jsxs77("div", { className: "fixed inset-0 z-9999 flex flex-col bg-background text-foreground", children: [
36948
+ /* @__PURE__ */ jsxs77("div", { className: "flex shrink-0 items-center justify-between border-b border-border bg-card px-4 py-3", children: [
36949
+ /* @__PURE__ */ jsx92("h2", { className: "text-base font-semibold", children: t("menubar.preview") }),
36950
+ /* @__PURE__ */ jsx92(
36951
+ "button",
36890
36952
  {
36891
- "data-testid": "preview-content",
36892
- className: UEDITOR_PROSEMIRROR_CLASS_NAME,
36893
- dangerouslySetInnerHTML: { __html: editor.getHTML() }
36953
+ type: "button",
36954
+ onClick: () => setShowPreviewDialog(false),
36955
+ "aria-label": t("menubar.closeDialog"),
36956
+ className: cn(
36957
+ "inline-flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground transition-colors",
36958
+ "hover:bg-accent hover:text-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-1"
36959
+ ),
36960
+ children: /* @__PURE__ */ jsx92(X19, { className: "h-4 w-4", "aria-hidden": "true" })
36894
36961
  }
36895
36962
  )
36896
- }
36897
- )
36963
+ ] }),
36964
+ /* @__PURE__ */ jsx92(
36965
+ "div",
36966
+ {
36967
+ "data-testid": "preview-content",
36968
+ className: "min-h-0 flex-1 overflow-y-auto overscroll-contain px-4 py-4 md:px-8",
36969
+ children: editor.isEmpty ? /* @__PURE__ */ jsx92("p", { className: "text-muted-foreground text-sm", children: t("menubar.previewEmpty") }) : /* @__PURE__ */ jsx92(
36970
+ "div",
36971
+ {
36972
+ className: UEDITOR_PROSEMIRROR_CLASS_NAME,
36973
+ dangerouslySetInnerHTML: { __html: editor.getHTML() }
36974
+ }
36975
+ )
36976
+ }
36977
+ )
36978
+ ] })
36898
36979
  ] });
36899
36980
  };
36900
36981
 
@@ -36918,7 +36999,6 @@ var UEditor = React82.forwardRef(({
36918
36999
  autofocus = false,
36919
37000
  showToolbar = true,
36920
37001
  showBubbleMenu = true,
36921
- showFloatingMenu = false,
36922
37002
  showCharacterCount = true,
36923
37003
  maxCharacters,
36924
37004
  minHeight = "200px",
@@ -37120,7 +37200,6 @@ var UEditor = React82.forwardRef(({
37120
37200
  lineHeights
37121
37201
  }
37122
37202
  ),
37123
- editable && showFloatingMenu && /* @__PURE__ */ jsx93(CustomFloatingMenu, { editor }),
37124
37203
  /* @__PURE__ */ jsxs78(
37125
37204
  "div",
37126
37205
  {
@@ -37153,7 +37232,7 @@ var UEditor = React82.forwardRef(({
37153
37232
  ref: activeTableCellHighlightRef,
37154
37233
  "aria-hidden": "true",
37155
37234
  "data-ueditor-active-cell-highlight": "",
37156
- className: "pointer-events-none hidden absolute z-20 rounded-[2px] border-2 border-primary bg-primary/10 transition-[left,top,width,height] duration-100"
37235
+ className: "pointer-events-none hidden absolute z-20 rounded-[2px] border-2 border-primary bg-primary/10"
37157
37236
  }
37158
37237
  ),
37159
37238
  editable && /* @__PURE__ */ jsx93(TableControls, { editor, containerRef: editorContentRef }),