@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/api-reference.json
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -890,7 +890,15 @@ var en_default = {
|
|
|
890
890
|
heading1: "Heading 1",
|
|
891
891
|
heading2: "Heading 2",
|
|
892
892
|
heading3: "Heading 3",
|
|
893
|
-
emoji: "Insert Emoji"
|
|
893
|
+
emoji: "Insert Emoji",
|
|
894
|
+
imageLayoutBlock: "Image Block",
|
|
895
|
+
imageLayoutLeft: "Wrap Text Right",
|
|
896
|
+
imageLayoutRight: "Wrap Text Left",
|
|
897
|
+
imageWidthSm: "Image Width Small",
|
|
898
|
+
imageWidthMd: "Image Width Medium",
|
|
899
|
+
imageWidthLg: "Image Width Large",
|
|
900
|
+
imageResetSize: "Reset Image Size",
|
|
901
|
+
imageDelete: "Delete Image"
|
|
894
902
|
},
|
|
895
903
|
slashCommand: {
|
|
896
904
|
basicBlocks: "Basic Blocks",
|
|
@@ -1114,7 +1122,15 @@ var vi_default = {
|
|
|
1114
1122
|
heading1: "Ti\xEAu \u0111\u1EC1 1",
|
|
1115
1123
|
heading2: "Ti\xEAu \u0111\u1EC1 2",
|
|
1116
1124
|
heading3: "Ti\xEAu \u0111\u1EC1 3",
|
|
1117
|
-
emoji: "Ch\xE8n Emoji"
|
|
1125
|
+
emoji: "Ch\xE8n Emoji",
|
|
1126
|
+
imageLayoutBlock: "\u1EA2nh D\u1EA1ng Kh\u1ED1i",
|
|
1127
|
+
imageLayoutLeft: "\u1EA2nh Tr\xE1i, Ch\u1EEF Ph\u1EA3i",
|
|
1128
|
+
imageLayoutRight: "\u1EA2nh Ph\u1EA3i, Ch\u1EEF Tr\xE1i",
|
|
1129
|
+
imageWidthSm: "\u1EA2nh Nh\u1ECF",
|
|
1130
|
+
imageWidthMd: "\u1EA2nh V\u1EEBa",
|
|
1131
|
+
imageWidthLg: "\u1EA2nh L\u1EDBn",
|
|
1132
|
+
imageResetSize: "\u0110\u1EB7t L\u1EA1i K\xEDch Th\u01B0\u1EDBc \u1EA2nh",
|
|
1133
|
+
imageDelete: "X\xF3a \u1EA2nh"
|
|
1118
1134
|
},
|
|
1119
1135
|
slashCommand: {
|
|
1120
1136
|
basicBlocks: "Kh\u1ED1i c\u01A1 b\u1EA3n",
|
|
@@ -1338,7 +1354,15 @@ var ko_default = {
|
|
|
1338
1354
|
heading1: "\uC81C\uBAA9 1",
|
|
1339
1355
|
heading2: "\uC81C\uBAA9 2",
|
|
1340
1356
|
heading3: "\uC81C\uBAA9 3",
|
|
1341
|
-
emoji: "\uC774\uBAA8\uC9C0 \uC0BD\uC785"
|
|
1357
|
+
emoji: "\uC774\uBAA8\uC9C0 \uC0BD\uC785",
|
|
1358
|
+
imageLayoutBlock: "\uC774\uBBF8\uC9C0 \uBE14\uB85D",
|
|
1359
|
+
imageLayoutLeft: "\uC67C\uCABD \uC774\uBBF8\uC9C0, \uC624\uB978\uCABD \uD14D\uC2A4\uD2B8",
|
|
1360
|
+
imageLayoutRight: "\uC624\uB978\uCABD \uC774\uBBF8\uC9C0, \uC67C\uCABD \uD14D\uC2A4\uD2B8",
|
|
1361
|
+
imageWidthSm: "\uC791\uC740 \uC774\uBBF8\uC9C0",
|
|
1362
|
+
imageWidthMd: "\uC911\uAC04 \uC774\uBBF8\uC9C0",
|
|
1363
|
+
imageWidthLg: "\uD070 \uC774\uBBF8\uC9C0",
|
|
1364
|
+
imageResetSize: "\uC774\uBBF8\uC9C0 \uD06C\uAE30 \uCD08\uAE30\uD654",
|
|
1365
|
+
imageDelete: "\uC774\uBBF8\uC9C0 \uC0AD\uC81C"
|
|
1342
1366
|
},
|
|
1343
1367
|
slashCommand: {
|
|
1344
1368
|
basicBlocks: "\uAE30\uBCF8 \uBE14\uB85D",
|
|
@@ -1561,7 +1585,15 @@ var ja_default = {
|
|
|
1561
1585
|
heading1: "\u898B\u51FA\u3057 1",
|
|
1562
1586
|
heading2: "\u898B\u51FA\u3057 2",
|
|
1563
1587
|
heading3: "\u898B\u51FA\u3057 3",
|
|
1564
|
-
emoji: "\u7D75\u6587\u5B57\u3092\u633F\u5165"
|
|
1588
|
+
emoji: "\u7D75\u6587\u5B57\u3092\u633F\u5165",
|
|
1589
|
+
imageLayoutBlock: "\u753B\u50CF\u30D6\u30ED\u30C3\u30AF",
|
|
1590
|
+
imageLayoutLeft: "\u753B\u50CF\u3092\u5DE6\u3001\u6587\u5B57\u3092\u53F3\u306B\u56DE\u308A\u8FBC\u307F",
|
|
1591
|
+
imageLayoutRight: "\u753B\u50CF\u3092\u53F3\u3001\u6587\u5B57\u3092\u5DE6\u306B\u56DE\u308A\u8FBC\u307F",
|
|
1592
|
+
imageWidthSm: "\u753B\u50CF \u5C0F",
|
|
1593
|
+
imageWidthMd: "\u753B\u50CF \u4E2D",
|
|
1594
|
+
imageWidthLg: "\u753B\u50CF \u5927",
|
|
1595
|
+
imageResetSize: "\u753B\u50CF\u30B5\u30A4\u30BA\u3092\u30EA\u30BB\u30C3\u30C8",
|
|
1596
|
+
imageDelete: "\u753B\u50CF\u3092\u524A\u9664"
|
|
1565
1597
|
},
|
|
1566
1598
|
slashCommand: {
|
|
1567
1599
|
basicBlocks: "\u57FA\u672C\u30D6\u30ED\u30C3\u30AF",
|
|
@@ -16367,6 +16399,7 @@ function Carousel({
|
|
|
16367
16399
|
const isDeckAnimation = effectiveAnimation === "coverflow" || effectiveAnimation === "stack";
|
|
16368
16400
|
const effectiveSlidesToShow = isDeckAnimation ? 1 : slidesToShow;
|
|
16369
16401
|
const maxIndex = Math.max(0, totalSlides - effectiveSlidesToShow);
|
|
16402
|
+
const shouldShowArrows = showArrows && isHorizontal;
|
|
16370
16403
|
const presetEffectOptions = React42.useMemo(() => {
|
|
16371
16404
|
if (effectPreset === "cinematic") {
|
|
16372
16405
|
return effectiveAnimation === "stack" ? {
|
|
@@ -16414,6 +16447,52 @@ function Carousel({
|
|
|
16414
16447
|
blur: 1
|
|
16415
16448
|
};
|
|
16416
16449
|
}
|
|
16450
|
+
if (effectPreset === "poster") {
|
|
16451
|
+
return effectiveAnimation === "stack" ? {
|
|
16452
|
+
mainScale: 1.12,
|
|
16453
|
+
sideScale: 0.88,
|
|
16454
|
+
farScale: 0.78,
|
|
16455
|
+
sideOpacity: 0.64,
|
|
16456
|
+
farOpacity: 0.22,
|
|
16457
|
+
depthStep: 92,
|
|
16458
|
+
blur: 2.8,
|
|
16459
|
+
stackOffset: 14,
|
|
16460
|
+
stackLift: 18
|
|
16461
|
+
} : {
|
|
16462
|
+
mainScale: 1.16,
|
|
16463
|
+
sideScale: 0.78,
|
|
16464
|
+
farScale: 0.68,
|
|
16465
|
+
sideOpacity: 0.68,
|
|
16466
|
+
farOpacity: 0.18,
|
|
16467
|
+
sideOffset: 18,
|
|
16468
|
+
rotate: 26,
|
|
16469
|
+
depthStep: 140,
|
|
16470
|
+
blur: 3
|
|
16471
|
+
};
|
|
16472
|
+
}
|
|
16473
|
+
if (effectPreset === "minimal") {
|
|
16474
|
+
return effectiveAnimation === "stack" ? {
|
|
16475
|
+
mainScale: 1.01,
|
|
16476
|
+
sideScale: 0.96,
|
|
16477
|
+
farScale: 0.92,
|
|
16478
|
+
sideOpacity: 0.88,
|
|
16479
|
+
farOpacity: 0.66,
|
|
16480
|
+
depthStep: 36,
|
|
16481
|
+
blur: 0,
|
|
16482
|
+
stackOffset: 26,
|
|
16483
|
+
stackLift: 6
|
|
16484
|
+
} : {
|
|
16485
|
+
mainScale: 1.02,
|
|
16486
|
+
sideScale: 0.94,
|
|
16487
|
+
farScale: 0.88,
|
|
16488
|
+
sideOpacity: 0.9,
|
|
16489
|
+
farOpacity: 0.62,
|
|
16490
|
+
sideOffset: 34,
|
|
16491
|
+
rotate: 10,
|
|
16492
|
+
depthStep: 54,
|
|
16493
|
+
blur: 0
|
|
16494
|
+
};
|
|
16495
|
+
}
|
|
16417
16496
|
return {};
|
|
16418
16497
|
}, [effectPreset, effectiveAnimation]);
|
|
16419
16498
|
const mergedEffectOptions = React42.useMemo(
|
|
@@ -16616,7 +16695,7 @@ function Carousel({
|
|
|
16616
16695
|
{
|
|
16617
16696
|
className: cn(
|
|
16618
16697
|
effectiveAnimation === "slide" ? "flex" : "grid",
|
|
16619
|
-
effectiveAnimation === "slide" && (isHorizontal ? "flex-row" : "flex-col"),
|
|
16698
|
+
effectiveAnimation === "slide" && (isHorizontal ? "flex-row" : "flex-col h-full"),
|
|
16620
16699
|
isDeckAnimation && "place-items-center [transform-style:preserve-3d]",
|
|
16621
16700
|
isHorizontal ? "touch-pan-y" : "touch-pan-x",
|
|
16622
16701
|
containerClassName
|
|
@@ -16637,7 +16716,7 @@ function Carousel({
|
|
|
16637
16716
|
{
|
|
16638
16717
|
className: cn(
|
|
16639
16718
|
"shrink-0",
|
|
16640
|
-
effectiveAnimation === "slide" ? isHorizontal ? "h-full" : "w-full" : "col-start-1 row-start-1",
|
|
16719
|
+
effectiveAnimation === "slide" ? isHorizontal ? "h-full" : "h-full w-full" : "col-start-1 row-start-1",
|
|
16641
16720
|
effectiveAnimation === "fade" && (idx === currentIndex ? "opacity-100 z-10" : "opacity-0 pointer-events-none z-0"),
|
|
16642
16721
|
effectiveAnimation === "scale" && (idx === currentIndex ? "opacity-100 scale-100 z-10" : "opacity-0 scale-95 pointer-events-none z-0"),
|
|
16643
16722
|
isDeckAnimation && "w-full max-w-[78%] md:max-w-[72%] transition-[opacity,transform] duration-500 ease-out",
|
|
@@ -16655,7 +16734,7 @@ function Carousel({
|
|
|
16655
16734
|
))
|
|
16656
16735
|
}
|
|
16657
16736
|
),
|
|
16658
|
-
|
|
16737
|
+
shouldShowArrows && totalSlides > effectiveSlidesToShow && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_jsx_runtime49.Fragment, { children: [
|
|
16659
16738
|
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
16660
16739
|
Button_default,
|
|
16661
16740
|
{
|
|
@@ -22488,6 +22567,8 @@ var import_react44 = require("@tiptap/react");
|
|
|
22488
22567
|
var import_jsx_runtime73 = require("react/jsx-runtime");
|
|
22489
22568
|
var MIN_IMAGE_SIZE_PX = 40;
|
|
22490
22569
|
var AXIS_LOCK_THRESHOLD_PX = 4;
|
|
22570
|
+
var IMAGE_LAYOUTS = /* @__PURE__ */ new Set(["block", "left", "right"]);
|
|
22571
|
+
var IMAGE_WIDTH_PRESETS = /* @__PURE__ */ new Set(["sm", "md", "lg"]);
|
|
22491
22572
|
function toNullableNumber(value) {
|
|
22492
22573
|
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
22493
22574
|
if (typeof value === "string") {
|
|
@@ -22499,6 +22580,33 @@ function toNullableNumber(value) {
|
|
|
22499
22580
|
function clamp8(value, min, max) {
|
|
22500
22581
|
return Math.min(max, Math.max(min, value));
|
|
22501
22582
|
}
|
|
22583
|
+
function parseImageLayout(value) {
|
|
22584
|
+
if (typeof value === "string" && IMAGE_LAYOUTS.has(value)) {
|
|
22585
|
+
return value;
|
|
22586
|
+
}
|
|
22587
|
+
return "block";
|
|
22588
|
+
}
|
|
22589
|
+
function parseImageWidthPreset(value) {
|
|
22590
|
+
if (typeof value === "string" && IMAGE_WIDTH_PRESETS.has(value)) {
|
|
22591
|
+
return value;
|
|
22592
|
+
}
|
|
22593
|
+
return null;
|
|
22594
|
+
}
|
|
22595
|
+
function getImageLayoutStyles(layout) {
|
|
22596
|
+
if (layout === "left") {
|
|
22597
|
+
return {
|
|
22598
|
+
"data-image-layout": "left",
|
|
22599
|
+
style: "float:left;display:block;margin:0.25rem 1rem 0.75rem 0;"
|
|
22600
|
+
};
|
|
22601
|
+
}
|
|
22602
|
+
if (layout === "right") {
|
|
22603
|
+
return {
|
|
22604
|
+
"data-image-layout": "right",
|
|
22605
|
+
style: "float:right;display:block;margin:0.25rem 0 0.75rem 1rem;"
|
|
22606
|
+
};
|
|
22607
|
+
}
|
|
22608
|
+
return {};
|
|
22609
|
+
}
|
|
22502
22610
|
function ResizableImageNodeView(props) {
|
|
22503
22611
|
const { node, selected, updateAttributes, editor, getPos } = props;
|
|
22504
22612
|
const wrapperRef = (0, import_react43.useRef)(null);
|
|
@@ -22508,6 +22616,8 @@ function ResizableImageNodeView(props) {
|
|
|
22508
22616
|
const widthAttr = toNullableNumber(node.attrs["width"]);
|
|
22509
22617
|
const heightAttr = toNullableNumber(node.attrs["height"]);
|
|
22510
22618
|
const textAlign = String(node.attrs["textAlign"] ?? "");
|
|
22619
|
+
const imageLayout = parseImageLayout(node.attrs["imageLayout"]);
|
|
22620
|
+
const preserveAspectByDefault = imageLayout === "left" || imageLayout === "right";
|
|
22511
22621
|
const dragStateRef = (0, import_react43.useRef)(null);
|
|
22512
22622
|
(0, import_react43.useEffect)(() => {
|
|
22513
22623
|
const img = imgRef.current;
|
|
@@ -22556,7 +22666,8 @@ function ResizableImageNodeView(props) {
|
|
|
22556
22666
|
const dy = event.clientY - drag.startY;
|
|
22557
22667
|
let nextW = drag.startW;
|
|
22558
22668
|
let nextH = drag.startH;
|
|
22559
|
-
|
|
22669
|
+
const shouldPreserveAspect = preserveAspectByDefault ? !event.ctrlKey : event.ctrlKey;
|
|
22670
|
+
if (shouldPreserveAspect) {
|
|
22560
22671
|
if (Math.abs(dx) >= Math.abs(dy)) {
|
|
22561
22672
|
nextW = clamp8(drag.startW + dx, MIN_IMAGE_SIZE_PX, drag.maxW);
|
|
22562
22673
|
nextH = clamp8(nextW / drag.aspect, MIN_IMAGE_SIZE_PX, Number.POSITIVE_INFINITY);
|
|
@@ -22583,7 +22694,8 @@ function ResizableImageNodeView(props) {
|
|
|
22583
22694
|
if (!drag) return;
|
|
22584
22695
|
updateAttributes({
|
|
22585
22696
|
width: Math.round(drag.lastW),
|
|
22586
|
-
height: Math.round(drag.lastH)
|
|
22697
|
+
height: Math.round(drag.lastH),
|
|
22698
|
+
imageWidthPreset: null
|
|
22587
22699
|
});
|
|
22588
22700
|
};
|
|
22589
22701
|
const onResizePointerUp = (event) => {
|
|
@@ -22601,14 +22713,15 @@ function ResizableImageNodeView(props) {
|
|
|
22601
22713
|
finishResize();
|
|
22602
22714
|
};
|
|
22603
22715
|
const showHandle = selected || isHovered || isResizing;
|
|
22604
|
-
const wrapperAlignClass = textAlign === "center" ? "mx-auto" : textAlign === "right" ? "ml-auto" : textAlign === "justify" ? "mx-auto" : "";
|
|
22605
|
-
const
|
|
22716
|
+
const wrapperAlignClass = imageLayout === "block" ? textAlign === "center" ? "mx-auto" : textAlign === "right" ? "ml-auto" : textAlign === "justify" ? "mx-auto" : "" : "";
|
|
22717
|
+
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";
|
|
22606
22718
|
return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
|
|
22607
22719
|
import_react44.NodeViewWrapper,
|
|
22608
22720
|
{
|
|
22609
22721
|
as: "div",
|
|
22610
22722
|
ref: wrapperRef,
|
|
22611
|
-
|
|
22723
|
+
"data-image-layout": imageLayout,
|
|
22724
|
+
className: ["relative block align-middle max-w-full my-4", wrapperLayoutClass, wrapperAlignClass].filter(Boolean).join(" "),
|
|
22612
22725
|
onMouseEnter: () => setIsHovered(true),
|
|
22613
22726
|
onMouseLeave: () => setIsHovered(false),
|
|
22614
22727
|
onClick: (e) => {
|
|
@@ -22678,6 +22791,25 @@ var ResizableImage = import_extension_image.default.extend({
|
|
|
22678
22791
|
return Number.isFinite(parsed) ? parsed : null;
|
|
22679
22792
|
},
|
|
22680
22793
|
renderHTML: (attrs) => typeof attrs.height === "number" ? { height: attrs.height } : {}
|
|
22794
|
+
},
|
|
22795
|
+
imageLayout: {
|
|
22796
|
+
default: "block",
|
|
22797
|
+
parseHTML: (element) => {
|
|
22798
|
+
const explicit = element.getAttribute("data-image-layout");
|
|
22799
|
+
if (explicit) return parseImageLayout(explicit);
|
|
22800
|
+
const floatValue = element.style.float;
|
|
22801
|
+
if (floatValue === "left" || floatValue === "right") return floatValue;
|
|
22802
|
+
return "block";
|
|
22803
|
+
},
|
|
22804
|
+
renderHTML: (attrs) => getImageLayoutStyles(parseImageLayout(attrs.imageLayout))
|
|
22805
|
+
},
|
|
22806
|
+
imageWidthPreset: {
|
|
22807
|
+
default: null,
|
|
22808
|
+
parseHTML: (element) => parseImageWidthPreset(element.getAttribute("data-image-size")),
|
|
22809
|
+
renderHTML: (attrs) => {
|
|
22810
|
+
const preset = parseImageWidthPreset(attrs.imageWidthPreset);
|
|
22811
|
+
return preset ? { "data-image-size": preset } : {};
|
|
22812
|
+
}
|
|
22681
22813
|
}
|
|
22682
22814
|
};
|
|
22683
22815
|
},
|
|
@@ -22906,6 +23038,96 @@ var EditorColorPalette = ({
|
|
|
22906
23038
|
)) })
|
|
22907
23039
|
] });
|
|
22908
23040
|
|
|
23041
|
+
// src/components/UEditor/image-commands.ts
|
|
23042
|
+
var import_state4 = require("@tiptap/pm/state");
|
|
23043
|
+
var IMAGE_WIDTHS_BY_LAYOUT = {
|
|
23044
|
+
block: {
|
|
23045
|
+
sm: 180,
|
|
23046
|
+
md: 280,
|
|
23047
|
+
lg: 380
|
|
23048
|
+
},
|
|
23049
|
+
wrap: {
|
|
23050
|
+
sm: 140,
|
|
23051
|
+
md: 200,
|
|
23052
|
+
lg: 260
|
|
23053
|
+
}
|
|
23054
|
+
};
|
|
23055
|
+
function isSelectedImage(editor) {
|
|
23056
|
+
const { selection } = editor.state;
|
|
23057
|
+
return selection instanceof import_state4.NodeSelection && selection.node.type.name === "image";
|
|
23058
|
+
}
|
|
23059
|
+
function applyImageLayout(editor, layout) {
|
|
23060
|
+
const { state, view } = editor;
|
|
23061
|
+
const { selection, schema } = state;
|
|
23062
|
+
if (!(selection instanceof import_state4.NodeSelection) || selection.node.type.name !== "image") {
|
|
23063
|
+
editor.chain().focus().updateAttributes("image", { imageLayout: layout }).run();
|
|
23064
|
+
return;
|
|
23065
|
+
}
|
|
23066
|
+
let transaction = state.tr.setNodeMarkup(selection.from, void 0, {
|
|
23067
|
+
...selection.node.attrs,
|
|
23068
|
+
imageLayout: layout
|
|
23069
|
+
});
|
|
23070
|
+
if (layout !== "block") {
|
|
23071
|
+
const nextPos = transaction.mapping.map(selection.to);
|
|
23072
|
+
const nextNode = transaction.doc.nodeAt(nextPos);
|
|
23073
|
+
if (!nextNode || nextNode.type.name !== "paragraph") {
|
|
23074
|
+
const paragraph = schema.nodes.paragraph?.create();
|
|
23075
|
+
if (paragraph) {
|
|
23076
|
+
transaction = transaction.insert(nextPos, paragraph);
|
|
23077
|
+
}
|
|
23078
|
+
}
|
|
23079
|
+
const resolvedPos = transaction.doc.resolve(Math.min(nextPos + 1, transaction.doc.content.size));
|
|
23080
|
+
transaction = transaction.setSelection(import_state4.TextSelection.near(resolvedPos));
|
|
23081
|
+
} else {
|
|
23082
|
+
const resolvedPos = transaction.doc.resolve(selection.from);
|
|
23083
|
+
transaction = transaction.setSelection(import_state4.NodeSelection.create(transaction.doc, resolvedPos.pos));
|
|
23084
|
+
}
|
|
23085
|
+
view.dispatch(transaction.scrollIntoView());
|
|
23086
|
+
view.focus();
|
|
23087
|
+
}
|
|
23088
|
+
function applyImageWidthPreset(editor, preset) {
|
|
23089
|
+
const attrs = editor.getAttributes("image");
|
|
23090
|
+
const mode = attrs.imageLayout === "left" || attrs.imageLayout === "right" ? "wrap" : "block";
|
|
23091
|
+
const width = IMAGE_WIDTHS_BY_LAYOUT[mode][preset];
|
|
23092
|
+
if (!isSelectedImage(editor)) {
|
|
23093
|
+
editor.chain().focus().updateAttributes("image", { width, imageWidthPreset: preset }).run();
|
|
23094
|
+
return;
|
|
23095
|
+
}
|
|
23096
|
+
const { state, view } = editor;
|
|
23097
|
+
const selection = state.selection;
|
|
23098
|
+
const transaction = state.tr.setNodeMarkup(selection.from, void 0, {
|
|
23099
|
+
...selection.node.attrs,
|
|
23100
|
+
width,
|
|
23101
|
+
imageWidthPreset: preset
|
|
23102
|
+
});
|
|
23103
|
+
view.dispatch(transaction.scrollIntoView());
|
|
23104
|
+
view.focus();
|
|
23105
|
+
}
|
|
23106
|
+
function resetImageSize(editor) {
|
|
23107
|
+
if (!isSelectedImage(editor)) {
|
|
23108
|
+
editor.chain().focus().updateAttributes("image", {
|
|
23109
|
+
width: null,
|
|
23110
|
+
height: null,
|
|
23111
|
+
imageWidthPreset: null
|
|
23112
|
+
}).run();
|
|
23113
|
+
return;
|
|
23114
|
+
}
|
|
23115
|
+
const { state, view } = editor;
|
|
23116
|
+
const selection = state.selection;
|
|
23117
|
+
const transaction = state.tr.setNodeMarkup(selection.from, void 0, {
|
|
23118
|
+
...selection.node.attrs,
|
|
23119
|
+
width: null,
|
|
23120
|
+
height: null,
|
|
23121
|
+
imageWidthPreset: null
|
|
23122
|
+
});
|
|
23123
|
+
view.dispatch(transaction.scrollIntoView());
|
|
23124
|
+
view.focus();
|
|
23125
|
+
}
|
|
23126
|
+
function deleteSelectedImage(editor) {
|
|
23127
|
+
if (!isSelectedImage(editor)) return;
|
|
23128
|
+
editor.chain().focus().deleteSelection().run();
|
|
23129
|
+
}
|
|
23130
|
+
|
|
22909
23131
|
// src/components/UEditor/inputs.tsx
|
|
22910
23132
|
var import_react46 = require("react");
|
|
22911
23133
|
var import_lucide_react42 = require("lucide-react");
|
|
@@ -23242,6 +23464,10 @@ var EditorToolbar = ({
|
|
|
23242
23464
|
const fileInputRef = (0, import_react48.useRef)(null);
|
|
23243
23465
|
const [isUploadingImage, setIsUploadingImage] = (0, import_react48.useState)(false);
|
|
23244
23466
|
const [imageUploadError, setImageUploadError] = (0, import_react48.useState)(null);
|
|
23467
|
+
const isImageSelected = editor.isActive("image");
|
|
23468
|
+
const imageAttrs = editor.getAttributes("image");
|
|
23469
|
+
const imageLayout = imageAttrs.imageLayout === "left" || imageAttrs.imageLayout === "right" ? imageAttrs.imageLayout : "block";
|
|
23470
|
+
const imageWidthPreset = imageAttrs.imageWidthPreset === "sm" || imageAttrs.imageWidthPreset === "md" || imageAttrs.imageWidthPreset === "lg" ? imageAttrs.imageWidthPreset : null;
|
|
23245
23471
|
const insertImageFiles = async (files) => {
|
|
23246
23472
|
if (files.length === 0) return;
|
|
23247
23473
|
setIsUploadingImage(true);
|
|
@@ -23574,6 +23800,85 @@ var EditorToolbar = ({
|
|
|
23574
23800
|
void insertImageFiles(files);
|
|
23575
23801
|
}
|
|
23576
23802
|
}
|
|
23803
|
+
),
|
|
23804
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: "my-1 border-t" }),
|
|
23805
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
|
|
23806
|
+
DropdownMenuItem,
|
|
23807
|
+
{
|
|
23808
|
+
icon: import_lucide_react44.AlignCenter,
|
|
23809
|
+
label: t("toolbar.imageLayoutBlock"),
|
|
23810
|
+
onClick: () => applyImageLayout(editor, "block"),
|
|
23811
|
+
active: isImageSelected && imageLayout === "block",
|
|
23812
|
+
disabled: !isImageSelected
|
|
23813
|
+
}
|
|
23814
|
+
),
|
|
23815
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
|
|
23816
|
+
DropdownMenuItem,
|
|
23817
|
+
{
|
|
23818
|
+
icon: import_lucide_react44.AlignLeft,
|
|
23819
|
+
label: t("toolbar.imageLayoutLeft"),
|
|
23820
|
+
onClick: () => applyImageLayout(editor, "left"),
|
|
23821
|
+
active: isImageSelected && imageLayout === "left",
|
|
23822
|
+
disabled: !isImageSelected
|
|
23823
|
+
}
|
|
23824
|
+
),
|
|
23825
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
|
|
23826
|
+
DropdownMenuItem,
|
|
23827
|
+
{
|
|
23828
|
+
icon: import_lucide_react44.AlignRight,
|
|
23829
|
+
label: t("toolbar.imageLayoutRight"),
|
|
23830
|
+
onClick: () => applyImageLayout(editor, "right"),
|
|
23831
|
+
active: isImageSelected && imageLayout === "right",
|
|
23832
|
+
disabled: !isImageSelected
|
|
23833
|
+
}
|
|
23834
|
+
),
|
|
23835
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: "my-1 border-t" }),
|
|
23836
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
|
|
23837
|
+
DropdownMenuItem,
|
|
23838
|
+
{
|
|
23839
|
+
label: t("toolbar.imageWidthSm"),
|
|
23840
|
+
onClick: () => applyImageWidthPreset(editor, "sm"),
|
|
23841
|
+
active: isImageSelected && imageWidthPreset === "sm",
|
|
23842
|
+
disabled: !isImageSelected
|
|
23843
|
+
}
|
|
23844
|
+
),
|
|
23845
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
|
|
23846
|
+
DropdownMenuItem,
|
|
23847
|
+
{
|
|
23848
|
+
label: t("toolbar.imageWidthMd"),
|
|
23849
|
+
onClick: () => applyImageWidthPreset(editor, "md"),
|
|
23850
|
+
active: isImageSelected && imageWidthPreset === "md",
|
|
23851
|
+
disabled: !isImageSelected
|
|
23852
|
+
}
|
|
23853
|
+
),
|
|
23854
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
|
|
23855
|
+
DropdownMenuItem,
|
|
23856
|
+
{
|
|
23857
|
+
label: t("toolbar.imageWidthLg"),
|
|
23858
|
+
onClick: () => applyImageWidthPreset(editor, "lg"),
|
|
23859
|
+
active: isImageSelected && imageWidthPreset === "lg",
|
|
23860
|
+
disabled: !isImageSelected
|
|
23861
|
+
}
|
|
23862
|
+
),
|
|
23863
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: "my-1 border-t" }),
|
|
23864
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
|
|
23865
|
+
DropdownMenuItem,
|
|
23866
|
+
{
|
|
23867
|
+
icon: import_lucide_react44.RotateCcw,
|
|
23868
|
+
label: t("toolbar.imageResetSize"),
|
|
23869
|
+
onClick: () => resetImageSize(editor),
|
|
23870
|
+
disabled: !isImageSelected
|
|
23871
|
+
}
|
|
23872
|
+
),
|
|
23873
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
|
|
23874
|
+
DropdownMenuItem,
|
|
23875
|
+
{
|
|
23876
|
+
icon: import_lucide_react44.Trash2,
|
|
23877
|
+
label: t("toolbar.imageDelete"),
|
|
23878
|
+
onClick: () => deleteSelectedImage(editor),
|
|
23879
|
+
disabled: !isImageSelected,
|
|
23880
|
+
destructive: true
|
|
23881
|
+
}
|
|
23577
23882
|
)
|
|
23578
23883
|
] })
|
|
23579
23884
|
}
|
|
@@ -23886,6 +24191,10 @@ var BubbleMenuContent = ({
|
|
|
23886
24191
|
const { textColors, highlightColors } = useEditorColors();
|
|
23887
24192
|
const [showLinkInput, setShowLinkInput] = (0, import_react49.useState)(false);
|
|
23888
24193
|
const [showEditorColorPalette, setShowEditorColorPalette] = (0, import_react49.useState)(false);
|
|
24194
|
+
const isImageSelected = editor.isActive("image");
|
|
24195
|
+
const imageAttrs = editor.getAttributes("image");
|
|
24196
|
+
const imageLayout = imageAttrs.imageLayout === "left" || imageAttrs.imageLayout === "right" ? imageAttrs.imageLayout : "block";
|
|
24197
|
+
const imageWidthPreset = imageAttrs.imageWidthPreset === "sm" || imageAttrs.imageWidthPreset === "md" || imageAttrs.imageWidthPreset === "lg" ? imageAttrs.imageWidthPreset : null;
|
|
23889
24198
|
(0, import_react49.useEffect)(() => {
|
|
23890
24199
|
onKeepOpenChange?.(showLinkInput);
|
|
23891
24200
|
}, [onKeepOpenChange, showLinkInput]);
|
|
@@ -23960,6 +24269,20 @@ var BubbleMenuContent = ({
|
|
|
23960
24269
|
) })
|
|
23961
24270
|
] });
|
|
23962
24271
|
}
|
|
24272
|
+
if (isImageSelected) {
|
|
24273
|
+
return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "flex items-center gap-0.5 p-1", children: [
|
|
24274
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)(ToolbarButton, { onClick: () => applyImageLayout(editor, "block"), active: imageLayout === "block", title: t("toolbar.imageLayoutBlock"), children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_lucide_react45.AlignCenter, { className: "w-4 h-4" }) }),
|
|
24275
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)(ToolbarButton, { onClick: () => applyImageLayout(editor, "left"), active: imageLayout === "left", title: t("toolbar.imageLayoutLeft"), children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_lucide_react45.AlignLeft, { className: "w-4 h-4" }) }),
|
|
24276
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)(ToolbarButton, { onClick: () => applyImageLayout(editor, "right"), active: imageLayout === "right", title: t("toolbar.imageLayoutRight"), children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_lucide_react45.AlignRight, { className: "w-4 h-4" }) }),
|
|
24277
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "w-px h-6 bg-border/50 mx-1" }),
|
|
24278
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)(ToolbarButton, { onClick: () => applyImageWidthPreset(editor, "sm"), active: imageWidthPreset === "sm", title: t("toolbar.imageWidthSm"), children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "text-[10px] font-semibold", children: "S" }) }),
|
|
24279
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)(ToolbarButton, { onClick: () => applyImageWidthPreset(editor, "md"), active: imageWidthPreset === "md", title: t("toolbar.imageWidthMd"), children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "text-[10px] font-semibold", children: "M" }) }),
|
|
24280
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)(ToolbarButton, { onClick: () => applyImageWidthPreset(editor, "lg"), active: imageWidthPreset === "lg", title: t("toolbar.imageWidthLg"), children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "text-[10px] font-semibold", children: "L" }) }),
|
|
24281
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "w-px h-6 bg-border/50 mx-1" }),
|
|
24282
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)(ToolbarButton, { onClick: () => resetImageSize(editor), title: t("toolbar.imageResetSize"), children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_lucide_react45.RotateCcw, { className: "w-4 h-4" }) }),
|
|
24283
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)(ToolbarButton, { onClick: () => deleteSelectedImage(editor), title: t("toolbar.imageDelete"), className: "text-destructive hover:text-destructive", children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_lucide_react45.Trash2, { className: "w-4 h-4" }) })
|
|
24284
|
+
] });
|
|
24285
|
+
}
|
|
23963
24286
|
return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "flex items-center gap-0.5 p-1", children: [
|
|
23964
24287
|
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)(ToolbarButton, { onClick: () => editor.chain().focus().toggleBold().run(), active: editor.isActive("bold"), title: t("toolbar.bold"), children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_lucide_react45.Bold, { className: "w-4 h-4" }) }),
|
|
23965
24288
|
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)(ToolbarButton, { onClick: () => editor.chain().focus().toggleItalic().run(), active: editor.isActive("italic"), title: t("toolbar.italic"), children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_lucide_react45.Italic, { className: "w-4 h-4" }) }),
|
|
@@ -24012,19 +24335,28 @@ var BubbleMenuContent = ({
|
|
|
24012
24335
|
] });
|
|
24013
24336
|
};
|
|
24014
24337
|
var CustomBubbleMenu = ({ editor }) => {
|
|
24338
|
+
const SHOW_DELAY_MS = 180;
|
|
24015
24339
|
const [isVisible, setIsVisible] = (0, import_react49.useState)(false);
|
|
24016
24340
|
const [position, setPosition] = (0, import_react49.useState)({ top: 0, left: 0 });
|
|
24017
24341
|
const menuRef = (0, import_react49.useRef)(null);
|
|
24018
24342
|
const keepOpenRef = (0, import_react49.useRef)(false);
|
|
24343
|
+
const showTimeoutRef = (0, import_react49.useRef)(null);
|
|
24019
24344
|
const setKeepOpen = (0, import_react49.useCallback)((next) => {
|
|
24020
24345
|
keepOpenRef.current = next;
|
|
24021
24346
|
if (next) setIsVisible(true);
|
|
24022
24347
|
}, []);
|
|
24023
24348
|
(0, import_react49.useEffect)(() => {
|
|
24349
|
+
const clearShowTimeout = () => {
|
|
24350
|
+
if (showTimeoutRef.current) {
|
|
24351
|
+
clearTimeout(showTimeoutRef.current);
|
|
24352
|
+
showTimeoutRef.current = null;
|
|
24353
|
+
}
|
|
24354
|
+
};
|
|
24024
24355
|
const updatePosition = () => {
|
|
24025
24356
|
const { state, view } = editor;
|
|
24026
24357
|
const { from, to, empty } = state.selection;
|
|
24027
24358
|
if (!keepOpenRef.current && (empty || !view.hasFocus())) {
|
|
24359
|
+
clearShowTimeout();
|
|
24028
24360
|
setIsVisible(false);
|
|
24029
24361
|
return;
|
|
24030
24362
|
}
|
|
@@ -24033,15 +24365,28 @@ var CustomBubbleMenu = ({ editor }) => {
|
|
|
24033
24365
|
const left = (start.left + end.left) / 2;
|
|
24034
24366
|
const top = start.top - 10;
|
|
24035
24367
|
setPosition({ top, left });
|
|
24036
|
-
|
|
24368
|
+
if (keepOpenRef.current) {
|
|
24369
|
+
clearShowTimeout();
|
|
24370
|
+
setIsVisible(true);
|
|
24371
|
+
return;
|
|
24372
|
+
}
|
|
24373
|
+
clearShowTimeout();
|
|
24374
|
+
showTimeoutRef.current = setTimeout(() => {
|
|
24375
|
+
setIsVisible(true);
|
|
24376
|
+
showTimeoutRef.current = null;
|
|
24377
|
+
}, SHOW_DELAY_MS);
|
|
24037
24378
|
};
|
|
24038
24379
|
const handleBlur = () => {
|
|
24039
|
-
if (!keepOpenRef.current)
|
|
24380
|
+
if (!keepOpenRef.current) {
|
|
24381
|
+
clearShowTimeout();
|
|
24382
|
+
setIsVisible(false);
|
|
24383
|
+
}
|
|
24040
24384
|
};
|
|
24041
24385
|
editor.on("selectionUpdate", updatePosition);
|
|
24042
24386
|
editor.on("focus", updatePosition);
|
|
24043
24387
|
editor.on("blur", handleBlur);
|
|
24044
24388
|
return () => {
|
|
24389
|
+
clearShowTimeout();
|
|
24045
24390
|
editor.off("selectionUpdate", updatePosition);
|
|
24046
24391
|
editor.off("focus", updatePosition);
|
|
24047
24392
|
editor.off("blur", handleBlur);
|
|
@@ -24525,7 +24870,21 @@ var UEditor = import_react50.default.forwardRef(({
|
|
|
24525
24870
|
"[&_blockquote]:rounded-r-lg",
|
|
24526
24871
|
"[&_blockquote]:italic",
|
|
24527
24872
|
"[&_blockquote]:text-muted-foreground",
|
|
24528
|
-
"[&_blockquote_p]:my-0"
|
|
24873
|
+
"[&_blockquote_p]:my-0",
|
|
24874
|
+
"[&_[data-image-layout='left']+p]:mt-1",
|
|
24875
|
+
"[&_[data-image-layout='left']+p]:min-h-[5rem]",
|
|
24876
|
+
"[&_[data-image-layout='right']+p]:mt-1",
|
|
24877
|
+
"[&_[data-image-layout='right']+p]:min-h-[5rem]",
|
|
24878
|
+
"max-md:[&_[data-image-layout='left']]:float-none",
|
|
24879
|
+
"max-md:[&_[data-image-layout='left']]:mr-0",
|
|
24880
|
+
"max-md:[&_[data-image-layout='left']]:ml-0",
|
|
24881
|
+
"max-md:[&_[data-image-layout='left']]:max-w-full",
|
|
24882
|
+
"max-md:[&_[data-image-layout='right']]:float-none",
|
|
24883
|
+
"max-md:[&_[data-image-layout='right']]:mr-0",
|
|
24884
|
+
"max-md:[&_[data-image-layout='right']]:ml-0",
|
|
24885
|
+
"max-md:[&_[data-image-layout='right']]:max-w-full",
|
|
24886
|
+
"max-md:[&_[data-image-layout='left']+p]:min-h-0",
|
|
24887
|
+
"max-md:[&_[data-image-layout='right']+p]:min-h-0"
|
|
24529
24888
|
)
|
|
24530
24889
|
}
|
|
24531
24890
|
},
|