58 lines
2.0 KiB
TypeScript
58 lines
2.0 KiB
TypeScript
import { useEffect } from 'react';
|
|
import shallow from 'zustand/shallow';
|
|
|
|
import { useStore, useStoreApi } from '../store';
|
|
import useKeyPress from './useKeyPress';
|
|
import { getConnectedEdges } from '../utils/graph';
|
|
import { EdgeChange, KeyCode, NodeChange, ReactFlowState } from '../types';
|
|
|
|
interface HookParams {
|
|
deleteKeyCode: KeyCode;
|
|
multiSelectionKeyCode: KeyCode;
|
|
}
|
|
|
|
const selector = (s: ReactFlowState) => ({
|
|
unsetNodesSelection: s.unsetNodesSelection,
|
|
setMultiSelectionActive: s.setMultiSelectionActive,
|
|
resetSelectedElements: s.resetSelectedElements,
|
|
onNodesChange: s.onNodesChange,
|
|
onEdgesChange: s.onEdgesChange,
|
|
});
|
|
|
|
export default ({ deleteKeyCode, multiSelectionKeyCode }: HookParams): void => {
|
|
const store = useStoreApi();
|
|
const { unsetNodesSelection, setMultiSelectionActive, resetSelectedElements, onNodesChange, onEdgesChange } =
|
|
useStore(selector, shallow);
|
|
|
|
const deleteKeyPressed = useKeyPress(deleteKeyCode);
|
|
const multiSelectionKeyPressed = useKeyPress(multiSelectionKeyCode);
|
|
|
|
useEffect(() => {
|
|
const { nodeInternals, edges } = store.getState();
|
|
// @TODO: work with nodeInternals instead of converting it to an array
|
|
const nodes = Array.from(nodeInternals).map(([_, node]) => node);
|
|
const selectedNodes = nodes.filter((n) => n.selected);
|
|
const selectedEdges = edges.filter((e) => e.selected);
|
|
|
|
if (deleteKeyPressed && (selectedNodes || selectedEdges)) {
|
|
const connectedEdges = getConnectedEdges(selectedNodes, edges);
|
|
|
|
const nodeChanges: NodeChange[] = selectedNodes.map((n) => ({ id: n.id, type: 'remove' }));
|
|
const edgeChanges: EdgeChange[] = [...selectedEdges, ...connectedEdges].map((e) => ({
|
|
id: e.id,
|
|
type: 'remove',
|
|
}));
|
|
|
|
onNodesChange?.(nodeChanges);
|
|
onEdgesChange?.(edgeChanges);
|
|
|
|
unsetNodesSelection();
|
|
resetSelectedElements();
|
|
}
|
|
}, [deleteKeyPressed, onNodesChange, onEdgesChange]);
|
|
|
|
useEffect(() => {
|
|
setMultiSelectionActive(multiSelectionKeyPressed);
|
|
}, [multiSelectionKeyPressed]);
|
|
};
|