@underverse-ui/underverse 1.0.204 → 1.0.205

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,6 +1,6 @@
1
1
  {
2
2
  "package": "@underverse-ui/underverse",
3
- "version": "1.0.204",
3
+ "version": "1.0.205",
4
4
  "sourceEntry": "src/index.ts",
5
5
  "totalExports": 252,
6
6
  "exports": [
@@ -2,13 +2,13 @@
2
2
  import {
3
3
  EmojiPicker,
4
4
  EmojiPicker_default
5
- } from "./chunk-CKKLFVOY.js";
6
- import "./chunk-ZUAIBY2Z.js";
5
+ } from "./chunk-Z63YNF3N.js";
6
+ import "./chunk-IXEFOLUD.js";
7
7
  import "./chunk-4TYW5K4J.js";
8
- import "./chunk-GSBRTFP2.js";
8
+ import "./chunk-XJR7E6QB.js";
9
9
  import "./chunk-NSBPE2FW.js";
10
10
  export {
11
11
  EmojiPicker,
12
12
  EmojiPicker_default as default
13
13
  };
14
- //# sourceMappingURL=EmojiPicker-UN6N7YVB.js.map
14
+ //# sourceMappingURL=EmojiPicker-BAWP2RAS.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  EmojiGridButton,
3
3
  formatEmojiCountLabel
4
- } from "./chunk-ZUAIBY2Z.js";
4
+ } from "./chunk-IXEFOLUD.js";
5
5
  import {
6
6
  COLUMN_RESIZE_LINE_THICKNESS,
7
7
  CellBgColorIcon,
@@ -42,6 +42,7 @@ import {
42
42
  getRelativeSelectedCellsMetrics,
43
43
  getSelectionTableCell,
44
44
  isColumnResizeHotspot,
45
+ isPointOverRenderedText,
45
46
  isRowResizeHotspot,
46
47
  isSafeUEditorUrl,
47
48
  mergeTableCellsPreservingColumnWidths,
@@ -52,12 +53,12 @@ import {
52
53
  sanitizeUEditorUrl,
53
54
  useEditorColors,
54
55
  useSharedEditorUiRenderState
55
- } from "./chunk-KFTYWTJR.js";
56
+ } from "./chunk-MJV7ETJM.js";
56
57
  import {
57
58
  Tooltip,
58
59
  cn,
59
60
  useSmartTranslations
60
- } from "./chunk-GSBRTFP2.js";
61
+ } from "./chunk-XJR7E6QB.js";
61
62
 
62
63
  // src/components/UEditor/prepare-content-for-save.ts
63
64
  var MIME_EXTENSION_MAP = {
@@ -472,7 +473,7 @@ async function prepareUEditorContentForSave({
472
473
  }
473
474
 
474
475
  // src/components/UEditor/UEditor.tsx
475
- import React14, { useEffect as useEffect9, useImperativeHandle as useImperativeHandle4, useMemo as useMemo2, useRef as useRef9 } from "react";
476
+ import React15, { useEffect as useEffect10, useImperativeHandle as useImperativeHandle4, useMemo as useMemo2, useRef as useRef10 } from "react";
476
477
  import { useEditor, EditorContent } from "@tiptap/react";
477
478
 
478
479
  // src/components/UEditor/extensions.ts
@@ -507,7 +508,7 @@ import { NodeViewWrapper, NodeViewContent } from "@tiptap/react";
507
508
  import React from "react";
508
509
  import { jsx } from "react/jsx-runtime";
509
510
  var LazyBaseEmojiPicker = React.lazy(async () => {
510
- const { EmojiPicker: EmojiPicker2 } = await import("./EmojiPicker-UN6N7YVB.js");
511
+ const { EmojiPicker: EmojiPicker2 } = await import("./EmojiPicker-BAWP2RAS.js");
511
512
  return { default: EmojiPicker2 };
512
513
  });
513
514
  var EmojiPicker = ({ onSelect }) => {
@@ -11457,6 +11458,22 @@ function buildLogicalRowMetrics({
11457
11458
  };
11458
11459
  });
11459
11460
  }
11461
+ function getTableCellTextSelectionRange(editor, cellPos) {
11462
+ const cellNode = editor.state.doc.nodeAt(cellPos);
11463
+ if (!cellNode || cellNode.type.name !== "tableCell" && cellNode.type.name !== "tableHeader") {
11464
+ return null;
11465
+ }
11466
+ let from = null;
11467
+ let to = null;
11468
+ cellNode.descendants((node, relativePos) => {
11469
+ if (!node.isText || node.nodeSize === 0) return true;
11470
+ const textStart = cellPos + 1 + relativePos;
11471
+ from ?? (from = textStart);
11472
+ to = textStart + node.nodeSize;
11473
+ return true;
11474
+ });
11475
+ return from !== null && to !== null && from < to ? { from, to } : null;
11476
+ }
11460
11477
  function buildTableControlLayout(editor, surface, cell) {
11461
11478
  const row = cell.closest("tr");
11462
11479
  const table = cell.closest("table");
@@ -11562,6 +11579,9 @@ function buildTableHoverState({
11562
11579
  layout,
11563
11580
  surface
11564
11581
  }) {
11582
+ if (event.buttons !== 0) {
11583
+ return DEFAULT_TABLE_HOVER_STATE;
11584
+ }
11565
11585
  const surfaceRect = surface.getBoundingClientRect();
11566
11586
  const relativeX = event.clientX - surfaceRect.left + surface.scrollLeft;
11567
11587
  const relativeY = event.clientY - surfaceRect.top + surface.scrollTop;
@@ -11571,8 +11591,8 @@ function buildTableHoverState({
11571
11591
  const directTableMenu = targetElement?.closest?.("[data-table-control='table-menu']");
11572
11592
  const directAddColumn = targetElement?.closest?.("[data-table-control='add-column']");
11573
11593
  const directAddRow = targetElement?.closest?.("[data-table-control='add-row']");
11574
- const directRowHandleIndex = directRowHandle instanceof HTMLElement ? Number.parseInt(directRowHandle.dataset.rowHandleIndex ?? "", 10) : Number.NaN;
11575
- const directColumnHandleIndex = directColumnHandle instanceof HTMLElement ? Number.parseInt(directColumnHandle.dataset.columnHandleIndex ?? "", 10) : Number.NaN;
11594
+ const directRowHandleIndex = directRowHandle instanceof HTMLElement && relativeX <= layout.tableLeft ? Number.parseInt(directRowHandle.dataset.rowHandleIndex ?? "", 10) : Number.NaN;
11595
+ const directColumnHandleIndex = directColumnHandle instanceof HTMLElement && relativeY <= layout.tableTop ? Number.parseInt(directColumnHandle.dataset.columnHandleIndex ?? "", 10) : Number.NaN;
11576
11596
  const visibleBounds = getVisibleTableBounds(layout);
11577
11597
  const rowRailTop = layout.wrapperTop + layout.wrapperHeight;
11578
11598
  const isMouseInTable = relativeX >= layout.tableLeft && relativeX <= layout.tableLeft + layout.tableWidth && relativeY >= layout.tableTop && relativeY <= layout.tableTop + layout.tableHeight;
@@ -11883,7 +11903,8 @@ function TableRowHandles({
11883
11903
  "data-row-handle-index": rowHandle.index,
11884
11904
  style: {
11885
11905
  top: Math.max(8, rowHandle.center - 12),
11886
- left: rowHandleLeft
11906
+ left: rowHandleLeft,
11907
+ pointerEvents: visible ? "auto" : "none"
11887
11908
  },
11888
11909
  children: /* @__PURE__ */ jsx16(
11889
11910
  Tooltip,
@@ -11916,7 +11937,10 @@ function TableRowHandles({
11916
11937
  style: {
11917
11938
  opacity: isShown ? 1 : 0,
11918
11939
  transform: isShown ? "scale(1)" : `scale(${IDLE_HANDLE_SCALE})`,
11919
- pointerEvents: isShown ? "auto" : "none"
11940
+ // The idle marker is only a location hint. Keeping it
11941
+ // pointer-transparent prevents it from stealing a text
11942
+ // selection near the first character of a table cell.
11943
+ pointerEvents: visible ? "auto" : "none"
11920
11944
  },
11921
11945
  children: visible ? /* @__PURE__ */ jsx16(GripVertical, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx16("div", { className: "h-3 w-1 rounded-full bg-muted-foreground/50 hover:bg-muted-foreground" })
11922
11946
  }
@@ -11954,7 +11978,8 @@ function TableColumnHandles({
11954
11978
  "data-column-handle-index": columnHandle.index,
11955
11979
  style: {
11956
11980
  top: columnHandleTop,
11957
- left: Math.max(8, columnHandle.center - 12)
11981
+ left: Math.max(8, columnHandle.center - 12),
11982
+ pointerEvents: visible ? "auto" : "none"
11958
11983
  },
11959
11984
  children: /* @__PURE__ */ jsx16(
11960
11985
  Tooltip,
@@ -11987,7 +12012,7 @@ function TableColumnHandles({
11987
12012
  style: {
11988
12013
  opacity: isShown ? 1 : 0,
11989
12014
  transform: isShown ? "scale(1)" : `scale(${IDLE_HANDLE_SCALE})`,
11990
- pointerEvents: isShown ? "auto" : "none"
12015
+ pointerEvents: visible ? "auto" : "none"
11991
12016
  },
11992
12017
  children: visible ? /* @__PURE__ */ jsx16(GripHorizontal, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx16("div", { className: "h-1 w-3 rounded-full bg-muted-foreground/50 hover:bg-muted-foreground" })
11993
12018
  }
@@ -12233,6 +12258,7 @@ function applyTableSize(editor, snapshot, dimensions) {
12233
12258
  // src/components/UEditor/table-controls.tsx
12234
12259
  import { Fragment as Fragment6, jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
12235
12260
  var TABLE_MENU_TOP_OFFSET = 10;
12261
+ var AXIS_HANDLE_RADIUS = 12;
12236
12262
  function nearestIndex(centers, position) {
12237
12263
  let bestIndex = 0;
12238
12264
  let bestDistance = Number.POSITIVE_INFINITY;
@@ -12410,6 +12436,20 @@ function TableControls({ editor, containerRef, showCellInspector = true }) {
12410
12436
  const surface2 = containerRef.current;
12411
12437
  const nextLayout = surface2 ? buildTableControlLayout(editor, surface2, cell) : null;
12412
12438
  if (!nextLayout) return;
12439
+ if (isPointOverRenderedText(cell, event.clientX, event.clientY)) {
12440
+ const textSelection = getTableCellTextSelectionRange(editor, nextLayout.cellPos);
12441
+ if (textSelection) {
12442
+ event.preventDefault();
12443
+ const didSelectText = editor.commands.setTextSelection(textSelection);
12444
+ if (didSelectText) {
12445
+ editor.view.focus();
12446
+ layoutRef.current = nextLayout;
12447
+ setLayout(nextLayout);
12448
+ setHoverState(DEFAULT_TABLE_HOVER_STATE);
12449
+ return;
12450
+ }
12451
+ }
12452
+ }
12413
12453
  const didSelect = editor.commands.setCellSelection({
12414
12454
  anchorCell: nextLayout.cellPos,
12415
12455
  headCell: nextLayout.cellPos
@@ -12876,8 +12916,8 @@ function TableControls({ editor, containerRef, showCellInspector = true }) {
12876
12916
  }
12877
12917
  const menuTop = Math.max(8, layout.tableTop - TABLE_MENU_TOP_OFFSET);
12878
12918
  const menuLeft = Math.max(8, layout.tableLeft);
12879
- const rowHandleLeft = layout.tableLeft - 12;
12880
- const columnHandleTop = layout.tableTop - 12;
12919
+ const rowHandleLeft = layout.tableLeft - AXIS_HANDLE_RADIUS;
12920
+ const columnHandleTop = layout.tableTop - AXIS_HANDLE_RADIUS;
12881
12921
  return /* @__PURE__ */ jsxs15(Fragment6, { children: [
12882
12922
  /* @__PURE__ */ jsx18(
12883
12923
  TableRowHandles,
@@ -14051,17 +14091,85 @@ function TableFormulaBar({ editor }) {
14051
14091
  );
14052
14092
  }
14053
14093
 
14094
+ // src/components/UEditor/use-editor-output.ts
14095
+ import * as React14 from "react";
14096
+ function normalizeDebounceMs(value) {
14097
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
14098
+ }
14099
+ function useUEditorOutput({
14100
+ onChange,
14101
+ onHtmlChange,
14102
+ onJsonChange,
14103
+ outputDebounceMs
14104
+ }) {
14105
+ const callbacksRef = React14.useRef({});
14106
+ const pendingEditorRef = React14.useRef(null);
14107
+ const timeoutRef = React14.useRef(null);
14108
+ const debounceMs = normalizeDebounceMs(outputDebounceMs);
14109
+ callbacksRef.current = { onChange, onHtmlChange, onJsonChange };
14110
+ const flushOutputUpdates = React14.useCallback(() => {
14111
+ if (timeoutRef.current !== null) {
14112
+ clearTimeout(timeoutRef.current);
14113
+ timeoutRef.current = null;
14114
+ }
14115
+ const editor = pendingEditorRef.current;
14116
+ pendingEditorRef.current = null;
14117
+ if (!editor || editor.isDestroyed) return;
14118
+ const callbacks = callbacksRef.current;
14119
+ if (callbacks.onChange || callbacks.onHtmlChange) {
14120
+ const html = editor.getHTML();
14121
+ callbacks.onChange?.(html);
14122
+ callbacks.onHtmlChange?.(html);
14123
+ }
14124
+ if (callbacks.onJsonChange) {
14125
+ callbacks.onJsonChange(editor.getJSON());
14126
+ }
14127
+ }, []);
14128
+ const scheduleOutputUpdate = React14.useCallback((editor) => {
14129
+ const callbacks = callbacksRef.current;
14130
+ if (!callbacks.onChange && !callbacks.onHtmlChange && !callbacks.onJsonChange) return;
14131
+ pendingEditorRef.current = editor;
14132
+ if (timeoutRef.current !== null) {
14133
+ clearTimeout(timeoutRef.current);
14134
+ timeoutRef.current = null;
14135
+ }
14136
+ if (debounceMs === 0) {
14137
+ flushOutputUpdates();
14138
+ return;
14139
+ }
14140
+ timeoutRef.current = setTimeout(flushOutputUpdates, debounceMs);
14141
+ }, [debounceMs, flushOutputUpdates]);
14142
+ React14.useEffect(() => {
14143
+ if (!pendingEditorRef.current || timeoutRef.current === null) return;
14144
+ clearTimeout(timeoutRef.current);
14145
+ timeoutRef.current = debounceMs === 0 ? null : setTimeout(flushOutputUpdates, debounceMs);
14146
+ if (debounceMs === 0) flushOutputUpdates();
14147
+ }, [debounceMs, flushOutputUpdates]);
14148
+ React14.useEffect(() => () => {
14149
+ if (timeoutRef.current !== null) {
14150
+ clearTimeout(timeoutRef.current);
14151
+ timeoutRef.current = null;
14152
+ }
14153
+ pendingEditorRef.current = null;
14154
+ }, []);
14155
+ return {
14156
+ flushOutputUpdates,
14157
+ scheduleOutputUpdate
14158
+ };
14159
+ }
14160
+
14054
14161
  // src/components/UEditor/UEditor.tsx
14055
14162
  import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
14056
- var LazyMenuBar = React14.lazy(async () => {
14057
- const { MenuBar } = await import("./menu-bar-6U5S4PS7.js");
14163
+ var LazyMenuBar = React15.lazy(async () => {
14164
+ const { MenuBar } = await import("./menu-bar-NDAP3SOR.js");
14058
14165
  return { default: MenuBar };
14059
14166
  });
14060
- var UEditor = React14.forwardRef(({
14167
+ var UEditor = React15.forwardRef(({
14061
14168
  content = "",
14062
14169
  onChange,
14063
14170
  onHtmlChange,
14064
14171
  onJsonChange,
14172
+ outputDebounceMs = 0,
14065
14173
  uploadImage,
14066
14174
  uploadImageForSave,
14067
14175
  uploadImageConcurrency = 3,
@@ -14099,15 +14207,21 @@ var UEditor = React14.forwardRef(({
14099
14207
  }, ref) => {
14100
14208
  const t = useSmartTranslations("UEditor");
14101
14209
  const effectivePlaceholder = placeholder ?? t("placeholder");
14102
- const inFlightPrepareRef = useRef9(null);
14103
- const lastAppliedContentRef = useRef9(content ?? "");
14104
- const scheduledFormulaRecalculateRef = useRef9(false);
14105
- const pendingFormulaTextRecalculateRef = useRef9(false);
14106
- const editorInstanceRef = useRef9(null);
14107
- const formulaRangePickRef = useRef9(null);
14108
- const formulaRangeSurfaceRef = useRef9(null);
14109
- const [formulaRangeHighlight, setFormulaRangeHighlight] = React14.useState(null);
14110
- const scheduleFormulaRecalculate = React14.useCallback((editor2, options) => {
14210
+ const inFlightPrepareRef = useRef10(null);
14211
+ const lastAppliedContentRef = useRef10(content ?? "");
14212
+ const scheduledFormulaRecalculateRef = useRef10(false);
14213
+ const pendingFormulaTextRecalculateRef = useRef10(false);
14214
+ const editorInstanceRef = useRef10(null);
14215
+ const formulaRangePickRef = useRef10(null);
14216
+ const formulaRangeSurfaceRef = useRef10(null);
14217
+ const [formulaRangeHighlight, setFormulaRangeHighlight] = React15.useState(null);
14218
+ const { flushOutputUpdates, scheduleOutputUpdate } = useUEditorOutput({
14219
+ onChange,
14220
+ onHtmlChange,
14221
+ onJsonChange,
14222
+ outputDebounceMs
14223
+ });
14224
+ const scheduleFormulaRecalculate = React15.useCallback((editor2, options) => {
14111
14225
  if (editor2.isDestroyed || scheduledFormulaRecalculateRef.current) return;
14112
14226
  if (!options?.force && isEditingTableFormulaText(editor2)) return;
14113
14227
  scheduledFormulaRecalculateRef.current = true;
@@ -14147,7 +14261,7 @@ var UEditor = React14.forwardRef(({
14147
14261
  ],
14148
14262
  [effectivePlaceholder, t, maxCharacters, uploadImage, resolvedUploadFile, imageInsertMode, maxImageFileSize, allowedImageMimeTypes, fallbackToDataUrl, editable, fetchMetadata, extraExtensions]
14149
14263
  );
14150
- const syncFormulaRangeHighlight = React14.useCallback((pickState) => {
14264
+ const syncFormulaRangeHighlight = React15.useCallback((pickState) => {
14151
14265
  const container = formulaRangeSurfaceRef.current;
14152
14266
  setFormulaRangeHighlight(container && pickState ? getFormulaRangePickHighlight(container, pickState) : null);
14153
14267
  }, []);
@@ -14248,14 +14362,7 @@ var UEditor = React14.forwardRef(({
14248
14362
  pendingFormulaTextRecalculateRef.current = false;
14249
14363
  }
14250
14364
  }
14251
- if (onChange || onHtmlChange) {
14252
- const html = editor2.getHTML();
14253
- onChange?.(html);
14254
- onHtmlChange?.(html);
14255
- }
14256
- if (onJsonChange) {
14257
- onJsonChange(editor2.getJSON());
14258
- }
14365
+ scheduleOutputUpdate(editor2);
14259
14366
  },
14260
14367
  onSelectionUpdate: ({ editor: editor2 }) => {
14261
14368
  if (pendingFormulaTextRecalculateRef.current && !isEditingTableFormulaText(editor2)) {
@@ -14269,9 +14376,10 @@ var UEditor = React14.forwardRef(({
14269
14376
  const shouldRecalculate = pendingFormulaTextRecalculateRef.current;
14270
14377
  pendingFormulaTextRecalculateRef.current = false;
14271
14378
  if (shouldRecalculate) scheduleFormulaRecalculate(editor2, { force: true });
14379
+ queueMicrotask(flushOutputUpdates);
14272
14380
  }
14273
14381
  });
14274
- useEffect9(() => {
14382
+ useEffect10(() => {
14275
14383
  editorInstanceRef.current = editor;
14276
14384
  return () => {
14277
14385
  if (editorInstanceRef.current === editor) editorInstanceRef.current = null;
@@ -14312,7 +14420,7 @@ var UEditor = React14.forwardRef(({
14312
14420
  }),
14313
14421
  [content, editor, uploadImageForSave, uploadFileForSave, uploadImageConcurrency]
14314
14422
  );
14315
- useEffect9(() => {
14423
+ useEffect10(() => {
14316
14424
  if (!editor) return;
14317
14425
  queueMicrotask(() => {
14318
14426
  if (!editor.isDestroyed) {
@@ -14320,7 +14428,7 @@ var UEditor = React14.forwardRef(({
14320
14428
  }
14321
14429
  });
14322
14430
  }, [editor]);
14323
- useEffect9(() => {
14431
+ useEffect10(() => {
14324
14432
  if (!editor) return;
14325
14433
  const nextContent = content ?? "";
14326
14434
  if (lastAppliedContentRef.current === nextContent) return;
@@ -14365,7 +14473,7 @@ var UEditor = React14.forwardRef(({
14365
14473
  ),
14366
14474
  children: [
14367
14475
  editable && (showMenuBar || showToolbar || showBubbleMenu) ? /* @__PURE__ */ jsxs17(EditorUiRenderStateProvider, { editor, children: [
14368
- showMenuBar && /* @__PURE__ */ jsx20(React14.Suspense, { fallback: null, children: /* @__PURE__ */ jsx20(
14476
+ showMenuBar && /* @__PURE__ */ jsx20(React15.Suspense, { fallback: null, children: /* @__PURE__ */ jsx20(
14369
14477
  LazyMenuBar,
14370
14478
  {
14371
14479
  editor,
@@ -14503,4 +14611,4 @@ export {
14503
14611
  prepareUEditorContentForSave,
14504
14612
  UEditor_default
14505
14613
  };
14506
- //# sourceMappingURL=chunk-CC3QO2YM.js.map
14614
+ //# sourceMappingURL=chunk-2V6A6PGI.js.map