diff --git a/src/container/NodeRenderer/index.tsx b/src/container/NodeRenderer/index.tsx index 002b015a..3c2025cc 100644 --- a/src/container/NodeRenderer/index.tsx +++ b/src/container/NodeRenderer/index.tsx @@ -44,14 +44,12 @@ interface NodesProps extends NodeRendererProps { parentId?: string; } -interface NodeProps extends NodesProps { - nodes: Node[]; +interface NodeProps extends Omit { node: Node; nodeType: string; } function Node({ - nodes, node, nodeType, isDraggable, @@ -79,7 +77,7 @@ function Node({ typeof node.width !== 'undefined' && typeof node.height !== 'undefined'; - const childNodes = useMemo(() => nodes.filter((n) => n.parentNode === node.id && !n.isHidden), [nodes, node.id]); + const { childNodes = [] } = node; const childRect = useMemo(() => getRectOfNodes(childNodes), [childNodes]); const isParentNode = !!childNodes.length; @@ -147,7 +145,6 @@ function Node({ function Nodes({ nodes, - parentId, isDraggable, resizeObserver, scale, @@ -159,12 +156,7 @@ function Nodes({ recursionDepth, ...props }: NodesProps): any { - const rootNodes = useMemo( - () => (parentId ? nodes.filter((n) => n.parentNode === parentId) : nodes.filter((n) => !n.parentNode)), - [nodes, parentId] - ); - - return rootNodes.map((node) => { + return nodes.map((node) => { const nodeType = node.type || 'default'; if (!props.nodeTypes[nodeType]) { @@ -175,7 +167,6 @@ function Nodes({ - + {node.childNodes && node.childNodes.length > 0 && ( + + )} ); }); diff --git a/src/hooks/useVisibleNodes.ts b/src/hooks/useVisibleNodes.ts index d6c9bd96..4a56f2f4 100644 --- a/src/hooks/useVisibleNodes.ts +++ b/src/hooks/useVisibleNodes.ts @@ -2,7 +2,26 @@ import { useCallback } from 'react'; import { useStore } from '../store'; import { getNodesInside } from '../utils/graph'; -import { ReactFlowState } from '../types'; +import { ReactFlowState, Node } from '../types'; + +function getChildNodes(nodes: Node[], parent?: Node): Node[] { + const children: Node[] = []; + const remaining: Node[] = []; + + for (let i = 0; i < nodes.length; i++) { + const n = nodes[i]; + if ((!parent && !n.parentNode) || n.parentNode === parent?.id) { + children.push(n); + } else { + remaining.push(n); + } + } + + return children.map((child) => { + child.childNodes = getChildNodes(remaining, child); + return child; + }); +} function useVisibleNodes(onlyRenderVisible: boolean) { const nodes = useStore( @@ -16,7 +35,7 @@ function useVisibleNodes(onlyRenderVisible: boolean) { ) ); - return nodes; + return getChildNodes(nodes); } export default useVisibleNodes; diff --git a/src/types/index.ts b/src/types/index.ts index 23fbb7e1..3ecfaa10 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -87,6 +87,7 @@ export interface Node { height?: number | null; handleBounds?: NodeHandleBounds; parentNode?: ElementId; + childNodes?: Node[]; } export enum ArrowHeadType {