@hitachivantara/uikit-react-lab
Version:
Contributed React components to UI Kit by the community.
114 lines (113 loc) • 4.03 kB
JavaScript
import { useFlowInstance } from "./useFlowInstance.js";
import { useNodeId as useNodeId$1 } from "./useNodeId.js";
import { useCallback, useMemo } from "react";
import { useEdges, useNodes, useStore } from "reactflow";
import { shallow } from "zustand/shallow";
//#region src/Flow/hooks/useFlowNode.ts
/** Uses coordinates to create the relative position vector */
function relativePosition(positionA, positionB) {
if (positionA && positionB) return {
x: positionB.x - positionA.x,
y: positionB.y - positionA.y
};
return {
x: 0,
y: 0
};
}
/** Retrieves the node instance */
function useFlowNode(id) {
const nodeId = useNodeId$1(id);
return useStore(useCallback((state) => state.getNodes().find((n) => n.id === nodeId), [nodeId]), shallow);
}
/** Provides the input edges connected to the node */
function useFlowNodeInputEdges(id) {
const nodeId = useNodeId$1(id);
return useStore(useCallback((state) => state.edges.filter((e) => e.target === nodeId), [nodeId]), shallow);
}
/** Gives the output edges connected from the node */
function useFlowNodeOutputEdges(id) {
const nodeId = useNodeId$1(id);
return useStore(useCallback((state) => state.edges.filter((e) => e.source === nodeId), [nodeId]), shallow);
}
/** Offers both input and output edges of the node */
function useFlowNodeEdges(id) {
const nodeId = useNodeId$1(id);
return useStore(useCallback((state) => state.edges.filter((e) => e.source === nodeId || e.target === nodeId), [nodeId]), shallow);
}
/** Gets the parent nodes of a specified node (nodes that have an output connected to one of the inputs of the node) */
function useFlowNodeParents(id) {
const inputEdges = useFlowNodeInputEdges(id);
return useStore(useCallback((state) => {
return inputEdges.map((e) => state.getNodes().find((n) => n.id === e.source)).filter((n) => n !== null);
}, [inputEdges]), shallow);
}
/** Retrieves the nodes connected to the inputs of the node */
function useFlowInputNodes(id) {
const nodeId = useNodeId$1(id);
const nodes = useNodes();
const edges = useEdges();
return useMemo(() => {
return edges.filter((e) => e.target === nodeId).map((e) => nodes.find((n) => n.id === e.source)).filter((n) => n !== null);
}, [
edges,
nodeId,
nodes
]);
}
/** Retrieves the nodes connected to the outputs of the node */
function useFlowOutputNodes(id) {
const nodeId = useNodeId$1(id);
const nodes = useNodes();
const edges = useEdges();
return useMemo(() => {
return edges.filter((e) => e.source === nodeId).map((e) => nodes.find((n) => n.id === e.target)).filter((n) => n !== null);
}, [
edges,
nodeId,
nodes
]);
}
/** Utilities to manipulate a node in the flow */
function useFlowNodeUtils(id) {
const nodeId = useNodeId$1(id);
const reactFlowInstance = useFlowInstance();
/** Mutate the node's `.data` object */
const setNodeData = useCallback((setNewData) => {
if (!nodeId) return;
reactFlowInstance.setNodes((nodes) => {
return nodes.map((n) => {
if (n.id === nodeId) return {
...n,
data: setNewData(n.data)
};
return n;
});
});
}, [nodeId, reactFlowInstance]);
const setNodeParent = useCallback((node, extent) => {
if (!nodeId) return;
reactFlowInstance.setNodes((nodes) => {
return nodes.map((n) => {
if (n.id === nodeId) return {
...n,
parentId: node ? node.id : void 0,
extent,
position: node ? relativePosition(node.position, n.position) : n.positionAbsolute ?? n.position
};
return n;
});
});
}, [nodeId, reactFlowInstance]);
return useMemo(() => ({
setNodeData,
setNodeParent
}), [setNodeData, setNodeParent]);
}
function useFlowNodeIntersections(id) {
const node = useFlowNode(useNodeId$1(id) ?? "");
const reactFlowInstance = useFlowInstance();
return node ? reactFlowInstance.getIntersectingNodes(node, false) : [];
}
//#endregion
export { useFlowInputNodes, useFlowNode, useFlowNodeEdges, useFlowNodeInputEdges, useFlowNodeIntersections, useFlowNodeOutputEdges, useFlowNodeParents, useFlowNodeUtils, useFlowOutputNodes };