Преглед изворни кода

merging Dashboard --> Modal

Artur Paikin пре 8 година
родитељ
комит
c6da666266

+ 5 - 3
example/main.js

@@ -1,13 +1,15 @@
 import Uppy from '../src/core/Core.js'
-import Modal from '../src/plugins/Modal'
-import Dashboard from '../src/plugins/dashboard'
+import Modal from '../src/plugins/modal'
+// import Dashboard from '../src/plugins/dashboard'
 import Dummy from '../src/plugins/Dummy'
+import DragDrop from '../src/plugins/DragDrop'
 import ProgressBar from '../src/plugins/ProgressBar'
 import Tus10 from '../src/plugins/Tus10'
 
 const uppy = new Uppy({debug: true})
   .use(Modal, {trigger: '#uppyModalOpener'})
-  .use(Dashboard, {target: Modal})
+  // .use(Dashboard, {target: Modal})
+  .use(DragDrop, {target: Modal})
   .use(Dummy, {target: Modal})
   .use(ProgressBar, {target: Modal})
   .use(Tus10, {endpoint: 'http://master.tus.io:8080/files/'})

+ 35 - 0
src/plugins/modal/Dashboard.js

@@ -0,0 +1,35 @@
+import html from 'yo-yo'
+import FileItem from './FileItem'
+import { uploadIcon } from './icons'
+
+function Dashboard (files, bus, autoProceed) {
+  const next = (ev) => {
+    bus.emit('next')
+  }
+
+  const selectedFiles = Object.keys(files).filter((file) => {
+    return files[file].progress !== 100
+  })
+  const selectedFileCount = Object.keys(selectedFiles).length
+  const isSomethingSelected = selectedFileCount > 0
+
+  return html`<div class="UppyDashboard">
+    <h3 class="UppyDashboard-title">Drag files here or select from</h3>
+    <ul class="UppyDashboard-list">
+      ${Object.keys(files).map((fileID) => {
+        return FileItem(bus, files[fileID])
+      })}
+    </ul>
+    ${!autoProceed && isSomethingSelected
+      ? html`<button class="UppyDashboard-upload"
+                     type="button"
+                     onclick=${next}>
+                ${uploadIcon()}
+                <sup class="UppyDashboard-uploadCount">${selectedFileCount}</sup>
+             </button>`
+      : null
+    }
+  </div>`
+}
+
+export default Dashboard

+ 0 - 0
src/plugins/dashboard/fileItem.js → src/plugins/modal/FileItem.js


+ 0 - 0
src/plugins/dashboard/index.js → src/plugins/modal/_dashboard.js


+ 17 - 10
src/plugins/dashboard/icons.js → src/plugins/modal/icons.js

@@ -2,10 +2,24 @@ import html from 'yo-yo'
 
 // https://css-tricks.com/creating-svg-icon-system-react/
 
