use generics across the library
This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
import { XYDrag, type OnDrag } from '@xyflow/system';
|
import { XYDrag, type NodeBase, type OnDrag, type XYDragParams } from '@xyflow/system';
|
||||||
|
|
||||||
import type { SvelteFlowStore } from '$lib/store/types';
|
import type { SvelteFlowStore } from '$lib/store/types';
|
||||||
|
import type { Node, Edge, NodeTargetEventWithPointer } from '$lib/types';
|
||||||
|
|
||||||
export type UseDragParams = {
|
export type UseDragParams<NodeType extends Node = Node, EdgeType extends Edge = Edge> = {
|
||||||
store: SvelteFlowStore;
|
store: SvelteFlowStore<NodeType, EdgeType>;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
noDragClass?: string;
|
noDragClass?: string;
|
||||||
handleSelector?: string;
|
handleSelector?: string;
|
||||||
@@ -16,7 +17,10 @@ export type UseDragParams = {
|
|||||||
onNodeMouseDown?: (id: string) => void;
|
onNodeMouseDown?: (id: string) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function drag(domNode: Element, params: UseDragParams) {
|
export default function drag<NodeType extends Node = Node, EdgeType extends Edge = Edge>(
|
||||||
|
domNode: Element,
|
||||||
|
params: UseDragParams<NodeType, EdgeType>
|
||||||
|
) {
|
||||||
const { store, onDrag, onDragStart, onDragStop, onNodeMouseDown } = params;
|
const { store, onDrag, onDragStart, onDragStop, onNodeMouseDown } = params;
|
||||||
const dragInstance = XYDrag({
|
const dragInstance = XYDrag({
|
||||||
onDrag,
|
onDrag,
|
||||||
@@ -27,7 +31,7 @@ export default function drag(domNode: Element, params: UseDragParams) {
|
|||||||
const { snapGrid, viewport } = store;
|
const { snapGrid, viewport } = store;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
nodes: store.nodes,
|
nodes: store.nodes satisfies NodeBase[],
|
||||||
nodeLookup: store.nodeLookup,
|
nodeLookup: store.nodeLookup,
|
||||||
edges: store.edges,
|
edges: store.edges,
|
||||||
nodeExtent: store.nodeExtent,
|
nodeExtent: store.nodeExtent,
|
||||||
@@ -46,9 +50,9 @@ export default function drag(domNode: Element, params: UseDragParams) {
|
|||||||
panBy: store.panBy
|
panBy: store.panBy
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
} as XYDragParams<NodeTargetEventWithPointer<MouseEvent | TouchEvent, NodeType>>);
|
||||||
|
|
||||||
function updateDrag(domNode: Element, params: UseDragParams) {
|
function updateDrag(domNode: Element, params: UseDragParams<NodeType, EdgeType>) {
|
||||||
if (params.disabled) {
|
if (params.disabled) {
|
||||||
dragInstance.destroy();
|
dragInstance.destroy();
|
||||||
return;
|
return;
|
||||||
@@ -67,7 +71,7 @@ export default function drag(domNode: Element, params: UseDragParams) {
|
|||||||
updateDrag(domNode, params);
|
updateDrag(domNode, params);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
update(params: UseDragParams) {
|
update(params: UseDragParams<NodeType, EdgeType>) {
|
||||||
updateDrag(domNode, params);
|
updateDrag(domNode, params);
|
||||||
},
|
},
|
||||||
destroy() {
|
destroy() {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<script lang="ts">
|
<script lang="ts" generics="NodeType extends Node = Node, EdgeType extends Edge = Edge">
|
||||||
import type { Component } from 'svelte';
|
import type { Component } from 'svelte';
|
||||||
import {
|
import {
|
||||||
ConnectionLineType,
|
ConnectionLineType,
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
} from '@xyflow/system';
|
} from '@xyflow/system';
|
||||||
|
|
||||||
import type { SvelteFlowStore } from '$lib/store/types';
|
import type { SvelteFlowStore } from '$lib/store/types';
|
||||||
|
import type { Node, Edge } from '$lib/types';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
store = $bindable(),
|
store = $bindable(),
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
style,
|
style,
|
||||||
LineComponent
|
LineComponent
|
||||||
}: {
|
}: {
|
||||||
store: SvelteFlowStore;
|
store: SvelteFlowStore<NodeType, EdgeType>;
|
||||||
type: ConnectionLineType;
|
type: ConnectionLineType;
|
||||||
containerStyle?: string;
|
containerStyle?: string;
|
||||||
style?: string;
|
style?: string;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<script lang="ts">
|
<script lang="ts" generics="NodeType extends Node = Node, EdgeType extends Edge = Edge">
|
||||||
import { setContext } from 'svelte';
|
import { setContext } from 'svelte';
|
||||||
|
|
||||||
import { elementSelectionKeys, getMarkerId } from '@xyflow/system';
|
import { elementSelectionKeys, getMarkerId } from '@xyflow/system';
|
||||||
|
|
||||||
import { BezierEdgeInternal } from '$lib/components/edges';
|
import { BezierEdgeInternal } from '$lib/components/edges';
|
||||||
|
|
||||||
import type { EdgeLayouted, Edge, EdgeEvents } from '$lib/types';
|
import type { Node, EdgeLayouted, Edge, EdgeEvents } from '$lib/types';
|
||||||
import type { SvelteFlowStore } from '$lib/store/types';
|
import type { SvelteFlowStore } from '$lib/store/types';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -15,7 +15,10 @@
|
|||||||
onedgecontextmenu,
|
onedgecontextmenu,
|
||||||
onedgepointerenter,
|
onedgepointerenter,
|
||||||
onedgepointerleave
|
onedgepointerleave
|
||||||
}: { store: SvelteFlowStore; edge: EdgeLayouted } & EdgeEvents = $props();
|
}: {
|
||||||
|
store: SvelteFlowStore<NodeType, EdgeType>;
|
||||||
|
edge: EdgeLayouted<EdgeType>;
|
||||||
|
} & EdgeEvents<EdgeType> = $props();
|
||||||
|
|
||||||
let {
|
let {
|
||||||
source,
|
source,
|
||||||
@@ -76,7 +79,7 @@
|
|||||||
|
|
||||||
function onmouseevent<T = MouseEvent>(
|
function onmouseevent<T = MouseEvent>(
|
||||||
event: T,
|
event: T,
|
||||||
callback: ({ edge, event }: { edge: Edge; event: T }) => void
|
callback: ({ edge, event }: { edge: EdgeType; event: T }) => void
|
||||||
) {
|
) {
|
||||||
const edge = store.edgeLookup.get(id);
|
const edge = store.edgeLookup.get(id);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<script lang="ts">
|
<script lang="ts" generics="NodeType extends Node = Node, EdgeType extends Edge = Edge">
|
||||||
import {
|
import {
|
||||||
shortcut,
|
shortcut,
|
||||||
type ShortcutEventDetail,
|
type ShortcutEventDetail,
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
import { isInputDOMNode, isMacOs } from '@xyflow/system';
|
import { isInputDOMNode, isMacOs } from '@xyflow/system';
|
||||||
|
|
||||||
import type { KeyHandlerProps } from './types';
|
import type { KeyHandlerProps } from './types';
|
||||||
import type { KeyDefinition, KeyDefinitionObject } from '$lib/types';
|
import type { Node, Edge, KeyDefinition, KeyDefinitionObject } from '$lib/types';
|
||||||
import { useSvelteFlow } from '$lib/hooks/useSvelteFlow.svelte';
|
import { useSvelteFlow } from '$lib/hooks/useSvelteFlow.svelte';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
@@ -17,9 +17,9 @@
|
|||||||
deleteKey = 'Backspace',
|
deleteKey = 'Backspace',
|
||||||
panActivationKey = ' ',
|
panActivationKey = ' ',
|
||||||
zoomActivationKey = isMacOs() ? 'Meta' : 'Control'
|
zoomActivationKey = isMacOs() ? 'Meta' : 'Control'
|
||||||
}: KeyHandlerProps = $props();
|
}: KeyHandlerProps<NodeType, EdgeType> = $props();
|
||||||
|
|
||||||
let { deleteElements } = useSvelteFlow();
|
let { deleteElements } = useSvelteFlow<NodeType, EdgeType>();
|
||||||
|
|
||||||
function isKeyObject(key?: KeyDefinition | null): key is KeyDefinitionObject {
|
function isKeyObject(key?: KeyDefinition | null): key is KeyDefinitionObject {
|
||||||
return key !== null && typeof key === 'object';
|
return key !== null && typeof key === 'object';
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import type { SvelteFlowStore } from '$lib/store/types';
|
import type { SvelteFlowStore } from '$lib/store/types';
|
||||||
import type { KeyDefinition } from '$lib/types';
|
import type { Node, Edge, KeyDefinition } from '$lib/types';
|
||||||
|
|
||||||
export type KeyHandlerProps = {
|
export type KeyHandlerProps<NodeType extends Node = Node, EdgeType extends Edge = Edge> = {
|
||||||
store: SvelteFlowStore;
|
store: SvelteFlowStore<NodeType, EdgeType>;
|
||||||
selectionKey?: KeyDefinition | KeyDefinition[] | null;
|
selectionKey?: KeyDefinition | KeyDefinition[] | null;
|
||||||
multiSelectionKey?: KeyDefinition | KeyDefinition[] | null;
|
multiSelectionKey?: KeyDefinition | KeyDefinition[] | null;
|
||||||
deleteKey?: KeyDefinition | KeyDefinition[] | null;
|
deleteKey?: KeyDefinition | KeyDefinition[] | null;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<script lang="ts">
|
<script lang="ts" generics="NodeType extends Node = Node, EdgeType extends Edge = Edge">
|
||||||
import { arrowKeyDiffs, getInternalNodesBounds, isNumeric, type Rect } from '@xyflow/system';
|
import { arrowKeyDiffs, getInternalNodesBounds, isNumeric, type Rect } from '@xyflow/system';
|
||||||
|
|
||||||
import { Selection } from '$lib/components/Selection';
|
import { Selection } from '$lib/components/Selection';
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
import type { NodeSelectionProps } from './types';
|
import type { NodeSelectionProps } from './types';
|
||||||
import { toPxString } from '$lib/utils';
|
import { toPxString } from '$lib/utils';
|
||||||
|
import type { Node, Edge } from '$lib/types';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
store = $bindable(),
|
store = $bindable(),
|
||||||
@@ -14,7 +15,7 @@
|
|||||||
onnodedragstop,
|
onnodedragstop,
|
||||||
onselectionclick,
|
onselectionclick,
|
||||||
onselectioncontextmenu
|
onselectioncontextmenu
|
||||||
}: NodeSelectionProps = $props();
|
}: NodeSelectionProps<NodeType, EdgeType> = $props();
|
||||||
|
|
||||||
let ref = $state<HTMLDivElement>();
|
let ref = $state<HTMLDivElement>();
|
||||||
|
|
||||||
@@ -63,13 +64,13 @@
|
|||||||
disabled: false,
|
disabled: false,
|
||||||
store,
|
store,
|
||||||
onDrag: (event, _, __, nodes) => {
|
onDrag: (event, _, __, nodes) => {
|
||||||
onnodedrag?.({ event, targetNode: null, nodes });
|
onnodedrag?.({ event, targetNode: null, nodes: nodes as NodeType[] });
|
||||||
},
|
},
|
||||||
onDragStart: (event, _, __, nodes) => {
|
onDragStart: (event, _, __, nodes) => {
|
||||||
onnodedragstart?.({ event, targetNode: null, nodes });
|
onnodedragstart?.({ event, targetNode: null, nodes: nodes as NodeType[] });
|
||||||
},
|
},
|
||||||
onDragStop: (event, _, __, nodes) => {
|
onDragStop: (event, _, __, nodes) => {
|
||||||
onnodedragstop?.({ event, targetNode: null, nodes });
|
onnodedragstop?.({ event, targetNode: null, nodes: nodes as NodeType[] });
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
{oncontextmenu}
|
{oncontextmenu}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import type { SvelteFlowStore } from '$lib/store/types';
|
import type { SvelteFlowStore } from '$lib/store/types';
|
||||||
import type { NodeEvents, NodeSelectionEvents } from '$lib/types';
|
import type { Node, Edge, NodeEvents, NodeSelectionEvents } from '$lib/types';
|
||||||
|
|
||||||
export type NodeSelectionProps = { store: SvelteFlowStore } & NodeSelectionEvents &
|
export type NodeSelectionProps<NodeType extends Node = Node, EdgeType extends Edge = Edge> = {
|
||||||
Pick<NodeEvents, 'onnodedrag' | 'onnodedragstart' | 'onnodedragstop'>;
|
store: SvelteFlowStore<NodeType, EdgeType>;
|
||||||
|
} & NodeSelectionEvents<NodeType> &
|
||||||
|
Pick<NodeEvents<NodeType>, 'onnodedrag' | 'onnodedragstart' | 'onnodedragstop'>;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<script lang="ts">
|
<script lang="ts" generics="NodeType extends Node = Node, EdgeType extends Edge = Edge">
|
||||||
import { setContext, onDestroy } from 'svelte';
|
import { setContext, onDestroy } from 'svelte';
|
||||||
import {
|
import {
|
||||||
arrowKeyDiffs,
|
arrowKeyDiffs,
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
import DefaultNode from '$lib/components/nodes/DefaultNode.svelte';
|
import DefaultNode from '$lib/components/nodes/DefaultNode.svelte';
|
||||||
|
|
||||||
import type { ConnectableContext, NodeWrapperProps } from './types';
|
import type { ConnectableContext, NodeWrapperProps } from './types';
|
||||||
import type { NodeEvents } from '$lib/types';
|
import type { Node, Edge, NodeEvents } from '$lib/types';
|
||||||
import { toPxString } from '$lib/utils';
|
import { toPxString } from '$lib/utils';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
onnodepointerleave,
|
onnodepointerleave,
|
||||||
onnodepointermove,
|
onnodepointermove,
|
||||||
onnodecontextmenu
|
onnodecontextmenu
|
||||||
}: NodeWrapperProps & NodeEvents = $props();
|
}: NodeWrapperProps<NodeType, EdgeType> & NodeEvents<NodeType> = $props();
|
||||||
|
|
||||||
let {
|
let {
|
||||||
data = {},
|
data = {},
|
||||||
@@ -55,7 +55,8 @@
|
|||||||
dragHandle,
|
dragHandle,
|
||||||
internals: {
|
internals: {
|
||||||
z: zIndex = 0,
|
z: zIndex = 0,
|
||||||
positionAbsolute: { x: positionX, y: positionY }
|
positionAbsolute: { x: positionX, y: positionY },
|
||||||
|
userNode
|
||||||
}
|
}
|
||||||
} = $derived(node);
|
} = $derived(node);
|
||||||
|
|
||||||
@@ -162,7 +163,7 @@
|
|||||||
store.handleNodeSelection(id);
|
store.handleNodeSelection(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
onnodeclick?.({ node, event });
|
onnodeclick?.({ node: userNode, event });
|
||||||
}
|
}
|
||||||
|
|
||||||
function onKeyDown(event: KeyboardEvent) {
|
function onKeyDown(event: KeyboardEvent) {
|
||||||
@@ -205,13 +206,17 @@
|
|||||||
nodeClickDistance,
|
nodeClickDistance,
|
||||||
onNodeMouseDown: store.handleNodeSelection,
|
onNodeMouseDown: store.handleNodeSelection,
|
||||||
onDrag: (event, _, targetNode, nodes) => {
|
onDrag: (event, _, targetNode, nodes) => {
|
||||||
onnodedrag?.({ event, targetNode, nodes });
|
onnodedrag?.({ event, targetNode: targetNode as NodeType, nodes: nodes as NodeType[] });
|
||||||
},
|
},
|
||||||
onDragStart: (event, _, targetNode, nodes) => {
|
onDragStart: (event, _, targetNode, nodes) => {
|
||||||
onnodedragstart?.({ event, targetNode, nodes });
|
onnodedragstart?.({
|
||||||
|
event,
|
||||||
|
targetNode: targetNode as NodeType,
|
||||||
|
nodes: nodes as NodeType[]
|
||||||
|
});
|
||||||
},
|
},
|
||||||
onDragStop: (event, _, targetNode, nodes) => {
|
onDragStop: (event, _, targetNode, nodes) => {
|
||||||
onnodedragstop?.({ event, targetNode, nodes });
|
onnodedragstop?.({ event, targetNode: targetNode as NodeType, nodes: nodes as NodeType[] });
|
||||||
},
|
},
|
||||||
store
|
store
|
||||||
}}
|
}}
|
||||||
@@ -230,10 +235,18 @@
|
|||||||
style:visibility={initialized ? 'visible' : 'hidden'}
|
style:visibility={initialized ? 'visible' : 'hidden'}
|
||||||
style="{style};width:{inlineDimensions.width};height:{inlineDimensions.height}"
|
style="{style};width:{inlineDimensions.width};height:{inlineDimensions.height}"
|
||||||
onclick={onSelectNodeHandler}
|
onclick={onSelectNodeHandler}
|
||||||
onpointerenter={onnodepointerenter ? (event) => onnodepointerenter({ node, event }) : undefined}
|
onpointerenter={onnodepointerenter
|
||||||
onpointerleave={onnodepointerleave ? (event) => onnodepointerleave({ node, event }) : undefined}
|
? (event) => onnodepointerenter({ node: userNode, event })
|
||||||
onpointermove={onnodepointermove ? (event) => onnodepointermove({ node, event }) : undefined}
|
: undefined}
|
||||||
oncontextmenu={onnodecontextmenu ? (event) => onnodecontextmenu({ node, event }) : undefined}
|
onpointerleave={onnodepointerleave
|
||||||
|
? (event) => onnodepointerleave({ node: userNode, event })
|
||||||
|
: undefined}
|
||||||
|
onpointermove={onnodepointermove
|
||||||
|
? (event) => onnodepointermove({ node: userNode, event })
|
||||||
|
: undefined}
|
||||||
|
oncontextmenu={onnodecontextmenu
|
||||||
|
? (event) => onnodecontextmenu({ node: userNode, event })
|
||||||
|
: undefined}
|
||||||
onkeydown={focusable ? onKeyDown : undefined}
|
onkeydown={focusable ? onKeyDown : undefined}
|
||||||
tabIndex={focusable ? 0 : undefined}
|
tabIndex={focusable ? 0 : undefined}
|
||||||
role={focusable ? 'button' : undefined}
|
role={focusable ? 'button' : undefined}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import type { SvelteFlowStore } from '$lib/store/types';
|
import type { SvelteFlowStore } from '$lib/store/types';
|
||||||
import type { InternalNode } from '$lib/types';
|
import type { Node, Edge, InternalNode } from '$lib/types';
|
||||||
|
|
||||||
export type ConnectableContext = {
|
export type ConnectableContext = {
|
||||||
value: boolean;
|
value: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type NodeWrapperProps = {
|
export type NodeWrapperProps<NodeType extends Node = Node, EdgeType extends Edge = Edge> = {
|
||||||
node: InternalNode;
|
node: InternalNode<NodeType>;
|
||||||
store: SvelteFlowStore;
|
store: SvelteFlowStore<NodeType, EdgeType>;
|
||||||
nodeClickDistance?: number;
|
nodeClickDistance?: number;
|
||||||
resizeObserver?: ResizeObserver | null;
|
resizeObserver?: ResizeObserver | null;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
<script lang="ts">
|
<script lang="ts" generics="NodeType extends Node = Node, EdgeType extends Edge = Edge">
|
||||||
import { onDestroy, setContext } from 'svelte';
|
import { onDestroy, setContext } from 'svelte';
|
||||||
|
|
||||||
import { createStore, key } from '$lib/store';
|
import { createStore, key } from '$lib/store';
|
||||||
import type { SvelteFlowProviderProps } from './types';
|
import type { SvelteFlowProviderProps } from './types';
|
||||||
import type { ProviderContext, SvelteFlowStore } from '$lib/store/types';
|
import type { ProviderContext, SvelteFlowStore } from '$lib/store/types';
|
||||||
|
import type { Node, Edge } from '$lib/types';
|
||||||
|
|
||||||
let { children }: SvelteFlowProviderProps = $props();
|
let { children }: SvelteFlowProviderProps = $props();
|
||||||
|
|
||||||
let store = $state.raw(
|
let store = $state.raw(
|
||||||
createStore({
|
createStore<NodeType, EdgeType>({
|
||||||
props: {},
|
props: {},
|
||||||
nodes: [],
|
nodes: [],
|
||||||
edges: []
|
edges: []
|
||||||
@@ -20,10 +21,10 @@
|
|||||||
getStore() {
|
getStore() {
|
||||||
return store;
|
return store;
|
||||||
},
|
},
|
||||||
setStore: (newStore: SvelteFlowStore) => {
|
setStore: (newStore: SvelteFlowStore<NodeType, EdgeType>) => {
|
||||||
store = newStore;
|
store = newStore;
|
||||||
}
|
}
|
||||||
} satisfies ProviderContext);
|
} satisfies ProviderContext<NodeType, EdgeType>);
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
store.reset();
|
store.reset();
|
||||||
|
|||||||
@@ -1,13 +1,5 @@
|
|||||||
import type { Snippet } from 'svelte';
|
import type { Snippet } from 'svelte';
|
||||||
import type { NodeOrigin } from '@xyflow/system';
|
|
||||||
import type { Edge, Node } from '$lib/types';
|
|
||||||
|
|
||||||
export type SvelteFlowProviderProps = {
|
export type SvelteFlowProviderProps = {
|
||||||
initialNodes?: Node[];
|
|
||||||
initialEdges?: Edge[];
|
|
||||||
initialWidth?: number;
|
|
||||||
initialHeight?: number;
|
|
||||||
fitView?: boolean;
|
|
||||||
nodeOrigin?: NodeOrigin;
|
|
||||||
children?: Snippet;
|
children?: Snippet;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts" generics="NodeType extends Node = Node, EdgeType extends Edge = Edge">
|
||||||
import { EdgeWrapper } from '$lib/components/EdgeWrapper';
|
import { EdgeWrapper } from '$lib/components/EdgeWrapper';
|
||||||
import { MarkerDefinition } from '$lib/container/EdgeRenderer/MarkerDefinition';
|
import { MarkerDefinition } from '$lib/container/EdgeRenderer/MarkerDefinition';
|
||||||
import type { EdgeEvents } from '$lib/types';
|
import type { Node, Edge, EdgeEvents } from '$lib/types';
|
||||||
import type { SvelteFlowStore } from '$lib/store/types';
|
import type { SvelteFlowStore } from '$lib/store/types';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
onedgecontextmenu,
|
onedgecontextmenu,
|
||||||
onedgepointerenter,
|
onedgepointerenter,
|
||||||
onedgepointerleave
|
onedgepointerleave
|
||||||
}: { store: SvelteFlowStore } & EdgeEvents = $props();
|
}: { store: SvelteFlowStore<NodeType, EdgeType> } & EdgeEvents<EdgeType> = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svg class="svelte-flow__marker">
|
<svg class="svelte-flow__marker">
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<script lang="ts">
|
<script lang="ts" generics="NodeType extends Node = Node, EdgeType extends Edge = Edge">
|
||||||
import { onDestroy } from 'svelte';
|
import { onDestroy } from 'svelte';
|
||||||
|
|
||||||
import { NodeWrapper } from '$lib/components/NodeWrapper';
|
import { NodeWrapper } from '$lib/components/NodeWrapper';
|
||||||
|
|
||||||
import type { NodeEvents } from '$lib/types';
|
import type { Node, Edge, NodeEvents } from '$lib/types';
|
||||||
import type { SvelteFlowStore } from '$lib/store/types';
|
import type { SvelteFlowStore } from '$lib/store/types';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
@@ -17,7 +17,10 @@
|
|||||||
onnodedrag,
|
onnodedrag,
|
||||||
onnodedragstart,
|
onnodedragstart,
|
||||||
onnodedragstop
|
onnodedragstop
|
||||||
}: { store: SvelteFlowStore; nodeClickDistance?: number } & NodeEvents = $props();
|
}: {
|
||||||
|
store: SvelteFlowStore<NodeType, EdgeType>;
|
||||||
|
nodeClickDistance?: number;
|
||||||
|
} & NodeEvents<NodeType> = $props();
|
||||||
|
|
||||||
const resizeObserver: ResizeObserver | null =
|
const resizeObserver: ResizeObserver | null =
|
||||||
typeof ResizeObserver === 'undefined'
|
typeof ResizeObserver === 'undefined'
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" generics="NodeType extends Node = Node, EdgeType extends Edge = Edge">
|
||||||
import { SelectionMode, getEventPosition, getNodesInside } from '@xyflow/system';
|
import { SelectionMode, getEventPosition, getNodesInside } from '@xyflow/system';
|
||||||
|
|
||||||
import type { Node, Edge } from '$lib/types';
|
import type { Node, Edge } from '$lib/types';
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
onpaneclick,
|
onpaneclick,
|
||||||
onpanecontextmenu,
|
onpanecontextmenu,
|
||||||
children
|
children
|
||||||
}: PaneProps = $props();
|
}: PaneProps<NodeType, EdgeType> = $props();
|
||||||
|
|
||||||
// svelte-ignore non_reactive_update
|
// svelte-ignore non_reactive_update
|
||||||
let container: HTMLDivElement;
|
let container: HTMLDivElement;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import type { Snippet } from 'svelte';
|
import type { Snippet } from 'svelte';
|
||||||
import type { PaneEvents } from '$lib/types';
|
import type { Node, Edge, PaneEvents } from '$lib/types';
|
||||||
import type { SvelteFlowStore } from '$lib/store/types';
|
import type { SvelteFlowStore } from '$lib/store/types';
|
||||||
|
|
||||||
export type PaneProps = {
|
export type PaneProps<NodeType extends Node = Node, EdgeType extends Edge = Edge> = {
|
||||||
store: SvelteFlowStore;
|
store: SvelteFlowStore<NodeType, EdgeType>;
|
||||||
panOnDrag?: boolean | number[];
|
panOnDrag?: boolean | number[];
|
||||||
selectionOnDrag?: boolean;
|
selectionOnDrag?: boolean;
|
||||||
children: Snippet;
|
children: Snippet;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import type { Snippet } from 'svelte';
|
import type { Snippet } from 'svelte';
|
||||||
import { type SvelteFlowRestProps } from '$lib/store/types';
|
import { type SvelteFlowRestProps } from '$lib/store/types';
|
||||||
import { toPxString } from '$lib/utils';
|
import { toPxString } from '$lib/utils';
|
||||||
import type { Node, Edge, NodeTypes } from '$lib/types';
|
import type { Node, Edge } from '$lib/types';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
width,
|
width,
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ import type { EdgeEvents, NodeEvents, NodeSelectionEvents, PaneEvents } from '$l
|
|||||||
export type SvelteFlowProps<
|
export type SvelteFlowProps<
|
||||||
NodeType extends Node = Node,
|
NodeType extends Node = Node,
|
||||||
EdgeType extends Edge = Edge
|
EdgeType extends Edge = Edge
|
||||||
> = NodeEvents &
|
> = NodeEvents<NodeType> &
|
||||||
NodeSelectionEvents &
|
NodeSelectionEvents<NodeType> &
|
||||||
EdgeEvents &
|
EdgeEvents<EdgeType> &
|
||||||
PaneEvents & {
|
PaneEvents & {
|
||||||
/** The id of the flow
|
/** The id of the flow
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
<script lang="ts">
|
<script lang="ts" generics="NodeType extends Node = Node, EdgeType extends Edge = Edge">
|
||||||
import type { SvelteFlowStore } from '$lib/store/types';
|
import type { SvelteFlowStore } from '$lib/store/types';
|
||||||
|
import type { Node, Edge } from '$lib/types';
|
||||||
import type { Snippet } from 'svelte';
|
import type { Snippet } from 'svelte';
|
||||||
|
|
||||||
let { store = $bindable(), children }: { store: SvelteFlowStore; children: Snippet } = $props();
|
let {
|
||||||
|
store = $bindable(),
|
||||||
|
children
|
||||||
|
}: { store: SvelteFlowStore<NodeType, EdgeType>; children: Snippet } = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
<script lang="ts">
|
<script lang="ts" generics="NodeType extends Node = Node, EdgeType extends Edge = Edge">
|
||||||
import { PanOnScrollMode, type PanZoomInstance, type Transform } from '@xyflow/system';
|
import { PanOnScrollMode, type PanZoomInstance, type Transform } from '@xyflow/system';
|
||||||
|
|
||||||
import zoom from '$lib/actions/zoom';
|
import zoom from '$lib/actions/zoom';
|
||||||
import type { ZoomProps } from './types';
|
import type { ZoomProps } from './types';
|
||||||
|
import type { Node, Edge } from '$lib/types';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
store = $bindable(),
|
store = $bindable(),
|
||||||
@@ -19,7 +20,7 @@
|
|||||||
onmoveend,
|
onmoveend,
|
||||||
oninit,
|
oninit,
|
||||||
children
|
children
|
||||||
}: ZoomProps = $props();
|
}: ZoomProps<NodeType, EdgeType> = $props();
|
||||||
|
|
||||||
let panOnDragActive = $derived(store.panActivationKeyPressed || panOnDrag);
|
let panOnDragActive = $derived(store.panActivationKeyPressed || panOnDrag);
|
||||||
let panOnScrollActive = $derived(store.panActivationKeyPressed || panOnScroll);
|
let panOnScrollActive = $derived(store.panActivationKeyPressed || panOnScroll);
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import type { SvelteFlowStore } from '$lib/store/types';
|
import type { SvelteFlowStore } from '$lib/store/types';
|
||||||
|
import type { Edge, Node } from '$lib/types';
|
||||||
import type { OnMoveStart, OnMove, OnMoveEnd, PanOnScrollMode } from '@xyflow/system';
|
import type { OnMoveStart, OnMove, OnMoveEnd, PanOnScrollMode } from '@xyflow/system';
|
||||||
import type { Snippet } from 'svelte';
|
import type { Snippet } from 'svelte';
|
||||||
|
|
||||||
export type ZoomProps = {
|
export type ZoomProps<NodeType extends Node = Node, EdgeType extends Edge = Edge> = {
|
||||||
store: SvelteFlowStore;
|
store: SvelteFlowStore<NodeType, EdgeType>;
|
||||||
panOnScrollMode: PanOnScrollMode;
|
panOnScrollMode: PanOnScrollMode;
|
||||||
preventScrolling: boolean;
|
preventScrolling: boolean;
|
||||||
zoomOnScroll: boolean;
|
zoomOnScroll: boolean;
|
||||||
|
|||||||
@@ -3,9 +3,13 @@ import type { StoreContext, SvelteFlowStore } from '../store/types';
|
|||||||
|
|
||||||
import { key } from '../store';
|
import { key } from '../store';
|
||||||
import { derivedWarning } from './derivedWarning.svelte';
|
import { derivedWarning } from './derivedWarning.svelte';
|
||||||
|
import type { Node, Edge } from '$lib/types';
|
||||||
|
|
||||||
export function useStore(): SvelteFlowStore {
|
export function useStore<
|
||||||
const storeContext = getContext<StoreContext>(key);
|
NodeType extends Node = Node,
|
||||||
|
EdgeType extends Edge = Edge
|
||||||
|
>(): SvelteFlowStore<NodeType, EdgeType> {
|
||||||
|
const storeContext = getContext<StoreContext<NodeType, EdgeType>>(key);
|
||||||
|
|
||||||
if (!storeContext) {
|
if (!storeContext) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import { untrack } from 'svelte';
|
|||||||
*
|
*
|
||||||
* @returns helper functions
|
* @returns helper functions
|
||||||
*/
|
*/
|
||||||
export function useSvelteFlow(): {
|
export function useSvelteFlow<NodeType extends Node = Node, EdgeType extends Edge = Edge>(): {
|
||||||
/**
|
/**
|
||||||
* Zooms viewport in by 1.2.
|
* Zooms viewport in by 1.2.
|
||||||
*
|
*
|
||||||
@@ -51,33 +51,33 @@ export function useSvelteFlow(): {
|
|||||||
* @param id - the node id
|
* @param id - the node id
|
||||||
* @returns the node or undefined if no node was found
|
* @returns the node or undefined if no node was found
|
||||||
*/
|
*/
|
||||||
getInternalNode: (id: string) => InternalNode | undefined;
|
getInternalNode: (id: string) => InternalNode<NodeType> | undefined;
|
||||||
/**
|
/**
|
||||||
* Returns a node by id.
|
* Returns a node by id.
|
||||||
*
|
*
|
||||||
* @param id - the node id
|
* @param id - the node id
|
||||||
* @returns the node or undefined if no node was found
|
* @returns the node or undefined if no node was found
|
||||||
*/
|
*/
|
||||||
getNode: (id: string) => Node | undefined;
|
getNode: (id: string) => NodeType | undefined;
|
||||||
/**
|
/**
|
||||||
* Returns nodes.
|
* Returns nodes.
|
||||||
*
|
*
|
||||||
* @returns nodes array
|
* @returns nodes array
|
||||||
*/
|
*/
|
||||||
getNodes: (ids?: string[]) => Node[];
|
getNodes: (ids?: string[]) => NodeType[];
|
||||||
/**
|
/**
|
||||||
* Returns an edge by id.
|
* Returns an edge by id.
|
||||||
*
|
*
|
||||||
* @param id - the edge id
|
* @param id - the edge id
|
||||||
* @returns the edge or undefined if no edge was found
|
* @returns the edge or undefined if no edge was found
|
||||||
*/
|
*/
|
||||||
getEdge: (id: string) => Edge | undefined;
|
getEdge: (id: string) => EdgeType | undefined;
|
||||||
/**
|
/**
|
||||||
* Returns edges.
|
* Returns edges.
|
||||||
*
|
*
|
||||||
* @returns edges array
|
* @returns edges array
|
||||||
*/
|
*/
|
||||||
getEdges: (ids?: string[]) => Edge[];
|
getEdges: (ids?: string[]) => EdgeType[];
|
||||||
/**
|
/**
|
||||||
* Sets the current zoom level.
|
* Sets the current zoom level.
|
||||||
*
|
*
|
||||||
@@ -133,10 +133,10 @@ export function useSvelteFlow(): {
|
|||||||
* @returns an array of intersecting nodes
|
* @returns an array of intersecting nodes
|
||||||
*/
|
*/
|
||||||
getIntersectingNodes: (
|
getIntersectingNodes: (
|
||||||
nodeOrRect: Node | { id: Node['id'] } | Rect,
|
nodeOrRect: NodeType | { id: NodeType['id'] } | Rect,
|
||||||
partially?: boolean,
|
partially?: boolean,
|
||||||
nodesToIntersect?: Node[]
|
nodesToIntersect?: NodeType[]
|
||||||
) => Node[];
|
) => NodeType[];
|
||||||
/**
|
/**
|
||||||
* Checks if the given node or rect intersects with the passed rect.
|
* Checks if the given node or rect intersects with the passed rect.
|
||||||
*
|
*
|
||||||
@@ -147,7 +147,7 @@ export function useSvelteFlow(): {
|
|||||||
* @returns true if the node or rect intersects with the given area
|
* @returns true if the node or rect intersects with the given area
|
||||||
*/
|
*/
|
||||||
isNodeIntersecting: (
|
isNodeIntersecting: (
|
||||||
nodeOrRect: Node | { id: Node['id'] } | Rect,
|
nodeOrRect: NodeType | { id: NodeType['id'] } | Rect,
|
||||||
area: Rect,
|
area: Rect,
|
||||||
partially?: boolean
|
partially?: boolean
|
||||||
) => boolean;
|
) => boolean;
|
||||||
@@ -170,9 +170,9 @@ export function useSvelteFlow(): {
|
|||||||
nodes,
|
nodes,
|
||||||
edges
|
edges
|
||||||
}: {
|
}: {
|
||||||
nodes?: (Node | { id: Node['id'] })[];
|
nodes?: (Partial<NodeType> & { id: string })[];
|
||||||
edges?: (Edge | { id: Edge['id'] })[];
|
edges?: (Partial<EdgeType> & { id: string })[];
|
||||||
}) => Promise<{ deletedNodes: Node[]; deletedEdges: Edge[] }>;
|
}) => Promise<{ deletedNodes: NodeType[]; deletedEdges: EdgeType[] }>;
|
||||||
/**
|
/**
|
||||||
* Converts a screen / client position to a flow position.
|
* Converts a screen / client position to a flow position.
|
||||||
*
|
*
|
||||||
@@ -209,12 +209,12 @@ export function useSvelteFlow(): {
|
|||||||
*/
|
*/
|
||||||
// updateNode: (
|
// updateNode: (
|
||||||
// id: string,
|
// id: string,
|
||||||
// nodeUpdate: Partial<Node> | ((node: Node) => Partial<Node>),
|
// nodeUpdate: Partial<NodeType> | ((node: NodeType) => Partial<NodeTyp>),
|
||||||
// options?: { replace: boolean }
|
// options?: { replace: boolean }
|
||||||
// ) => void;
|
// ) => void;
|
||||||
updateNode: (
|
updateNode: (
|
||||||
id: string,
|
id: string,
|
||||||
nodeUpdate: Partial<Node> | ((node: Node) => Partial<Node>),
|
nodeUpdate: Partial<NodeType> | ((node: NodeType) => NodeType),
|
||||||
options?: { replace: boolean }
|
options?: { replace: boolean }
|
||||||
) => void;
|
) => void;
|
||||||
/**
|
/**
|
||||||
@@ -229,7 +229,7 @@ export function useSvelteFlow(): {
|
|||||||
*/
|
*/
|
||||||
updateNodeData: (
|
updateNodeData: (
|
||||||
id: string,
|
id: string,
|
||||||
dataUpdate: object | ((node: Node) => object),
|
dataUpdate: Partial<NodeType['data']> | ((node: NodeType) => Partial<NodeType['data']>),
|
||||||
options?: { replace: boolean }
|
options?: { replace: boolean }
|
||||||
) => void;
|
) => void;
|
||||||
/**
|
/**
|
||||||
@@ -249,10 +249,10 @@ export function useSvelteFlow(): {
|
|||||||
*/
|
*/
|
||||||
updateEdge: (
|
updateEdge: (
|
||||||
id: string,
|
id: string,
|
||||||
edgeUpdate: Partial<Edge> | ((edge: Edge) => Partial<Edge>),
|
edgeUpdate: Partial<EdgeType> | ((edge: EdgeType) => EdgeType),
|
||||||
options?: { replace: boolean }
|
options?: { replace: boolean }
|
||||||
) => void;
|
) => void;
|
||||||
toObject: () => { nodes: Node[]; edges: Edge[]; viewport: Viewport };
|
toObject: () => { nodes: NodeType[]; edges: EdgeType[]; viewport: Viewport };
|
||||||
/**
|
/**
|
||||||
* Returns the bounds of the given nodes or node ids.
|
* Returns the bounds of the given nodes or node ids.
|
||||||
*
|
*
|
||||||
@@ -260,7 +260,7 @@ export function useSvelteFlow(): {
|
|||||||
*
|
*
|
||||||
* @returns the bounds of the given nodes
|
* @returns the bounds of the given nodes
|
||||||
*/
|
*/
|
||||||
getNodesBounds: (nodes: (Node | InternalNode | string)[]) => Rect;
|
getNodesBounds: (nodes: (NodeType | InternalNode<NodeType> | string)[]) => Rect;
|
||||||
/** Gets all connections for a given handle belonging to a specific node.
|
/** Gets all connections for a given handle belonging to a specific node.
|
||||||
*
|
*
|
||||||
* @param type - handle type 'source' or 'target'
|
* @param type - handle type 'source' or 'target'
|
||||||
@@ -282,9 +282,9 @@ export function useSvelteFlow(): {
|
|||||||
derivedWarning('useSvelteFlow');
|
derivedWarning('useSvelteFlow');
|
||||||
}
|
}
|
||||||
|
|
||||||
const store = useStore();
|
const store = useStore<NodeType, EdgeType>();
|
||||||
|
|
||||||
const getNodeRect = (node: Node | { id: Node['id'] }): Rect | null => {
|
const getNodeRect = (node: NodeType | { id: NodeType['id'] }): Rect | null => {
|
||||||
const nodeToUse = isNode(node) ? node : store.nodeLookup.get(node.id)!;
|
const nodeToUse = isNode(node) ? node : store.nodeLookup.get(node.id)!;
|
||||||
const position = nodeToUse.parentId
|
const position = nodeToUse.parentId
|
||||||
? evaluateAbsolutePosition(
|
? evaluateAbsolutePosition(
|
||||||
@@ -308,13 +308,13 @@ export function useSvelteFlow(): {
|
|||||||
|
|
||||||
function updateNode(
|
function updateNode(
|
||||||
id: string,
|
id: string,
|
||||||
nodeUpdate: Partial<Node> | ((node: Node) => Partial<Node>),
|
nodeUpdate: Partial<NodeType> | ((node: NodeType) => NodeType),
|
||||||
options: { replace: boolean } = { replace: false }
|
options: { replace: boolean } = { replace: false }
|
||||||
) {
|
) {
|
||||||
store.nodes = untrack(() => store.nodes).map((node) => {
|
store.nodes = untrack(() => store.nodes).map((node) => {
|
||||||
if (node.id === id) {
|
if (node.id === id) {
|
||||||
const nextNode = typeof nodeUpdate === 'function' ? nodeUpdate(node as Node) : nodeUpdate;
|
const nextNode = typeof nodeUpdate === 'function' ? nodeUpdate(node) : nodeUpdate;
|
||||||
return options?.replace && isNode(nextNode) ? nextNode : { ...node, ...nextNode };
|
return options?.replace && isNode<NodeType>(nextNode) ? nextNode : { ...node, ...nextNode };
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
@@ -323,13 +323,13 @@ export function useSvelteFlow(): {
|
|||||||
|
|
||||||
function updateEdge(
|
function updateEdge(
|
||||||
id: string,
|
id: string,
|
||||||
edgeUpdate: Partial<Edge> | ((edge: Edge) => Partial<Edge>),
|
edgeUpdate: Partial<EdgeType> | ((edge: EdgeType) => EdgeType),
|
||||||
options: { replace: boolean } = { replace: false }
|
options: { replace: boolean } = { replace: false }
|
||||||
) {
|
) {
|
||||||
store.edges = untrack(() => store.edges).map((edge) => {
|
store.edges = untrack(() => store.edges).map((edge) => {
|
||||||
if (edge.id === id) {
|
if (edge.id === id) {
|
||||||
const nextEdge = typeof edgeUpdate === 'function' ? edgeUpdate(edge) : edgeUpdate;
|
const nextEdge = typeof edgeUpdate === 'function' ? edgeUpdate(edge) : edgeUpdate;
|
||||||
return options.replace && isEdge(nextEdge) ? nextEdge : { ...edge, ...nextEdge };
|
return options.replace && isEdge<EdgeType>(nextEdge) ? nextEdge : { ...edge, ...nextEdge };
|
||||||
}
|
}
|
||||||
|
|
||||||
return edge;
|
return edge;
|
||||||
@@ -411,9 +411,9 @@ export function useSvelteFlow(): {
|
|||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
},
|
},
|
||||||
getIntersectingNodes: (
|
getIntersectingNodes: (
|
||||||
nodeOrRect: Node | { id: Node['id'] } | Rect,
|
nodeOrRect: NodeType | { id: NodeType['id'] } | Rect,
|
||||||
partially = true,
|
partially = true,
|
||||||
nodesToIntersect?: Node[]
|
nodesToIntersect?: NodeType[]
|
||||||
) => {
|
) => {
|
||||||
const isRect = isRectObject(nodeOrRect);
|
const isRect = isRectObject(nodeOrRect);
|
||||||
const nodeRect = isRect ? nodeOrRect : getNodeRect(nodeOrRect);
|
const nodeRect = isRect ? nodeOrRect : getNodeRect(nodeOrRect);
|
||||||
@@ -436,7 +436,7 @@ export function useSvelteFlow(): {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
isNodeIntersecting: (
|
isNodeIntersecting: (
|
||||||
nodeOrRect: Node | { id: Node['id'] } | Rect,
|
nodeOrRect: NodeType | { id: NodeType['id'] } | Rect,
|
||||||
area: Rect,
|
area: Rect,
|
||||||
partially = true
|
partially = true
|
||||||
) => {
|
) => {
|
||||||
@@ -453,7 +453,10 @@ export function useSvelteFlow(): {
|
|||||||
return partiallyVisible || overlappingArea >= nodeRect.width * nodeRect.height;
|
return partiallyVisible || overlappingArea >= nodeRect.width * nodeRect.height;
|
||||||
},
|
},
|
||||||
deleteElements: async ({ nodes: nodesToRemove = [], edges: edgesToRemove = [] }) => {
|
deleteElements: async ({ nodes: nodesToRemove = [], edges: edgesToRemove = [] }) => {
|
||||||
const { nodes: matchingNodes, edges: matchingEdges } = await getElementsToRemove({
|
const { nodes: matchingNodes, edges: matchingEdges } = await getElementsToRemove<
|
||||||
|
NodeType,
|
||||||
|
EdgeType
|
||||||
|
>({
|
||||||
nodesToRemove,
|
nodesToRemove,
|
||||||
edgesToRemove,
|
edgesToRemove,
|
||||||
nodes: store.nodes,
|
nodes: store.nodes,
|
||||||
@@ -537,8 +540,10 @@ export function useSvelteFlow(): {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const nextData = typeof dataUpdate === 'function' ? dataUpdate(node) : dataUpdate;
|
const nextData = typeof dataUpdate === 'function' ? dataUpdate(node) : dataUpdate;
|
||||||
|
updateNode(id, (node) => ({
|
||||||
updateNode(id, { data: options?.replace ? nextData : { ...node.data, ...nextData } });
|
...node,
|
||||||
|
data: options?.replace ? nextData : { ...node.data, ...nextData }
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
updateEdge,
|
updateEdge,
|
||||||
getNodesBounds: (nodes) => {
|
getNodesBounds: (nodes) => {
|
||||||
@@ -549,8 +554,14 @@ export function useSvelteFlow(): {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function getElements(lookup: Map<string, InternalNode>, ids: string[]): Node[];
|
function getElements<NodeType extends Node = Node>(
|
||||||
function getElements(lookup: Map<string, Edge>, ids: string[]): Edge[];
|
lookup: Map<string, InternalNode<NodeType>>,
|
||||||
|
ids: string[]
|
||||||
|
): NodeType[];
|
||||||
|
function getElements<EdgeType extends Edge = Edge>(
|
||||||
|
lookup: Map<string, EdgeType>,
|
||||||
|
ids: string[]
|
||||||
|
): EdgeType[];
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
function getElements(lookup: Map<string, any>, ids: string[]): any[] {
|
function getElements(lookup: Map<string, any>, ids: string[]): any[] {
|
||||||
const result = [];
|
const result = [];
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ export function getInitialStore<NodeType extends Node = Node, EdgeType extends E
|
|||||||
connectionLookup: ConnectionLookup = new Map();
|
connectionLookup: ConnectionLookup = new Map();
|
||||||
edgeLookup: EdgeLookup<EdgeType> = new Map();
|
edgeLookup: EdgeLookup<EdgeType> = new Map();
|
||||||
|
|
||||||
_prevVisibleEdges = new Map<string, EdgeLayouted>();
|
_prevVisibleEdges = new Map<string, EdgeLayouted<EdgeType>>();
|
||||||
visible = $derived.by(() => {
|
visible = $derived.by(() => {
|
||||||
const {
|
const {
|
||||||
// We need to access this._nodes to trigger on changes
|
// We need to access this._nodes to trigger on changes
|
||||||
@@ -158,8 +158,8 @@ export function getInitialStore<NodeType extends Node = Node, EdgeType extends E
|
|||||||
defaultEdgeOptions
|
defaultEdgeOptions
|
||||||
} = this;
|
} = this;
|
||||||
|
|
||||||
let visibleNodes: Map<string, InternalNode>;
|
let visibleNodes: Map<string, InternalNode<NodeType>>;
|
||||||
let visibleEdges: Map<string, EdgeLayouted>;
|
let visibleEdges: Map<string, EdgeLayouted<EdgeType>>;
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
edges,
|
edges,
|
||||||
|
|||||||
@@ -116,6 +116,6 @@ export type StoreContext<NodeType extends Node = Node, EdgeType extends Edge = E
|
|||||||
export type ProviderContext<
|
export type ProviderContext<
|
||||||
NodeType extends Node = Node,
|
NodeType extends Node = Node,
|
||||||
EdgeType extends Edge = Edge
|
EdgeType extends Edge = Edge
|
||||||
> = StoreContext & {
|
> = StoreContext<NodeType, EdgeType> & {
|
||||||
setStore: (store: SvelteFlowStore<NodeType, EdgeType>) => void;
|
setStore: (store: SvelteFlowStore<NodeType, EdgeType>) => void;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,13 +10,13 @@ import {
|
|||||||
type Transform
|
type Transform
|
||||||
} from '@xyflow/system';
|
} from '@xyflow/system';
|
||||||
|
|
||||||
export function getVisibleNodes(
|
export function getVisibleNodes<NodeType extends Node = Node>(
|
||||||
nodeLookup: NodeLookup,
|
nodeLookup: NodeLookup<InternalNode<NodeType>>,
|
||||||
transform: Transform,
|
transform: Transform,
|
||||||
width: number,
|
width: number,
|
||||||
height: number
|
height: number
|
||||||
) {
|
) {
|
||||||
const visibleNodes = new Map<string, InternalNode>();
|
const visibleNodes = new Map<string, InternalNode<NodeType>>();
|
||||||
getNodesInside(nodeLookup, { x: 0, y: 0, width: width, height: height }, transform, true).forEach(
|
getNodesInside(nodeLookup, { x: 0, y: 0, width: width, height: height }, transform, true).forEach(
|
||||||
(node) => {
|
(node) => {
|
||||||
visibleNodes.set(node.id, node);
|
visibleNodes.set(node.id, node);
|
||||||
@@ -29,7 +29,7 @@ export interface EdgeLayoutBaseOptions<NodeType extends Node = Node, EdgeType ex
|
|||||||
edges: EdgeType[];
|
edges: EdgeType[];
|
||||||
defaultEdgeOptions: DefaultEdgeOptions;
|
defaultEdgeOptions: DefaultEdgeOptions;
|
||||||
elevateEdgesOnSelect: boolean;
|
elevateEdgesOnSelect: boolean;
|
||||||
previousEdges: Map<string, EdgeLayouted>;
|
previousEdges: Map<string, EdgeLayouted<EdgeType>>;
|
||||||
nodeLookup: NodeLookup<InternalNode<NodeType>>;
|
nodeLookup: NodeLookup<InternalNode<NodeType>>;
|
||||||
connectionMode: ConnectionMode;
|
connectionMode: ConnectionMode;
|
||||||
onerror: OnError;
|
onerror: OnError;
|
||||||
@@ -44,7 +44,10 @@ export interface EdgeLayoutAllOptions<NodeType extends Node = Node, EdgeType ext
|
|||||||
height: never;
|
height: never;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EdgeLayoutOnlyVisibleOptions extends EdgeLayoutBaseOptions {
|
export interface EdgeLayoutOnlyVisibleOptions<
|
||||||
|
NodeType extends Node = Node,
|
||||||
|
EdgeType extends Edge = Edge
|
||||||
|
> extends EdgeLayoutBaseOptions<NodeType, EdgeType> {
|
||||||
visibleNodes: Map<string, InternalNode>;
|
visibleNodes: Map<string, InternalNode>;
|
||||||
transform: Transform;
|
transform: Transform;
|
||||||
width: number;
|
width: number;
|
||||||
@@ -54,9 +57,11 @@ export interface EdgeLayoutOnlyVisibleOptions extends EdgeLayoutBaseOptions {
|
|||||||
|
|
||||||
export type EdgeLayoutOptions<NodeType extends Node = Node, EdgeType extends Edge = Edge> =
|
export type EdgeLayoutOptions<NodeType extends Node = Node, EdgeType extends Edge = Edge> =
|
||||||
| EdgeLayoutAllOptions<NodeType, EdgeType>
|
| EdgeLayoutAllOptions<NodeType, EdgeType>
|
||||||
| EdgeLayoutOnlyVisibleOptions;
|
| EdgeLayoutOnlyVisibleOptions<NodeType, EdgeType>;
|
||||||
|
|
||||||
export function getLayoutedEdges(options: EdgeLayoutOptions): Map<string, EdgeLayouted> {
|
export function getLayoutedEdges<NodeType extends Node = Node, EdgeType extends Edge = Edge>(
|
||||||
|
options: EdgeLayoutOptions<NodeType, EdgeType>
|
||||||
|
): Map<string, EdgeLayouted<EdgeType>> {
|
||||||
const {
|
const {
|
||||||
edges,
|
edges,
|
||||||
defaultEdgeOptions,
|
defaultEdgeOptions,
|
||||||
@@ -67,7 +72,7 @@ export function getLayoutedEdges(options: EdgeLayoutOptions): Map<string, EdgeLa
|
|||||||
onlyRenderVisible,
|
onlyRenderVisible,
|
||||||
elevateEdgesOnSelect
|
elevateEdgesOnSelect
|
||||||
} = options;
|
} = options;
|
||||||
const layoutedEdges = new Map<string, EdgeLayouted>();
|
const layoutedEdges = new Map<string, EdgeLayouted<EdgeType>>();
|
||||||
for (const edge of edges) {
|
for (const edge of edges) {
|
||||||
const sourceNode = nodeLookup.get(edge.source);
|
const sourceNode = nodeLookup.get(edge.source);
|
||||||
const targetNode = nodeLookup.get(edge.target);
|
const targetNode = nodeLookup.get(edge.target);
|
||||||
|
|||||||
@@ -151,11 +151,11 @@ export type EdgeTypes = Record<
|
|||||||
|
|
||||||
export type DefaultEdgeOptions = DefaultEdgeOptionsBase<Edge>;
|
export type DefaultEdgeOptions = DefaultEdgeOptionsBase<Edge>;
|
||||||
|
|
||||||
export type EdgeLayouted = Edge &
|
export type EdgeLayouted<EdgeType extends Edge = Edge> = EdgeType &
|
||||||
EdgePosition & {
|
EdgePosition & {
|
||||||
sourceNode?: Node;
|
sourceNode?: Node;
|
||||||
targetNode?: Node;
|
targetNode?: Node;
|
||||||
sourceHandleId?: string | null;
|
sourceHandleId?: string | null;
|
||||||
targetHandleId?: string | null;
|
targetHandleId?: string | null;
|
||||||
edge: Edge;
|
edge: EdgeType;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,46 +1,46 @@
|
|||||||
import type { Edge } from './edges';
|
import type { Edge } from './edges';
|
||||||
import type { Node } from './nodes';
|
import type { Node } from './nodes';
|
||||||
|
|
||||||
export type NodeEventWithPointer<T = PointerEvent> = ({
|
export type NodeEventWithPointer<T = PointerEvent, NodeType extends Node = Node> = ({
|
||||||
node,
|
node,
|
||||||
event
|
event
|
||||||
}: {
|
}: {
|
||||||
node: Node;
|
node: NodeType;
|
||||||
event: T;
|
event: T;
|
||||||
}) => void;
|
}) => void;
|
||||||
|
|
||||||
export type NodesEventWithPointer<T = PointerEvent> = ({
|
export type NodesEventWithPointer<T = PointerEvent, NodeType extends Node = Node> = ({
|
||||||
nodes,
|
nodes,
|
||||||
event
|
event
|
||||||
}: {
|
}: {
|
||||||
nodes: Node[];
|
nodes: NodeType[];
|
||||||
event: T;
|
event: T;
|
||||||
}) => void;
|
}) => void;
|
||||||
|
|
||||||
export type NodeTargetEventWithPointer<T = PointerEvent> = ({
|
export type NodeTargetEventWithPointer<T = PointerEvent, NodeType extends Node = Node> = ({
|
||||||
targetNode,
|
targetNode,
|
||||||
nodes,
|
nodes,
|
||||||
event
|
event
|
||||||
}: {
|
}: {
|
||||||
targetNode: Node | null;
|
targetNode: NodeType | null;
|
||||||
nodes: Node[];
|
nodes: NodeType[];
|
||||||
event: T;
|
event: T;
|
||||||
}) => void;
|
}) => void;
|
||||||
|
|
||||||
export type NodeEvents = {
|
export type NodeEvents<NodeType extends Node = Node> = {
|
||||||
onnodeclick?: NodeEventWithPointer<MouseEvent | TouchEvent>;
|
onnodeclick?: NodeEventWithPointer<MouseEvent | TouchEvent, NodeType>;
|
||||||
onnodecontextmenu?: NodeEventWithPointer<MouseEvent>;
|
onnodecontextmenu?: NodeEventWithPointer<MouseEvent, NodeType>;
|
||||||
onnodedrag?: NodeTargetEventWithPointer<MouseEvent | TouchEvent>;
|
onnodedrag?: NodeTargetEventWithPointer<MouseEvent | TouchEvent, NodeType>;
|
||||||
onnodedragstart?: NodeTargetEventWithPointer<MouseEvent | TouchEvent>;
|
onnodedragstart?: NodeTargetEventWithPointer<MouseEvent | TouchEvent, NodeType>;
|
||||||
onnodedragstop?: NodeTargetEventWithPointer<MouseEvent | TouchEvent>;
|
onnodedragstop?: NodeTargetEventWithPointer<MouseEvent | TouchEvent, NodeType>;
|
||||||
onnodepointerenter?: NodeEventWithPointer;
|
onnodepointerenter?: NodeEventWithPointer<PointerEvent, NodeType>;
|
||||||
onnodepointerleave?: NodeEventWithPointer;
|
onnodepointerleave?: NodeEventWithPointer<PointerEvent, NodeType>;
|
||||||
onnodepointermove?: NodeEventWithPointer;
|
onnodepointermove?: NodeEventWithPointer<PointerEvent, NodeType>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type NodeSelectionEvents = {
|
export type NodeSelectionEvents<NodeType extends Node = Node> = {
|
||||||
onselectioncontextmenu?: NodesEventWithPointer<MouseEvent>;
|
onselectioncontextmenu?: NodesEventWithPointer<MouseEvent, NodeType>;
|
||||||
onselectionclick?: NodesEventWithPointer<MouseEvent>;
|
onselectionclick?: NodesEventWithPointer<MouseEvent, NodeType>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type PaneEvents = {
|
export type PaneEvents = {
|
||||||
@@ -48,9 +48,9 @@ export type PaneEvents = {
|
|||||||
onpanecontextmenu?: ({ event }: { event: MouseEvent }) => void;
|
onpanecontextmenu?: ({ event }: { event: MouseEvent }) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type EdgeEvents = {
|
export type EdgeEvents<EdgeType extends Edge = Edge> = {
|
||||||
onedgeclick?: ({ edge, event }: { edge: Edge; event: MouseEvent }) => void;
|
onedgeclick?: ({ edge, event }: { edge: EdgeType; event: MouseEvent }) => void;
|
||||||
onedgecontextmenu?: ({ edge, event }: { edge: Edge; event: MouseEvent }) => void;
|
onedgecontextmenu?: ({ edge, event }: { edge: EdgeType; event: MouseEvent }) => void;
|
||||||
onedgepointerenter?: ({ edge, event }: { edge: Edge; event: PointerEvent }) => void;
|
onedgepointerenter?: ({ edge, event }: { edge: EdgeType; event: PointerEvent }) => void;
|
||||||
onedgepointerleave?: ({ edge, event }: { edge: Edge; event: PointerEvent }) => void;
|
onedgepointerleave?: ({ edge, event }: { edge: EdgeType; event: PointerEvent }) => void;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user