feat(svelte): add nodesConnectable, nodesDraggable and elementsSelectable
This commit is contained in:
+1
-10
@@ -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>
|
||||
|
||||
|
||||
@@ -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;
|
||||
}, []);
|
||||
});
|
||||
}, []);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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')
|
||||
};
|
||||
|
||||
@@ -67,6 +67,7 @@ export type EdgeProps = Pick<
|
||||
| 'targetPosition'
|
||||
| 'animated'
|
||||
| 'selected'
|
||||
| 'selectable'
|
||||
| 'label'
|
||||
| 'labelStyle'
|
||||
| 'interactionWidth'
|
||||
|
||||
@@ -9,6 +9,7 @@ export type BaseEdge<EdgeData = any> = {
|
||||
animated?: boolean;
|
||||
hidden?: boolean;
|
||||
deletable?: boolean;
|
||||
selectable?: boolean;
|
||||
data?: EdgeData;
|
||||
selected?: boolean;
|
||||
markerStart?: EdgeMarkerType;
|
||||
|
||||
Reference in New Issue
Block a user