FileInput.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. const Plugin = require('../core/Plugin')
  2. const toArray = require('../utils/toArray')
  3. const Translator = require('../core/Translator')
  4. const { h } = require('preact')
  5. module.exports = class FileInput extends Plugin {
  6. constructor (uppy, opts) {
  7. super(uppy, opts)
  8. this.id = this.opts.id || 'FileInput'
  9. this.title = 'File Input'
  10. this.type = 'acquirer'
  11. const defaultLocale = {
  12. strings: {
  13. chooseFiles: 'Choose files'
  14. }
  15. }
  16. // Default options
  17. const defaultOptions = {
  18. target: null,
  19. pretty: true,
  20. inputName: 'files[]',
  21. locale: defaultLocale
  22. }
  23. // Merge default options with the ones set by user
  24. this.opts = Object.assign({}, defaultOptions, opts)
  25. this.locale = Object.assign({}, defaultLocale, this.opts.locale)
  26. this.locale.strings = Object.assign({}, defaultLocale.strings, this.opts.locale.strings)
  27. // i18n
  28. this.translator = new Translator({locale: this.locale})
  29. this.i18n = this.translator.translate.bind(this.translator)
  30. this.render = this.render.bind(this)
  31. this.handleInputChange = this.handleInputChange.bind(this)
  32. this.handleClick = this.handleClick.bind(this)
  33. }
  34. handleInputChange (ev) {
  35. this.uppy.log('[FileInput] Something selected through input...')
  36. const files = toArray(ev.target.files)
  37. files.forEach((file) => {
  38. try {
  39. this.uppy.addFile({
  40. source: this.id,
  41. name: file.name,
  42. type: file.type,
  43. data: file
  44. })
  45. } catch (err) {
  46. // Nothing, restriction errors handled in Core
  47. }
  48. })
  49. }
  50. handleClick (ev) {
  51. this.input.click()
  52. }
  53. render (state) {
  54. /* http://tympanus.net/codrops/2015/09/15/styling-customizing-file-inputs-smart-way/ */
  55. const hiddenInputStyle = {
  56. width: '0.1px',
  57. height: '0.1px',
  58. opacity: 0,
  59. overflow: 'hidden',
  60. position: 'absolute',
  61. zIndex: -1
  62. }
  63. const restrictions = this.uppy.opts.restrictions
  64. // empty value="" on file input, so that the input is cleared after a file is selected,
  65. // because Uppy will be handling the upload and so we can select same file
  66. // after removing — otherwise browser thinks it’s already selected
  67. return <div class="uppy-Root uppy-FileInput-container">
  68. <input class="uppy-FileInput-input"
  69. style={this.opts.pretty && hiddenInputStyle}
  70. type="file"
  71. name={this.opts.inputName}
  72. onchange={this.handleInputChange}
  73. multiple={restrictions.maxNumberOfFiles !== 1}
  74. accept={restrictions.allowedFileTypes}
  75. ref={(input) => { this.input = input }}
  76. value="" />
  77. {this.opts.pretty &&
  78. <button class="uppy-FileInput-btn" type="button" onclick={this.handleClick}>
  79. {this.i18n('chooseFiles')}
  80. </button>
  81. }
  82. </div>
  83. }
  84. install () {
  85. const target = this.opts.target
  86. if (target) {
  87. this.mount(target, this)
  88. }
  89. }
  90. uninstall () {
  91. this.unmount()
  92. }
  93. }