diff --git a/packages/vue-flow/src/components/Nodes/NodeWrapper.vue b/packages/vue-flow/src/components/Nodes/NodeWrapper.vue index 05a54413..ad06e6a4 100644 --- a/packages/vue-flow/src/components/Nodes/NodeWrapper.vue +++ b/packages/vue-flow/src/components/Nodes/NodeWrapper.vue @@ -31,7 +31,7 @@ const { getNode, addSelectedNodes, multiSelectionActive, - resetSelectedElements, + removeSelectedElements, getSelectedNodes, } = $(useVueFlow()) @@ -61,7 +61,7 @@ useDrag({ if (multiSelectionActive) { addSelectedNodes([node]) } else { - resetSelectedElements() + removeSelectedElements() setState({ nodesSelectionActive: false, }) diff --git a/packages/vue-flow/src/container/SelectionPane/SelectionPane.vue b/packages/vue-flow/src/container/SelectionPane/SelectionPane.vue index 45d1bcf9..c8b48dd8 100644 --- a/packages/vue-flow/src/container/SelectionPane/SelectionPane.vue +++ b/packages/vue-flow/src/container/SelectionPane/SelectionPane.vue @@ -14,7 +14,7 @@ const { nodesSelectionActive, userSelectionActive, elementsSelectable, - resetSelectedElements, + removeSelectedElements, setState, getSelectedEdges, getSelectedNodes, @@ -25,7 +25,7 @@ const onClick = (event: MouseEvent) => { setState({ nodesSelectionActive: false, }) - resetSelectedElements() + removeSelectedElements() } const onContextMenu = (event: MouseEvent) => emits.paneContextMenu(event) @@ -51,7 +51,7 @@ useKeyPress($$(deleteKeyCode), (keyPressed) => { nodesSelectionActive: false, }) - resetSelectedElements() + removeSelectedElements() } }) diff --git a/packages/vue-flow/src/store/actions.ts b/packages/vue-flow/src/store/actions.ts index d6be0429..33bcf173 100644 --- a/packages/vue-flow/src/store/actions.ts +++ b/packages/vue-flow/src/store/actions.ts @@ -187,7 +187,7 @@ export default (state: State, getters: ComputedGetters): Actions => { const selectedEdgesIds = edges.map((e) => e.id) let changedEdges: EdgeChange[] - if (state.multiSelectionActive) changedEdges = selectedEdgesIds.map((nodeId) => createSelectionChange(nodeId, true)) + if (state.multiSelectionActive) changedEdges = selectedEdgesIds.map((edgeId) => createSelectionChange(edgeId, true)) else changedEdges = getSelectionChanges(state.edges, selectedEdgesIds, getters.getNode.value) if (changedEdges.length) state.hooks.edgesChange.trigger(changedEdges) @@ -198,6 +198,36 @@ export default (state: State, getters: ComputedGetters): Actions => { addSelectedEdges(elements.filter(isGraphEdge)) } + const removeSelectedNodes: Actions['removeSelectedNodes'] = (nodes) => { + const unselectedNodesIds = nodes.map((n) => n.id) + + let changedNodes: NodeChange[] + if (state.multiSelectionActive) changedNodes = unselectedNodesIds.map((nodeId) => createSelectionChange(nodeId, false)) + else changedNodes = getSelectionChanges(state.nodes, unselectedNodesIds, getters.getNode.value) + + if (changedNodes.length) state.hooks.nodesChange.trigger(changedNodes) + } + + const removeSelectedEdges: Actions['removeSelectedEdges'] = (edges) => { + const unselectedEdgesIds = edges.map((e) => e.id) + + let changedEdges: EdgeChange[] + if (state.multiSelectionActive) changedEdges = unselectedEdgesIds.map((edgeId) => createSelectionChange(edgeId, false)) + else changedEdges = getSelectionChanges(state.edges, unselectedEdgesIds, getters.getNode.value) + + if (changedEdges.length) state.hooks.edgesChange.trigger(changedEdges) + } + + const removeSelectedElements: Actions['removeSelectedElements'] = (elements) => { + if (!elements) { + addSelectedNodes([]) + addSelectedEdges([]) + } else { + if (elements.nodes) removeSelectedNodes(elements.nodes.filter(isGraphNode)) + if (elements.edges) removeSelectedEdges(elements.edges.filter(isGraphEdge)) + } + } + const setMinZoom: Actions['setMinZoom'] = (minZoom: any) => { state.d3Zoom?.scaleExtent([minZoom, state.maxZoom]) state.minZoom = minZoom @@ -213,11 +243,6 @@ export default (state: State, getters: ComputedGetters): Actions => { state.translateExtent = translateExtent } - const resetSelectedElements: Actions['resetSelectedElements'] = () => { - addSelectedNodes([]) - addSelectedEdges([]) - } - const setInteractive: Actions['setInteractive'] = (isInteractive) => { state.nodesDraggable = isInteractive state.nodesConnectable = isInteractive @@ -355,7 +380,9 @@ export default (state: State, getters: ComputedGetters): Actions => { setMinZoom, setMaxZoom, setTranslateExtent, - resetSelectedElements, + removeSelectedElements, + removeSelectedNodes, + removeSelectedEdges, setInteractive, setState, $reset: () => { diff --git a/packages/vue-flow/src/types/store.ts b/packages/vue-flow/src/types/store.ts index f2bba37b..83fd3161 100644 --- a/packages/vue-flow/src/types/store.ts +++ b/packages/vue-flow/src/types/store.ts @@ -144,8 +144,12 @@ export interface Actions { addSelectedEdges: (edges: GraphEdge[]) => void /** manually select nodes and add to state */ addSelectedNodes: (nodes: GraphNode[]) => void - /** unselect all selected elements */ - resetSelectedElements: () => void + /** manually unselect edges and remove from state */ + removeSelectedEdges: (edges: GraphEdge[]) => void + /** manually unselect nodes and remove from state */ + removeSelectedNodes: (nodes: GraphNode[]) => void + /** unselect selected elements (if none are passed, all elements are unselected) */ + removeSelectedElements: (elements?: { nodes?: GraphNode[]; edges?: GraphEdge[] }) => void /** apply min zoom value to d3 */ setMinZoom: (zoom: number) => void /** apply max zoom value to d3 */