feat(nodes): add prop to disable automatic elevation of nodes on select

This commit is contained in:
Christopher Möller
2022-12-15 18:57:01 +01:00
parent 7ef2910808
commit 7318210a2c
8 changed files with 22 additions and 8 deletions
@@ -50,7 +50,7 @@ const initialEdges: Edge[] = [
const nodeOrigin: NodeOrigin = [0.5, 0.5]; const nodeOrigin: NodeOrigin = [0.5, 0.5];
const defaultEdgeOptions = { zIndex: 0 }; const defaultEdgeOptions = {};
const BasicFlow = () => { const BasicFlow = () => {
const instance = useReactFlow(); const instance = useReactFlow();
@@ -94,6 +94,8 @@ const BasicFlow = () => {
fitView fitView
defaultEdgeOptions={defaultEdgeOptions} defaultEdgeOptions={defaultEdgeOptions}
selectNodesOnDrag={false} selectNodesOnDrag={false}
elevateEdgesOnSelect
elevateNodesOnSelect={false}
// nodeOrigin={nodeOrigin} // nodeOrigin={nodeOrigin}
> >
<Background variant={BackgroundVariant.Dots} /> <Background variant={BackgroundVariant.Dots} />
@@ -44,6 +44,7 @@ type StoreUpdaterProps = Pick<
| 'onSelectionDragStop' | 'onSelectionDragStop'
| 'noPanClassName' | 'noPanClassName'
| 'nodeOrigin' | 'nodeOrigin'
| 'elevateNodesOnSelect'
> & { rfId: string }; > & { rfId: string };
const selector = (s: ReactFlowState) => ({ const selector = (s: ReactFlowState) => ({
@@ -92,6 +93,7 @@ const StoreUpdater = ({
nodesConnectable, nodesConnectable,
nodesFocusable, nodesFocusable,
edgesFocusable, edgesFocusable,
elevateNodesOnSelect,
minZoom, minZoom,
maxZoom, maxZoom,
nodeExtent, nodeExtent,
@@ -151,6 +153,7 @@ const StoreUpdater = ({
useDirectStoreUpdater('nodesFocusable', nodesFocusable, store.setState); useDirectStoreUpdater('nodesFocusable', nodesFocusable, store.setState);
useDirectStoreUpdater('edgesFocusable', edgesFocusable, store.setState); useDirectStoreUpdater('edgesFocusable', edgesFocusable, store.setState);
useDirectStoreUpdater('elementsSelectable', elementsSelectable, store.setState); useDirectStoreUpdater('elementsSelectable', elementsSelectable, store.setState);
useDirectStoreUpdater('elevateNodesOnSelect', elevateNodesOnSelect, store.setState);
useDirectStoreUpdater('snapToGrid', snapToGrid, store.setState); useDirectStoreUpdater('snapToGrid', snapToGrid, store.setState);
useDirectStoreUpdater('snapGrid', snapGrid, store.setState); useDirectStoreUpdater('snapGrid', snapGrid, store.setState);
useDirectStoreUpdater('onNodesChange', onNodesChange, store.setState); useDirectStoreUpdater('onNodesChange', onNodesChange, store.setState);
@@ -157,6 +157,7 @@ const ReactFlow = forwardRef<ReactFlowRefType, ReactFlowProps>(
attributionPosition, attributionPosition,
proOptions, proOptions,
defaultEdgeOptions, defaultEdgeOptions,
elevateNodesOnSelect = true,
elevateEdgesOnSelect = false, elevateEdgesOnSelect = false,
disableKeyboardA11y = false, disableKeyboardA11y = false,
style, style,
@@ -261,6 +262,7 @@ const ReactFlow = forwardRef<ReactFlowRefType, ReactFlowProps>(
nodesFocusable={nodesFocusable} nodesFocusable={nodesFocusable}
edgesFocusable={edgesFocusable} edgesFocusable={edgesFocusable}
elementsSelectable={elementsSelectable} elementsSelectable={elementsSelectable}
elevateNodesOnSelect={elevateNodesOnSelect}
minZoom={minZoom} minZoom={minZoom}
maxZoom={maxZoom} maxZoom={maxZoom}
nodeExtent={nodeExtent} nodeExtent={nodeExtent}
+7 -5
View File
@@ -24,8 +24,8 @@ const createRFStore = () =>
createStore<ReactFlowState>((set, get) => ({ createStore<ReactFlowState>((set, get) => ({
...initialState, ...initialState,
setNodes: (nodes: Node[]) => { setNodes: (nodes: Node[]) => {
const { nodeInternals, nodeOrigin } = get(); const { nodeInternals, nodeOrigin, elevateNodesOnSelect } = get();
set({ nodeInternals: createNodeInternals(nodes, nodeInternals, nodeOrigin) }); set({ nodeInternals: createNodeInternals(nodes, nodeInternals, nodeOrigin, elevateNodesOnSelect) });
}, },
getNodes: () => { getNodes: () => {
return Array.from(get().nodeInternals.values()); return Array.from(get().nodeInternals.values());
@@ -38,7 +38,9 @@ const createRFStore = () =>
const hasDefaultNodes = typeof nodes !== 'undefined'; const hasDefaultNodes = typeof nodes !== 'undefined';
const hasDefaultEdges = typeof edges !== 'undefined'; const hasDefaultEdges = typeof edges !== 'undefined';
const nodeInternals = hasDefaultNodes ? createNodeInternals(nodes, new Map(), get().nodeOrigin) : new Map(); const nodeInternals = hasDefaultNodes
? createNodeInternals(nodes, new Map(), get().nodeOrigin, get().elevateNodesOnSelect)
: new Map();
const nextEdges = hasDefaultEdges ? edges : []; const nextEdges = hasDefaultEdges ? edges : [];
set({ nodeInternals, edges: nextEdges, hasDefaultNodes, hasDefaultEdges }); set({ nodeInternals, edges: nextEdges, hasDefaultNodes, hasDefaultEdges });
@@ -128,12 +130,12 @@ const createRFStore = () =>
}, },
triggerNodeChanges: (changes: NodeChange[]) => { triggerNodeChanges: (changes: NodeChange[]) => {
const { onNodesChange, nodeInternals, hasDefaultNodes, nodeOrigin, getNodes } = get(); const { onNodesChange, nodeInternals, hasDefaultNodes, nodeOrigin, getNodes, elevateNodesOnSelect } = get();
if (changes?.length) { if (changes?.length) {
if (hasDefaultNodes) { if (hasDefaultNodes) {
const nodes = applyNodeChanges(changes, getNodes()); const nodes = applyNodeChanges(changes, getNodes());
const nextNodeInternals = createNodeInternals(nodes, nodeInternals, nodeOrigin); const nextNodeInternals = createNodeInternals(nodes, nodeInternals, nodeOrigin, elevateNodesOnSelect);
set({ nodeInternals: nextNodeInternals }); set({ nodeInternals: nextNodeInternals });
} }
+1
View File
@@ -45,6 +45,7 @@ const initialState: ReactFlowStore = {
nodesFocusable: true, nodesFocusable: true,
edgesFocusable: true, edgesFocusable: true,
elementsSelectable: true, elementsSelectable: true,
elevateNodesOnSelect: true,
fitViewOnInit: false, fitViewOnInit: false,
fitViewOnInitDone: false, fitViewOnInitDone: false,
fitViewOnInitOptions: undefined, fitViewOnInitOptions: undefined,
+4 -2
View File
@@ -46,13 +46,15 @@ function calculateXYZPosition(
export function createNodeInternals( export function createNodeInternals(
nodes: Node[], nodes: Node[],
nodeInternals: NodeInternals, nodeInternals: NodeInternals,
nodeOrigin: NodeOrigin nodeOrigin: NodeOrigin,
elevateNodesOnSelect: boolean
): NodeInternals { ): NodeInternals {
const nextNodeInternals = new Map<string, Node>(); const nextNodeInternals = new Map<string, Node>();
const parentNodes: ParentNodes = {}; const parentNodes: ParentNodes = {};
const selectedNodeZ: number = elevateNodesOnSelect ? 1000 : 0;
nodes.forEach((node) => { nodes.forEach((node) => {
const z = (isNumeric(node.zIndex) ? node.zIndex : 0) + (node.selected ? 1000 : 0); const z = (isNumeric(node.zIndex) ? node.zIndex : 0) + (node.selected ? selectedNodeZ : 0);
const currInternals = nodeInternals.get(node.id); const currInternals = nodeInternals.get(node.id);
const internals: Node = { const internals: Node = {
@@ -136,6 +136,7 @@ export type ReactFlowProps = HTMLAttributes<HTMLDivElement> & {
connectOnClick?: boolean; connectOnClick?: boolean;
attributionPosition?: PanelPosition; attributionPosition?: PanelPosition;
proOptions?: ProOptions; proOptions?: ProOptions;
elevateNodesOnSelect?: boolean;
elevateEdgesOnSelect?: boolean; elevateEdgesOnSelect?: boolean;
disableKeyboardA11y?: boolean; disableKeyboardA11y?: boolean;
}; };
+1
View File
@@ -171,6 +171,7 @@ export type ReactFlowStore = {
nodesFocusable: boolean; nodesFocusable: boolean;
edgesFocusable: boolean; edgesFocusable: boolean;
elementsSelectable: boolean; elementsSelectable: boolean;
elevateNodesOnSelect: boolean;
multiSelectionActive: boolean; multiSelectionActive: boolean;