+
-
+
{nodesSelectionActive &&
}
diff --git a/src/container/NodeRenderer/index.tsx b/src/container/NodeRenderer/index.tsx
index 3ca43ab9..079d6d23 100644
--- a/src/container/NodeRenderer/index.tsx
+++ b/src/container/NodeRenderer/index.tsx
@@ -22,7 +22,9 @@ function renderNode(
props: NodeRendererProps,
transform: Transform,
selectedElements: Elements | null,
- isInteractive: boolean
+ nodesDraggable: boolean,
+ nodesConnectable: boolean,
+ elementsSelectable: boolean
) {
const nodeType = node.type || 'default';
const NodeComponent = (props.nodeTypes[nodeType] || props.nodeTypes.default) as ComponentType
;
@@ -51,7 +53,9 @@ function renderNode(
selected={isSelected}
style={node.style}
className={node.className}
- isInteractive={isInteractive}
+ isDraggable={nodesDraggable}
+ isSelectable={elementsSelectable}
+ isConnectable={nodesConnectable}
sourcePosition={node.sourcePosition}
targetPosition={node.targetPosition}
selectNodesOnDrag={props.selectNodesOnDrag}
@@ -65,7 +69,10 @@ const NodeRenderer = memo(({ onlyRenderVisibleNodes = true, ...props }: NodeRend
const selectedElements = useStoreState((s) => s.selectedElements);
const width = useStoreState((s) => s.width);
const height = useStoreState((s) => s.height);
- const isInteractive = useStoreState((s) => s.isInteractive);
+ const nodesDraggable = useStoreState((s) => s.nodesDraggable);
+ const nodesConnectable = useStoreState((s) => s.nodesConnectable);
+ const elementsSelectable = useStoreState((s) => s.elementsSelectable);
+
const [tX, tY, tScale] = transform;
const transformStyle = {
transform: `translate(${tX}px,${tY}px) scale(${tScale})`,
@@ -77,7 +84,9 @@ const NodeRenderer = memo(({ onlyRenderVisibleNodes = true, ...props }: NodeRend
return (
- {renderNodes.map((node) => renderNode(node, props, transform, selectedElements, isInteractive))}
+ {renderNodes.map((node) =>
+ renderNode(node, props, transform, selectedElements, nodesDraggable, nodesConnectable, elementsSelectable)
+ )}
);
});
diff --git a/src/container/ReactFlow/index.tsx b/src/container/ReactFlow/index.tsx
index ead29f93..343e2964 100644
--- a/src/container/ReactFlow/index.tsx
+++ b/src/container/ReactFlow/index.tsx
@@ -56,7 +56,9 @@ export interface ReactFlowProps extends Omit, 'on
snapToGrid: boolean;
snapGrid: [number, number];
onlyRenderVisibleNodes: boolean;
- isInteractive: boolean;
+ nodesDraggable: boolean;
+ nodesConnectable: boolean;
+ elementsSelectable: boolean;
selectNodesOnDrag: boolean;
minZoom: number;
maxZoom: number;
@@ -89,7 +91,9 @@ const ReactFlow = ({
snapToGrid,
snapGrid,
onlyRenderVisibleNodes,
- isInteractive,
+ nodesDraggable,
+ nodesConnectable,
+ elementsSelectable,
selectNodesOnDrag,
minZoom,
maxZoom,
@@ -123,7 +127,9 @@ const ReactFlow = ({
snapToGrid={snapToGrid}
snapGrid={snapGrid}
onlyRenderVisibleNodes={onlyRenderVisibleNodes}
- isInteractive={isInteractive}
+ nodesDraggable={nodesDraggable}
+ nodesConnectable={nodesConnectable}
+ elementsSelectable={elementsSelectable}
selectNodesOnDrag={selectNodesOnDrag}
minZoom={minZoom}
maxZoom={maxZoom}
@@ -156,7 +162,9 @@ ReactFlow.defaultProps = {
snapToGrid: false,
snapGrid: [16, 16],
onlyRenderVisibleNodes: true,
- isInteractive: true,
+ nodesDraggable: true,
+ nodesConnectable: true,
+ elementsSelectable: true,
selectNodesOnDrag: true,
minZoom: 0.5,
maxZoom: 2,
diff --git a/src/store/index.ts b/src/store/index.ts
index bb5486c2..5194a04b 100644
--- a/src/store/index.ts
+++ b/src/store/index.ts
@@ -79,7 +79,9 @@ export interface StoreModel {
snapToGrid: boolean;
snapGrid: [number, number];
- isInteractive: boolean;
+ nodesDraggable: boolean;
+ nodesConnectable: boolean;
+ elementsSelectable: boolean;
reactFlowVersion: string;
@@ -116,6 +118,9 @@ export interface StoreModel {
setConnectionNodeId: Action;
setInteractive: Action;
+ setNodesDraggable: Action;
+ setNodesConnectable: Action;
+ setElementsSelectable: Action;
setUserSelection: Action;
updateUserSelection: Action;
@@ -162,7 +167,9 @@ export const storeModel: StoreModel = {
snapGrid: [16, 16],
snapToGrid: false,
- isInteractive: true,
+ nodesDraggable: true,
+ nodesConnectable: true,
+ elementsSelectable: true,
reactFlowVersion: typeof __REACT_FLOW_VERSION__ !== 'undefined' ? __REACT_FLOW_VERSION__ : '-',
@@ -373,7 +380,21 @@ export const storeModel: StoreModel = {
}),
setInteractive: action((state, isInteractive) => {
- state.isInteractive = isInteractive;
+ state.nodesDraggable = isInteractive;
+ state.nodesConnectable = isInteractive;
+ state.elementsSelectable = isInteractive;
+ }),
+
+ setNodesDraggable: action((state, nodesDraggable) => {
+ state.nodesDraggable = nodesDraggable;
+ }),
+
+ setNodesConnectable: action((state, nodesConnectable) => {
+ state.nodesConnectable = nodesConnectable;
+ }),
+
+ setElementsSelectable: action((state, elementsSelectable) => {
+ state.elementsSelectable = elementsSelectable;
}),
fitView: action((state, payload = { padding: 0.1 }) => {
diff --git a/src/style.css b/src/style.css
index 731a6191..e2057f62 100644
--- a/src/style.css
+++ b/src/style.css
@@ -112,7 +112,11 @@
font-size: 12px;
color: #222;
text-align: center;
+}
+.react-flow__node-default.selectable,
+.react-flow__node-input.selectable,
+.react-flow__node-output.selectable {
&.selected,
&.selected:hover {
box-shadow: 0 0 0 2px #555;
@@ -158,7 +162,12 @@
width: 10px;
height: 8px;
background: rgba(255, 255, 255, 0.4);
- cursor: crosshair;
+ pointer-events: none;
+
+ &.connectable {
+ pointer-events: all;
+ cursor: crosshair;
+ }
}
.react-flow__handle-bottom {
diff --git a/src/types/index.ts b/src/types/index.ts
index 9fd3db49..666a6e2d 100644
--- a/src/types/index.ts
+++ b/src/types/index.ts
@@ -94,6 +94,7 @@ export interface NodeProps {
type: string;
data: any;
selected: boolean;
+ isConnectable: boolean;
targetPosition?: Position;
sourcePosition?: Position;
}
@@ -102,6 +103,7 @@ export interface NodeComponentProps {
id: ElementId;
type: string;
data: any;
+ isConnectable: boolean;
selected?: boolean;
transform?: Transform;
xPos?: number;
@@ -126,7 +128,9 @@ export interface WrapNodeProps {
transform: Transform;
xPos: number;
yPos: number;
- isInteractive: boolean;
+ isSelectable: boolean;
+ isDraggable: boolean;
+ isConnectable: boolean;
selectNodesOnDrag: boolean;
onClick?: (node: Node) => void;
onMouseEnter?: (evt: MouseEvent, node: Node) => void;
@@ -182,6 +186,7 @@ export interface HandleElement extends XYPosition, Dimensions {
export interface HandleProps {
type: HandleType;
position: Position;
+ isConnectable?: boolean;
onConnect?: OnConnectFunc;
isValidConnection?: (connection: Connection) => boolean;
id?: string;