Skip to content

File Upload13.10.5

> Don't you worry about a thing!™


$ npm i @if-design-system/file-upload@13.10.5

  1. Image from iOS.jpg53.65KB
Edit this section

Overview

A file-upload component enables users to upload files to your service.

Edit this section

Variations

Type Purpose
Input Upload one or more files by using an input field.
Button Upload one or more files by clicking an action button that prompts a file selection dialog.
Drag and drop Drag and drop selected files directly into a drop zone area to upload.
Edit this section

Input

A file picker lets people browse files from device storage to choose a file or files to upload them to our products.

Usage

  1. Image from iOS.jpg 53.65KB

Sizing

The input file-upload follows the same standard in sizing as the input field component.

input[type="file"].if
  & ~ button.if.file-upload
    width 100%
    +IDS_BREAKPOINT_MQ_Smaller_Min()
      width calc((( 100% - (40px * 11) ) / 12 ) * 4 + 120px)
    +IDS_BREAKPOINT_MQ_Medium_Min()
      width 296px
    +IDS_BREAKPOINT_MQ_Large_Min()
      width 312px
    +IDS_BREAKPOINT_MQ_ExtraLarge_Min()
      width 360px
    +IDS_BREAKPOINT_MQ_Xxl_Min()
      width 400px

  &[data-size="largest"]
    & ~ button.if.file-upload
      width 100%
      +IDS_BREAKPOINT_MQ_Smaller_Min()
        width calc((( 100% - (40px * 11) ) / 12 ) * 7 + 240px)
      +IDS_BREAKPOINT_MQ_Medium_Min()
        width 548px
      +IDS_BREAKPOINT_MQ_Large_Min()
        width 576px
      +IDS_BREAKPOINT_MQ_ExtraLarge_Min()
        width 660px
      +IDS_BREAKPOINT_MQ_Xxl_Min()
        width 730px

  &[data-size="larger"]
    & ~ button.if.file-upload
      width 100%
      +IDS_BREAKPOINT_MQ_Smaller_Min()
        width calc((( 100% - (40px * 11) ) / 12 ) * 6 + 200px)
      +IDS_BREAKPOINT_MQ_Medium_Min()
        width 464px
      +IDS_BREAKPOINT_MQ_Large_Min()
        width 488px
      +IDS_BREAKPOINT_MQ_ExtraLarge_Min()
        width 560px
      +IDS_BREAKPOINT_MQ_Xxl_Min()
        width 620px

  &[]
    & ~ button.if.file-upload
      +IDS_BREAKPOINT_MQ_Smaller_Min()
        width calc((( 100% - (40px * 11) ) / 12 ) * 5 + 160px)
      +IDS_BREAKPOINT_MQ_Medium_Min()
        width 380px
      +IDS_BREAKPOINT_MQ_Large_Min()
        width 400px
      +IDS_BREAKPOINT_MQ_ExtraLarge_Min()
        width 460px
      +IDS_BREAKPOINT_MQ_Xxl_Min()
        width 510px

  &[data-size="medium"]
    & ~ button.if.file-upload
      width 100%
      +IDS_BREAKPOINT_MQ_Smaller_Min()
        width calc((( 100% - (40px * 11) ) / 12 ) * 4 + 120px)
      +IDS_BREAKPOINT_MQ_Medium_Min()
        width 296px
      +IDS_BREAKPOINT_MQ_Large_Min()
        width 312px
      +IDS_BREAKPOINT_MQ_ExtraLarge_Min()
        width 360px
      +IDS_BREAKPOINT_MQ_Xxl_Min()
        width 400px

  &[data-size="small"]
    & ~ button.if.file-upload
      width 100%
      +IDS_BREAKPOINT_MQ_Smaller_Min()
        width calc((( 100% - (40px * 11) ) / 12 ) * 3 + 80px)
      +IDS_BREAKPOINT_MQ_Medium_Min()
        width 212px
      +IDS_BREAKPOINT_MQ_Large_Min()
        width 224px
      +IDS_BREAKPOINT_MQ_ExtraLarge_Min()
        width 260px
      +IDS_BREAKPOINT_MQ_Xxl_Min()
        width 290px

  &[data-size="smaller"]
    & ~ button.if.file-upload
      width 100%
      +IDS_BREAKPOINT_MQ_Smaller_Min()
        width calc((( 100% - (40px * 11) ) / 12 ) * 2 + 40px)
      +IDS_BREAKPOINT_MQ_Medium_Min()
        width 128px
      +IDS_BREAKPOINT_MQ_Large_Min()
        width 136px
      +IDS_BREAKPOINT_MQ_ExtraLarge_Min()
        width 160px
      +IDS_BREAKPOINT_MQ_Xxl_Min()
        width 180px

  &[data-size="smallest"]
    & ~ button.if.file-upload
      width 100%
      +IDS_BREAKPOINT_MQ_Smaller_Min()
        width calc((( 100% - (40px * 11) ) / 12 ) * 2 + 40px)
      +IDS_BREAKPOINT_MQ_Medium_Min()
        width 44px
      +IDS_BREAKPOINT_MQ_Large_Min()
        width 48px
      +IDS_BREAKPOINT_MQ_ExtraLarge_Min()
        width 60px
      +IDS_BREAKPOINT_MQ_Xxl_Min()
        width 180px

