port more updates
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { NodeToolbar, useNodes } from '@xyflow/svelte';
|
import { NodeToolbar, useNodes } from '@xyflow/svelte';
|
||||||
|
|
||||||
const nodes = useNodes();
|
let nodes = useNodes();
|
||||||
|
|
||||||
let selectedNodeIds = $derived(
|
let selectedNodeIds = $derived(
|
||||||
nodes.current.filter((node) => node.selected).map((node) => node.id)
|
nodes.current.filter((node) => node.selected).map((node) => node.id)
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { writable } from 'svelte/store';
|
|
||||||
import { SvelteFlow, Controls, Background, MiniMap, type Node, type Edge } from '@xyflow/svelte';
|
import { SvelteFlow, Controls, Background, MiniMap, type Node, type Edge } from '@xyflow/svelte';
|
||||||
|
|
||||||
import '@xyflow/svelte/dist/style.css';
|
import '@xyflow/svelte/dist/style.css';
|
||||||
|
|
||||||
const nodes = writable<Node[]>([]);
|
let nodes = $state.raw<Node[]>([]);
|
||||||
const edges = writable<Edge[]>([]);
|
let edges = $state.raw<Edge[]>([]);
|
||||||
|
|
||||||
const resetNodesArray = () => {
|
const resetNodesArray = () => {
|
||||||
const node1: Node = {
|
const node1: Node = {
|
||||||
@@ -20,14 +19,14 @@
|
|||||||
position: { x: 100, y: 0 }
|
position: { x: 100, y: 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
$nodes = [node1, node2];
|
nodes = [node1, node2];
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<button onclick={resetNodesArray}> Reset </button>
|
<button onclick={resetNodesArray}> Reset </button>
|
||||||
|
|
||||||
<div style:height="100vh">
|
<div style:height="100vh">
|
||||||
<SvelteFlow {nodes} {edges} fitView>
|
<SvelteFlow bind:nodes bind:edges fitView>
|
||||||
<Controls />
|
<Controls />
|
||||||
<Background />
|
<Background />
|
||||||
<MiniMap />
|
<MiniMap />
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { writable } from 'svelte/store';
|
|
||||||
import {
|
import {
|
||||||
SvelteFlow,
|
SvelteFlow,
|
||||||
Controls,
|
Controls,
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { writable } from 'svelte/store';
|
|
||||||
import { SvelteFlow, Controls, Background, BackgroundVariant, MiniMap } from '@xyflow/svelte';
|
import { SvelteFlow, Controls, Background, BackgroundVariant, MiniMap } from '@xyflow/svelte';
|
||||||
|
|
||||||
import Sidebar from './Sidebar.svelte';
|
import Sidebar from './Sidebar.svelte';
|
||||||
|
|
||||||
import '@xyflow/svelte/dist/style.css';
|
import '@xyflow/svelte/dist/style.css';
|
||||||
|
|
||||||
const nodes = writable([
|
let nodes = $state.raw([
|
||||||
{
|
{
|
||||||
id: '1',
|
id: '1',
|
||||||
type: 'input',
|
type: 'input',
|
||||||
@@ -27,7 +26,7 @@
|
|||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const edges = writable([
|
let edges = $state.raw([
|
||||||
{
|
{
|
||||||
id: '1-2',
|
id: '1-2',
|
||||||
type: 'default',
|
type: 'default',
|
||||||
@@ -45,7 +44,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<SvelteFlow {nodes} {edges} fitView>
|
<SvelteFlow bind:nodes bind:edges fitView>
|
||||||
<Controls />
|
<Controls />
|
||||||
<Background variant={BackgroundVariant.Dots} />
|
<Background variant={BackgroundVariant.Dots} />
|
||||||
<MiniMap />
|
<MiniMap />
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { useEdges, useNodes, useSvelteFlow } from '@xyflow/svelte';
|
import { useEdges, useNodes, useSvelteFlow, useViewport } from '@xyflow/svelte';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
zoomIn,
|
zoomIn,
|
||||||
@@ -9,17 +9,18 @@
|
|||||||
setCenter,
|
setCenter,
|
||||||
setViewport,
|
setViewport,
|
||||||
getViewport,
|
getViewport,
|
||||||
viewport,
|
|
||||||
toObject,
|
toObject,
|
||||||
deleteElements
|
deleteElements
|
||||||
} = useSvelteFlow();
|
} = useSvelteFlow();
|
||||||
|
|
||||||
const nodes = useNodes();
|
let nodes = useNodes();
|
||||||
const edges = useEdges();
|
let edges = useEdges();
|
||||||
|
let viewport = useViewport();
|
||||||
|
|
||||||
const deleteNode = () => {
|
const deleteNode = () => {
|
||||||
$nodes.shift();
|
//TODO: do we really want to allow this?
|
||||||
$nodes = $nodes;
|
// nodes.shift();
|
||||||
|
// nodes = nodes;
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -33,11 +34,13 @@
|
|||||||
<button onclick={() => setViewport({ x: 100, y: 100, zoom: 2 })}>setViewport</button>
|
<button onclick={() => setViewport({ x: 100, y: 100, zoom: 2 })}>setViewport</button>
|
||||||
<button onclick={() => console.log(getViewport())}>getViewport</button>
|
<button onclick={() => console.log(getViewport())}>getViewport</button>
|
||||||
|
|
||||||
<button onclick={() => deleteElements({ edges: $edges.map((edge) => ({ id: edge.id })) })}
|
<button onclick={() => deleteElements({ edges: edges.current.map((edge) => ({ id: edge.id })) })}
|
||||||
>delete edges</button
|
>delete edges</button
|
||||||
>
|
>
|
||||||
<button onclick={() => deleteElements({ nodes: [{ id: $nodes[0].id }] })}>delete node</button>
|
<button onclick={() => deleteElements({ nodes: [{ id: nodes.current[0].id }] })}
|
||||||
<button onclick={() => deleteElements({ nodes: $nodes.map((node) => ({ id: node.id })) })}
|
>delete node</button
|
||||||
|
>
|
||||||
|
<button onclick={() => deleteElements({ nodes: nodes.current.map((node) => ({ id: node.id })) })}
|
||||||
>deleteElements</button
|
>deleteElements</button
|
||||||
>
|
>
|
||||||
<button onclick={() => deleteNode()}>delete via store</button>
|
<button onclick={() => deleteNode()}>delete via store</button>
|
||||||
@@ -49,13 +52,15 @@
|
|||||||
>
|
>
|
||||||
|
|
||||||
<div class="label">Nodes:</div>
|
<div class="label">Nodes:</div>
|
||||||
{#each $nodes as node (node.id)}
|
{#each nodes.current as node (node.id)}
|
||||||
<div>id: {node.id} | x: {node.position.x.toFixed(1)} y: {node.position.y.toFixed(1)}</div>
|
<div>id: {node.id} | x: {node.position.x.toFixed(1)} y: {node.position.y.toFixed(1)}</div>
|
||||||
{/each}
|
{/each}
|
||||||
|
|
||||||
<div class="label">Viewport:</div>
|
<div class="label">Viewport:</div>
|
||||||
<div>
|
<div>
|
||||||
x: {$viewport.x.toFixed(1)} y: {$viewport.y.toFixed(1)} zoom: {$viewport.zoom.toFixed(1)}
|
x: {viewport.current.x.toFixed(1)} y: {viewport.current.y.toFixed(1)} zoom: {viewport.current.zoom.toFixed(
|
||||||
|
1
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { writable } from 'svelte/store';
|
|
||||||
import {
|
import {
|
||||||
SvelteFlow,
|
SvelteFlow,
|
||||||
Controls,
|
Controls,
|
||||||
@@ -19,7 +18,7 @@
|
|||||||
custom: CustomNode
|
custom: CustomNode
|
||||||
};
|
};
|
||||||
|
|
||||||
const nodes = writable([
|
const nodes = $state.raw([
|
||||||
{
|
{
|
||||||
id: '1',
|
id: '1',
|
||||||
type: 'custom',
|
type: 'custom',
|
||||||
@@ -40,7 +39,7 @@
|
|||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const edges = writable([
|
const edges = $state.raw([
|
||||||
{
|
{
|
||||||
id: '1-2',
|
id: '1-2',
|
||||||
source: '1',
|
source: '1',
|
||||||
@@ -53,7 +52,7 @@
|
|||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const { updateNode } = useSvelteFlow();
|
const { updateNode } = $derived(useSvelteFlow());
|
||||||
|
|
||||||
const updateNodePosition = () => {
|
const updateNodePosition = () => {
|
||||||
updateNode('1', (node) => ({ position: { x: node.position.x + 10, y: node.position.y } }));
|
updateNode('1', (node) => ({ position: { x: node.position.x + 10, y: node.position.y } }));
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
onedgemouseleave
|
onedgemouseleave
|
||||||
}: { store: SvelteFlowStore; edge: EdgeLayouted } & EdgeEvents = $props();
|
}: { store: SvelteFlowStore; edge: EdgeLayouted } & EdgeEvents = $props();
|
||||||
|
|
||||||
|
$inspect(edge);
|
||||||
|
|
||||||
let {
|
let {
|
||||||
source,
|
source,
|
||||||
target,
|
target,
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
const previous = previousLayoutedEdges.get(edge.id);
|
const previous = previousLayoutedEdges.get(edge.id);
|
||||||
if (
|
if (
|
||||||
previous &&
|
previous &&
|
||||||
edge == previous.edge &&
|
edge === previous.edge &&
|
||||||
sourceNode == previous.sourceNode &&
|
sourceNode == previous.sourceNode &&
|
||||||
targetNode == previous.targetNode
|
targetNode == previous.targetNode
|
||||||
) {
|
) {
|
||||||
|
|||||||
+17
-2
@@ -4,7 +4,7 @@ import { useStore } from '$lib/store';
|
|||||||
* Hook for getting the current nodes from the store.
|
* Hook for getting the current nodes from the store.
|
||||||
*
|
*
|
||||||
* @public
|
* @public
|
||||||
* @returns store with an array of nodes
|
* @returns reactive signal of the current edges
|
||||||
*/
|
*/
|
||||||
export function useNodes() {
|
export function useNodes() {
|
||||||
const { nodes } = $derived(useStore());
|
const { nodes } = $derived(useStore());
|
||||||
@@ -19,7 +19,7 @@ export function useNodes() {
|
|||||||
* Hook for getting the current edges from the store.
|
* Hook for getting the current edges from the store.
|
||||||
*
|
*
|
||||||
* @public
|
* @public
|
||||||
* @returns store with an array of edges
|
* @returns reactive signal of the current edges
|
||||||
*/
|
*/
|
||||||
export function useEdges() {
|
export function useEdges() {
|
||||||
const { edges } = $derived(useStore());
|
const { edges } = $derived(useStore());
|
||||||
@@ -29,3 +29,18 @@ export function useEdges() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook for getting the current viewport from the store.
|
||||||
|
*
|
||||||
|
* @public
|
||||||
|
* @returns reactive signal of the current viewport
|
||||||
|
*/
|
||||||
|
export function useViewport() {
|
||||||
|
const { viewport } = $derived(useStore());
|
||||||
|
return {
|
||||||
|
get current() {
|
||||||
|
return viewport;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
+1
-1
@@ -370,7 +370,7 @@ export function useSvelteFlow(): {
|
|||||||
|
|
||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
},
|
},
|
||||||
getViewport: () => store.viewport,
|
getViewport: () => $state.snapshot(store.viewport),
|
||||||
setCenter: async (x, y, options) => {
|
setCenter: async (x, y, options) => {
|
||||||
const nextZoom = typeof options?.zoom !== 'undefined' ? options.zoom : store.maxZoom;
|
const nextZoom = typeof options?.zoom !== 'undefined' ? options.zoom : store.maxZoom;
|
||||||
const currentPanZoom = store.panZoom;
|
const currentPanZoom = store.panZoom;
|
||||||
+2
-3
@@ -1,4 +1,3 @@
|
|||||||
import { get } from 'svelte/store';
|
|
||||||
import type { UpdateNodeInternals } from '@xyflow/system';
|
import type { UpdateNodeInternals } from '@xyflow/system';
|
||||||
|
|
||||||
import { useStore } from '$lib/store';
|
import { useStore } from '$lib/store';
|
||||||
@@ -10,7 +9,7 @@ import { useStore } from '$lib/store';
|
|||||||
* @returns function for updating node internals
|
* @returns function for updating node internals
|
||||||
*/
|
*/
|
||||||
export function useUpdateNodeInternals(): UpdateNodeInternals {
|
export function useUpdateNodeInternals(): UpdateNodeInternals {
|
||||||
const { domNode, updateNodeInternals } = useStore();
|
const { domNode, updateNodeInternals } = $derived(useStore());
|
||||||
|
|
||||||
// @todo: do we want to add this to system?
|
// @todo: do we want to add this to system?
|
||||||
const updateInternals = (id: string | string[]) => {
|
const updateInternals = (id: string | string[]) => {
|
||||||
@@ -18,7 +17,7 @@ export function useUpdateNodeInternals(): UpdateNodeInternals {
|
|||||||
const updates = new Map();
|
const updates = new Map();
|
||||||
|
|
||||||
updateIds.forEach((updateId) => {
|
updateIds.forEach((updateId) => {
|
||||||
const nodeElement = get(domNode)?.querySelector(
|
const nodeElement = domNode?.querySelector(
|
||||||
`.svelte-flow__node[data-id="${updateId}"]`
|
`.svelte-flow__node[data-id="${updateId}"]`
|
||||||
) as HTMLDivElement;
|
) as HTMLDivElement;
|
||||||
|
|
||||||
@@ -31,10 +31,10 @@ export { useStore } from '$lib/store';
|
|||||||
export * from '$lib/utils';
|
export * from '$lib/utils';
|
||||||
|
|
||||||
//hooks
|
//hooks
|
||||||
export * from '$lib/hooks/useSvelteFlow';
|
export * from '$lib/hooks/useSvelteFlow.svelte';
|
||||||
export * from '$lib/hooks/useUpdateNodeInternals';
|
export * from '$lib/hooks/useUpdateNodeInternals.svelte';
|
||||||
export * from '$lib/hooks/useConnection.svelte';
|
export * from '$lib/hooks/useConnection.svelte';
|
||||||
export * from '$lib/hooks/useNodesEdges.svelte';
|
export * from '$lib/hooks/useNodesEdgesViewport.svelte';
|
||||||
export * from '$lib/hooks/useHandleConnections.svelte';
|
export * from '$lib/hooks/useHandleConnections.svelte';
|
||||||
export * from '$lib/hooks/useNodesData';
|
export * from '$lib/hooks/useNodesData';
|
||||||
export * from '$lib/hooks/useInternalNode';
|
export * from '$lib/hooks/useInternalNode';
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
type XYResizerChildChange
|
type XYResizerChildChange
|
||||||
} from '@xyflow/system';
|
} from '@xyflow/system';
|
||||||
import type { ResizeControlProps } from './types';
|
import type { ResizeControlProps } from './types';
|
||||||
import { get } from 'svelte/store';
|
import { useSvelteFlow } from '$lib/hooks/useSvelteFlow.svelte';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
nodeId,
|
nodeId,
|
||||||
@@ -34,6 +34,8 @@
|
|||||||
|
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
|
|
||||||
|
const { updateNode } = useSvelteFlow();
|
||||||
|
|
||||||
let id = $derived(
|
let id = $derived(
|
||||||
typeof nodeId === 'string' ? nodeId : getContext<string>('svelteflow__node_id')
|
typeof nodeId === 'string' ? nodeId : getContext<string>('svelteflow__node_id')
|
||||||
);
|
);
|
||||||
@@ -72,28 +74,20 @@
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
onChange: (change: XYResizerChange, childChanges: XYResizerChildChange[]) => {
|
onChange: (change: XYResizerChange, childChanges: XYResizerChildChange[]) => {
|
||||||
const node = store.nodeLookup.get(id)?.internals.userNode;
|
updateNode(id, (node) => ({
|
||||||
if (!node) {
|
...node,
|
||||||
return;
|
position: { x: change.x ?? node.position.x, y: change.y ?? node.position.y },
|
||||||
}
|
width: change.width ?? node.width,
|
||||||
|
height: change.height ?? node.height
|
||||||
if (change.x !== undefined && change.y !== undefined) {
|
}));
|
||||||
node.position = { x: change.x, y: change.y };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (change.width !== undefined && change.height !== undefined) {
|
|
||||||
node.width = change.width;
|
|
||||||
node.height = change.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// TODO: performance?
|
||||||
for (const childChange of childChanges) {
|
for (const childChange of childChanges) {
|
||||||
const childNode = store.nodeLookup.get(childChange.id)?.internals.userNode;
|
updateNode(childChange.id, (node) => ({
|
||||||
if (childNode) {
|
...node,
|
||||||
childNode.position = childChange.position;
|
position: childChange.position
|
||||||
}
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// store.nodes.set(get(store.nodes));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import portal from '$lib/actions/portal';
|
import portal from '$lib/actions/portal';
|
||||||
import { useStore } from '$lib/store';
|
import { useStore } from '$lib/store';
|
||||||
import { useSvelteFlow } from '$lib/hooks/useSvelteFlow';
|
import { useSvelteFlow } from '$lib/hooks/useSvelteFlow.svelte';
|
||||||
|
|
||||||
import type { InternalNode } from '$lib/types';
|
import type { InternalNode } from '$lib/types';
|
||||||
import type { NodeToolbarProps } from './types';
|
import type { NodeToolbarProps } from './types';
|
||||||
|
|||||||
Reference in New Issue
Block a user