A file dropzone action & component for Svelte.
npm i filedrop-svelte -D
# yarn add filedrop-svelte -dev
If using Typescript, see the Typescript section.
filedrop-svelte comes with both a component and an action. The component is basically a wrapper around the action with some some default styling.
See this REPL for minmimal usage.
<script>
    import FileDrop from "filedrop-svelte";
    import type { Files } from "filedrop-svelte";
    import fileSize from "filesize";
    let files: Files;
</script>
<FileDrop on:filedrop={(e) => { files = e.detail.files }}>
        Upload files
</FileDrop>
{#if files}
    <h3>Accepted files</h3>
    <ul>
        {#each files.accepted as file}
            <li>{file.name} - {fileSize(file.size)}</li>
        {/each}
    </ul>
    <h3>Rejected files</h3>
    <ul>
        {#each files.rejected as rejected}
            <li>{rejected.file.name} - {rejected.error.message}</li>
        {/each}
    </ul>
{/if}
See this REPL for minimal usage.
<script>
    import { filedrop } from "filedrop-svelte";
    import type { Files, FileDropOptions } from "filedrop-svelte";
    let options: FileDropOptions = {};
    let files: Files;
</script>
<div use:filedrop={options} on:filedrop={(e) => {files = e.detail.files}}>
    <!-- you can add your input[type="file"] here if you want.
    or you can omit it and it'll be appended -->
    Drag & drop files
    {files}
</div>
| parameter | purpose | type | default | 
|---|---|---|---|
| accept | specify file types to accept. See HTML attribute: accept on MDN Web Docs for more information. | stringstring[] | undefined | 
| maxSize | the maximum size a file can be in bytes. | number | undefined | 
| minSize | the minimum size a file can be in bytes. | number | undefined | 
| fileLimit | total number of files allowed in a transaction. A value of 0 disables the action/component, 1 turns multiple off, and any other value enables multiple. Any attempt to upload more files than allowed will result in the files being placed in rejections | numer | undefined | 
| multiple | sets the file input to multiple. See HTML attribute: multiple on MDN Web Docs for more information. | boolean | true | 
| disabled | disables the action/component, removing all event listeners | boolean | false | 
| windowDrop | determines whether or not files can be dropped anywhere in the window. A value of falsewould require that the files be droppped within the<FileDrop>component or the element withuse:filedrop. | boolean | true | 
| clickToUpload | causes the containing element to be treated as the input. If hideInput is true or undefined, disabling this does not change the tabindexof the container or remove thekeydowneventListener | boolean | true | 
| tabIndex | tab index of the container. if disabledistruethen this is set to-1. IfclickToUploadistrueorundefined, this defaults to 0. | number | 0 | 
| hideInput | if true or undefined, input[type='file'] will be set to display:none | boolean | true | 
| input | allows you to explicitly pass a reference to the file HTMLInputElementas a parameter. Ifundefined, the action will search forinput[type="file"]. If one is not found, it will be appeneded to the element withuse:filedrop | HTMLInputElement | undefined | 
| event | description | event.detail | 
|---|---|---|
| filedrop | one or more files has been selected in the file dialog or drag-and-dropped | FileDropSelectEvent | 
| filedragenter | a dragenter event has occurred on the container element containnig one or more files | FileDropDragEvent | 
| filedragleave | a dragleave event has occurred on the container element containing one or more files | FileDropDragEvent | 
| filedragover | a dragover event has occurred on the container element containing one or more files | FileDropDragEvent | 
| filedialogcancel | the file dialog has been canceled without selecting files | FileDropEvent | 
| filedialogclose | the file dialog has been closed with files selected | FileDropEvent | 
| filedialogopen | the file dialog has been opened | FileDropEvent | 
| windowfiledragenter | a dragenter event has occurred on the document (event is named windowfiledragenter so not to confuse document with file) | FileDropDragEvent | 
| windowfiledragleave | a dragleave event has occurred on the document (event is named windowfiledragleave so not to confuse document with file) | FileDropDragEvent | 
| windowfiledragover | a dragover event has occurred on the document (event is named windowfiledragover so not to confuse document with file) | FileDropDragEvent | 
| class | reason | code | 
|---|---|---|
| InvalidFileTypeError | file type does not satisfy accept | InvalidFileType(0) | 
| FileCountExceededError | total number of files selected or dropped exceeds fileLimit | FileCountExceeded(1) | 
| FileSizeMinimumNotMetError | file does not satisify minSize | FileSizeMinimumNotMet(2) | 
| FileSizeMaximumExceededError | file does not satisify maxSize | FileSizeMaximumExceeded(3) | 
In order for typings to work properly, you'll need to add the following to
global.d.ts until this issue is
resolved:
declare type FileDropEvent = import("filedrop-svelte/event").FileDropEvent;
declare type FileDropSelectEvent = import("filedrop-svelte/event").FileDropSelectEvent;
declare type FileDropDragEvent = import("filedrop-svelte/event").FileDropDragEvent;
declare namespace svelte.JSX {
    interface HTMLAttributes<T> {
        onfiledrop?: (event: CustomEvent<FileDropSelectEvent> & { target: EventTarget & T }) => void;
        onfiledragenter?: (event: CustomEvent<FileDropDragEvent> & { target: EventTarget & T }) => void;
        onfiledragleave?: (event: CustomEvent<FileDropDragEvent> & { target: EventTarget & T }) => void;
        onfiledragover?: (event: CustomEvent<FileDropDragEvent> & { target: EventTarget & T }) => void;
        onfiledialogcancel?: (event: CustomEvent<FileDropEvent> & { target: EventTarget & T }) => void;
        onfiledialogclose?: (event: CustomEvent<FileDropEvent> & { target: EventTarget & T }) => void;
        onfiledialogopen?: (event: CustomEvent<FileDropEvent> & { target: EventTarget & T }) => void;
        onwindowfiledragenter?: (event: CustomEvent<FileDropDragEvent> & { target: EventTarget & T }) => void;
        onwindowfiledragleave?: (event: CustomEvent<FileDropDragEvent> & { target: EventTarget & T }) => void;
        onwindowfiledragover?: (event: CustomEvent<FileDropDragEvent> & { target: EventTarget & T }) => void;
    }
}
You may need to edit tsconfig.json to include global.d.ts if it isn't already.
MIT