Behaviours

Interactions

Focus
Static
Complete
  1. Profile-photo.jpg 2.45MB

Modifiers

Disabled
Invalid
  1. Image from iOS.jpg File format not supported

Anatomy

  1. Image from iOS.jpg 53.65KB
  2. Image from iOS.jpg 53.65KB
Input file upload
  1. Label
  2. Input element
  3. List of files to upload

Specs

  1. Image from iOS.jpg 53.65KB

Implementation

<form autocomplete="off">
  <div class="if input-wrapper">
    <input type="file" class="if" accept="image/*" id="if-file-upload-1" placeholder="Välj bild at bifoga" />
    <label for="if-file-upload-1">Bifoga bild</label>
    <button aria-hidden="true" type="button" class="if file-upload">Välj bild at bifoga</button>
  </div>
</form>
Edit this section

Button

A file picker lets people browse files from device storage to choose a file or files to upload them to our products.

The main difference between this version and input is that the file upload component is styled like a button.

Anatomy

  1. Image from iOS.jpg 53.65KB
  2. Image from iOS.jpg 53.65KB
Button file upload
  1. A secondary button
  2. An icon representing the type of file to upload
  3. List of files to upload

Specs

  1. Image from iOS.jpg 53.65KB

Implementation

<form autocomplete="off">
  <div class="if input-wrapper">
    <input
      data-size="larger"
      type="file"
      class="if file-upload"
      accept=".doc,.docx,.xml,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document"
      id="if-file-upload-2"
      placeholder="Please upload your CV"
    />
    <label for="if-file-upload-2" class="if button secondary">
      <span class="if icon ui data-upload blue"></span>Upload your CV
    </label>
  </div>
</form>
Edit this section

Drag and drop

A drag-and-drop file upload lets people drag a file or files from their device to an area of the interface (a "drop zone") to upload them to your service.

Behaviours

Interactions

Focus

Modifiers

