init 🚀

This commit is contained in:
moklick
2019-07-15 16:48:04 +02:00
commit cf4441ce6d
24 changed files with 8924 additions and 0 deletions
+14
View File
@@ -0,0 +1,14 @@
import React from 'react';
import styled from '@emotion/styled';
const Handle = styled.div`
position: absolute;
width: 12px;
height: 12px;
transform: translate(-50%, -50%);
background: #222;
left: 50%;
border-radius: 50%;
`;
export default props => <Handle {...props} />;
+18
View File
@@ -0,0 +1,18 @@
import React from 'react';
import styled from '@emotion/styled';
import wrapNode from './wrapNode';
import Handle from '../Handle';
const Wrapper = styled.div`
background: #ff6060;
padding: 10px;
`;
export default wrapNode(({ data, style }) => (
<Wrapper style={style}>
<Handle style={{ top: 0 }} />
{data.label}
<Handle style={{ bottom: 0, top: 'auto', transform: 'translate(-50%, 50%)' }} />
</Wrapper>
));
+17
View File
@@ -0,0 +1,17 @@
import React from 'react';
import styled from '@emotion/styled';
import wrapNode from './wrapNode';
import Handle from '../Handle';
const Wrapper = styled.div`
background: #9999ff;
padding: 10px;
`;
export default wrapNode(({ data, style }) => (
<Wrapper style={style}>
{data.label}
<Handle style={{ bottom: 0, top: 'auto', transform: 'translate(-50%, 50%)' }} />
</Wrapper>
));
+17
View File
@@ -0,0 +1,17 @@
import React from 'react';
import styled from '@emotion/styled';
import wrapNode from './wrapNode';
import Handle from '../Handle';
const Wrapper = styled.div`
background: #55ff99;
padding: 10px;
`;
export default wrapNode(({ data, style }) => (
<Wrapper style={style}>
<Handle style={{ top: 0 }} />
{data.label}
</Wrapper>
));
+76
View File
@@ -0,0 +1,76 @@
import React, { useEffect, useRef, useContext } from 'react';
import styled from '@emotion/styled';
import ReactDraggable from 'react-draggable';
import { GraphContext } from '../../GraphContext';
const NodeWrapper = styled.div`
position: absolute;
width: 150px;
color: #222;
font-family: sans-serif;
font-size: 12px;
text-align: center;
cursor: grab;
border: 1px solid #ddd;
border-radius: 2px;
user-select: none;
pointer-events: all;
transform-origin: 0 0;
&:hover {
box-shadow: 0 1px 5px 2px rgba(0, 0, 0, 0.08);
}
`;
export default NodeComponent => (props) => {
const { position, data, onNodeClick } = props;
const { id, __width, __height } = data;
const nodeElement = useRef(null);
const graphContext = useContext(GraphContext);
const { x, y, k } = graphContext.transform;
useEffect(() => {
const bounds = nodeElement.current.getBoundingClientRect();
if (__width !== bounds.width || __height !== bounds.height) {
graphContext.updateNodeData(id, { __width: bounds.width, __height: bounds.height });
}
}, []);
const nodePosition = {
x: (k * position.x) + x,
y: (k * position.y) + y
};
return (
<ReactDraggable.DraggableCore
grid={[1, 1]}
onStart={(e) => {
const offsetX = e.clientX - position.x - x;
const offsetY = e.clientY - position.y - y;
graphContext.updateNodeData(id, { __offsetX: offsetX, __offsetY: offsetY });
}}
onDrag={(e, d) => {
const { __offsetX = 0, __offsetY = 0 } = data;
graphContext.updateNodePos(id, {
x: e.clientX - x - __offsetX,
y: e.clientY - y - __offsetY
});
}}
scale={k}
>
<NodeWrapper
className="node"
ref={nodeElement}
style={{ transform: `translate(${position.x}px,${position.y}px)` }}
onClick={() => onNodeClick(data)}
// style={{ transform: `translate(${nodePosition.x}px,${nodePosition.y}px) scale(${k})` }}
>
<NodeComponent {...props} />
</NodeWrapper>
</ReactDraggable.DraggableCore>
);
};
+60
View File
@@ -0,0 +1,60 @@
import React, { PureComponent } from 'react';
import styled from '@emotion/styled';
import { Consumer } from '../GraphContext';
import DefaultNode from './NodeTypes/DefaultNode';
import InputNode from './NodeTypes/InputNode';
import OutputNode from './NodeTypes/OutputNode';
const Nodes = styled.div`
width: 100%;
height: 100%;
position: absolute;
z-index: 2;
pointer-events: none;
transform-origin: 0 0;
`;
class NodeRenderer extends PureComponent {
renderNode(d, onNodeClick) {
const nodeType = d.data.type || 'default';
const NodeComponent = this.props.nodeTypes[nodeType];
return (
<NodeComponent
key={d.data.id}
position={d.position}
data={d.data}
style={d.style || {}}
onNodeClick={onNodeClick}
/>
);
}
render() {
return (
<Consumer>
{({ transform, nodes, onNodeClick }) => (
<Nodes
style={{
transform: `translate(${transform.x}px,${transform.y}px) scale(${transform.k})`
}}
>
{nodes.map(d => this.renderNode(d, onNodeClick))}
</Nodes>
)}
</Consumer>
);
}
}
NodeRenderer.defaultProps = {
nodeTypes: {
input: InputNode,
default: DefaultNode,
output: OutputNode
}
};
export default NodeRenderer;