start to migrate

This commit is contained in:
peterkogo
2024-11-12 16:46:09 +01:00
parent 352122968f
commit 880ed8886b
13 changed files with 528 additions and 519 deletions
@@ -1,15 +1,7 @@
<script lang="ts"> <script lang="ts">
import { Handle, Position, type NodeProps } from '@xyflow/svelte'; import { Handle, Position, type NodeProps } from '@xyflow/svelte';
type $$Props = NodeProps; let { isConnectable }: NodeProps = $props();
interface Props {
isConnectable: $$Props['isConnectable'];
[key: string]: any
}
let { isConnectable, ...rest }: Props = $props();
rest;
const handleStyle = 'width: 10px; height: 10px; bottom: -5px;'; const handleStyle = 'width: 10px; height: 10px; bottom: -5px;';
</script> </script>
@@ -2,16 +2,7 @@
import type { Writable } from 'svelte/store'; import type { Writable } from 'svelte/store';
import { Handle, Position, type NodeProps, type Node } from '@xyflow/svelte'; import { Handle, Position, type NodeProps, type Node } from '@xyflow/svelte';
type $$Props = NodeProps<Node<{ colorStore: Writable<string> }>>; let { data }: NodeProps<Node<{ colorStore: Writable<string> }>> = $props();
interface Props {
data: $$Props['data'];
[key: string]: any
}
let { data, ...rest }: Props = $props();
rest;
const { colorStore } = data; const { colorStore } = data;
</script> </script>
@@ -1,14 +1,7 @@
<script lang="ts"> <script lang="ts">
import { Handle, Position, type NodeProps, type Connection } from '@xyflow/svelte'; import { Handle, Position, type NodeProps, type Connection } from '@xyflow/svelte';
type $$Props = NodeProps; let { id }: NodeProps = $props();
interface Props {
id: $$Props['id'];
[key: string]: any
}
let { id, ...rest }: Props = $props();
function onConnectTarget(connection: Connection[]) { function onConnectTarget(connection: Connection[]) {
console.log('connect target', connection); console.log('connect target', connection);
@@ -25,8 +18,6 @@
function onDisconnectSource(connection: Connection[]) { function onDisconnectSource(connection: Connection[]) {
console.log('disconnect source', connection); console.log('disconnect source', connection);
} }
rest;
</script> </script>
<div class="custom"> <div class="custom">
@@ -1,15 +1,7 @@
<script lang="ts"> <script lang="ts">
import { NodeToolbar, type NodeProps, Handle, Position } from '@xyflow/svelte'; import { NodeToolbar, type NodeProps, Handle, Position } from '@xyflow/svelte';
type $$Props = NodeProps; let { data }: NodeProps = $props();
rest;
interface Props {
data: $$Props['data'];
[key: string]: any
}
let { data, ...rest }: Props = $props();
</script> </script>
<NodeToolbar <NodeToolbar
@@ -1,17 +1,11 @@
<script lang="ts"> <script lang="ts">
import { Handle, Position, type BuiltInNode, type NodeProps } from '@xyflow/svelte'; import { Handle, Position, type BuiltInNode, type NodeProps } from '@xyflow/svelte';
type $$Props = NodeProps<BuiltInNode>; let {
rest; data = { label: 'Node' },
positionAbsoluteX = 0,
interface Props { positionAbsoluteY = 0
data?: { label: string }; }: NodeProps = $props();
positionAbsoluteX?: number;
positionAbsoluteY?: number;
[key: string]: any
}
let { data = { label: 'Node' }, positionAbsoluteX = 0, positionAbsoluteY = 0, ...rest }: Props = $props();
</script> </script>
<div class="custom"> <div class="custom">
@@ -1,15 +1,7 @@
<script lang="ts"> <script lang="ts">
import type { BuiltInNode, NodeProps } from '@xyflow/svelte'; import type { BuiltInNode, NodeProps } from '@xyflow/svelte';
type $$Props = NodeProps<BuiltInNode>; let { data = { label: 'Node' } }: NodeProps<BuiltInNode> = $props();
rest;
interface Props {
data?: { label: string };
[key: string]: any
}
let { data = { label: 'Node' }, ...rest }: Props = $props();
</script> </script>
<div class="custom"> <div class="custom">
@@ -8,22 +8,16 @@
} from '@xyflow/svelte'; } from '@xyflow/svelte';
import { isTextNode, type MyNode } from './+page.svelte'; import { isTextNode, type MyNode } from './+page.svelte';
type $$Props = NodeProps; let { id }: NodeProps = $props();
interface Props {
id: $$Props['id'];
[key: string]: any
}
let { id, ...rest }: Props = $props();
rest;
const connections = useHandleConnections({ const connections = useHandleConnections({
nodeId: id, nodeId: id,
type: 'target' type: 'target'
}); });
let nodeData = $derived(useNodesData<MyNode>($connections.map((connection) => connection.source))); let nodeData = $derived(
useNodesData<MyNode>($connections.map((connection) => connection.source))
);
let textNodes = $derived($nodeData.filter(isTextNode)); let textNodes = $derived($nodeData.filter(isTextNode));
</script> </script>
@@ -1,18 +1,9 @@
<script lang="ts"> <script lang="ts">
import { Handle, Position, type NodeProps, useSvelteFlow } from '@xyflow/svelte'; import { Handle, Position, type NodeProps, useSvelteFlow } from '@xyflow/svelte';
type $$Props = NodeProps; let { id, data }: NodeProps = $props();
interface Props {
id: $$Props['id'];
data: $$Props['data'];
[key: string]: any
}
let { id, data, ...rest }: Props = $props();
const { updateNodeData } = useSvelteFlow(); const { updateNodeData } = useSvelteFlow();
rest;
</script> </script>
<div class="custom"> <div class="custom">
@@ -1,21 +1,12 @@
<script lang="ts"> <script lang="ts">
import { Handle, Position, type NodeProps, useUpdateNodeInternals } from '@xyflow/svelte'; import { Handle, Position, type NodeProps, useUpdateNodeInternals } from '@xyflow/svelte';
type $$Props = NodeProps; let { id }: NodeProps = $props();
interface Props {
id: $$Props['id'];
[key: string]: any
}
let { id, ...rest }: Props = $props();
rest;
const updateNodeInternals = useUpdateNodeInternals(); const updateNodeInternals = useUpdateNodeInternals();
let handleCount = $state(1); let handleCount = $state(1);
const onClick = () => { const onClick = () => {
handleCount += 1; handleCount += 1;
updateNodeInternals(id); updateNodeInternals(id);
+1 -1
View File
@@ -79,7 +79,7 @@
"svelte-eslint-parser": "^0.43.0", "svelte-eslint-parser": "^0.43.0",
"svelte-preprocess": "^6.0.3", "svelte-preprocess": "^6.0.3",
"tslib": "^2.8.1", "tslib": "^2.8.1",
"typescript": "5.4.2" "typescript": "^5.5.0"
}, },
"peerDependencies": { "peerDependencies": {
"svelte": "^3.0.0 || ^4.0.0 || ^5.0.0" "svelte": "^3.0.0 || ^4.0.0 || ^5.0.0"
@@ -19,79 +19,93 @@
import { updateStore, updateStoreByKeys, type UpdatableStoreProps } from './utils'; import { updateStore, updateStoreByKeys, type UpdatableStoreProps } from './utils';
import { useColorModeClass } from '$lib/hooks/useColorModeClass'; import { useColorModeClass } from '$lib/hooks/useColorModeClass';
type $$Props = SvelteFlowProps; let {
id = '1',
nodes,
edges,
fitView,
fitViewOptions,
minZoom,
maxZoom,
initialViewport,
viewport,
nodeTypes,
edgeTypes,
selectionKey,
selectionMode,
panActivationKey,
multiSelectionKey,
zoomActivationKey,
nodesDraggable,
nodesConnectable,
nodeDragThreshold,
elementsSelectable,
snapGrid,
deleteKey,
connectionRadius,
connectionLineType,
connectionMode = ConnectionMode.Strict,
connectionLineStyle = '',
connectionLineContainerStyle = '',
onMoveStart,
onMove,
onMoveEnd,
isValidConnection,
translateExtent,
nodeExtent,
onlyRenderVisibleElements,
panOnScrollMode = PanOnScrollMode.Free,
preventScrolling = true,
zoomOnScroll = true,
zoomOnDoubleClick = true,
zoomOnPinch = true,
panOnScroll = false,
panOnDrag = true,
selectionOnDrag,
autoPanOnConnect = true,
autoPanOnNodeDrag = true,
onerror,
ondelete,
onedgecreate,
attributionPosition,
proOptions,
defaultEdgeOptions,
width,
height,
colorMode = 'light',
onconnect,
onconnectstart,
onconnectend,
onbeforedelete,
oninit,
nodeOrigin,
paneClickDistance = 0,
nodeClickDistance = 0,
defaultMarkerColor = '#b1b1b7',
style,
class: className,
connectionLine,
children,
onnodeclick,
onnodecontextmenu,
onnodedrag,
onnodedragstart,
onnodedragstop,
onnodemouseenter,
onnodemousemove,
onnodemouseleave,
onselectionclick,
onselectioncontextmenu,
onedgeclick,
onedgecontextmenu,
onedgemouseenter,
onedgemouseleave,
...rest
}: SvelteFlowProps = $props();
export let id: $$Props['id'] = '1'; let domNode = $state<HTMLDivElement>();
export let nodes: $$Props['nodes']; let clientWidth = $state<number>();
export let edges: $$Props['edges']; let clientHeight = $state<number>();
export let fitView: $$Props['fitView'] = undefined;
export let fitViewOptions: $$Props['fitViewOptions'] = undefined;
export let minZoom: $$Props['minZoom'] = undefined;
export let maxZoom: $$Props['maxZoom'] = undefined;
export let initialViewport: $$Props['initialViewport'] = undefined;
export let viewport: $$Props['viewport'] = 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 panActivationKey: $$Props['panActivationKey'] = undefined;
export let multiSelectionKey: $$Props['multiSelectionKey'] = undefined;
export let zoomActivationKey: $$Props['zoomActivationKey'] = undefined;
export let nodesDraggable: $$Props['nodesDraggable'] = undefined;
export let nodesConnectable: $$Props['nodesConnectable'] = undefined;
export let nodeDragThreshold: $$Props['nodeDragThreshold'] = 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 connectionMode: $$Props['connectionMode'] = ConnectionMode.Strict;
export let connectionLineStyle: $$Props['connectionLineStyle'] = '';
export let connectionLineContainerStyle: $$Props['connectionLineContainerStyle'] = '';
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 translateExtent: $$Props['translateExtent'] = undefined;
export let nodeExtent: $$Props['nodeExtent'] = undefined;
export let onlyRenderVisibleElements: $$Props['onlyRenderVisibleElements'] = undefined;
export let panOnScrollMode: $$Props['panOnScrollMode'] = PanOnScrollMode.Free;
export let preventScrolling: $$Props['preventScrolling'] = true;
export let zoomOnScroll: $$Props['zoomOnScroll'] = true;
export let zoomOnDoubleClick: $$Props['zoomOnDoubleClick'] = true;
export let zoomOnPinch: $$Props['zoomOnPinch'] = true;
export let panOnScroll: $$Props['panOnScroll'] = false;
export let panOnDrag: $$Props['panOnDrag'] = true;
export let selectionOnDrag: $$Props['selectionOnDrag'] = undefined;
export let autoPanOnConnect: $$Props['autoPanOnConnect'] = true;
export let autoPanOnNodeDrag: $$Props['autoPanOnNodeDrag'] = true;
export let onerror: $$Props['onerror'] = undefined;
export let ondelete: $$Props['ondelete'] = undefined;
export let onedgecreate: $$Props['onedgecreate'] = undefined;
export let attributionPosition: $$Props['attributionPosition'] = undefined;
export let proOptions: $$Props['proOptions'] = undefined;
export let defaultEdgeOptions: $$Props['defaultEdgeOptions'] = undefined;
export let width: $$Props['width'] = undefined;
export let height: $$Props['height'] = undefined;
export let colorMode: $$Props['colorMode'] = 'light';
export let onconnect: $$Props['onconnect'] = undefined;
export let onconnectstart: $$Props['onconnectstart'] = undefined;
export let onconnectend: $$Props['onconnectend'] = undefined;
export let onbeforedelete: $$Props['onbeforedelete'] = undefined;
export let oninit: $$Props['oninit'] = undefined;
export let nodeOrigin: $$Props['nodeOrigin'] = undefined;
export let paneClickDistance: $$Props['paneClickDistance'] = 0;
export let nodeClickDistance: $$Props['nodeClickDistance'] = 0;
export let defaultMarkerColor = '#b1b1b7';
export let style: $$Props['style'] = undefined;
let className: $$Props['class'] = undefined;
export { className as class };
let domNode: HTMLDivElement;
let clientWidth: number;
let clientHeight: number;
const initViewport = $viewport || initialViewport; const initViewport = $viewport || initialViewport;
@@ -108,9 +122,9 @@
}); });
onMount(() => { onMount(() => {
store.width.set(clientWidth); store.width.set(clientWidth!);
store.height.set(clientHeight); store.height.set(clientHeight!);
store.domNode.set(domNode); store.domNode.set(domNode!);
store.syncNodeStores(nodes); store.syncNodeStores(nodes);
store.syncEdgeStores(edges); store.syncEdgeStores(edges);
@@ -139,26 +153,26 @@
}); });
// Update width & height on resize // Update width & height on resize
$: { $effect.pre(() => {
if (clientWidth !== undefined && clientHeight !== undefined) { if (clientWidth !== undefined && clientHeight !== undefined) {
store.width.set(clientWidth); store.width.set(clientWidth);
store.height.set(clientHeight); store.height.set(clientHeight);
} }
} });
// Call oninit once when flow is intialized // Call oninit once when flow is intialized
const { initialized } = store; const { initialized } = store;
let onInitCalled = false; let onInitCalled = $state(false);
$: { $effect.pre(() => {
if (!onInitCalled && $initialized) { if (!onInitCalled && $initialized) {
oninit?.(); oninit?.();
onInitCalled = true; onInitCalled = true;
} }
} });
// this updates the store for simple changes // this updates the store for simple changes
// where the prop names equals the store name // where the prop names equals the store name
$: { $effect(() => {
const updatableProps: UpdatableStoreProps = { const updatableProps: UpdatableStoreProps = {
flowId: id, flowId: id,
connectionLineType, connectionLineType,
@@ -186,18 +200,20 @@
}; };
updateStoreByKeys(store, updatableProps); updateStoreByKeys(store, updatableProps);
}
$: updateStore(store, {
nodeTypes,
edgeTypes,
minZoom,
maxZoom,
translateExtent,
paneClickDistance
}); });
$: colorModeClass = useColorModeClass(colorMode); $effect(() => {
updateStore(store, {
nodeTypes,
edgeTypes,
minZoom,
maxZoom,
translateExtent,
paneClickDistance
});
});
let colorModeClass = $derived(useColorModeClass(colorMode));
</script> </script>
<div <div
@@ -207,9 +223,7 @@
{style} {style}
class={cc(['svelte-flow', className, $colorModeClass])} class={cc(['svelte-flow', className, $colorModeClass])}
data-testid="svelte-flow__wrapper" data-testid="svelte-flow__wrapper"
on:dragover {...rest}
on:drop
{...$$restProps}
role="application" role="application"
> >
<KeyHandler <KeyHandler
@@ -242,44 +256,47 @@
<ViewportComponent> <ViewportComponent>
<EdgeRenderer <EdgeRenderer
on:edgeclick on:edgeclick
on:edgecontextmenu {onedgeclick}
on:edgemouseenter {onedgecontextmenu}
on:edgemouseleave {onedgemouseenter}
{onedgemouseleave}
{defaultEdgeOptions} {defaultEdgeOptions}
/> />
<ConnectionLine <!-- <ConnectionLine
containerStyle={connectionLineContainerStyle} containerStyle={connectionLineContainerStyle}
style={connectionLineStyle} style={connectionLineStyle}
isCustomComponent={$$slots.connectionLine} isCustomComponent={connectionLine}
> >
<slot name="connectionLine" slot="connectionLine" /> {#snippet connectionLine()}
</ConnectionLine> {@render connectionLine_render?.()}
<div class="svelte-flow__edgelabel-renderer" /> {/snippet}
<div class="svelte-flow__viewport-portal" /> </ConnectionLine> -->
<div class="svelte-flow__edgelabel-renderer"></div>
<div class="svelte-flow__viewport-portal"></div>
<NodeRenderer <NodeRenderer
{nodeClickDistance} {nodeClickDistance}
on:nodeclick {onnodeclick}
on:nodemouseenter {onnodecontextmenu}
on:nodemousemove {onnodemouseenter}
on:nodemouseleave {onnodemousemove}
on:nodedragstart {onnodemouseleave}
on:nodedrag {onnodedrag}
on:nodedragstop {onnodedragstart}
on:nodecontextmenu {onnodedragstop}
/> />
<NodeSelection <NodeSelection
on:selectionclick {onselectionclick}
on:selectioncontextmenu {onselectioncontextmenu}
on:nodedragstart {onnodedrag}
on:nodedrag {onnodedragstart}
on:nodedragstop {onnodedragstop}
/> />
</ViewportComponent> </ViewportComponent>
<UserSelection /> <UserSelection />
</Pane> </Pane>
</Zoom> </Zoom>
<Attribution {proOptions} position={attributionPosition} /> <Attribution {proOptions} position={attributionPosition} />
<slot /> {@render children?.()}
</div> </div>
<style> <style>
@@ -34,319 +34,327 @@ import type {
IsValidConnection IsValidConnection
} from '$lib/types'; } from '$lib/types';
import type { Writable } from 'svelte/store'; import type { Writable } from 'svelte/store';
import type { Snippet } from 'svelte';
import type { EdgeEvents, NodeEvents, NodeSelectionEvents, PaneEvents } from '$lib/types/events';
export type SvelteFlowProps = DOMAttributes<HTMLDivElement> & { export type SvelteFlowProps = NodeEvents &
/** The id of the flow NodeSelectionEvents &
* EdgeEvents &
* This is necessary if you want to render multiple flows. PaneEvents &
* @optional DOMAttributes<HTMLDivElement> & {
*/ /** The id of the flow
id?: string; *
/** An array of nodes to render in a controlled flow. * This is necessary if you want to render multiple flows.
* @example * @optional
* const nodes = writable([ */
* { id?: string;
* id: 'node-1', /** An array of nodes to render in a controlled flow.
* type: 'input', * @example
* data: { label: 'Node 1' }, * const nodes = writable([
* position: { x: 250, y: 50 } * {
* } * id: 'node-1',
* ]); * type: 'input',
*/ * data: { label: 'Node 1' },
nodes: Writable<Node[]>; * position: { x: 250, y: 50 }
/** An array of edges to render in a controlled flow. * }
* @example * ]);
* const edges = writable([ */
* { nodes: Writable<Node[]>;
* id: 'edge-1-2', /** An array of edges to render in a controlled flow.
* source: 'node-1', * @example
* target: 'node-2', * const edges = writable([
* } * {
* ]); * id: 'edge-1-2',
*/ * source: 'node-1',
edges: Writable<Edge[]>; * target: 'node-2',
/** Custom node types to be available in a flow. * }
* * ]);
* Svelte Flow matches a node's type to a component in the nodeTypes object. */
* @example edges: Writable<Edge[]>;
* import CustomNode from './CustomNode.svelte'; /** Custom node types to be available in a flow.
* *
* const nodeTypes = { nameOfNodeType: CustomNode }; * Svelte Flow matches a node's type to a component in the nodeTypes object.
*/ * @example
nodeTypes?: NodeTypes; * import CustomNode from './CustomNode.svelte';
/** Custom edge types to be available in a flow. *
* * const nodeTypes = { nameOfNodeType: CustomNode };
* Svelte Flow matches an edge's type to a component in the edgeTypes object. */
* @example nodeTypes?: NodeTypes;
* import CustomEdge from './CustomEdge.svelte'; /** Custom edge types to be available in a flow.
* *
* const edgeTypes = { nameOfEdgeType: CustomEdge }; * Svelte Flow matches an edge's type to a component in the edgeTypes object.
*/ * @example
edgeTypes?: EdgeTypes; * import CustomEdge from './CustomEdge.svelte';
/** Pressing down this key you can select multiple elements with a selection box. *
* @default 'Shift' * const edgeTypes = { nameOfEdgeType: CustomEdge };
*/ */
selectionKey?: KeyDefinition | KeyDefinition[] | null; edgeTypes?: EdgeTypes;
/** If a key is set, you can pan the viewport while that key is held down even if panOnScroll is set to false. /** Pressing down this key you can select multiple elements with a selection box.
* * @default 'Shift'
* By setting this prop to null you can disable this functionality. */
* @default 'Space' selectionKey?: KeyDefinition | KeyDefinition[] | null;
*/ /** If a key is set, you can pan the viewport while that key is held down even if panOnScroll is set to false.
panActivationKey?: KeyDefinition | KeyDefinition[] | null; *
/** Pressing down this key deletes all selected nodes & edges. * By setting this prop to null you can disable this functionality.
* @default 'Backspace' * @default 'Space'
*/ */
deleteKey?: KeyDefinition | KeyDefinition[] | null; panActivationKey?: KeyDefinition | KeyDefinition[] | null;
/** Pressing down this key you can select multiple elements by clicking. /** Pressing down this key deletes all selected nodes & edges.
* @default 'Meta' for macOS, "Ctrl" for other systems * @default 'Backspace'
*/ */
multiSelectionKey?: KeyDefinition | KeyDefinition[] | null; deleteKey?: KeyDefinition | KeyDefinition[] | null;
/** If a key is set, you can zoom the viewport while that key is held down even if panOnScroll is set to false. /** Pressing down this key you can select multiple elements by clicking.
* * @default 'Meta' for macOS, "Ctrl" for other systems
* By setting this prop to null you can disable this functionality. */
* @default 'Meta' for macOS, "Ctrl" for other systems multiSelectionKey?: KeyDefinition | KeyDefinition[] | null;
* */ /** If a key is set, you can zoom the viewport while that key is held down even if panOnScroll is set to false.
zoomActivationKey?: KeyDefinition | KeyDefinition[] | null; *
/** If set, initial viewport will show all nodes & edges */ * By setting this prop to null you can disable this functionality.
fitView?: boolean; * @default 'Meta' for macOS, "Ctrl" for other systems
/** Options to be used in combination with fitView * */
* @example zoomActivationKey?: KeyDefinition | KeyDefinition[] | null;
* const fitViewOptions = { /** If set, initial viewport will show all nodes & edges */
* padding: 0.1, fitView?: boolean;
* includeHiddenNodes: false, /** Options to be used in combination with fitView
* minZoom: 0.1, * @example
* maxZoom: 1, * const fitViewOptions = {
* duration: 200, * padding: 0.1,
* nodes: [{id: 'node-1'}, {id: 'node-2'}], // nodes to fit * includeHiddenNodes: false,
* }; * minZoom: 0.1,
*/ * maxZoom: 1,
fitViewOptions?: FitViewOptions; * duration: 200,
/** Defines nodes relative position to its coordinates * nodes: [{id: 'node-1'}, {id: 'node-2'}], // nodes to fit
* @example * };
* [0, 0] // default, top left */
* [0.5, 0.5] // center fitViewOptions?: FitViewOptions;
* [1, 1] // bottom right /** Defines nodes relative position to its coordinates
*/ * @example
nodeOrigin?: NodeOrigin; * [0, 0] // default, top left
/** With a threshold greater than zero you can control the distinction between node drag and click events. * [0.5, 0.5] // center
* * [1, 1] // bottom right
* If threshold equals 1, you need to drag the node 1 pixel before a drag event is fired. */
* @default 1 nodeOrigin?: NodeOrigin;
*/ /** With a threshold greater than zero you can control the distinction between node drag and click events.
nodeDragThreshold?: number; *
/** Distance that the mouse can move between mousedown/up that will trigger a click * If threshold equals 1, you need to drag the node 1 pixel before a drag event is fired.
* @default 0 * @default 1
*/ */
paneClickDistance?: number; nodeDragThreshold?: number;
/** Distance that the mouse can move between mousedown/up that will trigger a click /** Distance that the mouse can move between mousedown/up that will trigger a click
* @default 0 * @default 0
*/ */
nodeClickDistance?: number; paneClickDistance?: number;
/** Minimum zoom level /** Distance that the mouse can move between mousedown/up that will trigger a click
* @default 0.5 * @default 0
*/ */
minZoom?: number; nodeClickDistance?: number;
/** Maximum zoom level /** Minimum zoom level
* @default 2 * @default 0.5
*/ */
maxZoom?: number; minZoom?: number;
/** Sets the initial position and zoom of the viewport. /** Maximum zoom level
* * @default 2
* If a default viewport is provided but fitView is enabled, the default viewport will be ignored. */
* @example maxZoom?: number;
* const initialViewport = { /** Sets the initial position and zoom of the viewport.
* zoom: 0.5, *
* position: { x: 0, y: 0 } * If a default viewport is provided but fitView is enabled, the default viewport will be ignored.
* }; * @example
*/ * const initialViewport = {
initialViewport?: Viewport; * zoom: 0.5,
/** Custom viewport writable to be used instead of internal one */ * position: { x: 0, y: 0 }
viewport?: Writable<Viewport>; * };
/** The radius around a handle where you drop a connection line to create a new edge. */
* @default 20 initialViewport?: Viewport;
*/ /** Custom viewport writable to be used instead of internal one */
connectionRadius?: number; viewport?: Writable<Viewport>;
/** 'strict' connection mode will only allow you to connect source handles to target handles. /** The radius around a handle where you drop a connection line to create a new edge.
* * @default 20
* 'loose' connection mode will allow you to connect handles of any type to one another. */
* @default 'strict' connectionRadius?: number;
*/ /** 'strict' connection mode will only allow you to connect source handles to target handles.
connectionMode?: ConnectionMode; *
/** Styles to be applied to the connection line */ * 'loose' connection mode will allow you to connect handles of any type to one another.
connectionLineStyle?: string; * @default 'strict'
/** Styles to be applied to the container of the connection line */ */
connectionLineContainerStyle?: string; connectionMode?: ConnectionMode;
/** When set to "partial", when the user creates a selection box by click and dragging nodes that are only partially in the box are still selected. /** Provide a custom snippet to be used insted of the default connection line */
* @default 'full' connectionLine?: Snippet;
*/ /** Styles to be applied to the connection line */
selectionMode?: SelectionMode; connectionLineStyle?: string;
/** Grid all nodes will snap to /** Styles to be applied to the container of the connection line */
* @example [20, 20] connectionLineContainerStyle?: string;
*/ /** When set to "partial", when the user creates a selection box by click and dragging nodes that are only partially in the box are still selected.
snapGrid?: SnapGrid; * @default 'full'
/** Color of edge markers */
* @example "#b1b1b7" selectionMode?: SelectionMode;
*/ /** Grid all nodes will snap to
defaultMarkerColor?: string; * @example [20, 20]
/** Controls if all nodes should be draggable */
* @default true snapGrid?: SnapGrid;
*/ /** Color of edge markers
nodesDraggable?: boolean; * @example "#b1b1b7"
/** Controls if all nodes should be connectable to each other */
* @default true defaultMarkerColor?: string;
*/ /** Controls if all nodes should be draggable
nodesConnectable?: boolean; * @default true
/** Controls if all elements should (nodes & edges) be selectable */
* @default true nodesDraggable?: boolean;
*/ /** Controls if all nodes should be connectable to each other
elementsSelectable?: boolean; * @default true
/** By default the viewport extends infinitely. You can use this prop to set a boundary. */
* nodesConnectable?: boolean;
* The first pair of coordinates is the top left boundary and the second pair is the bottom right. /** Controls if all elements should (nodes & edges) be selectable
* @example [[-1000, -10000], [1000, 1000]] * @default true
*/ */
translateExtent?: CoordinateExtent; elementsSelectable?: boolean;
/** By default the nodes can be placed anywhere. You can use this prop to set a boundary. /** By default the viewport extends infinitely. You can use this prop to set a boundary.
* *
* The first pair of coordinates is the top left boundary and the second pair is the bottom right. * The first pair of coordinates is the top left boundary and the second pair is the bottom right.
* @example [[-1000, -10000], [1000, 1000]] * @example [[-1000, -10000], [1000, 1000]]
*/ */
nodeExtent?: CoordinateExtent; translateExtent?: CoordinateExtent;
/** Disabling this prop will allow the user to scroll the page even when their pointer is over the flow. /** By default the nodes can be placed anywhere. You can use this prop to set a boundary.
* @default true *
*/ * The first pair of coordinates is the top left boundary and the second pair is the bottom right.
preventScrolling?: boolean; * @example [[-1000, -10000], [1000, 1000]]
/** Controls if the viewport should zoom by scrolling inside the container */ */
zoomOnScroll?: boolean; nodeExtent?: CoordinateExtent;
/** Controls if the viewport should zoom by double clicking somewhere on the flow */ /** Disabling this prop will allow the user to scroll the page even when their pointer is over the flow.
zoomOnDoubleClick?: boolean; * @default true
/** Controls if the viewport should zoom by pinching on a touch screen */ */
zoomOnPinch?: boolean; preventScrolling?: boolean;
/** Controls if the viewport should pan by scrolling inside the container /** Controls if the viewport should zoom by scrolling inside the container */
* zoomOnScroll?: boolean;
* Can be limited to a specific direction with panOnScrollMode /** Controls if the viewport should zoom by double clicking somewhere on the flow */
*/ zoomOnDoubleClick?: boolean;
panOnScroll?: boolean; /** Controls if the viewport should zoom by pinching on a touch screen */
/** This prop is used to limit the direction of panning when panOnScroll is enabled. zoomOnPinch?: boolean;
* /** Controls if the viewport should pan by scrolling inside the container
* The "free" option allows panning in any direction. *
* @default "free" * Can be limited to a specific direction with panOnScrollMode
* @example "horizontal" | "vertical" */
*/ panOnScroll?: boolean;
panOnScrollMode?: PanOnScrollMode; /** This prop is used to limit the direction of panning when panOnScroll is enabled.
/** Enableing this prop allows users to pan the viewport by clicking and dragging. *
* * The "free" option allows panning in any direction.
* You can also set this prop to an array of numbers to limit which mouse buttons can activate panning. * @default "free"
* @example [0, 2] // allows panning with the left and right mouse buttons * @example "horizontal" | "vertical"
* [0, 1, 2, 3, 4] // allows panning with all mouse buttons */
*/ panOnScrollMode?: PanOnScrollMode;
panOnDrag?: boolean | number[]; /** Enableing this prop allows users to pan the viewport by clicking and dragging.
/** Select multiple elements with a selection box, without pressing down selectionKey */ *
selectionOnDrag?: boolean; * You can also set this prop to an array of numbers to limit which mouse buttons can activate panning.
/** You can enable this optimisation to instruct Svelte Flow to only render nodes and edges that would be visible in the viewport. * @example [0, 2] // allows panning with the left and right mouse buttons
* * [0, 1, 2, 3, 4] // allows panning with all mouse buttons
* This might improve performance when you have a large number of nodes and edges but also adds an overhead. */
* @default false panOnDrag?: boolean | number[];
*/ /** Select multiple elements with a selection box, without pressing down selectionKey */
onlyRenderVisibleElements?: boolean; selectionOnDrag?: boolean;
/** You can enable this prop to automatically pan the viewport while making a new connection. /** You can enable this optimisation to instruct Svelte Flow to only render nodes and edges that would be visible in the viewport.
* @default true *
*/ * This might improve performance when you have a large number of nodes and edges but also adds an overhead.
autoPanOnConnect?: boolean; * @default false
/** You can enable this prop to automatically pan the viewport while dragging a node. */
* @default true onlyRenderVisibleElements?: boolean;
*/ /** You can enable this prop to automatically pan the viewport while making a new connection.
autoPanOnNodeDrag?: boolean; * @default true
/** Set position of the attribution */
* @default 'bottom-right' autoPanOnConnect?: boolean;
* @example 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right' /** You can enable this prop to automatically pan the viewport while dragging a node.
*/ * @default true
attributionPosition?: PanelPosition; */
/** By default, we render a small attribution in the corner of your flows that links back to the project. autoPanOnNodeDrag?: boolean;
* /** Set position of the attribution
* Anyone is free to remove this attribution whether they're a Pro subscriber or not * @default 'bottom-right'
* but we ask that you take a quick look at our {@link https://reactflow.dev/learn/troubleshooting/remove-attribution | removing attribution guide} * @example 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right'
* before doing so. */
*/ attributionPosition?: PanelPosition;
proOptions?: ProOptions; /** By default, we render a small attribution in the corner of your flows that links back to the project.
/** Defaults to be applied to all new edges that are added to the flow. *
* * Anyone is free to remove this attribution whether they're a Pro subscriber or not
* Properties on a new edge will override these defaults if they exist. * but we ask that you take a quick look at our {@link https://reactflow.dev/learn/troubleshooting/remove-attribution | removing attribution guide}
* @example * before doing so.
* const defaultEdgeOptions = { */
* type: 'customEdgeType', proOptions?: ProOptions;
* animated: true, /** Defaults to be applied to all new edges that are added to the flow.
* interactionWidth: 10, *
* data: { label: 'custom label' }, * Properties on a new edge will override these defaults if they exist.
* hidden: false, * @example
* deletable: true, * const defaultEdgeOptions = {
* selected: false, * type: 'customEdgeType',
* focusable: true, * animated: true,
* markerStart: EdgeMarker.ArrowClosed, * interactionWidth: 10,
* markerEnd: EdgeMarker.ArrowClosed, * data: { label: 'custom label' },
* zIndex: 12, * hidden: false,
* ariaLabel: 'custom aria label' * deletable: true,
* } * selected: false,
*/ * focusable: true,
defaultEdgeOptions?: DefaultEdgeOptions; * markerStart: EdgeMarker.ArrowClosed,
/** Sets a fixed width for the flow */ * markerEnd: EdgeMarker.ArrowClosed,
width?: number; * zIndex: 12,
/** Sets a fixed height for the flow */ * ariaLabel: 'custom aria label'
height?: number; * }
/** Controls color scheme used for styling the flow */
* @default 'system' defaultEdgeOptions?: DefaultEdgeOptions;
* @example 'system' | 'light' | 'dark' /** Sets a fixed width for the flow */
*/ width?: number;
colorMode?: ColorMode; /** Sets a fixed height for the flow */
/** Class to be applied to the flow container */ height?: number;
class?: string; /** Controls color scheme used for styling the flow
/** Styles to be applied to the flow container */ * @default 'system'
style?: string; * @example 'system' | 'light' | 'dark'
/** Choose from the built-in edge types to be used for connections */
* @default 'default' | ConnectionLineType.Bezier colorMode?: ColorMode;
* @example 'straight' | 'default' | 'step' | 'smoothstep' | 'bezier' /** Class to be applied to the flow container */
* @example ConnectionLineType.Straight | ConnectionLineType.Default | ConnectionLineType.Step | ConnectionLineType.SmoothStep | ConnectionLineType.Bezier class?: string;
*/ /** Styles to be applied to the flow container */
connectionLineType?: ConnectionLineType; style?: string;
/** This callback can be used to validate a new connection /** Choose from the built-in edge types to be used for connections
* * @default 'default' | ConnectionLineType.Bezier
* If you return false, the edge will not be added to your flow. * @example 'straight' | 'default' | 'step' | 'smoothstep' | 'bezier'
* If you have custom connection logic its preferred to use this callback over the isValidConnection prop on the handle component for performance reasons. * @example ConnectionLineType.Straight | ConnectionLineType.Default | ConnectionLineType.Step | ConnectionLineType.SmoothStep | ConnectionLineType.Bezier
* @default (connection: Connection) => true */
*/ connectionLineType?: ConnectionLineType;
isValidConnection?: IsValidConnection; /** This callback can be used to validate a new connection
/** This event handler is called when the user begins to pan or zoom the viewport */ *
onMoveStart?: OnMoveStart; * If you return false, the edge will not be added to your flow.
/** This event handler is called when the user pans or zooms the viewport */ * If you have custom connection logic its preferred to use this callback over the isValidConnection prop on the handle component for performance reasons.
onMove?: OnMove; * @default (connection: Connection) => true
/** This event handler is called when the user stops panning or zooming the viewport */ */
onMoveEnd?: OnMoveEnd; isValidConnection?: IsValidConnection;
/** Ocassionally something may happen that causes Svelte Flow to throw an error. /** This event handler is called when the user begins to pan or zoom the viewport */
* onMoveStart?: OnMoveStart;
* Instead of exploding your application, we log a message to the console and then call this event handler. /** This event handler is called when the user pans or zooms the viewport */
* You might use it for additional logging or to show a message to the user. onMove?: OnMove;
*/ /** This event handler is called when the user stops panning or zooming the viewport */
onerror?: OnError; onMoveEnd?: OnMoveEnd;
/** This handler gets called when the user deletes nodes or edges. /** Ocassionally something may happen that causes Svelte Flow to throw an error.
* @example *
* onDelete={({nodes, edges}) => { * Instead of exploding your application, we log a message to the console and then call this event handler.
* console.log('deleted nodes:', nodes); * You might use it for additional logging or to show a message to the user.
* console.log('deleted edges:', edges); */
* }} onerror?: OnError;
*/ /** This handler gets called when the user deletes nodes or edges.
ondelete?: OnDelete; * @example
/** This handler gets called before the user deletes nodes or edges and provides a way to abort the deletion by returning false. */ * onDelete={({nodes, edges}) => {
onbeforedelete?: OnBeforeDelete; * console.log('deleted nodes:', nodes);
* console.log('deleted edges:', edges);
* }}
*/
ondelete?: OnDelete;
/** This handler gets called before the user deletes nodes or edges and provides a way to abort the deletion by returning false. */
onbeforedelete?: OnBeforeDelete;
/** This handler gets called when a new edge is created. You can use it to modify the newly created edge. */ /** This handler gets called when a new edge is created. You can use it to modify the newly created edge. */
onedgecreate?: OnEdgeCreate; onedgecreate?: OnEdgeCreate;
/** This event gets fired when a connection successfully completes and an edge is created. */ /** This event gets fired when a connection successfully completes and an edge is created. */
onconnect?: OnConnect; onconnect?: OnConnect;
/** When a user starts to drag a connection line, this event gets fired. */ /** When a user starts to drag a connection line, this event gets fired. */
onconnectstart?: OnConnectStart; onconnectstart?: OnConnectStart;
/** When a user stops dragging a connection line, this event gets fired. */ /** When a user stops dragging a connection line, this event gets fired. */
onconnectend?: OnConnectEnd; onconnectend?: OnConnectEnd;
/** This handler gets called when the flow is finished initializing */ /** This handler gets called when the flow is finished initializing */
oninit?: () => void; oninit?: () => void;
}; };
+56
View File
@@ -0,0 +1,56 @@
import type { Edge } from './edges';
import type { Node } from './nodes';
export type NodeEventWithPointer = ({
node,
event
}: {
node: Node;
event: MouseEvent | TouchEvent;
}) => void;
export type NodesEventWithPointer = ({
nodes,
event
}: {
nodes: Node[];
event: MouseEvent | TouchEvent;
}) => void;
export type NodeTargetEventWithPointer = ({
targetNode,
nodes,
event
}: {
targetNode: Node | null;
nodes: Node[];
event: MouseEvent | TouchEvent;
}) => void;
export type NodeEvents = {
onnodeclick?: NodeEventWithPointer;
onnodecontextmenu?: NodeEventWithPointer;
onnodedrag?: NodeTargetEventWithPointer;
onnodedragstart?: NodeTargetEventWithPointer;
onnodedragstop?: NodeTargetEventWithPointer;
onnodemouseenter?: NodeEventWithPointer;
onnodemouseleave?: NodeEventWithPointer;
onnodemousemove?: NodeEventWithPointer;
};
export type NodeSelectionEvents = {
onselectioncontextmenu?: NodesEventWithPointer;
onselectionclick?: NodesEventWithPointer;
};
export type PaneEvents = {
onpaneclick?: ({ event }: { event: MouseEvent | TouchEvent }) => void;
onpanecontextmenu?: ({ event }: { event: MouseEvent }) => void;
};
export type EdgeEvents = {
onedgeclick?: ({ edge, event }: { edge: Edge; event: MouseEvent | TouchEvent }) => void;
onedgecontextmenu?: ({ edge, event }: { edge: Edge; event: MouseEvent }) => void;
onedgemouseenter?: ({ edge, event }: { edge: Edge; event: MouseEvent }) => void;
onedgemouseleave?: ({ edge, event }: { edge: Edge; event: MouseEvent }) => void;
};