Static
Complete
<div class="if input-wrapper is-dragover">
  <input
    data-size="large"
    type="file"
    class="if drag-drop"
    multiple=""
    id="if-file-upload-7"
    placeholder="Drop files here to upload"
  />
  <label for="if-file-upload-7">When you drag files over</label>
  <button aria-hidden="true" type="button" class="if file-upload">
    <svg
      xmlns="http://www.w3.org/2000/svg"
      class="if loader dots horizontal small"
      viewBox="0 0 64 64"
      width="32"
      height="32"
    >
      <circle cx="8" cy="32" r="8" fill="#0054f0"></circle>
      <circle cx="32" cy="32" r="8" fill="#0054f0"></circle>
      <circle cx="56" cy="32" r="8" fill="#0054f0"></circle>
      <style>
        .if.loader.dots.horizontal circle {
          transform: scale(0);
          animation: ifAnimationLoaderHorizontal 1.15s infinite ease-in-out;
          transform-origin: 56px 32px;
        }
        .if.loader.dots.horizontal circle:nth-child(1) {
          animation-delay: -0.32s;
          transform-origin: 8px 32px;
        }
        .if.loader.dots.horizontal circle:nth-child(2) {
          animation-delay: -0.16s;
          transform-origin: 32px 32px;
        }
        @-moz-keyframes ifAnimationLoaderHorizontal {
          0%,
          80%,
          100% {
            transform: scale(0);
          }
          40% {
            transform: scale(1);
          }
        }
        @-webkit-keyframes ifAnimationLoaderHorizontal {
          0%,
          80%,
          100% {
            transform: scale(0);
          }
          40% {
            transform: scale(1);
          }
        }
        @-o-keyframes ifAnimationLoaderHorizontal {
          0%,
          80%,
          100% {
            transform: scale(0);
          }
          40% {
            transform: scale(1);
          }
        }
        @keyframes ifAnimationLoaderHorizontal {
          0%,
          80%,
          100% {
            transform: scale(0);
          }
          40% {
            transform: scale(1);
          }
        }
      </style>
    </svg>
    <svg class="if icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
      <title>data upload</title>
      <g
        class="if animate bounce"
        class="nc-icon-wrapper"
        stroke-linecap="square"
        stroke-linejoin="miter"
        stroke-width="1.5"
        fill="#6e625e"
        stroke="#6e625e"
      >
        <line
          data-cap="butt"
          data-color="color-2"
          x1="16"
          y1="24"
          x2="16"
          y2="2"
          fill="none"
          stroke-miterlimit="10"
          stroke-linecap="butt"
        />
        <polyline data-color="color-2" points="24 10 16 2 8 10" fill="none" stroke-miterlimit="10" />
      </g>
      <g
        class="nc-icon-wrapper"
        stroke-linecap="square"
        stroke-linejoin="miter"
        stroke-width="1.5"
        fill="#6e625e"
        stroke="#6e625e"
      >
        <polyline points="2 23 2 30 30 30 30 23" fill="none" stroke="#6e625e" stroke-miterlimit="10" />
      </g>
    </svg>
    <span class="if">
      Drop files here to upload
      <br />
      <span class="if fake-link text-meta">Or select files to upload</span>
    </span>
  </button>
