refactor(store): use store.setState directly instead of actions
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import React, { memo, useCallback, HTMLAttributes, FC, useEffect, useState } from 'react';
|
import React, { memo, useCallback, HTMLAttributes, FC, useEffect, useState } from 'react';
|
||||||
import cc from 'classcat';
|
import cc from 'classcat';
|
||||||
|
|
||||||
import { useStore } from '../../store';
|
import { useStore, useStoreApi } from '../../store';
|
||||||
|
|
||||||
import PlusIcon from '../../../assets/icons/plus.svg';
|
import PlusIcon from '../../../assets/icons/plus.svg';
|
||||||
import MinusIcon from '../../../assets/icons/minus.svg';
|
import MinusIcon from '../../../assets/icons/minus.svg';
|
||||||
@@ -31,7 +31,6 @@ export const ControlButton: FC<ControlButtonProps> = ({ children, className, ...
|
|||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|
||||||
const setInteractiveSelector = (s: ReactFlowState) => s.setInteractive;
|
|
||||||
const isInteractiveSelector = (s: ReactFlowState) => s.nodesDraggable && s.nodesConnectable && s.elementsSelectable;
|
const isInteractiveSelector = (s: ReactFlowState) => s.nodesDraggable && s.nodesConnectable && s.elementsSelectable;
|
||||||
|
|
||||||
const Controls: FC<ControlProps> = ({
|
const Controls: FC<ControlProps> = ({
|
||||||
@@ -47,8 +46,8 @@ const Controls: FC<ControlProps> = ({
|
|||||||
className,
|
className,
|
||||||
children,
|
children,
|
||||||
}) => {
|
}) => {
|
||||||
|
const store = useStoreApi();
|
||||||
const [isVisible, setIsVisible] = useState<boolean>(false);
|
const [isVisible, setIsVisible] = useState<boolean>(false);
|
||||||
const setInteractive = useStore(setInteractiveSelector);
|
|
||||||
const isInteractive = useStore(isInteractiveSelector);
|
const isInteractive = useStore(isInteractiveSelector);
|
||||||
const { zoomIn, zoomOut, fitView } = useZoomPanHelper();
|
const { zoomIn, zoomOut, fitView } = useZoomPanHelper();
|
||||||
|
|
||||||
@@ -70,9 +69,14 @@ const Controls: FC<ControlProps> = ({
|
|||||||
}, [fitView, fitViewParams, onFitView]);
|
}, [fitView, fitViewParams, onFitView]);
|
||||||
|
|
||||||
const onInteractiveChangeHandler = useCallback(() => {
|
const onInteractiveChangeHandler = useCallback(() => {
|
||||||
setInteractive?.(!isInteractive);
|
store.setState({
|
||||||
|
nodesDraggable: !isInteractive,
|
||||||
|
nodesConnectable: !isInteractive,
|
||||||
|
elementsSelectable: !isInteractive,
|
||||||
|
});
|
||||||
|
|
||||||
onInteractiveChange?.(!isInteractive);
|
onInteractiveChange?.(!isInteractive);
|
||||||
}, [isInteractive, setInteractive, onInteractiveChange]);
|
}, [isInteractive, onInteractiveChange]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setIsVisible(true);
|
setIsVisible(true);
|
||||||
|
|||||||
@@ -10,9 +10,6 @@ import { getMarkerId } from '../../utils/graph';
|
|||||||
|
|
||||||
const selector = (s: ReactFlowState) => ({
|
const selector = (s: ReactFlowState) => ({
|
||||||
addSelectedEdges: s.addSelectedEdges,
|
addSelectedEdges: s.addSelectedEdges,
|
||||||
setConnectionNodeId: s.setConnectionNodeId,
|
|
||||||
setNodesSelectionActive: s.setNodesSelectionActive,
|
|
||||||
setPosition: s.setConnectionPosition,
|
|
||||||
connectionMode: s.connectionMode,
|
connectionMode: s.connectionMode,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -57,10 +54,7 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
|||||||
markerStart,
|
markerStart,
|
||||||
}: WrapEdgeProps): JSX.Element | null => {
|
}: WrapEdgeProps): JSX.Element | null => {
|
||||||
const store = useStoreApi();
|
const store = useStoreApi();
|
||||||
const { addSelectedEdges, setConnectionNodeId, setNodesSelectionActive, setPosition, connectionMode } = useStore(
|
const { addSelectedEdges, connectionMode } = useStore(selector, shallow);
|
||||||
selector,
|
|
||||||
shallow
|
|
||||||
);
|
|
||||||
|
|
||||||
const [updating, setUpdating] = useState<boolean>(false);
|
const [updating, setUpdating] = useState<boolean>(false);
|
||||||
|
|
||||||
@@ -99,7 +93,7 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
|||||||
const onEdgeClick = useCallback(
|
const onEdgeClick = useCallback(
|
||||||
(event: React.MouseEvent<SVGGElement, MouseEvent>): void => {
|
(event: React.MouseEvent<SVGGElement, MouseEvent>): void => {
|
||||||
if (elementsSelectable) {
|
if (elementsSelectable) {
|
||||||
setNodesSelectionActive(false);
|
store.setState({ nodesSelectionActive: false });
|
||||||
addSelectedEdges([edgeElement.id]);
|
addSelectedEdges([edgeElement.id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,8 +163,7 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
|||||||
event,
|
event,
|
||||||
handleId,
|
handleId,
|
||||||
nodeId,
|
nodeId,
|
||||||
setConnectionNodeId,
|
store.setState,
|
||||||
setPosition,
|
|
||||||
onConnectEdge,
|
onConnectEdge,
|
||||||
isTarget,
|
isTarget,
|
||||||
isValidConnection,
|
isValidConnection,
|
||||||
@@ -180,18 +173,7 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
|||||||
store.getState
|
store.getState
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
[
|
[id, source, target, type, sourceHandleId, targetHandleId, edgeElement, onEdgeUpdate]
|
||||||
id,
|
|
||||||
source,
|
|
||||||
target,
|
|
||||||
type,
|
|
||||||
sourceHandleId,
|
|
||||||
targetHandleId,
|
|
||||||
setConnectionNodeId,
|
|
||||||
setPosition,
|
|
||||||
edgeElement,
|
|
||||||
onEdgeUpdate,
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const onEdgeUpdaterSourceMouseDown = useCallback(
|
const onEdgeUpdaterSourceMouseDown = useCallback(
|
||||||
|
|||||||
@@ -1,23 +1,19 @@
|
|||||||
import { MouseEvent as ReactMouseEvent } from 'react';
|
import { MouseEvent as ReactMouseEvent } from 'react';
|
||||||
|
import { SetState } from 'zustand';
|
||||||
|
|
||||||
import { getHostForElement } from '../../utils';
|
import { getHostForElement } from '../../utils';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
OnConnect,
|
OnConnect,
|
||||||
OnConnectStart,
|
OnConnectStart,
|
||||||
OnConnectStop,
|
OnConnectStop,
|
||||||
OnConnectEnd,
|
OnConnectEnd,
|
||||||
ConnectionMode,
|
ConnectionMode,
|
||||||
SetConnectionId,
|
|
||||||
Connection,
|
Connection,
|
||||||
HandleType,
|
HandleType,
|
||||||
XYPosition,
|
ReactFlowState,
|
||||||
} from '../../types';
|
} from '../../types';
|
||||||
|
|
||||||
type ValidConnectionFunc = (connection: Connection) => boolean;
|
type ValidConnectionFunc = (connection: Connection) => boolean;
|
||||||
export type SetSourceIdFunc = (params: SetConnectionId) => void;
|
|
||||||
|
|
||||||
export type SetPosition = (pos: XYPosition) => void;
|
|
||||||
|
|
||||||
type Result = {
|
type Result = {
|
||||||
elementBelow: Element | null;
|
elementBelow: Element | null;
|
||||||
@@ -90,8 +86,7 @@ export function onMouseDown(
|
|||||||
event: ReactMouseEvent,
|
event: ReactMouseEvent,
|
||||||
handleId: string | null,
|
handleId: string | null,
|
||||||
nodeId: string,
|
nodeId: string,
|
||||||
setConnectionNodeId: SetSourceIdFunc,
|
setState: SetState<ReactFlowState>,
|
||||||
setPosition: SetPosition,
|
|
||||||
onConnect: OnConnect,
|
onConnect: OnConnect,
|
||||||
isTarget: boolean,
|
isTarget: boolean,
|
||||||
isValidConnection: ValidConnectionFunc,
|
isValidConnection: ValidConnectionFunc,
|
||||||
@@ -122,18 +117,24 @@ export function onMouseDown(
|
|||||||
const containerBounds = reactFlowNode.getBoundingClientRect();
|
const containerBounds = reactFlowNode.getBoundingClientRect();
|
||||||
let recentHoveredHandle: Element;
|
let recentHoveredHandle: Element;
|
||||||
|
|
||||||
setPosition({
|
setState({
|
||||||
x: event.clientX - containerBounds.left,
|
connectionPosition: {
|
||||||
y: event.clientY - containerBounds.top,
|
x: event.clientX - containerBounds.left,
|
||||||
|
y: event.clientY - containerBounds.top,
|
||||||
|
},
|
||||||
|
connectionNodeId: nodeId,
|
||||||
|
connectionHandleId: handleId,
|
||||||
|
connectionHandleType: handleType,
|
||||||
});
|
});
|
||||||
|
|
||||||
setConnectionNodeId({ connectionNodeId: nodeId, connectionHandleId: handleId, connectionHandleType: handleType });
|
|
||||||
onConnectStart?.(event, { nodeId, handleId, handleType });
|
onConnectStart?.(event, { nodeId, handleId, handleType });
|
||||||
|
|
||||||
function onMouseMove(event: MouseEvent) {
|
function onMouseMove(event: MouseEvent) {
|
||||||
setPosition({
|
setState({
|
||||||
x: event.clientX - containerBounds.left,
|
connectionPosition: {
|
||||||
y: event.clientY - containerBounds.top,
|
x: event.clientX - containerBounds.left,
|
||||||
|
y: event.clientY - containerBounds.top,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { connection, elementBelow, isValid, isHoveringHandle } = checkElementBelowIsValid(
|
const { connection, elementBelow, isValid, isHoveringHandle } = checkElementBelowIsValid(
|
||||||
@@ -183,7 +184,11 @@ export function onMouseDown(
|
|||||||
}
|
}
|
||||||
|
|
||||||
resetRecentHandle(recentHoveredHandle);
|
resetRecentHandle(recentHoveredHandle);
|
||||||
setConnectionNodeId({ connectionNodeId: null, connectionHandleId: null, connectionHandleType: null });
|
setState({
|
||||||
|
connectionNodeId: null,
|
||||||
|
connectionHandleId: null,
|
||||||
|
connectionHandleType: null,
|
||||||
|
});
|
||||||
|
|
||||||
doc.removeEventListener('mousemove', onMouseMove as EventListenerOrEventListenerObject);
|
doc.removeEventListener('mousemove', onMouseMove as EventListenerOrEventListenerObject);
|
||||||
doc.removeEventListener('mouseup', onMouseUp as EventListenerOrEventListenerObject);
|
doc.removeEventListener('mouseup', onMouseUp as EventListenerOrEventListenerObject);
|
||||||
|
|||||||
@@ -2,18 +2,16 @@ import React, { memo, useContext, useCallback, HTMLAttributes, forwardRef } from
|
|||||||
import cc from 'classcat';
|
import cc from 'classcat';
|
||||||
import shallow from 'zustand/shallow';
|
import shallow from 'zustand/shallow';
|
||||||
|
|
||||||
import { useStore } from '../../store';
|
import { useStore, useStoreApi } from '../../store';
|
||||||
import NodeIdContext from '../../contexts/NodeIdContext';
|
import NodeIdContext from '../../contexts/NodeIdContext';
|
||||||
import { HandleProps, Connection, ReactFlowState, Position } from '../../types';
|
import { HandleProps, Connection, ReactFlowState, Position } from '../../types';
|
||||||
import { onMouseDown, SetSourceIdFunc, SetPosition } from './handler';
|
import { onMouseDown } from './handler';
|
||||||
|
|
||||||
const alwaysValid = () => true;
|
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) => ({
|
||||||
setPosition: s.setConnectionPosition,
|
|
||||||
setConnectionNodeId: s.setConnectionNodeId,
|
|
||||||
onConnectAction: s.onConnect,
|
onConnectAction: s.onConnect,
|
||||||
onConnectStart: s.onConnectStart,
|
onConnectStart: s.onConnectStart,
|
||||||
onConnectStop: s.onConnectStop,
|
onConnectStop: s.onConnectStop,
|
||||||
@@ -36,16 +34,12 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
|||||||
},
|
},
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
|
const store = useStoreApi();
|
||||||
const nodeId = useContext(NodeIdContext) as string;
|
const nodeId = useContext(NodeIdContext) as string;
|
||||||
const {
|
const { onConnectAction, onConnectStart, onConnectStop, onConnectEnd, connectionMode } = useStore(
|
||||||
setPosition,
|
selector,
|
||||||
setConnectionNodeId,
|
shallow
|
||||||
onConnectAction,
|
);
|
||||||
onConnectStart,
|
|
||||||
onConnectStop,
|
|
||||||
onConnectEnd,
|
|
||||||
connectionMode,
|
|
||||||
} = useStore(selector, shallow);
|
|
||||||
|
|
||||||
const handleId = id || null;
|
const handleId = id || null;
|
||||||
const isTarget = type === 'target';
|
const isTarget = type === 'target';
|
||||||
@@ -64,8 +58,7 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
|||||||
event,
|
event,
|
||||||
handleId,
|
handleId,
|
||||||
nodeId,
|
nodeId,
|
||||||
setConnectionNodeId as unknown as SetSourceIdFunc,
|
store.setState,
|
||||||
setPosition as unknown as SetPosition,
|
|
||||||
onConnectExtended,
|
onConnectExtended,
|
||||||
isTarget,
|
isTarget,
|
||||||
isValidConnection,
|
isValidConnection,
|
||||||
@@ -80,8 +73,6 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
|||||||
[
|
[
|
||||||
handleId,
|
handleId,
|
||||||
nodeId,
|
nodeId,
|
||||||
setConnectionNodeId,
|
|
||||||
setPosition,
|
|
||||||
onConnectExtended,
|
onConnectExtended,
|
||||||
isTarget,
|
isTarget,
|
||||||
isValidConnection,
|
isValidConnection,
|
||||||
|
|||||||
@@ -3,13 +3,12 @@ import { DraggableCore, DraggableData, DraggableEvent } from 'react-draggable';
|
|||||||
import cc from 'classcat';
|
import cc from 'classcat';
|
||||||
import shallow from 'zustand/shallow';
|
import shallow from 'zustand/shallow';
|
||||||
|
|
||||||
import { useStore } from '../../store';
|
import { useStore, useStoreApi } from '../../store';
|
||||||
import { Provider } from '../../contexts/NodeIdContext';
|
import { Provider } from '../../contexts/NodeIdContext';
|
||||||
import { NodeProps, WrapNodeProps, ReactFlowState } from '../../types';
|
import { NodeProps, WrapNodeProps, ReactFlowState } from '../../types';
|
||||||
|
|
||||||
const selector = (s: ReactFlowState) => ({
|
const selector = (s: ReactFlowState) => ({
|
||||||
addSelectedNodes: s.addSelectedNodes,
|
addSelectedNodes: s.addSelectedNodes,
|
||||||
setNodesSelectionActive: s.setNodesSelectionActive,
|
|
||||||
updateNodePosition: s.updateNodePosition,
|
updateNodePosition: s.updateNodePosition,
|
||||||
unselectNodesAndEdges: s.unselectNodesAndEdges,
|
unselectNodesAndEdges: s.unselectNodesAndEdges,
|
||||||
});
|
});
|
||||||
@@ -52,10 +51,8 @@ export default (NodeComponent: ComponentType<NodeProps>) => {
|
|||||||
noPanClassName,
|
noPanClassName,
|
||||||
noDragClassName,
|
noDragClassName,
|
||||||
}: WrapNodeProps) => {
|
}: WrapNodeProps) => {
|
||||||
const { addSelectedNodes, unselectNodesAndEdges, setNodesSelectionActive, updateNodePosition } = useStore(
|
const store = useStoreApi();
|
||||||
selector,
|
const { addSelectedNodes, unselectNodesAndEdges, updateNodePosition } = useStore(selector, shallow);
|
||||||
shallow
|
|
||||||
);
|
|
||||||
const nodeElement = useRef<HTMLDivElement>(null);
|
const nodeElement = useRef<HTMLDivElement>(null);
|
||||||
const hasPointerEvents = isSelectable || isDraggable || onClick || onMouseEnter || onMouseMove || onMouseLeave;
|
const hasPointerEvents = isSelectable || isDraggable || onClick || onMouseEnter || onMouseMove || onMouseLeave;
|
||||||
const nodeStyle: CSSProperties = useMemo(
|
const nodeStyle: CSSProperties = useMemo(
|
||||||
@@ -109,7 +106,7 @@ export default (NodeComponent: ComponentType<NodeProps>) => {
|
|||||||
(event: MouseEvent) => {
|
(event: MouseEvent) => {
|
||||||
if (!isDraggable) {
|
if (!isDraggable) {
|
||||||
if (isSelectable) {
|
if (isSelectable) {
|
||||||
setNodesSelectionActive(false);
|
store.setState({ nodesSelectionActive: false });
|
||||||
|
|
||||||
if (!selected) {
|
if (!selected) {
|
||||||
addSelectedNodes([node.id]);
|
addSelectedNodes([node.id]);
|
||||||
@@ -127,14 +124,14 @@ export default (NodeComponent: ComponentType<NodeProps>) => {
|
|||||||
onNodeDragStart?.(event as MouseEvent, node);
|
onNodeDragStart?.(event as MouseEvent, node);
|
||||||
|
|
||||||
if (selectNodesOnDrag && isSelectable) {
|
if (selectNodesOnDrag && isSelectable) {
|
||||||
setNodesSelectionActive(false);
|
store.setState({ nodesSelectionActive: false });
|
||||||
|
|
||||||
if (!selected) {
|
if (!selected) {
|
||||||
addSelectedNodes([node.id]);
|
addSelectedNodes([node.id]);
|
||||||
}
|
}
|
||||||
} else if (!selectNodesOnDrag && !selected && isSelectable) {
|
} else if (!selectNodesOnDrag && !selected && isSelectable) {
|
||||||
unselectNodesAndEdges();
|
unselectNodesAndEdges();
|
||||||
setNodesSelectionActive(false);
|
store.setState({ nodesSelectionActive: false });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[node, selected, selectNodesOnDrag, isSelectable, onNodeDragStart]
|
[node, selected, selectNodesOnDrag, isSelectable, onNodeDragStart]
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
import { SetState } from 'zustand';
|
||||||
import shallow from 'zustand/shallow';
|
import shallow from 'zustand/shallow';
|
||||||
|
|
||||||
import { useStore } from '../../store';
|
import { useStore, useStoreApi } from '../../store';
|
||||||
import {
|
import {
|
||||||
Node,
|
Node,
|
||||||
Edge,
|
Edge,
|
||||||
@@ -42,24 +43,11 @@ interface StoreUpdaterProps {
|
|||||||
const selector = (s: ReactFlowState) => ({
|
const selector = (s: ReactFlowState) => ({
|
||||||
setNodes: s.setNodes,
|
setNodes: s.setNodes,
|
||||||
setEdges: s.setEdges,
|
setEdges: s.setEdges,
|
||||||
setOnConnect: s.setOnConnect,
|
|
||||||
setOnConnectStart: s.setOnConnectStart,
|
|
||||||
setOnConnectStop: s.setOnConnectStop,
|
|
||||||
setOnConnectEnd: s.setOnConnectEnd,
|
|
||||||
setSnapGrid: s.setSnapGrid,
|
|
||||||
setSnapToGrid: s.setSnapToGrid,
|
|
||||||
setNodesDraggable: s.setNodesDraggable,
|
|
||||||
setNodesConnectable: s.setNodesConnectable,
|
|
||||||
setElementsSelectable: s.setElementsSelectable,
|
|
||||||
setMinZoom: s.setMinZoom,
|
setMinZoom: s.setMinZoom,
|
||||||
setMaxZoom: s.setMaxZoom,
|
setMaxZoom: s.setMaxZoom,
|
||||||
setTranslateExtent: s.setTranslateExtent,
|
setTranslateExtent: s.setTranslateExtent,
|
||||||
setNodeExtent: s.setNodeExtent,
|
setNodeExtent: s.setNodeExtent,
|
||||||
setConnectionMode: s.setConnectionMode,
|
|
||||||
setOnNodesChange: s.setOnNodesChange,
|
|
||||||
setOnEdgesChange: s.setOnEdgesChange,
|
|
||||||
reset: s.reset,
|
reset: s.reset,
|
||||||
setFitViewOnInit: s.setFitViewOnInit,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function useStoreUpdater<T>(value: T | undefined, setStoreState: (param: T) => void) {
|
function useStoreUpdater<T>(value: T | undefined, setStoreState: (param: T) => void) {
|
||||||
@@ -70,6 +58,15 @@ function useStoreUpdater<T>(value: T | undefined, setStoreState: (param: T) => v
|
|||||||
}, [value]);
|
}, [value]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function useDirectStoreUpdater(key: keyof ReactFlowState, value: any, setState: SetState<ReactFlowState>) {
|
||||||
|
useEffect(() => {
|
||||||
|
if (typeof value !== 'undefined') {
|
||||||
|
// @ts-ignore
|
||||||
|
setState({ [key]: value });
|
||||||
|
}
|
||||||
|
}, [value]);
|
||||||
|
}
|
||||||
|
|
||||||
const StoreUpdater = ({
|
const StoreUpdater = ({
|
||||||
nodes,
|
nodes,
|
||||||
edges,
|
edges,
|
||||||
@@ -91,28 +88,11 @@ const StoreUpdater = ({
|
|||||||
translateExtent,
|
translateExtent,
|
||||||
fitViewOnInit,
|
fitViewOnInit,
|
||||||
}: StoreUpdaterProps) => {
|
}: StoreUpdaterProps) => {
|
||||||
const {
|
const { setNodes, setEdges, setMinZoom, setMaxZoom, setTranslateExtent, setNodeExtent, reset } = useStore(
|
||||||
setNodes,
|
selector,
|
||||||
setEdges,
|
shallow
|
||||||
setOnConnect,
|
);
|
||||||
setOnConnectStart,
|
const store = useStoreApi();
|
||||||
setOnConnectStop,
|
|
||||||
setOnConnectEnd,
|
|
||||||
setNodesDraggable,
|
|
||||||
setSnapGrid,
|
|
||||||
setSnapToGrid,
|
|
||||||
setNodesConnectable,
|
|
||||||
setElementsSelectable,
|
|
||||||
setMinZoom,
|
|
||||||
setMaxZoom,
|
|
||||||
setTranslateExtent,
|
|
||||||
setNodeExtent,
|
|
||||||
setOnNodesChange,
|
|
||||||
setOnEdgesChange,
|
|
||||||
setConnectionMode,
|
|
||||||
reset,
|
|
||||||
setFitViewOnInit,
|
|
||||||
} = useStore(selector, shallow);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
@@ -122,24 +102,24 @@ const StoreUpdater = ({
|
|||||||
|
|
||||||
useStoreUpdater<Node[]>(nodes, setNodes);
|
useStoreUpdater<Node[]>(nodes, setNodes);
|
||||||
useStoreUpdater<Edge[]>(edges, setEdges);
|
useStoreUpdater<Edge[]>(edges, setEdges);
|
||||||
useStoreUpdater<OnConnect>(onConnect, setOnConnect);
|
|
||||||
useStoreUpdater<OnConnect>(onConnect, setOnConnect);
|
|
||||||
useStoreUpdater<OnConnectStart>(onConnectStart, setOnConnectStart);
|
|
||||||
useStoreUpdater<OnConnectStop>(onConnectStop, setOnConnectStop);
|
|
||||||
useStoreUpdater<OnConnectEnd>(onConnectEnd, setOnConnectEnd);
|
|
||||||
useStoreUpdater<boolean>(snapToGrid, setSnapToGrid);
|
|
||||||
useStoreUpdater<SnapGrid>(snapGrid, setSnapGrid);
|
|
||||||
useStoreUpdater<boolean>(nodesDraggable, setNodesDraggable);
|
|
||||||
useStoreUpdater<boolean>(nodesConnectable, setNodesConnectable);
|
|
||||||
useStoreUpdater<boolean>(elementsSelectable, setElementsSelectable);
|
|
||||||
useStoreUpdater<number>(minZoom, setMinZoom);
|
useStoreUpdater<number>(minZoom, setMinZoom);
|
||||||
useStoreUpdater<number>(maxZoom, setMaxZoom);
|
useStoreUpdater<number>(maxZoom, setMaxZoom);
|
||||||
useStoreUpdater<CoordinateExtent>(translateExtent, setTranslateExtent);
|
useStoreUpdater<CoordinateExtent>(translateExtent, setTranslateExtent);
|
||||||
useStoreUpdater<CoordinateExtent>(nodeExtent, setNodeExtent);
|
useStoreUpdater<CoordinateExtent>(nodeExtent, setNodeExtent);
|
||||||
useStoreUpdater<ConnectionMode>(connectionMode, setConnectionMode);
|
|
||||||
useStoreUpdater<OnNodesChange>(onNodesChange, setOnNodesChange);
|
useDirectStoreUpdater('connectionMode', connectionMode, store.setState);
|
||||||
useStoreUpdater<OnEdgesChange>(onEdgesChange, setOnEdgesChange);
|
useDirectStoreUpdater('onConnect', onConnect, store.setState);
|
||||||
useStoreUpdater<boolean>(fitViewOnInit, setFitViewOnInit);
|
useDirectStoreUpdater('onConnectStart', onConnectStart, store.setState);
|
||||||
|
useDirectStoreUpdater('onConnectStop', onConnectStop, store.setState);
|
||||||
|
useDirectStoreUpdater('onConnectEnd', onConnectEnd, store.setState);
|
||||||
|
useDirectStoreUpdater('nodesDraggable', nodesDraggable, store.setState);
|
||||||
|
useDirectStoreUpdater('nodesConnectable', nodesConnectable, store.setState);
|
||||||
|
useDirectStoreUpdater('elementsSelectable', elementsSelectable, store.setState);
|
||||||
|
useDirectStoreUpdater('fitViewOnInit', fitViewOnInit, store.setState);
|
||||||
|
useDirectStoreUpdater('snapToGrid', snapToGrid, store.setState);
|
||||||
|
useDirectStoreUpdater('snapGrid', snapGrid, store.setState);
|
||||||
|
useDirectStoreUpdater('onNodesChange', onNodesChange, store.setState);
|
||||||
|
useDirectStoreUpdater('onEdgesChange', onEdgesChange, store.setState);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,8 +30,6 @@ function getMousePosition(event: React.MouseEvent, containerBounds: DOMRect): XY
|
|||||||
const selector = (s: ReactFlowState) => ({
|
const selector = (s: ReactFlowState) => ({
|
||||||
userSelectionActive: s.userSelectionActive,
|
userSelectionActive: s.userSelectionActive,
|
||||||
elementsSelectable: s.elementsSelectable,
|
elementsSelectable: s.elementsSelectable,
|
||||||
setUserSelectionActive: s.setUserSelectionActive,
|
|
||||||
setNodesSelectionActive: s.setNodesSelectionActive,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const initialRect: SelectionRect = {
|
const initialRect: SelectionRect = {
|
||||||
@@ -50,16 +48,14 @@ export default memo(({ selectionKeyPressed }: UserSelectionProps) => {
|
|||||||
const prevSelectedEdgesCount = useRef<number>(0);
|
const prevSelectedEdgesCount = useRef<number>(0);
|
||||||
const containerBounds = useRef<DOMRect>();
|
const containerBounds = useRef<DOMRect>();
|
||||||
const [userSelectionRect, setUserSelectionRect] = useState<SelectionRect>(initialRect);
|
const [userSelectionRect, setUserSelectionRect] = useState<SelectionRect>(initialRect);
|
||||||
const { userSelectionActive, elementsSelectable, setUserSelectionActive, setNodesSelectionActive } = useStore(
|
const { userSelectionActive, elementsSelectable } = useStore(selector, shallow);
|
||||||
selector,
|
|
||||||
shallow
|
|
||||||
);
|
|
||||||
|
|
||||||
const renderUserSelectionPane = userSelectionActive || selectionKeyPressed;
|
const renderUserSelectionPane = userSelectionActive || selectionKeyPressed;
|
||||||
|
|
||||||
const resetUserSelection = useCallback(() => {
|
const resetUserSelection = useCallback(() => {
|
||||||
setUserSelectionRect(initialRect);
|
setUserSelectionRect(initialRect);
|
||||||
setUserSelectionActive(false);
|
|
||||||
|
store.setState({ userSelectionActive: false });
|
||||||
|
|
||||||
prevSelectedNodesCount.current = 0;
|
prevSelectedNodesCount.current = 0;
|
||||||
prevSelectedEdgesCount.current = 0;
|
prevSelectedEdgesCount.current = 0;
|
||||||
@@ -81,8 +77,7 @@ export default memo(({ selectionKeyPressed }: UserSelectionProps) => {
|
|||||||
draw: true,
|
draw: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
setUserSelectionActive(true);
|
store.setState({ userSelectionActive: true, nodesSelectionActive: false });
|
||||||
setNodesSelectionActive(false);
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onMouseMove = (event: React.MouseEvent): void => {
|
const onMouseMove = (event: React.MouseEvent): void => {
|
||||||
@@ -128,12 +123,14 @@ export default memo(({ selectionKeyPressed }: UserSelectionProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onMouseUp = useCallback(() => {
|
const onMouseUp = useCallback(() => {
|
||||||
setNodesSelectionActive(prevSelectedNodesCount.current > 0);
|
store.setState({ nodesSelectionActive: prevSelectedNodesCount.current > 0 });
|
||||||
|
|
||||||
resetUserSelection();
|
resetUserSelection();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onMouseLeave = useCallback(() => {
|
const onMouseLeave = useCallback(() => {
|
||||||
setNodesSelectionActive(false);
|
store.setState({ nodesSelectionActive: false });
|
||||||
|
|
||||||
resetUserSelection();
|
resetUserSelection();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React, { useCallback, memo, ReactNode, WheelEvent, MouseEvent } from 'react';
|
import React, { useCallback, memo, ReactNode, WheelEvent, MouseEvent } from 'react';
|
||||||
import shallow from 'zustand/shallow';
|
import shallow from 'zustand/shallow';
|
||||||
|
|
||||||
import { useStore } from '../../store';
|
import { useStore, useStoreApi } from '../../store';
|
||||||
import useGlobalKeyHandler from '../../hooks/useGlobalKeyHandler';
|
import useGlobalKeyHandler from '../../hooks/useGlobalKeyHandler';
|
||||||
import useKeyPress from '../../hooks/useKeyPress';
|
import useKeyPress from '../../hooks/useKeyPress';
|
||||||
import { GraphViewProps } from '../GraphView';
|
import { GraphViewProps } from '../GraphView';
|
||||||
@@ -27,7 +27,6 @@ interface FlowRendererProps
|
|||||||
}
|
}
|
||||||
|
|
||||||
const selector = (s: ReactFlowState) => ({
|
const selector = (s: ReactFlowState) => ({
|
||||||
setNodesSelectionActive: s.setNodesSelectionActive,
|
|
||||||
resetSelectedElements: s.resetSelectedElements,
|
resetSelectedElements: s.resetSelectedElements,
|
||||||
nodesSelectionActive: s.nodesSelectionActive,
|
nodesSelectionActive: s.nodesSelectionActive,
|
||||||
});
|
});
|
||||||
@@ -62,7 +61,8 @@ const FlowRenderer = ({
|
|||||||
noWheelClassName,
|
noWheelClassName,
|
||||||
noPanClassName,
|
noPanClassName,
|
||||||
}: FlowRendererProps) => {
|
}: FlowRendererProps) => {
|
||||||
const { setNodesSelectionActive, resetSelectedElements, nodesSelectionActive } = useStore(selector, shallow);
|
const store = useStoreApi();
|
||||||
|
const { resetSelectedElements, nodesSelectionActive } = useStore(selector, shallow);
|
||||||
const selectionKeyPressed = useKeyPress(selectionKeyCode);
|
const selectionKeyPressed = useKeyPress(selectionKeyCode);
|
||||||
|
|
||||||
useGlobalKeyHandler({ deleteKeyCode, multiSelectionKeyCode });
|
useGlobalKeyHandler({ deleteKeyCode, multiSelectionKeyCode });
|
||||||
@@ -70,8 +70,9 @@ const FlowRenderer = ({
|
|||||||
const onClick = useCallback(
|
const onClick = useCallback(
|
||||||
(event: MouseEvent) => {
|
(event: MouseEvent) => {
|
||||||
onPaneClick?.(event);
|
onPaneClick?.(event);
|
||||||
setNodesSelectionActive(false);
|
|
||||||
resetSelectedElements();
|
resetSelectedElements();
|
||||||
|
|
||||||
|
store.setState({ nodesSelectionActive: false });
|
||||||
},
|
},
|
||||||
[onPaneClick]
|
[onPaneClick]
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -48,9 +48,6 @@ const selector = (s: ReactFlowState) => ({
|
|||||||
d3Zoom: s.d3Zoom,
|
d3Zoom: s.d3Zoom,
|
||||||
d3Selection: s.d3Selection,
|
d3Selection: s.d3Selection,
|
||||||
d3ZoomHandler: s.d3ZoomHandler,
|
d3ZoomHandler: s.d3ZoomHandler,
|
||||||
|
|
||||||
initD3Zoom: s.initD3Zoom,
|
|
||||||
updateTransform: s.updateTransform,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const ZoomPane = ({
|
const ZoomPane = ({
|
||||||
@@ -77,7 +74,7 @@ const ZoomPane = ({
|
|||||||
const store = useStoreApi();
|
const store = useStoreApi();
|
||||||
const zoomPane = useRef<HTMLDivElement>(null);
|
const zoomPane = useRef<HTMLDivElement>(null);
|
||||||
const prevTransform = useRef<FlowTransform>({ x: 0, y: 0, zoom: 0 });
|
const prevTransform = useRef<FlowTransform>({ x: 0, y: 0, zoom: 0 });
|
||||||
const { d3Zoom, d3Selection, d3ZoomHandler, initD3Zoom, updateTransform } = useStore(selector, shallow);
|
const { d3Zoom, d3Selection, d3ZoomHandler } = useStore(selector, shallow);
|
||||||
const zoomActivationKeyPressed = useKeyPress(zoomActivationKeyCode);
|
const zoomActivationKeyPressed = useKeyPress(zoomActivationKeyCode);
|
||||||
|
|
||||||
useResizeHandler(zoomPane);
|
useResizeHandler(zoomPane);
|
||||||
@@ -95,7 +92,7 @@ const ZoomPane = ({
|
|||||||
|
|
||||||
d3ZoomInstance.transform(selection, updatedTransform);
|
d3ZoomInstance.transform(selection, updatedTransform);
|
||||||
|
|
||||||
initD3Zoom({
|
store.setState({
|
||||||
d3Zoom: d3ZoomInstance,
|
d3Zoom: d3ZoomInstance,
|
||||||
d3Selection: selection,
|
d3Selection: selection,
|
||||||
d3ZoomHandler: selection.on('wheel.zoom'),
|
d3ZoomHandler: selection.on('wheel.zoom'),
|
||||||
@@ -171,7 +168,7 @@ const ZoomPane = ({
|
|||||||
d3Zoom.on('zoom', null);
|
d3Zoom.on('zoom', null);
|
||||||
} else {
|
} else {
|
||||||
d3Zoom.on('zoom', (event: any) => {
|
d3Zoom.on('zoom', (event: any) => {
|
||||||
updateTransform([event.transform.x, event.transform.y, event.transform.k]);
|
store.setState({ transform: [event.transform.x, event.transform.y, event.transform.k] });
|
||||||
|
|
||||||
if (onMove) {
|
if (onMove) {
|
||||||
const flowTransform = eventToFlowTransform(event.transform);
|
const flowTransform = eventToFlowTransform(event.transform);
|
||||||
@@ -180,7 +177,7 @@ const ZoomPane = ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [selectionKeyPressed, d3Zoom, updateTransform, onMove]);
|
}, [selectionKeyPressed, d3Zoom, onMove]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (d3Zoom) {
|
if (d3Zoom) {
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ interface HookParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const selector = (s: ReactFlowState) => ({
|
const selector = (s: ReactFlowState) => ({
|
||||||
setNodesSelectionActive: s.setNodesSelectionActive,
|
|
||||||
setMultiSelectionActive: s.setMultiSelectionActive,
|
|
||||||
resetSelectedElements: s.resetSelectedElements,
|
resetSelectedElements: s.resetSelectedElements,
|
||||||
onNodesChange: s.onNodesChange,
|
onNodesChange: s.onNodesChange,
|
||||||
onEdgesChange: s.onEdgesChange,
|
onEdgesChange: s.onEdgesChange,
|
||||||
@@ -21,8 +19,7 @@ const selector = (s: ReactFlowState) => ({
|
|||||||
|
|
||||||
export default ({ deleteKeyCode, multiSelectionKeyCode }: HookParams): void => {
|
export default ({ deleteKeyCode, multiSelectionKeyCode }: HookParams): void => {
|
||||||
const store = useStoreApi();
|
const store = useStoreApi();
|
||||||
const { setNodesSelectionActive, setMultiSelectionActive, resetSelectedElements, onNodesChange, onEdgesChange } =
|
const { resetSelectedElements, onNodesChange, onEdgesChange } = useStore(selector, shallow);
|
||||||
useStore(selector, shallow);
|
|
||||||
|
|
||||||
const deleteKeyPressed = useKeyPress(deleteKeyCode);
|
const deleteKeyPressed = useKeyPress(deleteKeyCode);
|
||||||
const multiSelectionKeyPressed = useKeyPress(multiSelectionKeyCode);
|
const multiSelectionKeyPressed = useKeyPress(multiSelectionKeyCode);
|
||||||
@@ -46,12 +43,13 @@ export default ({ deleteKeyCode, multiSelectionKeyCode }: HookParams): void => {
|
|||||||
onNodesChange?.(nodeChanges);
|
onNodesChange?.(nodeChanges);
|
||||||
onEdgesChange?.(edgeChanges);
|
onEdgesChange?.(edgeChanges);
|
||||||
|
|
||||||
setNodesSelectionActive(false);
|
store.setState({ nodesSelectionActive: false });
|
||||||
|
|
||||||
resetSelectedElements();
|
resetSelectedElements();
|
||||||
}
|
}
|
||||||
}, [deleteKeyPressed, onNodesChange, onEdgesChange]);
|
}, [deleteKeyPressed, onNodesChange, onEdgesChange]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setMultiSelectionActive(multiSelectionKeyPressed);
|
store.setState({ multiSelectionActive: multiSelectionKeyPressed });
|
||||||
}, [multiSelectionKeyPressed]);
|
}, [multiSelectionKeyPressed]);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
import { useEffect, MutableRefObject } from 'react';
|
import { useEffect, MutableRefObject } from 'react';
|
||||||
|
|
||||||
import { useStore } from '../store';
|
import { useStoreApi } from '../store';
|
||||||
import { getDimensions } from '../utils';
|
import { getDimensions } from '../utils';
|
||||||
import { ReactFlowState } from '../types';
|
|
||||||
|
|
||||||
const updateSizeSelector = (state: ReactFlowState) => state.updateSize;
|
|
||||||
|
|
||||||
function useResizeHandler(rendererNode: MutableRefObject<HTMLDivElement | null>): void {
|
function useResizeHandler(rendererNode: MutableRefObject<HTMLDivElement | null>): void {
|
||||||
const updateSize = useStore(updateSizeSelector);
|
const store = useStoreApi();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let resizeObserver: ResizeObserver;
|
let resizeObserver: ResizeObserver;
|
||||||
@@ -23,7 +20,7 @@ function useResizeHandler(rendererNode: MutableRefObject<HTMLDivElement | null>)
|
|||||||
console.warn('The React Flow parent container needs a width and a height to render the graph.');
|
console.warn('The React Flow parent container needs a width and a height to render the graph.');
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSize(size);
|
store.setState({ width: size.width || 500, height: size.height || 500 });
|
||||||
};
|
};
|
||||||
|
|
||||||
updateDimensions();
|
updateDimensions();
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ import { useCallback } from 'react';
|
|||||||
import { useStore } from '../store';
|
import { useStore } from '../store';
|
||||||
import { UpdateNodeInternals, ReactFlowState } from '../types';
|
import { UpdateNodeInternals, ReactFlowState } from '../types';
|
||||||
|
|
||||||
const updateNodeDimsSelector = (state: ReactFlowState) => state.updateNodeDimensions;
|
const selector = (state: ReactFlowState) => state.updateNodeDimensions;
|
||||||
|
|
||||||
function useUpdateNodeInternals(): UpdateNodeInternals {
|
function useUpdateNodeInternals(): UpdateNodeInternals {
|
||||||
const updateNodeDimensions = useStore(updateNodeDimsSelector);
|
const updateNodeDimensions = useStore(selector);
|
||||||
|
|
||||||
return useCallback<UpdateNodeInternals>((id: string) => {
|
return useCallback<UpdateNodeInternals>((id: string) => {
|
||||||
const nodeElement = document.querySelector(`.react-flow__node[data-id="${id}"]`) as HTMLDivElement;
|
const nodeElement = document.querySelector(`.react-flow__node[data-id="${id}"]`) as HTMLDivElement;
|
||||||
|
|||||||
@@ -4,27 +4,14 @@ import createContext from 'zustand/context';
|
|||||||
import { clampPosition, getDimensions } from '../utils';
|
import { clampPosition, getDimensions } from '../utils';
|
||||||
import {
|
import {
|
||||||
ReactFlowState,
|
ReactFlowState,
|
||||||
ConnectionMode,
|
|
||||||
Node,
|
Node,
|
||||||
Edge,
|
Edge,
|
||||||
NodeDimensionUpdate,
|
NodeDimensionUpdate,
|
||||||
NodeDiffUpdate,
|
NodeDiffUpdate,
|
||||||
InitD3ZoomPayload,
|
|
||||||
CoordinateExtent,
|
CoordinateExtent,
|
||||||
OnConnect,
|
|
||||||
OnConnectStart,
|
|
||||||
OnConnectStop,
|
|
||||||
OnConnectEnd,
|
|
||||||
SetConnectionId,
|
|
||||||
SnapGrid,
|
|
||||||
NodeChange,
|
NodeChange,
|
||||||
OnNodesChange,
|
|
||||||
OnEdgesChange,
|
|
||||||
EdgeChange,
|
EdgeChange,
|
||||||
NodeDimensionChange,
|
NodeDimensionChange,
|
||||||
Transform,
|
|
||||||
Dimensions,
|
|
||||||
XYPosition,
|
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import { getHandleBounds } from '../components/Nodes/utils';
|
import { getHandleBounds } from '../components/Nodes/utils';
|
||||||
import { createSelectionChange, getSelectionChanges } from '../utils/changes';
|
import { createSelectionChange, getSelectionChanges } from '../utils/changes';
|
||||||
@@ -36,7 +23,6 @@ const { Provider, useStore, useStoreApi } = createContext<ReactFlowState>();
|
|||||||
const createStore = () =>
|
const createStore = () =>
|
||||||
create<ReactFlowState>((set, get) => ({
|
create<ReactFlowState>((set, get) => ({
|
||||||
...initialState,
|
...initialState,
|
||||||
|
|
||||||
setNodes: (nodes: Node[]) => {
|
setNodes: (nodes: Node[]) => {
|
||||||
const nodeInternals = createNodeInternals(nodes, get().nodeInternals);
|
const nodeInternals = createNodeInternals(nodes, get().nodeInternals);
|
||||||
|
|
||||||
@@ -158,13 +144,6 @@ const createStore = () =>
|
|||||||
onEdgesChange?.(edgesToUnselect);
|
onEdgesChange?.(edgesToUnselect);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
initD3Zoom: ({ d3Zoom, d3Selection, d3ZoomHandler, transform }: InitD3ZoomPayload) =>
|
|
||||||
set({
|
|
||||||
d3Zoom,
|
|
||||||
d3Selection,
|
|
||||||
d3ZoomHandler,
|
|
||||||
transform,
|
|
||||||
}),
|
|
||||||
setMinZoom: (minZoom: number) => {
|
setMinZoom: (minZoom: number) => {
|
||||||
const { d3Zoom, maxZoom } = get();
|
const { d3Zoom, maxZoom } = get();
|
||||||
d3Zoom?.scaleExtent([minZoom, maxZoom]);
|
d3Zoom?.scaleExtent([minZoom, maxZoom]);
|
||||||
@@ -183,7 +162,6 @@ const createStore = () =>
|
|||||||
|
|
||||||
set({ translateExtent });
|
set({ translateExtent });
|
||||||
},
|
},
|
||||||
|
|
||||||
resetSelectedElements: () => {
|
resetSelectedElements: () => {
|
||||||
const { nodeInternals, edges, onNodesChange, onEdgesChange } = get();
|
const { nodeInternals, edges, onNodesChange, onEdgesChange } = get();
|
||||||
// @TODO: work with nodeInternals instead of converting it to an array
|
// @TODO: work with nodeInternals instead of converting it to an array
|
||||||
@@ -210,33 +188,7 @@ const createStore = () =>
|
|||||||
nodeInternals: new Map(nodeInternals),
|
nodeInternals: new Map(nodeInternals),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
setUserSelectionActive: (userSelectionActive: boolean) => set({ userSelectionActive }),
|
|
||||||
setNodesSelectionActive: (nodesSelectionActive: boolean) => set({ nodesSelectionActive }),
|
|
||||||
updateTransform: (transform: Transform) => set({ transform }),
|
|
||||||
updateSize: (size: Dimensions) => set({ width: size.width || 500, height: size.height || 500 }),
|
|
||||||
setOnConnect: (onConnect: OnConnect) => set({ onConnect }),
|
|
||||||
setOnConnectStart: (onConnectStart: OnConnectStart) => set({ onConnectStart }),
|
|
||||||
setOnConnectStop: (onConnectStop: OnConnectStop) => set({ onConnectStop }),
|
|
||||||
setOnConnectEnd: (onConnectEnd: OnConnectEnd) => set({ onConnectEnd }),
|
|
||||||
setConnectionPosition: (connectionPosition: XYPosition) => set({ connectionPosition }),
|
|
||||||
setConnectionNodeId: (params: SetConnectionId) => set({ ...params }),
|
|
||||||
setSnapToGrid: (snapToGrid: boolean) => set({ snapToGrid }),
|
|
||||||
setSnapGrid: (snapGrid: SnapGrid) => set({ snapGrid }),
|
|
||||||
setInteractive: (isInteractive: boolean) =>
|
|
||||||
set({
|
|
||||||
nodesDraggable: isInteractive,
|
|
||||||
nodesConnectable: isInteractive,
|
|
||||||
elementsSelectable: isInteractive,
|
|
||||||
}),
|
|
||||||
setNodesDraggable: (nodesDraggable: boolean) => set({ nodesDraggable }),
|
|
||||||
setNodesConnectable: (nodesConnectable: boolean) => set({ nodesConnectable }),
|
|
||||||
setElementsSelectable: (elementsSelectable: boolean) => set({ elementsSelectable }),
|
|
||||||
setMultiSelectionActive: (multiSelectionActive: boolean) => set({ multiSelectionActive }),
|
|
||||||
setConnectionMode: (connectionMode: ConnectionMode) => set({ connectionMode }),
|
|
||||||
setOnNodesChange: (onNodesChange: OnNodesChange) => set({ onNodesChange }),
|
|
||||||
setOnEdgesChange: (onEdgesChange: OnEdgesChange) => set({ onEdgesChange }),
|
|
||||||
reset: () => set({ ...initialState }),
|
reset: () => set({ ...initialState }),
|
||||||
setFitViewOnInit: (fitViewOnInit: boolean) => set({ fitViewOnInit }),
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export { Provider, useStore, createStore, useStoreApi };
|
export { Provider, useStore, createStore, useStoreApi };
|
||||||
|
|||||||
+6
-42
@@ -1,7 +1,7 @@
|
|||||||
import { MouseEvent as ReactMouseEvent, ReactNode } from 'react';
|
import { MouseEvent as ReactMouseEvent, ReactNode } from 'react';
|
||||||
import { Selection as D3Selection, ZoomBehavior } from 'd3';
|
import { Selection as D3Selection, ZoomBehavior } from 'd3';
|
||||||
|
|
||||||
import { XYPosition, Rect, Transform, CoordinateExtent, Dimensions } from './utils';
|
import { XYPosition, Rect, Transform, CoordinateExtent } from './utils';
|
||||||
import { NodeChange, EdgeChange } from './changes';
|
import { NodeChange, EdgeChange } from './changes';
|
||||||
import { Node, NodeInternals, NodeDimensionUpdate, NodeDiffUpdate } from './nodes';
|
import { Node, NodeInternals, NodeDimensionUpdate, NodeDiffUpdate } from './nodes';
|
||||||
import { Edge } from './edges';
|
import { Edge } from './edges';
|
||||||
@@ -90,12 +90,6 @@ export type OnConnectStop = (event: MouseEvent) => void;
|
|||||||
|
|
||||||
export type OnConnectEnd = (event: MouseEvent) => void;
|
export type OnConnectEnd = (event: MouseEvent) => void;
|
||||||
|
|
||||||
export type SetConnectionId = {
|
|
||||||
connectionNodeId: string | null;
|
|
||||||
connectionHandleId: string | null;
|
|
||||||
connectionHandleType: HandleType | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export enum BackgroundVariant {
|
export enum BackgroundVariant {
|
||||||
Lines = 'lines',
|
Lines = 'lines',
|
||||||
Dots = 'dots',
|
Dots = 'dots',
|
||||||
@@ -143,13 +137,6 @@ export interface ZoomPanHelperFunctions {
|
|||||||
initialized: boolean;
|
initialized: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type InitD3ZoomPayload = {
|
|
||||||
d3Zoom: ZoomBehavior<Element, unknown>;
|
|
||||||
d3Selection: D3Selection<Element, unknown, null, undefined>;
|
|
||||||
d3ZoomHandler: ((this: Element, event: any, d: unknown) => void) | undefined;
|
|
||||||
transform: Transform;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ReactFlowStore = {
|
export type ReactFlowStore = {
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
@@ -190,6 +177,11 @@ export type ReactFlowStore = {
|
|||||||
|
|
||||||
fitViewOnInit: boolean;
|
fitViewOnInit: boolean;
|
||||||
fitViewOnInitDone: boolean;
|
fitViewOnInitDone: boolean;
|
||||||
|
|
||||||
|
onConnect?: OnConnect;
|
||||||
|
onConnectStart?: OnConnectStart;
|
||||||
|
onConnectStop?: OnConnectStop;
|
||||||
|
onConnectEnd?: OnConnectEnd;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ReactFlowActions = {
|
export type ReactFlowActions = {
|
||||||
@@ -197,43 +189,15 @@ export type ReactFlowActions = {
|
|||||||
setEdges: (edges: Edge[]) => void;
|
setEdges: (edges: Edge[]) => void;
|
||||||
updateNodeDimensions: (updates: NodeDimensionUpdate[]) => void;
|
updateNodeDimensions: (updates: NodeDimensionUpdate[]) => void;
|
||||||
updateNodePosition: (update: NodeDiffUpdate) => void;
|
updateNodePosition: (update: NodeDiffUpdate) => void;
|
||||||
setNodesSelectionActive: (isActive: boolean) => void;
|
|
||||||
setUserSelectionActive: (isActive: boolean) => void;
|
|
||||||
resetSelectedElements: () => void;
|
resetSelectedElements: () => void;
|
||||||
unselectNodesAndEdges: () => void;
|
unselectNodesAndEdges: () => void;
|
||||||
addSelectedNodes: (nodeIds: string[]) => void;
|
addSelectedNodes: (nodeIds: string[]) => void;
|
||||||
addSelectedEdges: (edgeIds: string[]) => void;
|
addSelectedEdges: (edgeIds: string[]) => void;
|
||||||
updateTransform: (transform: Transform) => void;
|
|
||||||
updateSize: (size: Dimensions) => void;
|
|
||||||
initD3Zoom: (payload: InitD3ZoomPayload) => void;
|
|
||||||
setMinZoom: (minZoom: number) => void;
|
setMinZoom: (minZoom: number) => void;
|
||||||
setMaxZoom: (maxZoom: number) => void;
|
setMaxZoom: (maxZoom: number) => void;
|
||||||
setTranslateExtent: (translateExtent: CoordinateExtent) => void;
|
setTranslateExtent: (translateExtent: CoordinateExtent) => void;
|
||||||
setNodeExtent: (nodeExtent: CoordinateExtent) => void;
|
setNodeExtent: (nodeExtent: CoordinateExtent) => void;
|
||||||
setOnConnect: (onConnectFunction: OnConnect) => void;
|
|
||||||
setOnConnectStart: (onConnectFunction: OnConnectStart) => void;
|
|
||||||
setOnConnectStop: (onConnectFunction: OnConnectStop) => void;
|
|
||||||
setOnConnectEnd: (onConnectFunction: OnConnectEnd) => void;
|
|
||||||
setConnectionPosition: (connectionPosition: XYPosition) => void;
|
|
||||||
setConnectionNodeId: (payload: SetConnectionId) => void;
|
|
||||||
setSnapToGrid: (snapToGrid: boolean) => void;
|
|
||||||
setSnapGrid: (snapGrid: SnapGrid) => void;
|
|
||||||
setInteractive: (isInteractive: boolean) => void;
|
|
||||||
setNodesDraggable: (nodesDraggable: boolean) => void;
|
|
||||||
setNodesConnectable: (nodesConnectable: boolean) => void;
|
|
||||||
setElementsSelectable: (elementsSelectable: boolean) => void;
|
|
||||||
setMultiSelectionActive: (multiSelectionActive: boolean) => void;
|
|
||||||
setConnectionMode: (connectionMode: ConnectionMode) => void;
|
|
||||||
setOnNodesChange: (onNodesChange: OnNodesChange) => void;
|
|
||||||
setOnEdgesChange: (onEdgesChange: OnEdgesChange) => void;
|
|
||||||
|
|
||||||
onConnect?: OnConnect;
|
|
||||||
onConnectStart?: OnConnectStart;
|
|
||||||
onConnectStop?: OnConnectStop;
|
|
||||||
onConnectEnd?: OnConnectEnd;
|
|
||||||
|
|
||||||
reset: () => void;
|
reset: () => void;
|
||||||
setFitViewOnInit: (fitViewOnInit: boolean) => void;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ReactFlowState = ReactFlowStore & ReactFlowActions;
|
export type ReactFlowState = ReactFlowStore & ReactFlowActions;
|
||||||
|
|||||||
Reference in New Issue
Block a user