feat(svelte): add nodesConnectable, nodesDraggable and elementsSelectable

This commit is contained in:
moklick
2023-05-22 12:24:35 +02:00
parent fb712a513f
commit ca4a6c20f9
10 changed files with 85 additions and 76 deletions
@@ -7,15 +7,6 @@
<defs> <defs>
{#each $markers as marker(marker.id)} {#each $markers as marker(marker.id)}
<Marker <Marker {...marker} />
id={marker.id}
type={marker.type}
color={marker.color}
width={marker.width}
height={marker.height}
markerUnits={marker.markerUnits}
strokeWidth={marker.strokeWidth}
orient={marker.orient}
/>
{/each} {/each}
</defs> </defs>
@@ -6,7 +6,7 @@
import { NodeWrapper } from '$lib/components/NodeWrapper'; import { NodeWrapper } from '$lib/components/NodeWrapper';
import { useStore } from '$lib/store'; import { useStore } from '$lib/store';
const { nodes, updateNodeDimensions } = useStore(); const { nodes, nodesDraggable, nodesConnectable, elementsSelectable, updateNodeDimensions } = useStore();
const resizeObserver: ResizeObserver | null = const resizeObserver: ResizeObserver | null =
typeof ResizeObserver === 'undefined' typeof ResizeObserver === 'undefined'
@@ -38,9 +38,9 @@
id={node.id} id={node.id}
data={node.data} data={node.data}
selected={node.selected} selected={node.selected}
draggable={node.draggable || node.draggable === undefined} draggable={!!(node.draggable || ($nodesDraggable && typeof node.draggable === 'undefined'))}
selectable={node.selectable || node.selectable === undefined} selectable={!!(node.selectable || ($elementsSelectable && typeof node.selectable === 'undefined'))}
connectable={node.connectable || node.connectable === undefined} connectable={!!(node.connectable || ($nodesConnectable && typeof node.connectable === 'undefined'))}
positionAbsolute={node.positionAbsolute} positionAbsolute={node.positionAbsolute}
positionOrigin={posOrigin} positionOrigin={posOrigin}
isParent={!!node[internalsSymbol]?.isParent} isParent={!!node[internalsSymbol]?.isParent}
@@ -26,6 +26,9 @@
export let edgeTypes: $$Props['edgeTypes'] = undefined; export let edgeTypes: $$Props['edgeTypes'] = undefined;
export let selectionKey: $$Props['selectionKey'] = undefined; export let selectionKey: $$Props['selectionKey'] = undefined;
export let selectionMode: $$Props['selectionMode'] = 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 snapGrid: $$Props['snapGrid'] = undefined;
export let deleteKey: $$Props['deleteKey'] = undefined; export let deleteKey: $$Props['deleteKey'] = undefined;
export let connectionRadius: $$Props['connectionRadius'] = undefined; export let connectionRadius: $$Props['connectionRadius'] = undefined;
@@ -60,7 +63,10 @@
selectionMode, selectionMode,
snapGrid, snapGrid,
isValidConnection, isValidConnection,
defaultMarkerColor defaultMarkerColor,
nodesDraggable,
nodesConnectable,
elementsSelectable,
}; };
Object.keys(updatableProps).forEach(prop => { Object.keys(updatableProps).forEach(prop => {
@@ -33,6 +33,9 @@ export type SvelteFlowProps = DOMAttributes<HTMLDivElement> & {
selectionMode?: SelectionMode; selectionMode?: SelectionMode;
snapGrid?: SnapGrid; snapGrid?: SnapGrid;
defaultMarkerColor?: string; defaultMarkerColor?: string;
nodesDraggable?: boolean;
nodesConnectable?: boolean;
elementsSelectable?: boolean;
class?: string; class?: string;
style?: string; style?: string;
@@ -17,7 +17,9 @@
export let showFitView: $$Props['showFitView'] = true; export let showFitView: $$Props['showFitView'] = true;
export let showInteractive: $$Props['showInteractive'] = 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; const isInteractive = true;
$: minZoomReached = $transform[2] <= $minZoom; $: minZoomReached = $transform[2] <= $minZoom;
@@ -36,12 +38,9 @@
}; };
const onToggleInteractivity = () => { const onToggleInteractivity = () => {
// store.setState({ nodesDraggable.set(!isInteractive);
// nodesDraggable: !isInteractive, nodesConnectable.set(!isInteractive);
// nodesConnectable: !isInteractive, elementsSelectable.set(!isInteractive);
// elementsSelectable: !isInteractive,
// });
// onInteractiveChange?.(!isInteractive);
}; };
</script> </script>
+58 -51
View File
@@ -7,57 +7,64 @@ import type { EdgeLayouted } from '$lib/types';
import type { SvelteFlowStoreState } from './types'; import type { SvelteFlowStoreState } from './types';
export function getEdgesLayouted(store: SvelteFlowStoreState) { export function getEdgesLayouted(store: SvelteFlowStoreState) {
return derived([store.edges, store.nodes], ([edges, nodes]) => { return derived(
return edges.reduce<EdgeLayouted[]>((res, edge) => { [store.edges, store.nodes, store.elementsSelectable],
const sourceNode = nodes.find((node) => node.id === edge.source); ([edges, nodes, elementsSelectable]) => {
const targetNode = nodes.find((node) => node.id === edge.target); return edges.reduce<EdgeLayouted[]>((res, edge) => {
const [sourceNodeRect, sourceHandleBounds, sourceIsValid] = getNodeData(sourceNode); const sourceNode = nodes.find((node) => node.id === edge.source);
const [targetNodeRect, targetHandleBounds, targetIsValid] = getNodeData(targetNode); 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; 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;
}, []);
});
} }
+1 -3
View File
@@ -332,9 +332,7 @@ export function createStore(params: CreateStoreParams): SvelteFlowStore {
connectionPath: getConnectionPath(store), connectionPath: getConnectionPath(store),
markers: derived( markers: derived(
[store.edges, store.defaultMarkerColor, store.flowId], [store.edges, store.defaultMarkerColor, store.flowId],
([edges, defaultColor, id]) => { ([edges, defaultColor, id]) => createMarkerIds(edges, { defaultColor, id })
return createMarkerIds(edges, { defaultColor, id });
}
), ),
// actions // actions
@@ -82,6 +82,9 @@ export const initialStoreState = {
connectionRadius: writable<number>(25), connectionRadius: writable<number>(25),
connectionLineType: writable<ConnectionLineType>(ConnectionLineType.Bezier), connectionLineType: writable<ConnectionLineType>(ConnectionLineType.Bezier),
isValidConnection: writable<IsValidConnection>(() => true), isValidConnection: writable<IsValidConnection>(() => true),
nodesDraggable: writable<boolean>(true),
nodesConnectable: writable<boolean>(true),
elementsSelectable: writable<boolean>(true),
markers: readable<MarkerProps[]>([]), markers: readable<MarkerProps[]>([]),
defaultMarkerColor: writable<string>('#b1b1b7') defaultMarkerColor: writable<string>('#b1b1b7')
}; };
+1
View File
@@ -67,6 +67,7 @@ export type EdgeProps = Pick<
| 'targetPosition' | 'targetPosition'
| 'animated' | 'animated'
| 'selected' | 'selected'
| 'selectable'
| 'label' | 'label'
| 'labelStyle' | 'labelStyle'
| 'interactionWidth' | 'interactionWidth'
+1
View File
@@ -9,6 +9,7 @@ export type BaseEdge<EdgeData = any> = {
animated?: boolean; animated?: boolean;
hidden?: boolean; hidden?: boolean;
deletable?: boolean; deletable?: boolean;
selectable?: boolean;
data?: EdgeData; data?: EdgeData;
selected?: boolean; selected?: boolean;
markerStart?: EdgeMarkerType; markerStart?: EdgeMarkerType;