diff --git a/src/ConnectionContext/index.js b/src/ConnectionContext/index.js index 0c753d53..1e286b18 100644 --- a/src/ConnectionContext/index.js +++ b/src/ConnectionContext/index.js @@ -4,7 +4,7 @@ export const ConnectionContext = createContext({}); export const Provider = memo(({ onConnect, children }) => { const [sourceId, setSourceId] = useState(null); - const [position, setPosition] = useState({ x:0, y: 0 }); + const [position, setPosition] = useState({ x: 0, y: 0 }); const connectionContext = useMemo(() => ({ sourceId, @@ -12,7 +12,7 @@ export const Provider = memo(({ onConnect, children }) => { position, setPosition, onConnect - }), [sourceId, position]); + }), [sourceId, position.x, position.y]); return ( diff --git a/src/EdgeRenderer/EdgeTypes/wrapEdge.js b/src/EdgeRenderer/EdgeTypes/wrapEdge.js index bf03fb8f..d89a5c02 100644 --- a/src/EdgeRenderer/EdgeTypes/wrapEdge.js +++ b/src/EdgeRenderer/EdgeTypes/wrapEdge.js @@ -2,8 +2,7 @@ import React, { memo } from 'react'; import cx from 'classnames'; import { setSelectedElements } from '../../state/actions'; - -const isInput = e => ['INPUT', 'SELECT', 'TEXTAREA'].includes(e.target.nodeName); +import { isInputNode } from '../../utils'; export default EdgeComponent => { const WrappedEdge = memo((props) => { @@ -17,7 +16,7 @@ export default EdgeComponent => { { - if (isInput(e)) { + if (isInputNode(e)) { return false; } diff --git a/src/GraphContext/index.js b/src/GraphContext/index.js index 6e9e131a..f6c2223a 100644 --- a/src/GraphContext/index.js +++ b/src/GraphContext/index.js @@ -8,12 +8,10 @@ import { parseElement, isNode, isEdge } from '../graph-utils'; export const GraphContext = createContext({}); -export const Provider = (props) => { - const { - elements, - children, - } = props; - +export const Provider = ({ + elements, + children, +}) => { const [state, dispatch] = useReducer(reducer, initialState); useEffect(() => { @@ -64,6 +62,8 @@ export const Provider = (props) => { export const { Consumer } = GraphContext; +Provider.displayName = 'GraphProvider'; + Provider.propTypes = { elements: PropTypes.arrayOf(PropTypes.object) }; diff --git a/src/NodeRenderer/NodeIdContext.js b/src/NodeRenderer/NodeIdContext.js index b9010195..5ca8cefc 100644 --- a/src/NodeRenderer/NodeIdContext.js +++ b/src/NodeRenderer/NodeIdContext.js @@ -4,4 +4,6 @@ export const NodeIdContext = createContext(null); export const Provider = NodeIdContext.Provider; export const Consumer = NodeIdContext.Consumer; +Provider.displayName = 'NodeIdProvider'; + export default NodeIdContext; diff --git a/src/NodeRenderer/NodeTypes/wrapNode.js b/src/NodeRenderer/NodeTypes/wrapNode.js index f4238a61..f94b060f 100644 --- a/src/NodeRenderer/NodeTypes/wrapNode.js +++ b/src/NodeRenderer/NodeTypes/wrapNode.js @@ -3,9 +3,9 @@ import ReactDraggable from 'react-draggable'; import cx from 'classnames'; import { updateNodeData, updateNodePos, setSelectedElements } from '../../state/actions'; +import { getDimensions, isInputNode } from '../../utils'; import { Provider } from '../NodeIdContext'; -const isInput = e => ['INPUT', 'SELECT', 'TEXTAREA'].includes(e.target.nodeName); const isHandle = e => ( e.target.className && e.target.className.includes && @@ -20,29 +20,27 @@ const getHandleBounds = (sel, nodeElement, parentBounds, k) => { } const bounds = handle.getBoundingClientRect(); - const unscaledWith = Math.round(bounds.width * (1 / k)); - const unscaledHeight = Math.round(bounds.height * (1 / k)); + const dimensions = getDimensions(handle); return { x: (bounds.x - parentBounds.x) * (1 / k), y: (bounds.y - parentBounds.y) * (1 / k), - width: unscaledWith, - height: unscaledHeight + ...dimensions }; }; const onStart = (evt, { dispatch, setOffset, onClick, id, type, data, position, transform }) => { - if (isInput(evt) || isHandle(evt)) { + if (isInputNode(evt) || isHandle(evt)) { return false; } const scaledClient = { x: evt.clientX * (1 / [transform[2]]), y: evt.clientY * (1 / [transform[2]]) - } - const offsetX = scaledClient.x - position.x - [transform[0]]; - const offsetY = scaledClient.y - position.y - [transform[1]]; - const node = { id, type, position, data } + }; + const offsetX = scaledClient.x - position.x - transform[0]; + const offsetY = scaledClient.y - position.y - transform[1]; + const node = { id, type, position, data }; dispatch(setSelectedElements({ id, type })); setOffset({ x: offsetX, y: offsetY }); @@ -51,14 +49,14 @@ const onStart = (evt, { dispatch, setOffset, onClick, id, type, data, position, const onDrag = (evt, { dispatch, setDragging, id, offset, transform }) => { const scaledClient = { - x: evt.clientX * (1 / [transform[2]]), - y: evt.clientY * (1 / [transform[2]]) + x: evt.clientX * (1 / transform[2]), + y: evt.clientY * (1 / transform[2]) }; setDragging(true); dispatch(updateNodePos(id, { - x: scaledClient.x - [transform[0]] - offset.x, - y: scaledClient.y - [transform[1]] - offset.y + x: scaledClient.x - transform[0] - offset.x, + y: scaledClient.y - transform[1] - offset.y })); }; @@ -74,7 +72,7 @@ const onStop = ({ onNodeDragStop, setDragging, isDragging, id, type, position, d }; export default NodeComponent => { - const WrappedComp = memo((props) => { + const NodeWrapper = memo((props) => { const nodeElement = useRef(null); const [offset, setOffset] = useState({ x: 0, y: 0 }); const [isDragging, setDragging] = useState(false); @@ -89,14 +87,13 @@ export default NodeComponent => { useEffect(() => { const bounds = nodeElement.current.getBoundingClientRect(); - const unscaledWith = Math.round(bounds.width * (1 / transform[2])); - const unscaledHeight = Math.round(bounds.height * (1 / transform[2])); + const dimensions = getDimensions(nodeElement.current); const handleBounds = { source: getHandleBounds('.source', nodeElement.current, bounds, transform[2]), target: getHandleBounds('.target', nodeElement.current, bounds, transform[2]) }; - dispatch(updateNodeData(id, { width: unscaledWith, height: unscaledHeight, handleBounds })); + dispatch(updateNodeData(id, { ...dimensions, handleBounds })); }, []); return ( @@ -125,8 +122,8 @@ export default NodeComponent => { ); }); - WrappedComp.displayName = 'Wrapped Node'; - WrappedComp.whyDidYouRender = false; + NodeWrapper.displayName = 'NodeWrapper'; + NodeWrapper.whyDidYouRender = false; - return WrappedComp; + return NodeWrapper; }; diff --git a/src/hooks/useKeyPress.js b/src/hooks/useKeyPress.js index cc165c5d..22739b8f 100644 --- a/src/hooks/useKeyPress.js +++ b/src/hooks/useKeyPress.js @@ -1,18 +1,18 @@ import { useState, useEffect } from 'react'; -const isInput = target => ['INPUT', 'SELECT', 'TEXTAREA'].includes(target.nodeName); +import { isInputNode } from '../utils'; export default function useKeyPress(targetKey) { const [keyPressed, setKeyPressed] = useState(false); function downHandler({ key, target }) { - if (key === targetKey && !isInput(target)) { + if (key === targetKey && !isInputNode(target)) { setKeyPressed(true); } } const upHandler = ({ key, target }) => { - if (key === targetKey && !isInput(target)) { + if (key === targetKey && !isInputNode(target)) { setKeyPressed(false); } }; diff --git a/src/utils.js b/src/utils.js index ec2e3f3b..191f8764 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,5 +1,7 @@ export const isFunction = obj => !!(obj && obj.constructor && obj.call && obj.apply); +export const isInputNode = e => e && e.target && ['INPUT', 'SELECT', 'TEXTAREA'].includes(e.target.nodeName); + export const getDimensions = (node) => { return { width: node.offsetWidth,