2.0.0 • Published 3 months ago

@georapbox/files-dropzone-element v2.0.0

Weekly downloads
-
License
MIT
Repository
github
Last release
3 months ago

npm version npm license

<files-dropzone>

A custom element that creates a drag and drop zone for files.

Note that the element does not provide any functionality for uploading files. Once files are dropped, you are free to process them however you like.

API documentation Demo

Install

$ npm install --save @georapbox/files-dropzone-element

Usage

Script

import { FilesDropzone } from './node_modules/@georapbox/files-dropzone-element/dist/files-dropzone.js';

// Manually define the element.
FilesDropzone.defineCustomElement();

Alternatively, you can import the automatically defined custom element.

import './node_modules/@georapbox/files-dropzone-element/dist/files-dropzone-defined.js';

Markup

<files-dropzone accept="image/*,.txt,application/pdf" multiple></files-dropzone>

Style

By default, the component comes with basic styling. However, you can customise the styles of the various elements of the component using either CSS Parts or CSS Custom Properties.

API

Properties

NameReflectsTypeRequiredDefaultDescription
accept1String-nullA string containing one or more of unique file type specifiers, separated by commas. Files that do not match one of the accepted file type specifiers, will be rejected.
disabledBoolean-falseDetermines whether the dropzone is disabled. If true, the dropzone will be disabled and the user will not be able to select files.
maxFilesmax-filesNumber-InfinityMaximum accepted number of files. Note that this property has effect only when multiple is true. If its value is set to 0 or any negative number, it will allow any number of files. If the number of dropped files is greater than the value set, all of the files will be rejected to avoid making unsafe assumptions on which files to accept.
maxSizemax-sizeNumber-InfinityMaximum file size (in bytes).
minSizemin-sizeNumber-0Minimum file size (in bytes).
multipleBoolean-falseIf true, allows drag 'n' drop (or selection from the file dialog) of multiple files. If set to false and many files are dropped, all of them will be rejected to avoid making unsafe assumptions on which files to accept.
autoFocusauto-focusBoolean-falseIf true, the dropzone will be focused when the component is rendered. It has no effect if disabled property is set to true.
noStyleno-styleBoolean-falseIf true, it will remove all default styling. It can be useful in cases you want to style the component's parts from scratch. Note that the available CSS Custom Properties can still be used.

1 Each unique file type specifier may take one of the following forms:

  • A valid case-insensitive filename extension, starting with a period (".") character. For example: .jpg, .pdf, or .doc.
  • A valid MIME type string, with no extensions.
  • A string to match any file of a specific type. For example: image/* for image files, audio/* for audio files, etc.
  • Any comination of the above. For example: image/*,.docx,application/pdf

Slots

NameDescription
(default)Un-named slot to override the default content of the dropzone area.

CSS Parts

NameDescription
dropzoneThe dropzone area.
dropzone--dragoverThe state of the dropzone when dragging over it.

CSS Custom Properties

NameDescriptionDefault
--dropzone-border-widthThe border width of the dropzone area.2px
--dropzone-border-styleThe border style of the dropzone area.dashed
--dropzone-border-radiusThe border radius of the dropzone area.0.25rem
--dropzone-border-colorThe border color of the dropzone area.#6c757d
--dropzone-border-color-dragoverThe border color of the dropzone when dragging over it.#0d6efd
--dropzone-border-color-hoverThe border color of the dropzone when hovering over it.var(--dropzone-border-color-dragover)
--dropzone-background-colorThe background color of the dropzone area.#ffffff
--dropzone-background-color-dragoverThe background color of the dropzone when dragging over it.#f4f4f5
--dropzone-background-color-hoverThe background color of the dropzone when hovering over it.var(--dropzone-background-color-dragover)
--dropzone-body-colorThe text color of the dropzone area.#3f3f46
--dropzone-body-color-dragoverThe text color of the dropzone when dragging over it.var(--dropzone-body-color)
--dropzone-body-color-hoverThe text color of the dropzone when hovering over it.var(--dropzone-body-color-dragover)
--dropzone-focus-shadow-rgbThe RGB color of the dropzone area focus shadow.49, 132, 253
--dropzone-focus-box-shadowThe box shadow of the dropzone area focus.0 0 0 0.25rem rgba(var(--dropzone-focus-shadow-rgb), 0.5)
--dropzone-transition-durationThe transition's duration for the dropzone area.0.2s

Methods

NameTypeDescriptionArguments
defineCustomElementStaticDefines/registers the custom element with the name provided. If no name is provided, the default name is used. The method checks if the element is already defined, hence will skip trying to redefine it.elementName='files-dropzone'
openFileDialog1InstanceOpens the native file dialog programmatically. The method will fail silently if the dropzone is disabled. Note that most browsers require a direct user interaction with the document, to open the file dialog, for security reasons. Therefore, if you are trying to call this method asynchronously, there's a good chance it's going to be blocked by the browser. For example in Safari 15.x, invoking this method inside a setTimeout with more that 1000ms delay, the dialog will not open.-

1 Instance methods are only available after the component has been defined. To ensure the component is defined, you can use whenDefined method of the CustomElementRegistry interface, eg customElements.whenDefined('files-dropzone').then(() => { /* call methods here */ });

