Merge pull request #2833 from wbkd/next-release

Next release: 11.5.6
This commit is contained in:
Moritz Klack
2023-02-13 16:36:25 +01:00
committed by GitHub
55 changed files with 250 additions and 178 deletions

View File

@@ -25,6 +25,7 @@
},
"devDependencies": {
"@cypress/skip-test": "^2.6.1",
"@types/dagre": "^0.7.48",
"@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6",
"@vitejs/plugin-react": "^3.0.1",

View File

@@ -1,4 +1,4 @@
import React, { FC } from 'react';
import { FC } from 'react';
import ReactFlow, {
Node,

View File

@@ -1,4 +1,4 @@
import React, { MouseEvent } from 'react';
import { MouseEvent } from 'react';
import ReactFlow, {
MiniMap,
Background,
@@ -8,7 +8,7 @@ import ReactFlow, {
Node,
Edge,
useReactFlow,
NodeOrigin,
Panel,
} from 'reactflow';
const onNodeDrag = (_: MouseEvent, node: Node) => console.log('drag', node);
@@ -22,7 +22,6 @@ const initialNodes: Node[] = [
data: { label: 'Node 1' },
position: { x: 250, y: 5 },
className: 'light',
draggable: false,
},
{
id: '2',
@@ -100,20 +99,12 @@ const BasicFlow = () => {
<MiniMap />
<Controls />
<div style={{ position: 'absolute', right: 10, top: 10, zIndex: 4 }}>
<button onClick={resetTransform} style={{ marginRight: 5 }}>
reset transform
</button>
<button onClick={updatePos} style={{ marginRight: 5 }}>
change pos
</button>
<button onClick={toggleClassnames} style={{ marginRight: 5 }}>
toggle classnames
</button>
<button onClick={logToObject} style={{ marginRight: 5 }}>
toObject
</button>
</div>
<Panel position="top-right">
<button onClick={resetTransform}>reset transform</button>
<button onClick={updatePos}>change pos</button>
<button onClick={toggleClassnames}>toggle classnames</button>
<button onClick={logToObject}>toObject</button>
</Panel>
</ReactFlow>
);
};

View File

@@ -1,4 +1,4 @@
import React, { useCallback } from 'react';
import { useCallback } from 'react';
import ReactFlow, {
Node,
addEdge,

View File

@@ -1,4 +1,4 @@
import React, { useState, useEffect, MouseEvent, ChangeEvent, useCallback } from 'react';
import { useState, useEffect, MouseEvent, ChangeEvent, useCallback } from 'react';
import ReactFlow, {
MiniMap,
Controls,

View File

@@ -1,4 +1,12 @@
import ReactFlow, { useReactFlow, Node, Edge, ReactFlowProvider, Background, BackgroundVariant } from 'reactflow';
import ReactFlow, {
useReactFlow,
Node,
Edge,
ReactFlowProvider,
Background,
BackgroundVariant,
Panel,
} from 'reactflow';
const defaultNodes: Node[] = [
{
@@ -72,18 +80,12 @@ const DefaultNodes = () => {
<ReactFlow defaultNodes={defaultNodes} defaultEdges={defaultEdges} defaultEdgeOptions={defaultEdgeOptions} fitView>
<Background variant={BackgroundVariant.Lines} />
<div style={{ position: 'absolute', right: 10, top: 10, zIndex: 4 }}>
<button onClick={resetTransform} style={{ marginRight: 5 }}>
reset transform
</button>
<button onClick={updateNodePositions} style={{ marginRight: 5 }}>
change pos
</button>
<button onClick={updateEdgeColors} style={{ marginRight: 5 }}>
red edges
</button>
<Panel position="top-right">
<button onClick={resetTransform}>reset transform</button>
<button onClick={updateNodePositions}>change pos</button>
<button onClick={updateEdgeColors}>red edges</button>
<button onClick={logToObject}>toObject</button>
</div>
</Panel>
</ReactFlow>
);
};

View File

@@ -1,4 +1,4 @@
import React, { MouseEvent } from 'react';
import { MouseEvent } from 'react';
import ReactFlow, { Node, Edge, useNodesState, useEdgesState } from 'reactflow';
import DragHandleNode from './DragHandleNode';

View File

@@ -1,4 +1,5 @@
import React, { DragEvent } from 'react';
import { DragEvent } from 'react';
import styles from './dnd.module.css';
const onDragStart = (event: DragEvent, nodeType: string) => {
@@ -9,25 +10,19 @@ const onDragStart = (event: DragEvent, nodeType: string) => {
const Sidebar = () => {
return (
<aside className={styles.aside}>
<div className={styles.description}>
You can drag these nodes to the pane on the left.
</div>
<div
className='react-flow__node-input'
onDragStart={(event: DragEvent) => onDragStart(event, 'input')}
draggable
>
<div className={styles.description}>You can drag these nodes to the pane on the left.</div>
<div className="react-flow__node-input" onDragStart={(event: DragEvent) => onDragStart(event, 'input')} draggable>
Input Node
</div>
<div
className='react-flow__node-default'
className="react-flow__node-default"
onDragStart={(event: DragEvent) => onDragStart(event, 'default')}
draggable
>
Default Node
</div>
<div
className='react-flow__node-output'
className="react-flow__node-output"
onDragStart={(event: DragEvent) => onDragStart(event, 'output')}
draggable
>

View File

@@ -1,4 +1,4 @@
import React, { useState, DragEvent } from 'react';
import { useState, DragEvent } from 'react';
import ReactFlow, {
ReactFlowProvider,
addEdge,

View File

@@ -2,7 +2,7 @@ import { Handle, NodeProps, Position, ReactFlowState, useStore } from 'reactflow
const connectionNodeIdSelector = (state: ReactFlowState) => state.connectionNodeId;
export default function CustomNode({ id }: NodeProps) {
export default function CustomNode({ id, isConnectable }: NodeProps) {
const connectionNodeId = useStore(connectionNodeIdSelector);
const isTarget = connectionNodeId && connectionNodeId !== id;
@@ -18,8 +18,20 @@ export default function CustomNode({ id }: NodeProps) {
backgroundColor: isTarget ? '#ffcce3' : '#ccd9f6',
}}
>
<Handle className="targetHandle" style={{ zIndex: 2 }} position={Position.Right} type="source" />
<Handle className="targetHandle" style={targetHandleStyle} position={Position.Left} type="target" />
<Handle
className="targetHandle"
style={{ zIndex: 2 }}
position={Position.Right}
type="source"
isConnectable={isConnectable}
/>
<Handle
className="targetHandle"
style={targetHandleStyle}
position={Position.Left}
type="target"
isConnectable={isConnectable}
/>
{label}
</div>
</div>

View File

@@ -1,4 +1,4 @@
import React, { MouseEvent, useCallback } from 'react';
import { MouseEvent, useCallback } from 'react';
import ReactFlow, {
Controls,
Background,

View File

@@ -1,7 +1,4 @@
/**
* Example for checking the different edge types and source and target positions
*/
import React, { useCallback } from 'react';
import { useCallback } from 'react';
import ReactFlow, {
Background,

View File

@@ -1,4 +1,4 @@
import React, { MouseEvent, useCallback } from 'react';
import { MouseEvent, useCallback } from 'react';
import ReactFlow, {
Controls,
Background,

View File

@@ -1,4 +1,4 @@
import React, { MouseEvent, CSSProperties, useCallback } from 'react';
import { MouseEvent, CSSProperties, useCallback } from 'react';
import ReactFlow, {
Background,

View File

@@ -1,4 +1,4 @@
import React, { useCallback } from 'react';
import { useCallback } from 'react';
import ReactFlow, {
Background,

View File

@@ -1,4 +1,4 @@
import React, { useState, useEffect, useCallback } from 'react';
import { useState, useEffect, useCallback } from 'react';
import ReactFlow, { addEdge, Connection, Edge, Node, useNodesState, useEdgesState, MiniMap, Controls } from 'reactflow';

View File

@@ -1,4 +1,4 @@
import React, { useState, MouseEvent as ReactMouseEvent, WheelEvent } from 'react';
import { useState, MouseEvent as ReactMouseEvent, WheelEvent } from 'react';
import ReactFlow, {
addEdge,
Node,

View File

@@ -1,4 +1,5 @@
import React, { useCallback } from 'react';
import { useCallback } from 'react';
import dagre from 'dagre';
import ReactFlow, {
Controls,
ReactFlowProvider,
@@ -10,10 +11,10 @@ import ReactFlow, {
useEdgesState,
MarkerType,
EdgeMarker,
Panel,
useReactFlow,
} from 'reactflow';
import dagre from 'dagre';
import initialItems from './initial-elements';
import styles from './layouting.module.css';
@@ -29,6 +30,7 @@ const nodeExtent: CoordinateExtent = [
const LayoutFlow = () => {
const [nodes, setNodes, onNodesChange] = useNodesState(initialItems.nodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialItems.edges);
const { fitView } = useReactFlow();
const onConnect = useCallback(
(connection: Connection) => {
@@ -85,31 +87,31 @@ const LayoutFlow = () => {
return (
<div className={styles.layoutflow}>
<ReactFlowProvider>
<ReactFlow
nodes={nodes}
edges={edges}
onConnect={onConnect}
nodeExtent={nodeExtent}
onInit={() => onLayout('TB')}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
>
<Controls />
</ReactFlow>
<div className={styles.controls}>
<button onClick={() => onLayout('TB')} style={{ marginRight: 10 }}>
vertical layout
</button>
<button onClick={() => onLayout('LR')} style={{ marginRight: 10 }}>
horizontal layout
</button>
<button onClick={() => unselect()}>unselect nodes</button>
<button onClick={() => changeMarker()}>change marker</button>
</div>
</ReactFlowProvider>
<ReactFlow
nodes={nodes}
edges={edges}
onConnect={onConnect}
nodeExtent={nodeExtent}
onInit={() => onLayout('TB')}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
>
<Controls />
</ReactFlow>
<Panel position="top-right">
<button onClick={() => onLayout('TB')}>vertical layout</button>
<button onClick={() => onLayout('LR')}>horizontal layout</button>
<button onClick={() => unselect()}>unselect nodes</button>
<button onClick={() => changeMarker()}>change marker</button>
<button onClick={() => fitView()}>fitView</button>
<button onClick={() => fitView({ nodes: nodes.slice(0, 2) })}>fitView partially</button>
</Panel>
</div>
);
};
export default LayoutFlow;
export default () => (
<ReactFlowProvider>
<LayoutFlow />
</ReactFlowProvider>
);

View File

@@ -2,10 +2,3 @@
flex-grow: 1;
position: relative;
}
.controls {
position: absolute;
right: 10px;
top: 10px;
z-index: 10;
}

View File

@@ -1,4 +1,4 @@
import React, { FC } from 'react';
import { FC } from 'react';
import ReactFlow, {
Background,

View File

@@ -1,4 +1,4 @@
import React, { useState, MouseEvent, useCallback } from 'react';
import { useState, MouseEvent, useCallback } from 'react';
import ReactFlow, {
Controls,
MiniMap,

View File

@@ -1,5 +1,4 @@
import React, { CSSProperties, useCallback } from 'react';
import { CSSProperties, useCallback } from 'react';
import ReactFlow, { addEdge, Node, Position, Connection, Edge, useNodesState, useEdgesState } from 'reactflow';
const initialNodes: Node[] = [

View File

@@ -1,4 +1,4 @@
import React, { useState, CSSProperties, FC, useCallback } from 'react';
import { useState, CSSProperties, FC, useCallback } from 'react';
import ReactFlow, {
addEdge,
Node,

View File

@@ -1,4 +1,4 @@
import React, { MouseEvent as ReactMouseEvent, CSSProperties, useCallback } from 'react';
import { MouseEvent as ReactMouseEvent, CSSProperties, useCallback } from 'react';
import ReactFlow, {
addEdge,
Node,

View File

@@ -1,4 +1,4 @@
import React, { MouseEvent, useCallback } from 'react';
import { MouseEvent, useCallback } from 'react';
import ReactFlow, {
Controls,
ReactFlowProvider,

View File

@@ -1,5 +1,6 @@
import React, { useCallback } from 'react';
import { useCallback } from 'react';
import ReactFlow, { ReactFlowProvider, Node, addEdge, Connection, Edge, useNodesState, useEdgesState } from 'reactflow';
import Controls from './Controls';
const initialNodes: Node[] = [

View File

@@ -1,4 +1,4 @@
import React, { useState, CSSProperties, useCallback } from 'react';
import { useState, CSSProperties, useCallback } from 'react';
import ReactFlow, {
ReactFlowInstance,
Edge,

View File

@@ -1,4 +1,4 @@
import React, { useState, MouseEvent, useCallback } from 'react';
import { useState, MouseEvent, useCallback } from 'react';
import ReactFlow, {
addEdge,
Node,
@@ -12,7 +12,6 @@ import ReactFlow, {
MiniMap,
Background,
Panel,
NodeOrigin,
} from 'reactflow';
import DebugNode from './DebugNode';

View File

@@ -1,4 +1,4 @@
import React, { useCallback } from 'react';
import { useCallback } from 'react';
import ReactFlow, { Node, Edge, useNodesState, useEdgesState, Position, Connection, addEdge } from 'reactflow';
import styles from './touch-device.module.css';

View File

@@ -182,12 +182,13 @@ const getId = () => `${id++}`;
const UpdateNodeInternalsFlow = () => {
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const onConnect = (params: Edge | Connection) => setEdges((els) => addEdge(params, els));
const { project } = useReactFlow();
const onEdgeUpdate = (oldEdge: Edge, newConnection: Connection) =>
setEdges((els) => updateEdge(oldEdge, newConnection, els));
const onConnect = useCallback((params: Edge | Connection) => setEdges((els) => addEdge(params, els)), [setEdges]);
const onEdgeUpdate = useCallback(
(oldEdge: Edge, newConnection: Connection) => setEdges((els) => updateEdge(oldEdge, newConnection, els)),
[]
);
const onPaneClick = useCallback(
(evt: MouseEvent) =>

View File

@@ -1,4 +1,4 @@
import React, { useState, useCallback } from 'react';
import { useState, useCallback, MouseEvent as ReactMouseEvent } from 'react';
import ReactFlow, {
Controls,
updateEdge,
@@ -60,9 +60,9 @@ const initialNodes: Node[] = [
const initialEdges = [{ id: 'e1-2', source: '1', target: '2', label: 'This is a draggable edge' }];
const onInit = (reactFlowInstance: ReactFlowInstance) => reactFlowInstance.fitView();
const onEdgeUpdateStart = (_: React.MouseEvent, edge: Edge, handleType: HandleType) =>
const onEdgeUpdateStart = (_: ReactMouseEvent, edge: Edge, handleType: HandleType) =>
console.log(`start update ${handleType} handle`, edge);
const onEdgeUpdateEnd = (_: MouseEvent, edge: Edge, handleType: HandleType) =>
const onEdgeUpdateEnd = (_: MouseEvent | TouchEvent, edge: Edge, handleType: HandleType) =>
console.log(`end update ${handleType} handle`, edge);
const UpdatableEdge = () => {
@@ -91,8 +91,8 @@ const UpdatableEdge = () => {
snapToGrid={true}
onEdgeUpdate={onEdgeUpdate}
onConnect={onConnect}
// onEdgeUpdateStart={onEdgeUpdateStart}
// onEdgeUpdateEnd={onEdgeUpdateEnd}
onEdgeUpdateStart={onEdgeUpdateStart}
onEdgeUpdateEnd={onEdgeUpdateEnd}
>
<Controls />
</ReactFlow>

View File

@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import { useEffect, useState } from 'react';
import ReactFlow, { Node, Edge, useNodesState, useEdgesState } from 'reactflow';
import styles from './updatenode.module.css';

View File

@@ -1,4 +1,4 @@
import React, { useCallback, MouseEvent, useEffect } from 'react';
import { useCallback, MouseEvent, useEffect } from 'react';
import ReactFlow, {
Background,
MiniMap,
@@ -10,6 +10,7 @@ import ReactFlow, {
Edge,
useNodesState,
useEdgesState,
Panel,
} from 'reactflow';
const initialNodes: Node[] = [
@@ -65,7 +66,7 @@ const UseZoomPanHelperFlow = () => {
addEdges,
getNodes,
getEdges,
deleteElements
deleteElements,
} = useReactFlow();
const onPaneClick = useCallback(
@@ -114,14 +115,14 @@ const UseZoomPanHelperFlow = () => {
}, [getNodes, getEdges]);
const deleteSelectedElements = useCallback(() => {
const selectedNodes = nodes.filter(node => node.selected);
const selectedEdges = edges.filter(edge => edge.selected);
const selectedNodes = nodes.filter((node) => node.selected);
const selectedEdges = edges.filter((edge) => edge.selected);
deleteElements({ nodes: selectedNodes, edges: selectedEdges });
}, [deleteElements, nodes, edges])
}, [deleteElements, nodes, edges]);
const deleteSomeElements = useCallback(() => {
deleteElements({ nodes: [{ id: '2' }], edges: [{ id: 'e1-3' }] })
}, [])
deleteElements({ nodes: [{ id: '2' }], edges: [{ id: 'e1-3' }] });
}, []);
useEffect(() => {
addEdges({ id: 'e3-4', source: '3', target: '4' });
@@ -142,7 +143,7 @@ const UseZoomPanHelperFlow = () => {
fitViewOptions={{ duration: 1200, padding: 0.2 }}
maxZoom={Infinity}
>
<div style={{ position: 'absolute', left: 0, top: 0, zIndex: 100 }}>
<Panel position="top-right">
<button onClick={() => zoomIn({ duration: 1200 })}>zoomIn</button>
<button onClick={() => zoomOut({ duration: 0 })}>zoomOut</button>
<button onClick={() => fitView({ duration: 1200, padding: 0.3 })}>fitView</button>
@@ -151,7 +152,7 @@ const UseZoomPanHelperFlow = () => {
<button onClick={logNodes}>useNodes</button>
<button onClick={deleteSelectedElements}>deleteSelectedElements</button>
<button onClick={deleteSomeElements}>deleteSomeElements</button>
</div>
</Panel>
<Background />
<MiniMap />
</ReactFlow>

View File

@@ -1,5 +1,12 @@
# @reactflow/background
## 11.1.8
### Patch Changes
- Updated dependencies [[`72216ff6`](https://github.com/wbkd/react-flow/commit/72216ff62014acd2d73999053c72bd7aeed351f6), [`959b1114`](https://github.com/wbkd/react-flow/commit/959b111448bba4686040473e46988be9e7befbe6), [`0d259b02`](https://github.com/wbkd/react-flow/commit/0d259b028558aab650546f3371a85f3bce45252f), [`f3de9335`](https://github.com/wbkd/react-flow/commit/f3de9335af6cd96cd77dc77f24a944eef85384e5), [`23424ea6`](https://github.com/wbkd/react-flow/commit/23424ea6750f092210f83df17a00c89adb910d96), [`021f5a92`](https://github.com/wbkd/react-flow/commit/021f5a9210f47a968e50446cd2f9dae1f97880a4)]:
- @reactflow/core@11.5.5
## 11.1.7
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@reactflow/background",
"version": "11.1.7",
"version": "11.1.8",
"description": "Background component with different variants for React Flow",
"keywords": [
"react",

View File

@@ -1,5 +1,12 @@
# @reactflow/controls
## 11.1.8
### Patch Changes
- Updated dependencies [[`72216ff6`](https://github.com/wbkd/react-flow/commit/72216ff62014acd2d73999053c72bd7aeed351f6), [`959b1114`](https://github.com/wbkd/react-flow/commit/959b111448bba4686040473e46988be9e7befbe6), [`0d259b02`](https://github.com/wbkd/react-flow/commit/0d259b028558aab650546f3371a85f3bce45252f), [`f3de9335`](https://github.com/wbkd/react-flow/commit/f3de9335af6cd96cd77dc77f24a944eef85384e5), [`23424ea6`](https://github.com/wbkd/react-flow/commit/23424ea6750f092210f83df17a00c89adb910d96), [`021f5a92`](https://github.com/wbkd/react-flow/commit/021f5a9210f47a968e50446cd2f9dae1f97880a4)]:
- @reactflow/core@11.5.5
## 11.1.7
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@reactflow/controls",
"version": "11.1.7",
"version": "11.1.8",
"description": "Component to control the viewport of a React Flow instance",
"keywords": [
"react",

View File

@@ -1,5 +1,16 @@
# @reactflow/core
## 11.5.5
### Patch Changes
- [#2834](https://github.com/wbkd/react-flow/pull/2834) [`23424ea6`](https://github.com/wbkd/react-flow/commit/23424ea6750f092210f83df17a00c89adb910d96) Thanks [@bcakmakoglu](https://github.com/bcakmakoglu)! - Add `nodes` to fit view options to allow fitting view only around specified set of nodes
- [#2836](https://github.com/wbkd/react-flow/pull/2836) [`959b1114`](https://github.com/wbkd/react-flow/commit/959b111448bba4686040473e46988be9e7befbe6) - Fix: connections for handles with bigger handles than connection radius
- [#2819](https://github.com/wbkd/react-flow/pull/2819) [`0d259b02`](https://github.com/wbkd/react-flow/commit/0d259b028558aab650546f3371a85f3bce45252f) Thanks [@bcakmakoglu](https://github.com/bcakmakoglu)! - Avoid triggering edge update if not using left mouse button
- [#2832](https://github.com/wbkd/react-flow/pull/2832) [`f3de9335`](https://github.com/wbkd/react-flow/commit/f3de9335af6cd96cd77dc77f24a944eef85384e5) - fitView: return type boolean
- [#2838](https://github.com/wbkd/react-flow/pull/2838) [`021f5a92`](https://github.com/wbkd/react-flow/commit/021f5a9210f47a968e50446cd2f9dae1f97880a4) - refactor: use key press handle modifier keys + input
- [#2839](https://github.com/wbkd/react-flow/pull/2839) [`72216ff6`](https://github.com/wbkd/react-flow/commit/72216ff62014acd2d73999053c72bd7aeed351f6) - fix PropsWithChildren: pass default generic for v17 types
## 11.5.4
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@reactflow/core",
"version": "11.5.4",
"version": "11.5.5",
"description": "Core components and util functions of React Flow.",
"keywords": [
"react",

View File

@@ -89,6 +89,11 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
const onEdgeMouseLeave = getMouseHandler(id, store.getState, onMouseLeave);
const handleEdgeUpdater = (event: React.MouseEvent<SVGGElement, MouseEvent>, isSourceHandle: boolean) => {
// avoid triggering edge updater if mouse btn is not left
if (event.button !== 0) {
return;
}
const nodeId = isSourceHandle ? target : source;
const handleId = (isSourceHandle ? targetHandleId : sourceHandleId) || null;
const handleType = isSourceHandle ? 'target' : 'source';

View File

@@ -67,6 +67,7 @@ export function handlePointerDown({
let autoPanStarted = false;
let connection: Connection | null = null;
let isValid = false;
let handleDomNode: Element | null = null;
const handleLookup = getHandleLookup({
nodes: getNodes(),
@@ -111,7 +112,7 @@ export function handlePointerDown({
autoPanStarted = true;
}
const { handleDomNode, ...result } = isValidHandle(
const result = isValidHandle(
event,
prevClosestHandle,
connectionMode,
@@ -122,9 +123,13 @@ export function handlePointerDown({
doc
);
handleDomNode = result.handleDomNode;
connection = result.connection;
isValid = result.isValid;
setState({
connectionPosition:
prevClosestHandle && result.isValid
prevClosestHandle && isValid
? rendererPointToPoint(
{
x: prevClosestHandle.x,
@@ -133,16 +138,13 @@ export function handlePointerDown({
transform
)
: connectionPosition,
connectionStatus: getConnectionStatus(!!prevClosestHandle, result.isValid),
connectionStatus: getConnectionStatus(!!prevClosestHandle, isValid),
});
if (!prevClosestHandle && !result.isValid) {
if (!prevClosestHandle && !isValid && !handleDomNode) {
return resetRecentHandle(prevActiveHandle);
}
connection = result.connection;
isValid = result.isValid;
if (connection.source !== connection.target && handleDomNode) {
resetRecentHandle(prevActiveHandle);
prevActiveHandle = handleDomNode;
@@ -154,7 +156,7 @@ export function handlePointerDown({
}
function onPointerUp(event: MouseEvent | TouchEvent) {
if (prevClosestHandle && connection && isValid) {
if ((prevClosestHandle || handleDomNode) && connection && isValid) {
onConnect?.(connection);
}
@@ -172,6 +174,7 @@ export function handlePointerDown({
autoPanStarted = false;
isValid = false;
connection = null;
handleDomNode = null;
doc.removeEventListener('mousemove', onPointerMove as EventListener);
doc.removeEventListener('mouseup', onPointerUp as EventListener);

View File

@@ -6,7 +6,7 @@ import { Provider } from '../../contexts/RFStoreContext';
import { createRFStore } from '../../store';
import type { ReactFlowState } from '../../types';
const ReactFlowProvider: FC<PropsWithChildren> = ({ children }) => {
const ReactFlowProvider: FC<PropsWithChildren<unknown>> = ({ children }) => {
const storeRef = useRef<StoreApi<ReactFlowState> | null>(null);
if (!storeRef.current) {

View File

@@ -4,7 +4,7 @@ import type { FC, PropsWithChildren } from 'react';
import StoreContext from '../../contexts/RFStoreContext';
import ReactFlowProvider from '../../components/ReactFlowProvider';
const Wrapper: FC<PropsWithChildren> = ({ children }) => {
const Wrapper: FC<PropsWithChildren<unknown>> = ({ children }) => {
const isWrapped = useContext(StoreContext);
if (isWrapped) {

View File

@@ -4,7 +4,7 @@ import { shallow } from 'zustand/shallow';
import { useStoreApi, useStore } from '../hooks/useStore';
import { pointToRendererPoint, getTransformForBounds, getD3Transition } from '../utils/graph';
import { fitView as fitViewStore } from '../store/utils';
import { fitView } from '../store/utils';
import type { ViewportHelperFunctions, ReactFlowState, XYPosition } from '../types';
// eslint-disable-next-line @typescript-eslint/no-empty-function
@@ -17,7 +17,7 @@ const initialViewportHelper: ViewportHelperFunctions = {
getZoom: () => 1,
setViewport: noop,
getViewport: () => ({ x: 0, y: 0, zoom: 1 }),
fitView: noop,
fitView: () => false,
setCenter: noop,
fitBounds: noop,
project: (position: XYPosition) => position,
@@ -51,7 +51,7 @@ const useViewportHelper = (): ViewportHelperFunctions => {
const [x, y, zoom] = store.getState().transform;
return { x, y, zoom };
},
fitView: (options) => fitViewStore(store.getState, options),
fitView: (options) => fitView(store.getState, options),
setCenter: (x, y, options) => {
const { width, height, maxZoom } = store.getState();
const nextZoom = typeof options?.zoom !== 'undefined' ? options.zoom : maxZoom;

View File

@@ -138,35 +138,43 @@ export function fitView(get: StoreApi<ReactFlowState>['getState'], options: Inte
fitViewOnInit,
nodeOrigin,
} = get();
const isInitialFitView = options.initial && !fitViewOnInitDone && fitViewOnInit;
const d3initialized = d3Zoom && d3Selection;
if ((options.initial && !fitViewOnInitDone && fitViewOnInit) || !options.initial) {
if (d3Zoom && d3Selection) {
const nodes = getNodes().filter((n) => (options.includeHiddenNodes ? n.width && n.height : !n.hidden));
if (d3initialized && (isInitialFitView || !options.initial)) {
const nodes = getNodes().filter((n) => {
const isVisible = options.includeHiddenNodes ? n.width && n.height : !n.hidden;
const nodesInitialized = nodes.every((n) => n.width && n.height);
if (nodes.length > 0 && nodesInitialized) {
const bounds = getRectOfNodes(nodes, nodeOrigin);
const [x, y, zoom] = getTransformForBounds(
bounds,
width,
height,
options.minZoom ?? minZoom,
options.maxZoom ?? maxZoom,
options.padding ?? 0.1
);
const nextTransform = zoomIdentity.translate(x, y).scale(zoom);
if (typeof options.duration === 'number' && options.duration > 0) {
d3Zoom.transform(getD3Transition(d3Selection, options.duration), nextTransform);
} else {
d3Zoom.transform(d3Selection, nextTransform);
}
return true;
if (options.nodes?.length) {
return isVisible && options.nodes.some((optionNode) => optionNode.id === n.id);
}
return isVisible;
});
const nodesInitialized = nodes.every((n) => n.width && n.height);
if (nodes.length > 0 && nodesInitialized) {
const bounds = getRectOfNodes(nodes, nodeOrigin);
const [x, y, zoom] = getTransformForBounds(
bounds,
width,
height,
options.minZoom ?? minZoom,
options.maxZoom ?? maxZoom,
options.padding ?? 0.1
);
const nextTransform = zoomIdentity.translate(x, y).scale(zoom);
if (typeof options.duration === 'number' && options.duration > 0) {
d3Zoom.transform(getD3Transition(d3Selection, options.duration), nextTransform);
} else {
d3Zoom.transform(d3Selection, nextTransform);
}
return true;
}
}

View File

@@ -230,4 +230,5 @@
width: 100%;
height: 100%;
pointer-events: none;
user-select: none;
}

View File

@@ -30,7 +30,7 @@ export type NodeTypesWrapped = { [key: string]: MemoExoticComponent<ComponentTyp
export type EdgeTypes = { [key: string]: ComponentType<EdgeProps> };
export type EdgeTypesWrapped = { [key: string]: MemoExoticComponent<ComponentType<WrapEdgeProps>> };
export type FitView = (fitViewOptions?: FitViewOptions) => void;
export type FitView = (fitViewOptions?: FitViewOptions) => boolean;
export type Project = (position: XYPosition) => XYPosition;
@@ -76,6 +76,7 @@ export type FitViewOptions = {
minZoom?: number;
maxZoom?: number;
duration?: number;
nodes?: (Partial<Node> & { id: Node['id'] })[];
};
export type OnConnectStartParams = {

View File

@@ -103,17 +103,12 @@ export function isInputDOMNode(event: KeyboardEvent | ReactKeyboardEvent): boole
// using composed path for handling shadow dom
const target = (kbEvent.composedPath?.()?.[0] || event.target) as HTMLElement;
const isInput = ['INPUT', 'SELECT', 'TEXTAREA'].includes(target?.nodeName) || target?.hasAttribute('contenteditable');
// we want to be able to do a multi selection event if we are in an input field
if (event.ctrlKey || event.metaKey || event.shiftKey) {
return false;
}
const isModifierKey = event.ctrlKey || event.metaKey || event.shiftKey;
// when an input field is focused we don't want to trigger deletion or movement of nodes
return (
['INPUT', 'SELECT', 'TEXTAREA'].includes(target?.nodeName) ||
target?.hasAttribute('contenteditable') ||
!!target?.closest('.nokey')
);
return (isInput && !isModifierKey) || !!target?.closest('.nokey');
}
export const isMouseEvent = (

View File

@@ -1,5 +1,12 @@
# @reactflow/minimap
## 11.3.8
### Patch Changes
- Updated dependencies [[`72216ff6`](https://github.com/wbkd/react-flow/commit/72216ff62014acd2d73999053c72bd7aeed351f6), [`959b1114`](https://github.com/wbkd/react-flow/commit/959b111448bba4686040473e46988be9e7befbe6), [`0d259b02`](https://github.com/wbkd/react-flow/commit/0d259b028558aab650546f3371a85f3bce45252f), [`f3de9335`](https://github.com/wbkd/react-flow/commit/f3de9335af6cd96cd77dc77f24a944eef85384e5), [`23424ea6`](https://github.com/wbkd/react-flow/commit/23424ea6750f092210f83df17a00c89adb910d96), [`021f5a92`](https://github.com/wbkd/react-flow/commit/021f5a9210f47a968e50446cd2f9dae1f97880a4)]:
- @reactflow/core@11.5.5
## 11.3.7
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@reactflow/minimap",
"version": "11.3.7",
"version": "11.3.8",
"description": "Minimap component for React Flow.",
"keywords": [
"react",

View File

@@ -1,5 +1,12 @@
# @reactflow/node-toolbar
## 1.1.8
### Patch Changes
- Updated dependencies [[`72216ff6`](https://github.com/wbkd/react-flow/commit/72216ff62014acd2d73999053c72bd7aeed351f6), [`959b1114`](https://github.com/wbkd/react-flow/commit/959b111448bba4686040473e46988be9e7befbe6), [`0d259b02`](https://github.com/wbkd/react-flow/commit/0d259b028558aab650546f3371a85f3bce45252f), [`f3de9335`](https://github.com/wbkd/react-flow/commit/f3de9335af6cd96cd77dc77f24a944eef85384e5), [`23424ea6`](https://github.com/wbkd/react-flow/commit/23424ea6750f092210f83df17a00c89adb910d96), [`021f5a92`](https://github.com/wbkd/react-flow/commit/021f5a9210f47a968e50446cd2f9dae1f97880a4)]:
- @reactflow/core@11.5.5
## 1.1.7
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@reactflow/node-toolbar",
"version": "1.1.7",
"version": "1.1.8",
"description": "A toolbar component for React Flow that can be attached to a node.",
"keywords": [
"react",

View File

@@ -1,5 +1,23 @@
# reactflow
## 11.5.6
### Patch Changes
- [#2834](https://github.com/wbkd/react-flow/pull/2834) [`23424ea6`](https://github.com/wbkd/react-flow/commit/23424ea6750f092210f83df17a00c89adb910d96) Thanks [@bcakmakoglu](https://github.com/bcakmakoglu)! - Add `nodes` to fit view options to allow fitting view only around specified set of nodes
- [#2836](https://github.com/wbkd/react-flow/pull/2836) [`959b1114`](https://github.com/wbkd/react-flow/commit/959b111448bba4686040473e46988be9e7befbe6) - Fix: connections for handles with bigger handles than connection radius
- [#2819](https://github.com/wbkd/react-flow/pull/2819) [`0d259b02`](https://github.com/wbkd/react-flow/commit/0d259b028558aab650546f3371a85f3bce45252f) Thanks [@bcakmakoglu](https://github.com/bcakmakoglu)! - Avoid triggering edge update if not using left mouse button
- [#2832](https://github.com/wbkd/react-flow/pull/2832) [`f3de9335`](https://github.com/wbkd/react-flow/commit/f3de9335af6cd96cd77dc77f24a944eef85384e5) - fitView: return type boolean
- [#2838](https://github.com/wbkd/react-flow/pull/2838) [`021f5a92`](https://github.com/wbkd/react-flow/commit/021f5a9210f47a968e50446cd2f9dae1f97880a4) - refactor: use key press handle modifier keys + input
- [#2839](https://github.com/wbkd/react-flow/pull/2839) [`72216ff6`](https://github.com/wbkd/react-flow/commit/72216ff62014acd2d73999053c72bd7aeed351f6) - fix PropsWithChildren: pass default generic for v17 types
- Updated dependencies [[`72216ff6`](https://github.com/wbkd/react-flow/commit/72216ff62014acd2d73999053c72bd7aeed351f6), [`959b1114`](https://github.com/wbkd/react-flow/commit/959b111448bba4686040473e46988be9e7befbe6), [`0d259b02`](https://github.com/wbkd/react-flow/commit/0d259b028558aab650546f3371a85f3bce45252f), [`f3de9335`](https://github.com/wbkd/react-flow/commit/f3de9335af6cd96cd77dc77f24a944eef85384e5), [`23424ea6`](https://github.com/wbkd/react-flow/commit/23424ea6750f092210f83df17a00c89adb910d96), [`021f5a92`](https://github.com/wbkd/react-flow/commit/021f5a9210f47a968e50446cd2f9dae1f97880a4)]:
- @reactflow/core@11.5.5
- @reactflow/background@11.1.8
- @reactflow/controls@11.1.8
- @reactflow/minimap@11.3.8
- @reactflow/node-toolbar@1.1.8
## 11.5.5
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "reactflow",
"version": "11.5.5",
"version": "11.5.6",
"description": "A highly customizable React library for building node-based editors and interactive flow charts",
"keywords": [
"react",

8
pnpm-lock.yaml generated
View File

@@ -58,6 +58,7 @@ importers:
specifiers:
'@cypress/skip-test': ^2.6.1
'@reactflow/node-resizer': workspace:*
'@types/dagre': ^0.7.48
'@types/react': ^18.0.17
'@types/react-dom': ^18.0.6
'@vitejs/plugin-react': ^3.0.1
@@ -84,6 +85,7 @@ importers:
reactflow: link:../../packages/reactflow
devDependencies:
'@cypress/skip-test': registry.npmjs.org/@cypress/skip-test/2.6.1
'@types/dagre': registry.npmjs.org/@types/dagre/0.7.48
'@types/react': registry.npmjs.org/@types/react/18.0.19
'@types/react-dom': registry.npmjs.org/@types/react-dom/18.0.6
'@vitejs/plugin-react': registry.npmjs.org/@vitejs/plugin-react/3.0.1_vite@4.0.4
@@ -2046,6 +2048,12 @@ packages:
'@types/d3-zoom': registry.npmjs.org/@types/d3-zoom/3.0.1
dev: false
registry.npmjs.org/@types/dagre/0.7.48:
resolution: {integrity: sha512-rF3yXSwHIrDxEkN6edCE4TXknb5YSEpiXfLaspw1I08grC49ZFuAVGOQCmZGIuLUGoFgcqGlUFBL/XrpgYpQgw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@types/dagre/-/dagre-0.7.48.tgz}
name: '@types/dagre'
version: 0.7.48
dev: true
registry.npmjs.org/@types/estree/0.0.39:
resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz}
name: '@types/estree'