</div>
<div class="if input-wrapper is-loading">
  <input
    data-size="large"
    type="file"
    class="if drag-drop"
    multiple=""
    id="if-file-upload-8"
    placeholder="Drop files here to upload"
  />
  <label for="if-file-upload-8">When it is uploading</label>
  <button aria-hidden="true" type="button" class="if file-upload">
    <svg
      xmlns="http://www.w3.org/2000/svg"
      class="if loader dots horizontal small"
      viewBox="0 0 64 64"
      width="32"
      height="32"
    >
      <circle cx="8" cy="32" r="8" fill="#0054f0"></circle>
      <circle cx="32" cy="32" r="8" fill="#0054f0"></circle>
      <circle cx="56" cy="32" r="8" fill="#0054f0"></circle>
      <style>
        .if.loader.dots.horizontal circle {
          transform: scale(0);
          animation: ifAnimationLoaderHorizontal 1.15s infinite ease-in-out;
          transform-origin: 56px 32px;
        }
        .if.loader.dots.horizontal circle:nth-child(1) {
          animation-delay: -0.32s;
          transform-origin: 8px 32px;
        }
        .if.loader.dots.horizontal circle:nth-child(2) {
          animation-delay: -0.16s;
          transform-origin: 32px 32px;
        }
        @-moz-keyframes ifAnimationLoaderHorizontal {
          0%,
          80%,
          100% {
            transform: scale(0);
          }
          40% {
            transform: scale(1);
          }
        }
        @-webkit-keyframes ifAnimationLoaderHorizontal {
          0%,
          80%,
          100% {
            transform: scale(0);
          }
          40% {
            transform: scale(1);
          }
        }
        @-o-keyframes ifAnimationLoaderHorizontal {
          0%,
          80%,
          100% {
            transform: scale(0);
          }
          40% {
            transform: scale(1);
          }
        }
        @keyframes ifAnimationLoaderHorizontal {
          0%,
          80%,
          100% {
            transform: scale(0);
          }
          40% {
            transform: scale(1);
          }
        }
      </style>
    </svg>
    <svg class="if icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
      <title>data upload</title>
      <g
        class="if animate bounce"
        class="nc-icon-wrapper"
        stroke-linecap="square"
        stroke-linejoin="miter"
        stroke-width="1.5"
        fill="#6e625e"
        stroke="#6e625e"
      >
        <line
          data-cap="butt"
          data-color="color-2"
          x1="16"
          y1="24"
          x2="16"
          y2="2"
          fill="none"
          stroke-miterlimit="10"
          stroke-linecap="butt"
        />
        <polyline data-color="color-2" points="24 10 16 2 8 10" fill="none" stroke-miterlimit="10" />
      </g>
      <g
        class="nc-icon-wrapper"
        stroke-linecap="square"
        stroke-linejoin="miter"
        stroke-width="1.5"
        fill="#6e625e"
        stroke="#6e625e"
      >
        <polyline points="2 23 2 30 30 30 30 23" fill="none" stroke="#6e625e" stroke-miterlimit="10" />
      </g>
    </svg>
    <span class="if">
      Drop files here to upload
      <br />
      <span class="if fake-link text-meta">Or select files to upload</span>
    </span>
  </button>
</div>

Anatomy

  1. Image from iOS.jpg 53.65KB
  2. Image from iOS.jpg 53.65KB
Drag and drop
  1. Label
  2. Listof files to upload
  3. Filename
  4. Filesize
  5. Action for file

Specs

  1. Image from iOS.jpg 53.65KB

Implementation

<form autocomplete="off">
  <div class="if input-wrapper">
    <input
      data-size="large"
      type="file"
      class="if drag-drop"
      multiple=""
      id="if-file-upload-anatomy-6"
      placeholder="Drop files here to upload"
    />
    <label for="if-file-upload-anatomy-6">Upload file</label>
    <button aria-hidden="true" type="button" class="if file-upload">
      <svg
        xmlns="http://www.w3.org/2000/svg"
        class="if loader dots horizontal small"
        viewBox="0 0 64 64"
        width="32"
        height="32"
      >
        <circle cx="8" cy="32" r="8" fill="#0054f0"></circle>
        <circle cx="32" cy="32" r="8" fill="#0054f0"></circle>
        <circle cx="56" cy="32" r="8" fill="#0054f0"></circle>
        <style>
          .if.loader.dots.horizontal circle {
            transform: scale(0);
            animation: ifAnimationLoaderHorizontal 1.15s infinite ease-in-out;
            transform-origin: 56px 32px;
          }
          .if.loader.dots.horizontal circle:nth-child(1) {
            animation-delay: -0.32s;
            transform-origin: 8px 32px;
          }
          .if.loader.dots.horizontal circle:nth-child(2) {
            animation-delay: -0.16s;
            transform-origin: 32px 32px;
          }
          @-moz-keyframes ifAnimationLoaderHorizontal {
            0%,
            80%,
            100% {
              transform: scale(0);
            }
            40% {
              transform: scale(1);
            }
          }
          @-webkit-keyframes ifAnimationLoaderHorizontal {
            0%,
            80%,
            100% {
              transform: scale(0);
            }
            40% {
              transform: scale(1);
            }
          }
          @-o-keyframes ifAnimationLoaderHorizontal {
            0%,
            80%,
            100% {
              transform: scale(0);
            }
            40% {
              transform: scale(1);
            }
          }
          @keyframes ifAnimationLoaderHorizontal {
            0%,
            80%,
            100% {
              transform: scale(0);
            }
            40% {
              transform: scale(1);
            }
          }
        </style>
      </svg>
      <svg class="if icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"></svg>
      <span class="if">
        Drop files here to upload
        <br />
        <span class="if fake-link text-meta">Or select files to upload</span>
      </span>
    </button>
    <div class="if uploaded-files"></div>
  </div>
