@underverse-ui/underverse 1.0.62 → 1.0.64
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 +374 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +65 -1
- package/dist/index.d.ts +65 -1
- package/dist/index.js +380 -15
- 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",
|
|
@@ -16201,6 +16233,7 @@ function Carousel({
|
|
|
16201
16233
|
const isDeckAnimation = effectiveAnimation === "coverflow" || effectiveAnimation === "stack";
|
|
16202
16234
|
const effectiveSlidesToShow = isDeckAnimation ? 1 : slidesToShow;
|
|
16203
16235
|
const maxIndex = Math.max(0, totalSlides - effectiveSlidesToShow);
|
|
16236
|
+
const shouldShowArrows = showArrows && isHorizontal;
|
|
16204
16237
|
const presetEffectOptions = React42.useMemo(() => {
|
|
16205
16238
|
if (effectPreset === "cinematic") {
|
|
16206
16239
|
return effectiveAnimation === "stack" ? {
|
|
@@ -16248,6 +16281,52 @@ function Carousel({
|
|
|
16248
16281
|
blur: 1
|
|
16249
16282
|
};
|
|
16250
16283
|
}
|
|
16284
|
+
if (effectPreset === "poster") {
|
|
16285
|
+
return effectiveAnimation === "stack" ? {
|
|
16286
|
+
mainScale: 1.12,
|
|
16287
|
+
sideScale: 0.88,
|
|
16288
|
+
farScale: 0.78,
|
|
16289
|
+
sideOpacity: 0.64,
|
|
16290
|
+
farOpacity: 0.22,
|
|
16291
|
+
depthStep: 92,
|
|
16292
|
+
blur: 2.8,
|
|
16293
|
+
stackOffset: 14,
|
|
16294
|
+
stackLift: 18
|
|
16295
|
+
} : {
|
|
16296
|
+
mainScale: 1.16,
|
|
16297
|
+
sideScale: 0.78,
|
|
16298
|
+
farScale: 0.68,
|
|
16299
|
+
sideOpacity: 0.68,
|
|
16300
|
+
farOpacity: 0.18,
|
|
16301
|
+
sideOffset: 18,
|
|
16302
|
+
rotate: 26,
|
|
16303
|
+
depthStep: 140,
|
|
16304
|
+
blur: 3
|
|
16305
|
+
};
|
|
16306
|
+
}
|
|
16307
|
+
if (effectPreset === "minimal") {
|
|
16308
|
+
return effectiveAnimation === "stack" ? {
|
|
16309
|
+
mainScale: 1.01,
|
|
16310
|
+
sideScale: 0.96,
|
|
16311
|
+
farScale: 0.92,
|
|
16312
|
+
sideOpacity: 0.88,
|
|
16313
|
+
farOpacity: 0.66,
|
|
16314
|
+
depthStep: 36,
|
|
16315
|
+
blur: 0,
|
|
16316
|
+
stackOffset: 26,
|
|
16317
|
+
stackLift: 6
|
|
16318
|
+
} : {
|
|
16319
|
+
mainScale: 1.02,
|
|
16320
|
+
sideScale: 0.94,
|
|
16321
|
+
farScale: 0.88,
|
|
16322
|
+
sideOpacity: 0.9,
|
|
16323
|
+
farOpacity: 0.62,
|
|
16324
|
+
sideOffset: 34,
|
|
16325
|
+
rotate: 10,
|
|
16326
|
+
depthStep: 54,
|
|
16327
|
+
blur: 0
|
|
16328
|
+
};
|
|
16329
|
+
}
|
|
16251
16330
|
return {};
|
|
16252
16331
|
}, [effectPreset, effectiveAnimation]);
|
|
16253
16332
|
const mergedEffectOptions = React42.useMemo(
|
|
@@ -16450,7 +16529,7 @@ function Carousel({
|
|
|
16450
16529
|
{
|
|
16451
16530
|
className: cn(
|
|
16452
16531
|
effectiveAnimation === "slide" ? "flex" : "grid",
|
|
16453
|
-
effectiveAnimation === "slide" && (isHorizontal ? "flex-row" : "flex-col"),
|
|
16532
|
+
effectiveAnimation === "slide" && (isHorizontal ? "flex-row" : "flex-col h-full"),
|
|
16454
16533
|
isDeckAnimation && "place-items-center [transform-style:preserve-3d]",
|
|
16455
16534
|
isHorizontal ? "touch-pan-y" : "touch-pan-x",
|
|
16456
16535
|
containerClassName
|
|
@@ -16471,7 +16550,7 @@ function Carousel({
|
|
|
16471
16550
|
{
|
|
16472
16551
|
className: cn(
|
|
16473
16552
|
"shrink-0",
|
|
16474
|
-
effectiveAnimation === "slide" ? isHorizontal ? "h-full" : "w-full" : "col-start-1 row-start-1",
|
|
16553
|
+
effectiveAnimation === "slide" ? isHorizontal ? "h-full" : "h-full w-full" : "col-start-1 row-start-1",
|
|
16475
16554
|
effectiveAnimation === "fade" && (idx === currentIndex ? "opacity-100 z-10" : "opacity-0 pointer-events-none z-0"),
|
|
16476
16555
|
effectiveAnimation === "scale" && (idx === currentIndex ? "opacity-100 scale-100 z-10" : "opacity-0 scale-95 pointer-events-none z-0"),
|
|
16477
16556
|
isDeckAnimation && "w-full max-w-[78%] md:max-w-[72%] transition-[opacity,transform] duration-500 ease-out",
|
|
@@ -16489,7 +16568,7 @@ function Carousel({
|
|
|
16489
16568
|
))
|
|
16490
16569
|
}
|
|
16491
16570
|
),
|
|
16492
|
-
|
|
16571
|
+
shouldShowArrows && totalSlides > effectiveSlidesToShow && /* @__PURE__ */ jsxs41(Fragment17, { children: [
|
|
16493
16572
|
/* @__PURE__ */ jsx49(
|
|
16494
16573
|
Button_default,
|
|
16495
16574
|
{
|
|
@@ -22334,6 +22413,8 @@ import { NodeViewWrapper, ReactNodeViewRenderer } from "@tiptap/react";
|
|
|
22334
22413
|
import { jsx as jsx73, jsxs as jsxs63 } from "react/jsx-runtime";
|
|
22335
22414
|
var MIN_IMAGE_SIZE_PX = 40;
|
|
22336
22415
|
var AXIS_LOCK_THRESHOLD_PX = 4;
|
|
22416
|
+
var IMAGE_LAYOUTS = /* @__PURE__ */ new Set(["block", "left", "right"]);
|
|
22417
|
+
var IMAGE_WIDTH_PRESETS = /* @__PURE__ */ new Set(["sm", "md", "lg"]);
|
|
22337
22418
|
function toNullableNumber(value) {
|
|
22338
22419
|
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
22339
22420
|
if (typeof value === "string") {
|
|
@@ -22345,6 +22426,33 @@ function toNullableNumber(value) {
|
|
|
22345
22426
|
function clamp8(value, min, max) {
|
|
22346
22427
|
return Math.min(max, Math.max(min, value));
|
|
22347
22428
|
}
|
|
22429
|
+
function parseImageLayout(value) {
|
|
22430
|
+
if (typeof value === "string" && IMAGE_LAYOUTS.has(value)) {
|
|
22431
|
+
return value;
|
|
22432
|
+
}
|
|
22433
|
+
return "block";
|
|
22434
|
+
}
|
|
22435
|
+
function parseImageWidthPreset(value) {
|
|
22436
|
+
if (typeof value === "string" && IMAGE_WIDTH_PRESETS.has(value)) {
|
|
22437
|
+
return value;
|
|
22438
|
+
}
|
|
22439
|
+
return null;
|
|
22440
|
+
}
|
|
22441
|
+
function getImageLayoutStyles(layout) {
|
|
22442
|
+
if (layout === "left") {
|
|
22443
|
+
return {
|
|
22444
|
+
"data-image-layout": "left",
|
|
22445
|
+
style: "float:left;display:block;margin:0.25rem 1rem 0.75rem 0;"
|
|
22446
|
+
};
|
|
22447
|
+
}
|
|
22448
|
+
if (layout === "right") {
|
|
22449
|
+
return {
|
|
22450
|
+
"data-image-layout": "right",
|
|
22451
|
+
style: "float:right;display:block;margin:0.25rem 0 0.75rem 1rem;"
|
|
22452
|
+
};
|
|
22453
|
+
}
|
|
22454
|
+
return {};
|
|
22455
|
+
}
|
|
22348
22456
|
function ResizableImageNodeView(props) {
|
|
22349
22457
|
const { node, selected, updateAttributes, editor, getPos } = props;
|
|
22350
22458
|
const wrapperRef = useRef25(null);
|
|
@@ -22354,6 +22462,8 @@ function ResizableImageNodeView(props) {
|
|
|
22354
22462
|
const widthAttr = toNullableNumber(node.attrs["width"]);
|
|
22355
22463
|
const heightAttr = toNullableNumber(node.attrs["height"]);
|
|
22356
22464
|
const textAlign = String(node.attrs["textAlign"] ?? "");
|
|
22465
|
+
const imageLayout = parseImageLayout(node.attrs["imageLayout"]);
|
|
22466
|
+
const preserveAspectByDefault = imageLayout === "left" || imageLayout === "right";
|
|
22357
22467
|
const dragStateRef = useRef25(null);
|
|
22358
22468
|
useEffect30(() => {
|
|
22359
22469
|
const img = imgRef.current;
|
|
@@ -22402,7 +22512,8 @@ function ResizableImageNodeView(props) {
|
|
|
22402
22512
|
const dy = event.clientY - drag.startY;
|
|
22403
22513
|
let nextW = drag.startW;
|
|
22404
22514
|
let nextH = drag.startH;
|
|
22405
|
-
|
|
22515
|
+
const shouldPreserveAspect = preserveAspectByDefault ? !event.ctrlKey : event.ctrlKey;
|
|
22516
|
+
if (shouldPreserveAspect) {
|
|
22406
22517
|
if (Math.abs(dx) >= Math.abs(dy)) {
|
|
22407
22518
|
nextW = clamp8(drag.startW + dx, MIN_IMAGE_SIZE_PX, drag.maxW);
|
|
22408
22519
|
nextH = clamp8(nextW / drag.aspect, MIN_IMAGE_SIZE_PX, Number.POSITIVE_INFINITY);
|
|
@@ -22429,7 +22540,8 @@ function ResizableImageNodeView(props) {
|
|
|
22429
22540
|
if (!drag) return;
|
|
22430
22541
|
updateAttributes({
|
|
22431
22542
|
width: Math.round(drag.lastW),
|
|
22432
|
-
height: Math.round(drag.lastH)
|
|
22543
|
+
height: Math.round(drag.lastH),
|
|
22544
|
+
imageWidthPreset: null
|
|
22433
22545
|
});
|
|
22434
22546
|
};
|
|
22435
22547
|
const onResizePointerUp = (event) => {
|
|
@@ -22447,14 +22559,15 @@ function ResizableImageNodeView(props) {
|
|
|
22447
22559
|
finishResize();
|
|
22448
22560
|
};
|
|
22449
22561
|
const showHandle = selected || isHovered || isResizing;
|
|
22450
|
-
const wrapperAlignClass = textAlign === "center" ? "mx-auto" : textAlign === "right" ? "ml-auto" : textAlign === "justify" ? "mx-auto" : "";
|
|
22451
|
-
const
|
|
22562
|
+
const wrapperAlignClass = imageLayout === "block" ? textAlign === "center" ? "mx-auto" : textAlign === "right" ? "ml-auto" : textAlign === "justify" ? "mx-auto" : "" : "";
|
|
22563
|
+
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";
|
|
22452
22564
|
return /* @__PURE__ */ jsxs63(
|
|
22453
22565
|
NodeViewWrapper,
|
|
22454
22566
|
{
|
|
22455
22567
|
as: "div",
|
|
22456
22568
|
ref: wrapperRef,
|
|
22457
|
-
|
|
22569
|
+
"data-image-layout": imageLayout,
|
|
22570
|
+
className: ["relative block align-middle max-w-full my-4", wrapperLayoutClass, wrapperAlignClass].filter(Boolean).join(" "),
|
|
22458
22571
|
onMouseEnter: () => setIsHovered(true),
|
|
22459
22572
|
onMouseLeave: () => setIsHovered(false),
|
|
22460
22573
|
onClick: (e) => {
|
|
@@ -22524,6 +22637,25 @@ var ResizableImage = Image3.extend({
|
|
|
22524
22637
|
return Number.isFinite(parsed) ? parsed : null;
|
|
22525
22638
|
},
|
|
22526
22639
|
renderHTML: (attrs) => typeof attrs.height === "number" ? { height: attrs.height } : {}
|
|
22640
|
+
},
|
|
22641
|
+
imageLayout: {
|
|
22642
|
+
default: "block",
|
|
22643
|
+
parseHTML: (element) => {
|
|
22644
|
+
const explicit = element.getAttribute("data-image-layout");
|
|
22645
|
+
if (explicit) return parseImageLayout(explicit);
|
|
22646
|
+
const floatValue = element.style.float;
|
|
22647
|
+
if (floatValue === "left" || floatValue === "right") return floatValue;
|
|
22648
|
+
return "block";
|
|
22649
|
+
},
|
|
22650
|
+
renderHTML: (attrs) => getImageLayoutStyles(parseImageLayout(attrs.imageLayout))
|
|
22651
|
+
},
|
|
22652
|
+
imageWidthPreset: {
|
|
22653
|
+
default: null,
|
|
22654
|
+
parseHTML: (element) => parseImageWidthPreset(element.getAttribute("data-image-size")),
|
|
22655
|
+
renderHTML: (attrs) => {
|
|
22656
|
+
const preset = parseImageWidthPreset(attrs.imageWidthPreset);
|
|
22657
|
+
return preset ? { "data-image-size": preset } : {};
|
|
22658
|
+
}
|
|
22527
22659
|
}
|
|
22528
22660
|
};
|
|
22529
22661
|
},
|
|
@@ -22711,6 +22843,7 @@ import {
|
|
|
22711
22843
|
Palette as Palette2,
|
|
22712
22844
|
Quote as QuoteIcon,
|
|
22713
22845
|
Redo as RedoIcon,
|
|
22846
|
+
RotateCcw as RotateCcw2,
|
|
22714
22847
|
Smile as Smile3,
|
|
22715
22848
|
Strikethrough as StrikethroughIcon,
|
|
22716
22849
|
Subscript as SubscriptIcon,
|
|
@@ -22786,6 +22919,96 @@ var EditorColorPalette = ({
|
|
|
22786
22919
|
)) })
|
|
22787
22920
|
] });
|
|
22788
22921
|
|
|
22922
|
+
// src/components/UEditor/image-commands.ts
|
|
22923
|
+
import { NodeSelection, TextSelection } from "@tiptap/pm/state";
|
|
22924
|
+
var IMAGE_WIDTHS_BY_LAYOUT = {
|
|
22925
|
+
block: {
|
|
22926
|
+
sm: 180,
|
|
22927
|
+
md: 280,
|
|
22928
|
+
lg: 380
|
|
22929
|
+
},
|
|
22930
|
+
wrap: {
|
|
22931
|
+
sm: 140,
|
|
22932
|
+
md: 200,
|
|
22933
|
+
lg: 260
|
|
22934
|
+
}
|
|
22935
|
+
};
|
|
22936
|
+
function isSelectedImage(editor) {
|
|
22937
|
+
const { selection } = editor.state;
|
|
22938
|
+
return selection instanceof NodeSelection && selection.node.type.name === "image";
|
|
22939
|
+
}
|
|
22940
|
+
function applyImageLayout(editor, layout) {
|
|
22941
|
+
const { state, view } = editor;
|
|
22942
|
+
const { selection, schema } = state;
|
|
22943
|
+
if (!(selection instanceof NodeSelection) || selection.node.type.name !== "image") {
|
|
22944
|
+
editor.chain().focus().updateAttributes("image", { imageLayout: layout }).run();
|
|
22945
|
+
return;
|
|
22946
|
+
}
|
|
22947
|
+
let transaction = state.tr.setNodeMarkup(selection.from, void 0, {
|
|
22948
|
+
...selection.node.attrs,
|
|
22949
|
+
imageLayout: layout
|
|
22950
|
+
});
|
|
22951
|
+
if (layout !== "block") {
|
|
22952
|
+
const nextPos = transaction.mapping.map(selection.to);
|
|
22953
|
+
const nextNode = transaction.doc.nodeAt(nextPos);
|
|
22954
|
+
if (!nextNode || nextNode.type.name !== "paragraph") {
|
|
22955
|
+
const paragraph = schema.nodes.paragraph?.create();
|
|
22956
|
+
if (paragraph) {
|
|
22957
|
+
transaction = transaction.insert(nextPos, paragraph);
|
|
22958
|
+
}
|
|
22959
|
+
}
|
|
22960
|
+
const resolvedPos = transaction.doc.resolve(Math.min(nextPos + 1, transaction.doc.content.size));
|
|
22961
|
+
transaction = transaction.setSelection(TextSelection.near(resolvedPos));
|
|
22962
|
+
} else {
|
|
22963
|
+
const resolvedPos = transaction.doc.resolve(selection.from);
|
|
22964
|
+
transaction = transaction.setSelection(NodeSelection.create(transaction.doc, resolvedPos.pos));
|
|
22965
|
+
}
|
|
22966
|
+
view.dispatch(transaction.scrollIntoView());
|
|
22967
|
+
view.focus();
|
|
22968
|
+
}
|
|
22969
|
+
function applyImageWidthPreset(editor, preset) {
|
|
22970
|
+
const attrs = editor.getAttributes("image");
|
|
22971
|
+
const mode = attrs.imageLayout === "left" || attrs.imageLayout === "right" ? "wrap" : "block";
|
|
22972
|
+
const width = IMAGE_WIDTHS_BY_LAYOUT[mode][preset];
|
|
22973
|
+
if (!isSelectedImage(editor)) {
|
|
22974
|
+
editor.chain().focus().updateAttributes("image", { width, imageWidthPreset: preset }).run();
|
|
22975
|
+
return;
|
|
22976
|
+
}
|
|
22977
|
+
const { state, view } = editor;
|
|
22978
|
+
const selection = state.selection;
|
|
22979
|
+
const transaction = state.tr.setNodeMarkup(selection.from, void 0, {
|
|
22980
|
+
...selection.node.attrs,
|
|
22981
|
+
width,
|
|
22982
|
+
imageWidthPreset: preset
|
|
22983
|
+
});
|
|
22984
|
+
view.dispatch(transaction.scrollIntoView());
|
|
22985
|
+
view.focus();
|
|
22986
|
+
}
|
|
22987
|
+
function resetImageSize(editor) {
|
|
22988
|
+
if (!isSelectedImage(editor)) {
|
|
22989
|
+
editor.chain().focus().updateAttributes("image", {
|
|
22990
|
+
width: null,
|
|
22991
|
+
height: null,
|
|
22992
|
+
imageWidthPreset: null
|
|
22993
|
+
}).run();
|
|
22994
|
+
return;
|
|
22995
|
+
}
|
|
22996
|
+
const { state, view } = editor;
|
|
22997
|
+
const selection = state.selection;
|
|
22998
|
+
const transaction = state.tr.setNodeMarkup(selection.from, void 0, {
|
|
22999
|
+
...selection.node.attrs,
|
|
23000
|
+
width: null,
|
|
23001
|
+
height: null,
|
|
23002
|
+
imageWidthPreset: null
|
|
23003
|
+
});
|
|
23004
|
+
view.dispatch(transaction.scrollIntoView());
|
|
23005
|
+
view.focus();
|
|
23006
|
+
}
|
|
23007
|
+
function deleteSelectedImage(editor) {
|
|
23008
|
+
if (!isSelectedImage(editor)) return;
|
|
23009
|
+
editor.chain().focus().deleteSelection().run();
|
|
23010
|
+
}
|
|
23011
|
+
|
|
22789
23012
|
// src/components/UEditor/inputs.tsx
|
|
22790
23013
|
import { useEffect as useEffect31, useRef as useRef26, useState as useState42 } from "react";
|
|
22791
23014
|
import { Check as Check10, X as X18 } from "lucide-react";
|
|
@@ -23122,6 +23345,10 @@ var EditorToolbar = ({
|
|
|
23122
23345
|
const fileInputRef = useRef28(null);
|
|
23123
23346
|
const [isUploadingImage, setIsUploadingImage] = useState44(false);
|
|
23124
23347
|
const [imageUploadError, setImageUploadError] = useState44(null);
|
|
23348
|
+
const isImageSelected = editor.isActive("image");
|
|
23349
|
+
const imageAttrs = editor.getAttributes("image");
|
|
23350
|
+
const imageLayout = imageAttrs.imageLayout === "left" || imageAttrs.imageLayout === "right" ? imageAttrs.imageLayout : "block";
|
|
23351
|
+
const imageWidthPreset = imageAttrs.imageWidthPreset === "sm" || imageAttrs.imageWidthPreset === "md" || imageAttrs.imageWidthPreset === "lg" ? imageAttrs.imageWidthPreset : null;
|
|
23125
23352
|
const insertImageFiles = async (files) => {
|
|
23126
23353
|
if (files.length === 0) return;
|
|
23127
23354
|
setIsUploadingImage(true);
|
|
@@ -23454,6 +23681,85 @@ var EditorToolbar = ({
|
|
|
23454
23681
|
void insertImageFiles(files);
|
|
23455
23682
|
}
|
|
23456
23683
|
}
|
|
23684
|
+
),
|
|
23685
|
+
/* @__PURE__ */ jsx77("div", { className: "my-1 border-t" }),
|
|
23686
|
+
/* @__PURE__ */ jsx77(
|
|
23687
|
+
DropdownMenuItem,
|
|
23688
|
+
{
|
|
23689
|
+
icon: AlignCenter,
|
|
23690
|
+
label: t("toolbar.imageLayoutBlock"),
|
|
23691
|
+
onClick: () => applyImageLayout(editor, "block"),
|
|
23692
|
+
active: isImageSelected && imageLayout === "block",
|
|
23693
|
+
disabled: !isImageSelected
|
|
23694
|
+
}
|
|
23695
|
+
),
|
|
23696
|
+
/* @__PURE__ */ jsx77(
|
|
23697
|
+
DropdownMenuItem,
|
|
23698
|
+
{
|
|
23699
|
+
icon: AlignLeft,
|
|
23700
|
+
label: t("toolbar.imageLayoutLeft"),
|
|
23701
|
+
onClick: () => applyImageLayout(editor, "left"),
|
|
23702
|
+
active: isImageSelected && imageLayout === "left",
|
|
23703
|
+
disabled: !isImageSelected
|
|
23704
|
+
}
|
|
23705
|
+
),
|
|
23706
|
+
/* @__PURE__ */ jsx77(
|
|
23707
|
+
DropdownMenuItem,
|
|
23708
|
+
{
|
|
23709
|
+
icon: AlignRight,
|
|
23710
|
+
label: t("toolbar.imageLayoutRight"),
|
|
23711
|
+
onClick: () => applyImageLayout(editor, "right"),
|
|
23712
|
+
active: isImageSelected && imageLayout === "right",
|
|
23713
|
+
disabled: !isImageSelected
|
|
23714
|
+
}
|
|
23715
|
+
),
|
|
23716
|
+
/* @__PURE__ */ jsx77("div", { className: "my-1 border-t" }),
|
|
23717
|
+
/* @__PURE__ */ jsx77(
|
|
23718
|
+
DropdownMenuItem,
|
|
23719
|
+
{
|
|
23720
|
+
label: t("toolbar.imageWidthSm"),
|
|
23721
|
+
onClick: () => applyImageWidthPreset(editor, "sm"),
|
|
23722
|
+
active: isImageSelected && imageWidthPreset === "sm",
|
|
23723
|
+
disabled: !isImageSelected
|
|
23724
|
+
}
|
|
23725
|
+
),
|
|
23726
|
+
/* @__PURE__ */ jsx77(
|
|
23727
|
+
DropdownMenuItem,
|
|
23728
|
+
{
|
|
23729
|
+
label: t("toolbar.imageWidthMd"),
|
|
23730
|
+
onClick: () => applyImageWidthPreset(editor, "md"),
|
|
23731
|
+
active: isImageSelected && imageWidthPreset === "md",
|
|
23732
|
+
disabled: !isImageSelected
|
|
23733
|
+
}
|
|
23734
|
+
),
|
|
23735
|
+
/* @__PURE__ */ jsx77(
|
|
23736
|
+
DropdownMenuItem,
|
|
23737
|
+
{
|
|
23738
|
+
label: t("toolbar.imageWidthLg"),
|
|
23739
|
+
onClick: () => applyImageWidthPreset(editor, "lg"),
|
|
23740
|
+
active: isImageSelected && imageWidthPreset === "lg",
|
|
23741
|
+
disabled: !isImageSelected
|
|
23742
|
+
}
|
|
23743
|
+
),
|
|
23744
|
+
/* @__PURE__ */ jsx77("div", { className: "my-1 border-t" }),
|
|
23745
|
+
/* @__PURE__ */ jsx77(
|
|
23746
|
+
DropdownMenuItem,
|
|
23747
|
+
{
|
|
23748
|
+
icon: RotateCcw2,
|
|
23749
|
+
label: t("toolbar.imageResetSize"),
|
|
23750
|
+
onClick: () => resetImageSize(editor),
|
|
23751
|
+
disabled: !isImageSelected
|
|
23752
|
+
}
|
|
23753
|
+
),
|
|
23754
|
+
/* @__PURE__ */ jsx77(
|
|
23755
|
+
DropdownMenuItem,
|
|
23756
|
+
{
|
|
23757
|
+
icon: Trash22,
|
|
23758
|
+
label: t("toolbar.imageDelete"),
|
|
23759
|
+
onClick: () => deleteSelectedImage(editor),
|
|
23760
|
+
disabled: !isImageSelected,
|
|
23761
|
+
destructive: true
|
|
23762
|
+
}
|
|
23457
23763
|
)
|
|
23458
23764
|
] })
|
|
23459
23765
|
}
|
|
@@ -23572,6 +23878,9 @@ var EditorToolbar = ({
|
|
|
23572
23878
|
import React70, { useCallback as useCallback17, useEffect as useEffect33, useMemo as useMemo22, useRef as useRef29, useState as useState45 } from "react";
|
|
23573
23879
|
import { createPortal as createPortal8 } from "react-dom";
|
|
23574
23880
|
import {
|
|
23881
|
+
AlignCenter as AlignCenter2,
|
|
23882
|
+
AlignLeft as AlignLeft2,
|
|
23883
|
+
AlignRight as AlignRight2,
|
|
23575
23884
|
Bold as BoldIcon2,
|
|
23576
23885
|
Code as CodeIcon2,
|
|
23577
23886
|
FileCode as FileCode4,
|
|
@@ -23587,9 +23896,11 @@ import {
|
|
|
23587
23896
|
Palette as Palette3,
|
|
23588
23897
|
Plus as Plus3,
|
|
23589
23898
|
Quote as QuoteIcon2,
|
|
23899
|
+
RotateCcw as RotateCcw3,
|
|
23590
23900
|
Subscript as SubscriptIcon2,
|
|
23591
23901
|
Superscript as SuperscriptIcon2,
|
|
23592
23902
|
Table as TableIcon2,
|
|
23903
|
+
Trash2 as Trash23,
|
|
23593
23904
|
Type as Type3,
|
|
23594
23905
|
Underline as UnderlineIcon2,
|
|
23595
23906
|
Strikethrough as StrikethroughIcon2
|
|
@@ -23788,6 +24099,10 @@ var BubbleMenuContent = ({
|
|
|
23788
24099
|
const { textColors, highlightColors } = useEditorColors();
|
|
23789
24100
|
const [showLinkInput, setShowLinkInput] = useState45(false);
|
|
23790
24101
|
const [showEditorColorPalette, setShowEditorColorPalette] = useState45(false);
|
|
24102
|
+
const isImageSelected = editor.isActive("image");
|
|
24103
|
+
const imageAttrs = editor.getAttributes("image");
|
|
24104
|
+
const imageLayout = imageAttrs.imageLayout === "left" || imageAttrs.imageLayout === "right" ? imageAttrs.imageLayout : "block";
|
|
24105
|
+
const imageWidthPreset = imageAttrs.imageWidthPreset === "sm" || imageAttrs.imageWidthPreset === "md" || imageAttrs.imageWidthPreset === "lg" ? imageAttrs.imageWidthPreset : null;
|
|
23791
24106
|
useEffect33(() => {
|
|
23792
24107
|
onKeepOpenChange?.(showLinkInput);
|
|
23793
24108
|
}, [onKeepOpenChange, showLinkInput]);
|
|
@@ -23862,6 +24177,20 @@ var BubbleMenuContent = ({
|
|
|
23862
24177
|
) })
|
|
23863
24178
|
] });
|
|
23864
24179
|
}
|
|
24180
|
+
if (isImageSelected) {
|
|
24181
|
+
return /* @__PURE__ */ jsxs68("div", { className: "flex items-center gap-0.5 p-1", children: [
|
|
24182
|
+
/* @__PURE__ */ jsx78(ToolbarButton, { onClick: () => applyImageLayout(editor, "block"), active: imageLayout === "block", title: t("toolbar.imageLayoutBlock"), children: /* @__PURE__ */ jsx78(AlignCenter2, { className: "w-4 h-4" }) }),
|
|
24183
|
+
/* @__PURE__ */ jsx78(ToolbarButton, { onClick: () => applyImageLayout(editor, "left"), active: imageLayout === "left", title: t("toolbar.imageLayoutLeft"), children: /* @__PURE__ */ jsx78(AlignLeft2, { className: "w-4 h-4" }) }),
|
|
24184
|
+
/* @__PURE__ */ jsx78(ToolbarButton, { onClick: () => applyImageLayout(editor, "right"), active: imageLayout === "right", title: t("toolbar.imageLayoutRight"), children: /* @__PURE__ */ jsx78(AlignRight2, { className: "w-4 h-4" }) }),
|
|
24185
|
+
/* @__PURE__ */ jsx78("div", { className: "w-px h-6 bg-border/50 mx-1" }),
|
|
24186
|
+
/* @__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" }) }),
|
|
24187
|
+
/* @__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" }) }),
|
|
24188
|
+
/* @__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" }) }),
|
|
24189
|
+
/* @__PURE__ */ jsx78("div", { className: "w-px h-6 bg-border/50 mx-1" }),
|
|
24190
|
+
/* @__PURE__ */ jsx78(ToolbarButton, { onClick: () => resetImageSize(editor), title: t("toolbar.imageResetSize"), children: /* @__PURE__ */ jsx78(RotateCcw3, { className: "w-4 h-4" }) }),
|
|
24191
|
+
/* @__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" }) })
|
|
24192
|
+
] });
|
|
24193
|
+
}
|
|
23865
24194
|
return /* @__PURE__ */ jsxs68("div", { className: "flex items-center gap-0.5 p-1", children: [
|
|
23866
24195
|
/* @__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" }) }),
|
|
23867
24196
|
/* @__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" }) }),
|
|
@@ -23914,19 +24243,28 @@ var BubbleMenuContent = ({
|
|
|
23914
24243
|
] });
|
|
23915
24244
|
};
|
|
23916
24245
|
var CustomBubbleMenu = ({ editor }) => {
|
|
24246
|
+
const SHOW_DELAY_MS = 180;
|
|
23917
24247
|
const [isVisible, setIsVisible] = useState45(false);
|
|
23918
24248
|
const [position, setPosition] = useState45({ top: 0, left: 0 });
|
|
23919
24249
|
const menuRef = useRef29(null);
|
|
23920
24250
|
const keepOpenRef = useRef29(false);
|
|
24251
|
+
const showTimeoutRef = useRef29(null);
|
|
23921
24252
|
const setKeepOpen = useCallback17((next) => {
|
|
23922
24253
|
keepOpenRef.current = next;
|
|
23923
24254
|
if (next) setIsVisible(true);
|
|
23924
24255
|
}, []);
|
|
23925
24256
|
useEffect33(() => {
|
|
24257
|
+
const clearShowTimeout = () => {
|
|
24258
|
+
if (showTimeoutRef.current) {
|
|
24259
|
+
clearTimeout(showTimeoutRef.current);
|
|
24260
|
+
showTimeoutRef.current = null;
|
|
24261
|
+
}
|
|
24262
|
+
};
|
|
23926
24263
|
const updatePosition = () => {
|
|
23927
24264
|
const { state, view } = editor;
|
|
23928
24265
|
const { from, to, empty } = state.selection;
|
|
23929
24266
|
if (!keepOpenRef.current && (empty || !view.hasFocus())) {
|
|
24267
|
+
clearShowTimeout();
|
|
23930
24268
|
setIsVisible(false);
|
|
23931
24269
|
return;
|
|
23932
24270
|
}
|
|
@@ -23935,15 +24273,28 @@ var CustomBubbleMenu = ({ editor }) => {
|
|
|
23935
24273
|
const left = (start.left + end.left) / 2;
|
|
23936
24274
|
const top = start.top - 10;
|
|
23937
24275
|
setPosition({ top, left });
|
|
23938
|
-
|
|
24276
|
+
if (keepOpenRef.current) {
|
|
24277
|
+
clearShowTimeout();
|
|
24278
|
+
setIsVisible(true);
|
|
24279
|
+
return;
|
|
24280
|
+
}
|
|
24281
|
+
clearShowTimeout();
|
|
24282
|
+
showTimeoutRef.current = setTimeout(() => {
|
|
24283
|
+
setIsVisible(true);
|
|
24284
|
+
showTimeoutRef.current = null;
|
|
24285
|
+
}, SHOW_DELAY_MS);
|
|
23939
24286
|
};
|
|
23940
24287
|
const handleBlur = () => {
|
|
23941
|
-
if (!keepOpenRef.current)
|
|
24288
|
+
if (!keepOpenRef.current) {
|
|
24289
|
+
clearShowTimeout();
|
|
24290
|
+
setIsVisible(false);
|
|
24291
|
+
}
|
|
23942
24292
|
};
|
|
23943
24293
|
editor.on("selectionUpdate", updatePosition);
|
|
23944
24294
|
editor.on("focus", updatePosition);
|
|
23945
24295
|
editor.on("blur", handleBlur);
|
|
23946
24296
|
return () => {
|
|
24297
|
+
clearShowTimeout();
|
|
23947
24298
|
editor.off("selectionUpdate", updatePosition);
|
|
23948
24299
|
editor.off("focus", updatePosition);
|
|
23949
24300
|
editor.off("blur", handleBlur);
|
|
@@ -24427,7 +24778,21 @@ var UEditor = React71.forwardRef(({
|
|
|
24427
24778
|
"[&_blockquote]:rounded-r-lg",
|
|
24428
24779
|
"[&_blockquote]:italic",
|
|
24429
24780
|
"[&_blockquote]:text-muted-foreground",
|
|
24430
|
-
"[&_blockquote_p]:my-0"
|
|
24781
|
+
"[&_blockquote_p]:my-0",
|
|
24782
|
+
"[&_[data-image-layout='left']+p]:mt-1",
|
|
24783
|
+
"[&_[data-image-layout='left']+p]:min-h-[5rem]",
|
|
24784
|
+
"[&_[data-image-layout='right']+p]:mt-1",
|
|
24785
|
+
"[&_[data-image-layout='right']+p]:min-h-[5rem]",
|
|
24786
|
+
"max-md:[&_[data-image-layout='left']]:float-none",
|
|
24787
|
+
"max-md:[&_[data-image-layout='left']]:mr-0",
|
|
24788
|
+
"max-md:[&_[data-image-layout='left']]:ml-0",
|
|
24789
|
+
"max-md:[&_[data-image-layout='left']]:max-w-full",
|
|
24790
|
+
"max-md:[&_[data-image-layout='right']]:float-none",
|
|
24791
|
+
"max-md:[&_[data-image-layout='right']]:mr-0",
|
|
24792
|
+
"max-md:[&_[data-image-layout='right']]:ml-0",
|
|
24793
|
+
"max-md:[&_[data-image-layout='right']]:max-w-full",
|
|
24794
|
+
"max-md:[&_[data-image-layout='left']+p]:min-h-0",
|
|
24795
|
+
"max-md:[&_[data-image-layout='right']+p]:min-h-0"
|
|
24431
24796
|
)
|
|
24432
24797
|
}
|
|
24433
24798
|
},
|