diff --git a/packages/core/src/store/actions.ts b/packages/core/src/store/actions.ts index 8fdb39ec..cc5854ad 100644 --- a/packages/core/src/store/actions.ts +++ b/packages/core/src/store/actions.ts @@ -600,6 +600,34 @@ export function useActions( return changedEdges } + // todo: maybe we should use a more immutable approach, this is a bit too much mutation and hard to maintain + const updateNode: Actions['updateNode'] = (id, nodeUpdate, options = { replace: true }) => { + const node = findNode(id) + + if (!node) { + return + } + + const nextNode = typeof nodeUpdate === 'function' ? nodeUpdate(node) : nodeUpdate + + if (options.replace) { + state.nodes.splice(state.nodes.indexOf(node), 1, nextNode as GraphNode) + } else { + Object.assign(node, nextNode) + } + } + + const updateNodeData: Actions['updateNodeData'] = (id, dataUpdate, options = { replace: false }) => { + updateNode( + id, + (node) => { + const nextData = typeof dataUpdate === 'function' ? dataUpdate(node) : dataUpdate + return options.replace ? { ...node, data: nextData } : { ...node, data: { ...node.data, ...nextData } } + }, + options, + ) + } + const startConnection: Actions['startConnection'] = (startHandle, position, event, isClick = false) => { if (isClick) { state.connectionClickStartHandle = startHandle @@ -902,6 +930,8 @@ export function useActions( findNode, findEdge, updateEdge, + updateNode, + updateNodeData, applyEdgeChanges, applyNodeChanges, addSelectedElements, diff --git a/packages/core/src/types/store.ts b/packages/core/src/types/store.ts index b9e5ca86..1f4bfa53 100644 --- a/packages/core/src/types/store.ts +++ b/packages/core/src/types/store.ts @@ -204,6 +204,18 @@ export type GetIntersectingNodes = ( nodes?: GraphNode[], ) => GraphNode[] +export type UpdateNode = = any>( + id: string, + nodeUpdate: Partial> | ((node: GraphNode) => Partial>), + options?: { replace: boolean }, +) => void + +export type UpdateNodeData = = any>( + id: string, + dataUpdate: Partial | ((node: GraphNode) => Partial), + options?: { replace: boolean }, +) => void + export type IsNodeIntersecting = (node: (Partial & { id: Node['id'] }) | Rect, area: Rect, partially?: boolean) => boolean export interface Actions extends ViewportFunctions { @@ -227,6 +239,10 @@ export interface Actions extends ViewportFunctions { findEdge: FindEdge /** updates an edge */ updateEdge: UpdateEdge + /** updates a node */ + updateNode: UpdateNode + /** updates the data of a node */ + updateNodeData: UpdateNodeData /** applies default edge change handler */ applyEdgeChanges: (changes: EdgeChange[]) => GraphEdge[] /** applies default node change handler */