feat(nodes): add selectNodesOnDrag prop type
This commit is contained in:
@@ -86,6 +86,7 @@ const BasicFlow = () => (
|
|||||||
- `snapGrid`: [x, y] array - default: `[16, 16]`
|
- `snapGrid`: [x, y] array - default: `[16, 16]`
|
||||||
- `onlyRenderVisibleNodes`: default: `true`
|
- `onlyRenderVisibleNodes`: default: `true`
|
||||||
- `isInteractive`: default: `true`. If the graph is not interactive you can't drag any nodes
|
- `isInteractive`: default: `true`. If the graph is not interactive you can't drag any nodes
|
||||||
|
- `selectNodesOnDrag`: default: `true`
|
||||||
|
|
||||||
## Styling
|
## Styling
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ const HorizontalFlow = () => {
|
|||||||
onElementsRemove={onElementsRemove}
|
onElementsRemove={onElementsRemove}
|
||||||
onConnect={onConnect}
|
onConnect={onConnect}
|
||||||
onLoad={onLoad}
|
onLoad={onLoad}
|
||||||
|
selectNodesOnDrag={false}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ interface OnDragStartParams {
|
|||||||
id: ElementId;
|
id: ElementId;
|
||||||
type: string;
|
type: string;
|
||||||
data: any;
|
data: any;
|
||||||
|
selectNodesOnDrag: boolean;
|
||||||
setOffset: (pos: XYPosition) => void;
|
setOffset: (pos: XYPosition) => void;
|
||||||
transform: Transform;
|
transform: Transform;
|
||||||
position: XYPosition;
|
position: XYPosition;
|
||||||
@@ -27,6 +28,7 @@ const onStart = ({
|
|||||||
id,
|
id,
|
||||||
type,
|
type,
|
||||||
data,
|
data,
|
||||||
|
selectNodesOnDrag,
|
||||||
setOffset,
|
setOffset,
|
||||||
transform,
|
transform,
|
||||||
position,
|
position,
|
||||||
@@ -42,12 +44,15 @@ const onStart = ({
|
|||||||
const offsetY = scaledClient.y - position.y - transform[1];
|
const offsetY = scaledClient.y - position.y - transform[1];
|
||||||
const node = { id, type, position, data };
|
const node = { id, type, position, data };
|
||||||
|
|
||||||
store.dispatch.setSelectedElements({ id, type } as Node);
|
|
||||||
setOffset({ x: offsetX, y: offsetY });
|
setOffset({ x: offsetX, y: offsetY });
|
||||||
|
|
||||||
if (onNodeDragStart) {
|
if (onNodeDragStart) {
|
||||||
onNodeDragStart(node);
|
onNodeDragStart(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (selectNodesOnDrag) {
|
||||||
|
store.dispatch.setSelectedElements({ id, type } as Node);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
interface OnDragParams {
|
interface OnDragParams {
|
||||||
@@ -83,19 +88,21 @@ interface OnDragStopParams {
|
|||||||
type: string;
|
type: string;
|
||||||
position: XYPosition;
|
position: XYPosition;
|
||||||
data: any;
|
data: any;
|
||||||
|
selectNodesOnDrag: boolean;
|
||||||
onNodeDragStop?: (node: Node) => void;
|
onNodeDragStop?: (node: Node) => void;
|
||||||
onClick?: (node: Node) => void;
|
onClick?: (node: Node) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const onStop = ({
|
const onStop = ({
|
||||||
onNodeDragStop,
|
|
||||||
onClick,
|
|
||||||
isDragging,
|
|
||||||
setDragging,
|
|
||||||
id,
|
id,
|
||||||
type,
|
type,
|
||||||
position,
|
position,
|
||||||
data,
|
data,
|
||||||
|
isDragging,
|
||||||
|
setDragging,
|
||||||
|
selectNodesOnDrag,
|
||||||
|
onNodeDragStop,
|
||||||
|
onClick,
|
||||||
}: OnDragStopParams): void => {
|
}: OnDragStopParams): void => {
|
||||||
const node = {
|
const node = {
|
||||||
id,
|
id,
|
||||||
@@ -104,8 +111,14 @@ const onStop = ({
|
|||||||
data,
|
data,
|
||||||
} as Node;
|
} as Node;
|
||||||
|
|
||||||
if (!isDragging && onClick) {
|
if (!isDragging) {
|
||||||
return onClick(node);
|
if (!selectNodesOnDrag) {
|
||||||
|
store.dispatch.setSelectedElements({ id, type } as Node);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onClick) {
|
||||||
|
return onClick(node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setDragging(false);
|
setDragging(false);
|
||||||
@@ -130,6 +143,7 @@ export default (NodeComponent: ComponentType<NodeComponentProps>) => {
|
|||||||
onNodeDragStop,
|
onNodeDragStop,
|
||||||
style,
|
style,
|
||||||
isInteractive,
|
isInteractive,
|
||||||
|
selectNodesOnDrag,
|
||||||
sourcePosition,
|
sourcePosition,
|
||||||
targetPosition,
|
targetPosition,
|
||||||
}: WrapNodeProps) => {
|
}: WrapNodeProps) => {
|
||||||
@@ -177,10 +191,22 @@ export default (NodeComponent: ComponentType<NodeComponentProps>) => {
|
|||||||
return (
|
return (
|
||||||
<DraggableCore
|
<DraggableCore
|
||||||
onStart={(evt) =>
|
onStart={(evt) =>
|
||||||
onStart({ evt: evt as MouseEvent, onNodeDragStart, id, type, data, setOffset, transform, position })
|
onStart({
|
||||||
|
evt: evt as MouseEvent,
|
||||||
|
selectNodesOnDrag,
|
||||||
|
onNodeDragStart,
|
||||||
|
id,
|
||||||
|
type,
|
||||||
|
data,
|
||||||
|
setOffset,
|
||||||
|
transform,
|
||||||
|
position,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
onDrag={(evt) => onDrag({ evt: evt as MouseEvent, setDragging, id, offset, transform })}
|
onDrag={(evt) => onDrag({ evt: evt as MouseEvent, setDragging, id, offset, transform })}
|
||||||
onStop={() => onStop({ onNodeDragStop, onClick, isDragging, setDragging, id, type, position, data })}
|
onStop={() =>
|
||||||
|
onStop({ onNodeDragStop, selectNodesOnDrag, onClick, isDragging, setDragging, id, type, position, data })
|
||||||
|
}
|
||||||
scale={transform[2]}
|
scale={transform[2]}
|
||||||
disabled={!isInteractive}
|
disabled={!isInteractive}
|
||||||
cancel=".nodrag"
|
cancel=".nodrag"
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ export interface GraphViewProps {
|
|||||||
snapGrid: [number, number];
|
snapGrid: [number, number];
|
||||||
onlyRenderVisibleNodes: boolean;
|
onlyRenderVisibleNodes: boolean;
|
||||||
isInteractive: boolean;
|
isInteractive: boolean;
|
||||||
|
selectNodesOnDrag: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GraphView = memo(
|
const GraphView = memo(
|
||||||
@@ -55,6 +56,7 @@ const GraphView = memo(
|
|||||||
snapGrid,
|
snapGrid,
|
||||||
onlyRenderVisibleNodes,
|
onlyRenderVisibleNodes,
|
||||||
isInteractive,
|
isInteractive,
|
||||||
|
selectNodesOnDrag,
|
||||||
}: GraphViewProps) => {
|
}: GraphViewProps) => {
|
||||||
const zoomPane = useRef<HTMLDivElement>(null);
|
const zoomPane = useRef<HTMLDivElement>(null);
|
||||||
const rendererNode = useRef<HTMLDivElement>(null);
|
const rendererNode = useRef<HTMLDivElement>(null);
|
||||||
@@ -132,6 +134,7 @@ const GraphView = memo(
|
|||||||
onNodeDragStop={onNodeDragStop}
|
onNodeDragStop={onNodeDragStop}
|
||||||
onNodeDragStart={onNodeDragStart}
|
onNodeDragStart={onNodeDragStart}
|
||||||
onlyRenderVisibleNodes={onlyRenderVisibleNodes}
|
onlyRenderVisibleNodes={onlyRenderVisibleNodes}
|
||||||
|
selectNodesOnDrag={selectNodesOnDrag}
|
||||||
/>
|
/>
|
||||||
<EdgeRenderer
|
<EdgeRenderer
|
||||||
width={width}
|
width={width}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { Node, Transform, NodeTypesType, WrapNodeProps, Elements, Edge } from '.
|
|||||||
|
|
||||||
interface NodeRendererProps {
|
interface NodeRendererProps {
|
||||||
nodeTypes: NodeTypesType;
|
nodeTypes: NodeTypesType;
|
||||||
|
selectNodesOnDrag: boolean;
|
||||||
onElementClick?: (element: Node | Edge) => void;
|
onElementClick?: (element: Node | Edge) => void;
|
||||||
onNodeDragStart?: (node: Node) => void;
|
onNodeDragStart?: (node: Node) => void;
|
||||||
onNodeDragStop?: (node: Node) => void;
|
onNodeDragStop?: (node: Node) => void;
|
||||||
@@ -44,6 +45,7 @@ function renderNode(
|
|||||||
isInteractive={isInteractive}
|
isInteractive={isInteractive}
|
||||||
sourcePosition={node.sourcePosition}
|
sourcePosition={node.sourcePosition}
|
||||||
targetPosition={node.targetPosition}
|
targetPosition={node.targetPosition}
|
||||||
|
selectNodesOnDrag={props.selectNodesOnDrag}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ export interface ReactFlowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'on
|
|||||||
snapGrid: [number, number];
|
snapGrid: [number, number];
|
||||||
onlyRenderVisibleNodes: boolean;
|
onlyRenderVisibleNodes: boolean;
|
||||||
isInteractive: boolean;
|
isInteractive: boolean;
|
||||||
|
selectNodesOnDrag: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ReactFlow = ({
|
const ReactFlow = ({
|
||||||
@@ -69,6 +70,7 @@ const ReactFlow = ({
|
|||||||
snapGrid,
|
snapGrid,
|
||||||
onlyRenderVisibleNodes,
|
onlyRenderVisibleNodes,
|
||||||
isInteractive,
|
isInteractive,
|
||||||
|
selectNodesOnDrag,
|
||||||
}: ReactFlowProps) => {
|
}: ReactFlowProps) => {
|
||||||
const nodeTypesParsed = useMemo(() => createNodeTypes(nodeTypes), []);
|
const nodeTypesParsed = useMemo(() => createNodeTypes(nodeTypes), []);
|
||||||
const edgeTypesParsed = useMemo(() => createEdgeTypes(edgeTypes), []);
|
const edgeTypesParsed = useMemo(() => createEdgeTypes(edgeTypes), []);
|
||||||
@@ -95,6 +97,7 @@ const ReactFlow = ({
|
|||||||
snapGrid={snapGrid}
|
snapGrid={snapGrid}
|
||||||
onlyRenderVisibleNodes={onlyRenderVisibleNodes}
|
onlyRenderVisibleNodes={onlyRenderVisibleNodes}
|
||||||
isInteractive={isInteractive}
|
isInteractive={isInteractive}
|
||||||
|
selectNodesOnDrag={selectNodesOnDrag}
|
||||||
/>
|
/>
|
||||||
{onSelectionChange && <SelectionListener onSelectionChange={onSelectionChange} />}
|
{onSelectionChange && <SelectionListener onSelectionChange={onSelectionChange} />}
|
||||||
{children}
|
{children}
|
||||||
@@ -124,6 +127,7 @@ ReactFlow.defaultProps = {
|
|||||||
snapGrid: [16, 16],
|
snapGrid: [16, 16],
|
||||||
onlyRenderVisibleNodes: true,
|
onlyRenderVisibleNodes: true,
|
||||||
isInteractive: true,
|
isInteractive: true,
|
||||||
|
selectNodesOnDrag: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ReactFlow;
|
export default ReactFlow;
|
||||||
|
|||||||
@@ -123,6 +123,7 @@ export interface WrapNodeProps {
|
|||||||
xPos: number;
|
xPos: number;
|
||||||
yPos: number;
|
yPos: number;
|
||||||
isInteractive: boolean;
|
isInteractive: boolean;
|
||||||
|
selectNodesOnDrag: boolean;
|
||||||
onClick?: (node: Node) => void;
|
onClick?: (node: Node) => void;
|
||||||
onNodeDragStart?: (node: Node) => void;
|
onNodeDragStart?: (node: Node) => void;
|
||||||
onNodeDragStop?: (node: Node) => void;
|
onNodeDragStop?: (node: Node) => void;
|
||||||
|
|||||||
Reference in New Issue
Block a user