Merge branch 'main' into feat/svelte
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -9,6 +9,7 @@ import CustomNode from '../examples/CustomNode';
|
||||
import DefaultNodes from '../examples/DefaultNodes';
|
||||
import DragHandle from '../examples/DragHandle';
|
||||
import DragNDrop from '../examples/DragNDrop';
|
||||
import EasyConnect from '../examples/EasyConnect';
|
||||
import Edges from '../examples/Edges';
|
||||
import EdgeRenderer from '../examples/EdgeRenderer';
|
||||
import EdgeTypes from '../examples/EdgeTypes';
|
||||
@@ -96,6 +97,11 @@ const routes: IRoute[] = [
|
||||
path: '/dragndrop',
|
||||
component: DragNDrop,
|
||||
},
|
||||
{
|
||||
name: 'EasyConnect',
|
||||
path: '/easy-connect',
|
||||
component: EasyConnect,
|
||||
},
|
||||
{
|
||||
name: 'Edges',
|
||||
path: '/edges',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { FC } from 'react';
|
||||
import { FC } from 'react';
|
||||
|
||||
import ReactFlow, {
|
||||
Node,
|
||||
|
||||
@@ -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);
|
||||
@@ -99,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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { useCallback } from 'react';
|
||||
import ReactFlow, {
|
||||
Node,
|
||||
addEdge,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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
|
||||
>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, DragEvent } from 'react';
|
||||
import { useState, DragEvent } from 'react';
|
||||
import ReactFlow, {
|
||||
ReactFlowProvider,
|
||||
addEdge,
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import { ConnectionLineComponentProps, getStraightPath } from 'reactflow';
|
||||
|
||||
function CustomConnectionLine({ fromX, fromY, toX, toY, connectionLineStyle }: ConnectionLineComponentProps) {
|
||||
const [edgePath] = getStraightPath({
|
||||
sourceX: fromX,
|
||||
sourceY: fromY,
|
||||
targetX: toX,
|
||||
targetY: toY,
|
||||
});
|
||||
|
||||
return (
|
||||
<g>
|
||||
<path style={connectionLineStyle} fill="none" d={edgePath} />
|
||||
<circle cx={toX} cy={toY} fill="black" r={3} stroke="black" strokeWidth={1.5} />
|
||||
</g>
|
||||
);
|
||||
}
|
||||
|
||||
export default CustomConnectionLine;
|
||||
@@ -0,0 +1,39 @@
|
||||
import { Handle, NodeProps, Position, ReactFlowState, useStore } from 'reactflow';
|
||||
|
||||
const connectionNodeIdSelector = (state: ReactFlowState) => state.connectionNodeId;
|
||||
|
||||
export default function CustomNode({ id, isConnectable }: NodeProps) {
|
||||
const connectionNodeId = useStore(connectionNodeIdSelector);
|
||||
const isTarget = connectionNodeId && connectionNodeId !== id;
|
||||
|
||||
const targetHandleStyle = { zIndex: isTarget ? 3 : 1 };
|
||||
const label = isTarget ? 'Drop here' : 'Drag to connect';
|
||||
|
||||
return (
|
||||
<div className="customNode">
|
||||
<div
|
||||
className="customNodeBody"
|
||||
style={{
|
||||
borderStyle: isTarget ? 'dashed' : 'solid',
|
||||
backgroundColor: isTarget ? '#ffcce3' : '#ccd9f6',
|
||||
}}
|
||||
>
|
||||
<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>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useStore, getStraightPath, EdgeProps } from 'reactflow';
|
||||
|
||||
import { getEdgeParams } from './utils.js';
|
||||
|
||||
function FloatingEdge({ id, source, target, markerEnd, style }: EdgeProps) {
|
||||
const sourceNode = useStore(useCallback((store) => store.nodeInternals.get(source), [source]));
|
||||
const targetNode = useStore(useCallback((store) => store.nodeInternals.get(target), [target]));
|
||||
|
||||
if (!sourceNode || !targetNode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { sx, sy, tx, ty } = getEdgeParams(sourceNode, targetNode);
|
||||
|
||||
const [edgePath] = getStraightPath({
|
||||
sourceX: sx,
|
||||
sourceY: sy,
|
||||
targetX: tx,
|
||||
targetY: ty,
|
||||
});
|
||||
|
||||
return <path id={id} className="react-flow__edge-path" d={edgePath} markerEnd={markerEnd} style={style} />;
|
||||
}
|
||||
|
||||
export default FloatingEdge;
|
||||
@@ -0,0 +1,85 @@
|
||||
import { useCallback } from 'react';
|
||||
import ReactFlow, { Node, Edge, addEdge, useNodesState, useEdgesState, MarkerType, OnConnect } from 'reactflow';
|
||||
|
||||
import CustomNode from './CustomNode';
|
||||
import FloatingEdge from './FloatingEdge';
|
||||
import CustomConnectionLine from './CustomConnectionLine';
|
||||
|
||||
import 'reactflow/dist/style.css';
|
||||
import './style.css';
|
||||
|
||||
const initialNodes: Node[] = [
|
||||
{
|
||||
id: '1',
|
||||
type: 'custom',
|
||||
position: { x: 0, y: 0 },
|
||||
data: {},
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
type: 'custom',
|
||||
position: { x: 250, y: 320 },
|
||||
data: {},
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
type: 'custom',
|
||||
position: { x: 40, y: 300 },
|
||||
data: {},
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
type: 'custom',
|
||||
position: { x: 300, y: 0 },
|
||||
data: {},
|
||||
},
|
||||
];
|
||||
|
||||
const initialEdges: Edge[] = [];
|
||||
|
||||
const connectionLineStyle = {
|
||||
strokeWidth: 3,
|
||||
stroke: 'black',
|
||||
};
|
||||
|
||||
const nodeTypes = {
|
||||
custom: CustomNode,
|
||||
};
|
||||
|
||||
const edgeTypes = {
|
||||
floating: FloatingEdge,
|
||||
};
|
||||
|
||||
const defaultEdgeOptions = {
|
||||
style: { strokeWidth: 3, stroke: 'black' },
|
||||
type: 'floating',
|
||||
markerEnd: {
|
||||
type: MarkerType.ArrowClosed,
|
||||
color: 'black',
|
||||
},
|
||||
};
|
||||
|
||||
const EasyConnectExample = () => {
|
||||
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
|
||||
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
|
||||
|
||||
const onConnect: OnConnect = useCallback((params) => setEdges((eds) => addEdge(params, eds)), [setEdges]);
|
||||
|
||||
return (
|
||||
<ReactFlow
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
onNodesChange={onNodesChange}
|
||||
onEdgesChange={onEdgesChange}
|
||||
onConnect={onConnect}
|
||||
fitView
|
||||
nodeTypes={nodeTypes}
|
||||
edgeTypes={edgeTypes}
|
||||
defaultEdgeOptions={defaultEdgeOptions}
|
||||
connectionLineComponent={CustomConnectionLine}
|
||||
connectionLineStyle={connectionLineStyle}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default EasyConnectExample;
|
||||
@@ -0,0 +1,54 @@
|
||||
.customNodeBody {
|
||||
width: 150px;
|
||||
height: 80px;
|
||||
border: 3px solid black;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.customNode:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -10px;
|
||||
left: 50%;
|
||||
height: 20px;
|
||||
width: 40px;
|
||||
transform: translate(-50%, 0);
|
||||
background: #d6d5e6;
|
||||
z-index: 1000;
|
||||
line-height: 1;
|
||||
border-radius: 4px;
|
||||
color: #fff;
|
||||
font-size: 9px;
|
||||
border: 2px solid #222138;
|
||||
}
|
||||
|
||||
div.sourceHandle {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
border-radius: 0;
|
||||
transform: none;
|
||||
border: none;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
div.targetHandle {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: blue;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
border-radius: 0;
|
||||
transform: none;
|
||||
border: none;
|
||||
opacity: 0;
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
import { Node, Position, MarkerType, XYPosition } from 'reactflow';
|
||||
|
||||
// this helper function returns the intersection point
|
||||
// of the line between the center of the intersectionNode and the target node
|
||||
function getNodeIntersection(intersectionNode: Node, targetNode: Node) {
|
||||
// https://math.stackexchange.com/questions/1724792/an-algorithm-for-finding-the-intersection-point-between-a-center-of-vision-and-a
|
||||
const {
|
||||
width: intersectionNodeWidth,
|
||||
height: intersectionNodeHeight,
|
||||
positionAbsolute: intersectionNodePosition,
|
||||
} = intersectionNode;
|
||||
const targetPosition = targetNode.positionAbsolute!;
|
||||
|
||||
const w = intersectionNodeWidth! / 2;
|
||||
const h = intersectionNodeHeight! / 2;
|
||||
|
||||
const x2 = intersectionNodePosition!.x + w;
|
||||
const y2 = intersectionNodePosition!.y + h;
|
||||
const x1 = targetPosition.x + w;
|
||||
const y1 = targetPosition.y + h;
|
||||
|
||||
const xx1 = (x1 - x2) / (2 * w) - (y1 - y2) / (2 * h);
|
||||
const yy1 = (x1 - x2) / (2 * w) + (y1 - y2) / (2 * h);
|
||||
const a = 1 / (Math.abs(xx1) + Math.abs(yy1));
|
||||
const xx3 = a * xx1;
|
||||
const yy3 = a * yy1;
|
||||
const x = w * (xx3 + yy3) + x2;
|
||||
const y = h * (-xx3 + yy3) + y2;
|
||||
|
||||
return { x, y };
|
||||
}
|
||||
|
||||
// returns the position (top,right,bottom or right) passed node compared to the intersection point
|
||||
function getEdgePosition(node: Node, intersectionPoint: XYPosition) {
|
||||
const n = { ...node.positionAbsolute, ...node };
|
||||
const nx = Math.round(n.x!);
|
||||
const ny = Math.round(n.y!);
|
||||
const px = Math.round(intersectionPoint.x);
|
||||
const py = Math.round(intersectionPoint.y);
|
||||
|
||||
if (px <= nx + 1) {
|
||||
return Position.Left;
|
||||
}
|
||||
if (px >= nx + n.width! - 1) {
|
||||
return Position.Right;
|
||||
}
|
||||
if (py <= ny + 1) {
|
||||
return Position.Top;
|
||||
}
|
||||
if (py >= n.y! + n.height! - 1) {
|
||||
return Position.Bottom;
|
||||
}
|
||||
|
||||
return Position.Top;
|
||||
}
|
||||
|
||||
// returns the parameters (sx, sy, tx, ty, sourcePos, targetPos) you need to create an edge
|
||||
export function getEdgeParams(source: Node, target: Node) {
|
||||
const sourceIntersectionPoint = getNodeIntersection(source, target);
|
||||
const targetIntersectionPoint = getNodeIntersection(target, source);
|
||||
|
||||
const sourcePos = getEdgePosition(source, sourceIntersectionPoint);
|
||||
const targetPos = getEdgePosition(target, targetIntersectionPoint);
|
||||
|
||||
return {
|
||||
sx: sourceIntersectionPoint.x,
|
||||
sy: sourceIntersectionPoint.y,
|
||||
tx: targetIntersectionPoint.x,
|
||||
ty: targetIntersectionPoint.y,
|
||||
sourcePos,
|
||||
targetPos,
|
||||
};
|
||||
}
|
||||
|
||||
export function createNodesAndEdges() {
|
||||
const nodes = [];
|
||||
const edges = [];
|
||||
const center = { x: window.innerWidth / 2, y: window.innerHeight / 2 };
|
||||
|
||||
nodes.push({ id: 'target', data: { label: 'Target' }, position: center });
|
||||
|
||||
for (let i = 0; i < 8; i++) {
|
||||
const degrees = i * (360 / 8);
|
||||
const radians = degrees * (Math.PI / 180);
|
||||
const x = 250 * Math.cos(radians) + center.x;
|
||||
const y = 250 * Math.sin(radians) + center.y;
|
||||
|
||||
nodes.push({ id: `${i}`, data: { label: 'Source' }, position: { x, y } });
|
||||
|
||||
edges.push({
|
||||
id: `edge-${i}`,
|
||||
target: 'target',
|
||||
source: `${i}`,
|
||||
type: 'floating',
|
||||
markerEnd: {
|
||||
type: MarkerType.Arrow,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return { nodes, edges };
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { MouseEvent, useCallback } from 'react';
|
||||
import { MouseEvent, useCallback } from 'react';
|
||||
import ReactFlow, {
|
||||
Controls,
|
||||
Background,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { MouseEvent, useCallback } from 'react';
|
||||
import { MouseEvent, useCallback } from 'react';
|
||||
import ReactFlow, {
|
||||
Controls,
|
||||
Background,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { MouseEvent, CSSProperties, useCallback } from 'react';
|
||||
import { MouseEvent, CSSProperties, useCallback } from 'react';
|
||||
|
||||
import ReactFlow, {
|
||||
Background,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import ReactFlow, {
|
||||
Background,
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -2,10 +2,3 @@
|
||||
flex-grow: 1;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.controls {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { FC } from 'react';
|
||||
import { FC } from 'react';
|
||||
|
||||
import ReactFlow, {
|
||||
Background,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, MouseEvent, useCallback } from 'react';
|
||||
import { useState, MouseEvent, useCallback } from 'react';
|
||||
import ReactFlow, {
|
||||
Controls,
|
||||
MiniMap,
|
||||
|
||||
@@ -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[] = [
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, CSSProperties, FC, useCallback } from 'react';
|
||||
import { useState, CSSProperties, FC, useCallback } from 'react';
|
||||
import ReactFlow, {
|
||||
addEdge,
|
||||
Node,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { MouseEvent, useCallback } from 'react';
|
||||
import { MouseEvent, useCallback } from 'react';
|
||||
import ReactFlow, {
|
||||
Controls,
|
||||
ReactFlowProvider,
|
||||
|
||||
@@ -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[] = [
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, CSSProperties, useCallback } from 'react';
|
||||
import { useState, CSSProperties, useCallback } from 'react';
|
||||
import ReactFlow, {
|
||||
ReactFlowInstance,
|
||||
Edge,
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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) =>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import React, { FC, useCallback, useState } from 'react';
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import ReactFlow, {
|
||||
addEdge,
|
||||
Handle,
|
||||
Connection,
|
||||
Position,
|
||||
Node,
|
||||
Edge,
|
||||
NodeProps,
|
||||
NodeTypes,
|
||||
useNodesState,
|
||||
useEdgesState,
|
||||
OnConnectStartParams,
|
||||
OnConnectStart,
|
||||
OnConnectEnd,
|
||||
OnConnect,
|
||||
} from 'reactflow';
|
||||
|
||||
import styles from './validation.module.css';
|
||||
@@ -49,24 +50,24 @@ const ValidationFlow = () => {
|
||||
const [nodes, , onNodesChange] = useNodesState(initialNodes);
|
||||
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
|
||||
|
||||
const onConnectStart = useCallback(
|
||||
(event: React.MouseEvent, params: OnConnectStartParams) => {
|
||||
const onConnectStart: OnConnectStart = useCallback(
|
||||
(event, params) => {
|
||||
console.log('on connect start', params, event, value);
|
||||
setValue(1);
|
||||
},
|
||||
[value]
|
||||
);
|
||||
|
||||
const onConnect = useCallback(
|
||||
(params: Connection | Edge) => {
|
||||
const onConnect: OnConnect = useCallback(
|
||||
(params) => {
|
||||
console.log('on connect', params);
|
||||
setEdges((eds) => addEdge(params, eds));
|
||||
},
|
||||
[setEdges]
|
||||
);
|
||||
|
||||
const onConnectEnd = useCallback(
|
||||
(event: MouseEvent) => {
|
||||
const onConnectEnd: OnConnectEnd = useCallback(
|
||||
(event) => {
|
||||
console.log('on connect end', event, value);
|
||||
setValue(0);
|
||||
},
|
||||
|
||||
@@ -24,10 +24,18 @@
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.validationflow :global .react-flow__handle-connecting {
|
||||
.validationflow :global .connecting {
|
||||
background: #ff6060;
|
||||
}
|
||||
|
||||
.validationflow :global .react-flow__handle-valid {
|
||||
.validationflow :global .valid {
|
||||
background: #55dd99;
|
||||
}
|
||||
|
||||
.validationflow :global .valid .react-flow__connection-path {
|
||||
stroke: #55dd99;
|
||||
}
|
||||
|
||||
.validationflow :global .invalid .react-flow__connection-path {
|
||||
stroke: #ff6060;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,42 @@
|
||||
# @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
|
||||
|
||||
- Updated dependencies [[`383a074a`](https://github.com/wbkd/react-flow/commit/383a074aeae6dbec8437fa08c7c8d8240838a84e)]:
|
||||
- @reactflow/core@11.5.4
|
||||
|
||||
## 11.1.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`be8097ac`](https://github.com/wbkd/react-flow/commit/be8097acadca3054c3b236ce4296fc516010ef8c), [`1527795d`](https://github.com/wbkd/react-flow/commit/1527795d18c3af38c8ec7059436ea0fbf6c27bbd), [`3b6348a8`](https://github.com/wbkd/react-flow/commit/3b6348a8d1573afb39576327318bc172e33393c2)]:
|
||||
- @reactflow/core@11.5.3
|
||||
|
||||
## 11.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2792](https://github.com/wbkd/react-flow/pull/2792) [`d8c679b4`](https://github.com/wbkd/react-flow/commit/d8c679b4c90c5b57d4b51e4aaa988243d6eaff5a) - Accept React 17 types as dev dependency
|
||||
|
||||
- Updated dependencies [[`d8c679b4`](https://github.com/wbkd/react-flow/commit/d8c679b4c90c5b57d4b51e4aaa988243d6eaff5a)]:
|
||||
- @reactflow/core@11.5.2
|
||||
|
||||
## 11.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`71153534`](https://github.com/wbkd/react-flow/commit/7115353418ebc7f7c81ab0e861200972bbf7dbd5)]:
|
||||
- @reactflow/core@11.5.1
|
||||
|
||||
## 11.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@reactflow/background",
|
||||
"version": "11.1.3",
|
||||
"version": "11.1.8",
|
||||
"description": "Background component with different variants for React Flow",
|
||||
"keywords": [
|
||||
"react",
|
||||
@@ -46,7 +46,7 @@
|
||||
"@reactflow/rollup-config": "workspace:*",
|
||||
"@reactflow/tsconfig": "workspace:*",
|
||||
"@types/node": "^18.7.16",
|
||||
"@types/react": "^18.0.19",
|
||||
"@types/react": ">=17",
|
||||
"react": "^18.2.0",
|
||||
"typescript": "^4.9.4"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,42 @@
|
||||
# @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
|
||||
|
||||
- Updated dependencies [[`383a074a`](https://github.com/wbkd/react-flow/commit/383a074aeae6dbec8437fa08c7c8d8240838a84e)]:
|
||||
- @reactflow/core@11.5.4
|
||||
|
||||
## 11.1.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`be8097ac`](https://github.com/wbkd/react-flow/commit/be8097acadca3054c3b236ce4296fc516010ef8c), [`1527795d`](https://github.com/wbkd/react-flow/commit/1527795d18c3af38c8ec7059436ea0fbf6c27bbd), [`3b6348a8`](https://github.com/wbkd/react-flow/commit/3b6348a8d1573afb39576327318bc172e33393c2)]:
|
||||
- @reactflow/core@11.5.3
|
||||
|
||||
## 11.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2792](https://github.com/wbkd/react-flow/pull/2792) [`d8c679b4`](https://github.com/wbkd/react-flow/commit/d8c679b4c90c5b57d4b51e4aaa988243d6eaff5a) - Accept React 17 types as dev dependency
|
||||
|
||||
- Updated dependencies [[`d8c679b4`](https://github.com/wbkd/react-flow/commit/d8c679b4c90c5b57d4b51e4aaa988243d6eaff5a)]:
|
||||
- @reactflow/core@11.5.2
|
||||
|
||||
## 11.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`71153534`](https://github.com/wbkd/react-flow/commit/7115353418ebc7f7c81ab0e861200972bbf7dbd5)]:
|
||||
- @reactflow/core@11.5.1
|
||||
|
||||
## 11.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@reactflow/controls",
|
||||
"version": "11.1.3",
|
||||
"version": "11.1.8",
|
||||
"description": "Component to control the viewport of a React Flow instance",
|
||||
"keywords": [
|
||||
"react",
|
||||
@@ -50,7 +50,7 @@
|
||||
"@reactflow/rollup-config": "workspace:*",
|
||||
"@reactflow/tsconfig": "workspace:*",
|
||||
"@types/node": "^18.7.16",
|
||||
"@types/react": "^18.0.19",
|
||||
"@types/react": ">=17",
|
||||
"typescript": "^4.9.4"
|
||||
},
|
||||
"rollup": {
|
||||
|
||||
@@ -1,5 +1,44 @@
|
||||
# @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
|
||||
|
||||
- [`383a074a`](https://github.com/wbkd/react-flow/commit/383a074aeae6dbec8437fa08c7c8d8240838a84e) Thanks [@bcakmakoglu](https://github.com/bcakmakoglu)! - Check if prevClosestHandle exists in onPointerUp. Fixes connections getting stuck on last handle and connecting, even when out of connectionRadius
|
||||
|
||||
## 11.5.3
|
||||
|
||||
This release fixes some issues with the newly introduced connection radius feature. We are now not only checking the radius but the handle itself too (like in the old version). That means that you can connect to a handle that is bigger than the connection radius. We are also not snapping connections anymore when they are not valid and pass a status class to the connection line that says if the current connection is valid or not. More over we fixed a connection issue with iOS.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2800](https://github.com/wbkd/react-flow/pull/2800) [`be8097ac`](https://github.com/wbkd/react-flow/commit/be8097acadca3054c3b236ce4296fc516010ef8c) - When node is not draggable, you can't move it with a selection either
|
||||
- [#2803](https://github.com/wbkd/react-flow/pull/2803) [`1527795d`](https://github.com/wbkd/react-flow/commit/1527795d18c3af38c8ec7059436ea0fbf6c27bbd) - connection: add status class (valid or invalid) while in connection radius
|
||||
- [#2801](https://github.com/wbkd/react-flow/pull/2801) [`3b6348a8`](https://github.com/wbkd/react-flow/commit/3b6348a8d1573afb39576327318bc172e33393c2) - fix(ios): connection error + dont snap invalid connection lines, check handle and connection radius
|
||||
|
||||
## 11.5.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2792](https://github.com/wbkd/react-flow/pull/2792) [`d8c679b4`](https://github.com/wbkd/react-flow/commit/d8c679b4c90c5b57d4b51e4aaa988243d6eaff5a) - Accept React 17 types as dev dependency
|
||||
|
||||
## 11.5.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2783](https://github.com/wbkd/react-flow/pull/2783) [`71153534`](https://github.com/wbkd/react-flow/commit/7115353418ebc7f7c81ab0e861200972bbf7dbd5) - connections: check handle below mouse before using connection radius
|
||||
|
||||
## 11.5.0
|
||||
|
||||
Lot's of improvements are coming with this release!
|
||||
@@ -8,23 +47,24 @@ Lot's of improvements are coming with this release!
|
||||
- **Auto pan**: When you drag a node, a selection or the connection line to the border of the pane, it will pan into that direction. That makes it easier to connect far away nodes for example. If you don't like it you can set `autoPnaOnNodeDrag` and `autoPanOnConnect` to false.
|
||||
- **Touch devices**: It's finally possibleto connect nodes with the connection line on touch devices. In combination with the new auto pan and connection radius the overall UX is way better.
|
||||
- **Errors**: We added an `onError` prop to get notified when an error like "couldn't find source handle" happens. This is useful if you want to log errors for example.
|
||||
- **Node type**: We added a second param to the generic `Node` type. You can not only pass `NodeData` but also the type as a second param:
|
||||
- **Node type**: We added a second param to the generic `Node` type. You can not only pass `NodeData` but also the type as a second param:
|
||||
|
||||
```ts
|
||||
type MyCustomNode = Node<MyCustomNodeData, 'custom-node-type'>
|
||||
type MyCustomNode = Node<MyCustomNodeData, 'custom-node-type'>;
|
||||
```
|
||||
|
||||
This makes it easier to work with different custom nodes and data types.
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#2754](https://github.com/wbkd/react-flow/pull/2754) [`e96309b6`](https://github.com/wbkd/react-flow/commit/e96309b6a57b1071faeebf7b0547fef7fd418694) - Add auto pan for connecting and node dragging and `connectionRadius`
|
||||
- [#2754](https://github.com/wbkd/react-flow/pull/2754) [`e96309b6`](https://github.com/wbkd/react-flow/commit/e96309b6a57b1071faeebf7b0547fef7fd418694) - Add auto pan for connecting and node dragging and `connectionRadius`
|
||||
- [#2773](https://github.com/wbkd/react-flow/pull/2773) - Add `onError` prop to get notified when an error happens
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2763](https://github.com/wbkd/react-flow/pull/2763) [`85003b01`](https://github.com/wbkd/react-flow/commit/85003b01add71ea852bd5b0d2f1e7496050a6b52) - Connecting nodes: Enable connections on touch devices
|
||||
- [#2763](https://github.com/wbkd/react-flow/pull/2763) [`85003b01`](https://github.com/wbkd/react-flow/commit/85003b01add71ea852bd5b0d2f1e7496050a6b52) - Connecting nodes: Enable connections on touch devices
|
||||
- [#2620](https://github.com/wbkd/react-flow/pull/2620) - Thanks [RichSchulz](https://github.com/RichSchulz)! - Types: improve typing for node type
|
||||
|
||||
|
||||
## 11.4.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@reactflow/core",
|
||||
"version": "11.5.0",
|
||||
"version": "11.5.5",
|
||||
"description": "Core components and util functions of React Flow.",
|
||||
"keywords": [
|
||||
"react",
|
||||
@@ -57,8 +57,8 @@
|
||||
"@reactflow/rollup-config": "workspace:*",
|
||||
"@reactflow/tsconfig": "workspace:*",
|
||||
"@types/node": "^18.7.16",
|
||||
"@types/react": "^18.0.17",
|
||||
"@types/react-dom": "^18.0.6",
|
||||
"@types/react": ">=17",
|
||||
"@types/react-dom": ">=17",
|
||||
"react": "^18.2.0",
|
||||
"typescript": "^4.9.4"
|
||||
},
|
||||
|
||||
@@ -1,12 +1,19 @@
|
||||
import { CSSProperties, useCallback } from 'react';
|
||||
import { shallow } from 'zustand/shallow';
|
||||
import cc from 'classcat';
|
||||
|
||||
import { useStore } from '../../hooks/useStore';
|
||||
import { getBezierPath } from '../Edges/BezierEdge';
|
||||
import { getSmoothStepPath } from '../Edges/SmoothStepEdge';
|
||||
import { getSimpleBezierPath } from '../Edges/SimpleBezierEdge';
|
||||
import { internalsSymbol } from '../../utils';
|
||||
import type { ConnectionLineComponent, HandleType, ReactFlowState, ReactFlowStore } from '../../types';
|
||||
import type {
|
||||
ConnectionLineComponent,
|
||||
ConnectionStatus,
|
||||
HandleType,
|
||||
ReactFlowState,
|
||||
ReactFlowStore,
|
||||
} from '../../types';
|
||||
import { Position, ConnectionLineType, ConnectionMode } from '../../types';
|
||||
|
||||
type ConnectionLineProps = {
|
||||
@@ -15,6 +22,7 @@ type ConnectionLineProps = {
|
||||
type: ConnectionLineType;
|
||||
style?: CSSProperties;
|
||||
CustomComponent?: ConnectionLineComponent;
|
||||
connectionStatus: ConnectionStatus | null;
|
||||
};
|
||||
|
||||
const oppositePosition = {
|
||||
@@ -30,6 +38,7 @@ const ConnectionLine = ({
|
||||
style,
|
||||
type = ConnectionLineType.Bezier,
|
||||
CustomComponent,
|
||||
connectionStatus,
|
||||
}: ConnectionLineProps) => {
|
||||
const { fromNode, handleId, toX, toY, connectionMode } = useStore(
|
||||
useCallback(
|
||||
@@ -80,6 +89,7 @@ const ConnectionLine = ({
|
||||
toY={toY}
|
||||
fromPosition={fromPosition}
|
||||
toPosition={toPosition}
|
||||
connectionStatus={connectionStatus}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -127,12 +137,13 @@ const selector = (s: ReactFlowState) => ({
|
||||
nodeId: s.connectionNodeId,
|
||||
handleType: s.connectionHandleType,
|
||||
nodesConnectable: s.nodesConnectable,
|
||||
connectionStatus: s.connectionStatus,
|
||||
width: s.width,
|
||||
height: s.height,
|
||||
});
|
||||
|
||||
function ConnectionLineWrapper({ containerStyle, style, type, component }: ConnectionLineWrapperProps) {
|
||||
const { nodeId, handleType, nodesConnectable, width, height } = useStore(selector, shallow);
|
||||
const { nodeId, handleType, nodesConnectable, width, height, connectionStatus } = useStore(selector, shallow);
|
||||
const isValid = !!(nodeId && handleType && width && nodesConnectable);
|
||||
|
||||
if (!isValid) {
|
||||
@@ -146,8 +157,15 @@ function ConnectionLineWrapper({ containerStyle, style, type, component }: Conne
|
||||
height={height}
|
||||
className="react-flow__edges react-flow__connectionline react-flow__container"
|
||||
>
|
||||
<g className="react-flow__connection">
|
||||
<ConnectionLine nodeId={nodeId} handleType={handleType} style={style} type={type} CustomComponent={component} />
|
||||
<g className={cc(['react-flow__connection', connectionStatus])}>
|
||||
<ConnectionLine
|
||||
nodeId={nodeId}
|
||||
handleType={handleType}
|
||||
style={style}
|
||||
type={type}
|
||||
CustomComponent={component}
|
||||
connectionStatus={connectionStatus}
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -2,11 +2,12 @@ import type { MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent } fro
|
||||
import { StoreApi } from 'zustand';
|
||||
|
||||
import { getHostForElement, calcAutoPan, getEventPosition } from '../../utils';
|
||||
import type { OnConnect, HandleType, ReactFlowState } from '../../types';
|
||||
import type { OnConnect, HandleType, ReactFlowState, Connection } from '../../types';
|
||||
import { pointToRendererPoint, rendererPointToPoint } from '../../utils/graph';
|
||||
import {
|
||||
ConnectionHandle,
|
||||
getClosestHandle,
|
||||
getConnectionStatus,
|
||||
getHandleLookup,
|
||||
getHandleType,
|
||||
isValidHandle,
|
||||
@@ -45,7 +46,6 @@ export function handlePointerDown({
|
||||
autoPanOnConnect,
|
||||
connectionRadius,
|
||||
onConnectStart,
|
||||
onConnectEnd,
|
||||
panBy,
|
||||
getNodes,
|
||||
cancelConnection,
|
||||
@@ -65,6 +65,9 @@ export function handlePointerDown({
|
||||
let prevActiveHandle: Element;
|
||||
let connectionPosition = getEventPosition(event, containerBounds);
|
||||
let autoPanStarted = false;
|
||||
let connection: Connection | null = null;
|
||||
let isValid = false;
|
||||
let handleDomNode: Element | null = null;
|
||||
|
||||
const handleLookup = getHandleLookup({
|
||||
nodes: getNodes(),
|
||||
@@ -89,6 +92,7 @@ export function handlePointerDown({
|
||||
connectionNodeId: nodeId,
|
||||
connectionHandleId: handleId,
|
||||
connectionHandleType: handleType,
|
||||
connectionStatus: null,
|
||||
});
|
||||
|
||||
onConnectStart?.(event, { nodeId, handleId, handleType });
|
||||
@@ -108,23 +112,8 @@ export function handlePointerDown({
|
||||
autoPanStarted = true;
|
||||
}
|
||||
|
||||
setState({
|
||||
connectionPosition: prevClosestHandle
|
||||
? rendererPointToPoint(
|
||||
{
|
||||
x: prevClosestHandle.x,
|
||||
y: prevClosestHandle.y,
|
||||
},
|
||||
transform
|
||||
)
|
||||
: connectionPosition,
|
||||
});
|
||||
|
||||
if (!prevClosestHandle) {
|
||||
return resetRecentHandle(prevActiveHandle);
|
||||
}
|
||||
|
||||
const { connection, handleDomNode, isValid } = isValidHandle(
|
||||
const result = isValidHandle(
|
||||
event,
|
||||
prevClosestHandle,
|
||||
connectionMode,
|
||||
nodeId,
|
||||
@@ -134,43 +123,58 @@ export function handlePointerDown({
|
||||
doc
|
||||
);
|
||||
|
||||
handleDomNode = result.handleDomNode;
|
||||
connection = result.connection;
|
||||
isValid = result.isValid;
|
||||
|
||||
setState({
|
||||
connectionPosition:
|
||||
prevClosestHandle && isValid
|
||||
? rendererPointToPoint(
|
||||
{
|
||||
x: prevClosestHandle.x,
|
||||
y: prevClosestHandle.y,
|
||||
},
|
||||
transform
|
||||
)
|
||||
: connectionPosition,
|
||||
connectionStatus: getConnectionStatus(!!prevClosestHandle, isValid),
|
||||
});
|
||||
|
||||
if (!prevClosestHandle && !isValid && !handleDomNode) {
|
||||
return resetRecentHandle(prevActiveHandle);
|
||||
}
|
||||
|
||||
if (connection.source !== connection.target && handleDomNode) {
|
||||
resetRecentHandle(prevActiveHandle);
|
||||
prevActiveHandle = handleDomNode;
|
||||
handleDomNode.classList.add('react-flow__handle-connecting');
|
||||
// @todo: remove the old class names "react-flow__handle-" in the next major version
|
||||
handleDomNode.classList.add('connecting', 'react-flow__handle-connecting');
|
||||
handleDomNode.classList.toggle('valid', isValid);
|
||||
handleDomNode.classList.toggle('react-flow__handle-valid', isValid);
|
||||
}
|
||||
}
|
||||
|
||||
function onPointerUp(event: MouseEvent | TouchEvent) {
|
||||
cancelAnimationFrame(autoPanId);
|
||||
autoPanStarted = false;
|
||||
|
||||
if (prevClosestHandle) {
|
||||
const { connection, isValid } = isValidHandle(
|
||||
prevClosestHandle,
|
||||
connectionMode,
|
||||
nodeId,
|
||||
handleId,
|
||||
isTarget ? 'target' : 'source',
|
||||
isValidConnection,
|
||||
doc
|
||||
);
|
||||
|
||||
if (isValid) {
|
||||
onConnect?.(connection);
|
||||
}
|
||||
if ((prevClosestHandle || handleDomNode) && connection && isValid) {
|
||||
onConnect?.(connection);
|
||||
}
|
||||
|
||||
onConnectEnd?.(event);
|
||||
// it's important to get a fresh reference from the store here
|
||||
// in order to get the latest state of onConnectEnd
|
||||
getState().onConnectEnd?.(event);
|
||||
|
||||
if (edgeUpdaterType) {
|
||||
onEdgeUpdateEnd?.(event);
|
||||
}
|
||||
|
||||
resetRecentHandle(prevActiveHandle);
|
||||
|
||||
cancelConnection();
|
||||
cancelAnimationFrame(autoPanId);
|
||||
autoPanStarted = false;
|
||||
isValid = false;
|
||||
connection = null;
|
||||
handleDomNode = null;
|
||||
|
||||
doc.removeEventListener('mousemove', onPointerMove as EventListener);
|
||||
doc.removeEventListener('mouseup', onPointerUp as EventListener);
|
||||
|
||||
@@ -102,6 +102,7 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
||||
|
||||
const doc = getHostForElement(event.target as HTMLElement);
|
||||
const { connection, isValid } = isValidHandle(
|
||||
event,
|
||||
{
|
||||
nodeId,
|
||||
id: handleId,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { ConnectionMode } from '../../types';
|
||||
import { internalsSymbol } from '../../utils';
|
||||
import { MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent } from 'react';
|
||||
|
||||
import { ConnectionMode, ConnectionStatus } from '../../types';
|
||||
import { getEventPosition, internalsSymbol } from '../../utils';
|
||||
import type { Connection, HandleType, XYPosition, Node, NodeHandleBounds } from '../../types';
|
||||
|
||||
export type ConnectionHandle = {
|
||||
@@ -59,9 +61,12 @@ type Result = {
|
||||
connection: Connection;
|
||||
};
|
||||
|
||||
const nullConnection: Connection = { source: null, target: null, sourceHandle: null, targetHandle: null };
|
||||
|
||||
// checks if and returns connection in fom of an object { source: 123, target: 312 }
|
||||
export function isValidHandle(
|
||||
handle: Pick<ConnectionHandle, 'nodeId' | 'id' | 'type'>,
|
||||
event: MouseEvent | TouchEvent | ReactMouseEvent | ReactTouchEvent,
|
||||
handle: Pick<ConnectionHandle, 'nodeId' | 'id' | 'type'> | null,
|
||||
connectionMode: ConnectionMode,
|
||||
fromNodeId: string,
|
||||
fromHandleId: string | null,
|
||||
@@ -73,23 +78,26 @@ export function isValidHandle(
|
||||
const handleDomNode = doc.querySelector(
|
||||
`.react-flow__handle[data-id="${handle?.nodeId}-${handle?.id}-${handle?.type}"]`
|
||||
);
|
||||
const { x, y } = getEventPosition(event);
|
||||
const handleBelow = doc.elementFromPoint(x, y);
|
||||
const handleToCheck = handleBelow?.classList.contains('react-flow__handle') ? handleBelow : handleDomNode;
|
||||
|
||||
const result: Result = {
|
||||
handleDomNode,
|
||||
handleDomNode: handleToCheck,
|
||||
isValid: false,
|
||||
connection: { source: null, target: null, sourceHandle: null, targetHandle: null },
|
||||
connection: nullConnection,
|
||||
};
|
||||
|
||||
if (handleDomNode) {
|
||||
const handleIsTarget = handle.type === 'target';
|
||||
const handleIsSource = handle.type === 'source';
|
||||
const handleNodeId = handleDomNode.getAttribute('data-nodeid');
|
||||
const handleId = handleDomNode.getAttribute('data-handleid');
|
||||
if (handleToCheck) {
|
||||
const handleType = getHandleType(undefined, handleToCheck);
|
||||
const handleNodeId = handleToCheck.getAttribute('data-nodeid');
|
||||
const handleId = handleToCheck.getAttribute('data-handleid');
|
||||
|
||||
const connection: Connection = {
|
||||
source: isTarget ? handle.nodeId : fromNodeId,
|
||||
sourceHandle: isTarget ? handle.id : fromHandleId,
|
||||
target: isTarget ? fromNodeId : handle.nodeId,
|
||||
targetHandle: isTarget ? fromHandleId : handle.id,
|
||||
source: isTarget ? handleNodeId : fromNodeId,
|
||||
sourceHandle: isTarget ? handleId : fromHandleId,
|
||||
target: isTarget ? fromNodeId : handleNodeId,
|
||||
targetHandle: isTarget ? fromHandleId : handleId,
|
||||
};
|
||||
|
||||
result.connection = connection;
|
||||
@@ -97,7 +105,7 @@ export function isValidHandle(
|
||||
// in strict mode we don't allow target to target or source to source connections
|
||||
const isValid =
|
||||
connectionMode === ConnectionMode.Strict
|
||||
? (isTarget && handleIsSource) || (!isTarget && handleIsTarget)
|
||||
? (isTarget && handleType === 'source') || (!isTarget && handleType === 'target')
|
||||
: handleNodeId !== fromNodeId || handleId !== fromHandleId;
|
||||
|
||||
if (isValid) {
|
||||
@@ -149,6 +157,17 @@ export function getHandleType(
|
||||
}
|
||||
|
||||
export function resetRecentHandle(handleDomNode: Element): void {
|
||||
handleDomNode?.classList.remove('react-flow__handle-valid');
|
||||
handleDomNode?.classList.remove('react-flow__handle-connecting');
|
||||
handleDomNode?.classList.remove('valid', 'connecting', 'react-flow__handle-valid', 'react-flow__handle-connecting');
|
||||
}
|
||||
|
||||
export function getConnectionStatus(isInsideConnectionRadius: boolean, isHandleValid: boolean) {
|
||||
let connectionStatus = null;
|
||||
|
||||
if (isHandleValid) {
|
||||
connectionStatus = 'valid';
|
||||
} else if (isInsideConnectionRadius && !isHandleValid) {
|
||||
connectionStatus = 'invalid';
|
||||
}
|
||||
|
||||
return connectionStatus as ConnectionStatus;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -133,10 +133,11 @@ function useDrag({
|
||||
const {
|
||||
nodeInternals,
|
||||
multiSelectionActive,
|
||||
domNode,
|
||||
nodesDraggable,
|
||||
unselectNodesAndEdges,
|
||||
onNodeDragStart,
|
||||
onSelectionDragStart,
|
||||
domNode,
|
||||
} = store.getState();
|
||||
|
||||
const onStart = nodeId ? onNodeDragStart : wrapSelectionDragFunc(onSelectionDragStart);
|
||||
@@ -157,7 +158,7 @@ function useDrag({
|
||||
|
||||
const pointerPos = getPointerPosition(event);
|
||||
lastPos.current = pointerPos;
|
||||
dragItems.current = getDragItems(nodeInternals, pointerPos, nodeId);
|
||||
dragItems.current = getDragItems(nodeInternals, nodesDraggable, pointerPos, nodeId);
|
||||
|
||||
if (onStart && dragItems.current) {
|
||||
const [currentNode, nodes] = getEventHandlerParams({
|
||||
|
||||
@@ -36,9 +36,19 @@ export function hasSelector(target: Element, selector: string, nodeRef: RefObjec
|
||||
}
|
||||
|
||||
// looks for all selected nodes and created a NodeDragItem for each of them
|
||||
export function getDragItems(nodeInternals: NodeInternals, mousePos: XYPosition, nodeId?: string): NodeDragItem[] {
|
||||
export function getDragItems(
|
||||
nodeInternals: NodeInternals,
|
||||
nodesDraggable: boolean,
|
||||
mousePos: XYPosition,
|
||||
nodeId?: string
|
||||
): NodeDragItem[] {
|
||||
return Array.from(nodeInternals.values())
|
||||
.filter((n) => (n.selected || n.id === nodeId) && (!n.parentNode || !isParentSelected(n, nodeInternals)))
|
||||
.filter(
|
||||
(n) =>
|
||||
(n.selected || n.id === nodeId) &&
|
||||
(!n.parentNode || !isParentSelected(n, nodeInternals)) &&
|
||||
(n.draggable || (nodesDraggable && typeof n.draggable === 'undefined'))
|
||||
)
|
||||
.map((n) => ({
|
||||
id: n.id,
|
||||
position: n.position || { x: 0, y: 0 },
|
||||
|
||||
@@ -7,9 +7,11 @@ function useUpdateNodePositions() {
|
||||
const store = useStoreApi();
|
||||
|
||||
const updatePositions = useCallback((params: { x: number; y: number; isShiftPressed: boolean }) => {
|
||||
const { nodeInternals, nodeExtent, updateNodePositions, getNodes, snapToGrid, snapGrid, onError } =
|
||||
const { nodeInternals, nodeExtent, updateNodePositions, getNodes, snapToGrid, snapGrid, onError, nodesDraggable } =
|
||||
store.getState();
|
||||
const selectedNodes = getNodes().filter((n) => n.selected);
|
||||
const selectedNodes = getNodes().filter(
|
||||
(n) => n.selected && (n.draggable || (nodesDraggable && typeof n.draggable === 'undefined'))
|
||||
);
|
||||
// by default a node moves 5px on each key press, or 20px if shift is pressed
|
||||
// if snap grid is enabled, we use that for the velocity.
|
||||
const xVelo = snapToGrid ? snapGrid[0] : 5;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -274,6 +274,7 @@ const createRFStore = () =>
|
||||
connectionNodeId: initialState.connectionNodeId,
|
||||
connectionHandleId: initialState.connectionHandleId,
|
||||
connectionHandleType: initialState.connectionHandleType,
|
||||
connectionStatus: initialState.connectionStatus,
|
||||
}),
|
||||
reset: () => set({ ...initialState }),
|
||||
}));
|
||||
|
||||
@@ -32,6 +32,7 @@ const initialState: ReactFlowStore = {
|
||||
connectionHandleId: null,
|
||||
connectionHandleType: 'source',
|
||||
connectionPosition: { x: 0, y: 0 },
|
||||
connectionStatus: null,
|
||||
connectionMode: ConnectionMode.Strict,
|
||||
domNode: null,
|
||||
paneDragging: false,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -230,4 +230,5 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import type { CSSProperties, ComponentType, HTMLAttributes, ReactNode, MouseEvent as ReactMouseEvent } from 'react';
|
||||
|
||||
import { Position } from '.';
|
||||
import { ConnectionStatus, Position } from '.';
|
||||
import type { Connection, HandleElement, HandleType, Node } from '.';
|
||||
|
||||
type EdgeLabelOptions = {
|
||||
@@ -155,6 +155,7 @@ export type ConnectionLineComponentProps = {
|
||||
toY: number;
|
||||
fromPosition: Position;
|
||||
toPosition: Position;
|
||||
connectionStatus: ConnectionStatus | null;
|
||||
};
|
||||
|
||||
export type ConnectionLineComponent = ComponentType<ConnectionLineComponentProps>;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -61,6 +61,8 @@ export interface Connection {
|
||||
targetHandle: string | null;
|
||||
}
|
||||
|
||||
export type ConnectionStatus = 'valid' | 'invalid';
|
||||
|
||||
export enum ConnectionMode {
|
||||
Strict = 'strict',
|
||||
Loose = 'loose',
|
||||
@@ -74,6 +76,7 @@ export type FitViewOptions = {
|
||||
minZoom?: number;
|
||||
maxZoom?: number;
|
||||
duration?: number;
|
||||
nodes?: (Partial<Node> & { id: Node['id'] })[];
|
||||
};
|
||||
|
||||
export type OnConnectStartParams = {
|
||||
@@ -166,6 +169,7 @@ export type ReactFlowStore = {
|
||||
connectionHandleId: string | null;
|
||||
connectionHandleType: HandleType | null;
|
||||
connectionPosition: XYPosition;
|
||||
connectionStatus: ConnectionStatus | null;
|
||||
connectionMode: ConnectionMode;
|
||||
|
||||
snapToGrid: boolean;
|
||||
|
||||
@@ -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 = (
|
||||
|
||||
@@ -1,5 +1,42 @@
|
||||
# @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
|
||||
|
||||
- Updated dependencies [[`383a074a`](https://github.com/wbkd/react-flow/commit/383a074aeae6dbec8437fa08c7c8d8240838a84e)]:
|
||||
- @reactflow/core@11.5.4
|
||||
|
||||
## 11.3.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`be8097ac`](https://github.com/wbkd/react-flow/commit/be8097acadca3054c3b236ce4296fc516010ef8c), [`1527795d`](https://github.com/wbkd/react-flow/commit/1527795d18c3af38c8ec7059436ea0fbf6c27bbd), [`3b6348a8`](https://github.com/wbkd/react-flow/commit/3b6348a8d1573afb39576327318bc172e33393c2)]:
|
||||
- @reactflow/core@11.5.3
|
||||
|
||||
## 11.3.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2792](https://github.com/wbkd/react-flow/pull/2792) [`d8c679b4`](https://github.com/wbkd/react-flow/commit/d8c679b4c90c5b57d4b51e4aaa988243d6eaff5a) - Accept React 17 types as dev dependency
|
||||
|
||||
- Updated dependencies [[`d8c679b4`](https://github.com/wbkd/react-flow/commit/d8c679b4c90c5b57d4b51e4aaa988243d6eaff5a)]:
|
||||
- @reactflow/core@11.5.2
|
||||
|
||||
## 11.3.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`71153534`](https://github.com/wbkd/react-flow/commit/7115353418ebc7f7c81ab0e861200972bbf7dbd5)]:
|
||||
- @reactflow/core@11.5.1
|
||||
|
||||
## 11.3.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@reactflow/minimap",
|
||||
"version": "11.3.3",
|
||||
"version": "11.3.8",
|
||||
"description": "Minimap component for React Flow.",
|
||||
"keywords": [
|
||||
"react",
|
||||
@@ -55,7 +55,7 @@
|
||||
"@reactflow/rollup-config": "workspace:*",
|
||||
"@reactflow/tsconfig": "workspace:*",
|
||||
"@types/node": "^18.7.16",
|
||||
"@types/react": "^18.0.19",
|
||||
"@types/react": ">=17",
|
||||
"react": "^18.2.0",
|
||||
"typescript": "^4.9.4"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# @reactflow/node-resizer
|
||||
|
||||
## 2.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2792](https://github.com/wbkd/react-flow/pull/2792) [`d8c679b4`](https://github.com/wbkd/react-flow/commit/d8c679b4c90c5b57d4b51e4aaa988243d6eaff5a) - Accept React 17 types as dev dependency
|
||||
|
||||
- Updated dependencies [[`d8c679b4`](https://github.com/wbkd/react-flow/commit/d8c679b4c90c5b57d4b51e4aaa988243d6eaff5a)]:
|
||||
- @reactflow/core@11.5.2
|
||||
|
||||
## 2.0.0
|
||||
|
||||
After this update it should be easier to update the node resizer (no need to update the reactflow package anymore).
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@reactflow/node-resizer",
|
||||
"version": "2.0.0",
|
||||
"version": "2.0.1",
|
||||
"description": "A helper component for resizing nodes.",
|
||||
"keywords": [
|
||||
"react",
|
||||
@@ -55,8 +55,8 @@
|
||||
"@types/d3-drag": "^3.0.1",
|
||||
"@types/d3-selection": "^3.0.3",
|
||||
"@types/node": "^18.7.16",
|
||||
"@types/react": "^18.0.19",
|
||||
"@types/react-dom": "^18.0.6",
|
||||
"@types/react": ">=17",
|
||||
"@types/react-dom": ">=17",
|
||||
"react": "^18.2.0",
|
||||
"typescript": "^4.9.4"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,42 @@
|
||||
# @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
|
||||
|
||||
- Updated dependencies [[`383a074a`](https://github.com/wbkd/react-flow/commit/383a074aeae6dbec8437fa08c7c8d8240838a84e)]:
|
||||
- @reactflow/core@11.5.4
|
||||
|
||||
## 1.1.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`be8097ac`](https://github.com/wbkd/react-flow/commit/be8097acadca3054c3b236ce4296fc516010ef8c), [`1527795d`](https://github.com/wbkd/react-flow/commit/1527795d18c3af38c8ec7059436ea0fbf6c27bbd), [`3b6348a8`](https://github.com/wbkd/react-flow/commit/3b6348a8d1573afb39576327318bc172e33393c2)]:
|
||||
- @reactflow/core@11.5.3
|
||||
|
||||
## 1.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2792](https://github.com/wbkd/react-flow/pull/2792) [`d8c679b4`](https://github.com/wbkd/react-flow/commit/d8c679b4c90c5b57d4b51e4aaa988243d6eaff5a) - Accept React 17 types as dev dependency
|
||||
|
||||
- Updated dependencies [[`d8c679b4`](https://github.com/wbkd/react-flow/commit/d8c679b4c90c5b57d4b51e4aaa988243d6eaff5a)]:
|
||||
- @reactflow/core@11.5.2
|
||||
|
||||
## 1.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`71153534`](https://github.com/wbkd/react-flow/commit/7115353418ebc7f7c81ab0e861200972bbf7dbd5)]:
|
||||
- @reactflow/core@11.5.1
|
||||
|
||||
## 1.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@reactflow/node-toolbar",
|
||||
"version": "1.1.3",
|
||||
"version": "1.1.8",
|
||||
"description": "A toolbar component for React Flow that can be attached to a node.",
|
||||
"keywords": [
|
||||
"react",
|
||||
@@ -36,7 +36,7 @@
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@reactflow/core": "workspace:^11.3.3",
|
||||
"@reactflow/core": "workspace:*",
|
||||
"classcat": "^5.0.3",
|
||||
"zustand": "^4.3.1"
|
||||
},
|
||||
@@ -49,8 +49,8 @@
|
||||
"@reactflow/rollup-config": "workspace:*",
|
||||
"@reactflow/tsconfig": "workspace:*",
|
||||
"@types/node": "^18.7.16",
|
||||
"@types/react": "^18.0.19",
|
||||
"@types/react-dom": "^18.0.6",
|
||||
"@types/react": ">=17",
|
||||
"@types/react-dom": ">=17",
|
||||
"react": "^18.2.0",
|
||||
"typescript": "^4.9.4"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,79 @@
|
||||
# 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
|
||||
|
||||
- [`383a074a`](https://github.com/wbkd/react-flow/commit/383a074aeae6dbec8437fa08c7c8d8240838a84e) Thanks [@bcakmakoglu](https://github.com/bcakmakoglu)! - Check if prevClosestHandle exists in onPointerUp. Fixes connections getting stuck on last handle and connecting, even when out of connectionRadius
|
||||
|
||||
- Updated dependencies [[`383a074a`](https://github.com/wbkd/react-flow/commit/383a074aeae6dbec8437fa08c7c8d8240838a84e)]:
|
||||
- @reactflow/core@11.5.4
|
||||
- @reactflow/background@11.1.7
|
||||
- @reactflow/controls@11.1.7
|
||||
- @reactflow/minimap@11.3.7
|
||||
- @reactflow/node-toolbar@1.1.7
|
||||
|
||||
## 11.5.4
|
||||
|
||||
This release fixes some issues with the newly introduced connection radius feature. We are now not only checking the radius but the handle itself too (like in the old version). That means that you can connect to a handle that is bigger than the connection radius. We are also not snapping connections anymore when they are not valid and pass a status class to the connection line that says if the current connection is valid or not. More over we fixed a connection issue with iOS.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2800](https://github.com/wbkd/react-flow/pull/2800) [`be8097ac`](https://github.com/wbkd/react-flow/commit/be8097acadca3054c3b236ce4296fc516010ef8c) - When node is not draggable, you can't move it with a selection either
|
||||
- [#2803](https://github.com/wbkd/react-flow/pull/2803) [`1527795d`](https://github.com/wbkd/react-flow/commit/1527795d18c3af38c8ec7059436ea0fbf6c27bbd) - connection: add status class (valid or invalid) while in connection radius
|
||||
- [#2801](https://github.com/wbkd/react-flow/pull/2801) [`3b6348a8`](https://github.com/wbkd/react-flow/commit/3b6348a8d1573afb39576327318bc172e33393c2) - fix(ios): connection error + dont snap invalid connection lines, check handle and connection radius
|
||||
|
||||
- Updated dependencies [[`be8097ac`](https://github.com/wbkd/react-flow/commit/be8097acadca3054c3b236ce4296fc516010ef8c), [`1527795d`](https://github.com/wbkd/react-flow/commit/1527795d18c3af38c8ec7059436ea0fbf6c27bbd), [`3b6348a8`](https://github.com/wbkd/react-flow/commit/3b6348a8d1573afb39576327318bc172e33393c2)]:
|
||||
- @reactflow/core@11.5.3
|
||||
- @reactflow/background@11.1.6
|
||||
- @reactflow/controls@11.1.6
|
||||
- @reactflow/minimap@11.3.6
|
||||
- @reactflow/node-toolbar@1.1.6
|
||||
|
||||
## 11.5.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2792](https://github.com/wbkd/react-flow/pull/2792) [`d8c679b4`](https://github.com/wbkd/react-flow/commit/d8c679b4c90c5b57d4b51e4aaa988243d6eaff5a) - Accept React 17 types as dev dependency
|
||||
|
||||
- Updated dependencies [[`d8c679b4`](https://github.com/wbkd/react-flow/commit/d8c679b4c90c5b57d4b51e4aaa988243d6eaff5a)]:
|
||||
- @reactflow/background@11.1.5
|
||||
- @reactflow/controls@11.1.5
|
||||
- @reactflow/core@11.5.2
|
||||
- @reactflow/minimap@11.3.5
|
||||
- @reactflow/node-toolbar@1.1.5
|
||||
|
||||
## 11.5.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2783](https://github.com/wbkd/react-flow/pull/2783) [`71153534`](https://github.com/wbkd/react-flow/commit/7115353418ebc7f7c81ab0e861200972bbf7dbd5) - connections: check handle below mouse before using connection radius
|
||||
|
||||
- Updated dependencies [[`71153534`](https://github.com/wbkd/react-flow/commit/7115353418ebc7f7c81ab0e861200972bbf7dbd5)]:
|
||||
- @reactflow/core@11.5.1
|
||||
- @reactflow/background@11.1.4
|
||||
- @reactflow/controls@11.1.4
|
||||
- @reactflow/minimap@11.3.4
|
||||
- @reactflow/node-toolbar@1.1.4
|
||||
|
||||
## 11.5.1
|
||||
|
||||
### Minor Changes
|
||||
@@ -8,26 +82,28 @@
|
||||
|
||||
## 11.5.0
|
||||
|
||||
Lot's of improvements are coming with this release!
|
||||
Lot's of improvements are coming with this release!
|
||||
|
||||
- **Connecting radius**: No need to drop a connection line on top of handle anymore. You only need to be close to the handle. That radius can be configured with the `connectionRadius` prop.
|
||||
- **Auto pan**: When you drag a node, a selection or the connection line to the border of the pane, it will pan into that direction. That makes it easier to connect far away nodes for example. If you don't like it you can set `autoPnaOnNodeDrag` and `autoPanOnConnect` to false.
|
||||
- **Touch devices**: It's finally possibleto connect nodes with the connection line on touch devices. In combination with the new auto pan and connection radius the overall UX is way better.
|
||||
- **Errors**: We added an `onError` prop to get notified when an error like "couldn't find source handle" happens. This is useful if you want to log errors for example.
|
||||
- **Node type**: We added a second param to the generic `Node` type. You can not only pass `NodeData` but also the type as a second param:
|
||||
- **Node type**: We added a second param to the generic `Node` type. You can not only pass `NodeData` but also the type as a second param:
|
||||
|
||||
```ts
|
||||
type MyCustomNode = Node<MyCustomNodeData, 'custom-node-type'>
|
||||
type MyCustomNode = Node<MyCustomNodeData, 'custom-node-type'>;
|
||||
```
|
||||
|
||||
This makes it easier to work with different custom nodes and data types.
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#2754](https://github.com/wbkd/react-flow/pull/2754) [`e96309b6`](https://github.com/wbkd/react-flow/commit/e96309b6a57b1071faeebf7b0547fef7fd418694) - Add auto pan for connecting and node dragging and `connectionRadius`
|
||||
- [#2754](https://github.com/wbkd/react-flow/pull/2754) [`e96309b6`](https://github.com/wbkd/react-flow/commit/e96309b6a57b1071faeebf7b0547fef7fd418694) - Add auto pan for connecting and node dragging and `connectionRadius`
|
||||
- [#2773](https://github.com/wbkd/react-flow/pull/2773) - Add `onError` prop to get notified when an error happens
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2763](https://github.com/wbkd/react-flow/pull/2763) [`85003b01`](https://github.com/wbkd/react-flow/commit/85003b01add71ea852bd5b0d2f1e7496050a6b52) - Connecting nodes: Enable connections on touch devices
|
||||
- [#2763](https://github.com/wbkd/react-flow/pull/2763) [`85003b01`](https://github.com/wbkd/react-flow/commit/85003b01add71ea852bd5b0d2f1e7496050a6b52) - Connecting nodes: Enable connections on touch devices
|
||||
- [#2620](https://github.com/wbkd/react-flow/pull/2620) - Thanks [RichSchulz](https://github.com/RichSchulz)! - Types: improve typing for node type
|
||||
|
||||
- Updated dependencies [[`e96309b6`](https://github.com/wbkd/react-flow/commit/e96309b6a57b1071faeebf7b0547fef7fd418694), [`85003b01`](https://github.com/wbkd/react-flow/commit/85003b01add71ea852bd5b0d2f1e7496050a6b52), [`4c516882`](https://github.com/wbkd/react-flow/commit/4c516882d2bbf426c1832a53ad40763cc1abef92)]:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "reactflow",
|
||||
"version": "11.5.1",
|
||||
"version": "11.5.6",
|
||||
"description": "A highly customizable React library for building node-based editors and interactive flow charts",
|
||||
"keywords": [
|
||||
"react",
|
||||
@@ -50,7 +50,7 @@
|
||||
"@reactflow/rollup-config": "workspace:*",
|
||||
"@reactflow/tsconfig": "workspace:*",
|
||||
"@types/node": "^18.7.16",
|
||||
"@types/react": "^18.0.19",
|
||||
"@types/react": ">=17",
|
||||
"react": "^18.2.0",
|
||||
"typescript": "^4.9.4"
|
||||
},
|
||||
|
||||
Generated
+152
-116
@@ -32,15 +32,15 @@ importers:
|
||||
'@changesets/changelog-github': registry.npmjs.org/@changesets/changelog-github/0.4.7
|
||||
'@changesets/cli': registry.npmjs.org/@changesets/cli/2.25.0
|
||||
'@preconstruct/cli': registry.npmjs.org/@preconstruct/cli/2.2.1
|
||||
'@typescript-eslint/eslint-plugin': registry.npmjs.org/@typescript-eslint/eslint-plugin/5.49.0_equgvmdpavr6nminvx2krii6h4
|
||||
'@typescript-eslint/parser': registry.npmjs.org/@typescript-eslint/parser/5.49.0_id2eilsndvzhjjktb64trvy3gu
|
||||
'@typescript-eslint/eslint-plugin': registry.npmjs.org/@typescript-eslint/eslint-plugin/5.51.0_bn63ywsy4d5iuct4ghawihpgsu
|
||||
'@typescript-eslint/parser': registry.npmjs.org/@typescript-eslint/parser/5.51.0_id2eilsndvzhjjktb64trvy3gu
|
||||
autoprefixer: registry.npmjs.org/autoprefixer/10.4.9_postcss@8.4.21
|
||||
concurrently: registry.npmjs.org/concurrently/7.6.0
|
||||
cypress: registry.npmjs.org/cypress/10.7.0
|
||||
eslint: registry.npmjs.org/eslint/8.23.1
|
||||
eslint-config-prettier: registry.npmjs.org/eslint-config-prettier/8.5.0_eslint@8.23.1
|
||||
eslint-plugin-prettier: registry.npmjs.org/eslint-plugin-prettier/4.2.1_cabrci5exjdaojcvd6xoxgeowu
|
||||
eslint-plugin-react: registry.npmjs.org/eslint-plugin-react/7.32.1_eslint@8.23.1
|
||||
eslint-plugin-react: registry.npmjs.org/eslint-plugin-react/7.32.2_eslint@8.23.1
|
||||
postcss: registry.npmjs.org/postcss/8.4.21
|
||||
postcss-cli: registry.npmjs.org/postcss-cli/10.1.0_postcss@8.4.21
|
||||
postcss-combine-duplicated-selectors: registry.npmjs.org/postcss-combine-duplicated-selectors/10.0.3_postcss@8.4.21
|
||||
@@ -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
|
||||
@@ -100,7 +102,7 @@ importers:
|
||||
'@reactflow/rollup-config': workspace:*
|
||||
'@reactflow/tsconfig': workspace:*
|
||||
'@types/node': ^18.7.16
|
||||
'@types/react': ^18.0.19
|
||||
'@types/react': '>=17'
|
||||
classcat: ^5.0.3
|
||||
react: ^18.2.0
|
||||
typescript: ^4.9.4
|
||||
@@ -125,7 +127,7 @@ importers:
|
||||
'@reactflow/rollup-config': workspace:*
|
||||
'@reactflow/tsconfig': workspace:*
|
||||
'@types/node': ^18.7.16
|
||||
'@types/react': ^18.0.19
|
||||
'@types/react': '>=17'
|
||||
classcat: ^5.0.3
|
||||
typescript: ^4.9.4
|
||||
dependencies:
|
||||
@@ -149,8 +151,8 @@ importers:
|
||||
'@types/d3-selection': ^3.0.3
|
||||
'@types/d3-zoom': ^3.0.1
|
||||
'@types/node': ^18.7.16
|
||||
'@types/react': ^18.0.17
|
||||
'@types/react-dom': ^18.0.6
|
||||
'@types/react': '>=17'
|
||||
'@types/react-dom': '>=17'
|
||||
classcat: ^5.0.3
|
||||
d3-drag: ^3.0.0
|
||||
d3-selection: ^3.0.0
|
||||
@@ -187,7 +189,7 @@ importers:
|
||||
'@types/d3-selection': ^3.0.3
|
||||
'@types/d3-zoom': ^3.0.1
|
||||
'@types/node': ^18.7.16
|
||||
'@types/react': ^18.0.19
|
||||
'@types/react': '>=17'
|
||||
classcat: ^5.0.3
|
||||
d3-selection: ^3.0.0
|
||||
d3-zoom: ^3.0.0
|
||||
@@ -220,8 +222,8 @@ importers:
|
||||
'@types/d3-drag': ^3.0.1
|
||||
'@types/d3-selection': ^3.0.3
|
||||
'@types/node': ^18.7.16
|
||||
'@types/react': ^18.0.19
|
||||
'@types/react-dom': ^18.0.6
|
||||
'@types/react': '>=17'
|
||||
'@types/react-dom': '>=17'
|
||||
classcat: ^5.0.4
|
||||
d3-drag: ^3.0.0
|
||||
d3-selection: ^3.0.0
|
||||
@@ -248,13 +250,13 @@ importers:
|
||||
|
||||
packages/node-toolbar:
|
||||
specifiers:
|
||||
'@reactflow/core': workspace:^11.3.3
|
||||
'@reactflow/core': workspace:*
|
||||
'@reactflow/eslint-config': workspace:*
|
||||
'@reactflow/rollup-config': workspace:*
|
||||
'@reactflow/tsconfig': workspace:*
|
||||
'@types/node': ^18.7.16
|
||||
'@types/react': ^18.0.19
|
||||
'@types/react-dom': ^18.0.6
|
||||
'@types/react': '>=17'
|
||||
'@types/react-dom': '>=17'
|
||||
classcat: ^5.0.3
|
||||
react: ^18.2.0
|
||||
typescript: ^4.9.4
|
||||
@@ -284,7 +286,7 @@ importers:
|
||||
'@reactflow/rollup-config': workspace:*
|
||||
'@reactflow/tsconfig': workspace:*
|
||||
'@types/node': ^18.7.16
|
||||
'@types/react': ^18.0.19
|
||||
'@types/react': '>=17'
|
||||
react: ^18.2.0
|
||||
typescript: ^4.9.4
|
||||
dependencies:
|
||||
@@ -327,7 +329,7 @@ importers:
|
||||
typescript: ^4.9.3
|
||||
vite: ^4.0.0
|
||||
dependencies:
|
||||
'@reactflow/core': registry.npmjs.org/@reactflow/core/11.5.1_biqbaboplfbrettd7655fr4n2y
|
||||
'@reactflow/core': link:../core
|
||||
cc: registry.npmjs.org/cc/3.0.1
|
||||
d3-drag: registry.npmjs.org/d3-drag/3.0.0
|
||||
d3-selection: registry.npmjs.org/d3-selection/3.0.0
|
||||
@@ -361,7 +363,7 @@ importers:
|
||||
eslint: registry.npmjs.org/eslint/8.23.1
|
||||
eslint-config-prettier: registry.npmjs.org/eslint-config-prettier/8.5.0_eslint@8.23.1
|
||||
eslint-config-turbo: registry.npmjs.org/eslint-config-turbo/0.0.7_eslint@8.23.1
|
||||
eslint-plugin-react: registry.npmjs.org/eslint-plugin-react/7.32.1_eslint@8.23.1
|
||||
eslint-plugin-react: registry.npmjs.org/eslint-plugin-react/7.32.2_eslint@8.23.1
|
||||
|
||||
tooling/rollup-config:
|
||||
specifiers:
|
||||
@@ -1667,30 +1669,6 @@ packages:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
registry.npmjs.org/@reactflow/core/11.5.1_biqbaboplfbrettd7655fr4n2y:
|
||||
resolution: {integrity: sha512-63pXpKNW5YHk8hOWpt7RaftSn7g92BvCCGpsUUaRDDuHvxmcqmMKPrAFkBPVc5JJ+Wubx4drThYJizgVP/j9/w==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@reactflow/core/-/core-11.5.1.tgz}
|
||||
id: registry.npmjs.org/@reactflow/core/11.5.1
|
||||
name: '@reactflow/core'
|
||||
version: 11.5.1
|
||||
peerDependencies:
|
||||
react: '>=17'
|
||||
react-dom: '>=17'
|
||||
dependencies:
|
||||
'@types/d3': registry.npmjs.org/@types/d3/7.4.0
|
||||
'@types/d3-drag': registry.npmjs.org/@types/d3-drag/3.0.1
|
||||
'@types/d3-selection': registry.npmjs.org/@types/d3-selection/3.0.3
|
||||
'@types/d3-zoom': registry.npmjs.org/@types/d3-zoom/3.0.1
|
||||
classcat: registry.npmjs.org/classcat/5.0.4
|
||||
d3-drag: registry.npmjs.org/d3-drag/3.0.0
|
||||
d3-selection: registry.npmjs.org/d3-selection/3.0.0
|
||||
d3-zoom: registry.npmjs.org/d3-zoom/3.0.0
|
||||
react: registry.npmjs.org/react/18.2.0
|
||||
react-dom: registry.npmjs.org/react-dom/18.2.0_react@18.2.0
|
||||
zustand: registry.npmjs.org/zustand/4.3.1_react@18.2.0
|
||||
transitivePeerDependencies:
|
||||
- immer
|
||||
dev: false
|
||||
|
||||
registry.npmjs.org/@rollup/plugin-alias/3.1.9_rollup@2.79.1:
|
||||
resolution: {integrity: sha512-QI5fsEvm9bDzt32k39wpOwZhVzRcL5ydcffUHMyLVaVaLeC70I8TJZ17F1z1eMoLu4E/UOcH9BWVkKpIKdrfiw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-3.1.9.tgz}
|
||||
id: registry.npmjs.org/@rollup/plugin-alias/3.1.9
|
||||
@@ -2247,6 +2225,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'
|
||||
@@ -2401,36 +2385,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
registry.npmjs.org/@typescript-eslint/eslint-plugin/5.49.0_equgvmdpavr6nminvx2krii6h4:
|
||||
resolution: {integrity: sha512-IhxabIpcf++TBaBa1h7jtOWyon80SXPRLDq0dVz5SLFC/eW6tofkw/O7Ar3lkx5z5U6wzbKDrl2larprp5kk5Q==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.49.0.tgz}
|
||||
id: registry.npmjs.org/@typescript-eslint/eslint-plugin/5.49.0
|
||||
name: '@typescript-eslint/eslint-plugin'
|
||||
version: 5.49.0
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
'@typescript-eslint/parser': ^5.0.0
|
||||
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||
typescript: '*'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/parser': registry.npmjs.org/@typescript-eslint/parser/5.49.0_id2eilsndvzhjjktb64trvy3gu
|
||||
'@typescript-eslint/scope-manager': registry.npmjs.org/@typescript-eslint/scope-manager/5.49.0
|
||||
'@typescript-eslint/type-utils': registry.npmjs.org/@typescript-eslint/type-utils/5.49.0_id2eilsndvzhjjktb64trvy3gu
|
||||
'@typescript-eslint/utils': registry.npmjs.org/@typescript-eslint/utils/5.49.0_id2eilsndvzhjjktb64trvy3gu
|
||||
debug: registry.npmjs.org/debug/4.3.4
|
||||
eslint: registry.npmjs.org/eslint/8.23.1
|
||||
ignore: registry.npmjs.org/ignore/5.2.4
|
||||
natural-compare-lite: registry.npmjs.org/natural-compare-lite/1.4.0
|
||||
regexpp: registry.npmjs.org/regexpp/3.2.0
|
||||
semver: registry.npmjs.org/semver/7.3.8
|
||||
tsutils: registry.npmjs.org/tsutils/3.21.0_typescript@4.9.4
|
||||
typescript: registry.npmjs.org/typescript/4.9.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
registry.npmjs.org/@typescript-eslint/eslint-plugin/5.49.0_rsaczafy73x3xqauzesvzbsgzy:
|
||||
resolution: {integrity: sha512-IhxabIpcf++TBaBa1h7jtOWyon80SXPRLDq0dVz5SLFC/eW6tofkw/O7Ar3lkx5z5U6wzbKDrl2larprp5kk5Q==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.49.0.tgz}
|
||||
id: registry.npmjs.org/@typescript-eslint/eslint-plugin/5.49.0
|
||||
@@ -2461,24 +2415,32 @@ packages:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
registry.npmjs.org/@typescript-eslint/parser/5.49.0_id2eilsndvzhjjktb64trvy3gu:
|
||||
resolution: {integrity: sha512-veDlZN9mUhGqU31Qiv2qEp+XrJj5fgZpJ8PW30sHU+j/8/e5ruAhLaVDAeznS7A7i4ucb/s8IozpDtt9NqCkZg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.49.0.tgz}
|
||||
id: registry.npmjs.org/@typescript-eslint/parser/5.49.0
|
||||
name: '@typescript-eslint/parser'
|
||||
version: 5.49.0
|
||||
registry.npmjs.org/@typescript-eslint/eslint-plugin/5.51.0_bn63ywsy4d5iuct4ghawihpgsu:
|
||||
resolution: {integrity: sha512-wcAwhEWm1RgNd7dxD/o+nnLW8oH+6RK1OGnmbmkj/GGoDPV1WWMVP0FXYQBivKHdwM1pwii3bt//RC62EriIUQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.51.0.tgz}
|
||||
id: registry.npmjs.org/@typescript-eslint/eslint-plugin/5.51.0
|
||||
name: '@typescript-eslint/eslint-plugin'
|
||||
version: 5.51.0
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
'@typescript-eslint/parser': ^5.0.0
|
||||
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||
typescript: '*'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/scope-manager': registry.npmjs.org/@typescript-eslint/scope-manager/5.49.0
|
||||
'@typescript-eslint/types': registry.npmjs.org/@typescript-eslint/types/5.49.0
|
||||
'@typescript-eslint/typescript-estree': registry.npmjs.org/@typescript-eslint/typescript-estree/5.49.0_typescript@4.9.4
|
||||
'@typescript-eslint/parser': registry.npmjs.org/@typescript-eslint/parser/5.51.0_id2eilsndvzhjjktb64trvy3gu
|
||||
'@typescript-eslint/scope-manager': registry.npmjs.org/@typescript-eslint/scope-manager/5.51.0
|
||||
'@typescript-eslint/type-utils': registry.npmjs.org/@typescript-eslint/type-utils/5.51.0_id2eilsndvzhjjktb64trvy3gu
|
||||
'@typescript-eslint/utils': registry.npmjs.org/@typescript-eslint/utils/5.51.0_id2eilsndvzhjjktb64trvy3gu
|
||||
debug: registry.npmjs.org/debug/4.3.4
|
||||
eslint: registry.npmjs.org/eslint/8.23.1
|
||||
grapheme-splitter: registry.npmjs.org/grapheme-splitter/1.0.4
|
||||
ignore: registry.npmjs.org/ignore/5.2.4
|
||||
natural-compare-lite: registry.npmjs.org/natural-compare-lite/1.4.0
|
||||
regexpp: registry.npmjs.org/regexpp/3.2.0
|
||||
semver: registry.npmjs.org/semver/7.3.8
|
||||
tsutils: registry.npmjs.org/tsutils/3.21.0_typescript@4.9.4
|
||||
typescript: registry.npmjs.org/typescript/4.9.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -2507,6 +2469,29 @@ packages:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
registry.npmjs.org/@typescript-eslint/parser/5.51.0_id2eilsndvzhjjktb64trvy3gu:
|
||||
resolution: {integrity: sha512-fEV0R9gGmfpDeRzJXn+fGQKcl0inIeYobmmUWijZh9zA7bxJ8clPhV9up2ZQzATxAiFAECqPQyMDB4o4B81AaA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.51.0.tgz}
|
||||
id: registry.npmjs.org/@typescript-eslint/parser/5.51.0
|
||||
name: '@typescript-eslint/parser'
|
||||
version: 5.51.0
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||
typescript: '*'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/scope-manager': registry.npmjs.org/@typescript-eslint/scope-manager/5.51.0
|
||||
'@typescript-eslint/types': registry.npmjs.org/@typescript-eslint/types/5.51.0
|
||||
'@typescript-eslint/typescript-estree': registry.npmjs.org/@typescript-eslint/typescript-estree/5.51.0_typescript@4.9.4
|
||||
debug: registry.npmjs.org/debug/4.3.4
|
||||
eslint: registry.npmjs.org/eslint/8.23.1
|
||||
typescript: registry.npmjs.org/typescript/4.9.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
registry.npmjs.org/@typescript-eslint/scope-manager/5.49.0:
|
||||
resolution: {integrity: sha512-clpROBOiMIzpbWNxCe1xDK14uPZh35u4QaZO1GddilEzoCLAEz4szb51rBpdgurs5k2YzPtJeTEN3qVbG+LRUQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.49.0.tgz}
|
||||
name: '@typescript-eslint/scope-manager'
|
||||
@@ -2517,27 +2502,14 @@ packages:
|
||||
'@typescript-eslint/visitor-keys': registry.npmjs.org/@typescript-eslint/visitor-keys/5.49.0
|
||||
dev: true
|
||||
|
||||
registry.npmjs.org/@typescript-eslint/type-utils/5.49.0_id2eilsndvzhjjktb64trvy3gu:
|
||||
resolution: {integrity: sha512-eUgLTYq0tR0FGU5g1YHm4rt5H/+V2IPVkP0cBmbhRyEmyGe4XvJ2YJ6sYTmONfjmdMqyMLad7SB8GvblbeESZA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.49.0.tgz}
|
||||
id: registry.npmjs.org/@typescript-eslint/type-utils/5.49.0
|
||||
name: '@typescript-eslint/type-utils'
|
||||
version: 5.49.0
|
||||
registry.npmjs.org/@typescript-eslint/scope-manager/5.51.0:
|
||||
resolution: {integrity: sha512-gNpxRdlx5qw3yaHA0SFuTjW4rxeYhpHxt491PEcKF8Z6zpq0kMhe0Tolxt0qjlojS+/wArSDlj/LtE69xUJphQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.51.0.tgz}
|
||||
name: '@typescript-eslint/scope-manager'
|
||||
version: 5.51.0
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
eslint: '*'
|
||||
typescript: '*'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/typescript-estree': registry.npmjs.org/@typescript-eslint/typescript-estree/5.49.0_typescript@4.9.4
|
||||
'@typescript-eslint/utils': registry.npmjs.org/@typescript-eslint/utils/5.49.0_id2eilsndvzhjjktb64trvy3gu
|
||||
debug: registry.npmjs.org/debug/4.3.4
|
||||
eslint: registry.npmjs.org/eslint/8.23.1
|
||||
tsutils: registry.npmjs.org/tsutils/3.21.0_typescript@4.9.4
|
||||
typescript: registry.npmjs.org/typescript/4.9.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
'@typescript-eslint/types': registry.npmjs.org/@typescript-eslint/types/5.51.0
|
||||
'@typescript-eslint/visitor-keys': registry.npmjs.org/@typescript-eslint/visitor-keys/5.51.0
|
||||
dev: true
|
||||
|
||||
registry.npmjs.org/@typescript-eslint/type-utils/5.49.0_zkdaqh7it7uc4cvz2haft7rc6u:
|
||||
@@ -2563,6 +2535,29 @@ packages:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
registry.npmjs.org/@typescript-eslint/type-utils/5.51.0_id2eilsndvzhjjktb64trvy3gu:
|
||||
resolution: {integrity: sha512-QHC5KKyfV8sNSyHqfNa0UbTbJ6caB8uhcx2hYcWVvJAZYJRBo5HyyZfzMdRx8nvS+GyMg56fugMzzWnojREuQQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.51.0.tgz}
|
||||
id: registry.npmjs.org/@typescript-eslint/type-utils/5.51.0
|
||||
name: '@typescript-eslint/type-utils'
|
||||
version: 5.51.0
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
eslint: '*'
|
||||
typescript: '*'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/typescript-estree': registry.npmjs.org/@typescript-eslint/typescript-estree/5.51.0_typescript@4.9.4
|
||||
'@typescript-eslint/utils': registry.npmjs.org/@typescript-eslint/utils/5.51.0_id2eilsndvzhjjktb64trvy3gu
|
||||
debug: registry.npmjs.org/debug/4.3.4
|
||||
eslint: registry.npmjs.org/eslint/8.23.1
|
||||
tsutils: registry.npmjs.org/tsutils/3.21.0_typescript@4.9.4
|
||||
typescript: registry.npmjs.org/typescript/4.9.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
registry.npmjs.org/@typescript-eslint/types/5.49.0:
|
||||
resolution: {integrity: sha512-7If46kusG+sSnEpu0yOz2xFv5nRz158nzEXnJFCGVEHWnuzolXKwrH5Bsf9zsNlOQkyZuk0BZKKoJQI+1JPBBg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/types/-/types-5.49.0.tgz}
|
||||
name: '@typescript-eslint/types'
|
||||
@@ -2570,6 +2565,13 @@ packages:
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
dev: true
|
||||
|
||||
registry.npmjs.org/@typescript-eslint/types/5.51.0:
|
||||
resolution: {integrity: sha512-SqOn0ANn/v6hFn0kjvLwiDi4AzR++CBZz0NV5AnusT2/3y32jdc0G4woXPWHCumWtUXZKPAS27/9vziSsC9jnw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/types/-/types-5.51.0.tgz}
|
||||
name: '@typescript-eslint/types'
|
||||
version: 5.51.0
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
dev: true
|
||||
|
||||
registry.npmjs.org/@typescript-eslint/typescript-estree/5.49.0_typescript@4.9.4:
|
||||
resolution: {integrity: sha512-PBdx+V7deZT/3GjNYPVQv1Nc0U46dAHbIuOG8AZ3on3vuEKiPDwFE/lG1snN2eUB9IhF7EyF7K1hmTcLztNIsA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.49.0.tgz}
|
||||
id: registry.npmjs.org/@typescript-eslint/typescript-estree/5.49.0
|
||||
@@ -2594,27 +2596,28 @@ packages:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
registry.npmjs.org/@typescript-eslint/utils/5.49.0_id2eilsndvzhjjktb64trvy3gu:
|
||||
resolution: {integrity: sha512-cPJue/4Si25FViIb74sHCLtM4nTSBXtLx1d3/QT6mirQ/c65bV8arBEebBJJizfq8W2YyMoPI/WWPFWitmNqnQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.49.0.tgz}
|
||||
id: registry.npmjs.org/@typescript-eslint/utils/5.49.0
|
||||
name: '@typescript-eslint/utils'
|
||||
version: 5.49.0
|
||||
registry.npmjs.org/@typescript-eslint/typescript-estree/5.51.0_typescript@4.9.4:
|
||||
resolution: {integrity: sha512-TSkNupHvNRkoH9FMA3w7TazVFcBPveAAmb7Sz+kArY6sLT86PA5Vx80cKlYmd8m3Ha2SwofM1KwraF24lM9FvA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.51.0.tgz}
|
||||
id: registry.npmjs.org/@typescript-eslint/typescript-estree/5.51.0
|
||||
name: '@typescript-eslint/typescript-estree'
|
||||
version: 5.51.0
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||
typescript: '*'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/json-schema': registry.npmjs.org/@types/json-schema/7.0.11
|
||||
'@types/semver': registry.npmjs.org/@types/semver/7.3.13
|
||||
'@typescript-eslint/scope-manager': registry.npmjs.org/@typescript-eslint/scope-manager/5.49.0
|
||||
'@typescript-eslint/types': registry.npmjs.org/@typescript-eslint/types/5.49.0
|
||||
'@typescript-eslint/typescript-estree': registry.npmjs.org/@typescript-eslint/typescript-estree/5.49.0_typescript@4.9.4
|
||||
eslint: registry.npmjs.org/eslint/8.23.1
|
||||
eslint-scope: registry.npmjs.org/eslint-scope/5.1.1
|
||||
eslint-utils: registry.npmjs.org/eslint-utils/3.0.0_eslint@8.23.1
|
||||
'@typescript-eslint/types': registry.npmjs.org/@typescript-eslint/types/5.51.0
|
||||
'@typescript-eslint/visitor-keys': registry.npmjs.org/@typescript-eslint/visitor-keys/5.51.0
|
||||
debug: registry.npmjs.org/debug/4.3.4
|
||||
globby: registry.npmjs.org/globby/11.1.0
|
||||
is-glob: registry.npmjs.org/is-glob/4.0.3
|
||||
semver: registry.npmjs.org/semver/7.3.8
|
||||
tsutils: registry.npmjs.org/tsutils/3.21.0_typescript@4.9.4
|
||||
typescript: registry.npmjs.org/typescript/4.9.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
dev: true
|
||||
|
||||
registry.npmjs.org/@typescript-eslint/utils/5.49.0_zkdaqh7it7uc4cvz2haft7rc6u:
|
||||
@@ -2640,6 +2643,29 @@ packages:
|
||||
- typescript
|
||||
dev: true
|
||||
|
||||
registry.npmjs.org/@typescript-eslint/utils/5.51.0_id2eilsndvzhjjktb64trvy3gu:
|
||||
resolution: {integrity: sha512-76qs+5KWcaatmwtwsDJvBk4H76RJQBFe+Gext0EfJdC3Vd2kpY2Pf//OHHzHp84Ciw0/rYoGTDnIAr3uWhhJYw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.51.0.tgz}
|
||||
id: registry.npmjs.org/@typescript-eslint/utils/5.51.0
|
||||
name: '@typescript-eslint/utils'
|
||||
version: 5.51.0
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||
dependencies:
|
||||
'@types/json-schema': registry.npmjs.org/@types/json-schema/7.0.11
|
||||
'@types/semver': registry.npmjs.org/@types/semver/7.3.13
|
||||
'@typescript-eslint/scope-manager': registry.npmjs.org/@typescript-eslint/scope-manager/5.51.0
|
||||
'@typescript-eslint/types': registry.npmjs.org/@typescript-eslint/types/5.51.0
|
||||
'@typescript-eslint/typescript-estree': registry.npmjs.org/@typescript-eslint/typescript-estree/5.51.0_typescript@4.9.4
|
||||
eslint: registry.npmjs.org/eslint/8.23.1
|
||||
eslint-scope: registry.npmjs.org/eslint-scope/5.1.1
|
||||
eslint-utils: registry.npmjs.org/eslint-utils/3.0.0_eslint@8.23.1
|
||||
semver: registry.npmjs.org/semver/7.3.8
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
dev: true
|
||||
|
||||
registry.npmjs.org/@typescript-eslint/visitor-keys/5.49.0:
|
||||
resolution: {integrity: sha512-v9jBMjpNWyn8B6k/Mjt6VbUS4J1GvUlR4x3Y+ibnP1z7y7V4n0WRz+50DY6+Myj0UaXVSuUlHohO+eZ8IJEnkg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.49.0.tgz}
|
||||
name: '@typescript-eslint/visitor-keys'
|
||||
@@ -2650,6 +2676,16 @@ packages:
|
||||
eslint-visitor-keys: registry.npmjs.org/eslint-visitor-keys/3.3.0
|
||||
dev: true
|
||||
|
||||
registry.npmjs.org/@typescript-eslint/visitor-keys/5.51.0:
|
||||
resolution: {integrity: sha512-Oh2+eTdjHjOFjKA27sxESlA87YPSOJafGCR0md5oeMdh1ZcCfAGCIOL216uTBAkAIptvLIfKQhl7lHxMJet4GQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.51.0.tgz}
|
||||
name: '@typescript-eslint/visitor-keys'
|
||||
version: 5.51.0
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
dependencies:
|
||||
'@typescript-eslint/types': registry.npmjs.org/@typescript-eslint/types/5.51.0
|
||||
eslint-visitor-keys: registry.npmjs.org/eslint-visitor-keys/3.3.0
|
||||
dev: true
|
||||
|
||||
registry.npmjs.org/@vitejs/plugin-react/3.0.1_vite@4.0.4:
|
||||
resolution: {integrity: sha512-mx+QvYwIbbpOIJw+hypjnW1lAbKDHtWK5ibkF/V1/oMBu8HU/chb+SnqJDAsLq1+7rGqjktCEomMTM5KShzUKQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-3.0.1.tgz}
|
||||
id: registry.npmjs.org/@vitejs/plugin-react/3.0.1
|
||||
@@ -4110,11 +4146,11 @@ packages:
|
||||
prettier-linter-helpers: registry.npmjs.org/prettier-linter-helpers/1.0.0
|
||||
dev: true
|
||||
|
||||
registry.npmjs.org/eslint-plugin-react/7.32.1_eslint@8.23.1:
|
||||
resolution: {integrity: sha512-vOjdgyd0ZHBXNsmvU+785xY8Bfe57EFbTYYk8XrROzWpr9QBvpjITvAXt9xqcE6+8cjR/g1+mfumPToxsl1www==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.1.tgz}
|
||||
id: registry.npmjs.org/eslint-plugin-react/7.32.1
|
||||
registry.npmjs.org/eslint-plugin-react/7.32.2_eslint@8.23.1:
|
||||
resolution: {integrity: sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz}
|
||||
id: registry.npmjs.org/eslint-plugin-react/7.32.2
|
||||
name: eslint-plugin-react
|
||||
version: 7.32.1
|
||||
version: 7.32.2
|
||||
engines: {node: '>=4'}
|
||||
peerDependencies:
|
||||
eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
|
||||
|
||||
Reference in New Issue
Block a user