Files
xyflow/packages/svelte/src/lib/container/SvelteFlow/SvelteFlow.svelte
T

164 lines
4.5 KiB
Svelte

<script lang="ts">
import { onMount } from 'svelte';
import cc from 'classcat';
import { Zoom } from '$lib/container/Zoom';
import { Pane } from '$lib/container/Pane';
import { Viewport } from '$lib/container/Viewport';
import { NodeRenderer } from '$lib/container/NodeRenderer';
import { EdgeRenderer } from '$lib/container/EdgeRenderer';
import { UserSelection } from '$lib/components/UserSelection';
import { NodeSelection } from '$lib/components/NodeSelection';
import { KeyHandler } from '$lib/components/KeyHandler';
import { ConnectionLine } from '$lib/components/ConnectionLine';
import { Attribution } from '$lib/components/Attribution';
import { useStore } from '$lib/store';
import type { SvelteFlowProps } from './types';
type $$Props = SvelteFlowProps;
export let id = '1';
export let fitView: $$Props['fitView'] = undefined;
export let minZoom: $$Props['minZoom'] = undefined;
export let maxZoom: $$Props['maxZoom'] = undefined;
export let initialViewport: $$Props['initialViewport'] = undefined;
export let nodeTypes: $$Props['nodeTypes'] = undefined;
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;
export let connectionLineType: $$Props['connectionLineType'] = undefined;
export let onMoveStart: $$Props['onMoveStart'] = undefined;
export let onMove: $$Props['onMove'] = undefined;
export let onMoveEnd: $$Props['onMoveEnd'] = undefined;
export let isValidConnection: $$Props['isValidConnection'] = undefined;
export let defaultMarkerColor = '#b1b1b7';
export let style: $$Props['style'] = undefined;
let className: $$Props['class'] = undefined;
export { className as class };
let domNode: HTMLDivElement;
$: flowId = id;
const store = useStore();
onMount(() => {
const { width, height } = domNode.getBoundingClientRect();
store.width.set(width);
store.height.set(height);
store.domNode.set(domNode);
return () => {
store.reset();
}
});
$: {
const updatableProps = {
flowId,
connectionLineType,
connectionRadius,
selectionMode,
snapGrid,
isValidConnection,
defaultMarkerColor,
nodesDraggable,
nodesConnectable,
elementsSelectable,
};
Object.keys(updatableProps).forEach(prop => {
// @ts-ignore
if (updatableProps[prop] !== undefined) {
// @ts-ignore
store[prop].set(updatableProps[prop]);
}
})
}
$: {
if (nodeTypes !== undefined) {
store.setNodeTypes(nodeTypes);
}
if (edgeTypes !== undefined) {
store.setEdgeTypes(edgeTypes);
}
if (minZoom !== undefined) {
store.setMinZoom(minZoom);
}
if (maxZoom !== undefined) {
store.setMaxZoom(maxZoom);
}
if (fitView !== undefined) {
store.fitViewOnInit.set(fitView);
}
}
</script>
<div
bind:this={domNode}
{style}
class={cc(['svelte-flow', className])}
data-testid="svelte-flow__wrapper"
on:dragover
on:drop
{...$$restProps}
>
<KeyHandler {selectionKey} {deleteKey} />
<Zoom {initialViewport} {onMoveStart} {onMove} {onMoveEnd}>
<Pane on:pane:click>
<Viewport>
<EdgeRenderer on:edge:click />
<ConnectionLine />
<div class="svelte-flow__edgelabel-renderer" />
<NodeRenderer
on:node:click
on:node:mouseenter
on:node:mousemove
on:node:mouseleave
on:connect:start
on:connect
on:connect:end
/>
<NodeSelection />
</Viewport>
<UserSelection />
</Pane>
</Zoom>
<Attribution />
<slot />
</div>
<style>
.svelte-flow {
width: 100%;
height: 100%;
overflow: hidden;
position: relative;
z-index: 0;
}
.svelte-flow :global(.svelte-flow__node-default),
.svelte-flow :global(.svelte-flow__node-input),
.svelte-flow :global(.svelte-flow__node-output) {
padding: 10px;
}
.svelte-flow__edgelabel-renderer {
position: absolute;
width: 100%;
height: 100%;
pointer-events: none;
user-select: none;
}
</style>