feat(nodes): add selectNodesOnDrag prop type

This commit is contained in:
moklick
2020-05-25 18:13:12 +02:00
parent b6b3fded77
commit 02b4dc82df
7 changed files with 47 additions and 9 deletions
+1
View File
@@ -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
+1
View File
@@ -28,6 +28,7 @@ const HorizontalFlow = () => {
onElementsRemove={onElementsRemove} onElementsRemove={onElementsRemove}
onConnect={onConnect} onConnect={onConnect}
onLoad={onLoad} onLoad={onLoad}
selectNodesOnDrag={false}
/> />
); );
} }
+35 -9
View File
@@ -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"
+3
View File
@@ -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}
+2
View File
@@ -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}
/> />
); );
} }
+4
View File
@@ -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;
+1
View File
@@ -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;