From f29898f0bd9f7b8371919c9bb9b9d51d72621f8f Mon Sep 17 00:00:00 2001 From: peterkogo Date: Fri, 6 Dec 2024 13:53:48 +0100 Subject: [PATCH] WIP: migrated store and useSvelteFlow hook to signals & solved state propagation for provider --- examples/astro-xyflow/src/env.d.ts | 1 + examples/svelte/package.json | 20 +- .../src/routes/examples/edges/+page.svelte | 18 +- .../routes/examples/edges/ButtonEdge.svelte | 52 +- .../routes/examples/intersections/Flow.svelte | 6 +- packages/svelte/package.json | 18 +- packages/svelte/src/lib/actions/drag/index.ts | 20 +- packages/svelte/src/lib/actions/zoom/index.ts | 14 +- .../ConnectionLine/ConnectionLine.svelte | 35 +- .../EdgeLabelRenderer.svelte | 4 +- .../components/EdgeWrapper/EdgeWrapper.svelte | 20 +- .../src/lib/components/Handle/Handle.svelte | 66 +- .../components/KeyHandler/KeyHandler.svelte | 50 +- .../src/lib/components/KeyHandler/types.ts | 2 + .../NodeSelection/NodeSelection.svelte | 11 +- .../src/lib/components/NodeSelection/types.ts | 3 +- .../components/NodeWrapper/NodeWrapper.svelte | 24 +- .../src/lib/components/NodeWrapper/types.ts | 2 + .../SvelteFlowProvider.svelte | 30 +- .../UserSelection/UserSelection.svelte | 12 +- .../ViewportPortal/ViewportPortal.svelte | 4 +- .../EdgeRenderer/EdgeRenderer.svelte | 69 +- .../MarkerDefinition/MarkerDefinition.svelte | 4 +- .../NodeRenderer/NodeRenderer.svelte | 43 +- .../svelte/src/lib/container/Pane/Pane.svelte | 62 +- .../svelte/src/lib/container/Pane/types.ts | 7 +- .../src/lib/container/Panel/Panel.svelte | 4 +- .../container/SvelteFlow/SvelteFlow.svelte | 243 ++---- .../src/lib/container/SvelteFlow/types.ts | 4 + .../src/lib/container/SvelteFlow/utils.ts | 91 --- .../lib/container/Viewport/Viewport.svelte | 8 +- .../svelte/src/lib/container/Zoom/Zoom.svelte | 47 +- .../svelte/src/lib/container/Zoom/types.ts | 2 + .../src/lib/hooks/derivedWarning.svelte.ts | 19 + packages/svelte/src/lib/hooks/index.ts | 1 + packages/svelte/src/lib/hooks/useStore.ts | 21 + ...eSvelteFlow.ts => useSvelteFlow.svelte.ts} | 163 ++-- packages/svelte/src/lib/index.ts | 2 +- .../lib/plugins/Background/Background.svelte | 8 +- .../src/lib/plugins/Controls/Controls.svelte | 33 +- .../src/lib/plugins/Minimap/Minimap.svelte | 39 +- .../plugins/NodeToolbar/NodeToolbar.svelte | 2 +- packages/svelte/src/lib/store/hook.svelte.ts | 24 + packages/svelte/src/lib/store/index.ts | 347 ++++---- .../src/lib/store/initial-store.svelte.ts | 318 ++++++++ packages/svelte/src/lib/store/types.ts | 18 +- packages/svelte/src/lib/store/utils.ts | 4 +- packages/svelte/src/routes/+page.svelte.d.ts | 23 + pnpm-lock.yaml | 747 +++++++++++++----- 49 files changed, 1622 insertions(+), 1143 deletions(-) delete mode 100644 packages/svelte/src/lib/container/SvelteFlow/utils.ts create mode 100644 packages/svelte/src/lib/hooks/derivedWarning.svelte.ts create mode 100644 packages/svelte/src/lib/hooks/index.ts create mode 100644 packages/svelte/src/lib/hooks/useStore.ts rename packages/svelte/src/lib/hooks/{useSvelteFlow.ts => useSvelteFlow.svelte.ts} (82%) create mode 100644 packages/svelte/src/lib/store/hook.svelte.ts create mode 100644 packages/svelte/src/lib/store/initial-store.svelte.ts create mode 100644 packages/svelte/src/routes/+page.svelte.d.ts diff --git a/examples/astro-xyflow/src/env.d.ts b/examples/astro-xyflow/src/env.d.ts index f964fe0c..acef35f1 100644 --- a/examples/astro-xyflow/src/env.d.ts +++ b/examples/astro-xyflow/src/env.d.ts @@ -1 +1,2 @@ +/// /// diff --git a/examples/svelte/package.json b/examples/svelte/package.json index 0cdc4813..4fba871e 100644 --- a/examples/svelte/package.json +++ b/examples/svelte/package.json @@ -13,24 +13,24 @@ }, "devDependencies": { "@sveltejs/adapter-auto": "^3.3.1", - "@sveltejs/kit": "^2.8.0", - "@typescript-eslint/eslint-plugin": "^8.14.0", - "@typescript-eslint/parser": "^8.14.0", + "@sveltejs/kit": "^2.9.0", + "@typescript-eslint/eslint-plugin": "^8.17.0", + "@typescript-eslint/parser": "^8.17.0", "eslint": "^8.53.0", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-svelte": "^2.46.0", - "prettier": "^3.3.3", - "prettier-plugin-svelte": "^3.2.8", - "svelte": "^5.1.16", - "svelte-check": "^4.0.7", + "eslint-plugin-svelte": "^2.46.1", + "prettier": "^3.4.2", + "prettier-plugin-svelte": "^3.3.2", + "svelte": "^5.7.1", + "svelte-check": "^4.1.1", "tslib": "^2.8.1", "typescript": "^5.6.3", - "vite": "^5.4.11" + "vite": "^6.0.3" }, "type": "module", "dependencies": { "@dagrejs/dagre": "^1.1.4", - "@sveltejs/vite-plugin-svelte": "^4.0.0", + "@sveltejs/vite-plugin-svelte": "^5.0.1", "@xyflow/svelte": "workspace:^" } } diff --git a/examples/svelte/src/routes/examples/edges/+page.svelte b/examples/svelte/src/routes/examples/edges/+page.svelte index c51e2dbf..15e92143 100644 --- a/examples/svelte/src/routes/examples/edges/+page.svelte +++ b/examples/svelte/src/routes/examples/edges/+page.svelte @@ -129,23 +129,7 @@ target: '6', label: 'hi', labelStyle: 'background: red; font-weight: 700; padding: 5px;', - style: 'stroke: #ffcc0', - markerEnd: { - type: MarkerType.Arrow, - color: '#FFCC00', - markerUnits: 'userSpaceOnUse', - width: 20, - height: 20, - strokeWidth: 2 - }, - markerStart: { - type: MarkerType.ArrowClosed, - color: '#FFCC00', - orient: 'auto-start-reverse', - markerUnits: 'userSpaceOnUse', - width: 20, - height: 20 - } + style: 'stroke: #ffcc0' } ]); diff --git a/examples/svelte/src/routes/examples/edges/ButtonEdge.svelte b/examples/svelte/src/routes/examples/edges/ButtonEdge.svelte index 93a14a46..9096a029 100644 --- a/examples/svelte/src/routes/examples/edges/ButtonEdge.svelte +++ b/examples/svelte/src/routes/examples/edges/ButtonEdge.svelte @@ -1,10 +1,15 @@ @@ -53,7 +62,24 @@ class="edgeButton" onclick={(event) => { event.stopPropagation(); - alert(`remove ${id}`); + updateEdge('e5-6', { + markerEnd: { + type: MarkerType.Arrow, + color: '#FFCC00', + markerUnits: 'userSpaceOnUse', + width: 20, + height: 20, + strokeWidth: 2 + }, + markerStart: { + type: MarkerType.ArrowClosed, + color: '#FFCC00', + orient: 'auto-start-reverse', + markerUnits: 'userSpaceOnUse', + width: 20, + height: 20 + } + }); }} > × diff --git a/examples/svelte/src/routes/examples/intersections/Flow.svelte b/examples/svelte/src/routes/examples/intersections/Flow.svelte index 253a8903..05d023d0 100644 --- a/examples/svelte/src/routes/examples/intersections/Flow.svelte +++ b/examples/svelte/src/routes/examples/intersections/Flow.svelte @@ -10,9 +10,9 @@ const nodes = writable(initialNodes); const edges = writable(initialEdges); - const { getIntersectingNodes } = useSvelteFlow(); + const { getIntersectingNodes } = $derived(useSvelteFlow()); - function onNodeDrag({ detail: { targetNode } }) { + function onNodeDrag({ targetNode }) { if (targetNode) { const intersections = getIntersectingNodes(targetNode).map((n) => n.id); @@ -25,7 +25,7 @@
- + diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 913259ea..07862bfd 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -56,26 +56,26 @@ }, "devDependencies": { "@sveltejs/adapter-auto": "^3.3.1", - "@sveltejs/kit": "^2.8.0", + "@sveltejs/kit": "^2.9.0", "@sveltejs/package": "^2.3.7", - "@typescript-eslint/eslint-plugin": "^8.14.0", - "@typescript-eslint/parser": "^8.14.0", + "@typescript-eslint/eslint-plugin": "^8.17.0", + "@typescript-eslint/parser": "^8.17.0", "autoprefixer": "^10.4.20", "cssnano": "^7.0.6", - "dotenv": "^16.4.5", + "dotenv": "^16.4.7", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-svelte": "^2.46.0", + "eslint-plugin-svelte": "^2.46.1", "postcss": "^8.4.49", "postcss-cli": "^11.0.0", "postcss-combine-duplicated-selectors": "^10.0.3", "postcss-import": "^16.1.0", "postcss-nested": "^7.0.2", "postcss-rename": "^0.6.1", - "prettier": "^3.3.3", - "prettier-plugin-svelte": "^3.2.8", - "svelte": "^5.1.16", - "svelte-check": "^4.0.7", + "prettier": "^3.4.2", + "prettier-plugin-svelte": "^3.3.2", + "svelte": "^5.7.1", + "svelte-check": "^4.1.1", "svelte-eslint-parser": "^0.43.0", "svelte-preprocess": "^6.0.3", "tslib": "^2.8.1", diff --git a/packages/svelte/src/lib/actions/drag/index.ts b/packages/svelte/src/lib/actions/drag/index.ts index 0d28f4e7..08848ffe 100644 --- a/packages/svelte/src/lib/actions/drag/index.ts +++ b/packages/svelte/src/lib/actions/drag/index.ts @@ -25,24 +25,24 @@ export default function drag(domNode: Element, params: UseDragParams) { onDragStop, onNodeMouseDown, getStoreItems: () => { - const snapGrid = get(store.snapGrid); + const snapGrid = store.snapGrid; const vp = get(store.viewport); return { nodes: get(store.nodes), - nodeLookup: get(store.nodeLookup), + nodeLookup: store.nodeLookup, edges: get(store.edges), - nodeExtent: get(store.nodeExtent), + nodeExtent: store.nodeExtent, snapGrid: snapGrid ? snapGrid : [0, 0], snapToGrid: !!snapGrid, - nodeOrigin: get(store.nodeOrigin), - multiSelectionActive: get(store.multiselectionKeyPressed), - domNode: get(store.domNode), + nodeOrigin: store.nodeOrigin, + multiSelectionActive: store.multiselectionKeyPressed, + domNode: store.domNode, transform: [vp.x, vp.y, vp.zoom], - autoPanOnNodeDrag: get(store.autoPanOnNodeDrag), - nodesDraggable: get(store.nodesDraggable), - selectNodesOnDrag: get(store.selectNodesOnDrag), - nodeDragThreshold: get(store.nodeDragThreshold), + autoPanOnNodeDrag: store.autoPanOnNodeDrag, + nodesDraggable: store.nodesDraggable, + selectNodesOnDrag: store.selectNodesOnDrag, + nodeDragThreshold: store.nodeDragThreshold, unselectNodesAndEdges: store.unselectNodesAndEdges, updateNodePositions: store.updateNodePositions, panBy: store.panBy diff --git a/packages/svelte/src/lib/actions/zoom/index.ts b/packages/svelte/src/lib/actions/zoom/index.ts index 85070d68..36eff896 100644 --- a/packages/svelte/src/lib/actions/zoom/index.ts +++ b/packages/svelte/src/lib/actions/zoom/index.ts @@ -14,13 +14,12 @@ type ZoomParams = { initialViewport: Viewport; minZoom: number; maxZoom: number; - dragging: Writable; + setPanZoomInstance: (panZoomInstance: PanZoomInstance) => void; onPanZoomStart?: OnPanZoom; onPanZoom?: OnPanZoom; onPanZoomEnd?: OnPanZoom; onPaneContextMenu?: (event: MouseEvent) => void; translateExtent: CoordinateExtent; - panZoom: Writable; zoomOnScroll: boolean; zoomOnPinch: boolean; zoomOnDoubleClick: boolean; @@ -38,18 +37,19 @@ type ZoomParams = { lib: string; paneClickDistance: number; onTransformChange: (transform: Transform) => void; + onDraggingChange: (dragging: boolean) => void; }; export default function zoom(domNode: Element, params: ZoomParams) { const { - panZoom, minZoom, maxZoom, initialViewport, viewport, - dragging, translateExtent, - paneClickDistance + paneClickDistance, + setPanZoomInstance, + onDraggingChange } = params; const panZoomInstance = XYPanZoom({ @@ -59,11 +59,11 @@ export default function zoom(domNode: Element, params: ZoomParams) { translateExtent, viewport: initialViewport, paneClickDistance, - onDraggingChange: dragging.set + onDraggingChange }); const currentViewport = panZoomInstance.getViewport(); viewport.set(currentViewport); - panZoom.set(panZoomInstance); + setPanZoomInstance(panZoomInstance); panZoomInstance.update(params); diff --git a/packages/svelte/src/lib/components/ConnectionLine/ConnectionLine.svelte b/packages/svelte/src/lib/components/ConnectionLine/ConnectionLine.svelte index 9a487427..221b9eab 100644 --- a/packages/svelte/src/lib/components/ConnectionLine/ConnectionLine.svelte +++ b/packages/svelte/src/lib/components/ConnectionLine/ConnectionLine.svelte @@ -9,35 +9,37 @@ getStraightPath } from '@xyflow/system'; - import { useStore } from '$lib/store'; + import type { SvelteFlowStore } from '$lib/store/types'; let { + store, containerStyle = '', style = '', connectionLine }: { + store: SvelteFlowStore; containerStyle: string; style: string; connectionLine?: Snippet; } = $props(); - const { width, height, connection, connectionLineType } = useStore(); + // $inspect(store.connection); let path = $derived.by(() => { - if (!$connection.inProgress) { + if (!store.connection.inProgress) { return ''; } const pathParams = { - sourceX: $connection.from.x, - sourceY: $connection.from.y, - sourcePosition: $connection.fromPosition, - targetX: $connection.to.x, - targetY: $connection.to.y, - targetPosition: $connection.toPosition + sourceX: store.connection.from.x, + sourceY: store.connection.from.y, + sourcePosition: store.connection.fromPosition, + targetX: store.connection.to.x, + targetY: store.connection.to.y, + targetPosition: store.connection.toPosition }; - switch ($connectionLineType) { + switch (store.connectionLineType) { case ConnectionLineType.Bezier: { const [path] = getBezierPath(pathParams); return path; @@ -50,7 +52,7 @@ case ConnectionLineType.SmoothStep: { const [path] = getSmoothStepPath({ ...pathParams, - borderRadius: $connectionLineType === ConnectionLineType.Step ? 0 : undefined + borderRadius: store.connectionLineType === ConnectionLineType.Step ? 0 : undefined }); return path; } @@ -58,9 +60,14 @@ }); -{#if $connection.inProgress} - - +{#if store.connection.inProgress} + + {#if connectionLine} {@render connectionLine()} {:else} diff --git a/packages/svelte/src/lib/components/EdgeLabelRenderer/EdgeLabelRenderer.svelte b/packages/svelte/src/lib/components/EdgeLabelRenderer/EdgeLabelRenderer.svelte index 3b561ae4..1b09ffb8 100644 --- a/packages/svelte/src/lib/components/EdgeLabelRenderer/EdgeLabelRenderer.svelte +++ b/packages/svelte/src/lib/components/EdgeLabelRenderer/EdgeLabelRenderer.svelte @@ -3,11 +3,11 @@ import portal from '$lib/actions/portal'; import { useStore } from '$lib/store'; - const { domNode } = useStore(); + const store = useStore(); let { children }: { children?: Snippet } = $props(); -
+
{@render children?.()}
diff --git a/packages/svelte/src/lib/components/EdgeWrapper/EdgeWrapper.svelte b/packages/svelte/src/lib/components/EdgeWrapper/EdgeWrapper.svelte index acaf86c6..d235ee72 100644 --- a/packages/svelte/src/lib/components/EdgeWrapper/EdgeWrapper.svelte +++ b/packages/svelte/src/lib/components/EdgeWrapper/EdgeWrapper.svelte @@ -9,10 +9,12 @@ import { useHandleEdgeSelect } from '$lib/hooks/useHandleEdgeSelect'; import type { EdgeLayouted, Edge, EdgeEvents } from '$lib/types'; + import type { SvelteFlowStore } from '$lib/store/types'; const { id, type = 'default', + store, source, target, data = {}, @@ -42,24 +44,24 @@ onedgecontextmenu, onedgemouseenter, onedgemouseleave - }: EdgeLayouted & EdgeEvents = $props(); + }: { store: SvelteFlowStore } & EdgeLayouted & EdgeEvents = $props(); setContext('svelteflow__edge_id', id); - const { edgeLookup, edgeTypes, flowId, elementsSelectable } = useStore(); - let edgeType = $derived(type ?? 'default'); - let EdgeComponent = $derived($edgeTypes[edgeType] ?? BezierEdgeInternal); + let EdgeComponent = $derived(store.edgeTypes[edgeType] ?? BezierEdgeInternal); let markerStartUrl = $derived( - markerStart ? `url('#${getMarkerId(markerStart, $flowId)}')` : undefined + markerStart ? `url('#${getMarkerId(markerStart, store.flowId)}')` : undefined ); - let markerEndUrl = $derived(markerEnd ? `url('#${getMarkerId(markerEnd, $flowId)}')` : undefined); - let isSelectable = $derived(selectable ?? $elementsSelectable); + let markerEndUrl = $derived( + markerEnd ? `url('#${getMarkerId(markerEnd, store.flowId)}')` : undefined + ); + let isSelectable = $derived(selectable ?? store.elementsSelectable); const handleEdgeSelect = useHandleEdgeSelect(); function onclick(event: MouseEvent | TouchEvent) { - const edge = $edgeLookup.get(id); + const edge = store.edgeLookup.get(id); if (edge) { handleEdgeSelect(id); @@ -71,7 +73,7 @@ event: MouseEvent, callback: ({ edge, event }: { edge: Edge; event: MouseEvent }) => void ) { - const edge = $edgeLookup.get(id); + const edge = store.edgeLookup.get(id); if (edge) { callback({ event, edge }); diff --git a/packages/svelte/src/lib/components/Handle/Handle.svelte b/packages/svelte/src/lib/components/Handle/Handle.svelte index f0721989..eb847c44 100644 --- a/packages/svelte/src/lib/components/Handle/Handle.svelte +++ b/packages/svelte/src/lib/components/Handle/Handle.svelte @@ -39,28 +39,8 @@ isConnectableProp !== undefined ? isConnectableProp : isConnectableContext.value ); - const { - connectionMode, - domNode, - nodeLookup, - connectionRadius, - viewport, - isValidConnection: isValidConnectionStore, - lib, - addEdge, - onedgecreate, - panBy, - cancelConnection, - updateConnection, - autoPanOnConnect, - edges, - connectionLookup, - onconnect: onConnectAction, - onconnectstart: onConnectStartAction, - onconnectend: onConnectEndAction, - flowId, - connection - } = useStore(); + let store = useStore(); + let { viewport, edges } = store; function onPointerDown(event: MouseEvent | TouchEvent) { const isMouseTriggered = isMouseEvent(event); @@ -70,39 +50,39 @@ handleId, nodeId, isTarget, - connectionRadius: $connectionRadius, - domNode: $domNode, - nodeLookup: $nodeLookup, - connectionMode: $connectionMode, - lib: $lib, - autoPanOnConnect: $autoPanOnConnect, - flowId: $flowId, - isValidConnection: isValidConnectionProp ?? $isValidConnectionStore, - updateConnection, - cancelConnection, - panBy, + connectionRadius: store.connectionRadius, + domNode: store.domNode, + nodeLookup: store.nodeLookup, + connectionMode: store.connectionMode, + lib: 'svelte', + autoPanOnConnect: store.autoPanOnConnect, + flowId: store.flowId, + isValidConnection: isValidConnectionProp ?? store.isValidConnection, + updateConnection: store.updateConnection, + cancelConnection: store.cancelConnection, + panBy: store.panBy, onConnect: (connection) => { - const edge = $onedgecreate ? $onedgecreate(connection) : connection; + const edge = store.onedgecreate ? store.onedgecreate(connection) : connection; if (!edge) { return; } - addEdge(edge); - $onConnectAction?.(connection); + store.addEdge(edge); + store.onconnect?.(connection); }, onConnectStart: (event, startParams) => { - $onConnectStartAction?.(event, { + store.onconnectstart?.(event, { nodeId: startParams.nodeId, handleId: startParams.handleId, handleType: startParams.handleType }); }, onConnectEnd: (event, connectionState) => { - $onConnectEndAction?.(event, connectionState); + store.onconnectend?.(event, connectionState); }, getTransform: () => [$viewport.x, $viewport.y, $viewport.zoom], - getFromHandle: () => $connection.fromHandle + getFromHandle: () => store.connection.fromHandle }); } } @@ -113,7 +93,7 @@ // eslint-disable-next-line @typescript-eslint/no-unused-expressions $edges; if (onconnect || ondisconnect) { - let connections = $connectionLookup.get(`${nodeId}-${type}-${handleId}`); + let connections = store.connectionLookup.get(`${nodeId}-${type}-${handleId}`); if (prevConnections && !areConnectionMapsEqual(connections, prevConnections)) { const _connections = connections ?? new Map(); @@ -128,7 +108,7 @@ let [connectionInProcess, connectingFrom, connectingTo, isPossibleEndHandle, valid] = $derived.by( () => { - const { fromHandle, toHandle, isValid } = $connection; + const { fromHandle, toHandle, isValid } = store.connection; const connectionInProcess = !!fromHandle; @@ -139,7 +119,7 @@ toHandle?.nodeId === nodeId && toHandle?.type === type && toHandle?.id === handleId; const isPossibleEndHandle = - $connectionMode === ConnectionMode.Strict + store.connectionMode === ConnectionMode.Strict ? fromHandle?.type !== type : nodeId !== fromHandle?.nodeId || handleId !== fromHandle?.id; @@ -158,7 +138,7 @@ The Handle component is the part of a node that can be used to connect nodes. data-handleid={handleId} data-nodeid={nodeId} data-handlepos={position} - data-id="{$flowId}-{nodeId}-{handleId}-{type}" + data-id="{store.flowId}-{nodeId}-{handleId}-{type}" class={cc([ 'svelte-flow__handle', `svelte-flow__handle-${position}`, diff --git a/packages/svelte/src/lib/components/KeyHandler/KeyHandler.svelte b/packages/svelte/src/lib/components/KeyHandler/KeyHandler.svelte index 721365e7..ccbbf90a 100644 --- a/packages/svelte/src/lib/components/KeyHandler/KeyHandler.svelte +++ b/packages/svelte/src/lib/components/KeyHandler/KeyHandler.svelte @@ -12,6 +12,7 @@ import type { KeyDefinition, KeyDefinitionObject } from '$lib/types'; let { + store, selectionKey = 'Shift', multiSelectionKey = isMacOs() ? 'Meta' : 'Control', deleteKey = 'Backspace', @@ -19,18 +20,7 @@ zoomActivationKey = isMacOs() ? 'Meta' : 'Control' }: KeyHandlerProps = $props(); - const { - selectionKeyPressed, - multiselectionKeyPressed, - deleteKeyPressed, - panActivationKeyPressed, - zoomActivationKeyPressed, - selectionRect, - onbeforedelete, - ondelete, - nodes: _nodes, - edges: _edges - } = useStore(); + const { nodes: _nodes, edges: _edges } = store; function isKeyObject(key?: KeyDefinition | null): key is KeyDefinitionObject { return key !== null && typeof key === 'object'; @@ -67,12 +57,12 @@ } function resetKeysAndSelection() { - selectionRect.set(null); - selectionKeyPressed.set(false); - multiselectionKeyPressed.set(false); - deleteKeyPressed.set(false); - panActivationKeyPressed.set(false); - zoomActivationKeyPressed.set(false); + store.selectionRect = null; + store.selectionKeyPressed = false; + store.multiselectionKeyPressed = false; + store.deleteKeyPressed = false; + store.panActivationKeyPressed = false; + store.zoomActivationKeyPressed = false; } async function handleDelete() { @@ -86,14 +76,14 @@ edgesToRemove: selectedEdges, nodes, edges, - onBeforeDelete: get(onbeforedelete) + onBeforeDelete: store.onbeforedelete }); if (matchingNodes.length || matchingEdges.length) { _nodes.update((nds) => nds.filter((node) => !matchingNodes.some((mN) => mN.id === node.id))); _edges.update((eds) => eds.filter((edge) => !matchingEdges.some((mE) => mE.id === edge.id))); - get(ondelete)?.({ + store.ondelete?.({ nodes: matchingNodes, edges: matchingEdges }); @@ -105,19 +95,19 @@ on:blur={resetKeysAndSelection} on:contextmenu={resetKeysAndSelection} use:shortcut={{ - trigger: getShortcutTrigger(selectionKey, () => selectionKeyPressed.set(true)), + trigger: getShortcutTrigger(selectionKey, () => (store.selectionKeyPressed = true)), type: 'keydown' }} use:shortcut={{ - trigger: getShortcutTrigger(selectionKey, () => selectionKeyPressed.set(false)), + trigger: getShortcutTrigger(selectionKey, () => (store.selectionKeyPressed = false)), type: 'keyup' }} use:shortcut={{ - trigger: getShortcutTrigger(multiSelectionKey, () => multiselectionKeyPressed.set(true)), + trigger: getShortcutTrigger(multiSelectionKey, () => (store.multiselectionKeyPressed = true)), type: 'keydown' }} use:shortcut={{ - trigger: getShortcutTrigger(multiSelectionKey, () => multiselectionKeyPressed.set(false)), + trigger: getShortcutTrigger(multiSelectionKey, () => (store.multiselectionKeyPressed = false)), type: 'keyup' }} use:shortcut={{ @@ -127,30 +117,30 @@ detail.originalEvent.metaKey || detail.originalEvent.shiftKey; if (!isModifierKey && !isInputDOMNode(detail.originalEvent)) { - deleteKeyPressed.set(true); + store.deleteKeyPressed = true; handleDelete(); } }), type: 'keydown' }} use:shortcut={{ - trigger: getShortcutTrigger(deleteKey, () => deleteKeyPressed.set(false)), + trigger: getShortcutTrigger(deleteKey, () => (store.deleteKeyPressed = false)), type: 'keyup' }} use:shortcut={{ - trigger: getShortcutTrigger(panActivationKey, () => panActivationKeyPressed.set(true)), + trigger: getShortcutTrigger(panActivationKey, () => (store.panActivationKeyPressed = true)), type: 'keydown' }} use:shortcut={{ - trigger: getShortcutTrigger(panActivationKey, () => panActivationKeyPressed.set(false)), + trigger: getShortcutTrigger(panActivationKey, () => (store.panActivationKeyPressed = false)), type: 'keyup' }} use:shortcut={{ - trigger: getShortcutTrigger(zoomActivationKey, () => zoomActivationKeyPressed.set(true)), + trigger: getShortcutTrigger(zoomActivationKey, () => (store.zoomActivationKeyPressed = true)), type: 'keydown' }} use:shortcut={{ - trigger: getShortcutTrigger(zoomActivationKey, () => zoomActivationKeyPressed.set(false)), + trigger: getShortcutTrigger(zoomActivationKey, () => (store.zoomActivationKeyPressed = false)), type: 'keyup' }} /> diff --git a/packages/svelte/src/lib/components/KeyHandler/types.ts b/packages/svelte/src/lib/components/KeyHandler/types.ts index 0df03d76..a7461883 100644 --- a/packages/svelte/src/lib/components/KeyHandler/types.ts +++ b/packages/svelte/src/lib/components/KeyHandler/types.ts @@ -1,6 +1,8 @@ +import type { SvelteFlowStore } from '$lib/store/types'; import type { KeyDefinition } from '$lib/types'; export type KeyHandlerProps = { + store: SvelteFlowStore; selectionKey?: KeyDefinition | KeyDefinition[] | null; multiSelectionKey?: KeyDefinition | KeyDefinition[] | null; deleteKey?: KeyDefinition | KeyDefinition[] | null; diff --git a/packages/svelte/src/lib/components/NodeSelection/NodeSelection.svelte b/packages/svelte/src/lib/components/NodeSelection/NodeSelection.svelte index f9e9cf88..0a8a8957 100644 --- a/packages/svelte/src/lib/components/NodeSelection/NodeSelection.svelte +++ b/packages/svelte/src/lib/components/NodeSelection/NodeSelection.svelte @@ -1,13 +1,13 @@ -{#if $selectionRectMode === 'nodes' && bounds && isNumeric(bounds.x) && isNumeric(bounds.y)} +{#if store.selectionRectMode === 'nodes' && bounds && isNumeric(bounds.x) && isNumeric(bounds.y)}
; diff --git a/packages/svelte/src/lib/components/NodeWrapper/NodeWrapper.svelte b/packages/svelte/src/lib/components/NodeWrapper/NodeWrapper.svelte index 308d0167..03e6cc70 100644 --- a/packages/svelte/src/lib/components/NodeWrapper/NodeWrapper.svelte +++ b/packages/svelte/src/lib/components/NodeWrapper/NodeWrapper.svelte @@ -1,17 +1,16 @@ diff --git a/packages/svelte/src/lib/components/ViewportPortal/ViewportPortal.svelte b/packages/svelte/src/lib/components/ViewportPortal/ViewportPortal.svelte index 2262c26b..d6aeb46a 100644 --- a/packages/svelte/src/lib/components/ViewportPortal/ViewportPortal.svelte +++ b/packages/svelte/src/lib/components/ViewportPortal/ViewportPortal.svelte @@ -6,9 +6,9 @@ let { children }: { children?: Snippet } = $props(); - const { domNode } = useStore(); + const store = useStore(); -
+
{@render children?.()}
diff --git a/packages/svelte/src/lib/container/EdgeRenderer/EdgeRenderer.svelte b/packages/svelte/src/lib/container/EdgeRenderer/EdgeRenderer.svelte index 2fab5055..5c2ab8b5 100644 --- a/packages/svelte/src/lib/container/EdgeRenderer/EdgeRenderer.svelte +++ b/packages/svelte/src/lib/container/EdgeRenderer/EdgeRenderer.svelte @@ -1,29 +1,59 @@ @@ -32,8 +62,9 @@ - {#each $visibleEdges as edge (edge.id)} + {#each layoutedEdges as edge (edge.id)}