From 2435a0da8ffab6e4d0a477aefc89bc6380ddba79 Mon Sep 17 00:00:00 2001 From: moklick Date: Mon, 23 Oct 2023 18:05:45 +0200 Subject: [PATCH] feat(svelte): ssr fitView --- packages/react/src/hooks/useReactFlow.ts | 4 +-- .../SvelteFlowProvider.svelte | 4 ++- .../components/SvelteFlowProvider/types.ts | 1 + .../container/SvelteFlow/SvelteFlow.svelte | 2 +- packages/svelte/src/lib/store/index.ts | 12 +++++--- .../svelte/src/lib/store/initial-store.ts | 28 ++++++++++++++++--- 6 files changed, 39 insertions(+), 12 deletions(-) diff --git a/packages/react/src/hooks/useReactFlow.ts b/packages/react/src/hooks/useReactFlow.ts index 70f5e203..301f49f5 100644 --- a/packages/react/src/hooks/useReactFlow.ts +++ b/packages/react/src/hooks/useReactFlow.ts @@ -211,7 +211,7 @@ export default function useReactFlow(): ReactFlo const overlappingArea = getOverlappingArea(currNodeRect, nodeRect); const partiallyVisible = partially && overlappingArea > 0; - return partiallyVisible || overlappingArea >= nodeOrRect.width! * nodeOrRect.height!; + return partiallyVisible || overlappingArea >= nodeRect.width * nodeRect.height; }); }, [] @@ -228,7 +228,7 @@ export default function useReactFlow(): ReactFlo const overlappingArea = getOverlappingArea(nodeRect, area); const partiallyVisible = partially && overlappingArea > 0; - return partiallyVisible || overlappingArea >= nodeOrRect.width! * nodeOrRect.height!; + return partiallyVisible || overlappingArea >= nodeRect.width * nodeRect.height; }, [] ); diff --git a/packages/svelte/src/lib/components/SvelteFlowProvider/SvelteFlowProvider.svelte b/packages/svelte/src/lib/components/SvelteFlowProvider/SvelteFlowProvider.svelte index 62ac3096..b943ab0a 100644 --- a/packages/svelte/src/lib/components/SvelteFlowProvider/SvelteFlowProvider.svelte +++ b/packages/svelte/src/lib/components/SvelteFlowProvider/SvelteFlowProvider.svelte @@ -10,12 +10,14 @@ export let initialEdges: $$Props['initialEdges'] = undefined; export let initialWidth: $$Props['initialWidth'] = undefined; export let initialHeight: $$Props['initialHeight'] = undefined; + export let fitView: $$Props['fitView'] = undefined; const store = createStore({ nodes: initialNodes, edges: initialEdges, width: initialWidth, - height: initialHeight + height: initialHeight, + fitView }); setContext(key, { diff --git a/packages/svelte/src/lib/components/SvelteFlowProvider/types.ts b/packages/svelte/src/lib/components/SvelteFlowProvider/types.ts index 8e21df16..769588b2 100644 --- a/packages/svelte/src/lib/components/SvelteFlowProvider/types.ts +++ b/packages/svelte/src/lib/components/SvelteFlowProvider/types.ts @@ -5,4 +5,5 @@ export type SvelteFlowProviderProps = { initialEdges?: Edge[]; initialWidth?: number; initialHeight?: number; + fitView?: boolean; }; diff --git a/packages/svelte/src/lib/container/SvelteFlow/SvelteFlow.svelte b/packages/svelte/src/lib/container/SvelteFlow/SvelteFlow.svelte index d9d3895b..4865594d 100644 --- a/packages/svelte/src/lib/container/SvelteFlow/SvelteFlow.svelte +++ b/packages/svelte/src/lib/container/SvelteFlow/SvelteFlow.svelte @@ -79,7 +79,7 @@ const store = hasContext(key) ? useStore() - : createStoreContext({ nodes: get(nodes), edges: get(edges), width, height }); + : createStoreContext({ nodes: get(nodes), edges: get(edges), width, height, fitView }); onMount(() => { store.width.set(clientWidth); diff --git a/packages/svelte/src/lib/store/index.ts b/packages/svelte/src/lib/store/index.ts index 9b27da78..0c49c337 100644 --- a/packages/svelte/src/lib/store/index.ts +++ b/packages/svelte/src/lib/store/index.ts @@ -33,14 +33,16 @@ export function createStore({ nodes, edges, width, - height + height, + fitView: fitViewOnCreate }: { nodes?: Node[]; edges?: Edge[]; width?: number; height?: number; + fitView?: boolean; }): SvelteFlowStore { - const store = getInitialStore({ nodes, edges, width, height }); + const store = getInitialStore({ nodes, edges, width, height, fitView: fitViewOnCreate }); function setNodeTypes(nodeTypes: NodeTypes) { store.nodeTypes.set({ @@ -347,14 +349,16 @@ export function createStoreContext({ nodes, edges, width, - height + height, + fitView }: { nodes?: Node[]; edges?: Edge[]; width?: number; height?: number; + fitView?: boolean; }) { - const store = createStore({ nodes, edges, width, height }); + const store = createStore({ nodes, edges, width, height, fitView }); setContext(key, { getStore: () => store diff --git a/packages/svelte/src/lib/store/initial-store.ts b/packages/svelte/src/lib/store/initial-store.ts index ccfecb30..8d166d21 100644 --- a/packages/svelte/src/lib/store/initial-store.ts +++ b/packages/svelte/src/lib/store/initial-store.ts @@ -14,7 +14,10 @@ import { type NodeOrigin, type OnError, devWarn, - type Viewport + type Viewport, + updateNodes, + getRectOfNodes, + getTransformForBounds } from '@xyflow/system'; import DefaultNode from '$lib/components/nodes/DefaultNode.svelte'; @@ -47,16 +50,33 @@ export const getInitialStore = ({ nodes = [], edges = [], width, - height + height, + fitView }: { nodes?: Node[]; edges?: Edge[]; width?: number; height?: number; + fitView?: boolean; }) => { + const nextNodes = updateNodes(nodes, [], { nodeOrigin: [0, 0], elevateNodesOnSelect: false }); + + let viewport: Viewport = { x: 0, y: 0, zoom: 1 }; + + if (fitView && width && height) { + const nodesWithDimensions = nextNodes.map((node) => ({ + ...node, + width: node.size?.width, + height: node.size?.height + })); + const bounds = getRectOfNodes(nodesWithDimensions, [0, 0]); + const transform = getTransformForBounds(bounds, width, height, 0.5, 2, 0.1); + viewport = { x: transform[0], y: transform[1], zoom: transform[2] }; + } + return { flowId: writable(null), - nodes: createNodesStore(nodes), + nodes: createNodesStore(nextNodes), visibleNodes: readable([]), edges: createEdgesStore(edges), edgeTree: readable[]>([]), @@ -85,7 +105,7 @@ export const getInitialStore = ({ selectionMode: writable(SelectionMode.Partial), nodeTypes: writable(initialNodeTypes), edgeTypes: writable(initialEdgeTypes), - viewport: writable({ x: 0, y: 0, zoom: 1 }), + viewport: writable(viewport), connectionMode: writable(ConnectionMode.Strict), domNode: writable(null), connection: readable(initConnectionProps),