From d6a410a0a3ef7ae462065b196d5aa83583f3d156 Mon Sep 17 00:00:00 2001 From: moklick Date: Wed, 18 Nov 2020 00:16:50 +0100 Subject: [PATCH 1/6] refactor(elementUpdater): simplify --- src/components/ElementUpdater/index.tsx | 137 +----------------------- src/store/index.ts | 52 ++++++++- 2 files changed, 53 insertions(+), 136 deletions(-) diff --git a/src/components/ElementUpdater/index.tsx b/src/components/ElementUpdater/index.tsx index a84c5c01..5bbe70a6 100644 --- a/src/components/ElementUpdater/index.tsx +++ b/src/components/ElementUpdater/index.tsx @@ -1,147 +1,18 @@ import { useEffect } from 'react'; -import isEqual from 'fast-deep-equal'; -import { useStoreState, useStoreActions } from '../../store/hooks'; -import { parseElement, isNode, isEdge } from '../../utils/graph'; -import { Elements, Node, Edge, FlowElement } from '../../types'; +import { useStoreActions } from '../../store/hooks'; +import { Elements } from '../../types'; interface ElementUpdaterProps { elements: Elements; } const ElementUpdater = ({ elements }: ElementUpdaterProps) => { - const stateElements = useStoreState((state) => state.elements); const setElements = useStoreActions((actions) => actions.setElements); useEffect(() => { - const nextElements: Elements = elements.map((propElement) => { - const existingElement = stateElements.find((el) => el.id === propElement.id?.toString()); - - if (existingElement) { - const data = !isEqual(existingElement.data, propElement.data) - ? { ...existingElement.data, ...propElement.data } - : existingElement.data; - - const style = !isEqual(existingElement.style, propElement.style) - ? { ...existingElement.style, ...propElement.style } - : existingElement.style; - - const elementProps = { - ...existingElement, - }; - - if (typeof data !== 'undefined') { - elementProps.data = data; - } - - if (typeof style !== 'undefined') { - elementProps.style = style; - } - - if (typeof propElement.className !== 'undefined') { - elementProps.className = propElement.className; - } - - if (typeof propElement.isHidden !== 'undefined') { - elementProps.isHidden = propElement.isHidden; - } - - 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)) { - const propNode = propElement as Node; - const nodeProps = elementProps as Node; - - const positionChanged = - existingElement.position.x !== propNode.position.x || existingElement.position.y !== propNode.position.y; - - if (positionChanged) { - nodeProps.__rf = { - ...existingElement.__rf, - position: propNode.position, - }; - nodeProps.position = propNode.position; - } - - if (typeof propNode.draggable !== 'undefined') { - nodeProps.draggable = propNode.draggable; - } - - if (typeof propNode.selectable !== 'undefined') { - nodeProps.selectable = propNode.selectable; - } - - if (typeof propNode.connectable !== 'undefined') { - nodeProps.connectable = propNode.connectable; - } - - return nodeProps; - } else if (isEdge(existingElement)) { - const propEdge = propElement as Edge; - const edgeProps = elementProps as Edge; - - const labelStyle = !isEqual(existingElement.labelStyle, propEdge.labelStyle) - ? { ...existingElement.labelStyle, ...propEdge.labelStyle } - : existingElement.labelStyle; - - const labelBgStyle = !isEqual(existingElement.labelBgStyle, propEdge.labelBgStyle) - ? { ...existingElement.labelBgStyle, ...propEdge.labelBgStyle } - : existingElement.labelBgStyle; - - if (typeof propEdge.label !== 'undefined') { - edgeProps.label = propEdge.label; - } - - if (typeof labelStyle !== 'undefined') { - edgeProps.labelStyle = labelStyle; - } - - if (typeof propEdge.labelShowBg !== 'undefined') { - edgeProps.labelShowBg = propEdge.labelShowBg; - } - - if (typeof propEdge.labelBgPadding !== 'undefined') { - edgeProps.labelBgPadding = propEdge.labelBgPadding; - } - - if (typeof propEdge.labelBgBorderRadius !== 'undefined') { - edgeProps.labelBgBorderRadius = propEdge.labelBgBorderRadius; - } - - if (typeof labelBgStyle !== 'undefined') { - edgeProps.labelBgStyle = labelBgStyle; - } - - if (typeof propEdge.animated !== 'undefined') { - edgeProps.animated = propEdge.animated; - } - - if (typeof propEdge.arrowHeadType !== 'undefined') { - edgeProps.arrowHeadType = propEdge.arrowHeadType; - } - - return edgeProps; - } - } - - return parseElement(propElement) as FlowElement; - }); - - const elementsChanged: boolean = !isEqual(stateElements, nextElements); - - if (elementsChanged) { - setElements(nextElements); - } - }, [elements, stateElements]); + setElements(elements); + }, [elements]); return null; }; diff --git a/src/store/index.ts b/src/store/index.ts index 5c33c697..9cc7f7f8 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -3,7 +3,7 @@ import isEqual from 'fast-deep-equal'; import { Selection as D3Selection, ZoomBehavior } from 'd3'; import { getDimensions } from '../utils'; -import { getNodesInside, getConnectedEdges, getRectOfNodes, isNode, isEdge } from '../utils/graph'; +import { getNodesInside, getConnectedEdges, getRectOfNodes, isNode, isEdge, parseElement } from '../utils/graph'; import { getHandleBounds } from '../components/Nodes/utils'; import { @@ -196,8 +196,54 @@ export const storeModel: StoreModel = { state.onConnectEnd = onConnectEnd; }), - setElements: action((state, elements) => { - state.elements = elements; + setElements: action((state, propElements) => { + // remove deleted elements + state.elements.forEach((se, i) => { + const removeElement = !propElements.some((pe) => pe.id === se.id); + + if (removeElement) { + state.elements.splice(i, 1); + } + }); + + propElements.forEach((el) => { + const storeElementIndex = state.elements.findIndex((se) => se.id === el.id); + + // update existing element + if (storeElementIndex !== -1) { + const storeElement = state.elements[storeElementIndex]; + + state.elements[storeElementIndex] = { + ...storeElement, + ...el, + }; + + if (isNode(state.elements[storeElementIndex])) { + const propNode = el as Node; + const storeNode = state.elements[storeElementIndex] as Node; + + const poitionChanged = + storeNode.position.x !== propNode.position.x || storeNode.position.y !== propNode.position.y; + + if (poitionChanged) { + (state.elements[storeElementIndex] as Node).__rf = { + ...storeNode.__rf, + position: propNode.position, + }; + } + + // 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 (propNode.type !== storeNode.type) { + (state.elements[storeElementIndex] as Node).__rf.width = null; + (state.elements[storeElementIndex] as Node).__rf.height = null; + } + } + } else { + // add new element + state.elements.push(parseElement(el)); + } + }); }), updateNodeDimensions: action((state, { id, nodeElement }) => { From c00cfca02c11c507301a84246fd4d90754198aec Mon Sep 17 00:00:00 2001 From: moklick Date: Wed, 18 Nov 2020 11:16:00 +0100 Subject: [PATCH 2/6] fix(store): remove elements --- src/store/index.ts | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/src/store/index.ts b/src/store/index.ts index 9cc7f7f8..89638164 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -198,13 +198,15 @@ export const storeModel: StoreModel = { setElements: action((state, propElements) => { // remove deleted elements - state.elements.forEach((se, i) => { - const removeElement = !propElements.some((pe) => pe.id === se.id); + for (let i = 0; i < state.elements.length; i++) { + const se = state.elements[i]; + const elementExistsInProps = propElements.find((pe) => pe.id === se.id); - if (removeElement) { + if (!elementExistsInProps) { state.elements.splice(i, 1); + i--; } - }); + } propElements.forEach((el) => { const storeElementIndex = state.elements.findIndex((se) => se.id === el.id); @@ -213,35 +215,44 @@ export const storeModel: StoreModel = { if (storeElementIndex !== -1) { const storeElement = state.elements[storeElementIndex]; - state.elements[storeElementIndex] = { - ...storeElement, - ...el, - }; - if (isNode(state.elements[storeElementIndex])) { const propNode = el as Node; const storeNode = state.elements[storeElementIndex] as Node; - const poitionChanged = + const positionChanged = storeNode.position.x !== propNode.position.x || storeNode.position.y !== propNode.position.y; - if (poitionChanged) { - (state.elements[storeElementIndex] as Node).__rf = { - ...storeNode.__rf, + if (positionChanged) { + (state.elements[storeElementIndex] as Node) = { + ...storeElement, + ...el, + __rf: { + ...storeNode.__rf, + position: propNode.position, + }, position: propNode.position, }; + } else { + state.elements[storeElementIndex] = { + ...storeElement, + ...el, + }; } - // 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 (propNode.type !== storeNode.type) { + if (typeof propNode.type !== 'undefined' && propNode.type !== storeNode.type) { (state.elements[storeElementIndex] as Node).__rf.width = null; (state.elements[storeElementIndex] as Node).__rf.height = null; } + } else { + state.elements[storeElementIndex] = { + ...storeElement, + ...el, + }; } } else { // add new element - state.elements.push(parseElement(el)); + state.elements.push(parseElement({ ...el })); } }); }), From 52a73d68a056cf882778a91ffbb1a019ee06ff97 Mon Sep 17 00:00:00 2001 From: moklick Date: Tue, 24 Nov 2020 18:21:36 +0100 Subject: [PATCH 3/6] refactor(store): simplify setElement --- example/src/Basic/index.js | 27 ++++++++++++++++++++++----- example/src/index.css | 5 +++++ src/store/index.ts | 30 +++++++++++------------------- 3 files changed, 38 insertions(+), 24 deletions(-) diff --git a/example/src/Basic/index.js b/example/src/Basic/index.js index 3395d29b..6c5acbe4 100644 --- a/example/src/Basic/index.js +++ b/example/src/Basic/index.js @@ -6,10 +6,10 @@ const onNodeDragStop = (event, node) => console.log('drag stop', node); const onElementClick = (event, element) => console.log('click', element); const initialElements = [ - { id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 } }, - { id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 100 } }, - { id: '3', data: { label: 'Node 3' }, position: { x: 400, y: 100 } }, - { id: '4', data: { label: 'Node 4' }, position: { x: 400, y: 200 } }, + { id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 }, className: 'light' }, + { id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 100 }, className: 'light' }, + { id: '3', data: { label: 'Node 3' }, position: { x: 400, y: 100 }, className: 'light' }, + { id: '4', data: { label: 'Node 4' }, position: { x: 400, y: 200 }, className: 'light' }, { id: 'e1-2', source: '1', target: '2', animated: true }, { id: 'e1-3', source: '1', target: '3' }, ]; @@ -40,9 +40,23 @@ const BasicFlow = () => { }; const logToObject = () => console.log(rfInstance.toObject()); - const resetTransform = () => rfInstance.setTransform({ x: 0, y: 0, zoom: 1 }); + const toggleClassnames = () => { + setElements((elms) => { + return elms.map((el) => { + if (isNode(el)) { + return { + ...el, + className: el.className === 'light' ? 'dark' : 'light', + }; + } + + return el; + }); + }); + }; + return ( { + diff --git a/example/src/index.css b/example/src/index.css index 76f50147..10b22e56 100644 --- a/example/src/index.css +++ b/example/src/index.css @@ -140,6 +140,11 @@ nav a.active:before { color: #f8f8f8; } +.react-flow__node.dark { + background: #557; + color: #f8f8f8; +} + .react-flow__node-selectorNode { font-size: 12px; background: #f0f2f3; diff --git a/src/store/index.ts b/src/store/index.ts index 89638164..fc46d917 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -213,30 +213,22 @@ export const storeModel: StoreModel = { // update existing element if (storeElementIndex !== -1) { - const storeElement = state.elements[storeElementIndex]; + let storeElement = state.elements[storeElementIndex]; + + if (isNode(storeElement)) { + let storeNode = storeElement as Node; - if (isNode(state.elements[storeElementIndex])) { const propNode = el as Node; - const storeNode = state.elements[storeElementIndex] as Node; - const positionChanged = storeNode.position.x !== propNode.position.x || storeNode.position.y !== propNode.position.y; + state.elements[storeElementIndex] = { + ...storeNode, + ...propNode, + }; + if (positionChanged) { - (state.elements[storeElementIndex] as Node) = { - ...storeElement, - ...el, - __rf: { - ...storeNode.__rf, - position: propNode.position, - }, - position: propNode.position, - }; - } else { - state.elements[storeElementIndex] = { - ...storeElement, - ...el, - }; + (state.elements[storeElementIndex] as Node).__rf.position = propNode.position; } // 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. @@ -252,7 +244,7 @@ export const storeModel: StoreModel = { } } else { // add new element - state.elements.push(parseElement({ ...el })); + state.elements.push(parseElement(el)); } }); }), From 93c5470d0149c6686d244bfb4f3277dc9e52d6a4 Mon Sep 17 00:00:00 2001 From: moklick Date: Tue, 24 Nov 2020 18:25:19 +0100 Subject: [PATCH 4/6] refactor(store): simplify setElement --- src/store/index.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/store/index.ts b/src/store/index.ts index fc46d917..53eee9a8 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -213,17 +213,15 @@ export const storeModel: StoreModel = { // update existing element if (storeElementIndex !== -1) { - let storeElement = state.elements[storeElementIndex]; + const storeElement = state.elements[storeElementIndex]; if (isNode(storeElement)) { - let storeNode = storeElement as Node; - const propNode = el as Node; const positionChanged = - storeNode.position.x !== propNode.position.x || storeNode.position.y !== propNode.position.y; + storeElement.position.x !== propNode.position.x || storeElement.position.y !== propNode.position.y; state.elements[storeElementIndex] = { - ...storeNode, + ...storeElement, ...propNode, }; @@ -232,9 +230,8 @@ export const storeModel: StoreModel = { } // 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 (typeof propNode.type !== 'undefined' && propNode.type !== storeNode.type) { + if (typeof propNode.type !== 'undefined' && propNode.type !== storeElement.type) { (state.elements[storeElementIndex] as Node).__rf.width = null; - (state.elements[storeElementIndex] as Node).__rf.height = null; } } else { state.elements[storeElementIndex] = { From 32415077fc618d7255190299abcaffe3b6cfd318 Mon Sep 17 00:00:00 2001 From: moklick Date: Thu, 26 Nov 2020 10:52:44 +0100 Subject: [PATCH 5/6] refactor(element-updates): check if node type changed --- src/store/index.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/store/index.ts b/src/store/index.ts index 53eee9a8..0e46aeb2 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -219,6 +219,7 @@ export const storeModel: StoreModel = { const propNode = el as Node; const positionChanged = storeElement.position.x !== propNode.position.x || storeElement.position.y !== propNode.position.y; + const typeChanged = typeof propNode.type !== 'undefined' && propNode.type !== storeElement.type; state.elements[storeElementIndex] = { ...storeElement, @@ -228,9 +229,10 @@ export const storeModel: StoreModel = { if (positionChanged) { (state.elements[storeElementIndex] as Node).__rf.position = propNode.position; } - // 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 (typeof propNode.type !== 'undefined' && propNode.type !== storeElement.type) { + + if (typeChanged) { + // 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. (state.elements[storeElementIndex] as Node).__rf.width = null; } } else { From e88dfdb65070b925acf19c282c75a78af8ee9fa7 Mon Sep 17 00:00:00 2001 From: moklick Date: Thu, 26 Nov 2020 14:25:39 +0100 Subject: [PATCH 6/6] refactor(nodes): use one resize observer for all nodes #723 --- src/components/Nodes/utils.ts | 11 ++++- src/components/Nodes/wrapNode.tsx | 23 +++++----- src/container/NodeRenderer/index.tsx | 17 ++++++- src/store/index.ts | 67 +++++++++++++--------------- src/types/index.ts | 1 + src/utils/index.ts | 4 +- 6 files changed, 70 insertions(+), 53 deletions(-) diff --git a/src/components/Nodes/utils.ts b/src/components/Nodes/utils.ts index 7d2a7d31..e917e853 100644 --- a/src/components/Nodes/utils.ts +++ b/src/components/Nodes/utils.ts @@ -1,7 +1,16 @@ import { HandleElement, Position } from '../../types'; import { getDimensions } from '../../utils'; -export const getHandleBounds = ( +export const getHandleBounds = (nodeElement: HTMLDivElement, scale: number) => { + const bounds = nodeElement.getBoundingClientRect(); + + return { + source: getHandleBoundsByHandleType('.source', nodeElement, bounds, scale), + target: getHandleBoundsByHandleType('.target', nodeElement, bounds, scale), + }; +}; + +export const getHandleBoundsByHandleType = ( selector: string, nodeElement: HTMLDivElement, parentBounds: ClientRect | DOMRect, diff --git a/src/components/Nodes/wrapNode.tsx b/src/components/Nodes/wrapNode.tsx index f498326a..3a3b95f4 100644 --- a/src/components/Nodes/wrapNode.tsx +++ b/src/components/Nodes/wrapNode.tsx @@ -35,6 +35,7 @@ export default (NodeComponent: ComponentType) => { snapToGrid, snapGrid, isDragging, + resizeObserver, }: WrapNodeProps) => { const updateNodeDimensions = useStoreActions((actions) => actions.updateNodeDimensions); const addSelectedElements = useStoreActions((actions) => actions.addSelectedElements); @@ -160,24 +161,19 @@ export default (NodeComponent: ComponentType) => { useEffect(() => { if (nodeElement.current && !isHidden) { updateNodeDimensions({ id, nodeElement: nodeElement.current }); + } + }, [id, isHidden]); - const resizeObserver = new ResizeObserver(() => { - if (nodeElement.current) { - updateNodeDimensions({ id, nodeElement: nodeElement.current }); - } - }); + useEffect(() => { + if (nodeElement.current) { + const currNode = nodeElement.current; + resizeObserver.observe(currNode); - resizeObserver.observe(nodeElement.current); - - return () => { - if (resizeObserver && nodeElement.current) { - resizeObserver.unobserve(nodeElement.current); - } - }; + return () => resizeObserver.unobserve(currNode); } return; - }, [id, isHidden]); + }, []); if (isHidden) { return null; @@ -213,6 +209,7 @@ export default (NodeComponent: ComponentType) => { onMouseLeave={onMouseLeaveHandler} onContextMenu={onContextMenuHandler} onClick={onSelectNodeHandler} + data-id={id} > { const elementsSelectable = useStoreState((state) => state.elementsSelectable); const viewportBox = useStoreState((state) => state.viewportBox); const nodes = useStoreState((state) => state.nodes); + const batchUpdateNodeDimensions = useStoreActions((actions) => actions.batchUpdateNodeDimensions); const visibleNodes = props.onlyRenderVisibleElements ? getNodesInside(nodes, viewportBox, transform, true) : nodes; @@ -37,6 +38,19 @@ const NodeRenderer = (props: NodeRendererProps) => { [transform[0], transform[1], transform[2]] ); + const resizeObserver = useMemo( + () => + new ResizeObserver((entries) => { + const updates = entries.map((entry) => ({ + id: entry.target.getAttribute('data-id') as string, + nodeElement: entry.target as HTMLDivElement, + })); + + batchUpdateNodeDimensions({ updates }); + }), + [] + ); + return (
{visibleNodes.map((node) => { @@ -81,6 +95,7 @@ const NodeRenderer = (props: NodeRendererProps) => { isDraggable={isDraggable} isSelectable={isSelectable} isConnectable={isConnectable} + resizeObserver={resizeObserver} /> ); })} diff --git a/src/store/index.ts b/src/store/index.ts index 0e46aeb2..3c3948cf 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -1,4 +1,4 @@ -import { createStore, Action, action, ActionOn, actionOn, Thunk, thunk, computed, Computed } from 'easy-peasy'; +import { createStore, Action, action, Thunk, thunk, computed, Computed } from 'easy-peasy'; import isEqual from 'fast-deep-equal'; import { Selection as D3Selection, ZoomBehavior } from 'd3'; @@ -33,6 +33,10 @@ type NodeDimensionUpdate = { nodeElement: HTMLDivElement; }; +type NodeDimensionUpdates = { + updates: NodeDimensionUpdate[]; +}; + type InitD3Zoom = { d3Zoom: ZoomBehavior; d3Selection: D3Selection; @@ -90,8 +94,8 @@ export interface StoreModel { setElements: Action; + batchUpdateNodeDimensions: Action; updateNodeDimensions: Action; - updateNodeHandlePositions: ActionOn; updateNodePos: Action; updateNodePosDiff: Action; @@ -248,50 +252,39 @@ export const storeModel: StoreModel = { }); }), - updateNodeDimensions: action((state, { id, nodeElement }) => { - const dimensions = getDimensions(nodeElement); - const matchingNode = state.nodes.find((n) => n.id === id); + batchUpdateNodeDimensions: action((state, { updates }) => { + updates.forEach((update) => { + const dimensions = getDimensions(update.nodeElement); + const matchingIndex = state.elements.findIndex((n) => n.id === update.id); + const matchingNode = state.elements[matchingIndex] as Node; - // only update when size change - if ( - !matchingNode || - (matchingNode.__rf.width === dimensions.width && matchingNode.__rf.height === dimensions.height) - ) { - return; - } + if ( + matchingIndex !== -1 && + dimensions.width && + dimensions.height && + (matchingNode.__rf.width !== dimensions.width || matchingNode.__rf.height !== dimensions.height) + ) { + const handleBounds = getHandleBounds(update.nodeElement, state.transform[2]); - state.elements.forEach((n) => { - if (n.id === id && isNode(n)) { - n.__rf.width = dimensions.width; - n.__rf.height = dimensions.height; + (state.elements[matchingIndex] as Node).__rf.width = dimensions.width; + (state.elements[matchingIndex] as Node).__rf.height = dimensions.height; + (state.elements[matchingIndex] as Node).__rf.handleBounds = handleBounds; } }); }), - updateNodeHandlePositions: actionOn( - (actions) => actions.updateNodeDimensions, - (state, target) => { - const { nodeElement, id } = target.payload; - const matchingNode = state.nodes.find((n) => n.id === id); + updateNodeDimensions: action((state, { id, nodeElement }) => { + const dimensions = getDimensions(nodeElement); + const matchingIndex = state.elements.findIndex((n) => n.id === id); - if (!matchingNode) { - return; - } + if (matchingIndex !== -1 && dimensions.width && dimensions.height) { + const handleBounds = getHandleBounds(nodeElement, state.transform[2]); - const bounds = nodeElement.getBoundingClientRect(); - - const handleBounds = { - source: getHandleBounds('.source', nodeElement, bounds, state.transform[2]), - target: getHandleBounds('.target', nodeElement, bounds, state.transform[2]), - }; - - state.elements.forEach((n) => { - if (n.id === id && isNode(n)) { - n.__rf.handleBounds = handleBounds; - } - }); + (state.elements[matchingIndex] as Node).__rf.width = dimensions.width; + (state.elements[matchingIndex] as Node).__rf.height = dimensions.height; + (state.elements[matchingIndex] as Node).__rf.handleBounds = handleBounds; } - ), + }), updateNodePos: action((state, { id, pos }) => { let position: XYPosition = pos; diff --git a/src/types/index.ts b/src/types/index.ts index eb94c85d..3476d7a8 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -224,6 +224,7 @@ export interface WrapNodeProps { snapToGrid?: boolean; snapGrid?: SnapGrid; isDragging?: boolean; + resizeObserver: ResizeObserver; } export type FitViewParams = { diff --git a/src/utils/index.ts b/src/utils/index.ts index caffa530..13832a31 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,6 +1,8 @@ import { DraggableEvent } from 'react-draggable'; import { MouseEvent as ReactMouseEvent } from 'react'; +import { Dimensions } from '../types'; + export const isInputDOMNode = (e: ReactMouseEvent | DraggableEvent | KeyboardEvent) => { const target = e?.target as HTMLElement; @@ -9,7 +11,7 @@ export const isInputDOMNode = (e: ReactMouseEvent | DraggableEvent | KeyboardEve ); }; -export const getDimensions = (node: HTMLDivElement) => ({ +export const getDimensions = (node: HTMLDivElement): Dimensions => ({ width: node.offsetWidth, height: node.offsetHeight, });