refactor(node-resizer): use nodeId from context, fix glitches while resizing
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import { memo, useContext, HTMLAttributes, forwardRef, MouseEvent as ReactMouseEvent } from 'react';
|
||||
import { memo, HTMLAttributes, forwardRef, MouseEvent as ReactMouseEvent } from 'react';
|
||||
import cc from 'classcat';
|
||||
import shallow from 'zustand/shallow';
|
||||
|
||||
import { useStore, useStoreApi } from '../../hooks/useStore';
|
||||
import NodeIdContext from '../../contexts/NodeIdContext';
|
||||
import { useNodeId } from '../../contexts/NodeIdContext';
|
||||
import { checkElementBelowIsValid, handleMouseDown } from './handler';
|
||||
import { getHostForElement } from '../../utils';
|
||||
import { addEdge } from '../../utils/graph';
|
||||
@@ -37,7 +37,9 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
||||
ref
|
||||
) => {
|
||||
const store = useStoreApi();
|
||||
const nodeId = useContext(NodeIdContext) as string;
|
||||
|
||||
// @fixme: remove type assertion and handle nodeId === null
|
||||
const nodeId = useNodeId() as string;
|
||||
const { connectionStartHandle, connectOnClick, noPanClassName } = useStore(selector, shallow);
|
||||
|
||||
const handleId = id || null;
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import { createContext } from 'react';
|
||||
import { createContext, useContext } from 'react';
|
||||
|
||||
export const NodeIdContext = createContext<string | null>(null);
|
||||
export const Provider = NodeIdContext.Provider;
|
||||
export const Consumer = NodeIdContext.Consumer;
|
||||
|
||||
export const useNodeId = (): string | null => {
|
||||
const nodeId = useContext(NodeIdContext);
|
||||
return nodeId;
|
||||
};
|
||||
|
||||
export default NodeIdContext;
|
||||
|
||||
@@ -22,7 +22,6 @@ export {
|
||||
getNodePositionWithOrigin,
|
||||
} from './utils/graph';
|
||||
export { applyNodeChanges, applyEdgeChanges } from './utils/changes';
|
||||
export { createNodeInternals } from './store/utils';
|
||||
export { getMarkerEnd } from './components/Edges/utils';
|
||||
export { default as ReactFlowProvider } from './components/ReactFlowProvider';
|
||||
export { default as Panel } from './components/Panel';
|
||||
@@ -40,5 +39,6 @@ export { default as useOnViewportChange } from './hooks/useOnViewportChange';
|
||||
export { default as useOnSelectionChange } from './hooks/useOnSelectionChange';
|
||||
export { default as useNodesInitialized } from './hooks/useNodesInitialized';
|
||||
export { default as useGetPointerPosition } from './hooks/useGetPointerPosition';
|
||||
export { useNodeId } from './contexts/NodeIdContext';
|
||||
|
||||
export * from './types';
|
||||
|
||||
@@ -17,6 +17,7 @@ import type {
|
||||
NodePositionChange,
|
||||
NodeDragItem,
|
||||
UnselectNodesAndEdgesParams,
|
||||
NodeChange,
|
||||
} from '../types';
|
||||
|
||||
const createRFStore = () =>
|
||||
@@ -102,47 +103,41 @@ const createRFStore = () =>
|
||||
onNodesChange?.(changes);
|
||||
}
|
||||
},
|
||||
updateNodePositions: (
|
||||
nodeDragItems: NodeDragItem[] | Node[],
|
||||
positionChanged = true,
|
||||
dragging = false,
|
||||
applyChanges = true
|
||||
) => {
|
||||
const { onNodesChange, nodeInternals, hasDefaultNodes, nodeOrigin } = get();
|
||||
updateNodePositions: (nodeDragItems: NodeDragItem[] | Node[], positionChanged = true, dragging = false) => {
|
||||
const { triggerNodeChanges } = get();
|
||||
|
||||
if (hasDefaultNodes || onNodesChange) {
|
||||
const changes = nodeDragItems.map((node) => {
|
||||
const change: NodePositionChange = {
|
||||
id: node.id,
|
||||
type: 'position',
|
||||
dragging,
|
||||
};
|
||||
const changes = nodeDragItems.map((node) => {
|
||||
const change: NodePositionChange = {
|
||||
id: node.id,
|
||||
type: 'position',
|
||||
dragging,
|
||||
};
|
||||
|
||||
if (positionChanged) {
|
||||
change.positionAbsolute = node.positionAbsolute;
|
||||
change.position = node.position;
|
||||
}
|
||||
|
||||
return change;
|
||||
});
|
||||
|
||||
if (changes?.length) {
|
||||
if (hasDefaultNodes) {
|
||||
const nodes = applyNodeChanges(changes, Array.from(nodeInternals.values()));
|
||||
const nextNodeInternals = createNodeInternals(nodes, nodeInternals, nodeOrigin);
|
||||
set({ nodeInternals: nextNodeInternals });
|
||||
}
|
||||
|
||||
if (applyChanges) {
|
||||
onNodesChange?.(changes);
|
||||
}
|
||||
if (positionChanged) {
|
||||
change.positionAbsolute = node.positionAbsolute;
|
||||
change.position = node.position;
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
return change;
|
||||
});
|
||||
|
||||
return null;
|
||||
triggerNodeChanges(changes);
|
||||
},
|
||||
|
||||
triggerNodeChanges: (changes: NodeChange[]) => {
|
||||
const { onNodesChange, nodeInternals, hasDefaultNodes, nodeOrigin } = get();
|
||||
|
||||
if (changes?.length) {
|
||||
if (hasDefaultNodes) {
|
||||
const nodes = applyNodeChanges(changes, Array.from(nodeInternals.values()));
|
||||
const nextNodeInternals = createNodeInternals(nodes, nodeInternals, nodeOrigin);
|
||||
set({ nodeInternals: nextNodeInternals });
|
||||
}
|
||||
|
||||
onNodesChange?.(changes);
|
||||
}
|
||||
},
|
||||
|
||||
addSelectedNodes: (selectedNodeIds: string[]) => {
|
||||
const { multiSelectionActive, nodeInternals, edges } = get();
|
||||
let changedNodes: NodeSelectionChange[];
|
||||
|
||||
@@ -7,8 +7,9 @@ import type { Edge } from './edges';
|
||||
export type NodeDimensionChange = {
|
||||
id: string;
|
||||
type: 'dimensions';
|
||||
dimensions: Dimensions;
|
||||
dimensions?: Dimensions;
|
||||
updateStyle?: boolean;
|
||||
resizing?: boolean;
|
||||
};
|
||||
|
||||
export type NodePositionChange = {
|
||||
|
||||
@@ -215,12 +215,7 @@ export type ReactFlowActions = {
|
||||
setEdges: (edges: Edge[]) => void;
|
||||
setDefaultNodesAndEdges: (nodes?: Node[], edges?: Edge[]) => void;
|
||||
updateNodeDimensions: (updates: NodeDimensionUpdate[]) => void;
|
||||
updateNodePositions: (
|
||||
nodeDragItems: NodeDragItem[] | Node[],
|
||||
positionChanged: boolean,
|
||||
dragging: boolean,
|
||||
applyChanges?: boolean
|
||||
) => NodePositionChange[] | null;
|
||||
updateNodePositions: (nodeDragItems: NodeDragItem[] | Node[], positionChanged: boolean, dragging: boolean) => void;
|
||||
resetSelectedElements: () => void;
|
||||
unselectNodesAndEdges: (params?: UnselectNodesAndEdgesParams) => void;
|
||||
addSelectedNodes: (nodeIds: string[]) => void;
|
||||
@@ -231,6 +226,7 @@ export type ReactFlowActions = {
|
||||
setNodeExtent: (nodeExtent: CoordinateExtent) => void;
|
||||
cancelConnection: () => void;
|
||||
reset: () => void;
|
||||
triggerNodeChanges: (changes: NodeChange[]) => void;
|
||||
};
|
||||
|
||||
export type ReactFlowState = ReactFlowStore & ReactFlowActions;
|
||||
|
||||
@@ -31,6 +31,7 @@ export type Node<T = any> = {
|
||||
positionAbsolute?: XYPosition;
|
||||
ariaLabel?: string;
|
||||
focusable?: boolean;
|
||||
resizing?: boolean;
|
||||
|
||||
// only used internally
|
||||
[internalsSymbol]?: {
|
||||
|
||||
@@ -94,6 +94,10 @@ function applyChanges(changes: any[], elements: any[]): any[] {
|
||||
updateItem.style = { ...(updateItem.style || {}), ...currentChange.dimensions };
|
||||
}
|
||||
|
||||
if (typeof currentChange.resizing === 'boolean') {
|
||||
updateItem.resizing = currentChange.resizing;
|
||||
}
|
||||
|
||||
if (updateItem.expandParent) {
|
||||
handleParentExpand(res, updateItem);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user