From 6f3c22ee664112af98e8ade5a2d1f7e2a81aace1 Mon Sep 17 00:00:00 2001 From: braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Wed, 10 May 2023 13:08:53 +0200 Subject: [PATCH] fix(core): properly reset state and retain reactivity Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com> --- packages/core/src/store/actions.ts | 47 +++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/packages/core/src/store/actions.ts b/packages/core/src/store/actions.ts index 527ab168..b7fecbe4 100644 --- a/packages/core/src/store/actions.ts +++ b/packages/core/src/store/actions.ts @@ -657,6 +657,8 @@ export function useActions( const setState: Actions['setState'] = (options) => { const opts = options instanceof Function ? options(state) : options + + // these options will be set using the appropriate methods const skip: (keyof typeof opts)[] = [ 'modelValue', 'nodes', @@ -669,6 +671,17 @@ export function useActions( 'defaultEdgeOptions', ] + // these options cannot be set after initialization + const exclude: (keyof typeof opts)[] = [ + 'd3Zoom', + 'd3Selection', + 'd3ZoomHandler', + 'viewportRef', + 'vueFlowRef', + 'dimensions', + 'hooks', + ] + // we need to set the default opts before setting any elements so the options are applied to the elements on first render if (isDef(opts.defaultEdgeOptions)) { state.defaultEdgeOptions = opts.defaultEdgeOptions @@ -708,9 +721,11 @@ export function useActions( } Object.keys(opts).forEach((o) => { - const option = opts[o as keyof typeof opts] - if (!skip.includes(o as keyof typeof opts) && isDef(option)) { - ;(state)[o] = option + const key = o as keyof State + const option = opts[key] + + if (![...skip, ...exclude].includes(key) && isDef(option)) { + ;(state)[key] = option } }) @@ -824,7 +839,31 @@ export function useActions( project: (position) => viewportHelper.project(position), toObject, updateNodeInternals, - $reset: () => {}, + $reset: () => { + const resetState = useState() + + state.edges = [] + state.nodes = [] + + // reset the zoom state + if (state.d3Zoom && state.d3Selection) { + const updatedTransform = zoomIdentity + .translate(resetState.defaultViewport.x ?? 0, resetState.defaultViewport.y ?? 0) + .scale(clamp(resetState.defaultViewport.zoom ?? 1, resetState.minZoom, resetState.maxZoom)) + + const bbox = state.viewportRef!.getBoundingClientRect() + + const extent: CoordinateExtent = [ + [0, 0], + [bbox.width, bbox.height], + ] + + const constrainedTransform = state.d3Zoom.constrain()(updatedTransform, extent, resetState.translateExtent) + state.d3Zoom.transform(state.d3Selection, constrainedTransform) + } + + setState(resetState) + }, $destroy: () => {}, } }