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.
Files changed (47) hide show
  1. package/README.md +3 -3
  2. package/dist/index.cjs +1077 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.js +1046 -2
  5. package/dist/index.js.map +1 -0
  6. package/package.json +62 -161
  7. package/src/{index.js → index.jsx} +10 -7
  8. package/typings/tests/tsconfig.json +12 -11
  9. package/.babelrc.js +0 -28
  10. package/.codeclimate.yml +0 -15
  11. package/.editorconfig +0 -13
  12. package/.eslintignore +0 -3
  13. package/.eslintrc +0 -37
  14. package/.gitpod.yml +0 -6
  15. package/.husky/commit-msg +0 -5
  16. package/.husky/pre-commit +0 -5
  17. package/.nvmrc +0 -1
  18. package/.releaserc.json +0 -27
  19. package/CHANGELOG.md +0 -6
  20. package/commitlint.config.js +0 -1
  21. package/dist/es/index.js +0 -1048
  22. package/dist/es/package.json +0 -1
  23. package/dist/es/utils/index.js +0 -366
  24. package/examples/.eslintrc +0 -5
  25. package/examples/accept/README.md +0 -144
  26. package/examples/basic/README.md +0 -70
  27. package/examples/class-component/README.md +0 -45
  28. package/examples/drag-overlay/README.md +0 -132
  29. package/examples/events/README.md +0 -164
  30. package/examples/file-dialog/README.md +0 -90
  31. package/examples/forms/README.md +0 -69
  32. package/examples/maxFiles/README.md +0 -58
  33. package/examples/no-jsx/README.md +0 -32
  34. package/examples/pintura/README.md +0 -146
  35. package/examples/plugins/README.md +0 -55
  36. package/examples/previews/README.md +0 -86
  37. package/examples/styling/README.md +0 -126
  38. package/examples/theme.css +0 -37
  39. package/examples/validator/README.md +0 -68
  40. package/rollup.config.js +0 -33
  41. package/src/.eslintrc +0 -37
  42. package/src/__snapshots__/index.spec.js.snap +0 -3
  43. package/src/index.spec.js +0 -3777
  44. package/src/utils/index.spec.js +0 -625
  45. package/styleguide.config.js +0 -107
  46. package/testSetup.js +0 -8
  47. package/typings/.eslintrc +0 -28
