@trafica/editor 1.0.45 → 1.0.47
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/dist/index.js +135 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +135 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -8034,6 +8034,7 @@ function EditorCore({
|
|
|
8034
8034
|
const isComposingRef = useRef(false);
|
|
8035
8035
|
const stateRef = useRef(engine.getState());
|
|
8036
8036
|
const [selectedImagePath, setSelectedImagePath] = useState(null);
|
|
8037
|
+
const [imageDragState, setImageDragState] = useState(null);
|
|
8037
8038
|
const [findReplaceOpen, setFindReplaceOpen] = useState(false);
|
|
8038
8039
|
const [findReplaceMode, setFindReplaceMode] = useState("find");
|
|
8039
8040
|
const [linkPopupOpen, setLinkPopupOpen] = useState(false);
|
|
@@ -8514,7 +8515,19 @@ function EditorCore({
|
|
|
8514
8515
|
const fig = target.closest("[data-image-path]");
|
|
8515
8516
|
if (fig == null ? void 0 : fig.dataset.imagePath) {
|
|
8516
8517
|
e.preventDefault();
|
|
8517
|
-
|
|
8518
|
+
const path = JSON.parse(fig.dataset.imagePath);
|
|
8519
|
+
setSelectedImagePath(path);
|
|
8520
|
+
const imgEl = fig.querySelector("img");
|
|
8521
|
+
const rect = imgEl == null ? void 0 : imgEl.getBoundingClientRect();
|
|
8522
|
+
imageDragRef.current = {
|
|
8523
|
+
imagePath: path,
|
|
8524
|
+
startX: e.clientX,
|
|
8525
|
+
startY: e.clientY,
|
|
8526
|
+
active: false,
|
|
8527
|
+
ghostW: Math.min((rect == null ? void 0 : rect.width) || 300, 320),
|
|
8528
|
+
ghostH: Math.min((rect == null ? void 0 : rect.height) || 200, 200),
|
|
8529
|
+
ghostSrc: (imgEl == null ? void 0 : imgEl.src) || ""
|
|
8530
|
+
};
|
|
8518
8531
|
return;
|
|
8519
8532
|
}
|
|
8520
8533
|
setSelectedImagePath(null);
|
|
@@ -8567,6 +8580,7 @@ function EditorCore({
|
|
|
8567
8580
|
engine.dispatch(tr);
|
|
8568
8581
|
}, [engine]);
|
|
8569
8582
|
const imageResizeRef = useRef(null);
|
|
8583
|
+
const imageDragRef = useRef(null);
|
|
8570
8584
|
useEffect(() => {
|
|
8571
8585
|
const onMouseMove = (e) => {
|
|
8572
8586
|
const drag = imageResizeRef.current;
|
|
@@ -8599,6 +8613,48 @@ function EditorCore({
|
|
|
8599
8613
|
document.removeEventListener("mouseup", onMouseUp);
|
|
8600
8614
|
};
|
|
8601
8615
|
}, [engine]);
|
|
8616
|
+
useEffect(() => {
|
|
8617
|
+
const DRAG_THRESHOLD = 6;
|
|
8618
|
+
const onMouseMove = (e) => {
|
|
8619
|
+
const drag = imageDragRef.current;
|
|
8620
|
+
if (!drag) return;
|
|
8621
|
+
const dx = e.clientX - drag.startX;
|
|
8622
|
+
const dy = e.clientY - drag.startY;
|
|
8623
|
+
if (!drag.active && Math.sqrt(dx * dx + dy * dy) < DRAG_THRESHOLD) return;
|
|
8624
|
+
drag.active = true;
|
|
8625
|
+
const container = containerRef.current;
|
|
8626
|
+
const { dropIndex, indicatorClientY } = getImageDropTarget(container, e.clientY, drag.imagePath);
|
|
8627
|
+
setImageDragState({
|
|
8628
|
+
ghostX: e.clientX,
|
|
8629
|
+
ghostY: e.clientY,
|
|
8630
|
+
ghostW: drag.ghostW,
|
|
8631
|
+
ghostH: drag.ghostH,
|
|
8632
|
+
ghostSrc: drag.ghostSrc,
|
|
8633
|
+
dropIndicatorClientY: indicatorClientY,
|
|
8634
|
+
dropIndex,
|
|
8635
|
+
imagePath: drag.imagePath
|
|
8636
|
+
});
|
|
8637
|
+
};
|
|
8638
|
+
const onMouseUp = (e) => {
|
|
8639
|
+
const drag = imageDragRef.current;
|
|
8640
|
+
if (!drag) return;
|
|
8641
|
+
imageDragRef.current = null;
|
|
8642
|
+
if (!drag.active) {
|
|
8643
|
+
setImageDragState(null);
|
|
8644
|
+
return;
|
|
8645
|
+
}
|
|
8646
|
+
const container = containerRef.current;
|
|
8647
|
+
const { dropIndex } = getImageDropTarget(container, e.clientY, drag.imagePath);
|
|
8648
|
+
setImageDragState(null);
|
|
8649
|
+
moveImageInDoc(drag.imagePath, dropIndex, engine);
|
|
8650
|
+
};
|
|
8651
|
+
document.addEventListener("mousemove", onMouseMove);
|
|
8652
|
+
document.addEventListener("mouseup", onMouseUp);
|
|
8653
|
+
return () => {
|
|
8654
|
+
document.removeEventListener("mousemove", onMouseMove);
|
|
8655
|
+
document.removeEventListener("mouseup", onMouseUp);
|
|
8656
|
+
};
|
|
8657
|
+
}, [engine]);
|
|
8602
8658
|
useEffect(() => {
|
|
8603
8659
|
const container = containerRef.current;
|
|
8604
8660
|
if (!container) return;
|
|
@@ -8716,6 +8772,19 @@ function EditorCore({
|
|
|
8716
8772
|
].join(" ")
|
|
8717
8773
|
}
|
|
8718
8774
|
),
|
|
8775
|
+
imageDragState && (() => {
|
|
8776
|
+
const container = containerRef.current;
|
|
8777
|
+
if (!container) return null;
|
|
8778
|
+
const cr = container.getBoundingClientRect();
|
|
8779
|
+
const relY = imageDragState.dropIndicatorClientY - cr.top + container.scrollTop;
|
|
8780
|
+
return /* @__PURE__ */ jsx(
|
|
8781
|
+
"div",
|
|
8782
|
+
{
|
|
8783
|
+
className: "editor-image-drop-indicator",
|
|
8784
|
+
style: { top: relY }
|
|
8785
|
+
}
|
|
8786
|
+
);
|
|
8787
|
+
})(),
|
|
8719
8788
|
linkTooltip && /* @__PURE__ */ jsxs(
|
|
8720
8789
|
"div",
|
|
8721
8790
|
{
|
|
@@ -8776,6 +8845,26 @@ function EditorCore({
|
|
|
8776
8845
|
onClose: () => setSelectedImagePath(null)
|
|
8777
8846
|
}
|
|
8778
8847
|
),
|
|
8848
|
+
imageDragState && /* @__PURE__ */ jsx(
|
|
8849
|
+
"div",
|
|
8850
|
+
{
|
|
8851
|
+
className: "editor-image-drag-ghost",
|
|
8852
|
+
style: {
|
|
8853
|
+
left: imageDragState.ghostX,
|
|
8854
|
+
top: imageDragState.ghostY,
|
|
8855
|
+
width: imageDragState.ghostW,
|
|
8856
|
+
height: imageDragState.ghostH
|
|
8857
|
+
},
|
|
8858
|
+
children: /* @__PURE__ */ jsx(
|
|
8859
|
+
"img",
|
|
8860
|
+
{
|
|
8861
|
+
src: imageDragState.ghostSrc,
|
|
8862
|
+
alt: "",
|
|
8863
|
+
style: { width: "100%", height: "100%", objectFit: "contain", display: "block" }
|
|
8864
|
+
}
|
|
8865
|
+
)
|
|
8866
|
+
}
|
|
8867
|
+
),
|
|
8779
8868
|
!readOnly && /* @__PURE__ */ jsx(
|
|
8780
8869
|
"div",
|
|
8781
8870
|
{
|
|
@@ -8798,6 +8887,51 @@ function EditorCore({
|
|
|
8798
8887
|
}
|
|
8799
8888
|
);
|
|
8800
8889
|
}
|
|
8890
|
+
function getImageDropTarget(container, clientY, imagePath) {
|
|
8891
|
+
const fallback = { dropIndex: imagePath[0], indicatorClientY: clientY };
|
|
8892
|
+
if (!container) return fallback;
|
|
8893
|
+
const blocks = Array.from(
|
|
8894
|
+
container.querySelectorAll(":scope > [data-block-path]")
|
|
8895
|
+
);
|
|
8896
|
+
if (blocks.length === 0) return fallback;
|
|
8897
|
+
const gaps = [];
|
|
8898
|
+
gaps.push({ y: blocks[0].getBoundingClientRect().top, index: 0 });
|
|
8899
|
+
for (let i = 0; i < blocks.length - 1; i++) {
|
|
8900
|
+
const bottom = blocks[i].getBoundingClientRect().bottom;
|
|
8901
|
+
const top = blocks[i + 1].getBoundingClientRect().top;
|
|
8902
|
+
gaps.push({ y: (bottom + top) / 2, index: i + 1 });
|
|
8903
|
+
}
|
|
8904
|
+
gaps.push({ y: blocks[blocks.length - 1].getBoundingClientRect().bottom, index: blocks.length });
|
|
8905
|
+
let best = gaps[0];
|
|
8906
|
+
let bestDist = Math.abs(clientY - best.y);
|
|
8907
|
+
for (const gap of gaps) {
|
|
8908
|
+
const dist = Math.abs(clientY - gap.y);
|
|
8909
|
+
if (dist < bestDist) {
|
|
8910
|
+
bestDist = dist;
|
|
8911
|
+
best = gap;
|
|
8912
|
+
}
|
|
8913
|
+
}
|
|
8914
|
+
return { dropIndex: best.index, indicatorClientY: best.y };
|
|
8915
|
+
}
|
|
8916
|
+
function moveImageInDoc(imagePath, targetIndex, engine) {
|
|
8917
|
+
const state = engine.getState();
|
|
8918
|
+
const imageNode = getNodeAtPath(state.doc, imagePath);
|
|
8919
|
+
if (!imageNode) return;
|
|
8920
|
+
const isTopLevel = imagePath.length === 1;
|
|
8921
|
+
const topLevelIndex = imagePath[0];
|
|
8922
|
+
let adj = targetIndex;
|
|
8923
|
+
if (isTopLevel) {
|
|
8924
|
+
if (targetIndex > topLevelIndex) adj = targetIndex - 1;
|
|
8925
|
+
adj = Math.max(0, Math.min(state.doc.children.length - 1, adj));
|
|
8926
|
+
if (adj === topLevelIndex) return;
|
|
8927
|
+
} else {
|
|
8928
|
+
adj = Math.max(0, Math.min(state.doc.children.length, adj));
|
|
8929
|
+
}
|
|
8930
|
+
const tr = createTransaction();
|
|
8931
|
+
tr.steps.push({ type: "delete_node", path: imagePath });
|
|
8932
|
+
tr.steps.push({ type: "insert_node", parentPath: [], index: adj, node: imageNode });
|
|
8933
|
+
engine.dispatch(tr);
|
|
8934
|
+
}
|
|
8801
8935
|
var BLOCK_TAGS = "p|h[1-6]|ul|ol|li|blockquote|pre|figure|table|thead|tbody|tr|th|td";
|
|
8802
8936
|
var _OPEN_ONLY_RE = new RegExp(`^<(${BLOCK_TAGS})(?:\\s[^>]*)?>$`, "i");
|
|
8803
8937
|
var _CLOSE_ONLY_RE = new RegExp(`^<\\/(${BLOCK_TAGS})>$`, "i");
|