Merge pull request #2833 from wbkd/next-release

Next release: 11.5.6
This commit is contained in:
Moritz Klack
2023-02-13 16:36:25 +01:00
committed by GitHub
55 changed files with 250 additions and 178 deletions
+1
View File
@@ -25,6 +25,7 @@
}, },
"devDependencies": { "devDependencies": {
"@cypress/skip-test": "^2.6.1", "@cypress/skip-test": "^2.6.1",
"@types/dagre": "^0.7.48",
"@types/react": "^18.0.17", "@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6", "@types/react-dom": "^18.0.6",
"@vitejs/plugin-react": "^3.0.1", "@vitejs/plugin-react": "^3.0.1",
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import { FC } from 'react';
import ReactFlow, { import ReactFlow, {
Node, Node,
+8 -17
View File
@@ -1,4 +1,4 @@
import React, { MouseEvent } from 'react'; import { MouseEvent } from 'react';
import ReactFlow, { import ReactFlow, {
MiniMap, MiniMap,
Background, Background,
@@ -8,7 +8,7 @@ import ReactFlow, {
Node, Node,
Edge, Edge,
useReactFlow, useReactFlow,
NodeOrigin, Panel,
} from 'reactflow'; } from 'reactflow';
const onNodeDrag = (_: MouseEvent, node: Node) => console.log('drag', node); const onNodeDrag = (_: MouseEvent, node: Node) => console.log('drag', node);
@@ -22,7 +22,6 @@ const initialNodes: Node[] = [
data: { label: 'Node 1' }, data: { label: 'Node 1' },
position: { x: 250, y: 5 }, position: { x: 250, y: 5 },
className: 'light', className: 'light',
draggable: false,
}, },
{ {
id: '2', id: '2',
@@ -100,20 +99,12 @@ const BasicFlow = () => {
<MiniMap /> <MiniMap />
<Controls /> <Controls />
<div style={{ position: 'absolute', right: 10, top: 10, zIndex: 4 }}> <Panel position="top-right">
<button onClick={resetTransform} style={{ marginRight: 5 }}> <button onClick={resetTransform}>reset transform</button>
reset transform <button onClick={updatePos}>change pos</button>
</button> <button onClick={toggleClassnames}>toggle classnames</button>
<button onClick={updatePos} style={{ marginRight: 5 }}> <button onClick={logToObject}>toObject</button>
change pos </Panel>
</button>
<button onClick={toggleClassnames} style={{ marginRight: 5 }}>
toggle classnames
</button>
<button onClick={logToObject} style={{ marginRight: 5 }}>
toObject
</button>
</div>
</ReactFlow> </ReactFlow>
); );
}; };
@@ -1,4 +1,4 @@
import React, { useCallback } from 'react'; import { useCallback } from 'react';
import ReactFlow, { import ReactFlow, {
Node, Node,
addEdge, addEdge,
@@ -1,4 +1,4 @@
import React, { useState, useEffect, MouseEvent, ChangeEvent, useCallback } from 'react'; import { useState, useEffect, MouseEvent, ChangeEvent, useCallback } from 'react';
import ReactFlow, { import ReactFlow, {
MiniMap, MiniMap,
Controls, 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[] = [ const defaultNodes: Node[] = [
{ {
@@ -72,18 +80,12 @@ const DefaultNodes = () => {
<ReactFlow defaultNodes={defaultNodes} defaultEdges={defaultEdges} defaultEdgeOptions={defaultEdgeOptions} fitView> <ReactFlow defaultNodes={defaultNodes} defaultEdges={defaultEdges} defaultEdgeOptions={defaultEdgeOptions} fitView>
<Background variant={BackgroundVariant.Lines} /> <Background variant={BackgroundVariant.Lines} />
<div style={{ position: 'absolute', right: 10, top: 10, zIndex: 4 }}> <Panel position="top-right">
<button onClick={resetTransform} style={{ marginRight: 5 }}> <button onClick={resetTransform}>reset transform</button>
reset transform <button onClick={updateNodePositions}>change pos</button>
</button> <button onClick={updateEdgeColors}>red edges</button>
<button onClick={updateNodePositions} style={{ marginRight: 5 }}>
change pos
</button>
<button onClick={updateEdgeColors} style={{ marginRight: 5 }}>
red edges
</button>
<button onClick={logToObject}>toObject</button> <button onClick={logToObject}>toObject</button>
</div> </Panel>
</ReactFlow> </ReactFlow>
); );
}; };
@@ -1,4 +1,4 @@
import React, { MouseEvent } from 'react'; import { MouseEvent } from 'react';
import ReactFlow, { Node, Edge, useNodesState, useEdgesState } from 'reactflow'; import ReactFlow, { Node, Edge, useNodesState, useEdgesState } from 'reactflow';
import DragHandleNode from './DragHandleNode'; import DragHandleNode from './DragHandleNode';
@@ -1,4 +1,5 @@
import React, { DragEvent } from 'react'; import { DragEvent } from 'react';
import styles from './dnd.module.css'; import styles from './dnd.module.css';
const onDragStart = (event: DragEvent, nodeType: string) => { const onDragStart = (event: DragEvent, nodeType: string) => {
@@ -9,25 +10,19 @@ const onDragStart = (event: DragEvent, nodeType: string) => {
const Sidebar = () => { const Sidebar = () => {
return ( return (
<aside className={styles.aside}> <aside className={styles.aside}>
<div className={styles.description}> <div className={styles.description}>You can drag these nodes to the pane on the left.</div>
You can drag these nodes to the pane on the left. <div className="react-flow__node-input" onDragStart={(event: DragEvent) => onDragStart(event, 'input')} draggable>
</div>
<div
className='react-flow__node-input'
onDragStart={(event: DragEvent) => onDragStart(event, 'input')}
draggable
>
Input Node Input Node
</div> </div>
<div <div
className='react-flow__node-default' className="react-flow__node-default"
onDragStart={(event: DragEvent) => onDragStart(event, 'default')} onDragStart={(event: DragEvent) => onDragStart(event, 'default')}
draggable draggable
> >
Default Node Default Node
</div> </div>
<div <div
className='react-flow__node-output' className="react-flow__node-output"
onDragStart={(event: DragEvent) => onDragStart(event, 'output')} onDragStart={(event: DragEvent) => onDragStart(event, 'output')}
draggable draggable
> >
@@ -1,4 +1,4 @@
import React, { useState, DragEvent } from 'react'; import { useState, DragEvent } from 'react';
import ReactFlow, { import ReactFlow, {
ReactFlowProvider, ReactFlowProvider,
addEdge, addEdge,
@@ -2,7 +2,7 @@ import { Handle, NodeProps, Position, ReactFlowState, useStore } from 'reactflow
const connectionNodeIdSelector = (state: ReactFlowState) => state.connectionNodeId; const connectionNodeIdSelector = (state: ReactFlowState) => state.connectionNodeId;
export default function CustomNode({ id }: NodeProps) { export default function CustomNode({ id, isConnectable }: NodeProps) {
const connectionNodeId = useStore(connectionNodeIdSelector); const connectionNodeId = useStore(connectionNodeIdSelector);
const isTarget = connectionNodeId && connectionNodeId !== id; const isTarget = connectionNodeId && connectionNodeId !== id;
@@ -18,8 +18,20 @@ export default function CustomNode({ id }: NodeProps) {
backgroundColor: isTarget ? '#ffcce3' : '#ccd9f6', backgroundColor: isTarget ? '#ffcce3' : '#ccd9f6',
}} }}
> >
<Handle className="targetHandle" style={{ zIndex: 2 }} position={Position.Right} type="source" /> <Handle
<Handle className="targetHandle" style={targetHandleStyle} position={Position.Left} type="target" /> 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} {label}
</div> </div>
</div> </div>
@@ -1,4 +1,4 @@
import React, { MouseEvent, useCallback } from 'react'; import { MouseEvent, useCallback } from 'react';
import ReactFlow, { import ReactFlow, {
Controls, Controls,
Background, Background,
@@ -1,7 +1,4 @@
/** import { useCallback } from 'react';
* Example for checking the different edge types and source and target positions
*/
import React, { useCallback } from 'react';
import ReactFlow, { import ReactFlow, {
Background, Background,
@@ -1,4 +1,4 @@
import React, { MouseEvent, useCallback } from 'react'; import { MouseEvent, useCallback } from 'react';
import ReactFlow, { import ReactFlow, {
Controls, Controls,
Background, Background,
@@ -1,4 +1,4 @@
import React, { MouseEvent, CSSProperties, useCallback } from 'react'; import { MouseEvent, CSSProperties, useCallback } from 'react';
import ReactFlow, { import ReactFlow, {
Background, Background,
@@ -1,4 +1,4 @@
import React, { useCallback } from 'react'; import { useCallback } from 'react';
import ReactFlow, { import ReactFlow, {
Background, 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'; 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, { import ReactFlow, {
addEdge, addEdge,
Node, Node,
@@ -1,4 +1,5 @@
import React, { useCallback } from 'react'; import { useCallback } from 'react';
import dagre from 'dagre';
import ReactFlow, { import ReactFlow, {
Controls, Controls,
ReactFlowProvider, ReactFlowProvider,
@@ -10,10 +11,10 @@ import ReactFlow, {
useEdgesState, useEdgesState,
MarkerType, MarkerType,
EdgeMarker, EdgeMarker,
Panel,
useReactFlow,
} from 'reactflow'; } from 'reactflow';
import dagre from 'dagre';
import initialItems from './initial-elements'; import initialItems from './initial-elements';
import styles from './layouting.module.css'; import styles from './layouting.module.css';
@@ -29,6 +30,7 @@ const nodeExtent: CoordinateExtent = [
const LayoutFlow = () => { const LayoutFlow = () => {
const [nodes, setNodes, onNodesChange] = useNodesState(initialItems.nodes); const [nodes, setNodes, onNodesChange] = useNodesState(initialItems.nodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialItems.edges); const [edges, setEdges, onEdgesChange] = useEdgesState(initialItems.edges);
const { fitView } = useReactFlow();
const onConnect = useCallback( const onConnect = useCallback(
(connection: Connection) => { (connection: Connection) => {
@@ -85,31 +87,31 @@ const LayoutFlow = () => {
return ( return (
<div className={styles.layoutflow}> <div className={styles.layoutflow}>
<ReactFlowProvider> <ReactFlow
<ReactFlow nodes={nodes}
nodes={nodes} edges={edges}
edges={edges} onConnect={onConnect}
onConnect={onConnect} nodeExtent={nodeExtent}
nodeExtent={nodeExtent} onInit={() => onLayout('TB')}
onInit={() => onLayout('TB')} onNodesChange={onNodesChange}
onNodesChange={onNodesChange} onEdgesChange={onEdgesChange}
onEdgesChange={onEdgesChange} >
> <Controls />
<Controls /> </ReactFlow>
</ReactFlow> <Panel position="top-right">
<div className={styles.controls}> <button onClick={() => onLayout('TB')}>vertical layout</button>
<button onClick={() => onLayout('TB')} style={{ marginRight: 10 }}> <button onClick={() => onLayout('LR')}>horizontal layout</button>
vertical layout <button onClick={() => unselect()}>unselect nodes</button>
</button> <button onClick={() => changeMarker()}>change marker</button>
<button onClick={() => onLayout('LR')} style={{ marginRight: 10 }}> <button onClick={() => fitView()}>fitView</button>
horizontal layout <button onClick={() => fitView({ nodes: nodes.slice(0, 2) })}>fitView partially</button>
</button> </Panel>
<button onClick={() => unselect()}>unselect nodes</button>
<button onClick={() => changeMarker()}>change marker</button>
</div>
</ReactFlowProvider>
</div> </div>
); );
}; };
export default LayoutFlow; export default () => (
<ReactFlowProvider>
<LayoutFlow />
</ReactFlowProvider>
);
@@ -2,10 +2,3 @@
flex-grow: 1; flex-grow: 1;
position: relative; 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, { import ReactFlow, {
Background, Background,
@@ -1,4 +1,4 @@
import React, { useState, MouseEvent, useCallback } from 'react'; import { useState, MouseEvent, useCallback } from 'react';
import ReactFlow, { import ReactFlow, {
Controls, Controls,
MiniMap, 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'; import ReactFlow, { addEdge, Node, Position, Connection, Edge, useNodesState, useEdgesState } from 'reactflow';
const initialNodes: Node[] = [ const initialNodes: Node[] = [
@@ -1,4 +1,4 @@
import React, { useState, CSSProperties, FC, useCallback } from 'react'; import { useState, CSSProperties, FC, useCallback } from 'react';
import ReactFlow, { import ReactFlow, {
addEdge, addEdge,
Node, Node,
@@ -1,4 +1,4 @@
import React, { MouseEvent as ReactMouseEvent, CSSProperties, useCallback } from 'react'; import { MouseEvent as ReactMouseEvent, CSSProperties, useCallback } from 'react';
import ReactFlow, { import ReactFlow, {
addEdge, addEdge,
Node, Node,
@@ -1,4 +1,4 @@
import React, { MouseEvent, useCallback } from 'react'; import { MouseEvent, useCallback } from 'react';
import ReactFlow, { import ReactFlow, {
Controls, Controls,
ReactFlowProvider, 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 ReactFlow, { ReactFlowProvider, Node, addEdge, Connection, Edge, useNodesState, useEdgesState } from 'reactflow';
import Controls from './Controls'; import Controls from './Controls';
const initialNodes: Node[] = [ const initialNodes: Node[] = [
@@ -1,4 +1,4 @@
import React, { useState, CSSProperties, useCallback } from 'react'; import { useState, CSSProperties, useCallback } from 'react';
import ReactFlow, { import ReactFlow, {
ReactFlowInstance, ReactFlowInstance,
Edge, Edge,
@@ -1,4 +1,4 @@
import React, { useState, MouseEvent, useCallback } from 'react'; import { useState, MouseEvent, useCallback } from 'react';
import ReactFlow, { import ReactFlow, {
addEdge, addEdge,
Node, Node,
@@ -12,7 +12,6 @@ import ReactFlow, {
MiniMap, MiniMap,
Background, Background,
Panel, Panel,
NodeOrigin,
} from 'reactflow'; } from 'reactflow';
import DebugNode from './DebugNode'; 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 ReactFlow, { Node, Edge, useNodesState, useEdgesState, Position, Connection, addEdge } from 'reactflow';
import styles from './touch-device.module.css'; import styles from './touch-device.module.css';
@@ -182,12 +182,13 @@ const getId = () => `${id++}`;
const UpdateNodeInternalsFlow = () => { const UpdateNodeInternalsFlow = () => {
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const onConnect = (params: Edge | Connection) => setEdges((els) => addEdge(params, els));
const { project } = useReactFlow(); 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( const onPaneClick = useCallback(
(evt: MouseEvent) => (evt: MouseEvent) =>
@@ -1,4 +1,4 @@
import React, { useState, useCallback } from 'react'; import { useState, useCallback, MouseEvent as ReactMouseEvent } from 'react';
import ReactFlow, { import ReactFlow, {
Controls, Controls,
updateEdge, updateEdge,
@@ -60,9 +60,9 @@ const initialNodes: Node[] = [
const initialEdges = [{ id: 'e1-2', source: '1', target: '2', label: 'This is a draggable edge' }]; const initialEdges = [{ id: 'e1-2', source: '1', target: '2', label: 'This is a draggable edge' }];
const onInit = (reactFlowInstance: ReactFlowInstance) => reactFlowInstance.fitView(); 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); 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); console.log(`end update ${handleType} handle`, edge);
const UpdatableEdge = () => { const UpdatableEdge = () => {
@@ -91,8 +91,8 @@ const UpdatableEdge = () => {
snapToGrid={true} snapToGrid={true}
onEdgeUpdate={onEdgeUpdate} onEdgeUpdate={onEdgeUpdate}
onConnect={onConnect} onConnect={onConnect}
// onEdgeUpdateStart={onEdgeUpdateStart} onEdgeUpdateStart={onEdgeUpdateStart}
// onEdgeUpdateEnd={onEdgeUpdateEnd} onEdgeUpdateEnd={onEdgeUpdateEnd}
> >
<Controls /> <Controls />
</ReactFlow> </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 ReactFlow, { Node, Edge, useNodesState, useEdgesState } from 'reactflow';
import styles from './updatenode.module.css'; 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, { import ReactFlow, {
Background, Background,
MiniMap, MiniMap,
@@ -10,6 +10,7 @@ import ReactFlow, {
Edge, Edge,
useNodesState, useNodesState,
useEdgesState, useEdgesState,
Panel,
} from 'reactflow'; } from 'reactflow';
const initialNodes: Node[] = [ const initialNodes: Node[] = [
@@ -65,7 +66,7 @@ const UseZoomPanHelperFlow = () => {
addEdges, addEdges,
getNodes, getNodes,
getEdges, getEdges,
deleteElements deleteElements,
} = useReactFlow(); } = useReactFlow();
const onPaneClick = useCallback( const onPaneClick = useCallback(
@@ -114,14 +115,14 @@ const UseZoomPanHelperFlow = () => {
}, [getNodes, getEdges]); }, [getNodes, getEdges]);
const deleteSelectedElements = useCallback(() => { const deleteSelectedElements = useCallback(() => {
const selectedNodes = nodes.filter(node => node.selected); const selectedNodes = nodes.filter((node) => node.selected);
const selectedEdges = edges.filter(edge => edge.selected); const selectedEdges = edges.filter((edge) => edge.selected);
deleteElements({ nodes: selectedNodes, edges: selectedEdges }); deleteElements({ nodes: selectedNodes, edges: selectedEdges });
}, [deleteElements, nodes, edges]) }, [deleteElements, nodes, edges]);
const deleteSomeElements = useCallback(() => { const deleteSomeElements = useCallback(() => {
deleteElements({ nodes: [{ id: '2' }], edges: [{ id: 'e1-3' }] }) deleteElements({ nodes: [{ id: '2' }], edges: [{ id: 'e1-3' }] });
}, []) }, []);
useEffect(() => { useEffect(() => {
addEdges({ id: 'e3-4', source: '3', target: '4' }); addEdges({ id: 'e3-4', source: '3', target: '4' });
@@ -142,7 +143,7 @@ const UseZoomPanHelperFlow = () => {
fitViewOptions={{ duration: 1200, padding: 0.2 }} fitViewOptions={{ duration: 1200, padding: 0.2 }}
maxZoom={Infinity} 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={() => zoomIn({ duration: 1200 })}>zoomIn</button>
<button onClick={() => zoomOut({ duration: 0 })}>zoomOut</button> <button onClick={() => zoomOut({ duration: 0 })}>zoomOut</button>
<button onClick={() => fitView({ duration: 1200, padding: 0.3 })}>fitView</button> <button onClick={() => fitView({ duration: 1200, padding: 0.3 })}>fitView</button>
@@ -151,7 +152,7 @@ const UseZoomPanHelperFlow = () => {
<button onClick={logNodes}>useNodes</button> <button onClick={logNodes}>useNodes</button>
<button onClick={deleteSelectedElements}>deleteSelectedElements</button> <button onClick={deleteSelectedElements}>deleteSelectedElements</button>
<button onClick={deleteSomeElements}>deleteSomeElements</button> <button onClick={deleteSomeElements}>deleteSomeElements</button>
</div> </Panel>
<Background /> <Background />
<MiniMap /> <MiniMap />
</ReactFlow> </ReactFlow>
+7
View File
@@ -1,5 +1,12 @@
# @reactflow/background # @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 ## 11.1.7
### Patch Changes ### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@reactflow/background", "name": "@reactflow/background",
"version": "11.1.7", "version": "11.1.8",
"description": "Background component with different variants for React Flow", "description": "Background component with different variants for React Flow",
"keywords": [ "keywords": [
"react", "react",
+7
View File
@@ -1,5 +1,12 @@
# @reactflow/controls # @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 ## 11.1.7
### Patch Changes ### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@reactflow/controls", "name": "@reactflow/controls",
"version": "11.1.7", "version": "11.1.8",
"description": "Component to control the viewport of a React Flow instance", "description": "Component to control the viewport of a React Flow instance",
"keywords": [ "keywords": [
"react", "react",
+11
View File
@@ -1,5 +1,16 @@
# @reactflow/core # @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 ## 11.5.4
### Patch Changes ### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@reactflow/core", "name": "@reactflow/core",
"version": "11.5.4", "version": "11.5.5",
"description": "Core components and util functions of React Flow.", "description": "Core components and util functions of React Flow.",
"keywords": [ "keywords": [
"react", "react",
@@ -89,6 +89,11 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
const onEdgeMouseLeave = getMouseHandler(id, store.getState, onMouseLeave); const onEdgeMouseLeave = getMouseHandler(id, store.getState, onMouseLeave);
const handleEdgeUpdater = (event: React.MouseEvent<SVGGElement, MouseEvent>, isSourceHandle: boolean) => { 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 nodeId = isSourceHandle ? target : source;
const handleId = (isSourceHandle ? targetHandleId : sourceHandleId) || null; const handleId = (isSourceHandle ? targetHandleId : sourceHandleId) || null;
const handleType = isSourceHandle ? 'target' : 'source'; const handleType = isSourceHandle ? 'target' : 'source';
+11 -8
View File
@@ -67,6 +67,7 @@ export function handlePointerDown({
let autoPanStarted = false; let autoPanStarted = false;
let connection: Connection | null = null; let connection: Connection | null = null;
let isValid = false; let isValid = false;
let handleDomNode: Element | null = null;
const handleLookup = getHandleLookup({ const handleLookup = getHandleLookup({
nodes: getNodes(), nodes: getNodes(),
@@ -111,7 +112,7 @@ export function handlePointerDown({
autoPanStarted = true; autoPanStarted = true;
} }
const { handleDomNode, ...result } = isValidHandle( const result = isValidHandle(
event, event,
prevClosestHandle, prevClosestHandle,
connectionMode, connectionMode,
@@ -122,9 +123,13 @@ export function handlePointerDown({
doc doc
); );
handleDomNode = result.handleDomNode;
connection = result.connection;
isValid = result.isValid;
setState({ setState({
connectionPosition: connectionPosition:
prevClosestHandle && result.isValid prevClosestHandle && isValid
? rendererPointToPoint( ? rendererPointToPoint(
{ {
x: prevClosestHandle.x, x: prevClosestHandle.x,
@@ -133,16 +138,13 @@ export function handlePointerDown({
transform transform
) )
: connectionPosition, : connectionPosition,
connectionStatus: getConnectionStatus(!!prevClosestHandle, result.isValid), connectionStatus: getConnectionStatus(!!prevClosestHandle, isValid),
}); });
if (!prevClosestHandle && !result.isValid) { if (!prevClosestHandle && !isValid && !handleDomNode) {
return resetRecentHandle(prevActiveHandle); return resetRecentHandle(prevActiveHandle);
} }
connection = result.connection;
isValid = result.isValid;
if (connection.source !== connection.target && handleDomNode) { if (connection.source !== connection.target && handleDomNode) {
resetRecentHandle(prevActiveHandle); resetRecentHandle(prevActiveHandle);
prevActiveHandle = handleDomNode; prevActiveHandle = handleDomNode;
@@ -154,7 +156,7 @@ export function handlePointerDown({
} }
function onPointerUp(event: MouseEvent | TouchEvent) { function onPointerUp(event: MouseEvent | TouchEvent) {
if (prevClosestHandle && connection && isValid) { if ((prevClosestHandle || handleDomNode) && connection && isValid) {
onConnect?.(connection); onConnect?.(connection);
} }
@@ -172,6 +174,7 @@ export function handlePointerDown({
autoPanStarted = false; autoPanStarted = false;
isValid = false; isValid = false;
connection = null; connection = null;
handleDomNode = null;
doc.removeEventListener('mousemove', onPointerMove as EventListener); doc.removeEventListener('mousemove', onPointerMove as EventListener);
doc.removeEventListener('mouseup', onPointerUp as EventListener); doc.removeEventListener('mouseup', onPointerUp as EventListener);
@@ -6,7 +6,7 @@ import { Provider } from '../../contexts/RFStoreContext';
import { createRFStore } from '../../store'; import { createRFStore } from '../../store';
import type { ReactFlowState } from '../../types'; import type { ReactFlowState } from '../../types';
const ReactFlowProvider: FC<PropsWithChildren> = ({ children }) => { const ReactFlowProvider: FC<PropsWithChildren<unknown>> = ({ children }) => {
const storeRef = useRef<StoreApi<ReactFlowState> | null>(null); const storeRef = useRef<StoreApi<ReactFlowState> | null>(null);
if (!storeRef.current) { if (!storeRef.current) {
@@ -4,7 +4,7 @@ import type { FC, PropsWithChildren } from 'react';
import StoreContext from '../../contexts/RFStoreContext'; import StoreContext from '../../contexts/RFStoreContext';
import ReactFlowProvider from '../../components/ReactFlowProvider'; import ReactFlowProvider from '../../components/ReactFlowProvider';
const Wrapper: FC<PropsWithChildren> = ({ children }) => { const Wrapper: FC<PropsWithChildren<unknown>> = ({ children }) => {
const isWrapped = useContext(StoreContext); const isWrapped = useContext(StoreContext);
if (isWrapped) { if (isWrapped) {
+3 -3
View File
@@ -4,7 +4,7 @@ import { shallow } from 'zustand/shallow';
import { useStoreApi, useStore } from '../hooks/useStore'; import { useStoreApi, useStore } from '../hooks/useStore';
import { pointToRendererPoint, getTransformForBounds, getD3Transition } from '../utils/graph'; 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'; import type { ViewportHelperFunctions, ReactFlowState, XYPosition } from '../types';
// eslint-disable-next-line @typescript-eslint/no-empty-function // eslint-disable-next-line @typescript-eslint/no-empty-function
@@ -17,7 +17,7 @@ const initialViewportHelper: ViewportHelperFunctions = {
getZoom: () => 1, getZoom: () => 1,
setViewport: noop, setViewport: noop,
getViewport: () => ({ x: 0, y: 0, zoom: 1 }), getViewport: () => ({ x: 0, y: 0, zoom: 1 }),
fitView: noop, fitView: () => false,
setCenter: noop, setCenter: noop,
fitBounds: noop, fitBounds: noop,
project: (position: XYPosition) => position, project: (position: XYPosition) => position,
@@ -51,7 +51,7 @@ const useViewportHelper = (): ViewportHelperFunctions => {
const [x, y, zoom] = store.getState().transform; const [x, y, zoom] = store.getState().transform;
return { x, y, zoom }; return { x, y, zoom };
}, },
fitView: (options) => fitViewStore(store.getState, options), fitView: (options) => fitView(store.getState, options),
setCenter: (x, y, options) => { setCenter: (x, y, options) => {
const { width, height, maxZoom } = store.getState(); const { width, height, maxZoom } = store.getState();
const nextZoom = typeof options?.zoom !== 'undefined' ? options.zoom : maxZoom; const nextZoom = typeof options?.zoom !== 'undefined' ? options.zoom : maxZoom;
+34 -26
View File
@@ -138,35 +138,43 @@ export function fitView(get: StoreApi<ReactFlowState>['getState'], options: Inte
fitViewOnInit, fitViewOnInit,
nodeOrigin, nodeOrigin,
} = get(); } = get();
const isInitialFitView = options.initial && !fitViewOnInitDone && fitViewOnInit;
const d3initialized = d3Zoom && d3Selection;
if ((options.initial && !fitViewOnInitDone && fitViewOnInit) || !options.initial) { if (d3initialized && (isInitialFitView || !options.initial)) {
if (d3Zoom && d3Selection) { const nodes = getNodes().filter((n) => {
const nodes = getNodes().filter((n) => (options.includeHiddenNodes ? n.width && n.height : !n.hidden)); const isVisible = options.includeHiddenNodes ? n.width && n.height : !n.hidden;
const nodesInitialized = nodes.every((n) => n.width && n.height); if (options.nodes?.length) {
return isVisible && options.nodes.some((optionNode) => optionNode.id === n.id);
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;
} }
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;
} }
} }
+1
View File
@@ -230,4 +230,5 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
pointer-events: none; pointer-events: none;
user-select: none;
} }
+2 -1
View File
@@ -30,7 +30,7 @@ export type NodeTypesWrapped = { [key: string]: MemoExoticComponent<ComponentTyp
export type EdgeTypes = { [key: string]: ComponentType<EdgeProps> }; export type EdgeTypes = { [key: string]: ComponentType<EdgeProps> };
export type EdgeTypesWrapped = { [key: string]: MemoExoticComponent<ComponentType<WrapEdgeProps>> }; 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; export type Project = (position: XYPosition) => XYPosition;
@@ -76,6 +76,7 @@ export type FitViewOptions = {
minZoom?: number; minZoom?: number;
maxZoom?: number; maxZoom?: number;
duration?: number; duration?: number;
nodes?: (Partial<Node> & { id: Node['id'] })[];
}; };
export type OnConnectStartParams = { export type OnConnectStartParams = {
+3 -8
View File
@@ -103,17 +103,12 @@ export function isInputDOMNode(event: KeyboardEvent | ReactKeyboardEvent): boole
// using composed path for handling shadow dom // using composed path for handling shadow dom
const target = (kbEvent.composedPath?.()?.[0] || event.target) as HTMLElement; 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 // 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) { const isModifierKey = event.ctrlKey || event.metaKey || event.shiftKey;
return false;
}
// when an input field is focused we don't want to trigger deletion or movement of nodes // when an input field is focused we don't want to trigger deletion or movement of nodes
return ( return (isInput && !isModifierKey) || !!target?.closest('.nokey');
['INPUT', 'SELECT', 'TEXTAREA'].includes(target?.nodeName) ||
target?.hasAttribute('contenteditable') ||
!!target?.closest('.nokey')
);
} }
export const isMouseEvent = ( export const isMouseEvent = (
+7
View File
@@ -1,5 +1,12 @@
# @reactflow/minimap # @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 ## 11.3.7
### Patch Changes ### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@reactflow/minimap", "name": "@reactflow/minimap",
"version": "11.3.7", "version": "11.3.8",
"description": "Minimap component for React Flow.", "description": "Minimap component for React Flow.",
"keywords": [ "keywords": [
"react", "react",
+7
View File
@@ -1,5 +1,12 @@
# @reactflow/node-toolbar # @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 ## 1.1.7
### Patch Changes ### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@reactflow/node-toolbar", "name": "@reactflow/node-toolbar",
"version": "1.1.7", "version": "1.1.8",
"description": "A toolbar component for React Flow that can be attached to a node.", "description": "A toolbar component for React Flow that can be attached to a node.",
"keywords": [ "keywords": [
"react", "react",
+18
View File
@@ -1,5 +1,23 @@
# reactflow # 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 ## 11.5.5
### Patch Changes ### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "reactflow", "name": "reactflow",
"version": "11.5.5", "version": "11.5.6",
"description": "A highly customizable React library for building node-based editors and interactive flow charts", "description": "A highly customizable React library for building node-based editors and interactive flow charts",
"keywords": [ "keywords": [
"react", "react",
+8
View File
@@ -58,6 +58,7 @@ importers:
specifiers: specifiers:
'@cypress/skip-test': ^2.6.1 '@cypress/skip-test': ^2.6.1
'@reactflow/node-resizer': workspace:* '@reactflow/node-resizer': workspace:*
'@types/dagre': ^0.7.48
'@types/react': ^18.0.17 '@types/react': ^18.0.17
'@types/react-dom': ^18.0.6 '@types/react-dom': ^18.0.6
'@vitejs/plugin-react': ^3.0.1 '@vitejs/plugin-react': ^3.0.1
@@ -84,6 +85,7 @@ importers:
reactflow: link:../../packages/reactflow reactflow: link:../../packages/reactflow
devDependencies: devDependencies:
'@cypress/skip-test': registry.npmjs.org/@cypress/skip-test/2.6.1 '@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': registry.npmjs.org/@types/react/18.0.19
'@types/react-dom': registry.npmjs.org/@types/react-dom/18.0.6 '@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 '@vitejs/plugin-react': registry.npmjs.org/@vitejs/plugin-react/3.0.1_vite@4.0.4
@@ -2046,6 +2048,12 @@ packages:
'@types/d3-zoom': registry.npmjs.org/@types/d3-zoom/3.0.1 '@types/d3-zoom': registry.npmjs.org/@types/d3-zoom/3.0.1
dev: false 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: 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} 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' name: '@types/estree'