feat(rg): add onConnect callback

This commit is contained in:
moklick
2019-07-29 18:18:27 +02:00
parent cc14c724d0
commit 8fb45f4894
26 changed files with 434 additions and 120 deletions
+4 -3
View File
@@ -1,6 +1,7 @@
import React from 'react';
import Handle from '../Handle';
import TargetHandle from '../HandleTypes/TargetHandle';
import SourceHandle from '../HandleTypes/SourceHandle';
const nodeStyles = {
background: '#ff6060',
@@ -11,8 +12,8 @@ const nodeStyles = {
export default ({ data, style }) => (
<div style={{ ...nodeStyles, ...style }}>
<Handle input />
<TargetHandle />
{data.label}
<Handle output />
<SourceHandle />
</div>
);
+2 -2
View File
@@ -1,6 +1,6 @@
import React from 'react';
import Handle from '../Handle';
import SourceHandle from '../HandleTypes/SourceHandle';
const nodeStyles = {
background: '#9999ff',
@@ -15,6 +15,6 @@ export default ({ data, style }) => (
className="react-graph__node-inner"
>
{data.label}
<Handle output />
<SourceHandle />
</div>
);
+2 -2
View File
@@ -1,6 +1,6 @@
import React from 'react';
import Handle from '../Handle';
import TargetHandle from '../HandleTypes/TargetHandle';
const nodeStyles = {
background: '#55dd99',
@@ -11,7 +11,7 @@ const nodeStyles = {
export default ({ data, style }) => (
<div style={{ ...nodeStyles, ...style }}>
<Handle input />
<TargetHandle />
{data.label}
</div>
);
+50 -6
View File
@@ -5,14 +5,38 @@ import cx from 'classnames';
import { GraphContext } from '../../GraphContext';
import { updateNodeData, updateNodePos, setSelectedElements } from '../../state/actions';
import { isNode } from '../../graph-utils';
import { Provider } from '../NodeIdContext';
const isInputTarget = (e) => ['INPUT', 'SELECT', 'TEXTAREA'].includes(e.target.nodeName);
const isInput = e => ['INPUT', 'SELECT', 'TEXTAREA'].includes(e.target.nodeName);
const isHandle = e => e.target.className.includes('source');
const getHandleBounds = (sel, nodeElement, parentBounds) => {
const handle = nodeElement.querySelector(sel);
if (!handle) {
return null;
}
const bounds = handle.getBoundingClientRect();
return {
x: bounds.x - parentBounds.x,
y: bounds.y - parentBounds.y,
width: bounds.width,
height: bounds.height
};
};
const onDragOver = evt => {
evt.preventDefault();
evt.dataTransfer.dropEffect = "move";
}
export default NodeComponent => memo((props) => {
const nodeElement = useRef(null);
const { state, dispatch } = useContext(GraphContext);
const [offset, setOffset] = useState({ x: 0, y: 0 });
const { data, onClick, type, id, __rg } = props;
const { data, onClick, type, id, __rg, onConnect } = props;
const { position } = __rg;
const [ x, y, k ] = state.transform;
const selected = state.selectedElements.filter(isNode).map(e => e.id).includes(id);
@@ -22,12 +46,16 @@ export default NodeComponent => memo((props) => {
const bounds = nodeElement.current.getBoundingClientRect();
const unscaledWith = Math.round(bounds.width * (1 / k));
const unscaledHeight = Math.round(bounds.height * (1 / k));
const handleBounds = {
source: getHandleBounds('.source', nodeElement.current, bounds),
target: getHandleBounds('.target', nodeElement.current, bounds)
};
dispatch(updateNodeData(id, { width: unscaledWith, height: unscaledHeight }));
dispatch(updateNodeData(id, { width: unscaledWith, height: unscaledHeight, handleBounds }));
}, []);
const onStart = (evt) => {
if (isInputTarget(evt)) {
if (isInput(evt) || isHandle(evt)) {
return false;
}
@@ -54,7 +82,7 @@ export default NodeComponent => memo((props) => {
};
const onNodeClick = (evt) => {
if (isInputTarget(evt)) {
if (isInput(evt)) {
return false;
}
@@ -62,6 +90,18 @@ export default NodeComponent => memo((props) => {
onClick({ id, type, data, position });
};
const onDrop = (evt) => {
evt.preventDefault();
const sourceId = evt.dataTransfer.getData('text/plain');
if (sourceId === id) {
return false;
}
onConnect({ sourceId, targetId: id });
};
return (
<ReactDraggable.DraggableCore
grid={[1, 1]}
@@ -70,12 +110,16 @@ export default NodeComponent => memo((props) => {
scale={k}
>
<div
onDrop={onDrop}
onDragOver={onDragOver}
className={nodeClasses}
ref={nodeElement}
style={{ zIndex: selected ? 10 : 3, transform: `translate(${position.x}px,${position.y}px)` }}
onClick={onNodeClick}
>
<NodeComponent {...props} selected={selected} />
<Provider value={id}>
<NodeComponent {...props} selected={selected} />
</Provider>
</div>
</ReactDraggable.DraggableCore>
);