feat(svelte): add updateNodeInternals

This commit is contained in:
moklick
2023-09-14 19:31:15 +02:00
parent 89610ccd29
commit f919cb152d
8 changed files with 172 additions and 37 deletions

View File

@@ -1,46 +1,47 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { page } from '$app/stores';
import { goto } from '$app/navigation';
import { page } from '$app/stores';
const routes = [
'customnode',
'drag-n-drop',
'edges',
'figma',
'interaction',
'overview',
'stress',
'subflows',
'usesvelteflow',
'validation'
];
const routes = [
'customnode',
'drag-n-drop',
'edges',
'figma',
'interaction',
'overview',
'stress',
'subflows',
'usesvelteflow',
'useupdatenodeinternals',
'validation'
];
const onChange = (event: Event) => {
const route = (event.target as HTMLSelectElement).value;
goto(route);
};
const onChange = (event: Event) => {
const route = (event.target as HTMLSelectElement).value;
goto(route);
};
</script>
<header>
<div class="logo">Svelte Flow</div>
<select on:change={onChange} value={$page.route.id}>
{#each routes as route}
<option value={`/${route}`}>{route}</option>
{/each}
</select>
<div class="logo">Svelte Flow</div>
<select on:change={onChange} value={$page.route.id}>
{#each routes as route}
<option value={`/${route}`}>{route}</option>
{/each}
</select>
</header>
<style>
header {
padding: 10px;
border-bottom: 1px solid #eee;
display: flex;
font-weight: 700;
align-items: center;
color: #111;
}
header {
padding: 10px;
border-bottom: 1px solid #eee;
display: flex;
font-weight: 700;
align-items: center;
color: #111;
}
.logo {
margin-right: 1rem;
}
.logo {
margin-right: 1rem;
}
</style>

View File

@@ -0,0 +1,9 @@
<script lang="ts">
import { SvelteFlowProvider } from '@xyflow/svelte';
import Flow from './Flow.svelte';
</script>
<SvelteFlowProvider>
<Flow />
</SvelteFlowProvider>

View File

@@ -0,0 +1,29 @@
<script lang="ts">
import { Handle, Position, type NodeProps, useUpdateNodeInternals } from '@xyflow/svelte';
type $$Props = NodeProps;
export let id: $$Props['id'];
const updateNodeInternals = useUpdateNodeInternals();
$: handleCount = 1;
const onClick = () => {
handleCount += 1;
updateNodeInternals(id);
};
</script>
<Handle type="target" position={Position.Top} on:connect />
<button on:click={onClick}>add handle</button>
{#each Array.from({ length: handleCount }) as handle, i}
<Handle
type="source"
position={Position.Bottom}
id={`${i}`}
style={`left: ${i * 10}px;`}
on:connect
/>
{/each}

View File

@@ -0,0 +1,68 @@
<script lang="ts">
import { writable } from 'svelte/store';
import {
SvelteFlow,
Controls,
Background,
BackgroundVariant,
MiniMap,
type NodeTypes
} from '@xyflow/svelte';
import CustomNode from './CustomNode.svelte';
import '@xyflow/svelte/dist/style.css';
const nodeTypes: NodeTypes = {
custom: CustomNode
};
const nodes = writable([
{
id: '1',
type: 'custom',
data: { label: 'Input Node' },
position: { x: 150, y: 0 }
},
{
id: '2',
type: 'default',
data: { label: 'Node' },
position: { x: 0, y: 150 }
},
{
id: '3',
type: 'output',
data: { label: 'Output Node' },
position: { x: 300, y: 150 }
}
]);
const edges = writable([
{
id: '1-2',
source: '1',
target: '2'
},
{
id: '1-3',
source: '1',
target: '3'
}
]);
</script>
<main>
<SvelteFlow {nodes} {edges} {nodeTypes} fitView>
<Controls />
<Background variant={BackgroundVariant.Dots} />
<MiniMap />
</SvelteFlow>
</main>
<style>
main {
height: 100%;
display: flex;
}
</style>

View File

@@ -1,6 +1,6 @@
{
"name": "@xyflow/svelte",
"version": "0.0.18",
"version": "0.0.19",
"description": "Svelte Flow - A highly customizable Svelte library for building node-based editors, workflow systems, diagrams and more.",
"keywords": [
"svelte",

View File

@@ -27,7 +27,6 @@ export function useSvelteFlow(): {
nodes: SvelteFlowStore['nodes'];
edges: SvelteFlowStore['edges'];
} {
// how to get the new context here? fit view doesn't work, because the store is not updated (uses old nodes store)
const {
zoomIn,
zoomOut,

View File

@@ -0,0 +1,28 @@
import { get } from 'svelte/store';
import type { UpdateNodeInternals, NodeDimensionUpdate } from '@xyflow/system';
import { useStore } from '$lib/store';
export function useUpdateNodeInternals(): UpdateNodeInternals {
const { domNode, updateNodeDimensions } = useStore();
// @todo: do we want to add this to system?
const updateInternals = (id: string | string[]) => {
const updateIds = Array.isArray(id) ? id : [id];
const updates = updateIds.reduce<NodeDimensionUpdate[]>((res, updateId) => {
const nodeElement = get(domNode)?.querySelector(
`.svelte-flow__node[data-id="${updateId}"]`
) as HTMLDivElement;
if (nodeElement) {
res.push({ id: updateId, nodeElement, forceUpdate: true });
}
return res;
}, []);
requestAnimationFrame(() => updateNodeDimensions(updates));
};
return updateInternals;
}

View File

@@ -20,6 +20,7 @@ export { useStore } from '$lib/store';
// utils
export * from '$lib/utils';
export * from '$lib/hooks/useSvelteFlow';
export * from '$lib/hooks/useUpdateNodeInternals';
// types
export type { Edge, EdgeProps, EdgeTypes, DefaultEdgeOptions } from '$lib/types/edges';