Legend SparkExperimental โ€” not for production

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:

FieldValue
filesArray of absolute native paths. Local file URLs in a source are normalized.
textA string.
urlsArray of absolute URLs. Windows sources allow one URL; multiple URLs reject with E_UNSUPPORTED_OPTION.
dataMap 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

CallbackPayload
onDragEnter, onDropDropEvent: payload fields plus x, y, and operation.
onDragOverDragOverEvent: only x, y, and operation.
onDragLeaveNo 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.