</form>
Edit this section

File list

The file list contains these elements:

  1. A file feedback (size or error message)
  2. A file icon
  3. An action
  4. A file name
  1. Image from iOS.jpg Upload error
  2. Image from iOS.jpg File format not supported
  3. A very long image name that is truncated.png 53.65KB
  4. profile.png 53.65KB
  5. Image from iOS.jpg 53.65KB
  6. CV.pdf 83.31KB
  7. Profile-photo.jpg 2.45MB
File list
  1. File feedback
  2. File icon
  3. File name
  4. File action
<div class="if uploaded-files">
  <ol class="if">
    <li class="if error">
      <span class="if file-name ui icon symbol image" title="Image from iOS.jpg">Image from iOS.jpg</span>
      <span class="if file-feedback">Upload error</span>
      <button type="button" class="if file-action refresh">Try again</button>
    </li>
    <li class="if error">
      <span class="if file-name ui icon symbol image" title="Image from iOS.jpg">Image from iOS.jpg</span>
      <span class="if file-feedback">File format not supported</span>
    </li>
    <li class="if">
      <span class="if file-name ui icon symbol image" title="A very long image name that is truncated.png">
        A very long image name that is truncated.png
      </span>
      <span class="if file-feedback">53.65<abbr title="Kilobytes">KB</abbr></span>
      <button type="button" class="if file-action load">
        <svg class="if loader dots horizontal" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
          <g class="if svg g">
            <circle class="if svg circle" fill="#0054f0" cx="8" cy="32" r="6" />
            <circle class="if svg circle" fill="#0054f0" cx="32" cy="32" r="6" />
            <circle class="if svg circle" fill="#0054f0" cx="56" cy="32" r="6" />
          </g>
        </svg>
      </button>
    </li>
    <li class="if">
      <span class="if file-name ui icon symbol image" title="Image from iOS.jpg">Image from iOS.jpg</span>
      <span class="if file-feedback">53.65<abbr title="Kilobytes">KB</abbr></span>
      <button type="button" class="if file-action delete"></button>
    </li>
    <li class="if">
      <span class="if file-name ui icon symbol document" title="CV.pdf">CV.pdf</span>
      <span class="if file-feedback">83.31<abbr title="Kilobytes">KB</abbr></span>
      <button type="button" class="if file-action delete"></button>
    </li>
    <li class="if">
      <span class="if file-name ui icon symbol image" title="Profile-photo.jpg">Profile-photo.jpg</span>
      <span class="if file-feedback">2.45<abbr title="Megabytes">MB</abbr></span>
      <button type="button" class="if file-action delete"></button>
    </li>
  </ol>
</div>

File icon

Use an icon that fits the file that is to be uploaded. You match the mime-type and or file extension in your JavaScript to display correct icon.

<li class="if">
  <span class="if file-name [ui icon symbol image]" title="Profile-photo.jpg">Profile-photo.jpg</span>
  <span class="if file-feedback">2.45<abbr title="Megabytes">MB</abbr></span>
  <button type="button" class="if file-action delete"></button>
</li>

File name

The name of the file to be uploaded. If the file name is too long, it is truncated with ellipsis. Users can hover over the file name to get the full name.

<li class="if">
  <span class="if file-name ui icon symbol image" title="Profile-photo.jpg">Profile-photo.jpg</span>
  <span class="if file-feedback">2.45<abbr title="Megabytes">MB</abbr></span>
  <button type="button" class="if file-action delete"></button>
