Skip to content

Commit

Permalink
Merge pull request #12 from clarkmcc/xyflow-upgrade
Browse files Browse the repository at this point in the history
Updating to xyflow
  • Loading branch information
clarkmcc authored Jan 19, 2024
2 parents 115e936 + 4afbe18 commit ec7dd11
Show file tree
Hide file tree
Showing 21 changed files with 76 additions and 169 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ _Note: This project is still in development and the API is likely to change._
## Getting Started

```
npm install reactflow @clarkmcc/ngraph
npm install @xyflow/react @clarkmcc/ngraph
```

## Credits
Expand Down
4 changes: 2 additions & 2 deletions lib/NodeGraphEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import {
useNodesState,
useReactFlow,
useStoreApi,
} from 'reactflow'
} from '@xyflow/react'
import {
GraphConfigProvider,
useGraphConfig,
} from './context/GraphConfigContext'
import 'reactflow/dist/style.css'
import '@xyflow/react/dist/style.css'
import { useBuildGraphConfig, useNodeTypes } from './hooks/config'
import {
forwardRef,
Expand Down
2 changes: 1 addition & 1 deletion lib/NodeGraphEditorCustomInput.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
Edge,
Node,
ReactFlowProvider,
} from 'reactflow'
} from '@xyflow/react'
import { useBuildGraphConfig } from './hooks/config.ts'
import { NodeInputField } from './components/NodeInputField.tsx'
import { InputProps } from './config.ts'
Expand Down
2 changes: 1 addition & 1 deletion lib/NodeGraphEditorCustomNode.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
Node,
Position,
ReactFlowProvider,
} from 'reactflow'
} from '@xyflow/react'
import { NodeContainer } from './components/NodeContainer'
import { useFocusBlur } from './hooks/focus'
import { Handle } from './components/Handle'
Expand Down
2 changes: 1 addition & 1 deletion lib/NodeGraphEditorInputGroups.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
Edge,
Node,
ReactFlowProvider,
} from 'reactflow'
} from '@xyflow/react'
import { useBuildGraphConfig } from './hooks/config.ts'
import { InputProps } from './config.ts'
import { Wheel } from '@uiw/react-color'
Expand Down
4 changes: 2 additions & 2 deletions lib/clipboard.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Edge, Node, ReactFlowState } from 'reactflow'
import { Edge, Node, ReactFlowState } from '@xyflow/react'
import { Dispatch, SetStateAction } from 'react'
import { nanoid } from 'nanoid'

