Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 0 additions & 107 deletions apps/example-apps/react/examples/interaction/drag-and-drop/App.jsx

This file was deleted.

63 changes: 63 additions & 0 deletions apps/example-apps/react/examples/interaction/drag-and-drop/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import {
Background,
Connection,
Controls,
ReactFlow,
ReactFlowProvider,
addEdge,
useEdgesState,
useNodesState,
} from '@xyflow/react';
import { useCallback } from 'react';

import '@xyflow/react/dist/style.css';

import Sidebar from './Sidebar';
import { DnDProvider, DragGhost } from './useDnD';

const initialNodes = [
{
id: '1',
type: 'input',
data: { label: 'input node' },
position: { x: 250, y: 5 },
},
];

const DnDFlow = () => {
const [nodes, _, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState([]);

const onConnect = useCallback(
(params: Connection) => setEdges((eds) => addEdge(params, eds)),
[],
);

return (
<div className="dndflow">
<div className="reactflow-wrapper">
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
fitView
>
<Controls />
<Background />
</ReactFlow>
</div>
<Sidebar />
<DragGhost />
</div>
);
};

export default () => (
<ReactFlowProvider>
<DnDProvider>
<DnDFlow />
</DnDProvider>
</ReactFlowProvider>
);

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
---
title: Drag and Drop
description: Drag and drop outside of the React Flow pane with native HTML Drag and Drop API or react-draggable.
description: Drag and drop outside of the React Flow pane with native pointer events.
---

A drag and drop user interface is very common for node-based workflow editors. The drag and drop behavior outside of the React Flow pane is not built in but can be implemented with the native [HTML Drag and Drop API](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API) (used in this example) or a third party library like [react-draggable](https://github.com/react-grid-layout/react-draggable).
A drag and drop user interface is very common for node-based workflow editors.
The drag and drop behavior outside of the React Flow pane is not built in but
can be implemented with the native [pointer events](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events).

The reason why we use pointer events instead of the HTML Drag and Drop API is that
the HTML Drag and Drop API does not provide support for touch devices.
By using pointer events we can support both touch devices and the mouse.

<RemoteCodeViewer route="examples/interaction/drag-and-drop" framework="react" />

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { useDnD } from './useDnD';

export default () => {
const { startDragging } = useDnD();

return (
<aside>
<div className="description">
You can drag these nodes to the pane on the right.
</div>
<div
className="dndnode input"
onPointerDown={(event) => startDragging(event, 'input')}
>
Input Node
</div>
<div className="dndnode" onPointerDown={(event) => startDragging(event, 'default')}>
Default Node
</div>
<div
className="dndnode output"
onPointerDown={(event) => startDragging(event, 'output')}
>
Output Node
</div>
</aside>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ body {
cursor: grab;
}

.dndflow .dndnode:active {
cursor: grabbing;
}

.dndflow .dndnode.input {
border-color: #0041d0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import App from './App';
import './index.css';

const container = document.querySelector('#app');
if (!container) {
throw new Error("Root container '#app' not found");
}
const root = createRoot(container);
Copy link
Preview

Copilot AI Aug 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The createRoot call should use the non-null assertion operator since we've already verified container is not null, or the type should be updated to reflect this.

Suggested change
const root = createRoot(container);
const root = createRoot(container!);

Copilot uses AI. Check for mistakes.


root.render(<App />);
Loading