</li>

File feedback

The feedback text usually contains the file size. If there's an error, you can display an error text there.

<li class="if">
  <span class="if file-name ui icon symbol image" title="Profile-photo.jpg">Profile-photo.jpg</span>
  <span class="if file-feedback">2.45<abbr title="Megabytes">MB</abbr></span>
  <button type="button" class="if file-action delete"></button>
</li>
<li class="if error">
  <span class="if file-name ui icon symbol image" title="Profile-photo.jpg">Profile-photo.jpg</span>
  <span class="if file-feedback">File format not supported</span>
</li>

File action

The file action depicts the current action that's available for the file that is uploading or is to be uploaded.

Delete

If there applies a feature to delete specific files before upload, or after a file is uploaded, you can use this icon and relevant action to delete the file.

Load

When an image is uploaded, for example on the change-event, use the loader as the action.

Success

When a file has successfully been uploaded. The check mark should only be visible for 1-2 seconds, before turning back to a cross (the delete action).

Refresh

If something went wrong with the upload, use the refresh icon and relevant action.

  1. Image from iOS.jpg 53.65KB
  2. Image from iOS.jpg 53.65KB
  3. Image from iOS.jpg 53.65KB
  4. Image from iOS.jpg Upload failed
<li class="if">
  <span class="if file-name ui icon symbol image" title="Profile-photo.jpg">Profile-photo.jpg</span>
  <span class="if file-feedback">2.45<abbr title="Megabytes">MB</abbr></span>
  <button type="button" class="if file-action [delete|refresh|success]"></button>
</li>
<li class="if">
  <span class="if file-name ui icon symbol image" title="Profile-photo.jpg">Profile-photo.jpg</span>
  <span class="if file-feedback">2.45<abbr title="Megabytes">MB</abbr></span>
  <button type="button" class="if file-action load">
    <svg class="if loader dots horizontal" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
      <g class="if svg g">
        <circle class="if svg circle" fill="#0054f0" cx="8" cy="32" r="6" />
        <circle class="if svg circle" fill="#0054f0" cx="32" cy="32" r="6" />
        <circle class="if svg circle" fill="#0054f0" cx="56" cy="32" r="6" />
      </g>
    </svg>
  </button>
</li>

Error

If there's an error, you can display that text in the feedback element, but remember to use the .if.error on the list-element.

<li class="if error">
  <span class="if file-name ui icon symbol image" title="Profile-photo.jpg">Profile-photo.jpg</span>
  <span class="if file-feedback">File upload failed</span>
  <button type="button" class="if file-action refresh">Try again</button>
</li>

Implementation

Regarding removal of files when selecting multiple

There is no direct way of removing one element or more from the list of files to be uploaded. You can however remove all by reselecting the desired files.

But, you can do it the hard way:

  1. Copy the FileList object into an array
  2. Remove element from the copied array
  3. When uploading via AJAX (only known way so far), only pass the desired files
Edit this section

Implementation

JavaScript implementation example

import { getSize, getSizeName, getSizeFullName } from './helper-file';
import tooltip from './tooltip';

