feat(svelte): ssr

This commit is contained in:
moklick
2023-10-05 17:27:53 +02:00
parent 1c791811a9
commit f37a2d9a19
10 changed files with 111 additions and 59 deletions
@@ -116,6 +116,8 @@
class:parent={isParent} class:parent={isParent}
style:z-index={zIndex} style:z-index={zIndex}
style:transform="translate({positionOrigin?.x ?? 0}px, {positionOrigin?.y ?? 0}px)" 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} {style}
on:click={onSelectNodeHandler} on:click={onSelectNodeHandler}
on:mouseenter={(event) => dispatch('nodemouseenter', { node, event })} on:mouseenter={(event) => dispatch('nodemouseenter', { node, event })}
@@ -2,8 +2,14 @@
import { onDestroy, setContext } from 'svelte'; import { onDestroy, setContext } from 'svelte';
import { createStore, key } from '$lib/store'; 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, { setContext(key, {
getStore: () => store getStore: () => store
@@ -0,0 +1,6 @@
import type { Edge, Node } from '$lib/types';
export type SvelteFlowProviderProps = {
nodes?: Node[];
edges?: Edge[];
};
@@ -8,8 +8,6 @@
export let defaultEdgeOptions: DefaultEdgeOptions | undefined; export let defaultEdgeOptions: DefaultEdgeOptions | undefined;
const { const {
width,
height,
elementsSelectable, elementsSelectable,
edgeTree, edgeTree,
edges: { setDefaultOptions } edges: { setDefaultOptions }
@@ -21,7 +19,7 @@
</script> </script>
{#each $edgeTree as group (group.level)} {#each $edgeTree as group (group.level)}
<svg width={$width} height={$height} style="z-index: {group.level}" class="svelte-flow__edges"> <svg style="z-index: {group.level}" class="svelte-flow__edges">
{#if group.isMaxLevel} <MarkerDefinition />{/if} {#if group.isMaxLevel} <MarkerDefinition />{/if}
<g> <g>
{#each group.edges as edge (edge.id)} {#each group.edges as edge (edge.id)}
@@ -16,6 +16,7 @@
import { key, useStore, createStoreContext } from '$lib/store'; import { key, useStore, createStoreContext } from '$lib/store';
import type { SvelteFlowProps } from './types'; import type { SvelteFlowProps } from './types';
import { updateStore, updateStoreByKeys, type UpdatableStoreProps } from './utils'; import { updateStore, updateStoreByKeys, type UpdatableStoreProps } from './utils';
import { get } from 'svelte/store';
type $$Props = SvelteFlowProps; type $$Props = SvelteFlowProps;
@@ -63,6 +64,8 @@
export let attributionPosition: $$Props['attributionPosition'] = undefined; export let attributionPosition: $$Props['attributionPosition'] = undefined;
export let proOptions: $$Props['proOptions'] = undefined; export let proOptions: $$Props['proOptions'] = undefined;
export let defaultEdgeOptions: $$Props['defaultEdgeOptions'] = undefined; export let defaultEdgeOptions: $$Props['defaultEdgeOptions'] = undefined;
export let width: $$Props['width'] = undefined;
export let height: $$Props['height'] = undefined;
export let defaultMarkerColor = '#b1b1b7'; export let defaultMarkerColor = '#b1b1b7';
@@ -72,7 +75,9 @@
let domNode: HTMLDivElement; let domNode: HTMLDivElement;
const store = hasContext(key) ? useStore() : createStoreContext(); const store = hasContext(key)
? useStore()
: createStoreContext({ nodes: get(nodes), edges: get(edges), width, height });
onMount(() => { onMount(() => {
const { width, height } = domNode.getBoundingClientRect(); const { width, height } = domNode.getBoundingClientRect();
@@ -72,6 +72,8 @@ export type SvelteFlowProps = DOMAttributes<HTMLDivElement> & {
attributionPosition?: PanelPosition; attributionPosition?: PanelPosition;
proOptions?: ProOptions; proOptions?: ProOptions;
defaultEdgeOptions?: DefaultEdgeOptions; defaultEdgeOptions?: DefaultEdgeOptions;
width?: number;
height?: number;
class?: string; class?: string;
style?: string; style?: string;
+24 -4
View File
@@ -29,8 +29,18 @@ import { getDerivedConnectionProps } from './derived-connection-props';
export const key = Symbol(); export const key = Symbol();
export function createStore(): SvelteFlowStore { export function createStore({
const store = getInitialStore(); nodes,
edges,
width,
height
}: {
nodes?: Node[];
edges?: Edge[];
width?: number;
height?: number;
}): SvelteFlowStore {
const store = getInitialStore({ nodes, edges, width, height });
function setNodeTypes(nodeTypes: NodeTypes) { function setNodeTypes(nodeTypes: NodeTypes) {
store.nodeTypes.set({ store.nodeTypes.set({
@@ -333,8 +343,18 @@ export function useStore(): SvelteFlowStore {
return store.getStore(); return store.getStore();
} }
export function createStoreContext() { export function createStoreContext({
const store = createStore(); nodes,
edges,
width,
height
}: {
nodes?: Node[];
edges?: Edge[];
width?: number;
height?: number;
}) {
const store = createStore({ nodes, edges, width, height });
setContext(key, { setContext(key, {
getStore: () => store getStore: () => store
+61 -49
View File
@@ -24,7 +24,7 @@ import BezierEdge from '$lib/components/edges/BezierEdge.svelte';
import StraightEdge from '$lib/components/edges/StraightEdge.svelte'; import StraightEdge from '$lib/components/edges/StraightEdge.svelte';
import SmoothStepEdge from '$lib/components/edges/SmoothStepEdge.svelte'; import SmoothStepEdge from '$lib/components/edges/SmoothStepEdge.svelte';
import StepEdge from '$lib/components/edges/StepEdge.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 { createNodesStore, createEdgesStore } from './utils';
import { initConnectionProps, type ConnectionProps } from './derived-connection-props'; import { initConnectionProps, type ConnectionProps } from './derived-connection-props';
@@ -41,51 +41,63 @@ export const initialEdgeTypes = {
step: StepEdge step: StepEdge
}; };
export const getInitialStore = () => ({ export const getInitialStore = ({
flowId: writable<string | null>(null), nodes = [],
nodes: createNodesStore([]), edges = [],
visibleNodes: readable<Node[]>([]), width,
edges: createEdgesStore([]), height
edgeTree: readable<GroupedEdges<EdgeLayouted>[]>([]), }: {
height: writable<number>(500), nodes?: Node[];
width: writable<number>(500), edges?: Edge[];
minZoom: writable<number>(0.5), width?: number;
maxZoom: writable<number>(2), height?: number;
nodeOrigin: writable<NodeOrigin>([0, 0]), }) => {
nodeDragThreshold: writable<number>(0), return {
nodeExtent: writable<CoordinateExtent>(infiniteExtent), flowId: writable<string | null>(null),
translateExtent: writable<CoordinateExtent>(infiniteExtent), nodes: createNodesStore(nodes),
autoPanOnNodeDrag: writable<boolean>(true), visibleNodes: readable<Node[]>([]),
autoPanOnConnect: writable<boolean>(true), edges: createEdgesStore(edges),
fitViewOnInit: writable<boolean>(false), edgeTree: readable<GroupedEdges<EdgeLayouted>[]>([]),
fitViewOnInitDone: writable<boolean>(false), height: writable<number>(500),
fitViewOptions: writable<FitViewOptions>(undefined), width: writable<number>(500),
panZoom: writable<PanZoomInstance | null>(null), minZoom: writable<number>(0.5),
snapGrid: writable<SnapGrid | null>(null), maxZoom: writable<number>(2),
dragging: writable<boolean>(false), nodeOrigin: writable<NodeOrigin>([0, 0]),
selectionRect: writable<SelectionRect | null>(null), nodeDragThreshold: writable<number>(0),
selectionKeyPressed: writable<boolean>(false), nodeExtent: writable<CoordinateExtent>(infiniteExtent),
multiselectionKeyPressed: writable<boolean>(false), translateExtent: writable<CoordinateExtent>(infiniteExtent),
deleteKeyPressed: writable<boolean>(false), autoPanOnNodeDrag: writable<boolean>(true),
panActivationKeyPressed: writable<boolean>(false), autoPanOnConnect: writable<boolean>(true),
selectionRectMode: writable<string | null>(null), fitViewOnInit: writable<boolean>(false),
selectionMode: writable<SelectionMode>(SelectionMode.Partial), fitViewOnInitDone: writable<boolean>(false),
nodeTypes: writable<NodeTypes>(initialNodeTypes), fitViewOptions: writable<FitViewOptions>(undefined),
edgeTypes: writable<EdgeTypes>(initialEdgeTypes), panZoom: writable<PanZoomInstance | null>(null),
viewport: writable<Viewport>({ x: 0, y: 0, zoom: 1 }), snapGrid: writable<SnapGrid | null>(null),
connectionMode: writable<ConnectionMode>(ConnectionMode.Strict), dragging: writable<boolean>(false),
domNode: writable<HTMLDivElement | null>(null), selectionRect: writable<SelectionRect | null>(null),
connection: readable<ConnectionProps>(initConnectionProps), selectionKeyPressed: writable<boolean>(false),
connectionLineType: writable<ConnectionLineType>(ConnectionLineType.Bezier), multiselectionKeyPressed: writable<boolean>(false),
connectionRadius: writable<number>(20), deleteKeyPressed: writable<boolean>(false),
isValidConnection: writable<IsValidConnection>(() => true), panActivationKeyPressed: writable<boolean>(false),
nodesDraggable: writable<boolean>(true), selectionRectMode: writable<string | null>(null),
nodesConnectable: writable<boolean>(true), selectionMode: writable<SelectionMode>(SelectionMode.Partial),
elementsSelectable: writable<boolean>(true), nodeTypes: writable<NodeTypes>(initialNodeTypes),
selectNodesOnDrag: writable<boolean>(true), edgeTypes: writable<EdgeTypes>(initialEdgeTypes),
markers: readable<MarkerProps[]>([]), viewport: writable<Viewport>({ x: 0, y: 0, zoom: 1 }),
defaultMarkerColor: writable<string>('#b1b1b7'), connectionMode: writable<ConnectionMode>(ConnectionMode.Strict),
lib: readable<string>('svelte'), domNode: writable<HTMLDivElement | null>(null),
onlyRenderVisibleElements: writable<boolean>(false), connection: readable<ConnectionProps>(initConnectionProps),
onError: writable<OnError>(devWarn) connectionLineType: writable<ConnectionLineType>(ConnectionLineType.Bezier),
}); connectionRadius: writable<number>(20),
isValidConnection: writable<IsValidConnection>(() => true),
nodesDraggable: writable<boolean>(true),
nodesConnectable: writable<boolean>(true),
elementsSelectable: writable<boolean>(true),
selectNodesOnDrag: writable<boolean>(true),
markers: readable<MarkerProps[]>([]),
defaultMarkerColor: writable<string>('#b1b1b7'),
lib: readable<string>('svelte'),
onlyRenderVisibleElements: writable<boolean>(false),
onError: writable<OnError>(devWarn)
};
};
+1 -1
View File
@@ -6,7 +6,7 @@ import {
type Writable, type Writable,
get get
} from 'svelte/store'; } 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'; import type { DefaultEdgeOptions, DefaultNodeOptions, Edge, Node } from '$lib/types';
@@ -9,6 +9,7 @@ export function getVisibleNodes(store: SvelteFlowStoreState) {
[store.nodes, store.onlyRenderVisibleElements, store.width, store.height, store.viewport], [store.nodes, store.onlyRenderVisibleElements, store.width, store.height, store.viewport],
([nodes, onlyRenderVisibleElements, width, height, viewport]) => { ([nodes, onlyRenderVisibleElements, width, height, viewport]) => {
const transform: Transform = [viewport.x, viewport.y, viewport.zoom]; const transform: Transform = [viewport.x, viewport.y, viewport.zoom];
return onlyRenderVisibleElements return onlyRenderVisibleElements
? getNodesInside<Node>(nodes, { x: 0, y: 0, width, height }, transform, true) ? getNodesInside<Node>(nodes, { x: 0, y: 0, width, height }, transform, true)
: nodes; : nodes;