Drag and drop
Native drag sources and drop destinations for files, text, URLs, and custom data.
Use DragDropView from @legendapp/spark/drag-drop to drag or receive files, text, URLs, and custom data. It accepts ordinary React Native view props.
Native drag behavior on macOS and Windows still needs validation.
Sources and destinations
import { Text } from 'react-native';
import { DragDropView } from '@legendapp/spark/drag-drop';
export function DragExample() {
return (
<>
<DragDropView
source={{ data: { 'application/x-my-item': JSON.stringify({ id: '42' }) } }}
sourceOperations={['copy', 'move']}
onDragEnd={event => console.log(event.accepted, event.operation)}
onError={console.error}
>
<Text>Drag this item</Text>
</DragDropView>
<DragDropView
acceptedTypes={['files', 'application/x-my-item']}
acceptedOperations={['copy', 'move']}
onDrop={({ files, data, operation, x, y }) => {
console.log({ files, data, operation, x, y });
}}
onError={console.error}
>
<Text>Drop here</Text>
</DragDropView>
</>
);
}Payloads and negotiation
DragPayload can contain several representations at once:
| Field | Value |
|---|---|
files | Array of absolute native paths. Local file URLs in a source are normalized. |
text | A string. |
urls | Array of absolute URLs. Windows sources allow one URL; multiple URLs reject with E_UNSUPPORTED_OPTION. |
data | Map of lowercase custom MIME names to UTF-8 strings. The app owns JSON schemas and validation. |
A source must contain at least one representation. text/plain, text/uri-list, and application/x-spark-drag are reserved; use the built-in fields for text and URLs.
sourceOperations and acceptedOperations accept copy, move, and link, and each defaults to ['copy']. Destinations default to acceptedTypes={['files', 'text', 'urls']}; custom MIME types require explicit opt-in. The first mutually supported target operation wins. Empty accepted operations or types reject all drops; disabled disables both directions.
Accepted types determine drop eligibility. A payload may still include coexisting built-in representations, while custom data is restricted to requested custom types.
Events
| Callback | Payload |
|---|---|
onDragEnter, onDrop | DropEvent: payload fields plus x, y, and operation. |
onDragOver | DragOverEvent: only x, y, and operation. |
onDragLeave | No payload. |
onDragEnd | { accepted: true, operation: 'copy' | 'move' | 'link' } or { accepted: false, operation: 'none' }. |
Coordinates are logical units from the destination's top-left corner. For a move, save the dropped data before deleting it at the source. An accepted drop does not confirm that saving succeeded.
Availability and errors
getDragDropAvailability() synchronously reports an unsupported platform or a missing native component. An unavailable host renders an ordinary View with the children intact. Remount after repairing the host to retry.
Handle onError to show unavailable-host and native errors; it defaults to console.error. Invalid props throw during render. Invalid native events report through onError and skip their callback.
See the drag-and-drop source guide and shared error contracts.