Browse Source

Upgrade standard to v14 (#1860)

* Update eslint dependencies.

* standard --fix

* build: disable handler name lint rule

* status-bar: manually fix lint errors

* webcam: manually fix lint errors

* url: manually fix lint errors

* react-native: manually fix lint errors

* dashboard: manually fix lint errors

* informer: manually fix linting errors

* progress-bar: manually fix lint errors

* provider-views: manually fix lint errors

* redux-dev-tools: manually fix lint errors

* build: disable buggy no-unused-vars rule

* examples: manually fix lint errors

* ` quotes for code things, ' for text things
Renée Kooi 5 years ago
parent
commit
733de659da
64 changed files with 1290 additions and 860 deletions
  1. 2 0
      .eslintrc.json
  2. 8 8
      bin/locale-packs.js
  3. 20 11
      examples/react-native-expo/App.js
  4. 21 15
      examples/react-native-expo/FileList.js
  5. 5 2
      examples/react-native-expo/PauseResumeButton.js
  6. 6 3
      examples/react-native-expo/ProgressBar.js
  7. 2 1
      examples/react-native-expo/SelectFilesButton.js
  8. 463 266
      package-lock.json
  9. 9 9
      package.json
  10. 2 2
      packages/@uppy/aws-s3-multipart/src/MultipartUploader.js
  11. 1 1
      packages/@uppy/companion/src/server/Uploader.js
  12. 2 2
      packages/@uppy/companion/src/server/provider/instagram/adapter.js
  13. 2 2
      packages/@uppy/companion/src/standalone/index.js
  14. 1 1
      packages/@uppy/companion/test/__tests__/companion.js
  15. 1 2
      packages/@uppy/companion/test/mockserver.js
  16. 1 1
      packages/@uppy/core/src/__snapshots__/index.test.js.snap
  17. 2 2
      packages/@uppy/core/src/index.js
  18. 2 2
      packages/@uppy/core/src/index.test.js
  19. 27 19
      packages/@uppy/dashboard/src/components/AddFiles.js
  20. 9 4
      packages/@uppy/dashboard/src/components/AddFilesPanel.js
  21. 17 11
      packages/@uppy/dashboard/src/components/Dashboard.js
  22. 39 21
      packages/@uppy/dashboard/src/components/FileCard/index.js
  23. 27 26
      packages/@uppy/dashboard/src/components/FileItem/Buttons/index.js
  24. 10 10
      packages/@uppy/dashboard/src/components/FileItem/FileInfo/index.js
  25. 7 7
      packages/@uppy/dashboard/src/components/FileItem/FilePreviewAndLink/index.js
  26. 9 8
      packages/@uppy/dashboard/src/components/FileItem/FileProgress/PauseResumeCancelIcon.js
  27. 5 4
      packages/@uppy/dashboard/src/components/FileItem/FileProgress/index.js
  28. 3 1
      packages/@uppy/dashboard/src/components/FileList.js
  29. 9 4
      packages/@uppy/dashboard/src/components/PickerPanelContent.js
  30. 25 25
      packages/@uppy/dashboard/src/components/PickerPanelTopBar.js
  31. 92 60
      packages/@uppy/dashboard/src/components/icons.js
  32. 1 1
      packages/@uppy/dashboard/src/utils/createSuperFocus.js
  33. 4 2
      packages/@uppy/drag-drop/src/index.js
  34. 12 6
      packages/@uppy/facebook/src/index.js
  35. 9 6
      packages/@uppy/file-input/src/index.js
  36. 14 8
      packages/@uppy/informer/src/index.js
  37. 10 4
      packages/@uppy/progress-bar/src/index.js
  38. 15 13
      packages/@uppy/provider-views/src/AuthView.js
  39. 14 8
      packages/@uppy/provider-views/src/Breadcrumbs.js
  40. 1 1
      packages/@uppy/provider-views/src/Browser.js
  41. 31 27
      packages/@uppy/provider-views/src/Filter.js
  42. 12 10
      packages/@uppy/provider-views/src/FooterActions.js
  43. 18 16
      packages/@uppy/provider-views/src/Item/components/GridLi.js
  44. 28 9
      packages/@uppy/provider-views/src/Item/components/ItemIcon.js
  45. 21 19
      packages/@uppy/provider-views/src/Item/components/ListLi.js
  46. 4 2
      packages/@uppy/provider-views/src/ItemList.js
  47. 5 3
      packages/@uppy/provider-views/src/Loader.js
  48. 4 2
      packages/@uppy/provider-views/src/index.js
  49. 17 10
      packages/@uppy/react-native/file-picker/index.js
  50. 16 13
      packages/@uppy/react-native/file-picker/instagram.js
  51. 6 3
      packages/@uppy/react-native/file-picker/url.js
  52. 2 1
      packages/@uppy/redux-dev-tools/src/index.js
  53. 141 110
      packages/@uppy/status-bar/src/StatusBar.js
  54. 2 1
      packages/@uppy/tus/src/index.js
  55. 20 16
      packages/@uppy/url/src/UrlUI.js
  56. 10 6
      packages/@uppy/url/src/index.js
  57. 5 3
      packages/@uppy/webcam/src/CameraIcon.js
  58. 8 4
      packages/@uppy/webcam/src/RecordButton.js
  59. 4 2
      packages/@uppy/webcam/src/SnapshotButton.js
  60. 19 16
      packages/@uppy/webcam/src/index.js
  61. 1 1
      test/endtoend/transloadit/test.js
  62. 1 1
      test/endtoend/utils.js
  63. 5 5
      website/inject.js
  64. 1 1
      website/scripts/highlight.js

+ 2 - 0
.eslintrc.json

@@ -14,6 +14,8 @@
   "rules": {
     "jsx-quotes": ["error", "prefer-double"],
     "compat/compat": ["error"],
+    "react/jsx-handler-names": ["warn"], // maybe we want to do this in the future?
+    "no-unused-vars": ["off"], // Buggy: wrongly flags `i` in `for (const i in iterator)`—reenable ASAP
 
     "jsdoc/check-alignment": ["warn"],
     "jsdoc/check-examples": ["warn"],

+ 8 - 8
bin/locale-packs.js

@@ -18,7 +18,7 @@ if (mode === 'build') {
 } else if (mode === 'test') {
   test()
 } else {
-  throw new Error(`First argument must be either 'build' or 'test'`)
+  throw new Error("First argument must be either 'build' or 'test'")
 }
 
 function getSources (pluginName) {
@@ -49,7 +49,7 @@ function buildPluginsList () {
   const packagesGlobPath = path.join(__dirname, '..', 'packages', '@uppy', '*', 'package.json')
   const files = glob.sync(packagesGlobPath)
 
-  console.log(`--> Checked plugins could be instantiated and have defaultLocale in them:\n`)
+  console.log('--> Checked plugins could be instantiated and have defaultLocale in them:\n')
   for (const file of files) {
     const dirName = path.dirname(file)
     const pluginName = path.basename(dirName)
@@ -115,7 +115,7 @@ function buildPluginsList () {
     }
   }
 
-  console.log(``)
+  console.log('')
 
   return { plugins, sources }
 }
@@ -221,19 +221,19 @@ function test () {
   }
 
   if (warnings.length) {
-    console.error(`--> Locale warnings: `)
+    console.error('--> Locale warnings: ')
     console.error(warnings.join('\n'))
-    console.error(``)
+    console.error('')
   }
   if (fatals.length) {
-    console.error(`--> Locale fatal warnings: `)
+    console.error('--> Locale fatal warnings: ')
     console.error(fatals.join('\n'))
-    console.error(``)
+    console.error('')
     process.exit(1)
   }
 
   if (!warnings.length && !fatals.length) {
     console.log(`--> All locale strings have matching keys ${chalk.green(': )')}`)
-    console.log(``)
+    console.log('')
   }
 }

+ 20 - 11
examples/react-native-expo/App.js

@@ -119,12 +119,15 @@ export default class App extends React.Component {
         paddingLeft: 50,
         paddingRight: 50,
         flex: 1
-      }}>
+      }}
+      >
         <Text style={{
           fontSize: 25,
           marginBottom: 20,
           textAlign: 'center'
-        }}>Uppy in React Native</Text>
+        }}
+        >Uppy in React Native
+        </Text>
         <View style={{ alignItems: 'center' }}>
           <Image
             style={{ width: 80, height: 78, marginBottom: 50 }}
@@ -133,13 +136,17 @@ export default class App extends React.Component {
         </View>
         <SelectFiles showFilePicker={this.showFilePicker} />
 
-        {this.state.info
-          ? <Text style={{
-            marginBottom: 10,
-            marginTop: 10,
-            color: '#b8006b' }}>{this.state.info.message}</Text>
-          : null
-        }
+        {this.state.info ? (
+          <Text
+            style={{
+              marginBottom: 10,
+              marginTop: 10,
+              color: '#b8006b'
+            }}
+          >
+            {this.state.info.message}
+          </Text>
+        ) : null}
 
         <ProgressBar progress={this.state.totalProgress} />
 
@@ -147,13 +154,15 @@ export default class App extends React.Component {
           isPaused={this.state.isPaused}
           onPress={this.togglePauseResume}
           uploadStarted={this.state.uploadStarted}
-          uploadComplete={this.state.uploadComplete} />
+          uploadComplete={this.state.uploadComplete}
+        />
 
         <UppyFilePicker
           uppy={this.uppy}
           show={this.state.isFilePickerVisible}
           onRequestClose={this.hideFilePicker}
-          companionUrl="http://localhost:3020" />
+          companionUrl="http://localhost:3020"
+        />
 
         <FileList uppy={this.uppy} />
 

+ 21 - 15
examples/react-native-expo/FileList.js

@@ -16,12 +16,14 @@ import SvgUri from 'react-native-svg-uri'
 // }
 
 function FileIcon () {
-  return <View style={styles.itemIconContainer}>
-    <Image
-      style={styles.itemIcon}
-      source={require('./assets/file-icon.png')}
-    />
-  </View>
+  return (
+    <View style={styles.itemIconContainer}>
+      <Image
+        style={styles.itemIcon}
+        source={require('./assets/file-icon.png')}
+      />
+    </View>
+  )
 }
 
 function UppyDashboardFileIcon (props) {
@@ -31,10 +33,12 @@ function UppyDashboardFileIcon (props) {
   }
   const color = getFileTypeIcon(props.type).color
   return (
-    <View style={{
-      ...styles.itemIconContainer,
-      backgroundColor: color
-    }}>
+    <View
+      style={{
+        ...styles.itemIconContainer,
+        backgroundColor: color
+      }}
+    >
       <SvgUri
         width={50}
         height={50}
@@ -60,12 +64,14 @@ export default function FileList (props) {
         renderItem={({ item }) => {
           return (
             <View style={styles.item}>
-              {item.type === 'image'
-                ? <Image
+              {item.type === 'image' ? (
+                <Image
                   style={styles.itemImage}
-                  source={{ uri: item.data.uri }} />
-                : <UppyDashboardFileIcon type={item.type} />
-              }
+                  source={{ uri: item.data.uri }}
+                />
+              ) : (
+                <UppyDashboardFileIcon type={item.type} />
+              )}
               <Text style={styles.itemName}>{truncateString(item.name, 20)}</Text>
               <Text style={styles.itemType}>{item.type}</Text>
             </View>

+ 5 - 2
examples/react-native-expo/PauseResumeButton.js

@@ -9,9 +9,12 @@ export default function PauseResumeButton (props) {
   return (
     <TouchableHighlight
       onPress={props.onPress}
-      style={styles.button}>
+      style={styles.button}
+    >
       <Text
-        style={styles.text}>{props.isPaused ? 'Resume' : 'Pause'}</Text>
+        style={styles.text}
+      >{props.isPaused ? 'Resume' : 'Pause'}
+      </Text>
     </TouchableHighlight>
   )
 }

+ 6 - 3
examples/react-native-expo/ProgressBar.js

@@ -11,18 +11,21 @@ export default function ProgressBar (props) {
     <View style={{
       marginTop: 15,
       marginBottom: 15
-    }}>
+    }}
+    >
       <View
         style={{
           height: 5,
           overflow: 'hidden',
           backgroundColor: '#dee1e3'
-        }}>
+        }}
+      >
         <View style={{
           height: 5,
           backgroundColor: progress === 100 ? colorGreen : colorBlue,
           width: progress + '%'
-        }} />
+        }}
+        />
       </View>
       <Text>{progress ? progress + '%' : null}</Text>
     </View>

+ 2 - 1
examples/react-native-expo/SelectFilesButton.js

@@ -5,7 +5,8 @@ export default function SelectFiles (props) {
   return (
     <TouchableHighlight
       onPress={props.showFilePicker}
-      style={styles.button}>
+      style={styles.button}
+    >
       <Text style={styles.text}>Select files</Text>
     </TouchableHighlight>
   )

File diff suppressed because it is too large
+ 463 - 266
package-lock.json


+ 9 - 9
package.json

@@ -120,17 +120,17 @@
     "enzyme": "^3.9.0",
     "enzyme-adapter-react-16": "^1.11.2",
     "es6-promise": "4.2.5",
-    "eslint": "^6.1.0",
-    "eslint-config-standard": "^13.0.1",
-    "eslint-config-standard-jsx": "^7.0.0",
+    "eslint": "^6.5.1",
+    "eslint-config-standard": "^14.1.0",
+    "eslint-config-standard-jsx": "^8.1.0",
     "eslint-plugin-compat": "^3.3.0",
-    "eslint-plugin-import": "^2.18.1",
-    "eslint-plugin-jest": "^22.11.1",
+    "eslint-plugin-import": "^2.18.2",
+    "eslint-plugin-jest": "^22.17.0",
     "eslint-plugin-jsdoc": "^15.5.3",
-    "eslint-plugin-node": "^9.1.0",
+    "eslint-plugin-node": "^10.0.0",
     "eslint-plugin-promise": "^4.2.1",
-    "eslint-plugin-react": "^7.14.2",
-    "eslint-plugin-standard": "^4.0.0",
+    "eslint-plugin-react": "^7.15.1",
+    "eslint-plugin-standard": "^4.0.1",
     "events.once": "^2.0.2",
     "exorcist": "^1.0.1",
     "express": "4.17.1",
@@ -146,7 +146,7 @@
     "json3": "^3.3.2",
     "last-commit-message": "^1.0.0",
     "lerna": "^3.14.1",
-    "lint-staged": "^8.1.7",
+    "lint-staged": "^9.4.1",
     "mime-types": "2.1.24",
     "minify-stream": "^1.2.0",
     "mkdirp": "0.5.1",

+ 2 - 2
packages/@uppy/aws-s3-multipart/src/MultipartUploader.js

@@ -58,7 +58,7 @@ class MultipartUploader {
         typeof result.uploadId === 'string' &&
         typeof result.key === 'string'
       if (!valid) {
-        throw new TypeError(`AwsS3/Multipart: Got incorrect result from 'createMultipartUpload()', expected an object '{ uploadId, key }'.`)
+        throw new TypeError('AwsS3/Multipart: Got incorrect result from `createMultipartUpload()`, expected an object `{ uploadId, key }`.')
       }
       return result
     }).then((result) => {
@@ -145,7 +145,7 @@ class MultipartUploader {
       const valid = typeof result === 'object' && result &&
         typeof result.url === 'string'
       if (!valid) {
-        throw new TypeError(`AwsS3/Multipart: Got incorrect result from 'prepareUploadPart()', expected an object '{ url }'.`)
+        throw new TypeError('AwsS3/Multipart: Got incorrect result from `prepareUploadPart()`, expected an object `{ url }`.')
       }
       return result
     }).then(({ url }) => {

+ 1 - 1
packages/@uppy/companion/src/server/Uploader.js

@@ -173,7 +173,7 @@ class Uploader {
    */
   onSocketReady (callback) {
     emitter().once(`connection:${this.token}`, () => callback())
-    logger.debug(`waiting for connection`, 'uploader.socket.wait', this.shortToken)
+    logger.debug('waiting for connection', 'uploader.socket.wait', this.shortToken)
   }
 
   cleanUp () {

+ 2 - 2
packages/@uppy/companion/src/server/provider/instagram/adapter.js

@@ -30,9 +30,9 @@ exports.getItemSubList = (item) => {
 }
 
 exports.getItemName = (item) => {
-  if (item && item['created_time']) {
+  if (item && item.created_time) {
     const ext = item.type === 'video' ? 'mp4' : 'jpeg'
-    const date = new Date(item['created_time'] * 1000)
+    const date = new Date(item.created_time * 1000)
     const name = date.toLocaleDateString([], {
       year: 'numeric',
       month: 'short',

+ 2 - 2
packages/@uppy/companion/src/standalone/index.js

@@ -42,9 +42,9 @@ morgan.token('url', (req, res) => {
     return `${req.path}?${qs.stringify(query)}`
   }
 
-  if (req.query && req.query['access_token']) {
+  if (req.query && req.query.access_token) {
     return mask('access_token')
-  } else if (req.query && req.query['uppyAuthToken']) {
+  } else if (req.query && req.query.uppyAuthToken) {
     return mask('uppyAuthToken')
   }
 

+ 1 - 1
packages/@uppy/companion/test/__tests__/companion.js

@@ -87,7 +87,7 @@ describe('test authentication', () => {
       .get('/drive/callback')
       .expect(302)
       .expect((res) => {
-        expect(res.header['location']).toContain('http://localhost:3020/drive/send-token?uppyAuthToken=')
+        expect(res.header.location).toContain('http://localhost:3020/drive/send-token?uppyAuthToken=')
       })
   })
 

+ 1 - 2
packages/@uppy/companion/test/mockserver.js

@@ -12,8 +12,7 @@ authServer.all('*/callback', (req, res, next) => {
   next()
 })
 authServer.all('/drive/send-token', (req, res, next) => {
-  req.session.grant = {
-    state: req.query.state || 'non-empty-value' }
+  req.session.grant = { state: req.query.state || 'non-empty-value' }
   next()
 })
 

+ 1 - 1
packages/@uppy/core/src/__snapshots__/index.test.js.snap

@@ -8,7 +8,7 @@ exports[`src/Core plugins should not be able to add an invalid plugin 1`] = `"Ex
 
 exports[`src/Core plugins should prevent the same plugin from being added more than once 1`] = `
 "Already found a plugin named 'TestSelector1'. Tried to use: 'TestSelector1'.
-Uppy plugins must have unique 'id' options. See https://uppy.io/docs/plugins/#id."
+Uppy plugins must have unique \`id\` options. See https://uppy.io/docs/plugins/#id."
 `;
 
 exports[`src/Core uploading a file should only upload files that are not already assigned to another upload id 1`] = `

+ 2 - 2
packages/@uppy/core/src/index.js

@@ -117,7 +117,7 @@ class Uppy {
     if (this.opts.restrictions.allowedFileTypes &&
         this.opts.restrictions.allowedFileTypes !== null &&
         !Array.isArray(this.opts.restrictions.allowedFileTypes)) {
-      throw new TypeError(`'restrictions.allowedFileTypes' must be an array`)
+      throw new TypeError('`restrictions.allowedFileTypes` must be an array')
     }
 
     // i18n
@@ -961,7 +961,7 @@ class Uppy {
     if (existsPluginAlready) {
       const msg = `Already found a plugin named '${existsPluginAlready.id}'. ` +
         `Tried to use: '${pluginId}'.\n` +
-        `Uppy plugins must have unique 'id' options. See https://uppy.io/docs/plugins/#id.`
+        'Uppy plugins must have unique `id` options. See https://uppy.io/docs/plugins/#id.'
       throw new Error(msg)
     }
 

