Merge branch 'main' into v11
This commit is contained in:
@@ -4,7 +4,7 @@ import { select } from 'd3-selection';
|
||||
|
||||
import { useStoreApi } from '../../store';
|
||||
import { pointToRendererPoint } from '../../utils/graph';
|
||||
import { NodeDragItem, NodeDragHandler } from '../../types';
|
||||
import { NodeDragItem, Node, SelectionDragHandler } from '../../types';
|
||||
import { getDragItems, getEventHandlerParams, hasSelector, updatePosition } from './utils';
|
||||
import { handleNodeClick } from '../../components/Nodes/utils';
|
||||
|
||||
@@ -13,9 +13,6 @@ export type UseDragData = { dx: number; dy: number };
|
||||
|
||||
type UseDragParams = {
|
||||
nodeRef: RefObject<Element>;
|
||||
onStart?: NodeDragHandler;
|
||||
onDrag?: NodeDragHandler;
|
||||
onStop?: NodeDragHandler;
|
||||
disabled?: boolean;
|
||||
noDragClassName?: string;
|
||||
handleSelector?: string;
|
||||
@@ -24,10 +21,11 @@ type UseDragParams = {
|
||||
selectNodesOnDrag?: boolean;
|
||||
};
|
||||
|
||||
function wrapSelectionDragFunc(selectionFunc?: SelectionDragHandler) {
|
||||
return (event: MouseEvent, _: Node, nodes: Node[]) => selectionFunc?.(event, nodes);
|
||||
}
|
||||
|
||||
function useDrag({
|
||||
onStart,
|
||||
onDrag,
|
||||
onStop,
|
||||
nodeRef,
|
||||
disabled = false,
|
||||
noDragClassName,
|
||||
@@ -60,7 +58,15 @@ function useDrag({
|
||||
} else {
|
||||
const dragHandler = drag()
|
||||
.on('start', (event: UseDragEvent) => {
|
||||
const { nodeInternals, multiSelectionActive, unselectNodesAndEdges } = store.getState();
|
||||
const {
|
||||
nodeInternals,
|
||||
multiSelectionActive,
|
||||
unselectNodesAndEdges,
|
||||
onNodeDragStart,
|
||||
onSelectionDragStart,
|
||||
} = store.getState();
|
||||
|
||||
const onStart = nodeId ? onNodeDragStart : wrapSelectionDragFunc(onSelectionDragStart);
|
||||
|
||||
if (!selectNodesOnDrag && !multiSelectionActive && nodeId) {
|
||||
if (!nodeInternals.get(nodeId)?.selected) {
|
||||
@@ -77,6 +83,7 @@ function useDrag({
|
||||
}
|
||||
|
||||
const pointerPos = getPointerPosition(event);
|
||||
lastPos.current = pointerPos;
|
||||
dragItems.current = getDragItems(nodeInternals, pointerPos, nodeId);
|
||||
|
||||
if (onStart && dragItems.current) {
|
||||
@@ -89,7 +96,7 @@ function useDrag({
|
||||
}
|
||||
})
|
||||
.on('drag', (event: UseDragEvent) => {
|
||||
const { updateNodePositions, nodeInternals, nodeExtent } = store.getState();
|
||||
const { updateNodePositions, nodeInternals, nodeExtent, onNodeDrag, onSelectionDrag } = store.getState();
|
||||
const pointerPos = getPointerPosition(event);
|
||||
|
||||
// skip events without movement
|
||||
@@ -99,6 +106,8 @@ function useDrag({
|
||||
updatePosition(n, pointerPos, nodeInternals, nodeExtent)
|
||||
);
|
||||
|
||||
const onDrag = nodeId ? onNodeDrag : wrapSelectionDragFunc(onSelectionDrag);
|
||||
|
||||
updateNodePositions(dragItems.current, true, true);
|
||||
setDragging(true);
|
||||
|
||||
@@ -115,6 +124,9 @@ function useDrag({
|
||||
event.on('end', (event) => {
|
||||
setDragging(false);
|
||||
if (dragItems.current) {
|
||||
const { updateNodePositions, nodeInternals, onNodeDragStop, onSelectionDragStop } = store.getState();
|
||||
const onStop = nodeId ? onNodeDragStop : wrapSelectionDragFunc(onSelectionDragStop);
|
||||
|
||||
updateNodePositions(dragItems.current, false, false);
|
||||
|
||||
if (onStop) {
|
||||
@@ -146,9 +158,6 @@ function useDrag({
|
||||
}
|
||||
}
|
||||
}, [
|
||||
onStart,
|
||||
onDrag,
|
||||
onStop,
|
||||
nodeRef,
|
||||
disabled,
|
||||
noDragClassName,
|
||||
|
||||
@@ -39,7 +39,8 @@ export function getDragItems(nodeInternals: NodeInternals, mousePos: XYPosition,
|
||||
.filter((n) => (n.selected || n.id === nodeId) && (!n.parentNode || !isParentSelected(n, nodeInternals)))
|
||||
.map((n) => ({
|
||||
id: n.id,
|
||||
position: n.positionAbsolute || { x: 0, y: 0 },
|
||||
position: n.position || { x: 0, y: 0 },
|
||||
positionAbsolute: n.positionAbsolute || { x: 0, y: 0 },
|
||||
distance: {
|
||||
x: mousePos.x - (n.positionAbsolute?.x ?? 0),
|
||||
y: mousePos.y - (n.positionAbsolute?.y ?? 0),
|
||||
@@ -94,14 +95,28 @@ export function updatePosition(
|
||||
];
|
||||
}
|
||||
|
||||
dragItem.position = currentExtent ? clampPosition(nextPosition, currentExtent as CoordinateExtent) : nextPosition;
|
||||
let parentPosition = { x: 0, y: 0 };
|
||||
|
||||
if (dragItem.parentNode) {
|
||||
const parentNode = nodeInternals.get(dragItem.parentNode);
|
||||
parentPosition = { x: parentNode?.positionAbsolute?.x ?? 0, y: parentNode?.positionAbsolute?.y ?? 0 };
|
||||
}
|
||||
|
||||
dragItem.positionAbsolute = currentExtent
|
||||
? clampPosition(nextPosition, currentExtent as CoordinateExtent)
|
||||
: nextPosition;
|
||||
|
||||
dragItem.position = {
|
||||
x: dragItem.positionAbsolute.x - parentPosition.x,
|
||||
y: dragItem.positionAbsolute.y - parentPosition.y,
|
||||
};
|
||||
|
||||
return dragItem;
|
||||
}
|
||||
|
||||
// returns two params:
|
||||
// 1. the dragged node (or the first of the list, if we are dragging a node selection)
|
||||
// 2. array of selected nodes (handy when multi selection is active)
|
||||
// 2. array of selected nodes (for multi selections)
|
||||
export function getEventHandlerParams({
|
||||
nodeId,
|
||||
dragItems,
|
||||
@@ -116,6 +131,8 @@ export function getEventHandlerParams({
|
||||
|
||||
return {
|
||||
...node,
|
||||
position: n.position,
|
||||
positionAbsolute: n.positionAbsolute,
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -38,12 +38,12 @@ const useViewportHelper = (): ViewportHelperFunctions => {
|
||||
zoomIn: (options) => d3Zoom.scaleBy(getD3Transition(d3Selection, options?.duration), 1.2),
|
||||
zoomOut: (options) => d3Zoom.scaleBy(getD3Transition(d3Selection, options?.duration), 1 / 1.2),
|
||||
zoomTo: (zoomLevel, options) => d3Zoom.scaleTo(getD3Transition(d3Selection, options?.duration), zoomLevel),
|
||||
getZoom: () => {
|
||||
const [, , zoom] = store.getState().transform;
|
||||
return zoom;
|
||||
},
|
||||
getZoom: () => store.getState().transform[2],
|
||||
setViewport: (transform, options) => {
|
||||
const nextTransform = zoomIdentity.translate(transform.x, transform.y).scale(transform.zoom);
|
||||
const [x, y, zoom] = store.getState().transform;
|
||||
const nextTransform = zoomIdentity
|
||||
.translate(transform.x ?? x, transform.y ?? y)
|
||||
.scale(transform.zoom ?? zoom);
|
||||
d3Zoom.transform(getD3Transition(d3Selection, options?.duration), nextTransform);
|
||||
},
|
||||
getViewport: () => {
|
||||
|
||||
@@ -8,11 +8,10 @@ import { ReactFlowState } from '../types';
|
||||
function useVisibleNodes(onlyRenderVisible: boolean) {
|
||||
const nodes = useStore(
|
||||
useCallback(
|
||||
(s: ReactFlowState) => {
|
||||
return onlyRenderVisible
|
||||
(s: ReactFlowState) =>
|
||||
onlyRenderVisible
|
||||
? getNodesInside(s.nodeInternals, { x: 0, y: 0, width: s.width, height: s.height }, s.transform, true)
|
||||
: Array.from(s.nodeInternals.values());
|
||||
},
|
||||
: Array.from(s.nodeInternals.values()),
|
||||
[onlyRenderVisible]
|
||||
)
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user