diff --git a/example/src/NodeTypeChange/index.js b/example/src/NodeTypeChange/index.js new file mode 100644 index 00000000..b414392b --- /dev/null +++ b/example/src/NodeTypeChange/index.js @@ -0,0 +1,52 @@ +import React, { useState } from 'react'; + +import ReactFlow, { addEdge } from 'react-flow-renderer'; + +const onLoad = (reactFlowInstance) => reactFlowInstance.fitView(); + +const initialElements = [ + { + id: '1', + sourcePosition: 'right', + type: 'input', + data: { label: 'Input' }, + position: { x: 0, y: 80 }, + }, + { + id: '2', + type: 'output', + sourcePosition: 'right', + targetPosition: 'left', + data: { label: 'A Node' }, + position: { x: 250, y: 0 }, + }, + { id: 'e1-2', source: '1', type: 'smoothstep', target: '2', animated: true }, +]; + +const HorizontalFlow = () => { + const [elements, setElements] = useState(initialElements); + const onConnect = (params) => setElements((els) => addEdge(params, els)); + const changeType = () => { + setElements((elms) => + elms.map((el) => { + if (el.type === 'input') { + return el; + } + + el.type = el.type === 'default' ? 'output' : 'default'; + + return { ...el }; + }) + ); + }; + + return ( + + + + ); +}; + +export default HorizontalFlow; diff --git a/example/src/index.js b/example/src/index.js index f90eee35..639183b4 100644 --- a/example/src/index.js +++ b/example/src/index.js @@ -15,6 +15,7 @@ import Provider from './Provider'; import Hidden from './Hidden'; import EdgeTypes from './EdgeTypes'; import CustomConnectionLine from './CustomConnectionLine'; +import NodeTypeChange from './NodeTypeChange'; import './index.css'; @@ -79,6 +80,10 @@ const routes = [ path: '/custom-connectionline', component: CustomConnectionLine, }, + { + path: '/nodetype-change', + component: NodeTypeChange, + }, ]; const navLinks = routes.filter((route) => route.label); diff --git a/src/hooks/useElementUpdater.ts b/src/hooks/useElementUpdater.ts index f3f7fdc1..0f2bac7c 100644 --- a/src/hooks/useElementUpdater.ts +++ b/src/hooks/useElementUpdater.ts @@ -44,6 +44,13 @@ const useElementUpdater = (propElements: Elements): void => { if (typeof propElement.type !== 'undefined') { elementProps.type = propElement.type; + + // we reset the elements dimensions here in order to force a re-calculation of the bounds. + // When the type of a node changes it is possible that the number or positions of handles changes too. + if (isNode(existingElement) && propElement.type !== existingElement.type) { + existingElement.__rf.width = null; + existingElement.__rf.height = null; + } } if (isNode(existingElement)) {