refactor(nodewrapper): use offsetWidth
This commit is contained in:
@@ -4,7 +4,7 @@ export const ConnectionContext = createContext({});
|
|||||||
|
|
||||||
export const Provider = memo(({ onConnect, children }) => {
|
export const Provider = memo(({ onConnect, children }) => {
|
||||||
const [sourceId, setSourceId] = useState(null);
|
const [sourceId, setSourceId] = useState(null);
|
||||||
const [position, setPosition] = useState({ x:0, y: 0 });
|
const [position, setPosition] = useState({ x: 0, y: 0 });
|
||||||
|
|
||||||
const connectionContext = useMemo(() => ({
|
const connectionContext = useMemo(() => ({
|
||||||
sourceId,
|
sourceId,
|
||||||
@@ -12,7 +12,7 @@ export const Provider = memo(({ onConnect, children }) => {
|
|||||||
position,
|
position,
|
||||||
setPosition,
|
setPosition,
|
||||||
onConnect
|
onConnect
|
||||||
}), [sourceId, position]);
|
}), [sourceId, position.x, position.y]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConnectionContext.Provider value={connectionContext}>
|
<ConnectionContext.Provider value={connectionContext}>
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ import React, { memo } from 'react';
|
|||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
|
|
||||||
import { setSelectedElements } from '../../state/actions';
|
import { setSelectedElements } from '../../state/actions';
|
||||||
|
import { isInputNode } from '../../utils';
|
||||||
const isInput = e => ['INPUT', 'SELECT', 'TEXTAREA'].includes(e.target.nodeName);
|
|
||||||
|
|
||||||
export default EdgeComponent => {
|
export default EdgeComponent => {
|
||||||
const WrappedEdge = memo((props) => {
|
const WrappedEdge = memo((props) => {
|
||||||
@@ -17,7 +16,7 @@ export default EdgeComponent => {
|
|||||||
<g
|
<g
|
||||||
className={edgeClasses}
|
className={edgeClasses}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
if (isInput(e)) {
|
if (isInputNode(e)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,12 +8,10 @@ import { parseElement, isNode, isEdge } from '../graph-utils';
|
|||||||
|
|
||||||
export const GraphContext = createContext({});
|
export const GraphContext = createContext({});
|
||||||
|
|
||||||
export const Provider = (props) => {
|
export const Provider = ({
|
||||||
const {
|
elements,
|
||||||
elements,
|
children,
|
||||||
children,
|
}) => {
|
||||||
} = props;
|
|
||||||
|
|
||||||
const [state, dispatch] = useReducer(reducer, initialState);
|
const [state, dispatch] = useReducer(reducer, initialState);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -64,6 +62,8 @@ export const Provider = (props) => {
|
|||||||
|
|
||||||
export const { Consumer } = GraphContext;
|
export const { Consumer } = GraphContext;
|
||||||
|
|
||||||
|
Provider.displayName = 'GraphProvider';
|
||||||
|
|
||||||
Provider.propTypes = {
|
Provider.propTypes = {
|
||||||
elements: PropTypes.arrayOf(PropTypes.object)
|
elements: PropTypes.arrayOf(PropTypes.object)
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,4 +4,6 @@ export const NodeIdContext = createContext(null);
|
|||||||
export const Provider = NodeIdContext.Provider;
|
export const Provider = NodeIdContext.Provider;
|
||||||
export const Consumer = NodeIdContext.Consumer;
|
export const Consumer = NodeIdContext.Consumer;
|
||||||
|
|
||||||
|
Provider.displayName = 'NodeIdProvider';
|
||||||
|
|
||||||
export default NodeIdContext;
|
export default NodeIdContext;
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ import ReactDraggable from 'react-draggable';
|
|||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
|
|
||||||
import { updateNodeData, updateNodePos, setSelectedElements } from '../../state/actions';
|
import { updateNodeData, updateNodePos, setSelectedElements } from '../../state/actions';
|
||||||
|
import { getDimensions, isInputNode } from '../../utils';
|
||||||
import { Provider } from '../NodeIdContext';
|
import { Provider } from '../NodeIdContext';
|
||||||
|
|
||||||
const isInput = e => ['INPUT', 'SELECT', 'TEXTAREA'].includes(e.target.nodeName);
|
|
||||||
const isHandle = e => (
|
const isHandle = e => (
|
||||||
e.target.className &&
|
e.target.className &&
|
||||||
e.target.className.includes &&
|
e.target.className.includes &&
|
||||||
@@ -20,29 +20,27 @@ const getHandleBounds = (sel, nodeElement, parentBounds, k) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const bounds = handle.getBoundingClientRect();
|
const bounds = handle.getBoundingClientRect();
|
||||||
const unscaledWith = Math.round(bounds.width * (1 / k));
|
const dimensions = getDimensions(handle);
|
||||||
const unscaledHeight = Math.round(bounds.height * (1 / k));
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
x: (bounds.x - parentBounds.x) * (1 / k),
|
x: (bounds.x - parentBounds.x) * (1 / k),
|
||||||
y: (bounds.y - parentBounds.y) * (1 / k),
|
y: (bounds.y - parentBounds.y) * (1 / k),
|
||||||
width: unscaledWith,
|
...dimensions
|
||||||
height: unscaledHeight
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const onStart = (evt, { dispatch, setOffset, onClick, id, type, data, position, transform }) => {
|
const onStart = (evt, { dispatch, setOffset, onClick, id, type, data, position, transform }) => {
|
||||||
if (isInput(evt) || isHandle(evt)) {
|
if (isInputNode(evt) || isHandle(evt)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const scaledClient = {
|
const scaledClient = {
|
||||||
x: evt.clientX * (1 / [transform[2]]),
|
x: evt.clientX * (1 / [transform[2]]),
|
||||||
y: evt.clientY * (1 / [transform[2]])
|
y: evt.clientY * (1 / [transform[2]])
|
||||||
}
|
};
|
||||||
const offsetX = scaledClient.x - position.x - [transform[0]];
|
const offsetX = scaledClient.x - position.x - transform[0];
|
||||||
const offsetY = scaledClient.y - position.y - [transform[1]];
|
const offsetY = scaledClient.y - position.y - transform[1];
|
||||||
const node = { id, type, position, data }
|
const node = { id, type, position, data };
|
||||||
|
|
||||||
dispatch(setSelectedElements({ id, type }));
|
dispatch(setSelectedElements({ id, type }));
|
||||||
setOffset({ x: offsetX, y: offsetY });
|
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 onDrag = (evt, { dispatch, setDragging, id, offset, transform }) => {
|
||||||
const scaledClient = {
|
const scaledClient = {
|
||||||
x: evt.clientX * (1 / [transform[2]]),
|
x: evt.clientX * (1 / transform[2]),
|
||||||
y: evt.clientY * (1 / [transform[2]])
|
y: evt.clientY * (1 / transform[2])
|
||||||
};
|
};
|
||||||
|
|
||||||
setDragging(true);
|
setDragging(true);
|
||||||
dispatch(updateNodePos(id, {
|
dispatch(updateNodePos(id, {
|
||||||
x: scaledClient.x - [transform[0]] - offset.x,
|
x: scaledClient.x - transform[0] - offset.x,
|
||||||
y: scaledClient.y - [transform[1]] - offset.y
|
y: scaledClient.y - transform[1] - offset.y
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -74,7 +72,7 @@ const onStop = ({ onNodeDragStop, setDragging, isDragging, id, type, position, d
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default NodeComponent => {
|
export default NodeComponent => {
|
||||||
const WrappedComp = memo((props) => {
|
const NodeWrapper = memo((props) => {
|
||||||
const nodeElement = useRef(null);
|
const nodeElement = useRef(null);
|
||||||
const [offset, setOffset] = useState({ x: 0, y: 0 });
|
const [offset, setOffset] = useState({ x: 0, y: 0 });
|
||||||
const [isDragging, setDragging] = useState(false);
|
const [isDragging, setDragging] = useState(false);
|
||||||
@@ -89,14 +87,13 @@ export default NodeComponent => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const bounds = nodeElement.current.getBoundingClientRect();
|
const bounds = nodeElement.current.getBoundingClientRect();
|
||||||
const unscaledWith = Math.round(bounds.width * (1 / transform[2]));
|
const dimensions = getDimensions(nodeElement.current);
|
||||||
const unscaledHeight = Math.round(bounds.height * (1 / transform[2]));
|
|
||||||
const handleBounds = {
|
const handleBounds = {
|
||||||
source: getHandleBounds('.source', nodeElement.current, bounds, transform[2]),
|
source: getHandleBounds('.source', nodeElement.current, bounds, transform[2]),
|
||||||
target: getHandleBounds('.target', 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 (
|
return (
|
||||||
@@ -125,8 +122,8 @@ export default NodeComponent => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
WrappedComp.displayName = 'Wrapped Node';
|
NodeWrapper.displayName = 'NodeWrapper';
|
||||||
WrappedComp.whyDidYouRender = false;
|
NodeWrapper.whyDidYouRender = false;
|
||||||
|
|
||||||
return WrappedComp;
|
return NodeWrapper;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
|
|
||||||
const isInput = target => ['INPUT', 'SELECT', 'TEXTAREA'].includes(target.nodeName);
|
import { isInputNode } from '../utils';
|
||||||
|
|
||||||
export default function useKeyPress(targetKey) {
|
export default function useKeyPress(targetKey) {
|
||||||
const [keyPressed, setKeyPressed] = useState(false);
|
const [keyPressed, setKeyPressed] = useState(false);
|
||||||
|
|
||||||
function downHandler({ key, target }) {
|
function downHandler({ key, target }) {
|
||||||
if (key === targetKey && !isInput(target)) {
|
if (key === targetKey && !isInputNode(target)) {
|
||||||
setKeyPressed(true);
|
setKeyPressed(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const upHandler = ({ key, target }) => {
|
const upHandler = ({ key, target }) => {
|
||||||
if (key === targetKey && !isInput(target)) {
|
if (key === targetKey && !isInputNode(target)) {
|
||||||
setKeyPressed(false);
|
setKeyPressed(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
export const isFunction = obj => !!(obj && obj.constructor && obj.call && obj.apply);
|
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) => {
|
export const getDimensions = (node) => {
|
||||||
return {
|
return {
|
||||||
width: node.offsetWidth,
|
width: node.offsetWidth,
|
||||||
|
|||||||
Reference in New Issue
Block a user