feat(svelte): add useHandleConnections, useNodesData and useUpdateNodeData
This commit is contained in:
@@ -5,7 +5,7 @@ function ResultNode() {
|
||||
const connections = useHandleConnections({
|
||||
handleType: 'target',
|
||||
});
|
||||
const nodesData = useNodesData<{ text: string }>(connections.map((connection) => connection.source));
|
||||
const nodesData = useNodesData(connections.map((connection) => connection.source));
|
||||
|
||||
useEffect(() => {
|
||||
console.log('incoming data changed', nodesData);
|
||||
@@ -16,7 +16,8 @@ function ResultNode() {
|
||||
<Handle type="target" position={Position.Left} />
|
||||
<div>
|
||||
incoming texts:{' '}
|
||||
{nodesData?.filter((nodeData) => nodeData.text).map(({ text }, i) => <div key={i}>{text}</div>) || 'none'}
|
||||
{nodesData?.filter((nodeData) => nodeData.text !== undefined).map(({ text }, i) => <div key={i}>{text}</div>) ||
|
||||
'none'}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -5,7 +5,7 @@ function UppercaseNode({ id }: NodeProps) {
|
||||
const connections = useHandleConnections({
|
||||
handleType: 'target',
|
||||
});
|
||||
const nodeData = useNodesData<{ text: string }>(connections[0]?.source);
|
||||
const nodeData = useNodesData(connections[0]?.source);
|
||||
const updateNodeData = useUpdateNodeData();
|
||||
|
||||
useEffect(() => {
|
||||
@@ -14,9 +14,9 @@ function UppercaseNode({ id }: NodeProps) {
|
||||
|
||||
return (
|
||||
<div style={{ background: '#eee', color: '#222', padding: 10, fontSize: 12, borderRadius: 10 }}>
|
||||
<Handle type="source" position={Position.Right} />
|
||||
<div>uppercase transform</div>
|
||||
<Handle type="target" position={Position.Left} isConnectable={connections.length === 0} />
|
||||
<div>uppercase transform</div>
|
||||
<Handle type="source" position={Position.Right} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -15,13 +15,18 @@ import TextNode from './TextNode';
|
||||
import ResultNode from './ResultNode';
|
||||
import UppercaseNode from './UppercaseNode';
|
||||
|
||||
export type TextNode = Node<{ text: string }, 'text'>;
|
||||
export type ResultNode = Node<{}, 'result'>;
|
||||
export type UppercaseNode = Node<{}, 'uppercase'>;
|
||||
export type MyNode = Node<{ text: string }, 'text'> | Node<{}, 'result'> | Node<{}, 'uppercase'>;
|
||||
|
||||
const nodeTypes = {
|
||||
text: TextNode,
|
||||
result: ResultNode,
|
||||
uppercase: UppercaseNode,
|
||||
};
|
||||
|
||||
const initNodes: Node[] = [
|
||||
const initNodes: MyNode[] = [
|
||||
{
|
||||
id: '1',
|
||||
type: 'text',
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
'drag-n-drop',
|
||||
'edges',
|
||||
'figma',
|
||||
'handle-connect',
|
||||
'interaction',
|
||||
'intersections',
|
||||
'node-toolbar',
|
||||
@@ -18,6 +19,7 @@
|
||||
'stress',
|
||||
'subflows',
|
||||
'two-way-viewport',
|
||||
'usenodesdata',
|
||||
'usesvelteflow',
|
||||
'useupdatenodeinternals',
|
||||
'validation'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import type { Writable } from 'svelte/store';
|
||||
import { Handle, Position, type NodeProps, BezierEdge, SmoothStepEdge } from '@xyflow/svelte';
|
||||
import { Handle, Position, type NodeProps } from '@xyflow/svelte';
|
||||
|
||||
type $$Props = NodeProps;
|
||||
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
<script lang="ts">
|
||||
import { writable } from 'svelte/store';
|
||||
import {
|
||||
SvelteFlow,
|
||||
Controls,
|
||||
Background,
|
||||
BackgroundVariant,
|
||||
MiniMap,
|
||||
type Node,
|
||||
type NodeTypes,
|
||||
type Edge
|
||||
} from '@xyflow/svelte';
|
||||
import SingleHandleNode from './SingleHandleNode.svelte';
|
||||
import MultiHandleNode from './MultiHandleNode.svelte';
|
||||
|
||||
import '@xyflow/svelte/dist/style.css';
|
||||
|
||||
const nodeTypes: NodeTypes = {
|
||||
single: SingleHandleNode,
|
||||
multi: MultiHandleNode
|
||||
};
|
||||
|
||||
const nodes = writable<Node[]>([
|
||||
{
|
||||
id: '1',
|
||||
type: 'single',
|
||||
data: {},
|
||||
position: { x: 0, y: 0 }
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
type: 'single',
|
||||
data: {},
|
||||
position: { x: 200, y: -100 }
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
type: 'single',
|
||||
data: {},
|
||||
position: { x: 200, y: 100 }
|
||||
},
|
||||
|
||||
{
|
||||
id: '4',
|
||||
type: 'multi',
|
||||
data: {},
|
||||
position: { x: 400, y: 0 }
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
type: 'multi',
|
||||
data: {},
|
||||
position: { x: 600, y: -100 }
|
||||
},
|
||||
{
|
||||
id: '6',
|
||||
type: 'multi',
|
||||
data: {},
|
||||
position: { x: 600, y: 100 }
|
||||
}
|
||||
]);
|
||||
|
||||
const edges = writable<Edge[]>([
|
||||
{
|
||||
id: 'e1-2',
|
||||
source: '1',
|
||||
target: '2'
|
||||
},
|
||||
{
|
||||
id: 'e1-3',
|
||||
source: '1',
|
||||
target: '3'
|
||||
},
|
||||
|
||||
{
|
||||
id: 'e4a-5',
|
||||
source: '4',
|
||||
sourceHandle: 'a',
|
||||
target: '5'
|
||||
},
|
||||
{
|
||||
id: 'e4b-5',
|
||||
source: '4',
|
||||
sourceHandle: 'b',
|
||||
target: '6'
|
||||
}
|
||||
]);
|
||||
</script>
|
||||
|
||||
<SvelteFlow {nodes} {edges} {nodeTypes} fitView colorMode="dark">
|
||||
<Controls />
|
||||
<Background variant={BackgroundVariant.Dots} />
|
||||
<MiniMap />
|
||||
</SvelteFlow>
|
||||
@@ -0,0 +1,110 @@
|
||||
<script lang="ts">
|
||||
import {
|
||||
Handle,
|
||||
Position,
|
||||
type NodeProps,
|
||||
type Connection,
|
||||
useHandleConnections
|
||||
} from '@xyflow/svelte';
|
||||
|
||||
type $$Props = NodeProps;
|
||||
|
||||
export let id: $$Props['id'];
|
||||
|
||||
function onConnectTarget(connection: Connection[]) {
|
||||
console.log('connect target', connection);
|
||||
}
|
||||
|
||||
function onConnectSource(handleId: string, connection: Connection[]) {
|
||||
console.log('connect source', handleId, connection);
|
||||
}
|
||||
|
||||
function onDisconnectTarget(connection: Connection[]) {
|
||||
console.log('disconnect target', connection);
|
||||
}
|
||||
|
||||
function onDisconnectSource(handleId: string, connection: Connection[]) {
|
||||
console.log('disconnect source', handleId, connection);
|
||||
}
|
||||
|
||||
const connections = useHandleConnections({ nodeId: id, type: 'target' });
|
||||
|
||||
$: {
|
||||
console.log('connections', id, $connections);
|
||||
}
|
||||
|
||||
export let data: $$Props['data'];
|
||||
export let targetPosition: $$Props['targetPosition'] = Position.Top;
|
||||
export let sourcePosition: $$Props['sourcePosition'] = Position.Bottom;
|
||||
export let width: $$Props['width'] = undefined;
|
||||
export let height: $$Props['height'] = undefined;
|
||||
export let selected: $$Props['selected'] = undefined;
|
||||
export let type: $$Props['type'] = undefined;
|
||||
export let zIndex: $$Props['zIndex'] = undefined;
|
||||
export let dragging: $$Props['dragging'] = false;
|
||||
export let dragHandle: $$Props['dragHandle'] = undefined;
|
||||
export let positionAbsolute: $$Props['positionAbsolute'] = {
|
||||
x: 0,
|
||||
y: 0
|
||||
};
|
||||
export let isConnectable: $$Props['isConnectable'] = undefined;
|
||||
|
||||
data;
|
||||
targetPosition;
|
||||
sourcePosition;
|
||||
width;
|
||||
height;
|
||||
selected;
|
||||
type;
|
||||
zIndex;
|
||||
dragging;
|
||||
dragHandle;
|
||||
positionAbsolute;
|
||||
isConnectable;
|
||||
</script>
|
||||
|
||||
<div class="custom">
|
||||
<Handle
|
||||
type="target"
|
||||
position={Position.Left}
|
||||
onconnect={onConnectTarget}
|
||||
ondisconnect={onDisconnectTarget}
|
||||
/>
|
||||
<div>node {id}</div>
|
||||
<Handle
|
||||
id="a"
|
||||
type="source"
|
||||
position={Position.Right}
|
||||
onconnect={(connections) => onConnectSource('a', connections)}
|
||||
ondisconnect={(connections) => onDisconnectSource('a', connections)}
|
||||
class="source-a"
|
||||
/>
|
||||
<Handle
|
||||
id="b"
|
||||
type="source"
|
||||
position={Position.Right}
|
||||
onconnect={(connections) => onConnectSource('b', connections)}
|
||||
ondisconnect={(connections) => onDisconnectSource('b', connections)}
|
||||
class="source-b"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.custom {
|
||||
background-color: #333;
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.custom :global(.source-a) {
|
||||
top: 5px;
|
||||
transform: translate(50%, 0);
|
||||
}
|
||||
|
||||
.custom :global(.source-b) {
|
||||
bottom: 5px;
|
||||
top: auto;
|
||||
transform: translate(50%, 0);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,77 @@
|
||||
<script lang="ts">
|
||||
import { Handle, Position, type NodeProps, type Connection } from '@xyflow/svelte';
|
||||
|
||||
type $$Props = NodeProps;
|
||||
|
||||
export let id: $$Props['id'];
|
||||
|
||||
function onConnectTarget(connection: Connection[]) {
|
||||
console.log('connect target', connection);
|
||||
}
|
||||
|
||||
function onConnectSource(connection: Connection[]) {
|
||||
console.log('connect source', connection);
|
||||
}
|
||||
|
||||
function onDisconnectTarget(connection: Connection[]) {
|
||||
console.log('disconnect target', connection);
|
||||
}
|
||||
|
||||
function onDisconnectSource(connection: Connection[]) {
|
||||
console.log('disconnect source', connection);
|
||||
}
|
||||
|
||||
export let data: $$Props['data'];
|
||||
export let targetPosition: $$Props['targetPosition'] = Position.Top;
|
||||
export let sourcePosition: $$Props['sourcePosition'] = Position.Bottom;
|
||||
export let width: $$Props['width'] = undefined;
|
||||
export let height: $$Props['height'] = undefined;
|
||||
export let selected: $$Props['selected'] = undefined;
|
||||
export let type: $$Props['type'] = undefined;
|
||||
export let zIndex: $$Props['zIndex'] = undefined;
|
||||
export let dragging: $$Props['dragging'] = false;
|
||||
export let dragHandle: $$Props['dragHandle'] = undefined;
|
||||
export let positionAbsolute: $$Props['positionAbsolute'] = {
|
||||
x: 0,
|
||||
y: 0
|
||||
};
|
||||
export let isConnectable: $$Props['isConnectable'] = undefined;
|
||||
|
||||
data;
|
||||
targetPosition;
|
||||
sourcePosition;
|
||||
width;
|
||||
height;
|
||||
selected;
|
||||
type;
|
||||
zIndex;
|
||||
dragging;
|
||||
dragHandle;
|
||||
positionAbsolute;
|
||||
isConnectable;
|
||||
</script>
|
||||
|
||||
<div class="custom">
|
||||
<Handle
|
||||
type="target"
|
||||
position={Position.Left}
|
||||
onconnect={onConnectTarget}
|
||||
ondisconnect={onDisconnectTarget}
|
||||
/>
|
||||
<div>node {id}</div>
|
||||
<Handle
|
||||
type="source"
|
||||
position={Position.Right}
|
||||
onconnect={onConnectSource}
|
||||
ondisconnect={onDisconnectSource}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.custom {
|
||||
background-color: #333;
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,80 @@
|
||||
<script lang="ts">
|
||||
import { writable } from 'svelte/store';
|
||||
import {
|
||||
SvelteFlow,
|
||||
Controls,
|
||||
Background,
|
||||
BackgroundVariant,
|
||||
MiniMap,
|
||||
type Node,
|
||||
type NodeTypes,
|
||||
type Edge
|
||||
} from '@xyflow/svelte';
|
||||
import '@xyflow/svelte/dist/style.css';
|
||||
|
||||
import TextNode from './TextNode.svelte';
|
||||
import UppercaseNode from './UppercaseNode.svelte';
|
||||
import ResultNode from './ResultNode.svelte';
|
||||
|
||||
const nodeTypes: NodeTypes = {
|
||||
text: TextNode,
|
||||
uppercase: UppercaseNode,
|
||||
result: ResultNode
|
||||
};
|
||||
|
||||
const nodes = writable<Node[]>([
|
||||
{
|
||||
id: '1',
|
||||
type: 'text',
|
||||
data: {
|
||||
text: 'hello'
|
||||
},
|
||||
position: { x: -100, y: -50 }
|
||||
},
|
||||
{
|
||||
id: '1a',
|
||||
type: 'uppercase',
|
||||
data: {},
|
||||
position: { x: 100, y: 0 }
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
type: 'text',
|
||||
data: {
|
||||
text: 'world'
|
||||
},
|
||||
position: { x: 0, y: 100 }
|
||||
},
|
||||
|
||||
{
|
||||
id: '3',
|
||||
type: 'result',
|
||||
data: {},
|
||||
position: { x: 300, y: 50 }
|
||||
}
|
||||
]);
|
||||
|
||||
const edges = writable<Edge[]>([
|
||||
{
|
||||
id: 'e1-1a',
|
||||
source: '1',
|
||||
target: '1a'
|
||||
},
|
||||
{
|
||||
id: 'e1a-3',
|
||||
source: '1a',
|
||||
target: '3'
|
||||
},
|
||||
{
|
||||
id: 'e2-3',
|
||||
source: '2',
|
||||
target: '3'
|
||||
}
|
||||
]);
|
||||
</script>
|
||||
|
||||
<SvelteFlow {nodes} {edges} {nodeTypes} fitView>
|
||||
<Controls />
|
||||
<Background variant={BackgroundVariant.Dots} />
|
||||
<MiniMap />
|
||||
</SvelteFlow>
|
||||
@@ -0,0 +1,38 @@
|
||||
<script lang="ts">
|
||||
import {
|
||||
Handle,
|
||||
Position,
|
||||
useHandleConnections,
|
||||
useNodesData,
|
||||
useUpdateNodeData,
|
||||
type NodeProps
|
||||
} from '@xyflow/svelte';
|
||||
|
||||
type $$Props = NodeProps;
|
||||
|
||||
export let id: $$Props['id'];
|
||||
|
||||
const connections = useHandleConnections({
|
||||
nodeId: id,
|
||||
type: 'target'
|
||||
});
|
||||
|
||||
const nodeData = useNodesData($connections.map((connection) => connection.source));
|
||||
</script>
|
||||
|
||||
<div class="custom">
|
||||
<Handle type="target" position={Position.Left} />
|
||||
<div>incoming texts:</div>
|
||||
|
||||
{#each $nodeData as data}
|
||||
<div>{data.text}</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.custom {
|
||||
background-color: #eee;
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,29 @@
|
||||
<script lang="ts">
|
||||
import { Handle, Position, type NodeProps, useUpdateNodeData } from '@xyflow/svelte';
|
||||
|
||||
type $$Props = NodeProps;
|
||||
|
||||
export let id: $$Props['id'];
|
||||
export let data: $$Props['data'];
|
||||
|
||||
const updateNodeData = useUpdateNodeData();
|
||||
</script>
|
||||
|
||||
<div class="custom">
|
||||
<div>node {id}</div>
|
||||
<div>
|
||||
<input
|
||||
value={data.text}
|
||||
on:input={(evt) => updateNodeData(id, { text: evt.currentTarget.value })}
|
||||
/>
|
||||
</div>
|
||||
<Handle type="source" position={Position.Right} />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.custom {
|
||||
background-color: #eee;
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,40 @@
|
||||
<script lang="ts">
|
||||
import {
|
||||
Handle,
|
||||
Position,
|
||||
type NodeProps,
|
||||
useHandleConnections,
|
||||
useNodesData,
|
||||
useUpdateNodeData
|
||||
} from '@xyflow/svelte';
|
||||
|
||||
type $$Props = NodeProps;
|
||||
|
||||
export let id: $$Props['id'];
|
||||
|
||||
const updateNodeData = useUpdateNodeData();
|
||||
const connections = useHandleConnections({
|
||||
nodeId: id,
|
||||
type: 'target'
|
||||
});
|
||||
|
||||
$: nodeData = useNodesData($connections[0]?.source);
|
||||
|
||||
$: {
|
||||
updateNodeData(id, { text: $nodeData?.text?.toUpperCase() || '' });
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="custom">
|
||||
<Handle type="target" position={Position.Left} isConnectable={$connections.length === 0} />
|
||||
<div>uppercase transform</div>
|
||||
<Handle type="source" position={Position.Right} />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.custom {
|
||||
background-color: #eee;
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user