diff --git a/examples/react/src/examples/Basic/index.tsx b/examples/react/src/examples/Basic/index.tsx index 8d9c7dfd..f454b313 100644 --- a/examples/react/src/examples/Basic/index.tsx +++ b/examples/react/src/examples/Basic/index.tsx @@ -10,9 +10,10 @@ import { Edge, useReactFlow, Panel, + OnNodeDrag, } from '@xyflow/react'; -const onNodeDrag = (_: MouseEvent, node: Node) => console.log('drag', node); +const onNodeDrag: OnNodeDrag = (_, node) => console.log('drag', node); const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node); const onNodeClick = (_: MouseEvent, node: Node) => console.log('click', node); diff --git a/examples/react/src/examples/CustomNode/ColorSelectorNode.tsx b/examples/react/src/examples/CustomNode/ColorSelectorNode.tsx index 6857e1ac..72255e27 100644 --- a/examples/react/src/examples/CustomNode/ColorSelectorNode.tsx +++ b/examples/react/src/examples/CustomNode/ColorSelectorNode.tsx @@ -1,6 +1,8 @@ -import React, { memo, FC, CSSProperties, useCallback, useEffect } from 'react'; +import React, { memo, FC, CSSProperties, useCallback } from 'react'; import { Handle, Position, NodeProps, Connection, Edge, useOnViewportChange, Viewport } from '@xyflow/react'; +import type { ColorSelectorNode } from '.'; + const targetHandleStyle: CSSProperties = { background: '#555' }; const sourceHandleStyleA: CSSProperties = { ...targetHandleStyle, top: 10 }; const sourceHandleStyleB: CSSProperties = { @@ -11,7 +13,7 @@ const sourceHandleStyleB: CSSProperties = { const onConnect = (params: Connection | Edge) => console.log('handle onConnect', params); -const ColorSelectorNode: FC = ({ data, isConnectable }) => { +const ColorSelectorNode: FC> = ({ data, isConnectable }) => { const onStart = useCallback((viewport: Viewport) => console.log('onStart', viewport), []); const onChange = useCallback((viewport: Viewport) => console.log('onChange', viewport), []); const onEnd = useCallback((viewport: Viewport) => console.log('onEnd', viewport), []); diff --git a/examples/react/src/examples/CustomNode/index.tsx b/examples/react/src/examples/CustomNode/index.tsx index ce7d0f62..22433db0 100644 --- a/examples/react/src/examples/CustomNode/index.tsx +++ b/examples/react/src/examples/CustomNode/index.tsx @@ -5,24 +5,32 @@ import { Controls, addEdge, Node, - ReactFlowInstance, Position, SnapGrid, - Connection, - useNodesState, useEdgesState, Background, Edge, + OnNodeDrag, + OnInit, + applyNodeChanges, + OnNodesChange, + OnConnect, } from '@xyflow/react'; import ColorSelectorNode from './ColorSelectorNode'; -const onInit = (reactFlowInstance: ReactFlowInstance) => { +export type ColorSelectorNode = Node< + { color: string; onChange: (event: ChangeEvent) => void }, + 'selectorNode' +>; +export type MyNode = Node | ColorSelectorNode; + +const onInit: OnInit = (reactFlowInstance) => { console.log('flow loaded:', reactFlowInstance); }; -const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node); -const onNodeClick = (_: MouseEvent, node: Node) => console.log('click', node); +const onNodeDragStop: OnNodeDrag = (_, node) => console.log('drag stop', node); +const onNodeClick = (_: MouseEvent, node: MyNode) => console.log('click', node); const initBgColor = '#1A192B'; @@ -34,7 +42,16 @@ const nodeTypes = { }; const CustomNodeFlow = () => { - const [nodes, setNodes, onNodesChange] = useNodesState([]); + const [nodes, setNodes] = useState([]); + const onNodesChange: OnNodesChange = useCallback( + (changes) => + setNodes((nds) => { + const nextNodes = applyNodeChanges(changes, nds); + return nextNodes; + }), + [setNodes] + ); + const [edges, setEdges, onEdgesChange] = useEdgesState([]); const [bgColor, setBgColor] = useState(initBgColor); @@ -120,9 +137,8 @@ const CustomNodeFlow = () => { ]); }, []); - const onConnect = useCallback( - (connection: Connection) => - setEdges((eds) => addEdge({ ...connection, animated: true, style: { stroke: '#fff' } }, eds)), + const onConnect: OnConnect = useCallback( + (connection) => setEdges((eds) => addEdge({ ...connection, animated: true, style: { stroke: '#fff' } }, eds)), [setEdges] ); @@ -145,14 +161,14 @@ const CustomNodeFlow = () => { maxZoom={2} > { + nodeStrokeColor={(n: MyNode): string => { if (n.type === 'input') return '#0041d0'; if (n.type === 'selectorNode') return bgColor; if (n.type === 'output') return '#ff0072'; return '#eee'; }} - nodeColor={(n: Node): string => { + nodeColor={(n: MyNode): string => { if (n.type === 'selectorNode') return bgColor; return '#fff'; diff --git a/examples/svelte/src/routes/examples/handle-connect/MultiHandleNode.svelte b/examples/svelte/src/routes/examples/handle-connect/MultiHandleNode.svelte index ebc85c74..f411fc44 100644 --- a/examples/svelte/src/routes/examples/handle-connect/MultiHandleNode.svelte +++ b/examples/svelte/src/routes/examples/handle-connect/MultiHandleNode.svelte @@ -43,10 +43,8 @@ export let zIndex: $$Props['zIndex'] = undefined; export let dragging: $$Props['dragging'] = false; export let dragHandle: $$Props['dragHandle'] = undefined; - export let positionAbsolute: $$Props['positionAbsolute'] = { - x: 0, - y: 0 - }; + export let positionAbsoluteX: $$Props['positionAbsoluteX'] = 0; + export let positionAbsoluteY: $$Props['positionAbsoluteY'] = 0; export let isConnectable: $$Props['isConnectable'] = undefined; data; @@ -59,7 +57,8 @@ zIndex; dragging; dragHandle; - positionAbsolute; + positionAbsoluteX; + positionAbsoluteY; isConnectable; diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 2dd4e593..70a3de11 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,19 +1,28 @@ # @xyflow/react +## 12.0.0-next.8 + +### Patch changes + +- fix `OnNodeDrag` type + ## 12.0.0-next.7 ## Minor changes -- pass Node/Edge types to changes thanks @FelipeEmos -- use position instead of positionAbsolute for `getNodesBounds` - add second option param to `screenToFlowPosition` for configuring if `snapToGrid` should be used + +### Patch changes + +- pass `Node`/ `Edge` types to changes thanks @FelipeEmos +- use position instead of positionAbsolute for `getNodesBounds` - infer types for `getIncomers`, `getOutgoers`, `updateEdge`, `addEdge` and `getConnectedEdges` thanks @joeyballentine - refactor handles: prefix with flow id for handling nested flows - add comments for types like `ReactFlowProps` or `Node` for a better developer experience ## 12.0.0-next.6 -### Minor changes +### Patch changes - fix `deleteElements` - refactor internal `applyChanges` diff --git a/packages/react/src/components/EdgeWrapper/index.tsx b/packages/react/src/components/EdgeWrapper/index.tsx index cb9b9c8b..28323a19 100644 --- a/packages/react/src/components/EdgeWrapper/index.tsx +++ b/packages/react/src/components/EdgeWrapper/index.tsx @@ -186,6 +186,7 @@ export function EdgeWrapper({ animated: edge.animated, inactive: !isSelectable && !onClick, updating: updateHover, + selectable: isSelectable, }, ])} onClick={onEdgeClick} diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index 3cabb813..8ad67000 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -67,7 +67,6 @@ export { type OnError, type NodeProps, type NodeOrigin, - type OnNodeDrag, type OnSelectionDrag, Position, type XYPosition, diff --git a/packages/react/src/styles/base.css b/packages/react/src/styles/base.css index 4a7281dc..d6be5b10 100644 --- a/packages/react/src/styles/base.css +++ b/packages/react/src/styles/base.css @@ -1,21 +1,3 @@ /* this will be exported as base.css and can be used for a basic styling */ @import '../../../system/src/styles/init.css'; @import '../../../system/src/styles/base.css'; - -.react-flow { - --edge-label-background-color-default: #ffffff; - --edge-label-color-default: inherit; -} - -.react-flow.dark { - --edge-label-background-color-default: #141414; - --edge-label-color-default: #f8f8f8; -} - -.react-flow__edge-textbg { - fill: var(--edge-label-background-color, var(--edge-label-background-color-default)); -} - -.react-flow__edge-text { - fill: var(--edge-label-color, var(--edge-label-color-default)); -} diff --git a/packages/react/src/styles/style.css b/packages/react/src/styles/style.css index 2ff7f6c1..71b4d08c 100644 --- a/packages/react/src/styles/style.css +++ b/packages/react/src/styles/style.css @@ -3,20 +3,10 @@ @import '../../../system/src/styles/style.css'; @import '../../../system/src/styles/node-resizer.css'; -.react-flow { - --edge-label-background-color-default: #ffffff; - --edge-label-color-default: inherit; -} - -.react-flow.dark { - --edge-label-background-color-default: #141414; - --edge-label-color-default: #f8f8f8; -} - .react-flow__edge-textbg { - fill: var(--edge-label-background-color, var(--edge-label-background-color-default)); + fill: var(--xy-edge-label-background-color, var(--xy-edge-label-background-color-default)); } .react-flow__edge-text { - fill: var(--edge-label-color, var(--edge-label-color-default)); + fill: var(--xy-edge-label-color, var(--xy-edge-label-color-default)); } diff --git a/packages/react/src/types/component-props.ts b/packages/react/src/types/component-props.ts index 50f07303..f8bc8dfd 100644 --- a/packages/react/src/types/component-props.ts +++ b/packages/react/src/types/component-props.ts @@ -40,10 +40,10 @@ import type { OnDelete, OnNodesChange, OnEdgesChange, - NodeDragHandler, NodeMouseHandler, SelectionDragHandler, EdgeMouseHandler, + OnNodeDrag, } from '.'; /** @@ -111,11 +111,11 @@ export interface ReactFlowProps extends Omit, 'on /** This event handler is called when a user right clicks on a node */ onNodeContextMenu?: NodeMouseHandler; /** This event handler is called when a user starts to drag a node */ - onNodeDragStart?: NodeDragHandler; + onNodeDragStart?: OnNodeDrag; /** This event handler is called when a user drags a node */ - onNodeDrag?: NodeDragHandler; + onNodeDrag?: OnNodeDrag; /** This event handler is called when a user stops dragging a node */ - onNodeDragStop?: NodeDragHandler; + onNodeDragStop?: OnNodeDrag; /** This event handler is called when a user clicks on an edge */ onEdgeClick?: (event: ReactMouseEvent, edge: Edge) => void; /** This event handler is called when a user right clicks on an edge */ diff --git a/packages/react/src/types/general.ts b/packages/react/src/types/general.ts index 9a36e41f..1a7462ad 100644 --- a/packages/react/src/types/general.ts +++ b/packages/react/src/types/general.ts @@ -19,7 +19,7 @@ import { ComponentType } from 'react'; export type OnNodesChange = (changes: NodeChange[]) => void; export type OnEdgesChange = (changes: EdgeChange[]) => void; -export type OnNodesDelete = (nodes: Node[]) => void; +export type OnNodesDelete = (nodes: NodeType[]) => void; export type OnEdgesDelete = (edges: Edge[]) => void; export type OnDelete = (params: { nodes: Node[]; edges: Edge[] }) => void; diff --git a/packages/react/src/types/nodes.ts b/packages/react/src/types/nodes.ts index 71bfb685..612c1d50 100644 --- a/packages/react/src/types/nodes.ts +++ b/packages/react/src/types/nodes.ts @@ -3,11 +3,11 @@ import type { CoordinateExtent, NodeBase, NodeOrigin, OnError } from '@xyflow/sy import { NodeTypes } from './general'; -// eslint-disable-next-line @typescript-eslint/no-explicit-any /** * The node data structure that gets used for the nodes prop. * @public */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any export type Node = NodeBase< NodeData, NodeType @@ -18,9 +18,13 @@ export type Node void; -export type NodeDragHandler = (event: ReactMouseEvent, node: Node, nodes: Node[]) => void; -export type SelectionDragHandler = (event: ReactMouseEvent, nodes: Node[]) => void; +export type NodeMouseHandler = (event: ReactMouseEvent, node: NodeType) => void; +export type SelectionDragHandler = (event: ReactMouseEvent, nodes: NodeType[]) => void; +export type OnNodeDrag = ( + event: ReactMouseEvent, + node: NodeType, + nodes: NodeType[] +) => void; export type NodeWrapperProps = { id: string; diff --git a/packages/react/src/types/store.ts b/packages/react/src/types/store.ts index b138fc9d..a0d5f8cc 100644 --- a/packages/react/src/types/store.ts +++ b/packages/react/src/types/store.ts @@ -17,7 +17,6 @@ import { type PanBy, type OnConnectStart, type OnConnectEnd, - type OnNodeDrag, type OnSelectionDrag, type OnMoveStart, type OnMove, @@ -43,6 +42,7 @@ import type { OnSelectionChangeFunc, UnselectNodesAndEdgesParams, OnDelete, + OnNodeDrag, } from '.'; export type ReactFlowStore = { diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index b7557fff..6b9e940a 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,11 +1,24 @@ # @xyflow/svelte +## 0.0.35 + +## Minor changes + +- add `getNode`, `getNodes`, `getEdge` and `getEdges` to `useSvelteFlow` + +## Patch changes + +- Edge label has a default background and is clickable + ## 0.0.34 ## Minor changes - add second option param to `screenToFlowPosition` for configuring if `snapToGrid` should be used - add slot to `Controls` + +## Patch changes + - cleanup `ControlButton` types - infer types for `getIncomers`, `getOutgoers`, `updateEdge`, `addEdge` and `getConnectedEdges` thanks @joeyballentine - refactor handles: prefix with flow id for handling nested flows @@ -42,7 +55,7 @@ - add `onbeforedelete` handler to prevent/ manage deletions - TSDocs for hooks and some types -### Minor changes +### Patch changes - new nodeDragThreshold default is 1 - refactor/simplify edge rendering diff --git a/packages/svelte/src/lib/components/BaseEdge/BaseEdge.svelte b/packages/svelte/src/lib/components/BaseEdge/BaseEdge.svelte index d1c60f8f..36b3763e 100644 --- a/packages/svelte/src/lib/components/BaseEdge/BaseEdge.svelte +++ b/packages/svelte/src/lib/components/BaseEdge/BaseEdge.svelte @@ -1,7 +1,7 @@ @@ -43,13 +42,7 @@ {/if} {#if label} - -
- {label} -
-
+ + {label} + {/if} diff --git a/packages/svelte/src/lib/components/EdgeLabel/EdgeLabel.svelte b/packages/svelte/src/lib/components/EdgeLabel/EdgeLabel.svelte new file mode 100644 index 00000000..81039d0d --- /dev/null +++ b/packages/svelte/src/lib/components/EdgeLabel/EdgeLabel.svelte @@ -0,0 +1,28 @@ + + + +
{ + if (id) handleEdgeSelect(id); + }} + > + +
+
diff --git a/packages/svelte/src/lib/components/EdgeLabel/index.ts b/packages/svelte/src/lib/components/EdgeLabel/index.ts new file mode 100644 index 00000000..2e0a457c --- /dev/null +++ b/packages/svelte/src/lib/components/EdgeLabel/index.ts @@ -0,0 +1 @@ +export { default as EdgeLabel } from './EdgeLabel.svelte'; diff --git a/packages/svelte/src/lib/components/EdgeWrapper/EdgeWrapper.svelte b/packages/svelte/src/lib/components/EdgeWrapper/EdgeWrapper.svelte index c68ea1d5..0d4c126b 100644 --- a/packages/svelte/src/lib/components/EdgeWrapper/EdgeWrapper.svelte +++ b/packages/svelte/src/lib/components/EdgeWrapper/EdgeWrapper.svelte @@ -1,14 +1,14 @@