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..a8c0f55d 100644 --- a/examples/react/src/examples/CustomNode/index.tsx +++ b/examples/react/src/examples/CustomNode/index.tsx @@ -5,24 +5,33 @@ import { Controls, addEdge, Node, - ReactFlowInstance, Position, SnapGrid, - Connection, - useNodesState, useEdgesState, Background, Edge, + OnNodeDrag, + OnInit, + applyNodeChanges, + OnNodesChange, + OnConnect, + OnBeforeDelete, } 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 +43,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,12 +138,13 @@ 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] ); + const onBeforeDelete: OnBeforeDelete = useCallback(async (params) => true, []); + return ( { fitView minZoom={0.3} maxZoom={2} + onBeforeDelete={onBeforeDelete} > { + 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/react/src/examples/Edges/index.tsx b/examples/react/src/examples/Edges/index.tsx index d6870621..bbba30fb 100644 --- a/examples/react/src/examples/Edges/index.tsx +++ b/examples/react/src/examples/Edges/index.tsx @@ -175,6 +175,15 @@ const edgeTypes: EdgeTypes = { custom2: CustomEdge2, }; +const defaultEdgeOptions = { + markerEnd: { + type: MarkerType.ArrowClosed, + color: 'red', + width: 20, + height: 20, + }, +}; + const EdgesFlow = () => { const [nodes, , onNodesChange] = useNodesState(initialNodes); const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); @@ -197,6 +206,7 @@ const EdgesFlow = () => { onEdgeMouseMove={onEdgeMouseMove} onEdgeMouseLeave={onEdgeMouseLeave} onDelete={console.log} + defaultEdgeOptions={defaultEdgeOptions} > diff --git a/examples/react/src/examples/Subflow/index.tsx b/examples/react/src/examples/Subflow/index.tsx index e2e9af89..19dc119a 100644 --- a/examples/react/src/examples/Subflow/index.tsx +++ b/examples/react/src/examples/Subflow/index.tsx @@ -13,6 +13,7 @@ import { MiniMap, Background, Panel, + NodeOrigin, } from '@xyflow/react'; import DebugNode from './DebugNode'; @@ -119,6 +120,7 @@ const initialNodes: Node[] = [ data: { label: 'Node 3' }, position: { x: 400, y: 100 }, className: 'light', + extent: 'parent', }, ]; diff --git a/examples/react/src/examples/UseNodesData/index.tsx b/examples/react/src/examples/UseNodesData/index.tsx index d6b697a9..d99ddb43 100644 --- a/examples/react/src/examples/UseNodesData/index.tsx +++ b/examples/react/src/examples/UseNodesData/index.tsx @@ -18,7 +18,7 @@ import UppercaseNode from './UppercaseNode'; export type TextNode = Node<{ text: string }, 'text'>; export type ResultNode = Node<{}, 'result'>; export type UppercaseNode = Node<{}, 'uppercase'>; -export type MyNode = Node<{ text: string }, 'text'> | Node<{}, 'result'> | Node<{}, 'uppercase'>; +export type MyNode = Node | TextNode | ResultNode | UppercaseNode; const nodeTypes = { text: TextNode, diff --git a/examples/svelte/src/routes/examples/add-node-on-drop/Flow.svelte b/examples/svelte/src/routes/examples/add-node-on-drop/Flow.svelte index 809ae82c..e767e4ac 100644 --- a/examples/svelte/src/routes/examples/add-node-on-drop/Flow.svelte +++ b/examples/svelte/src/routes/examples/add-node-on-drop/Flow.svelte @@ -34,7 +34,7 @@ // See of connection landed inside the flow pane const targetIsPane = (event.target as HTMLDivElement)?.classList.contains('svelte-flow__pane'); - if (targetIsPane) { + if (targetIsPane && 'clientX' in event && 'clientY' in event) { const id = getId(); const position = { x: event.clientX, 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/examples/svelte/src/routes/examples/overview/+page.svelte b/examples/svelte/src/routes/examples/overview/+page.svelte index 586af3b9..2f21107d 100644 --- a/examples/svelte/src/routes/examples/overview/+page.svelte +++ b/examples/svelte/src/routes/examples/overview/+page.svelte @@ -22,6 +22,7 @@ import CustomEdge from './CustomEdge.svelte'; import '@xyflow/svelte/dist/style.css'; + import InitTracker from './InitTracker.svelte'; const nodeTypes: NodeTypes = { custom: CustomNode, @@ -148,6 +149,7 @@ selectionMode={SelectionMode.Full} initialViewport={{ x: 100, y: 100, zoom: 2 }} snapGrid={[25, 25]} + oninit={() => console.log('on init')} on:nodeclick={(event) => console.log('on node click', event)} on:nodemouseenter={(event) => console.log('on node enter', event)} on:nodemouseleave={(event) => console.log('on node leave', event)} @@ -207,6 +209,8 @@ }}>hide/unhide + +