From ca4a6c20f9e5a2520414fe7e8b6f10748b842e6a Mon Sep 17 00:00:00 2001 From: moklick Date: Mon, 22 May 2023 12:24:35 +0200 Subject: [PATCH] feat(svelte): add nodesConnectable, nodesDraggable and elementsSelectable --- .../MarkerDefinition/MarkerDefinition.svelte | 11 +- .../NodeRenderer/NodeRenderer.svelte | 8 +- .../container/SvelteFlow/SvelteFlow.svelte | 8 +- .../src/lib/container/SvelteFlow/types.ts | 3 + .../src/lib/plugins/Controls/Controls.svelte | 13 +-- .../svelte/src/lib/store/edges-layouted.ts | 109 ++++++++++-------- packages/svelte/src/lib/store/index.ts | 4 +- .../svelte/src/lib/store/initial-store.ts | 3 + packages/svelte/src/lib/types/edges.ts | 1 + packages/system/src/types/edges.ts | 1 + 10 files changed, 85 insertions(+), 76 deletions(-) diff --git a/packages/svelte/src/lib/container/EdgeRenderer/MarkerDefinition/MarkerDefinition.svelte b/packages/svelte/src/lib/container/EdgeRenderer/MarkerDefinition/MarkerDefinition.svelte index 602d6b57..26c53926 100644 --- a/packages/svelte/src/lib/container/EdgeRenderer/MarkerDefinition/MarkerDefinition.svelte +++ b/packages/svelte/src/lib/container/EdgeRenderer/MarkerDefinition/MarkerDefinition.svelte @@ -7,15 +7,6 @@ {#each $markers as marker(marker.id)} - + {/each} \ No newline at end of file diff --git a/packages/svelte/src/lib/container/NodeRenderer/NodeRenderer.svelte b/packages/svelte/src/lib/container/NodeRenderer/NodeRenderer.svelte index 1f940958..99694d65 100644 --- a/packages/svelte/src/lib/container/NodeRenderer/NodeRenderer.svelte +++ b/packages/svelte/src/lib/container/NodeRenderer/NodeRenderer.svelte @@ -6,7 +6,7 @@ import { NodeWrapper } from '$lib/components/NodeWrapper'; import { useStore } from '$lib/store'; - const { nodes, updateNodeDimensions } = useStore(); + const { nodes, nodesDraggable, nodesConnectable, elementsSelectable, updateNodeDimensions } = useStore(); const resizeObserver: ResizeObserver | null = typeof ResizeObserver === 'undefined' @@ -38,9 +38,9 @@ id={node.id} data={node.data} selected={node.selected} - draggable={node.draggable || node.draggable === undefined} - selectable={node.selectable || node.selectable === undefined} - connectable={node.connectable || node.connectable === undefined} + draggable={!!(node.draggable || ($nodesDraggable && typeof node.draggable === 'undefined'))} + selectable={!!(node.selectable || ($elementsSelectable && typeof node.selectable === 'undefined'))} + connectable={!!(node.connectable || ($nodesConnectable && typeof node.connectable === 'undefined'))} positionAbsolute={node.positionAbsolute} positionOrigin={posOrigin} isParent={!!node[internalsSymbol]?.isParent} diff --git a/packages/svelte/src/lib/container/SvelteFlow/SvelteFlow.svelte b/packages/svelte/src/lib/container/SvelteFlow/SvelteFlow.svelte index 35eb0247..c1a3131e 100644 --- a/packages/svelte/src/lib/container/SvelteFlow/SvelteFlow.svelte +++ b/packages/svelte/src/lib/container/SvelteFlow/SvelteFlow.svelte @@ -26,6 +26,9 @@ export let edgeTypes: $$Props['edgeTypes'] = undefined; export let selectionKey: $$Props['selectionKey'] = undefined; export let selectionMode: $$Props['selectionMode'] = undefined; + export let nodesDraggable: $$Props['nodesDraggable'] = undefined; + export let nodesConnectable: $$Props['nodesConnectable'] = undefined; + export let elementsSelectable: $$Props['elementsSelectable'] = undefined; export let snapGrid: $$Props['snapGrid'] = undefined; export let deleteKey: $$Props['deleteKey'] = undefined; export let connectionRadius: $$Props['connectionRadius'] = undefined; @@ -60,7 +63,10 @@ selectionMode, snapGrid, isValidConnection, - defaultMarkerColor + defaultMarkerColor, + nodesDraggable, + nodesConnectable, + elementsSelectable, }; Object.keys(updatableProps).forEach(prop => { diff --git a/packages/svelte/src/lib/container/SvelteFlow/types.ts b/packages/svelte/src/lib/container/SvelteFlow/types.ts index 539de845..653faf48 100644 --- a/packages/svelte/src/lib/container/SvelteFlow/types.ts +++ b/packages/svelte/src/lib/container/SvelteFlow/types.ts @@ -33,6 +33,9 @@ export type SvelteFlowProps = DOMAttributes & { selectionMode?: SelectionMode; snapGrid?: SnapGrid; defaultMarkerColor?: string; + nodesDraggable?: boolean; + nodesConnectable?: boolean; + elementsSelectable?: boolean; class?: string; style?: string; diff --git a/packages/svelte/src/lib/plugins/Controls/Controls.svelte b/packages/svelte/src/lib/plugins/Controls/Controls.svelte index 3501b156..c3d73450 100644 --- a/packages/svelte/src/lib/plugins/Controls/Controls.svelte +++ b/packages/svelte/src/lib/plugins/Controls/Controls.svelte @@ -17,7 +17,9 @@ export let showFitView: $$Props['showFitView'] = true; export let showInteractive: $$Props['showInteractive'] = true; - const { zoomIn, zoomOut, fitView, transform, minZoom, maxZoom } = useStore(); + const { + zoomIn, zoomOut, fitView, transform, minZoom, maxZoom, nodesDraggable, nodesConnectable, elementsSelectable + } = useStore(); const isInteractive = true; $: minZoomReached = $transform[2] <= $minZoom; @@ -36,12 +38,9 @@ }; const onToggleInteractivity = () => { - // store.setState({ - // nodesDraggable: !isInteractive, - // nodesConnectable: !isInteractive, - // elementsSelectable: !isInteractive, - // }); - // onInteractiveChange?.(!isInteractive); + nodesDraggable.set(!isInteractive); + nodesConnectable.set(!isInteractive); + elementsSelectable.set(!isInteractive); }; diff --git a/packages/svelte/src/lib/store/edges-layouted.ts b/packages/svelte/src/lib/store/edges-layouted.ts index f26a3449..36db500d 100644 --- a/packages/svelte/src/lib/store/edges-layouted.ts +++ b/packages/svelte/src/lib/store/edges-layouted.ts @@ -7,57 +7,64 @@ import type { EdgeLayouted } from '$lib/types'; import type { SvelteFlowStoreState } from './types'; export function getEdgesLayouted(store: SvelteFlowStoreState) { - return derived([store.edges, store.nodes], ([edges, nodes]) => { - return edges.reduce((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); + return derived( + [store.edges, store.nodes, store.elementsSelectable], + ([edges, nodes, elementsSelectable]) => { + return edges.reduce((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 res; + } + + 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; + + if (!sourceHandle || !targetHandle) { + return res; + } + + 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; + const selectable = !!( + edge.selectable || + (elementsSelectable && typeof edge.selectable === 'undefined') + ); + + res.push({ + ...edge, + selectable, + type: edgeType, + sourceX, + sourceY, + targetX, + targetY, + sourcePosition, + targetPosition, + sourceHandleId, + targetHandleId + } as EdgeLayouted); - if (!sourceIsValid || !targetIsValid) { return res; - } - - 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; - - if (!sourceHandle || !targetHandle) { - return res; - } - - 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; - - res.push({ - ...edge, - selectable: edge.selectable || typeof edge.selectable === 'undefined', - type: edgeType, - sourceX, - sourceY, - targetX, - targetY, - sourcePosition, - targetPosition, - sourceHandleId, - targetHandleId - } as EdgeLayouted); - - return res; - }, []); - }); + }, []); + } + ); } diff --git a/packages/svelte/src/lib/store/index.ts b/packages/svelte/src/lib/store/index.ts index 96b8dfe7..c8cbdc3f 100644 --- a/packages/svelte/src/lib/store/index.ts +++ b/packages/svelte/src/lib/store/index.ts @@ -332,9 +332,7 @@ export function createStore(params: CreateStoreParams): SvelteFlowStore { connectionPath: getConnectionPath(store), markers: derived( [store.edges, store.defaultMarkerColor, store.flowId], - ([edges, defaultColor, id]) => { - return createMarkerIds(edges, { defaultColor, id }); - } + ([edges, defaultColor, id]) => createMarkerIds(edges, { defaultColor, id }) ), // actions diff --git a/packages/svelte/src/lib/store/initial-store.ts b/packages/svelte/src/lib/store/initial-store.ts index a11d2a29..79890fe3 100644 --- a/packages/svelte/src/lib/store/initial-store.ts +++ b/packages/svelte/src/lib/store/initial-store.ts @@ -82,6 +82,9 @@ export const initialStoreState = { connectionRadius: writable(25), connectionLineType: writable(ConnectionLineType.Bezier), isValidConnection: writable(() => true), + nodesDraggable: writable(true), + nodesConnectable: writable(true), + elementsSelectable: writable(true), markers: readable([]), defaultMarkerColor: writable('#b1b1b7') }; diff --git a/packages/svelte/src/lib/types/edges.ts b/packages/svelte/src/lib/types/edges.ts index 6a5ced4f..411b5929 100644 --- a/packages/svelte/src/lib/types/edges.ts +++ b/packages/svelte/src/lib/types/edges.ts @@ -67,6 +67,7 @@ export type EdgeProps = Pick< | 'targetPosition' | 'animated' | 'selected' + | 'selectable' | 'label' | 'labelStyle' | 'interactionWidth' diff --git a/packages/system/src/types/edges.ts b/packages/system/src/types/edges.ts index 3b9e4e29..b4e95a35 100644 --- a/packages/system/src/types/edges.ts +++ b/packages/system/src/types/edges.ts @@ -9,6 +9,7 @@ export type BaseEdge = { animated?: boolean; hidden?: boolean; deletable?: boolean; + selectable?: boolean; data?: EdgeData; selected?: boolean; markerStart?: EdgeMarkerType;