Drop Zone Component

A CSS implementation of the Sprout drop zone component.

Related

Example

html
<div class="spr-drop-zone spr-drop-zone-initial">
  <img src="https://sprout-cdn.kabbage.com/components/drop-zone/folder-upload.svg" class="browse-files-icon">
  <a href="javascript:;" class="browse-files">Browse files</a>
  <span class="show-on-desktop">or drag and drop here</span>
  <div class="file-hint">
    Accepted file formats: image files, text files, PDF, DOC, DOCX. Max file size: 50 MB.
  </div>
</div>
<br><br>
<div class="spr-drop-zone spr-drop-zone-initial spr-drop-zone-hover">
  <img src="https://sprout-cdn.kabbage.com/components/drop-zone/folder-upload-hover.svg" class="browse-files-icon">
  <a href="javascript:;" class="browse-files">Browse files</a>
  <span class="show-on-desktop">or drag and drop here</span>
  <div class="file-hint">
    Accepted file formats: image files, text files, PDF, DOC, DOCX. Max file size: 50 MB.
  </div>
</div>
<br><br>
<div class="spr-drop-zone spr-drop-zone-uploaded">
  <strong>Uploaded files</strong>
  <input type="file" class="spr-drop-zone-input">
  <div class="files">
    <div class="file">
      <div class="filename-container">
        <div class="filename">kabbageDocumentsupload.pdf</div>
        <a href="javascript:;" class="show-on-mobile">Remove</a>
      </div>
      <div class="status">
         <a href="javascript:;" class="show-on-desktop">Remove</a>
         <i class="spr-icon spr-icon-check-fill status-icon success"></i>
      </div>
    </div>
    <div class="file">
      <div class="filename-container">
        <div class="filename">kabbageDocumentsupload.pdf</div>
        <a href="javascript:;" class="show-on-mobile">Remove</a>
      </div>
      <div class="status">
         <a href="javascript:;" class="show-on-desktop">Remove</a>
         <div class="spr-spinner-container status-icon">
           <svg viewBox="0 0 24 24">
             <circle class="spr-spinner" cx="12" cy="12" r="10.5" fill="none" stroke-width="3"></circle>
           </svg>
         </div>
      </div>
    </div>
    <div class="file">
      <div class="filename-container">
        <div class="filename">kabbageDocumentsupload.pdf</div>
        <a href="javascript:;" class="show-on-mobile spr-inline-sm">Retry</a>
        <a href="javascript:;" class="show-on-mobile">Remove</a>
      </div>
      <div class="status error">
         <a href="javascript:;" class="show-on-desktop spr-inline-sm">Retry</a>
         <a href="javascript:;" class="show-on-desktop">Remove</a>
         <i class="spr-icon spr-icon-alert-fill status-icon error"></i>
      </div>
    </div>
  </div>
  <div class="more-files">
    <a href="javascript:;">Add more files</a>
    <span class="show-on-desktop">or drag and drop here</span>
  </div>
  <div class="file-hint">
    Accepted file formats: image files, text files, PDF, DOC, DOCX. Max file size: 50 MB.
  </div>
</div>
<br><br>
<div class="spr-drop-zone spr-drop-zone-uploaded spr-drop-zone-hover">
  <strong>Uploaded files</strong>
  <div class="files">
    <div class="file">
      <div class="filename-container">
        <div class="filename">kabbageDocumentsupload.pdf</div>
        <a href="javascript:;" class="show-on-mobile">Remove</a>
      </div>
      <div class="status">
         <a href="javascript:;" class="show-on-desktop">Remove</a>
         <i class="spr-icon spr-icon-check-fill status-icon success"></i>
      </div>
    </div>
  </div>
  <div class="more-files">
    <a href="javascript:;">Add more files</a>
    <span class="show-on-desktop">or drag and drop here</span>
  </div>
  <div class="file-hint">
    Accepted file formats: image files, text files, PDF, DOC, DOCX. Max file size: 50 MB.
  </div>
</div>

Compiled CSS

Example

scss
@import 'components/drop-zone';
css compiled
@keyframes openPopover {
  from {
    transform: scale(0.9);
  }
  to {
    transform: scale(1);
  }
}

.spr-icon-rotate-90 {
  transform: rotate(90deg);
}

.spr-icon-rotate-180 {
  transform: rotate(180deg);
}

.spr-icon-rotate-270 {
  transform: rotate(270deg);
}