-export const pluginIcon = html`<svg width="16px" height="16px" viewBox="0 0 32 30" class="UppyModalTab-icon">
-    <path d="M6.6209894,11.1451162 C6.6823051,11.2751669 6.81374248,11.3572188 6.95463813,11.3572188 L12.6925482,11.3572188 L12.6925482,16.0630427 C12.6925482,17.880509 14.1726048,18.75 16.0000083,18.75 C17.8261072,18.75 19.3074684,17.8801847 19.3074684,16.0630427 L19.3074684,11.3572188 L25.0437478,11.3572188 C25.1875787,11.3572188 25.3164069,11.2751669 25.3790272,11.1451162 C25.4370814,11.0173358 25.4171865,10.8642587 25.3252129,10.7562615 L16.278212,0.127131837 C16.2093949,0.0463771751 16.1069846,0 15.9996822,0 C15.8910751,0 15.7886648,0.0463771751 15.718217,0.127131837 L6.6761083,10.7559371 C6.58250402,10.8642587 6.56293518,11.0173358 6.6209894,11.1451162 L6.6209894,11.1451162 Z"/>
-    <path d="M28.8008722,6.11142645 C28.5417891,5.19831555 28.1583331,4.6875 27.3684848,4.6875 L21.6124454,4.6875 L22.8190234,6.10307874 L27.4986725,6.10307874 L29.9195817,19.3486449 L21.3943891,19.3502502 L21.3943891,22.622552 L10.8023461,22.622552 L10.8023461,19.3524977 L2.07815702,19.3534609 L5.22979699,6.10307874 L9.17871529,6.10307874 L10.3840011,4.6875 L4.6308691,4.6875 C3.83940559,4.6875 3.37421888,5.2390909 3.19815864,6.11142645 L0,19.7470874 L0,28.2212959 C0,29.2043992 0.801477937,30 1.78870751,30 L30.2096773,30 C31.198199,30 32,29.2043992 32,28.2212959 L32,19.7470874 L28.8008722,6.11142645 L28.8008722,6.11142645 Z"/>
+export function defaultTabIcon () {
+  return html`<svg class="UppyIcon UppyModalTab-icon" width="28" height="28" viewBox="0 0 101 58">
+      <path d="M17.582.3L.915 41.713l32.94 13.295L17.582.3zm83.333 41.414L67.975 55.01 84.25.3l16.665 41.414zm-48.998 5.403L63.443 35.59H38.386l11.527 11.526v5.905l-3.063 3.32 1.474 1.36 2.59-2.806 2.59 2.807 1.475-1.357-3.064-3.32v-5.906zm16.06-26.702c-3.973 0-7.194-3.22-7.194-7.193 0-3.973 3.222-7.193 7.193-7.193 3.974 0 7.193 3.22 7.193 7.19 0 3.974-3.22 7.194-7.195 7.194zM70.48 8.682c-.737 0-1.336.6-1.336 1.337 0 .736.6 1.335 1.337 1.335.738 0 1.338-.598 1.338-1.336 0-.74-.6-1.338-1.338-1.338zM33.855 20.415c-3.973 0-7.193-3.22-7.193-7.193 0-3.973 3.22-7.193 7.195-7.193 3.973 0 7.192 3.22 7.192 7.19 0 3.974-3.22 7.194-7.192 7.194zM36.36 8.682c-.737 0-1.336.6-1.336 1.337 0 .736.6 1.335 1.337 1.335.738 0 1.338-.598 1.338-1.336 0-.74-.598-1.338-1.337-1.338z"/>
+    </svg>`
+}
+
+export function closeIcon () {
+  return html`<svg class="UppyIcon" width="15px" height="15px" viewBox="0 0 17 17">
+    <polygon points="16 1.45229667 15.5477033 1 8.50031987 8.04738346 1.45229667 1 1 1.45229667 8.04738346 8.49968013 1 15.5477033 1.45229667 16 8.50031987 8.95261654 15.5477033 16 16 15.5477033 8.95261654 8.49968013"></polygon>
   </svg>`
+}
+
+export function pluginIcon () {
+  return html`<svg class="UppyIcon" width="16px" height="16px" viewBox="0 0 32 30" class="UppyModalTab-icon">
+      <path d="M6.6209894,11.1451162 C6.6823051,11.2751669 6.81374248,11.3572188 6.95463813,11.3572188 L12.6925482,11.3572188 L12.6925482,16.0630427 C12.6925482,17.880509 14.1726048,18.75 16.0000083,18.75 C17.8261072,18.75 19.3074684,17.8801847 19.3074684,16.0630427 L19.3074684,11.3572188 L25.0437478,11.3572188 C25.1875787,11.3572188 25.3164069,11.2751669 25.3790272,11.1451162 C25.4370814,11.0173358 25.4171865,10.8642587 25.3252129,10.7562615 L16.278212,0.127131837 C16.2093949,0.0463771751 16.1069846,0 15.9996822,0 C15.8910751,0 15.7886648,0.0463771751 15.718217,0.127131837 L6.6761083,10.7559371 C6.58250402,10.8642587 6.56293518,11.0173358 6.6209894,11.1451162 L6.6209894,11.1451162 Z"/>
+      <path d="M28.8008722,6.11142645 C28.5417891,5.19831555 28.1583331,4.6875 27.3684848,4.6875 L21.6124454,4.6875 L22.8190234,6.10307874 L27.4986725,6.10307874 L29.9195817,19.3486449 L21.3943891,19.3502502 L21.3943891,22.622552 L10.8023461,22.622552 L10.8023461,19.3524977 L2.07815702,19.3534609 L5.22979699,6.10307874 L9.17871529,6.10307874 L10.3840011,4.6875 L4.6308691,4.6875 C3.83940559,4.6875 3.37421888,5.2390909 3.19815864,6.11142645 L0,19.7470874 L0,28.2212959 C0,29.2043992 0.801477937,30 1.78870751,30 L30.2096773,30 C31.198199,30 32,29.2043992 32,28.2212959 L32,19.7470874 L28.8008722,6.11142645 L28.8008722,6.11142645 Z"/>
+    </svg>`
+}
 
 export function checkIcon () {
   return html`<svg class="UppyIcon" width="18px" height="18px" viewBox="0 0 18 18">
