react-dropzone
Advanced tools
Comparing version 3.13.1 to 3.13.2
@@ -97,2 +97,8 @@ (function webpackUniversalModuleDefinition(root, factory) { | ||
function fileAccepted(file, accept) { | ||
// Firefox versions prior to 53 return a bogus MIME type for every file drag, so dragovers with | ||
// that MIME type will always be accepted | ||
return file.type === 'application/x-moz-file' || (0, _attrAccept2.default)(file, accept); | ||
} | ||
var Dropzone = function (_React$Component) { | ||
@@ -114,5 +120,5 @@ _inherits(Dropzone, _React$Component); | ||
_this.renderChildren = function (children) { | ||
_this.renderChildren = function (children, isDragActive, isDragReject) { | ||
if (typeof children === 'function') { | ||
return children(_this.state); | ||
return children(_extends({}, _this.state, { isDragActive: isDragActive, isDragReject: isDragReject })); | ||
} | ||
@@ -130,7 +136,6 @@ return children; | ||
_this.onFileDialogCancel = _this.onFileDialogCancel.bind(_this); | ||
_this.fileAccepted = _this.fileAccepted.bind(_this); | ||
_this.setRef = _this.setRef.bind(_this); | ||
_this.isFileDialogActive = false; | ||
_this.state = { | ||
isDragActive: false, | ||
draggedFiles: [], | ||
acceptedFiles: [], | ||
@@ -195,11 +200,4 @@ rejectedFiles: [] | ||
var files = (0, _getDataTransferItems2.default)(e); | ||
var allFilesAccepted = this.allFilesAccepted(files); | ||
var isMultipleAllowed = this.props.multiple || files.length <= 1; | ||
this.setState({ draggedFiles: (0, _getDataTransferItems2.default)(e) }); | ||
this.setState({ | ||
isDragActive: allFilesAccepted, | ||
isDragReject: !allFilesAccepted || !isMultipleAllowed | ||
}); | ||
if (this.props.onDragEnter) { | ||
@@ -241,6 +239,4 @@ this.props.onDragEnter.call(this, e); | ||
this.setState({ | ||
isDragActive: false, | ||
isDragReject: false | ||
}); | ||
// Clear dragging files state | ||
this.setState({ draggedFiles: [] }); | ||
@@ -261,3 +257,4 @@ if (this.props.onDragLeave) { | ||
multiple = _props.multiple, | ||
disablePreview = _props.disablePreview; | ||
disablePreview = _props.disablePreview, | ||
accept = _props.accept; | ||
@@ -286,3 +283,3 @@ var fileList = (0, _getDataTransferItems2.default)(e); | ||
if (_this3.fileAccepted(file) && _this3.fileMatchSize(file)) { | ||
if (fileAccepted(file, accept) && _this3.fileMatchSize(file)) { | ||
acceptedFiles.push(file); | ||
@@ -312,6 +309,8 @@ } else { | ||
// Clear files value | ||
this.draggedFiles = null; | ||
// Reset drag state | ||
this.setState({ | ||
isDragActive: false, | ||
isDragReject: false, | ||
draggedFiles: [], | ||
acceptedFiles: acceptedFiles, | ||
@@ -363,9 +362,2 @@ rejectedFiles: rejectedFiles | ||
}, { | ||
key: 'fileAccepted', | ||
value: function fileAccepted(file) { | ||
// Firefox versions prior to 53 return a bogus MIME type for every file drag, so dragovers with | ||
// that MIME type will always be accepted | ||
return file.type === 'application/x-moz-file' || (0, _attrAccept2.default)(file, this.props.accept); | ||
} | ||
}, { | ||
key: 'fileMatchSize', | ||
@@ -378,3 +370,7 @@ value: function fileMatchSize(file) { | ||
value: function allFilesAccepted(files) { | ||
return files.every(this.fileAccepted); | ||
var _this4 = this; | ||
return files.every(function (file) { | ||
return fileAccepted(file, _this4.props.accept); | ||
}); | ||
} | ||
@@ -398,3 +394,3 @@ | ||
value: function render() { | ||
var _this4 = this; | ||
var _this5 = this; | ||
@@ -417,6 +413,8 @@ var _props3 = this.props, | ||
var _state = this.state, | ||
isDragActive = _state.isDragActive, | ||
isDragReject = _state.isDragReject; | ||
var draggedFiles = this.state.draggedFiles; | ||
var filesCount = draggedFiles.length; | ||
var isMultipleAllowed = multiple || filesCount <= 1; | ||
var isDragActive = filesCount > 0 && this.allFilesAccepted(draggedFiles); | ||
var isDragReject = filesCount > 0 && (!isDragActive || !isMultipleAllowed); | ||
@@ -468,3 +466,3 @@ className = className || ''; | ||
ref: function ref(el) { | ||
return _this4.fileInputEl = el; | ||
return _this5.fileInputEl = el; | ||
}, // eslint-disable-line | ||
@@ -499,3 +497,3 @@ onChange: this.onDrop | ||
}), | ||
this.renderChildren(children), | ||
this.renderChildren(children, isDragActive, isDragReject), | ||
_react2.default.createElement('input', _extends({}, inputProps /* expand user provided inputProps first so inputAttributes override them */, inputAttributes)) | ||
@@ -502,0 +500,0 @@ ); |
@@ -1,2 +0,2 @@ | ||
By providing `accept` prop you can make Dropzone to accept specifi file types and reject the others. | ||
By providing `accept` prop you can make Dropzone to accept specific file types and reject the others. | ||
@@ -56,4 +56,45 @@ The value must be a comma-separated list of unique content type specifiers: | ||
### Warning | ||
Keep in mind that mime type determination is not reliable accross platforms. CSV files, for example, are reported as text/plain under macOS but as application/vnd.ms-excel under Windows. In some cases there might not be a mime type set at all. | ||
### Browser limitations | ||
Because of HTML5 File API differences across different browsers during the drag, Dropzone will only display `rejected` styles in Chrome (and Chromium based browser). It isn't working in Safari nor IE. | ||
Also, at this moment it's not possible to read file names (and thus, file extensions) during the drag operation. For that reason, if you want to react on different file types _during_ the drag operation, _you have to use_ mime types and not extensions! For example, the following example won't work even in Chrome: | ||
``` | ||
<Dropzone | ||
accept=".jpeg,.png" | ||
> | ||
{({ isDragActive, isDragReject }) => { | ||
if (isDragActive) { | ||
return "All files will be accepted"; | ||
} | ||
if (isDragReject) { | ||
return "Some files will be rejected"; | ||
} | ||
return "Dropping some files here..."; | ||
}} | ||
</Dropzone> | ||
``` | ||
but this one will: | ||
``` | ||
<Dropzone | ||
accept="image/jpeg, image/png" | ||
> | ||
{({ isDragActive, isDragReject }) => { | ||
if (isDragActive) { | ||
return "All files will be accepted"; | ||
} | ||
if (isDragReject) { | ||
return "Some files will be rejected"; | ||
} | ||
return "Dropping some files here..."; | ||
}} | ||
</Dropzone> | ||
``` | ||
### Notes | ||
Mime type determination is not reliable accross platforms. CSV files, for example, are reported as text/plain under macOS but as application/vnd.ms-excel under Windows. In some cases there might not be a mime type set at all. | ||
@@ -78,3 +78,3 @@ { | ||
"babel-register": "^6.9.0", | ||
"css-loader": "^0.26.1", | ||
"css-loader": "^0.28.1", | ||
"cz-conventional-changelog": "^1.2.0", | ||
@@ -89,3 +89,4 @@ "enzyme": "^2.6.0", | ||
"imagemin-pngquant": "^5.0.0", | ||
"jest": "^18.0.0", | ||
"jest": "^20.0.1", | ||
"jest-enzyme": "^3.2.0", | ||
"lint-staged": "^3.2.1", | ||
@@ -110,3 +111,3 @@ "markdownlint-cli": "^0.2.0", | ||
}, | ||
"version": "3.13.1" | ||
"version": "3.13.2" | ||
} |
@@ -12,2 +12,8 @@ /* eslint prefer-template: 0 */ | ||
function fileAccepted(file, accept) { | ||
// Firefox versions prior to 53 return a bogus MIME type for every file drag, so dragovers with | ||
// that MIME type will always be accepted | ||
return file.type === 'application/x-moz-file' || accepts(file, accept); | ||
} | ||
class Dropzone extends React.Component { | ||
@@ -29,7 +35,6 @@ static onDocumentDragOver(e) { | ||
this.onFileDialogCancel = this.onFileDialogCancel.bind(this); | ||
this.fileAccepted = this.fileAccepted.bind(this); | ||
this.setRef = this.setRef.bind(this); | ||
this.isFileDialogActive = false; | ||
this.state = { | ||
isDragActive: false, | ||
draggedFiles: [], | ||
acceptedFiles: [], | ||
@@ -85,11 +90,4 @@ rejectedFiles: [] | ||
const files = getDataTransferItems(e); | ||
const allFilesAccepted = this.allFilesAccepted(files); | ||
const isMultipleAllowed = this.props.multiple || files.length <= 1; | ||
this.setState({ draggedFiles: getDataTransferItems(e) }); | ||
this.setState({ | ||
isDragActive: allFilesAccepted, | ||
isDragReject: !allFilesAccepted || !isMultipleAllowed | ||
}); | ||
if (this.props.onDragEnter) { | ||
@@ -124,6 +122,4 @@ this.props.onDragEnter.call(this, e); | ||
this.setState({ | ||
isDragActive: false, | ||
isDragReject: false | ||
}); | ||
// Clear dragging files state | ||
this.setState({ draggedFiles: [] }); | ||
@@ -136,3 +132,3 @@ if (this.props.onDragLeave) { | ||
onDrop(e) { | ||
const { onDrop, onDropAccepted, onDropRejected, multiple, disablePreview } = this.props; | ||
const { onDrop, onDropAccepted, onDropRejected, multiple, disablePreview, accept } = this.props; | ||
const fileList = getDataTransferItems(e); | ||
@@ -160,3 +156,3 @@ const acceptedFiles = []; | ||
if (this.fileAccepted(file) && this.fileMatchSize(file)) { | ||
if (fileAccepted(file, accept) && this.fileMatchSize(file)) { | ||
acceptedFiles.push(file); | ||
@@ -186,6 +182,8 @@ } else { | ||
// Clear files value | ||
this.draggedFiles = null; | ||
// Reset drag state | ||
this.setState({ | ||
isDragActive: false, | ||
isDragReject: false, | ||
draggedFiles: [], | ||
acceptedFiles, | ||
@@ -230,8 +228,2 @@ rejectedFiles | ||
fileAccepted(file) { | ||
// Firefox versions prior to 53 return a bogus MIME type for every file drag, so dragovers with | ||
// that MIME type will always be accepted | ||
return file.type === 'application/x-moz-file' || accepts(file, this.props.accept); | ||
} | ||
fileMatchSize(file) { | ||
@@ -242,3 +234,3 @@ return file.size <= this.props.maxSize && file.size >= this.props.minSize; | ||
allFilesAccepted(files) { | ||
return files.every(this.fileAccepted); | ||
return files.every(file => fileAccepted(file, this.props.accept)); | ||
} | ||
@@ -257,5 +249,5 @@ | ||
renderChildren = (children) => { | ||
renderChildren = (children, isDragActive, isDragReject) => { | ||
if (typeof children === 'function') { | ||
return children(this.state); | ||
return children({ ...this.state, isDragActive, isDragReject }); | ||
} | ||
@@ -285,3 +277,7 @@ return children; | ||
const { isDragActive, isDragReject } = this.state; | ||
const { draggedFiles } = this.state; | ||
const filesCount = draggedFiles.length; | ||
const isMultipleAllowed = multiple || filesCount <= 1; | ||
const isDragActive = filesCount > 0 && this.allFilesAccepted(draggedFiles); | ||
const isDragReject = filesCount > 0 && (!isDragActive || !isMultipleAllowed); | ||
@@ -376,3 +372,3 @@ className = className || ''; | ||
> | ||
{this.renderChildren(children)} | ||
{this.renderChildren(children, isDragActive, isDragReject)} | ||
<input | ||
@@ -379,0 +375,0 @@ {...inputProps/* expand user provided inputProps first so inputAttributes override them */} |
@@ -6,2 +6,3 @@ import React from 'react'; | ||
const Dropzone = require(process.env.NODE_ENV === 'production' ? '../dist/index' : './index'); // eslint-disable-line import/no-dynamic-require | ||
const DummyChildComponent = () => null; | ||
@@ -336,7 +337,10 @@ let files; | ||
const dropzone = mount( | ||
<Dropzone /> | ||
<Dropzone> | ||
{props => <DummyChildComponent {...props} />} | ||
</Dropzone> | ||
); | ||
const child = dropzone.find(DummyChildComponent); | ||
dropzone.simulate('dragEnter', { dataTransfer: { files } }); | ||
expect(dropzone.state().isDragActive).toEqual(true); | ||
expect(dropzone.state().isDragReject).toEqual(false); | ||
expect(child).toHaveProp('isDragActive', true); | ||
expect(child).toHaveProp('isDragReject', false); | ||
}); | ||
@@ -346,7 +350,10 @@ | ||
const dropzone = mount( | ||
<Dropzone accept="image/*" /> | ||
<Dropzone accept="image/*"> | ||
{props => <DummyChildComponent {...props} />} | ||
</Dropzone> | ||
); | ||
const child = dropzone.find(DummyChildComponent); | ||
dropzone.simulate('dragEnter', { dataTransfer: { files: files.concat(images) } }); | ||
expect(dropzone.state().isDragActive).toEqual(false); | ||
expect(dropzone.state().isDragReject).toEqual(true); | ||
expect(child).toHaveProp('isDragActive', false); | ||
expect(child).toHaveProp('isDragReject', true); | ||
}); | ||
@@ -359,7 +366,10 @@ | ||
multiple={false} | ||
/> | ||
> | ||
{props => <DummyChildComponent {...props} />} | ||
</Dropzone> | ||
); | ||
const child = dropzone.find(DummyChildComponent); | ||
dropzone.simulate('dragEnter', { dataTransfer: { files } }); | ||
expect(dropzone.state().isDragActive).toEqual(false); | ||
expect(dropzone.state().isDragReject).toEqual(true); | ||
expect(child).toHaveProp('isDragActive', false); | ||
expect(child).toHaveProp('isDragReject', true); | ||
}); | ||
@@ -372,9 +382,28 @@ | ||
multiple={false} | ||
/> | ||
> | ||
{props => <DummyChildComponent {...props} />} | ||
</Dropzone> | ||
); | ||
const child = dropzone.find(DummyChildComponent); | ||
dropzone.simulate('dragEnter', { dataTransfer: { files: images } }); | ||
expect(dropzone.state().isDragActive).toEqual(true); | ||
expect(dropzone.state().isDragReject).toEqual(true); | ||
expect(child).toHaveProp('isDragActive', true); | ||
expect(child).toHaveProp('isDragReject', true); | ||
}); | ||
it('should set proper dragActive state if accept prop changes mid-drag', () => { | ||
const dropzone = mount( | ||
<Dropzone accept="image/*"> | ||
{props => <DummyChildComponent {...props} />} | ||
</Dropzone> | ||
); | ||
const child = dropzone.find(DummyChildComponent); | ||
dropzone.simulate('dragEnter', { dataTransfer: { files: images } }); | ||
expect(child).toHaveProp('isDragActive', true); | ||
expect(child).toHaveProp('isDragReject', false); | ||
dropzone.setProps({ accept: 'text/*' }); | ||
expect(child).toHaveProp('isDragActive', false); | ||
expect(child).toHaveProp('isDragReject', true); | ||
}); | ||
it('should expose state to children', () => { | ||
@@ -411,18 +440,32 @@ const dropzone = mount( | ||
if (isDragActive) { | ||
return <DragActiveComponent />; | ||
return ( | ||
<DragActiveComponent | ||
isDragActive={isDragActive} | ||
isDragReject={isDragReject} | ||
/> | ||
); | ||
} | ||
return <ChildComponent />; | ||
return ( | ||
<ChildComponent | ||
isDragActive={isDragActive} | ||
isDragReject={isDragReject} | ||
/> | ||
); | ||
}} | ||
</Dropzone> | ||
); | ||
dropzone.find(ChildComponent).simulate('dragEnter', { dataTransfer: { files } }); | ||
const child = dropzone.find(ChildComponent); | ||
child.simulate('dragEnter', { dataTransfer: { files } }); | ||
dropzone.simulate('dragEnter', { dataTransfer: { files } }); | ||
// make sure we handle any duplicate dragEnter events that the browser may send us | ||
dropzone.simulate('dragEnter', { dataTransfer: { files } }); | ||
expect(dropzone.state().isDragActive).toEqual(true); | ||
expect(dropzone.state().isDragReject).toEqual(false); | ||
const dragActiveChild = dropzone.find(DragActiveComponent); | ||
expect(dragActiveChild).toBePresent(); | ||
expect(dragActiveChild).toHaveProp('isDragActive', true); | ||
expect(dragActiveChild).toHaveProp('isDragReject', false); | ||
dropzone.simulate('dragLeave', { dataTransfer: { files } }); | ||
expect(dropzone.state().isDragActive).toEqual(false); | ||
expect(dropzone.state().isDragReject).toEqual(false); | ||
expect(dropzone.find(DragActiveComponent)).toBeEmpty(); | ||
expect(child).toHaveProp('isDragActive', false); | ||
expect(child).toHaveProp('isDragReject', false); | ||
}); | ||
@@ -454,10 +497,13 @@ }); | ||
onDropRejected={dropRejectedSpy} | ||
/> | ||
> | ||
{props => <DummyChildComponent {...props} />} | ||
</Dropzone> | ||
); | ||
const child = dropzone.find(DummyChildComponent); | ||
dropzone.simulate('dragEnter', { dataTransfer: { files } }); | ||
expect(dropzone.state().isDragActive).toEqual(true); | ||
expect(dropzone.state().isDragReject).toEqual(false); | ||
expect(child).toHaveProp('isDragActive', true); | ||
expect(child).toHaveProp('isDragReject', false); | ||
dropzone.simulate('drop', { dataTransfer: { files } }); | ||
expect(dropzone.state().isDragActive).toEqual(false); | ||
expect(dropzone.state().isDragReject).toEqual(false); | ||
expect(child).toHaveProp('isDragActive', false); | ||
expect(child).toHaveProp('isDragReject', false); | ||
}); | ||
@@ -892,4 +938,3 @@ | ||
> | ||
<p>Outer content</p> | ||
<InnerDropzone /> | ||
{props => <InnerDropzone {...props} />} | ||
</Dropzone> | ||
@@ -902,4 +947,4 @@ ); | ||
innerDropzone.simulate('dragEnter', { dataTransfer: { files: images } }); | ||
expect(outerDropzone.state().isDragActive).toEqual(true); | ||
expect(outerDropzone.state().isDragReject).toEqual(false); | ||
expect(innerDropzone).toHaveProp('isDragActive', true); | ||
expect(innerDropzone).toHaveProp('isDragReject', false); | ||
expect(innerDropzone.find(InnerDragAccepted).exists()).toEqual(true); | ||
@@ -933,4 +978,4 @@ expect(innerDropzone.find(InnerDragRejected).exists()).toEqual(false); | ||
expect(outerDropRejectedSpy.firstCall.args[0]).toHaveLength(1); | ||
expect(outerDropzone.state().isDragActive).toEqual(false); | ||
expect(outerDropzone.state().isDragReject).toEqual(false); | ||
expect(innerDropzone).toHaveProp('isDragActive', false); | ||
expect(innerDropzone).toHaveProp('isDragReject', false); | ||
}); | ||
@@ -937,0 +982,0 @@ }); |
/* eslint prefer-template: 0 */ | ||
require('jest-enzyme'); | ||
@@ -3,0 +4,0 @@ global.window.URL = { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
448488
2313
35