Events

NameDescriptionEvent Detail
files-dropzone-dropEmitted when one or more files are selected, either by using the native file dialog or dropping files in the dropzone area. The event is emitted regardless if the dropped files are accepted or rejected. Files are accepted or rejected based on the accept, max-files, max-size, min-size and multiple attributes.{acceptedFiles: Array<File>, rejectedFiles: Array<{file: File, errors: Array<{code: 'TOO_MANY_FILES' \| 'FILE_TOO_LARGE' \| FILE_TOO_SMALL \| 'INVALID_MIME_TYPE', message: string}>}>}
files-dropzone-drop-acceptedEmitted when one or more dropped files are accepted. If no files are accepted, the event is not emitted at all.{acceptedFiles: Array<File>}
files-dropzone-drop-rejectedEmitted when one or more dropped files are rejected. If no files are rejected, the event is not emitted at all.{rejectedFiles: Array<{file: File, errors: Array<{code: 'TOO_MANY_FILES' \| 'FILE_TOO_LARGE' \| FILE_TOO_SMALL \| 'INVALID_MIME_TYPE', message: string}>}>}
files-dropzone-dragenterEmitted on dragenter event. The event is not emitted if disabled attribute is set.-
files-dropzone-dragoverEmitted on dragover event. The event is not emitted if disabled attribute is set.-
files-dropzone-dragleaveEmitted on dragleave event. The event is not emitted if disabled attribute is set.-
files-dropzone-errorEmitted if there is any error in the process of reading dropped files or directories.{error: any}

Usage example

Below is a basic usage example of the custom element that also demonstrates styles customization.

<head>
  <style>
    files-dropzone {
      --dropzone-border-color: #dbdbdb;
      --dropzone-border-color-dragover: #0096bfab;
      --dropzone-background-color: #f7f7f7;
      --dropzone-background-color-dragover: #efefef;
      --dropzone-body-color: #363636;
      --dropzone-body-color-dragover: #363636;
    }

    files-dropzone::part(dropzone) {
      display: flex;
      flex-direction: column;
      gap: 0.5rem;
    }

    @media (prefers-color-scheme: dark) {
      files-dropzone {
        --dropzone-border-color: #526980;
        --dropzone-border-color-dragover: #0096bfab;
        --dropzone-background-color: #1a242f;
        --dropzone-background-color-dragover: #161f27;
        --dropzone-body-color: #dbdbdb;
        --dropzone-body-color-dragover: #dbdbdb;
      }
    }
  </style>
</head>

<body>
  <files-dropzone accept="image/png,image/jpg" multiple>
    <span>Drag 'n' drop files here, or click to select files</span>
    <small>Accepted file types: <code>png</code>, <code>jpg</code></small>
  </files-dropzone>

  <h3>Accepted files</h3>
  <ul id="accepted-files"></ul>

  <h3>Rejected files</h3>
  <ul id="rejected-files"></ul>

  <script type="module">
    import { FilesDropzone } from 'https://unpkg.com/@georapbox/files-dropzone-element';

    FilesDropzone.defineCustomElement();

    const drozone = document.querySelector('files-dropzone');
    const acceptedFilesList = document.getElementById('accepted-files');
    const rejectedFilesList = document.getElementById('rejected-files');

    dropzone.addEventListener('files-dropzone-drop', evt => {
      const { acceptedFiles, rejectedFiles } = evt.detail;

      acceptedFilesList.replaceChildren();
      rejectedFilesList.replaceChildren();

      acceptedFiles.forEach(file => {
        const li = document.createElement('li');
        li.textContent = `${file.name} - ${file.size} bytes`;
        acceptedFilesList.appendChild(li);
      });

      rejectedFiles.forEach(file => {
        const li = document.createElement('li');
        li.textContent = `${file.name} - ${file.size} bytes`;
        rejectedFilesList.appendChild(li);
      });
    });
  </script>
</body>  

Changelog

For API updates and breaking changes, check the CHANGELOG.

License

The MIT License (MIT)

2.0.0

3 months ago

1.2.0

5 months ago

1.2.1

5 months ago

1.1.1

11 months ago

1.1.0

1 year ago

1.0.0

1 year ago