Bläddra i källkod

Merge pull request #845 from transloadit/doc/react

Documentation improvements: individual React component pages, more plugin options
Artur Paikin 7 år sedan
förälder
incheckning
69b5e7934b
40 ändrade filer med 928 tillägg och 260 borttagningar
  1. 2 3
      src/core/Core.js
  2. 32 3
      src/core/Translator.js
  3. 16 0
      src/core/Translator.test.js
  4. 9 5
      src/plugins/Dashboard/ActionBrowseTagline.js
  5. 3 3
      src/plugins/Dashboard/Dashboard.js
  6. 22 5
      src/plugins/Dashboard/FileCard.js
  7. 1 1
      src/plugins/Dashboard/FileItem.js
  8. 27 26
      src/plugins/Dashboard/FileList.js
  9. 2 1
      src/plugins/Dashboard/Tabs.js
  10. 7 5
      src/plugins/Dashboard/index.js
  11. 5 2
      src/plugins/DragDrop/index.js
  12. 1 1
      test/endtoend/src/main.js
  13. 17 0
      website/src/docs/aws-s3.md
  14. 76 47
      website/src/docs/dashboard.md
  15. 28 6
      website/src/docs/dragdrop.md
  16. 53 0
      website/src/docs/dropbox.md
  17. 19 4
      website/src/docs/fileinput.md
  18. 13 1
      website/src/docs/form.md
  19. 53 0
      website/src/docs/google-drive.md
  20. 16 0
      website/src/docs/informer.md
  21. 53 0
      website/src/docs/instagram.md
  22. 6 49
      website/src/docs/plugins.md
  23. 16 0
      website/src/docs/progressbar.md
  24. 37 0
      website/src/docs/providers.md
  25. 79 0
      website/src/docs/react-dashboard-modal.md
  26. 16 51
      website/src/docs/react-dashboard.md
  27. 26 0
      website/src/docs/react-dragdrop.md
  28. 25 0
      website/src/docs/react-progressbar.md
  29. 26 0
      website/src/docs/react-statusbar.md
  30. 11 7
      website/src/docs/react.md
  31. 1 1
      website/src/docs/redux.md
  32. 71 30
      website/src/docs/statusbar.md
  33. 24 0
      website/src/docs/transloadit.md
  34. 6 0
      website/src/docs/tus.md
  35. 6 0
      website/src/docs/uppy.md
  36. 62 0
      website/src/docs/url.md
  37. 32 6
      website/src/docs/webcam.md
  38. 1 1
      website/src/docs/writing-plugins.md
  39. 21 2
      website/src/docs/xhrupload.md
  40. 7 0
      website/themes/uppy/layout/partials/sidebar.ejs

+ 2 - 3
src/core/Core.js

