Skip to Content
ExamplesInteraction

Connection Events

React Flow emits different events during the connection process that you can use to update your UI or your flow in different ways. The example below demonstrates which events are fired and when.

/* xyflow theme files. Delete these to start from our base */ .react-flow { --xy-background-color: #f7f9fb; /* Custom Variables */ --xy-theme-selected: #f57dbd; --xy-theme-hover: #c5c5c5; --xy-theme-edge-hover: black; --xy-theme-color-focus: #e8e8e8; /* Built-in Variables see https://reactflow.dev/learn/customization/theming */ --xy-node-border-default: 1px solid #ededed; --xy-node-boxshadow-default: 0px 3.54px 4.55px 0px #00000005, 0px 3.54px 4.55px 0px #0000000d, 0px 0.51px 1.01px 0px #0000001a; --xy-node-border-radius-default: 8px; --xy-handle-background-color-default: #ffffff; --xy-handle-border-color-default: #aaaaaa; --xy-edge-label-color-default: #505050; --xy-node-background-color-default: #ffffff; --xy-theme-panel-bg: #ffffff; --xy-theme-panel-text: #111827; --xy-theme-resize-handle-bg: #ffffff; --xy-theme-focus-border: #d9d9d9; --xy-theme-muted-bg: #f3f4f6; --xy-theme-subtle-border: #d1d5db; } .react-flow.dark { --xy-background-color: #101012; --xy-node-background-color-default: #1a1b1e; --xy-node-border-default: 1px solid #303238; --xy-handle-background-color-default: #141519; --xy-handle-border-color-default: #5a5d66; --xy-edge-label-color-default: #e6e7ea; --xy-theme-hover: #7a7d86; --xy-theme-edge-hover: #f3f4f6; --xy-theme-panel-bg: #141519; --xy-theme-panel-text: #f3f4f6; --xy-theme-resize-handle-bg: #141519; --xy-theme-focus-border: #5f6470; --xy-theme-muted-bg: #24262c; --xy-theme-subtle-border: #3f434c; --xy-node-boxshadow-default: none; --xy-theme-color-focus: #4b4e57; --color-background: #1a1b1e; --color-hover-bg: #24262c; --color-disabled: #8b9099; } .react-flow { background-color: var(--xy-background-color); } /* Customizing Default Theming */ .react-flow__node { box-shadow: var(--xy-node-boxshadow-default); border-radius: var(--xy-node-border-radius-default); background-color: var(--xy-node-background-color-default); display: flex; justify-content: center; align-items: center; text-align: center; padding: 10px; font-size: 12px; flex-direction: column; border: var(--xy-node-border-default); color: var(--xy-node-color, var(--xy-node-color-default)); } .react-flow__node.selectable:focus { box-shadow: 0px 0px 0px 4px var(--xy-theme-color-focus); border-color: var(--xy-theme-focus-border); } .react-flow__node.selectable:focus:active { box-shadow: var(--xy-node-boxshadow-default); } .react-flow__node.selectable:hover, .react-flow__node.draggable:hover { border-color: var(--xy-theme-hover); } .react-flow__node.selectable.selected { border-color: var(--xy-theme-selected); box-shadow: var(--xy-node-boxshadow-default); } .react-flow__node-group { background-color: rgba(207, 182, 255, 0.4); border-color: #9e86ed; } .react-flow.dark .react-flow__node-group { background-color: rgba(123, 107, 148, 0.22); border-color: #7b6b94; } .react-flow__edge.selectable:hover .react-flow__edge-path, .react-flow__edge.selectable.selected .react-flow__edge-path { stroke: var(--xy-theme-edge-hover); } .react-flow__handle { background-color: var(--xy-handle-background-color-default); } .react-flow__handle.connectionindicator:hover { pointer-events: all; border-color: var(--xy-theme-edge-hover); background-color: var(--xy-handle-background-color-default); } .react-flow__handle.connectionindicator:focus, .react-flow__handle.connectingfrom, .react-flow__handle.connectingto { border-color: var(--xy-theme-edge-hover); } .react-flow__node-resizer { border-radius: 0; border: none; } .react-flow__resize-control.handle { background-color: var(--xy-theme-resize-handle-bg); border-color: #9e86ed; border-radius: 0; width: 5px; height: 5px; } /* Custom Example CSS - This CSS is to improve the example experience. You can remove it if you want to use the default styles. New Theme Classes: .xy-theme__button - Styles for buttons. .xy-theme__input - Styles for text inputs. .xy-theme__checkbox - Styles for checkboxes. .xy-theme__select - Styles for dropdown selects. .xy-theme__label - Styles for labels. Use these classes to apply consistent theming across your components. */ :root { --color-primary: #ff0073; --color-background: #fefefe; --color-hover-bg: #f6f6f6; --color-disabled: #76797e; } .xy-theme__button-group { display: flex; align-items: center; .xy-theme__button:first-child { border-radius: 100px 0 0 100px; } .xy-theme__button:last-child { border-radius: 0 100px 100px 0; margin: 0; } } /* Custom Button Styling */ .xy-theme__button { display: inline-flex; align-items: center; justify-content: center; height: 2.5rem; padding: 0 1rem; border-radius: 100px; border: 1px solid var(--color-primary); background-color: var(--color-background); color: var(--color-primary); transition: background-color 0.2s ease, border-color 0.2s ease; box-shadow: var(--xy-node-boxshadow-default); cursor: pointer; } .xy-theme__button.active { background-color: var(--color-primary); color: white; border-color: var(--color-primary); } .xy-theme__button.active:hover, .xy-theme__button.active:active { background-color: var(--color-primary); opacity: 0.9; } .xy-theme__button:hover { background-color: var(--xy-controls-button-background-color-hover-default); } .xy-theme__button:active { background-color: var(--color-hover-bg); } .xy-theme__button:disabled { color: var(--color-disabled); opacity: 0.8; cursor: not-allowed; border: 1px solid var(--color-disabled); } .xy-theme__button > span { margin-right: 0.2rem; } /* Add gap between adjacent buttons */ .xy-theme__button + .xy-theme__button { margin-left: 0.3rem; } /* Example Input Styling */ .xy-theme__input { padding: 0.5rem 0.75rem; border: 1px solid var(--color-primary); border-radius: 7px; background-color: var(--color-background); transition: background-color 0.2s ease, border-color 0.2s ease; font-size: 1rem; color: var(--xy-theme-panel-text); } .xy-theme__input:focus { outline: none; border-color: var(--color-primary); box-shadow: 0 0 0 2px rgba(255, 0, 115, 0.3); } /* Specific Checkbox Styling */ .xy-theme__checkbox { appearance: none; -webkit-appearance: none; width: 1.25rem; height: 1.25rem; border-radius: 7px; border: 2px solid var(--color-primary); background-color: var(--color-background); transition: background-color 0.2s ease, border-color 0.2s ease; cursor: pointer; display: inline-block; vertical-align: middle; margin-right: 0.5rem; } .xy-theme__checkbox:checked { background-color: var(--color-primary); border-color: var(--color-primary); } .xy-theme__checkbox:focus { outline: none; box-shadow: 0 0 0 2px rgba(255, 0, 115, 0.3); } /* Dropdown Styling */ .xy-theme__select { padding: 0.5rem 0.75rem; border: 1px solid var(--color-primary); border-radius: 50px; background-color: var(--color-background); transition: background-color 0.2s ease, border-color 0.2s ease; font-size: 1rem; color: var(--xy-theme-panel-text); margin-right: 0.5rem; box-shadow: var(--xy-node-boxshadow-default); } .xy-theme__select:focus { outline: none; border-color: var(--color-primary); box-shadow: 0 0 0 2px rgba(255, 0, 115, 0.3); } .xy-theme__label { margin-top: 10px; margin-bottom: 3px; display: inline-block; color: var(--xy-theme-panel-text); }

For a new connection created by dragging from a handle, the following events are called in order:

  • onConnectStart is called with the mouse event and an object containing the source node, potentially the source handle id, and the handle type.

  • onConnect is only called when the connection is released on a handle that is connectable. It is called with a complete connection object containing the source and target node, and the source and target handle ids if present.

  • onConnectEnd is called when a connection is released, regardless of whether it was successful or not. It is called with the mouse event.

When an edge is reconnected by dragging an existing edge, the following events are called in order:

You can see many of these events in use in our add node on edge drop and temporary edges examples!

Last updated on