.spr-drop-zone {
  max-width: 42rem;
  border-radius: 0.25rem;
  background-color: #fff;
  padding: 1.5rem 1rem 1rem 1rem;
  background-image: url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' rx='4' ry='4' stroke='%23bbbdc4' stroke-width='2' stroke-dasharray='1%2c 7' stroke-dashoffset='0' stroke-linecap='square'/%3e%3c/svg%3e");
  font-family: "AvenirNext", "Helvetica Neue", Arial, sans-serif;
  font-size: 16px;
  line-height: 1.375rem;
  letter-spacing: 0;
  font-weight: 400;
}

@media only screen and (min-width: 37.5rem) {
  .spr-drop-zone {
    padding: 1.5rem 1.5rem;
  }
}

.spr-drop-zone-hover {
  background-image: url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' rx='4' ry='4' stroke='%2320883a' stroke-width='4' stroke-dasharray='1%2c 7' stroke-dashoffset='0' stroke-linecap='square'/%3e%3c/svg%3e");
}

.spr-drop-zone-initial {
  display: flex;
  align-items: center;
  flex-direction: column;
  text-align: center;
  padding: 2rem 2rem;
}

.spr-drop-zone-initial .browse-files-icon {
  width: 2.875rem;
  height: 2.5rem;
  cursor: pointer;
}

.spr-drop-zone-initial .browse-files {
  padding: 0.75rem 0 0.25rem;
}

.spr-drop-zone-uploaded .files {
  padding: 0.5rem 0 1rem;
}

.spr-drop-zone-uploaded .files .file {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  padding: 0.75rem 0rem;
  box-shadow: 0 1px 0 0 #e4e5e7;
}

.spr-drop-zone-uploaded .files .file > :not(:last-child) {
  margin-right: 0rem;
}

.spr-drop-zone-uploaded .files .file .filename-container,
.spr-drop-zone-uploaded .files .file .filename {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.spr-drop-zone-uploaded .files .file .status {
  padding-left: 0.5rem;
}

@media only screen and (min-width: 37.5rem) {
  .spr-drop-zone-uploaded .files .file .status {
    min-width: 7rem;
    text-align: right;
  }
  .spr-drop-zone-uploaded .files .file .status.error {
    min-width: 10rem;
  }
}

@media only screen and (min-width: 37.5rem) {
  .spr-drop-zone-uploaded .files .file .status .show-on-desktop {
    vertical-align: middle;
  }
}

.spr-drop-zone-uploaded .files .file .status-icon {
  margin-left: 1rem;
}

.spr-drop-zone-uploaded .files .file .status-icon.success {
  background-color: #20883a;
}

.spr-drop-zone-uploaded .files .file .status-icon.error {
  background-color: #dd1d33;
}

.spr-drop-zone-uploaded .more-files {
  text-align: center;
}

.spr-drop-zone .spr-drop-zone-input {
  position: absolute;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  width: 0.0625rem;
  height: 0.0625rem;
  margin: -0.0625rem;
  padding: 0;
  border: 0;
}

.spr-drop-zone .file-hint {
  padding-top: 0.25rem;
  text-align: center;
  color: #6b6f7b;
  font-family: "AvenirNext", "Helvetica Neue", Arial, sans-serif;
  font-size: 0.875rem;
  line-height: 1.25rem;
  letter-spacing: 0;
  font-weight: 400;
}

.spr-drop-zone .show-on-desktop {
  display: none;
}

@media only screen and (min-width: 37.5rem) {
  .spr-drop-zone .show-on-desktop {
    display: inline;
  }
}

.spr-drop-zone .show-on-mobile {
  display: inline;
}

@media only screen and (min-width: 37.5rem) {
  .spr-drop-zone .show-on-mobile {
    display: none;
  }
}

.spr-drop-zone .spr-helper-text-error {
  margin-top: 0.5rem;
}

.spr-drop-zone a {
  color: #056ad7;
  text-decoration: none;
  font-weight: 600;
  cursor: pointer;
  transition-property: color;
  transition-duration: 0.11s;
  transition-timing-function: ease-in-out;
}

.spr-drop-zone a:focus:not(:focus-visible) {
  outline: none;
}

.spr-drop-zone a:focus-visible {
  outline: 5px auto Highlight;
  outline: 5px auto -webkit-focus-ring-color;
}

.spr-drop-zone a:hover {
  text-decoration: underline;
  color: #033e7d;
}