@underverse-ui/underverse 1.0.63 → 1.0.65
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 +334 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +64 -0
- package/dist/index.d.ts +64 -0
- package/dist/index.js +340 -20
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -708,7 +708,15 @@ var en_default = {
|
|
|
708
708
|
heading1: "Heading 1",
|
|
709
709
|
heading2: "Heading 2",
|
|
710
710
|
heading3: "Heading 3",
|
|
711
|
-
emoji: "Insert Emoji"
|
|
711
|
+
emoji: "Insert Emoji",
|
|
712
|
+
imageLayoutBlock: "Image Block",
|
|
713
|
+
imageLayoutLeft: "Wrap Text Right",
|
|
714
|
+
imageLayoutRight: "Wrap Text Left",
|
|
715
|
+
imageWidthSm: "Image Width Small",
|
|
716
|
+
imageWidthMd: "Image Width Medium",
|
|
717
|
+
imageWidthLg: "Image Width Large",
|
|
718
|
+
imageResetSize: "Reset Image Size",
|
|
719
|
+
imageDelete: "Delete Image"
|
|
712
720
|
},
|
|
713
721
|
slashCommand: {
|
|
714
722
|
basicBlocks: "Basic Blocks",
|
|
@@ -932,7 +940,15 @@ var vi_default = {
|
|
|
932
940
|
heading1: "Ti\xEAu \u0111\u1EC1 1",
|
|
933
941
|
heading2: "Ti\xEAu \u0111\u1EC1 2",
|
|
934
942
|
heading3: "Ti\xEAu \u0111\u1EC1 3",
|
|
935
|
-
emoji: "Ch\xE8n Emoji"
|
|
943
|
+
emoji: "Ch\xE8n Emoji",
|
|
944
|
+
imageLayoutBlock: "\u1EA2nh D\u1EA1ng Kh\u1ED1i",
|
|
945
|
+
imageLayoutLeft: "\u1EA2nh Tr\xE1i, Ch\u1EEF Ph\u1EA3i",
|
|
946
|
+
imageLayoutRight: "\u1EA2nh Ph\u1EA3i, Ch\u1EEF Tr\xE1i",
|
|
947
|
+
imageWidthSm: "\u1EA2nh Nh\u1ECF",
|
|
948
|
+
imageWidthMd: "\u1EA2nh V\u1EEBa",
|
|
949
|
+
imageWidthLg: "\u1EA2nh L\u1EDBn",
|
|
950
|
+
imageResetSize: "\u0110\u1EB7t L\u1EA1i K\xEDch Th\u01B0\u1EDBc \u1EA2nh",
|
|
951
|
+
imageDelete: "X\xF3a \u1EA2nh"
|
|
936
952
|
},
|
|
937
953
|
slashCommand: {
|
|
938
954
|
basicBlocks: "Kh\u1ED1i c\u01A1 b\u1EA3n",
|
|
@@ -1156,7 +1172,15 @@ var ko_default = {
|
|
|
1156
1172
|
heading1: "\uC81C\uBAA9 1",
|
|
1157
1173
|
heading2: "\uC81C\uBAA9 2",
|
|
1158
1174
|
heading3: "\uC81C\uBAA9 3",
|
|
1159
|
-
emoji: "\uC774\uBAA8\uC9C0 \uC0BD\uC785"
|
|
1175
|
+
emoji: "\uC774\uBAA8\uC9C0 \uC0BD\uC785",
|
|
1176
|
+
imageLayoutBlock: "\uC774\uBBF8\uC9C0 \uBE14\uB85D",
|
|
1177
|
+
imageLayoutLeft: "\uC67C\uCABD \uC774\uBBF8\uC9C0, \uC624\uB978\uCABD \uD14D\uC2A4\uD2B8",
|
|
1178
|
+
imageLayoutRight: "\uC624\uB978\uCABD \uC774\uBBF8\uC9C0, \uC67C\uCABD \uD14D\uC2A4\uD2B8",
|
|
1179
|
+
imageWidthSm: "\uC791\uC740 \uC774\uBBF8\uC9C0",
|
|
1180
|
+
imageWidthMd: "\uC911\uAC04 \uC774\uBBF8\uC9C0",
|
|
1181
|
+
imageWidthLg: "\uD070 \uC774\uBBF8\uC9C0",
|
|
1182
|
+
imageResetSize: "\uC774\uBBF8\uC9C0 \uD06C\uAE30 \uCD08\uAE30\uD654",
|
|
1183
|
+
imageDelete: "\uC774\uBBF8\uC9C0 \uC0AD\uC81C"
|
|
1160
1184
|
},
|
|
1161
1185
|
slashCommand: {
|
|
1162
1186
|
basicBlocks: "\uAE30\uBCF8 \uBE14\uB85D",
|
|
@@ -1379,7 +1403,15 @@ var ja_default = {
|
|
|
1379
1403
|
heading1: "\u898B\u51FA\u3057 1",
|
|
1380
1404
|
heading2: "\u898B\u51FA\u3057 2",
|
|
1381
1405
|
heading3: "\u898B\u51FA\u3057 3",
|
|
1382
|
-
emoji: "\u7D75\u6587\u5B57\u3092\u633F\u5165"
|
|
1406
|
+
emoji: "\u7D75\u6587\u5B57\u3092\u633F\u5165",
|
|
1407
|
+
imageLayoutBlock: "\u753B\u50CF\u30D6\u30ED\u30C3\u30AF",
|
|
1408
|
+
imageLayoutLeft: "\u753B\u50CF\u3092\u5DE6\u3001\u6587\u5B57\u3092\u53F3\u306B\u56DE\u308A\u8FBC\u307F",
|
|
1409
|
+
imageLayoutRight: "\u753B\u50CF\u3092\u53F3\u3001\u6587\u5B57\u3092\u5DE6\u306B\u56DE\u308A\u8FBC\u307F",
|
|
1410
|
+
imageWidthSm: "\u753B\u50CF \u5C0F",
|
|
1411
|
+
imageWidthMd: "\u753B\u50CF \u4E2D",
|
|
1412
|
+
imageWidthLg: "\u753B\u50CF \u5927",
|
|
1413
|
+
imageResetSize: "\u753B\u50CF\u30B5\u30A4\u30BA\u3092\u30EA\u30BB\u30C3\u30C8",
|
|
1414
|
+
imageDelete: "\u753B\u50CF\u3092\u524A\u9664"
|
|
1383
1415
|
},
|
|
1384
1416
|
slashCommand: {
|
|
1385
1417
|
basicBlocks: "\u57FA\u672C\u30D6\u30ED\u30C3\u30AF",
|
|
@@ -16218,12 +16250,12 @@ function Carousel({
|
|
|
16218
16250
|
mainScale: 1.12,
|
|
16219
16251
|
sideScale: 0.82,
|
|
16220
16252
|
farScale: 0.72,
|
|
16221
|
-
sideOpacity: 0.
|
|
16222
|
-
farOpacity: 0.
|
|
16253
|
+
sideOpacity: 0.84,
|
|
16254
|
+
farOpacity: 0.44,
|
|
16223
16255
|
sideOffset: 22,
|
|
16224
16256
|
rotate: 20,
|
|
16225
16257
|
depthStep: 120,
|
|
16226
|
-
blur:
|
|
16258
|
+
blur: 1.6
|
|
16227
16259
|
};
|
|
16228
16260
|
}
|
|
16229
16261
|
if (effectPreset === "gallery") {
|
|
@@ -16302,12 +16334,12 @@ function Carousel({
|
|
|
16302
16334
|
mainScale: 1.04,
|
|
16303
16335
|
sideScale: effectiveAnimation === "stack" ? 0.93 : 0.88,
|
|
16304
16336
|
farScale: effectiveAnimation === "stack" ? 0.86 : 0.76,
|
|
16305
|
-
sideOpacity: effectiveAnimation === "stack" ? 0.
|
|
16306
|
-
farOpacity: effectiveAnimation === "stack" ? 0.
|
|
16337
|
+
sideOpacity: effectiveAnimation === "stack" ? 0.8 : 0.86,
|
|
16338
|
+
farOpacity: effectiveAnimation === "stack" ? 0.5 : 0.48,
|
|
16307
16339
|
sideOffset: effectiveAnimation === "stack" ? 20 : 28,
|
|
16308
16340
|
rotate: 24,
|
|
16309
16341
|
depthStep: effectiveAnimation === "stack" ? 60 : 90,
|
|
16310
|
-
blur: 1.
|
|
16342
|
+
blur: 1.1,
|
|
16311
16343
|
stackOffset: 20,
|
|
16312
16344
|
stackLift: 12,
|
|
16313
16345
|
...presetEffectOptions,
|
|
@@ -16460,7 +16492,7 @@ function Carousel({
|
|
|
16460
16492
|
opacity: distance === 0 ? 1 : distance === 1 || distance === -1 ? mergedEffectOptions.sideOpacity : mergedEffectOptions.farOpacity,
|
|
16461
16493
|
transform: `translate3d(${xOffset2}px, ${yOffset}px, -${absDistance * mergedEffectOptions.depthStep}px) scale(${scale2})`,
|
|
16462
16494
|
filter: distance === 0 ? "blur(0px)" : `blur(${Math.min(absDistance, 2) * mergedEffectOptions.blur}px)`,
|
|
16463
|
-
pointerEvents:
|
|
16495
|
+
pointerEvents: "auto"
|
|
16464
16496
|
};
|
|
16465
16497
|
}
|
|
16466
16498
|
const xOffset = distance * mergedEffectOptions.sideOffset;
|
|
@@ -16470,7 +16502,7 @@ function Carousel({
|
|
|
16470
16502
|
opacity: distance === 0 ? 1 : distance === 1 || distance === -1 ? mergedEffectOptions.sideOpacity : mergedEffectOptions.farOpacity,
|
|
16471
16503
|
transform: `translate3d(${xOffset}%, 0, -${absDistance * mergedEffectOptions.depthStep}px) rotateY(${rotateY}deg) scale(${scale})`,
|
|
16472
16504
|
filter: distance === 0 ? "blur(0px)" : `blur(${Math.min(absDistance, 2) * mergedEffectOptions.blur}px)`,
|
|
16473
|
-
pointerEvents:
|
|
16505
|
+
pointerEvents: "auto"
|
|
16474
16506
|
};
|
|
16475
16507
|
},
|
|
16476
16508
|
[effectiveAnimation, getLoopDistance, mergedEffectOptions]
|
|
@@ -16522,10 +16554,12 @@ function Carousel({
|
|
|
16522
16554
|
effectiveAnimation === "fade" && (idx === currentIndex ? "opacity-100 z-10" : "opacity-0 pointer-events-none z-0"),
|
|
16523
16555
|
effectiveAnimation === "scale" && (idx === currentIndex ? "opacity-100 scale-100 z-10" : "opacity-0 scale-95 pointer-events-none z-0"),
|
|
16524
16556
|
isDeckAnimation && "w-full max-w-[78%] md:max-w-[72%] transition-[opacity,transform] duration-500 ease-out",
|
|
16557
|
+
isDeckAnimation && idx !== currentIndex && "cursor-pointer",
|
|
16525
16558
|
effectiveAnimation !== "slide" && "transition-[opacity,transform] duration-500 ease-in-out",
|
|
16526
16559
|
slideClassName
|
|
16527
16560
|
),
|
|
16528
16561
|
style: effectiveAnimation === "slide" ? { [isHorizontal ? "width" : "height"]: `${slideWidth}%` } : isDeckAnimation ? getDeckSlideStyles(idx) : void 0,
|
|
16562
|
+
onClick: isDeckAnimation && idx !== currentIndex ? () => scrollTo(idx) : void 0,
|
|
16529
16563
|
role: "group",
|
|
16530
16564
|
"aria-roledescription": "slide",
|
|
16531
16565
|
"aria-label": `${idx + 1} of ${totalSlides}`,
|
|
@@ -22381,6 +22415,8 @@ import { NodeViewWrapper, ReactNodeViewRenderer } from "@tiptap/react";
|
|
|
22381
22415
|
import { jsx as jsx73, jsxs as jsxs63 } from "react/jsx-runtime";
|
|
22382
22416
|
var MIN_IMAGE_SIZE_PX = 40;
|
|
22383
22417
|
var AXIS_LOCK_THRESHOLD_PX = 4;
|
|
22418
|
+
var IMAGE_LAYOUTS = /* @__PURE__ */ new Set(["block", "left", "right"]);
|
|
22419
|
+
var IMAGE_WIDTH_PRESETS = /* @__PURE__ */ new Set(["sm", "md", "lg"]);
|
|
22384
22420
|
function toNullableNumber(value) {
|
|
22385
22421
|
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
22386
22422
|
if (typeof value === "string") {
|
|
@@ -22392,6 +22428,33 @@ function toNullableNumber(value) {
|
|
|
22392
22428
|
function clamp8(value, min, max) {
|
|
22393
22429
|
return Math.min(max, Math.max(min, value));
|
|
22394
22430
|
}
|
|
22431
|
+
function parseImageLayout(value) {
|
|
22432
|
+
if (typeof value === "string" && IMAGE_LAYOUTS.has(value)) {
|
|
22433
|
+
return value;
|
|
22434
|
+
}
|
|
22435
|
+
return "block";
|
|
22436
|
+
}
|
|
22437
|
+
function parseImageWidthPreset(value) {
|
|
22438
|
+
if (typeof value === "string" && IMAGE_WIDTH_PRESETS.has(value)) {
|
|
22439
|
+
return value;
|
|
22440
|
+
}
|
|
22441
|
+
return null;
|
|
22442
|
+
}
|
|
22443
|
+
function getImageLayoutStyles(layout) {
|
|
22444
|
+
if (layout === "left") {
|
|
22445
|
+
return {
|
|
22446
|
+
"data-image-layout": "left",
|
|
22447
|
+
style: "float:left;display:block;margin:0.25rem 1rem 0.75rem 0;"
|
|
22448
|
+
};
|
|
22449
|
+
}
|
|
22450
|
+
if (layout === "right") {
|
|
22451
|
+
return {
|
|
22452
|
+
"data-image-layout": "right",
|
|
22453
|
+
style: "float:right;display:block;margin:0.25rem 0 0.75rem 1rem;"
|
|
22454
|
+
};
|
|
22455
|
+
}
|
|
22456
|
+
return {};
|
|
22457
|
+
}
|
|
22395
22458
|
function ResizableImageNodeView(props) {
|
|
22396
22459
|
const { node, selected, updateAttributes, editor, getPos } = props;
|
|
22397
22460
|
const wrapperRef = useRef25(null);
|
|
@@ -22401,6 +22464,8 @@ function ResizableImageNodeView(props) {
|
|
|
22401
22464
|
const widthAttr = toNullableNumber(node.attrs["width"]);
|
|
22402
22465
|
const heightAttr = toNullableNumber(node.attrs["height"]);
|
|
22403
22466
|
const textAlign = String(node.attrs["textAlign"] ?? "");
|
|
22467
|
+
const imageLayout = parseImageLayout(node.attrs["imageLayout"]);
|
|
22468
|
+
const preserveAspectByDefault = imageLayout === "left" || imageLayout === "right";
|
|
22404
22469
|
const dragStateRef = useRef25(null);
|
|
22405
22470
|
useEffect30(() => {
|
|
22406
22471
|
const img = imgRef.current;
|
|
@@ -22449,7 +22514,8 @@ function ResizableImageNodeView(props) {
|
|
|
22449
22514
|
const dy = event.clientY - drag.startY;
|
|
22450
22515
|
let nextW = drag.startW;
|
|
22451
22516
|
let nextH = drag.startH;
|
|
22452
|
-
|
|
22517
|
+
const shouldPreserveAspect = preserveAspectByDefault ? !event.ctrlKey : event.ctrlKey;
|
|
22518
|
+
if (shouldPreserveAspect) {
|
|
22453
22519
|
if (Math.abs(dx) >= Math.abs(dy)) {
|
|
22454
22520
|
nextW = clamp8(drag.startW + dx, MIN_IMAGE_SIZE_PX, drag.maxW);
|
|
22455
22521
|
nextH = clamp8(nextW / drag.aspect, MIN_IMAGE_SIZE_PX, Number.POSITIVE_INFINITY);
|
|
@@ -22476,7 +22542,8 @@ function ResizableImageNodeView(props) {
|
|
|
22476
22542
|
if (!drag) return;
|
|
22477
22543
|
updateAttributes({
|
|
22478
22544
|
width: Math.round(drag.lastW),
|
|
22479
|
-
height: Math.round(drag.lastH)
|
|
22545
|
+
height: Math.round(drag.lastH),
|
|
22546
|
+
imageWidthPreset: null
|
|
22480
22547
|
});
|
|
22481
22548
|
};
|
|
22482
22549
|
const onResizePointerUp = (event) => {
|
|
@@ -22494,14 +22561,15 @@ function ResizableImageNodeView(props) {
|
|
|
22494
22561
|
finishResize();
|
|
22495
22562
|
};
|
|
22496
22563
|
const showHandle = selected || isHovered || isResizing;
|
|
22497
|
-
const wrapperAlignClass = textAlign === "center" ? "mx-auto" : textAlign === "right" ? "ml-auto" : textAlign === "justify" ? "mx-auto" : "";
|
|
22498
|
-
const
|
|
22564
|
+
const wrapperAlignClass = imageLayout === "block" ? textAlign === "center" ? "mx-auto" : textAlign === "right" ? "ml-auto" : textAlign === "justify" ? "mx-auto" : "" : "";
|
|
22565
|
+
const wrapperLayoutClass = imageLayout === "left" ? "float-left mr-4 mb-3 mt-1 clear-none max-w-[min(45%,20rem)]" : imageLayout === "right" ? "float-right ml-4 mb-3 mt-1 clear-none max-w-[min(45%,20rem)]" : "w-fit";
|
|
22499
22566
|
return /* @__PURE__ */ jsxs63(
|
|
22500
22567
|
NodeViewWrapper,
|
|
22501
22568
|
{
|
|
22502
22569
|
as: "div",
|
|
22503
22570
|
ref: wrapperRef,
|
|
22504
|
-
|
|
22571
|
+
"data-image-layout": imageLayout,
|
|
22572
|
+
className: ["relative block align-middle max-w-full my-4", wrapperLayoutClass, wrapperAlignClass].filter(Boolean).join(" "),
|
|
22505
22573
|
onMouseEnter: () => setIsHovered(true),
|
|
22506
22574
|
onMouseLeave: () => setIsHovered(false),
|
|
22507
22575
|
onClick: (e) => {
|
|
@@ -22571,6 +22639,25 @@ var ResizableImage = Image3.extend({
|
|
|
22571
22639
|
return Number.isFinite(parsed) ? parsed : null;
|
|
22572
22640
|
},
|
|
22573
22641
|
renderHTML: (attrs) => typeof attrs.height === "number" ? { height: attrs.height } : {}
|
|
22642
|
+
},
|
|
22643
|
+
imageLayout: {
|
|
22644
|
+
default: "block",
|
|
22645
|
+
parseHTML: (element) => {
|
|
22646
|
+
const explicit = element.getAttribute("data-image-layout");
|
|
22647
|
+
if (explicit) return parseImageLayout(explicit);
|
|
22648
|
+
const floatValue = element.style.float;
|
|
22649
|
+
if (floatValue === "left" || floatValue === "right") return floatValue;
|
|
22650
|
+
return "block";
|
|
22651
|
+
},
|
|
22652
|
+
renderHTML: (attrs) => getImageLayoutStyles(parseImageLayout(attrs.imageLayout))
|
|
22653
|
+
},
|
|
22654
|
+
imageWidthPreset: {
|
|
22655
|
+
default: null,
|
|
22656
|
+
parseHTML: (element) => parseImageWidthPreset(element.getAttribute("data-image-size")),
|
|
22657
|
+
renderHTML: (attrs) => {
|
|
22658
|
+
const preset = parseImageWidthPreset(attrs.imageWidthPreset);
|
|
22659
|
+
return preset ? { "data-image-size": preset } : {};
|
|
22660
|
+
}
|
|
22574
22661
|
}
|
|
22575
22662
|
};
|
|
22576
22663
|
},
|
|
@@ -22758,6 +22845,7 @@ import {
|
|
|
22758
22845
|
Palette as Palette2,
|
|
22759
22846
|
Quote as QuoteIcon,
|
|
22760
22847
|
Redo as RedoIcon,
|
|
22848
|
+
RotateCcw as RotateCcw2,
|
|
22761
22849
|
Smile as Smile3,
|
|
22762
22850
|
Strikethrough as StrikethroughIcon,
|
|
22763
22851
|
Subscript as SubscriptIcon,
|
|
@@ -22833,6 +22921,96 @@ var EditorColorPalette = ({
|
|
|
22833
22921
|
)) })
|
|
22834
22922
|
] });
|
|
22835
22923
|
|
|
22924
|
+
// src/components/UEditor/image-commands.ts
|
|
22925
|
+
import { NodeSelection, TextSelection } from "@tiptap/pm/state";
|
|
22926
|
+
var IMAGE_WIDTHS_BY_LAYOUT = {
|
|
22927
|
+
block: {
|
|
22928
|
+
sm: 180,
|
|
22929
|
+
md: 280,
|
|
22930
|
+
lg: 380
|
|
22931
|
+
},
|
|
22932
|
+
wrap: {
|
|
22933
|
+
sm: 140,
|
|
22934
|
+
md: 200,
|
|
22935
|
+
lg: 260
|
|
22936
|
+
}
|
|
22937
|
+
};
|
|
22938
|
+
function isSelectedImage(editor) {
|
|
22939
|
+
const { selection } = editor.state;
|
|
22940
|
+
return selection instanceof NodeSelection && selection.node.type.name === "image";
|
|
22941
|
+
}
|
|
22942
|
+
function applyImageLayout(editor, layout) {
|
|
22943
|
+
const { state, view } = editor;
|
|
22944
|
+
const { selection, schema } = state;
|
|
22945
|
+
if (!(selection instanceof NodeSelection) || selection.node.type.name !== "image") {
|
|
22946
|
+
editor.chain().focus().updateAttributes("image", { imageLayout: layout }).run();
|
|
22947
|
+
return;
|
|
22948
|
+
}
|
|
22949
|
+
let transaction = state.tr.setNodeMarkup(selection.from, void 0, {
|
|
22950
|
+
...selection.node.attrs,
|
|
22951
|
+
imageLayout: layout
|
|
22952
|
+
});
|
|
22953
|
+
if (layout !== "block") {
|
|
22954
|
+
const nextPos = transaction.mapping.map(selection.to);
|
|
22955
|
+
const nextNode = transaction.doc.nodeAt(nextPos);
|
|
22956
|
+
if (!nextNode || nextNode.type.name !== "paragraph") {
|
|
22957
|
+
const paragraph = schema.nodes.paragraph?.create();
|
|
22958
|
+
if (paragraph) {
|
|
22959
|
+
transaction = transaction.insert(nextPos, paragraph);
|
|
22960
|
+
}
|
|
22961
|
+
}
|
|
22962
|
+
const resolvedPos = transaction.doc.resolve(Math.min(nextPos + 1, transaction.doc.content.size));
|
|
22963
|
+
transaction = transaction.setSelection(TextSelection.near(resolvedPos));
|
|
22964
|
+
} else {
|
|
22965
|
+
const resolvedPos = transaction.doc.resolve(selection.from);
|
|
22966
|
+
transaction = transaction.setSelection(NodeSelection.create(transaction.doc, resolvedPos.pos));
|
|
22967
|
+
}
|
|
22968
|
+
view.dispatch(transaction.scrollIntoView());
|
|
22969
|
+
view.focus();
|
|
22970
|
+
}
|
|
22971
|
+
function applyImageWidthPreset(editor, preset) {
|
|
22972
|
+
const attrs = editor.getAttributes("image");
|
|
22973
|
+
const mode = attrs.imageLayout === "left" || attrs.imageLayout === "right" ? "wrap" : "block";
|
|
22974
|
+
const width = IMAGE_WIDTHS_BY_LAYOUT[mode][preset];
|
|
22975
|
+
if (!isSelectedImage(editor)) {
|
|
22976
|
+
editor.chain().focus().updateAttributes("image", { width, imageWidthPreset: preset }).run();
|
|
22977
|
+
return;
|
|
22978
|
+
}
|
|
22979
|
+
const { state, view } = editor;
|
|
22980
|
+
const selection = state.selection;
|
|
22981
|
+
const transaction = state.tr.setNodeMarkup(selection.from, void 0, {
|
|
22982
|
+
...selection.node.attrs,
|
|
22983
|
+
width,
|
|
22984
|
+
imageWidthPreset: preset
|
|
22985
|
+
});
|
|
22986
|
+
view.dispatch(transaction.scrollIntoView());
|
|
22987
|
+
view.focus();
|
|
22988
|
+
}
|
|
22989
|
+
function resetImageSize(editor) {
|
|
22990
|
+
if (!isSelectedImage(editor)) {
|
|
22991
|
+
editor.chain().focus().updateAttributes("image", {
|
|
22992
|
+
width: null,
|
|
22993
|
+
height: null,
|
|
22994
|
+
imageWidthPreset: null
|
|
22995
|
+
}).run();
|
|
22996
|
+
return;
|
|
22997
|
+
}
|
|
22998
|
+
const { state, view } = editor;
|
|
22999
|
+
const selection = state.selection;
|
|
23000
|
+
const transaction = state.tr.setNodeMarkup(selection.from, void 0, {
|
|
23001
|
+
...selection.node.attrs,
|
|
23002
|
+
width: null,
|
|
23003
|
+
height: null,
|
|
23004
|
+
imageWidthPreset: null
|
|
23005
|
+
});
|
|
23006
|
+
view.dispatch(transaction.scrollIntoView());
|
|
23007
|
+
view.focus();
|
|
23008
|
+
}
|
|
23009
|
+
function deleteSelectedImage(editor) {
|
|
23010
|
+
if (!isSelectedImage(editor)) return;
|
|
23011
|
+
editor.chain().focus().deleteSelection().run();
|
|
23012
|
+
}
|
|
23013
|
+
|
|
22836
23014
|
// src/components/UEditor/inputs.tsx
|
|
22837
23015
|
import { useEffect as useEffect31, useRef as useRef26, useState as useState42 } from "react";
|
|
22838
23016
|
import { Check as Check10, X as X18 } from "lucide-react";
|
|
@@ -23169,6 +23347,10 @@ var EditorToolbar = ({
|
|
|
23169
23347
|
const fileInputRef = useRef28(null);
|
|
23170
23348
|
const [isUploadingImage, setIsUploadingImage] = useState44(false);
|
|
23171
23349
|
const [imageUploadError, setImageUploadError] = useState44(null);
|
|
23350
|
+
const isImageSelected = editor.isActive("image");
|
|
23351
|
+
const imageAttrs = editor.getAttributes("image");
|
|
23352
|
+
const imageLayout = imageAttrs.imageLayout === "left" || imageAttrs.imageLayout === "right" ? imageAttrs.imageLayout : "block";
|
|
23353
|
+
const imageWidthPreset = imageAttrs.imageWidthPreset === "sm" || imageAttrs.imageWidthPreset === "md" || imageAttrs.imageWidthPreset === "lg" ? imageAttrs.imageWidthPreset : null;
|
|
23172
23354
|
const insertImageFiles = async (files) => {
|
|
23173
23355
|
if (files.length === 0) return;
|
|
23174
23356
|
setIsUploadingImage(true);
|
|
@@ -23501,6 +23683,85 @@ var EditorToolbar = ({
|
|
|
23501
23683
|
void insertImageFiles(files);
|
|
23502
23684
|
}
|
|
23503
23685
|
}
|
|
23686
|
+
),
|
|
23687
|
+
/* @__PURE__ */ jsx77("div", { className: "my-1 border-t" }),
|
|
23688
|
+
/* @__PURE__ */ jsx77(
|
|
23689
|
+
DropdownMenuItem,
|
|
23690
|
+
{
|
|
23691
|
+
icon: AlignCenter,
|
|
23692
|
+
label: t("toolbar.imageLayoutBlock"),
|
|
23693
|
+
onClick: () => applyImageLayout(editor, "block"),
|
|
23694
|
+
active: isImageSelected && imageLayout === "block",
|
|
23695
|
+
disabled: !isImageSelected
|
|
23696
|
+
}
|
|
23697
|
+
),
|
|
23698
|
+
/* @__PURE__ */ jsx77(
|
|
23699
|
+
DropdownMenuItem,
|
|
23700
|
+
{
|
|
23701
|
+
icon: AlignLeft,
|
|
23702
|
+
label: t("toolbar.imageLayoutLeft"),
|
|
23703
|
+
onClick: () => applyImageLayout(editor, "left"),
|
|
23704
|
+
active: isImageSelected && imageLayout === "left",
|
|
23705
|
+
disabled: !isImageSelected
|
|
23706
|
+
}
|
|
23707
|
+
),
|
|
23708
|
+
/* @__PURE__ */ jsx77(
|
|
23709
|
+
DropdownMenuItem,
|
|
23710
|
+
{
|
|
23711
|
+
icon: AlignRight,
|
|
23712
|
+
label: t("toolbar.imageLayoutRight"),
|
|
23713
|
+
onClick: () => applyImageLayout(editor, "right"),
|
|
23714
|
+
active: isImageSelected && imageLayout === "right",
|
|
23715
|
+
disabled: !isImageSelected
|
|
23716
|
+
}
|
|
23717
|
+
),
|
|
23718
|
+
/* @__PURE__ */ jsx77("div", { className: "my-1 border-t" }),
|
|
23719
|
+
/* @__PURE__ */ jsx77(
|
|
23720
|
+
DropdownMenuItem,
|
|
23721
|
+
{
|
|
23722
|
+
label: t("toolbar.imageWidthSm"),
|
|
23723
|
+
onClick: () => applyImageWidthPreset(editor, "sm"),
|
|
23724
|
+
active: isImageSelected && imageWidthPreset === "sm",
|
|
23725
|
+
disabled: !isImageSelected
|
|
23726
|
+
}
|
|
23727
|
+
),
|
|
23728
|
+
/* @__PURE__ */ jsx77(
|
|
23729
|
+
DropdownMenuItem,
|
|
23730
|
+
{
|
|
23731
|
+
label: t("toolbar.imageWidthMd"),
|
|
23732
|
+
onClick: () => applyImageWidthPreset(editor, "md"),
|
|
23733
|
+
active: isImageSelected && imageWidthPreset === "md",
|
|
23734
|
+
disabled: !isImageSelected
|
|
23735
|
+
}
|
|
23736
|
+
),
|
|
23737
|
+
/* @__PURE__ */ jsx77(
|
|
23738
|
+
DropdownMenuItem,
|
|
23739
|
+
{
|
|
23740
|
+
label: t("toolbar.imageWidthLg"),
|
|
23741
|
+
onClick: () => applyImageWidthPreset(editor, "lg"),
|
|
23742
|
+
active: isImageSelected && imageWidthPreset === "lg",
|
|
23743
|
+
disabled: !isImageSelected
|
|
23744
|
+
}
|
|
23745
|
+
),
|
|
23746
|
+
/* @__PURE__ */ jsx77("div", { className: "my-1 border-t" }),
|
|
23747
|
+
/* @__PURE__ */ jsx77(
|
|
23748
|
+
DropdownMenuItem,
|
|
23749
|
+
{
|
|
23750
|
+
icon: RotateCcw2,
|
|
23751
|
+
label: t("toolbar.imageResetSize"),
|
|
23752
|
+
onClick: () => resetImageSize(editor),
|
|
23753
|
+
disabled: !isImageSelected
|
|
23754
|
+
}
|
|
23755
|
+
),
|
|
23756
|
+
/* @__PURE__ */ jsx77(
|
|
23757
|
+
DropdownMenuItem,
|
|
23758
|
+
{
|
|
23759
|
+
icon: Trash22,
|
|
23760
|
+
label: t("toolbar.imageDelete"),
|
|
23761
|
+
onClick: () => deleteSelectedImage(editor),
|
|
23762
|
+
disabled: !isImageSelected,
|
|
23763
|
+
destructive: true
|
|
23764
|
+
}
|
|
23504
23765
|
)
|
|
23505
23766
|
] })
|
|
23506
23767
|
}
|
|
@@ -23619,6 +23880,9 @@ var EditorToolbar = ({
|
|
|
23619
23880
|
import React70, { useCallback as useCallback17, useEffect as useEffect33, useMemo as useMemo22, useRef as useRef29, useState as useState45 } from "react";
|
|
23620
23881
|
import { createPortal as createPortal8 } from "react-dom";
|
|
23621
23882
|
import {
|
|
23883
|
+
AlignCenter as AlignCenter2,
|
|
23884
|
+
AlignLeft as AlignLeft2,
|
|
23885
|
+
AlignRight as AlignRight2,
|
|
23622
23886
|
Bold as BoldIcon2,
|
|
23623
23887
|
Code as CodeIcon2,
|
|
23624
23888
|
FileCode as FileCode4,
|
|
@@ -23634,9 +23898,11 @@ import {
|
|
|
23634
23898
|
Palette as Palette3,
|
|
23635
23899
|
Plus as Plus3,
|
|
23636
23900
|
Quote as QuoteIcon2,
|
|
23901
|
+
RotateCcw as RotateCcw3,
|
|
23637
23902
|
Subscript as SubscriptIcon2,
|
|
23638
23903
|
Superscript as SuperscriptIcon2,
|
|
23639
23904
|
Table as TableIcon2,
|
|
23905
|
+
Trash2 as Trash23,
|
|
23640
23906
|
Type as Type3,
|
|
23641
23907
|
Underline as UnderlineIcon2,
|
|
23642
23908
|
Strikethrough as StrikethroughIcon2
|
|
@@ -23835,6 +24101,10 @@ var BubbleMenuContent = ({
|
|
|
23835
24101
|
const { textColors, highlightColors } = useEditorColors();
|
|
23836
24102
|
const [showLinkInput, setShowLinkInput] = useState45(false);
|
|
23837
24103
|
const [showEditorColorPalette, setShowEditorColorPalette] = useState45(false);
|
|
24104
|
+
const isImageSelected = editor.isActive("image");
|
|
24105
|
+
const imageAttrs = editor.getAttributes("image");
|
|
24106
|
+
const imageLayout = imageAttrs.imageLayout === "left" || imageAttrs.imageLayout === "right" ? imageAttrs.imageLayout : "block";
|
|
24107
|
+
const imageWidthPreset = imageAttrs.imageWidthPreset === "sm" || imageAttrs.imageWidthPreset === "md" || imageAttrs.imageWidthPreset === "lg" ? imageAttrs.imageWidthPreset : null;
|
|
23838
24108
|
useEffect33(() => {
|
|
23839
24109
|
onKeepOpenChange?.(showLinkInput);
|
|
23840
24110
|
}, [onKeepOpenChange, showLinkInput]);
|
|
@@ -23909,6 +24179,20 @@ var BubbleMenuContent = ({
|
|
|
23909
24179
|
) })
|
|
23910
24180
|
] });
|
|
23911
24181
|
}
|
|
24182
|
+
if (isImageSelected) {
|
|
24183
|
+
return /* @__PURE__ */ jsxs68("div", { className: "flex items-center gap-0.5 p-1", children: [
|
|
24184
|
+
/* @__PURE__ */ jsx78(ToolbarButton, { onClick: () => applyImageLayout(editor, "block"), active: imageLayout === "block", title: t("toolbar.imageLayoutBlock"), children: /* @__PURE__ */ jsx78(AlignCenter2, { className: "w-4 h-4" }) }),
|
|
24185
|
+
/* @__PURE__ */ jsx78(ToolbarButton, { onClick: () => applyImageLayout(editor, "left"), active: imageLayout === "left", title: t("toolbar.imageLayoutLeft"), children: /* @__PURE__ */ jsx78(AlignLeft2, { className: "w-4 h-4" }) }),
|
|
24186
|
+
/* @__PURE__ */ jsx78(ToolbarButton, { onClick: () => applyImageLayout(editor, "right"), active: imageLayout === "right", title: t("toolbar.imageLayoutRight"), children: /* @__PURE__ */ jsx78(AlignRight2, { className: "w-4 h-4" }) }),
|
|
24187
|
+
/* @__PURE__ */ jsx78("div", { className: "w-px h-6 bg-border/50 mx-1" }),
|
|
24188
|
+
/* @__PURE__ */ jsx78(ToolbarButton, { onClick: () => applyImageWidthPreset(editor, "sm"), active: imageWidthPreset === "sm", title: t("toolbar.imageWidthSm"), children: /* @__PURE__ */ jsx78("span", { className: "text-[10px] font-semibold", children: "S" }) }),
|
|
24189
|
+
/* @__PURE__ */ jsx78(ToolbarButton, { onClick: () => applyImageWidthPreset(editor, "md"), active: imageWidthPreset === "md", title: t("toolbar.imageWidthMd"), children: /* @__PURE__ */ jsx78("span", { className: "text-[10px] font-semibold", children: "M" }) }),
|
|
24190
|
+
/* @__PURE__ */ jsx78(ToolbarButton, { onClick: () => applyImageWidthPreset(editor, "lg"), active: imageWidthPreset === "lg", title: t("toolbar.imageWidthLg"), children: /* @__PURE__ */ jsx78("span", { className: "text-[10px] font-semibold", children: "L" }) }),
|
|
24191
|
+
/* @__PURE__ */ jsx78("div", { className: "w-px h-6 bg-border/50 mx-1" }),
|
|
24192
|
+
/* @__PURE__ */ jsx78(ToolbarButton, { onClick: () => resetImageSize(editor), title: t("toolbar.imageResetSize"), children: /* @__PURE__ */ jsx78(RotateCcw3, { className: "w-4 h-4" }) }),
|
|
24193
|
+
/* @__PURE__ */ jsx78(ToolbarButton, { onClick: () => deleteSelectedImage(editor), title: t("toolbar.imageDelete"), className: "text-destructive hover:text-destructive", children: /* @__PURE__ */ jsx78(Trash23, { className: "w-4 h-4" }) })
|
|
24194
|
+
] });
|
|
24195
|
+
}
|
|
23912
24196
|
return /* @__PURE__ */ jsxs68("div", { className: "flex items-center gap-0.5 p-1", children: [
|
|
23913
24197
|
/* @__PURE__ */ jsx78(ToolbarButton, { onClick: () => editor.chain().focus().toggleBold().run(), active: editor.isActive("bold"), title: t("toolbar.bold"), children: /* @__PURE__ */ jsx78(BoldIcon2, { className: "w-4 h-4" }) }),
|
|
23914
24198
|
/* @__PURE__ */ jsx78(ToolbarButton, { onClick: () => editor.chain().focus().toggleItalic().run(), active: editor.isActive("italic"), title: t("toolbar.italic"), children: /* @__PURE__ */ jsx78(ItalicIcon2, { className: "w-4 h-4" }) }),
|
|
@@ -23961,19 +24245,28 @@ var BubbleMenuContent = ({
|
|
|
23961
24245
|
] });
|
|
23962
24246
|
};
|
|
23963
24247
|
var CustomBubbleMenu = ({ editor }) => {
|
|
24248
|
+
const SHOW_DELAY_MS = 180;
|
|
23964
24249
|
const [isVisible, setIsVisible] = useState45(false);
|
|
23965
24250
|
const [position, setPosition] = useState45({ top: 0, left: 0 });
|
|
23966
24251
|
const menuRef = useRef29(null);
|
|
23967
24252
|
const keepOpenRef = useRef29(false);
|
|
24253
|
+
const showTimeoutRef = useRef29(null);
|
|
23968
24254
|
const setKeepOpen = useCallback17((next) => {
|
|
23969
24255
|
keepOpenRef.current = next;
|
|
23970
24256
|
if (next) setIsVisible(true);
|
|
23971
24257
|
}, []);
|
|
23972
24258
|
useEffect33(() => {
|
|
24259
|
+
const clearShowTimeout = () => {
|
|
24260
|
+
if (showTimeoutRef.current) {
|
|
24261
|
+
clearTimeout(showTimeoutRef.current);
|
|
24262
|
+
showTimeoutRef.current = null;
|
|
24263
|
+
}
|
|
24264
|
+
};
|
|
23973
24265
|
const updatePosition = () => {
|
|
23974
24266
|
const { state, view } = editor;
|
|
23975
24267
|
const { from, to, empty } = state.selection;
|
|
23976
24268
|
if (!keepOpenRef.current && (empty || !view.hasFocus())) {
|
|
24269
|
+
clearShowTimeout();
|
|
23977
24270
|
setIsVisible(false);
|
|
23978
24271
|
return;
|
|
23979
24272
|
}
|
|
@@ -23982,15 +24275,28 @@ var CustomBubbleMenu = ({ editor }) => {
|
|
|
23982
24275
|
const left = (start.left + end.left) / 2;
|
|
23983
24276
|
const top = start.top - 10;
|
|
23984
24277
|
setPosition({ top, left });
|
|
23985
|
-
|
|
24278
|
+
if (keepOpenRef.current) {
|
|
24279
|
+
clearShowTimeout();
|
|
24280
|
+
setIsVisible(true);
|
|
24281
|
+
return;
|
|
24282
|
+
}
|
|
24283
|
+
clearShowTimeout();
|
|
24284
|
+
showTimeoutRef.current = setTimeout(() => {
|
|
24285
|
+
setIsVisible(true);
|
|
24286
|
+
showTimeoutRef.current = null;
|
|
24287
|
+
}, SHOW_DELAY_MS);
|
|
23986
24288
|
};
|
|
23987
24289
|
const handleBlur = () => {
|
|
23988
|
-
if (!keepOpenRef.current)
|
|
24290
|
+
if (!keepOpenRef.current) {
|
|
24291
|
+
clearShowTimeout();
|
|
24292
|
+
setIsVisible(false);
|
|
24293
|
+
}
|
|
23989
24294
|
};
|
|
23990
24295
|
editor.on("selectionUpdate", updatePosition);
|
|
23991
24296
|
editor.on("focus", updatePosition);
|
|
23992
24297
|
editor.on("blur", handleBlur);
|
|
23993
24298
|
return () => {
|
|
24299
|
+
clearShowTimeout();
|
|
23994
24300
|
editor.off("selectionUpdate", updatePosition);
|
|
23995
24301
|
editor.off("focus", updatePosition);
|
|
23996
24302
|
editor.off("blur", handleBlur);
|
|
@@ -24474,7 +24780,21 @@ var UEditor = React71.forwardRef(({
|
|
|
24474
24780
|
"[&_blockquote]:rounded-r-lg",
|
|
24475
24781
|
"[&_blockquote]:italic",
|
|
24476
24782
|
"[&_blockquote]:text-muted-foreground",
|
|
24477
|
-
"[&_blockquote_p]:my-0"
|
|
24783
|
+
"[&_blockquote_p]:my-0",
|
|
24784
|
+
"[&_[data-image-layout='left']+p]:mt-1",
|
|
24785
|
+
"[&_[data-image-layout='left']+p]:min-h-[5rem]",
|
|
24786
|
+
"[&_[data-image-layout='right']+p]:mt-1",
|
|
24787
|
+
"[&_[data-image-layout='right']+p]:min-h-[5rem]",
|
|
24788
|
+
"max-md:[&_[data-image-layout='left']]:float-none",
|
|
24789
|
+
"max-md:[&_[data-image-layout='left']]:mr-0",
|
|
24790
|
+
"max-md:[&_[data-image-layout='left']]:ml-0",
|
|
24791
|
+
"max-md:[&_[data-image-layout='left']]:max-w-full",
|
|
24792
|
+
"max-md:[&_[data-image-layout='right']]:float-none",
|
|
24793
|
+
"max-md:[&_[data-image-layout='right']]:mr-0",
|
|
24794
|
+
"max-md:[&_[data-image-layout='right']]:ml-0",
|
|
24795
|
+
"max-md:[&_[data-image-layout='right']]:max-w-full",
|
|
24796
|
+
"max-md:[&_[data-image-layout='left']+p]:min-h-0",
|
|
24797
|
+
"max-md:[&_[data-image-layout='right']+p]:min-h-0"
|
|
24478
24798
|
)
|
|
24479
24799
|
}
|
|
24480
24800
|
},
|