@@ -31,7 +31,7 @@ class Uppy {
         exceedsSize: 'This file exceeds maximum allowed size of',
         youCanOnlyUploadFileTypes: 'You can only upload:',
         uppyServerError: 'Connection with Uppy Server failed',
-        failedToUpload: 'Failed to upload',
+        failedToUpload: 'Failed to upload %{file}',
         noInternetConnection: 'No Internet connection',
         connectedToInternet: 'Connected to the Internet',
         noFilesFound: 'You have no files or folders here'
@@ -657,8 +657,7 @@ class Uppy {
       this.setFileState(file.id, { error: error.message })
       this.setState({ error: error.message })
 
-      let message
-      message = `${this.i18n('failedToUpload')} ${file.name}`
+      let message = this.i18n('failedToUpload', { file: file.name })
       if (typeof error === 'object' && error.message) {
         message = { message: message, details: error.message }
       }

+ 32 - 3
src/core/Translator.js

@@ -41,9 +41,10 @@ module.exports = class Translator {
    * @return {string} interpolated
    */
   interpolate (phrase, options) {
-    const replace = String.prototype.replace
+    const { split, replace } = String.prototype
     const dollarRegex = /\$/g
     const dollarBillsYall = '$$$$'
+    let interpolated = [phrase]
 
     for (let arg in options) {
       if (arg !== '_' && options.hasOwnProperty(arg)) {
@@ -57,10 +58,28 @@ module.exports = class Translator {
         // We create a new `RegExp` each time instead of using a more-efficient
         // string replace so that the same argument can be replaced multiple times
         // in the same phrase.
-        phrase = replace.call(phrase, new RegExp('%\\{' + arg + '\\}', 'g'), replacement)
+        interpolated = insertReplacement(interpolated, new RegExp('%\\{' + arg + '\\}', 'g'), replacement)
       }
     }
-    return phrase
+
+    return interpolated
+
+    function insertReplacement (source, rx, replacement) {
+      const newParts = []
+      source.forEach((chunk) => {
+        split.call(chunk, rx).forEach((raw, i, list) => {
+          if (raw !== '') {
+            newParts.push(raw)
+          }
+
+          // Interlace with the `replacement` value
+          if (i < list.length - 1) {
+            newParts.push(replacement)
+          }
+        })
+      })
+      return newParts
+    }
   }
 
   /**
@@ -71,6 +90,16 @@ module.exports = class Translator {
    * @return {string} translated (and interpolated)
    */
   translate (key, options) {
+    return this.translateArray(key, options).join('')
+  }
+
+  /**
+   * Get a translation and return the translated and interpolated parts as an array.
+   * @param {string} key
+   * @param {object} options with values that will be used to replace placeholders
+   * @return {Array} The translated and interpolated parts, in order.
+   */
+  translateArray (key, options) {
     if (options && typeof options.smart_count !== 'undefined') {
       var plural = this.locale.pluralize(options.smart_count)
       return this.interpolate(this.opts.locale.strings[key][plural], options)

+ 16 - 0
src/core/Translator.test.js

@@ -8,6 +8,22 @@ describe('core/translator', () => {
       const core = new Core({ locale: russian })
       expect(core.translator.translate('chooseFile')).toEqual('Выберите файл')
     })
+
+    it('should translate a string with non-string elements', () => {
+      const core = new Core({
+        locale: {
+          strings: {
+            test: 'Hello %{who}!',
+            test2: 'Hello %{who}'
+          }
+        }
+      })
+
+      const who = Symbol('who')
+      expect(core.translator.translateArray('test', { who: who })).toEqual(['Hello ', who, '!'])
+      // No empty string at the end.
+      expect(core.translator.translateArray('test2', { who: who })).toEqual(['Hello ', who])
+    })
   })
 
   describe('interpolation', () => {

+ 9 - 5
src/plugins/Dashboard/ActionBrowseTagline.js

@@ -11,17 +11,21 @@ class ActionBrowseTagline extends Component {
   }
 
   render () {
+    const browse = (
+      <button type="button" class="uppy-Dashboard-browse" onclick={this.handleClick}>
+        {this.props.i18n('browse')}
+      </button>
+    )
+
     // empty value="" on file input, so that the input is cleared after a file is selected,
     // because Uppy will be handling the upload and so we can select same file
     // after removing — otherwise browser thinks it’s already selected
     return (
       <span>
         {this.props.acquirers.length === 0
-          ? this.props.i18n('dropPaste')
-          : this.props.i18n('dropPasteImport')
-        } <button type="button" class="uppy-Dashboard-browse" onclick={this.handleClick}>
-          {this.props.i18n('browse')}
-        </button>
+          ? this.props.i18nArray('dropPaste', { browse })
+          : this.props.i18nArray('dropPasteImport', { browse })
+        }
         <input class="uppy-Dashboard-input"
           hidden
           aria-hidden="true"

+ 3 - 3
src/plugins/Dashboard/Dashboard.js

@@ -8,11 +8,11 @@ const { h } = require('preact')
 // http://dev.edenspiekermann.com/2016/02/11/introducing-accessible-modal-dialog
 // https://github.com/ghosh/micromodal
 
-const renderInnerPanel = (props) => {
+const PanelContent = (props) => {
   return <div style={{ width: '100%', height: '100%' }}>
     <div class="uppy-DashboardContent-bar">
       <div class="uppy-DashboardContent-title">
-        {props.i18n('importFrom')} {props.activePanel ? props.activePanel.name : null}
+        {props.i18n('importFrom', { name: props.activePanel.name })}
       </div>
       <button class="uppy-DashboardContent-back"
         type="button"
@@ -73,7 +73,7 @@ module.exports = function Dashboard (props) {
             role="tabpanel"
             id={props.activePanel && `uppy-DashboardContent-panel--${props.activePanel.id}`}
             aria-hidden={props.activePanel ? 'false' : 'true'}>
-            {props.activePanel && renderInnerPanel(props)}
+            {props.activePanel && <PanelContent {...props} />}
           </div>
 
           <div class="uppy-Dashboard-progressindicators">

+ 22 - 5
src/plugins/Dashboard/FileCard.js

@@ -56,13 +56,30 @@ module.exports = class FileCard extends Component {
   }
 
   render () {
+    if (!this.props.fileCardFor) {
+      return <div class="uppy-DashboardFileCard" aria-hidden />
+    }
+
     const file = this.props.files[this.props.fileCardFor]
 
-    return <div class="uppy-DashboardFileCard" aria-hidden={!this.props.fileCardFor}>
-      {this.props.fileCardFor &&
+    console.log({
+      what: this.props.i18n('editing', {
+        file: 'test'
+      }),
+      ever: this.props.i18nArray('editing', {
+        file: <span class="uppy-DashboardContent-titleFile">{file.meta ? file.meta.name : file.name}</span>
+      })
+    })
+
+    return (
+      <div class="uppy-DashboardFileCard" aria-hidden={!this.props.fileCardFor}>
         <div style={{ width: '100%', height: '100%' }}>
           <div class="uppy-DashboardContent-bar">
-            <h2 class="uppy-DashboardContent-title">{this.props.i18n('editing')} <span class="uppy-DashboardContent-titleFile">{file.meta ? file.meta.name : file.name}</span></h2>
+            <h2 class="uppy-DashboardContent-title">
+              {this.props.i18nArray('editing', {
+                file: <span class="uppy-DashboardContent-titleFile">{file.meta ? file.meta.name : file.name}</span>
+              })}
+            </h2>
             <button class="uppy-DashboardContent-back" type="button" title={this.props.i18n('finishEditingFile')}
               onclick={this.handleSave}>{this.props.i18n('done')}</button>
           </div>
@@ -86,7 +103,7 @@ module.exports = class FileCard extends Component {
             </div>
           </div>
         </div>
-      }
-    </div>
+      </div>
+    )
   }
 }

+ 1 - 1
src/plugins/Dashboard/FileItem.js

@@ -103,7 +103,7 @@ module.exports = function fileItem (props) {
         {file.source && <div class="uppy-DashboardItem-sourceIcon">
             {acquirers.map(acquirer => {
               if (acquirer.id === file.source) {
-                return <span title={`${props.i18n('fileSource')}: ${acquirer.name}`}>
+                return <span title={props.i18n('fileSource', { name: acquirer.name })}>
                   {acquirer.icon()}
                 </span>
               }

+ 27 - 26
src/plugins/Dashboard/FileList.js

@@ -15,35 +15,36 @@ module.exports = (props) => {
     {noFiles &&
       <div class="uppy-Dashboard-bgIcon">
         <div class="uppy-Dashboard-dropFilesTitle">
-          {h(ActionBrowseTagline, {
-            acquirers: props.acquirers,
-            handleInputChange: props.handleInputChange,
-            i18n: props.i18n,
-            allowedFileTypes: props.allowedFileTypes,
-            maxNumberOfFiles: props.maxNumberOfFiles
-          })}
+          <ActionBrowseTagline
+            acquirers={props.acquirers}
+            handleInputChange={props.handleInputChange}
+            i18n={props.i18n}
+            i18nArray={props.i18nArray}
+            allowedFileTypes={props.allowedFileTypes}
+            maxNumberOfFiles={props.maxNumberOfFiles}
+          />
         </div>
         { props.note && <div class="uppy-Dashboard-note">{props.note}</div> }
       </div>
     }
-    {Object.keys(props.files).map((fileID) => {
-      return FileItem({
-        acquirers: props.acquirers,
-        file: props.files[fileID],
-        toggleFileCard: props.toggleFileCard,
-        showProgressDetails: props.showProgressDetails,
-        info: props.info,
-        log: props.log,
-        i18n: props.i18n,
-        removeFile: props.removeFile,
-        pauseUpload: props.pauseUpload,
-        cancelUpload: props.cancelUpload,
-        retryUpload: props.retryUpload,
-        resumableUploads: props.resumableUploads,
-        isWide: props.isWide,
-        showLinkToFileUploadResult: props.showLinkToFileUploadResult,
-        metaFields: props.metaFields
-      })
-    })}
+    {Object.keys(props.files).map((fileID) => (
+      <FileItem
+        acquirers={props.acquirers}
+        file={props.files[fileID]}
+        toggleFileCard={props.toggleFileCard}
+        showProgressDetails={props.showProgressDetails}
+        info={props.info}
+        log={props.log}
+        i18n={props.i18n}
+        removeFile={props.removeFile}
+        pauseUpload={props.pauseUpload}
+        cancelUpload={props.cancelUpload}
+        retryUpload={props.retryUpload}
+        resumableUploads={props.resumableUploads}
+        isWide={props.isWide}
+        showLinkToFileUploadResult={props.showLinkToFileUploadResult}
+        metaFields={props.metaFields}
+      />
+    ))}
   </ul>
 }

+ 2 - 1
src/plugins/Dashboard/Tabs.js

@@ -23,7 +23,8 @@ class Tabs extends Component {
             <ActionBrowseTagline
               acquirers={this.props.acquirers}
               handleInputChange={this.props.handleInputChange}
-              i18n={this.props.i18n} />
+              i18n={this.props.i18n}
+              i18nArray={this.props.i18nArray} />
           </div>
         </div>
       )

+ 7 - 5
src/plugins/Dashboard/index.js

@@ -41,25 +41,25 @@ module.exports = class Dashboard extends Plugin {
         selectToUpload: 'Select files to upload',
         closeModal: 'Close Modal',
         upload: 'Upload',
-        importFrom: 'Import from',
+        importFrom: 'Import from %{name}',
         dashboardWindowTitle: 'Uppy Dashboard Window (Press escape to close)',
         dashboardTitle: 'Uppy Dashboard',
         copyLinkToClipboardSuccess: 'Link copied to clipboard',
         copyLinkToClipboardFallback: 'Copy the URL below',
         copyLink: 'Copy link',
-        fileSource: 'File source',
+        fileSource: 'File source: %{name}',
         done: 'Done',
         name: 'Name',
         removeFile: 'Remove file',
         editFile: 'Edit file',
-        editing: 'Editing',
+        editing: 'Editing %{file}',
         finishEditingFile: 'Finish editing file',
         saveChanges: 'Save changes',
         cancel: 'Cancel',
         localDisk: 'Local Disk',
         myDevice: 'My Device',
-        dropPasteImport: 'Drop files here, paste, import from one of the locations above or',
-        dropPaste: 'Drop files here, paste or',
+        dropPasteImport: 'Drop files here, paste, import from one of the locations above or %{browse}',
+        dropPaste: 'Drop files here, paste or %{browse}',
         browse: 'browse',
         fileProgress: 'File progress: upload speed and ETA',
         numberOfSelectedFiles: 'Number of selected files',
@@ -117,6 +117,7 @@ module.exports = class Dashboard extends Plugin {
 
     this.translator = new Translator({locale: this.locale})
     this.i18n = this.translator.translate.bind(this.translator)
+    this.i18nArray = this.translator.translateArray.bind(this.translator)
 
     this.openModal = this.openModal.bind(this)
     this.closeModal = this.closeModal.bind(this)
@@ -467,6 +468,7 @@ module.exports = class Dashboard extends Plugin {
       hideAllPanels: this.hideAllPanels,
       log: this.uppy.log,
       i18n: this.i18n,
+      i18nArray: this.i18nArray,
       addFile: this.uppy.addFile,
       removeFile: this.uppy.removeFile,
       info: this.uppy.info,

+ 5 - 2
src/plugins/DragDrop/index.js

@@ -17,7 +17,7 @@ module.exports = class DragDrop extends Plugin {
 
     const defaultLocale = {
       strings: {
-        dropHereOr: 'Drop files here or',
+        dropHereOr: 'Drop files here or %{browse}',
         browse: 'browse'
       }
     }
@@ -44,6 +44,7 @@ module.exports = class DragDrop extends Plugin {
     // i18n
     this.translator = new Translator({locale: this.locale})
     this.i18n = this.translator.translate.bind(this.translator)
+    this.i18nArray = this.translator.translateArray.bind(this.translator)
 
     // Bind `this` to class methods
     this.handleDrop = this.handleDrop.bind(this)
@@ -140,7 +141,9 @@ module.exports = class DragDrop extends Plugin {
               }}
               onchange={this.handleInputChange}
               value="" />
-            {this.i18n('dropHereOr')} <span class="uppy-DragDrop-dragText">{this.i18n('browse')}</span>
+            {this.i18nArray('dropHereOr', {
+              browse: <span class="uppy-DragDrop-dragText">{this.i18n('browse')}</span>
+            })}
           </label>
           <span class="uppy-DragDrop-note">{this.opts.note}</span>
         </div>

+ 1 - 1
test/endtoend/src/main.js

@@ -24,7 +24,7 @@ const uppyi18n = Uppy({
     target: '#uppyi18n',
     locale: {
       strings: {
-        dropHereOr: 'Перенесите файлы сюда или',
+        dropHereOr: 'Перенесите файлы сюда или %{browse}',
         browse: 'выберите'
       }
     }

+ 17 - 0
website/src/docs/aws-s3.md

@@ -25,6 +25,10 @@ There is also a separate plugin for S3 Multipart uploads. Multipart in this sens
 
 ## Options
 
+### `id: 'AwsS3'`
+
+A unique identifier for this plugin. Defaults to `'AwsS3'`.
+
 ### `host`
 
 When using [uppy-server][uppy-server docs] to sign S3 uploads, set this option to the root URL of the uppy-server.
@@ -66,6 +70,19 @@ The default is 30 seconds.
 Limit the amount of uploads going on at the same time. This is passed through to [XHRUpload](/docs/xhrupload#limit-0); see its documentation page for details.
 Set to `0` to disable limiting.
 
+### `locale: {}`
+
+Localize text that is shown to the user.
+
+The default English strings are:
+
+```js
+strings: {
+  // Shown in the StatusBar while the upload is being signed.
+  preparingUpload: 'Preparing upload...'
+}
+```
+
 ## S3 Bucket configuration
 
 S3 buckets do not allow public uploads by default.

+ 76 - 47
website/src/docs/dashboard.md

@@ -14,6 +14,14 @@ Dashboard is a universal UI plugin for Uppy:
 - Progress: total and for individual files
 - Ability to pause/resume or cancel (depending on uploader plugin) individual or all files
 
+```js
+const Dashboard = require('uppy/lib/plugins/Dashboard')
+
+uppy.use(Dashboard, {
+  // Options
+})
+```
+
 [Try it live](/examples/dashboard/)
 
 ## Options
@@ -40,54 +48,15 @@ uppy.use(Dashboard, {
   disablePageScrollWhenModalOpen: true,
   proudlyDisplayPoweredByUppy: true,
   onRequestCloseModal: () => this.closeModal(),
-  locale: {
-    strings: {
-      selectToUpload: 'Select files to upload',
-      closeModal: 'Close Modal',
-      upload: 'Upload',
-      importFrom: 'Import from',
-      dashboardWindowTitle: 'Uppy Dashboard Window (Press escape to close)',
-      dashboardTitle: 'Uppy Dashboard',
-      copyLinkToClipboardSuccess: 'Link copied to clipboard.',
-      copyLinkToClipboardFallback: 'Copy the URL below',
-      copyLink: 'Copy link',
-      fileSource: 'File source',
-      done: 'Done',
-      name: 'Name',
-      removeFile: 'Remove file',
-      editFile: 'Edit file',
-      editing: 'Editing',
-      finishEditingFile: 'Finish editing file',
-      localDisk: 'Local Disk',
-      myDevice: 'My Device',
-      dropPasteImport: 'Drop files here, paste, import from one of the locations above or',
-      dropPaste: 'Drop files here, paste or',
-      browse: 'browse',
-      fileProgress: 'File progress: upload speed and ETA',
-      numberOfSelectedFiles: 'Number of selected files',
-      uploadAllNewFiles: 'Upload all new files',
-      emptyFolderAdded: 'No files were added from empty folder',
-      uploadComplete: 'Upload complete',
-      resumeUpload: 'Resume upload',
-      pauseUpload: 'Pause upload',
-      retryUpload: 'Retry upload',
-      uploadXFiles: {
-        0: 'Upload %{smart_count} file',
-        1: 'Upload %{smart_count} files'
-      },
-      uploadXNewFiles: {
-        0: 'Upload +%{smart_count} file',
-        1: 'Upload +%{smart_count} files'
-      },
-      folderAdded: {
-        0: 'Added %{smart_count} file from %{folder}',
-        1: 'Added %{smart_count} files from %{folder}'
-      }
-    }
-  }
+  locale: {}
 })
 ```
 
+### `id: 'Dashboard'`
+
+A unique identifier for this Dashboard. Defaults to `'Dashboard'`. Change this if you need multiple Dashboard instances.
+Plugins that are added by the Dashboard get unique IDs based on this ID, like `'Dashboard:StatusBar'` and `'Dashboard:Informer'`.
+
 ### `target: 'body'`
 
 Dashboard is rendered into `body` by default, because by default it’s hidden and only opened as a modal when `trigger` is clicked.
@@ -187,9 +156,69 @@ Dashboard ships with the `Informer` plugin that notifies when the browser is off
 
 Dashboard ships with `ThumbnailGenerator` plugin that adds small resized image thumbnails to images, for preview purposes only. If you want, you can disable the `ThumbnailGenerator` and/or provide your custom solution.
 
-### `locale`
+### `locale: {}`
+
+Localize text that is shown to the user.
+
+The default English strings are:
+
+```js
+strings: {
+  // When `inline: false`, used as the screen reader label for the button that closes the modal.
+  closeModal: 'Close Modal',
+  // Used as the header for import panels, eg. "Import from Google Drive"
+  importFrom: 'Import from %{name}',
+  // When `inline: false`, used as the screen reader label for the dashboard modal.
+  dashboardWindowTitle: 'Uppy Dashboard Window (Press escape to close)',
+  // When `inline: true`, used as the screen reader label for the dashboard area.
+  dashboardTitle: 'Uppy Dashboard',
+  // Shown in the Informer when a link to a file was copied to the clipboard.
+  copyLinkToClipboardSuccess: 'Link copied to clipboard.',
+  // Used when a link cannot be copied automatically—the user has to select the text from the
+  // input element below this string.
+  copyLinkToClipboardFallback: 'Copy the URL below',
+  // Used as the hover title and screen reader label for buttons that copy a file link.
+  copyLink: 'Copy link',
+  // Used as the hover title and screen reader label for file source icons. Eg. "File source: Dropbox"
+  fileSource: 'File source: %{name}',
+  // Used as the label for buttons that accept and close panels (remote providers or metadata editor)
+  done: 'Done',
+  // Used as the screen reader label for buttons that remove a file.
+  removeFile: 'Remove file',
+  // Used as the screen reader label for buttons that open the metadata editor panel for a file.
+  editFile: 'Edit file',
+  // Shown in the panel header for the metadata editor. Rendered as "Editing image.png".
+  editing: 'Editing %{file}',
+  // Used as the screen reader label for the button that saves metadata edits and returns to the
+  // file list view.
+  finishEditingFile: 'Finish editing file',
+  // Used as the label for the tab button that opens the system file selection dialog.
+  myDevice: 'My Device',
+  // Shown in the main dashboard area when no files have been selected, and one or more
+  // remote provider plugins are in use. %{browse} is replaced with a link that opens the system
+  // file selection dialog.
+  dropPasteImport: 'Drop files here, paste, import from one of the locations above or %{browse}',
+  // Shown in the main dashboard area when no files have been selected, and no provider
+  // plugins are in use. %{browse} is replaced with a link that opens the system
+  // file selection dialog.
+  dropPaste: 'Drop files here, paste or %{browse}',
+  // This string is clickable and opens the system file selection dialog.
+  browse: 'browse',
+  // Used as the hover text and screen reader label for file progress indicators when
+  // they have been fully uploaded.
+  uploadComplete: 'Upload complete',
+  // Used as the hover text and screen reader label for the buttons to resume paused uploads.
+  resumeUpload: 'Resume upload',
+  // Used as the hover text and screen reader label for the buttons to pause uploads.
+  pauseUpload: 'Pause upload',
+  // Used as the hover text and screen reader label for the buttons to retry failed uploads.
+  retryUpload: 'Retry upload'
+}
+```
+
+### `replaceTargetContent: false`
 
-See [general plugin options](/docs/plugins).
+Remove all children of the `target` element before mounting the Dashboard. By default, Uppy will append any UI to the `target` DOM element. This is the least dangerous option. However, there might be cases when you’d want to clear the container element before placing Uppy UI in there (for example, to provide a fallback `<form>` that will be shown if Uppy or JavaScript is not available). Set `replaceTargetContent: true` to clear the `target` before appending.
 
 ## Methods
 

+ 28 - 6
website/src/docs/dragdrop.md

@@ -7,6 +7,14 @@ permalink: docs/dragdrop/
 
 DragDrop renders a simple Drag and Drop area for file selection. Useful when you only want the local device as a file source, don’t need file previews and metadata editing UI, and the [Dashboard](/docs/dashboard/) feels like an overkill.
 
+```js
+const DragDrop = require('uppy/lib/plugins/DragDrop')
+
+uppy.use(DragDrop, {
+  // Options
+})
+```
+
 [Try it live](/examples/dragdrop/)
 
 ## Options
@@ -17,17 +25,16 @@ uppy.use(DragDrop, {
   width: '100%',
   height: '100%',
   note: null,
-  locale: {
-    strings: {
-      dropHereOr: 'Drop files here or',
-      browse: 'browse'
-    }
-  }
+  locale: {}
 })
 ```
 
 > Note that certain [restrictions set in Uppy’s main options](/docs/uppy#restrictions), namely `maxNumberOfFiles` and `allowedFileTypes`, affect the system file picker dialog. If `maxNumberOfFiles: 1`, users will only be able to select one file, and `allowedFileTypes: ['video/*', '.gif']` means only videos or gifs (files with `.gif` extension) will be selectable.
 
+### `id: 'DragDrop'`
+
+A unique identifier for this DragDrop. Defaults to `'DragDrop'`. Use this if you need to add multiple DragDrop instances.
+
 ### `target: null`
 
 DOM element, CSS selector, or plugin to place the drag and drop area into.
@@ -44,3 +51,18 @@ Drag and drop area height, set in inline CSS, so feel free to use percentage, pi
 
 Optionally specify a string of text that explains something about the upload for the user. This is a place to explain `restrictions` that are put in place. For example: `'Images and video only, 2–3 files, up to 1 MB'`.
 
+### `locale: {}`
+
+Localize text that is shown to the user.
+
+The default English strings are:
+
+```js
+strings: {
+  // Text to show on the droppable area.
+  // `%{browse}` is replaced with a link that opens the system file selection dialog.
+  dropHereOr: 'Drop here or %{browse}',
+  // Used as the label for the link that opens the system file selection dialog.
+  browse: 'browse'
+}
+```

+ 53 - 0
website/src/docs/dropbox.md

@@ -0,0 +1,53 @@
+---
+type: docs
+order: 51
+title: "Dropbox"
+permalink: docs/dropbox/
+---
+
+The Dropbox plugin lets users import files their Google Drive account.
+
+An Uppy Server instance is required for the Dropbox plugin to work. Uppy Server handles authentication with Dropbox, downloads the files, and uploads them to the destination. This saves the user bandwidth, especially helpful if they are on a mobile connection.
+
+```js
+const Dropbox = require('uppy/lib/plugins/Dropbox')
+
+uppy.use(Dropbox, {
+  // Options
+})
+```
+
+[Try live!](/examples/dashboard/)
+
+## Options
+
+```js
+uppy.use(Dropbox, {
+  target: Dashboard,
+  host: 'https://server.uppy.io/',
+})
+```
+
+### `id: 'Dropbox'`
+
+A unique identifier for this plugin. Defaults to `'Dropbox'`.
+
+### `target: null`
+
+DOM element, CSS selector, or plugin to mount the Dropbox provider into. This should normally be the Dashboard.
+
+### `host: null`
+
+URL to an Uppy Server instance.
+
+### `locale: {}`
+
+Localize text that is shown to the user.
+
+The default English strings are:
+
+```js
+strings: {
+  // TODO
+}
+```

+ 19 - 4
website/src/docs/fileinput.md

@@ -7,6 +7,14 @@ permalink: docs/fileinput/
 
 `FileInput` is the most barebones UI for selecting files—it shows a single button that, when clicked, opens up the browser's file selector.
 
+```js
+const XHRUpload = require('uppy/lib/plugins/XHRUpload')
+
+uppy.use(XHRUpload, {
+  // Options
+})
+```
+
 [Try it live](/examples/xhrupload) - The XHRUpload example uses a `FileInput`.
 
 ## Options
@@ -17,15 +25,16 @@ uppy.use(FileInput, {
   pretty: true,
   inputName: 'files[]',
   locale: {
-    strings: {
-      chooseFiles: 'Choose files'
-    }
   }
 })
 ```
 
 > Note that certain [restrictions set in Uppy’s main options](/docs/uppy#restrictions), namely `maxNumberOfFiles` and `allowedFileTypes`, affect the system file picker dialog. If `maxNumberOfFiles: 1`, users will only be able to select one file, and `allowedFileTypes: ['video/*', '.gif']` means only videos or gifs (files with `.gif` extension) will be selectable.
 
+### `id: 'FileInput'`
+
+A unique identifier for this FileInput. Defaults to `'FileInput'`. Use this if you need to add multiple FileInput instances.
+
 ### `target: null`
 
 DOM element, CSS selector, or plugin to mount the file input into.
@@ -40,4 +49,10 @@ The `name` attribute for the `<input type="file">` element.
 
 ### `locale: {}`
 
-Custom text to show on the button when `pretty` is true.
+When `pretty` is set, specify a custom label for the button.
+
+```js
+strings: {
+  chooseFiles: 'Choose files'
+}
+```

+ 13 - 1
website/src/docs/form.md

@@ -7,6 +7,14 @@ permalink: docs/form/
 
 Form plugin collects metadata from any specified `<form>` element, right before Uppy begins uploading/processing files. And then optionally appends results back to the form. Currently the appended result is a stringified version of a [`result`](docs/uppy/#uppy-upload) returned from `uppy.upload()` or `complete` event.
 
+```js
+const Form = require('uppy/lib/plugins/Form')
+
+uppy.use(Form, {
+  // Options
+})
+```
+
 ## Options
 
 ```js
@@ -19,6 +27,10 @@ uppy.use(Form, {
 })
 ```
 
+### `id: 'Form'`
+
+A unique identifier for this Form. Defaults to `'Form'`.
+
 ### `target: null`
 
 DOM element or CSS selector for the form element. Required for the plugin to work.
@@ -33,7 +45,7 @@ Whether to add upload/encoding results back to the form in an `<input name="uppy
 
 ### `resultName: 'uppyResult'`
 
-The `name` attribute for the `<input type="hidden">` where the result will be added. 
+The `name` attribute for the `<input type="hidden">` where the result will be added.
 
 ### `submitOnSuccess: false`
 

+ 53 - 0
website/src/docs/google-drive.md

@@ -0,0 +1,53 @@
+---
+type: docs
+order: 52
+title: "GoogleDrive"
+permalink: docs/google-drive/
+---
+
+The GoogleDrive plugin lets users import files their Google Drive account.
+
+An Uppy Server instance is required for the GoogleDrive plugin to work. Uppy Server handles authentication with Google, downloads files from the Drive and uploads them to the destination. This saves the user bandwidth, especially helpful if they are on a mobile connection.
+
+```js
+const GoogleDrive = require('uppy/lib/plugins/GoogleDrive')
+
+uppy.use(GoogleDrive, {
+  // Options
+})
+```
+
+[Try live!](/examples/dashboard/)
+
+## Options
+
+```js
+uppy.use(GoogleDrive, {
+  target: Dashboard,
+  host: 'https://server.uppy.io/',
+})
+```
+
+### `id: 'GoogleDrive'`
+
+A unique identifier for this plugin. Defaults to `'GoogleDrive'`.
+
+### `target: null`
+
+DOM element, CSS selector, or plugin to mount the GoogleDrive provider into. This should normally be the Dashboard.
+
+### `host: null`
+
+URL to an Uppy Server instance.
+
+### `locale: {}`
+
+Localize text that is shown to the user.
+
+The default English strings are:
+
+```js
+strings: {
+  // TODO
+}
+```

+ 16 - 0
website/src/docs/informer.md

@@ -7,10 +7,22 @@ permalink: docs/informer/
 
 The Informer is a pop-up bar for showing notifications. When plugins have some exciting news (or error) to share, they can show a notification here.
 
+```js
+const Informer = require('uppy/lib/plugins/Informer')
+
+uppy.use(Informer, {
+  // Options
+})
+```
+
 [Try it live](/examples/dashboard/) - The Informer is included in the Dashboard by default.
 
 ## Options
 
+### `id: 'Informer'`
+
+A unique identifier for this Informer. Defaults to `'Informer'`. Use this if you need multiple Informer instances.
+
 ### `target: null`
 
 DOM element, CSS selector, or plugin to mount the informer into.
@@ -29,3 +41,7 @@ uppy.use(Informer, {
   }
 })
 ```
+
+### `replaceTargetContent: false`
+
+Remove all children of the `target` element before mounting the Informer. By default, Uppy will append any UI to the `target` DOM element. This is the least dangerous option. However, you may have some fallback HTML inside the `target` element in case JavaScript or Uppy is not available. In that case you can set `replaceTargetContent: true` to clear the `target` before appending.

+ 53 - 0
website/src/docs/instagram.md

@@ -0,0 +1,53 @@
+---
+type: docs
+order: 53
+title: "Instagram"
+permalink: docs/instagram/
+---
+
+The Instagram plugin lets users import files their Google Drive account.
+
+An Uppy Server instance is required for the Instagram plugin to work. Uppy Server handles authentication with Instagram, downloads the pictures and videos, and uploads them to the destination. This saves the user bandwidth, especially helpful if they are on a mobile connection.
+
+```js
+const Instagram = require('uppy/lib/plugins/Instagram')
+
+uppy.use(Instagram, {
+  // Options
+})
+```
+
+[Try live!](/examples/dashboard/)
+
+## Options
+
+```js
+uppy.use(Instagram, {
+  target: Dashboard,
+  host: 'https://server.uppy.io/',
+})
+```
+
+### `id: 'Instagram'`
+
+A unique identifier for this plugin. Defaults to `'Instagram'`.
+
+### `target: null`
+
+DOM element, CSS selector, or plugin to mount the Instagram provider into. This should normally be the Dashboard.
+
+### `host: null`
+
+URL to an Uppy Server instance.
+
+### `locale: {}`
+
+Localize text that is shown to the user.
+
+The default English strings are:
+
+```js
+strings: {
+  // TODO
+}
+```

+ 6 - 49
website/src/docs/plugins.md

@@ -11,8 +11,12 @@ Plugins are what makes Uppy useful: they help select, manipulate and upload file
   - [Dashboard](/docs/dashboard) — full featured sleek UI with file previews, metadata editing, upload/pause/resume/cancel buttons and more. Includes `StatusBar` and `Informer` plugins by default
   - [DragDrop](/docs/dragdrop) — plain and simple drag and drop area
   - [FileInput](/docs/fileinput) — even more plain and simple, just a button
-  - [Provider Plugins](#Provider-Plugins) (remote sources that work through [Uppy Server](/docs/uppy-server/)): Instagram, GoogleDrive, Dropbox, Url (direct link)
   - [Webcam](/docs/webcam) — upload selfies or audio / video recordings
+  - [Provider Plugins](/docs/providers) (remote sources that work through [Uppy Server](/docs/uppy-server/))
+    - [Dropbox](/docs/dropbox) – import files from Dropbox
+    - [GoogleDrive](/docs/google-drive) – import files from Google Drive
+    - [Instagram](/docs/instagram) – import files from Instagram
+    - [Url](/docs/url) – import files from any public URL
 - **Uploaders:**
   - [Tus](/docs/tus) — uploads using the [tus](https://tus.io) resumable upload protocol
   - [XHRUpload](/docs/xhrupload) — classic multipart form uploads or binary uploads using XMLHTTPRequest
@@ -62,24 +66,6 @@ uppy.use(GoogleDrive, {target: Dashboard})
 
 In the example above the `Dashboard` gets rendered into an element with ID `uppy`, while `GoogleDrive` is rendered into the `Dashboard` itself.
 
-### `endpoint`
-
-Used by uploader plugins, such as [Tus](/docs/tus) and [XHRUpload](/docs/xhrupload). Expects a `string` with a url that will be used for file uploading.
-
-### `host`
-
-Used by remote provider plugins, such as Google Drive, Instagram or Dropbox. Specifies the url to your running `uppy-server`. This allows uppy to know what server to connect to when server related operations are required by the provider plugin.
-
-```js
-// for Google Drive
-const GoogleDrive = require('uppy/lib/plugins/GoogleDrive')
-uppy.use(GoogleDrive, {target: Dashboard, host: 'http://localhost:3020'})
-```
-
-### `replaceTargetContent: false`
-
-By default Uppy will append any UI to a DOM element, if such element is specified as a `target`. This default is the least dangerous option. However, there might be cases when you’d want to clear the container element before placing Uppy UI in there (for example, to provide a fallback `<form>` that will be shown if Uppy or JavaScript is not loaded/supported on the page). Set `replaceTargetContent: true` to clear the `target` before appending.
-
 ### `locale: {}`
 
 Same as with Uppy.Core’s setting from above, this allows you to override plugin’s locale string, so that instead of `Select files` in English, your users will see `Выберите файлы` in Russian. Example:
@@ -97,33 +83,4 @@ See plugin documentation pages for other plugin-specific options.
 
 ## Provider Plugins
 
-The Provider plugins help you connect to your accounts with remote file providers such as [Dropbox](https://dropbox.com), [Google Drive](https://drive.google.com), [Instagram](https://instagram.com) and remote urls (import a file by pasting a direct link to it). Because this requires server to server communication, they work tightly with [uppy-server](https://github.com/transloadit/uppy-server) to manage the server to server authorization for your account. Virtually most of the communication (file download/upload) is done on the server-to-server end, so this saves you the stress of data consumption on the client.
-
-As of now, the supported providers are **Dropbox**, **GoogleDrive**, **Instagram**, and **Url**.
-
-Usage of the Provider plugins is not that different from any other *acquirer* plugin, except that it takes an extra option `host`, which specifies the url to your running `uppy-server`. This allows Uppy to know what server to connect to when server related operations are required by the provider plugin. Here's a quick example.
-
-```js
-const Uppy = require('uppy/lib/core')
-const Dashboard = require('uppy/lib/plugins/Dashboard')
-const uppy = Uppy()
-uppy.use(Dashboard, {
-  trigger: '#pick-files'
-})
-
-// for Google Drive
-const GoogleDrive = require('uppy/lib/plugins/GoogleDrive')
-uppy.use(GoogleDrive, {target: Dashboard, host: 'http://localhost:3020'})
-
-// for Dropbox
-const Dropbox = require('uppy/lib/plugins/Dropbox')
-uppy.use(Dropbox, {target: Dashboard, host: 'http://localhost:3020'})
-
-// for Instagram
-const Instagram = require('uppy/lib/plugins/Instagram')
-uppy.use(Instagram, {target: Dashboard, host: 'http://localhost:3020'})
-
-// for Url
-const Url = require('uppy/lib/plugins/Url')
-uppy.use(Url, {target: Dashboard, host: 'http://localhost:3020'})
-```
+See the [Provider Plugins](/docs/providers) documentation page for information on provider plugins.

+ 16 - 0
website/src/docs/progressbar.md

@@ -7,6 +7,14 @@ permalink: docs/progressbar/
 
 ProgressBar is a minimalist plugin that shows the current upload progress in a thin bar element, similar to the ones used by YouTube and GitHub when navigating between pages.
 
+```js
+const ProgressBar = require('uppy/lib/plugins/ProgressBar')
+
+uppy.use(ProgressBar, {
+  // Options
+})
+```
+
 [Try it live](/examples/dragdrop/) - The DragDrop example uses ProgressBars to show progress.
 
 ## Options
@@ -19,6 +27,10 @@ uppy.use(ProgressBar, {
 })
 ```
 
+### `id: 'ProgressBar'`
+
+A unique identifier for this ProgressBar. Defaults to `'ProgressBar'`. Use this if you need to add multiple ProgressBar instances.
+
 ### `target: null`
 
 DOM element, CSS selector, or plugin to mount the progress bar into.
@@ -37,3 +49,7 @@ uppy.use(ProgressBar, {
 ### `hideAfterFinish: true`
 
 When true, hides the progress bar after the upload has finished. If false, it remains visible.
+
+### `replaceTargetContent: false`
+
+Remove all children of the `target` element before mounting the ProgressBar. By default, Uppy will append any UI to the `target` DOM element. This is the least dangerous option. However, you may have some fallback HTML inside the `target` element in case JavaScript or Uppy is not available. In that case you can set `replaceTargetContent: true` to clear the `target` before appending.

+ 37 - 0
website/src/docs/providers.md

@@ -0,0 +1,37 @@
+---
+title: "Provider Plugins"
+type: docs
+permalink: docs/providers/
+order: 50
+---
+
+The Provider plugins help you connect to your accounts with remote file providers such as [Dropbox](https://dropbox.com), [Google Drive](https://drive.google.com), [Instagram](https://instagram.com) and remote urls (import a file by pasting a direct link to it). Because this requires server to server communication, they work tightly with [uppy-server](https://github.com/transloadit/uppy-server) to manage the server to server authorization for your account. Almost all of the communication (file download/upload) is done on the server-to-server end, so this saves you the stress and bills of data consumption on the client.
+
+As of now, the supported providers are [**Dropbox**](/docs/dropbox), [**GoogleDrive**](/docs/google-drive), [**Instagram**](/docs/instagram), and [**Url**](/docs/url).
+
+Usage of the Provider plugins is not that different from any other *acquirer* plugin, except that it takes an extra option `host`, which specifies the url to your running `uppy-server`. This allows Uppy to know what server to connect to when server related operations are required by the provider plugin. Here's a quick example.
+
+```js
+const Uppy = require('uppy/lib/core')
+const Dashboard = require('uppy/lib/plugins/Dashboard')
+const uppy = Uppy()
+uppy.use(Dashboard, {
+  trigger: '#pick-files'
+})
+
+// for Google Drive
+const GoogleDrive = require('uppy/lib/plugins/GoogleDrive')
+uppy.use(GoogleDrive, {target: Dashboard, host: 'http://localhost:3020'})
+
+// for Dropbox
+const Dropbox = require('uppy/lib/plugins/Dropbox')
+uppy.use(Dropbox, {target: Dashboard, host: 'http://localhost:3020'})
+
+// for Instagram
+const Instagram = require('uppy/lib/plugins/Instagram')
+uppy.use(Instagram, {target: Dashboard, host: 'http://localhost:3020'})
+
+// for Url
+const Url = require('uppy/lib/plugins/Url')
+uppy.use(Url, {target: Dashboard, host: 'http://localhost:3020'})
+```

+ 79 - 0
website/src/docs/react-dashboard-modal.md

@@ -0,0 +1,79 @@
+---
+title: "&lt;DashboardModal />"
+type: docs
+permalink: docs/react/dashboard-modal/
+order: 65
+---
+
+The `<DashboardModal />` component wraps the [Dashboard][] plugin, allowing control over the modal `open` state using a prop.
+
+```js
+import DashboardModal from 'uppy/lib/react/DashboardModal';
+```
+
+<!-- Make sure the old name of this section still works -->
+<a id="Options"></a>
+## Props
+
+On top of all the [Dashboard][] options, the `<DashboardModal />` plugin adds two additional props:
+
+ - `open` - Boolean true or false, setting this to `true` opens the modal and setting it to `false` closes it.
+ - `onRequestClose` - Callback called when the user attempts to close the modal, either by clicking the close button or by clicking outside the modal (if the `closeModalOnClickOutside` prop is set).
+
+To use other plugins like [Webcam][] with the `<DashboardModal />` component, add them to the Uppy instance and then specify their `id` in the [`plugins`](/docs/dashboard/#plugins) prop:
+
+```js
+// Do this wherever you initialize Uppy, eg. in a React component's constructor method.
+// Do NOT do it in `render()` or any other method that is called more than once!
+uppy.use(Webcam) // `id` defaults to "Webcam"
+uppy.use(Webcam, { id: 'MyWebcam' }) // `id` is… "MyWebcam"
+```
+
+Then do `plugins={['Webcam']}`.
+
+A full example that uses a button to open the modal is shown below:
+
+```js
+class MusicUploadButton extends React.Component {
+  constructor (props) {
+    super(props)
+
+    this.state = {
+      modalOpen: false
+    }
+
+    this.handleOpen = this.handleOpen.bind(this)
+    this.handleClose = this.handleClose.bind(this)
+  }
+
+  handleOpen () {
+    this.setState({
+      modalOpen: true
+    })
+  }
+
+  handleClose () {
+    this.setState({
+      modalOpen: false
+    })
+  }
+
+  render () {
+    return (
+      <div>
+        <button onClick={this.handleOpen}>Upload some music</button>
+        <DashboardModal
+          uppy={this.props.uppy}
+          closeModalOnClickOutside
+          open={this.state.modalOpen}
+          onRequestClose={this.handleClose}
+          plugins={['Webcam']}
+        />
+      </div>
+    );
+  }
+}
+```
+
+[Dashboard]: /docs/dashboard/
+[Webcam]: /docs/webcam/

+ 16 - 51
website/src/docs/react-dashboard.md

@@ -1,20 +1,21 @@
 ---
-title: "DashboardModal"
+title: "&lt;Dashboard />"
 type: docs
-permalink: docs/react/dashboard-modal/
-order: 51
+permalink: docs/react/dashboard/
+order: 64
 ---
 
-The `<DashboardModal />` component wraps the [Dashboard][] plugin, allowing control over the modal `open` state using a prop.
+The `<Dashboard />` component wraps the [Dashboard][] plugin. It only renders the Dashboard inline. To use the Dashboard modal (`inline: false`), use the [`<DashboardModal />`](/docs/react/dashboard-modal) component.
 
-## Options
+```js
+import Dashboard from 'uppy/lib/react/Dashboard';
+```
 
-On top of all the [Dashboard][] options, the `<DashboardModal />` plugin adds two additional props:
+## Props
 
- - `open` - Boolean true or false, setting this to `true` opens the modal and setting it to `false` closes it.
- - `onRequestClose` - Callback called when the user attempts to close the modal, either by clicking the close button or by clicking outside the modal (if the `closeModalOnClickOutside` prop is set).
+The `<Dashboard />` component supports all [Dashboard][] options as props.
 
-To use other plugins like [Webcam][] with the `<DashboardModal />` component, add them to the Uppy instance and then specify their `id` in the [`plugins`](/docs/dashboard/#plugins) prop:
+The `<Dashboard />` cannot be passed to a `target:` option of a remote provider or plugins like [Webcam][]. To use other plugins like [Webcam][] with the `<Dashboard />` component, first add them to the Uppy instance, and then specify their `id` in the [`plugins`](/docs/dashboard/#plugins) prop:
 
 ```js
 // Do this wherever you initialize Uppy, eg. in a React component's constructor method.
@@ -23,50 +24,14 @@ uppy.use(Webcam) // `id` defaults to "Webcam"
 uppy.use(Webcam, { id: 'MyWebcam' }) // `id` is… "MyWebcam"
 ```
 
-Then do `plugins={['Webcam']}`.
-
-A full example that uses a button to open the modal is shown below:
+Then in `render()` do:
 
 ```js
-class MusicUploadButton extends React.Component {
-  constructor (props) {
-    super(props)
-
-    this.state = {
-      modalOpen: false
-    }
-
-    this.handleOpen = this.handleOpen.bind(this)
-    this.handleClose = this.handleClose.bind(this)
-  }
-
-  handleOpen () {
-    this.setState({
-      modalOpen: true
-    })
-  }
-
-  handleClose () {
-    this.setState({
-      modalOpen: false
-    })
-  }
-
-  render () {
-    return (
-      <div>
-        <button onClick={this.handleOpen}>Upload some music</button>
-        <DashboardModal
-          uppy={this.props.uppy}
-          closeModalOnClickOutside
-          open={this.state.modalOpen}
-          onRequestClose={this.handleClose}
-          plugins={['Webcam']}
-        />
-      </div>
-    );
-  }
-}
+<Dashboard
+  plugins={['Webcam']}
+  {...props}
+/>
 ```
 
 [Dashboard]: /docs/dashboard/
+[Webcam]: /docs/webcam/

+ 26 - 0
website/src/docs/react-dragdrop.md

@@ -0,0 +1,26 @@
+---
+title: "&lt;DragDrop />"
+type: docs
+permalink: docs/react/dragdrop/
+order: 62
+---
+
+The `<DragDrop />` component wraps the [DragDrop][] plugin.
+
+```js
+import DragDrop from 'uppy/lib/react/DragDrop';
+```
+
+## Props
+
+The `<DragDrop />` component supports all [DragDrop][] options as props.
+
+```js
+<DragDrop
+  width="100%"
+  height="100%"
+  note="Images up to 200×200px"
+/>
+```
+
+[DragDrop]: /docs/dragdrop/

+ 25 - 0
website/src/docs/react-progressbar.md

@@ -0,0 +1,25 @@
+---
+title: "&lt;ProgressBar />"
+type: docs
+permalink: docs/react/progressbar/
+order: 63
+---
+
+The `<ProgressBar />` component wraps the [ProgressBar][] plugin.
+
+```js
+import ProgressBar from 'uppy/lib/react/ProgressBar';
+```
+
+## Props
+
+The `<ProgressBar />` component supports all [ProgressBar][] options as props.
+
+```js
+<ProgressBar
+  fixed
+  hideAfterFinish
+/>
+```
+
+[ProgressBar]: /docs/progressbar/

+ 26 - 0
website/src/docs/react-statusbar.md

@@ -0,0 +1,26 @@
+---
+title: "&lt;StatusBar />"
+type: docs
+permalink: docs/react/statusbar/
+order: 61
+---
+
+The `<StatusBar />` component wraps the [StatusBar][] plugin.
+
+```js
+import StatusBar from 'uppy/lib/react/StatusBar';
+```
+
+## Props
+
+The `<StatusBar />` component supports all [StatusBar][] options as props.
+
+```js
+<StatusBar
+  hideUploadButton
+  hideAfterFinish={false}
+  showProgressDetails
+/>
+```
+
+[StatusBar]: /docs/statusbar/

+ 11 - 7
website/src/docs/react.md

@@ -2,7 +2,7 @@
 title: "Introduction"
 type: docs
 permalink: docs/react/
-order: 50
+order: 60
 ---
 
 Uppy provides [React][] components for the included UI plugins.
@@ -54,16 +54,20 @@ const AvatarPicker = ({ currentAvatar }) => {
 
 The plugins that are available as React component wrappers are:
 
- - [Dashboard][]
- - [DashboardModal][]
- - [DragDrop][]
- - [ProgressBar][]
- - [StatusBar][]
+ - [&lt;Dashboard />][] - renders an inline [Dashboard][]
+ - [&lt;DashboardModal />][] - renders a [Dashboard][] modal
+ - [&lt;DragDrop />][] - renders a [DragDrop][] area
+ - [&lt;ProgressBar />][] - renders a [ProgressBar][]
+ - [&lt;StatusBar />][] - renders a [StatusBar][]
 
 [React]: https://facebook.github.io/react
 [Preact]: https://preactjs.com/
+[&lt;Dashboard />]: /docs/react/dashboard
+[&lt;DragDrop />]: /docs/react/dragdrop
+[&lt;ProgressBar />]: /docs/react/progressbar
+[&lt;StatusBar />]: /docs/react/statusbar
+[&lt;DashboardModal />]: /docs/react/dashboard-modal
 [Dashboard]: /docs/dashboard
 [DragDrop]: /docs/dragdrop
 [ProgressBar]: /docs/progressbar
 [StatusBar]: /docs/statusbar
-[DashboardModal]: /docs/react/dashboard-modal

+ 1 - 1
website/src/docs/redux.md

@@ -2,7 +2,7 @@
 title: "Redux"
 type: docs
 permalink: docs/redux
-order: 57
+order: 67
 ---
 
 Uppy supports popular [Redux](https://redux.js.org/) state management library in two ways:

+ 71 - 30
website/src/docs/statusbar.md

@@ -8,6 +8,14 @@ permalink: docs/statusbar/
 The StatusBar shows upload progress and speed, ETAs, pre- and post-processing information, and allows users to control (pause/resume/cancel) the upload.
 Best used together with a simple file source plugin, such as [FileInput][] or [DragDrop][], or a custom implementation.
 
+```js
+const StatusBar = require('uppy/lib/plugins/StatusBar')
+
+uppy.use(StatusBar, {
+  // Options
+})
+```
+
 [Try it live](/examples/statusbar/)
 
 ## Options
@@ -18,39 +26,14 @@ uppy.use(StatusBar, {
   hideUploadButton: false,
   showProgressDetails: false,
   hideAfterFinish: true
-  locale: {
-    strings: {
-      uploading: 'Uploading',
-      complete: 'Complete',
-      uploadFailed: 'Upload failed',
-      pleasePressRetry: 'Please press Retry to upload again',
-      paused: 'Paused',
-      error: 'Error',
-      retry: 'Retry',
-      pressToRetry: 'Press to retry',
-      retryUpload: 'Retry upload',
-      resumeUpload: 'Resume upload',
-      cancelUpload: 'Cancel upload',
-      pauseUpload: 'Pause upload',
-      filesUploadedOfTotal: {
-        0: '%{complete} of %{smart_count} file uploaded',
-        1: '%{complete} of %{smart_count} files uploaded'
-      },
-      dataUploadedOfTotal: '%{complete} of %{total}',
-      xTimeLeft: '%{time} left',
-      uploadXFiles: {
-        0: 'Upload %{smart_count} file',
-        1: 'Upload %{smart_count} files'
-      },
-      uploadXNewFiles: {
-        0: 'Upload +%{smart_count} file',
-        1: 'Upload +%{smart_count} files'
-      }
-    }
-  }
+  locale: {}
 })
 ```
 
+### `id: 'StatusBar'`
+
+A unique identifier for this StatusBar. Defaults to `'StatusBar'`. Use this if you need to add multiple StatusBar instances.
+
 ### `target: null`
 
 DOM element, CSS selector, or plugin to mount the StatusBar into.
@@ -66,5 +49,63 @@ By default, progress in StatusBar is shown as simple percentage. If you’d like
 `showProgressDetails: false`: Uploading: 45%
 `showProgressDetails: true`: Uploading: 45%・43 MB of 101 MB・8s left
 
+### `locale: {}`
+
+Localize text that is shown to the user.
+
+The default English strings are:
+
+```js
+strings: {
+  // Shown in the status bar while files are being uploaded.
+  uploading: 'Uploading',
+  // Shown in the status bar once all files have been uploaded.
+  complete: 'Complete',
+  // Shown in the status bar if an upload failed.
+  uploadFailed: 'Upload failed',
+  // Shown next to `uploadFailed`.
+  pleasePressRetry: 'Please press Retry to upload again',
+  // Shown in the status bar while the upload is paused.
+  paused: 'Paused',
+  error: 'Error',
+  // Used as the label for the button that retries an upload.
+  retry: 'Retry',
+  // Used as the label for the button that cancels an upload.
+  cancel: 'Cancel',
+  // Used as the screen reader label for the button that retries an upload.
+  retryUpload: 'Retry upload',
+  // Used as the screen reader label for the button that pauses an upload.
+  pauseUpload: 'Pause upload',
+  // Used as the screen reader label for the button that resumes a paused upload.
+  resumeUpload: 'Resume upload',
+  // Used as the screen reader label for the button that cancels an upload.
+  cancelUpload: 'Cancel upload',
+  // When `showProgressDetails` is set, shows the number of files that have been fully uploaded so far.
+  filesUploadedOfTotal: {
+    0: '%{complete} of %{smart_count} file uploaded',
+    1: '%{complete} of %{smart_count} files uploaded'
+  },
+  // When `showProgressDetails` is set, shows the amount of bytes that have been uploaded so far.
+  dataUploadedOfTotal: '%{complete} of %{total}',
+  // When `showProgressDetails` is set, shows an estimation of how long the upload will take to complete.
+  xTimeLeft: '%{time} left',
+  // Used as the label for the button that starts an upload.
+  uploadXFiles: {
+    0: 'Upload %{smart_count} file',
+    1: 'Upload %{smart_count} files'
+  },
+  // Used as the label for the button that starts an upload, if another upload has been started in the past
+  // and new files were added later.
+  uploadXNewFiles: {
+    0: 'Upload +%{smart_count} file',
+    1: 'Upload +%{smart_count} files'
+  }
+}
+```
+
+### `replaceTargetContent: false`
+
+Remove all children of the `target` element before mounting the StatusBar. By default, Uppy will append any UI to the `target` DOM element. This is the least dangerous option. However, you may have some fallback HTML inside the `target` element in case JavaScript or Uppy is not available. In that case you can set `replaceTargetContent: true` to clear the `target` before appending.
+
 [FileInput]: https://github.com/transloadit/uppy/blob/master/src/plugins/FileInput.js
 [DragDrop]: /docs/dragdrop

+ 24 - 0
website/src/docs/transloadit.md

@@ -10,6 +10,8 @@ The Transloadit plugin can be used to upload files to [Transloadit](https://tran
 [Try it live](/examples/transloadit/)
 
 ```js
+const Transloadit = require('uppy/lib/plugins/Transloadit')
+
 uppy.use(Transloadit, {
   service: 'https://api2.transloadit.com',
   params: null,
@@ -49,6 +51,10 @@ uppy.use(Dropbox, {
 
 ## Options
 
+### `id: 'Transloadit'`
+
+A unique identifier for this plugin. Defaults to `'Transloadit'`.
+
 ### `service`
 
 The Transloadit API URL to use. Defaults to `https://api2.transloadit.com`, which will attempt to route traffic efficiently based on where your users are. You can set this to something like `https://api2-us-east-1.transloadit.com` if you want to use a particular region.
@@ -205,6 +211,24 @@ uppy.use(Transloadit, {
 })
 ```
 
+### `locale: {}`
+
+Localize text that is shown to the user.
+
+The default English strings are:
+
+```js
+strings: {
+  // Shown while Assemblies are being created for an upload.
+  creatingAssembly: 'Preparing upload...'
+  // Shown if an Assembly could not be created.
+  creatingAssemblyFailed: 'Transloadit: Could not create Assembly',
+  // Shown after uploads have succeeded, but when the Assembly is still executing.
+  // This only shows if `waitForMetadata` or `waitForEncoding` was set.
+  encoding: 'Encoding...'
+}
+```
+
 ## Events
 
 ### `transloadit:assembly-created`

+ 6 - 0
website/src/docs/tus.md

@@ -8,6 +8,8 @@ permalink: docs/tus/
 The Tus plugin brings [tus.io](http://tus.io) resumable file uploading to Uppy by wrapping the [tus-js-client][].
 
 ```js
+const Tus = require('uppy/lib/plugins/Tus')
+
 uppy.use(Tus, {
   endpoint: 'https://master.tus.io/files/', // use your tus endpoint here
   resume: true,
@@ -20,6 +22,10 @@ uppy.use(Tus, {
 
 The Tus plugin supports all of [tus-js-client][]’s options. Additionally:
 
+### `id: 'Tus'`
+
+A unique identifier for this plugin. Defaults to `'Tus'`.
+
 ### `resume: true`
 
 A boolean indicating whether tus should attempt to resume the upload if the upload has been started in the past. This includes storing the file’s upload url. Use false to force an entire reupload.

+ 6 - 0
website/src/docs/uppy.md

@@ -7,6 +7,12 @@ permalink: docs/uppy/
 
 Core module that orchestrates everything in Uppy, exposing `state`, `events` and `methods`.
 
+```js
+const Uppy = require('uppy/lib/core')
+
+const uppy = Uppy()
+```
+
 ## Options
 
 ```js

+ 62 - 0
website/src/docs/url.md

@@ -0,0 +1,62 @@
+---
+type: docs
+order: 54
+title: "Url"
+permalink: docs/url/
+---
+
+The Url plugin lets users import files from the Internet. Paste any URL and it'll be added!
+
+An Uppy Server instance is required for the Url plugin to work. Uppy Server will download the files and upload them to their destination. This saves bandwidth for the user (especially on mobile connections) and helps avoid CORS restrictions.
+
+```js
+const Url = require('uppy/lib/plugins/Url')
+
+uppy.use(Url, {
+  // Options
+})
+```
+
+[Try live!](/examples/dashboard/)
+
+## Options
+
+```js
+uppy.use(Url, {
+  target: Dashboard,
+  host: 'https://server.uppy.io/',
+  locale: {}
+})
+```
+
+### `id: 'Url'`
+
+A unique identifier for this plugin. Defaults to `'Url'`.
+
+### `target: null`
+
+DOM element, CSS selector, or plugin to mount the Url provider into. This should normally be the Dashboard.
+
+### `host: null`
+
+URL to an Uppy Server instance.
+
+### `locale: {}`
+
+Localize text that is shown to the user.
+
+The default English strings are:
+
+```js
+strings: {
+  // Label for the "Import" button.
+  import: 'Import',
+  // Placeholder text for the URL input.
+  enterUrlToImport: 'Enter URL to import a file',
+  // Error message shown if Uppy Server could not load a URL.
+  failedToFetch: 'Uppy Server failed to fetch this URL, please make sure it’s correct',
+  // Error message shown if the input does not look like a URL.
+  enterCorrectUrl: 'Incorrect URL: Please make sure you are entering a direct link to a file'
+}
+```
+

+ 32 - 6
website/src/docs/webcam.md

@@ -9,6 +9,14 @@ The Webcam plugin lets you take photos and record videos with a built-in camera
 
 > To use the Webcam plugin in Chrome, [your site should be served over https](https://developers.google.com/web/updates/2015/10/chrome-47-webrtc#public_service_announcements). This restriction does not apply on `localhost`, so you don't have to jump through many hoops during development.
 
+```js
+const Webcam = require('uppy/lib/plugins/Webcam')
+
+uppy.use(Webcam, {
+  // Options
+})
+```
+
 [Try live!](/examples/dashboard/)
 
 ## Options
@@ -25,14 +33,14 @@ uppy.use(Webcam, {
   ],
   mirror: true,
   facingMode: 'user',
-  locale: {
-    strings: {
-      smile: 'Smile!'
-    }
-  }
+  locale: {}
 })
 ```
 
+### `id: 'Webcam'`
+
+A unique identifier for this plugin. Defaults to `'Webcam'`.
+
 ### `target: null`
 
 DOM element, CSS selector, or plugin to mount Webcam into.
@@ -72,4 +80,22 @@ Devices sometimes have multiple cameras, front and back, for example. There’s
 
 ### `locale: {}`
 
-There is only one localizable string: `strings.smile`. It's shown before a picture is taken, when the `countdown` option is set to true.
+Localize text that is shown to the user.
+
+The default English strings are:
+
+```js
+strings: {
+  // Shown before a picture is taken when the `countdown` option is set.
+  smile: 'Smile!',
+  // Used as the label for the button that takes a picture.
+  // This is not visibly rendered but is picked up by screen readers.
+  takePicture: 'Take a picture',
+  // Used as the label for the button that starts a video recording.
+  // This is not visibly rendered but is picked up by screen readers.
+  startRecording: 'Begin video recording',
+  // Used as the label for the button that stops a video recording.
+  // This is not visibly rendered but is picked up by screen readers.
+  stopRecording: 'Stop video recording',
+}
+```

+ 1 - 1
website/src/docs/writing-plugins.md

@@ -2,7 +2,7 @@
 type: docs
 title: "Writing Plugins"
 permalink: docs/writing-plugins/
-order: 20
+order: 11
 ---
 
 There are a few useful Uppy plugins out there, but there might come a time when you’ll want to build your own.

+ 21 - 2
website/src/docs/xhrupload.md

@@ -7,16 +7,22 @@ permalink: docs/xhrupload/
 
 The XHRUpload plugin handles classic HTML multipart form uploads, as well as uploads using the HTTP `PUT` method.
 
-[Try it live](/examples/xhrupload/)
-
 ```js
+const XHRUpload = require('uppy/lib/plugins/XHRUpload')
+
 uppy.use(XHRUpload, {
   endpoint: 'http://my-website.org/upload'
 })
 ```
 
+[Try it live](/examples/xhrupload/)
+
 ## Options
 
+### `id: 'XHRUpload'`
+
+A unique identifier for this plugin. Defaults to `'XHRUpload'`.
+
 ### `endpoint: ''`
 
 URL to upload to.
@@ -147,6 +153,19 @@ The default is 30 seconds.
 
 Limit the amount of uploads going on at the same time. Passing `0` means no limit.
 
+### `locale: {}`
+
+Localize text that is shown to the user.
+
+The default English strings are:
+
+```js
+strings: {
+  // Shown in the Informer if an upload is being canceled because it stalled for too long.
+  timedOut: 'Upload stalled for %{seconds} seconds, aborting.'
+}
+```
+
 ## POST Parameters / Form Fields
 
 When using XHRUpload with `formData: true`, file metadata is sent along with each upload request. You can set metadata for a file using [`uppy.setFileMeta(fileID, data)`](/docs/uppy#uppy-setFileMeta-fileID-data), or for all files simultaneously using [`uppy.setMeta(data)`](/docs/uppy#uppy-setMeta-data).

+ 7 - 0
website/themes/uppy/layout/partials/sidebar.ejs

@@ -19,6 +19,13 @@
           <li>
             <a href="/<%- path %>" class="sidebar-link<%- page.title === p.title ? ' current' : '' %><%- p.is_new ? ' new' : '' %>"><%- p.title %></a>
           </li>
+        <% } else if (path === 'docs/providers/') { %>
+          <li>
+            <h3><a href="/docs/providers/">Remote Providers</a></h3>
+          </li>
+          <li>
+            <a href="/<%- path %>" class="sidebar-link<%- page.title === p.title ? ' current' : '' %><%- p.is_new ? ' new' : '' %>"><%- p.title %></a>
+          </li>
         <% } else if (path === 'docs/react/') { %>
           <li>
             <h3><a href="/docs/react/">React Components</a></h3>