diff --git a/packages/svelte/README.md b/packages/svelte/README.md index cedf99aa..5de9a3fc 100644 --- a/packages/svelte/README.md +++ b/packages/svelte/README.md @@ -39,7 +39,7 @@ A basic flow looks like this: custom: CustomNode }; - // We are using writables for the nodes to sync them easily. When a user drags a node for example, Svelte Flow updates its position. + // We are using writables for the nodes and edges to sync them easily. When a user drags a node for example, Svelte Flow updates its position. // This also makes it easier to update nodes in user land. const nodes = writable([ { diff --git a/packages/svelte/src/lib/container/NodeRenderer/NodeRenderer.svelte b/packages/svelte/src/lib/container/NodeRenderer/NodeRenderer.svelte index 7bf598c2..685e163f 100644 --- a/packages/svelte/src/lib/container/NodeRenderer/NodeRenderer.svelte +++ b/packages/svelte/src/lib/container/NodeRenderer/NodeRenderer.svelte @@ -5,8 +5,13 @@ import { NodeWrapper } from '$lib/components/NodeWrapper'; import { useStore } from '$lib/store'; - const { nodes, nodesDraggable, nodesConnectable, elementsSelectable, updateNodeDimensions } = - useStore(); + const { + visibleNodes, + nodesDraggable, + nodesConnectable, + elementsSelectable, + updateNodeDimensions + } = useStore(); const resizeObserver: ResizeObserver | null = typeof ResizeObserver === 'undefined' @@ -26,7 +31,7 @@
- {#each $nodes as node (node.id)} + {#each $visibleNodes as node (node.id)} {@const posOrigin = getPositionWithOrigin({ x: node.positionAbsolute?.x ?? 0, y: node.positionAbsolute?.y ?? 0, diff --git a/packages/svelte/src/lib/container/SvelteFlow/SvelteFlow.svelte b/packages/svelte/src/lib/container/SvelteFlow/SvelteFlow.svelte index 2a9c8058..592c3a61 100644 --- a/packages/svelte/src/lib/container/SvelteFlow/SvelteFlow.svelte +++ b/packages/svelte/src/lib/container/SvelteFlow/SvelteFlow.svelte @@ -42,6 +42,7 @@ export let onMoveEnd: $$Props['onMoveEnd'] = undefined; export let isValidConnection: $$Props['isValidConnection'] = undefined; export let translateExtent: $$Props['translateExtent'] = undefined; + export let onlyRenderVisibleElements: $$Props['onlyRenderVisibleElements'] = undefined; export let panOnScrollMode: PanOnScrollMode = PanOnScrollMode.Free; export let preventScrolling: boolean = true; export let zoomOnScroll: boolean = true; @@ -99,6 +100,7 @@ nodesDraggable, nodesConnectable, elementsSelectable, + onlyRenderVisibleElements, isValidConnection }; diff --git a/packages/svelte/src/lib/container/SvelteFlow/types.ts b/packages/svelte/src/lib/container/SvelteFlow/types.ts index 95fc9a0f..9f5cc0f4 100644 --- a/packages/svelte/src/lib/container/SvelteFlow/types.ts +++ b/packages/svelte/src/lib/container/SvelteFlow/types.ts @@ -46,6 +46,7 @@ export type SvelteFlowProps = DOMAttributes & { zoomOnPinch?: boolean; panOnScroll?: boolean; panOnDrag?: boolean | number[]; + onlyRenderVisibleElements?: boolean; class?: string; style?: string; diff --git a/packages/svelte/src/lib/container/SvelteFlow/utils.ts b/packages/svelte/src/lib/container/SvelteFlow/utils.ts index a6ae47df..ce82b5cd 100644 --- a/packages/svelte/src/lib/container/SvelteFlow/utils.ts +++ b/packages/svelte/src/lib/container/SvelteFlow/utils.ts @@ -57,6 +57,7 @@ export type UpdatableStoreProps = { nodesDraggable?: UnwrapWritable; nodesConnectable?: UnwrapWritable; elementsSelectable?: UnwrapWritable; + onlyRenderVisibleElements?: UnwrapWritable; isValidConnection?: UnwrapWritable; }; diff --git a/packages/svelte/src/lib/store/index.ts b/packages/svelte/src/lib/store/index.ts index d519e3ce..9934076d 100644 --- a/packages/svelte/src/lib/store/index.ts +++ b/packages/svelte/src/lib/store/index.ts @@ -29,6 +29,7 @@ import { import type { SvelteFlowStore } from './types'; import { syncNodeStores, syncEdgeStores } from './utils'; import { getEdgeTree } from './edge-tree'; +import { getVisibleNodes } from './visible-nodes'; export const key = Symbol(); @@ -343,6 +344,7 @@ export function createStore(): SvelteFlowStore { // derived state edgeTree: getEdgeTree(store, onError), connectionPath: getConnectionPath(store), + visibleNodes: getVisibleNodes(store), markers: derived( [store.edges, store.defaultMarkerColor, store.flowId], ([edges, defaultColor, id]) => createMarkerIds(edges, { defaultColor, id }) diff --git a/packages/svelte/src/lib/store/initial-store.ts b/packages/svelte/src/lib/store/initial-store.ts index a58e9237..84b576df 100644 --- a/packages/svelte/src/lib/store/initial-store.ts +++ b/packages/svelte/src/lib/store/initial-store.ts @@ -21,7 +21,7 @@ import BezierEdge from '$lib/components/edges/BezierEdge.svelte'; import StraightEdge from '$lib/components/edges/StraightEdge.svelte'; import SmoothStepEdge from '$lib/components/edges/SmoothStepEdge.svelte'; import StepEdge from '$lib/components/edges/StepEdge.svelte'; -import type { ConnectionData, NodeTypes, EdgeTypes, EdgeLayouted } from '$lib/types'; +import type { ConnectionData, NodeTypes, EdgeTypes, EdgeLayouted, Node } from '$lib/types'; import { createNodes, createEdges } from './utils'; export const initConnectionData = { @@ -47,6 +47,7 @@ export const initialEdgeTypes = { export const getInitialStore = () => ({ flowId: writable(null), nodes: createNodes([]), + visibleNodes: readable([]), edges: createEdges([]), edgeTree: readable[]>([]), height: writable(500), diff --git a/packages/svelte/src/lib/store/visible-nodes.ts b/packages/svelte/src/lib/store/visible-nodes.ts new file mode 100644 index 00000000..5fff7fd6 --- /dev/null +++ b/packages/svelte/src/lib/store/visible-nodes.ts @@ -0,0 +1,16 @@ +import { derived } from 'svelte/store'; +import { getNodesInside } from '@xyflow/system'; + +import type { Node } from '$lib/types'; +import type { SvelteFlowStoreState } from './types'; + +export function getVisibleNodes(store: SvelteFlowStoreState) { + return derived( + [store.nodes, store.onlyRenderVisibleElements, store.width, store.height, store.transform], + ([nodes, onlyRenderVisibleElements, width, height, transform]) => { + return onlyRenderVisibleElements + ? getNodesInside(nodes, { x: 0, y: 0, width, height }, transform, true) + : nodes; + } + ); +}