feat(nodes): add class name option closes #254
This commit is contained in:
@@ -132,6 +132,7 @@ Node example: `{ id: '1', type: 'input', data: { label: 'Node 1' }, position: {
|
||||
- `data`: {} *(required if you are using a standard type, otherwise depends on your implementation)*
|
||||
- `type`: 'input' | 'output' | 'default' or a custom one you implemented
|
||||
- `style`: css properties
|
||||
- `className`: additional class name
|
||||
- `targetPosition`: 'left' | 'right' | 'top' | 'bottom' handle position - default: 'top'
|
||||
- `sourcePosition`: 'left' | 'right' | 'top' | 'bottom' handle position - default: 'bottom'
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ const onLoad = (graph) => {
|
||||
};
|
||||
|
||||
const initialElements = [
|
||||
{ id: '1', sourcePosition: 'right', type: 'input', data: { label: 'Input' }, position: { x: 0, y: 80 } },
|
||||
{ id: '1', sourcePosition: 'right', type: 'input', className: 'dark-node', data: { label: 'Input' }, position: { x: 0, y: 80 } },
|
||||
{ id: '2', sourcePosition: 'right', targetPosition: 'left', data: { label: 'A Node' }, position: { x: 250, y: 0 } },
|
||||
{ id: '3', sourcePosition: 'right', targetPosition: 'left', data: { label: 'Another node' }, position: { x: 250, y: 160 } },
|
||||
{ id: '4', sourcePosition: 'right', targetPosition: 'left', data: { label: 'Node 4' }, position: { x: 500, y: 80 } },
|
||||
@@ -21,6 +21,15 @@ const HorizontalFlow = () => {
|
||||
const onElementsRemove = (elementsToRemove) =>
|
||||
setElements(els => removeElements(elementsToRemove, els));
|
||||
const onConnect = (params) => setElements(els => addEdge(params, els));
|
||||
const changeClassName = () => {
|
||||
setElements(elms => elms.map(el => {
|
||||
if (el.type === 'input') {
|
||||
el.className = el.className ? '' : 'dark-node';
|
||||
}
|
||||
|
||||
return {...el};
|
||||
}))
|
||||
}
|
||||
|
||||
return (
|
||||
<ReactFlow
|
||||
@@ -29,7 +38,14 @@ const HorizontalFlow = () => {
|
||||
onConnect={onConnect}
|
||||
onLoad={onLoad}
|
||||
selectNodesOnDrag={false}
|
||||
/>
|
||||
>
|
||||
<button
|
||||
onClick={changeClassName}
|
||||
style={{ position: 'absolute', right: 10, top: 30, zIndex: 4 }}
|
||||
>
|
||||
change class name
|
||||
</button>
|
||||
</ReactFlow>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -136,6 +136,11 @@ nav a.active:before {
|
||||
color: #111;
|
||||
}
|
||||
|
||||
.dark-node>div {
|
||||
background: #333 !important;
|
||||
color: #f8f8f8 !important;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
nav {
|
||||
position: relative;
|
||||
|
||||
@@ -142,6 +142,7 @@ export default (NodeComponent: ComponentType<NodeComponentProps>) => {
|
||||
onNodeDragStart,
|
||||
onNodeDragStop,
|
||||
style,
|
||||
className,
|
||||
isInteractive,
|
||||
selectNodesOnDrag,
|
||||
sourcePosition,
|
||||
@@ -151,7 +152,8 @@ export default (NodeComponent: ComponentType<NodeComponentProps>) => {
|
||||
const [offset, setOffset] = useState({ x: 0, y: 0 });
|
||||
const [isDragging, setDragging] = useState(false);
|
||||
const position = { x: xPos, y: yPos };
|
||||
const nodeClasses = cx('react-flow__node', { selected });
|
||||
const nodeClasses = cx('react-flow__node', `react-flow__node-${type}`, className, { selected });
|
||||
|
||||
const nodeStyle: CSSProperties = {
|
||||
zIndex: selected ? 10 : 3,
|
||||
transform: `translate(${xPos}px,${yPos}px)`,
|
||||
|
||||
@@ -42,6 +42,7 @@ function renderNode(
|
||||
transform={transform}
|
||||
selected={isSelected}
|
||||
style={node.style}
|
||||
className={node.className}
|
||||
isInteractive={isInteractive}
|
||||
sourcePosition={node.sourcePosition}
|
||||
targetPosition={node.targetPosition}
|
||||
|
||||
@@ -28,34 +28,33 @@ const useElementUpdater = (elements: Elements): void => {
|
||||
? { ...existingNode.style, ...propNode.style }
|
||||
: existingNode.style;
|
||||
|
||||
const className = existingNode.className === propNode.className ? existingNode.className : propNode.className;
|
||||
|
||||
const positionChanged =
|
||||
existingNode.position.x !== propNode.position.x || existingNode.position.y !== propNode.position.y;
|
||||
|
||||
if (positionChanged) {
|
||||
return {
|
||||
...existingNode,
|
||||
__rg: {
|
||||
...existingNode.__rg,
|
||||
position: propNode.position,
|
||||
},
|
||||
position: propNode.position,
|
||||
data,
|
||||
style,
|
||||
};
|
||||
}
|
||||
|
||||
if (style) {
|
||||
return {
|
||||
...existingNode,
|
||||
data,
|
||||
style,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
const nodeProps = {
|
||||
...existingNode,
|
||||
data,
|
||||
};
|
||||
|
||||
if (positionChanged) {
|
||||
nodeProps.__rg = {
|
||||
...existingNode.__rg,
|
||||
position: propNode.position,
|
||||
};
|
||||
nodeProps.position = propNode.position;
|
||||
}
|
||||
|
||||
if (typeof style !== 'undefined') {
|
||||
nodeProps.style = style;
|
||||
}
|
||||
|
||||
if (typeof className !== 'undefined') {
|
||||
nodeProps.className = className;
|
||||
}
|
||||
|
||||
return nodeProps;
|
||||
}
|
||||
|
||||
return parseElement(propNode) as Node;
|
||||
|
||||
@@ -37,6 +37,7 @@ export interface Node {
|
||||
__rg?: any;
|
||||
data?: any;
|
||||
style?: CSSProperties;
|
||||
className?: string;
|
||||
targetPosition?: Position;
|
||||
sourcePosition?: Position;
|
||||
}
|
||||
@@ -128,6 +129,7 @@ export interface WrapNodeProps {
|
||||
onNodeDragStart?: (node: Node) => void;
|
||||
onNodeDragStop?: (node: Node) => void;
|
||||
style?: CSSProperties;
|
||||
className?: string;
|
||||
sourcePosition?: Position;
|
||||
targetPosition?: Position;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user