diff --git a/packages/svelte/src/lib/components/EdgeLabel/EdgeLabel.svelte b/packages/svelte/src/lib/components/EdgeLabel/EdgeLabel.svelte index 4c0be0c0..e60899c7 100644 --- a/packages/svelte/src/lib/components/EdgeLabel/EdgeLabel.svelte +++ b/packages/svelte/src/lib/components/EdgeLabel/EdgeLabel.svelte @@ -2,7 +2,7 @@ import { getContext, type Snippet } from 'svelte'; import { EdgeLabelRenderer } from '$lib/components/EdgeLabelRenderer'; - import { useHandleEdgeSelect } from '$lib/hooks/useHandleEdgeSelect'; + import { useStore } from '$lib/store'; let { style, @@ -16,7 +16,7 @@ children?: Snippet; } = $props(); - const handleEdgeSelect = useHandleEdgeSelect(); + const store = useStore(); const id = getContext('svelteflow__edge_id'); @@ -30,7 +30,7 @@ tabindex="-1" onkeyup={() => {}} onclick={() => { - if (id) handleEdgeSelect(id); + if (id) store.handleEdgeSelection(id); }} > {@render children?.()} diff --git a/packages/svelte/src/lib/components/EdgeWrapper/EdgeWrapper.svelte b/packages/svelte/src/lib/components/EdgeWrapper/EdgeWrapper.svelte index faad3aec..df120dc8 100644 --- a/packages/svelte/src/lib/components/EdgeWrapper/EdgeWrapper.svelte +++ b/packages/svelte/src/lib/components/EdgeWrapper/EdgeWrapper.svelte @@ -5,7 +5,6 @@ import { getMarkerId } from '@xyflow/system'; import { BezierEdgeInternal } from '$lib/components/edges'; - import { useHandleEdgeSelect } from '$lib/hooks/useHandleEdgeSelect'; import type { EdgeLayouted, Edge, EdgeEvents } from '$lib/types'; import type { SvelteFlowStore } from '$lib/store/types'; @@ -61,13 +60,11 @@ markerEnd ? `url('#${getMarkerId(markerEnd, store.flowId)}')` : undefined ); - const handleEdgeSelect = useHandleEdgeSelect(); - function onclick(event: MouseEvent | TouchEvent) { const edge = store.edgeLookup.get(id); if (edge) { - handleEdgeSelect(id); + store.handleEdgeSelection(id); onedgeclick?.({ event, edge }); } } diff --git a/packages/svelte/src/lib/hooks/useColorMode.ts b/packages/svelte/src/lib/hooks/useColorMode.svelte.ts similarity index 100% rename from packages/svelte/src/lib/hooks/useColorMode.ts rename to packages/svelte/src/lib/hooks/useColorMode.svelte.ts diff --git a/packages/svelte/src/lib/hooks/useHandleEdgeSelect.ts b/packages/svelte/src/lib/hooks/useHandleEdgeSelect.ts deleted file mode 100644 index 2b6b1ff0..00000000 --- a/packages/svelte/src/lib/hooks/useHandleEdgeSelect.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { errorMessages } from '@xyflow/system'; - -import { useStore } from '$lib/store'; - -export function useHandleEdgeSelect() { - const store = useStore(); - - return (id: string) => { - const edge = store.edgeLookup.get(id); - - if (!edge) { - console.warn('012', errorMessages['error012'](id)); - return; - } - - const selectable = - edge.selectable || (store.elementsSelectable && typeof edge.selectable === 'undefined'); - - if (selectable) { - store.selectionRect = null; - store.selectionRectMode = null; - - if (!edge.selected) { - store.addSelectedEdges([id]); - } else if (edge.selected && store.multiselectionKeyPressed) { - store.unselectNodesAndEdges({ nodes: [], edges: [edge] }); - } - } - }; -} diff --git a/packages/svelte/src/lib/hooks/useInitialized.ts b/packages/svelte/src/lib/hooks/useInitialized.svelte.ts similarity index 55% rename from packages/svelte/src/lib/hooks/useInitialized.ts rename to packages/svelte/src/lib/hooks/useInitialized.svelte.ts index 0f486abf..aa897901 100644 --- a/packages/svelte/src/lib/hooks/useInitialized.ts +++ b/packages/svelte/src/lib/hooks/useInitialized.svelte.ts @@ -1,15 +1,16 @@ import { useStore } from '$lib/store'; -import type { Readable } from 'svelte/store'; /** * Hook for seeing if nodes are initialized * @returns - nodesInitialized Writable */ export function useNodesInitialized() { - const { nodesInitialized } = useStore(); + const { nodesInitialized } = $derived(useStore()); return { - subscribe: nodesInitialized.subscribe - } as Readable; + get current() { + return nodesInitialized; + } + }; } /** @@ -17,8 +18,10 @@ export function useNodesInitialized() { * @returns - initialized Writable */ export function useInitialized() { - const { initialized } = useStore(); + const { initialized } = $derived(useStore()); return { - subscribe: initialized.subscribe - } as Readable; + get current() { + return initialized; + } + }; } diff --git a/packages/svelte/src/lib/hooks/useInternalNode.svelte.ts b/packages/svelte/src/lib/hooks/useInternalNode.svelte.ts new file mode 100644 index 00000000..cad6d9c9 --- /dev/null +++ b/packages/svelte/src/lib/hooks/useInternalNode.svelte.ts @@ -0,0 +1,25 @@ +import { useStore } from '$lib/store'; +import type { InternalNode } from '$lib/types'; + +/** + * Hook to get an internal node by id. + * + * @public + * @param id - the node id + * @returns a readable with an internal node or undefined + */ +export function useInternalNode(id: string): { current: InternalNode | undefined } { + const { nodeLookup, nodes } = $derived(useStore()); + + const node = $derived.by(() => { + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + nodes; + return nodeLookup.get(id); + }); + + return { + get current() { + return node; + } + }; +} diff --git a/packages/svelte/src/lib/hooks/useInternalNode.ts b/packages/svelte/src/lib/hooks/useInternalNode.ts deleted file mode 100644 index 16c83960..00000000 --- a/packages/svelte/src/lib/hooks/useInternalNode.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { derived, type Readable } from 'svelte/store'; - -import { useStore } from '$lib/store'; -import type { InternalNode } from '$lib/types'; - -/** - * Hook to get an internal node by id. - * - * @public - * @param id - the node id - * @returns a readable with an internal node or undefined - */ -export function useInternalNode(id: string): Readable { - const { nodeLookup, nodes } = useStore(); - - return derived([nodeLookup, nodes], ([nodeLookup]) => nodeLookup.get(id)); -} diff --git a/packages/svelte/src/lib/index.ts b/packages/svelte/src/lib/index.ts index 7e6a5148..dc3027f9 100644 --- a/packages/svelte/src/lib/index.ts +++ b/packages/svelte/src/lib/index.ts @@ -37,8 +37,8 @@ export * from '$lib/hooks/useConnection.svelte'; export * from '$lib/hooks/useNodesEdgesViewport.svelte'; export * from '$lib/hooks/useHandleConnections.svelte'; export * from '$lib/hooks/useNodesData.svelte'; -export * from '$lib/hooks/useInternalNode'; -export { useInitialized, useNodesInitialized } from '$lib/hooks/useInitialized'; +export * from '$lib/hooks/useInternalNode.svelte'; +export { useInitialized, useNodesInitialized } from '$lib/hooks/useInitialized.svelte'; // types export type { diff --git a/packages/svelte/src/lib/store/index.ts b/packages/svelte/src/lib/store/index.ts index 7910ce55..ac65bd75 100644 --- a/packages/svelte/src/lib/store/index.ts +++ b/packages/svelte/src/lib/store/index.ts @@ -309,6 +309,29 @@ export function createStore(signals: StoreSignals): SvelteFlowStore { } } + function handleEdgeSelection(id: string) { + const edge = store.edgeLookup.get(id); + + if (!edge) { + console.warn('012', errorMessages['error012'](id)); + return; + } + + const selectable = + edge.selectable || (store.elementsSelectable && typeof edge.selectable === 'undefined'); + + if (selectable) { + store.selectionRect = null; + store.selectionRectMode = null; + + if (!edge.selected) { + addSelectedEdges([id]); + } else if (edge.selected && store.multiselectionKeyPressed) { + unselectNodesAndEdges({ nodes: [], edges: [edge] }); + } + } + } + function panBy(delta: XYPosition) { return panBySystem({ delta, @@ -354,6 +377,7 @@ export function createStore(signals: StoreSignals): SvelteFlowStore { addSelectedNodes, addSelectedEdges, handleNodeSelection, + handleEdgeSelection, panBy, updateConnection, cancelConnection, diff --git a/packages/svelte/src/lib/store/types.ts b/packages/svelte/src/lib/store/types.ts index 33ebfa89..9009a93b 100644 --- a/packages/svelte/src/lib/store/types.ts +++ b/packages/svelte/src/lib/store/types.ts @@ -30,6 +30,7 @@ export type SvelteFlowStoreActions = { addSelectedNodes: (ids: string[]) => void; addSelectedEdges: (ids: string[]) => void; handleNodeSelection: (id: string) => void; + handleEdgeSelection: (id: string) => void; panBy: (delta: XYPosition) => Promise; updateConnection: UpdateConnection; cancelConnection: () => void;