diff --git a/packages/svelte/src/lib/components/NodeWrapper/NodeWrapper.svelte b/packages/svelte/src/lib/components/NodeWrapper/NodeWrapper.svelte index 8f13be9b..7ba52792 100644 --- a/packages/svelte/src/lib/components/NodeWrapper/NodeWrapper.svelte +++ b/packages/svelte/src/lib/components/NodeWrapper/NodeWrapper.svelte @@ -141,7 +141,7 @@ handleNodeSelection(id); } - dispatchNodeEvent('nodeclick', { node, event }); + dispatchNodeEvent('nodeclick', { node: node.internals.userNode, event }); } diff --git a/packages/svelte/src/lib/components/NodeWrapper/types.ts b/packages/svelte/src/lib/components/NodeWrapper/types.ts index 7277be5f..842eb70b 100644 --- a/packages/svelte/src/lib/components/NodeWrapper/types.ts +++ b/packages/svelte/src/lib/components/NodeWrapper/types.ts @@ -1,4 +1,4 @@ -import type { Node } from '$lib/types'; +import type { InternalNode, Node } from '$lib/types'; export type NodeWrapperProps = Pick< Node, @@ -32,6 +32,6 @@ export type NodeWrapperProps = Pick< resizeObserver?: ResizeObserver | null; isParent?: boolean; zIndex: number; - node: Node; + node: InternalNode; initialized: boolean; }; diff --git a/packages/svelte/src/lib/hooks/useInternalNode.ts b/packages/svelte/src/lib/hooks/useInternalNode.ts new file mode 100644 index 00000000..16c83960 --- /dev/null +++ b/packages/svelte/src/lib/hooks/useInternalNode.ts @@ -0,0 +1,17 @@ +import { derived, type Readable } from 'svelte/store'; + +import { useStore } from '$lib/store'; +import type { InternalNode } from '$lib/types'; + +/** + * Hook to get an internal node by id. + * + * @public + * @param id - the node id + * @returns a readable with an internal node or undefined + */ +export function useInternalNode(id: string): Readable { + const { nodeLookup, nodes } = useStore(); + + return derived([nodeLookup, nodes], ([nodeLookup]) => nodeLookup.get(id)); +} diff --git a/packages/svelte/src/lib/hooks/useSvelteFlow.ts b/packages/svelte/src/lib/hooks/useSvelteFlow.ts index 6c83418f..be40af64 100644 --- a/packages/svelte/src/lib/hooks/useSvelteFlow.ts +++ b/packages/svelte/src/lib/hooks/useSvelteFlow.ts @@ -18,7 +18,7 @@ import { } from '@xyflow/system'; import { useStore } from '$lib/store'; -import type { Edge, FitViewOptions, Node } from '$lib/types'; +import type { Edge, FitViewOptions, InternalNode, Node } from '$lib/types'; import { isNode } from '$lib/utils'; /** @@ -41,6 +41,13 @@ export function useSvelteFlow(): { * @param options.duration - optional duration. If set, a transition will be applied */ zoomOut: ZoomInOut; + /** + * Returns an internal node by id. + * + * @param id - the node id + * @returns the node or undefined if no node was found + */ + getInternalNode: (id: string) => InternalNode | undefined; /** * Returns a node by id. * @@ -280,10 +287,13 @@ export function useSvelteFlow(): { } }; + const getInternalNode = (id: string) => get(nodeLookup).get(id); + return { zoomIn, zoomOut, - getNode: (id) => get(nodeLookup).get(id), + getInternalNode, + getNode: (id) => getInternalNode(id)?.internals.userNode, getNodes: (ids) => (ids === undefined ? get(nodes) : getElements(get(nodeLookup), ids)), getEdge: (id) => get(edgeLookup).get(id), getEdges: (ids) => (ids === undefined ? get(edges) : getElements(get(edgeLookup), ids)), @@ -474,14 +484,17 @@ export function useSvelteFlow(): { viewport }; } - -function getElements(lookup: Map, ids: string[]) { +function getElements(lookup: Map, ids: string[]): Node[]; +function getElements(lookup: Map, ids: string[]): Edge[]; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function getElements(lookup: Map, ids: string[]): any[] { const result = []; for (const id of ids) { - const element = lookup.get(id); + const item = lookup.get(id); - if (element) { + if (item) { + const element = 'internals' in item ? item.internals?.userNode : item; result.push(element); } }