@bian-womp/spark-workbench 0.3.42 → 0.3.44
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectionBoundOverlay.d.ts","sourceRoot":"","sources":["../../../../src/misc/SelectionBoundOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"SelectionBoundOverlay.d.ts","sourceRoot":"","sources":["../../../../src/misc/SelectionBoundOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAMN,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAGnE,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC;IAC3C,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAChD,UAAU,EAAE,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC;IACjD,YAAY,EAAE,MAAM,CAAC;CACtB,CAmRA,CAAC"}
|
package/lib/esm/index.js
CHANGED
|
@@ -5844,6 +5844,13 @@ function useKeyboardShortcutToast() {
|
|
|
5844
5844
|
const SelectionBoundOverlay = ({ selection, rfInstance, viewportTick }) => {
|
|
5845
5845
|
const overlayRef = useRef(null);
|
|
5846
5846
|
const [parentRect, setParentRect] = useState(null);
|
|
5847
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
5848
|
+
const [bounds, setBounds] = useState(null);
|
|
5849
|
+
const dragStateRef = useRef(null);
|
|
5850
|
+
const moveListenerRef = useRef(null);
|
|
5851
|
+
const upListenerRef = useRef(null);
|
|
5852
|
+
useRef(null);
|
|
5853
|
+
const { wb } = useWorkbenchContext();
|
|
5847
5854
|
useEffect(() => {
|
|
5848
5855
|
if (!overlayRef.current)
|
|
5849
5856
|
return;
|
|
@@ -5863,56 +5870,190 @@ const SelectionBoundOverlay = ({ selection, rfInstance, viewportTick }) => {
|
|
|
5863
5870
|
window.removeEventListener("scroll", scrollHandler, true);
|
|
5864
5871
|
};
|
|
5865
5872
|
}, [viewportTick]);
|
|
5866
|
-
const
|
|
5873
|
+
const cleanupDragListeners = useCallback(() => {
|
|
5874
|
+
if (moveListenerRef.current) {
|
|
5875
|
+
window.removeEventListener("mousemove", moveListenerRef.current);
|
|
5876
|
+
moveListenerRef.current = null;
|
|
5877
|
+
}
|
|
5878
|
+
if (upListenerRef.current) {
|
|
5879
|
+
window.removeEventListener("mouseup", upListenerRef.current);
|
|
5880
|
+
upListenerRef.current = null;
|
|
5881
|
+
}
|
|
5882
|
+
dragStateRef.current = null;
|
|
5883
|
+
setIsDragging(false);
|
|
5884
|
+
}, []);
|
|
5885
|
+
useEffect(() => cleanupDragListeners, [cleanupDragListeners]);
|
|
5886
|
+
const handleMouseMove = useCallback((e) => {
|
|
5887
|
+
if (!rfInstance || !wb || !parentRect)
|
|
5888
|
+
return;
|
|
5889
|
+
const dragState = dragStateRef.current;
|
|
5890
|
+
if (!dragState)
|
|
5891
|
+
return;
|
|
5892
|
+
e.preventDefault();
|
|
5893
|
+
e.stopPropagation();
|
|
5894
|
+
const current = rfInstance.screenToFlowPosition({
|
|
5895
|
+
x: e.clientX,
|
|
5896
|
+
y: e.clientY,
|
|
5897
|
+
});
|
|
5898
|
+
const dx = current.x - dragState.startFlow.x;
|
|
5899
|
+
const dy = current.y - dragState.startFlow.y;
|
|
5900
|
+
// Update nodes directly via React Flow for immediate visual feedback
|
|
5901
|
+
const nodes = rfInstance.getNodes();
|
|
5902
|
+
const updatedNodes = nodes.map((node) => {
|
|
5903
|
+
if (dragState.initialPositions[node.id]) {
|
|
5904
|
+
const initialPos = dragState.initialPositions[node.id];
|
|
5905
|
+
return {
|
|
5906
|
+
...node,
|
|
5907
|
+
position: {
|
|
5908
|
+
x: initialPos.x + dx,
|
|
5909
|
+
y: initialPos.y + dy,
|
|
5910
|
+
},
|
|
5911
|
+
};
|
|
5912
|
+
}
|
|
5913
|
+
return node;
|
|
5914
|
+
});
|
|
5915
|
+
rfInstance.setNodes(updatedNodes);
|
|
5916
|
+
// Also update workbench state
|
|
5917
|
+
const nextPositions = {};
|
|
5918
|
+
for (const [nodeId, pos] of Object.entries(dragState.initialPositions)) {
|
|
5919
|
+
nextPositions[nodeId] = { x: pos.x + dx, y: pos.y + dy };
|
|
5920
|
+
}
|
|
5921
|
+
if (Object.keys(nextPositions).length) {
|
|
5922
|
+
wb.setPositions(nextPositions, { commit: false });
|
|
5923
|
+
}
|
|
5924
|
+
}, [rfInstance, wb, parentRect]);
|
|
5925
|
+
const handleMouseUp = useCallback((e) => {
|
|
5926
|
+
if (!rfInstance || !wb) {
|
|
5927
|
+
cleanupDragListeners();
|
|
5928
|
+
return;
|
|
5929
|
+
}
|
|
5930
|
+
const dragState = dragStateRef.current;
|
|
5931
|
+
if (!dragState) {
|
|
5932
|
+
cleanupDragListeners();
|
|
5933
|
+
return;
|
|
5934
|
+
}
|
|
5935
|
+
e.preventDefault();
|
|
5936
|
+
e.stopPropagation();
|
|
5937
|
+
const current = rfInstance.screenToFlowPosition({
|
|
5938
|
+
x: e.clientX,
|
|
5939
|
+
y: e.clientY,
|
|
5940
|
+
});
|
|
5941
|
+
const dx = current.x - dragState.startFlow.x;
|
|
5942
|
+
const dy = current.y - dragState.startFlow.y;
|
|
5943
|
+
const nextPositions = {};
|
|
5944
|
+
for (const [nodeId, pos] of Object.entries(dragState.initialPositions)) {
|
|
5945
|
+
nextPositions[nodeId] = { x: pos.x + dx, y: pos.y + dy };
|
|
5946
|
+
}
|
|
5947
|
+
if (Object.keys(nextPositions).length) {
|
|
5948
|
+
wb.setPositions(nextPositions, { commit: true });
|
|
5949
|
+
}
|
|
5950
|
+
cleanupDragListeners();
|
|
5951
|
+
}, [cleanupDragListeners, rfInstance, wb]);
|
|
5952
|
+
const handleMouseDown = useCallback((e) => {
|
|
5953
|
+
if (e.button !== 0)
|
|
5954
|
+
return;
|
|
5955
|
+
if (!rfInstance || !wb)
|
|
5956
|
+
return;
|
|
5957
|
+
if (selection.nodes.length < 2)
|
|
5958
|
+
return;
|
|
5959
|
+
e.preventDefault();
|
|
5960
|
+
e.stopPropagation();
|
|
5961
|
+
const startFlow = rfInstance.screenToFlowPosition({
|
|
5962
|
+
x: e.clientX,
|
|
5963
|
+
y: e.clientY,
|
|
5964
|
+
});
|
|
5965
|
+
const positions = wb.getPositions();
|
|
5966
|
+
const initialPositions = {};
|
|
5967
|
+
for (const nodeId of selection.nodes) {
|
|
5968
|
+
const pos = positions[nodeId];
|
|
5969
|
+
if (pos) {
|
|
5970
|
+
initialPositions[nodeId] = pos;
|
|
5971
|
+
}
|
|
5972
|
+
}
|
|
5973
|
+
if (!Object.keys(initialPositions).length)
|
|
5974
|
+
return;
|
|
5975
|
+
dragStateRef.current = { startFlow, initialPositions };
|
|
5976
|
+
setIsDragging(true);
|
|
5977
|
+
moveListenerRef.current = handleMouseMove;
|
|
5978
|
+
upListenerRef.current = handleMouseUp;
|
|
5979
|
+
window.addEventListener("mousemove", handleMouseMove, { passive: false });
|
|
5980
|
+
window.addEventListener("mouseup", handleMouseUp, { passive: false });
|
|
5981
|
+
}, [handleMouseMove, handleMouseUp, rfInstance, selection.nodes, wb]);
|
|
5982
|
+
// Continuous bounds update loop
|
|
5983
|
+
useEffect(() => {
|
|
5867
5984
|
if (typeof document === "undefined" ||
|
|
5868
5985
|
!rfInstance ||
|
|
5869
5986
|
!parentRect ||
|
|
5870
5987
|
selection.nodes.length < 2) {
|
|
5871
|
-
|
|
5988
|
+
setBounds(null);
|
|
5989
|
+
return;
|
|
5872
5990
|
}
|
|
5873
|
-
let
|
|
5874
|
-
|
|
5875
|
-
|
|
5876
|
-
if (!
|
|
5877
|
-
|
|
5878
|
-
|
|
5879
|
-
const
|
|
5880
|
-
|
|
5881
|
-
|
|
5882
|
-
|
|
5883
|
-
|
|
5884
|
-
|
|
5885
|
-
|
|
5886
|
-
|
|
5887
|
-
|
|
5888
|
-
|
|
5889
|
-
|
|
5991
|
+
let animationFrameId = null;
|
|
5992
|
+
let isActive = true;
|
|
5993
|
+
const updateBounds = () => {
|
|
5994
|
+
if (!isActive)
|
|
5995
|
+
return;
|
|
5996
|
+
let calculatedBounds = null;
|
|
5997
|
+
for (const nodeId of selection.nodes) {
|
|
5998
|
+
const el = document.querySelector(`.react-flow__node[data-id="${nodeId}"]`);
|
|
5999
|
+
if (!el)
|
|
6000
|
+
continue;
|
|
6001
|
+
const rect = el.getBoundingClientRect();
|
|
6002
|
+
const relativeLeft = rect.left - parentRect.left;
|
|
6003
|
+
const relativeTop = rect.top - parentRect.top;
|
|
6004
|
+
const relativeRight = rect.right - parentRect.left;
|
|
6005
|
+
const relativeBottom = rect.bottom - parentRect.top;
|
|
6006
|
+
if (!calculatedBounds) {
|
|
6007
|
+
calculatedBounds = {
|
|
6008
|
+
left: relativeLeft,
|
|
6009
|
+
top: relativeTop,
|
|
6010
|
+
right: relativeRight,
|
|
6011
|
+
bottom: relativeBottom,
|
|
6012
|
+
};
|
|
6013
|
+
}
|
|
6014
|
+
else {
|
|
6015
|
+
calculatedBounds.left = Math.min(calculatedBounds.left, relativeLeft);
|
|
6016
|
+
calculatedBounds.top = Math.min(calculatedBounds.top, relativeTop);
|
|
6017
|
+
calculatedBounds.right = Math.max(calculatedBounds.right, relativeRight);
|
|
6018
|
+
calculatedBounds.bottom = Math.max(calculatedBounds.bottom, relativeBottom);
|
|
6019
|
+
}
|
|
5890
6020
|
}
|
|
5891
|
-
|
|
5892
|
-
|
|
5893
|
-
|
|
5894
|
-
|
|
5895
|
-
bounds.bottom = Math.max(bounds.bottom, relativeBottom);
|
|
6021
|
+
setBounds(calculatedBounds);
|
|
6022
|
+
// Continue the animation loop
|
|
6023
|
+
if (isActive) {
|
|
6024
|
+
animationFrameId = requestAnimationFrame(updateBounds);
|
|
5896
6025
|
}
|
|
5897
|
-
}
|
|
5898
|
-
|
|
6026
|
+
};
|
|
6027
|
+
// Start the animation loop
|
|
6028
|
+
animationFrameId = requestAnimationFrame(updateBounds);
|
|
6029
|
+
return () => {
|
|
6030
|
+
isActive = false;
|
|
6031
|
+
if (animationFrameId !== null) {
|
|
6032
|
+
cancelAnimationFrame(animationFrameId);
|
|
6033
|
+
}
|
|
6034
|
+
};
|
|
5899
6035
|
}, [selection.nodes, rfInstance, viewportTick, parentRect]);
|
|
5900
|
-
if (!
|
|
6036
|
+
if (!bounds || selection.nodes.length < 2) {
|
|
5901
6037
|
return jsx("div", { ref: overlayRef, style: { display: "none" } });
|
|
5902
6038
|
}
|
|
5903
|
-
const { left, top, right, bottom } =
|
|
6039
|
+
const { left, top, right, bottom } = bounds;
|
|
5904
6040
|
const width = right - left;
|
|
5905
6041
|
const height = bottom - top;
|
|
5906
|
-
return (jsx("div", { ref: overlayRef, style: {
|
|
6042
|
+
return (jsx("div", { ref: overlayRef, onMouseDown: handleMouseDown, style: {
|
|
5907
6043
|
position: "absolute",
|
|
5908
6044
|
left: `${left}px`,
|
|
5909
6045
|
top: `${top}px`,
|
|
5910
6046
|
width: `${width}px`,
|
|
5911
6047
|
height: `${height}px`,
|
|
5912
|
-
border: "1px dashed #0ea5e9",
|
|
5913
|
-
|
|
6048
|
+
border: isDragging ? "2px solid #0ea5e9" : "1px dashed #0ea5e9",
|
|
6049
|
+
backgroundColor: isDragging
|
|
6050
|
+
? "rgba(14, 165, 233, 0.05)"
|
|
6051
|
+
: "transparent",
|
|
6052
|
+
pointerEvents: "auto",
|
|
6053
|
+
cursor: isDragging ? "grabbing" : "move",
|
|
5914
6054
|
zIndex: 4,
|
|
5915
6055
|
boxSizing: "border-box",
|
|
6056
|
+
transition: isDragging ? "none" : "border 0.1s ease",
|
|
5916
6057
|
} }));
|
|
5917
6058
|
};
|
|
5918
6059
|
|