From 10f31e79e66419ce0280113caa50be5adb07de86 Mon Sep 17 00:00:00 2001 From: moklick Date: Thu, 7 Dec 2023 12:24:03 +0100 Subject: [PATCH] refactor(types): use custom node type as generic --- .../additional-components/MiniMap/types.ts | 16 ++--- packages/react/src/hooks/useNodes.ts | 4 +- .../react/src/hooks/useNodesEdgesState.ts | 12 ++-- packages/react/src/hooks/useReactFlow.ts | 59 ++++++++-------- packages/react/src/types/changes.ts | 16 ++--- packages/react/src/types/edges.ts | 34 +++++++++- packages/react/src/types/general.ts | 13 ++-- packages/react/src/types/instance.ts | 67 ++++++++++--------- packages/react/src/types/nodes.ts | 21 +++--- packages/react/src/utils/changes.ts | 8 +-- packages/svelte/src/lib/types/edges.ts | 18 +++++ packages/svelte/src/lib/types/nodes.ts | 8 +-- 12 files changed, 160 insertions(+), 116 deletions(-) diff --git a/packages/react/src/additional-components/MiniMap/types.ts b/packages/react/src/additional-components/MiniMap/types.ts index 5667f7a8..3b24b08d 100644 --- a/packages/react/src/additional-components/MiniMap/types.ts +++ b/packages/react/src/additional-components/MiniMap/types.ts @@ -4,12 +4,12 @@ import type { PanelPosition, XYPosition } from '@xyflow/system'; import type { Node } from '../../types'; -export type GetMiniMapNodeAttribute = (node: Node) => string; +export type GetMiniMapNodeAttribute = (node: NodeType) => string; -export type MiniMapProps = Omit, 'onClick'> & { - nodeColor?: string | GetMiniMapNodeAttribute; - nodeStrokeColor?: string | GetMiniMapNodeAttribute; - nodeClassName?: string | GetMiniMapNodeAttribute; +export type MiniMapProps = Omit, 'onClick'> & { + nodeColor?: string | GetMiniMapNodeAttribute; + nodeStrokeColor?: string | GetMiniMapNodeAttribute; + nodeClassName?: string | GetMiniMapNodeAttribute; nodeBorderRadius?: number; nodeStrokeWidth?: number; nodeComponent?: ComponentType; @@ -18,7 +18,7 @@ export type MiniMapProps = Omit, ' maskStrokeWidth?: number; position?: PanelPosition; onClick?: (event: MouseEvent, position: XYPosition) => void; - onNodeClick?: (event: MouseEvent, node: Node) => void; + onNodeClick?: (event: MouseEvent, node: NodeType) => void; pannable?: boolean; zoomable?: boolean; ariaLabel?: string | null; @@ -27,8 +27,8 @@ export type MiniMapProps = Omit, ' offsetScale?: number; }; -export type MiniMapNodes = Pick< - MiniMapProps, +export type MiniMapNodes = Pick< + MiniMapProps, 'nodeColor' | 'nodeStrokeColor' | 'nodeClassName' | 'nodeBorderRadius' | 'nodeStrokeWidth' | 'nodeComponent' > & { onClick?: (event: MouseEvent, nodeId: string) => void; diff --git a/packages/react/src/hooks/useNodes.ts b/packages/react/src/hooks/useNodes.ts index cc75f142..1ccd1d85 100644 --- a/packages/react/src/hooks/useNodes.ts +++ b/packages/react/src/hooks/useNodes.ts @@ -5,8 +5,8 @@ import type { Node, ReactFlowState } from '../types'; const nodesSelector = (state: ReactFlowState) => state.nodes; -function useNodes(): Node[] { - const nodes = useStore(nodesSelector, shallow); +function useNodes(): NodeType[] { + const nodes = useStore(nodesSelector, shallow) as NodeType[]; return nodes; } diff --git a/packages/react/src/hooks/useNodesEdgesState.ts b/packages/react/src/hooks/useNodesEdgesState.ts index 19754aa4..5255c7dd 100644 --- a/packages/react/src/hooks/useNodesEdgesState.ts +++ b/packages/react/src/hooks/useNodesEdgesState.ts @@ -11,14 +11,14 @@ type OnChange = (changes: ChangesType[]) => void; // const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); function createUseItemsState( applyChanges: ApplyChanges -): ( - initialItems: Node[] -) => [Node[], Dispatch[]>>, OnChange]; +): ( + initialItems: NodeType[] +) => [NodeType[], Dispatch>, OnChange]; function createUseItemsState( applyChanges: ApplyChanges -): ( - initialItems: Edge[] -) => [Edge[], Dispatch[]>>, OnChange]; +): ( + initialItems: EdgeType[] +) => [EdgeType[], Dispatch>, OnChange]; function createUseItemsState( applyChanges: ApplyChanges ): (initialItems: any[]) => [any[], Dispatch>, OnChange] { diff --git a/packages/react/src/hooks/useReactFlow.ts b/packages/react/src/hooks/useReactFlow.ts index 44e29c14..2875ca03 100644 --- a/packages/react/src/hooks/useReactFlow.ts +++ b/packages/react/src/hooks/useReactFlow.ts @@ -26,31 +26,34 @@ import type { } from '../types'; /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ -export default function useReactFlow(): ReactFlowInstance { +export default function useReactFlow(): ReactFlowInstance< + NodeType, + EdgeType +> { const viewportHelper = useViewportHelper(); const store = useStoreApi(); - const getNodes = useCallback>(() => { - return store.getState().nodes.map((n) => ({ ...n })); + const getNodes = useCallback>(() => { + return store.getState().nodes.map((n) => ({ ...n })) as NodeType[]; }, []); - const getNode = useCallback>((id) => { - return store.getState().nodeLookup.get(id); + const getNode = useCallback>((id) => { + return store.getState().nodeLookup.get(id) as NodeType; }, []); - const getEdges = useCallback>(() => { + const getEdges = useCallback>(() => { const { edges = [] } = store.getState(); - return edges.map((e) => ({ ...e })); + return edges.map((e) => ({ ...e })) as EdgeType[]; }, []); - const getEdge = useCallback>((id) => { + const getEdge = useCallback>((id) => { const { edges = [] } = store.getState(); - return edges.find((e) => e.id === id); + return edges.find((e) => e.id === id) as EdgeType; }, []); - const setNodes = useCallback>((payload) => { + const setNodes = useCallback>((payload) => { const { nodes, setNodes, hasDefaultNodes, onNodesChange } = store.getState(); - const nextNodes = typeof payload === 'function' ? payload(nodes) : payload; + const nextNodes = typeof payload === 'function' ? payload(nodes as NodeType[]) : payload; if (hasDefaultNodes) { setNodes(nextNodes); @@ -58,14 +61,14 @@ export default function useReactFlow(): ReactFlo const changes = nextNodes.length === 0 ? nodes.map((node) => ({ type: 'remove', id: node.id } as NodeRemoveChange)) - : nextNodes.map((node) => ({ item: node, type: 'reset' } as NodeResetChange)); + : nextNodes.map((node) => ({ item: node, type: 'reset' } as NodeResetChange)); onNodesChange(changes); } }, []); - const setEdges = useCallback>((payload) => { + const setEdges = useCallback>((payload) => { const { edges = [], setEdges, hasDefaultEdges, onEdgesChange } = store.getState(); - const nextEdges = typeof payload === 'function' ? payload(edges) : payload; + const nextEdges = typeof payload === 'function' ? payload(edges as EdgeType[]) : payload; if (hasDefaultEdges) { setEdges(nextEdges); @@ -73,12 +76,12 @@ export default function useReactFlow(): ReactFlo const changes = nextEdges.length === 0 ? edges.map((edge) => ({ type: 'remove', id: edge.id } as EdgeRemoveChange)) - : nextEdges.map((edge) => ({ item: edge, type: 'reset' } as EdgeResetChange)); + : nextEdges.map((edge) => ({ item: edge, type: 'reset' } as EdgeResetChange)); onEdgesChange(changes); } }, []); - const addNodes = useCallback>((payload) => { + const addNodes = useCallback>((payload) => { const nodes = Array.isArray(payload) ? payload : [payload]; const { nodes: currentNodes, hasDefaultNodes, onNodesChange, setNodes } = store.getState(); @@ -86,29 +89,29 @@ export default function useReactFlow(): ReactFlo const nextNodes = [...currentNodes, ...nodes]; setNodes(nextNodes); } else if (onNodesChange) { - const changes = nodes.map((node) => ({ item: node, type: 'add' } as NodeAddChange)); + const changes = nodes.map((node) => ({ item: node, type: 'add' } as NodeAddChange)); onNodesChange(changes); } }, []); - const addEdges = useCallback>((payload) => { + const addEdges = useCallback>((payload) => { const nextEdges = Array.isArray(payload) ? payload : [payload]; const { edges = [], setEdges, hasDefaultEdges, onEdgesChange } = store.getState(); if (hasDefaultEdges) { setEdges([...edges, ...nextEdges]); } else if (onEdgesChange) { - const changes = nextEdges.map((edge) => ({ item: edge, type: 'add' } as EdgeAddChange)); + const changes = nextEdges.map((edge) => ({ item: edge, type: 'add' } as EdgeAddChange)); onEdgesChange(changes); } }, []); - const toObject = useCallback>(() => { + const toObject = useCallback>(() => { const { nodes = [], edges = [], transform } = store.getState(); const [x, y, zoom] = transform; return { - nodes: nodes.map((n) => ({ ...n })), - edges: edges.map((e) => ({ ...e })), + nodes: nodes.map((n) => ({ ...n })) as NodeType[], + edges: edges.map((e) => ({ ...e })) as EdgeType[], viewport: { x, y, @@ -180,11 +183,9 @@ export default function useReactFlow(): ReactFlo }, []); const getNodeRect = useCallback( - ( - nodeOrRect: Node | { id: Node['id'] } | Rect - ): [Rect | null, Node | null | undefined, boolean] => { + (nodeOrRect: NodeType | { id: Node['id'] } | Rect): [Rect | null, NodeType | null | undefined, boolean] => { const isRect = isRectObject(nodeOrRect); - const node = isRect ? null : store.getState().nodeLookup.get(nodeOrRect.id); + const node = isRect ? null : (store.getState().nodeLookup.get(nodeOrRect.id) as NodeType); if (!isRect && !node) { [null, null, isRect]; @@ -197,7 +198,7 @@ export default function useReactFlow(): ReactFlo [] ); - const getIntersectingNodes = useCallback>( + const getIntersectingNodes = useCallback>( (nodeOrRect, partially = true, nodes) => { const [nodeRect, node, isRect] = getNodeRect(nodeOrRect); @@ -215,12 +216,12 @@ export default function useReactFlow(): ReactFlo const partiallyVisible = partially && overlappingArea > 0; return partiallyVisible || overlappingArea >= nodeRect.width * nodeRect.height; - }); + }) as NodeType[]; }, [] ); - const isNodeIntersecting = useCallback>( + const isNodeIntersecting = useCallback>( (nodeOrRect, area, partially = true) => { const [nodeRect] = getNodeRect(nodeOrRect); diff --git a/packages/react/src/types/changes.ts b/packages/react/src/types/changes.ts index 69ee0f1f..440a4c6b 100644 --- a/packages/react/src/types/changes.ts +++ b/packages/react/src/types/changes.ts @@ -30,13 +30,13 @@ export type NodeRemoveChange = { type: 'remove'; }; -export type NodeAddChange = { - item: Node; +export type NodeAddChange = { + item: NodeType; type: 'add'; }; -export type NodeResetChange = { - item: Node; +export type NodeResetChange = { + item: NodeType; type: 'reset'; }; @@ -50,12 +50,12 @@ export type NodeChange = export type EdgeSelectionChange = NodeSelectionChange; export type EdgeRemoveChange = NodeRemoveChange; -export type EdgeAddChange = { - item: Edge; +export type EdgeAddChange = { + item: EdgeType; type: 'add'; }; -export type EdgeResetChange = { - item: Edge; +export type EdgeResetChange = { + item: EdgeType; type: 'reset'; }; export type EdgeChange = EdgeSelectionChange | EdgeRemoveChange | EdgeAddChange | EdgeResetChange; diff --git a/packages/react/src/types/edges.ts b/packages/react/src/types/edges.ts index fecd7c7b..836087fc 100644 --- a/packages/react/src/types/edges.ts +++ b/packages/react/src/types/edges.ts @@ -1,6 +1,13 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import type { CSSProperties, HTMLAttributes, ReactNode, MouseEvent as ReactMouseEvent, ComponentType } from 'react'; +import type { + CSSProperties, + HTMLAttributes, + ReactNode, + MouseEvent as ReactMouseEvent, + ComponentType, + MemoExoticComponent, +} from 'react'; import type { EdgeBase, BezierPathOptions, @@ -119,6 +126,9 @@ export type BaseEdgeProps = EdgeLabelOptions & { style?: CSSProperties; }; +/** + * Helper type for edge components that get exported by the library. + */ export type EdgeComponentProps = EdgePosition & EdgeLabelOptions & { id?: EdgeProps['id']; @@ -134,10 +144,29 @@ export type EdgeComponentWithPathOptions = EdgeComponentProps & { pathOptions?: PathOptions; }; +/** + * BezierEdge component props + */ export type BezierEdgeProps = EdgeComponentWithPathOptions; + +/** + * SmoothStepEdge component props + */ export type SmoothStepEdgeProps = EdgeComponentWithPathOptions; + +/** + * StepEdge component props + */ export type StepEdgeProps = EdgeComponentWithPathOptions; + +/** + * StraightEdge component props + */ export type StraightEdgeProps = Omit; + +/** + * SimpleBezier component props + */ export type SimpleBezierEdgeProps = EdgeComponentProps; export type OnEdgeUpdateFunc = (oldEdge: Edge, newConnection: Connection) => void; @@ -157,3 +186,6 @@ export type ConnectionLineComponentProps = { }; export type ConnectionLineComponent = ComponentType; + +export type EdgeTypes = { [key: string]: ComponentType }; +export type EdgeTypesWrapped = { [key: string]: MemoExoticComponent> }; diff --git a/packages/react/src/types/general.ts b/packages/react/src/types/general.ts index b2e7098a..a212b057 100644 --- a/packages/react/src/types/general.ts +++ b/packages/react/src/types/general.ts @@ -1,9 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import type { ComponentType, MemoExoticComponent } from 'react'; import { FitViewParamsBase, FitViewOptionsBase, - NodeProps, ZoomInOut, ZoomTo, SetViewport, @@ -14,7 +12,7 @@ import { XYPosition, } from '@xyflow/system'; -import type { NodeChange, EdgeChange, Node, WrapNodeProps, Edge, EdgeProps, WrapEdgeProps, ReactFlowInstance } from '.'; +import type { NodeChange, EdgeChange, Node, Edge, ReactFlowInstance } from '.'; export type OnNodesChange = (changes: NodeChange[]) => void; export type OnEdgesChange = (changes: EdgeChange[]) => void; @@ -23,11 +21,6 @@ export type OnNodesDelete = (nodes: Node[]) => void; export type OnEdgesDelete = (edges: Edge[]) => void; export type OnDelete = (params: { nodes: Node[]; edges: Edge[] }) => void; -export type NodeTypes = { [key: string]: ComponentType }; -export type NodeTypesWrapped = { [key: string]: MemoExoticComponent> }; -export type EdgeTypes = { [key: string]: ComponentType }; -export type EdgeTypesWrapped = { [key: string]: MemoExoticComponent> }; - export type UnselectNodesAndEdgesParams = { nodes?: Node[]; edges?: Edge[]; @@ -43,7 +36,9 @@ export type OnSelectionChangeFunc = (params: OnSelectionChangeParams) => void; export type FitViewParams = FitViewParamsBase; export type FitViewOptions = FitViewOptionsBase; export type FitView = (fitViewOptions?: FitViewOptions) => boolean; -export type OnInit = (reactFlowInstance: ReactFlowInstance) => void; +export type OnInit = ( + reactFlowInstance: ReactFlowInstance +) => void; export type ViewportHelperFunctions = { zoomIn: ZoomInOut; diff --git a/packages/react/src/types/instance.ts b/packages/react/src/types/instance.ts index f229ec87..6ac81e04 100644 --- a/packages/react/src/types/instance.ts +++ b/packages/react/src/types/instance.ts @@ -3,9 +3,9 @@ import type { Rect, Viewport } from '@xyflow/system'; import type { Node, Edge, ViewportHelperFunctions } from '.'; -export type ReactFlowJsonObject = { - nodes: Node[]; - edges: Edge[]; +export type ReactFlowJsonObject = { + nodes: NodeType[]; + edges: EdgeType[]; viewport: Viewport; }; @@ -15,30 +15,33 @@ export type DeleteElementsOptions = { }; export namespace Instance { - export type GetNodes = () => Node[]; - export type SetNodes = ( - payload: Node[] | ((nodes: Node[]) => Node[]) + export type GetNodes = () => NodeType[]; + export type SetNodes = ( + payload: NodeType[] | ((nodes: NodeType[]) => NodeType[]) ) => void; - export type AddNodes = (payload: Node[] | Node) => void; - export type GetNode = (id: string) => Node | undefined; - export type GetEdges = () => Edge[]; - export type SetEdges = ( - payload: Edge[] | ((edges: Edge[]) => Edge[]) + export type AddNodes = (payload: NodeType[] | NodeType) => void; + export type GetNode = (id: string) => NodeType | undefined; + export type GetEdges = () => EdgeType[]; + export type SetEdges = ( + payload: EdgeType[] | ((edges: EdgeType[]) => EdgeType[]) ) => void; - export type GetEdge = (id: string) => Edge | undefined; - export type AddEdges = (payload: Edge[] | Edge) => void; - export type ToObject = () => ReactFlowJsonObject; + export type GetEdge = (id: string) => EdgeType | undefined; + export type AddEdges = (payload: EdgeType[] | EdgeType) => void; + export type ToObject = () => ReactFlowJsonObject< + NodeType, + EdgeType + >; export type DeleteElements = ({ nodes, edges }: DeleteElementsOptions) => { deletedNodes: Node[]; deletedEdges: Edge[]; }; - export type GetIntersectingNodes = ( - node: Node | { id: Node['id'] } | Rect, + export type GetIntersectingNodes = ( + node: NodeType | { id: Node['id'] } | Rect, partially?: boolean, - nodes?: Node[] - ) => Node[]; - export type IsNodeIntersecting = ( - node: Node | { id: Node['id'] } | Rect, + nodes?: NodeType[] + ) => NodeType[]; + export type IsNodeIntersecting = ( + node: NodeType | { id: Node['id'] } | Rect, area: Rect, partially?: boolean ) => boolean; @@ -47,18 +50,18 @@ export namespace Instance { export type getOutgoers = (node: string | Node | { id: Node['id'] }) => Node[]; } -export type ReactFlowInstance = { - getNodes: Instance.GetNodes; - setNodes: Instance.SetNodes; - addNodes: Instance.AddNodes; - getNode: Instance.GetNode; - getEdges: Instance.GetEdges; - setEdges: Instance.SetEdges; - addEdges: Instance.AddEdges; - getEdge: Instance.GetEdge; - toObject: Instance.ToObject; +export type ReactFlowInstance = { + getNodes: Instance.GetNodes; + setNodes: Instance.SetNodes; + addNodes: Instance.AddNodes; + getNode: Instance.GetNode; + getEdges: Instance.GetEdges; + setEdges: Instance.SetEdges; + addEdges: Instance.AddEdges; + getEdge: Instance.GetEdge; + toObject: Instance.ToObject; deleteElements: Instance.DeleteElements; - getIntersectingNodes: Instance.GetIntersectingNodes; - isNodeIntersecting: Instance.IsNodeIntersecting; + getIntersectingNodes: Instance.GetIntersectingNodes; + isNodeIntersecting: Instance.IsNodeIntersecting; viewportInitialized: boolean; } & Omit; diff --git a/packages/react/src/types/nodes.ts b/packages/react/src/types/nodes.ts index 4d10b76b..7bccfe0a 100644 --- a/packages/react/src/types/nodes.ts +++ b/packages/react/src/types/nodes.ts @@ -1,5 +1,6 @@ -import type { CSSProperties, MouseEvent as ReactMouseEvent } from 'react'; -import type { NodeBase, XYPosition } from '@xyflow/system'; +/* eslint-disable @typescript-eslint/no-explicit-any */ +import type { CSSProperties, ComponentType, MemoExoticComponent, MouseEvent as ReactMouseEvent } from 'react'; +import type { NodeBase, NodeProps, XYPosition } from '@xyflow/system'; /** * The node data structure that gets used for the nodes prop. @@ -9,17 +10,8 @@ export type Node & { - /** - * Inline style object - */ style?: CSSProperties; - /** - * Inline style object - */ className?: string; - /** - * Inline style object - */ resizing?: boolean; }; @@ -27,8 +19,8 @@ export type NodeMouseHandler = (event: ReactMouseEvent, node: Node) => void; export type NodeDragHandler = (event: ReactMouseEvent, node: Node, nodes: Node[]) => void; export type SelectionDragHandler = (event: ReactMouseEvent, nodes: Node[]) => void; -export type WrapNodeProps = Pick< - Node, +export type WrapNodeProps = Pick< + NodeType, 'id' | 'data' | 'style' | 'className' | 'dragHandle' | 'sourcePosition' | 'targetPosition' | 'hidden' | 'ariaLabel' > & { type: string; @@ -59,3 +51,6 @@ export type WrapNodeProps = Pick< width?: number; height?: number; }; + +export type NodeTypes = { [key: string]: ComponentType }; +export type NodeTypesWrapped = { [key: string]: MemoExoticComponent> }; diff --git a/packages/react/src/utils/changes.ts b/packages/react/src/utils/changes.ts index 0cf87e6f..72e28b9e 100644 --- a/packages/react/src/utils/changes.ts +++ b/packages/react/src/utils/changes.ts @@ -159,8 +159,8 @@ function applyChanges(changes: any[], elements: any[]): any[] { ); */ -export function applyNodeChanges(changes: NodeChange[], nodes: Node[]): Node[] { - return applyChanges(changes, nodes) as Node[]; +export function applyNodeChanges(changes: NodeChange[], nodes: NodeType[]): NodeType[] { + return applyChanges(changes, nodes) as NodeType[]; } /** @@ -183,8 +183,8 @@ export function applyNodeChanges(changes: NodeChange[], nodes: N ); */ -export function applyEdgeChanges(changes: EdgeChange[], edges: Edge[]): Edge[] { - return applyChanges(changes, edges) as Edge[]; +export function applyEdgeChanges(changes: EdgeChange[], edges: EdgeType[]): EdgeType[] { + return applyChanges(changes, edges) as EdgeType[]; } export const createSelectionChange = (id: string, selected: boolean) => ({ diff --git a/packages/svelte/src/lib/types/edges.ts b/packages/svelte/src/lib/types/edges.ts index c1d3778d..218c7e6f 100644 --- a/packages/svelte/src/lib/types/edges.ts +++ b/packages/svelte/src/lib/types/edges.ts @@ -53,6 +53,9 @@ export type EdgeProps = Omit, 'sourceHandle' | 'targetHandle' | targetHandleId?: string | null; }; +/** + * Helper type for edge components that get exported by the library. + */ export type EdgeComponentProps = EdgePosition & { id?: EdgeProps['id']; hidden?: EdgeProps['hidden']; @@ -73,9 +76,24 @@ export type EdgeComponentWithPathOptions = EdgeComponentProps & { pathOptions?: PathOptions; }; +/** + * BezierEdge component props + */ export type BezierEdgeProps = EdgeComponentWithPathOptions; + +/** + * SmoothStepEdge component props + */ export type SmoothStepEdgeProps = EdgeComponentWithPathOptions; + +/** + * StepEdge component props + */ export type StepEdgeProps = EdgeComponentWithPathOptions; + +/** + * StraightEdge component props + */ export type StraightEdgeProps = Omit; export type EdgeTypes = Record>>; diff --git a/packages/svelte/src/lib/types/nodes.ts b/packages/svelte/src/lib/types/nodes.ts index 292ae4fa..4121754a 100644 --- a/packages/svelte/src/lib/types/nodes.ts +++ b/packages/svelte/src/lib/types/nodes.ts @@ -1,11 +1,11 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ - import type { ComponentType, SvelteComponent } from 'svelte'; import type { NodeBase, NodeProps } from '@xyflow/system'; -// @todo: currently the helper function only like Node from '@reactflow/core' -// we need a base node type or helpes that accept Node like types -// eslint-disable-next-line @typescript-eslint/no-explicit-any +/** + * The node data structure that gets used for the nodes prop. + * @public + */ export type Node< NodeData = any, NodeType extends string | undefined = string | undefined