Utility Classes

Beginner · 2 min read · Updated Nov 6, 2026

Utility Classes: Control Node and Canvas Interactions

React Flow provides built-in CSS utility classes that help developers control how users interact with nodes, edges, and the workflow canvas. These classes make it easier to prevent unwanted dragging, disable canvas panning, and manage interactive elements inside custom nodes.

Utility classes are especially useful when building advanced workflow editors, interactive forms, and visual programming applications.

1. The nodrag Utility Class

The nodrag class prevents users from dragging a node when interacting with specific elements inside it. It is useful for input fields, buttons, dropdowns, and other interactive components.

Code Example

import { Handle, Position } from '@xyflow/react';

export function CustomNode({ data }) {
  return (
    <div className="custom-node">
      <Handle type="target" position={Position.Left} />

      <strong>{data.label}</strong>

      <input
        className="nodrag"
        placeholder="Enter text"
      />

      <button className="nodrag">
        Submit
      </button>

      <Handle type="source" position={Position.Right} />
    </div>
  );
}

This allows users to interact with form elements without accidentally moving the entire node.

2. The nopan Utility Class

The nopan class prevents canvas panning when interacting with a specific element. It is useful for custom toolbars, controls, and interactive UI elements placed inside the React Flow canvas.

Code Example

import { Panel } from '@xyflow/react';

export default function WorkflowToolbar() {
  return (
    <Panel position="top-right">
      <div className="nopan">
        <button>Save Flow</button>
        <button>Export</button>
      </div>
    </Panel>
  );
}

This keeps toolbar interactions separate from canvas navigation.

3. The nowheel Utility Class

The nowheel class prevents mouse wheel events from triggering React Flow's default zoom behavior on a specific element. It is useful for scrollable content inside custom nodes, such as text areas, lists, and dropdown menus.

Code Example

export function ScrollableNode({ data }) {
  return (
    <div className="custom-node">
      <strong>{data.label}</strong>

      <div
        className="nowheel"
        style={{
          height: 120,
          overflowY: 'auto',
        }}
      >
        {data.items.map((item, index) => (
          <p key={index}>{item}</p>
        ))}
      </div>
    </div>
  );
}

Users can scroll through the node content without unintentionally zooming the entire workflow canvas.

4. Combining Utility Classes

You can combine multiple React Flow utility classes to control different interactions within the same custom node. This is particularly useful when building nodes containing forms, scrollable content, and interactive buttons.

Code Example

export function AdvancedNode({ data }) {
  return (
    <div className="custom-node">
      <strong>{data.label}</strong>

      <input
        className="nodrag"
        placeholder="Node title"
      />

      <div className="nowheel">
        <textarea
          className="nodrag"
          placeholder="Write description..."
        />
      </div>

      <button className="nodrag nopan">
        Save Changes
      </button>
    </div>
  );
}

Combining these classes creates a smoother user experience by separating node interactions from canvas navigation.

5. Styling React Flow Utility Classes

React Flow utility classes control interaction behavior, while CSS allows you to customize the appearance of your node components and interactive elements.

Code Example

.custom-node {
  padding: 16px;
  background: #ffffff;
  border: 1px solid #e2e8f0;
  border-radius: 10px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.custom-node input,
.custom-node textarea {
  padding: 8px;
  border: 1px solid #cbd5e1;
  border-radius: 6px;
  outline: none;
}

.custom-node button {
  padding: 8px 12px;
  background: #6366f1;
  color: #ffffff;
  border: none;
  border-radius: 6px;
  cursor: pointer;
}

This approach helps maintain consistent styling across interactive React Flow nodes.