Last active
February 11, 2021 11:00
-
-
Save bohnacker/5baa14e917e910e8bb1910c86131c8b6 to your computer and use it in GitHub Desktop.
Svelte action to turn a node into a file drop area. Demo at: https://svelte.dev/repl/d3af7296998346aeb50d6657b7e31d26?version=3.32.3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// The action "dropable" turns a node into a file drop area and dispatches the custom event "files" when | |
// on or more files were dropped. You'll get an array of files in event.detail. | |
// You can provide filetypes as a string or an array of strings, e.g.: "text/html" or ["image/png", "image/jpeg"] | |
// Matching will be done by searching for the substring, so filetype "image/" will match all images | |
// or "/svg" will match "image/svg+xml". | |
export function dropable(node, filetypes) { | |
if (typeof filetypes === "string") filetypes = [filetypes] | |
function dragoverHandler(ev) { | |
ev.preventDefault(); | |
} | |
async function dropHandler(ev) { | |
ev.preventDefault(); | |
let files = []; | |
if (ev.dataTransfer.items) { | |
// Use DataTransferItemList interface to access the file(s) | |
for (let i = 0; i < ev.dataTransfer.items.length; i++) { | |
// If dropped items aren't files, reject them | |
if (ev.dataTransfer.items[i].kind === 'file') { | |
files.push(ev.dataTransfer.items[i].getAsFile()); | |
} | |
} | |
} else { | |
// Use DataTransfer interface to access the file(s) | |
for (let i = 0; i < ev.dataTransfer.files.length; i++) { | |
files.push(ev.dataTransfer.files[i]); | |
} | |
} | |
// If filetypes are given, check all files if they match with one of the given types. | |
if (filetypes) { | |
files = files.filter(file => { | |
let match = false; | |
filetypes.forEach(type => { | |
console.log("check", type, "on", file.type) | |
if (file.type.indexOf(type) >= 0) match = true; | |
}); | |
return match; | |
}); | |
} | |
node.dispatchEvent( new CustomEvent("files", {detail: files}) ); | |
} | |
node.addEventListener('dragover', dragoverHandler); | |
node.addEventListener('drop', dropHandler); | |
return { | |
update(newFiletypes) { | |
filetypes = newFiletypes; | |
if (typeof filetypes === "string") filetypes = [filetypes] | |
}, | |
destroy() { | |
node.removeEventListener('dragover', dragoverHandler); | |
node.removeEventListener('drop', dropHandler); | |
} | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment