@underverse-ui/underverse 1.0.141 → 1.0.142
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/api-reference.json +1 -1
- package/dist/index.cjs +121 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +121 -30
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -25261,6 +25261,7 @@ import Typography from "@tiptap/extension-typography";
|
|
|
25261
25261
|
import Subscript from "@tiptap/extension-subscript";
|
|
25262
25262
|
import Superscript from "@tiptap/extension-superscript";
|
|
25263
25263
|
import HorizontalRule from "@tiptap/extension-horizontal-rule";
|
|
25264
|
+
import Gapcursor from "@tiptap/extension-gapcursor";
|
|
25264
25265
|
import { common, createLowlight } from "lowlight";
|
|
25265
25266
|
|
|
25266
25267
|
// src/components/UEditor/slash-command.tsx
|
|
@@ -26051,7 +26052,6 @@ import { mergeAttributes as mergeAttributes4 } from "@tiptap/core";
|
|
|
26051
26052
|
import { NodeViewWrapper as NodeViewWrapper4, ReactNodeViewRenderer as ReactNodeViewRenderer4 } from "@tiptap/react";
|
|
26052
26053
|
import { jsx as jsx81, jsxs as jsxs67 } from "react/jsx-runtime";
|
|
26053
26054
|
var MIN_IMAGE_SIZE_PX = 40;
|
|
26054
|
-
var AXIS_LOCK_THRESHOLD_PX = 4;
|
|
26055
26055
|
var IMAGE_LAYOUTS = /* @__PURE__ */ new Set(["block", "left", "right"]);
|
|
26056
26056
|
var IMAGE_WIDTH_PRESETS = /* @__PURE__ */ new Set(["sm", "md", "lg"]);
|
|
26057
26057
|
function toNullableNumber(value) {
|
|
@@ -26092,6 +26092,41 @@ function getImageLayoutStyles(layout) {
|
|
|
26092
26092
|
}
|
|
26093
26093
|
return {};
|
|
26094
26094
|
}
|
|
26095
|
+
function getAspectRatio({
|
|
26096
|
+
img,
|
|
26097
|
+
widthAttr,
|
|
26098
|
+
heightAttr,
|
|
26099
|
+
fallbackWidth,
|
|
26100
|
+
fallbackHeight
|
|
26101
|
+
}) {
|
|
26102
|
+
if (widthAttr && heightAttr) return widthAttr / heightAttr;
|
|
26103
|
+
if (img.naturalWidth > 0 && img.naturalHeight > 0) return img.naturalWidth / img.naturalHeight;
|
|
26104
|
+
if (fallbackWidth > 0 && fallbackHeight > 0) return fallbackWidth / fallbackHeight;
|
|
26105
|
+
return 1;
|
|
26106
|
+
}
|
|
26107
|
+
function sizeFromWidth(width, aspect, maxWidth) {
|
|
26108
|
+
let nextW = clamp8(width, MIN_IMAGE_SIZE_PX, maxWidth);
|
|
26109
|
+
let nextH = nextW / aspect;
|
|
26110
|
+
if (nextH < MIN_IMAGE_SIZE_PX) {
|
|
26111
|
+
nextH = MIN_IMAGE_SIZE_PX;
|
|
26112
|
+
nextW = clamp8(nextH * aspect, MIN_IMAGE_SIZE_PX, maxWidth);
|
|
26113
|
+
nextH = nextW / aspect;
|
|
26114
|
+
}
|
|
26115
|
+
return { width: nextW, height: nextH };
|
|
26116
|
+
}
|
|
26117
|
+
function sizeFromHeight(height, aspect, maxWidth) {
|
|
26118
|
+
let nextH = Math.max(MIN_IMAGE_SIZE_PX, height);
|
|
26119
|
+
let nextW = nextH * aspect;
|
|
26120
|
+
if (nextW > maxWidth) {
|
|
26121
|
+
nextW = maxWidth;
|
|
26122
|
+
nextH = nextW / aspect;
|
|
26123
|
+
}
|
|
26124
|
+
if (nextW < MIN_IMAGE_SIZE_PX) {
|
|
26125
|
+
nextW = MIN_IMAGE_SIZE_PX;
|
|
26126
|
+
nextH = nextW / aspect;
|
|
26127
|
+
}
|
|
26128
|
+
return { width: nextW, height: nextH };
|
|
26129
|
+
}
|
|
26095
26130
|
function ResizableImageNodeView(props) {
|
|
26096
26131
|
const { node, selected, updateAttributes, editor, getPos } = props;
|
|
26097
26132
|
const wrapperRef = useRef29(null);
|
|
@@ -26102,7 +26137,6 @@ function ResizableImageNodeView(props) {
|
|
|
26102
26137
|
const heightAttr = toNullableNumber(node.attrs["height"]);
|
|
26103
26138
|
const textAlign = String(node.attrs["textAlign"] ?? "");
|
|
26104
26139
|
const imageLayout = parseImageLayout(node.attrs["imageLayout"]);
|
|
26105
|
-
const preserveAspectByDefault = imageLayout === "left" || imageLayout === "right";
|
|
26106
26140
|
const dragStateRef = useRef29(null);
|
|
26107
26141
|
useEffect34(() => {
|
|
26108
26142
|
const img = imgRef.current;
|
|
@@ -26126,7 +26160,13 @@ function ResizableImageNodeView(props) {
|
|
|
26126
26160
|
const maxW = editorEl ? editorEl.getBoundingClientRect().width : Number.POSITIVE_INFINITY;
|
|
26127
26161
|
const startW = Math.max(MIN_IMAGE_SIZE_PX, rect.width);
|
|
26128
26162
|
const startH = Math.max(MIN_IMAGE_SIZE_PX, rect.height);
|
|
26129
|
-
const aspect =
|
|
26163
|
+
const aspect = getAspectRatio({
|
|
26164
|
+
img,
|
|
26165
|
+
widthAttr,
|
|
26166
|
+
heightAttr,
|
|
26167
|
+
fallbackWidth: startW,
|
|
26168
|
+
fallbackHeight: startH
|
|
26169
|
+
});
|
|
26130
26170
|
dragStateRef.current = {
|
|
26131
26171
|
pointerId: event.pointerId,
|
|
26132
26172
|
startX: event.clientX,
|
|
@@ -26135,7 +26175,6 @@ function ResizableImageNodeView(props) {
|
|
|
26135
26175
|
startH,
|
|
26136
26176
|
lastW: startW,
|
|
26137
26177
|
lastH: startH,
|
|
26138
|
-
axis: null,
|
|
26139
26178
|
aspect,
|
|
26140
26179
|
maxW: Math.max(MIN_IMAGE_SIZE_PX, maxW)
|
|
26141
26180
|
};
|
|
@@ -26149,24 +26188,9 @@ function ResizableImageNodeView(props) {
|
|
|
26149
26188
|
if (event.pointerId !== drag.pointerId) return;
|
|
26150
26189
|
const dx = event.clientX - drag.startX;
|
|
26151
26190
|
const dy = event.clientY - drag.startY;
|
|
26152
|
-
|
|
26153
|
-
|
|
26154
|
-
const
|
|
26155
|
-
if (shouldPreserveAspect) {
|
|
26156
|
-
if (Math.abs(dx) >= Math.abs(dy)) {
|
|
26157
|
-
nextW = clamp8(drag.startW + dx, MIN_IMAGE_SIZE_PX, drag.maxW);
|
|
26158
|
-
nextH = clamp8(nextW / drag.aspect, MIN_IMAGE_SIZE_PX, Number.POSITIVE_INFINITY);
|
|
26159
|
-
} else {
|
|
26160
|
-
nextH = clamp8(drag.startH + dy, MIN_IMAGE_SIZE_PX, Number.POSITIVE_INFINITY);
|
|
26161
|
-
nextW = clamp8(nextH * drag.aspect, MIN_IMAGE_SIZE_PX, drag.maxW);
|
|
26162
|
-
}
|
|
26163
|
-
} else {
|
|
26164
|
-
if (!drag.axis && (Math.abs(dx) > AXIS_LOCK_THRESHOLD_PX || Math.abs(dy) > AXIS_LOCK_THRESHOLD_PX)) {
|
|
26165
|
-
drag.axis = Math.abs(dx) >= Math.abs(dy) ? "x" : "y";
|
|
26166
|
-
}
|
|
26167
|
-
if (drag.axis === "x") nextW = clamp8(drag.startW + dx, MIN_IMAGE_SIZE_PX, drag.maxW);
|
|
26168
|
-
if (drag.axis === "y") nextH = clamp8(drag.startH + dy, MIN_IMAGE_SIZE_PX, Number.POSITIVE_INFINITY);
|
|
26169
|
-
}
|
|
26191
|
+
const nextSize = Math.abs(dx) >= Math.abs(dy) ? sizeFromWidth(drag.startW + dx, drag.aspect, drag.maxW) : sizeFromHeight(drag.startH + dy, drag.aspect, drag.maxW);
|
|
26192
|
+
const nextW = nextSize.width;
|
|
26193
|
+
const nextH = nextSize.height;
|
|
26170
26194
|
drag.lastW = nextW;
|
|
26171
26195
|
drag.lastH = nextH;
|
|
26172
26196
|
img.style.width = `${Math.round(nextW)}px`;
|
|
@@ -27089,6 +27113,7 @@ function buildUEditorExtensions({
|
|
|
27089
27113
|
}
|
|
27090
27114
|
}),
|
|
27091
27115
|
HorizontalRule,
|
|
27116
|
+
Gapcursor,
|
|
27092
27117
|
Link.configure({
|
|
27093
27118
|
openOnClick: false,
|
|
27094
27119
|
protocols: ["http", "https", "mailto", "tel"],
|
|
@@ -27475,6 +27500,43 @@ function isSelectedImage(editor) {
|
|
|
27475
27500
|
const { selection } = editor.state;
|
|
27476
27501
|
return selection instanceof NodeSelection && selection.node.type.name === "image";
|
|
27477
27502
|
}
|
|
27503
|
+
function toPositiveNumber(value) {
|
|
27504
|
+
if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
|
|
27505
|
+
if (typeof value === "string") {
|
|
27506
|
+
const parsed = Number.parseInt(value, 10);
|
|
27507
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
|
|
27508
|
+
}
|
|
27509
|
+
return null;
|
|
27510
|
+
}
|
|
27511
|
+
function getImageElementAtSelection(editor, pos) {
|
|
27512
|
+
const nodeDom = editor.view.nodeDOM(pos);
|
|
27513
|
+
if (!(nodeDom instanceof HTMLElement)) return null;
|
|
27514
|
+
if (nodeDom.tagName === "IMG") return nodeDom;
|
|
27515
|
+
return nodeDom.querySelector("img");
|
|
27516
|
+
}
|
|
27517
|
+
function getImageAspectRatio(editor, attrs, pos) {
|
|
27518
|
+
const widthAttr = toPositiveNumber(attrs.width);
|
|
27519
|
+
const heightAttr = toPositiveNumber(attrs.height);
|
|
27520
|
+
if (widthAttr && heightAttr) return widthAttr / heightAttr;
|
|
27521
|
+
const imageElement = typeof pos === "number" ? getImageElementAtSelection(editor, pos) : null;
|
|
27522
|
+
if (!imageElement) return null;
|
|
27523
|
+
if (imageElement.naturalWidth > 0 && imageElement.naturalHeight > 0) {
|
|
27524
|
+
return imageElement.naturalWidth / imageElement.naturalHeight;
|
|
27525
|
+
}
|
|
27526
|
+
const rect = imageElement.getBoundingClientRect();
|
|
27527
|
+
if (rect.width > 0 && rect.height > 0) return rect.width / rect.height;
|
|
27528
|
+
const width = toPositiveNumber(imageElement.getAttribute("width")) ?? toPositiveNumber(imageElement.style.width);
|
|
27529
|
+
const height = toPositiveNumber(imageElement.getAttribute("height")) ?? toPositiveNumber(imageElement.style.height);
|
|
27530
|
+
return width && height ? width / height : null;
|
|
27531
|
+
}
|
|
27532
|
+
function getImagePresetAttributes(editor, width, preset, attrs, pos) {
|
|
27533
|
+
const aspect = getImageAspectRatio(editor, attrs, pos);
|
|
27534
|
+
return {
|
|
27535
|
+
width,
|
|
27536
|
+
height: aspect ? Math.round(width / aspect) : toPositiveNumber(attrs.height),
|
|
27537
|
+
imageWidthPreset: preset
|
|
27538
|
+
};
|
|
27539
|
+
}
|
|
27478
27540
|
function applyImageLayout(editor, layout) {
|
|
27479
27541
|
const { state, view } = editor;
|
|
27480
27542
|
const { selection, schema } = state;
|
|
@@ -27509,15 +27571,15 @@ function applyImageWidthPreset(editor, preset) {
|
|
|
27509
27571
|
const mode = attrs.imageLayout === "left" || attrs.imageLayout === "right" ? "wrap" : "block";
|
|
27510
27572
|
const width = IMAGE_WIDTHS_BY_LAYOUT[mode][preset];
|
|
27511
27573
|
if (!isSelectedImage(editor)) {
|
|
27512
|
-
editor.chain().focus().updateAttributes("image",
|
|
27574
|
+
editor.chain().focus().updateAttributes("image", getImagePresetAttributes(editor, width, preset, attrs)).run();
|
|
27513
27575
|
return;
|
|
27514
27576
|
}
|
|
27515
27577
|
const { state, view } = editor;
|
|
27516
27578
|
const selection = state.selection;
|
|
27579
|
+
const nextAttrs = getImagePresetAttributes(editor, width, preset, selection.node.attrs, selection.from);
|
|
27517
27580
|
const transaction = state.tr.setNodeMarkup(selection.from, void 0, {
|
|
27518
27581
|
...selection.node.attrs,
|
|
27519
|
-
|
|
27520
|
-
imageWidthPreset: preset
|
|
27582
|
+
...nextAttrs
|
|
27521
27583
|
});
|
|
27522
27584
|
view.dispatch(transaction.scrollIntoView());
|
|
27523
27585
|
view.focus();
|
|
@@ -29465,10 +29527,22 @@ var CustomBubbleMenu = ({
|
|
|
29465
29527
|
setIsVisible(false);
|
|
29466
29528
|
return;
|
|
29467
29529
|
}
|
|
29468
|
-
|
|
29469
|
-
|
|
29470
|
-
|
|
29471
|
-
|
|
29530
|
+
let start;
|
|
29531
|
+
let end;
|
|
29532
|
+
try {
|
|
29533
|
+
start = view.coordsAtPos(from);
|
|
29534
|
+
end = view.coordsAtPos(to);
|
|
29535
|
+
} catch {
|
|
29536
|
+
clearShowTimeout();
|
|
29537
|
+
setIsVisible(false);
|
|
29538
|
+
return;
|
|
29539
|
+
}
|
|
29540
|
+
const viewportPadding = 8;
|
|
29541
|
+
const left = Math.min(
|
|
29542
|
+
window.innerWidth - viewportPadding,
|
|
29543
|
+
Math.max(viewportPadding, (start.left + end.left) / 2)
|
|
29544
|
+
);
|
|
29545
|
+
const top = Math.max(viewportPadding, start.top - BUBBLE_MENU_OFFSET);
|
|
29472
29546
|
setPosition({ top, left });
|
|
29473
29547
|
if (keepOpenRef.current) {
|
|
29474
29548
|
clearShowTimeout();
|
|
@@ -29490,11 +29564,17 @@ var CustomBubbleMenu = ({
|
|
|
29490
29564
|
editor.on("selectionUpdate", updatePosition);
|
|
29491
29565
|
editor.on("focus", updatePosition);
|
|
29492
29566
|
editor.on("blur", handleBlur);
|
|
29567
|
+
editor.on("transaction", updatePosition);
|
|
29568
|
+
editor.on("update", updatePosition);
|
|
29569
|
+
const animationFrameId = requestAnimationFrame(updatePosition);
|
|
29493
29570
|
return () => {
|
|
29571
|
+
cancelAnimationFrame(animationFrameId);
|
|
29494
29572
|
clearShowTimeout();
|
|
29495
29573
|
editor.off("selectionUpdate", updatePosition);
|
|
29496
29574
|
editor.off("focus", updatePosition);
|
|
29497
29575
|
editor.off("blur", handleBlur);
|
|
29576
|
+
editor.off("transaction", updatePosition);
|
|
29577
|
+
editor.off("update", updatePosition);
|
|
29498
29578
|
};
|
|
29499
29579
|
}, [editor]);
|
|
29500
29580
|
if (!isVisible) return null;
|
|
@@ -29504,7 +29584,7 @@ var CustomBubbleMenu = ({
|
|
|
29504
29584
|
{
|
|
29505
29585
|
ref: menuRef,
|
|
29506
29586
|
"data-popover": true,
|
|
29507
|
-
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",
|
|
29587
|
+
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",
|
|
29508
29588
|
style: {
|
|
29509
29589
|
top: `${position.top}px`,
|
|
29510
29590
|
left: `${position.left}px`,
|
|
@@ -35427,6 +35507,17 @@ var UEDITOR_PROSEMIRROR_CLASS_NAME = cn(
|
|
|
35427
35507
|
"[&_.is-editor-empty]:before:float-left",
|
|
35428
35508
|
"[&_.is-editor-empty]:before:pointer-events-none",
|
|
35429
35509
|
"[&_.is-editor-empty]:before:h-0",
|
|
35510
|
+
"[&_.ProseMirror-gapcursor]:pointer-events-none",
|
|
35511
|
+
"[&_.ProseMirror-gapcursor]:absolute",
|
|
35512
|
+
"[&_.ProseMirror-gapcursor]:hidden",
|
|
35513
|
+
"[&_.ProseMirror-gapcursor:after]:content-['']",
|
|
35514
|
+
"[&_.ProseMirror-gapcursor:after]:block",
|
|
35515
|
+
"[&_.ProseMirror-gapcursor:after]:absolute",
|
|
35516
|
+
"[&_.ProseMirror-gapcursor:after]:top-[-2px]",
|
|
35517
|
+
"[&_.ProseMirror-gapcursor:after]:w-8",
|
|
35518
|
+
"[&_.ProseMirror-gapcursor:after]:border-t-2",
|
|
35519
|
+
"[&_.ProseMirror-gapcursor:after]:border-primary",
|
|
35520
|
+
"[&.ProseMirror-focused_.ProseMirror-gapcursor]:block",
|
|
35430
35521
|
"[&_ul[data-type='taskList']]:list-none",
|
|
35431
35522
|
"[&_ul[data-type='taskList']]:pl-0",
|
|
35432
35523
|
"[&_ul[data-type='taskList']_li]:flex",
|