feat(react): Support Mutiple useOnSelectionChange Hook subscribers
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useCallback } from 'react';
|
||||
import {
|
||||
import { useCallback, useState } from 'react';
|
||||
import {
|
||||
ReactFlow,
|
||||
addEdge,
|
||||
ReactFlowProvider,
|
||||
@@ -35,9 +35,9 @@ const initialEdges: Edge[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const SelectionLogger = () => {
|
||||
const SelectionLogger = ({ id }: { id: string }) => {
|
||||
const onChange = useCallback(({ nodes, edges }: OnSelectionChangeParams) => {
|
||||
console.log(nodes, edges);
|
||||
console.log(id, nodes, edges);
|
||||
}, []);
|
||||
|
||||
useOnSelectionChange({
|
||||
@@ -63,14 +63,23 @@ const Flow = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const WrappedFlow = () => (
|
||||
<ReactFlowProvider>
|
||||
<Flow />
|
||||
<SelectionLogger />
|
||||
<div style={{ position: 'absolute', right: 10, top: 10, zIndex: 4 }}>
|
||||
<input type={'text'} placeholder={'name'} />
|
||||
</div>
|
||||
</ReactFlowProvider>
|
||||
);
|
||||
const WrappedFlow = () => {
|
||||
const [secondLoggerActive, setSecondLoggerActive] = useState<boolean>(false);
|
||||
|
||||
const toggleSecondLogger = () => {
|
||||
setSecondLoggerActive(!secondLoggerActive);
|
||||
};
|
||||
|
||||
return (
|
||||
<ReactFlowProvider>
|
||||
<Flow />
|
||||
<SelectionLogger id="Logger 1" />
|
||||
{secondLoggerActive && <SelectionLogger id="Logger 2" />}
|
||||
<div style={{ position: 'absolute', right: 10, top: 10, zIndex: 4 }}>
|
||||
<button onClick={toggleSecondLogger}>{secondLoggerActive ? 'Disable' : 'Enable'} Logger 2</button>
|
||||
</div>
|
||||
</ReactFlowProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default WrappedFlow;
|
||||
|
||||
@@ -33,7 +33,7 @@ const SelectionListener = memo(({ onSelectionChange }: SelectionListenerProps) =
|
||||
useEffect(() => {
|
||||
const params = { nodes: selectedNodes, edges: selectedEdges };
|
||||
onSelectionChange?.(params);
|
||||
store.getState().onSelectionChange?.(params);
|
||||
store.getState().onSelectionChange.forEach((fn) => fn(params));
|
||||
}, [selectedNodes, selectedEdges, onSelectionChange]);
|
||||
|
||||
return null;
|
||||
|
||||
@@ -4,14 +4,19 @@ import { useStoreApi } from './useStore';
|
||||
import type { OnSelectionChangeFunc } from '../types';
|
||||
|
||||
export type UseOnSelectionChangeOptions = {
|
||||
onChange?: OnSelectionChangeFunc;
|
||||
onChange: OnSelectionChangeFunc;
|
||||
};
|
||||
|
||||
function useOnSelectionChange({ onChange }: UseOnSelectionChangeOptions) {
|
||||
const store = useStoreApi();
|
||||
|
||||
useEffect(() => {
|
||||
store.setState({ onSelectionChange: onChange });
|
||||
const addedOnSelectionChange = [...store.getState().onSelectionChange, onChange];
|
||||
store.setState({ onSelectionChange: addedOnSelectionChange });
|
||||
return () => {
|
||||
const removedOnSelectionChange = store.getState().onSelectionChange.filter((fn) => fn !== onChange);
|
||||
store.setState({ onSelectionChange: removedOnSelectionChange });
|
||||
};
|
||||
}, [onChange]);
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +92,7 @@ const getInitialState = ({
|
||||
connectionRadius: 20,
|
||||
onError: () => null,
|
||||
isValidConnection: undefined,
|
||||
onSelectionChange: [],
|
||||
|
||||
lib: 'react',
|
||||
};
|
||||
|
||||
@@ -123,8 +123,8 @@ export type ReactFlowStore = {
|
||||
onViewportChangeStart?: OnViewportChange;
|
||||
onViewportChange?: OnViewportChange;
|
||||
onViewportChangeEnd?: OnViewportChange;
|
||||
|
||||
onSelectionChange?: OnSelectionChangeFunc;
|
||||
|
||||
onSelectionChange: OnSelectionChangeFunc[];
|
||||
|
||||
ariaLiveMessage: string;
|
||||
autoPanOnConnect: boolean;
|
||||
|
||||
704
pnpm-lock.yaml
generated
704
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user