JSFiddle - React, Tailwind, and code Playground
by _sir
HTML
<div id="dropzone" ondragover="handleDragOver(event)" ondrop="handleDrop(event)"></div>
CSS
#dropzone {
width: 100vw;
height: 100vh;
}
JavaScript
let files = [];
/**
* @param {FileSystemDirectoryEntry} entry
* @returns {Promise[FileSystemEntry]}
*/
const getDirectoryEntries = (entry) => new Promise((res, rej) => entry.createReader().readEntries(res, rej));
const handleDragOver = event => event.preventDefault();
function handleDrop(event) {
event.preventDefault();
files = [];
const dataTransferItems = Object.keys(event.dataTransfer.items);
Promise.all(dataTransferItems.map(async (key) => {
const item = event.dataTransfer.items[key];
const entry = item.webkitGetAsEntry();
if (!entry) return;
if (entry.isFile) {
files.push(entry.fullPath);
return entry.fullPath;
} else if (entry.isDirectory) {
return getDirectoryEntries(entry).then()
const directoryReader = entry.createReader();
return await walkDirRecursively(entry.fullPath, directoryReader);
}
})).then(() => console.log(files));
}
function walkDirRecursively(path, directoryReader) {
const readerPromise = new Promise((resolve, reject) =>
directoryReader.readEntries(resolve, reject));
return readerPromise.then((entries) => {
entries.reduce((acc, entry) => acc.then((data) => {
if (entry.isFile) {
const newPath = path + "/" + entry.name;
files.push(newPath);
return [...data, newPath];
}
if (entry.isDirectory) {
const newPath = path + "/" + entry.name;
const newDirectoryReader = entry.createReader();
return walkDirRecursively(newPath, newDirectoryReader);
}
// unlikely case
return data;
}), Promise.resolve([]));
});
}