@@ -1,625 +0,0 @@
1
- beforeEach(() => {
2
- jest.resetModules();
3
- });
4
-
5
- describe("fileMatchSize()", () => {
6
- /**
7
- * @constant
8
- * @type {import('./index')}
9
- */
10
- let utils;
11
- beforeEach(async () => {
12
- utils = await import("./index");
13
- });
14
-
15
- it("should return true if the file object doesn't have a {size} property", () => {
16
- expect(utils.fileMatchSize({})).toEqual([true, null]);
17
- expect(utils.fileMatchSize({ size: null })).toEqual([true, null]);
18
- });
19
-
20
- it("should return true if the minSize and maxSize were not provided", () => {
21
- expect(utils.fileMatchSize({ size: 100 })).toEqual([true, null]);
22
- expect(utils.fileMatchSize({ size: 100 }, undefined, undefined)).toEqual([
23
- true,
24
- null,
25
- ]);
26
- expect(utils.fileMatchSize({ size: 100 }, null, null)).toEqual([
27
- true,
28
- null,
29
- ]);
30
- });
31
-
32
- it("should return true if the file {size} is within the [minSize, maxSize] range", () => {
33
- expect(utils.fileMatchSize({ size: 100 }, 10, 200)).toEqual([true, null]);
34
- expect(utils.fileMatchSize({ size: 100 }, 10, 99)).toEqual([
35
- false,
36
- { code: "file-too-large", message: "File is larger than 99 bytes" },
37
- ]);
38
- expect(utils.fileMatchSize({ size: 100 }, 101, 200)).toEqual([
39
- false,
40
- { code: "file-too-small", message: "File is smaller than 101 bytes" },
41
- ]);
42
- });
43
-
44
- it("should return true if the file {size} is more than minSize", () => {
45
- expect(utils.fileMatchSize({ size: 100 }, 100)).toEqual([true, null]);
46
- expect(utils.fileMatchSize({ size: 100 }, 101)).toEqual([
47
- false,
48
- { code: "file-too-small", message: "File is smaller than 101 bytes" },
49
- ]);
50
- });
51
-
52
- it("should return true if the file {size} is less than maxSize", () => {
53
- expect(utils.fileMatchSize({ size: 100 }, undefined, 100)).toEqual([
54
- true,
55
- null,
56
- ]);
57
- expect(utils.fileMatchSize({ size: 100 }, null, 100)).toEqual([true, null]);
58
- expect(utils.fileMatchSize({ size: 100 }, undefined, 99)).toEqual([
59
- false,
60
- { code: "file-too-large", message: "File is larger than 99 bytes" },
61
- ]);
62
- expect(utils.fileMatchSize({ size: 100 }, null, 99)).toEqual([
63
- false,
64
- { code: "file-too-large", message: "File is larger than 99 bytes" },
65
- ]);
66
- });
67
- });
68
-
69
- describe("isIeOrEdge", () => {
70
- /**
71
- * @constant
72
- * @type {import('./index')}
73
- */
74
- let utils;
75
- beforeEach(async () => {
76
- utils = await import("./index");
77
- });
78
-
79
- it("should return true for IE10", () => {
80
- const userAgent =
81
- "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729)";
82
-
83
- expect(utils.isIeOrEdge(userAgent)).toBe(true);
84
- });
85
-
86
- it("should return true for IE11", () => {
87
- const userAgent =
88
- "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; rv:11.0) like Gecko";
89
- expect(utils.isIeOrEdge(userAgent)).toBe(true);
90
- });
91
-
92
- it("should return true for Edge", () => {
93
- const userAgent =
94
- "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16258";
95
-
96
- expect(utils.isIeOrEdge(userAgent)).toBe(true);
97
- });
98
-
99
- it("should return false for Chrome", () => {
100
- const userAgent =
101
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36";
102
-
103
- expect(utils.isIeOrEdge(userAgent)).toBe(false);
104
- });
105
- });
106
-
107
- describe("isKindFile()", () => {
108
- it('should return true for DataTransferItem of kind "file"', async () => {
109
- /**
110
- * @constant
111
- * @type {import('./index')}
112
- */
113
- const utils = await import("./index");
114
- expect(utils.isKindFile({ kind: "file" })).toBe(true);
115
- expect(utils.isKindFile({ kind: "text/html" })).toBe(false);
116
- expect(utils.isKindFile({})).toBe(false);
117
- expect(utils.isKindFile(null)).toBe(false);
118
- });
119
- });
120
-
121
- describe("isPropagationStopped()", () => {
122
- const trueFn = jest.fn(() => true);
123
-
124
- /**
125
- * @constant
126
- * @type {import('./index')}
127
- */
128
- let utils;
129
- beforeEach(async () => {
130
- utils = await import("./index");
131
- });
132
-
133
- it("should return result of isPropagationStopped() if isPropagationStopped exists", () => {
134
- expect(utils.isPropagationStopped({ isPropagationStopped: trueFn })).toBe(
135
- true
136
- );
137
- });
138
-
139
- it("should return value of cancelBubble if isPropagationStopped doesnt exist and cancelBubble exists", () => {
140
- expect(utils.isPropagationStopped({ cancelBubble: true })).toBe(true);
141
- });
142
-
143
- it("should return false if isPropagationStopped and cancelBubble are missing", () => {
144
- expect(utils.isPropagationStopped({})).toBe(false);
145
- });
146
- });
147
-
148
- describe("isEvtWithFiles()", () => {
149
- /**
150
- * @constant
151
- * @type {import('./index')}
152
- */
153
- let utils;
154
- beforeEach(async () => {
155
- utils = await import("./index");
156
- });
157
-
158
- it("should return true if some dragged types are files", () => {
159
- expect(utils.isEvtWithFiles({ dataTransfer: { types: ["Files"] } })).toBe(
160
- true
161
- );
162
- expect(
163
- utils.isEvtWithFiles({
164
- dataTransfer: { types: ["application/x-moz-file"] },
165
- })
166
- ).toBe(true);
167
- expect(
168
- utils.isEvtWithFiles({
169
- dataTransfer: { types: ["Files", "application/x-moz-file"] },
170
- })
171
- ).toBe(true);
172
- expect(
173
- utils.isEvtWithFiles({ dataTransfer: { types: ["text/plain"] } })
174
- ).toBe(false);
175
- expect(
176
- utils.isEvtWithFiles({ dataTransfer: { types: ["text/html"] } })
177
- ).toBe(false);
178
- expect(
179
- utils.isEvtWithFiles({
180
- dataTransfer: { types: ["Files", "application/test"] },
181
- })
182
- ).toBe(true);
183
- expect(
184
- utils.isEvtWithFiles({
185
- dataTransfer: { types: ["application/x-moz-file", "application/test"] },
186
- })
187
- ).toBe(true);
188
- });
189
-
190
- it("should return true if the event has a target with files", () => {
191
- expect(utils.isEvtWithFiles({ target: { files: [] } })).toBe(true);
192
- });
193
-
194
- it("should return false otherwise", () => {
195
- expect(utils.isEvtWithFiles({})).toBe(false);
196
- });
197
- });
198
-
199
- describe("composeEventHandlers()", () => {
200
- /**
201
- * @constant
202
- * @type {import('./index')}
203
- */
204
- let utils;
205
- beforeEach(async () => {
206
- utils = await import("./index");
207
- });
208
-
209
- it("returns a fn", () => {
210
- const fn = utils.composeEventHandlers(() => {});
211
- expect(typeof fn).toBe("function");
212
- });
213
-
214
- it("runs every passed fn in order", () => {
215
- const fn1 = jest.fn();
216
- const fn2 = jest.fn();
217
- const fn = utils.composeEventHandlers(fn1, fn2);
218
- const event = { type: "click" };
219
- const data = { ping: true };
220
- fn(event, data);
221
- expect(fn1).toHaveBeenCalledWith(event, data);
222
- expect(fn2).toHaveBeenCalledWith(event, data);
223
- });
224
-
225
- it("stops after first fn that calls stopPropagation()", () => {
226
- const fn1 = jest.fn().mockImplementation((event) => {
227
- Object.defineProperty(event, "cancelBubble", { value: true });
228
- return event;
229
- });
230
- const fn2 = jest.fn();
231
- const fn = utils.composeEventHandlers(fn1, fn2);
232
- const event = new MouseEvent("click");
233
- fn(event);
234
- expect(fn1).toHaveBeenCalledWith(event);
235
- expect(fn2).not.toHaveBeenCalled();
236
- });
237
-
238
- it("stops before first fn if bubble is already canceled", () => {
239
- const fn1 = jest.fn();
240
- const fn2 = jest.fn();
241
- const fn = utils.composeEventHandlers(fn1, fn2);
242
- const event = new MouseEvent("click");
243
- Object.defineProperty(event, "cancelBubble", { value: true });
244
- fn(event);
245
- expect(fn1).not.toHaveBeenCalled();
246
- expect(fn2).not.toHaveBeenCalled();
247
- });
248
- });
249
-
250
- describe("fileAccepted()", () => {
251
- /**
252
- * @constant
253
- * @type {import('./index')}
254
- */
255
- let utils;
256
- beforeEach(async () => {
257
- utils = await import("./index");
258
- });
259
-
260
- it("accepts bogus firefox file", () => {
261
- const file = createFile("bogus.png", 100, "application/x-moz-file");
262
- expect(utils.fileAccepted(file, ".pdf")).toEqual([true, null]);
263
- });
264
-
265
- it("accepts DataTransferItem with empty type during drag (Chrome .md file issue)", () => {
266
- // Simulate Chrome's DataTransferItem during drag with empty type
267
- const dataTransferItem = {
268
- type: "",
269
- kind: "file",
270
- getAsFile: () => createFile("README.md", 100, ""),
271
- };
272
- expect(utils.fileAccepted(dataTransferItem, "text/markdown")).toEqual([
273
- true,
274
- null,
275
- ]);
276
- });
277
-
278
- it("rejects regular File with empty type (not DataTransferItem)", () => {
279
- // Regular File objects (on drop) with empty type should still be rejected
280
- const file = createFile("unknown.xyz", 100, "");
281
- expect(utils.fileAccepted(file, "text/markdown")).toEqual([
282
- false,
283
- {
284
- code: "file-invalid-type",
285
- message: "File type must be text/markdown",
286
- },
287
- ]);
288
- });
289
-
290
- it("accepts file when single accept criteria", () => {
291
- const file = createFile("hamster.pdf", 100, "application/pdf");
292
- expect(utils.fileAccepted(file, ".pdf")).toEqual([true, null]);
293
- });
294
-
295
- it("accepts file when multiple accept criteria", () => {
296
- const file = createFile("hamster.pdf", 100, "application/pdf");
297
- expect(utils.fileAccepted(file, ".pdf,.png")).toEqual([true, null]);
298
- });
299
-
300
- it("rejects file when single accept criteria", () => {
301
- const file = createFile("hamster.pdf", 100, "application/pdf");
302
- expect(utils.fileAccepted(file, ".png")).toEqual([
303
- false,
304
- { code: "file-invalid-type", message: "File type must be .png" },
305
- ]);
306
- });
307
-
308
- it("rejects file when multiple accept criteria", () => {
309
- const file = createFile("hamster.pdf", 100, "application/pdf");
310
- expect(utils.fileAccepted(file, ".gif,.png")).toEqual([
311
- false,
312
- {
313
- code: "file-invalid-type",
314
- message: "File type must be one of .gif, .png",
315
- },
316
- ]);
317
- });
318
- });
319
-
320
- describe("getTooLargeRejectionErr()", () => {
321
- /**
322
- * @constant
323
- * @type {import('./index')}
324
- */
325
- let utils;
326
- beforeEach(async () => {
327
- utils = await import("./index");
328
- });
329
-
330
- it("prints byte when maxSize is 1", () => {
331
- expect(utils.getTooLargeRejectionErr(1).message).toEqual(
332
- "File is larger than 1 byte"
333
- );
334
- });
335
-
336
- it("prints bytes when maxSize > 1", () => {
337
- expect(utils.getTooLargeRejectionErr(100).message).toEqual(
338
- "File is larger than 100 bytes"
339
- );
340
- });
341
- });
342
-
343
- describe("getTooSmallRejectionErr()", () => {
344
- /**
345
- * @constant
346
- * @type {import('./index')}
347
- */
348
- let utils;
349
- beforeEach(async () => {
350
- utils = await import("./index");
351
- });
352
-
353
- it("prints byte when minSize is 1", () => {
354
- expect(utils.getTooSmallRejectionErr(1).message).toEqual(
355
- "File is smaller than 1 byte"
356
- );
357
- });
358
-
359
- it("prints bytes when minSize > 1", () => {
360
- expect(utils.getTooSmallRejectionErr(100).message).toEqual(
361
- "File is smaller than 100 bytes"
362
- );
363
- });
364
- });
365
-
366
- describe("allFilesAccepted()", () => {
367
- /**
368
- * @constant
369
- * @type {import('./index')}
370
- */
371
- let utils;
372
- beforeEach(async () => {
373
- utils = await import("./index");
374
- });
375
- it("rejects file when multiple accept criteria", () => {
376
- const files = [
377
- createFile("hamster.pdf", 100, "application/pdf"),
378
- createFile("fish.pdf", 100, "application/pdf"),
379
- ];
380
- const images = [
381
- createFile("cats.gif", 1234, "image/gif"),
382
- createFile("dogs.gif", 2345, "image/jpeg"),
383
- ];
384
- expect(utils.allFilesAccepted({ files, multiple: true })).toEqual(true);
385
- expect(
386
- utils.allFilesAccepted({ files, multiple: true, maxFiles: 10 })
387
- ).toEqual(true);
388
- expect(
389
- utils.allFilesAccepted({ files, multiple: false, maxFiles: 10 })
390
- ).toEqual(false);
391
- expect(
392
- utils.allFilesAccepted({ files, multiple: true, accept: "image/jpeg" })
393
- ).toEqual(false);
394
- expect(
395
- utils.allFilesAccepted({
396
- files: images,
397
- multiple: true,
398
- accept: "image/*",
399
- })
400
- ).toEqual(true);
401
- expect(
402
- utils.allFilesAccepted({ files, multiple: true, minSize: 110 })
403
- ).toEqual(false);
404
- expect(
405
- utils.allFilesAccepted({ files, multiple: true, maxSize: 99 })
406
- ).toEqual(false);
407
- expect(
408
- utils.allFilesAccepted({ files, multiple: true, maxFiles: 1 })
409
- ).toEqual(false);
410
-
411
- expect(
412
- utils.allFilesAccepted({
413
- files,
414
- validator: () => ({ code: "not-allowed", message: "Cannot do this!" }),
415
- })
416
- ).toEqual(false);
417
- });
418
- });
419
-
420
- describe("ErrorCode", () => {
421
- /**
422
- * @constant
423
- * @type {import('./index')}
424
- */
425
- let utils;
426
- beforeEach(async () => {
427
- utils = await import("./index");
428
- });
429
-
430
- it("should exist and have known error code properties", () => {
431
- expect(utils.ErrorCode.FileInvalidType).toEqual(utils.FILE_INVALID_TYPE);
432
- expect(utils.ErrorCode.FileTooLarge).toEqual(utils.FILE_TOO_LARGE);
433
- expect(utils.ErrorCode.FileTooSmall).toEqual(utils.FILE_TOO_SMALL);
434
- expect(utils.ErrorCode.TooManyFiles).toEqual(utils.TOO_MANY_FILES);
435
- });
436
- });
437
-
438
- describe("canUseFileSystemAccessAPI()", () => {
439
- /**
440
- * @constant
441
- * @type {import('./index')}
442
- */
443
- let utils;
444
- beforeEach(async () => {
445
- utils = await import("./index");
446
- });
447
-
448
- it("should return false if not", () => {
449
- expect(utils.canUseFileSystemAccessAPI()).toBe(false);
450
- });
451
-
452
- it("should return true if yes", () => {
453
- // TODO: If we use these in other tests, restore once test is done
454
- window.showOpenFilePicker = jest.fn();
455
- expect(utils.canUseFileSystemAccessAPI()).toBe(true);
456
- });
457
- });
458
-
459
- describe("pickerOptionsFromAccept()", () => {
460
- /**
461
- * @constant
462
- * @type {import('./index')}
463
- */
464
- let utils;
465
- beforeEach(async () => {
466
- utils = await import("./index");
467
- });
468
-
469
- it("converts the {accept} prop to file picker options", () => {
470
- expect(
471
- utils.pickerOptionsFromAccept({
472
- "image/*": [".png", ".jpg"], // ok
473
- "text/*": [".txt", ".pdf"], // ok
474
- "audio/*": ["mp3"], // not ok
475
- "*": [".p12"], // not ok
476
- })
477
- ).toEqual([
478
- {
479
- description: "Files",
480
- accept: {
481
- "image/*": [".png", ".jpg"],
482
- "text/*": [".txt", ".pdf"],
483
- },
484
- },
485
- ]);
486
- });
487
- });
488
-
489
- describe("acceptPropAsAcceptAttr()", () => {
490
- /**
491
- * @constant
492
- * @type {import('./index')}
493
- */
494
- let utils;
495
- beforeEach(async () => {
496
- utils = await import("./index");
497
- });
498
-
499
- it("converts {accept} to an array of strings", () => {
500
- expect(
501
- utils.acceptPropAsAcceptAttr({
502
- "image/*": [".png", ".jpg"],
503
- "text/*": [".txt", ".pdf"],
504
- "audio/*": ["mp3"], // `mp3` not ok
505
- "*": [".p12"], // `*` not ok
506
- })
507
- ).toEqual("image/*,.png,.jpg,text/*,.txt,.pdf,audio/*,.p12");
508
- });
509
- });
510
-
511
- describe("isMIMEType()", () => {
512
- /**
513
- * @constant
514
- * @type {import('./index')}
515
- */
516
- let utils;
517
- beforeEach(async () => {
518
- utils = await import("./index");
519
- });
520
-
521
- it("checks that the value is a valid MIME type string", () => {
522
- expect(utils.isMIMEType("text/html")).toBe(true);
523
- expect(utils.isMIMEType("text/*")).toBe(true);
524
- expect(utils.isMIMEType("image/*")).toBe(true);
525
- expect(utils.isMIMEType("video/*")).toBe(true);
526
- expect(utils.isMIMEType("audio/*")).toBe(true);
527
- expect(utils.isMIMEType("application/*")).toBe(true);
528
- expect(utils.isMIMEType("test/*")).toBe(false);
529
- expect(utils.isMIMEType("text")).toBe(false);
530
- expect(utils.isMIMEType("")).toBe(false);
531
- expect(utils.isMIMEType(undefined)).toBe(false);
532
- });
533
- });
534
-
535
- describe("isExt()", () => {
536
- /**
537
- * @constant
538
- * @type {import('./index')}
539
- */
540
- let utils;
541
- beforeEach(async () => {
542
- utils = await import("./index");
543
- });
544
-
545
- it("checks that the value is a valid file extension", () => {
546
- expect(utils.isExt(".jpg")).toBe(true);
547
- expect(utils.isExt("me.jpg")).toBe(true);
548
- expect(utils.isExt("me.prev.png")).toBe(true);
549
- expect(utils.isExt("")).toBe(false);
550
- expect(utils.isExt("text")).toBe(false);
551
- expect(utils.isExt(undefined)).toBe(false);
552
- });
553
- });
554
-
555
- describe("isAbort()", () => {
556
- /**
557
- * @constant
558
- * @type {import('./index')}
559
- */
560
- let utils;
561
- beforeEach(async () => {
562
- utils = await import("./index");
563
- });
564
-
565
- it("should work as expected", () => {
566
- expect(utils.isAbort(new DOMException())).toBe(false);
567
- expect(utils.isAbort(new DOMException("some err"))).toBe(false);
568
- expect(utils.isAbort(new DOMException("some err", "Noop"))).toBe(false);
569
- expect(utils.isAbort(new DOMException("some err", "AbortError"))).toBe(
570
- true
571
- );
572
- const err = new DOMException("some err");
573
- const e = new Proxy(err, {
574
- get(t, p) {
575
- if (p === "code") {
576
- return 20;
577
- }
578
- return t[p];
579
- },
580
- });
581
- expect(utils.isAbort(e)).toBe(true);
582
- });
583
- });
584
-
585
- describe("isSecurityError()", () => {
586
- /**
587
- * @constant
588
- * @type {import('./index')}
589
- */
590
- let utils;
591
- beforeEach(async () => {
592
- utils = await import("./index");
593
- });
594
-
595
- it("should work as expected", () => {
596
- expect(utils.isSecurityError(new DOMException())).toBe(false);
597
- expect(utils.isSecurityError(new DOMException("some err"))).toBe(false);
598
- expect(utils.isSecurityError(new DOMException("some err", "Noop"))).toBe(
599
- false
600
- );
601
- expect(
602
- utils.isSecurityError(new DOMException("some err", "SecurityError"))
603
- ).toBe(true);
604
- const err = new DOMException("some err");
605
- const e = new Proxy(err, {
606
- get(t, p) {
607
- if (p === "code") {
608
- return 18;
609
- }
610
- return t[p];
611
- },
612
- });
613
- expect(utils.isSecurityError(e)).toBe(true);
614
- });
615
- });
616
-
617
- function createFile(name, size, type) {
618
- const file = new File([], name, { type });
619
- Object.defineProperty(file, "size", {
620
- get() {
621
- return size;
622
- },
623
- });
624
- return file;
625
- }