index.js 3.2 KB

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