refactor(store): use store.setState directly instead of actions

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