chore(react): avoid deselection on pane click if elementsSelectable=false

This commit is contained in:
moklick
2025-04-15 08:25:01 +02:00
parent 25fe1edca8
commit f9f9e6f168
3 changed files with 22 additions and 21 deletions
@@ -10,6 +10,7 @@ import {
useEdgesState, useEdgesState,
useOnSelectionChange, useOnSelectionChange,
OnSelectionChangeParams, OnSelectionChangeParams,
Panel,
} from '@xyflow/react'; } from '@xyflow/react';
const initialNodes: Node[] = [ const initialNodes: Node[] = [
@@ -51,6 +52,12 @@ const Flow = () => {
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const onConnect = useCallback((params: Edge | Connection) => setEdges((els) => addEdge(params, els)), [setEdges]); const onConnect = useCallback((params: Edge | Connection) => setEdges((els) => addEdge(params, els)), [setEdges]);
const [elementsSelectable, setElementsSelectable] = useState<boolean>(true);
const [secondLoggerActive, setSecondLoggerActive] = useState<boolean>(true);
const toggleSecondLogger = () => {
setSecondLoggerActive(!secondLoggerActive);
};
return ( return (
<ReactFlow <ReactFlow
@@ -59,27 +66,17 @@ const Flow = () => {
onNodesChange={onNodesChange} onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange} onEdgesChange={onEdgesChange}
onConnect={onConnect} onConnect={onConnect}
/> elementsSelectable={elementsSelectable}
); >
}; <Panel>
<button onClick={toggleSecondLogger}>{secondLoggerActive ? 'Disable' : 'Enable'} Logger 2</button>
<button onClick={() => setElementsSelectable((s) => !s)}>toggle selectable</button>
</Panel>
const WrappedFlow = () => {
const [secondLoggerActive, setSecondLoggerActive] = useState<boolean>(true);
const toggleSecondLogger = () => {
setSecondLoggerActive(!secondLoggerActive);
};
return (
<ReactFlowProvider>
<Flow />
<SelectionLogger id="Logger 1" /> <SelectionLogger id="Logger 1" />
{secondLoggerActive && <SelectionLogger id="Logger 2" />} {secondLoggerActive && <SelectionLogger id="Logger 2" />}
<div style={{ position: 'absolute', right: 10, top: 10, zIndex: 4 }}> </ReactFlow>
<button onClick={toggleSecondLogger}>{secondLoggerActive ? 'Disable' : 'Enable'} Logger 2</button>
</div>
</ReactFlowProvider>
); );
}; };
export default WrappedFlow; export default Flow;
@@ -19,13 +19,13 @@ const selector = (s: ReactFlowState) => {
const selectedEdges = []; const selectedEdges = [];
for (const [, node] of s.nodeLookup) { for (const [, node] of s.nodeLookup) {
if (node.selected && (s.elementsSelectable || node.selectable)) { if (node.selected) {
selectedNodes.push(node.internals.userNode); selectedNodes.push(node.internals.userNode);
} }
} }
for (const [, edge] of s.edgeLookup) { for (const [, edge] of s.edgeLookup) {
if (edge.selected && (s.elementsSelectable || edge.selectable)) { if (edge.selected) {
selectedEdges.push(edge); selectedEdges.push(edge);
} }
} }
+5 -1
View File
@@ -297,7 +297,11 @@ const createStore = ({
get().panZoom?.setClickDistance(clickDistance); get().panZoom?.setClickDistance(clickDistance);
}, },
resetSelectedElements: () => { resetSelectedElements: () => {
const { edges, nodes, triggerNodeChanges, triggerEdgeChanges } = get(); const { edges, nodes, triggerNodeChanges, triggerEdgeChanges, elementsSelectable } = get();
if (!elementsSelectable) {
return;
}
const nodeChanges = nodes.reduce<NodeSelectionChange[]>( const nodeChanges = nodes.reduce<NodeSelectionChange[]>(
(res, node) => (node.selected ? [...res, createSelectionChange(node.id, false)] : res), (res, node) => (node.selected ? [...res, createSelectionChange(node.id, false)] : res),