react-dropzone 4.2.10 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,18 @@
1
+ You can programmatically invoke default OS file prompt. In order to do that you'll have to set the ref on your `Dropzone` instance and call the instance `open` method.
2
+
3
+ **Please note**, that for security reasons most browsers require popups and dialogues to originate from a direct user interaction (i.e. click). If you are calling `dropzoneRef.open()` asynchronously, there’s a good chance it’s going to be blocked by the browser. So if you are calling `dropzoneRef.open()` asynchronously, be sure there is no more than *1000ms* delay between user interaction and `dropzoneRef.open()` call. Due to the lack of official docs on this (at least we haven’t found any. If you know one, feel free to open PR), there is no guarantee that **allowed delay duration** will not be changed in later browser versions. Since implementations may differ between different browsers, avoid calling open asynchronously if possible.
4
+
5
+ ```
6
+ let dropzoneRef;
7
+
8
+ <div>
9
+ <Dropzone ref={(node) => { dropzoneRef = node; }} onDrop={(accepted, rejected) => { alert(accepted) }}>
10
+ <p>Drop files here.</p>
11
+ </Dropzone>
12
+ <button type="button" onClick={() => { dropzoneRef.open() }}>
13
+ Open File Dialog
14
+ </button>
15
+ </div>
16
+ ```
17
+
18
+ The completion handler for the `open` function is also the `onDrop` function.
package/package.json CHANGED
@@ -26,11 +26,11 @@
26
26
  "size-limit": [
27
27
  {
28
28
  "path": "dist/index.js",
29
- "limit": "5.5 KB"
29
+ "limit": "6 KB"
30
30
  },
31
31
  {
32
32
  "path": "dist/es/index.js",
33
- "limit": "3 KB"
33
+ "limit": "4 KB"
34
34
  }
35
35
  ],
36
36
  "lint-staged": {
@@ -74,7 +74,7 @@
74
74
  "react": ">=0.14.0"
75
75
  },
76
76
  "dependencies": {
77
- "attr-accept": "^1.0.3",
77
+ "attr-accept": "^1.1.3",
78
78
  "prop-types": "^15.5.7"
79
79
  },
80
80
  "devDependencies": {
@@ -123,5 +123,5 @@
123
123
  "path": "@commitlint/prompt"
124
124
  }
125
125
  },
126
- "version": "4.2.10"
126
+ "version": "4.3.0"
127
127
  }
@@ -1,7 +1,7 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`Dropzone basics should render children 1`] = `"<div class=\\"\\" aria-disabled=\\"false\\" style=\\"width: 200px; height: 200px; border-width: 2px; border-color: #666; border-style: dashed; border-radius: 5px;\\"><p>some content</p><input type=\\"file\\" multiple=\\"\\" autocomplete=\\"off\\" style=\\"display: none;\\"></div>"`;
4
-
5
- exports[`Dropzone document drop protection does not prevent stray drops when preventDropOnDocument is false 1`] = `"<div class=\\"\\" aria-disabled=\\"false\\" style=\\"width: 200px; height: 200px; border-width: 2px; border-color: #666; border-style: dashed; border-radius: 5px;\\"><input type=\\"file\\" multiple=\\"\\" autocomplete=\\"off\\" style=\\"display: none;\\"></div>"`;
6
-
7
- exports[`Dropzone document drop protection installs hooks to prevent stray drops from taking over the browser window 1`] = `"<div class=\\"\\" aria-disabled=\\"false\\" style=\\"width: 200px; height: 200px; border-width: 2px; border-color: #666; border-style: dashed; border-radius: 5px;\\"><p>Content</p><input type=\\"file\\" multiple=\\"\\" autocomplete=\\"off\\" style=\\"display: none;\\"></div>"`;
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Dropzone basics should render children 1`] = `"<div class=\\"\\" aria-disabled=\\"false\\" style=\\"position: relative; width: 200px; height: 200px; border-width: 2px; border-color: #666; border-style: dashed; border-radius: 5px;\\"><p>some content</p><input type=\\"file\\" multiple=\\"\\" autocomplete=\\"off\\" style=\\"position: absolute; top: 0px; right: 0px; bottom: 0px; left: 0px; opacity: 0.00001; pointer-events: none;\\"></div>"`;
4
+
5
+ exports[`Dropzone document drop protection does not prevent stray drops when preventDropOnDocument is false 1`] = `"<div class=\\"\\" aria-disabled=\\"false\\" style=\\"position: relative; width: 200px; height: 200px; border-width: 2px; border-color: #666; border-style: dashed; border-radius: 5px;\\"><input type=\\"file\\" multiple=\\"\\" autocomplete=\\"off\\" style=\\"position: absolute; top: 0px; right: 0px; bottom: 0px; left: 0px; opacity: 0.00001; pointer-events: none;\\"></div>"`;
6
+
7
+ exports[`Dropzone document drop protection installs hooks to prevent stray drops from taking over the browser window 1`] = `"<div class=\\"\\" aria-disabled=\\"false\\" style=\\"position: relative; width: 200px; height: 200px; border-width: 2px; border-color: #666; border-style: dashed; border-radius: 5px;\\"><p>Content</p><input type=\\"file\\" multiple=\\"\\" autocomplete=\\"off\\" style=\\"position: absolute; top: 0px; right: 0px; bottom: 0px; left: 0px; opacity: 0.00001; pointer-events: none;\\"></div>"`;
package/src/index.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  allFilesAccepted,
9
9
  fileMatchSize,
