From f37a2d9a19820c4c4f64bbe59583e40d3cdf4810 Mon Sep 17 00:00:00 2001 From: moklick Date: Thu, 5 Oct 2023 17:27:53 +0200 Subject: [PATCH] feat(svelte): ssr --- .../components/NodeWrapper/NodeWrapper.svelte | 2 + .../SvelteFlowProvider.svelte | 8 +- .../components/SvelteFlowProvider/types.ts | 6 + .../EdgeRenderer/EdgeRenderer.svelte | 4 +- .../container/SvelteFlow/SvelteFlow.svelte | 7 +- .../src/lib/container/SvelteFlow/types.ts | 2 + packages/svelte/src/lib/store/index.ts | 28 ++++- .../svelte/src/lib/store/initial-store.ts | 110 ++++++++++-------- packages/svelte/src/lib/store/utils.ts | 2 +- .../svelte/src/lib/store/visible-nodes.ts | 1 + 10 files changed, 111 insertions(+), 59 deletions(-) create mode 100644 packages/svelte/src/lib/components/SvelteFlowProvider/types.ts diff --git a/packages/svelte/src/lib/components/NodeWrapper/NodeWrapper.svelte b/packages/svelte/src/lib/components/NodeWrapper/NodeWrapper.svelte index fd44335a..c1dfb7f0 100644 --- a/packages/svelte/src/lib/components/NodeWrapper/NodeWrapper.svelte +++ b/packages/svelte/src/lib/components/NodeWrapper/NodeWrapper.svelte @@ -116,6 +116,8 @@ class:parent={isParent} style:z-index={zIndex} style:transform="translate({positionOrigin?.x ?? 0}px, {positionOrigin?.y ?? 0}px)" + style:width={node.dimensions?.width && `${node.dimensions?.width}px`} + style:height={node.dimensions?.height && `${node.dimensions?.height}px`} {style} on:click={onSelectNodeHandler} on:mouseenter={(event) => dispatch('nodemouseenter', { node, event })} diff --git a/packages/svelte/src/lib/components/SvelteFlowProvider/SvelteFlowProvider.svelte b/packages/svelte/src/lib/components/SvelteFlowProvider/SvelteFlowProvider.svelte index aacc69c4..b4b6a986 100644 --- a/packages/svelte/src/lib/components/SvelteFlowProvider/SvelteFlowProvider.svelte +++ b/packages/svelte/src/lib/components/SvelteFlowProvider/SvelteFlowProvider.svelte @@ -2,8 +2,14 @@ import { onDestroy, setContext } from 'svelte'; import { createStore, key } from '$lib/store'; + import type { SvelteFlowProviderProps } from './types'; - const store = createStore(); + type $$Props = SvelteFlowProviderProps; + + export let nodes: $$Props['nodes'] = undefined; + export let edges: $$Props['edges'] = undefined; + + const store = createStore({ nodes, edges }); setContext(key, { getStore: () => store diff --git a/packages/svelte/src/lib/components/SvelteFlowProvider/types.ts b/packages/svelte/src/lib/components/SvelteFlowProvider/types.ts new file mode 100644 index 00000000..74ddb713 --- /dev/null +++ b/packages/svelte/src/lib/components/SvelteFlowProvider/types.ts @@ -0,0 +1,6 @@ +import type { Edge, Node } from '$lib/types'; + +export type SvelteFlowProviderProps = { + nodes?: Node[]; + edges?: Edge[]; +}; diff --git a/packages/svelte/src/lib/container/EdgeRenderer/EdgeRenderer.svelte b/packages/svelte/src/lib/container/EdgeRenderer/EdgeRenderer.svelte index 4831278d..77848c02 100644 --- a/packages/svelte/src/lib/container/EdgeRenderer/EdgeRenderer.svelte +++ b/packages/svelte/src/lib/container/EdgeRenderer/EdgeRenderer.svelte @@ -8,8 +8,6 @@ export let defaultEdgeOptions: DefaultEdgeOptions | undefined; const { - width, - height, elementsSelectable, edgeTree, edges: { setDefaultOptions } @@ -21,7 +19,7 @@ {#each $edgeTree as group (group.level)} - + {#if group.isMaxLevel} {/if} {#each group.edges as edge (edge.id)} diff --git a/packages/svelte/src/lib/container/SvelteFlow/SvelteFlow.svelte b/packages/svelte/src/lib/container/SvelteFlow/SvelteFlow.svelte index ef5d547b..5da987b5 100644 --- a/packages/svelte/src/lib/container/SvelteFlow/SvelteFlow.svelte +++ b/packages/svelte/src/lib/container/SvelteFlow/SvelteFlow.svelte @@ -16,6 +16,7 @@ import { key, useStore, createStoreContext } from '$lib/store'; import type { SvelteFlowProps } from './types'; import { updateStore, updateStoreByKeys, type UpdatableStoreProps } from './utils'; + import { get } from 'svelte/store'; type $$Props = SvelteFlowProps; @@ -63,6 +64,8 @@ export let attributionPosition: $$Props['attributionPosition'] = undefined; export let proOptions: $$Props['proOptions'] = undefined; export let defaultEdgeOptions: $$Props['defaultEdgeOptions'] = undefined; + export let width: $$Props['width'] = undefined; + export let height: $$Props['height'] = undefined; export let defaultMarkerColor = '#b1b1b7'; @@ -72,7 +75,9 @@ let domNode: HTMLDivElement; - const store = hasContext(key) ? useStore() : createStoreContext(); + const store = hasContext(key) + ? useStore() + : createStoreContext({ nodes: get(nodes), edges: get(edges), width, height }); onMount(() => { const { width, height } = domNode.getBoundingClientRect(); diff --git a/packages/svelte/src/lib/container/SvelteFlow/types.ts b/packages/svelte/src/lib/container/SvelteFlow/types.ts index 91f3bb70..754a6710 100644 --- a/packages/svelte/src/lib/container/SvelteFlow/types.ts +++ b/packages/svelte/src/lib/container/SvelteFlow/types.ts @@ -72,6 +72,8 @@ export type SvelteFlowProps = DOMAttributes & { attributionPosition?: PanelPosition; proOptions?: ProOptions; defaultEdgeOptions?: DefaultEdgeOptions; + width?: number; + height?: number; class?: string; style?: string; diff --git a/packages/svelte/src/lib/store/index.ts b/packages/svelte/src/lib/store/index.ts index 22d49ac3..9b27da78 100644 --- a/packages/svelte/src/lib/store/index.ts +++ b/packages/svelte/src/lib/store/index.ts @@ -29,8 +29,18 @@ import { getDerivedConnectionProps } from './derived-connection-props'; export const key = Symbol(); -export function createStore(): SvelteFlowStore { - const store = getInitialStore(); +export function createStore({ + nodes, + edges, + width, + height +}: { + nodes?: Node[]; + edges?: Edge[]; + width?: number; + height?: number; +}): SvelteFlowStore { + const store = getInitialStore({ nodes, edges, width, height }); function setNodeTypes(nodeTypes: NodeTypes) { store.nodeTypes.set({ @@ -333,8 +343,18 @@ export function useStore(): SvelteFlowStore { return store.getStore(); } -export function createStoreContext() { - const store = createStore(); +export function createStoreContext({ + nodes, + edges, + width, + height +}: { + nodes?: Node[]; + edges?: Edge[]; + width?: number; + height?: number; +}) { + const store = createStore({ nodes, edges, width, height }); 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 c9deb622..f684dd33 100644 --- a/packages/svelte/src/lib/store/initial-store.ts +++ b/packages/svelte/src/lib/store/initial-store.ts @@ -24,7 +24,7 @@ import BezierEdge from '$lib/components/edges/BezierEdge.svelte'; import StraightEdge from '$lib/components/edges/StraightEdge.svelte'; import SmoothStepEdge from '$lib/components/edges/SmoothStepEdge.svelte'; import StepEdge from '$lib/components/edges/StepEdge.svelte'; -import type { NodeTypes, EdgeTypes, EdgeLayouted, Node, FitViewOptions } from '$lib/types'; +import type { NodeTypes, EdgeTypes, EdgeLayouted, Node, Edge, FitViewOptions } from '$lib/types'; import { createNodesStore, createEdgesStore } from './utils'; import { initConnectionProps, type ConnectionProps } from './derived-connection-props'; @@ -41,51 +41,63 @@ export const initialEdgeTypes = { step: StepEdge }; -export const getInitialStore = () => ({ - flowId: writable(null), - nodes: createNodesStore([]), - visibleNodes: readable([]), - edges: createEdgesStore([]), - edgeTree: readable[]>([]), - height: writable(500), - width: writable(500), - minZoom: writable(0.5), - maxZoom: writable(2), - nodeOrigin: writable([0, 0]), - nodeDragThreshold: writable(0), - nodeExtent: writable(infiniteExtent), - translateExtent: writable(infiniteExtent), - autoPanOnNodeDrag: writable(true), - autoPanOnConnect: writable(true), - fitViewOnInit: writable(false), - fitViewOnInitDone: writable(false), - fitViewOptions: writable(undefined), - panZoom: writable(null), - snapGrid: writable(null), - dragging: writable(false), - selectionRect: writable(null), - selectionKeyPressed: writable(false), - multiselectionKeyPressed: writable(false), - deleteKeyPressed: writable(false), - panActivationKeyPressed: writable(false), - selectionRectMode: writable(null), - selectionMode: writable(SelectionMode.Partial), - nodeTypes: writable(initialNodeTypes), - edgeTypes: writable(initialEdgeTypes), - viewport: writable({ x: 0, y: 0, zoom: 1 }), - connectionMode: writable(ConnectionMode.Strict), - domNode: writable(null), - connection: readable(initConnectionProps), - connectionLineType: writable(ConnectionLineType.Bezier), - connectionRadius: writable(20), - isValidConnection: writable(() => true), - nodesDraggable: writable(true), - nodesConnectable: writable(true), - elementsSelectable: writable(true), - selectNodesOnDrag: writable(true), - markers: readable([]), - defaultMarkerColor: writable('#b1b1b7'), - lib: readable('svelte'), - onlyRenderVisibleElements: writable(false), - onError: writable(devWarn) -}); +export const getInitialStore = ({ + nodes = [], + edges = [], + width, + height +}: { + nodes?: Node[]; + edges?: Edge[]; + width?: number; + height?: number; +}) => { + return { + flowId: writable(null), + nodes: createNodesStore(nodes), + visibleNodes: readable([]), + edges: createEdgesStore(edges), + edgeTree: readable[]>([]), + height: writable(500), + width: writable(500), + minZoom: writable(0.5), + maxZoom: writable(2), + nodeOrigin: writable([0, 0]), + nodeDragThreshold: writable(0), + nodeExtent: writable(infiniteExtent), + translateExtent: writable(infiniteExtent), + autoPanOnNodeDrag: writable(true), + autoPanOnConnect: writable(true), + fitViewOnInit: writable(false), + fitViewOnInitDone: writable(false), + fitViewOptions: writable(undefined), + panZoom: writable(null), + snapGrid: writable(null), + dragging: writable(false), + selectionRect: writable(null), + selectionKeyPressed: writable(false), + multiselectionKeyPressed: writable(false), + deleteKeyPressed: writable(false), + panActivationKeyPressed: writable(false), + selectionRectMode: writable(null), + selectionMode: writable(SelectionMode.Partial), + nodeTypes: writable(initialNodeTypes), + edgeTypes: writable(initialEdgeTypes), + viewport: writable({ x: 0, y: 0, zoom: 1 }), + connectionMode: writable(ConnectionMode.Strict), + domNode: writable(null), + connection: readable(initConnectionProps), + connectionLineType: writable(ConnectionLineType.Bezier), + connectionRadius: writable(20), + isValidConnection: writable(() => true), + nodesDraggable: writable(true), + nodesConnectable: writable(true), + elementsSelectable: writable(true), + selectNodesOnDrag: writable(true), + markers: readable([]), + defaultMarkerColor: writable('#b1b1b7'), + lib: readable('svelte'), + onlyRenderVisibleElements: writable(false), + onError: writable(devWarn) + }; +}; diff --git a/packages/svelte/src/lib/store/utils.ts b/packages/svelte/src/lib/store/utils.ts index adf64c0f..cfd5b343 100644 --- a/packages/svelte/src/lib/store/utils.ts +++ b/packages/svelte/src/lib/store/utils.ts @@ -6,7 +6,7 @@ import { type Writable, get } from 'svelte/store'; -import { updateNodes, type Transform, type Viewport, type PanZoomInstance } from '@xyflow/system'; +import { updateNodes, type Viewport, type PanZoomInstance } from '@xyflow/system'; import type { DefaultEdgeOptions, DefaultNodeOptions, Edge, Node } from '$lib/types'; diff --git a/packages/svelte/src/lib/store/visible-nodes.ts b/packages/svelte/src/lib/store/visible-nodes.ts index 73ed53a4..2d9ab7fb 100644 --- a/packages/svelte/src/lib/store/visible-nodes.ts +++ b/packages/svelte/src/lib/store/visible-nodes.ts @@ -9,6 +9,7 @@ export function getVisibleNodes(store: SvelteFlowStoreState) { [store.nodes, store.onlyRenderVisibleElements, store.width, store.height, store.viewport], ([nodes, onlyRenderVisibleElements, width, height, viewport]) => { const transform: Transform = [viewport.x, viewport.y, viewport.zoom]; + return onlyRenderVisibleElements ? getNodesInside(nodes, { x: 0, y: 0, width, height }, transform, true) : nodes;