FileInput.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. const Plugin = require('../core/Plugin')
  2. const { toArray } = require('../core/Utils')
  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. this.uppy.addFile({
  39. source: this.id,
  40. name: file.name,
  41. type: file.type,
  42. data: file
  43. })
  44. })
  45. }
  46. handleClick (ev) {
  47. this.input.click()
  48. }
  49. render (state) {
  50. /* http://tympanus.net/codrops/2015/09/15/styling-customizing-file-inputs-smart-way/ */
  51. const hiddenInputStyle = {
  52. width: '0.1px',
  53. height: '0.1px',
  54. opacity: 0,
  55. overflow: 'hidden',
  56. position: 'absolute',
  57. zIndex: -1
  58. }
  59. const restrictions = this.uppy.opts.restrictions
  60. // empty value="" on file input, so that the input is cleared after a file is selected,
  61. // because Uppy will be handling the upload and so we can select same file
  62. // after removing — otherwise browser thinks it’s already selected
  63. return <div class="uppy-Root uppy-FileInput-container">
  64. <input class="uppy-FileInput-input"
  65. style={this.opts.pretty && hiddenInputStyle}
  66. type="file"
  67. name={this.opts.inputName}
  68. onchange={this.handleInputChange}
  69. multiple={restrictions.maxNumberOfFiles !== 1}
  70. accept={restrictions.allowedFileTypes}
  71. ref={(input) => { this.input = input }}
  72. value="" />
  73. {this.opts.pretty &&
  74. <button class="uppy-FileInput-btn" type="button" onclick={this.handleClick}>
  75. {this.i18n('chooseFiles')}
  76. </button>
  77. }
  78. </div>
  79. }
  80. install () {
  81. const target = this.opts.target
  82. if (target) {
  83. this.mount(target, this)
  84. }
  85. }
  86. uninstall () {
  87. this.unmount()
  88. }
  89. }