const createFileListItem = (file, input) => {
  const listItemContainer = document.createElement('li');
  listItemContainer.classList.add('if');

  const fileNameElement = document.createElement('span');
  fileNameElement.classList.add('if');
  fileNameElement.classList.add('file-name');
  fileNameElement.classList.add('ui');
  fileNameElement.classList.add('icon');
  fileNameElement.classList.add('symbol');

  if (input.accept.indexOf('image') !== -1) {
    fileNameElement.classList.add('image');
  } else {
    fileNameElement.classList.add('document');
  }

  fileNameElement.setAttribute('title', file.name);

  const fileFeedbackElement = document.createElement('span');
  fileFeedbackElement.classList.add('if');
  fileFeedbackElement.classList.add('file-feedback');

  const fileAction = document.createElement('button');
  fileAction.setAttribute('type', 'button');
  fileAction.classList.add('if');
  fileAction.classList.add('file-action');
  fileAction.classList.add('delete');

  const fileSize = document.createElement('abbr');
  fileSize.setAttribute('title', getSizeFullName(file.size));

  const fileNameText = document.createTextNode(file.name);
  const fileFeedbackText = document.createTextNode(getSize(file.size));
  const fileSizeText = document.createTextNode(getSizeName(file.size));

  fileNameElement.appendChild(fileNameText);
  fileFeedbackElement.appendChild(fileFeedbackText);
  fileSize.appendChild(fileSizeText);
  fileFeedbackElement.appendChild(fileSize);

  listItemContainer.appendChild(fileNameElement);
  listItemContainer.appendChild(fileFeedbackElement);
  listItemContainer.appendChild(fileAction);

  return listItemContainer;
};

const createFileList = (input, files) => {
  if (!files.length) return;
  const container = document.createElement('div');
  container.classList.add('if');
  container.classList.add('uploaded-files');
  const list = document.createElement('ol');
  list.classList.add('if');

  Array.from(files).forEach(file => {
    list.appendChild(createFileListItem(file, input));
  });

  container.appendChild(list);

  return container;
};
const fileInputs = document.querySelectorAll('input[type="file"].if');
fileInputs.forEach(input => {
  input.addEventListener('change', () => {
    const fileUpload = input.parentElement.querySelector('.if.uploaded-files');
    if (fileUpload) {
      input.parentElement.removeChild(fileUpload);
    }
    input.parentElement.appendChild(createFileList(input, input.files));

    tooltip();
  });
});

const prevent = e => {
  e.preventDefault();
  e.stopPropagation();
};

const addDragOverClass = inputContainer => {
  inputContainer.classList.add('is-dragover');
};

const removeDragOverClass = inputContainer => {
  inputContainer.classList.remove('is-dragover');
};

const setDroppedFiles = (e, input) => {
  const files = e.dataTransfer.files;

  const fileUpload = input.parentElement.querySelector('.if.uploaded-files');
  if (fileUpload) {
    input.parentElement.removeChild(fileUpload);
  }
  input.parentElement.appendChild(createFileList(input, files));

  tooltip();
};

const init = () => {
  const fileDragNDropInputs = document.querySelectorAll('input[type=file].if.drag-drop');

  fileDragNDropInputs.forEach(input => {
    const form = input.closest('form');
    if (form) {
      form.addEventListener('drag', prevent);
      form.addEventListener('dragstart', prevent);
      form.addEventListener('dragend', prevent);
      form.addEventListener('dragover', prevent);
      form.addEventListener('dragenter', prevent);
      form.addEventListener('dragleave', prevent);
      form.addEventListener('drop', prevent);
    }
  });

  fileDragNDropInputs.forEach(input => {
    const inputContainer = input.parentElement;

    inputContainer.addEventListener('drag', prevent);
    inputContainer.addEventListener('dragstart', prevent);
    inputContainer.addEventListener('dragend', prevent);
    inputContainer.addEventListener('dragover', prevent);
    inputContainer.addEventListener('dragenter', prevent);
    inputContainer.addEventListener('dragleave', prevent);
    inputContainer.addEventListener('drop', prevent);

    inputContainer.addEventListener('dragover', () => {
      addDragOverClass(inputContainer);
    });
    inputContainer.addEventListener('dragenter', () => {
      addDragOverClass(inputContainer);
    });

    inputContainer.addEventListener('dragleave', () => {
      removeDragOverClass(inputContainer);
    });
    inputContainer.addEventListener('dragend', () => {
      removeDragOverClass(inputContainer);
    });
    inputContainer.addEventListener('drop', () => {
      removeDragOverClass(inputContainer);
    });
    inputContainer.addEventListener('drop', e => {
      setDroppedFiles(e, input);
    });
  });
};

export default init;
Edit this section

Contact us