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>
{#each $markers as marker(marker.id)}
<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}
/>
<Marker {...marker} />
{/each}
</defs>
@@ -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}
@@ -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 => {
@@ -33,6 +33,9 @@ export type SvelteFlowProps = DOMAttributes<HTMLDivElement> & {
selectionMode?: SelectionMode;
snapGrid?: SnapGrid;
defaultMarkerColor?: string;
nodesDraggable?: boolean;
nodesConnectable?: boolean;
elementsSelectable?: boolean;
class?: string;
style?: string;
@@ -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);
};
</script>
+58 -51
View File
@@ -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<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);
return derived(
[store.edges, store.nodes, store.elementsSelectable],
([edges, nodes, elementsSelectable]) => {
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 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;
}, []);
});
}, []);
}
);
}
+1 -3
View File
@@ -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
@@ -82,6 +82,9 @@ export const initialStoreState = {
connectionRadius: writable<number>(25),
connectionLineType: writable<ConnectionLineType>(ConnectionLineType.Bezier),
isValidConnection: writable<IsValidConnection>(() => true),
nodesDraggable: writable<boolean>(true),
nodesConnectable: writable<boolean>(true),
elementsSelectable: writable<boolean>(true),
markers: readable<MarkerProps[]>([]),
defaultMarkerColor: writable<string>('#b1b1b7')
};
+1
View File
@@ -67,6 +67,7 @@ export type EdgeProps = Pick<
| 'targetPosition'
| 'animated'
| 'selected'
| 'selectable'
| 'label'
| 'labelStyle'
| 'interactionWidth'
+1
View File
@@ -9,6 +9,7 @@ export type BaseEdge<EdgeData = any> = {
animated?: boolean;
hidden?: boolean;
deletable?: boolean;
selectable?: boolean;
data?: EdgeData;
selected?: boolean;
markerStart?: EdgeMarkerType;