Merge pull request #400 from namack/add-event-handlers

Add event handlers
This commit is contained in:
Moritz
2020-08-04 21:06:38 +02:00
committed by GitHub
17 changed files with 64 additions and 61 deletions
+6 -6
View File
@@ -79,23 +79,23 @@ const BasicFlow = () => <ReactFlow elements={elements} />;
- `onlyRenderVisibleNodes`: default: `true` - `onlyRenderVisibleNodes`: default: `true`
#### Event Handlers #### Event Handlers
- `onElementClick(element: Node | Edge)`: called when user clicks node or edge click - `onElementClick(evt: MouseEvent, element: Node | Edge)`: called when user clicks node or edge click
- `onElementsRemove(elements: Elements)`: called when user removes node or edge - `onElementsRemove(elements: Elements)`: called when user removes node or edge
- `onNodeDragStart(node: Node)`: node drag start - `onNodeDragStart(evt: MouseEvent, node: Node)`: node drag start
- `onNodeDragStop(node: Node)`: node drag stop - `onNodeDragStop(evt: MouseEvent, node: Node)`: node drag stop
- `onNodeMouseEnter(evt: MouseEvent, node: Node)`: node mouse enter - `onNodeMouseEnter(evt: MouseEvent, node: Node)`: node mouse enter
- `onNodeMouseMove(evt: MouseEvent, node: Node)`: node mouse move - `onNodeMouseMove(evt: MouseEvent, node: Node)`: node mouse move
- `onNodeMouseLeave(evt: MouseEvent, node: Node)`: node mouse leave - `onNodeMouseLeave(evt: MouseEvent, node: Node)`: node mouse leave
- `onNodeContextMenu(evt: MouseEvent, node: Node)`: node context menu - `onNodeContextMenu(evt: MouseEvent, node: Node)`: node context menu
- `onConnect({ source, target })`: called when user connects two nodes - `onConnect({ source, target })`: called when user connects two nodes
- `onConnectStart({ nodeId, handleType })`: called when user starts to drag connection line - `onConnectStart(evt: MouseEvent, { nodeId, handleType })`: called when user starts to drag connection line
- `onConnectStop()`: called when user stops to drag connection line - `onConnectStop(evt: MouseEvent)`: called when user stops to drag connection line
- `onLoad(reactFlowInstance)`: called after flow is initialized - `onLoad(reactFlowInstance)`: called after flow is initialized
- `onMove()`: called when user is panning or zooming - `onMove()`: called when user is panning or zooming
- `onMoveStart()`: called when user starts panning or zooming - `onMoveStart()`: called when user starts panning or zooming
- `onMoveEnd()`: called when user ends panning or zooming - `onMoveEnd()`: called when user ends panning or zooming
- `onSelectionChange(elements: Elements)`: called when user selects one or multiple elements - `onSelectionChange(elements: Elements)`: called when user selects one or multiple elements
- `onPaneClick()`: called when user clicks directly on the canvas - `onPaneClick(evt: MouseEvent)`: called when user clicks directly on the canvas
#### Interaction #### Interaction
- `nodesDraggable`: default: `true`. This applies to all nodes. You can also change the behavior of a specific node with the `draggable` node option. - `nodesDraggable`: default: `true`. This applies to all nodes. You can also change the behavior of a specific node with the `draggable` node option.
+2 -2
View File
@@ -2,9 +2,9 @@ import React, { useState } from 'react';
import ReactFlow, { removeElements, addEdge, isNode, Background } from 'react-flow-renderer'; import ReactFlow, { removeElements, addEdge, isNode, Background } from 'react-flow-renderer';
const onNodeDragStop = (node) => console.log('drag stop', node); const onNodeDragStop = (evt, node) => console.log('drag stop', node);
const onLoad = (reactFlowInstance) => console.log('flow loaded:', reactFlowInstance); const onLoad = (reactFlowInstance) => console.log('flow loaded:', reactFlowInstance);
const onElementClick = (element) => console.log('click', element); const onElementClick = (evt, element) => console.log('click', element);
const initialElements = [ const initialElements = [
{ id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 } }, { id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 } },
+2 -2
View File
@@ -4,8 +4,8 @@ import ReactFlow, { isEdge, removeElements, addEdge, MiniMap, Controls } from 'r
import ColorSelectorNode from './ColorSelectorNode'; import ColorSelectorNode from './ColorSelectorNode';
const onNodeDragStop = (node) => console.log('drag stop', node); const onNodeDragStop = (evt, node) => console.log('drag stop', node);
const onElementClick = (element) => console.log('click', element); const onElementClick = (evt, element) => console.log('click', element);
const onLoad = (reactFlowInstance) => console.log('flow loaded:', reactFlowInstance); const onLoad = (reactFlowInstance) => console.log('flow loaded:', reactFlowInstance);
const initBgColor = '#f0e742'; const initBgColor = '#f0e742';
+2 -2
View File
@@ -4,8 +4,8 @@ import ReactFlow, { removeElements, addEdge, MiniMap, Controls, Background } fro
import CustomEdge from './CustomEdge'; import CustomEdge from './CustomEdge';
const onNodeDragStop = (node) => console.log('drag stop', node); const onNodeDragStop = (evt, node) => console.log('drag stop', node);
const onElementClick = (element) => console.log('click', element); const onElementClick = (evt, element) => console.log('click', element);
const onLoad = (reactFlowInstance) => reactFlowInstance.fitView(); const onLoad = (reactFlowInstance) => reactFlowInstance.fitView();
const initialElements = [ const initialElements = [
+2 -2
View File
@@ -2,9 +2,9 @@ import React, { useState } from 'react';
import ReactFlow, { removeElements, addEdge, MiniMap, Controls, Background } from 'react-flow-renderer'; import ReactFlow, { removeElements, addEdge, MiniMap, Controls, Background } from 'react-flow-renderer';
const onNodeDragStop = (node) => console.log('drag stop', node); const onNodeDragStop = (evt, node) => console.log('drag stop', node);
const onLoad = (reactFlowInstance) => console.log('flow loaded:', reactFlowInstance); const onLoad = (reactFlowInstance) => console.log('flow loaded:', reactFlowInstance);
const onElementClick = (element) => console.log('click', element); const onElementClick = (evt, element) => console.log('click', element);
const EmptyFlow = () => { const EmptyFlow = () => {
const [elements, setElements] = useState([]); const [elements, setElements] = useState([]);
+4 -4
View File
@@ -11,10 +11,10 @@ const initialElements = [
{ id: 'e1-3', source: '1', target: '3' }, { id: 'e1-3', source: '1', target: '3' },
]; ];
const onNodeDragStart = (node) => console.log('drag start', node); const onNodeDragStart = (evt, node) => console.log('drag start', node);
const onNodeDragStop = (node) => console.log('drag stop', node); const onNodeDragStop = (evt, node) => console.log('drag stop', node);
const onElementClick = (element) => console.log('click', element); const onElementClick = (evt, element) => console.log('click', evt, element);
const onPaneClick = () => console.log('onPaneClick'); const onPaneClick = (evt) => console.log('onPaneClick', evt);
const InteractionFlow = () => { const InteractionFlow = () => {
const [elements, setElements] = useState(initialElements); const [elements, setElements] = useState(initialElements);
+3 -3
View File
@@ -2,9 +2,9 @@ import React, { useState } from 'react';
import ReactFlow, { removeElements, addEdge, MiniMap, Controls, Background, isNode } from 'react-flow-renderer'; import ReactFlow, { removeElements, addEdge, MiniMap, Controls, Background, isNode } from 'react-flow-renderer';
const onNodeDragStart = (node) => console.log('drag start', node); const onNodeDragStart = (evt, node) => console.log('drag start', node);
const onNodeDragStop = (node) => console.log('drag stop', node); const onNodeDragStop = (evt, node) => console.log('drag stop', node);
const onElementClick = (element) => console.log(`${isNode(element) ? 'node' : 'edge'} click:`, element); const onElementClick = (evt, element) => console.log(`${isNode(element) ? 'node' : 'edge'} click:`, element);
const onSelectionChange = (elements) => console.log('selection change', elements); const onSelectionChange = (elements) => console.log('selection change', elements);
const onLoad = (reactFlowInstance) => { const onLoad = (reactFlowInstance) => {
console.log('flow loaded:', reactFlowInstance); console.log('flow loaded:', reactFlowInstance);
+1 -1
View File
@@ -5,7 +5,7 @@ import Sidebar from './Sidebar';
import './provider.css'; import './provider.css';
const onElementClick = (element) => console.log('click', element); const onElementClick = (evt, element) => console.log('click', element);
const initialElements = [ const initialElements = [
{ id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 } }, { id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 } },
+2 -2
View File
@@ -15,9 +15,9 @@ const isValidConnection = (connection) => connection.target === 'B';
const onLoad = (reactFlowInstance) => reactFlowInstance.fitView(); const onLoad = (reactFlowInstance) => reactFlowInstance.fitView();
const onConnectStart = ({ nodeId, handleType }) => console.log('on connect start', { nodeId, handleType }); const onConnectStart = (evt, { nodeId, handleType }) => console.log('on connect start', { nodeId, handleType });
const onConnectStop = () => console.log('on connect stop'); const onConnectStop = (evt) => console.log('on connect stop', evt);
const CustomInput = () => ( const CustomInput = () => (
<> <>
+3 -3
View File
@@ -14,7 +14,7 @@ interface EdgeWrapperProps {
labelShowBg?: boolean; labelShowBg?: boolean;
labelBgStyle: CSSProperties; labelBgStyle: CSSProperties;
className?: string; className?: string;
onClick?: (edge: Edge) => void; onClick?: (evt: React.MouseEvent, edge: Edge) => void;
animated?: boolean; animated?: boolean;
selected: boolean; selected: boolean;
elementsSelectable: boolean; elementsSelectable: boolean;
@@ -51,7 +51,7 @@ export default (EdgeComponent: ComponentType<EdgeCompProps>) => {
const edgeGroupStyle: CSSProperties = { const edgeGroupStyle: CSSProperties = {
pointerEvents: elementsSelectable ? 'all' : 'none', pointerEvents: elementsSelectable ? 'all' : 'none',
}; };
const onEdgeClick = (): void => { const onEdgeClick = (evt: React.MouseEvent<SVGGElement, MouseEvent>): void => {
if (!elementsSelectable) { if (!elementsSelectable) {
return; return;
} }
@@ -59,7 +59,7 @@ export default (EdgeComponent: ComponentType<EdgeCompProps>) => {
setSelectedElements({ id, source, target }); setSelectedElements({ id, source, target });
if (onClick) { if (onClick) {
onClick({ id, source, target, type }); onClick(evt, { id, source, target, type });
} }
}; };
+2 -2
View File
@@ -66,7 +66,7 @@ function onMouseDown(
setConnectionNodeId({ connectionNodeId: nodeId, connectionHandleType: handleType }); setConnectionNodeId({ connectionNodeId: nodeId, connectionHandleType: handleType });
if (onConnectStart) { if (onConnectStart) {
onConnectStart({ nodeId, handleType }); onConnectStart(evt, { nodeId, handleType });
} }
function resetRecentHandle(): void { function resetRecentHandle(): void {
@@ -142,7 +142,7 @@ function onMouseDown(
setConnectionNodeId({ connectionNodeId: null, connectionHandleType: null }); setConnectionNodeId({ connectionNodeId: null, connectionHandleType: null });
if (onConnectStop) { if (onConnectStop) {
onConnectStop(); onConnectStop(evt);
} }
document.removeEventListener('mousemove', onMouseMove); document.removeEventListener('mousemove', onMouseMove);
+11 -8
View File
@@ -44,7 +44,7 @@ interface OnDragStartParams {
transform: Transform; transform: Transform;
position: XYPosition; position: XYPosition;
setSelectedElements: (elms: Elements | Node | Edge) => void; setSelectedElements: (elms: Elements | Node | Edge) => void;
onNodeDragStart?: (node: Node) => void; onNodeDragStart?: (evt: MouseEvent, node: Node) => void;
} }
const onStart = ({ const onStart = ({
@@ -74,7 +74,7 @@ const onStart = ({
setOffset({ x: offsetX, y: offsetY }); setOffset({ x: offsetX, y: offsetY });
if (onNodeDragStart) { if (onNodeDragStart) {
onNodeDragStart(node); onNodeDragStart(evt as MouseEvent, node);
} }
if (selectNodesOnDrag && isSelectable) { if (selectNodesOnDrag && isSelectable) {
@@ -110,6 +110,7 @@ const onDrag = ({ evt, setDragging, id, offset, transform, updateNodePos }: OnDr
}; };
interface OnDragStopParams { interface OnDragStopParams {
evt: MouseEvent;
isDragging: boolean; isDragging: boolean;
setDragging: (isDragging: boolean) => void; setDragging: (isDragging: boolean) => void;
id: ElementId; id: ElementId;
@@ -119,11 +120,12 @@ interface OnDragStopParams {
selectNodesOnDrag: boolean; selectNodesOnDrag: boolean;
isSelectable: boolean; isSelectable: boolean;
setSelectedElements: (elms: Elements | Node | Edge) => void; setSelectedElements: (elms: Elements | Node | Edge) => void;
onNodeDragStop?: (node: Node) => void; onNodeDragStop?: (evt: MouseEvent, node: Node) => void;
onClick?: (node: Node) => void; onClick?: (evt: MouseEvent, node: Node) => void;
} }
const onStop = ({ const onStop = ({
evt,
id, id,
type, type,
position, position,
@@ -148,14 +150,14 @@ const onStop = ({
} }
if (onClick) { if (onClick) {
return onClick(node); return onClick(evt, node);
} }
} }
setDragging(false); setDragging(false);
if (onNodeDragStop) { if (onNodeDragStop) {
onNodeDragStop(node); onNodeDragStop(evt, node);
} }
}; };
@@ -240,7 +242,7 @@ export default (NodeComponent: ComponentType<NodeComponentProps>) => {
setSelectedElements({ id: node.id, type: node.type } as Node); setSelectedElements({ id: node.id, type: node.type } as Node);
if (onClick) { if (onClick) {
onClick(node); return (evt: MouseEvent) => onClick(evt, node);
} }
} }
@@ -298,8 +300,9 @@ export default (NodeComponent: ComponentType<NodeComponentProps>) => {
}) })
} }
onDrag={(evt) => onDrag({ evt: evt as MouseEvent, setDragging, id, offset, transform, updateNodePos })} onDrag={(evt) => onDrag({ evt: evt as MouseEvent, setDragging, id, offset, transform, updateNodePos })}
onStop={() => onStop={(evt) =>
onStop({ onStop({
evt: evt as MouseEvent,
onNodeDragStop, onNodeDragStop,
selectNodesOnDrag, selectNodesOnDrag,
isSelectable, isSelectable,
+1 -1
View File
@@ -10,7 +10,7 @@ interface EdgeRendererProps {
edgeTypes: any; edgeTypes: any;
connectionLineType: ConnectionLineType; connectionLineType: ConnectionLineType;
connectionLineStyle?: CSSProperties; connectionLineStyle?: CSSProperties;
onElementClick?: (element: Node | Edge) => void; onElementClick?: (evt: React.MouseEvent, element: Node | Edge) => void;
arrowHeadColor: string; arrowHeadColor: string;
markerEndId?: string; markerEndId?: string;
} }
+6 -6
View File
@@ -26,14 +26,14 @@ import {
export interface GraphViewProps { export interface GraphViewProps {
elements: Elements; elements: Elements;
onElementClick?: (element: Node | Edge) => void; onElementClick?: (evt: MouseEvent, element: Node | Edge) => void;
onElementsRemove?: (elements: Elements) => void; onElementsRemove?: (elements: Elements) => void;
onNodeMouseEnter?: (evt: MouseEvent, node: Node) => void; onNodeMouseEnter?: (evt: MouseEvent, node: Node) => void;
onNodeMouseMove?: (evt: MouseEvent, node: Node) => void; onNodeMouseMove?: (evt: MouseEvent, node: Node) => void;
onNodeMouseLeave?: (evt: MouseEvent, node: Node) => void; onNodeMouseLeave?: (evt: MouseEvent, node: Node) => void;
onNodeContextMenu?: (evt: MouseEvent, node: Node) => void; onNodeContextMenu?: (evt: MouseEvent, node: Node) => void;
onNodeDragStart?: (node: Node) => void; onNodeDragStart?: (evt: MouseEvent, node: Node) => void;
onNodeDragStop?: (node: Node) => void; onNodeDragStop?: (evt: MouseEvent, node: Node) => void;
onConnect?: (connection: Connection | Edge) => void; onConnect?: (connection: Connection | Edge) => void;
onConnectStart?: OnConnectStartFunc; onConnectStart?: OnConnectStartFunc;
onConnectStop?: () => void; onConnectStop?: () => void;
@@ -41,7 +41,7 @@ export interface GraphViewProps {
onMove?: (flowTransform?: FlowTransform) => void; onMove?: (flowTransform?: FlowTransform) => void;
onMoveStart?: (flowTransform?: FlowTransform) => void; onMoveStart?: (flowTransform?: FlowTransform) => void;
onMoveEnd?: (flowTransform?: FlowTransform) => void; onMoveEnd?: (flowTransform?: FlowTransform) => void;
onPaneClick?: () => void; onPaneClick?: (evt: MouseEvent) => void;
selectionKeyCode: number; selectionKeyCode: number;
nodeTypes: NodeTypesType; nodeTypes: NodeTypesType;
edgeTypes: EdgeTypesType; edgeTypes: EdgeTypesType;
@@ -125,8 +125,8 @@ const GraphView = ({
const fitView = useStoreActions((actions) => actions.fitView); const fitView = useStoreActions((actions) => actions.fitView);
const zoom = useStoreActions((actions) => actions.zoom); const zoom = useStoreActions((actions) => actions.zoom);
const onZoomPaneClick = useCallback(() => { const onZoomPaneClick = useCallback((evt: React.MouseEvent) => {
onPaneClick?.(); onPaneClick?.(evt);
unsetNodesSelection(); unsetNodesSelection();
}, [onPaneClick]); }, [onPaneClick]);
+3 -3
View File
@@ -7,13 +7,13 @@ import { Node, Transform, NodeTypesType, WrapNodeProps, Elements, Edge } from '.
interface NodeRendererProps { interface NodeRendererProps {
nodeTypes: NodeTypesType; nodeTypes: NodeTypesType;
selectNodesOnDrag: boolean; selectNodesOnDrag: boolean;
onElementClick?: (element: Node | Edge) => void; onElementClick?: (evt: MouseEvent, element: Node | Edge) => void;
onNodeMouseEnter?: (evt: MouseEvent, node: Node) => void; onNodeMouseEnter?: (evt: MouseEvent, node: Node) => void;
onNodeMouseMove?: (evt: MouseEvent, node: Node) => void; onNodeMouseMove?: (evt: MouseEvent, node: Node) => void;
onNodeMouseLeave?: (evt: MouseEvent, node: Node) => void; onNodeMouseLeave?: (evt: MouseEvent, node: Node) => void;
onNodeContextMenu?: (evt: MouseEvent, node: Node) => void; onNodeContextMenu?: (evt: MouseEvent, node: Node) => void;
onNodeDragStart?: (node: Node) => void; onNodeDragStart?: (evt: MouseEvent, node: Node) => void;
onNodeDragStop?: (node: Node) => void; onNodeDragStop?: (evt: MouseEvent, node: Node) => void;
onlyRenderVisibleNodes?: boolean; onlyRenderVisibleNodes?: boolean;
} }
+3 -3
View File
@@ -34,14 +34,14 @@ import '../../style.css';
export interface ReactFlowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onLoad'> { export interface ReactFlowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onLoad'> {
elements: Elements; elements: Elements;
onElementClick?: (element: Node | Edge) => void; onElementClick?: (evt: MouseEvent, element: Node | Edge) => void;
onElementsRemove?: (elements: Elements) => void; onElementsRemove?: (elements: Elements) => void;
onNodeMouseEnter?: (evt: MouseEvent, node: Node) => void; onNodeMouseEnter?: (evt: MouseEvent, node: Node) => void;
onNodeMouseMove?: (evt: MouseEvent, node: Node) => void; onNodeMouseMove?: (evt: MouseEvent, node: Node) => void;
onNodeMouseLeave?: (evt: MouseEvent, node: Node) => void; onNodeMouseLeave?: (evt: MouseEvent, node: Node) => void;
onNodeContextMenu?: (evt: MouseEvent, node: Node) => void; onNodeContextMenu?: (evt: MouseEvent, node: Node) => void;
onNodeDragStart?: (node: Node) => void; onNodeDragStart?: (evt: MouseEvent, node: Node) => void;
onNodeDragStop?: (node: Node) => void; onNodeDragStop?: (evt: MouseEvent, node: Node) => void;
onConnect?: (connection: Edge | Connection) => void; onConnect?: (connection: Edge | Connection) => void;
onConnectStart?: OnConnectStartFunc; onConnectStart?: OnConnectStartFunc;
onConnectStop?: () => void; onConnectStop?: () => void;
+11 -11
View File
@@ -1,4 +1,4 @@
import { CSSProperties, MouseEvent } from 'react'; import { CSSProperties, MouseEvent as ReactMouseEvent } from 'react';
export type ElementId = string; export type ElementId = string;
@@ -154,13 +154,13 @@ export interface WrapNodeProps {
isDraggable: boolean; isDraggable: boolean;
isConnectable: boolean; isConnectable: boolean;
selectNodesOnDrag: boolean; selectNodesOnDrag: boolean;
onClick?: (node: Node) => void; onClick?: (evt: ReactMouseEvent, node: Node) => void;
onMouseEnter?: (evt: MouseEvent, node: Node) => void; onMouseEnter?: (evt: ReactMouseEvent, node: Node) => void;
onMouseMove?: (evt: MouseEvent, node: Node) => void; onMouseMove?: (evt: ReactMouseEvent, node: Node) => void;
onMouseLeave?: (evt: MouseEvent, node: Node) => void; onMouseLeave?: (evt: ReactMouseEvent, node: Node) => void;
onContextMenu?: (evt: MouseEvent, node: Node) => void; onContextMenu?: (evt: ReactMouseEvent, node: Node) => void;
onNodeDragStart?: (node: Node) => void; onNodeDragStart?: (evt: ReactMouseEvent, node: Node) => void;
onNodeDragStop?: (node: Node) => void; onNodeDragStop?: (evt: ReactMouseEvent, node: Node) => void;
style?: CSSProperties; style?: CSSProperties;
className?: string; className?: string;
sourcePosition?: Position; sourcePosition?: Position;
@@ -202,8 +202,8 @@ export type OnConnectStartParams = {
nodeId: ElementId | null; nodeId: ElementId | null;
handleType: HandleType | null; handleType: HandleType | null;
}; };
export type OnConnectStartFunc = (params: OnConnectStartParams) => void; export type OnConnectStartFunc = (evt: ReactMouseEvent, params: OnConnectStartParams) => void;
export type OnConnectStopFunc = () => void; export type OnConnectStopFunc = (evt: MouseEvent) => void;
export type SetConnectionId = { export type SetConnectionId = {
connectionNodeId: ElementId | null; connectionNodeId: ElementId | null;
@@ -235,7 +235,7 @@ export interface EdgeCompProps {
labelStyle?: CSSProperties; labelStyle?: CSSProperties;
labelShowBg?: boolean; labelShowBg?: boolean;
labelBgStyle?: CSSProperties; labelBgStyle?: CSSProperties;
onClick?: (edge: Edge) => void; onClick?: (evt: ReactMouseEvent, edge: Edge) => void;
animated?: boolean; animated?: boolean;
selected?: boolean; selected?: boolean;
data?: any; data?: any;