-
-
Notifications
You must be signed in to change notification settings - Fork 98
Make Drag and Drop Example work on Touch Devices #970
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 5 commits
b64baba
4e757cc
e7aad35
ef2340e
dc7b5d8
61205db
1964e60
4bd1b0f
1caa61b
9db58a7
352e11a
bcf733a
8de0479
a979eb3
ac6ff1c
06855b3
b7c64ca
2e6b368
e4f55e4
aa34916
2bb5a9b
29af599
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
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 | ||||
---|---|---|---|---|---|---|
|
@@ -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); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback |
||||||
|
||||||
root.render(<App />); |
Uh oh!
There was an error while loading. Please reload this page.