react-dropzone 14.4.1 → 16.0.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.
- package/README.md +3 -3
- package/dist/index.cjs +1077 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +1046 -2
- package/dist/index.js.map +1 -0
- package/package.json +62 -161
- package/src/{index.js → index.jsx} +10 -7
- package/typings/tests/tsconfig.json +12 -11
- package/.babelrc.js +0 -28
- package/.codeclimate.yml +0 -15
- package/.editorconfig +0 -13
- package/.eslintignore +0 -3
- package/.eslintrc +0 -37
- package/.gitpod.yml +0 -6
- package/.husky/commit-msg +0 -5
- package/.husky/pre-commit +0 -5
- package/.nvmrc +0 -1
- package/.releaserc.json +0 -27
- package/CHANGELOG.md +0 -6
- package/commitlint.config.js +0 -1
- package/dist/es/index.js +0 -1048
- package/dist/es/package.json +0 -1
- package/dist/es/utils/index.js +0 -366
- package/examples/.eslintrc +0 -5
- package/examples/accept/README.md +0 -144
- package/examples/basic/README.md +0 -70
- package/examples/class-component/README.md +0 -45
- package/examples/drag-overlay/README.md +0 -132
- package/examples/events/README.md +0 -164
- package/examples/file-dialog/README.md +0 -90
- package/examples/forms/README.md +0 -69
- package/examples/maxFiles/README.md +0 -58
- package/examples/no-jsx/README.md +0 -32
- package/examples/pintura/README.md +0 -146
- package/examples/plugins/README.md +0 -55
- package/examples/previews/README.md +0 -86
- package/examples/styling/README.md +0 -126
- package/examples/theme.css +0 -37
- package/examples/validator/README.md +0 -68
- package/rollup.config.js +0 -33
- package/src/.eslintrc +0 -37
- package/src/__snapshots__/index.spec.js.snap +0 -3
- package/src/index.spec.js +0 -3777
- package/src/utils/index.spec.js +0 -625
- package/styleguide.config.js +0 -107
- package/testSetup.js +0 -8
- package/typings/.eslintrc +0 -28
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
The hook accepts a `getFilesFromEvent` prop that enhances the handling of dropped file system objects and allows more flexible use of them e.g. passing a function that accepts drop event of a folder and resolves it to an array of files adds plug-in functionality of folders drag-and-drop.
|
|
2
|
-
|
|
3
|
-
Though, note that the provided `getFilesFromEvent` fn must return a `Promise` with a list of `File` objects (or `DataTransferItem` of `{kind: 'file'}` when data cannot be accessed).
|
|
4
|
-
Otherwise, the results will be discarded and none of the drag events callbacks will be invoked.
|
|
5
|
-
|
|
6
|
-
In case you need to extend the `File` with some additional properties, you should use [Object.defineProperty()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty) so that the result will still pass through our filter:
|
|
7
|
-
|
|
8
|
-
```jsx harmony
|
|
9
|
-
import React from 'react';
|
|
10
|
-
import {useDropzone} from 'react-dropzone';
|
|
11
|
-
|
|
12
|
-
function Plugin(props) {
|
|
13
|
-
const {acceptedFiles, getRootProps, getInputProps} = useDropzone({
|
|
14
|
-
getFilesFromEvent: event => myCustomFileGetter(event)
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
const files = acceptedFiles.map(f => (
|
|
18
|
-
<li key={f.name}>
|
|
19
|
-
{f.name} has <strong>myProps</strong>: {f.myProp === true ? 'YES' : ''}
|
|
20
|
-
</li>
|
|
21
|
-
));
|
|
22
|
-
|
|
23
|
-
return (
|
|
24
|
-
<section className="container">
|
|
25
|
-
<div {...getRootProps({className: 'dropzone'})}>
|
|
26
|
-
<input {...getInputProps()} />
|
|
27
|
-
<p>Drag 'n' drop some files here, or click to select files</p>
|
|
28
|
-
</div>
|
|
29
|
-
<aside>
|
|
30
|
-
<h4>Files</h4>
|
|
31
|
-
<ul>{files}</ul>
|
|
32
|
-
</aside>
|
|
33
|
-
</section>
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async function myCustomFileGetter(event) {
|
|
38
|
-
const files = [];
|
|
39
|
-
const fileList = event.dataTransfer ? event.dataTransfer.files : event.target.files;
|
|
40
|
-
|
|
41
|
-
for (var i = 0; i < fileList.length; i++) {
|
|
42
|
-
const file = fileList.item(i);
|
|
43
|
-
|
|
44
|
-
Object.defineProperty(file, 'myProp', {
|
|
45
|
-
value: true
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
files.push(file);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return files;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
<Plugin />
|
|
55
|
-
```
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
Starting with version 7.0.0, the `{preview}` property generation on the [File](https://developer.mozilla.org/en-US/docs/Web/API/File) objects and the `{disablePreview}` property on the `<Dropzone>` have been removed.
|
|
2
|
-
|
|
3
|
-
If you need the `{preview}`, it can be easily achieved in the `onDrop()` callback:
|
|
4
|
-
|
|
5
|
-
```jsx harmony
|
|
6
|
-
import React, {useEffect, useState} from 'react';
|
|
7
|
-
import {useDropzone} from 'react-dropzone';
|
|
8
|
-
|
|
9
|
-
const thumbsContainer = {
|
|
10
|
-
display: 'flex',
|
|
11
|
-
flexDirection: 'row',
|
|
12
|
-
flexWrap: 'wrap',
|
|
13
|
-
marginTop: 16
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const thumb = {
|
|
17
|
-
display: 'inline-flex',
|
|
18
|
-
borderRadius: 2,
|
|
19
|
-
border: '1px solid #eaeaea',
|
|
20
|
-
marginBottom: 8,
|
|
21
|
-
marginRight: 8,
|
|
22
|
-
width: 100,
|
|
23
|
-
height: 100,
|
|
24
|
-
padding: 4,
|
|
25
|
-
boxSizing: 'border-box'
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const thumbInner = {
|
|
29
|
-
display: 'flex',
|
|
30
|
-
minWidth: 0,
|
|
31
|
-
overflow: 'hidden'
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
const img = {
|
|
35
|
-
display: 'block',
|
|
36
|
-
width: 'auto',
|
|
37
|
-
height: '100%'
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
function Previews(props) {
|
|
42
|
-
const [files, setFiles] = useState([]);
|
|
43
|
-
const {getRootProps, getInputProps} = useDropzone({
|
|
44
|
-
accept: {
|
|
45
|
-
'image/*': []
|
|
46
|
-
},
|
|
47
|
-
onDrop: acceptedFiles => {
|
|
48
|
-
setFiles(acceptedFiles.map(file => Object.assign(file, {
|
|
49
|
-
preview: URL.createObjectURL(file)
|
|
50
|
-
})));
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
const thumbs = files.map(file => (
|
|
55
|
-
<div style={thumb} key={file.name}>
|
|
56
|
-
<div style={thumbInner}>
|
|
57
|
-
<img
|
|
58
|
-
src={file.preview}
|
|
59
|
-
style={img}
|
|
60
|
-
// Revoke data uri after image is loaded
|
|
61
|
-
onLoad={() => { URL.revokeObjectURL(file.preview) }}
|
|
62
|
-
/>
|
|
63
|
-
</div>
|
|
64
|
-
</div>
|
|
65
|
-
));
|
|
66
|
-
|
|
67
|
-
useEffect(() => {
|
|
68
|
-
// Make sure to revoke the data uris to avoid memory leaks, will run on unmount
|
|
69
|
-
return () => files.forEach(file => URL.revokeObjectURL(file.preview));
|
|
70
|
-
}, [files]);
|
|
71
|
-
|
|
72
|
-
return (
|
|
73
|
-
<section className="container">
|
|
74
|
-
<div {...getRootProps({className: 'dropzone'})}>
|
|
75
|
-
<input {...getInputProps()} />
|
|
76
|
-
<p>Drag 'n' drop some files here, or click to select files</p>
|
|
77
|
-
</div>
|
|
78
|
-
<aside style={thumbsContainer}>
|
|
79
|
-
{thumbs}
|
|
80
|
-
</aside>
|
|
81
|
-
</section>
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
<Previews />
|
|
86
|
-
```
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
The hook fn doesn't set any styles on either of the prop fns (`getRootProps()`/`getInputProps()`).
|
|
2
|
-
|
|
3
|
-
### Using inline styles
|
|
4
|
-
|
|
5
|
-
```jsx harmony
|
|
6
|
-
import React, {useMemo} from 'react';
|
|
7
|
-
import {useDropzone} from 'react-dropzone';
|
|
8
|
-
|
|
9
|
-
const baseStyle = {
|
|
10
|
-
flex: 1,
|
|
11
|
-
display: 'flex',
|
|
12
|
-
flexDirection: 'column',
|
|
13
|
-
alignItems: 'center',
|
|
14
|
-
padding: '20px',
|
|
15
|
-
borderWidth: 2,
|
|
16
|
-
borderRadius: 2,
|
|
17
|
-
borderColor: '#eeeeee',
|
|
18
|
-
borderStyle: 'dashed',
|
|
19
|
-
backgroundColor: '#fafafa',
|
|
20
|
-
color: '#bdbdbd',
|
|
21
|
-
outline: 'none',
|
|
22
|
-
transition: 'border .24s ease-in-out'
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const focusedStyle = {
|
|
26
|
-
borderColor: '#2196f3'
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const acceptStyle = {
|
|
30
|
-
borderColor: '#00e676'
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const rejectStyle = {
|
|
34
|
-
borderColor: '#ff1744'
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
function StyledDropzone(props) {
|
|
38
|
-
const {
|
|
39
|
-
getRootProps,
|
|
40
|
-
getInputProps,
|
|
41
|
-
isFocused,
|
|
42
|
-
isDragAccept,
|
|
43
|
-
isDragReject
|
|
44
|
-
} = useDropzone({accept: {'image/*': []}});
|
|
45
|
-
|
|
46
|
-
const style = useMemo(() => ({
|
|
47
|
-
...baseStyle,
|
|
48
|
-
...(isFocused ? focusedStyle : {}),
|
|
49
|
-
...(isDragAccept ? acceptStyle : {}),
|
|
50
|
-
...(isDragReject ? rejectStyle : {})
|
|
51
|
-
}), [
|
|
52
|
-
isFocused,
|
|
53
|
-
isDragAccept,
|
|
54
|
-
isDragReject
|
|
55
|
-
]);
|
|
56
|
-
|
|
57
|
-
return (
|
|
58
|
-
<div className="container">
|
|
59
|
-
<div {...getRootProps({style})}>
|
|
60
|
-
<input {...getInputProps()} />
|
|
61
|
-
<p>Drag 'n' drop some files here, or click to select files</p>
|
|
62
|
-
</div>
|
|
63
|
-
</div>
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
<StyledDropzone />
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
### Using styled-components
|
|
71
|
-
|
|
72
|
-
```jsx harmony
|
|
73
|
-
import React from 'react';
|
|
74
|
-
import {useDropzone} from 'react-dropzone';
|
|
75
|
-
import styled from 'styled-components';
|
|
76
|
-
|
|
77
|
-
const getColor = (props) => {
|
|
78
|
-
if (props.isDragAccept) {
|
|
79
|
-
return '#00e676';
|
|
80
|
-
}
|
|
81
|
-
if (props.isDragReject) {
|
|
82
|
-
return '#ff1744';
|
|
83
|
-
}
|
|
84
|
-
if (props.isFocused) {
|
|
85
|
-
return '#2196f3';
|
|
86
|
-
}
|
|
87
|
-
return '#eeeeee';
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const Container = styled.div`
|
|
91
|
-
flex: 1;
|
|
92
|
-
display: flex;
|
|
93
|
-
flex-direction: column;
|
|
94
|
-
align-items: center;
|
|
95
|
-
padding: 20px;
|
|
96
|
-
border-width: 2px;
|
|
97
|
-
border-radius: 2px;
|
|
98
|
-
border-color: ${props => getColor(props)};
|
|
99
|
-
border-style: dashed;
|
|
100
|
-
background-color: #fafafa;
|
|
101
|
-
color: #bdbdbd;
|
|
102
|
-
outline: none;
|
|
103
|
-
transition: border .24s ease-in-out;
|
|
104
|
-
`;
|
|
105
|
-
|
|
106
|
-
function StyledDropzone(props) {
|
|
107
|
-
const {
|
|
108
|
-
getRootProps,
|
|
109
|
-
getInputProps,
|
|
110
|
-
isFocused,
|
|
111
|
-
isDragAccept,
|
|
112
|
-
isDragReject
|
|
113
|
-
} = useDropzone({accept: {'image/*': []}});
|
|
114
|
-
|
|
115
|
-
return (
|
|
116
|
-
<div className="container">
|
|
117
|
-
<Container {...getRootProps({isFocused, isDragAccept, isDragReject})}>
|
|
118
|
-
<input {...getInputProps()} />
|
|
119
|
-
<p>Drag 'n' drop some files here, or click to select files</p>
|
|
120
|
-
</Container>
|
|
121
|
-
</div>
|
|
122
|
-
);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
<StyledDropzone />
|
|
126
|
-
```
|
package/examples/theme.css
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
.container {
|
|
2
|
-
display: flex;
|
|
3
|
-
flex-direction: column;
|
|
4
|
-
font-family: sans-serif;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
.container > p {
|
|
8
|
-
font-size: 1rem;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
.container > em {
|
|
12
|
-
font-size: .8rem;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.dropzone {
|
|
16
|
-
flex: 1;
|
|
17
|
-
display: flex;
|
|
18
|
-
flex-direction: column;
|
|
19
|
-
align-items: center;
|
|
20
|
-
padding: 20px;
|
|
21
|
-
border-width: 2px;
|
|
22
|
-
border-radius: 2px;
|
|
23
|
-
border-color: #eeeeee;
|
|
24
|
-
border-style: dashed;
|
|
25
|
-
background-color: #fafafa;
|
|
26
|
-
color: #bdbdbd;
|
|
27
|
-
outline: none;
|
|
28
|
-
transition: border .24s ease-in-out;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
.dropzone:focus {
|
|
32
|
-
border-color: #2196f3;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.dropzone.disabled {
|
|
36
|
-
opacity: 0.6;
|
|
37
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
By providing `validator` prop you can specify custom validation for files.
|
|
2
|
-
|
|
3
|
-
The value must be a function that accepts File object and returns null if file should be accepted or error object/array of error objects if file should be rejected.
|
|
4
|
-
|
|
5
|
-
```jsx harmony
|
|
6
|
-
import React from 'react';
|
|
7
|
-
import {useDropzone} from 'react-dropzone';
|
|
8
|
-
|
|
9
|
-
const maxLength = 20;
|
|
10
|
-
|
|
11
|
-
function nameLengthValidator(file) {
|
|
12
|
-
if (file.name.length > maxLength) {
|
|
13
|
-
return {
|
|
14
|
-
code: "name-too-large",
|
|
15
|
-
message: `Name is larger than ${maxLength} characters`
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return null
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function CustomValidation(props) {
|
|
23
|
-
const {
|
|
24
|
-
acceptedFiles,
|
|
25
|
-
fileRejections,
|
|
26
|
-
getRootProps,
|
|
27
|
-
getInputProps
|
|
28
|
-
} = useDropzone({
|
|
29
|
-
validator: nameLengthValidator
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
const acceptedFileItems = acceptedFiles.map(file => (
|
|
33
|
-
<li key={file.path}>
|
|
34
|
-
{file.path} - {file.size} bytes
|
|
35
|
-
</li>
|
|
36
|
-
));
|
|
37
|
-
|
|
38
|
-
const fileRejectionItems = fileRejections.map(({ file, errors }) => (
|
|
39
|
-
<li key={file.path}>
|
|
40
|
-
{file.path} - {file.size} bytes
|
|
41
|
-
<ul>
|
|
42
|
-
{errors.map(e => (
|
|
43
|
-
<li key={e.code}>{e.message}</li>
|
|
44
|
-
))}
|
|
45
|
-
</ul>
|
|
46
|
-
</li>
|
|
47
|
-
));
|
|
48
|
-
|
|
49
|
-
return (
|
|
50
|
-
<section className="container">
|
|
51
|
-
<div {...getRootProps({ className: 'dropzone' })}>
|
|
52
|
-
<input {...getInputProps()} />
|
|
53
|
-
<p>Drag 'n' drop some files here, or click to select files</p>
|
|
54
|
-
<em>(Only files with name less than 20 characters will be accepted)</em>
|
|
55
|
-
</div>
|
|
56
|
-
<aside>
|
|
57
|
-
<h4>Accepted files</h4>
|
|
58
|
-
<ul>{acceptedFileItems}</ul>
|
|
59
|
-
<h4>Rejected files</h4>
|
|
60
|
-
<ul>{fileRejectionItems}</ul>
|
|
61
|
-
</aside>
|
|
62
|
-
</section>
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
<CustomValidation />
|
|
67
|
-
```
|
|
68
|
-
|
package/rollup.config.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
const { nodeResolve } = require("@rollup/plugin-node-resolve");
|
|
2
|
-
const commonjs = require("@rollup/plugin-commonjs");
|
|
3
|
-
const { babel } = require("@rollup/plugin-babel");
|
|
4
|
-
const { terser } = require("rollup-plugin-terser");
|
|
5
|
-
|
|
6
|
-
const umdGlobals = {
|
|
7
|
-
react: "React",
|
|
8
|
-
"prop-types": "PropTypes",
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
module.exports = [
|
|
12
|
-
{
|
|
13
|
-
input: "./src/index.js",
|
|
14
|
-
output: {
|
|
15
|
-
file: "dist/index.js",
|
|
16
|
-
format: "umd",
|
|
17
|
-
name: "reactDropzone",
|
|
18
|
-
globals: umdGlobals,
|
|
19
|
-
sourcemap: "inline",
|
|
20
|
-
exports: "named",
|
|
21
|
-
},
|
|
22
|
-
external: Object.keys(umdGlobals),
|
|
23
|
-
plugins: [
|
|
24
|
-
nodeResolve(),
|
|
25
|
-
commonjs({ include: "**/node_modules/**" }),
|
|
26
|
-
babel({
|
|
27
|
-
exclude: "**/node_modules/**",
|
|
28
|
-
babelHelpers: "bundled",
|
|
29
|
-
}),
|
|
30
|
-
terser(),
|
|
31
|
-
],
|
|
32
|
-
},
|
|
33
|
-
];
|
package/src/.eslintrc
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"root": true,
|
|
3
|
-
"parser": "@babel/eslint-parser",
|
|
4
|
-
"parserOptions": {
|
|
5
|
-
"ecmaVersion": 2017,
|
|
6
|
-
"sourceType": "module"
|
|
7
|
-
},
|
|
8
|
-
"env": {
|
|
9
|
-
"es6": true,
|
|
10
|
-
"browser": true,
|
|
11
|
-
"node": true,
|
|
12
|
-
"jest": true
|
|
13
|
-
},
|
|
14
|
-
"plugins": [
|
|
15
|
-
"import",
|
|
16
|
-
"jsx-a11y",
|
|
17
|
-
"prettier",
|
|
18
|
-
"react",
|
|
19
|
-
"react-hooks"
|
|
20
|
-
],
|
|
21
|
-
"extends": [
|
|
22
|
-
"eslint:recommended",
|
|
23
|
-
"plugin:react/recommended",
|
|
24
|
-
"plugin:jsx-a11y/recommended",
|
|
25
|
-
"plugin:prettier/recommended"
|
|
26
|
-
],
|
|
27
|
-
"rules": {
|
|
28
|
-
"react-hooks/rules-of-hooks": 2,
|
|
29
|
-
"react/forbid-prop-types": 0,
|
|
30
|
-
"react/require-default-props": 0
|
|
31
|
-
},
|
|
32
|
-
"settings": {
|
|
33
|
-
"react": {
|
|
34
|
-
"version": "detect"
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
-
|
|
3
|
-
exports[`useDropzone() hook behavior renders the root and input nodes with the necessary props 1`] = `"<div role=\\"presentation\\" tabindex=\\"0\\"><input multiple=\\"\\" type=\\"file\\" style=\\"border: 0px; clip: rect(0px, 0px, 0px, 0px); clip-path: inset(50%); height: 1px; margin: 0px -1px -1px 0px; overflow: hidden; padding: 0px; position: absolute; width: 1px; white-space: nowrap;\\" tabindex=\\"-1\\"></div>"`;
|