diff --git a/src/components/Nodes/wrapNode.tsx b/src/components/Nodes/wrapNode.tsx index b8ea5fdf..43b08e3c 100644 --- a/src/components/Nodes/wrapNode.tsx +++ b/src/components/Nodes/wrapNode.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useRef, memo, ComponentType, CSSProperties, useMemo, MouseEvent, useCallback } from 'react'; -import { DraggableCore } from 'react-draggable'; +import { DraggableCore, DraggableData, DraggableEvent } from 'react-draggable'; import cc from 'classcat'; import { useStoreActions } from '../../store/hooks'; @@ -21,6 +21,7 @@ export default (NodeComponent: ComponentType) => { onMouseLeave, onContextMenu, onNodeDragStart, + onNodeDrag, onNodeDragStop, style, className, @@ -107,7 +108,7 @@ export default (NodeComponent: ComponentType) => { ); const onDragStart = useCallback( - (event) => { + (event: DraggableEvent) => { onNodeDragStart?.(event as MouseEvent, node); if (selectNodesOnDrag && isSelectable) { @@ -125,12 +126,14 @@ export default (NodeComponent: ComponentType) => { ); const onDrag = useCallback( - (_, data) => { + (event: DraggableEvent, draggbleData: DraggableData) => { + onNodeDrag?.(event as MouseEvent, id, draggbleData); + updateNodePosDiff({ id, diff: { - x: data.deltaX, - y: data.deltaY, + x: draggbleData.deltaX, + y: draggbleData.deltaY, }, }); }, @@ -138,7 +141,7 @@ export default (NodeComponent: ComponentType) => { ); const onDragStop = useCallback( - (event) => { + (event: DraggableEvent) => { // onDragStop also gets called when user just clicks on a node. // Because of that we set dragging to true inside the onDrag handler and handle the click here if (!isDragging) { diff --git a/src/container/GraphView/index.tsx b/src/container/GraphView/index.tsx index 363b50b9..780f8fcc 100644 --- a/src/container/GraphView/index.tsx +++ b/src/container/GraphView/index.tsx @@ -40,6 +40,7 @@ const GraphView = ({ onNodeMouseLeave, onNodeContextMenu, onNodeDragStart, + onNodeDrag, onNodeDragStop, onSelectionDragStart, onSelectionDrag, @@ -243,6 +244,7 @@ const GraphView = ({ onNodeMouseLeave={onNodeMouseLeave} onNodeContextMenu={onNodeContextMenu} onNodeDragStop={onNodeDragStop} + onNodeDrag={onNodeDrag} onNodeDragStart={onNodeDragStart} selectNodesOnDrag={selectNodesOnDrag} snapToGrid={snapToGrid} diff --git a/src/container/NodeRenderer/index.tsx b/src/container/NodeRenderer/index.tsx index ad31abeb..1834ae24 100644 --- a/src/container/NodeRenderer/index.tsx +++ b/src/container/NodeRenderer/index.tsx @@ -1,9 +1,9 @@ import React, { memo, useMemo, ComponentType, MouseEvent } from 'react'; +import { DraggableData } from 'react-draggable'; import { getNodesInside } from '../../utils/graph'; import { useStoreState, useStoreActions } from '../../store/hooks'; -import { Node, NodeTypesType, WrapNodeProps, Edge } from '../../types'; - +import { Node, NodeTypesType, WrapNodeProps, Edge, ElementId } from '../../types'; interface NodeRendererProps { nodeTypes: NodeTypesType; selectNodesOnDrag: boolean; @@ -13,6 +13,7 @@ interface NodeRendererProps { onNodeMouseLeave?: (event: MouseEvent, node: Node) => void; onNodeContextMenu?: (event: MouseEvent, node: Node) => void; onNodeDragStart?: (event: MouseEvent, node: Node) => void; + onNodeDrag?: (event: MouseEvent, nodeId: ElementId, data: DraggableData) => void; onNodeDragStop?: (event: MouseEvent, node: Node) => void; snapToGrid: boolean; snapGrid: [number, number]; @@ -91,6 +92,7 @@ const NodeRenderer = (props: NodeRendererProps) => { onMouseLeave={props.onNodeMouseLeave} onContextMenu={props.onNodeContextMenu} onNodeDragStart={props.onNodeDragStart} + onNodeDrag={props.onNodeDrag} onNodeDragStop={props.onNodeDragStop} scale={transform[2]} selected={selectedElements?.some(({ id }) => id === node.id) || false} diff --git a/src/container/ReactFlow/index.tsx b/src/container/ReactFlow/index.tsx index 6c974de4..354d57a2 100644 --- a/src/container/ReactFlow/index.tsx +++ b/src/container/ReactFlow/index.tsx @@ -1,5 +1,6 @@ import React, { useMemo, CSSProperties, HTMLAttributes, MouseEvent, WheelEvent } from 'react'; import cc from 'classcat'; +import { DraggableData } from 'react-draggable'; import GraphView from '../GraphView'; import ElementUpdater from '../../components/ElementUpdater'; @@ -31,6 +32,7 @@ import { PanOnScrollMode, OnEdgeUpdateFunc, NodeExtent, + ElementId, } from '../../types'; import '../../style.css'; @@ -58,6 +60,7 @@ export interface ReactFlowProps extends Omit, 'on onNodeMouseLeave?: (event: MouseEvent, node: Node) => void; onNodeContextMenu?: (event: MouseEvent, node: Node) => void; onNodeDragStart?: (event: MouseEvent, node: Node) => void; + onNodeDrag?: (event: MouseEvent, nodeId: ElementId, data: DraggableData) => void; onNodeDragStop?: (event: MouseEvent, node: Node) => void; onConnect?: (connection: Edge | Connection) => void; onConnectStart?: OnConnectStartFunc; @@ -130,6 +133,7 @@ const ReactFlow = ({ onNodeMouseLeave, onNodeContextMenu, onNodeDragStart, + onNodeDrag, onNodeDragStop, onSelectionChange, onSelectionDragStart, @@ -191,6 +195,7 @@ const ReactFlow = ({ onNodeMouseLeave={onNodeMouseLeave} onNodeContextMenu={onNodeContextMenu} onNodeDragStart={onNodeDragStart} + onNodeDrag={onNodeDrag} onNodeDragStop={onNodeDragStop} nodeTypes={nodeTypesParsed} edgeTypes={edgeTypesParsed} diff --git a/src/types/index.ts b/src/types/index.ts index 888a5b00..44dd7d00 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,4 +1,5 @@ import { CSSProperties, MouseEvent as ReactMouseEvent } from 'react'; +import { DraggableData } from 'react-draggable'; export type ElementId = string; @@ -196,6 +197,7 @@ export interface NodeComponentProps { onMouseLeave?: (node: Node) => void; onContextMenu?: (node: Node) => void; onNodeDragStart?: (node: Node) => void; + onNodeDrag?: (node: Node) => void; onNodeDragStop?: (node: Node) => void; style?: CSSProperties; isDragging?: boolean; @@ -219,6 +221,7 @@ export interface WrapNodeProps { onMouseLeave?: (event: ReactMouseEvent, node: Node) => void; onContextMenu?: (event: ReactMouseEvent, node: Node) => void; onNodeDragStart?: (event: ReactMouseEvent, node: Node) => void; + onNodeDrag?: (event: ReactMouseEvent, nodeId: ElementId, data: DraggableData) => void; onNodeDragStop?: (event: ReactMouseEvent, node: Node) => void; style?: CSSProperties; className?: string;