diff --git a/examples/react/src/examples/UseNodesData/TextNode.tsx b/examples/react/src/examples/UseNodesData/TextNode.tsx index a7388cb0..e787d824 100644 --- a/examples/react/src/examples/UseNodesData/TextNode.tsx +++ b/examples/react/src/examples/UseNodesData/TextNode.tsx @@ -1,10 +1,10 @@ import { memo, ChangeEventHandler } from 'react'; -import { Position, NodeProps, useUpdateNodeData, Handle } from '@xyflow/react'; +import { Position, NodeProps, useSetNodeData, Handle } from '@xyflow/react'; function TextNode({ id, data }: NodeProps) { - const updateNodeData = useUpdateNodeData(); + const setNodeData = useSetNodeData(); - const onChange: ChangeEventHandler = (evt) => updateNodeData(id, { text: evt.target.value }); + const onChange: ChangeEventHandler = (evt) => setNodeData(id, { text: evt.target.value }); return (
diff --git a/examples/react/src/examples/UseNodesData/UppercaseNode.tsx b/examples/react/src/examples/UseNodesData/UppercaseNode.tsx index 438c25cc..47ecd87c 100644 --- a/examples/react/src/examples/UseNodesData/UppercaseNode.tsx +++ b/examples/react/src/examples/UseNodesData/UppercaseNode.tsx @@ -1,15 +1,15 @@ import { memo, useEffect } from 'react'; -import { Position, NodeProps, useUpdateNodeData, Handle, useHandleConnections, useNodesData } from '@xyflow/react'; +import { Position, NodeProps, useSetNodeData, Handle, useHandleConnections, useNodesData } from '@xyflow/react'; function UppercaseNode({ id }: NodeProps) { const connections = useHandleConnections({ type: 'target', }); const nodeData = useNodesData(connections[0]?.source); - const updateNodeData = useUpdateNodeData(); + const setNodeData = useSetNodeData(); useEffect(() => { - updateNodeData(id, { text: nodeData?.text.toUpperCase() }); + setNodeData(id, { text: nodeData?.text.toUpperCase() }); }, [nodeData]); return ( diff --git a/examples/svelte/src/routes/examples/usenodesdata/ResultNode.svelte b/examples/svelte/src/routes/examples/usenodesdata/ResultNode.svelte index 2664e8ef..9dd98173 100644 --- a/examples/svelte/src/routes/examples/usenodesdata/ResultNode.svelte +++ b/examples/svelte/src/routes/examples/usenodesdata/ResultNode.svelte @@ -4,7 +4,6 @@ Position, useHandleConnections, useNodesData, - useUpdateNodeData, type NodeProps } from '@xyflow/svelte'; diff --git a/examples/svelte/src/routes/examples/usenodesdata/TextNode.svelte b/examples/svelte/src/routes/examples/usenodesdata/TextNode.svelte index 142a14bb..63f2d83b 100644 --- a/examples/svelte/src/routes/examples/usenodesdata/TextNode.svelte +++ b/examples/svelte/src/routes/examples/usenodesdata/TextNode.svelte @@ -1,12 +1,12 @@
@@ -14,7 +14,7 @@
updateNodeData(id, { text: evt.currentTarget.value })} + on:input={(evt) => setNodeData(id, { text: evt.currentTarget.value })} />
diff --git a/examples/svelte/src/routes/examples/usenodesdata/UppercaseNode.svelte b/examples/svelte/src/routes/examples/usenodesdata/UppercaseNode.svelte index 3e311f1f..b23481d8 100644 --- a/examples/svelte/src/routes/examples/usenodesdata/UppercaseNode.svelte +++ b/examples/svelte/src/routes/examples/usenodesdata/UppercaseNode.svelte @@ -5,14 +5,14 @@ type NodeProps, useHandleConnections, useNodesData, - useUpdateNodeData + useSetNodeData } from '@xyflow/svelte'; type $$Props = NodeProps; export let id: $$Props['id']; - const updateNodeData = useUpdateNodeData(); + const setNodeData = useSetNodeData(); const connections = useHandleConnections({ nodeId: id, type: 'target' @@ -21,7 +21,7 @@ $: nodeData = useNodesData($connections[0]?.source); $: { - updateNodeData(id, { text: $nodeData?.text?.toUpperCase() || '' }); + setNodeData(id, { text: $nodeData?.text?.toUpperCase() || '' }); } diff --git a/packages/react/src/hooks/useSetNodeData.ts b/packages/react/src/hooks/useSetNodeData.ts new file mode 100644 index 00000000..16d33f66 --- /dev/null +++ b/packages/react/src/hooks/useSetNodeData.ts @@ -0,0 +1,30 @@ +import { useCallback } from 'react'; + +import useReactFlow from './useReactFlow'; +import { Node } from '../types'; + +export function useSetNodeData() { + const { setNodes } = useReactFlow(); + + const setNodeData = useCallback( + function setNodesData( + id: string, + dataUpdate: object | ((node: NodeType) => object), + options: { replace: boolean } = { replace: true } + ) { + setNodes((prevNodes) => + prevNodes.map((node) => { + if (node.id === id) { + const nextData = typeof dataUpdate === 'function' ? dataUpdate(node as NodeType) : dataUpdate; + return options.replace ? { ...node, data: nextData } : { ...node, data: { ...node.data, ...nextData } }; + } + + return node; + }) + ); + }, + [setNodes] + ); + + return setNodeData; +} diff --git a/packages/react/src/hooks/useUpdateNodeData.ts b/packages/react/src/hooks/useUpdateNodeData.ts deleted file mode 100644 index 10cd71e2..00000000 --- a/packages/react/src/hooks/useUpdateNodeData.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { useCallback } from 'react'; - -import useReactFlow from './useReactFlow'; - -export function useUpdateNodeData() { - const { setNodes } = useReactFlow(); - - const updateNodeData = useCallback((id: string, data: unknown) => { - setNodes((prevNodes) => prevNodes.map((node) => (node.id === id ? { ...node, data } : node))); - }, []); - - return updateNodeData; -} diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index 63b70c98..ab450904 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -23,7 +23,7 @@ export { default as useOnViewportChange, type UseOnViewportChangeOptions } from export { default as useOnSelectionChange, type UseOnSelectionChangeOptions } from './hooks/useOnSelectionChange'; export { default as useNodesInitialized, type UseNodesInitializedOptions } from './hooks/useNodesInitialized'; export { useHandleConnections } from './hooks/useHandleConnections'; -export { useUpdateNodeData } from './hooks/useUpdateNodeData'; +export { useSetNodeData } from './hooks/useSetNodeData'; export { useNodesData } from './hooks/useNodesData'; export { useNodeId } from './contexts/NodeIdContext'; diff --git a/packages/svelte/src/lib/hooks/useSetNodeData.ts b/packages/svelte/src/lib/hooks/useSetNodeData.ts new file mode 100644 index 00000000..51aaaacb --- /dev/null +++ b/packages/svelte/src/lib/hooks/useSetNodeData.ts @@ -0,0 +1,28 @@ +import { useStore } from '$lib/store'; +import type { Node } from '$lib/types'; + +export function useSetNodeData() { + const { nodes } = useStore(); + + const setNodeData = ( + id: string, + dataUpdate: object | ((node: NodeType) => object), + options: { replace: boolean } = { replace: true } + ) => { + nodes.update((nds) => + nds.map((node) => { + if (node.id === id) { + const nextData = + typeof dataUpdate === 'function' ? dataUpdate(node as NodeType) : dataUpdate; + return options.replace + ? { ...node, data: nextData } + : { ...node, data: { ...node.data, ...nextData } }; + } + + return node; + }) + ); + }; + + return setNodeData; +} diff --git a/packages/svelte/src/lib/hooks/useUpdateNodeData.ts b/packages/svelte/src/lib/hooks/useUpdateNodeData.ts deleted file mode 100644 index cb45dd10..00000000 --- a/packages/svelte/src/lib/hooks/useUpdateNodeData.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { useStore } from '$lib/store'; - -export function useUpdateNodeData(): (id: string, data: unknown) => void { - const { nodes } = useStore(); - - const updateNodeData = (id: string, data: unknown) => { - nodes.update((nds) => - nds.map((node) => { - if (node.id === id) { - return { - ...node, - data - }; - } - - return node; - }) - ); - }; - - return updateNodeData; -} diff --git a/packages/svelte/src/lib/index.ts b/packages/svelte/src/lib/index.ts index 71841ec7..4675f2ca 100644 --- a/packages/svelte/src/lib/index.ts +++ b/packages/svelte/src/lib/index.ts @@ -29,7 +29,7 @@ export * from '$lib/hooks/useConnection'; export * from '$lib/hooks/useNodesEdges'; export * from '$lib/hooks/useHandleConnections'; export * from '$lib/hooks/useNodesData'; -export * from '$lib/hooks/useUpdateNodeData'; +export * from '$lib/hooks/useSetNodeData'; // types export type {