feat(svelte): edge types, use edge-utils
This commit is contained in:
@@ -1,26 +1,44 @@
|
||||
<script lang="ts">
|
||||
export let id: string = '1';
|
||||
import type { SvelteComponentTyped } from 'svelte';
|
||||
import { Position } from '@reactflow/system';
|
||||
|
||||
import { useStore } from '$lib/store';
|
||||
import BezierEdge from '$lib/components/edges/StraightEdge.svelte';
|
||||
import type { EdgeProps } from '$lib/types';
|
||||
|
||||
export let id: string;
|
||||
export let type: string = 'default';
|
||||
export let sourceX: number = 0;
|
||||
export let sourceY: number = 0;
|
||||
export let targetX: number = 0;
|
||||
export let targetY: number = 0;
|
||||
export let sourcePosition: Position = Position.Bottom;
|
||||
export let targetPosition: Position = Position.Top;
|
||||
|
||||
const { edgeTypesStore } = useStore();
|
||||
const edgeComponent: typeof SvelteComponentTyped<EdgeProps> = $edgeTypesStore[type] || BezierEdge;
|
||||
</script>
|
||||
|
||||
<g
|
||||
class="react-flow__edge"
|
||||
data-id={id}
|
||||
>
|
||||
<path
|
||||
d={`M ${sourceX},${sourceY}L ${targetX},${targetY}`}
|
||||
fill="none"
|
||||
class="react-flow__edge-path"
|
||||
<svelte:component
|
||||
this={edgeComponent}
|
||||
{id}
|
||||
{sourceX}
|
||||
{sourceY}
|
||||
{targetX}
|
||||
{targetY}
|
||||
{sourcePosition}
|
||||
{targetPosition}
|
||||
/>
|
||||
</g>
|
||||
|
||||
<style>
|
||||
.react-flow__edge-path {
|
||||
.react-flow__edge :global(path) {
|
||||
stroke: #ccc;
|
||||
stroke-width: 1;
|
||||
fill: none;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,21 @@
|
||||
<script lang="ts">
|
||||
import { getBezierPath } from '@reactflow/edge-utils';
|
||||
import type { EdgeProps } from '$lib/types';
|
||||
|
||||
interface $$Props extends EdgeProps {}
|
||||
|
||||
export let id: $$Props['id'];
|
||||
export let sourceX: $$Props['sourceX'] = 0;
|
||||
export let sourceY: $$Props['sourceY'] = 0;
|
||||
export let targetX: $$Props['targetX'] = 0;
|
||||
export let targetY: $$Props['targetY'] = 0;
|
||||
export let sourcePosition: $$Props['sourcePosition'] = undefined;
|
||||
export let targetPosition: $$Props['targetPosition'] = undefined;
|
||||
|
||||
$: [path] = getBezierPath({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition });
|
||||
</script>
|
||||
|
||||
<path
|
||||
d={path}
|
||||
class="react-flow__edge-path"
|
||||
/>
|
||||
@@ -0,0 +1,21 @@
|
||||
<script lang="ts">
|
||||
import { getSmoothStepPath } from '@reactflow/edge-utils';
|
||||
import type { EdgeProps } from '$lib/types';
|
||||
|
||||
interface $$Props extends EdgeProps {}
|
||||
|
||||
export let id: $$Props['id'];
|
||||
export let sourceX: $$Props['sourceX'] = 0;
|
||||
export let sourceY: $$Props['sourceY'] = 0;
|
||||
export let targetX: $$Props['targetX'] = 0;
|
||||
export let targetY: $$Props['targetY'] = 0;
|
||||
export let sourcePosition: $$Props['sourcePosition'] = undefined;
|
||||
export let targetPosition: $$Props['targetPosition'] = undefined;
|
||||
|
||||
$: [path] = getSmoothStepPath({ sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition });
|
||||
</script>
|
||||
|
||||
<path
|
||||
d={path}
|
||||
class="react-flow__edge-path"
|
||||
/>
|
||||
@@ -0,0 +1,19 @@
|
||||
<script lang="ts">
|
||||
import { getStraightPath } from '@reactflow/edge-utils';
|
||||
import type { EdgeProps } from '$lib/types';
|
||||
|
||||
interface $$Props extends EdgeProps {}
|
||||
|
||||
export let id: $$Props['id'];
|
||||
export let sourceX: $$Props['sourceX'] = 0;
|
||||
export let sourceY: $$Props['sourceY'] = 0;
|
||||
export let targetX: $$Props['targetX'] = 0;
|
||||
export let targetY: $$Props['targetY'] = 0;
|
||||
|
||||
$: [path] = getStraightPath({ sourceX, sourceY, targetX, targetY });
|
||||
</script>
|
||||
|
||||
<path
|
||||
d={path}
|
||||
class="react-flow__edge-path"
|
||||
/>
|
||||
@@ -1,14 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { useStore } from '$lib/store';
|
||||
import { SelectionMode, type Node, type Edge } from '@reactflow/system';
|
||||
import { getConnectedEdges, getEventPosition, getNodesInside } from '@reactflow/utils';
|
||||
|
||||
const { nodesStore, edgesStore, transformStore, nodeOriginStore, draggingStore, selectionRectStore, selectionRectModeStore, selectionKeyPressedStore, resetSelectedElements } = useStore();
|
||||
|
||||
const wrapHandler = (
|
||||
<script lang="ts" context="module">
|
||||
export function wrapHandler(
|
||||
handler: (evt: MouseEvent) => void,
|
||||
container: HTMLDivElement
|
||||
): (evt: MouseEvent) => void => {
|
||||
): (evt: MouseEvent) => void {
|
||||
return (event: MouseEvent) => {
|
||||
if (event.target !== container) {
|
||||
return;
|
||||
@@ -18,6 +12,29 @@
|
||||
};
|
||||
};
|
||||
|
||||
export function toggleSelected<Item extends Node | Edge>(ids: string[]) {
|
||||
return (item: Item) => {
|
||||
const isSelected = ids.includes(item.id);
|
||||
|
||||
if (item.selected !== isSelected) {
|
||||
return {
|
||||
...item,
|
||||
selected: isSelected,
|
||||
};
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { useStore } from '$lib/store';
|
||||
import { SelectionMode, type Node, type Edge } from '@reactflow/system';
|
||||
import { getConnectedEdges, getEventPosition, getNodesInside } from '@reactflow/utils';
|
||||
|
||||
const { nodesStore, edgesStore, transformStore, nodeOriginStore, draggingStore, selectionRectStore, selectionRectModeStore, selectionKeyPressedStore, resetSelectedElements } = useStore();
|
||||
|
||||
// @todo take from props
|
||||
const elementsSelectable = true;
|
||||
const selectionMode = SelectionMode.Partial
|
||||
@@ -67,20 +84,7 @@
|
||||
// onSelectionStart?.(event);
|
||||
};
|
||||
|
||||
function toggleSelected<Item extends Node | Edge>(ids: string[]) {
|
||||
return (item: Item) => {
|
||||
const isSelected = ids.includes(item.id);
|
||||
|
||||
if (item.selected !== isSelected) {
|
||||
return {
|
||||
...item,
|
||||
selected: isSelected,
|
||||
};
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseMove(event: MouseEvent) {
|
||||
if (!isSelecting || !containerBounds || !$selectionRectStore) {
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
export let position: PanelPosition = 'top-right';
|
||||
export let style: string = '';
|
||||
export { className as class }
|
||||
|
||||
let className: string;
|
||||
export { className as class }
|
||||
|
||||
$: positionClasses = `${position}`.split('-');
|
||||
</script>
|
||||
|
||||
@@ -27,7 +27,10 @@ import { SelectionMode } from 'reactflow';
|
||||
import DefaultNode from '$lib/components/nodes/DefaultNode.svelte';
|
||||
import InputNode from '$lib/components/nodes/InputNode.svelte';
|
||||
import OutputNode from '$lib/components/nodes/OutputNode.svelte';
|
||||
import type { NodeTypes } from '$lib/types';
|
||||
import type { EdgeTypes, NodeTypes } from '$lib/types';
|
||||
import BezierEdge from '$lib/components/edges/BezierEdge.svelte';
|
||||
import StraightEdge from '$lib/components/edges/StraightEdge.svelte';
|
||||
import SmoothStepEdge from '$lib/components/edges/SmoothStepEdge.svelte';
|
||||
|
||||
export const key = Symbol();
|
||||
|
||||
@@ -38,6 +41,7 @@ type CreateStoreProps = {
|
||||
nodeOrigin?: NodeOrigin;
|
||||
transform?: Transform;
|
||||
nodeTypes?: NodeTypes;
|
||||
edgeTypes?: EdgeTypes;
|
||||
id?: string;
|
||||
};
|
||||
|
||||
@@ -65,6 +69,7 @@ type SvelteFlowStore = {
|
||||
selectionMode: Writable<SelectionMode>;
|
||||
selectionKeyPressedStore: Writable<boolean>;
|
||||
nodeTypesStore: Writable<NodeTypes>;
|
||||
edgeTypesStore: Writable<EdgeTypes>;
|
||||
zoomIn: (options?: ViewportHelperFunctionOptions) => void;
|
||||
zoomOut: (options?: ViewportHelperFunctionOptions) => void;
|
||||
fitView: (options?: ViewportHelperFunctionOptions) => boolean;
|
||||
@@ -84,6 +89,7 @@ export function createStore({
|
||||
nodeOrigin = [0, 0],
|
||||
fitView: fitViewOnInit = false,
|
||||
nodeTypes = {},
|
||||
edgeTypes = {},
|
||||
id = '1'
|
||||
}: CreateStoreProps): SvelteFlowStore {
|
||||
const nodesStore = writable(nodes.map((n) => ({ ...n, positionAbsolute: n.position })));
|
||||
@@ -108,6 +114,13 @@ export function createStore({
|
||||
default: nodeTypes.default || DefaultNode
|
||||
});
|
||||
|
||||
const edgeTypesStore = writable({
|
||||
...edgeTypes,
|
||||
straight: edgeTypes.straight || StraightEdge,
|
||||
smoothstep: edgeTypes.smoothstep || SmoothStepEdge,
|
||||
default: edgeTypes.default || BezierEdge
|
||||
});
|
||||
|
||||
let fitViewOnInitDone = false;
|
||||
|
||||
const edgesWithDataStore = derived([edgesStore, nodesStore], ([$edges, $nodes]) => {
|
||||
@@ -293,6 +306,7 @@ export function createStore({
|
||||
selectionRectModeStore,
|
||||
selectionMode,
|
||||
nodeTypesStore,
|
||||
edgeTypesStore,
|
||||
updateNodePositions,
|
||||
updateNodeDimensions,
|
||||
zoomIn,
|
||||
@@ -304,5 +318,6 @@ export function createStore({
|
||||
|
||||
export function useStore(): SvelteFlowStore {
|
||||
const { getStore } = getContext<{ getStore: () => SvelteFlowStore }>(key);
|
||||
|
||||
return getStore();
|
||||
}
|
||||
|
||||
@@ -13,3 +13,15 @@ export type NodeProps<NodeData extends Record<string, unknown> = Record<string,
|
||||
};
|
||||
|
||||
export type NodeTypes = Record<string, typeof SvelteComponentTyped<NodeProps>>;
|
||||
|
||||
export type EdgeProps = {
|
||||
id: string;
|
||||
sourceX: number;
|
||||
sourceY: number;
|
||||
targetX: number;
|
||||
targetY: number;
|
||||
sourcePosition?: Position;
|
||||
targetPosition?: Position;
|
||||
};
|
||||
|
||||
export type EdgeTypes = Record<string, typeof SvelteComponentTyped<EdgeProps>>;
|
||||
|
||||
Reference in New Issue
Block a user