migrate examples

This commit is contained in:
peterkogo
2024-11-12 13:03:28 +01:00
parent 3fc693b9d3
commit 352122968f
47 changed files with 322 additions and 202 deletions
@@ -35,7 +35,7 @@
<header> <header>
<div class="logo">Svelte Flow</div> <div class="logo">Svelte Flow</div>
<select on:change={onChange} value={$page.route.id}> <select onchange={onChange} value={$page.route.id}>
{#each routes as route} {#each routes as route}
<option value={`/examples/${route}`}>{route}</option> <option value={`/examples/${route}`}>{route}</option>
{/each} {/each}
@@ -3,7 +3,11 @@
type $$Props = NodeProps; type $$Props = NodeProps;
export let data: $$Props['data']; interface Props {
data: $$Props['data'];
}
let { data }: Props = $props();
</script> </script>
<NodeToolbar <NodeToolbar
@@ -5,7 +5,7 @@
</script> </script>
<div class="container"> <div class="container">
<div class="drag-handle custom-drag-handle" /> <div class="drag-handle custom-drag-handle"></div>
</div> </div>
<style> <style>
@@ -1,11 +1,16 @@
<script lang="ts"> <script lang="ts">
import { Header } from '$components/Header'; import { Header } from '$components/Header';
interface Props {
children?: import('svelte').Snippet;
}
let { children }: Props = $props();
</script> </script>
<div class="app"> <div class="app">
<Header /> <Header />
<div class="flow"> <div class="flow">
<slot /> {@render children?.()}
</div> </div>
</div> </div>
@@ -22,8 +22,8 @@
const nodes = writable<Node[]>(initialNodes); const nodes = writable<Node[]>(initialNodes);
const edges = writable<Edge[]>([]); const edges = writable<Edge[]>([]);
let connectingNodeId: string | null = '0'; let connectingNodeId: string | null = $state('0');
let rect: DOMRectReadOnly; let rect: DOMRectReadOnly = $state();
let id = 1; let id = 1;
const getId = () => `${id++}`; const getId = () => `${id++}`;
@@ -36,7 +36,7 @@
{ id: 'A-D', source: 'A', target: 'D' } { id: 'A-D', source: 'A', target: 'D' }
]); ]);
let colorMode: ColorMode = 'light'; let colorMode: ColorMode = $state('light');
</script> </script>
<SvelteFlow {nodes} {edges} {colorMode} fitView> <SvelteFlow {nodes} {edges} {colorMode} fitView>
@@ -26,7 +26,9 @@
<div style="height:100vh;"> <div style="height:100vh;">
<SvelteFlow {nodeTypes} {nodes} {edges} fitView> <SvelteFlow {nodeTypes} {nodes} {edges} fitView>
<ConnectionLine slot="connectionLine" /> {#snippet connectionLine()}
<ConnectionLine />
{/snippet}
<Background variant={BackgroundVariant.Lines} /> <Background variant={BackgroundVariant.Lines} />
</SvelteFlow> </SvelteFlow>
</div> </div>
@@ -3,20 +3,22 @@
const connection = useConnection(); const connection = useConnection();
let path: string | null = null; let path: string | null = $derived.by(() => {
if ($connection.inProgress) {
$: if ($connection.inProgress) { const { from, to, fromPosition, toPosition } = $connection;
const { from, to, fromPosition, toPosition } = $connection; const pathParams = {
const pathParams = { sourceX: from.x,
sourceX: from.x, sourceY: from.y,
sourceY: from.y, sourcePosition: fromPosition,
sourcePosition: fromPosition, targetX: to.x,
targetX: to.x, targetY: to.y,
targetY: to.y, targetPosition: toPosition
targetPosition: toPosition };
}; const [path] = getBezierPath(pathParams);
[path] = getBezierPath(pathParams); return path;
} }
return null;
});
</script> </script>
{#if $connection.inProgress} {#if $connection.inProgress}
@@ -3,8 +3,13 @@
type $$Props = NodeProps; type $$Props = NodeProps;
export let isConnectable: $$Props['isConnectable']; interface Props {
$$restProps; isConnectable: $$Props['isConnectable'];
[key: string]: any
}
let { isConnectable, ...rest }: Props = $props();
rest;
const handleStyle = 'width: 10px; height: 10px; bottom: -5px;'; const handleStyle = 'width: 10px; height: 10px; bottom: -5px;';
</script> </script>
@@ -4,9 +4,14 @@
type $$Props = NodeProps<Node<{ colorStore: Writable<string> }>>; type $$Props = NodeProps<Node<{ colorStore: Writable<string> }>>;
export let data: $$Props['data']; interface Props {
data: $$Props['data'];
[key: string]: any
}
$$restProps; let { data, ...rest }: Props = $props();
rest;
const { colorStore } = data; const { colorStore } = data;
</script> </script>
@@ -19,7 +24,7 @@
<input <input
class="nodrag" class="nodrag"
type="color" type="color"
on:input={(evt) => colorStore.set(evt.currentTarget.value)} oninput={(evt) => colorStore.set(evt.currentTarget.value)}
value={$colorStore} value={$colorStore}
/> />
<Handle type="source" position={Position.Right} id="a" style="top: 20px;" /> <Handle type="source" position={Position.Right} id="a" style="top: 20px;" />
@@ -71,8 +71,8 @@
defaultEdgeOptions={{ type: 'smoothstep', animated: true }} defaultEdgeOptions={{ type: 'smoothstep', animated: true }}
> >
<Panel position="top-right"> <Panel position="top-right">
<button on:click={() => onLayout('TB')}>vertical layout</button> <button onclick={() => onLayout('TB')}>vertical layout</button>
<button on:click={() => onLayout('LR')}>horizontal layout</button> <button onclick={() => onLayout('LR')}>horizontal layout</button>
</Panel> </Panel>
<Background /> <Background />
</SvelteFlow> </SvelteFlow>
@@ -83,9 +83,7 @@
$nodes = $nodes; $nodes = $nodes;
}; };
$: { $inspect($nodes);
console.log($nodes);
}
</script> </script>
<main> <main>
@@ -17,21 +17,21 @@
<div class="label">You can drag these nodes to the pane on the left.</div> <div class="label">You can drag these nodes to the pane on the left.</div>
<div <div
class="input-node node" class="input-node node"
on:dragstart={(event) => onDragStart(event, 'input')} ondragstart={(event) => onDragStart(event, 'input')}
draggable={true} draggable={true}
> >
Input Node Input Node
</div> </div>
<div <div
class="default-node node" class="default-node node"
on:dragstart={(event) => onDragStart(event, 'default')} ondragstart={(event) => onDragStart(event, 'default')}
draggable={true} draggable={true}
> >
Default Node Default Node
</div> </div>
<div <div
class="output-node node" class="output-node node"
on:dragstart={(event) => onDragStart(event, 'output')} ondragstart={(event) => onDragStart(event, 'output')}
draggable={true} draggable={true}
> >
Output Node Output Node
@@ -7,7 +7,8 @@
BackgroundVariant, BackgroundVariant,
MiniMap, MiniMap,
MarkerType, MarkerType,
type Connection type Connection,
type EdgeTypes
} from '@xyflow/svelte'; } from '@xyflow/svelte';
import '@xyflow/svelte/dist/style.css'; import '@xyflow/svelte/dist/style.css';
@@ -147,23 +148,23 @@
} }
} }
]); ]);
const edgeTypes = { const edgeTypes: EdgeTypes = {
button: ButtonEdge, button: ButtonEdge,
customBezier: CustomBezierEdge customBezier: CustomBezierEdge
}; };
function getEdgeId(connection: Connection) { function getEdgeId(connection: Connection) {
return `edge-${connection.source}-${connection.target}}`; return `edge-${connection.source}-${connection.target}}`;
} }
$: console.log('edges', $edges); $inspect($edges);
</script> </script>
<SvelteFlow <SvelteFlow
{nodes} {nodes}
{edges} {edges}
{edgeTypes} {edgeTypes}
fitView fitView
nodeDragThreshold={2} nodeDragThreshold={2}
onedgecreate={(connection) => { onedgecreate={(connection) => {
@@ -3,28 +3,44 @@
type $$Props = EdgeProps; type $$Props = EdgeProps;
export let id: $$Props['id'] = '';
export let style: $$Props['style'] = undefined;
export let markerEnd: $$Props['markerEnd'] = undefined;
export let sourceX: $$Props['sourceX'];
export let sourceY: $$Props['sourceY'];
export let sourcePosition: $$Props['sourcePosition'];
export let targetX: $$Props['targetX']; interface Props {
export let targetY: $$Props['targetY']; id?: $$Props['id'];
export let targetPosition: $$Props['targetPosition']; style?: $$Props['style'];
markerEnd?: $$Props['markerEnd'];
sourceX: $$Props['sourceX'];
sourceY: $$Props['sourceY'];
sourcePosition: $$Props['sourcePosition'];
targetX: $$Props['targetX'];
targetY: $$Props['targetY'];
targetPosition: $$Props['targetPosition'];
[key: string]: any
}
$$restProps; let {
id = '',
style = undefined,
markerEnd = undefined,
sourceX,
sourceY,
sourcePosition,
targetX,
targetY,
targetPosition,
...rest
}: Props = $props();
$: [edgePath, labelX, labelY] = getBezierPath({ rest;
let [edgePath, labelX, labelY] = $derived(getBezierPath({
sourceX, sourceX,
sourceY, sourceY,
sourcePosition, sourcePosition,
targetX, targetX,
targetY, targetY,
targetPosition targetPosition
}); }));
</script> </script>
<BaseEdge path={edgePath} {markerEnd} {style} /> <BaseEdge path={edgePath} {markerEnd} {style} />
@@ -35,7 +51,7 @@
> >
<button <button
class="edgeButton" class="edgeButton"
on:click={(event) => { onclick={(event) => {
event.stopPropagation(); event.stopPropagation();
alert(`remove ${id}`); alert(`remove ${id}`);
}} }}
@@ -3,22 +3,41 @@
type $$Props = EdgeProps; 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']; interface Props {
export let targetY: $$Props['targetY']; label?: $$Props['label'];
export let targetPosition: $$Props['targetPosition']; labelStyle?: $$Props['labelStyle'];
style?: $$Props['style'];
markerStart?: $$Props['markerStart'];
markerEnd?: $$Props['markerEnd'];
interactionWidth?: $$Props['interactionWidth'];
sourceX: $$Props['sourceX'];
sourceY: $$Props['sourceY'];
sourcePosition: $$Props['sourcePosition'];
targetX: $$Props['targetX'];
targetY: $$Props['targetY'];
targetPosition: $$Props['targetPosition'];
[key: string]: any
}
$$restProps; let {
label = undefined,
labelStyle = undefined,
style = undefined,
markerStart = undefined,
markerEnd = undefined,
interactionWidth = undefined,
sourceX,
sourceY,
sourcePosition,
targetX,
targetY,
targetPosition,
...rest
}: Props = $props();
rest;
</script> </script>
<BezierEdge <BezierEdge
@@ -7,9 +7,7 @@
useHandleConnections useHandleConnections
} from '@xyflow/svelte'; } from '@xyflow/svelte';
type $$Props = NodeProps; let { id }: NodeProps = $props();
export let id: $$Props['id'];
function onConnectTarget(connection: Connection[]) { function onConnectTarget(connection: Connection[]) {
console.log('connect target', connection); console.log('connect target', connection);
@@ -29,11 +27,7 @@
const connections = useHandleConnections({ nodeId: id, type: 'target' }); const connections = useHandleConnections({ nodeId: id, type: 'target' });
$: { $inspect('connections', $connections);
console.log('connections', id, $connections);
}
$$restProps;
</script> </script>
<div class="custom"> <div class="custom">
@@ -3,7 +3,12 @@
type $$Props = NodeProps; type $$Props = NodeProps;
export let id: $$Props['id']; interface Props {
id: $$Props['id'];
[key: string]: any
}
let { id, ...rest }: Props = $props();
function onConnectTarget(connection: Connection[]) { function onConnectTarget(connection: Connection[]) {
console.log('connect target', connection); console.log('connect target', connection);
@@ -21,7 +26,7 @@
console.log('disconnect source', connection); console.log('disconnect source', connection);
} }
$$restProps; rest;
</script> </script>
<div class="custom"> <div class="custom">
@@ -39,18 +39,18 @@
const onPaneContextMenu = (event: MouseEvent) => console.log('onPaneContextMenu', event); const onPaneContextMenu = (event: MouseEvent) => console.log('onPaneContextMenu', event);
const onMoveEnd: OnMoveEnd = (_, viewport) => console.log('onMoveEnd', viewport); const onMoveEnd: OnMoveEnd = (_, viewport) => console.log('onMoveEnd', viewport);
let isSelectable = false; let isSelectable = $state(false);
let isDraggable = false; let isDraggable = $state(false);
let isConnectable = false; let isConnectable = $state(false);
let zoomOnScroll = false; let zoomOnScroll = $state(false);
let zoomOnPinch = false; let zoomOnPinch = $state(false);
let panOnScroll = false; let panOnScroll = $state(false);
let panOnScrollMode = PanOnScrollMode.Free; let panOnScrollMode = $state(PanOnScrollMode.Free);
let zoomOnDoubleClick = false; let zoomOnDoubleClick = $state(false);
let panOnDrag = true; let panOnDrag = $state(true);
let captureZoomClick = false; let captureZoomClick = $state(false);
let captureZoomScroll = false; let captureZoomScroll = $state(false);
let captureElementClick = false; let captureElementClick = $state(false);
</script> </script>
<SvelteFlow <SvelteFlow
@@ -143,7 +143,7 @@
<select <select
id="panonscrollmode" id="panonscrollmode"
bind:value={panOnScrollMode} bind:value={panOnScrollMode}
on:change={(event) => { onchange={(event) => {
panOnScrollMode = PanOnScrollMode.Free; panOnScrollMode = PanOnScrollMode.Free;
}} }}
class="svelte-flow__panonscrollmode" class="svelte-flow__panonscrollmode"
@@ -128,7 +128,7 @@
} }
]); ]);
let snapToGrid = false; let snapToGrid = $state(false);
</script> </script>
<SvelteFlow <SvelteFlow
@@ -144,7 +144,7 @@
<Controls /> <Controls />
<Panel position="bottom-right"> <Panel position="bottom-right">
<button <button
on:click={() => { onclick={() => {
snapToGrid = !snapToGrid; snapToGrid = !snapToGrid;
}} }}
> >
@@ -4,7 +4,11 @@
type $$Props = NodeProps<ResizeNode>; type $$Props = NodeProps<ResizeNode>;
export let data: $$Props['data']; interface Props {
data: $$Props['data'];
}
let { data }: Props = $props();
</script> </script>
<NodeResizeControl <NodeResizeControl
@@ -4,8 +4,12 @@
type $$Props = NodeProps<ResizeNode>; type $$Props = NodeProps<ResizeNode>;
export let data: $$Props['data']; interface Props {
export let selected: $$Props['selected'] = undefined; data: $$Props['data'];
selected?: $$Props['selected'];
}
let { data, selected = undefined }: Props = $props();
</script> </script>
<NodeResizer <NodeResizer
@@ -4,7 +4,11 @@
type $$Props = NodeProps<ResizeNode>; type $$Props = NodeProps<ResizeNode>;
export let data: $$Props['data']; interface Props {
data: $$Props['data'];
}
let { data }: Props = $props();
</script> </script>
<NodeResizeControl <NodeResizeControl
@@ -4,7 +4,11 @@
type $$Props = NodeProps<ResizeNode>; type $$Props = NodeProps<ResizeNode>;
export let data: $$Props['data']; interface Props {
data: $$Props['data'];
}
let { data }: Props = $props();
</script> </script>
<NodeResizeControl <NodeResizeControl
@@ -2,9 +2,14 @@
import { NodeToolbar, type NodeProps, Handle, Position } from '@xyflow/svelte'; import { NodeToolbar, type NodeProps, Handle, Position } from '@xyflow/svelte';
type $$Props = NodeProps; type $$Props = NodeProps;
$$restProps; rest;
export let data: $$Props['data']; interface Props {
data: $$Props['data'];
[key: string]: any
}
let { data, ...rest }: Props = $props();
</script> </script>
<NodeToolbar <NodeToolbar
@@ -3,8 +3,8 @@
const nodes = useNodes(); const nodes = useNodes();
$: selectedNodeIds = $nodes.filter((node) => node.selected).map((node) => node.id); let selectedNodeIds = $derived($nodes.filter((node) => node.selected).map((node) => node.id));
$: isVisible = selectedNodeIds.length > 1; let isVisible = $derived(selectedNodeIds.length > 1);
</script> </script>
<NodeToolbar nodeId={selectedNodeIds} {isVisible}> <NodeToolbar nodeId={selectedNodeIds} {isVisible}>
@@ -134,9 +134,7 @@
$edges = $edges; $edges = $edges;
} }
$: { $inspect($nodes);
console.log('nodes changed', $nodes);
}
</script> </script>
<SvelteFlow <SvelteFlow
@@ -199,7 +197,9 @@
deleteKey={['Backspace', 'd']} deleteKey={['Backspace', 'd']}
> >
<Controls orientation="horizontal" {fitViewOptions}> <Controls orientation="horizontal" {fitViewOptions}>
<ControlButton slot="before">xy</ControlButton> {#snippet before()}
<ControlButton>xy</ControlButton>
{/snippet}
<ControlButton aria-label="log" on:click={() => console.log('control button')} <ControlButton aria-label="log" on:click={() => console.log('control button')}
>log</ControlButton >log</ControlButton
> >
@@ -207,10 +207,10 @@
<Background variant={BackgroundVariant.Dots} /> <Background variant={BackgroundVariant.Dots} />
<MiniMap /> <MiniMap />
<Panel position="top-right"> <Panel position="top-right">
<button on:click={updateNode}>update node pos</button> <button onclick={updateNode}>update node pos</button>
<button on:click={updateEdge}>update edge type</button> <button onclick={updateEdge}>update edge type</button>
<button <button
on:click={() => { onclick={() => {
console.log($nodes, $nodes.length); console.log($nodes, $nodes.length);
$nodes[$nodes.length - 1].hidden = !$nodes[$nodes.length - 1].hidden; $nodes[$nodes.length - 1].hidden = !$nodes[$nodes.length - 1].hidden;
$nodes = $nodes; $nodes = $nodes;
@@ -6,32 +6,37 @@
type EdgeProps, type EdgeProps,
getBezierPath getBezierPath
} from '@xyflow/svelte'; } from '@xyflow/svelte';
interface Props {
[key: string]: any
}
let { ...props }: Props = $props();
type $$Props = EdgeProps; type $$Props = EdgeProps;
$: [path, labelX, labelY] = getBezierPath({ let [path, labelX, labelY] = $derived(getBezierPath({
sourceX: $$props.sourceX, sourceX: props.sourceX,
sourceY: $$props.sourceY, sourceY: props.sourceY,
targetX: $$props.targetX, targetX: props.targetX,
targetY: $$props.targetY, targetY: props.targetY,
sourcePosition: $$props.sourcePosition, sourcePosition: props.sourcePosition,
targetPosition: $$props.targetPosition targetPosition: props.targetPosition
}); }));
const edges = useEdges(); const edges = useEdges();
function onClick() { function onClick() {
edges.update((eds) => eds.filter((e) => e.id !== $$props.id)); edges.update((eds) => eds.filter((e) => e.id !== props.id));
} }
</script> </script>
<BaseEdge {path} {labelX} {labelY} {...$$props} /> <BaseEdge {path} {labelX} {labelY} {...props} />
<EdgeLabelRenderer> <EdgeLabelRenderer>
<button <button
style:transform={`translate(-50%,-50%) translate(${labelX}px,${labelY}px)`} style:transform={`translate(-50%,-50%) translate(${labelX}px,${labelY}px)`}
class="edge-button" class="edge-button"
on:click={onClick} onclick={onClick}
> >
</button> </button>
@@ -2,11 +2,16 @@
import { Handle, Position, type BuiltInNode, type NodeProps } from '@xyflow/svelte'; import { Handle, Position, type BuiltInNode, type NodeProps } from '@xyflow/svelte';
type $$Props = NodeProps<BuiltInNode>; type $$Props = NodeProps<BuiltInNode>;
$$restProps; rest;
export let data: { label: string } = { label: 'Node' }; interface Props {
export let positionAbsoluteX: number = 0; data?: { label: string };
export let positionAbsoluteY: number = 0; positionAbsoluteX?: number;
positionAbsoluteY?: number;
[key: string]: any
}
let { data = { label: 'Node' }, positionAbsoluteX = 0, positionAbsoluteY = 0, ...rest }: Props = $props();
</script> </script>
<div class="custom"> <div class="custom">
@@ -2,14 +2,19 @@
import type { BuiltInNode, NodeProps } from '@xyflow/svelte'; import type { BuiltInNode, NodeProps } from '@xyflow/svelte';
type $$Props = NodeProps<BuiltInNode>; type $$Props = NodeProps<BuiltInNode>;
$$restProps; rest;
export let data: { label: string } = { label: 'Node' }; interface Props {
data?: { label: string };
[key: string]: any
}
let { data = { label: 'Node' }, ...rest }: Props = $props();
</script> </script>
<div class="custom"> <div class="custom">
<div>{data.label}</div> <div>{data.label}</div>
<div class="custom-drag-handle" style="width:15px;height:15px;background:#222;" /> <div class="custom-drag-handle" style="width:15px;height:15px;background:#222;"></div>
</div> </div>
<style> <style>
@@ -4,15 +4,15 @@
const nodesInitialized = useNodesInitialized(); const nodesInitialized = useNodesInitialized();
const initialized = useInitialized(); const initialized = useInitialized();
$: { $effect(() => {
if (nodesInitialized) { if (nodesInitialized) {
console.log('nodes initialized'); console.log('nodes initialized');
} }
} });
$: { $effect(() => {
if (initialized) { if (initialized) {
console.log('initialized'); console.log('initialized');
} }
} });
</script> </script>
@@ -24,7 +24,7 @@
}; };
</script> </script>
<button on:click={resetNodesArray}> Reset </button> <button onclick={resetNodesArray}> Reset </button>
<div style:height="100vh"> <div style:height="100vh">
<SvelteFlow {nodes} {edges} fitView> <SvelteFlow {nodes} {edges} fitView>
@@ -116,9 +116,7 @@
{ id: 'e4b1-4b2', source: '4b1', target: '4b2' } { id: 'e4b1-4b2', source: '4b1', target: '4b2' }
]); ]);
$: { $inspect($nodes);
console.log($nodes);
}
</script> </script>
<SvelteFlow {nodes} {edges} {nodeTypes} fitView minZoom={0.1} maxZoom={2.5}> <SvelteFlow {nodes} {edges} {nodeTypes} fitView minZoom={0.1} maxZoom={2.5}>
@@ -3,12 +3,23 @@
type $$Props = NodeProps; type $$Props = NodeProps;
export let id: string; interface Props {
export let positionAbsoluteX: number = 0; id: string;
export let positionAbsoluteY: number = 0; positionAbsoluteX?: number;
export let zIndex: number = 0; positionAbsoluteY?: number;
zIndex?: number;
[key: string]: any
}
$$restProps; let {
id,
positionAbsoluteX = 0,
positionAbsoluteY = 0,
zIndex = 0,
...rest
}: Props = $props();
rest;
</script> </script>
<Handle type="target" position={Position.Top} /> <Handle type="target" position={Position.Top} />
@@ -40,7 +40,7 @@
<Background variant={BackgroundVariant.Dots} /> <Background variant={BackgroundVariant.Dots} />
<Panel> <Panel>
<button on:click={updateViewport}>update viewport</button> <button onclick={updateViewport}>update viewport</button>
<button on:click={() => fitView()}>fitView</button> <button onclick={() => fitView()}>fitView</button>
</Panel> </Panel>
</SvelteFlow> </SvelteFlow>
@@ -1,4 +1,4 @@
<script context="module" lang="ts"> <script module lang="ts">
import type { Node } from '@xyflow/svelte'; import type { Node } from '@xyflow/svelte';
type TextNodeType = Node<{ text: string }, 'text'>; type TextNodeType = Node<{ text: string }, 'text'>;
@@ -10,16 +10,21 @@
type $$Props = NodeProps; type $$Props = NodeProps;
export let id: $$Props['id']; interface Props {
$$restProps; id: $$Props['id'];
[key: string]: any
}
let { id, ...rest }: Props = $props();
rest;
const connections = useHandleConnections({ const connections = useHandleConnections({
nodeId: id, nodeId: id,
type: 'target' type: 'target'
}); });
$: nodeData = useNodesData<MyNode>($connections.map((connection) => connection.source)); let nodeData = $derived(useNodesData<MyNode>($connections.map((connection) => connection.source)));
$: textNodes = $nodeData.filter(isTextNode); let textNodes = $derived($nodeData.filter(isTextNode));
</script> </script>
<div class="custom"> <div class="custom">
@@ -3,11 +3,16 @@
type $$Props = NodeProps; type $$Props = NodeProps;
export let id: $$Props['id']; interface Props {
export let data: $$Props['data']; id: $$Props['id'];
data: $$Props['data'];
[key: string]: any
}
let { id, data, ...rest }: Props = $props();
const { updateNodeData } = useSvelteFlow(); const { updateNodeData } = useSvelteFlow();
$$restProps; rest;
</script> </script>
<div class="custom"> <div class="custom">
@@ -15,7 +20,7 @@
<div> <div>
<input <input
value={data.text} value={data.text}
on:input={(evt) => updateNodeData(id, { text: evt.currentTarget.value })} oninput={(evt) => updateNodeData(id, { text: evt.currentTarget.value })}
/> />
</div> </div>
<Handle type="source" position={Position.Right} /> <Handle type="source" position={Position.Right} />
@@ -5,15 +5,12 @@
useHandleConnections, useHandleConnections,
useNodesData, useNodesData,
useSvelteFlow, useSvelteFlow,
type Node,
type NodeProps type NodeProps
} from '@xyflow/svelte'; } from '@xyflow/svelte';
import { isTextNode, type MyNode } from './+page.svelte'; import { isTextNode, type MyNode } from './+page.svelte';
type $$Props = NodeProps; let { id, data }: NodeProps<Node<{ text: string }>> = $props();
export let id: $$Props['id'];
export let data: $$Props['data'];
$$restProps;
const { updateNodeData } = useSvelteFlow(); const { updateNodeData } = useSvelteFlow();
const connections = useHandleConnections({ const connections = useHandleConnections({
@@ -21,16 +18,16 @@
type: 'target' type: 'target'
}); });
$: nodeData = useNodesData<MyNode>($connections[0]?.source); let nodeData = $derived(useNodesData<MyNode>($connections[0]?.source));
$: textNode = isTextNode($nodeData) ? $nodeData : null; let textNode = $derived(isTextNode($nodeData) ? $nodeData : null);
$: console.log(textNode?.data, data); $inspect(textNode?.data, data);
$: { $effect.pre(() => {
const input = textNode?.data.text.toUpperCase() ?? ''; const input = textNode?.data.text.toUpperCase() ?? '';
updateNodeData(id, { text: input }); updateNodeData(id, { text: input });
console.log('updatedNodeData with', input); console.log('updatedNodeData with', input);
} });
</script> </script>
<div class="custom"> <div class="custom">
@@ -25,24 +25,24 @@
<aside> <aside>
<div class="label">Functions:</div> <div class="label">Functions:</div>
<button on:click={() => zoomIn()}>zoom in</button> <button onclick={() => zoomIn()}>zoom in</button>
<button on:click={() => zoomOut({ duration: 1000 })}>zoom out transition</button> <button onclick={() => zoomOut({ duration: 1000 })}>zoom out transition</button>
<button on:click={() => setZoom(2)}>set zoom</button> <button onclick={() => setZoom(2)}>set zoom</button>
<button on:click={() => fitView()}>fitView</button> <button onclick={() => fitView()}>fitView</button>
<button on:click={() => setCenter(0, 0)}>setCenter 0, 0</button> <button onclick={() => setCenter(0, 0)}>setCenter 0, 0</button>
<button on:click={() => setViewport({ x: 100, y: 100, zoom: 2 })}>setViewport</button> <button onclick={() => setViewport({ x: 100, y: 100, zoom: 2 })}>setViewport</button>
<button on:click={() => console.log(getViewport())}>getViewport</button> <button onclick={() => console.log(getViewport())}>getViewport</button>
<button on:click={() => deleteElements({ edges: $edges.map((edge) => ({ id: edge.id })) })} <button onclick={() => deleteElements({ edges: $edges.map((edge) => ({ id: edge.id })) })}
>delete edges</button >delete edges</button
> >
<button on:click={() => deleteElements({ nodes: [{ id: $nodes[0].id }] })}>delete node</button> <button onclick={() => deleteElements({ nodes: [{ id: $nodes[0].id }] })}>delete node</button>
<button on:click={() => deleteElements({ nodes: $nodes.map((node) => ({ id: node.id })) })} <button onclick={() => deleteElements({ nodes: $nodes.map((node) => ({ id: node.id })) })}
>deleteElements</button >deleteElements</button
> >
<button on:click={() => deleteNode()}>delete via store</button> <button onclick={() => deleteNode()}>delete via store</button>
<button <button
on:click={() => { onclick={() => {
const { nodes, edges, viewport } = toObject(); const { nodes, edges, viewport } = toObject();
console.log(nodes, edges, viewport); console.log(nodes, edges, viewport);
}}>toObject</button }}>toObject</button
@@ -3,12 +3,18 @@
type $$Props = NodeProps; type $$Props = NodeProps;
export let id: $$Props['id']; interface Props {
$$restProps; id: $$Props['id'];
[key: string]: any
}
let { id, ...rest }: Props = $props();
rest;
const updateNodeInternals = useUpdateNodeInternals(); const updateNodeInternals = useUpdateNodeInternals();
$: handleCount = 1; let handleCount = $state(1);
const onClick = () => { const onClick = () => {
handleCount += 1; handleCount += 1;
@@ -17,7 +23,7 @@
</script> </script>
<Handle type="target" position={Position.Top} /> <Handle type="target" position={Position.Top} />
<button on:click={onClick}>add handle</button> <button onclick={onClick}>add handle</button>
{#each Array.from({ length: handleCount }) as handle, i} {#each Array.from({ length: handleCount }) as handle, i}
<Handle type="source" position={Position.Bottom} id={`${i}`} style={`left: ${i * 10}px;`} /> <Handle type="source" position={Position.Bottom} id={`${i}`} style={`left: ${i * 10}px;`} />
@@ -66,7 +66,7 @@
<Background variant={BackgroundVariant.Dots} /> <Background variant={BackgroundVariant.Dots} />
<MiniMap /> <MiniMap />
<Panel><button on:click={updateNodePosition}>update node</button></Panel> <Panel><button onclick={updateNodePosition}>update node</button></Panel>
</SvelteFlow> </SvelteFlow>
</main> </main>
@@ -3,7 +3,11 @@
import Flow from './Flow.svelte'; import Flow from './Flow.svelte';
export let data: { flowConfig: FlowConfig }; interface Props {
data: { flowConfig: FlowConfig };
}
let { data }: Props = $props();
</script> </script>
<SvelteFlowProvider> <SvelteFlowProvider>
@@ -4,7 +4,11 @@
import '@xyflow/svelte/dist/style.css'; import '@xyflow/svelte/dist/style.css';
export let flowConfig: FlowConfig; interface Props {
flowConfig: FlowConfig;
}
let { flowConfig }: Props = $props();
// Create writables here so it is easier to create test cases // Create writables here so it is easier to create test cases
const nodes = writable(flowConfig.flowProps?.nodes); const nodes = writable(flowConfig.flowProps?.nodes);
+3 -1
View File
@@ -6,7 +6,9 @@ const config = {
// Consult https://kit.svelte.dev/docs/integrations#preprocessors // Consult https://kit.svelte.dev/docs/integrations#preprocessors
// for more information about preprocessors // for more information about preprocessors
preprocess: vitePreprocess(), preprocess: vitePreprocess(),
// compilerOptions: {
// runes: true
// },
kit: { kit: {
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list. // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
// If your environment is not supported or you settled on a specific environment, switch out the adapter. // If your environment is not supported or you settled on a specific environment, switch out the adapter.
+8 -10
View File
@@ -1,4 +1,4 @@
import type { SvelteComponent, ComponentType } from 'svelte'; import type { Component } from 'svelte';
import type { import type {
EdgeBase, EdgeBase,
BezierPathOptions, BezierPathOptions,
@@ -113,15 +113,13 @@ export type StraightEdgeProps = Omit<EdgeComponentProps, 'sourcePosition' | 'tar
export type EdgeTypes = Record< export type EdgeTypes = Record<
string, string,
ComponentType< Component<
SvelteComponent< EdgeProps & {
EdgeProps & { // eslint-disable-next-line @typescript-eslint/no-explicit-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any data?: any;
data?: any; // eslint-disable-next-line @typescript-eslint/no-explicit-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any type: any;
type: any; }
}
>
> >
>; >;
+8 -10
View File
@@ -1,4 +1,4 @@
import type { ComponentType, SvelteComponent } from 'svelte'; import type { Component } from 'svelte';
import type { InternalNodeBase, NodeBase, NodeProps as NodePropsBase } from '@xyflow/system'; import type { InternalNodeBase, NodeBase, NodeProps as NodePropsBase } from '@xyflow/system';
/** /**
@@ -30,15 +30,13 @@ export type NodeProps<NodeType extends Node = Node> = NodePropsBase<NodeType> &
export type NodeTypes = Record< export type NodeTypes = Record<
string, string,
ComponentType< Component<
SvelteComponent< NodeProps & {
NodeProps & { // eslint-disable-next-line @typescript-eslint/no-explicit-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any data: any;
data: any; // eslint-disable-next-line @typescript-eslint/no-explicit-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any type: any;
type: any; }
}
>
> >
>; >;