react-dnd-html5-backend
react-dnd-html5-backend copied to clipboard
Feature request: Support native folder drop
Currently, the native drag source for Files only extracts "files" from the data transfer object. In order to use Chrome's support for folders and folder traversal, it would be nice to have the "items" as well.
I've been able to monkey patch the HTML5Backend to pass along what I need.
function makeFolderAwareHTML5Backend(manager) {
const backend = HTML5Backend(manager);
const orig = backend.handleTopDropCapture;
backend.handleTopDropCapture = function(event) {
backend.currentNativeSource.item.items = event.dataTransfer.items;
return orig(event);
}
return backend;
}
export default DragDropContext(makeFolderAwareHTML5Backend)(DropTarget(types, fileTarget, collect)(App));
:+1: would really like this feature as well
@vgatto thank you for this monkey patch!
@vgatto really thank you for this path
Doesn't work for me :(
thanks @vgatto your sample was a great help. I created html-dir-content to help with the traversing of folder structure and your code helped me tie them together.
In case someone ends up with a use case such as mine, here's what i ended up with:
//dndBackendWithFolderSupport.js
import HTML5Backend from "react-dnd-html5-backend";
import {getFilesFromDragEvent} from "html-dir-content";
export default (manager: Object) => {
const backend = HTML5Backend(manager),
orgTopDropCapture = backend.handleTopDropCapture;
backend.handleTopDropCapture = (e) => {
orgTopDropCapture.call(backend, e);
backend.currentNativeSource.item.dirContent = getFilesFromDragEvent(e); //returns a promise
};
return backend;
}
//my component
const dndSpec = {
drop(props: Props, monitor: { getItem: () => any }) {
const dndItem = monitor.getItem();
if (dndItem) {
if (dndItem.urls && dndItem.urls.length) {
//handle urls
}
else {
dndItem.dirContent.then((files: Object[]) => {
if (files.length){
// handle dragged folder(s)
}
else if (dndItem.files && dndItem.files.length){
//handle dragged files
}
});
}
}
return {
dndFinished: true
};
},
};