10
10
  onDocumentDragOver,
11
- getDataTransferItems,
11
+ getDataTransferItems as defaultGetDataTransferItem,
12
12
  isIeOrEdge
13
13
  } from './utils'
14
14
  import styles from './utils/styles'
@@ -94,11 +94,12 @@ class Dropzone extends React.Component {
94
94
  this.dragTargets.push(evt.target)
95
95
  }
96
96
 
97
- this.setState({
98
- isDragActive: true, // Do not rely on files for the drag state. It doesn't work in Safari.
99
- draggedFiles: getDataTransferItems(evt)
97
+ Promise.resolve(this.props.getDataTransferItems(evt)).then(draggedFiles => {
98
+ this.setState({
99
+ isDragActive: true, // Do not rely on files for the drag state. It doesn't work in Safari.
100
+ draggedFiles
101
+ })
100
102
  })
101
-
102
103
  if (this.props.onDragEnter) {
103
104
  this.props.onDragEnter.call(this, evt)
104
105
  }
@@ -144,10 +145,15 @@ class Dropzone extends React.Component {
144
145
  }
145
146
 
146
147
  onDrop(evt) {
147
- const { onDrop, onDropAccepted, onDropRejected, multiple, disablePreview, accept } = this.props
148
- const fileList = getDataTransferItems(evt)
149
- const acceptedFiles = []
150
- const rejectedFiles = []
148
+ const {
149
+ onDrop,
150
+ onDropAccepted,
151
+ onDropRejected,
152
+ multiple,
153
+ disablePreview,
154
+ accept,
155
+ getDataTransferItems
156
+ } = this.props
151
157
 
152
158
  // Stop default browser behavior
153
159
  evt.preventDefault()
@@ -156,54 +162,57 @@ class Dropzone extends React.Component {
156
162
  this.dragTargets = []
157
163
  this.isFileDialogActive = false
158
164
 
159
- fileList.forEach(file => {
160
- if (!disablePreview) {
161
- try {
162
- file.preview = window.URL.createObjectURL(file) // eslint-disable-line no-param-reassign
163
- } catch (err) {
164
- if (process.env.NODE_ENV !== 'production') {
165
- console.error('Failed to generate preview for file', file, err) // eslint-disable-line no-console
166
- }
167
- }
168
- }
165
+ // Clear files value
166
+ this.draggedFiles = null
169
167
 
170
- if (
171
- fileAccepted(file, accept) &&
172
- fileMatchSize(file, this.props.maxSize, this.props.minSize)
173
- ) {
174
- acceptedFiles.push(file)
175
- } else {
176
- rejectedFiles.push(file)
177
- }
168
+ // Reset drag state
169
+ this.setState({
170
+ isDragActive: false,
171
+ draggedFiles: []
178
172
  })
179
173
 
180
- if (!multiple) {
181
- // if not in multi mode add any extra accepted files to rejected.
182
- // This will allow end users to easily ignore a multi file drop in "single" mode.
183
- rejectedFiles.push(...acceptedFiles.splice(1))
184
- }
174
+ Promise.resolve(getDataTransferItems(evt)).then(fileList => {
175
+ const acceptedFiles = []
176
+ const rejectedFiles = []
177
+
178
+ fileList.forEach(file => {
179
+ if (!disablePreview) {
180
+ try {
181
+ file.preview = window.URL.createObjectURL(file) // eslint-disable-line no-param-reassign
182
+ } catch (err) {
183
+ if (process.env.NODE_ENV !== 'production') {
184
+ console.error('Failed to generate preview for file', file, err) // eslint-disable-line no-console
185
+ }
186
+ }
187
+ }
185
188
 
186
- if (onDrop) {
187
- onDrop.call(this, acceptedFiles, rejectedFiles, evt)
188
- }
189
+ if (
190
+ fileAccepted(file, accept) &&
191
+ fileMatchSize(file, this.props.maxSize, this.props.minSize)
192
+ ) {
193
+ acceptedFiles.push(file)
194
+ } else {
195
+ rejectedFiles.push(file)
196
+ }
197
+ })
189
198
 
190
- if (rejectedFiles.length > 0 && onDropRejected) {
191
- onDropRejected.call(this, rejectedFiles, evt)
192
- }
199
+ if (!multiple) {
200
+ // if not in multi mode add any extra accepted files to rejected.
201
+ // This will allow end users to easily ignore a multi file drop in "single" mode.
202
+ rejectedFiles.push(...acceptedFiles.splice(1))
203
+ }
193
204
 
194
- if (acceptedFiles.length > 0 && onDropAccepted) {
195
- onDropAccepted.call(this, acceptedFiles, evt)
196
- }
205
+ if (onDrop) {
206
+ onDrop.call(this, acceptedFiles, rejectedFiles, evt)
207
+ }
197
208
 
198
- // Clear files value
199
- this.draggedFiles = null
209
+ if (rejectedFiles.length > 0 && onDropRejected) {
210
+ onDropRejected.call(this, rejectedFiles, evt)
211
+ }
200
212
 
201
- // Reset drag state
202
- this.setState({
203
- isDragActive: false,
204
- draggedFiles: [],
205
- acceptedFiles,
206
- rejectedFiles
213
+ if (acceptedFiles.length > 0 && onDropAccepted) {
214
+ onDropAccepted.call(this, acceptedFiles, evt)
215
+ }
207
216
  })
208
217
  }
209
218
 
@@ -335,15 +344,15 @@ class Dropzone extends React.Component {
335
344
  if (noStyles) {
336
345
  style = styles.default
337
346
  activeStyle = styles.active
338
- acceptStyle = style.active
347
+ acceptStyle = styles.active
339
348
  rejectStyle = styles.rejected
340
349
  disabledStyle = styles.disabled
341
350
  }
342
351
 
343
- let appliedStyle = { ...style }
352
+ let appliedStyle = { position: 'relative', ...style }
344
353
  if (activeStyle && isDragActive) {
345
354
  appliedStyle = {
346
- ...style,
355
+ ...appliedStyle,
347
356
  ...activeStyle
348
357
  }
349
358
  }
@@ -361,7 +370,7 @@ class Dropzone extends React.Component {
361
370
  }
362
371
  if (disabledStyle && disabled) {
363
372
  appliedStyle = {
364
- ...style,
373
+ ...appliedStyle,
365
374
  ...disabledStyle
366
375
  }
367
376
  }
@@ -370,7 +379,16 @@ class Dropzone extends React.Component {
370
379
  accept,
371
380
  disabled,
372
381
  type: 'file',
373
- style: { display: 'none' },
382
+ style: {
383
+ position: 'absolute',
384
+ top: 0,
385
+ right: 0,
386
+ bottom: 0,
387
+ left: 0,
388
+ opacity: 0.00001,
389
+ pointerEvents: 'none',
390
+ ...inputProps.style
391
+ },
374
392
  multiple: supportMultiple && multiple,
375
393
  ref: this.setRefs,
376
394
  onChange: this.onDrop,
@@ -392,6 +410,7 @@ class Dropzone extends React.Component {
392
410
  onFileDialogCancel,
393
411
  maxSize,
394
412
  minSize,
413
+ getDataTransferItems,
395
414
  ...divProps
396
415
  } = props
397
416
 
@@ -429,7 +448,7 @@ Dropzone.propTypes = {
429
448
  * Windows. In some cases there might not be a mime type set at all.
430
449
  * See: https://github.com/react-dropzone/react-dropzone/issues/276
431
450
  */
432
- accept: PropTypes.string,
451
+ accept: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
433
452
 
434
453
  /**
435
454
  * Contents of the dropzone
@@ -531,6 +550,13 @@ Dropzone.propTypes = {
531
550
  */
532
551
  disabledStyle: PropTypes.object,
533
552
 
553
+ /**
554
+ * getDataTransferItems handler
555
+ * @param {Event} event
556
+ * @returns {Array} array of File objects
557
+ */
558
+ getDataTransferItems: PropTypes.func,
559
+
534
560
  /**
535
561
  * onClick callback
536
562
  * @param {Event} event
@@ -583,7 +609,9 @@ Dropzone.defaultProps = {
583
609
  disabled: false,
584
610
  disablePreview: false,
585
611
  disableClick: false,
612
+ inputProps: {},
586
613
  multiple: true,
587
614
  maxSize: Infinity,
588
- minSize: 0
615
+ minSize: 0,
616
+ getDataTransferItems: defaultGetDataTransferItem
589
617
  }