Expand All @@ -8,7 +8,7 @@ export enum ClipboardItem {

export namespace ClipboardItem {
export async function copyNodesAndEdges(state: ReactFlowState) {
const nodes = state.getNodes().filter((n) => n.selected)
const nodes = state.nodes.filter((n) => n.selected)
const nodeIds = nodes.map((n) => n.id)

// Edges selected because both the source and target nodes are selected
Expand Down
13 changes: 5 additions & 8 deletions lib/components/Edge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
useOnSelectionChange,
useStoreApi,
useViewport,
} from 'reactflow'
} from '@xyflow/react'
import { useGraphConfig } from '../context/GraphConfigContext'
import { GraphConfig } from '../config.ts'

Expand Down Expand Up @@ -50,10 +50,10 @@ export function Edge({
const [config] = useGraphConfig()
const api = useStoreApi()
const [edgePath] = getBezierPath({
sourceX: sourceX - 8,
sourceX: sourceX - 20,
sourceY: sourceY,
sourcePosition,
targetX: targetX + 8,
targetX: targetX + 20,
targetY: targetY,
targetPosition,
})
Expand All @@ -79,10 +79,7 @@ export function Edge({
// Determine selection state once initially
useEffect(() => {
onSelectionChange({
nodes: api
.getState()
.getNodes()
.filter((n) => n.selected),
nodes: api.getState().nodes.filter((n) => n.selected),
edges: [],
})
}, [])
Expand All @@ -104,7 +101,7 @@ export function Edge({
// todo:(performance) may need to revisit this if performance becomes a concern
const valueType = getTargetHandleValueType(
config,
api.getState().getNodes(),
api.getState().nodes,
target,
targetHandleId,
)
Expand Down
12 changes: 5 additions & 7 deletions lib/components/Handle.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { NodeInputConfig, ValueTypeConfig } from '../config'
import { CSSProperties, memo, useCallback, useMemo, useRef } from 'react'
import {
Connection,
HandleType,
Position,
useStoreApi,
Handle as FlowHandle,
} from 'reactflow'
IsValidConnection,
} from '@xyflow/react'
import { useGraphConfig } from '../context/GraphConfigContext'

type HandleProps = Pick<NodeInputConfig, 'isArray' | 'id'> &
Expand All @@ -27,13 +27,13 @@ export const Handle = memo(({ style, ...props }: HandleProps) => {

const api = useStoreApi()

const isValidConnection = useCallback((connection: Connection) => {
const isValidConnection: IsValidConnection = useCallback((connection) => {
const sourceNodeType = api
.getState()
.nodeInternals.get(connection.source!)?.type
.nodeLookup.get(connection.source!)?.type
const targetNodeType = api
.getState()
.nodeInternals.get(connection.target!)?.type
.nodeLookup.get(connection.target!)?.type

const sourceNodeConfig = config.getNodeConfig(sourceNodeType!)
const targetNodeConfig = config.getNodeConfig(targetNodeType!)
Expand Down Expand Up @@ -91,8 +91,6 @@ export const Handle = memo(({ style, ...props }: HandleProps) => {
justifyContent: 'center',
alignItems: 'center',
position: 'absolute',
left: props.position === Position.Left ? -8 : undefined,
right: props.position === Position.Right ? -8 : undefined,
zIndex: 1000000,
}}
>
Expand Down
2 changes: 1 addition & 1 deletion lib/components/NodeContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Node, Position } from 'reactflow'
import { Node, Position } from '@xyflow/react'
import { CSSProperties, JSX, ReactElement, useMemo } from 'react'
import { NodeHeader } from './NodeHeader'
import {
Expand Down
2 changes: 1 addition & 1 deletion lib/components/NodeDenseLinkedField.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { memo } from 'react'
import { Handle } from './Handle.js'
import { Position } from 'reactflow'
import { Position } from '@xyflow/react'
import { NodeInputConfig, ValueTypeConfig } from '../config'

type NodeDenseLinkedFieldProps = NodeInputConfig &
Expand Down
2 changes: 1 addition & 1 deletion lib/components/NodeDenseOutputField.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { memo } from 'react'
import { Handle } from './Handle'
import { NodeOutputConfig, ValueTypeConfig } from '../config'
import { Position } from 'reactflow'
import { Position } from '@xyflow/react'

type NodeDenseOutputFieldProps = NodeOutputConfig &
Pick<ValueTypeConfig, 'color'>
Expand Down
2 changes: 1 addition & 1 deletion lib/components/NodeLinkedField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Handle } from './Handle.js'
import { Label } from './Label.js'
import { NodeInputConfig, ValueTypeConfig } from '../config'
import { memo } from 'react'
import { Position } from 'reactflow'
import { Position } from '@xyflow/react'

type NodeLinkedFieldProps = NodeInputConfig &
Pick<ValueTypeConfig, 'shape' | 'color'>
Expand Down
2 changes: 1 addition & 1 deletion lib/components/NodeOutputField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Handle } from './Handle'
import { Label } from './Label'
import { NodeOutputConfig } from '../config'
import { useGraphConfig } from '../context/GraphConfigContext'
import { Position } from 'reactflow'
import { Position } from '@xyflow/react'

type NodeOutputFieldProps = NodeOutputConfig

Expand Down
2 changes: 1 addition & 1 deletion lib/hooks/connect.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useGraphConfig } from '../context/GraphConfigContext'
import { addEdge, Connection, useNodes, useReactFlow } from 'reactflow'
import { addEdge, Connection, useNodes, useReactFlow } from '@xyflow/react'
import { useCallback } from 'react'

export function useSocketConnect() {
Expand Down
4 changes: 2 additions & 2 deletions lib/hooks/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
useNodeId,
useReactFlow,
useStore,
} from 'reactflow'
} from '@xyflow/react'
import { shallow } from 'zustand/shallow'

const INPUT_GROUPS_FIELD = '__inputGroupsExpanded'
Expand Down Expand Up @@ -163,7 +163,7 @@ export function useNodesData<T>(nodeId: string): T {
return useStore(
useCallback(
(s) => {
return s.nodeInternals.get(nodeId)?.data || null
return s.nodeLookup.get(nodeId)?.data || null
},
[nodeId],
),
Expand Down
21 changes: 10 additions & 11 deletions lib/layout/dagre.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { Edge, Node, Position } from 'reactflow'
import { Edge, Node, Position } from '@xyflow/react'
import { layout, graphlib } from 'dagre'

type LayoutResult = { nodes: Node[]; edges: Edge[] }

export function computeDagreLayout(nodes: Node[], edges: Edge[]): LayoutResult {
export function computeDagreLayout(nodes: Node[], edges: Edge[]): Node[] {
const g = new graphlib.Graph()
g.setDefaultEdgeLabel(() => ({}))
g.setGraph({ rankdir: 'LR' })

nodes.forEach((node) => {
g.setNode(node.id, { width: node.width, height: node.height })
g.setNode(node.id, {
width: node.computed?.width,
height: node.computed?.height,
})
})

edges.forEach((edge) => {
Expand All @@ -18,21 +19,19 @@ export function computeDagreLayout(nodes: Node[], edges: Edge[]): LayoutResult {

layout(g)

nodes.forEach((node) => {
return nodes.map((node) => {
const nodeWithPosition = g.node(node.id)
node.targetPosition = Position.Left
node.sourcePosition = Position.Right

// We are shifting the dagre node position (anchor=center center) to the top left
// so it matches the React Flow node anchor point (top left).
if (node.width && node.height) {
if (node.computed?.width && node.computed?.height) {
node.position = {
x: nodeWithPosition.x - node.width / 2 + 70,
y: nodeWithPosition.y - node.height / 2 + 50,
x: nodeWithPosition.x - node.computed?.width / 2 + 70,
y: nodeWithPosition.y - node.computed?.height / 2 + 50,
}
}
return node
})

return { nodes, edges }
}
10 changes: 4 additions & 6 deletions lib/layout/layout.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useCallback } from 'react'
import { computeDagreLayout } from './dagre'
import { Edge, Instance, Node, useReactFlow } from 'reactflow'
import { Instance, Node, useReactFlow } from '@xyflow/react'

export enum LayoutEngine {
Dagre,
Expand All @@ -9,19 +9,17 @@ export enum LayoutEngine {
type LayoutFunc = () => void

export function useLayoutEngine(engine: LayoutEngine): LayoutFunc {
const { getNodes, getEdges, setNodes, setEdges } = useReactFlow()
const { getNodes, getEdges, setNodes } = useReactFlow()
return useCallback(() => {
const { nodes, edges } = computeLayout(engine, getNodes, getEdges)
setNodes(nodes)
setEdges(edges)
setNodes(computeLayout(engine, getNodes, getEdges))
}, [engine])
}

function computeLayout(
engine: LayoutEngine,
getNodes: Instance.GetNodes<any>,
getEdges: Instance.GetEdges<any>,
): { nodes: Node[]; edges: Edge[] } {
): Node[] {
switch (engine) {
case LayoutEngine.Dagre:
return computeDagreLayout(getNodes(), getEdges())
Expand Down
2 changes: 1 addition & 1 deletion lib/node-types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
useCallback,
useMemo,
} from 'react'
import { Edge, Node, Position } from 'reactflow'
import { Edge, Node, Position } from '@xyflow/react'
import { useNodesEdges } from './hooks/node'
import {
GraphConfig,
Expand Down
Loading

0 comments on commit ec7dd11

Please sign in to comment.