migrate some components
This commit is contained in:
@@ -2,13 +2,10 @@
|
|||||||
import { Panel } from '$lib/container/Panel';
|
import { Panel } from '$lib/container/Panel';
|
||||||
import type { AttributionProps } from './types';
|
import type { AttributionProps } from './types';
|
||||||
|
|
||||||
type $$Props = AttributionProps;
|
let { proOptions, position = 'bottom-right' }: AttributionProps = $props();
|
||||||
|
|
||||||
export let proOptions: $$Props['proOptions'] = undefined;
|
|
||||||
export let position: $$Props['position'] = 'bottom-right';
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if !proOptions?.hideAttribution}
|
{#if proOptions?.hideAttribution}
|
||||||
<Panel
|
<Panel
|
||||||
{position}
|
{position}
|
||||||
class="svelte-flow__attribution"
|
class="svelte-flow__attribution"
|
||||||
|
|||||||
@@ -3,22 +3,19 @@
|
|||||||
import type { BaseEdgeProps } from './types';
|
import type { BaseEdgeProps } from './types';
|
||||||
import EdgeLabel from '../EdgeLabel/EdgeLabel.svelte';
|
import EdgeLabel from '../EdgeLabel/EdgeLabel.svelte';
|
||||||
|
|
||||||
type $$Props = BaseEdgeProps;
|
let {
|
||||||
|
id,
|
||||||
export let id: $$Props['id'] = undefined;
|
path,
|
||||||
export let path: $$Props['path'];
|
label,
|
||||||
export let label: $$Props['label'] = undefined;
|
labelX,
|
||||||
export let labelX: $$Props['labelX'] = undefined;
|
labelY,
|
||||||
export let labelY: $$Props['labelY'] = undefined;
|
labelStyle,
|
||||||
export let labelStyle: $$Props['labelStyle'] = undefined;
|
markerStart,
|
||||||
export let markerStart: $$Props['markerStart'] = undefined;
|
markerEnd,
|
||||||
export let markerEnd: $$Props['markerEnd'] = undefined;
|
style,
|
||||||
export let style: $$Props['style'] = undefined;
|
interactionWidth = 20,
|
||||||
export let interactionWidth: $$Props['interactionWidth'] = 20;
|
class: className
|
||||||
let className: $$Props['class'] = undefined;
|
}: BaseEdgeProps = $props();
|
||||||
export { className as class };
|
|
||||||
|
|
||||||
let interactionWidthValue = interactionWidth === undefined ? 20 : interactionWidth;
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<path
|
<path
|
||||||
@@ -31,11 +28,11 @@
|
|||||||
{style}
|
{style}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{#if interactionWidthValue}
|
{#if interactionWidth > 0}
|
||||||
<path
|
<path
|
||||||
d={path}
|
d={path}
|
||||||
stroke-opacity={0}
|
stroke-opacity={0}
|
||||||
stroke-width={interactionWidthValue}
|
stroke-width={interactionWidth}
|
||||||
fill="none"
|
fill="none"
|
||||||
class="svelte-flow__edge-interaction"
|
class="svelte-flow__edge-interaction"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import cc from 'classcat';
|
import cc from 'classcat';
|
||||||
|
import type { Snippet } from 'svelte';
|
||||||
import { useStore } from '$lib/store';
|
|
||||||
import {
|
import {
|
||||||
ConnectionLineType,
|
ConnectionLineType,
|
||||||
getBezierPath,
|
getBezierPath,
|
||||||
@@ -10,50 +9,61 @@
|
|||||||
getStraightPath
|
getStraightPath
|
||||||
} from '@xyflow/system';
|
} from '@xyflow/system';
|
||||||
|
|
||||||
export let containerStyle: string = '';
|
import { useStore } from '$lib/store';
|
||||||
export let style: string = '';
|
|
||||||
export let isCustomComponent: boolean = false;
|
let {
|
||||||
|
containerStyle = '',
|
||||||
|
style = '',
|
||||||
|
connectionLine
|
||||||
|
}: {
|
||||||
|
containerStyle: string;
|
||||||
|
style: string;
|
||||||
|
connectionLine?: Snippet;
|
||||||
|
} = $props();
|
||||||
|
|
||||||
const { width, height, connection, connectionLineType } = useStore();
|
const { width, height, connection, connectionLineType } = useStore();
|
||||||
|
|
||||||
let path: string | null = null;
|
let path = $derived.by(() => {
|
||||||
|
if (!$connection.inProgress) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
$: if ($connection.inProgress && !isCustomComponent) {
|
|
||||||
const { from, to, fromPosition, toPosition } = $connection;
|
|
||||||
const pathParams = {
|
const pathParams = {
|
||||||
sourceX: from.x,
|
sourceX: $connection.from.x,
|
||||||
sourceY: from.y,
|
sourceY: $connection.from.y,
|
||||||
sourcePosition: fromPosition,
|
sourcePosition: $connection.fromPosition,
|
||||||
targetX: to.x,
|
targetX: $connection.to.x,
|
||||||
targetY: to.y,
|
targetY: $connection.to.y,
|
||||||
targetPosition: toPosition
|
targetPosition: $connection.toPosition
|
||||||
};
|
};
|
||||||
|
|
||||||
switch ($connectionLineType) {
|
switch ($connectionLineType) {
|
||||||
case ConnectionLineType.Bezier:
|
case ConnectionLineType.Bezier: {
|
||||||
[path] = getBezierPath(pathParams);
|
const [path] = getBezierPath(pathParams);
|
||||||
break;
|
return path;
|
||||||
|
}
|
||||||
|
case ConnectionLineType.Straight: {
|
||||||
|
const [path] = getStraightPath(pathParams);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
case ConnectionLineType.Step:
|
case ConnectionLineType.Step:
|
||||||
[path] = getSmoothStepPath({
|
case ConnectionLineType.SmoothStep: {
|
||||||
|
const [path] = getSmoothStepPath({
|
||||||
...pathParams,
|
...pathParams,
|
||||||
borderRadius: 0
|
borderRadius: $connectionLineType === ConnectionLineType.Step ? 0 : undefined
|
||||||
});
|
});
|
||||||
break;
|
return path;
|
||||||
case ConnectionLineType.SmoothStep:
|
}
|
||||||
[path] = getSmoothStepPath(pathParams);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
[path] = getStraightPath(pathParams);
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if $connection.inProgress}
|
{#if $connection.inProgress}
|
||||||
<svg width={$width} height={$height} class="svelte-flow__connectionline" style={containerStyle}>
|
<svg width={$width} height={$height} class="svelte-flow__connectionline" style={containerStyle}>
|
||||||
<g class={cc(['svelte-flow__connection', getConnectionStatus($connection.isValid)])}>
|
<g class={cc(['svelte-flow__connection', getConnectionStatus($connection.isValid)])}>
|
||||||
<slot name="connectionLine" />
|
{#if connectionLine}
|
||||||
<!-- slot fallbacks do not work if slots are forwarded in parent -->
|
{@render connectionLine()}
|
||||||
{#if !isCustomComponent}
|
{:else}
|
||||||
<path d={path} {style} fill="none" class="svelte-flow__connection-path" />
|
<path d={path} {style} fill="none" class="svelte-flow__connection-path" />
|
||||||
{/if}
|
{/if}
|
||||||
</g>
|
</g>
|
||||||
|
|||||||
@@ -1,13 +1,20 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { getContext } from 'svelte';
|
import { getContext, type Snippet } from 'svelte';
|
||||||
|
|
||||||
import { EdgeLabelRenderer } from '$lib/components/EdgeLabelRenderer';
|
import { EdgeLabelRenderer } from '$lib/components/EdgeLabelRenderer';
|
||||||
import { useHandleEdgeSelect } from '$lib/hooks/useHandleEdgeSelect';
|
import { useHandleEdgeSelect } from '$lib/hooks/useHandleEdgeSelect';
|
||||||
import type { BaseEdgeProps } from '$lib/components/BaseEdge/types';
|
|
||||||
|
|
||||||
export let style: BaseEdgeProps['labelStyle'] = undefined;
|
let {
|
||||||
export let x: BaseEdgeProps['labelX'] = undefined;
|
style,
|
||||||
export let y: BaseEdgeProps['labelY'] = undefined;
|
x,
|
||||||
|
y,
|
||||||
|
children
|
||||||
|
}: {
|
||||||
|
style?: string;
|
||||||
|
x?: number;
|
||||||
|
y?: number;
|
||||||
|
children?: Snippet;
|
||||||
|
} = $props();
|
||||||
|
|
||||||
const handleEdgeSelect = useHandleEdgeSelect();
|
const handleEdgeSelect = useHandleEdgeSelect();
|
||||||
|
|
||||||
@@ -21,11 +28,11 @@
|
|||||||
style={'pointer-events: all;' + style}
|
style={'pointer-events: all;' + style}
|
||||||
role="button"
|
role="button"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
on:keyup={() => {}}
|
onkeyup={() => {}}
|
||||||
on:click={() => {
|
onclick={() => {
|
||||||
if (id) handleEdgeSelect(id);
|
if (id) handleEdgeSelect(id);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<slot />
|
{@render children?.()}
|
||||||
</div>
|
</div>
|
||||||
</EdgeLabelRenderer>
|
</EdgeLabelRenderer>
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import type { Snippet } from 'svelte';
|
||||||
import portal from '$lib/actions/portal';
|
import portal from '$lib/actions/portal';
|
||||||
import { useStore } from '$lib/store';
|
import { useStore } from '$lib/store';
|
||||||
|
|
||||||
const { domNode } = useStore();
|
const { domNode } = useStore();
|
||||||
|
|
||||||
|
let { children }: { children?: Snippet } = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div use:portal={{ target: '.svelte-flow__edgelabel-renderer', domNode: $domNode }}>
|
<div use:portal={{ target: '.svelte-flow__edgelabel-renderer', domNode: $domNode }}>
|
||||||
<slot />
|
{@render children?.()}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -40,6 +40,8 @@
|
|||||||
export let ariaLabel: $$Props['ariaLabel'] = undefined;
|
export let ariaLabel: $$Props['ariaLabel'] = undefined;
|
||||||
export let interactionWidth: $$Props['interactionWidth'] = undefined;
|
export let interactionWidth: $$Props['interactionWidth'] = undefined;
|
||||||
|
|
||||||
|
// TODO SVELTE5
|
||||||
|
|
||||||
// @ todo: support edge updates
|
// @ todo: support edge updates
|
||||||
let className: string = '';
|
let className: string = '';
|
||||||
export { className as class };
|
export { className as class };
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
//TODO SVELTE5
|
||||||
import { getContext } from 'svelte';
|
import { getContext } from 'svelte';
|
||||||
import type { Writable } from 'svelte/store';
|
import type { Writable } from 'svelte/store';
|
||||||
import cc from 'classcat';
|
import cc from 'classcat';
|
||||||
|
|||||||
@@ -1,22 +1,23 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { get } from 'svelte/store';
|
||||||
import {
|
import {
|
||||||
shortcut,
|
shortcut,
|
||||||
type ShortcutEventDetail,
|
type ShortcutEventDetail,
|
||||||
type ShortcutModifierDefinition
|
type ShortcutModifierDefinition
|
||||||
} from '@svelte-put/shortcut';
|
} from '@svelte-put/shortcut';
|
||||||
import { isInputDOMNode, isMacOs } from '@xyflow/system';
|
import { getElementsToRemove, isInputDOMNode, isMacOs } from '@xyflow/system';
|
||||||
|
|
||||||
import { useStore } from '$lib/store';
|
import { useStore } from '$lib/store';
|
||||||
import type { KeyHandlerProps } from './types';
|
import type { KeyHandlerProps } from './types';
|
||||||
import type { KeyDefinition, KeyDefinitionObject } from '$lib/types';
|
import type { KeyDefinition, KeyDefinitionObject } from '$lib/types';
|
||||||
|
|
||||||
type $$Props = KeyHandlerProps;
|
let {
|
||||||
|
selectionKey = 'Shift',
|
||||||
export let selectionKey: $$Props['selectionKey'] = 'Shift';
|
multiSelectionKey = isMacOs() ? 'Meta' : 'Control',
|
||||||
export let multiSelectionKey: $$Props['multiSelectionKey'] = isMacOs() ? 'Meta' : 'Control';
|
deleteKey = 'Backspace',
|
||||||
export let deleteKey: $$Props['deleteKey'] = 'Backspace';
|
panActivationKey = ' ',
|
||||||
export let panActivationKey: $$Props['panActivationKey'] = ' ';
|
zoomActivationKey = isMacOs() ? 'Meta' : 'Control'
|
||||||
export let zoomActivationKey: $$Props['zoomActivationKey'] = isMacOs() ? 'Meta' : 'Control';
|
}: KeyHandlerProps = $props();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
selectionKeyPressed,
|
selectionKeyPressed,
|
||||||
@@ -24,7 +25,11 @@
|
|||||||
deleteKeyPressed,
|
deleteKeyPressed,
|
||||||
panActivationKeyPressed,
|
panActivationKeyPressed,
|
||||||
zoomActivationKeyPressed,
|
zoomActivationKeyPressed,
|
||||||
selectionRect
|
selectionRect,
|
||||||
|
onbeforedelete,
|
||||||
|
ondelete,
|
||||||
|
nodes: _nodes,
|
||||||
|
edges: _edges
|
||||||
} = useStore();
|
} = useStore();
|
||||||
|
|
||||||
function isKeyObject(key?: KeyDefinition | null): key is KeyDefinitionObject {
|
function isKeyObject(key?: KeyDefinition | null): key is KeyDefinitionObject {
|
||||||
@@ -69,6 +74,31 @@
|
|||||||
panActivationKeyPressed.set(false);
|
panActivationKeyPressed.set(false);
|
||||||
zoomActivationKeyPressed.set(false);
|
zoomActivationKeyPressed.set(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleDelete() {
|
||||||
|
const nodes = get(_nodes);
|
||||||
|
const edges = get(_edges);
|
||||||
|
const selectedNodes = nodes.filter((node) => node.selected);
|
||||||
|
const selectedEdges = edges.filter((edge) => edge.selected);
|
||||||
|
|
||||||
|
const { nodes: matchingNodes, edges: matchingEdges } = await getElementsToRemove({
|
||||||
|
nodesToRemove: selectedNodes,
|
||||||
|
edgesToRemove: selectedEdges,
|
||||||
|
nodes,
|
||||||
|
edges,
|
||||||
|
onBeforeDelete: get(onbeforedelete)
|
||||||
|
});
|
||||||
|
|
||||||
|
if (matchingNodes.length || matchingEdges.length) {
|
||||||
|
_nodes.update((nds) => nds.filter((node) => !matchingNodes.some((mN) => mN.id === node.id)));
|
||||||
|
_edges.update((eds) => eds.filter((edge) => !matchingEdges.some((mE) => mE.id === edge.id)));
|
||||||
|
|
||||||
|
get(ondelete)?.({
|
||||||
|
nodes: matchingNodes,
|
||||||
|
edges: matchingEdges
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:window
|
<svelte:window
|
||||||
@@ -98,6 +128,7 @@
|
|||||||
detail.originalEvent.shiftKey;
|
detail.originalEvent.shiftKey;
|
||||||
if (!isModifierKey && !isInputDOMNode(detail.originalEvent)) {
|
if (!isModifierKey && !isInputDOMNode(detail.originalEvent)) {
|
||||||
deleteKeyPressed.set(true);
|
deleteKeyPressed.set(true);
|
||||||
|
handleDelete();
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
type: 'keydown'
|
type: 'keydown'
|
||||||
|
|||||||
@@ -1,37 +1,39 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createEventDispatcher } from 'svelte';
|
|
||||||
import { getInternalNodesBounds, isNumeric, type Rect } from '@xyflow/system';
|
import { getInternalNodesBounds, isNumeric, type Rect } from '@xyflow/system';
|
||||||
|
|
||||||
import { useStore } from '$lib/store';
|
import { useStore } from '$lib/store';
|
||||||
import { Selection } from '$lib/components/Selection';
|
import { Selection } from '$lib/components/Selection';
|
||||||
import drag from '$lib/actions/drag';
|
import drag from '$lib/actions/drag';
|
||||||
import type { Node, NodeEventMap } from '$lib/types';
|
|
||||||
|
import type { NodeSelectionProps } from './types';
|
||||||
|
|
||||||
|
let {
|
||||||
|
onnodedrag,
|
||||||
|
onnodedragstart,
|
||||||
|
onnodedragstop,
|
||||||
|
onselectionclick,
|
||||||
|
onselectioncontextmenu
|
||||||
|
}: NodeSelectionProps = $props();
|
||||||
|
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
const { selectionRectMode, nodes, nodeLookup } = store;
|
const { selectionRectMode, nodes, nodeLookup } = store;
|
||||||
|
|
||||||
const dispatch = createEventDispatcher<
|
let bounds: Rect | null = $derived.by(() => {
|
||||||
NodeEventMap & {
|
if ($selectionRectMode === 'nodes') {
|
||||||
selectioncontextmenu: { nodes: Node[]; event: MouseEvent | TouchEvent };
|
$nodes;
|
||||||
selectionclick: { nodes: Node[]; event: MouseEvent | TouchEvent };
|
return getInternalNodesBounds($nodeLookup, { filter: (node) => !!node.selected });
|
||||||
}
|
}
|
||||||
>();
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
let bounds: Rect | null = null;
|
function oncontextmenu(event: MouseEvent | TouchEvent) {
|
||||||
|
const selectedNodes = $nodes.filter((n) => n.selected);
|
||||||
$: if ($selectionRectMode === 'nodes') {
|
onselectioncontextmenu?.({ nodes: selectedNodes, event });
|
||||||
bounds = getInternalNodesBounds($nodeLookup, { filter: (node) => !!node.selected });
|
|
||||||
$nodes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onContextMenu(event: MouseEvent | TouchEvent) {
|
function onclick(event: MouseEvent | TouchEvent) {
|
||||||
const selectedNodes = $nodes.filter((n) => n.selected);
|
const selectedNodes = $nodes.filter((n) => n.selected);
|
||||||
dispatch('selectioncontextmenu', { nodes: selectedNodes, event });
|
onselectionclick?.({ nodes: selectedNodes, event });
|
||||||
}
|
|
||||||
|
|
||||||
function onClick(event: MouseEvent | TouchEvent) {
|
|
||||||
const selectedNodes = $nodes.filter((n) => n.selected);
|
|
||||||
dispatch('selectionclick', { nodes: selectedNodes, event });
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -43,20 +45,20 @@
|
|||||||
disabled: false,
|
disabled: false,
|
||||||
store,
|
store,
|
||||||
onDrag: (event, _, __, nodes) => {
|
onDrag: (event, _, __, nodes) => {
|
||||||
dispatch('nodedrag', { event, targetNode: null, nodes });
|
onnodedrag?.({ event, targetNode: null, nodes });
|
||||||
},
|
},
|
||||||
onDragStart: (event, _, __, nodes) => {
|
onDragStart: (event, _, __, nodes) => {
|
||||||
dispatch('nodedragstart', { event, targetNode: null, nodes });
|
onnodedragstart?.({ event, targetNode: null, nodes });
|
||||||
},
|
},
|
||||||
onDragStop: (event, _, __, nodes) => {
|
onDragStop: (event, _, __, nodes) => {
|
||||||
dispatch('nodedragstop', { event, targetNode: null, nodes });
|
onnodedragstop?.({ event, targetNode: null, nodes });
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
on:contextmenu={onContextMenu}
|
{oncontextmenu}
|
||||||
on:click={onClick}
|
{onclick}
|
||||||
role="button"
|
role="button"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
on:keyup={() => {}}
|
onkeyup={() => {}}
|
||||||
>
|
>
|
||||||
<Selection width="100%" height="100%" x={0} y={0} />
|
<Selection width="100%" height="100%" x={0} y={0} />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
import type { NodeEvents, NodeSelectionEvents } from '$lib/types';
|
||||||
|
|
||||||
|
export type NodeSelectionProps = NodeSelectionEvents &
|
||||||
|
Pick<NodeEvents, 'onnodedrag' | 'onnodedragstart' | 'onnodedragstop'>;
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
<svelte:options immutable />
|
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { setContext, onDestroy, createEventDispatcher } from 'svelte';
|
import { setContext, onDestroy } from 'svelte';
|
||||||
import { get, writable } from 'svelte/store';
|
import { get, writable } from 'svelte/store';
|
||||||
import cc from 'classcat';
|
import cc from 'classcat';
|
||||||
import { errorMessages, Position } from '@xyflow/system';
|
import { errorMessages, Position } from '@xyflow/system';
|
||||||
@@ -11,42 +9,48 @@
|
|||||||
import DefaultNode from '$lib/components/nodes/DefaultNode.svelte';
|
import DefaultNode from '$lib/components/nodes/DefaultNode.svelte';
|
||||||
import type { NodeWrapperProps } from './types';
|
import type { NodeWrapperProps } from './types';
|
||||||
import { getNodeInlineStyleDimensions } from './utils';
|
import { getNodeInlineStyleDimensions } from './utils';
|
||||||
import type { NodeEventMap } from '$lib/types';
|
import type { NodeEvents } from '$lib/types';
|
||||||
|
|
||||||
interface $$Props extends NodeWrapperProps {}
|
let {
|
||||||
|
node,
|
||||||
export let node: $$Props['node'];
|
id,
|
||||||
export let id: $$Props['id'];
|
data = {},
|
||||||
export let data: $$Props['data'] = {};
|
selected = false,
|
||||||
export let selected: $$Props['selected'] = false;
|
draggable,
|
||||||
export let draggable: $$Props['draggable'] = undefined;
|
selectable,
|
||||||
export let selectable: $$Props['selectable'] = undefined;
|
deletable,
|
||||||
export let connectable: $$Props['connectable'] = true;
|
connectable = true,
|
||||||
export let deletable: $$Props['deletable'] = true;
|
hidden = false,
|
||||||
export let hidden: $$Props['hidden'] = false;
|
dragging = false,
|
||||||
export let dragging: boolean = false;
|
resizeObserver = null,
|
||||||
export let resizeObserver: $$Props['resizeObserver'] = null;
|
style,
|
||||||
export let style: $$Props['style'] = undefined;
|
class: className,
|
||||||
export let type: $$Props['type'] = 'default';
|
type = 'default',
|
||||||
export let isParent: $$Props['isParent'] = false;
|
isParent = false,
|
||||||
export let positionX: $$Props['positionX'];
|
parentId,
|
||||||
export let positionY: $$Props['positionY'];
|
positionX,
|
||||||
export let sourcePosition: $$Props['sourcePosition'] = undefined;
|
positionY,
|
||||||
export let targetPosition: $$Props['targetPosition'] = undefined;
|
sourcePosition,
|
||||||
export let zIndex: $$Props['zIndex'];
|
targetPosition,
|
||||||
export let measuredWidth: $$Props['measuredWidth'] = undefined;
|
zIndex,
|
||||||
export let measuredHeight: $$Props['measuredHeight'] = undefined;
|
measuredWidth,
|
||||||
export let initialWidth: $$Props['initialWidth'] = undefined;
|
measuredHeight,
|
||||||
export let initialHeight: $$Props['initialHeight'] = undefined;
|
initialWidth,
|
||||||
export let width: $$Props['width'] = undefined;
|
initialHeight,
|
||||||
export let height: $$Props['height'] = undefined;
|
width,
|
||||||
export let dragHandle: $$Props['dragHandle'] = undefined;
|
height,
|
||||||
export let initialized: $$Props['initialized'] = false;
|
dragHandle,
|
||||||
export let parentId: $$Props['parentId'] = undefined;
|
initialized = false,
|
||||||
export let nodeClickDistance: $$Props['nodeClickDistance'] = undefined;
|
nodeClickDistance,
|
||||||
|
onnodeclick,
|
||||||
let className: string = '';
|
onnodedrag,
|
||||||
export { className as class };
|
onnodedragstart,
|
||||||
|
onnodedragstop,
|
||||||
|
onnodemouseenter,
|
||||||
|
onnodemouseleave,
|
||||||
|
onnodemousemove,
|
||||||
|
onnodecontextmenu
|
||||||
|
}: NodeWrapperProps & NodeEvents = $props();
|
||||||
|
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
const {
|
const {
|
||||||
@@ -57,78 +61,85 @@
|
|||||||
updateNodeInternals
|
updateNodeInternals
|
||||||
} = store;
|
} = store;
|
||||||
|
|
||||||
let nodeRef: HTMLDivElement;
|
let nodeRef: HTMLDivElement | null = $state(null);
|
||||||
let prevNodeRef: HTMLDivElement | null = null;
|
let prevNodeRef: HTMLDivElement | null = null;
|
||||||
|
|
||||||
const dispatchNodeEvent = createEventDispatcher<NodeEventMap>();
|
|
||||||
const connectableStore = writable(connectable);
|
const connectableStore = writable(connectable);
|
||||||
let prevType: string | undefined = undefined;
|
|
||||||
let prevSourcePosition: Position | undefined = undefined;
|
|
||||||
let prevTargetPosition: Position | undefined = undefined;
|
|
||||||
|
|
||||||
$: nodeType = type || 'default';
|
let prevType: string | undefined;
|
||||||
$: nodeTypeValid = !!$nodeTypes[nodeType];
|
let prevSourcePosition: Position | undefined;
|
||||||
$: nodeComponent = $nodeTypes[nodeType] || DefaultNode;
|
let prevTargetPosition: Position | undefined;
|
||||||
|
|
||||||
$: {
|
let NodeComponent = $derived($nodeTypes[type] ?? DefaultNode);
|
||||||
if (!nodeTypeValid) {
|
|
||||||
console.warn('003', errorMessages['error003'](type!));
|
if (process.env.NODE_ENV === 'development') {
|
||||||
}
|
$effect(() => {
|
||||||
|
const valid = !!$nodeTypes[type];
|
||||||
|
if (!valid) {
|
||||||
|
console.warn('003', errorMessages['error003'](type!));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$: inlineStyleDimensions = getNodeInlineStyleDimensions({
|
let inlineStyleDimensions = $derived(
|
||||||
width,
|
getNodeInlineStyleDimensions({
|
||||||
height,
|
width,
|
||||||
initialWidth,
|
height,
|
||||||
initialHeight,
|
initialWidth,
|
||||||
measuredWidth,
|
initialHeight,
|
||||||
measuredHeight
|
measuredWidth,
|
||||||
|
measuredHeight
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
connectableStore.set(!!connectable);
|
||||||
});
|
});
|
||||||
|
|
||||||
$: {
|
$effect(() => {
|
||||||
connectableStore.set(!!connectable);
|
|
||||||
}
|
|
||||||
|
|
||||||
$: {
|
|
||||||
// if type, sourcePosition or targetPosition changes,
|
// if type, sourcePosition or targetPosition changes,
|
||||||
// we need to re-calculate the handle positions
|
// we need to re-calculate the handle positions
|
||||||
const doUpdate =
|
const doUpdate =
|
||||||
(prevType && nodeType !== prevType) ||
|
(prevType && type !== prevType) ||
|
||||||
(prevSourcePosition && sourcePosition !== prevSourcePosition) ||
|
(prevSourcePosition && sourcePosition !== prevSourcePosition) ||
|
||||||
(prevTargetPosition && targetPosition !== prevTargetPosition);
|
(prevTargetPosition && targetPosition !== prevTargetPosition);
|
||||||
|
|
||||||
if (doUpdate) {
|
if (doUpdate && nodeRef !== null) {
|
||||||
requestAnimationFrame(() =>
|
requestAnimationFrame(() => {
|
||||||
updateNodeInternals(
|
if (nodeRef !== null) {
|
||||||
new Map([
|
updateNodeInternals(
|
||||||
[
|
new Map([
|
||||||
id,
|
[
|
||||||
{
|
|
||||||
id,
|
id,
|
||||||
nodeElement: nodeRef,
|
{
|
||||||
force: true
|
id,
|
||||||
}
|
nodeElement: nodeRef,
|
||||||
]
|
force: true
|
||||||
])
|
}
|
||||||
)
|
]
|
||||||
);
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
prevType = nodeType;
|
prevType = type;
|
||||||
prevSourcePosition = sourcePosition;
|
prevSourcePosition = sourcePosition;
|
||||||
prevTargetPosition = targetPosition;
|
prevTargetPosition = targetPosition;
|
||||||
}
|
});
|
||||||
|
|
||||||
setContext('svelteflow__node_id', id);
|
setContext('svelteflow__node_id', id);
|
||||||
setContext('svelteflow__node_connectable', connectableStore);
|
setContext('svelteflow__node_connectable', connectableStore);
|
||||||
|
|
||||||
$: {
|
// TODO: extract this part!
|
||||||
if (resizeObserver && (nodeRef !== prevNodeRef || !initialized)) {
|
$effect(() => {
|
||||||
|
// TODO: HOLY MOLY! changing the order of the initialized breaks effect subscriptions
|
||||||
|
if (resizeObserver && (!initialized || nodeRef !== prevNodeRef)) {
|
||||||
prevNodeRef && resizeObserver.unobserve(prevNodeRef);
|
prevNodeRef && resizeObserver.unobserve(prevNodeRef);
|
||||||
nodeRef && resizeObserver.observe(nodeRef);
|
nodeRef && resizeObserver.observe(nodeRef);
|
||||||
prevNodeRef = nodeRef;
|
prevNodeRef = nodeRef;
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
if (prevNodeRef) {
|
if (prevNodeRef) {
|
||||||
@@ -143,12 +154,12 @@
|
|||||||
handleNodeSelection(id);
|
handleNodeSelection(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatchNodeEvent('nodeclick', { node: node.internals.userNode, event });
|
onnodeclick?.({ node: node.internals.userNode, event });
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||||
{#if !hidden}
|
{#if !hidden}
|
||||||
<div
|
<div
|
||||||
use:drag={{
|
use:drag={{
|
||||||
@@ -160,19 +171,19 @@
|
|||||||
nodeClickDistance,
|
nodeClickDistance,
|
||||||
onNodeMouseDown: handleNodeSelection,
|
onNodeMouseDown: handleNodeSelection,
|
||||||
onDrag: (event, _, targetNode, nodes) => {
|
onDrag: (event, _, targetNode, nodes) => {
|
||||||
dispatchNodeEvent('nodedrag', { event, targetNode, nodes });
|
onnodedrag?.({ event, targetNode, nodes });
|
||||||
},
|
},
|
||||||
onDragStart: (event, _, targetNode, nodes) => {
|
onDragStart: (event, _, targetNode, nodes) => {
|
||||||
dispatchNodeEvent('nodedragstart', { event, targetNode, nodes });
|
onnodedragstart?.({ event, targetNode, nodes });
|
||||||
},
|
},
|
||||||
onDragStop: (event, _, targetNode, nodes) => {
|
onDragStop: (event, _, targetNode, nodes) => {
|
||||||
dispatchNodeEvent('nodedragstop', { event, targetNode, nodes });
|
onnodedragstop?.({ event, targetNode, nodes });
|
||||||
},
|
},
|
||||||
store
|
store
|
||||||
}}
|
}}
|
||||||
bind:this={nodeRef}
|
bind:this={nodeRef}
|
||||||
data-id={id}
|
data-id={id}
|
||||||
class={cc(['svelte-flow__node', `svelte-flow__node-${nodeType}`, className])}
|
class={cc(['svelte-flow__node', `svelte-flow__node-${type}`, className])}
|
||||||
class:dragging
|
class:dragging
|
||||||
class:selected
|
class:selected
|
||||||
class:draggable
|
class:draggable
|
||||||
@@ -184,14 +195,13 @@
|
|||||||
style:transform="translate({positionX}px, {positionY}px)"
|
style:transform="translate({positionX}px, {positionY}px)"
|
||||||
style:visibility={initialized ? 'visible' : 'hidden'}
|
style:visibility={initialized ? 'visible' : 'hidden'}
|
||||||
style="{style ?? ''};{inlineStyleDimensions.width}{inlineStyleDimensions.height}"
|
style="{style ?? ''};{inlineStyleDimensions.width}{inlineStyleDimensions.height}"
|
||||||
on:click={onSelectNodeHandler}
|
onclick={onSelectNodeHandler}
|
||||||
on:mouseenter={(event) => dispatchNodeEvent('nodemouseenter', { node, event })}
|
onmouseenter={onnodemouseenter ? (event) => onnodemouseenter({ node, event }) : undefined}
|
||||||
on:mouseleave={(event) => dispatchNodeEvent('nodemouseleave', { node, event })}
|
onmouseleave={onnodemouseleave ? (event) => onnodemouseleave({ node, event }) : undefined}
|
||||||
on:mousemove={(event) => dispatchNodeEvent('nodemousemove', { node, event })}
|
onmousemove={onnodemousemove ? (event) => onnodemousemove({ node, event }) : undefined}
|
||||||
on:contextmenu={(event) => dispatchNodeEvent('nodecontextmenu', { node, event })}
|
oncontextmenu={onnodecontextmenu ? (event) => onnodecontextmenu({ node, event }) : undefined}
|
||||||
>
|
>
|
||||||
<svelte:component
|
<NodeComponent
|
||||||
this={nodeComponent}
|
|
||||||
{data}
|
{data}
|
||||||
{id}
|
{id}
|
||||||
{selected}
|
{selected}
|
||||||
@@ -204,7 +214,7 @@
|
|||||||
{draggable}
|
{draggable}
|
||||||
{dragHandle}
|
{dragHandle}
|
||||||
{parentId}
|
{parentId}
|
||||||
type={nodeType}
|
{type}
|
||||||
isConnectable={$connectableStore}
|
isConnectable={$connectableStore}
|
||||||
positionAbsoluteX={positionX}
|
positionAbsoluteX={positionX}
|
||||||
positionAbsoluteY={positionY}
|
positionAbsoluteY={positionY}
|
||||||
|
|||||||
@@ -34,5 +34,5 @@ export type NodeWrapperProps = Pick<
|
|||||||
zIndex: number;
|
zIndex: number;
|
||||||
node: InternalNode;
|
node: InternalNode;
|
||||||
initialized: boolean;
|
initialized: boolean;
|
||||||
nodeClickDistance?: number;
|
nodeClickDistance: number;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,17 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export let x: number | null = 0;
|
let {
|
||||||
export let y: number | null = 0;
|
x = 0,
|
||||||
export let width: number | string | null = 0;
|
y = 0,
|
||||||
export let height: number | string | null = 0;
|
width = 0,
|
||||||
export let isVisible: boolean = true;
|
height = 0,
|
||||||
|
isVisible = true
|
||||||
|
}: {
|
||||||
|
x?: number | null;
|
||||||
|
y?: number | null;
|
||||||
|
width?: number | string | null;
|
||||||
|
height?: number | string | null;
|
||||||
|
isVisible?: boolean;
|
||||||
|
} = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if isVisible}
|
{#if isVisible}
|
||||||
@@ -12,7 +20,7 @@
|
|||||||
style:width={typeof width === 'string' ? width : `${width}px`}
|
style:width={typeof width === 'string' ? width : `${width}px`}
|
||||||
style:height={typeof height === 'string' ? height : `${height}px`}
|
style:height={typeof height === 'string' ? height : `${height}px`}
|
||||||
style:transform={`translate(${x}px, ${y}px)`}
|
style:transform={`translate(${x}px, ${y}px)`}
|
||||||
/>
|
></div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import type { Snippet } from 'svelte';
|
||||||
|
|
||||||
import portal from '$lib/actions/portal';
|
import portal from '$lib/actions/portal';
|
||||||
import { useStore } from '$lib/store';
|
import { useStore } from '$lib/store';
|
||||||
|
|
||||||
|
let { children }: { children?: Snippet } = $props();
|
||||||
|
|
||||||
const { domNode } = useStore();
|
const { domNode } = useStore();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div use:portal={{ target: '.svelte-flow__viewport-portal', domNode: $domNode }}>
|
<div use:portal={{ target: '.svelte-flow__viewport-portal', domNode: $domNode }}>
|
||||||
<slot />
|
{@render children?.()}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,36 +2,37 @@
|
|||||||
import { getBezierPath } from '@xyflow/system';
|
import { getBezierPath } from '@xyflow/system';
|
||||||
|
|
||||||
import type { BezierEdgeProps } from '$lib/types';
|
import type { BezierEdgeProps } from '$lib/types';
|
||||||
|
|
||||||
import { BaseEdge } from '$lib/components/BaseEdge';
|
import { BaseEdge } from '$lib/components/BaseEdge';
|
||||||
|
|
||||||
type $$Props = BezierEdgeProps;
|
let {
|
||||||
|
id,
|
||||||
export let id: $$Props['id'] = undefined;
|
label,
|
||||||
export let label: $$Props['label'] = undefined;
|
labelStyle,
|
||||||
export let labelStyle: $$Props['labelStyle'] = undefined;
|
style,
|
||||||
export let style: $$Props['style'] = undefined;
|
markerStart,
|
||||||
export let markerStart: $$Props['markerStart'] = undefined;
|
markerEnd,
|
||||||
export let markerEnd: $$Props['markerEnd'] = undefined;
|
pathOptions,
|
||||||
export let pathOptions: $$Props['pathOptions'] = undefined;
|
interactionWidth,
|
||||||
export let interactionWidth: $$Props['interactionWidth'] = undefined;
|
|
||||||
|
|
||||||
export let sourceX: $$Props['sourceX'];
|
|
||||||
export let sourceY: $$Props['sourceY'];
|
|
||||||
export let sourcePosition: $$Props['sourcePosition'];
|
|
||||||
|
|
||||||
export let targetX: $$Props['targetX'];
|
|
||||||
export let targetY: $$Props['targetY'];
|
|
||||||
export let targetPosition: $$Props['targetPosition'];
|
|
||||||
|
|
||||||
$: [path, labelX, labelY] = getBezierPath({
|
|
||||||
sourceX,
|
sourceX,
|
||||||
sourceY,
|
sourceY,
|
||||||
|
sourcePosition,
|
||||||
targetX,
|
targetX,
|
||||||
targetY,
|
targetY,
|
||||||
sourcePosition,
|
targetPosition
|
||||||
targetPosition,
|
}: BezierEdgeProps = $props();
|
||||||
curvature: pathOptions?.curvature
|
|
||||||
});
|
let [path, labelX, labelY] = $derived(
|
||||||
|
getBezierPath({
|
||||||
|
sourceX,
|
||||||
|
sourceY,
|
||||||
|
targetX,
|
||||||
|
targetY,
|
||||||
|
sourcePosition,
|
||||||
|
targetPosition,
|
||||||
|
curvature: pathOptions?.curvature
|
||||||
|
})
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<BaseEdge
|
<BaseEdge
|
||||||
|
|||||||
@@ -3,35 +3,31 @@
|
|||||||
|
|
||||||
import type { EdgeProps } from '$lib/types';
|
import type { EdgeProps } from '$lib/types';
|
||||||
import { BaseEdge } from '$lib/components/BaseEdge';
|
import { BaseEdge } from '$lib/components/BaseEdge';
|
||||||
|
let {
|
||||||
type $$Props = EdgeProps;
|
|
||||||
|
|
||||||
export let label: $$Props['label'] = undefined;
|
|
||||||
export let labelStyle: $$Props['labelStyle'] = undefined;
|
|
||||||
export let style: $$Props['style'] = undefined;
|
|
||||||
export let markerStart: $$Props['markerStart'] = undefined;
|
|
||||||
export let markerEnd: $$Props['markerEnd'] = undefined;
|
|
||||||
export let interactionWidth: $$Props['interactionWidth'] = undefined;
|
|
||||||
|
|
||||||
export let sourceX: $$Props['sourceX'];
|
|
||||||
export let sourceY: $$Props['sourceY'];
|
|
||||||
export let sourcePosition: $$Props['sourcePosition'];
|
|
||||||
|
|
||||||
export let targetX: $$Props['targetX'];
|
|
||||||
export let targetY: $$Props['targetY'];
|
|
||||||
export let targetPosition: $$Props['targetPosition'];
|
|
||||||
|
|
||||||
$: [path, labelX, labelY] = getBezierPath({
|
|
||||||
sourceX,
|
sourceX,
|
||||||
sourceY,
|
sourceY,
|
||||||
|
sourcePosition,
|
||||||
targetX,
|
targetX,
|
||||||
targetY,
|
targetY,
|
||||||
sourcePosition,
|
targetPosition,
|
||||||
targetPosition
|
label,
|
||||||
});
|
labelStyle,
|
||||||
|
markerStart,
|
||||||
|
markerEnd,
|
||||||
|
interactionWidth,
|
||||||
|
style
|
||||||
|
}: EdgeProps = $props();
|
||||||
|
|
||||||
// this is a workaround for suppressing the warning about unused props
|
let [path, labelX, labelY] = $derived(
|
||||||
$$restProps;
|
getBezierPath({
|
||||||
|
sourceX,
|
||||||
|
sourceY,
|
||||||
|
targetX,
|
||||||
|
targetY,
|
||||||
|
sourcePosition,
|
||||||
|
targetPosition
|
||||||
|
})
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<BaseEdge
|
<BaseEdge
|
||||||
|
|||||||
@@ -4,35 +4,35 @@
|
|||||||
import type { SmoothStepEdgeProps } from '$lib/types';
|
import type { SmoothStepEdgeProps } from '$lib/types';
|
||||||
import { BaseEdge } from '$lib/components/BaseEdge';
|
import { BaseEdge } from '$lib/components/BaseEdge';
|
||||||
|
|
||||||
type $$Props = SmoothStepEdgeProps;
|
let {
|
||||||
|
id,
|
||||||
export let id: $$Props['id'] = undefined;
|
label,
|
||||||
export let label: $$Props['label'] = undefined;
|
labelStyle,
|
||||||
export let labelStyle: $$Props['labelStyle'] = undefined;
|
style,
|
||||||
export let style: $$Props['style'] = undefined;
|
markerStart,
|
||||||
export let markerStart: $$Props['markerStart'] = undefined;
|
markerEnd,
|
||||||
export let markerEnd: $$Props['markerEnd'] = undefined;
|
pathOptions,
|
||||||
export let pathOptions: $$Props['pathOptions'] = undefined;
|
interactionWidth,
|
||||||
export let interactionWidth: $$Props['interactionWidth'] = undefined;
|
|
||||||
|
|
||||||
export let sourceX: $$Props['sourceX'];
|
|
||||||
export let sourceY: $$Props['sourceY'];
|
|
||||||
export let sourcePosition: $$Props['sourcePosition'];
|
|
||||||
|
|
||||||
export let targetX: $$Props['targetX'];
|
|
||||||
export let targetY: $$Props['targetY'];
|
|
||||||
export let targetPosition: $$Props['targetPosition'];
|
|
||||||
|
|
||||||
$: [path, labelX, labelY] = getSmoothStepPath({
|
|
||||||
sourceX,
|
sourceX,
|
||||||
sourceY,
|
sourceY,
|
||||||
|
sourcePosition,
|
||||||
targetX,
|
targetX,
|
||||||
targetY,
|
targetY,
|
||||||
sourcePosition,
|
targetPosition
|
||||||
targetPosition,
|
}: SmoothStepEdgeProps = $props();
|
||||||
borderRadius: pathOptions?.borderRadius,
|
|
||||||
offset: pathOptions?.offset
|
let [path, labelX, labelY] = $derived(
|
||||||
});
|
getSmoothStepPath({
|
||||||
|
sourceX,
|
||||||
|
sourceY,
|
||||||
|
targetX,
|
||||||
|
targetY,
|
||||||
|
sourcePosition,
|
||||||
|
targetPosition,
|
||||||
|
borderRadius: pathOptions?.borderRadius,
|
||||||
|
offset: pathOptions?.offset
|
||||||
|
})
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<BaseEdge
|
<BaseEdge
|
||||||
|
|||||||
@@ -4,34 +4,31 @@
|
|||||||
import type { EdgeProps } from '$lib/types';
|
import type { EdgeProps } from '$lib/types';
|
||||||
import { BaseEdge } from '$lib/components/BaseEdge';
|
import { BaseEdge } from '$lib/components/BaseEdge';
|
||||||
|
|
||||||
type $$Props = EdgeProps;
|
let {
|
||||||
|
|
||||||
export let label: $$Props['label'] = undefined;
|
|
||||||
export let labelStyle: $$Props['labelStyle'] = undefined;
|
|
||||||
export let style: $$Props['style'] = undefined;
|
|
||||||
export let markerStart: $$Props['markerStart'] = undefined;
|
|
||||||
export let markerEnd: $$Props['markerEnd'] = undefined;
|
|
||||||
export let interactionWidth: $$Props['interactionWidth'] = undefined;
|
|
||||||
|
|
||||||
export let sourceX: $$Props['sourceX'];
|
|
||||||
export let sourceY: $$Props['sourceY'];
|
|
||||||
export let sourcePosition: $$Props['sourcePosition'];
|
|
||||||
|
|
||||||
export let targetX: $$Props['targetX'];
|
|
||||||
export let targetY: $$Props['targetY'];
|
|
||||||
export let targetPosition: $$Props['targetPosition'];
|
|
||||||
|
|
||||||
$: [path, labelX, labelY] = getSmoothStepPath({
|
|
||||||
sourceX,
|
sourceX,
|
||||||
sourceY,
|
sourceY,
|
||||||
|
sourcePosition,
|
||||||
targetX,
|
targetX,
|
||||||
targetY,
|
targetY,
|
||||||
sourcePosition,
|
targetPosition,
|
||||||
targetPosition
|
label,
|
||||||
});
|
labelStyle,
|
||||||
|
markerStart,
|
||||||
|
markerEnd,
|
||||||
|
interactionWidth,
|
||||||
|
style
|
||||||
|
}: EdgeProps = $props();
|
||||||
|
|
||||||
// this is a workaround for suppressing the warning about unused props
|
let [path, labelX, labelY] = $derived(
|
||||||
$$restProps;
|
getSmoothStepPath({
|
||||||
|
sourceX,
|
||||||
|
sourceY,
|
||||||
|
targetX,
|
||||||
|
targetY,
|
||||||
|
sourcePosition,
|
||||||
|
targetPosition
|
||||||
|
})
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<BaseEdge
|
<BaseEdge
|
||||||
|
|||||||
@@ -4,35 +4,35 @@
|
|||||||
import type { StepEdgeProps } from '$lib/types';
|
import type { StepEdgeProps } from '$lib/types';
|
||||||
import { BaseEdge } from '$lib/components/BaseEdge';
|
import { BaseEdge } from '$lib/components/BaseEdge';
|
||||||
|
|
||||||
type $$Props = StepEdgeProps;
|
let {
|
||||||
|
id,
|
||||||
export let id: $$Props['id'] = undefined;
|
label,
|
||||||
export let label: $$Props['label'] = undefined;
|
labelStyle,
|
||||||
export let labelStyle: $$Props['labelStyle'] = undefined;
|
style,
|
||||||
export let style: $$Props['style'] = undefined;
|
markerStart,
|
||||||
export let markerStart: $$Props['markerStart'] = undefined;
|
markerEnd,
|
||||||
export let markerEnd: $$Props['markerEnd'] = undefined;
|
pathOptions,
|
||||||
export let pathOptions: $$Props['pathOptions'] = undefined;
|
interactionWidth,
|
||||||
export let interactionWidth: $$Props['interactionWidth'] = undefined;
|
|
||||||
|
|
||||||
export let sourceX: $$Props['sourceX'];
|
|
||||||
export let sourceY: $$Props['sourceY'];
|
|
||||||
export let sourcePosition: $$Props['sourcePosition'];
|
|
||||||
|
|
||||||
export let targetX: $$Props['targetX'];
|
|
||||||
export let targetY: $$Props['targetY'];
|
|
||||||
export let targetPosition: $$Props['targetPosition'];
|
|
||||||
|
|
||||||
$: [path, labelX, labelY] = getSmoothStepPath({
|
|
||||||
sourceX,
|
sourceX,
|
||||||
sourceY,
|
sourceY,
|
||||||
|
sourcePosition,
|
||||||
targetX,
|
targetX,
|
||||||
targetY,
|
targetY,
|
||||||
sourcePosition,
|
targetPosition
|
||||||
targetPosition,
|
}: StepEdgeProps = $props();
|
||||||
borderRadius: 0,
|
|
||||||
offset: pathOptions?.offset
|
let [path, labelX, labelY] = $derived(
|
||||||
});
|
getSmoothStepPath({
|
||||||
|
sourceX,
|
||||||
|
sourceY,
|
||||||
|
targetX,
|
||||||
|
targetY,
|
||||||
|
sourcePosition,
|
||||||
|
targetPosition,
|
||||||
|
borderRadius: 0,
|
||||||
|
offset: pathOptions?.offset
|
||||||
|
})
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<BaseEdge
|
<BaseEdge
|
||||||
|
|||||||
@@ -4,35 +4,32 @@
|
|||||||
import type { EdgeProps } from '$lib/types';
|
import type { EdgeProps } from '$lib/types';
|
||||||
import { BaseEdge } from '$lib/components/BaseEdge';
|
import { BaseEdge } from '$lib/components/BaseEdge';
|
||||||
|
|
||||||
type $$Props = EdgeProps;
|
let {
|
||||||
|
|
||||||
export let label: $$Props['label'] = undefined;
|
|
||||||
export let labelStyle: $$Props['labelStyle'] = undefined;
|
|
||||||
export let style: $$Props['style'] = undefined;
|
|
||||||
export let markerStart: $$Props['markerStart'] = undefined;
|
|
||||||
export let markerEnd: $$Props['markerEnd'] = undefined;
|
|
||||||
export let interactionWidth: $$Props['interactionWidth'] = undefined;
|
|
||||||
|
|
||||||
export let sourceX: $$Props['sourceX'];
|
|
||||||
export let sourceY: $$Props['sourceY'];
|
|
||||||
export let sourcePosition: $$Props['sourcePosition'];
|
|
||||||
|
|
||||||
export let targetX: $$Props['targetX'];
|
|
||||||
export let targetY: $$Props['targetY'];
|
|
||||||
export let targetPosition: $$Props['targetPosition'];
|
|
||||||
|
|
||||||
$: [path, labelX, labelY] = getSmoothStepPath({
|
|
||||||
sourceX,
|
sourceX,
|
||||||
sourceY,
|
sourceY,
|
||||||
|
sourcePosition,
|
||||||
targetX,
|
targetX,
|
||||||
targetY,
|
targetY,
|
||||||
sourcePosition,
|
|
||||||
targetPosition,
|
targetPosition,
|
||||||
borderRadius: 0
|
label,
|
||||||
});
|
labelStyle,
|
||||||
|
markerStart,
|
||||||
|
markerEnd,
|
||||||
|
interactionWidth,
|
||||||
|
style
|
||||||
|
}: EdgeProps = $props();
|
||||||
|
|
||||||
// this is a workaround for suppressing the warning about unused props
|
let [path, labelX, labelY] = $derived(
|
||||||
$$restProps;
|
getSmoothStepPath({
|
||||||
|
sourceX,
|
||||||
|
sourceY,
|
||||||
|
targetX,
|
||||||
|
targetY,
|
||||||
|
sourcePosition,
|
||||||
|
targetPosition,
|
||||||
|
borderRadius: 0
|
||||||
|
})
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<BaseEdge
|
<BaseEdge
|
||||||
|
|||||||
@@ -4,28 +4,28 @@
|
|||||||
import type { StraightEdgeProps } from '$lib/types';
|
import type { StraightEdgeProps } from '$lib/types';
|
||||||
import { BaseEdge } from '$lib/components/BaseEdge';
|
import { BaseEdge } from '$lib/components/BaseEdge';
|
||||||
|
|
||||||
type $$Props = StraightEdgeProps;
|
let {
|
||||||
|
id,
|
||||||
export let id: $$Props['id'] = undefined;
|
label,
|
||||||
export let label: $$Props['label'] = undefined;
|
labelStyle,
|
||||||
export let labelStyle: $$Props['labelStyle'] = undefined;
|
style,
|
||||||
export let style: $$Props['style'] = undefined;
|
markerStart,
|
||||||
export let markerStart: $$Props['markerStart'] = undefined;
|
markerEnd,
|
||||||
export let markerEnd: $$Props['markerEnd'] = undefined;
|
interactionWidth,
|
||||||
export let interactionWidth: $$Props['interactionWidth'] = undefined;
|
|
||||||
|
|
||||||
export let sourceX: $$Props['sourceX'];
|
|
||||||
export let sourceY: $$Props['sourceY'];
|
|
||||||
|
|
||||||
export let targetX: $$Props['targetX'];
|
|
||||||
export let targetY: $$Props['targetY'];
|
|
||||||
|
|
||||||
$: [path, labelX, labelY] = getStraightPath({
|
|
||||||
sourceX,
|
sourceX,
|
||||||
sourceY,
|
sourceY,
|
||||||
targetX,
|
targetX,
|
||||||
targetY
|
targetY
|
||||||
});
|
}: StraightEdgeProps = $props();
|
||||||
|
|
||||||
|
let [path, labelX, labelY] = $derived(
|
||||||
|
getStraightPath({
|
||||||
|
sourceX,
|
||||||
|
sourceY,
|
||||||
|
targetX,
|
||||||
|
targetY
|
||||||
|
})
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<BaseEdge
|
<BaseEdge
|
||||||
|
|||||||
@@ -4,30 +4,27 @@
|
|||||||
import type { EdgeProps } from '$lib/types';
|
import type { EdgeProps } from '$lib/types';
|
||||||
import { BaseEdge } from '$lib/components/BaseEdge';
|
import { BaseEdge } from '$lib/components/BaseEdge';
|
||||||
|
|
||||||
type $$Props = EdgeProps;
|
let {
|
||||||
|
|
||||||
export let label: $$Props['label'] = undefined;
|
|
||||||
export let labelStyle: $$Props['labelStyle'] = undefined;
|
|
||||||
export let style: $$Props['style'] = undefined;
|
|
||||||
export let markerStart: $$Props['markerStart'] = undefined;
|
|
||||||
export let markerEnd: $$Props['markerEnd'] = undefined;
|
|
||||||
export let interactionWidth: $$Props['interactionWidth'] = undefined;
|
|
||||||
|
|
||||||
export let sourceX: $$Props['sourceX'];
|
|
||||||
export let sourceY: $$Props['sourceY'];
|
|
||||||
|
|
||||||
export let targetX: $$Props['targetX'];
|
|
||||||
export let targetY: $$Props['targetY'];
|
|
||||||
|
|
||||||
$: [path, labelX, labelY] = getStraightPath({
|
|
||||||
sourceX,
|
sourceX,
|
||||||
sourceY,
|
sourceY,
|
||||||
targetX,
|
targetX,
|
||||||
targetY
|
targetY,
|
||||||
});
|
label,
|
||||||
|
labelStyle,
|
||||||
|
markerStart,
|
||||||
|
markerEnd,
|
||||||
|
interactionWidth,
|
||||||
|
style
|
||||||
|
}: EdgeProps = $props();
|
||||||
|
|
||||||
// this is a workaround for suppressing the warning about unused props
|
let [path, labelX, labelY] = $derived(
|
||||||
$$restProps;
|
getStraightPath({
|
||||||
|
sourceX,
|
||||||
|
sourceY,
|
||||||
|
targetX,
|
||||||
|
targetY
|
||||||
|
})
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<BaseEdge
|
<BaseEdge
|
||||||
|
|||||||
@@ -4,16 +4,14 @@
|
|||||||
import { Handle } from '$lib/components/Handle';
|
import { Handle } from '$lib/components/Handle';
|
||||||
import type { NodeProps } from '$lib/types';
|
import type { NodeProps } from '$lib/types';
|
||||||
|
|
||||||
interface $$Props extends NodeProps {}
|
let {
|
||||||
|
// TODO: do we really want this!?
|
||||||
export let data: $$Props['data'] = { label: 'Node' };
|
data = { label: 'Node' },
|
||||||
export let targetPosition: $$Props['targetPosition'] = undefined;
|
targetPosition = Position.Top,
|
||||||
export let sourcePosition: $$Props['sourcePosition'] = undefined;
|
sourcePosition = Position.Bottom
|
||||||
|
}: NodeProps = $props();
|
||||||
// this is a workaround for suppressing the warning about unused props
|
|
||||||
$$restProps;
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Handle type="target" position={targetPosition ?? Position.Top} />
|
<Handle type="target" position={targetPosition} />
|
||||||
{data?.label}
|
{data?.label}
|
||||||
<Handle type="source" position={sourcePosition ?? Position.Bottom} />
|
<Handle type="source" position={sourcePosition} />
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { NodeProps } from '$lib/types';
|
import type { NodeProps } from '$lib/types';
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
let {}: NodeProps = $props();
|
||||||
interface $$Props extends NodeProps {}
|
|
||||||
|
|
||||||
// this is a workaround for suppressing the warning about unused props
|
|
||||||
$$restProps;
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -4,14 +4,8 @@
|
|||||||
|
|
||||||
import { Handle } from '$lib/components/Handle';
|
import { Handle } from '$lib/components/Handle';
|
||||||
|
|
||||||
interface $$Props extends NodeProps {}
|
let { data = { label: 'Node' }, sourcePosition = Position.Bottom }: NodeProps = $props();
|
||||||
|
|
||||||
export let data: $$Props['data'] = { label: 'Node' };
|
|
||||||
export let sourcePosition: $$Props['sourcePosition'] = undefined;
|
|
||||||
|
|
||||||
// this is a workaround for suppressing the warning about unused props
|
|
||||||
$$restProps;
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{data?.label}
|
{data?.label}
|
||||||
<Handle type="source" position={sourcePosition ?? Position.Bottom} />
|
<Handle type="source" position={sourcePosition} />
|
||||||
|
|||||||
@@ -4,14 +4,8 @@
|
|||||||
|
|
||||||
import { Handle } from '$lib/components/Handle';
|
import { Handle } from '$lib/components/Handle';
|
||||||
|
|
||||||
interface $$Props extends NodeProps {}
|
let { data = { label: 'Node' }, targetPosition = Position.Top }: NodeProps = $props();
|
||||||
|
|
||||||
export let data: $$Props['data'] = { label: 'Node' };
|
|
||||||
export let targetPosition: $$Props['targetPosition'] = undefined;
|
|
||||||
|
|
||||||
// this is a workaround for suppressing the warning about unused props
|
|
||||||
$$restProps;
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{data?.label}
|
{data?.label}
|
||||||
<Handle type="target" position={targetPosition ?? Position.Top} />
|
<Handle type="target" position={targetPosition} />
|
||||||
|
|||||||
@@ -3,24 +3,24 @@
|
|||||||
import type { PanelProps } from './types';
|
import type { PanelProps } from './types';
|
||||||
import { useStore } from '$lib/store';
|
import { useStore } from '$lib/store';
|
||||||
|
|
||||||
type $$Props = PanelProps;
|
let {
|
||||||
|
position = 'top-right',
|
||||||
export let position: $$Props['position'] = 'top-right';
|
style,
|
||||||
export let style: $$Props['style'] = undefined;
|
class: className,
|
||||||
|
children,
|
||||||
let className: $$Props['class'] = undefined;
|
...restProps
|
||||||
export { className as class };
|
}: PanelProps = $props();
|
||||||
|
|
||||||
const { selectionRectMode } = useStore();
|
const { selectionRectMode } = useStore();
|
||||||
|
|
||||||
$: positionClasses = `${position}`.split('-');
|
let positionClasses = $derived(`${position}`.split('-'));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class={cc(['svelte-flow__panel', className, ...positionClasses])}
|
class={cc(['svelte-flow__panel', className, ...positionClasses])}
|
||||||
{style}
|
{style}
|
||||||
style:pointer-events={$selectionRectMode ? 'none' : ''}
|
style:pointer-events={$selectionRectMode ? 'none' : ''}
|
||||||
{...$$restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
<slot />
|
{@render children?.()}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -79,8 +79,8 @@
|
|||||||
onbeforedelete,
|
onbeforedelete,
|
||||||
oninit,
|
oninit,
|
||||||
nodeOrigin,
|
nodeOrigin,
|
||||||
paneClickDistance = 0,
|
paneClickDistance = 1,
|
||||||
nodeClickDistance = 0,
|
nodeClickDistance = 1,
|
||||||
defaultMarkerColor = '#b1b1b7',
|
defaultMarkerColor = '#b1b1b7',
|
||||||
style,
|
style,
|
||||||
class: className,
|
class: className,
|
||||||
@@ -109,6 +109,8 @@
|
|||||||
|
|
||||||
const initViewport = $viewport || initialViewport;
|
const initViewport = $viewport || initialViewport;
|
||||||
|
|
||||||
|
//TODO SVELTE5
|
||||||
|
|
||||||
const store = hasContext(key)
|
const store = hasContext(key)
|
||||||
? useStore()
|
? useStore()
|
||||||
: createStoreContext({
|
: createStoreContext({
|
||||||
@@ -262,15 +264,11 @@
|
|||||||
{onedgemouseleave}
|
{onedgemouseleave}
|
||||||
{defaultEdgeOptions}
|
{defaultEdgeOptions}
|
||||||
/>
|
/>
|
||||||
<!-- <ConnectionLine
|
<ConnectionLine
|
||||||
containerStyle={connectionLineContainerStyle}
|
containerStyle={connectionLineContainerStyle}
|
||||||
style={connectionLineStyle}
|
style={connectionLineStyle}
|
||||||
isCustomComponent={connectionLine}
|
{connectionLine}
|
||||||
>
|
/>
|
||||||
{#snippet connectionLine()}
|
|
||||||
{@render connectionLine_render?.()}
|
|
||||||
{/snippet}
|
|
||||||
</ConnectionLine> -->
|
|
||||||
<div class="svelte-flow__edgelabel-renderer"></div>
|
<div class="svelte-flow__edgelabel-renderer"></div>
|
||||||
<div class="svelte-flow__viewport-portal"></div>
|
<div class="svelte-flow__viewport-portal"></div>
|
||||||
<NodeRenderer
|
<NodeRenderer
|
||||||
|
|||||||
@@ -271,36 +271,36 @@ export function createStore({
|
|||||||
if (resetEdges) store.edges.set(get(store.edges));
|
if (resetEdges) store.edges.set(get(store.edges));
|
||||||
}
|
}
|
||||||
|
|
||||||
store.deleteKeyPressed.subscribe(async (deleteKeyPressed) => {
|
// store.deleteKeyPressed.subscribe(async (deleteKeyPressed) => {
|
||||||
if (deleteKeyPressed) {
|
// if (deleteKeyPressed) {
|
||||||
const nodes = get(store.nodes);
|
// const nodes = get(store.nodes);
|
||||||
const edges = get(store.edges);
|
// const edges = get(store.edges);
|
||||||
const selectedNodes = nodes.filter((node) => node.selected);
|
// const selectedNodes = nodes.filter((node) => node.selected);
|
||||||
const selectedEdges = edges.filter((edge) => edge.selected);
|
// const selectedEdges = edges.filter((edge) => edge.selected);
|
||||||
|
|
||||||
const { nodes: matchingNodes, edges: matchingEdges } = await getElementsToRemove({
|
// const { nodes: matchingNodes, edges: matchingEdges } = await getElementsToRemove({
|
||||||
nodesToRemove: selectedNodes,
|
// nodesToRemove: selectedNodes,
|
||||||
edgesToRemove: selectedEdges,
|
// edgesToRemove: selectedEdges,
|
||||||
nodes,
|
// nodes,
|
||||||
edges,
|
// edges,
|
||||||
onBeforeDelete: get(store.onbeforedelete)
|
// onBeforeDelete: get(store.onbeforedelete)
|
||||||
});
|
// });
|
||||||
|
|
||||||
if (matchingNodes.length || matchingEdges.length) {
|
// if (matchingNodes.length || matchingEdges.length) {
|
||||||
store.nodes.update((nds) =>
|
// store.nodes.update((nds) =>
|
||||||
nds.filter((node) => !matchingNodes.some((mN) => mN.id === node.id))
|
// nds.filter((node) => !matchingNodes.some((mN) => mN.id === node.id))
|
||||||
);
|
// );
|
||||||
store.edges.update((eds) =>
|
// store.edges.update((eds) =>
|
||||||
eds.filter((edge) => !matchingEdges.some((mE) => mE.id === edge.id))
|
// eds.filter((edge) => !matchingEdges.some((mE) => mE.id === edge.id))
|
||||||
);
|
// );
|
||||||
|
|
||||||
get(store.ondelete)?.({
|
// get(store.ondelete)?.({
|
||||||
nodes: matchingNodes,
|
// nodes: matchingNodes,
|
||||||
edges: matchingEdges
|
// edges: matchingEdges
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
|
|
||||||
function addSelectedNodes(ids: string[]) {
|
function addSelectedNodes(ids: string[]) {
|
||||||
const isMultiSelection = get(store.multiselectionKeyPressed);
|
const isMultiSelection = get(store.multiselectionKeyPressed);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
export * from './nodes';
|
export * from './nodes';
|
||||||
export * from './edges';
|
export * from './edges';
|
||||||
export * from './general';
|
export * from './general';
|
||||||
|
export * from './events';
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ export type DefaultNodeOptions = Partial<Omit<Node, 'id'>>;
|
|||||||
|
|
||||||
export type BuiltInNode = Node<{ label: string }, 'input' | 'output' | 'default'>;
|
export type BuiltInNode = Node<{ label: string }, 'input' | 'output' | 'default'>;
|
||||||
|
|
||||||
|
// TODO SVELTE5 remove this
|
||||||
export type NodeEventMap = {
|
export type NodeEventMap = {
|
||||||
nodeclick: { node: Node; event: MouseEvent | TouchEvent };
|
nodeclick: { node: Node; event: MouseEvent | TouchEvent };
|
||||||
nodecontextmenu: { node: Node; event: MouseEvent | TouchEvent };
|
nodecontextmenu: { node: Node; event: MouseEvent | TouchEvent };
|
||||||
|
|||||||
Reference in New Issue
Block a user