+ 2 - 2
packages/@uppy/core/src/index.test.js

@@ -667,7 +667,7 @@ describe('src/Core', () => {
           }
         })
       }).toThrow(
-        'Cannot add the duplicate file \'foo.jpg\', it already exists'
+        "Cannot add the duplicate file 'foo.jpg', it already exists"
       )
       expect(core.getFiles().length).toEqual(1)
     })
@@ -1389,7 +1389,7 @@ describe('src/Core', () => {
         })
         core.log('hi')
       } catch (err) {
-        expect(err).toMatchObject(new Error(`'restrictions.allowedFileTypes' must be an array`))
+        expect(err).toMatchObject(new Error('`restrictions.allowedFileTypes` must be an array'))
       }
     })
 

+ 27 - 19
packages/@uppy/dashboard/src/components/AddFiles.js

@@ -38,7 +38,8 @@ class AddFiles extends Component {
         href="https://uppy.io"
         rel="noreferrer noopener"
         target="_blank"
-        class="uppy-Dashboard-poweredBy">
+        class="uppy-Dashboard-poweredBy"
+      >
         {this.props.i18n('poweredBy') + ' '}
         <svg aria-hidden="true" focusable="false" class="UppyIcon uppy-Dashboard-poweredByIcon" width="11" height="11" viewBox="0 0 11 11">
           <path d="M7.365 10.5l-.01-4.045h2.612L5.5.806l-4.467 5.65h2.604l.01 4.044h3.718z" fill-rule="evenodd" />
@@ -50,7 +51,8 @@ class AddFiles extends Component {
 
   renderHiddenFileInput () {
     return (
-      <input class="uppy-Dashboard-input"
+      <input
+        class="uppy-Dashboard-input"
         hidden
         aria-hidden="true"
         tabindex={-1}
@@ -59,15 +61,18 @@ class AddFiles extends Component {
         multiple={this.props.maxNumberOfFiles !== 1}
         onchange={this.handleFileInputChange}
         accept={this.props.allowedFileTypes}
-        ref={(ref) => { this.fileInput = ref }} />
+        ref={(ref) => { this.fileInput = ref }}
+      />
     )
   }
 
   renderDropPasteBrowseTagline () {
     const browse =
-      <button type="button"
+      <button
+        type="button"
         class="uppy-u-reset uppy-Dashboard-browse"
-        onclick={this.triggerFileInputClick}>
+        onclick={this.triggerFileInputClick}
+      >
         {this.props.i18n('browse')}
       </button>
 
@@ -75,8 +80,7 @@ class AddFiles extends Component {
       <div class="uppy-Dashboard-dropFilesTitle">
         {this.props.acquirers.length === 0
           ? this.props.i18nArray('dropPaste', { browse })
-          : this.props.i18nArray('dropPasteImport', { browse })
-        }
+          : this.props.i18nArray('dropPasteImport', { browse })}
       </div>
     )
   }
@@ -84,12 +88,14 @@ class AddFiles extends Component {
   renderMyDeviceAcquirer () {
     return (
       <div class="uppy-DashboardTab" role="presentation">
-        <button type="button"
+        <button
+          type="button"
           class="uppy-DashboardTab-btn"
           role="tab"
           tabindex={0}
           data-uppy-super-focusable
-          onclick={this.triggerFileInputClick}>
+          onclick={this.triggerFileInputClick}
+        >
           {localIcon()}
           <div class="uppy-DashboardTab-name">{this.props.i18n('myDevice')}</div>
         </button>
@@ -100,14 +106,16 @@ class AddFiles extends Component {
   renderAcquirer (acquirer) {
     return (
       <div class="uppy-DashboardTab" role="presentation">
-        <button type="button"
+        <button
+          type="button"
           class="uppy-DashboardTab-btn"
           role="tab"
           tabindex={0}
           aria-controls={`uppy-DashboardContent-panel--${acquirer.id}`}
           aria-selected={this.props.activePickerPanel.id === acquirer.id}
           data-uppy-super-focusable
-          onclick={() => this.props.showPanel(acquirer.id)}>
+          onclick={() => this.props.showPanel(acquirer.id)}
+        >
           {acquirer.icon()}
           <div class="uppy-DashboardTab-name">{acquirer.name}</div>
         </button>
@@ -123,17 +131,17 @@ class AddFiles extends Component {
           {this.renderDropPasteBrowseTagline()}
           {
             this.props.acquirers.length > 0 &&
-            <div class="uppy-DashboardTabs-list" role="tablist">
-              {this.renderMyDeviceAcquirer()}
-              {this.props.acquirers.map((acquirer) =>
-                this.renderAcquirer(acquirer)
-              )}
-            </div>
+              <div class="uppy-DashboardTabs-list" role="tablist">
+                {this.renderMyDeviceAcquirer()}
+                {this.props.acquirers.map((acquirer) =>
+                  this.renderAcquirer(acquirer)
+                )}
+              </div>
           }
         </div>
         <div class="uppy-DashboardAddFiles-info">
-          { this.props.note && <div class="uppy-Dashboard-note">{this.props.note}</div> }
-          { this.props.proudlyDisplayPoweredByUppy && this.renderPoweredByUppy(this.props) }
+          {this.props.note && <div class="uppy-Dashboard-note">{this.props.note}</div>}
+          {this.props.proudlyDisplayPoweredByUppy && this.renderPoweredByUppy(this.props)}
         </div>
       </div>
     )

+ 9 - 4
packages/@uppy/dashboard/src/components/AddFilesPanel.js

@@ -3,16 +3,21 @@ const AddFiles = require('./AddFiles')
 
 const AddFilesPanel = (props) => {
   return (
-    <div class="uppy-Dashboard-AddFilesPanel"
+    <div
+      class="uppy-Dashboard-AddFilesPanel"
       data-uppy-panelType="AddFiles"
-      aria-hidden={props.showAddFilesPanel}>
+      aria-hidden={props.showAddFilesPanel}
+    >
       <div class="uppy-DashboardContent-bar">
         <div class="uppy-DashboardContent-title" role="heading" aria-level="h1">
           {props.i18n('addingMoreFiles')}
         </div>
-        <button class="uppy-DashboardContent-back"
+        <button
+          class="uppy-DashboardContent-back"
           type="button"
-          onclick={(ev) => props.toggleAddFilesPanel(false)}>{props.i18n('back')}</button>
+          onclick={(ev) => props.toggleAddFilesPanel(false)}
+        >{props.i18n('back')}
+        </button>
       </div>
       <AddFiles {...props} />
     </div>

+ 17 - 11
packages/@uppy/dashboard/src/components/Dashboard.js

@@ -17,7 +17,8 @@ function TransitionWrapper (props) {
     <PreactCSSTransitionGroup
       transitionName="uppy-transition-slideDownUp"
       transitionEnterTimeout={250}
-      transitionLeaveTimeout={250}>
+      transitionLeaveTimeout={250}
+    >
       {props.children}
     </PreactCSSTransitionGroup>
   )
@@ -42,7 +43,8 @@ module.exports = function Dashboard (props) {
   )
 
   return (
-    <div class={dashboardClassName}
+    <div
+      class={dashboardClassName}
       aria-hidden={props.inline ? 'false' : props.isHidden}
       aria-label={!props.inline ? props.i18n('dashboardWindowTitle') : props.i18n('dashboardTitle')}
       onpaste={props.handlePaste}
@@ -53,20 +55,24 @@ module.exports = function Dashboard (props) {
     >
       <div class="uppy-Dashboard-overlay" tabindex={-1} onclick={props.handleClickOutside} />
 
-      <div class="uppy-Dashboard-inner"
+      <div
+        class="uppy-Dashboard-inner"
         aria-modal={!props.inline && 'true'}
         role={!props.inline && 'dialog'}
         style={{
           width: props.inline && props.width ? props.width : '',
           height: props.inline && props.height ? props.height : ''
-        }}>
+        }}
+      >
 
         {!props.inline ? (
-          <button class="uppy-u-reset uppy-Dashboard-close"
+          <button
+            class="uppy-u-reset uppy-Dashboard-close"
             type="button"
             aria-label={props.i18n('closeModal')}
             title={props.i18n('closeModal')}
-            onclick={props.closeModal}>
+            onclick={props.closeModal}
+          >
             <span aria-hidden="true">&times;</span>
           </button>
         ) : null}
@@ -76,24 +82,24 @@ module.exports = function Dashboard (props) {
             {props.i18n('dropHint')}
           </div>
 
-          { (!noFiles && props.showSelectedFiles) && <PanelTopBar {...props} /> }
+          {(!noFiles && props.showSelectedFiles) && <PanelTopBar {...props} />}
 
-          { props.showSelectedFiles ? (
+          {props.showSelectedFiles ? (
             noFiles ? <AddFiles {...props} /> : <FileList {...props} />
           ) : (
             <AddFiles {...props} />
           )}
 
           <TransitionWrapper>
-            { props.showAddFilesPanel ? <AddFilesPanel key="AddFilesPanel" {...props} /> : null }
+            {props.showAddFilesPanel ? <AddFilesPanel key="AddFilesPanel" {...props} /> : null}
           </TransitionWrapper>
 
           <TransitionWrapper>
-            { props.fileCardFor ? <FileCard key="FileCard" {...props} /> : null }
+            {props.fileCardFor ? <FileCard key="FileCard" {...props} /> : null}
           </TransitionWrapper>
 
           <TransitionWrapper>
-            { props.activePickerPanel ? <PickerPanelContent key="PickerPanelContent" {...props} /> : null }
+            {props.activePickerPanel ? <PickerPanelContent key="PickerPanelContent" {...props} /> : null}
           </TransitionWrapper>
 
           <div class="uppy-Dashboard-progressindicators">

+ 39 - 21
packages/@uppy/dashboard/src/components/FileCard/index.js

@@ -52,19 +52,23 @@ class FileCard extends Component {
 
     return metaFields.map((field) => {
       const id = `uppy-Dashboard-FileCard-input-${field.id}`
-      return <fieldset class="uppy-Dashboard-FileCard-fieldset">
-        <label class="uppy-Dashboard-FileCard-label" for={id}>{field.name}</label>
-        <input class="uppy-u-reset uppy-c-textInput uppy-Dashboard-FileCard-input"
-          id={id}
-          type="text"
-          value={this.state.formState[field.id]}
-          placeholder={field.placeholder}
-          onkeyup={this.saveOnEnter}
-          onkeydown={this.saveOnEnter}
-          onkeypress={this.saveOnEnter}
-          oninput={ev => this.tempStoreMeta(ev, field.id)}
-          data-uppy-super-focusable />
-      </fieldset>
+      return (
+        <fieldset key={field.id} class="uppy-Dashboard-FileCard-fieldset">
+          <label class="uppy-Dashboard-FileCard-label" for={id}>{field.name}</label>
+          <input
+            class="uppy-u-reset uppy-c-textInput uppy-Dashboard-FileCard-input"
+            id={id}
+            type="text"
+            value={this.state.formState[field.id]}
+            placeholder={field.placeholder}
+            onkeyup={this.saveOnEnter}
+            onkeydown={this.saveOnEnter}
+            onkeypress={this.saveOnEnter}
+            oninput={ev => this.tempStoreMeta(ev, field.id)}
+            data-uppy-super-focusable
+          />
+        </fieldset>
+      )
     })
   }
 
@@ -72,20 +76,26 @@ class FileCard extends Component {
     const file = this.props.files[this.props.fileCardFor]
 
     return (
-      <div class="uppy-Dashboard-FileCard"
+      <div
+        class="uppy-Dashboard-FileCard"
         data-uppy-panelType="FileCard"
         onDragOver={ignoreEvent}
         onDragLeave={ignoreEvent}
         onDrop={ignoreEvent}
-        onPaste={ignoreEvent}>
+        onPaste={ignoreEvent}
+      >
         <div class="uppy-DashboardContent-bar">
           <div class="uppy-DashboardContent-title" role="heading" aria-level="h1">
             {this.props.i18nArray('editing', {
               file: <span class="uppy-DashboardContent-titleFile">{file.meta ? file.meta.name : file.name}</span>
             })}
           </div>
-          <button class="uppy-DashboardContent-back" type="button" title={this.props.i18n('finishEditingFile')}
-            onclick={this.handleSave}>{this.props.i18n('done')}</button>
+          <button
+            class="uppy-DashboardContent-back" type="button" title={this.props.i18n('finishEditingFile')}
+            onclick={this.handleSave}
+          >
+            {this.props.i18n('done')}
+          </button>
         </div>
 
         <div class="uppy-Dashboard-FileCard-inner">
@@ -98,12 +108,20 @@ class FileCard extends Component {
           </div>
 
           <div class="uppy-Dashboard-FileCard-actions">
-            <button class="uppy-u-reset uppy-c-btn uppy-c-btn-primary uppy-Dashboard-FileCard-actionsBtn"
+            <button
+              class="uppy-u-reset uppy-c-btn uppy-c-btn-primary uppy-Dashboard-FileCard-actionsBtn"
               type="button"
-              onclick={this.handleSave}>{this.props.i18n('saveChanges')}</button>
-            <button class="uppy-u-reset uppy-c-btn uppy-c-btn-link uppy-Dashboard-FileCard-actionsBtn"
+              onclick={this.handleSave}
+            >
+              {this.props.i18n('saveChanges')}
+            </button>
+            <button
+              class="uppy-u-reset uppy-c-btn uppy-c-btn-link uppy-Dashboard-FileCard-actionsBtn"
               type="button"
-              onclick={this.handleCancel}>{this.props.i18n('cancel')}</button>
+              onclick={this.handleCancel}
+            >
+              {this.props.i18n('cancel')}
+            </button>
           </div>
         </div>
       </div>

+ 27 - 26
packages/@uppy/dashboard/src/components/FileItem/Buttons/index.js

@@ -7,28 +7,28 @@ const renderEditButton = (props) => (
   !props.uploadInProgressOrComplete &&
   props.metaFields &&
   props.metaFields.length > 0 &&
-  <button
-    class="uppy-u-reset uppy-DashboardItem-action uppy-DashboardItem-action--edit"
-    type="button"
-    aria-label={props.i18n('editFile') + ' ' + props.file.meta.name}
-    title={props.i18n('editFile')}
-    onclick={(e) => props.toggleFileCard(props.file.id)}
-  >
-    {iconPencil()}
-  </button>
+    <button
+      class="uppy-u-reset uppy-DashboardItem-action uppy-DashboardItem-action--edit"
+      type="button"
+      aria-label={props.i18n('editFile') + ' ' + props.file.meta.name}
+      title={props.i18n('editFile')}
+      onclick={(e) => props.toggleFileCard(props.file.id)}
+    >
+      {iconPencil()}
+    </button>
 )
 
 const renderRemoveButton = (props) => (
   props.showRemoveButton &&
-  <button
-    class="uppy-u-reset uppy-DashboardItem-action uppy-DashboardItem-action--remove"
-    type="button"
-    aria-label={props.i18n('removeFile')}
-    title={props.i18n('removeFile')}
-    onclick={() => props.removeFile(props.file.id)}
-  >
-    {iconCross()}
-  </button>
+    <button
+      class="uppy-u-reset uppy-DashboardItem-action uppy-DashboardItem-action--remove"
+      type="button"
+      aria-label={props.i18n('removeFile')}
+      title={props.i18n('removeFile')}
+      onclick={() => props.removeFile(props.file.id)}
+    >
+      {iconCross()}
+    </button>
 )
 
 const copyLinkToClipboard = (event, props) =>
@@ -44,14 +44,15 @@ const copyLinkToClipboard = (event, props) =>
 const renderCopyLinkButton = (props) => (
   props.showLinkToFileUploadResult &&
   props.file.uploadURL &&
-  <button class="uppy-u-reset uppy-DashboardItem-action uppy-DashboardItem-action--copyLink"
-    type="button"
-    aria-label={props.i18n('copyLink')}
-    title={props.i18n('copyLink')}
-    onclick={(event) => copyLinkToClipboard(event, props)}
-  >
-    {iconCopyLink()}
-  </button>
+    <button
+      class="uppy-u-reset uppy-DashboardItem-action uppy-DashboardItem-action--copyLink"
+      type="button"
+      aria-label={props.i18n('copyLink')}
+      title={props.i18n('copyLink')}
+      onclick={(event) => copyLinkToClipboard(event, props)}
+    >
+      {iconCopyLink()}
+    </button>
 )
 
 module.exports = function Buttons (props) {

+ 10 - 10
packages/@uppy/dashboard/src/components/FileItem/FileInfo/index.js

@@ -10,13 +10,13 @@ const renderAcquirerIcon = (acquirer, props) =>
 const renderFileSource = (props) => (
   props.file.source &&
   props.file.source !== props.id &&
-  <div class="uppy-DashboardItem-sourceIcon">
-    {props.acquirers.map(acquirer => {
-      if (acquirer.id === props.file.source) {
-        return renderAcquirerIcon(acquirer, props)
-      }
-    })}
-  </div>
+    <div class="uppy-DashboardItem-sourceIcon">
+      {props.acquirers.map(acquirer => {
+        if (acquirer.id === props.file.source) {
+          return renderAcquirerIcon(acquirer, props)
+        }
+      })}
+    </div>
 )
 
 const renderFileName = (props) => {
@@ -42,9 +42,9 @@ const renderFileName = (props) => {
 
 const renderFileSize = (props) => (
   props.file.data.size &&
-  <div class="uppy-DashboardItem-statusSize">
-    {prettyBytes(props.file.data.size)}
-  </div>
+    <div class="uppy-DashboardItem-statusSize">
+      {prettyBytes(props.file.data.size)}
+    </div>
 )
 
 module.exports = function FileInfo (props) {

+ 7 - 7
packages/@uppy/dashboard/src/components/FileItem/FilePreviewAndLink/index.js

@@ -11,13 +11,13 @@ module.exports = function FilePreviewAndLink (props) {
       {
         props.showLinkToFileUploadResult &&
         props.file.uploadURL &&
-        <a
-          class="uppy-DashboardItem-previewLink"
-          href={props.file.uploadURL}
-          rel="noreferrer noopener"
-          target="_blank"
-          aria-label={props.file.meta.name}
-        />
+          <a
+            class="uppy-DashboardItem-previewLink"
+            href={props.file.uploadURL}
+            rel="noreferrer noopener"
+            target="_blank"
+            aria-label={props.file.meta.name}
+          />
       }
       <FilePreview file={props.file} />
     </div>

+ 9 - 8
packages/@uppy/dashboard/src/components/FileItem/FileProgress/PauseResumeCancelIcon.js

@@ -14,21 +14,22 @@ module.exports = function PauseResumeCancelIcon (props) {
     <svg aria-hidden="true" focusable="false" width="70" height="70" viewBox="0 0 36 36" class="UppyIcon UppyIcon-progressCircle">
       <g class="progress-group">
         <circle class="bg" r="15" cx="18" cy="18" stroke-width="2" fill="none" />
-        <circle class="progress" r="15" cx="18" cy="18" transform="rotate(-90, 18, 18)" stroke-width="2" fill="none"
+        <circle
+          class="progress" r="15" cx="18" cy="18" transform="rotate(-90, 18, 18)" stroke-width="2" fill="none"
           stroke-dasharray={circleLength}
           stroke-dashoffset={circleLength - (circleLength / 100 * props.progress)}
         />
       </g>
       {
         !props.hidePauseResumeCancelButtons &&
-        <g>
-          <polygon class="play" transform="translate(3, 3)" points="12 20 12 10 20 15" />
-          <g class="pause" transform="translate(14.5, 13)">
-            <rect x="0" y="0" width="2" height="10" rx="0" />
-            <rect x="5" y="0" width="2" height="10" rx="0" />
+          <g>
+            <polygon class="play" transform="translate(3, 3)" points="12 20 12 10 20 15" />
+            <g class="pause" transform="translate(14.5, 13)">
+              <rect x="0" y="0" width="2" height="10" rx="0" />
+              <rect x="5" y="0" width="2" height="10" rx="0" />
+            </g>
+            <polygon class="cancel" transform="translate(2, 2)" points="19.8856516 11.0625 16 14.9481516 12.1019737 11.0625 11.0625 12.1143484 14.9481516 16 11.0625 19.8980263 12.1019737 20.9375 16 17.0518484 19.8856516 20.9375 20.9375 19.8980263 17.0518484 16 20.9375 12" />
           </g>
-          <polygon class="cancel" transform="translate(2, 2)" points="19.8856516 11.0625 16 14.9481516 12.1019737 11.0625 11.0625 12.1143484 14.9481516 16 11.0625 19.8980263 12.1019737 20.9375 16 17.0518484 19.8856516 20.9375 20.9375 19.8980263 17.0518484 16 20.9375 12" />
-        </g>
       }
       <polygon class="check" transform="translate(2, 3)" points="14 22.5 7 15.2457065 8.99985857 13.1732815 14 18.3547104 22.9729883 9 25 11.1005634" />
     </svg>

+ 5 - 4
packages/@uppy/dashboard/src/components/FileItem/FileProgress/index.js

@@ -69,13 +69,14 @@ module.exports = function FileProgress (props) {
           title={progressIndicatorTitle(props)}
           onclick={() => onPauseResumeCancelRetry(props)}
         >
-          {props.error
-            ? props.hideRetryButton ? null : iconRetry()
-            : <PauseResumeCancelIcon
+          {props.error ? (
+            props.hideRetryButton ? null : iconRetry()
+          ) : (
+            <PauseResumeCancelIcon
               progress={props.file.progress.percentage}
               hidePauseResumeCancelButtons={props.hidePauseResumeCancelButtons}
             />
-          }
+          )}
         </button>
       </div>
     )

+ 3 - 1
packages/@uppy/dashboard/src/components/FileList.js

@@ -39,9 +39,11 @@ module.exports = (props) => {
     <ul
       class={dashboardFilesClass}
       // making <ul> not focusable for firefox
-      tabindex="-1">
+      tabindex="-1"
+    >
       {Object.keys(props.files).map((fileID) => (
         <FileItem
+          key={fileID}
           {...fileProps}
           file={props.files[fileID]}
         />

+ 9 - 4
packages/@uppy/dashboard/src/components/PickerPanelContent.js

@@ -3,21 +3,26 @@ const ignoreEvent = require('../utils/ignoreEvent.js')
 
 function PickerPanelContent (props) {
   return (
-    <div class="uppy-DashboardContent-panel"
+    <div
+      class="uppy-DashboardContent-panel"
       role="tabpanel"
       data-uppy-panelType="PickerPanel"
       id={`uppy-DashboardContent-panel--${props.activePickerPanel.id}`}
       onDragOver={ignoreEvent}
       onDragLeave={ignoreEvent}
       onDrop={ignoreEvent}
-      onPaste={ignoreEvent}>
+      onPaste={ignoreEvent}
+    >
       <div class="uppy-DashboardContent-bar">
         <div class="uppy-DashboardContent-title" role="heading" aria-level="h1">
           {props.i18n('importFrom', { name: props.activePickerPanel.name })}
         </div>
-        <button class="uppy-DashboardContent-back"
+        <button
+          class="uppy-DashboardContent-back"
           type="button"
-          onclick={props.hideAllPanels}>{props.i18n('done')}</button>
+          onclick={props.hideAllPanels}
+        >{props.i18n('done')}
+        </button>
       </div>
       <div class="uppy-DashboardContent-panelBody">
         {props.getPlugin(props.activePickerPanel.id).render(props.state)}

+ 25 - 25
packages/@uppy/dashboard/src/components/PickerPanelTopBar.js

@@ -78,36 +78,36 @@ function PanelTopBar (props) {
 
   return (
     <div class="uppy-DashboardContent-bar">
-      { // always on the left
-        !props.isAllComplete
-          ? <button
-            class="uppy-DashboardContent-back"
-            type="button"
-            onclick={props.cancelAll}
-          >
-            {props.i18n('cancel')}
-          </button>
-          : <div />
-      }
+      {!props.isAllComplete ? (
+        <button
+          class="uppy-DashboardContent-back"
+          type="button"
+          onclick={props.cancelAll}
+        >
+          {props.i18n('cancel')}
+        </button>
+      ) : (
+        <div />
+      )}
 
       <div class="uppy-DashboardContent-title" role="heading" aria-level="h1">
         <UploadStatus {...props} />
       </div>
 
-      { // always on the right
-        allowNewUpload
-          ? <button
-            class="uppy-DashboardContent-addMore"
-            type="button"
-            aria-label={props.i18n('addMoreFiles')}
-            title={props.i18n('addMoreFiles')}
-            onclick={() => props.toggleAddFilesPanel(true)}
-          >
-            {iconPlus()}
-            <span class="uppy-DashboardContent-addMoreCaption">{props.i18n('addMore')}</span>
-          </button>
-          : <div />
-      }
+      {allowNewUpload ? (
+        <button
+          class="uppy-DashboardContent-addMore"
+          type="button"
+          aria-label={props.i18n('addMoreFiles')}
+          title={props.i18n('addMoreFiles')}
+          onclick={() => props.toggleAddFilesPanel(true)}
+        >
+          {iconPlus()}
+          <span class="uppy-DashboardContent-addMoreCaption">{props.i18n('addMore')}</span>
+        </button>
+      ) : (
+        <div />
+      )}
     </div>
   )
 }

+ 92 - 60
packages/@uppy/dashboard/src/components/icons.js

@@ -3,111 +3,143 @@ const { h } = require('preact')
 // https://css-tricks.com/creating-svg-icon-system-react/
 
 function defaultPickerIcon () {
-  return <svg aria-hidden="true" focusable="false" width="30" height="30" viewBox="0 0 30 30">
-    <path d="M15 30c8.284 0 15-6.716 15-15 0-8.284-6.716-15-15-15C6.716 0 0 6.716 0 15c0 8.284 6.716 15 15 15zm4.258-12.676v6.846h-8.426v-6.846H5.204l9.82-12.364 9.82 12.364H19.26z" />
-  </svg>
+  return (
+    <svg aria-hidden="true" focusable="false" width="30" height="30" viewBox="0 0 30 30">
+      <path d="M15 30c8.284 0 15-6.716 15-15 0-8.284-6.716-15-15-15C6.716 0 0 6.716 0 15c0 8.284 6.716 15 15 15zm4.258-12.676v6.846h-8.426v-6.846H5.204l9.82-12.364 9.82 12.364H19.26z" />
+    </svg>
+  )
 }
 
 function iconCopy () {
-  return <svg aria-hidden="true" focusable="false" class="UppyIcon" width="51" height="51" viewBox="0 0 51 51">
-    <path d="M17.21 45.765a5.394 5.394 0 0 1-7.62 0l-4.12-4.122a5.393 5.393 0 0 1 0-7.618l6.774-6.775-2.404-2.404-6.775 6.776c-3.424 3.427-3.424 9 0 12.426l4.12 4.123a8.766 8.766 0 0 0 6.216 2.57c2.25 0 4.5-.858 6.214-2.57l13.55-13.552a8.72 8.72 0 0 0 2.575-6.213 8.73 8.73 0 0 0-2.575-6.213l-4.123-4.12-2.404 2.404 4.123 4.12a5.352 5.352 0 0 1 1.58 3.81c0 1.438-.562 2.79-1.58 3.808l-13.55 13.55z" />
-    <path d="M44.256 2.858A8.728 8.728 0 0 0 38.043.283h-.002a8.73 8.73 0 0 0-6.212 2.574l-13.55 13.55a8.725 8.725 0 0 0-2.575 6.214 8.73 8.73 0 0 0 2.574 6.216l4.12 4.12 2.405-2.403-4.12-4.12a5.357 5.357 0 0 1-1.58-3.812c0-1.437.562-2.79 1.58-3.808l13.55-13.55a5.348 5.348 0 0 1 3.81-1.58c1.44 0 2.792.562 3.81 1.58l4.12 4.12c2.1 2.1 2.1 5.518 0 7.617L39.2 23.775l2.404 2.404 6.775-6.777c3.426-3.427 3.426-9 0-12.426l-4.12-4.12z" />
-  </svg>
+  return (
+    <svg aria-hidden="true" focusable="false" class="UppyIcon" width="51" height="51" viewBox="0 0 51 51">
+      <path d="M17.21 45.765a5.394 5.394 0 0 1-7.62 0l-4.12-4.122a5.393 5.393 0 0 1 0-7.618l6.774-6.775-2.404-2.404-6.775 6.776c-3.424 3.427-3.424 9 0 12.426l4.12 4.123a8.766 8.766 0 0 0 6.216 2.57c2.25 0 4.5-.858 6.214-2.57l13.55-13.552a8.72 8.72 0 0 0 2.575-6.213 8.73 8.73 0 0 0-2.575-6.213l-4.123-4.12-2.404 2.404 4.123 4.12a5.352 5.352 0 0 1 1.58 3.81c0 1.438-.562 2.79-1.58 3.808l-13.55 13.55z" />
+      <path d="M44.256 2.858A8.728 8.728 0 0 0 38.043.283h-.002a8.73 8.73 0 0 0-6.212 2.574l-13.55 13.55a8.725 8.725 0 0 0-2.575 6.214 8.73 8.73 0 0 0 2.574 6.216l4.12 4.12 2.405-2.403-4.12-4.12a5.357 5.357 0 0 1-1.58-3.812c0-1.437.562-2.79 1.58-3.808l13.55-13.55a5.348 5.348 0 0 1 3.81-1.58c1.44 0 2.792.562 3.81 1.58l4.12 4.12c2.1 2.1 2.1 5.518 0 7.617L39.2 23.775l2.404 2.404 6.775-6.777c3.426-3.427 3.426-9 0-12.426l-4.12-4.12z" />
+    </svg>
+  )
 }
 
 function iconResume () {
-  return <svg aria-hidden="true" focusable="false" class="UppyIcon" width="25" height="25" viewBox="0 0 44 44">
-    <polygon class="play" transform="translate(6, 5.5)" points="13 21.6666667 13 11 21 16.3333333" />
-  </svg>
+  return (
+    <svg aria-hidden="true" focusable="false" class="UppyIcon" width="25" height="25" viewBox="0 0 44 44">
+      <polygon class="play" transform="translate(6, 5.5)" points="13 21.6666667 13 11 21 16.3333333" />
+    </svg>
+  )
 }
 
 function iconPause () {
-  return <svg aria-hidden="true" focusable="false" class="UppyIcon" width="25px" height="25px" viewBox="0 0 44 44">
-    <g transform="translate(18, 17)" class="pause">
-      <rect x="0" y="0" width="2" height="10" rx="0" />
-      <rect x="6" y="0" width="2" height="10" rx="0" />
-    </g>
-  </svg>
+  return (
+    <svg aria-hidden="true" focusable="false" class="UppyIcon" width="25px" height="25px" viewBox="0 0 44 44">
+      <g transform="translate(18, 17)" class="pause">
+        <rect x="0" y="0" width="2" height="10" rx="0" />
+        <rect x="6" y="0" width="2" height="10" rx="0" />
+      </g>
+    </svg>
+  )
 }
 
 function localIcon () {
-  return <svg aria-hidden="true" focusable="false" fill="#607d8b" width="27" height="25" viewBox="0 0 27 25">
-    <path d="M5.586 9.288a.313.313 0 0 0 .282.176h4.84v3.922c0 1.514 1.25 2.24 2.792 2.24 1.54 0 2.79-.726 2.79-2.24V9.464h4.84c.122 0 .23-.068.284-.176a.304.304 0 0 0-.046-.324L13.735.106a.316.316 0 0 0-.472 0l-7.63 8.857a.302.302 0 0 0-.047.325z" />
-    <path d="M24.3 5.093c-.218-.76-.54-1.187-1.208-1.187h-4.856l1.018 1.18h3.948l2.043 11.038h-7.193v2.728H9.114v-2.725h-7.36l2.66-11.04h3.33l1.018-1.18H3.907c-.668 0-1.06.46-1.21 1.186L0 16.456v7.062C0 24.338.676 25 1.51 25h23.98c.833 0 1.51-.663 1.51-1.482v-7.062L24.3 5.093z" />
-  </svg>
+  return (
+    <svg aria-hidden="true" focusable="false" fill="#607d8b" width="27" height="25" viewBox="0 0 27 25">
+      <path d="M5.586 9.288a.313.313 0 0 0 .282.176h4.84v3.922c0 1.514 1.25 2.24 2.792 2.24 1.54 0 2.79-.726 2.79-2.24V9.464h4.84c.122 0 .23-.068.284-.176a.304.304 0 0 0-.046-.324L13.735.106a.316.316 0 0 0-.472 0l-7.63 8.857a.302.302 0 0 0-.047.325z" />
+      <path d="M24.3 5.093c-.218-.76-.54-1.187-1.208-1.187h-4.856l1.018 1.18h3.948l2.043 11.038h-7.193v2.728H9.114v-2.725h-7.36l2.66-11.04h3.33l1.018-1.18H3.907c-.668 0-1.06.46-1.21 1.186L0 16.456v7.062C0 24.338.676 25 1.51 25h23.98c.833 0 1.51-.663 1.51-1.482v-7.062L24.3 5.093z" />
+    </svg>
+  )
 }
 
 function iconRetry () {
-  return <svg aria-hidden="true" focusable="false" class="UppyIcon retry" width="28" height="31" viewBox="0 0 16 19">
-    <path d="M16 11a8 8 0 1 1-8-8v2a6 6 0 1 0 6 6h2z" />
-    <path d="M7.9 3H10v2H7.9z" />
-    <path d="M8.536.5l3.535 3.536-1.414 1.414L7.12 1.914z" />
-    <path d="M10.657 2.621l1.414 1.415L8.536 7.57 7.12 6.157z" />
-  </svg>
+  return (
+    <svg aria-hidden="true" focusable="false" class="UppyIcon retry" width="28" height="31" viewBox="0 0 16 19">
+      <path d="M16 11a8 8 0 1 1-8-8v2a6 6 0 1 0 6 6h2z" />
+      <path d="M7.9 3H10v2H7.9z" />
+      <path d="M8.536.5l3.535 3.536-1.414 1.414L7.12 1.914z" />
+      <path d="M10.657 2.621l1.414 1.415L8.536 7.57 7.12 6.157z" />
+    </svg>
+  )
 }
 
 function checkIcon () {
-  return <svg aria-hidden="true" focusable="false" class="UppyIcon UppyIcon-check" width="13" height="9" viewBox="0 0 13 9">
-    <polygon points="5 7.293 1.354 3.647 0.646 4.354 5 8.707 12.354 1.354 11.646 0.647" />
-  </svg>
+  return (
+    <svg aria-hidden="true" focusable="false" class="UppyIcon UppyIcon-check" width="13" height="9" viewBox="0 0 13 9">
+      <polygon points="5 7.293 1.354 3.647 0.646 4.354 5 8.707 12.354 1.354 11.646 0.647" />
+    </svg>
+  )
 }
 
 function iconAudio () {
-  return <svg aria-hidden="true" focusable="false" class="UppyIcon" width="25" height="25" viewBox="0 0 25 25">
-    <path d="M9.5 18.64c0 1.14-1.145 2-2.5 2s-2.5-.86-2.5-2c0-1.14 1.145-2 2.5-2 .557 0 1.079.145 1.5.396V7.25a.5.5 0 0 1 .379-.485l9-2.25A.5.5 0 0 1 18.5 5v11.64c0 1.14-1.145 2-2.5 2s-2.5-.86-2.5-2c0-1.14 1.145-2 2.5-2 .557 0 1.079.145 1.5.396V8.67l-8 2v7.97zm8-11v-2l-8 2v2l8-2zM7 19.64c.855 0 1.5-.484 1.5-1s-.645-1-1.5-1-1.5.484-1.5 1 .645 1 1.5 1zm9-2c.855 0 1.5-.484 1.5-1s-.645-1-1.5-1-1.5.484-1.5 1 .645 1 1.5 1z" fill="#049BCF" fill-rule="nonzero" />
-  </svg>
+  return (
+    <svg aria-hidden="true" focusable="false" class="UppyIcon" width="25" height="25" viewBox="0 0 25 25">
+      <path d="M9.5 18.64c0 1.14-1.145 2-2.5 2s-2.5-.86-2.5-2c0-1.14 1.145-2 2.5-2 .557 0 1.079.145 1.5.396V7.25a.5.5 0 0 1 .379-.485l9-2.25A.5.5 0 0 1 18.5 5v11.64c0 1.14-1.145 2-2.5 2s-2.5-.86-2.5-2c0-1.14 1.145-2 2.5-2 .557 0 1.079.145 1.5.396V8.67l-8 2v7.97zm8-11v-2l-8 2v2l8-2zM7 19.64c.855 0 1.5-.484 1.5-1s-.645-1-1.5-1-1.5.484-1.5 1 .645 1 1.5 1zm9-2c.855 0 1.5-.484 1.5-1s-.645-1-1.5-1-1.5.484-1.5 1 .645 1 1.5 1z" fill="#049BCF" fill-rule="nonzero" />
+    </svg>
+  )
 }
 
 function iconVideo () {
-  return <svg aria-hidden="true" focusable="false" class="UppyIcon" width="25" height="25" viewBox="0 0 25 25">
-    <path d="M16 11.834l4.486-2.691A1 1 0 0 1 22 10v6a1 1 0 0 1-1.514.857L16 14.167V17a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v2.834zM15 9H5v8h10V9zm1 4l5 3v-6l-5 3z" fill="#19AF67" fill-rule="nonzero" />
-  </svg>
+  return (
+    <svg aria-hidden="true" focusable="false" class="UppyIcon" width="25" height="25" viewBox="0 0 25 25">
+      <path d="M16 11.834l4.486-2.691A1 1 0 0 1 22 10v6a1 1 0 0 1-1.514.857L16 14.167V17a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v2.834zM15 9H5v8h10V9zm1 4l5 3v-6l-5 3z" fill="#19AF67" fill-rule="nonzero" />
+    </svg>
+  )
 }
 
 function iconPDF () {
-  return <svg aria-hidden="true" focusable="false" class="UppyIcon" width="25" height="25" viewBox="0 0 25 25">
-    <path d="M9.766 8.295c-.691-1.843-.539-3.401.747-3.726 1.643-.414 2.505.938 2.39 3.299-.039.79-.194 1.662-.537 3.148.324.49.66.967 1.055 1.51.17.231.382.488.629.757 1.866-.128 3.653.114 4.918.655 1.487.635 2.192 1.685 1.614 2.84-.566 1.133-1.839 1.084-3.416.249-1.141-.604-2.457-1.634-3.51-2.707a13.467 13.467 0 0 0-2.238.426c-1.392 4.051-4.534 6.453-5.707 4.572-.986-1.58 1.38-4.206 4.914-5.375.097-.322.185-.656.264-1.001.08-.353.306-1.31.407-1.737-.678-1.059-1.2-2.031-1.53-2.91zm2.098 4.87c-.033.144-.068.287-.104.427l.033-.01-.012.038a14.065 14.065 0 0 1 1.02-.197l-.032-.033.052-.004a7.902 7.902 0 0 1-.208-.271c-.197-.27-.38-.526-.555-.775l-.006.028-.002-.003c-.076.323-.148.632-.186.8zm5.77 2.978c1.143.605 1.832.632 2.054.187.26-.519-.087-1.034-1.113-1.473-.911-.39-2.175-.608-3.55-.608.845.766 1.787 1.459 2.609 1.894zM6.559 18.789c.14.223.693.16 1.425-.413.827-.648 1.61-1.747 2.208-3.206-2.563 1.064-4.102 2.867-3.633 3.62zm5.345-10.97c.088-1.793-.351-2.48-1.146-2.28-.473.119-.564 1.05-.056 2.405.213.566.52 1.188.908 1.859.18-.858.268-1.453.294-1.984z" fill="#E2514A" fill-rule="nonzero" />
-  </svg>
+  return (
+    <svg aria-hidden="true" focusable="false" class="UppyIcon" width="25" height="25" viewBox="0 0 25 25">
+      <path d="M9.766 8.295c-.691-1.843-.539-3.401.747-3.726 1.643-.414 2.505.938 2.39 3.299-.039.79-.194 1.662-.537 3.148.324.49.66.967 1.055 1.51.17.231.382.488.629.757 1.866-.128 3.653.114 4.918.655 1.487.635 2.192 1.685 1.614 2.84-.566 1.133-1.839 1.084-3.416.249-1.141-.604-2.457-1.634-3.51-2.707a13.467 13.467 0 0 0-2.238.426c-1.392 4.051-4.534 6.453-5.707 4.572-.986-1.58 1.38-4.206 4.914-5.375.097-.322.185-.656.264-1.001.08-.353.306-1.31.407-1.737-.678-1.059-1.2-2.031-1.53-2.91zm2.098 4.87c-.033.144-.068.287-.104.427l.033-.01-.012.038a14.065 14.065 0 0 1 1.02-.197l-.032-.033.052-.004a7.902 7.902 0 0 1-.208-.271c-.197-.27-.38-.526-.555-.775l-.006.028-.002-.003c-.076.323-.148.632-.186.8zm5.77 2.978c1.143.605 1.832.632 2.054.187.26-.519-.087-1.034-1.113-1.473-.911-.39-2.175-.608-3.55-.608.845.766 1.787 1.459 2.609 1.894zM6.559 18.789c.14.223.693.16 1.425-.413.827-.648 1.61-1.747 2.208-3.206-2.563 1.064-4.102 2.867-3.633 3.62zm5.345-10.97c.088-1.793-.351-2.48-1.146-2.28-.473.119-.564 1.05-.056 2.405.213.566.52 1.188.908 1.859.18-.858.268-1.453.294-1.984z" fill="#E2514A" fill-rule="nonzero" />
+    </svg>
+  )
 }
 
 function iconFile () {
-  return <svg aria-hidden="true" focusable="false" class="UppyIcon" width="25" height="25" viewBox="0 0 25 25">
-    <g fill="#A7AFB7" fill-rule="nonzero">
-      <path d="M5.5 22a.5.5 0 0 1-.5-.5v-18a.5.5 0 0 1 .5-.5h10.719a.5.5 0 0 1 .367.16l3.281 3.556a.5.5 0 0 1 .133.339V21.5a.5.5 0 0 1-.5.5h-14zm.5-1h13V7.25L16 4H6v17z" />
-      <path d="M15 4v3a1 1 0 0 0 1 1h3V7h-3V4h-1z" />
-    </g>
-  </svg>
+  return (
+    <svg aria-hidden="true" focusable="false" class="UppyIcon" width="25" height="25" viewBox="0 0 25 25">
+      <g fill="#A7AFB7" fill-rule="nonzero">
+        <path d="M5.5 22a.5.5 0 0 1-.5-.5v-18a.5.5 0 0 1 .5-.5h10.719a.5.5 0 0 1 .367.16l3.281 3.556a.5.5 0 0 1 .133.339V21.5a.5.5 0 0 1-.5.5h-14zm.5-1h13V7.25L16 4H6v17z" />
+        <path d="M15 4v3a1 1 0 0 0 1 1h3V7h-3V4h-1z" />
+      </g>
+    </svg>
+  )
 }
 
 function iconText () {
-  return <svg aria-hidden="true" focusable="false" class="UppyIcon" width="25" height="25" viewBox="0 0 25 25">
-    <path d="M4.5 7h13a.5.5 0 1 1 0 1h-13a.5.5 0 0 1 0-1zm0 3h15a.5.5 0 1 1 0 1h-15a.5.5 0 1 1 0-1zm0 3h15a.5.5 0 1 1 0 1h-15a.5.5 0 1 1 0-1zm0 3h10a.5.5 0 1 1 0 1h-10a.5.5 0 1 1 0-1z" fill="#5A5E69" fill-rule="nonzero" />
-  </svg>
+  return (
+    <svg aria-hidden="true" focusable="false" class="UppyIcon" width="25" height="25" viewBox="0 0 25 25">
+      <path d="M4.5 7h13a.5.5 0 1 1 0 1h-13a.5.5 0 0 1 0-1zm0 3h15a.5.5 0 1 1 0 1h-15a.5.5 0 1 1 0-1zm0 3h15a.5.5 0 1 1 0 1h-15a.5.5 0 1 1 0-1zm0 3h10a.5.5 0 1 1 0 1h-10a.5.5 0 1 1 0-1z" fill="#5A5E69" fill-rule="nonzero" />
+    </svg>
+  )
 }
 
 function iconCopyLink () {
-  return <svg aria-hidden="true" focusable="false" class="UppyIcon" width="14" height="14" viewBox="0 0 14 12">
-    <path d="M7.94 7.703a2.613 2.613 0 0 1-.626 2.681l-.852.851a2.597 2.597 0 0 1-1.849.766A2.616 2.616 0 0 1 2.764 7.54l.852-.852a2.596 2.596 0 0 1 2.69-.625L5.267 7.099a1.44 1.44 0 0 0-.833.407l-.852.851a1.458 1.458 0 0 0 1.03 2.486c.39 0 .755-.152 1.03-.426l.852-.852c.231-.231.363-.522.406-.824l1.04-1.038zm4.295-5.937A2.596 2.596 0 0 0 10.387 1c-.698 0-1.355.272-1.849.766l-.852.851a2.614 2.614 0 0 0-.624 2.688l1.036-1.036c.041-.304.173-.6.407-.833l.852-.852c.275-.275.64-.426 1.03-.426a1.458 1.458 0 0 1 1.03 2.486l-.852.851a1.442 1.442 0 0 1-.824.406l-1.04 1.04a2.596 2.596 0 0 0 2.683-.628l.851-.85a2.616 2.616 0 0 0 0-3.697zm-6.88 6.883a.577.577 0 0 0 .82 0l3.474-3.474a.579.579 0 1 0-.819-.82L5.355 7.83a.579.579 0 0 0 0 .819z" />
-  </svg>
+  return (
+    <svg aria-hidden="true" focusable="false" class="UppyIcon" width="14" height="14" viewBox="0 0 14 12">
+      <path d="M7.94 7.703a2.613 2.613 0 0 1-.626 2.681l-.852.851a2.597 2.597 0 0 1-1.849.766A2.616 2.616 0 0 1 2.764 7.54l.852-.852a2.596 2.596 0 0 1 2.69-.625L5.267 7.099a1.44 1.44 0 0 0-.833.407l-.852.851a1.458 1.458 0 0 0 1.03 2.486c.39 0 .755-.152 1.03-.426l.852-.852c.231-.231.363-.522.406-.824l1.04-1.038zm4.295-5.937A2.596 2.596 0 0 0 10.387 1c-.698 0-1.355.272-1.849.766l-.852.851a2.614 2.614 0 0 0-.624 2.688l1.036-1.036c.041-.304.173-.6.407-.833l.852-.852c.275-.275.64-.426 1.03-.426a1.458 1.458 0 0 1 1.03 2.486l-.852.851a1.442 1.442 0 0 1-.824.406l-1.04 1.04a2.596 2.596 0 0 0 2.683-.628l.851-.85a2.616 2.616 0 0 0 0-3.697zm-6.88 6.883a.577.577 0 0 0 .82 0l3.474-3.474a.579.579 0 1 0-.819-.82L5.355 7.83a.579.579 0 0 0 0 .819z" />
+    </svg>
+  )
 }
 
 function iconPencil () {
-  return <svg aria-hidden="true" focusable="false" class="UppyIcon" width="14" height="14" viewBox="0 0 14 14">
-    <g fill-rule="evenodd"><path d="M1.5 10.793h2.793A1 1 0 0 0 5 10.5L11.5 4a1 1 0 0 0 0-1.414L9.707.793a1 1 0 0 0-1.414 0l-6.5 6.5A1 1 0 0 0 1.5 8v2.793zm1-1V8L9 1.5l1.793 1.793-6.5 6.5H2.5z" fill-rule="nonzero" /><rect x="1" y="12.293" width="11" height="1" rx=".5" /><path fill-rule="nonzero" d="M6.793 2.5L9.5 5.207l.707-.707L7.5 1.793z" /></g>
-  </svg>
+  return (
+    <svg aria-hidden="true" focusable="false" class="UppyIcon" width="14" height="14" viewBox="0 0 14 14">
+      <g fill-rule="evenodd"><path d="M1.5 10.793h2.793A1 1 0 0 0 5 10.5L11.5 4a1 1 0 0 0 0-1.414L9.707.793a1 1 0 0 0-1.414 0l-6.5 6.5A1 1 0 0 0 1.5 8v2.793zm1-1V8L9 1.5l1.793 1.793-6.5 6.5H2.5z" fill-rule="nonzero" /><rect x="1" y="12.293" width="11" height="1" rx=".5" /><path fill-rule="nonzero" d="M6.793 2.5L9.5 5.207l.707-.707L7.5 1.793z" /></g>
+    </svg>
+  )
 }
 
 function iconCross () {
-  return <svg aria-hidden="true" focusable="false" class="UppyIcon" width="18" height="18" viewBox="0 0 18 18">
-    <path d="M9 0C4.034 0 0 4.034 0 9s4.034 9 9 9 9-4.034 9-9-4.034-9-9-9z" />
-    <path fill="#FFF" d="M13 12.222l-.778.778L9 9.778 5.778 13 5 12.222 8.222 9 5 5.778 5.778 5 9 8.222 12.222 5l.778.778L9.778 9z" />
-  </svg>
+  return (
+    <svg aria-hidden="true" focusable="false" class="UppyIcon" width="18" height="18" viewBox="0 0 18 18">
+      <path d="M9 0C4.034 0 0 4.034 0 9s4.034 9 9 9 9-4.034 9-9-4.034-9-9-9z" />
+      <path fill="#FFF" d="M13 12.222l-.778.778L9 9.778 5.778 13 5 12.222 8.222 9 5 5.778 5.778 5 9 8.222 12.222 5l.778.778L9.778 9z" />
+    </svg>
+  )
 }
 
 function iconPlus () {
-  return <svg aria-hidden="true" focusable="false" class="UppyIcon" width="15" height="15" viewBox="0 0 15 15">
-    <path d="M8 6.5h6a.5.5 0 0 1 .5.5v.5a.5.5 0 0 1-.5.5H8v6a.5.5 0 0 1-.5.5H7a.5.5 0 0 1-.5-.5V8h-6a.5.5 0 0 1-.5-.5V7a.5.5 0 0 1 .5-.5h6v-6A.5.5 0 0 1 7 0h.5a.5.5 0 0 1 .5.5v6z" />
-  </svg>
+  return (
+    <svg aria-hidden="true" focusable="false" class="UppyIcon" width="15" height="15" viewBox="0 0 15 15">
+      <path d="M8 6.5h6a.5.5 0 0 1 .5.5v.5a.5.5 0 0 1-.5.5H8v6a.5.5 0 0 1-.5.5H7a.5.5 0 0 1-.5-.5V8h-6a.5.5 0 0 1-.5-.5V7a.5.5 0 0 1 .5-.5h6v-6A.5.5 0 0 1 7 0h.5a.5.5 0 0 1 .5.5v6z" />
+    </svg>
+  )
 }
 
 module.exports = {

+ 1 - 1
packages/@uppy/dashboard/src/utils/createSuperFocus.js

@@ -19,7 +19,7 @@ module.exports = function createSuperFocus () {
     // [Practical check] without this line, typing in the search input in googledrive overlay won't work.
     if (isFocusInOverlay && lastFocusWasOnSuperFocusableEl) return
 
-    const superFocusableEl = overlayEl.querySelector(`[data-uppy-super-focusable]`)
+    const superFocusableEl = overlayEl.querySelector('[data-uppy-super-focusable]')
     // If we are already in the topmost overlay, AND there are no super focusable elements yet, - leave focus up to the user.
     // [Practical check] without this line, if you are in an empty folder in google drive, and something's uploading in the bg, - focus will be jumping to Done all the time.
     if (isFocusInOverlay && !superFocusableEl) return

+ 4 - 2
packages/@uppy/drag-drop/src/index.js

@@ -139,7 +139,8 @@ module.exports = class DragDrop extends Plugin {
         name={this.opts.inputName}
         multiple={restrictions.maxNumberOfFiles !== 1}
         accept={restrictions.allowedFileTypes}
-        onchange={this.handleInputChange} />
+        onchange={this.handleInputChange}
+      />
     )
   }
 
@@ -189,7 +190,8 @@ module.exports = class DragDrop extends Plugin {
         onClick={() => this.fileInputRef.click()}
         onDragOver={this.handleDragOver}
         onDragLeave={this.handleDragLeave}
-        onDrop={this.handleDrop} >
+        onDrop={this.handleDrop}
+      >
         {this.renderHiddenFileInput()}
         <div class="uppy-DragDrop-inner">
           {this.renderArrowSvg()}

+ 12 - 6
packages/@uppy/facebook/src/index.js

@@ -12,14 +12,20 @@ module.exports = class Facebook extends Plugin {
     Provider.initPlugin(this, opts)
     this.title = this.opts.title || 'Facebook'
     this.icon = () => (
-      <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
-        width="266.893px" height="266.895px" viewBox="0 0 266.893 266.895" enable-background="new 0 0 266.893 266.895">
-        <path id="Blue_1_" fill="#3C5A99" d="M248.082,262.307c7.854,0,14.223-6.369,14.223-14.225V18.812
+      <svg
+        version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
+        width="266.893px" height="266.895px" viewBox="0 0 266.893 266.895" enable-background="new 0 0 266.893 266.895"
+      >
+        <path
+          id="Blue_1_" fill="#3C5A99" d="M248.082,262.307c7.854,0,14.223-6.369,14.223-14.225V18.812
           c0-7.857-6.368-14.224-14.223-14.224H18.812c-7.857,0-14.224,6.367-14.224,14.224v229.27c0,7.855,6.366,14.225,14.224,14.225
-          H248.082z" />
-        <path id="f" fill="#FFFFFF" d="M182.409,262.307v-99.803h33.499l5.016-38.895h-38.515V98.777c0-11.261,3.127-18.935,19.275-18.935
+          H248.082z"
+        />
+        <path
+          id="f" fill="#FFFFFF" d="M182.409,262.307v-99.803h33.499l5.016-38.895h-38.515V98.777c0-11.261,3.127-18.935,19.275-18.935
           l20.596-0.009V45.045c-3.562-0.474-15.788-1.533-30.012-1.533c-29.695,0-50.025,18.126-50.025,51.413v28.684h-33.585v38.895h33.585
-          v99.803H182.409z" />
+          v99.803H182.409z"
+        />
       </svg>
     )
 

+ 9 - 6
packages/@uppy/file-input/src/index.js

@@ -90,21 +90,24 @@ module.exports = class FileInput extends Plugin {
 
     return (
       <div class="uppy-Root uppy-FileInput-container">
-        <input class="uppy-FileInput-input"
+        <input
+          class="uppy-FileInput-input"
           style={this.opts.pretty && hiddenInputStyle}
           type="file"
           name={this.opts.inputName}
           onchange={this.handleInputChange}
           multiple={restrictions.maxNumberOfFiles !== 1}
           accept={accept}
-          ref={(input) => { this.input = input }} />
+          ref={(input) => { this.input = input }}
+        />
         {this.opts.pretty &&
-          <button class="uppy-FileInput-btn"
+          <button
+            class="uppy-FileInput-btn"
             type="button"
-            onclick={this.handleClick}>
+            onclick={this.handleClick}
+          >
             {this.i18n('chooseFiles')}
-          </button>
-        }
+          </button>}
       </div>
     )
   }

+ 14 - 8
packages/@uppy/informer/src/index.js

@@ -30,17 +30,23 @@ module.exports = class Informer extends Plugin {
     const { isHidden, message, details } = state.info
 
     return (
-      <div class="uppy uppy-Informer"
-        aria-hidden={isHidden}>
+      <div
+        class="uppy uppy-Informer"
+        aria-hidden={isHidden}
+      >
         <p role="alert">
           {message}
           {' '}
-          {details && <span
-            aria-label={details}
-            data-microtip-position="top-left"
-            data-microtip-size="medium"
-            role="tooltip">?</span>
-          }
+          {details && (
+            <span
+              aria-label={details}
+              data-microtip-position="top-left"
+              data-microtip-size="medium"
+              role="tooltip"
+            >
+              ?
+            </span>
+          )}
         </p>
       </div>
     )

+ 10 - 4
packages/@uppy/progress-bar/src/index.js

@@ -31,10 +31,16 @@ module.exports = class ProgressBar extends Plugin {
   render (state) {
     const progress = state.totalProgress || 0
     const isHidden = progress === 100 && this.opts.hideAfterFinish
-    return <div class="uppy uppy-ProgressBar" style={{ position: this.opts.fixed ? 'fixed' : 'initial' }} aria-hidden={isHidden}>
-      <div class="uppy-ProgressBar-inner" style={{ width: progress + '%' }} />
-      <div class="uppy-ProgressBar-percentage">{progress}</div>
-    </div>
+    return (
+      <div
+        class="uppy uppy-ProgressBar"
+        style={{ position: this.opts.fixed ? 'fixed' : 'initial' }}
+        aria-hidden={isHidden}
+      >
+        <div class="uppy-ProgressBar-inner" style={{ width: progress + '%' }} />
+        <div class="uppy-ProgressBar-percentage">{progress}</div>
+      </div>
+    )
   }
 
   install () {

+ 15 - 13
packages/@uppy/provider-views/src/AuthView.js

@@ -5,20 +5,22 @@ class AuthView extends Component {
     const pluginNameComponent = (
       <span class="uppy-Provider-authTitleName">{this.props.pluginName}<br /></span>
     )
-    return <div class="uppy-Provider-auth">
-      <div class="uppy-Provider-authIcon">{this.props.pluginIcon()}</div>
-      <div class="uppy-Provider-authTitle">
-        {this.props.i18nArray('authenticateWithTitle', { pluginName: pluginNameComponent })}
+    return (
+      <div class="uppy-Provider-auth">
+        <div class="uppy-Provider-authIcon">{this.props.pluginIcon()}</div>
+        <div class="uppy-Provider-authTitle">
+          {this.props.i18nArray('authenticateWithTitle', { pluginName: pluginNameComponent })}
+        </div>
+        <button
+          type="button"
+          class="uppy-u-reset uppy-c-btn uppy-c-btn-primary uppy-Provider-authBtn"
+          onclick={this.props.handleAuth}
+          data-uppy-super-focusable
+        >
+          {this.props.i18nArray('authenticateWith', { pluginName: this.props.pluginName })}
+        </button>
       </div>
-      <button
-        type="button"
-        class="uppy-u-reset uppy-c-btn uppy-c-btn-primary uppy-Provider-authBtn"
-        onclick={this.props.handleAuth}
-        data-uppy-super-focusable
-      >
-        {this.props.i18nArray('authenticateWith', { pluginName: this.props.pluginName })}
-      </button>
-    </div>
+    )
   }
 }
 

+ 14 - 8
packages/@uppy/provider-views/src/Breadcrumbs.js

@@ -1,26 +1,32 @@
 const { h } = require('preact')
 
+// TODO use Fragment when upgrading to preact X
+/* eslint-disable react/jsx-key */
 const Breadcrumb = (props) => [
   <button
     type="button"
     class="uppy-u-reset"
-    onclick={props.getFolder}>{props.title}
+    onclick={props.getFolder}
+  >
+    {props.title}
   </button>,
   !props.isLast ? ' / ' : ''
 ]
+/* eslint-enable react/jsx-key */
 
 module.exports = (props) => {
   return (
     <div class="uppy-Provider-breadcrumbs">
       <div class="uppy-Provider-breadcrumbsIcon">{props.breadcrumbsIcon}</div>
       {
-        props.directories.map((directory, i) => {
-          return Breadcrumb({
-            getFolder: () => props.getFolder(directory.id),
-            title: i === 0 ? props.title : directory.title,
-            isLast: i + 1 === props.directories.length
-          })
-        })
+        props.directories.map((directory, i) => (
+          <Breadcrumb
+            key={directory.id}
+            getFolder={() => props.getFolder(directory.id)}
+            title={i === 0 ? props.title : directory.title}
+            isLast={i + 1 === props.directories.length}
+          />
+        ))
       }
     </div>
   )

+ 1 - 1
packages/@uppy/provider-views/src/Browser.js

@@ -32,7 +32,7 @@ const Browser = (props) => {
           </button>
         </div>
       </div>
-      { props.showFilter && <Filter {...props} /> }
+      {props.showFilter && <Filter {...props} />}
       <ItemList
         columns={[{
           name: 'Name',

+ 31 - 27
packages/@uppy/provider-views/src/Filter.js

@@ -14,32 +14,36 @@ module.exports = class Filter extends Component {
   }
 
   render () {
-    return <div class="uppy-ProviderBrowser-search">
-      <input
-        class="uppy-u-reset uppy-ProviderBrowser-searchInput"
-        type="text"
-        placeholder={this.props.i18n('filter')}
-        aria-label={this.props.i18n('filter')}
-        onkeyup={this.preventEnterPress}
-        onkeydown={this.preventEnterPress}
-        onkeypress={this.preventEnterPress}
-        oninput={(e) => this.props.filterQuery(e)}
-        value={this.props.filterInput} />
-      <svg aria-hidden="true" focusable="false" class="UppyIcon uppy-ProviderBrowser-searchIcon" width="12" height="12" viewBox="0 0 12 12">
-        <path d="M8.638 7.99l3.172 3.172a.492.492 0 1 1-.697.697L7.91 8.656a4.977 4.977 0 0 1-2.983.983C2.206 9.639 0 7.481 0 4.819 0 2.158 2.206 0 4.927 0c2.721 0 4.927 2.158 4.927 4.82a4.74 4.74 0 0 1-1.216 3.17zm-3.71.685c2.176 0 3.94-1.726 3.94-3.856 0-2.129-1.764-3.855-3.94-3.855C2.75.964.984 2.69.984 4.819c0 2.13 1.765 3.856 3.942 3.856z" />
-      </svg>
-      { this.props.filterInput &&
-        <button
-          class="uppy-u-reset uppy-ProviderBrowser-searchClose"
-          type="button"
-          aria-label={this.props.i18n('resetFilter')}
-          title={this.props.i18n('resetFilter')}
-          onclick={this.props.filterQuery}>
-          <svg aria-hidden="true" focusable="false" class="UppyIcon" viewBox="0 0 19 19">
-            <path d="M17.318 17.232L9.94 9.854 9.586 9.5l-.354.354-7.378 7.378h.707l-.62-.62v.706L9.318 9.94l.354-.354-.354-.354L1.94 1.854v.707l.62-.62h-.706l7.378 7.378.354.354.354-.354 7.378-7.378h-.707l.622.62v-.706L9.854 9.232l-.354.354.354.354 7.378 7.378.708-.707-7.38-7.378v.708l7.38-7.38.353-.353-.353-.353-.622-.622-.353-.353-.354.352-7.378 7.38h.708L2.56 1.23 2.208.88l-.353.353-.622.62-.353.355.352.353 7.38 7.38v-.708l-7.38 7.38-.353.353.352.353.622.622.353.353.354-.353 7.38-7.38h-.708l7.38 7.38z" />
-          </svg>
-        </button>
-      }
-    </div>
+    return (
+      <div class="uppy-ProviderBrowser-search">
+        <input
+          class="uppy-u-reset uppy-ProviderBrowser-searchInput"
+          type="text"
+          placeholder={this.props.i18n('filter')}
+          aria-label={this.props.i18n('filter')}
+          onkeyup={this.preventEnterPress}
+          onkeydown={this.preventEnterPress}
+          onkeypress={this.preventEnterPress}
+          oninput={(e) => this.props.filterQuery(e)}
+          value={this.props.filterInput}
+        />
+        <svg aria-hidden="true" focusable="false" class="UppyIcon uppy-ProviderBrowser-searchIcon" width="12" height="12" viewBox="0 0 12 12">
+          <path d="M8.638 7.99l3.172 3.172a.492.492 0 1 1-.697.697L7.91 8.656a4.977 4.977 0 0 1-2.983.983C2.206 9.639 0 7.481 0 4.819 0 2.158 2.206 0 4.927 0c2.721 0 4.927 2.158 4.927 4.82a4.74 4.74 0 0 1-1.216 3.17zm-3.71.685c2.176 0 3.94-1.726 3.94-3.856 0-2.129-1.764-3.855-3.94-3.855C2.75.964.984 2.69.984 4.819c0 2.13 1.765 3.856 3.942 3.856z" />
+        </svg>
+        {this.props.filterInput && (
+          <button
+            class="uppy-u-reset uppy-ProviderBrowser-searchClose"
+            type="button"
+            aria-label={this.props.i18n('resetFilter')}
+            title={this.props.i18n('resetFilter')}
+            onclick={this.props.filterQuery}
+          >
+            <svg aria-hidden="true" focusable="false" class="UppyIcon" viewBox="0 0 19 19">
+              <path d="M17.318 17.232L9.94 9.854 9.586 9.5l-.354.354-7.378 7.378h.707l-.62-.62v.706L9.318 9.94l.354-.354-.354-.354L1.94 1.854v.707l.62-.62h-.706l7.378 7.378.354.354.354-.354 7.378-7.378h-.707l.622.62v-.706L9.854 9.232l-.354.354.354.354 7.378 7.378.708-.707-7.38-7.378v.708l7.38-7.38.353-.353-.353-.353-.622-.622-.353-.353-.354.352-7.378 7.38h.708L2.56 1.23 2.208.88l-.353.353-.622.62-.353.355.352.353 7.38 7.38v-.708l-7.38 7.38-.353.353.352.353.622.622.353.353.354-.353 7.38-7.38h-.708l7.38 7.38z" />
+            </svg>
+          </button>
+        )}
+      </div>
+    )
   }
 }

+ 12 - 10
packages/@uppy/provider-views/src/FooterActions.js

@@ -1,14 +1,16 @@
 const { h } = require('preact')
 
 module.exports = (props) => {
-  return <div class="uppy-ProviderBrowser-footer">
-    <button class="uppy-u-reset uppy-c-btn uppy-c-btn-primary" onclick={props.done}>
-      {props.i18n('selectX', {
-        smart_count: props.selected
-      })}
-    </button>
-    <button class="uppy-u-reset uppy-c-btn uppy-c-btn-link" onclick={props.cancel}>
-      {props.i18n('cancel')}
-    </button>
-  </div>
+  return (
+    <div class="uppy-ProviderBrowser-footer">
+      <button class="uppy-u-reset uppy-c-btn uppy-c-btn-primary" onclick={props.done}>
+        {props.i18n('selectX', {
+          smart_count: props.selected
+        })}
+      </button>
+      <button class="uppy-u-reset uppy-c-btn uppy-c-btn-link" onclick={props.cancel}>
+        {props.i18n('cancel')}
+      </button>
+    </div>
+  )
 }

+ 18 - 16
packages/@uppy/provider-views/src/Item/components/GridLi.js

@@ -2,21 +2,23 @@ const { h } = require('preact')
 
 // it could be a <li><button class="fake-checkbox"/> <button/></li>
 module.exports = (props) => {
-  return <li class={props.className}>
-    <div aria-hidden class={`uppy-ProviderBrowserItem-fakeCheckbox ${props.isChecked ? 'uppy-ProviderBrowserItem-fakeCheckbox--is-checked' : ''}`} />
-    <button
-      type="button"
-      class="uppy-u-reset uppy-ProviderBrowserItem-inner"
-      onclick={props.toggleCheckbox}
+  return (
+    <li class={props.className}>
+      <div aria-hidden class={`uppy-ProviderBrowserItem-fakeCheckbox ${props.isChecked ? 'uppy-ProviderBrowserItem-fakeCheckbox--is-checked' : ''}`} />
+      <button
+        type="button"
+        class="uppy-u-reset uppy-ProviderBrowserItem-inner"
+        onclick={props.toggleCheckbox}
 
-      role="option"
-      aria-label={props.isChecked ? props.i18n('unselectFileNamed', { name: props.title }) : props.i18n('selectFileNamed', { name: props.title })}
-      aria-selected={props.isChecked}
-      aria-disabled={props.isDisabled}
-      data-uppy-super-focusable
-    >
-      {props.itemIconEl}
-      {props.showTitles && props.title}
-    </button>
-  </li>
+        role="option"
+        aria-label={props.isChecked ? props.i18n('unselectFileNamed', { name: props.title }) : props.i18n('selectFileNamed', { name: props.title })}
+        aria-selected={props.isChecked}
+        aria-disabled={props.isDisabled}
+        data-uppy-super-focusable
+      >
+        {props.itemIconEl}
+        {props.showTitles && props.title}
+      </button>
+    </li>
+  )
 }

+ 28 - 9
packages/@uppy/provider-views/src/Item/components/ItemIcon.js

@@ -1,21 +1,40 @@
 const { h } = require('preact')
 
+function FileIcon () {
+  return (
+    <svg aria-hidden="true" focusable="false" class="UppyIcon" width={11} height={14.5} viewBox="0 0 44 58">
+      <path d="M27.437.517a1 1 0 0 0-.094.03H4.25C2.037.548.217 2.368.217 4.58v48.405c0 2.212 1.82 4.03 4.03 4.03H39.03c2.21 0 4.03-1.818 4.03-4.03V15.61a1 1 0 0 0-.03-.28 1 1 0 0 0 0-.093 1 1 0 0 0-.03-.032 1 1 0 0 0 0-.03 1 1 0 0 0-.032-.063 1 1 0 0 0-.03-.063 1 1 0 0 0-.032 0 1 1 0 0 0-.03-.063 1 1 0 0 0-.032-.03 1 1 0 0 0-.03-.063 1 1 0 0 0-.063-.062l-14.593-14a1 1 0 0 0-.062-.062A1 1 0 0 0 28 .708a1 1 0 0 0-.374-.157 1 1 0 0 0-.156 0 1 1 0 0 0-.03-.03l-.003-.003zM4.25 2.547h22.218v9.97c0 2.21 1.82 4.03 4.03 4.03h10.564v36.438a2.02 2.02 0 0 1-2.032 2.032H4.25c-1.13 0-2.032-.9-2.032-2.032V4.58c0-1.13.902-2.032 2.03-2.032zm24.218 1.345l10.375 9.937.75.718H30.5c-1.13 0-2.032-.9-2.032-2.03V3.89z" />
+    </svg>
+  )
+}
+
+function FolderIcon () {
+  return (
+    <svg aria-hidden="true" focusable="false" class="UppyIcon" style={{ width: 16, marginRight: 3 }} viewBox="0 0 276.157 276.157">
+      <path d="M273.08 101.378c-3.3-4.65-8.86-7.32-15.254-7.32h-24.34V67.59c0-10.2-8.3-18.5-18.5-18.5h-85.322c-3.63 0-9.295-2.875-11.436-5.805l-6.386-8.735c-4.982-6.814-15.104-11.954-23.546-11.954H58.73c-9.292 0-18.638 6.608-21.737 15.372l-2.033 5.752c-.958 2.71-4.72 5.37-7.596 5.37H18.5C8.3 49.09 0 57.39 0 67.59v167.07c0 .886.16 1.73.443 2.52.152 3.306 1.18 6.424 3.053 9.064 3.3 4.652 8.86 7.32 15.255 7.32h188.487c11.395 0 23.27-8.425 27.035-19.18l40.677-116.188c2.11-6.035 1.43-12.164-1.87-16.816zM18.5 64.088h8.864c9.295 0 18.64-6.607 21.738-15.37l2.032-5.75c.96-2.712 4.722-5.373 7.597-5.373h29.565c3.63 0 9.295 2.876 11.437 5.806l6.386 8.735c4.982 6.815 15.104 11.954 23.546 11.954h85.322c1.898 0 3.5 1.602 3.5 3.5v26.47H69.34c-11.395 0-23.27 8.423-27.035 19.178L15 191.23V67.59c0-1.898 1.603-3.5 3.5-3.5zm242.29 49.15l-40.676 116.188c-1.674 4.78-7.812 9.135-12.877 9.135H18.75c-1.447 0-2.576-.372-3.02-.997-.442-.625-.422-1.814.057-3.18l40.677-116.19c1.674-4.78 7.812-9.134 12.877-9.134h188.487c1.448 0 2.577.372 3.02.997.443.625.423 1.814-.056 3.18z" />
+    </svg>
+  )
+}
+
+function VideoIcon () {
+  return (
+    <svg aria-hidden="true" focusable="false" viewBox="0 0 58 58">
+      <path d="M36.537 28.156l-11-7a1.005 1.005 0 0 0-1.02-.033C24.2 21.3 24 21.635 24 22v14a1 1 0 0 0 1.537.844l11-7a1.002 1.002 0 0 0 0-1.688zM26 34.18V23.82L34.137 29 26 34.18z" />
+      <path d="M57 6H1a1 1 0 0 0-1 1v44a1 1 0 0 0 1 1h56a1 1 0 0 0 1-1V7a1 1 0 0 0-1-1zM10 28H2v-9h8v9zm-8 2h8v9H2v-9zm10 10V8h34v42H12V40zm44-12h-8v-9h8v9zm-8 2h8v9h-8v-9zm8-22v9h-8V8h8zM2 8h8v9H2V8zm0 42v-9h8v9H2zm54 0h-8v-9h8v9z" />
+    </svg>
+  )
+}
+
 module.exports = (props) => {
   if (props.itemIconString === null) return
 
   switch (props.itemIconString) {
     case 'file':
-      return <svg aria-hidden="true" focusable="false" class="UppyIcon" width={11} height={14.5} viewBox="0 0 44 58">
-        <path d="M27.437.517a1 1 0 0 0-.094.03H4.25C2.037.548.217 2.368.217 4.58v48.405c0 2.212 1.82 4.03 4.03 4.03H39.03c2.21 0 4.03-1.818 4.03-4.03V15.61a1 1 0 0 0-.03-.28 1 1 0 0 0 0-.093 1 1 0 0 0-.03-.032 1 1 0 0 0 0-.03 1 1 0 0 0-.032-.063 1 1 0 0 0-.03-.063 1 1 0 0 0-.032 0 1 1 0 0 0-.03-.063 1 1 0 0 0-.032-.03 1 1 0 0 0-.03-.063 1 1 0 0 0-.063-.062l-14.593-14a1 1 0 0 0-.062-.062A1 1 0 0 0 28 .708a1 1 0 0 0-.374-.157 1 1 0 0 0-.156 0 1 1 0 0 0-.03-.03l-.003-.003zM4.25 2.547h22.218v9.97c0 2.21 1.82 4.03 4.03 4.03h10.564v36.438a2.02 2.02 0 0 1-2.032 2.032H4.25c-1.13 0-2.032-.9-2.032-2.032V4.58c0-1.13.902-2.032 2.03-2.032zm24.218 1.345l10.375 9.937.75.718H30.5c-1.13 0-2.032-.9-2.032-2.03V3.89z" />
-      </svg>
+      return <FileIcon />
     case 'folder':
-      return <svg aria-hidden="true" focusable="false" class="UppyIcon" style={{ width: 16, marginRight: 3 }} viewBox="0 0 276.157 276.157">
-        <path d="M273.08 101.378c-3.3-4.65-8.86-7.32-15.254-7.32h-24.34V67.59c0-10.2-8.3-18.5-18.5-18.5h-85.322c-3.63 0-9.295-2.875-11.436-5.805l-6.386-8.735c-4.982-6.814-15.104-11.954-23.546-11.954H58.73c-9.292 0-18.638 6.608-21.737 15.372l-2.033 5.752c-.958 2.71-4.72 5.37-7.596 5.37H18.5C8.3 49.09 0 57.39 0 67.59v167.07c0 .886.16 1.73.443 2.52.152 3.306 1.18 6.424 3.053 9.064 3.3 4.652 8.86 7.32 15.255 7.32h188.487c11.395 0 23.27-8.425 27.035-19.18l40.677-116.188c2.11-6.035 1.43-12.164-1.87-16.816zM18.5 64.088h8.864c9.295 0 18.64-6.607 21.738-15.37l2.032-5.75c.96-2.712 4.722-5.373 7.597-5.373h29.565c3.63 0 9.295 2.876 11.437 5.806l6.386 8.735c4.982 6.815 15.104 11.954 23.546 11.954h85.322c1.898 0 3.5 1.602 3.5 3.5v26.47H69.34c-11.395 0-23.27 8.423-27.035 19.178L15 191.23V67.59c0-1.898 1.603-3.5 3.5-3.5zm242.29 49.15l-40.676 116.188c-1.674 4.78-7.812 9.135-12.877 9.135H18.75c-1.447 0-2.576-.372-3.02-.997-.442-.625-.422-1.814.057-3.18l40.677-116.19c1.674-4.78 7.812-9.134 12.877-9.134h188.487c1.448 0 2.577.372 3.02.997.443.625.423 1.814-.056 3.18z" />
-      </svg>
+      return <FolderIcon />
     case 'video':
-      return <svg aria-hidden="true" focusable="false" viewBox="0 0 58 58">
-        <path d="M36.537 28.156l-11-7a1.005 1.005 0 0 0-1.02-.033C24.2 21.3 24 21.635 24 22v14a1 1 0 0 0 1.537.844l11-7a1.002 1.002 0 0 0 0-1.688zM26 34.18V23.82L34.137 29 26 34.18z" /><path d="M57 6H1a1 1 0 0 0-1 1v44a1 1 0 0 0 1 1h56a1 1 0 0 0 1-1V7a1 1 0 0 0-1-1zM10 28H2v-9h8v9zm-8 2h8v9H2v-9zm10 10V8h34v42H12V40zm44-12h-8v-9h8v9zm-8 2h8v9h-8v-9zm8-22v9h-8V8h8zM2 8h8v9H2V8zm0 42v-9h8v9H2zm54 0h-8v-9h8v9z" />
-      </svg>
+      return <VideoIcon />
     default:
       return <img src={props.itemIconString} />
   }

+ 21 - 19
packages/@uppy/provider-views/src/Item/components/ListLi.js

@@ -23,29 +23,30 @@ const getAriaLabelOfCheckbox = (props) => {
 //   + checkbox (selects file)
 //   + file name (selects file)
 module.exports = (props) => {
-  return <li class={props.className}>
-    <button
-      type="button"
-      class={`uppy-u-reset uppy-ProviderBrowserItem-fakeCheckbox ${props.isChecked ? 'uppy-ProviderBrowserItem-fakeCheckbox--is-checked' : ''}`}
-      onClick={props.toggleCheckbox}
-      // for the <label/>
-      id={props.id}
-      role="option"
-      aria-label={getAriaLabelOfCheckbox(props)}
-      aria-selected={props.isChecked}
-      aria-disabled={props.isDisabled}
-      data-uppy-super-focusable
-    />
+  return (
+    <li class={props.className}>
+      <button
+        type="button"
+        class={`uppy-u-reset uppy-ProviderBrowserItem-fakeCheckbox ${props.isChecked ? 'uppy-ProviderBrowserItem-fakeCheckbox--is-checked' : ''}`}
+        onClick={props.toggleCheckbox}
+        // for the <label/>
+        id={props.id}
+        role="option"
+        aria-label={getAriaLabelOfCheckbox(props)}
+        aria-selected={props.isChecked}
+        aria-disabled={props.isDisabled}
+        data-uppy-super-focusable
+      />
 
-    {
-      props.type === 'file'
+      {props.type === 'file' ? (
         // label for a checkbox
-        ? <label for={props.id} className="uppy-u-reset uppy-ProviderBrowserItem-inner">
+        <label for={props.id} className="uppy-u-reset uppy-ProviderBrowserItem-inner">
           {props.itemIconEl}
           {props.showTitles && props.title}
         </label>
+      ) : (
         // button to open a folder
-        : <button
+        <button
           type="button"
           class="uppy-u-reset uppy-ProviderBrowserItem-inner"
           onclick={props.handleFolderClick}
@@ -54,6 +55,7 @@ module.exports = (props) => {
           {props.itemIconEl}
           {props.showTitles && props.title}
         </button>
-    }
-  </li>
+      )}
+    </li>
+  )
 }

+ 4 - 2
packages/@uppy/provider-views/src/ItemList.js

@@ -20,11 +20,13 @@ module.exports = (props) => {
 
   return (
     <div class="uppy-ProviderBrowser-body">
-      <ul class="uppy-ProviderBrowser-list"
+      <ul
+        class="uppy-ProviderBrowser-list"
         onscroll={props.handleScroll}
         role="listbox"
         // making <ul> not focusable for firefox
-        tabindex="-1">
+        tabindex="-1"
+      >
         {props.folders.map(folder =>
           Item({
             ...getSharedProps(folder, props),

+ 5 - 3
packages/@uppy/provider-views/src/Loader.js

@@ -1,7 +1,9 @@
 const { h } = require('preact')
 
 module.exports = (props) => {
-  return <div class="uppy-Provider-loading">
-    <span>{props.i18n('loading')}</span>
-  </div>
+  return (
+    <div class="uppy-Provider-loading">
+      <span>{props.i18n('loading')}</span>
+    </div>
+  )
 }

+ 4 - 2
packages/@uppy/provider-views/src/index.js

@@ -41,7 +41,8 @@ module.exports = class ProviderView {
   static VERSION = require('../package.json').version
 
   /**
-   * @param {object} instance of the plugin
+   * @param {object} plugin instance of the plugin
+   * @param {object} opts
    */
   constructor (plugin, opts) {
     this.plugin = plugin
@@ -586,7 +587,8 @@ module.exports = class ProviderView {
             pluginIcon={this.plugin.icon}
             handleAuth={this.handleAuth}
             i18n={this.plugin.uppy.i18n}
-            i18nArray={this.plugin.uppy.i18nArray} />
+            i18nArray={this.plugin.uppy.i18nArray}
+          />
         </CloseWrapper>
       )
     }

+ 17 - 10
packages/@uppy/react-native/file-picker/index.js

@@ -4,7 +4,8 @@ import {
   Modal,
   Text,
   ScrollView,
-  TouchableOpacity } from 'react-native'
+  TouchableOpacity
+} from 'react-native'
 import takePicture from './takePicture'
 import selectImage from './selectImage'
 import selectDocument from './selectDocument'
@@ -104,20 +105,23 @@ export default class UppyReactNativeFilePicker extends React.Component {
   renderSourceList () {
     return (
       <ScrollView
-        contentContainerStyle={styles.providerList}>
+        contentContainerStyle={styles.providerList}
+      >
         {this.state.providers.map((item, index) => {
           return (
             <TouchableOpacity
               style={styles.providerButton}
               key={index}
-              onPress={ev => this.chooseProvider(item.id)}>
+              onPress={ev => this.chooseProvider(item.id)}
+            >
               <Text style={styles.providerButtonText}>{item.title}</Text>
             </TouchableOpacity>
           )
         })}
         <TouchableOpacity
           style={styles.cancelButton}
-          onPress={ev => this.props.onRequestClose()}>
+          onPress={ev => this.props.onRequestClose()}
+        >
           <Text style={styles.cancelButtonText}>Cancel</Text>
         </TouchableOpacity>
       </ScrollView>
@@ -131,9 +135,10 @@ export default class UppyReactNativeFilePicker extends React.Component {
         transparent={false}
         visible={this.props.show}
         supportedOrientations={['portrait', 'portrait-upside-down', 'landscape', 'landscape-left', 'landscape-right']}
-        onRequestClose={this.props.onRequestClose}>
-        {this.state.openProvider
-          ? <Provider
+        onRequestClose={this.props.onRequestClose}
+      >
+        {this.state.openProvider ? (
+          <Provider
             providerID={this.state.openProvider}
             uppy={this.uppy}
             onDone={() => {
@@ -142,9 +147,11 @@ export default class UppyReactNativeFilePicker extends React.Component {
               })
               this.props.onRequestClose()
             }}
-            {...this.props} />
-          : this.renderSourceList()
-        }
+            {...this.props}
+          />
+        ) : (
+          this.renderSourceList()
+        )}
       </Modal>
     )
   }

+ 16 - 13
packages/@uppy/react-native/file-picker/instagram.js

@@ -4,7 +4,8 @@ import {
   View,
   FlatList,
   Image,
-  WebView } from 'react-native'
+  WebView
+} from 'react-native'
 import Instagram from '@uppy/instagram'
 
 function getQueryParamValueFromUrl (name, url) {
@@ -78,18 +79,20 @@ export default class UppyRNInstagram extends React.Component {
 
   renderInstagram () {
     console.log(this.state.authUrl)
-    return <WebView
-      source={{ uri: this.state.authUrl }}
-      style={{ marginTop: 20 }}
-      onNavigationStateChange={(ev) => {
-        const url = ev.url
-        const token = getQueryParamValueFromUrl('uppyAuthToken', url)
-        console.log(token)
-        this.plugin.provider.setAuthToken(token)
-        console.log(this.plugin.provider.list('recent'))
-        // return this.renderGrid(this.state.instagram.items)
-      }}
-    />
+    return (
+      <WebView
+        source={{ uri: this.state.authUrl }}
+        style={{ marginTop: 20 }}
+        onNavigationStateChange={(ev) => {
+          const url = ev.url
+          const token = getQueryParamValueFromUrl('uppyAuthToken', url)
+          console.log(token)
+          this.plugin.provider.setAuthToken(token)
+          console.log(this.plugin.provider.list('recent'))
+          // return this.renderGrid(this.state.instagram.items)
+        }}
+      />
+    )
   }
 
   render () {

+ 6 - 3
packages/@uppy/react-native/file-picker/url.js

@@ -5,7 +5,8 @@ import {
   TouchableOpacity,
   Text,
   TextInput,
-  View } from 'react-native'
+  View
+} from 'react-native'
 import Url from '@uppy/url'
 
 export default class UppyRNUrl extends React.Component {
@@ -58,12 +59,14 @@ export default class UppyRNUrl extends React.Component {
         />
         <TouchableOpacity
           style={styles.buttonImport}
-          onPress={this.onPressImport}>
+          onPress={this.onPressImport}
+        >
           <Text style={styles.buttonImportText}>Import</Text>
         </TouchableOpacity>
         <TouchableOpacity
           style={styles.buttonCancel}
-          onPress={ev => this.props.onDone()}>
+          onPress={ev => this.props.onDone()}
+        >
           <Text style={styles.buttonCancelText}>Cancel</Text>
         </TouchableOpacity>
       </View>

+ 2 - 1
packages/@uppy/redux-dev-tools/src/index.js

@@ -40,11 +40,12 @@ module.exports = class ReduxDevTools extends Plugin {
           case 'RESET':
             this.uppy.reset()
             return
-          case 'IMPORT_STATE':
+          case 'IMPORT_STATE': {
             const computedStates = message.payload.nextLiftedState.computedStates
             this.uppy.store.state = Object.assign({}, this.uppy.getState(), computedStates[computedStates.length - 1].state)
             this.uppy.updateAll(this.uppy.getState())
             return
+          }
           case 'JUMP_TO_STATE':
           case 'JUMP_TO_ACTION':
             this.uppy.store.state = Object.assign({}, this.uppy.getState(), JSON.parse(message.state))

+ 141 - 110
packages/@uppy/status-bar/src/StatusBar.js

@@ -52,7 +52,8 @@ function togglePauseResume (props) {
 module.exports = (props) => {
   props = props || {}
 
-  const { newFiles,
+  const {
+    newFiles,
     allowNewUpload,
     isUploadInProgress,
     isAllPaused,
@@ -61,7 +62,8 @@ module.exports = (props) => {
     hideUploadButton,
     hidePauseResumeButton,
     hideCancelButton,
-    hideRetryButton } = props
+    hideRetryButton
+  } = props
 
   const uploadState = props.uploadState
 
@@ -120,18 +122,20 @@ module.exports = (props) => {
 
   return (
     <div class={statusBarClassNames} aria-hidden={isHidden}>
-      <div class={progressClassNames}
+      <div
+        class={progressClassNames}
         style={{ width: width + '%' }}
         role="progressbar"
         aria-valuemin="0"
         aria-valuemax="100"
-        aria-valuenow={progressValue} />
+        aria-valuenow={progressValue}
+      />
       {progressBarContent}
       <div class="uppy-StatusBar-actions">
-        { showUploadBtn ? <UploadBtn {...props} uploadState={uploadState} /> : null }
-        { showRetryBtn ? <RetryBtn {...props} /> : null }
-        { showPauseResumeBtn ? <PauseResumeButton {...props} /> : null }
-        { showCancelBtn ? <CancelBtn {...props} /> : null }
+        {showUploadBtn ? <UploadBtn {...props} uploadState={uploadState} /> : null}
+        {showRetryBtn ? <RetryBtn {...props} /> : null}
+        {showPauseResumeBtn ? <PauseResumeButton {...props} /> : null}
+        {showCancelBtn ? <CancelBtn {...props} /> : null}
       </div>
     </div>
   )
@@ -146,23 +150,28 @@ const UploadBtn = (props) => {
     { 'uppy-c-btn-primary': props.uploadState === statusBarStates.STATE_WAITING }
   )
 
-  return <button type="button"
-    class={uploadBtnClassNames}
-    aria-label={props.i18n('uploadXFiles', { smart_count: props.newFiles })}
-    onclick={props.startUpload}
-    data-uppy-super-focusable>
-    {props.newFiles && props.isUploadStarted
-      ? props.i18n('uploadXNewFiles', { smart_count: props.newFiles })
-      : props.i18n('uploadXFiles', { smart_count: props.newFiles })
-    }
-  </button>
+  return (
+    <button
+      type="button"
+      class={uploadBtnClassNames}
+      aria-label={props.i18n('uploadXFiles', { smart_count: props.newFiles })}
+      onclick={props.startUpload}
+      data-uppy-super-focusable
+    >
+      {props.newFiles && props.isUploadStarted
+        ? props.i18n('uploadXNewFiles', { smart_count: props.newFiles })
+        : props.i18n('uploadXFiles', { smart_count: props.newFiles })}
+    </button>
+  )
 }
 
 const RetryBtn = (props) => {
   return (
-    <button type="button"
+    <button
+      type="button"
       class="uppy-u-reset uppy-c-btn uppy-StatusBar-actionBtn uppy-StatusBar-actionBtn--retry" aria-label={props.i18n('retryUpload')} onclick={props.retryAll}
-      data-uppy-super-focusable>
+      data-uppy-super-focusable
+    >
       <svg aria-hidden="true" focusable="false" class="UppyIcon" width="8" height="10" viewBox="0 0 8 10">
         <path d="M4 2.408a2.75 2.75 0 1 0 2.75 2.75.626.626 0 0 1 1.25.018v.023a4 4 0 1 1-4-4.041V.25a.25.25 0 0 1 .389-.208l2.299 1.533a.25.25 0 0 1 0 .416l-2.3 1.533A.25.25 0 0 1 4 3.316v-.908z" />
       </svg>
@@ -172,64 +181,75 @@ const RetryBtn = (props) => {
 }
 
 const CancelBtn = (props) => {
-  return <button
-    type="button"
-    class="uppy-u-reset uppy-StatusBar-actionCircleBtn"
-    title={props.i18n('cancel')}
-    aria-label={props.i18n('cancel')}
-    onclick={props.cancelAll}
-    data-uppy-super-focusable>
-    <svg aria-hidden="true" focusable="false" class="UppyIcon" width="16" height="16" viewBox="0 0 16 16">
-      <g fill="none" fill-rule="evenodd">
-        <circle fill="#888" cx="8" cy="8" r="8" />
-        <path fill="#FFF" d="M9.283 8l2.567 2.567-1.283 1.283L8 9.283 5.433 11.85 4.15 10.567 6.717 8 4.15 5.433 5.433 4.15 8 6.717l2.567-2.567 1.283 1.283z" />
-      </g>
-    </svg>
-  </button>
+  return (
+    <button
+      type="button"
+      class="uppy-u-reset uppy-StatusBar-actionCircleBtn"
+      title={props.i18n('cancel')}
+      aria-label={props.i18n('cancel')}
+      onclick={props.cancelAll}
+      data-uppy-super-focusable
+    >
+      <svg aria-hidden="true" focusable="false" class="UppyIcon" width="16" height="16" viewBox="0 0 16 16">
+        <g fill="none" fill-rule="evenodd">
+          <circle fill="#888" cx="8" cy="8" r="8" />
+          <path fill="#FFF" d="M9.283 8l2.567 2.567-1.283 1.283L8 9.283 5.433 11.85 4.15 10.567 6.717 8 4.15 5.433 5.433 4.15 8 6.717l2.567-2.567 1.283 1.283z" />
+        </g>
+      </svg>
+    </button>
+  )
 }
 
 const PauseResumeButton = (props) => {
   const { isAllPaused, i18n } = props
   const title = isAllPaused ? i18n('resume') : i18n('pause')
 
-  return <button
-    title={title}
-    aria-label={title}
-    class="uppy-u-reset uppy-StatusBar-actionCircleBtn"
-    type="button"
-    onclick={() => togglePauseResume(props)}
-    data-uppy-super-focusable>
-    {isAllPaused
-      ? <svg aria-hidden="true" focusable="false" class="UppyIcon" width="16" height="16" viewBox="0 0 16 16">
-        <g fill="none" fill-rule="evenodd">
-          <circle fill="#888" cx="8" cy="8" r="8" />
-          <path fill="#FFF" d="M6 4.25L11.5 8 6 11.75z" />
-        </g>
-      </svg>
-      : <svg aria-hidden="true" focusable="false" class="UppyIcon" width="16" height="16" viewBox="0 0 16 16">
-        <g fill="none" fill-rule="evenodd">
-          <circle fill="#888" cx="8" cy="8" r="8" />
-          <path d="M5 4.5h2v7H5v-7zm4 0h2v7H9v-7z" fill="#FFF" />
-        </g>
-      </svg>
-    }
-  </button>
+  return (
+    <button
+      title={title}
+      aria-label={title}
+      class="uppy-u-reset uppy-StatusBar-actionCircleBtn"
+      type="button"
+      onclick={() => togglePauseResume(props)}
+      data-uppy-super-focusable
+    >
+      {isAllPaused ? (
+        <svg aria-hidden="true" focusable="false" class="UppyIcon" width="16" height="16" viewBox="0 0 16 16">
+          <g fill="none" fill-rule="evenodd">
+            <circle fill="#888" cx="8" cy="8" r="8" />
+            <path fill="#FFF" d="M6 4.25L11.5 8 6 11.75z" />
+          </g>
+        </svg>
+      ) : (
+        <svg aria-hidden="true" focusable="false" class="UppyIcon" width="16" height="16" viewBox="0 0 16 16">
+          <g fill="none" fill-rule="evenodd">
+            <circle fill="#888" cx="8" cy="8" r="8" />
+            <path d="M5 4.5h2v7H5v-7zm4 0h2v7H9v-7z" fill="#FFF" />
+          </g>
+        </svg>
+      )}
+    </button>
+  )
 }
 
 const LoadingSpinner = () => {
-  return <svg aria-hidden="true" focusable="false" class="uppy-StatusBar-spinner" width="14" height="14">
-    <path d="M13.983 6.547c-.12-2.509-1.64-4.893-3.939-5.936-2.48-1.127-5.488-.656-7.556 1.094C.524 3.367-.398 6.048.162 8.562c.556 2.495 2.46 4.52 4.94 5.183 2.932.784 5.61-.602 7.256-3.015-1.493 1.993-3.745 3.309-6.298 2.868-2.514-.434-4.578-2.349-5.153-4.84a6.226 6.226 0 0 1 2.98-6.778C6.34.586 9.74 1.1 11.373 3.493c.407.596.693 1.282.842 1.988.127.598.073 1.197.161 1.794.078.525.543 1.257 1.15.864.525-.341.49-1.05.456-1.592-.007-.15.02.3 0 0" fill-rule="evenodd" />
-  </svg>
+  return (
+    <svg aria-hidden="true" focusable="false" class="uppy-StatusBar-spinner" width="14" height="14">
+      <path d="M13.983 6.547c-.12-2.509-1.64-4.893-3.939-5.936-2.48-1.127-5.488-.656-7.556 1.094C.524 3.367-.398 6.048.162 8.562c.556 2.495 2.46 4.52 4.94 5.183 2.932.784 5.61-.602 7.256-3.015-1.493 1.993-3.745 3.309-6.298 2.868-2.514-.434-4.578-2.349-5.153-4.84a6.226 6.226 0 0 1 2.98-6.778C6.34.586 9.74 1.1 11.373 3.493c.407.596.693 1.282.842 1.988.127.598.073 1.197.161 1.794.078.525.543 1.257 1.15.864.525-.341.49-1.05.456-1.592-.007-.15.02.3 0 0" fill-rule="evenodd" />
+    </svg>
+  )
 }
 
 const ProgressBarProcessing = (props) => {
   const value = Math.round(props.value * 100)
 
-  return <div class="uppy-StatusBar-content">
-    <LoadingSpinner />
-    {props.mode === 'determinate' ? `${value}% \u00B7 ` : ''}
-    {props.message}
-  </div>
+  return (
+    <div class="uppy-StatusBar-content">
+      <LoadingSpinner />
+      {props.mode === 'determinate' ? `${value}% \u00B7 ` : ''}
+      {props.message}
+    </div>
+  )
 }
 
 const renderDot = () =>
@@ -238,43 +258,47 @@ const renderDot = () =>
 const ProgressDetails = (props) => {
   const ifShowFilesUploadedOfTotal = props.numUploads > 1
 
-  return <div class="uppy-StatusBar-statusSecondary">
-    {
-      ifShowFilesUploadedOfTotal &&
-      props.i18n('filesUploadedOfTotal', {
-        complete: props.complete,
-        smart_count: props.numUploads
-      })
-    }
-    <span class="uppy-StatusBar-additionalInfo">
-      {/* When should we render this dot?
-        1. .-additionalInfo is shown (happens only on desktops)
-        2. AND 'filesUploadedOfTotal' was shown
-      */}
-      {ifShowFilesUploadedOfTotal && renderDot()}
-
+  return (
+    <div class="uppy-StatusBar-statusSecondary">
       {
-        props.i18n('dataUploadedOfTotal', {
-          complete: prettyBytes(props.totalUploadedSize),
-          total: prettyBytes(props.totalSize)
+        ifShowFilesUploadedOfTotal &&
+        props.i18n('filesUploadedOfTotal', {
+          complete: props.complete,
+          smart_count: props.numUploads
         })
       }
+      <span class="uppy-StatusBar-additionalInfo">
+        {/* When should we render this dot?
+          1. .-additionalInfo is shown (happens only on desktops)
+          2. AND 'filesUploadedOfTotal' was shown
+        */}
+        {ifShowFilesUploadedOfTotal && renderDot()}
+
+        {
+          props.i18n('dataUploadedOfTotal', {
+            complete: prettyBytes(props.totalUploadedSize),
+            total: prettyBytes(props.totalSize)
+          })
+        }
 
-      {renderDot()}
+        {renderDot()}
 
-      {
-        props.i18n('xTimeLeft', {
-          time: prettyETA(props.totalETA)
-        })
-      }
-    </span>
-  </div>
+        {
+          props.i18n('xTimeLeft', {
+            time: prettyETA(props.totalETA)
+          })
+        }
+      </span>
+    </div>
+  )
 }
 
 const UnknownProgressDetails = (props) => {
-  return <div class="uppy-StatusBar-statusSecondary">
-    { props.i18n('filesUploadedOfTotal', { complete: props.complete, smart_count: props.numUploads }) }
-  </div>
+  return (
+    <div class="uppy-StatusBar-statusSecondary">
+      {props.i18n('filesUploadedOfTotal', { complete: props.complete, smart_count: props.numUploads })}
+    </div>
+  )
 }
 
 const UploadNewlyAddedFiles = (props) => {
@@ -285,17 +309,21 @@ const UploadNewlyAddedFiles = (props) => {
     'uppy-StatusBar-actionBtn--uploadNewlyAdded'
   )
 
-  return <div class="uppy-StatusBar-statusSecondary">
-    <div class="uppy-StatusBar-statusSecondaryHint">
-      { props.i18n('xMoreFilesAdded', { smart_count: props.newFiles }) }
+  return (
+    <div class="uppy-StatusBar-statusSecondary">
+      <div class="uppy-StatusBar-statusSecondaryHint">
+        {props.i18n('xMoreFilesAdded', { smart_count: props.newFiles })}
+      </div>
+      <button
+        type="button"
+        class={uploadBtnClassNames}
+        aria-label={props.i18n('uploadXFiles', { smart_count: props.newFiles })}
+        onclick={props.startUpload}
+      >
+        {props.i18n('upload')}
+      </button>
     </div>
-    <button type="button"
-      class={uploadBtnClassNames}
-      aria-label={props.i18n('uploadXFiles', { smart_count: props.newFiles })}
-      onclick={props.startUpload}>
-      {props.i18n('upload')}
-    </button>
-  </div>
+  )
 }
 
 const ThrottledProgressDetails = throttle(ProgressDetails, 500, { leading: true, trailing: true })
@@ -310,16 +338,15 @@ const ProgressBarUploading = (props) => {
 
   return (
     <div class="uppy-StatusBar-content" aria-label={title} title={title}>
-      { !props.isAllPaused ? <LoadingSpinner /> : null }
+      {!props.isAllPaused ? <LoadingSpinner /> : null}
       <div class="uppy-StatusBar-status">
         <div class="uppy-StatusBar-statusPrimary">
           {props.supportsUploadProgress ? `${title}: ${props.totalProgress}%` : title}
         </div>
-        { !props.isAllPaused && !showUploadNewlyAddedFiles && props.showProgressDetails
+        {!props.isAllPaused && !showUploadNewlyAddedFiles && props.showProgressDetails
           ? (props.supportsUploadProgress ? <ThrottledProgressDetails {...props} /> : <UnknownProgressDetails {...props} />)
-          : null
-        }
-        { showUploadNewlyAddedFiles ? <UploadNewlyAddedFiles {...props} /> : null }
+          : null}
+        {showUploadNewlyAddedFiles ? <UploadNewlyAddedFiles {...props} /> : null}
       </div>
     </div>
   )
@@ -354,11 +381,15 @@ const ProgressBarError = ({ error, retryAll, hideRetryButton, i18n }) => {
       {/* {!hideRetryButton &&
         <span class="uppy-StatusBar-contentPadding">{i18n('pleasePressRetry')}</span>
       } */}
-      <span class="uppy-StatusBar-details"
+      <span
+        class="uppy-StatusBar-details"
         aria-label={error}
         data-microtip-position="top-right"
         data-microtip-size="medium"
-        role="tooltip">?</span>
+        role="tooltip"
+      >
+        ?
+      </span>
     </div>
   )
 }

+ 2 - 1
packages/@uppy/tus/src/index.js

@@ -66,6 +66,7 @@ module.exports = class Tus extends Plugin {
 
     /**
      * Simultaneous upload limiting is shared across all uploads with this plugin.
+     *
      * @type {RateLimitedQueue}
      */
     this.requests = new RateLimitedQueue(this.opts.limit)
@@ -293,7 +294,7 @@ module.exports = class Tus extends Plugin {
    * @param {UppyFile} file for use with upload
    * @param {number} current file in a queue
    * @param {number} total number of files in a queue
-   * @return {Promise<void>}
+   * @returns {Promise<void>}
    */
   uploadRemote (file, current, total) {
     this.resetUploaderReferences(file.id)

+ 20 - 16
packages/@uppy/url/src/UrlUI.js

@@ -22,22 +22,26 @@ class UrlUI extends Component {
   }
 
   render () {
-    return <div class="uppy-Url">
-      <input
-        class="uppy-u-reset uppy-c-textInput uppy-Url-input"
-        type="text"
-        aria-label={this.props.i18n('enterUrlToImport')}
-        placeholder={this.props.i18n('enterUrlToImport')}
-        onkeyup={this.handleKeyPress}
-        ref={(input) => { this.input = input }}
-        data-uppy-super-focusable />
-      <button
-        class="uppy-u-reset uppy-c-btn uppy-c-btn-primary uppy-Url-importButton"
-        type="button"
-        onclick={this.handleClick}>
-        {this.props.i18n('import')}
-      </button>
-    </div>
+    return (
+      <div class="uppy-Url">
+        <input
+          class="uppy-u-reset uppy-c-textInput uppy-Url-input"
+          type="text"
+          aria-label={this.props.i18n('enterUrlToImport')}
+          placeholder={this.props.i18n('enterUrlToImport')}
+          onkeyup={this.handleKeyPress}
+          ref={(input) => { this.input = input }}
+          data-uppy-super-focusable
+        />
+        <button
+          class="uppy-u-reset uppy-c-btn uppy-c-btn-primary uppy-Url-importButton"
+          type="button"
+          onclick={this.handleClick}
+        >
+          {this.props.i18n('import')}
+        </button>
+      </div>
+    )
   }
 }
 

+ 10 - 6
packages/@uppy/url/src/index.js

@@ -5,6 +5,14 @@ const { RequestClient } = require('@uppy/companion-client')
 const UrlUI = require('./UrlUI.js')
 const forEachDroppedOrPastedUrl = require('./utils/forEachDroppedOrPastedUrl')
 
+function UrlIcon () {
+  return (
+    <svg aria-hidden="true" focusable="false" width="23" height="23" viewBox="0 0 23 23">
+      <path d="M20.485 11.236l-2.748 2.737c-.184.182-.367.365-.642.547-1.007.73-2.107 1.095-3.298 1.095-1.65 0-3.298-.73-4.398-2.19-.275-.365-.183-1.003.183-1.277.367-.273 1.008-.182 1.283.183 1.191 1.642 3.482 1.915 5.13.73a.714.714 0 0 0 .367-.365l2.75-2.737c1.373-1.46 1.373-3.74-.093-5.108a3.72 3.72 0 0 0-5.13 0L12.33 6.4a.888.888 0 0 1-1.283 0 .88.88 0 0 1 0-1.277l1.558-1.55a5.38 5.38 0 0 1 7.605 0c2.29 2.006 2.382 5.564.274 7.662zm-8.979 6.294L9.95 19.081a3.72 3.72 0 0 1-5.13 0c-1.467-1.368-1.467-3.74-.093-5.108l2.75-2.737.366-.365c.824-.547 1.74-.82 2.748-.73 1.008.183 1.833.639 2.382 1.46.275.365.917.456 1.283.182.367-.273.458-.912.183-1.277-.916-1.186-2.199-1.915-3.573-2.098-1.374-.273-2.84.091-4.031 1.004l-.55.547-2.749 2.737c-2.107 2.189-2.015 5.655.092 7.753C4.727 21.453 6.101 22 7.475 22c1.374 0 2.749-.547 3.848-1.55l1.558-1.551a.88.88 0 0 0 0-1.278c-.367-.364-1.008-.456-1.375-.09z" fill="#FF814F" fill-rule="nonzero" />
+    </svg>
+  )
+}
+
 /**
  * Url
  *
@@ -17,9 +25,7 @@ module.exports = class Url extends Plugin {
     this.id = this.opts.id || 'Url'
     this.title = this.opts.title || 'Link'
     this.type = 'acquirer'
-    this.icon = () => <svg aria-hidden="true" focusable="false" width="23" height="23" viewBox="0 0 23 23">
-      <path d="M20.485 11.236l-2.748 2.737c-.184.182-.367.365-.642.547-1.007.73-2.107 1.095-3.298 1.095-1.65 0-3.298-.73-4.398-2.19-.275-.365-.183-1.003.183-1.277.367-.273 1.008-.182 1.283.183 1.191 1.642 3.482 1.915 5.13.73a.714.714 0 0 0 .367-.365l2.75-2.737c1.373-1.46 1.373-3.74-.093-5.108a3.72 3.72 0 0 0-5.13 0L12.33 6.4a.888.888 0 0 1-1.283 0 .88.88 0 0 1 0-1.277l1.558-1.55a5.38 5.38 0 0 1 7.605 0c2.29 2.006 2.382 5.564.274 7.662zm-8.979 6.294L9.95 19.081a3.72 3.72 0 0 1-5.13 0c-1.467-1.368-1.467-3.74-.093-5.108l2.75-2.737.366-.365c.824-.547 1.74-.82 2.748-.73 1.008.183 1.833.639 2.382 1.46.275.365.917.456 1.283.182.367-.273.458-.912.183-1.277-.916-1.186-2.199-1.915-3.573-2.098-1.374-.273-2.84.091-4.031 1.004l-.55.547-2.749 2.737c-2.107 2.189-2.015 5.655.092 7.753C4.727 21.453 6.101 22 7.475 22c1.374 0 2.749-.547 3.848-1.55l1.558-1.551a.88.88 0 0 0 0-1.278c-.367-.364-1.008-.456-1.375-.09z" fill="#FF814F" fill-rule="nonzero" />
-    </svg>
+    this.icon = () => <UrlIcon />
 
     // Set default options and locale
     this.defaultLocale = {
@@ -162,9 +168,7 @@ module.exports = class Url extends Plugin {
   }
 
   render (state) {
-    return <UrlUI
-      i18n={this.i18n}
-      addFile={this.addFile} />
+    return <UrlUI i18n={this.i18n} addFile={this.addFile} />
   }
 
   install () {

+ 5 - 3
packages/@uppy/webcam/src/CameraIcon.js

@@ -1,7 +1,9 @@
 const { h } = require('preact')
 
 module.exports = (props) => {
-  return <svg aria-hidden="true" focusable="false" fill="#0097DC" width="66" height="55" viewBox="0 0 66 55">
-    <path d="M57.3 8.433c4.59 0 8.1 3.51 8.1 8.1v29.7c0 4.59-3.51 8.1-8.1 8.1H8.7c-4.59 0-8.1-3.51-8.1-8.1v-29.7c0-4.59 3.51-8.1 8.1-8.1h9.45l4.59-7.02c.54-.54 1.35-1.08 2.16-1.08h16.2c.81 0 1.62.54 2.16 1.08l4.59 7.02h9.45zM33 14.64c-8.62 0-15.393 6.773-15.393 15.393 0 8.62 6.773 15.393 15.393 15.393 8.62 0 15.393-6.773 15.393-15.393 0-8.62-6.773-15.393-15.393-15.393zM33 40c-5.648 0-9.966-4.319-9.966-9.967 0-5.647 4.318-9.966 9.966-9.966s9.966 4.319 9.966 9.966C42.966 35.681 38.648 40 33 40z" fill-rule="evenodd" />
-  </svg>
+  return (
+    <svg aria-hidden="true" focusable="false" fill="#0097DC" width="66" height="55" viewBox="0 0 66 55">
+      <path d="M57.3 8.433c4.59 0 8.1 3.51 8.1 8.1v29.7c0 4.59-3.51 8.1-8.1 8.1H8.7c-4.59 0-8.1-3.51-8.1-8.1v-29.7c0-4.59 3.51-8.1 8.1-8.1h9.45l4.59-7.02c.54-.54 1.35-1.08 2.16-1.08h16.2c.81 0 1.62.54 2.16 1.08l4.59 7.02h9.45zM33 14.64c-8.62 0-15.393 6.773-15.393 15.393 0 8.62 6.773 15.393 15.393 15.393 8.62 0 15.393-6.773 15.393-15.393 0-8.62-6.773-15.393-15.393-15.393zM33 40c-5.648 0-9.966-4.319-9.966-9.967 0-5.647 4.318-9.966 9.966-9.966s9.966 4.319 9.966 9.966C42.966 35.681 38.648 40 33 40z" fill-rule="evenodd" />
+    </svg>
+  )
 }

+ 8 - 4
packages/@uppy/webcam/src/RecordButton.js

@@ -3,12 +3,14 @@ const { h } = require('preact')
 module.exports = function RecordButton ({ recording, onStartRecording, onStopRecording, i18n }) {
   if (recording) {
     return (
-      <button class="uppy-u-reset uppy-c-btn uppy-Webcam-button uppy-Webcam-button--video"
+      <button
+        class="uppy-u-reset uppy-c-btn uppy-Webcam-button uppy-Webcam-button--video"
         type="button"
         title={i18n('stopRecording')}
         aria-label={i18n('stopRecording')}
         onclick={onStopRecording}
-        data-uppy-super-focusable>
+        data-uppy-super-focusable
+      >
         <svg aria-hidden="true" focusable="false" class="UppyIcon" width="100" height="100" viewBox="0 0 100 100">
           <rect x="15" y="15" width="70" height="70" />
         </svg>
@@ -17,12 +19,14 @@ module.exports = function RecordButton ({ recording, onStartRecording, onStopRec
   }
 
   return (
-    <button class="uppy-u-reset uppy-c-btn uppy-Webcam-button uppy-Webcam-button--video"
+    <button
+      class="uppy-u-reset uppy-c-btn uppy-Webcam-button uppy-Webcam-button--video"
       type="button"
       title={i18n('startRecording')}
       aria-label={i18n('startRecording')}
       onclick={onStartRecording}
-      data-uppy-super-focusable>
+      data-uppy-super-focusable
+    >
       <svg aria-hidden="true" focusable="false" class="UppyIcon" width="100" height="100" viewBox="0 0 100 100">
         <circle cx="50" cy="50" r="40" />
       </svg>

+ 4 - 2
packages/@uppy/webcam/src/SnapshotButton.js

@@ -3,12 +3,14 @@ const CameraIcon = require('./CameraIcon')
 
 module.exports = ({ onSnapshot, i18n }) => {
   return (
-    <button class="uppy-u-reset uppy-c-btn uppy-Webcam-button uppy-Webcam-button--picture"
+    <button
+      class="uppy-u-reset uppy-c-btn uppy-Webcam-button uppy-Webcam-button--picture"
       type="button"
       title={i18n('takePicture')}
       aria-label={i18n('takePicture')}
       onclick={onSnapshot}
-      data-uppy-super-focusable>
+      data-uppy-super-focusable
+    >
       {CameraIcon()}
     </button>
   )

+ 19 - 16
packages/@uppy/webcam/src/index.js

@@ -345,24 +345,27 @@ module.exports = class Webcam extends Plugin {
     const webcamState = this.getPluginState()
 
     if (!webcamState.cameraReady) {
-      return <PermissionsScreen
-        icon={CameraIcon}
-        i18n={this.i18n} />
+      return (
+        <PermissionsScreen icon={CameraIcon} i18n={this.i18n} />
+      )
     }
 
-    return <CameraScreen
-      {...webcamState}
-      onSnapshot={this.takeSnapshot}
-      onStartRecording={this.startRecording}
-      onStopRecording={this.stopRecording}
-      onFocus={this.focus}
-      onStop={this.stop}
-      i18n={this.i18n}
-      modes={this.opts.modes}
-      supportsRecording={supportsMediaRecorder()}
-      recording={webcamState.isRecording}
-      mirror={this.opts.mirror}
-      src={this.stream} />
+    return (
+      <CameraScreen
+        {...webcamState}
+        onSnapshot={this.takeSnapshot}
+        onStartRecording={this.startRecording}
+        onStopRecording={this.stopRecording}
+        onFocus={this.focus}
+        onStop={this.stop}
+        i18n={this.i18n}
+        modes={this.opts.modes}
+        supportsRecording={supportsMediaRecorder()}
+        recording={webcamState.isRecording}
+        mirror={this.opts.mirror}
+        src={this.stream}
+      />
+    )
   }
 
   install () {

+ 1 - 1
test/endtoend/transloadit/test.js

@@ -40,7 +40,7 @@ describe('Transloadit file processing', () => {
         selectFakeFile,
         'uppyTransloadit',
         path.basename(img), // name
-        `image/jpeg`, // type
+        'image/jpeg', // type
         fs.readFileSync(img, 'base64') // b64
       )
       // browser.execute(selectFakeFile, 'uppyTransloadit')

+ 1 - 1
test/endtoend/utils.js

@@ -159,7 +159,7 @@ class TusService {
     const proxy = httpProxy.createProxyServer()
     this.slowServer = http.createServer((req, res) => {
       proxy.web(req, res, {
-        target: `http://localhost:1080`,
+        target: 'http://localhost:1080',
         // 200 kbps max upload, checking the rate limit every 20ms
         buffer: req.pipe(brake({
           period: 20,

+ 5 - 5
website/inject.js

@@ -156,8 +156,8 @@ async function injectGhStars () {
 
 async function injectMarkdown () {
   const sources = {
-    '.github/ISSUE_TEMPLATE/integration_help.md': `src/_template/integration_help.md`,
-    '.github/CONTRIBUTING.md': `src/_template/contributing.md`
+    '.github/ISSUE_TEMPLATE/integration_help.md': 'src/_template/integration_help.md',
+    '.github/CONTRIBUTING.md': 'src/_template/contributing.md'
   }
 
   for (const src in sources) {
@@ -173,9 +173,9 @@ async function injectMarkdown () {
     let content = `<!-- WARNING! This file was injected. Please edit in "${src}" instead and run "${path.basename(__filename)}" -->\n\n`
     content += parts.join('---\n')
     fs.writeFileSync(dstpath, content, 'utf-8')
-    console.info(chalk.green(`✓ injected: `), chalk.grey(srcpath))
+    console.info(chalk.green('✓ injected: '), chalk.grey(srcpath))
   }
-  touch(path.join(webRoot, `/src/support.md`))
+  touch(path.join(webRoot, '/src/support.md'))
 }
 
 function injectLocaleList () {
@@ -215,7 +215,7 @@ function injectLocaleList () {
 
   const dstpath = path.join(webRoot, 'src', '_template', 'list_of_locale_packs.md')
   fs.writeFileSync(dstpath, resultingMdTable, 'utf-8')
-  console.info(chalk.green(`✓ injected: `), chalk.grey(dstpath))
+  console.info(chalk.green('✓ injected: '), chalk.grey(dstpath))
 }
 
 async function readConfig () {

+ 1 - 1
website/scripts/highlight.js

@@ -17,7 +17,7 @@ const unhighlightedCodeRx = /<pre><code class="([^"]*)?">([\s\S]*?)<\/code><\/pr
 
 function highlight (lang, code) {
   const startTag = `<figure class="highlight ${lang}"><table><tr><td class="code"><pre>`
-  const endTag = `</pre></td></tr></table></figure>`
+  const endTag = '</pre></td></tr></table></figure>'
   let parsedCode = ''
   if (Prism.languages[lang]) {
     parsedCode = Prism.highlight(code, Prism.languages[lang])

Some files were not shown because too many files changed in this diff