@underverse-ui/underverse 2.0.31 → 2.0.32

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.
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getPanelBorderRadiusClass,
3
3
  useUnderverseUIConfig
4
- } from "./chunk-37MHVJMV.js";
4
+ } from "./chunk-4TXHZS3S.js";
5
5
  import {
6
6
  cn,
7
7
  useGlobalI18n
@@ -253,4 +253,4 @@ var Modal_default = Modal;
253
253
  export {
254
254
  Modal_default
255
255
  };
256
- //# sourceMappingURL=chunk-2P7TSXEE.js.map
256
+ //# sourceMappingURL=chunk-RSSSQS2A.js.map
package/dist/index.cjs CHANGED
@@ -6393,10 +6393,15 @@ function isCrossRealmTableRow(value) {
6393
6393
  function isCrossRealmTableCell(value) {
6394
6394
  return isCrossRealmElement(value) && ["TD", "TH"].includes(String(value.tagName).toUpperCase()) && "cellIndex" in value;
6395
6395
  }
6396
+ function isValidProseMirrorPosition(doc, pos) {
6397
+ return Number.isInteger(pos) && pos >= 0 && pos <= doc.content.size;
6398
+ }
6396
6399
  function findTableRowNodeInfo(view, rowElement) {
6400
+ if (!view.dom.contains(rowElement)) return null;
6397
6401
  const firstCell = rowElement.querySelector("th,td");
6398
- if (!firstCell) return null;
6402
+ if (!isCrossRealmTableCell(firstCell) || !view.dom.contains(firstCell)) return null;
6399
6403
  const cellPos = view.posAtDOM(firstCell, 0);
6404
+ if (!isValidProseMirrorPosition(view.state.doc, cellPos)) return null;
6400
6405
  const $pos = view.state.doc.resolve(cellPos);
6401
6406
  for (let depth = $pos.depth; depth > 0; depth -= 1) {
6402
6407
  const node = $pos.node(depth);
@@ -6438,14 +6443,14 @@ function getSelectionTableCell(view) {
6438
6443
  const browserSelection = realm?.getSelection();
6439
6444
  const anchorElement = resolveEventElement(browserSelection?.anchorNode ?? null);
6440
6445
  const anchorCell = anchorElement?.closest?.("th,td");
6441
- if (realm && anchorCell instanceof realm.HTMLElement) {
6446
+ if (isCrossRealmTableCell(anchorCell) && view.dom.contains(anchorCell)) {
6442
6447
  return anchorCell;
6443
6448
  }
6444
6449
  const { from } = view.state.selection;
6445
6450
  const domAtPos = view.domAtPos(from);
6446
6451
  const element = resolveEventElement(domAtPos.node);
6447
6452
  const cell = element?.closest?.("th,td");
6448
- return realm && cell instanceof realm.HTMLElement ? cell : null;
6453
+ return isCrossRealmTableCell(cell) && view.dom.contains(cell) ? cell : null;
6449
6454
  }
6450
6455
  function resolveRowResizeTarget(cell, clientX, clientY) {
6451
6456
  const rect = cell.getBoundingClientRect();
@@ -8448,18 +8453,22 @@ function getTableAnchorPos(editor) {
8448
8453
  const editorWindow = editorDocument.defaultView;
8449
8454
  const selectionAnchor = resolveEventElement(editorWindow?.getSelection()?.anchorNode ?? null);
8450
8455
  const selectionCell2 = selectionAnchor?.closest?.("th,td");
8451
- if (editorWindow && selectionCell2 instanceof editorWindow.HTMLTableCellElement && editor.view.dom.contains(selectionCell2)) {
8452
- return editor.view.posAtDOM(selectionCell2, 0) + 1;
8456
+ if (isCrossRealmTableCell(selectionCell2) && editor.view.dom.contains(selectionCell2)) {
8457
+ const cellPos2 = editor.view.posAtDOM(selectionCell2, 0);
8458
+ return isValidProseMirrorPosition(editor.state.doc, cellPos2) && isValidProseMirrorPosition(editor.state.doc, cellPos2 + 1) ? cellPos2 + 1 : null;
8453
8459
  }
8454
8460
  const activeElement = editorWindow && editorDocument.activeElement instanceof editorWindow.Element ? editorDocument.activeElement : null;
8455
8461
  const activeCell = activeElement?.closest?.("th,td");
8456
- if (editorWindow && activeCell instanceof editorWindow.HTMLTableCellElement && editor.view.dom.contains(activeCell)) {
8457
- return editor.view.posAtDOM(activeCell, 0) + 1;
8462
+ if (isCrossRealmTableCell(activeCell) && editor.view.dom.contains(activeCell)) {
8463
+ const cellPos2 = editor.view.posAtDOM(activeCell, 0);
8464
+ return isValidProseMirrorPosition(editor.state.doc, cellPos2) && isValidProseMirrorPosition(editor.state.doc, cellPos2 + 1) ? cellPos2 + 1 : null;
8458
8465
  }
8459
8466
  const tables = editor.view.dom.querySelectorAll("table");
8460
8467
  if (tables.length !== 1) return null;
8461
8468
  const firstCell = tables[0]?.querySelector("th,td");
8462
- return editorWindow && firstCell instanceof editorWindow.HTMLTableCellElement ? editor.view.posAtDOM(firstCell, 0) + 1 : null;
8469
+ if (!isCrossRealmTableCell(firstCell) || !editor.view.dom.contains(firstCell)) return null;
8470
+ const cellPos = editor.view.posAtDOM(firstCell, 0);
8471
+ return isValidProseMirrorPosition(editor.state.doc, cellPos) && isValidProseMirrorPosition(editor.state.doc, cellPos + 1) ? cellPos + 1 : null;
8463
8472
  }
8464
8473
  function computeEditorUiRenderState(editor) {
8465
8474
  const textStyle = editor.getAttributes("textStyle");
@@ -40861,6 +40870,7 @@ function getBubbleMenuPosition({
40861
40870
  end,
40862
40871
  menuSize,
40863
40872
  viewport,
40873
+ preferredPlacement = "auto",
40864
40874
  offset = 16,
40865
40875
  padding = 8
40866
40876
  }) {
@@ -40868,7 +40878,7 @@ function getBubbleMenuPosition({
40868
40878
  const selectionBottom = Math.max(start.bottom, end.bottom);
40869
40879
  const spaceAbove = selectionTop - offset - padding;
40870
40880
  const spaceBelow = viewport.height - padding - selectionBottom - offset;
40871
- const placement = menuSize.height <= spaceAbove || spaceAbove >= spaceBelow ? "top" : "bottom";
40881
+ const placement = preferredPlacement === "auto" ? menuSize.height <= spaceAbove || spaceAbove >= spaceBelow ? "top" : "bottom" : preferredPlacement;
40872
40882
  const halfWidth = menuSize.width / 2;
40873
40883
  const minLeft = padding + halfWidth;
40874
40884
  const maxLeft = viewport.width - padding - halfWidth;
@@ -41772,6 +41782,7 @@ var LinkPreviewContent = ({ editor, onEdit }) => {
41772
41782
  };
41773
41783
  var CustomBubbleMenu = ({
41774
41784
  editor,
41785
+ placement = "auto",
41775
41786
  fontSizes,
41776
41787
  lineHeights
41777
41788
  }) => {
@@ -41865,6 +41876,7 @@ var CustomBubbleMenu = ({
41865
41876
  width: editorWindow?.innerWidth ?? window.innerWidth,
41866
41877
  height: editorWindow?.innerHeight ?? window.innerHeight
41867
41878
  },
41879
+ preferredPlacement: placement,
41868
41880
  offset: BUBBLE_MENU_OFFSET
41869
41881
  }));
41870
41882
  if (keepOpenRef.current) {
@@ -41911,7 +41923,7 @@ var CustomBubbleMenu = ({
41911
41923
  editorWindow?.removeEventListener("resize", schedulePositionUpdate);
41912
41924
  editorWindow?.removeEventListener("scroll", schedulePositionUpdate, true);
41913
41925
  };
41914
- }, [editor, editorDocument, editorWindow]);
41926
+ }, [editor, editorDocument, editorWindow, placement]);
41915
41927
  (0, import_react76.useEffect)(() => {
41916
41928
  if (!isVisible || !portalWindow?.ResizeObserver) return;
41917
41929
  const menu = menuRef.current;
@@ -41965,6 +41977,7 @@ var CustomBubbleMenu = ({
41965
41977
  {
41966
41978
  ref: menuRef,
41967
41979
  "data-popover": true,
41980
+ "data-placement": position.placement,
41968
41981
  className: "fixed z-[99999] flex rounded-xl border border-border/40 bg-card text-card-foreground shadow-lg backdrop-blur-sm overflow-hidden animate-in fade-in-0 zoom-in-95",
41969
41982
  style: {
41970
41983
  top: `${position.top}px`,
@@ -46780,6 +46793,7 @@ function getCellFromTarget(target) {
46780
46793
  return null;
46781
46794
  }
46782
46795
  function findTableInfo(editor, pos) {
46796
+ if (!isValidProseMirrorPosition(editor.state.doc, pos)) return null;
46783
46797
  const $pos = editor.state.doc.resolve(pos);
46784
46798
  for (let depth = $pos.depth; depth > 0; depth -= 1) {
46785
46799
  const node = $pos.node(depth);
@@ -46822,6 +46836,7 @@ function buildLogicalColumnMetrics({
46822
46836
  for (const tableCell of Array.from(firstRow.cells)) {
46823
46837
  if (!isTableCellElement(tableCell)) continue;
46824
46838
  const cellPos = editor.view.posAtDOM(tableCell, 0);
46839
+ if (!isValidProseMirrorPosition(editor.state.doc, cellPos)) continue;
46825
46840
  const relativeCellPos = getCellRelativePosFromDomPos(map, tableInfo.start, cellPos);
46826
46841
  if (relativeCellPos == null) continue;
46827
46842
  const cellMapRect = map.findCell(relativeCellPos);
@@ -46895,18 +46910,20 @@ function buildLogicalRowMetrics({
46895
46910
  if (visualRows.length > 0) {
46896
46911
  return visualRows.sort((a, b) => a.index - b.index);
46897
46912
  }
46898
- return rows.map((tableRow, index) => {
46913
+ return rows.flatMap((tableRow, index) => {
46899
46914
  const rowRect = tableRow.getBoundingClientRect();
46900
46915
  const anchorCell = tableRow.cells.item(0) ?? cornerCell;
46901
46916
  const start = rowRect.height > 0 ? rowRect.top - surfaceRect.top - surface.clientTop + surface.scrollTop : tableTop + index * fallbackHeight;
46902
46917
  const size = metricOrFallback(rowRect.height, fallbackHeight);
46903
- return {
46918
+ const cellPos = editor.view.posAtDOM(anchorCell, 0);
46919
+ if (!isValidProseMirrorPosition(editor.state.doc, cellPos)) return [];
46920
+ return [{
46904
46921
  index,
46905
- cellPos: editor.view.posAtDOM(anchorCell, 0),
46922
+ cellPos,
46906
46923
  start,
46907
46924
  size,
46908
46925
  center: start + size / 2
46909
- };
46926
+ }];
46910
46927
  });
46911
46928
  }
46912
46929
  function getTableCellTextSelectionRange(editor, cellPos) {
@@ -46926,6 +46943,7 @@ function getTableCellTextSelectionRange(editor, cellPos) {
46926
46943
  return from !== null && to !== null && from < to ? { from, to } : null;
46927
46944
  }
46928
46945
  function buildTableControlLayout(editor, surface, cell) {
46946
+ if (!editor.view.dom.contains(cell)) return null;
46929
46947
  const row = cell.closest("tr");
46930
46948
  const table = cell.closest("table");
46931
46949
  if (!isTableRowElement(row) || !isTableElement(table)) {
@@ -46934,6 +46952,7 @@ function buildTableControlLayout(editor, surface, cell) {
46934
46952
  const rows = Array.from(table.rows).filter(isTableRowElement);
46935
46953
  const cornerCell = getLastCell(table);
46936
46954
  const cellPos = editor.view.posAtDOM(cell, 0);
46955
+ if (!isValidProseMirrorPosition(editor.state.doc, cellPos)) return null;
46937
46956
  const tableInfo = findTableInfo(editor, cellPos);
46938
46957
  if (rows.length === 0 || !tableInfo || !isTableCellElement(cornerCell)) {
46939
46958
  return null;
@@ -47891,7 +47910,7 @@ function getSelectedCell(editor) {
47891
47910
  const browserSelection = editorWindow?.getSelection();
47892
47911
  const anchorElement = resolveEventElement(browserSelection?.anchorNode ?? null);
47893
47912
  const anchorCell = anchorElement?.closest?.("th,td");
47894
- if (isCrossRealmTableCell(anchorCell)) {
47913
+ if (isCrossRealmTableCell(anchorCell) && editor.view.dom.contains(anchorCell)) {
47895
47914
  return anchorCell;
47896
47915
  }
47897
47916
  const domAtPos = editor.view.domAtPos(editor.state.selection.from);
@@ -49368,12 +49387,12 @@ function getFormulaEditingTableContext(view) {
49368
49387
  if (!getCellText2(node).startsWith("=")) return null;
49369
49388
  const cellPos = $from.before(depth);
49370
49389
  const cellDom = view.nodeDOM(cellPos);
49371
- if (!(cellDom instanceof HTMLTableCellElement)) return null;
49390
+ if (!isCrossRealmTableCell(cellDom) || !view.dom.contains(cellDom)) return null;
49372
49391
  const tableDepth = depth - 2;
49373
49392
  const tableNode = tableDepth > 0 ? $from.node(tableDepth) : null;
49374
49393
  if (!tableNode || tableNode.type.name !== "table") return null;
49375
49394
  const tableDom = cellDom.closest("table");
49376
- if (!(tableDom instanceof HTMLTableElement)) return null;
49395
+ if (!isCrossRealmTable(tableDom) || !view.dom.contains(tableDom)) return null;
49377
49396
  const tableMap = import_tables9.TableMap.get(tableNode);
49378
49397
  const tableStart = $from.start(tableDepth);
49379
49398
  const formulaCellRect = tableMap.findCell(cellPos - tableStart);
@@ -49445,6 +49464,7 @@ function getReferenceInsertionPrefix(view, cellContentStart, insertionPos) {
49445
49464
  return isInsideFunctionArguments && followsReference ? "," : "";
49446
49465
  }
49447
49466
  function findTableForPos(view, pos) {
49467
+ if (!isValidProseMirrorPosition(view.state.doc, pos)) return null;
49448
49468
  const $pos = view.state.doc.resolve(pos);
49449
49469
  for (let depth = $pos.depth; depth > 0; depth -= 1) {
49450
49470
  const node = $pos.node(depth);
@@ -49473,8 +49493,9 @@ function getCellRelativePosFromDomPos2(map, tableStart, domPos) {
49473
49493
  function getFormulaTableCellInfo(view, target, tablePos) {
49474
49494
  const element = resolveEventElement(target);
49475
49495
  const cell = element?.closest?.("th,td");
49476
- if (!(cell instanceof HTMLTableCellElement)) return null;
49496
+ if (!isCrossRealmTableCell(cell) || !view.dom.contains(cell)) return null;
49477
49497
  const domPos = view.posAtDOM(cell, 0);
49498
+ if (!isValidProseMirrorPosition(view.state.doc, domPos)) return null;
49478
49499
  const tableInfo = findTableForPos(view, domPos);
49479
49500
  if (!tableInfo || tableInfo.pos !== tablePos) return null;
49480
49501
  const map = import_tables9.TableMap.get(tableInfo.node);
@@ -50172,6 +50193,7 @@ var UEditor = import_react86.default.forwardRef(({
50172
50193
  autofocus = false,
50173
50194
  showToolbar = true,
50174
50195
  showBubbleMenu = true,
50196
+ bubbleMenuPlacement = "auto",
50175
50197
  showFloatingMenu = false,
50176
50198
  showCharacterCount = true,
50177
50199
  showFooter = true,
@@ -50531,6 +50553,7 @@ var UEditor = import_react86.default.forwardRef(({
50531
50553
  CustomBubbleMenu,
50532
50554
  {
50533
50555
  editor,
50556
+ placement: bubbleMenuPlacement,
50534
50557
  fontSizes,
50535
50558
  lineHeights
50536
50559
  }