streamline onselectionchange

This commit is contained in:
peterkogo
2025-05-13 15:44:44 +02:00
parent 08ce321d4c
commit a05b6ad61e
10 changed files with 31 additions and 29 deletions
@@ -2,7 +2,7 @@
import { import {
Handle, Handle,
Position, Position,
useSelectionChanged, useOnSelectionChange,
type BuiltInNode, type BuiltInNode,
type NodeProps type NodeProps
} from '@xyflow/svelte'; } from '@xyflow/svelte';
@@ -13,7 +13,7 @@
positionAbsoluteY = 0 positionAbsoluteY = 0
}: NodeProps<BuiltInNode> = $props(); }: NodeProps<BuiltInNode> = $props();
useSelectionChanged(({ nodes, edges }) => { useOnSelectionChange(({ nodes, edges }) => {
console.log('on selection changed via hook', { nodes, edges }); console.log('on selection changed via hook', { nodes, edges });
}); });
</script> </script>
@@ -216,7 +216,7 @@
connectionMode={ConnectionMode.Strict} connectionMode={ConnectionMode.Strict}
attributionPosition={'top-center'} attributionPosition={'top-center'}
deleteKey={['Backspace', 'd']} deleteKey={['Backspace', 'd']}
onselectionchanged={({ nodes, edges }) => { onselectionchange={({ nodes, edges }) => {
console.log('on selection changed via prop', { nodes, edges }); console.log('on selection changed via prop', { nodes, edges });
}} }}
selectNodesOnDrag selectNodesOnDrag
@@ -69,7 +69,8 @@
edges = $bindable([]), edges = $bindable([]),
viewport = $bindable(undefined), viewport = $bindable(undefined),
...props ...props
}: SvelteFlowProps<NodeType, EdgeType> & HTMLAttributes<HTMLDivElement> = $props(); }: SvelteFlowProps<NodeType, EdgeType> &
Omit<HTMLAttributes<HTMLDivElement>, 'onselectionchange'> = $props();
// svelte-ignore non_reactive_update // svelte-ignore non_reactive_update
let store = createStore<NodeType, EdgeType>({ let store = createStore<NodeType, EdgeType>({
@@ -113,8 +114,8 @@
// handle selection change // handle selection change
$effect(() => { $effect(() => {
const params = { nodes: store.selectedNodes, edges: store.selectedEdges }; const params = { nodes: store.selectedNodes, edges: store.selectedEdges };
untrack(() => props.onselectionchanged)?.(params); untrack(() => props.onselectionchange)?.(params);
for (const handler of store.selectionChangedHandlers.values()) { for (const handler of store.selectionChangeHandlers.values()) {
handler(params); handler(params);
} }
}); });
@@ -22,7 +22,8 @@
clientWidth?: number; clientWidth?: number;
clientHeight?: number; clientHeight?: number;
children?: Snippet; children?: Snippet;
rest: SvelteFlowRestProps<NodeType, EdgeType> & HTMLAttributes<HTMLDivElement>; rest: SvelteFlowRestProps<NodeType, EdgeType> &
Omit<HTMLAttributes<HTMLDivElement>, 'onselectionchange'>;
} = $props(); } = $props();
// Unfortunately we have to destructure the props here this way, // Unfortunately we have to destructure the props here this way,
@@ -52,7 +53,7 @@
onclickconnectstart, onclickconnectstart,
onclickconnectend, onclickconnectend,
oninit, oninit,
onselectionchanged, onselectionchange,
clickConnect, clickConnect,
fitView, fitView,
fitViewOptions, fitViewOptions,
@@ -36,7 +36,7 @@ import type {
OnBeforeDelete, OnBeforeDelete,
IsValidConnection, IsValidConnection,
OnBeforeReconnect, OnBeforeReconnect,
OnSelectionChanged OnSelectionChange
} from '$lib/types'; } from '$lib/types';
import type { Component } from 'svelte'; import type { Component } from 'svelte';
@@ -454,5 +454,5 @@ export type SvelteFlowProps<
/** This handler gets called when the flow is finished initializing */ /** This handler gets called when the flow is finished initializing */
oninit?: () => void; oninit?: () => void;
/** This event handler gets called when the selected nodes & edges change */ /** This event handler gets called when the selected nodes & edges change */
onselectionchanged?: OnSelectionChanged<NodeType, EdgeType>; onselectionchange?: OnSelectionChange<NodeType, EdgeType>;
}; };
@@ -0,0 +1,15 @@
import type { OnSelectionChange } from '$lib/types';
import { useStore } from '$lib/hooks/useStore';
export function useOnSelectionChange(onselectionchange: OnSelectionChange) {
const store = $derived(useStore());
const symbol = Symbol();
$effect(() => {
store.selectionChangeHandlers.set(symbol, onselectionchange);
return () => {
store.selectionChangeHandlers.delete(symbol);
};
});
}
@@ -1,15 +0,0 @@
import type { OnSelectionChanged } from '$lib/types';
import { useStore } from '$lib/hooks/useStore';
export function useSelectionChanged(onselectionchanged: OnSelectionChanged) {
const store = $derived(useStore());
const symbol = Symbol();
$effect(() => {
store.selectionChangedHandlers.set(symbol, onselectionchanged);
return () => {
store.selectionChangedHandlers.delete(symbol);
};
});
}
+1 -1
View File
@@ -39,7 +39,7 @@ export * from '$lib/hooks/useNodeConnections.svelte';
export * from '$lib/hooks/useNodesData.svelte'; export * from '$lib/hooks/useNodesData.svelte';
export * from '$lib/hooks/useInternalNode.svelte'; export * from '$lib/hooks/useInternalNode.svelte';
export * from '$lib/hooks/useInitialized.svelte'; export * from '$lib/hooks/useInitialized.svelte';
export * from '$lib/hooks/useSelectionChanged.svelte'; export * from '$lib/hooks/useOnSelectionChange.svelte';
//actions //actions
export * from '$lib/actions/portal'; export * from '$lib/actions/portal';
@@ -60,7 +60,7 @@ import type {
EdgeLayouted, EdgeLayouted,
InternalNode, InternalNode,
OnBeforeReconnect, OnBeforeReconnect,
OnSelectionChanged OnSelectionChange
} from '$lib/types'; } from '$lib/types';
import type { StoreSignals } from './types'; import type { StoreSignals } from './types';
@@ -183,7 +183,7 @@ export function getInitialStore<NodeType extends Node = Node, EdgeType extends E
return this._prevSelectedEdges; return this._prevSelectedEdges;
}); });
selectionChangedHandlers = new Map<symbol, OnSelectionChanged<NodeType, EdgeType>>(); selectionChangeHandlers = new Map<symbol, OnSelectionChange<NodeType, EdgeType>>();
nodeLookup: NodeLookup<InternalNode<NodeType>> = new Map(); nodeLookup: NodeLookup<InternalNode<NodeType>> = new Map();
parentLookup: ParentLookup<InternalNode<NodeType>> = new Map(); parentLookup: ParentLookup<InternalNode<NodeType>> = new Map();
+1 -1
View File
@@ -44,7 +44,7 @@ export type IsValidConnection<EdgeType extends Edge = Edge> = (
edge: EdgeType | Connection edge: EdgeType | Connection
) => boolean; ) => boolean;
export type OnSelectionChanged< export type OnSelectionChange<
NodeType extends Node = Node, NodeType extends Node = Node,
EdgeType extends Edge = Edge EdgeType extends Edge = Edge
> = (params: { nodes: NodeType[]; edges: EdgeType[] }) => void; > = (params: { nodes: NodeType[]; edges: EdgeType[] }) => void;