refactor(onConnect): use onConnect handlers from store #2230
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { MouseEvent as ReactMouseEvent, FC } from 'react';
|
import { FC, useCallback, useState } from 'react';
|
||||||
import ReactFlow, {
|
import ReactFlow, {
|
||||||
addEdge,
|
addEdge,
|
||||||
Handle,
|
Handle,
|
||||||
@@ -6,11 +6,11 @@ import ReactFlow, {
|
|||||||
Position,
|
Position,
|
||||||
Node,
|
Node,
|
||||||
Edge,
|
Edge,
|
||||||
OnConnectStartParams,
|
|
||||||
NodeProps,
|
NodeProps,
|
||||||
NodeTypes,
|
NodeTypes,
|
||||||
useNodesState,
|
useNodesState,
|
||||||
useEdgesState,
|
useEdgesState,
|
||||||
|
OnConnectStartParams,
|
||||||
} from 'react-flow-renderer';
|
} from 'react-flow-renderer';
|
||||||
|
|
||||||
import './validation.css';
|
import './validation.css';
|
||||||
@@ -23,10 +23,6 @@ const initialNodes: Node[] = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const isValidConnection = (connection: Connection) => connection.target === 'B';
|
const isValidConnection = (connection: Connection) => connection.target === 'B';
|
||||||
const onConnectStart = (_: ReactMouseEvent, { nodeId, handleType }: OnConnectStartParams) =>
|
|
||||||
console.log('on connect start', { nodeId, handleType });
|
|
||||||
const onConnectStop = (event: MouseEvent) => console.log('on connect stop', event);
|
|
||||||
const onConnectEnd = (event: MouseEvent) => console.log('on connect end', event);
|
|
||||||
|
|
||||||
const CustomInput: FC<NodeProps> = () => (
|
const CustomInput: FC<NodeProps> = () => (
|
||||||
<>
|
<>
|
||||||
@@ -49,13 +45,33 @@ const nodeTypes: NodeTypes = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const ValidationFlow = () => {
|
const ValidationFlow = () => {
|
||||||
|
const [value, setValue] = useState(0);
|
||||||
const [nodes, , onNodesChange] = useNodesState(initialNodes);
|
const [nodes, , onNodesChange] = useNodesState(initialNodes);
|
||||||
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
|
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
|
||||||
|
|
||||||
const onConnect = (params: Connection | Edge) => {
|
const onConnectStart = useCallback(
|
||||||
console.log('on connect', params);
|
(event: React.MouseEvent, params: OnConnectStartParams) => {
|
||||||
setEdges((eds) => addEdge(params, eds));
|
console.log('on connect start', params, event, value);
|
||||||
};
|
setValue(1);
|
||||||
|
},
|
||||||
|
[value]
|
||||||
|
);
|
||||||
|
|
||||||
|
const onConnect = useCallback(
|
||||||
|
(params: Connection | Edge) => {
|
||||||
|
console.log('on connect', params);
|
||||||
|
setEdges((eds) => addEdge(params, eds));
|
||||||
|
},
|
||||||
|
[setEdges]
|
||||||
|
);
|
||||||
|
|
||||||
|
const onConnectEnd = useCallback(
|
||||||
|
(event: MouseEvent) => {
|
||||||
|
console.log('on connect end', event, value);
|
||||||
|
setValue(0);
|
||||||
|
},
|
||||||
|
[value]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ReactFlow
|
<ReactFlow
|
||||||
@@ -68,7 +84,6 @@ const ValidationFlow = () => {
|
|||||||
className="validationflow"
|
className="validationflow"
|
||||||
nodeTypes={nodeTypes}
|
nodeTypes={nodeTypes}
|
||||||
onConnectStart={onConnectStart}
|
onConnectStart={onConnectStart}
|
||||||
onConnectStop={onConnectStop}
|
|
||||||
onConnectEnd={onConnectEnd}
|
onConnectEnd={onConnectEnd}
|
||||||
fitView
|
fitView
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,19 +1,13 @@
|
|||||||
import React, { memo, ComponentType, useState, useMemo } from 'react';
|
import React, { memo, ComponentType, useState, useMemo } from 'react';
|
||||||
import cc from 'classcat';
|
import cc from 'classcat';
|
||||||
import shallow from 'zustand/shallow';
|
|
||||||
|
|
||||||
import { useStore, useStoreApi } from '../../store';
|
import { useStoreApi } from '../../store';
|
||||||
import { EdgeProps, WrapEdgeProps, ReactFlowState, Connection } from '../../types';
|
import { EdgeProps, WrapEdgeProps, Connection } from '../../types';
|
||||||
import { handleMouseDown } from '../../components/Handle/handler';
|
import { handleMouseDown } from '../../components/Handle/handler';
|
||||||
import { EdgeAnchor } from './EdgeAnchor';
|
import { EdgeAnchor } from './EdgeAnchor';
|
||||||
import { getMarkerId } from '../../utils/graph';
|
import { getMarkerId } from '../../utils/graph';
|
||||||
import { getMouseHandler } from './utils';
|
import { getMouseHandler } from './utils';
|
||||||
|
|
||||||
const selector = (s: ReactFlowState) => ({
|
|
||||||
addSelectedEdges: s.addSelectedEdges,
|
|
||||||
connectionMode: s.connectionMode,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
||||||
const EdgeWrapper = ({
|
const EdgeWrapper = ({
|
||||||
id,
|
id,
|
||||||
@@ -56,11 +50,11 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
|||||||
rfId,
|
rfId,
|
||||||
}: WrapEdgeProps): JSX.Element | null => {
|
}: WrapEdgeProps): JSX.Element | null => {
|
||||||
const [updating, setUpdating] = useState<boolean>(false);
|
const [updating, setUpdating] = useState<boolean>(false);
|
||||||
const { addSelectedEdges, connectionMode } = useStore(selector, shallow);
|
|
||||||
const store = useStoreApi();
|
const store = useStoreApi();
|
||||||
|
|
||||||
const onEdgeClick = (event: React.MouseEvent<SVGGElement, MouseEvent>): void => {
|
const onEdgeClick = (event: React.MouseEvent<SVGGElement, MouseEvent>): void => {
|
||||||
const edge = store.getState().edges.find((e) => e.id === id)!;
|
const { edges, addSelectedEdges } = store.getState();
|
||||||
|
const edge = edges.find((e) => e.id === id)!;
|
||||||
|
|
||||||
if (elementsSelectable) {
|
if (elementsSelectable) {
|
||||||
store.setState({ nodesSelectionActive: false });
|
store.setState({ nodesSelectionActive: false });
|
||||||
@@ -86,7 +80,7 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
|||||||
|
|
||||||
onEdgeUpdateStart?.(event, edge, handleType);
|
onEdgeUpdateStart?.(event, edge, handleType);
|
||||||
|
|
||||||
const _onEdgeUpdate = onEdgeUpdateEnd
|
const _onEdgeUpdateEnd = onEdgeUpdateEnd
|
||||||
? (evt: MouseEvent): void => onEdgeUpdateEnd(evt, edge, handleType)
|
? (evt: MouseEvent): void => onEdgeUpdateEnd(evt, edge, handleType)
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
@@ -99,19 +93,18 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
handleMouseDown(
|
handleMouseDown({
|
||||||
event,
|
event,
|
||||||
handleId,
|
handleId,
|
||||||
nodeId,
|
nodeId,
|
||||||
store.setState,
|
onConnect: onConnectEdge,
|
||||||
onConnectEdge,
|
|
||||||
isTarget,
|
isTarget,
|
||||||
|
getState: store.getState,
|
||||||
|
setState: store.setState,
|
||||||
isValidConnection,
|
isValidConnection,
|
||||||
connectionMode,
|
elementEdgeUpdaterType: handleType,
|
||||||
handleType,
|
onEdgeUpdateEnd: _onEdgeUpdateEnd,
|
||||||
_onEdgeUpdate,
|
});
|
||||||
store.getState
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onEdgeUpdaterSourceMouseDown = (event: React.MouseEvent<SVGGElement, MouseEvent>): void =>
|
const onEdgeUpdaterSourceMouseDown = (event: React.MouseEvent<SVGGElement, MouseEvent>): void =>
|
||||||
|
|||||||
@@ -1,17 +1,8 @@
|
|||||||
import { MouseEvent as ReactMouseEvent } from 'react';
|
import { MouseEvent as ReactMouseEvent } from 'react';
|
||||||
import { SetState } from 'zustand';
|
import { GetState, SetState } from 'zustand';
|
||||||
|
|
||||||
import { getHostForElement } from '../../utils';
|
import { getHostForElement } from '../../utils';
|
||||||
import {
|
import { OnConnect, ConnectionMode, Connection, HandleType, ReactFlowState } from '../../types';
|
||||||
OnConnect,
|
|
||||||
OnConnectStart,
|
|
||||||
OnConnectStop,
|
|
||||||
OnConnectEnd,
|
|
||||||
ConnectionMode,
|
|
||||||
Connection,
|
|
||||||
HandleType,
|
|
||||||
ReactFlowState,
|
|
||||||
} from '../../types';
|
|
||||||
|
|
||||||
type ValidConnectionFunc = (connection: Connection) => boolean;
|
type ValidConnectionFunc = (connection: Connection) => boolean;
|
||||||
|
|
||||||
@@ -83,21 +74,29 @@ function resetRecentHandle(hoveredHandle: Element): void {
|
|||||||
hoveredHandle?.classList.remove('react-flow__handle-connecting');
|
hoveredHandle?.classList.remove('react-flow__handle-connecting');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function handleMouseDown(
|
export function handleMouseDown({
|
||||||
event: ReactMouseEvent,
|
event,
|
||||||
handleId: string | null,
|
handleId,
|
||||||
nodeId: string,
|
nodeId,
|
||||||
setState: SetState<ReactFlowState>,
|
onConnect,
|
||||||
onConnect: OnConnect,
|
isTarget,
|
||||||
isTarget: boolean,
|
getState,
|
||||||
isValidConnection: ValidConnectionFunc,
|
setState,
|
||||||
connectionMode: ConnectionMode,
|
isValidConnection,
|
||||||
elementEdgeUpdaterType?: HandleType,
|
elementEdgeUpdaterType,
|
||||||
onEdgeUpdateEnd?: (evt: MouseEvent) => void,
|
onEdgeUpdateEnd,
|
||||||
onConnectStart?: OnConnectStart,
|
}: {
|
||||||
onConnectStop?: OnConnectStop,
|
event: ReactMouseEvent;
|
||||||
onConnectEnd?: OnConnectEnd
|
handleId: string | null;
|
||||||
): void {
|
nodeId: string;
|
||||||
|
onConnect: OnConnect;
|
||||||
|
isTarget: boolean;
|
||||||
|
getState: GetState<ReactFlowState>;
|
||||||
|
setState: SetState<ReactFlowState>;
|
||||||
|
isValidConnection: ValidConnectionFunc;
|
||||||
|
elementEdgeUpdaterType?: HandleType;
|
||||||
|
onEdgeUpdateEnd?: (evt: MouseEvent) => void;
|
||||||
|
}): void {
|
||||||
const reactFlowNode = (event.target as Element).closest('.react-flow');
|
const reactFlowNode = (event.target as Element).closest('.react-flow');
|
||||||
// when react-flow is used inside a shadow root we can't use document
|
// when react-flow is used inside a shadow root we can't use document
|
||||||
const doc = getHostForElement(event.target as HTMLElement);
|
const doc = getHostForElement(event.target as HTMLElement);
|
||||||
@@ -114,6 +113,7 @@ export function handleMouseDown(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { onConnectStart, connectionMode } = getState();
|
||||||
const handleType = elementEdgeUpdaterType ? elementEdgeUpdaterType : elementBelowIsTarget ? 'target' : 'source';
|
const handleType = elementEdgeUpdaterType ? elementEdgeUpdaterType : elementBelowIsTarget ? 'target' : 'source';
|
||||||
const containerBounds = reactFlowNode.getBoundingClientRect();
|
const containerBounds = reactFlowNode.getBoundingClientRect();
|
||||||
let recentHoveredHandle: Element;
|
let recentHoveredHandle: Element;
|
||||||
@@ -160,6 +160,7 @@ export function handleMouseDown(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onMouseUp(event: MouseEvent) {
|
function onMouseUp(event: MouseEvent) {
|
||||||
|
const { onConnectStop, onConnectEnd } = getState();
|
||||||
const { connection, isValid } = checkElementBelowIsValid(
|
const { connection, isValid } = checkElementBelowIsValid(
|
||||||
event,
|
event,
|
||||||
connectionMode,
|
connectionMode,
|
||||||
|
|||||||
@@ -14,14 +14,6 @@ const alwaysValid = () => true;
|
|||||||
export type HandleComponentProps = HandleProps & Omit<HTMLAttributes<HTMLDivElement>, 'id'>;
|
export type HandleComponentProps = HandleProps & Omit<HTMLAttributes<HTMLDivElement>, 'id'>;
|
||||||
|
|
||||||
const selector = (s: ReactFlowState) => ({
|
const selector = (s: ReactFlowState) => ({
|
||||||
onConnectAction: s.onConnect,
|
|
||||||
onConnectStart: s.onConnectStart,
|
|
||||||
onConnectStop: s.onConnectStop,
|
|
||||||
onConnectEnd: s.onConnectEnd,
|
|
||||||
onClickConnectStart: s.onClickConnectStart,
|
|
||||||
onClickConnectStop: s.onClickConnectStop,
|
|
||||||
onClickConnectEnd: s.onClickConnectEnd,
|
|
||||||
connectionMode: s.connectionMode,
|
|
||||||
connectionStartHandle: s.connectionStartHandle,
|
connectionStartHandle: s.connectionStartHandle,
|
||||||
connectOnClick: s.connectOnClick,
|
connectOnClick: s.connectOnClick,
|
||||||
hasDefaultEdges: s.hasDefaultEdges,
|
hasDefaultEdges: s.hasDefaultEdges,
|
||||||
@@ -45,25 +37,13 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
|||||||
) => {
|
) => {
|
||||||
const store = useStoreApi();
|
const store = useStoreApi();
|
||||||
const nodeId = useContext(NodeIdContext) as string;
|
const nodeId = useContext(NodeIdContext) as string;
|
||||||
const {
|
const { connectionStartHandle, connectOnClick, hasDefaultEdges } = useStore(selector, shallow);
|
||||||
onConnectAction,
|
|
||||||
onConnectStart,
|
|
||||||
onConnectStop,
|
|
||||||
onConnectEnd,
|
|
||||||
onClickConnectStart,
|
|
||||||
onClickConnectStop,
|
|
||||||
onClickConnectEnd,
|
|
||||||
connectionMode,
|
|
||||||
connectionStartHandle,
|
|
||||||
connectOnClick,
|
|
||||||
hasDefaultEdges,
|
|
||||||
} = useStore(selector, shallow);
|
|
||||||
|
|
||||||
const handleId = id || null;
|
const handleId = id || null;
|
||||||
const isTarget = type === 'target';
|
const isTarget = type === 'target';
|
||||||
|
|
||||||
const onConnectExtended = (params: Connection) => {
|
const onConnectExtended = (params: Connection) => {
|
||||||
const { defaultEdgeOptions } = store.getState();
|
const { defaultEdgeOptions, onConnect: onConnectAction } = store.getState();
|
||||||
|
|
||||||
const edgeParams = {
|
const edgeParams = {
|
||||||
...defaultEdgeOptions,
|
...defaultEdgeOptions,
|
||||||
@@ -80,26 +60,22 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
|||||||
|
|
||||||
const onMouseDownHandler = (event: React.MouseEvent<HTMLDivElement>) => {
|
const onMouseDownHandler = (event: React.MouseEvent<HTMLDivElement>) => {
|
||||||
if (event.button === 0) {
|
if (event.button === 0) {
|
||||||
handleMouseDown(
|
handleMouseDown({
|
||||||
event,
|
event,
|
||||||
handleId,
|
handleId,
|
||||||
nodeId,
|
nodeId,
|
||||||
store.setState,
|
onConnect: onConnectExtended,
|
||||||
onConnectExtended,
|
|
||||||
isTarget,
|
isTarget,
|
||||||
|
getState: store.getState,
|
||||||
|
setState: store.setState,
|
||||||
isValidConnection,
|
isValidConnection,
|
||||||
connectionMode,
|
});
|
||||||
undefined,
|
|
||||||
undefined,
|
|
||||||
onConnectStart,
|
|
||||||
onConnectStop,
|
|
||||||
onConnectEnd
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
onMouseDown?.(event);
|
onMouseDown?.(event);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onClick = (event: React.MouseEvent) => {
|
const onClick = (event: React.MouseEvent) => {
|
||||||
|
const { onClickConnectStart, onClickConnectStop, onClickConnectEnd, connectionMode } = store.getState();
|
||||||
if (!connectionStartHandle) {
|
if (!connectionStartHandle) {
|
||||||
onClickConnectStart?.(event, { nodeId, handleId, handleType: type });
|
onClickConnectStart?.(event, { nodeId, handleId, handleType: type });
|
||||||
store.setState({ connectionStartHandle: { nodeId, type, handleId } });
|
store.setState({ connectionStartHandle: { nodeId, type, handleId } });
|
||||||
|
|||||||
Reference in New Issue
Block a user