fix(selection-change): only trigger once
This commit is contained in:
@@ -1,29 +1,38 @@
|
|||||||
import { useEffect } from 'react';
|
import { memo, useEffect } from 'react';
|
||||||
import shallow from 'zustand/shallow';
|
import shallow from 'zustand/shallow';
|
||||||
|
|
||||||
import { ReactFlowState, OnSelectionChangeFunc } from '../../types';
|
import { ReactFlowState, OnSelectionChangeFunc, Node, Edge } from '../../types';
|
||||||
import { useStore } from '../../store';
|
import { useStore } from '../../store';
|
||||||
|
|
||||||
interface SelectionListenerProps {
|
interface SelectionListenerProps {
|
||||||
onSelectionChange: OnSelectionChangeFunc;
|
onSelectionChange: OnSelectionChangeFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @TODO: work with nodeInternals instead of converting it to an array
|
|
||||||
const selector = (s: ReactFlowState) => ({
|
const selector = (s: ReactFlowState) => ({
|
||||||
selectedNodes: Array.from(s.nodeInternals)
|
selectedNodes: Array.from(s.nodeInternals.values()).filter((n) => n.selected),
|
||||||
.filter(([_, n]) => n.selected)
|
|
||||||
.map(([_, node]) => node),
|
|
||||||
selectedEdges: s.edges.filter((e) => e.selected),
|
selectedEdges: s.edges.filter((e) => e.selected),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const areEqual = (objA: any, objB: any) => {
|
||||||
|
const selectedNodeIdsA = objA.selectedNodes.map((n: Node) => n.id);
|
||||||
|
const selectedNodeIdsB = objB.selectedNodes.map((n: Node) => n.id);
|
||||||
|
|
||||||
|
const selectedEdgeIdsA = objA.selectedEdges.map((e: Edge) => e.id);
|
||||||
|
const selectedEdgeIdsB = objB.selectedEdges.map((e: Edge) => e.id);
|
||||||
|
|
||||||
|
return shallow(selectedNodeIdsA, selectedNodeIdsB) && shallow(selectedEdgeIdsA, selectedEdgeIdsB);
|
||||||
|
};
|
||||||
|
|
||||||
// This is just a helper component for calling the onSelectionChange listener.
|
// This is just a helper component for calling the onSelectionChange listener.
|
||||||
// @TODO: Now that we have the onNodesChange and on EdgesChange listeners, do we still need this component?
|
// @TODO: Now that we have the onNodesChange and on EdgesChange listeners, do we still need this component?
|
||||||
export default ({ onSelectionChange }: SelectionListenerProps) => {
|
function SelectionListener({ onSelectionChange }: SelectionListenerProps) {
|
||||||
const { selectedNodes, selectedEdges } = useStore(selector, shallow);
|
const { selectedNodes, selectedEdges } = useStore(selector, areEqual);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
onSelectionChange({ nodes: selectedNodes, edges: selectedEdges });
|
onSelectionChange({ nodes: selectedNodes, edges: selectedEdges });
|
||||||
}, [selectedNodes, selectedEdges]);
|
}, [selectedNodes, selectedEdges]);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
export default memo(SelectionListener);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export type OnEdgesChange = (nodes: EdgeChange[]) => void;
|
|||||||
export type OnNodesDelete = (nodes: Node[]) => void;
|
export type OnNodesDelete = (nodes: Node[]) => void;
|
||||||
export type OnEdgesDelete = (edges: Edge[]) => void;
|
export type OnEdgesDelete = (edges: Edge[]) => void;
|
||||||
|
|
||||||
export type OnMove = (event: MouseEvent | TouchEvent, viweport: Viewport) => void;
|
export type OnMove = (event: MouseEvent | TouchEvent, viewport: Viewport) => void;
|
||||||
export type OnMoveStart = OnMove;
|
export type OnMoveStart = OnMove;
|
||||||
export type OnMoveEnd = OnMove;
|
export type OnMoveEnd = OnMove;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user