refactor(onConnect): use onConnect handlers from store #2230

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