diff --git a/examples/vite-app/src/examples/NodeResizer/index.tsx b/examples/vite-app/src/examples/NodeResizer/index.tsx index 3b176e39..af0a660c 100644 --- a/examples/vite-app/src/examples/NodeResizer/index.tsx +++ b/examples/vite-app/src/examples/NodeResizer/index.tsx @@ -1,13 +1,5 @@ import { useCallback } from 'react'; -import ReactFlow, { - Controls, - addEdge, - Position, - Connection, - useNodesState, - useEdgesState, - NodeChange, -} from 'reactflow'; +import ReactFlow, { Controls, addEdge, Position, Connection, useNodesState, useEdgesState } from 'reactflow'; import CustomNode from './CustomNode'; @@ -41,7 +33,7 @@ const initialNodes = [ ]; const CustomNodeFlow = () => { - const [nodes, setNodes, _onNodesChange] = useNodesState(initialNodes); + const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); const onConnect = useCallback( @@ -49,13 +41,6 @@ const CustomNodeFlow = () => { [setEdges] ); - const onNodesChange = useCallback( - (changes: NodeChange[]) => { - _onNodesChange(changes); - }, - [_onNodesChange] - ); - return ( { fitView minZoom={0.3} maxZoom={2} + snapToGrid > diff --git a/packages/node-resizer/package.json b/packages/node-resizer/package.json index 43ee7540..4ef4f1ba 100644 --- a/packages/node-resizer/package.json +++ b/packages/node-resizer/package.json @@ -38,7 +38,7 @@ "dependencies": { "@babel/runtime": "^7.18.9", "@reactflow/core": "workspace:*", - "classcat": "^5.0.3", + "classcat": "^5.0.4", "d3-drag": "^3.0.0", "d3-selection": "^3.0.0", "zustand": "^4.1.1" diff --git a/packages/node-resizer/src/NodeResizer.tsx b/packages/node-resizer/src/NodeResizer.tsx index 9e6764bf..0660adf6 100644 --- a/packages/node-resizer/src/NodeResizer.tsx +++ b/packages/node-resizer/src/NodeResizer.tsx @@ -1,7 +1,14 @@ import { useRef, useEffect } from 'react'; +import cc from 'classcat'; import { drag } from 'd3-drag'; import { select } from 'd3-selection'; -import { useStoreApi, useGetPointerPosition } from '@reactflow/core'; +import { + useStoreApi, + useGetPointerPosition, + NodeChange, + NodePositionChange, + NodeDimensionChange, +} from '@reactflow/core'; import type { Dimensions, Node, XYPosition } from '@reactflow/core'; import type { D3DragEvent, SubjectPosition } from 'd3'; @@ -17,6 +24,7 @@ type ResizeHandleProps = { enableY?: boolean; top?: number | string; left?: number | string; + className?: string; }; type ResizeDragEvent = D3DragEvent; @@ -29,6 +37,7 @@ function ResizeHandle({ enableX = false, enableY = false, nodeId, + className, }: ResizeHandleProps) { const store = useStoreApi(); const resizeHandleRef = useRef(null); @@ -65,12 +74,13 @@ function ResizeHandle({ nodeElementRef.current = document.querySelector(`.react-flow__node[data-id="${nodeId}"]`) as HTMLDivElement; }) .on('drag', (event: ResizeDragEvent) => { - const { updateNodePositions, nodeInternals } = store.getState(); + const { updateNodePositions, nodeInternals, onNodesChange } = store.getState(); const pointerPos = getPointerPosition(event); const nodeEl = nodeElementRef.current; const node = nodeInternals.get(nodeId); if (nodeEl && node) { + const changes: NodeChange[] = []; const distX = enableX ? pointerPos.xSnapped - initialDimensionsRef.current.x : 0; const distY = enableY ? pointerPos.ySnapped - initialDimensionsRef.current.y : 0; const width = initialDimensionsRef.current.width + (invertX ? -distX : distX); @@ -81,7 +91,7 @@ function ResizeHandle({ const y = invertY ? initialDimensionsRef.current.nodeY + distY : initialDimensionsRef.current.nodeY; if (x !== node.position.x || y !== node.position.y) { - updateNodePositions( + const positionChanges: NodePositionChange[] | null = updateNodePositions( [ { id: nodeId, @@ -89,16 +99,31 @@ function ResizeHandle({ } as Node, ], true, + false, false ); + + if (positionChanges?.length) { + changes.push(positionChanges[0]); + } } } - if (width !== node.width) { - nodeEl.style.width = `${width}px`; + if (width !== node.width || height !== node.height) { + const dimensionChange: NodeDimensionChange = { + id: nodeId, + type: 'dimensions', + updateStyle: true, + dimensions: { + width: width !== node.width ? width : node.width, + height: height !== node.height ? height : node.height, + }, + }; + changes.push(dimensionChange); } - if (height !== node.height) { - nodeEl.style.height = `${height}px`; + + if (changes.length) { + onNodesChange?.(changes); } } }); @@ -112,7 +137,7 @@ function ResizeHandle({ return (
- - - - - - - - + + + + + + + + ); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a8406c2d..4eafb92f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -230,7 +230,7 @@ importers: '@types/node': ^18.7.16 '@types/react': ^18.0.19 '@types/react-dom': ^18.0.6 - classcat: ^5.0.3 + classcat: ^5.0.4 d3-drag: ^3.0.0 d3-selection: ^3.0.0 react: ^18.2.0