@@ -14,13 +28,6 @@ export function checkIcon () {
   </svg>`
 }
 
-export const removeIc = html`<svg aria-hidden="true" width="18px" height="18px" viewBox="0 0 18 18">
-    <g transform="translate(1.000000, 1.000000)" stroke="#000">
-      <ellipse cx="8" cy="8" rx="8" ry="8" fill="transparent" />
-      <polygon points="11.2 4.99297991 11.0070201 4.8 8.00013648 7.80688361 4.99297991 4.8 4.8 4.99297991 7.80688361 7.99986352 4.8 11.0070201 4.99297991 11.2 8.00013648 8.19311639 11.0070201 11.2 11.2 11.0070201 8.19311639 7.99986352"/>
-    </g>
-  </svg>`
-
 export function removeIcon () {
   return html`<svg aria-hidden="true" class="UppyIcon" width="16px" height="16px" viewBox="0 0 16 16">
     <path d="M8,16 C12.418278,16 16,12.418278 16,8 C16,3.581722 12.418278,0 8,0 C3.581722,0 0,3.581722 0,8 C0,12.418278 3.581722,16 8,16 L8,16 Z M8,15.04 C4.11191536,15.04 0.96,11.8880846 0.96,8 C0.96,4.11191536 4.11191536,0.96 8,0.96 C11.8880846,0.96 15.04,4.11191536 15.04,8 C15.04,11.8880846 11.8880846,15.04 8,15.04 L8,15.04 Z"/>

+ 36 - 14
src/plugins/Modal.js → src/plugins/modal/index.js

@@ -1,9 +1,11 @@
-import Plugin from './Plugin'
+import Plugin from '../Plugin'
+import Dashboard from './Dashboard.js'
+import { defaultTabIcon, closeIcon } from './icons'
+import dragDrop from 'drag-drop'
 import yo from 'yo-yo'
 
 /**
- * Modal
- *
+ * Modal Dialog & Dashboard
  */
 export default class Modal extends Plugin {
   constructor (core, opts) {
@@ -15,11 +17,7 @@ export default class Modal extends Plugin {
     // set default options
     const defaultOptions = {
       target: '.UppyModal',
-      defaultTabIcon: yo`
-        <svg class="UppyModalTab-icon" width="28" height="28" viewBox="0 0 101 58">
-          <path d="M17.582.3L.915 41.713l32.94 13.295L17.582.3zm83.333 41.414L67.975 55.01 84.25.3l16.665 41.414zm-48.998 5.403L63.443 35.59H38.386l11.527 11.526v5.905l-3.063 3.32 1.474 1.36 2.59-2.806 2.59 2.807 1.475-1.357-3.064-3.32v-5.906zm16.06-26.702c-3.973 0-7.194-3.22-7.194-7.193 0-3.973 3.222-7.193 7.193-7.193 3.974 0 7.193 3.22 7.193 7.19 0 3.974-3.22 7.194-7.195 7.194zM70.48 8.682c-.737 0-1.336.6-1.336 1.337 0 .736.6 1.335 1.337 1.335.738 0 1.338-.598 1.338-1.336 0-.74-.6-1.338-1.338-1.338zM33.855 20.415c-3.973 0-7.193-3.22-7.193-7.193 0-3.973 3.22-7.193 7.195-7.193 3.973 0 7.192 3.22 7.192 7.19 0 3.974-3.22 7.194-7.192 7.194zM36.36 8.682c-.737 0-1.336.6-1.336 1.337 0 .736.6 1.335 1.337 1.335.738 0 1.338-.598 1.338-1.336 0-.74-.598-1.338-1.337-1.338z"/>
-        </svg>
-      `,
+      defaultTabIcon: defaultTabIcon(),
       panelSelectorPrefix: 'UppyModalContent-panel'
     }
 
@@ -168,9 +166,28 @@ export default class Modal extends Plugin {
     })
   }
 
+  handleDrop (files) {
+    this.core.log('All right, someone dropped something...')
+
+    files.forEach((file) => {
+      this.core.emitter.emit('file-add', {
+        source: this.id,
+        name: file.name,
+        type: file.type,
+        data: file
+      })
+    })
+
+    this.core.addMeta({bla: 'bla'})
+  }
+
   render (state) {
     // http://dev.edenspiekermann.com/2016/02/11/introducing-accessible-modal-dialog
 
+    const autoProceed = this.core.opts.autoProceed
+    const files = state.files
+    const bus = this.core.emitter
+
     const modalTargets = state.modal.targets
 
     const acquirers = modalTargets.filter((target) => {
@@ -181,15 +198,18 @@ export default class Modal extends Plugin {
       return target.type === 'progressindicator'
     })
 
-    const targetClassName = this.opts.target.substring(1)
+    // const targetClassName = this.opts.target.substring(1)
 
-    return yo`<div class="Uppy ${targetClassName}"
+    return yo`<div class="Uppy UppyTheme--default UppyModal"
                    aria-hidden="${state.modal.isHidden}"
                    aria-label="Uppy Dialog Window (Press escape to close)"
                    role="dialog">
       <div class="UppyModal-overlay"
                   onclick=${this.hideModal}></div>
         <div class="UppyModal-inner" tabindex="0">
+          <div class="UppyModal-dashboard">
+            ${Dashboard(files, bus, autoProceed)}
+          </div>
           <ul class="UppyModalTabs" role="tablist">
             ${acquirers.map((target) => {
               return yo`<li class="UppyModalTab">
@@ -206,7 +226,6 @@ export default class Modal extends Plugin {
           </ul>
 
           <div class="UppyModalContent">
-            <div class="UppyModal-presenter"></div>
             ${acquirers.map((target) => {
               return yo`<div class="UppyModalContent-panel"
                              id="${this.opts.panelSelectorPrefix}--${target.id}"
@@ -224,9 +243,7 @@ export default class Modal extends Plugin {
           <button class="UppyModal-close"
                   title="Close Uppy modal"
                   onclick=${this.hideModal}>
-                  <svg width="15px" height="15px" viewBox="0 0 17 17">
-                    <polygon stroke="#000000" points="16 1.45229667 15.5477033 1 8.50031987 8.04738346 1.45229667 1 1 1.45229667 8.04738346 8.49968013 1 15.5477033 1.45229667 16 8.50031987 8.95261654 15.5477033 16 16 15.5477033 8.95261654 8.49968013"></polygon>
-                  </svg>
+                  ${closeIcon()}
           </button>
       </div>
     </div>`
@@ -243,5 +260,10 @@ export default class Modal extends Plugin {
     document.body.appendChild(this.el)
 
     this.events()
+
+    dragDrop(this.opts.target, (files) => {
+      this.handleDrop(files)
+      this.core.log(files)
+    })
   }
 }

+ 16 - 8
src/scss/_dashboard.scss

@@ -5,17 +5,23 @@
 .UppyDashboard {
   height: 100%;
   position: relative;
+  padding: 0 20px;
+  padding-top: 40px;
 }
 
 .UppyDashboard-title {
-  font-size: 15px;
+  font-size: 13px;
   text-transform: uppercase;
   letter-spacing: 2px;
   font-weight: normal;
   text-align: center;
   margin: 0;
   padding: 0;
-  padding-top: 15px;
+  position: absolute;
+  top: 15px;
+  left: 0;
+  width: 100%;
+  text-align: center;
 }
 
 .UppyDashboard-list {
@@ -25,13 +31,14 @@
   border-color: lighten($color-gray, 30%);
   margin: 0;
   padding: 0;
-  position: absolute;
-  top: 50px;
-  bottom: 15px;
-  right: 15px;
-  left: 0;
   overflow: scroll;
-  padding: 15px;
+  height: 100%;
+  // position: absolute;
+  // top: 50px;
+  // bottom: 15px;
+  // right: 15px;
+  // left: 0;
+  // padding: 15px;
 }
 
 .UppyDashboardItem {
@@ -63,6 +70,7 @@
 
 .UppyDashboardItem-name {
   font-size: 13px;
+  line-height: 1.4;
   font-weight: bold;
   margin: 0;
   padding: 0;

+ 22 - 15
src/scss/_modal.scss

@@ -58,15 +58,19 @@
   margin: 0;
   padding: 0;
   // white-space: nowrap;
-  width: 8%;
-  height: 100%;
-  float: left;
-  padding-top: 20px;
-  text-align: center;
+  // width: 8%;
+  height: 20%;
+  // float: left;
+  // padding-top: 20px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
 }
 
 .UppyModalTab {
-  margin-bottom: 25px;
+  margin: 0 5px;
+  width: 40px;
+  display: inline-block;
 }
 
 .UppyModalTab-name {
@@ -89,12 +93,12 @@
   -webkit-appearance: none;
   outline: none;
   transition: all 0.3s;
-  fill: $color-asphalt-gray;
+  color: $color-asphalt-gray;
 
   &:focus,
   &:active,
   &:hover {
-    fill: darken($color-cornflower-blue, 25%);
+    color: darken($color-cornflower-blue, 25%);
   }
 
   &:hover .UppyModalTab-name {
@@ -103,27 +107,30 @@
 }
 
 .UppyModalTab-btn[aria-selected=true] {
-  // background-color: $color-cornflower-blue;
-  fill: $color-cornflower-blue;
+  color: $color-cornflower-blue;
 }
 
 // On SVG sizing: https://sarasoueidan.com/blog/svg-style-inheritance-and-FOUSVG/
 .UppyModalTab-icon {
-  // fill: $color-asphalt-gray;
-  // margin-right: 8px;
   width: 25px;
   height: 25px;
   vertical-align: middle;
 }
 
+// Modal Dashboard
+
+.UppyModal-dashboard {
+  height: 80%;
+}
+
 // Modal content
 
 .UppyModalContent {
   height: 100%;
-  width: 92%;
+  // width: 92%;
   position: relative;
-  float: left;
-  // margin-left: 80px;
+  // float: left;
+  display: none;
 }
 
 .UppyModalContent-panel {