diff --git a/README.md b/README.md
index bbb4e74f..3e39618e 100644
--- a/README.md
+++ b/README.md
@@ -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'
diff --git a/example/src/Horizontal/index.js b/example/src/Horizontal/index.js
index 87cbf227..47684f5d 100644
--- a/example/src/Horizontal/index.js
+++ b/example/src/Horizontal/index.js
@@ -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 (
{
onConnect={onConnect}
onLoad={onLoad}
selectNodesOnDrag={false}
- />
+ >
+
+
);
}
diff --git a/example/src/index.css b/example/src/index.css
index 87da1ef6..cf5db29f 100644
--- a/example/src/index.css
+++ b/example/src/index.css
@@ -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;
diff --git a/src/components/Nodes/wrapNode.tsx b/src/components/Nodes/wrapNode.tsx
index bf938cf1..a1fb111a 100644
--- a/src/components/Nodes/wrapNode.tsx
+++ b/src/components/Nodes/wrapNode.tsx
@@ -142,6 +142,7 @@ export default (NodeComponent: ComponentType) => {
onNodeDragStart,
onNodeDragStop,
style,
+ className,
isInteractive,
selectNodesOnDrag,
sourcePosition,
@@ -151,7 +152,8 @@ export default (NodeComponent: ComponentType) => {
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)`,
diff --git a/src/container/NodeRenderer/index.tsx b/src/container/NodeRenderer/index.tsx
index e28c13ed..6c9d684b 100644
--- a/src/container/NodeRenderer/index.tsx
+++ b/src/container/NodeRenderer/index.tsx
@@ -42,6 +42,7 @@ function renderNode(
transform={transform}
selected={isSelected}
style={node.style}
+ className={node.className}
isInteractive={isInteractive}
sourcePosition={node.sourcePosition}
targetPosition={node.targetPosition}
diff --git a/src/hooks/useElementUpdater.ts b/src/hooks/useElementUpdater.ts
index 7eda42d4..c8c6936d 100644
--- a/src/hooks/useElementUpdater.ts
+++ b/src/hooks/useElementUpdater.ts
@@ -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;
diff --git a/src/types/index.ts b/src/types/index.ts
index b3cb1584..34b84d42 100644
--- a/src/types/index.ts
+++ b/src/types/index.ts
@@ -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;
}