@@ -42,9 +42,11 @@ const Marker = ({
|
||||
);
|
||||
};
|
||||
|
||||
// when you have multiple flows on a page and you hide the first one, the other ones have no markers anymore
|
||||
// when they do have markers with the same ids. To prevent this the user can pass a unique id to the react flow wrapper
|
||||
// that we can then use for creating our unique marker ids
|
||||
/*
|
||||
* when you have multiple flows on a page and you hide the first one, the other ones have no markers anymore
|
||||
* when they do have markers with the same ids. To prevent this the user can pass a unique id to the react flow wrapper
|
||||
* that we can then use for creating our unique marker ids
|
||||
*/
|
||||
const MarkerDefinitions = ({ defaultColor, rfId }: MarkerDefinitionsProps) => {
|
||||
const edges = useStore((s) => s.edges);
|
||||
const defaultEdgeOptions = useStore((s) => s.defaultEdgeOptions);
|
||||
|
||||
@@ -44,29 +44,31 @@ function NodeRendererComponent<NodeType extends Node>(props: NodeRendererProps<N
|
||||
<div className="react-flow__nodes" style={containerStyle}>
|
||||
{nodeIds.map((nodeId) => {
|
||||
return (
|
||||
// The split of responsibilities between NodeRenderer and
|
||||
// NodeComponentWrapper may appear weird. However, it’s designed to
|
||||
// minimize the cost of updates when individual nodes change.
|
||||
//
|
||||
// For example, when you’re dragging a single node, that node gets
|
||||
// updated multiple times per second. If `NodeRenderer` were to update
|
||||
// every time, it would have to re-run the `nodes.map()` loop every
|
||||
// time. This gets pricey with hundreds of nodes, especially if every
|
||||
// loop cycle does more than just rendering a JSX element!
|
||||
//
|
||||
// As a result of this choice, we took the following implementation
|
||||
// decisions:
|
||||
// - NodeRenderer subscribes *only* to node IDs – and therefore
|
||||
// rerender *only* when visible nodes are added or removed.
|
||||
// - NodeRenderer performs all operations the result of which can be
|
||||
// shared between nodes (such as creating the `ResizeObserver`
|
||||
// instance, or subscribing to `selector`). This means extra prop
|
||||
// drilling into `NodeComponentWrapper`, but it means we need to run
|
||||
// these operations only once – instead of once per node.
|
||||
// - Any operations that you’d normally write inside `nodes.map` are
|
||||
// moved into `NodeComponentWrapper`. This ensures they are
|
||||
// memorized – so if `NodeRenderer` *has* to rerender, it only
|
||||
// needs to regenerate the list of nodes, nothing else.
|
||||
/*
|
||||
* The split of responsibilities between NodeRenderer and
|
||||
* NodeComponentWrapper may appear weird. However, it’s designed to
|
||||
* minimize the cost of updates when individual nodes change.
|
||||
*
|
||||
* For example, when you’re dragging a single node, that node gets
|
||||
* updated multiple times per second. If `NodeRenderer` were to update
|
||||
* every time, it would have to re-run the `nodes.map()` loop every
|
||||
* time. This gets pricey with hundreds of nodes, especially if every
|
||||
* loop cycle does more than just rendering a JSX element!
|
||||
*
|
||||
* As a result of this choice, we took the following implementation
|
||||
* decisions:
|
||||
* - NodeRenderer subscribes *only* to node IDs – and therefore
|
||||
* rerender *only* when visible nodes are added or removed.
|
||||
* - NodeRenderer performs all operations the result of which can be
|
||||
* shared between nodes (such as creating the `ResizeObserver`
|
||||
* instance, or subscribing to `selector`). This means extra prop
|
||||
* drilling into `NodeComponentWrapper`, but it means we need to run
|
||||
* these operations only once – instead of once per node.
|
||||
* - Any operations that you’d normally write inside `nodes.map` are
|
||||
* moved into `NodeComponentWrapper`. This ensures they are
|
||||
* memorized – so if `NodeRenderer` *has* to rerender, it only
|
||||
* needs to regenerate the list of nodes, nothing else.
|
||||
*/
|
||||
<NodeWrapper<NodeType>
|
||||
key={nodeId}
|
||||
id={nodeId}
|
||||
|
||||
@@ -233,8 +233,10 @@ export function Pane({
|
||||
(event.target as Partial<Element>)?.releasePointerCapture?.(event.pointerId);
|
||||
const { userSelectionRect } = store.getState();
|
||||
|
||||
// We only want to trigger click functions when in selection mode if
|
||||
// the user did not move the mouse.
|
||||
/*
|
||||
* We only want to trigger click functions when in selection mode if
|
||||
* the user did not move the mouse.
|
||||
*/
|
||||
if (!userSelectionActive && userSelectionRect && event.target === container.current) {
|
||||
onClick?.(event);
|
||||
}
|
||||
@@ -246,8 +248,10 @@ export function Pane({
|
||||
});
|
||||
onSelectionEnd?.(event);
|
||||
|
||||
// If the user kept holding the selectionKey during the selection,
|
||||
// we need to reset the selectionInProgress, so the next click event is not prevented
|
||||
/*
|
||||
* If the user kept holding the selectionKey during the selection,
|
||||
* we need to reset the selectionInProgress, so the next click event is not prevented
|
||||
*/
|
||||
if (selectionKeyPressed || selectionOnDrag) {
|
||||
selectionInProgress.current = false;
|
||||
}
|
||||
|
||||
@@ -31,8 +31,10 @@ export function Wrapper({
|
||||
const isWrapped = useContext(StoreContext);
|
||||
|
||||
if (isWrapped) {
|
||||
// we need to wrap it with a fragment because it's not allowed for children to be a ReactNode
|
||||
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18051
|
||||
/*
|
||||
* we need to wrap it with a fragment because it's not allowed for children to be a ReactNode
|
||||
* https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18051
|
||||
*/
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
|
||||
@@ -312,4 +312,24 @@ function ReactFlow<NodeType extends Node = Node, EdgeType extends Edge = Edge>(
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The `<ReactFlow />` component is the heart of your React Flow application.
|
||||
* It renders your nodes and edges and handles user interaction
|
||||
*
|
||||
* @public
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
*import { ReactFlow } from '@xyflow/react'
|
||||
*
|
||||
*export default function Flow() {
|
||||
* return (<ReactFlow
|
||||
* nodes={...}
|
||||
* edges={...}
|
||||
* onNodesChange={...}
|
||||
* ...
|
||||
* />);
|
||||
*}
|
||||
*```
|
||||
*/
|
||||
export default fixedForwardRef(ReactFlow);
|
||||
|
||||
Reference in New Issue
Block a user