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
package/dist/es/package.json
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"type":"module"}
|
package/dist/es/utils/index.js
DELETED
|
@@ -1,366 +0,0 @@
|
|
|
1
|
-
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
2
|
-
|
|
3
|
-
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
4
|
-
|
|
5
|
-
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
6
|
-
|
|
7
|
-
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
8
|
-
|
|
9
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
10
|
-
|
|
11
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
12
|
-
|
|
13
|
-
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
14
|
-
|
|
15
|
-
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
|
16
|
-
|
|
17
|
-
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
18
|
-
|
|
19
|
-
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
20
|
-
|
|
21
|
-
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
22
|
-
|
|
23
|
-
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
24
|
-
|
|
25
|
-
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
26
|
-
|
|
27
|
-
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
28
|
-
|
|
29
|
-
import _accepts from "attr-accept";
|
|
30
|
-
var accepts = typeof _accepts === "function" ? _accepts : _accepts.default; // Error codes
|
|
31
|
-
|
|
32
|
-
export var FILE_INVALID_TYPE = "file-invalid-type";
|
|
33
|
-
export var FILE_TOO_LARGE = "file-too-large";
|
|
34
|
-
export var FILE_TOO_SMALL = "file-too-small";
|
|
35
|
-
export var TOO_MANY_FILES = "too-many-files";
|
|
36
|
-
export var ErrorCode = {
|
|
37
|
-
FileInvalidType: FILE_INVALID_TYPE,
|
|
38
|
-
FileTooLarge: FILE_TOO_LARGE,
|
|
39
|
-
FileTooSmall: FILE_TOO_SMALL,
|
|
40
|
-
TooManyFiles: TOO_MANY_FILES
|
|
41
|
-
};
|
|
42
|
-
/**
|
|
43
|
-
*
|
|
44
|
-
* @param {string} accept
|
|
45
|
-
*/
|
|
46
|
-
|
|
47
|
-
export var getInvalidTypeRejectionErr = function getInvalidTypeRejectionErr() {
|
|
48
|
-
var accept = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
|
|
49
|
-
var acceptArr = accept.split(",");
|
|
50
|
-
var msg = acceptArr.length > 1 ? "one of ".concat(acceptArr.join(", ")) : acceptArr[0];
|
|
51
|
-
return {
|
|
52
|
-
code: FILE_INVALID_TYPE,
|
|
53
|
-
message: "File type must be ".concat(msg)
|
|
54
|
-
};
|
|
55
|
-
};
|
|
56
|
-
export var getTooLargeRejectionErr = function getTooLargeRejectionErr(maxSize) {
|
|
57
|
-
return {
|
|
58
|
-
code: FILE_TOO_LARGE,
|
|
59
|
-
message: "File is larger than ".concat(maxSize, " ").concat(maxSize === 1 ? "byte" : "bytes")
|
|
60
|
-
};
|
|
61
|
-
};
|
|
62
|
-
export var getTooSmallRejectionErr = function getTooSmallRejectionErr(minSize) {
|
|
63
|
-
return {
|
|
64
|
-
code: FILE_TOO_SMALL,
|
|
65
|
-
message: "File is smaller than ".concat(minSize, " ").concat(minSize === 1 ? "byte" : "bytes")
|
|
66
|
-
};
|
|
67
|
-
};
|
|
68
|
-
export var TOO_MANY_FILES_REJECTION = {
|
|
69
|
-
code: TOO_MANY_FILES,
|
|
70
|
-
message: "Too many files"
|
|
71
|
-
};
|
|
72
|
-
/**
|
|
73
|
-
* Check if the given file is a DataTransferItem with an empty type.
|
|
74
|
-
*
|
|
75
|
-
* During drag events, browsers may return DataTransferItem objects instead of File objects.
|
|
76
|
-
* Some browsers (e.g., Chrome) return an empty MIME type for certain file types (like .md files)
|
|
77
|
-
* on DataTransferItem during drag events, even though the type is correctly set during drop.
|
|
78
|
-
*
|
|
79
|
-
* This function detects such cases by checking for:
|
|
80
|
-
* 1. Empty type string
|
|
81
|
-
* 2. Presence of getAsFile method (indicates it's a DataTransferItem, not a File)
|
|
82
|
-
*
|
|
83
|
-
* We accept these during drag to provide proper UI feedback, while maintaining
|
|
84
|
-
* strict validation during drop when real File objects are available.
|
|
85
|
-
*
|
|
86
|
-
* @param {File | DataTransferItem} file
|
|
87
|
-
* @returns {boolean}
|
|
88
|
-
*/
|
|
89
|
-
|
|
90
|
-
export function isDataTransferItemWithEmptyType(file) {
|
|
91
|
-
return file.type === "" && typeof file.getAsFile === "function";
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Check if file is accepted.
|
|
95
|
-
*
|
|
96
|
-
* Firefox versions prior to 53 return a bogus MIME type for every file drag,
|
|
97
|
-
* so dragovers with that MIME type will always be accepted.
|
|
98
|
-
*
|
|
99
|
-
* Chrome/other browsers may return an empty MIME type for files during drag events,
|
|
100
|
-
* so we accept those as well (we'll validate properly on drop).
|
|
101
|
-
*
|
|
102
|
-
* @param {File} file
|
|
103
|
-
* @param {string} accept
|
|
104
|
-
* @returns
|
|
105
|
-
*/
|
|
106
|
-
|
|
107
|
-
export function fileAccepted(file, accept) {
|
|
108
|
-
var isAcceptable = file.type === "application/x-moz-file" || accepts(file, accept) || isDataTransferItemWithEmptyType(file);
|
|
109
|
-
return [isAcceptable, isAcceptable ? null : getInvalidTypeRejectionErr(accept)];
|
|
110
|
-
}
|
|
111
|
-
export function fileMatchSize(file, minSize, maxSize) {
|
|
112
|
-
if (isDefined(file.size)) {
|
|
113
|
-
if (isDefined(minSize) && isDefined(maxSize)) {
|
|
114
|
-
if (file.size > maxSize) return [false, getTooLargeRejectionErr(maxSize)];
|
|
115
|
-
if (file.size < minSize) return [false, getTooSmallRejectionErr(minSize)];
|
|
116
|
-
} else if (isDefined(minSize) && file.size < minSize) return [false, getTooSmallRejectionErr(minSize)];else if (isDefined(maxSize) && file.size > maxSize) return [false, getTooLargeRejectionErr(maxSize)];
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return [true, null];
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function isDefined(value) {
|
|
123
|
-
return value !== undefined && value !== null;
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
*
|
|
127
|
-
* @param {object} options
|
|
128
|
-
* @param {File[]} options.files
|
|
129
|
-
* @param {string} [options.accept]
|
|
130
|
-
* @param {number} [options.minSize]
|
|
131
|
-
* @param {number} [options.maxSize]
|
|
132
|
-
* @param {boolean} [options.multiple]
|
|
133
|
-
* @param {number} [options.maxFiles]
|
|
134
|
-
* @param {(f: File) => FileError|FileError[]|null} [options.validator]
|
|
135
|
-
* @returns
|
|
136
|
-
*/
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
export function allFilesAccepted(_ref) {
|
|
140
|
-
var files = _ref.files,
|
|
141
|
-
accept = _ref.accept,
|
|
142
|
-
minSize = _ref.minSize,
|
|
143
|
-
maxSize = _ref.maxSize,
|
|
144
|
-
multiple = _ref.multiple,
|
|
145
|
-
maxFiles = _ref.maxFiles,
|
|
146
|
-
validator = _ref.validator;
|
|
147
|
-
|
|
148
|
-
if (!multiple && files.length > 1 || multiple && maxFiles >= 1 && files.length > maxFiles) {
|
|
149
|
-
return false;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return files.every(function (file) {
|
|
153
|
-
var _fileAccepted = fileAccepted(file, accept),
|
|
154
|
-
_fileAccepted2 = _slicedToArray(_fileAccepted, 1),
|
|
155
|
-
accepted = _fileAccepted2[0];
|
|
156
|
-
|
|
157
|
-
var _fileMatchSize = fileMatchSize(file, minSize, maxSize),
|
|
158
|
-
_fileMatchSize2 = _slicedToArray(_fileMatchSize, 1),
|
|
159
|
-
sizeMatch = _fileMatchSize2[0];
|
|
160
|
-
|
|
161
|
-
var customErrors = validator ? validator(file) : null;
|
|
162
|
-
return accepted && sizeMatch && !customErrors;
|
|
163
|
-
});
|
|
164
|
-
} // React's synthetic events has event.isPropagationStopped,
|
|
165
|
-
// but to remain compatibility with other libs (Preact) fall back
|
|
166
|
-
// to check event.cancelBubble
|
|
167
|
-
|
|
168
|
-
export function isPropagationStopped(event) {
|
|
169
|
-
if (typeof event.isPropagationStopped === "function") {
|
|
170
|
-
return event.isPropagationStopped();
|
|
171
|
-
} else if (typeof event.cancelBubble !== "undefined") {
|
|
172
|
-
return event.cancelBubble;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
return false;
|
|
176
|
-
}
|
|
177
|
-
export function isEvtWithFiles(event) {
|
|
178
|
-
if (!event.dataTransfer) {
|
|
179
|
-
return !!event.target && !!event.target.files;
|
|
180
|
-
} // https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/types
|
|
181
|
-
// https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types#file
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
return Array.prototype.some.call(event.dataTransfer.types, function (type) {
|
|
185
|
-
return type === "Files" || type === "application/x-moz-file";
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
export function isKindFile(item) {
|
|
189
|
-
return _typeof(item) === "object" && item !== null && item.kind === "file";
|
|
190
|
-
} // allow the entire document to be a drag target
|
|
191
|
-
|
|
192
|
-
export function onDocumentDragOver(event) {
|
|
193
|
-
event.preventDefault();
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
function isIe(userAgent) {
|
|
197
|
-
return userAgent.indexOf("MSIE") !== -1 || userAgent.indexOf("Trident/") !== -1;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
function isEdge(userAgent) {
|
|
201
|
-
return userAgent.indexOf("Edge/") !== -1;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
export function isIeOrEdge() {
|
|
205
|
-
var userAgent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window.navigator.userAgent;
|
|
206
|
-
return isIe(userAgent) || isEdge(userAgent);
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* This is intended to be used to compose event handlers
|
|
210
|
-
* They are executed in order until one of them calls `event.isPropagationStopped()`.
|
|
211
|
-
* Note that the check is done on the first invoke too,
|
|
212
|
-
* meaning that if propagation was stopped before invoking the fns,
|
|
213
|
-
* no handlers will be executed.
|
|
214
|
-
*
|
|
215
|
-
* @param {Function} fns the event hanlder functions
|
|
216
|
-
* @return {Function} the event handler to add to an element
|
|
217
|
-
*/
|
|
218
|
-
|
|
219
|
-
export function composeEventHandlers() {
|
|
220
|
-
for (var _len = arguments.length, fns = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
221
|
-
fns[_key] = arguments[_key];
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
return function (event) {
|
|
225
|
-
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
|
226
|
-
args[_key2 - 1] = arguments[_key2];
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
return fns.some(function (fn) {
|
|
230
|
-
if (!isPropagationStopped(event) && fn) {
|
|
231
|
-
fn.apply(void 0, [event].concat(args));
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
return isPropagationStopped(event);
|
|
235
|
-
});
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* canUseFileSystemAccessAPI checks if the [File System Access API](https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API)
|
|
240
|
-
* is supported by the browser.
|
|
241
|
-
* @returns {boolean}
|
|
242
|
-
*/
|
|
243
|
-
|
|
244
|
-
export function canUseFileSystemAccessAPI() {
|
|
245
|
-
return "showOpenFilePicker" in window;
|
|
246
|
-
}
|
|
247
|
-
/**
|
|
248
|
-
* Convert the `{accept}` dropzone prop to the
|
|
249
|
-
* `{types}` option for https://developer.mozilla.org/en-US/docs/Web/API/window/showOpenFilePicker
|
|
250
|
-
*
|
|
251
|
-
* @param {AcceptProp} accept
|
|
252
|
-
* @returns {{accept: string[]}[]}
|
|
253
|
-
*/
|
|
254
|
-
|
|
255
|
-
export function pickerOptionsFromAccept(accept) {
|
|
256
|
-
if (isDefined(accept)) {
|
|
257
|
-
var acceptForPicker = Object.entries(accept).filter(function (_ref2) {
|
|
258
|
-
var _ref3 = _slicedToArray(_ref2, 2),
|
|
259
|
-
mimeType = _ref3[0],
|
|
260
|
-
ext = _ref3[1];
|
|
261
|
-
|
|
262
|
-
var ok = true;
|
|
263
|
-
|
|
264
|
-
if (!isMIMEType(mimeType)) {
|
|
265
|
-
console.warn("Skipped \"".concat(mimeType, "\" because it is not a valid MIME type. Check https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types for a list of valid MIME types."));
|
|
266
|
-
ok = false;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
if (!Array.isArray(ext) || !ext.every(isExt)) {
|
|
270
|
-
console.warn("Skipped \"".concat(mimeType, "\" because an invalid file extension was provided."));
|
|
271
|
-
ok = false;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
return ok;
|
|
275
|
-
}).reduce(function (agg, _ref4) {
|
|
276
|
-
var _ref5 = _slicedToArray(_ref4, 2),
|
|
277
|
-
mimeType = _ref5[0],
|
|
278
|
-
ext = _ref5[1];
|
|
279
|
-
|
|
280
|
-
return _objectSpread(_objectSpread({}, agg), {}, _defineProperty({}, mimeType, ext));
|
|
281
|
-
}, {});
|
|
282
|
-
return [{
|
|
283
|
-
// description is required due to https://crbug.com/1264708
|
|
284
|
-
description: "Files",
|
|
285
|
-
accept: acceptForPicker
|
|
286
|
-
}];
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
return accept;
|
|
290
|
-
}
|
|
291
|
-
/**
|
|
292
|
-
* Convert the `{accept}` dropzone prop to an array of MIME types/extensions.
|
|
293
|
-
* @param {AcceptProp} accept
|
|
294
|
-
* @returns {string}
|
|
295
|
-
*/
|
|
296
|
-
|
|
297
|
-
export function acceptPropAsAcceptAttr(accept) {
|
|
298
|
-
if (isDefined(accept)) {
|
|
299
|
-
return Object.entries(accept).reduce(function (a, _ref6) {
|
|
300
|
-
var _ref7 = _slicedToArray(_ref6, 2),
|
|
301
|
-
mimeType = _ref7[0],
|
|
302
|
-
ext = _ref7[1];
|
|
303
|
-
|
|
304
|
-
return [].concat(_toConsumableArray(a), [mimeType], _toConsumableArray(ext));
|
|
305
|
-
}, []) // Silently discard invalid entries as pickerOptionsFromAccept warns about these
|
|
306
|
-
.filter(function (v) {
|
|
307
|
-
return isMIMEType(v) || isExt(v);
|
|
308
|
-
}).join(",");
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
return undefined;
|
|
312
|
-
}
|
|
313
|
-
/**
|
|
314
|
-
* Check if v is an exception caused by aborting a request (e.g window.showOpenFilePicker()).
|
|
315
|
-
*
|
|
316
|
-
* See https://developer.mozilla.org/en-US/docs/Web/API/DOMException.
|
|
317
|
-
* @param {any} v
|
|
318
|
-
* @returns {boolean} True if v is an abort exception.
|
|
319
|
-
*/
|
|
320
|
-
|
|
321
|
-
export function isAbort(v) {
|
|
322
|
-
return v instanceof DOMException && (v.name === "AbortError" || v.code === v.ABORT_ERR);
|
|
323
|
-
}
|
|
324
|
-
/**
|
|
325
|
-
* Check if v is a security error.
|
|
326
|
-
*
|
|
327
|
-
* See https://developer.mozilla.org/en-US/docs/Web/API/DOMException.
|
|
328
|
-
* @param {any} v
|
|
329
|
-
* @returns {boolean} True if v is a security error.
|
|
330
|
-
*/
|
|
331
|
-
|
|
332
|
-
export function isSecurityError(v) {
|
|
333
|
-
return v instanceof DOMException && (v.name === "SecurityError" || v.code === v.SECURITY_ERR);
|
|
334
|
-
}
|
|
335
|
-
/**
|
|
336
|
-
* Check if v is a MIME type string.
|
|
337
|
-
*
|
|
338
|
-
* See accepted format: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#unique_file_type_specifiers.
|
|
339
|
-
*
|
|
340
|
-
* @param {string} v
|
|
341
|
-
*/
|
|
342
|
-
|
|
343
|
-
export function isMIMEType(v) {
|
|
344
|
-
return v === "audio/*" || v === "video/*" || v === "image/*" || v === "text/*" || v === "application/*" || /\w+\/[-+.\w]+/g.test(v);
|
|
345
|
-
}
|
|
346
|
-
/**
|
|
347
|
-
* Check if v is a file extension.
|
|
348
|
-
* @param {string} v
|
|
349
|
-
*/
|
|
350
|
-
|
|
351
|
-
export function isExt(v) {
|
|
352
|
-
return /^.*\.[\w]+$/.test(v);
|
|
353
|
-
}
|
|
354
|
-
/**
|
|
355
|
-
* @typedef {Object.<string, string[]>} AcceptProp
|
|
356
|
-
*/
|
|
357
|
-
|
|
358
|
-
/**
|
|
359
|
-
* @typedef {object} FileError
|
|
360
|
-
* @property {string} message
|
|
361
|
-
* @property {ErrorCode|string} code
|
|
362
|
-
*/
|
|
363
|
-
|
|
364
|
-
/**
|
|
365
|
-
* @typedef {"file-invalid-type"|"file-too-large"|"file-too-small"|"too-many-files"} ErrorCode
|
|
366
|
-
*/
|
package/examples/.eslintrc
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
By providing `accept` prop you can make the dropzone accept specific file types and reject the others.
|
|
2
|
-
|
|
3
|
-
The value must be an object with a common [MIME type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types) as keys and an array of file extensions as values (similar to [showOpenFilePicker](https://developer.mozilla.org/en-US/docs/Web/API/window/showOpenFilePicker)'s types `accept` option).
|
|
4
|
-
```js static
|
|
5
|
-
useDropzone({
|
|
6
|
-
accept: {
|
|
7
|
-
'image/png': ['.png'],
|
|
8
|
-
'text/html': ['.html', '.htm'],
|
|
9
|
-
}
|
|
10
|
-
})
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
For more information see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input.
|
|
14
|
-
|
|
15
|
-
```jsx harmony
|
|
16
|
-
import React from 'react';
|
|
17
|
-
import {useDropzone} from 'react-dropzone';
|
|
18
|
-
|
|
19
|
-
function Accept(props) {
|
|
20
|
-
const {
|
|
21
|
-
acceptedFiles,
|
|
22
|
-
fileRejections,
|
|
23
|
-
getRootProps,
|
|
24
|
-
getInputProps
|
|
25
|
-
} = useDropzone({
|
|
26
|
-
accept: {
|
|
27
|
-
'image/jpeg': [],
|
|
28
|
-
'image/png': []
|
|
29
|
-
}
|
|
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 *.jpeg and *.png images 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
|
-
<Accept />
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
### Browser limitations
|
|
70
|
-
|
|
71
|
-
Because of HTML5 File API differences across different browsers during the drag, Dropzone might not be able to detect whether the files are accepted or rejected in Safari nor IE.
|
|
72
|
-
|
|
73
|
-
Furthermore, 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:
|
|
74
|
-
|
|
75
|
-
```jsx harmony
|
|
76
|
-
import React from 'react';
|
|
77
|
-
import {useDropzone} from 'react-dropzone';
|
|
78
|
-
|
|
79
|
-
function Accept(props) {
|
|
80
|
-
const {
|
|
81
|
-
getRootProps,
|
|
82
|
-
getInputProps,
|
|
83
|
-
isDragActive,
|
|
84
|
-
isDragAccept,
|
|
85
|
-
isDragReject
|
|
86
|
-
} = useDropzone({
|
|
87
|
-
accept: {
|
|
88
|
-
'image/jpeg': ['.jpeg', '.png']
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
return (
|
|
93
|
-
<div className="container">
|
|
94
|
-
<div {...getRootProps({className: 'dropzone'})}>
|
|
95
|
-
<input {...getInputProps()} />
|
|
96
|
-
{isDragAccept && (<p>All files will be accepted</p>)}
|
|
97
|
-
{isDragReject && (<p>Some files will be rejected</p>)}
|
|
98
|
-
{!isDragActive && (<p>Drop some files here ...</p>)}
|
|
99
|
-
</div>
|
|
100
|
-
</div>
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
<Accept />
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
but this one will:
|
|
108
|
-
|
|
109
|
-
```jsx harmony
|
|
110
|
-
import React from 'react';
|
|
111
|
-
import {useDropzone} from 'react-dropzone';
|
|
112
|
-
|
|
113
|
-
function Accept(props) {
|
|
114
|
-
const {
|
|
115
|
-
getRootProps,
|
|
116
|
-
getInputProps,
|
|
117
|
-
isDragActive,
|
|
118
|
-
isDragAccept,
|
|
119
|
-
isDragReject
|
|
120
|
-
} = useDropzone({
|
|
121
|
-
accept: {
|
|
122
|
-
'image/*': ['.jpeg', '.png']
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
return (
|
|
127
|
-
<div className="container">
|
|
128
|
-
<div {...getRootProps({className: "dropzone"})}>
|
|
129
|
-
<input {...getInputProps()} />
|
|
130
|
-
{isDragAccept && (<p>All files will be accepted</p>)}
|
|
131
|
-
{isDragReject && (<p>Some files will be rejected</p>)}
|
|
132
|
-
{!isDragActive && (<p>Drop some files here ...</p>)}
|
|
133
|
-
</div>
|
|
134
|
-
</div>
|
|
135
|
-
);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
<Accept />
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
### Notes
|
|
142
|
-
|
|
143
|
-
Mime type determination is not reliable across 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.
|
|
144
|
-
|
package/examples/basic/README.md
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
The `useDropzone` hook just binds the necessary handlers to create a drag 'n' drop zone.
|
|
2
|
-
Use the `getRootProps()` fn to get the props required for drag 'n' drop and use them on any element.
|
|
3
|
-
For click and keydown behavior, use the `getInputProps()` fn and use the returned props on an `<input>`.
|
|
4
|
-
|
|
5
|
-
Furthermore, the hook supports folder drag 'n' drop by default. See [file-selector](https://github.com/react-dropzone/file-selector) for more info about supported browsers.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
```jsx harmony
|
|
9
|
-
import React from 'react';
|
|
10
|
-
import {useDropzone} from 'react-dropzone';
|
|
11
|
-
|
|
12
|
-
function Basic(props) {
|
|
13
|
-
const {acceptedFiles, getRootProps, getInputProps} = useDropzone();
|
|
14
|
-
|
|
15
|
-
const files = acceptedFiles.map(file => (
|
|
16
|
-
<li key={file.path}>
|
|
17
|
-
{file.path} - {file.size} bytes
|
|
18
|
-
</li>
|
|
19
|
-
));
|
|
20
|
-
|
|
21
|
-
return (
|
|
22
|
-
<section className="container">
|
|
23
|
-
<div {...getRootProps({className: 'dropzone'})}>
|
|
24
|
-
<input {...getInputProps()} />
|
|
25
|
-
<p>Drag 'n' drop some files here, or click to select files</p>
|
|
26
|
-
</div>
|
|
27
|
-
<aside>
|
|
28
|
-
<h4>Files</h4>
|
|
29
|
-
<ul>{files}</ul>
|
|
30
|
-
</aside>
|
|
31
|
-
</section>
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
<Basic />
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
Dropzone with `disabled` property:
|
|
39
|
-
|
|
40
|
-
```jsx harmony
|
|
41
|
-
import React from 'react';
|
|
42
|
-
import {useDropzone} from 'react-dropzone';
|
|
43
|
-
|
|
44
|
-
function Basic(props) {
|
|
45
|
-
const {acceptedFiles, getRootProps, getInputProps} = useDropzone({
|
|
46
|
-
disabled: true
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
const files = acceptedFiles.map(file => (
|
|
50
|
-
<li key={file.name}>
|
|
51
|
-
{file.name} - {file.size} bytes
|
|
52
|
-
</li>
|
|
53
|
-
));
|
|
54
|
-
|
|
55
|
-
return (
|
|
56
|
-
<section className="container">
|
|
57
|
-
<div {...getRootProps({className: 'dropzone disabled'})}>
|
|
58
|
-
<input {...getInputProps()} />
|
|
59
|
-
<p>Drag 'n' drop some files here, or click to select files</p>
|
|
60
|
-
</div>
|
|
61
|
-
<aside>
|
|
62
|
-
<h4>Files</h4>
|
|
63
|
-
<ul>{files}</ul>
|
|
64
|
-
</aside>
|
|
65
|
-
</section>
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
<Basic />
|
|
70
|
-
```
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
If you're still using class components, you can use the [`<Dropzone>`](https://react-dropzone.js.org/#components) component provided by the lib:
|
|
2
|
-
|
|
3
|
-
```jsx harmony
|
|
4
|
-
import React, {Component} from 'react';
|
|
5
|
-
import Dropzone from 'react-dropzone';
|
|
6
|
-
|
|
7
|
-
class Basic extends Component {
|
|
8
|
-
constructor() {
|
|
9
|
-
super();
|
|
10
|
-
this.onDrop = (files) => {
|
|
11
|
-
this.setState({files})
|
|
12
|
-
};
|
|
13
|
-
this.state = {
|
|
14
|
-
files: []
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
render() {
|
|
19
|
-
const files = this.state.files.map(file => (
|
|
20
|
-
<li key={file.name}>
|
|
21
|
-
{file.name} - {file.size} bytes
|
|
22
|
-
</li>
|
|
23
|
-
));
|
|
24
|
-
|
|
25
|
-
return (
|
|
26
|
-
<Dropzone onDrop={this.onDrop}>
|
|
27
|
-
{({getRootProps, getInputProps}) => (
|
|
28
|
-
<section className="container">
|
|
29
|
-
<div {...getRootProps({className: 'dropzone'})}>
|
|
30
|
-
<input {...getInputProps()} />
|
|
31
|
-
<p>Drag 'n' drop some files here, or click to select files</p>
|
|
32
|
-
</div>
|
|
33
|
-
<aside>
|
|
34
|
-
<h4>Files</h4>
|
|
35
|
-
<ul>{files}</ul>
|
|
36
|
-
</aside>
|
|
37
|
-
</section>
|
|
38
|
-
)}
|
|
39
|
-
</Dropzone>
|
|
40
|
-
);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
<Basic />
|
|
45
|
-
```
|