feat(svelte): add subflows

This commit is contained in:
moklick
2023-03-15 18:34:07 +01:00
parent 9e961809ee
commit 77d14f9ad0
15 changed files with 347 additions and 84 deletions
+43 -43
View File
@@ -8,55 +8,55 @@ import type { SvelteFlowStoreState } from './types';
export function getEdgesLayouted(store: SvelteFlowStoreState) {
return derived([store.edges, store.nodes], ([edges, nodes]) => {
return edges
.map((edge) => {
const sourceNode = nodes.find((node) => node.id === edge.source);
const targetNode = nodes.find((node) => node.id === edge.target);
const [sourceNodeRect, sourceHandleBounds, sourceIsValid] = getNodeData(sourceNode);
const [targetNodeRect, targetHandleBounds, targetIsValid] = getNodeData(targetNode);
return edges.reduce<EdgeLayouted[]>((res, edge) => {
const sourceNode = nodes.find((node) => node.id === edge.source);
const targetNode = nodes.find((node) => node.id === edge.target);
const [sourceNodeRect, sourceHandleBounds, sourceIsValid] = getNodeData(sourceNode);
const [targetNodeRect, targetHandleBounds, targetIsValid] = getNodeData(targetNode);
if (!sourceIsValid || !targetIsValid) {
return null;
}
if (!sourceIsValid || !targetIsValid) {
return res;
}
const edgeType = edge.type || 'default';
const edgeType = edge.type || 'default';
const targetNodeHandles = targetHandleBounds!.target;
const sourceHandle = getHandle(sourceHandleBounds!.source!, edge.sourceHandle);
const targetHandle = getHandle(targetNodeHandles!, edge.targetHandle);
const sourcePosition = sourceHandle?.position || Position.Bottom;
const targetPosition = targetHandle?.position || Position.Top;
const targetNodeHandles = targetHandleBounds!.target;
const sourceHandle = getHandle(sourceHandleBounds!.source!, edge.sourceHandle);
const targetHandle = getHandle(targetNodeHandles!, edge.targetHandle);
const sourcePosition = sourceHandle?.position || Position.Bottom;
const targetPosition = targetHandle?.position || Position.Top;
if (!sourceHandle || !targetHandle) {
return null;
}
if (!sourceHandle || !targetHandle) {
return res;
}
const { sourceX, sourceY, targetX, targetY } = getEdgePositions(
sourceNodeRect,
sourceHandle,
sourcePosition,
targetNodeRect,
targetHandle,
targetPosition
);
const { sourceX, sourceY, targetX, targetY } = getEdgePositions(
sourceNodeRect,
sourceHandle,
sourcePosition,
targetNodeRect,
targetHandle,
targetPosition
);
// we nee to do this to match the types
const sourceHandleId = edge.sourceHandle;
const targetHandleId = edge.targetHandle;
// we nee to do this to match the types
const sourceHandleId = edge.sourceHandle;
const targetHandleId = edge.targetHandle;
return {
...edge,
type: edgeType,
sourceX,
sourceY,
targetX,
targetY,
sourcePosition,
targetPosition,
sourceHandleId,
targetHandleId
};
})
.filter((e) => e !== null) as EdgeLayouted[];
res.push({
...edge,
type: edgeType,
sourceX,
sourceY,
targetX,
targetY,
sourcePosition,
targetPosition,
sourceHandleId,
targetHandleId
} as EdgeLayouted);
return res;
}, []);
});
}
+18 -11
View File
@@ -19,7 +19,7 @@ import {
} from '@reactflow/utils';
import { addEdge as addEdgeUtil } from '$lib/utils';
import type { EdgeTypes, NodeTypes, Node, Edge, ConnectionData } from '$lib/types';
import type { EdgeTypes, NodeTypes, Node, Edge, ConnectionData, FitViewOptions } from '$lib/types';
import { getEdgesLayouted } from './edges-layouted';
import { getConnectionPath } from './connection-path';
import {
@@ -102,15 +102,20 @@ export function createStore(params: CreateStoreParams): SvelteFlowStore {
);
if (doUpdate) {
node[internalsSymbol] = {
...node[internalsSymbol],
handleBounds: {
source: getHandleBounds('.source', update.nodeElement, zoom, node.origin),
target: getHandleBounds('.target', update.nodeElement, zoom, node.origin)
const newNode = {
...node,
width: dimensions.width,
height: dimensions.height,
[internalsSymbol]: {
...node[internalsSymbol],
handleBounds: {
source: getHandleBounds('.source', update.nodeElement, zoom, node.origin),
target: getHandleBounds('.target', update.nodeElement, zoom, node.origin)
}
}
};
node.width = dimensions.width;
node.height = dimensions.height;
return newNode;
}
}
@@ -121,7 +126,7 @@ export function createStore(params: CreateStoreParams): SvelteFlowStore {
const fitViewOnInitDone =
get(store.fitViewOnInitDone) ||
(get(store.fitViewOnInit) && !!d3Zoom && !!d3Selection && fitView());
(get(store.fitViewOnInit) && !!d3Zoom && !!d3Selection && fitView({ nodes: nextNodes }));
store.fitViewOnInitDone.set(fitViewOnInitDone);
store.nodes.set(nextNodes);
@@ -162,16 +167,18 @@ export function createStore(params: CreateStoreParams): SvelteFlowStore {
}
}
function fitView() {
function fitView(options?: FitViewOptions) {
const { zoom: d3Zoom, selection: d3Selection } = get(store.d3);
if (!d3Zoom || !d3Selection) {
return false;
}
const fitViewNodes = options?.nodes || get(store.nodes);
return fitViewUtil(
{
nodes: get(store.nodes),
nodes: fitViewNodes as Node[],
width: get(store.width),
height: get(store.height),
minZoom: 0.2,
+2 -2
View File
@@ -7,7 +7,7 @@ import type {
} from '@reactflow/system';
import type { initialStoreState } from './initial-store';
import type { Node, Edge, ConnectionData, NodeTypes, EdgeTypes } from '$lib/types';
import type { Node, Edge, ConnectionData, NodeTypes, EdgeTypes, FitViewOptions } from '$lib/types';
import type { Writable } from 'svelte/store';
export type SvelteFlowStoreActions = {
@@ -18,7 +18,7 @@ export type SvelteFlowStoreActions = {
zoomOut: (options?: ViewportHelperFunctionOptions) => void;
setMinZoom: (minZoom: number) => void;
setMaxZoom: (maxZoom: number) => void;
fitView: (options?: ViewportHelperFunctionOptions) => boolean;
fitView: (options?: FitViewOptions) => boolean;
updateNodePositions: (
nodeDragItems: NodeDragItem[],
positionChanged?: boolean,