react-dropzone 11.7.0 → 12.0.2
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/.eslintrc +1 -3
- package/README.md +6 -1
- package/commitlint.config.js +1 -1
- package/dist/es/index.js +55 -43
- package/dist/es/utils/index.js +22 -22
- package/dist/index.js +3 -3
- package/examples/accept/README.md +10 -3
- package/examples/no-jsx/README.md +32 -0
- package/package.json +7 -6
- package/rollup.config.js +20 -20
- package/src/.eslintrc +1 -2
- package/src/index.js +330 -277
- package/src/index.spec.js +1784 -1498
- package/src/utils/index.js +100 -73
- package/src/utils/index.spec.js +386 -289
- package/styleguide.config.js +57 -50
- package/testSetup.js +7 -1
- package/typings/.eslintrc +1 -1
- package/typings/react-dropzone.d.ts +25 -14
- package/typings/tests/accept.tsx +10 -9
- package/typings/tests/all.tsx +7 -5
- package/typings/tests/basic.tsx +8 -7
- package/typings/tests/events.tsx +8 -6
- package/typings/tests/file-dialog.tsx +4 -3
- package/typings/tests/hook.tsx +6 -6
- package/typings/tests/plugin.tsx +11 -22
- package/typings/tests/refs.tsx +4 -4
package/src/index.spec.js
CHANGED
|
@@ -1,24 +1,33 @@
|
|
|
1
1
|
/* eslint react/prop-types: 0, jsx-a11y/label-has-for: 0 */
|
|
2
|
-
import React, { createRef } from
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
import React, { createRef } from "react";
|
|
3
|
+
import {
|
|
4
|
+
act,
|
|
5
|
+
cleanup,
|
|
6
|
+
fireEvent,
|
|
7
|
+
render,
|
|
8
|
+
waitFor,
|
|
9
|
+
} from "@testing-library/react";
|
|
10
|
+
import { renderHook } from "@testing-library/react-hooks";
|
|
11
|
+
import { fromEvent } from "file-selector";
|
|
12
|
+
import * as utils from "./utils";
|
|
13
|
+
import Dropzone, { useDropzone } from "./index";
|
|
14
|
+
|
|
15
|
+
describe("useDropzone() hook", () => {
|
|
16
|
+
let files;
|
|
17
|
+
let images;
|
|
12
18
|
|
|
13
19
|
beforeEach(() => {
|
|
14
|
-
files = [createFile(
|
|
15
|
-
images = [
|
|
16
|
-
|
|
20
|
+
files = [createFile("file1.pdf", 1111, "application/pdf")];
|
|
21
|
+
images = [
|
|
22
|
+
createFile("cats.gif", 1234, "image/gif"),
|
|
23
|
+
createFile("dogs.gif", 2345, "image/jpeg"),
|
|
24
|
+
];
|
|
25
|
+
});
|
|
17
26
|
|
|
18
|
-
afterEach(cleanup)
|
|
27
|
+
afterEach(cleanup);
|
|
19
28
|
|
|
20
|
-
describe(
|
|
21
|
-
it(
|
|
29
|
+
describe("behavior", () => {
|
|
30
|
+
it("renders the root and input nodes with the necessary props", () => {
|
|
22
31
|
const { container } = render(
|
|
23
32
|
<Dropzone>
|
|
24
33
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -27,12 +36,12 @@ describe('useDropzone() hook', () => {
|
|
|
27
36
|
</div>
|
|
28
37
|
)}
|
|
29
38
|
</Dropzone>
|
|
30
|
-
)
|
|
31
|
-
expect(container.innerHTML).toMatchSnapshot()
|
|
32
|
-
})
|
|
39
|
+
);
|
|
40
|
+
expect(container.innerHTML).toMatchSnapshot();
|
|
41
|
+
});
|
|
33
42
|
|
|
34
|
-
it(
|
|
35
|
-
const accept =
|
|
43
|
+
it("sets {accept} prop on the <input>", () => {
|
|
44
|
+
const accept = "image/jpeg";
|
|
36
45
|
const { container } = render(
|
|
37
46
|
<Dropzone accept={accept}>
|
|
38
47
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -41,14 +50,14 @@ describe('useDropzone() hook', () => {
|
|
|
41
50
|
</div>
|
|
42
51
|
)}
|
|
43
52
|
</Dropzone>
|
|
44
|
-
)
|
|
53
|
+
);
|
|
45
54
|
|
|
46
|
-
const input = container.querySelector(
|
|
55
|
+
const input = container.querySelector("input");
|
|
47
56
|
|
|
48
|
-
expect(input).toHaveAttribute(
|
|
49
|
-
})
|
|
57
|
+
expect(input).toHaveAttribute("accept", accept);
|
|
58
|
+
});
|
|
50
59
|
|
|
51
|
-
it(
|
|
60
|
+
it("updates {multiple} prop on the <input> when it changes", () => {
|
|
52
61
|
const { container, rerender } = render(
|
|
53
62
|
<Dropzone accept="image/jpeg">
|
|
54
63
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -57,9 +66,12 @@ describe('useDropzone() hook', () => {
|
|
|
57
66
|
</div>
|
|
58
67
|
)}
|
|
59
68
|
</Dropzone>
|
|
60
|
-
)
|
|
69
|
+
);
|
|
61
70
|
|
|
62
|
-
expect(container.querySelector(
|
|
71
|
+
expect(container.querySelector("input")).toHaveAttribute(
|
|
72
|
+
"accept",
|
|
73
|
+
"image/jpeg"
|
|
74
|
+
);
|
|
63
75
|
|
|
64
76
|
rerender(
|
|
65
77
|
<Dropzone accept="image/png">
|
|
@@ -69,12 +81,15 @@ describe('useDropzone() hook', () => {
|
|
|
69
81
|
</div>
|
|
70
82
|
)}
|
|
71
83
|
</Dropzone>
|
|
72
|
-
)
|
|
84
|
+
);
|
|
73
85
|
|
|
74
|
-
expect(container.querySelector(
|
|
75
|
-
|
|
86
|
+
expect(container.querySelector("input")).toHaveAttribute(
|
|
87
|
+
"accept",
|
|
88
|
+
"image/png"
|
|
89
|
+
);
|
|
90
|
+
});
|
|
76
91
|
|
|
77
|
-
it(
|
|
92
|
+
it("sets {multiple} prop on the <input>", () => {
|
|
78
93
|
const { container } = render(
|
|
79
94
|
<Dropzone multiple>
|
|
80
95
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -83,13 +98,13 @@ describe('useDropzone() hook', () => {
|
|
|
83
98
|
</div>
|
|
84
99
|
)}
|
|
85
100
|
</Dropzone>
|
|
86
|
-
)
|
|
101
|
+
);
|
|
87
102
|
|
|
88
|
-
const input = container.querySelector(
|
|
89
|
-
expect(input).toHaveAttribute(
|
|
90
|
-
})
|
|
103
|
+
const input = container.querySelector("input");
|
|
104
|
+
expect(input).toHaveAttribute("multiple");
|
|
105
|
+
});
|
|
91
106
|
|
|
92
|
-
it(
|
|
107
|
+
it("updates {multiple} prop on the <input> when it changes", () => {
|
|
93
108
|
const { container, rerender } = render(
|
|
94
109
|
<Dropzone multiple={false}>
|
|
95
110
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -98,9 +113,9 @@ describe('useDropzone() hook', () => {
|
|
|
98
113
|
</div>
|
|
99
114
|
)}
|
|
100
115
|
</Dropzone>
|
|
101
|
-
)
|
|
116
|
+
);
|
|
102
117
|
|
|
103
|
-
expect(container.querySelector(
|
|
118
|
+
expect(container.querySelector("input")).not.toHaveAttribute("multiple");
|
|
104
119
|
|
|
105
120
|
rerender(
|
|
106
121
|
<Dropzone multiple>
|
|
@@ -110,13 +125,13 @@ describe('useDropzone() hook', () => {
|
|
|
110
125
|
</div>
|
|
111
126
|
)}
|
|
112
127
|
</Dropzone>
|
|
113
|
-
)
|
|
128
|
+
);
|
|
114
129
|
|
|
115
|
-
expect(container.querySelector(
|
|
116
|
-
})
|
|
130
|
+
expect(container.querySelector("input")).toHaveAttribute("multiple");
|
|
131
|
+
});
|
|
117
132
|
|
|
118
|
-
it(
|
|
119
|
-
const name =
|
|
133
|
+
it("sets any props passed to the input props getter on the <input>", () => {
|
|
134
|
+
const name = "dropzone-input";
|
|
120
135
|
const { container } = render(
|
|
121
136
|
<Dropzone multiple>
|
|
122
137
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -125,31 +140,31 @@ describe('useDropzone() hook', () => {
|
|
|
125
140
|
</div>
|
|
126
141
|
)}
|
|
127
142
|
</Dropzone>
|
|
128
|
-
)
|
|
143
|
+
);
|
|
129
144
|
|
|
130
|
-
const input = container.querySelector(
|
|
131
|
-
expect(input).toHaveAttribute(
|
|
132
|
-
})
|
|
145
|
+
const input = container.querySelector("input");
|
|
146
|
+
expect(input).toHaveAttribute("name", name);
|
|
147
|
+
});
|
|
133
148
|
|
|
134
|
-
it(
|
|
135
|
-
const ariaLabel =
|
|
149
|
+
it("sets any props passed to the root props getter on the root node", () => {
|
|
150
|
+
const ariaLabel = "Dropzone area";
|
|
136
151
|
const { container } = render(
|
|
137
152
|
<Dropzone multiple>
|
|
138
153
|
{({ getRootProps, getInputProps }) => (
|
|
139
|
-
<div {...getRootProps({
|
|
154
|
+
<div {...getRootProps({ "aria-label": ariaLabel })}>
|
|
140
155
|
<input {...getInputProps()} />
|
|
141
156
|
</div>
|
|
142
157
|
)}
|
|
143
158
|
</Dropzone>
|
|
144
|
-
)
|
|
159
|
+
);
|
|
145
160
|
|
|
146
|
-
const dropzone = container.querySelector(
|
|
161
|
+
const dropzone = container.querySelector("div");
|
|
147
162
|
|
|
148
|
-
expect(dropzone).toHaveAttribute(
|
|
149
|
-
})
|
|
163
|
+
expect(dropzone).toHaveAttribute("aria-label", ariaLabel);
|
|
164
|
+
});
|
|
150
165
|
|
|
151
|
-
it(
|
|
152
|
-
const event = createDtWithFiles(files)
|
|
166
|
+
it("runs the custom callback handlers provided to the root props getter", async () => {
|
|
167
|
+
const event = createDtWithFiles(files);
|
|
153
168
|
|
|
154
169
|
const rootProps = {
|
|
155
170
|
onClick: jest.fn(),
|
|
@@ -159,8 +174,8 @@ describe('useDropzone() hook', () => {
|
|
|
159
174
|
onDragEnter: jest.fn(),
|
|
160
175
|
onDragOver: jest.fn(),
|
|
161
176
|
onDragLeave: jest.fn(),
|
|
162
|
-
onDrop: jest.fn()
|
|
163
|
-
}
|
|
177
|
+
onDrop: jest.fn(),
|
|
178
|
+
};
|
|
164
179
|
|
|
165
180
|
const ui = (
|
|
166
181
|
<Dropzone>
|
|
@@ -170,43 +185,43 @@ describe('useDropzone() hook', () => {
|
|
|
170
185
|
</div>
|
|
171
186
|
)}
|
|
172
187
|
</Dropzone>
|
|
173
|
-
)
|
|
188
|
+
);
|
|
174
189
|
|
|
175
|
-
const { container, rerender } = render(ui)
|
|
190
|
+
const { container, rerender } = render(ui);
|
|
176
191
|
|
|
177
|
-
const dropzone = container.querySelector(
|
|
192
|
+
const dropzone = container.querySelector("div");
|
|
178
193
|
|
|
179
|
-
fireEvent.click(dropzone)
|
|
180
|
-
expect(rootProps.onClick).toHaveBeenCalled()
|
|
194
|
+
fireEvent.click(dropzone);
|
|
195
|
+
expect(rootProps.onClick).toHaveBeenCalled();
|
|
181
196
|
|
|
182
|
-
fireEvent.focus(dropzone)
|
|
183
|
-
fireEvent.keyDown(dropzone)
|
|
184
|
-
expect(rootProps.onFocus).toHaveBeenCalled()
|
|
185
|
-
expect(rootProps.onKeyDown).toHaveBeenCalled()
|
|
197
|
+
fireEvent.focus(dropzone);
|
|
198
|
+
fireEvent.keyDown(dropzone);
|
|
199
|
+
expect(rootProps.onFocus).toHaveBeenCalled();
|
|
200
|
+
expect(rootProps.onKeyDown).toHaveBeenCalled();
|
|
186
201
|
|
|
187
|
-
fireEvent.blur(dropzone)
|
|
188
|
-
expect(rootProps.onBlur).toHaveBeenCalled()
|
|
202
|
+
fireEvent.blur(dropzone);
|
|
203
|
+
expect(rootProps.onBlur).toHaveBeenCalled();
|
|
189
204
|
|
|
190
|
-
fireEvent.dragEnter(dropzone, event)
|
|
191
|
-
await flushPromises(rerender, ui)
|
|
192
|
-
expect(rootProps.onDragEnter).toHaveBeenCalled()
|
|
205
|
+
fireEvent.dragEnter(dropzone, event);
|
|
206
|
+
await flushPromises(rerender, ui);
|
|
207
|
+
expect(rootProps.onDragEnter).toHaveBeenCalled();
|
|
193
208
|
|
|
194
|
-
fireEvent.dragOver(dropzone, event)
|
|
195
|
-
expect(rootProps.onDragOver).toHaveBeenCalled()
|
|
209
|
+
fireEvent.dragOver(dropzone, event);
|
|
210
|
+
expect(rootProps.onDragOver).toHaveBeenCalled();
|
|
196
211
|
|
|
197
|
-
fireEvent.dragLeave(dropzone, event)
|
|
198
|
-
expect(rootProps.onDragLeave).toHaveBeenCalled()
|
|
212
|
+
fireEvent.dragLeave(dropzone, event);
|
|
213
|
+
expect(rootProps.onDragLeave).toHaveBeenCalled();
|
|
199
214
|
|
|
200
|
-
fireEvent.drop(dropzone, event)
|
|
201
|
-
await flushPromises(rerender, ui)
|
|
202
|
-
expect(rootProps.onDrop).toHaveBeenCalled()
|
|
203
|
-
})
|
|
215
|
+
fireEvent.drop(dropzone, event);
|
|
216
|
+
await flushPromises(rerender, ui);
|
|
217
|
+
expect(rootProps.onDrop).toHaveBeenCalled();
|
|
218
|
+
});
|
|
204
219
|
|
|
205
|
-
it(
|
|
220
|
+
it("runs the custom callback handlers provided to the input props getter", async () => {
|
|
206
221
|
const inputProps = {
|
|
207
222
|
onClick: jest.fn(),
|
|
208
|
-
onChange: jest.fn()
|
|
209
|
-
}
|
|
223
|
+
onChange: jest.fn(),
|
|
224
|
+
};
|
|
210
225
|
|
|
211
226
|
const ui = (
|
|
212
227
|
<Dropzone>
|
|
@@ -216,23 +231,23 @@ describe('useDropzone() hook', () => {
|
|
|
216
231
|
</div>
|
|
217
232
|
)}
|
|
218
233
|
</Dropzone>
|
|
219
|
-
)
|
|
234
|
+
);
|
|
220
235
|
|
|
221
|
-
const { container, rerender } = render(ui)
|
|
236
|
+
const { container, rerender } = render(ui);
|
|
222
237
|
|
|
223
|
-
const input = container.querySelector(
|
|
238
|
+
const input = container.querySelector("input");
|
|
224
239
|
|
|
225
|
-
fireEvent.click(input)
|
|
226
|
-
await flushPromises(rerender, ui)
|
|
227
|
-
expect(inputProps.onClick).toHaveBeenCalled()
|
|
240
|
+
fireEvent.click(input);
|
|
241
|
+
await flushPromises(rerender, ui);
|
|
242
|
+
expect(inputProps.onClick).toHaveBeenCalled();
|
|
228
243
|
|
|
229
|
-
fireEvent.change(input)
|
|
230
|
-
await flushPromises(rerender, ui)
|
|
231
|
-
expect(inputProps.onChange).toHaveBeenCalled()
|
|
232
|
-
})
|
|
244
|
+
fireEvent.change(input);
|
|
245
|
+
await flushPromises(rerender, ui);
|
|
246
|
+
expect(inputProps.onChange).toHaveBeenCalled();
|
|
247
|
+
});
|
|
233
248
|
|
|
234
|
-
it(
|
|
235
|
-
const event = createDtWithFiles(files)
|
|
249
|
+
it("runs no callback handlers if {disabled} is true", () => {
|
|
250
|
+
const event = createDtWithFiles(files);
|
|
236
251
|
|
|
237
252
|
const rootProps = {
|
|
238
253
|
onClick: jest.fn(),
|
|
@@ -242,13 +257,13 @@ describe('useDropzone() hook', () => {
|
|
|
242
257
|
onDragEnter: jest.fn(),
|
|
243
258
|
onDragOver: jest.fn(),
|
|
244
259
|
onDragLeave: jest.fn(),
|
|
245
|
-
onDrop: jest.fn()
|
|
246
|
-
}
|
|
260
|
+
onDrop: jest.fn(),
|
|
261
|
+
};
|
|
247
262
|
|
|
248
263
|
const inputProps = {
|
|
249
264
|
onClick: jest.fn(),
|
|
250
|
-
onChange: jest.fn()
|
|
251
|
-
}
|
|
265
|
+
onChange: jest.fn(),
|
|
266
|
+
};
|
|
252
267
|
|
|
253
268
|
const { container } = render(
|
|
254
269
|
<Dropzone disabled>
|
|
@@ -258,59 +273,59 @@ describe('useDropzone() hook', () => {
|
|
|
258
273
|
</div>
|
|
259
274
|
)}
|
|
260
275
|
</Dropzone>
|
|
261
|
-
)
|
|
276
|
+
);
|
|
262
277
|
|
|
263
|
-
const dropzone = container.querySelector(
|
|
278
|
+
const dropzone = container.querySelector("div");
|
|
264
279
|
|
|
265
|
-
fireEvent.click(dropzone)
|
|
266
|
-
expect(rootProps.onClick).not.toHaveBeenCalled()
|
|
280
|
+
fireEvent.click(dropzone);
|
|
281
|
+
expect(rootProps.onClick).not.toHaveBeenCalled();
|
|
267
282
|
|
|
268
|
-
fireEvent.focus(dropzone)
|
|
269
|
-
fireEvent.keyDown(dropzone)
|
|
270
|
-
expect(rootProps.onFocus).not.toHaveBeenCalled()
|
|
271
|
-
expect(rootProps.onKeyDown).not.toHaveBeenCalled()
|
|
283
|
+
fireEvent.focus(dropzone);
|
|
284
|
+
fireEvent.keyDown(dropzone);
|
|
285
|
+
expect(rootProps.onFocus).not.toHaveBeenCalled();
|
|
286
|
+
expect(rootProps.onKeyDown).not.toHaveBeenCalled();
|
|
272
287
|
|
|
273
|
-
fireEvent.blur(dropzone)
|
|
274
|
-
expect(rootProps.onBlur).not.toHaveBeenCalled()
|
|
288
|
+
fireEvent.blur(dropzone);
|
|
289
|
+
expect(rootProps.onBlur).not.toHaveBeenCalled();
|
|
275
290
|
|
|
276
|
-
fireEvent.dragEnter(dropzone, event)
|
|
277
|
-
expect(rootProps.onDragEnter).not.toHaveBeenCalled()
|
|
291
|
+
fireEvent.dragEnter(dropzone, event);
|
|
292
|
+
expect(rootProps.onDragEnter).not.toHaveBeenCalled();
|
|
278
293
|
|
|
279
|
-
fireEvent.dragOver(dropzone, event)
|
|
280
|
-
expect(rootProps.onDragOver).not.toHaveBeenCalled()
|
|
294
|
+
fireEvent.dragOver(dropzone, event);
|
|
295
|
+
expect(rootProps.onDragOver).not.toHaveBeenCalled();
|
|
281
296
|
|
|
282
|
-
fireEvent.dragLeave(dropzone, event)
|
|
283
|
-
expect(rootProps.onDragLeave).not.toHaveBeenCalled()
|
|
297
|
+
fireEvent.dragLeave(dropzone, event);
|
|
298
|
+
expect(rootProps.onDragLeave).not.toHaveBeenCalled();
|
|
284
299
|
|
|
285
|
-
fireEvent.drop(dropzone, event)
|
|
286
|
-
expect(rootProps.onDrop).not.toHaveBeenCalled()
|
|
300
|
+
fireEvent.drop(dropzone, event);
|
|
301
|
+
expect(rootProps.onDrop).not.toHaveBeenCalled();
|
|
287
302
|
|
|
288
|
-
const input = container.querySelector(
|
|
303
|
+
const input = container.querySelector("input");
|
|
289
304
|
|
|
290
|
-
fireEvent.click(input)
|
|
291
|
-
expect(inputProps.onClick).not.toHaveBeenCalled()
|
|
305
|
+
fireEvent.click(input);
|
|
306
|
+
expect(inputProps.onClick).not.toHaveBeenCalled();
|
|
292
307
|
|
|
293
|
-
fireEvent.change(input)
|
|
294
|
-
expect(inputProps.onChange).not.toHaveBeenCalled()
|
|
295
|
-
})
|
|
308
|
+
fireEvent.change(input);
|
|
309
|
+
expect(inputProps.onChange).not.toHaveBeenCalled();
|
|
310
|
+
});
|
|
296
311
|
|
|
297
|
-
test(
|
|
298
|
-
const { result } = renderHook(() => useDropzone())
|
|
299
|
-
const { rootRef, inputRef, getRootProps, getInputProps } = result.current
|
|
312
|
+
test("{rootRef, inputRef} are exposed", () => {
|
|
313
|
+
const { result } = renderHook(() => useDropzone());
|
|
314
|
+
const { rootRef, inputRef, getRootProps, getInputProps } = result.current;
|
|
300
315
|
|
|
301
316
|
const { container } = render(
|
|
302
317
|
<div {...getRootProps()}>
|
|
303
318
|
<input {...getInputProps()} />
|
|
304
319
|
</div>
|
|
305
|
-
)
|
|
320
|
+
);
|
|
306
321
|
|
|
307
|
-
expect(container.querySelector(
|
|
308
|
-
expect(container.querySelector(
|
|
309
|
-
})
|
|
322
|
+
expect(container.querySelector("div")).toEqual(rootRef.current);
|
|
323
|
+
expect(container.querySelector("input")).toEqual(inputRef.current);
|
|
324
|
+
});
|
|
310
325
|
|
|
311
|
-
test(
|
|
312
|
-
const dropzoneRef = createRef()
|
|
313
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
326
|
+
test("<Dropzone> exposes and sets the ref if using a ref object", () => {
|
|
327
|
+
const dropzoneRef = createRef();
|
|
328
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
314
329
|
|
|
315
330
|
const ui = (
|
|
316
331
|
<Dropzone ref={dropzoneRef}>
|
|
@@ -321,25 +336,25 @@ describe('useDropzone() hook', () => {
|
|
|
321
336
|
</div>
|
|
322
337
|
)}
|
|
323
338
|
</Dropzone>
|
|
324
|
-
)
|
|
339
|
+
);
|
|
325
340
|
|
|
326
|
-
const { rerender } = render(ui)
|
|
341
|
+
const { rerender } = render(ui);
|
|
327
342
|
|
|
328
|
-
expect(dropzoneRef.current).not.toBeNull()
|
|
329
|
-
expect(typeof dropzoneRef.current.open).toEqual(
|
|
343
|
+
expect(dropzoneRef.current).not.toBeNull();
|
|
344
|
+
expect(typeof dropzoneRef.current.open).toEqual("function");
|
|
330
345
|
|
|
331
|
-
act(() => dropzoneRef.current.open())
|
|
332
|
-
expect(onClickSpy).toHaveBeenCalled()
|
|
346
|
+
act(() => dropzoneRef.current.open());
|
|
347
|
+
expect(onClickSpy).toHaveBeenCalled();
|
|
333
348
|
|
|
334
|
-
rerender(null)
|
|
349
|
+
rerender(null);
|
|
335
350
|
|
|
336
|
-
expect(dropzoneRef.current).toBeNull()
|
|
337
|
-
})
|
|
351
|
+
expect(dropzoneRef.current).toBeNull();
|
|
352
|
+
});
|
|
338
353
|
|
|
339
|
-
test(
|
|
340
|
-
let dropzoneRef
|
|
341
|
-
const setRef = ref => (dropzoneRef = ref)
|
|
342
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
354
|
+
test("<Dropzone> exposes and sets the ref if using a ref fn", () => {
|
|
355
|
+
let dropzoneRef;
|
|
356
|
+
const setRef = (ref) => (dropzoneRef = ref);
|
|
357
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
343
358
|
|
|
344
359
|
const ui = (
|
|
345
360
|
<Dropzone ref={setRef}>
|
|
@@ -350,22 +365,22 @@ describe('useDropzone() hook', () => {
|
|
|
350
365
|
</div>
|
|
351
366
|
)}
|
|
352
367
|
</Dropzone>
|
|
353
|
-
)
|
|
368
|
+
);
|
|
354
369
|
|
|
355
|
-
const { rerender } = render(ui)
|
|
370
|
+
const { rerender } = render(ui);
|
|
356
371
|
|
|
357
|
-
expect(dropzoneRef).not.toBeNull()
|
|
358
|
-
expect(typeof dropzoneRef.open).toEqual(
|
|
372
|
+
expect(dropzoneRef).not.toBeNull();
|
|
373
|
+
expect(typeof dropzoneRef.open).toEqual("function");
|
|
359
374
|
|
|
360
|
-
act(() => dropzoneRef.open())
|
|
361
|
-
expect(onClickSpy).toHaveBeenCalled()
|
|
375
|
+
act(() => dropzoneRef.open());
|
|
376
|
+
expect(onClickSpy).toHaveBeenCalled();
|
|
362
377
|
|
|
363
|
-
rerender(null)
|
|
364
|
-
expect(dropzoneRef).toBeNull()
|
|
365
|
-
})
|
|
378
|
+
rerender(null);
|
|
379
|
+
expect(dropzoneRef).toBeNull();
|
|
380
|
+
});
|
|
366
381
|
|
|
367
382
|
test("<Dropzone> doesn't invoke the ref fn if it hasn't changed", () => {
|
|
368
|
-
const setRef = jest.fn()
|
|
383
|
+
const setRef = jest.fn();
|
|
369
384
|
|
|
370
385
|
const { rerender } = render(
|
|
371
386
|
<Dropzone ref={setRef}>
|
|
@@ -375,16 +390,18 @@ describe('useDropzone() hook', () => {
|
|
|
375
390
|
</div>
|
|
376
391
|
)}
|
|
377
392
|
</Dropzone>
|
|
378
|
-
)
|
|
393
|
+
);
|
|
379
394
|
|
|
380
395
|
rerender(
|
|
381
|
-
<Dropzone ref={setRef}>
|
|
382
|
-
|
|
396
|
+
<Dropzone ref={setRef}>
|
|
397
|
+
{({ getRootProps }) => <div {...getRootProps()} />}
|
|
398
|
+
</Dropzone>
|
|
399
|
+
);
|
|
383
400
|
|
|
384
|
-
expect(setRef).toHaveBeenCalledTimes(1)
|
|
385
|
-
})
|
|
401
|
+
expect(setRef).toHaveBeenCalledTimes(1);
|
|
402
|
+
});
|
|
386
403
|
|
|
387
|
-
it(
|
|
404
|
+
it("sets {isFocused} to false if {disabled} is true", () => {
|
|
388
405
|
const { container, rerender } = render(
|
|
389
406
|
<Dropzone>
|
|
390
407
|
{({ getRootProps, getInputProps, isFocused }) => (
|
|
@@ -394,12 +411,12 @@ describe('useDropzone() hook', () => {
|
|
|
394
411
|
</div>
|
|
395
412
|
)}
|
|
396
413
|
</Dropzone>
|
|
397
|
-
)
|
|
414
|
+
);
|
|
398
415
|
|
|
399
|
-
const dropzone = container.querySelector(
|
|
416
|
+
const dropzone = container.querySelector("div");
|
|
400
417
|
|
|
401
|
-
fireEvent.focus(dropzone)
|
|
402
|
-
expect(dropzone.querySelector(
|
|
418
|
+
fireEvent.focus(dropzone);
|
|
419
|
+
expect(dropzone.querySelector("#focus")).not.toBeNull();
|
|
403
420
|
|
|
404
421
|
rerender(
|
|
405
422
|
<Dropzone disabled>
|
|
@@ -410,12 +427,12 @@ describe('useDropzone() hook', () => {
|
|
|
410
427
|
</div>
|
|
411
428
|
)}
|
|
412
429
|
</Dropzone>
|
|
413
|
-
)
|
|
430
|
+
);
|
|
414
431
|
|
|
415
|
-
expect(dropzone.querySelector(
|
|
416
|
-
})
|
|
432
|
+
expect(dropzone.querySelector("#focus")).toBeNull();
|
|
433
|
+
});
|
|
417
434
|
|
|
418
|
-
test(
|
|
435
|
+
test("{tabindex} is 0 if {disabled} is false", () => {
|
|
419
436
|
const { container } = render(
|
|
420
437
|
<Dropzone>
|
|
421
438
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -424,11 +441,11 @@ describe('useDropzone() hook', () => {
|
|
|
424
441
|
</div>
|
|
425
442
|
)}
|
|
426
443
|
</Dropzone>
|
|
427
|
-
)
|
|
428
|
-
expect(container.querySelector(
|
|
429
|
-
})
|
|
444
|
+
);
|
|
445
|
+
expect(container.querySelector("div")).toHaveAttribute("tabindex", "0");
|
|
446
|
+
});
|
|
430
447
|
|
|
431
|
-
test(
|
|
448
|
+
test("{tabindex} is not set if {disabled} is true", () => {
|
|
432
449
|
const { container, rerender } = render(
|
|
433
450
|
<Dropzone>
|
|
434
451
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -437,9 +454,9 @@ describe('useDropzone() hook', () => {
|
|
|
437
454
|
</div>
|
|
438
455
|
)}
|
|
439
456
|
</Dropzone>
|
|
440
|
-
)
|
|
457
|
+
);
|
|
441
458
|
|
|
442
|
-
expect(container.querySelector(
|
|
459
|
+
expect(container.querySelector("div")).toHaveAttribute("tabindex", "0");
|
|
443
460
|
|
|
444
461
|
rerender(
|
|
445
462
|
<Dropzone disabled>
|
|
@@ -449,12 +466,12 @@ describe('useDropzone() hook', () => {
|
|
|
449
466
|
</div>
|
|
450
467
|
)}
|
|
451
468
|
</Dropzone>
|
|
452
|
-
)
|
|
469
|
+
);
|
|
453
470
|
|
|
454
|
-
expect(container.querySelector(
|
|
455
|
-
})
|
|
471
|
+
expect(container.querySelector("div")).not.toHaveAttribute("tabindex");
|
|
472
|
+
});
|
|
456
473
|
|
|
457
|
-
test(
|
|
474
|
+
test("{tabindex} is not set if {noKeyboard} is true", () => {
|
|
458
475
|
const { container, rerender } = render(
|
|
459
476
|
<Dropzone>
|
|
460
477
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -463,9 +480,9 @@ describe('useDropzone() hook', () => {
|
|
|
463
480
|
</div>
|
|
464
481
|
)}
|
|
465
482
|
</Dropzone>
|
|
466
|
-
)
|
|
483
|
+
);
|
|
467
484
|
|
|
468
|
-
expect(container.querySelector(
|
|
485
|
+
expect(container.querySelector("div")).toHaveAttribute("tabindex", "0");
|
|
469
486
|
|
|
470
487
|
rerender(
|
|
471
488
|
<Dropzone noKeyboard>
|
|
@@ -475,51 +492,51 @@ describe('useDropzone() hook', () => {
|
|
|
475
492
|
</div>
|
|
476
493
|
)}
|
|
477
494
|
</Dropzone>
|
|
478
|
-
)
|
|
495
|
+
);
|
|
479
496
|
|
|
480
|
-
expect(container.querySelector(
|
|
481
|
-
})
|
|
497
|
+
expect(container.querySelector("div")).not.toHaveAttribute("tabindex");
|
|
498
|
+
});
|
|
482
499
|
|
|
483
|
-
test(
|
|
484
|
-
const data = createDtWithFiles(files)
|
|
500
|
+
test("refs are set when {refKey} is set to a different value", (done) => {
|
|
501
|
+
const data = createDtWithFiles(files);
|
|
485
502
|
|
|
486
503
|
class MyView extends React.Component {
|
|
487
504
|
render() {
|
|
488
|
-
const { children, innerRef, ...rest } = this.props
|
|
505
|
+
const { children, innerRef, ...rest } = this.props;
|
|
489
506
|
return (
|
|
490
507
|
<div id="dropzone" ref={innerRef} {...rest}>
|
|
491
508
|
<div>{children}</div>
|
|
492
509
|
</div>
|
|
493
|
-
)
|
|
510
|
+
);
|
|
494
511
|
}
|
|
495
512
|
}
|
|
496
513
|
|
|
497
514
|
const ui = (
|
|
498
515
|
<Dropzone>
|
|
499
516
|
{({ getRootProps }) => (
|
|
500
|
-
<MyView {...getRootProps({ refKey:
|
|
517
|
+
<MyView {...getRootProps({ refKey: "innerRef" })}>
|
|
501
518
|
<span>Drop some files here ...</span>
|
|
502
519
|
</MyView>
|
|
503
520
|
)}
|
|
504
521
|
</Dropzone>
|
|
505
|
-
)
|
|
522
|
+
);
|
|
506
523
|
|
|
507
|
-
const { container, rerender } = render(ui)
|
|
508
|
-
const dropzone = container.querySelector(
|
|
524
|
+
const { container, rerender } = render(ui);
|
|
525
|
+
const dropzone = container.querySelector("#dropzone");
|
|
509
526
|
|
|
510
527
|
const fn = async () => {
|
|
511
|
-
fireDrop(dropzone, data)
|
|
512
|
-
await flushPromises(rerender, ui)
|
|
513
|
-
done()
|
|
514
|
-
}
|
|
528
|
+
fireDrop(dropzone, data);
|
|
529
|
+
await flushPromises(rerender, ui);
|
|
530
|
+
done();
|
|
531
|
+
};
|
|
515
532
|
|
|
516
|
-
expect(fn).not.toThrow()
|
|
517
|
-
})
|
|
533
|
+
expect(fn).not.toThrow();
|
|
534
|
+
});
|
|
518
535
|
|
|
519
|
-
test(
|
|
520
|
-
const activeRef = createRef()
|
|
521
|
-
const active = <span ref={activeRef}>I am active</span
|
|
522
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
536
|
+
test("click events originating from <label> should not trigger file dialog open twice", () => {
|
|
537
|
+
const activeRef = createRef();
|
|
538
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
539
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
523
540
|
|
|
524
541
|
const { container } = render(
|
|
525
542
|
<Dropzone>
|
|
@@ -530,35 +547,35 @@ describe('useDropzone() hook', () => {
|
|
|
530
547
|
</label>
|
|
531
548
|
)}
|
|
532
549
|
</Dropzone>
|
|
533
|
-
)
|
|
550
|
+
);
|
|
534
551
|
|
|
535
|
-
const dropzone = container.querySelector(
|
|
552
|
+
const dropzone = container.querySelector("label");
|
|
536
553
|
|
|
537
|
-
const event = new Event(
|
|
554
|
+
const event = new Event("click", { bubbles: true, cancelable: true });
|
|
538
555
|
|
|
539
|
-
fireEvent(dropzone, event)
|
|
556
|
+
fireEvent(dropzone, event);
|
|
540
557
|
|
|
541
|
-
const ref = activeRef.current
|
|
542
|
-
expect(ref).not.toBeNull()
|
|
543
|
-
expect(dropzone).toContainElement(ref)
|
|
544
|
-
expect(onClickSpy).toHaveBeenCalledTimes(1)
|
|
545
|
-
})
|
|
546
|
-
})
|
|
558
|
+
const ref = activeRef.current;
|
|
559
|
+
expect(ref).not.toBeNull();
|
|
560
|
+
expect(dropzone).toContainElement(ref);
|
|
561
|
+
expect(onClickSpy).toHaveBeenCalledTimes(1);
|
|
562
|
+
});
|
|
563
|
+
});
|
|
547
564
|
|
|
548
|
-
describe(
|
|
549
|
-
const addEventListenerSpy = jest.spyOn(document,
|
|
550
|
-
const removeEventListenerSpy = jest.spyOn(document,
|
|
565
|
+
describe("document drop protection", () => {
|
|
566
|
+
const addEventListenerSpy = jest.spyOn(document, "addEventListener");
|
|
567
|
+
const removeEventListenerSpy = jest.spyOn(document, "removeEventListener");
|
|
551
568
|
// Collect the list of addEventListener/removeEventListener spy calls into an object keyed by event name
|
|
552
|
-
const collectEventListenerCalls = spy =>
|
|
569
|
+
const collectEventListenerCalls = (spy) =>
|
|
553
570
|
spy.mock.calls.reduce(
|
|
554
571
|
(acc, [eventName, ...rest]) => ({
|
|
555
572
|
...acc,
|
|
556
|
-
[eventName]: rest
|
|
573
|
+
[eventName]: rest,
|
|
557
574
|
}),
|
|
558
575
|
{}
|
|
559
|
-
)
|
|
576
|
+
);
|
|
560
577
|
|
|
561
|
-
it(
|
|
578
|
+
it("installs hooks to prevent stray drops from taking over the browser window", () => {
|
|
562
579
|
render(
|
|
563
580
|
<Dropzone>
|
|
564
581
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -567,24 +584,24 @@ describe('useDropzone() hook', () => {
|
|
|
567
584
|
</div>
|
|
568
585
|
)}
|
|
569
586
|
</Dropzone>
|
|
570
|
-
)
|
|
587
|
+
);
|
|
571
588
|
|
|
572
|
-
expect(addEventListenerSpy).toHaveBeenCalledTimes(2)
|
|
589
|
+
expect(addEventListenerSpy).toHaveBeenCalledTimes(2);
|
|
573
590
|
|
|
574
|
-
const addEventCalls = collectEventListenerCalls(addEventListenerSpy)
|
|
575
|
-
const events = Object.keys(addEventCalls)
|
|
591
|
+
const addEventCalls = collectEventListenerCalls(addEventListenerSpy);
|
|
592
|
+
const events = Object.keys(addEventCalls);
|
|
576
593
|
|
|
577
|
-
expect(events).toContain(
|
|
578
|
-
expect(events).toContain(
|
|
594
|
+
expect(events).toContain("dragover");
|
|
595
|
+
expect(events).toContain("drop");
|
|
579
596
|
|
|
580
|
-
events.forEach(eventName => {
|
|
581
|
-
const [fn, options] = addEventCalls[eventName]
|
|
582
|
-
expect(fn).toBeDefined()
|
|
583
|
-
expect(options).toBe(false)
|
|
584
|
-
})
|
|
585
|
-
})
|
|
597
|
+
events.forEach((eventName) => {
|
|
598
|
+
const [fn, options] = addEventCalls[eventName];
|
|
599
|
+
expect(fn).toBeDefined();
|
|
600
|
+
expect(options).toBe(false);
|
|
601
|
+
});
|
|
602
|
+
});
|
|
586
603
|
|
|
587
|
-
it(
|
|
604
|
+
it("removes document hooks when unmounted", () => {
|
|
588
605
|
const { unmount } = render(
|
|
589
606
|
<Dropzone>
|
|
590
607
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -593,27 +610,29 @@ describe('useDropzone() hook', () => {
|
|
|
593
610
|
</div>
|
|
594
611
|
)}
|
|
595
612
|
</Dropzone>
|
|
596
|
-
)
|
|
613
|
+
);
|
|
597
614
|
|
|
598
|
-
unmount()
|
|
615
|
+
unmount();
|
|
599
616
|
|
|
600
|
-
expect(removeEventListenerSpy).toHaveBeenCalledTimes(2)
|
|
617
|
+
expect(removeEventListenerSpy).toHaveBeenCalledTimes(2);
|
|
601
618
|
|
|
602
|
-
const addEventCalls = collectEventListenerCalls(addEventListenerSpy)
|
|
603
|
-
const removeEventCalls = collectEventListenerCalls(
|
|
604
|
-
|
|
619
|
+
const addEventCalls = collectEventListenerCalls(addEventListenerSpy);
|
|
620
|
+
const removeEventCalls = collectEventListenerCalls(
|
|
621
|
+
removeEventListenerSpy
|
|
622
|
+
);
|
|
623
|
+
const events = Object.keys(removeEventCalls);
|
|
605
624
|
|
|
606
|
-
expect(events).toContain(
|
|
607
|
-
expect(events).toContain(
|
|
625
|
+
expect(events).toContain("dragover");
|
|
626
|
+
expect(events).toContain("drop");
|
|
608
627
|
|
|
609
|
-
events.forEach(eventName => {
|
|
610
|
-
const [a] = addEventCalls[eventName]
|
|
611
|
-
const [b] = removeEventCalls[eventName]
|
|
612
|
-
expect(a).toEqual(b)
|
|
613
|
-
})
|
|
614
|
-
})
|
|
628
|
+
events.forEach((eventName) => {
|
|
629
|
+
const [a] = addEventCalls[eventName];
|
|
630
|
+
const [b] = removeEventCalls[eventName];
|
|
631
|
+
expect(a).toEqual(b);
|
|
632
|
+
});
|
|
633
|
+
});
|
|
615
634
|
|
|
616
|
-
it(
|
|
635
|
+
it("terminates drags and drops on elements outside our dropzone", () => {
|
|
617
636
|
render(
|
|
618
637
|
<Dropzone>
|
|
619
638
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -622,20 +641,20 @@ describe('useDropzone() hook', () => {
|
|
|
622
641
|
</div>
|
|
623
642
|
)}
|
|
624
643
|
</Dropzone>
|
|
625
|
-
)
|
|
644
|
+
);
|
|
626
645
|
|
|
627
|
-
const dragEvt = new Event(
|
|
628
|
-
const dragEvtPreventDefaultSpy = jest.spyOn(dragEvt,
|
|
629
|
-
fireEvent(document.body, dragEvt)
|
|
630
|
-
expect(dragEvtPreventDefaultSpy).toHaveBeenCalled()
|
|
646
|
+
const dragEvt = new Event("dragover", { bubbles: true });
|
|
647
|
+
const dragEvtPreventDefaultSpy = jest.spyOn(dragEvt, "preventDefault");
|
|
648
|
+
fireEvent(document.body, dragEvt);
|
|
649
|
+
expect(dragEvtPreventDefaultSpy).toHaveBeenCalled();
|
|
631
650
|
|
|
632
|
-
const dropEvt = new Event(
|
|
633
|
-
const dropEvtPreventDefaultSpy = jest.spyOn(dropEvt,
|
|
634
|
-
fireEvent(document.body, dropEvt)
|
|
635
|
-
expect(dropEvtPreventDefaultSpy).toHaveBeenCalled()
|
|
636
|
-
})
|
|
651
|
+
const dropEvt = new Event("drop", { bubbles: true });
|
|
652
|
+
const dropEvtPreventDefaultSpy = jest.spyOn(dropEvt, "preventDefault");
|
|
653
|
+
fireEvent(document.body, dropEvt);
|
|
654
|
+
expect(dropEvtPreventDefaultSpy).toHaveBeenCalled();
|
|
655
|
+
});
|
|
637
656
|
|
|
638
|
-
it(
|
|
657
|
+
it("permits drags and drops on elements inside our dropzone", () => {
|
|
639
658
|
const { container } = render(
|
|
640
659
|
<Dropzone>
|
|
641
660
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -644,19 +663,19 @@ describe('useDropzone() hook', () => {
|
|
|
644
663
|
</div>
|
|
645
664
|
)}
|
|
646
665
|
</Dropzone>
|
|
647
|
-
)
|
|
648
|
-
const dropzone = container.querySelector(
|
|
666
|
+
);
|
|
667
|
+
const dropzone = container.querySelector("div");
|
|
649
668
|
|
|
650
|
-
const dropEvt = new Event(
|
|
651
|
-
const dropEvtPreventDefaultSpy = jest.spyOn(dropEvt,
|
|
669
|
+
const dropEvt = new Event("drop", { bubbles: true });
|
|
670
|
+
const dropEvtPreventDefaultSpy = jest.spyOn(dropEvt, "preventDefault");
|
|
652
671
|
|
|
653
|
-
fireEvent(dropzone, dropEvt)
|
|
672
|
+
fireEvent(dropzone, dropEvt);
|
|
654
673
|
// A call is from the onDrop handler for the dropzone,
|
|
655
674
|
// but there should be no more than 1
|
|
656
|
-
expect(dropEvtPreventDefaultSpy).toHaveBeenCalled()
|
|
657
|
-
})
|
|
675
|
+
expect(dropEvtPreventDefaultSpy).toHaveBeenCalled();
|
|
676
|
+
});
|
|
658
677
|
|
|
659
|
-
it(
|
|
678
|
+
it("does not prevent stray drops when {preventDropOnDocument} is false", () => {
|
|
660
679
|
render(
|
|
661
680
|
<Dropzone preventDropOnDocument={false}>
|
|
662
681
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -665,25 +684,25 @@ describe('useDropzone() hook', () => {
|
|
|
665
684
|
</div>
|
|
666
685
|
)}
|
|
667
686
|
</Dropzone>
|
|
668
|
-
)
|
|
687
|
+
);
|
|
669
688
|
|
|
670
|
-
const dropEvt = new Event(
|
|
671
|
-
const dropEvtPreventDefaultSpy = jest.spyOn(dropEvt,
|
|
672
|
-
fireEvent(document.body, dropEvt)
|
|
673
|
-
expect(dropEvtPreventDefaultSpy).toHaveBeenCalledTimes(0)
|
|
674
|
-
})
|
|
675
|
-
})
|
|
689
|
+
const dropEvt = new Event("drop", { bubbles: true });
|
|
690
|
+
const dropEvtPreventDefaultSpy = jest.spyOn(dropEvt, "preventDefault");
|
|
691
|
+
fireEvent(document.body, dropEvt);
|
|
692
|
+
expect(dropEvtPreventDefaultSpy).toHaveBeenCalledTimes(0);
|
|
693
|
+
});
|
|
694
|
+
});
|
|
676
695
|
|
|
677
|
-
describe(
|
|
678
|
-
const data = createDtWithFiles(files)
|
|
696
|
+
describe("event propagation", () => {
|
|
697
|
+
const data = createDtWithFiles(files);
|
|
679
698
|
|
|
680
|
-
test(
|
|
699
|
+
test("drag events propagate from the inner dropzone to parents", async () => {
|
|
681
700
|
const innerProps = {
|
|
682
701
|
onDragEnter: jest.fn(),
|
|
683
702
|
onDragOver: jest.fn(),
|
|
684
703
|
onDragLeave: jest.fn(),
|
|
685
|
-
onDrop: jest.fn()
|
|
686
|
-
}
|
|
704
|
+
onDrop: jest.fn(),
|
|
705
|
+
};
|
|
687
706
|
|
|
688
707
|
const InnerDropzone = () => (
|
|
689
708
|
<Dropzone {...innerProps}>
|
|
@@ -693,14 +712,14 @@ describe('useDropzone() hook', () => {
|
|
|
693
712
|
</div>
|
|
694
713
|
)}
|
|
695
714
|
</Dropzone>
|
|
696
|
-
)
|
|
715
|
+
);
|
|
697
716
|
|
|
698
717
|
const parentProps = {
|
|
699
718
|
onDragEnter: jest.fn(),
|
|
700
719
|
onDragOver: jest.fn(),
|
|
701
720
|
onDragLeave: jest.fn(),
|
|
702
|
-
onDrop: jest.fn()
|
|
703
|
-
}
|
|
721
|
+
onDrop: jest.fn(),
|
|
722
|
+
};
|
|
704
723
|
|
|
705
724
|
const ui = (
|
|
706
725
|
<Dropzone {...parentProps}>
|
|
@@ -711,45 +730,45 @@ describe('useDropzone() hook', () => {
|
|
|
711
730
|
</div>
|
|
712
731
|
)}
|
|
713
732
|
</Dropzone>
|
|
714
|
-
)
|
|
733
|
+
);
|
|
715
734
|
|
|
716
|
-
const { container, rerender } = render(ui)
|
|
735
|
+
const { container, rerender } = render(ui);
|
|
717
736
|
|
|
718
|
-
const innerDropzone = container.querySelector(
|
|
737
|
+
const innerDropzone = container.querySelector("#inner-dropzone");
|
|
719
738
|
|
|
720
|
-
fireDragEnter(innerDropzone, data)
|
|
721
|
-
await flushPromises(rerender, ui)
|
|
722
|
-
expect(innerProps.onDragEnter).toHaveBeenCalled()
|
|
723
|
-
expect(parentProps.onDragEnter).toHaveBeenCalled()
|
|
739
|
+
fireDragEnter(innerDropzone, data);
|
|
740
|
+
await flushPromises(rerender, ui);
|
|
741
|
+
expect(innerProps.onDragEnter).toHaveBeenCalled();
|
|
742
|
+
expect(parentProps.onDragEnter).toHaveBeenCalled();
|
|
724
743
|
|
|
725
|
-
fireDragOver(innerDropzone, data)
|
|
726
|
-
expect(innerProps.onDragOver).toHaveBeenCalled()
|
|
727
|
-
expect(parentProps.onDragOver).toHaveBeenCalled()
|
|
744
|
+
fireDragOver(innerDropzone, data);
|
|
745
|
+
expect(innerProps.onDragOver).toHaveBeenCalled();
|
|
746
|
+
expect(parentProps.onDragOver).toHaveBeenCalled();
|
|
728
747
|
|
|
729
|
-
fireDragLeave(innerDropzone, data)
|
|
730
|
-
expect(innerProps.onDragLeave).toHaveBeenCalled()
|
|
731
|
-
expect(parentProps.onDragLeave).toHaveBeenCalled()
|
|
748
|
+
fireDragLeave(innerDropzone, data);
|
|
749
|
+
expect(innerProps.onDragLeave).toHaveBeenCalled();
|
|
750
|
+
expect(parentProps.onDragLeave).toHaveBeenCalled();
|
|
732
751
|
|
|
733
|
-
fireDrop(innerDropzone, data)
|
|
734
|
-
await flushPromises(rerender, ui)
|
|
735
|
-
expect(innerProps.onDrop).toHaveBeenCalled()
|
|
736
|
-
expect(parentProps.onDrop).toHaveBeenCalled()
|
|
737
|
-
})
|
|
752
|
+
fireDrop(innerDropzone, data);
|
|
753
|
+
await flushPromises(rerender, ui);
|
|
754
|
+
expect(innerProps.onDrop).toHaveBeenCalled();
|
|
755
|
+
expect(parentProps.onDrop).toHaveBeenCalled();
|
|
756
|
+
});
|
|
738
757
|
|
|
739
|
-
test(
|
|
758
|
+
test("drag events do not propagate from the inner dropzone to parent dropzone if user invoked stopPropagation() on the events", async () => {
|
|
740
759
|
const innerProps = {
|
|
741
760
|
onDragEnter: jest.fn(),
|
|
742
761
|
onDragOver: jest.fn(),
|
|
743
762
|
onDragLeave: jest.fn(),
|
|
744
|
-
onDrop: jest.fn()
|
|
745
|
-
}
|
|
763
|
+
onDrop: jest.fn(),
|
|
764
|
+
};
|
|
746
765
|
|
|
747
|
-
Object.keys(innerProps).forEach(prop =>
|
|
766
|
+
Object.keys(innerProps).forEach((prop) =>
|
|
748
767
|
innerProps[prop].mockImplementation((...args) => {
|
|
749
|
-
const event = prop ===
|
|
750
|
-
event.stopPropagation()
|
|
768
|
+
const event = prop === "onDrop" ? args.pop() : args.shift();
|
|
769
|
+
event.stopPropagation();
|
|
751
770
|
})
|
|
752
|
-
)
|
|
771
|
+
);
|
|
753
772
|
|
|
754
773
|
const InnerDropzone = () => (
|
|
755
774
|
<Dropzone {...innerProps}>
|
|
@@ -759,14 +778,14 @@ describe('useDropzone() hook', () => {
|
|
|
759
778
|
</div>
|
|
760
779
|
)}
|
|
761
780
|
</Dropzone>
|
|
762
|
-
)
|
|
781
|
+
);
|
|
763
782
|
|
|
764
783
|
const parentProps = {
|
|
765
784
|
onDragEnter: jest.fn(),
|
|
766
785
|
onDragOver: jest.fn(),
|
|
767
786
|
onDragLeave: jest.fn(),
|
|
768
|
-
onDrop: jest.fn()
|
|
769
|
-
}
|
|
787
|
+
onDrop: jest.fn(),
|
|
788
|
+
};
|
|
770
789
|
|
|
771
790
|
const ui = (
|
|
772
791
|
<Dropzone {...parentProps}>
|
|
@@ -777,38 +796,38 @@ describe('useDropzone() hook', () => {
|
|
|
777
796
|
</div>
|
|
778
797
|
)}
|
|
779
798
|
</Dropzone>
|
|
780
|
-
)
|
|
799
|
+
);
|
|
781
800
|
|
|
782
|
-
const { container, rerender } = render(ui)
|
|
801
|
+
const { container, rerender } = render(ui);
|
|
783
802
|
|
|
784
|
-
const innerDropzone = container.querySelector(
|
|
803
|
+
const innerDropzone = container.querySelector("#inner-dropzone");
|
|
785
804
|
|
|
786
|
-
fireDragEnter(innerDropzone, data)
|
|
787
|
-
await flushPromises(rerender, ui)
|
|
788
|
-
expect(innerProps.onDragEnter).toHaveBeenCalled()
|
|
789
|
-
expect(parentProps.onDragEnter).not.toHaveBeenCalled()
|
|
805
|
+
fireDragEnter(innerDropzone, data);
|
|
806
|
+
await flushPromises(rerender, ui);
|
|
807
|
+
expect(innerProps.onDragEnter).toHaveBeenCalled();
|
|
808
|
+
expect(parentProps.onDragEnter).not.toHaveBeenCalled();
|
|
790
809
|
|
|
791
|
-
fireDragOver(innerDropzone, data)
|
|
792
|
-
expect(innerProps.onDragOver).toHaveBeenCalled()
|
|
793
|
-
expect(parentProps.onDragOver).not.toHaveBeenCalled()
|
|
810
|
+
fireDragOver(innerDropzone, data);
|
|
811
|
+
expect(innerProps.onDragOver).toHaveBeenCalled();
|
|
812
|
+
expect(parentProps.onDragOver).not.toHaveBeenCalled();
|
|
794
813
|
|
|
795
|
-
fireDragLeave(innerDropzone, data)
|
|
796
|
-
expect(innerProps.onDragLeave).toHaveBeenCalled()
|
|
797
|
-
expect(parentProps.onDragLeave).not.toHaveBeenCalled()
|
|
814
|
+
fireDragLeave(innerDropzone, data);
|
|
815
|
+
expect(innerProps.onDragLeave).toHaveBeenCalled();
|
|
816
|
+
expect(parentProps.onDragLeave).not.toHaveBeenCalled();
|
|
798
817
|
|
|
799
|
-
fireDrop(innerDropzone, data)
|
|
800
|
-
await flushPromises(rerender, ui)
|
|
801
|
-
expect(innerProps.onDrop).toHaveBeenCalled()
|
|
802
|
-
expect(parentProps.onDrop).not.toHaveBeenCalled()
|
|
803
|
-
})
|
|
818
|
+
fireDrop(innerDropzone, data);
|
|
819
|
+
await flushPromises(rerender, ui);
|
|
820
|
+
expect(innerProps.onDrop).toHaveBeenCalled();
|
|
821
|
+
expect(parentProps.onDrop).not.toHaveBeenCalled();
|
|
822
|
+
});
|
|
804
823
|
|
|
805
|
-
test(
|
|
824
|
+
test("drag events do not propagate from the inner dropzone to parent dropzone if {noDragEventsBubbling} is true", async () => {
|
|
806
825
|
const innerProps = {
|
|
807
826
|
onDragEnter: jest.fn(),
|
|
808
827
|
onDragOver: jest.fn(),
|
|
809
828
|
onDragLeave: jest.fn(),
|
|
810
|
-
onDrop: jest.fn()
|
|
811
|
-
}
|
|
829
|
+
onDrop: jest.fn(),
|
|
830
|
+
};
|
|
812
831
|
|
|
813
832
|
const InnerDropzone = () => (
|
|
814
833
|
<Dropzone {...innerProps} noDragEventsBubbling>
|
|
@@ -818,14 +837,14 @@ describe('useDropzone() hook', () => {
|
|
|
818
837
|
</div>
|
|
819
838
|
)}
|
|
820
839
|
</Dropzone>
|
|
821
|
-
)
|
|
840
|
+
);
|
|
822
841
|
|
|
823
842
|
const parentProps = {
|
|
824
843
|
onDragEnter: jest.fn(),
|
|
825
844
|
onDragOver: jest.fn(),
|
|
826
845
|
onDragLeave: jest.fn(),
|
|
827
|
-
onDrop: jest.fn()
|
|
828
|
-
}
|
|
846
|
+
onDrop: jest.fn(),
|
|
847
|
+
};
|
|
829
848
|
|
|
830
849
|
const ui = (
|
|
831
850
|
<Dropzone {...parentProps}>
|
|
@@ -836,38 +855,38 @@ describe('useDropzone() hook', () => {
|
|
|
836
855
|
</div>
|
|
837
856
|
)}
|
|
838
857
|
</Dropzone>
|
|
839
|
-
)
|
|
858
|
+
);
|
|
840
859
|
|
|
841
|
-
const { container, rerender } = render(ui)
|
|
860
|
+
const { container, rerender } = render(ui);
|
|
842
861
|
|
|
843
|
-
const outerDropzone = container.querySelector(
|
|
844
|
-
const innerDropzone = container.querySelector(
|
|
862
|
+
const outerDropzone = container.querySelector("#outer-dropzone");
|
|
863
|
+
const innerDropzone = container.querySelector("#inner-dropzone");
|
|
845
864
|
|
|
846
865
|
// Sets drag targets on the outer dropzone
|
|
847
|
-
fireDragEnter(outerDropzone, data)
|
|
848
|
-
await flushPromises(rerender, ui)
|
|
849
|
-
|
|
850
|
-
fireDragEnter(innerDropzone, data)
|
|
851
|
-
await flushPromises(rerender, ui)
|
|
852
|
-
expect(innerProps.onDragEnter).toHaveBeenCalled()
|
|
853
|
-
expect(parentProps.onDragEnter).toHaveBeenCalledTimes(1)
|
|
854
|
-
|
|
855
|
-
fireDragOver(innerDropzone, data)
|
|
856
|
-
expect(innerProps.onDragOver).toHaveBeenCalled()
|
|
857
|
-
expect(parentProps.onDragOver).not.toHaveBeenCalled()
|
|
858
|
-
|
|
859
|
-
fireDragLeave(innerDropzone, data)
|
|
860
|
-
expect(innerProps.onDragLeave).toHaveBeenCalled()
|
|
861
|
-
expect(parentProps.onDragLeave).not.toHaveBeenCalled()
|
|
862
|
-
|
|
863
|
-
fireDrop(innerDropzone, data)
|
|
864
|
-
await flushPromises(rerender, ui)
|
|
865
|
-
expect(innerProps.onDrop).toHaveBeenCalled()
|
|
866
|
-
expect(parentProps.onDrop).not.toHaveBeenCalled()
|
|
867
|
-
})
|
|
868
|
-
|
|
869
|
-
test(
|
|
870
|
-
const innerDragLeave = jest.fn()
|
|
866
|
+
fireDragEnter(outerDropzone, data);
|
|
867
|
+
await flushPromises(rerender, ui);
|
|
868
|
+
|
|
869
|
+
fireDragEnter(innerDropzone, data);
|
|
870
|
+
await flushPromises(rerender, ui);
|
|
871
|
+
expect(innerProps.onDragEnter).toHaveBeenCalled();
|
|
872
|
+
expect(parentProps.onDragEnter).toHaveBeenCalledTimes(1);
|
|
873
|
+
|
|
874
|
+
fireDragOver(innerDropzone, data);
|
|
875
|
+
expect(innerProps.onDragOver).toHaveBeenCalled();
|
|
876
|
+
expect(parentProps.onDragOver).not.toHaveBeenCalled();
|
|
877
|
+
|
|
878
|
+
fireDragLeave(innerDropzone, data);
|
|
879
|
+
expect(innerProps.onDragLeave).toHaveBeenCalled();
|
|
880
|
+
expect(parentProps.onDragLeave).not.toHaveBeenCalled();
|
|
881
|
+
|
|
882
|
+
fireDrop(innerDropzone, data);
|
|
883
|
+
await flushPromises(rerender, ui);
|
|
884
|
+
expect(innerProps.onDrop).toHaveBeenCalled();
|
|
885
|
+
expect(parentProps.onDrop).not.toHaveBeenCalled();
|
|
886
|
+
});
|
|
887
|
+
|
|
888
|
+
test("onDragLeave is not invoked for the parent dropzone if it was invoked for an inner dropzone", async () => {
|
|
889
|
+
const innerDragLeave = jest.fn();
|
|
871
890
|
const InnerDropzone = () => (
|
|
872
891
|
<Dropzone onDragLeave={innerDragLeave}>
|
|
873
892
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -876,9 +895,9 @@ describe('useDropzone() hook', () => {
|
|
|
876
895
|
</div>
|
|
877
896
|
)}
|
|
878
897
|
</Dropzone>
|
|
879
|
-
)
|
|
898
|
+
);
|
|
880
899
|
|
|
881
|
-
const parentDragLeave = jest.fn()
|
|
900
|
+
const parentDragLeave = jest.fn();
|
|
882
901
|
const ui = (
|
|
883
902
|
<Dropzone onDragLeave={parentDragLeave}>
|
|
884
903
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -888,36 +907,38 @@ describe('useDropzone() hook', () => {
|
|
|
888
907
|
</div>
|
|
889
908
|
)}
|
|
890
909
|
</Dropzone>
|
|
891
|
-
)
|
|
910
|
+
);
|
|
892
911
|
|
|
893
|
-
const { container, rerender } = render(ui)
|
|
912
|
+
const { container, rerender } = render(ui);
|
|
894
913
|
|
|
895
|
-
const parentDropzone = container.querySelector(
|
|
914
|
+
const parentDropzone = container.querySelector("#parent-dropzone");
|
|
896
915
|
|
|
897
|
-
fireDragEnter(parentDropzone, data)
|
|
898
|
-
await flushPromises(rerender, ui)
|
|
916
|
+
fireDragEnter(parentDropzone, data);
|
|
917
|
+
await flushPromises(rerender, ui);
|
|
899
918
|
|
|
900
|
-
const innerDropzone = container.querySelector(
|
|
901
|
-
fireDragEnter(innerDropzone, data)
|
|
902
|
-
await flushPromises(rerender, ui)
|
|
919
|
+
const innerDropzone = container.querySelector("#inner-dropzone");
|
|
920
|
+
fireDragEnter(innerDropzone, data);
|
|
921
|
+
await flushPromises(rerender, ui);
|
|
903
922
|
|
|
904
|
-
fireDragLeave(innerDropzone, data)
|
|
905
|
-
expect(innerDragLeave).toHaveBeenCalled()
|
|
906
|
-
expect(parentDragLeave).not.toHaveBeenCalled()
|
|
907
|
-
})
|
|
908
|
-
})
|
|
923
|
+
fireDragLeave(innerDropzone, data);
|
|
924
|
+
expect(innerDragLeave).toHaveBeenCalled();
|
|
925
|
+
expect(parentDragLeave).not.toHaveBeenCalled();
|
|
926
|
+
});
|
|
927
|
+
});
|
|
909
928
|
|
|
910
|
-
describe(
|
|
911
|
-
it(
|
|
912
|
-
const data = createDtWithFiles(files)
|
|
929
|
+
describe("plugin integration", () => {
|
|
930
|
+
it("uses provided getFilesFromEvent()", async () => {
|
|
931
|
+
const data = createDtWithFiles(files);
|
|
913
932
|
|
|
914
933
|
const props = {
|
|
915
|
-
getFilesFromEvent: jest
|
|
934
|
+
getFilesFromEvent: jest
|
|
935
|
+
.fn()
|
|
936
|
+
.mockImplementation((event) => fromEvent(event)),
|
|
916
937
|
onDragEnter: jest.fn(),
|
|
917
938
|
onDragOver: jest.fn(),
|
|
918
939
|
onDragLeave: jest.fn(),
|
|
919
|
-
onDrop: jest.fn()
|
|
920
|
-
}
|
|
940
|
+
onDrop: jest.fn(),
|
|
941
|
+
};
|
|
921
942
|
|
|
922
943
|
const ui = (
|
|
923
944
|
<Dropzone {...props}>
|
|
@@ -927,30 +948,30 @@ describe('useDropzone() hook', () => {
|
|
|
927
948
|
</div>
|
|
928
949
|
)}
|
|
929
950
|
</Dropzone>
|
|
930
|
-
)
|
|
931
|
-
const { container, rerender } = render(ui)
|
|
932
|
-
const dropzone = container.querySelector(
|
|
951
|
+
);
|
|
952
|
+
const { container, rerender } = render(ui);
|
|
953
|
+
const dropzone = container.querySelector("div");
|
|
933
954
|
|
|
934
|
-
fireDragEnter(dropzone, data)
|
|
935
|
-
await flushPromises(rerender, ui)
|
|
936
|
-
expect(props.onDragEnter).toHaveBeenCalled()
|
|
955
|
+
fireDragEnter(dropzone, data);
|
|
956
|
+
await flushPromises(rerender, ui);
|
|
957
|
+
expect(props.onDragEnter).toHaveBeenCalled();
|
|
937
958
|
|
|
938
|
-
fireDragOver(dropzone, data)
|
|
939
|
-
expect(props.onDragOver).toHaveBeenCalled()
|
|
959
|
+
fireDragOver(dropzone, data);
|
|
960
|
+
expect(props.onDragOver).toHaveBeenCalled();
|
|
940
961
|
|
|
941
|
-
fireDragLeave(dropzone, data)
|
|
942
|
-
expect(props.onDragLeave).toHaveBeenCalled()
|
|
962
|
+
fireDragLeave(dropzone, data);
|
|
963
|
+
expect(props.onDragLeave).toHaveBeenCalled();
|
|
943
964
|
|
|
944
|
-
fireDrop(dropzone, data)
|
|
945
|
-
await flushPromises(rerender, ui)
|
|
946
|
-
expect(props.onDrop).toHaveBeenCalled()
|
|
965
|
+
fireDrop(dropzone, data);
|
|
966
|
+
await flushPromises(rerender, ui);
|
|
967
|
+
expect(props.onDrop).toHaveBeenCalled();
|
|
947
968
|
|
|
948
|
-
expect(props.getFilesFromEvent).toHaveBeenCalledTimes(2)
|
|
949
|
-
})
|
|
950
|
-
})
|
|
969
|
+
expect(props.getFilesFromEvent).toHaveBeenCalledTimes(2);
|
|
970
|
+
});
|
|
971
|
+
});
|
|
951
972
|
|
|
952
|
-
describe(
|
|
953
|
-
it(
|
|
973
|
+
describe("onFocus", () => {
|
|
974
|
+
it("sets focus state", () => {
|
|
954
975
|
const { container } = render(
|
|
955
976
|
<Dropzone>
|
|
956
977
|
{({ getRootProps, getInputProps, isFocused }) => (
|
|
@@ -960,33 +981,35 @@ describe('useDropzone() hook', () => {
|
|
|
960
981
|
</div>
|
|
961
982
|
)}
|
|
962
983
|
</Dropzone>
|
|
963
|
-
)
|
|
984
|
+
);
|
|
964
985
|
|
|
965
|
-
const dropzone = container.querySelector(
|
|
986
|
+
const dropzone = container.querySelector("div");
|
|
966
987
|
|
|
967
|
-
fireEvent.focus(dropzone)
|
|
968
|
-
expect(dropzone.querySelector(
|
|
969
|
-
})
|
|
988
|
+
fireEvent.focus(dropzone);
|
|
989
|
+
expect(dropzone.querySelector("#focus")).not.toBeNull();
|
|
990
|
+
});
|
|
970
991
|
|
|
971
|
-
it(
|
|
992
|
+
it("does not set focus state if user stopped event propagation", () => {
|
|
972
993
|
const { container } = render(
|
|
973
994
|
<Dropzone>
|
|
974
995
|
{({ getRootProps, getInputProps, isFocused }) => (
|
|
975
|
-
<div
|
|
996
|
+
<div
|
|
997
|
+
{...getRootProps({ onFocus: (event) => event.stopPropagation() })}
|
|
998
|
+
>
|
|
976
999
|
<input {...getInputProps()} />
|
|
977
1000
|
{isFocused && <div id="focus" />}
|
|
978
1001
|
</div>
|
|
979
1002
|
)}
|
|
980
1003
|
</Dropzone>
|
|
981
|
-
)
|
|
1004
|
+
);
|
|
982
1005
|
|
|
983
|
-
const dropzone = container.querySelector(
|
|
1006
|
+
const dropzone = container.querySelector("div");
|
|
984
1007
|
|
|
985
|
-
fireEvent.focus(dropzone)
|
|
986
|
-
expect(dropzone.querySelector(
|
|
987
|
-
})
|
|
1008
|
+
fireEvent.focus(dropzone);
|
|
1009
|
+
expect(dropzone.querySelector("#focus")).toBeNull();
|
|
1010
|
+
});
|
|
988
1011
|
|
|
989
|
-
it(
|
|
1012
|
+
it("does not set focus state if {noKeyboard} is true", () => {
|
|
990
1013
|
const { container } = render(
|
|
991
1014
|
<Dropzone noKeyboard>
|
|
992
1015
|
{({ getRootProps, getInputProps, isFocused }) => (
|
|
@@ -996,15 +1019,15 @@ describe('useDropzone() hook', () => {
|
|
|
996
1019
|
</div>
|
|
997
1020
|
)}
|
|
998
1021
|
</Dropzone>
|
|
999
|
-
)
|
|
1022
|
+
);
|
|
1000
1023
|
|
|
1001
|
-
const dropzone = container.querySelector(
|
|
1024
|
+
const dropzone = container.querySelector("div");
|
|
1002
1025
|
|
|
1003
|
-
fireEvent.focus(dropzone)
|
|
1004
|
-
expect(dropzone.querySelector(
|
|
1005
|
-
})
|
|
1026
|
+
fireEvent.focus(dropzone);
|
|
1027
|
+
expect(dropzone.querySelector("#focus")).toBeNull();
|
|
1028
|
+
});
|
|
1006
1029
|
|
|
1007
|
-
it(
|
|
1030
|
+
it("restores focus behavior if {noKeyboard} is set back to false", () => {
|
|
1008
1031
|
const { container, rerender } = render(
|
|
1009
1032
|
<Dropzone noKeyboard>
|
|
1010
1033
|
{({ getRootProps, getInputProps, isFocused }) => (
|
|
@@ -1014,12 +1037,12 @@ describe('useDropzone() hook', () => {
|
|
|
1014
1037
|
</div>
|
|
1015
1038
|
)}
|
|
1016
1039
|
</Dropzone>
|
|
1017
|
-
)
|
|
1040
|
+
);
|
|
1018
1041
|
|
|
1019
|
-
const dropzone = container.querySelector(
|
|
1042
|
+
const dropzone = container.querySelector("div");
|
|
1020
1043
|
|
|
1021
|
-
fireEvent.focus(dropzone)
|
|
1022
|
-
expect(dropzone.querySelector(
|
|
1044
|
+
fireEvent.focus(dropzone);
|
|
1045
|
+
expect(dropzone.querySelector("#focus")).toBeNull();
|
|
1023
1046
|
|
|
1024
1047
|
rerender(
|
|
1025
1048
|
<Dropzone noKeyboard={false}>
|
|
@@ -1030,15 +1053,15 @@ describe('useDropzone() hook', () => {
|
|
|
1030
1053
|
</div>
|
|
1031
1054
|
)}
|
|
1032
1055
|
</Dropzone>
|
|
1033
|
-
)
|
|
1056
|
+
);
|
|
1034
1057
|
|
|
1035
|
-
fireEvent.focus(dropzone)
|
|
1036
|
-
expect(dropzone.querySelector(
|
|
1037
|
-
})
|
|
1038
|
-
})
|
|
1058
|
+
fireEvent.focus(dropzone);
|
|
1059
|
+
expect(dropzone.querySelector("#focus")).not.toBeNull();
|
|
1060
|
+
});
|
|
1061
|
+
});
|
|
1039
1062
|
|
|
1040
|
-
describe(
|
|
1041
|
-
it(
|
|
1063
|
+
describe("onBlur", () => {
|
|
1064
|
+
it("unsets focus state", () => {
|
|
1042
1065
|
const { container } = render(
|
|
1043
1066
|
<Dropzone>
|
|
1044
1067
|
{({ getRootProps, getInputProps, isFocused }) => (
|
|
@@ -1048,38 +1071,40 @@ describe('useDropzone() hook', () => {
|
|
|
1048
1071
|
</div>
|
|
1049
1072
|
)}
|
|
1050
1073
|
</Dropzone>
|
|
1051
|
-
)
|
|
1074
|
+
);
|
|
1052
1075
|
|
|
1053
|
-
const dropzone = container.querySelector(
|
|
1076
|
+
const dropzone = container.querySelector("div");
|
|
1054
1077
|
|
|
1055
|
-
fireEvent.focus(dropzone)
|
|
1056
|
-
expect(dropzone.querySelector(
|
|
1078
|
+
fireEvent.focus(dropzone);
|
|
1079
|
+
expect(dropzone.querySelector("#focus")).not.toBeNull();
|
|
1057
1080
|
|
|
1058
|
-
fireEvent.blur(dropzone)
|
|
1059
|
-
expect(dropzone.querySelector(
|
|
1060
|
-
})
|
|
1081
|
+
fireEvent.blur(dropzone);
|
|
1082
|
+
expect(dropzone.querySelector("#focus")).toBeNull();
|
|
1083
|
+
});
|
|
1061
1084
|
|
|
1062
|
-
it(
|
|
1085
|
+
it("does not unset focus state if user stopped event propagation", () => {
|
|
1063
1086
|
const { container } = render(
|
|
1064
1087
|
<Dropzone>
|
|
1065
1088
|
{({ getRootProps, getInputProps, isFocused }) => (
|
|
1066
|
-
<div
|
|
1089
|
+
<div
|
|
1090
|
+
{...getRootProps({ onBlur: (event) => event.stopPropagation() })}
|
|
1091
|
+
>
|
|
1067
1092
|
<input {...getInputProps()} />
|
|
1068
1093
|
{isFocused && <div id="focus" />}
|
|
1069
1094
|
</div>
|
|
1070
1095
|
)}
|
|
1071
1096
|
</Dropzone>
|
|
1072
|
-
)
|
|
1097
|
+
);
|
|
1073
1098
|
|
|
1074
|
-
const dropzone = container.querySelector(
|
|
1099
|
+
const dropzone = container.querySelector("div");
|
|
1075
1100
|
|
|
1076
|
-
fireEvent.focus(dropzone)
|
|
1077
|
-
expect(dropzone.querySelector(
|
|
1078
|
-
fireEvent.blur(dropzone)
|
|
1079
|
-
expect(dropzone.querySelector(
|
|
1080
|
-
})
|
|
1101
|
+
fireEvent.focus(dropzone);
|
|
1102
|
+
expect(dropzone.querySelector("#focus")).not.toBeNull();
|
|
1103
|
+
fireEvent.blur(dropzone);
|
|
1104
|
+
expect(dropzone.querySelector("#focus")).not.toBeNull();
|
|
1105
|
+
});
|
|
1081
1106
|
|
|
1082
|
-
it(
|
|
1107
|
+
it("does not unset focus state if {noKeyboard} is true", () => {
|
|
1083
1108
|
const { container, rerender } = render(
|
|
1084
1109
|
<Dropzone>
|
|
1085
1110
|
{({ getRootProps, getInputProps, isFocused }) => (
|
|
@@ -1089,12 +1114,12 @@ describe('useDropzone() hook', () => {
|
|
|
1089
1114
|
</div>
|
|
1090
1115
|
)}
|
|
1091
1116
|
</Dropzone>
|
|
1092
|
-
)
|
|
1117
|
+
);
|
|
1093
1118
|
|
|
1094
|
-
const dropzone = container.querySelector(
|
|
1119
|
+
const dropzone = container.querySelector("div");
|
|
1095
1120
|
|
|
1096
|
-
fireEvent.focus(dropzone)
|
|
1097
|
-
expect(dropzone.querySelector(
|
|
1121
|
+
fireEvent.focus(dropzone);
|
|
1122
|
+
expect(dropzone.querySelector("#focus")).not.toBeNull();
|
|
1098
1123
|
|
|
1099
1124
|
rerender(
|
|
1100
1125
|
<Dropzone noKeyboard>
|
|
@@ -1105,13 +1130,13 @@ describe('useDropzone() hook', () => {
|
|
|
1105
1130
|
</div>
|
|
1106
1131
|
)}
|
|
1107
1132
|
</Dropzone>
|
|
1108
|
-
)
|
|
1133
|
+
);
|
|
1109
1134
|
|
|
1110
|
-
fireEvent.blur(dropzone)
|
|
1111
|
-
expect(dropzone.querySelector(
|
|
1112
|
-
})
|
|
1135
|
+
fireEvent.blur(dropzone);
|
|
1136
|
+
expect(dropzone.querySelector("#focus")).not.toBeNull();
|
|
1137
|
+
});
|
|
1113
1138
|
|
|
1114
|
-
it(
|
|
1139
|
+
it("restores blur behavior if {noKeyboard} is set back to false", () => {
|
|
1115
1140
|
const { container, rerender } = render(
|
|
1116
1141
|
<Dropzone>
|
|
1117
1142
|
{({ getRootProps, getInputProps, isFocused }) => (
|
|
@@ -1121,12 +1146,12 @@ describe('useDropzone() hook', () => {
|
|
|
1121
1146
|
</div>
|
|
1122
1147
|
)}
|
|
1123
1148
|
</Dropzone>
|
|
1124
|
-
)
|
|
1149
|
+
);
|
|
1125
1150
|
|
|
1126
|
-
const dropzone = container.querySelector(
|
|
1151
|
+
const dropzone = container.querySelector("div");
|
|
1127
1152
|
|
|
1128
|
-
fireEvent.focus(dropzone)
|
|
1129
|
-
expect(dropzone.querySelector(
|
|
1153
|
+
fireEvent.focus(dropzone);
|
|
1154
|
+
expect(dropzone.querySelector("#focus")).not.toBeNull();
|
|
1130
1155
|
|
|
1131
1156
|
rerender(
|
|
1132
1157
|
<Dropzone noKeyboard>
|
|
@@ -1137,10 +1162,10 @@ describe('useDropzone() hook', () => {
|
|
|
1137
1162
|
</div>
|
|
1138
1163
|
)}
|
|
1139
1164
|
</Dropzone>
|
|
1140
|
-
)
|
|
1165
|
+
);
|
|
1141
1166
|
|
|
1142
|
-
fireEvent.blur(dropzone)
|
|
1143
|
-
expect(dropzone.querySelector(
|
|
1167
|
+
fireEvent.blur(dropzone);
|
|
1168
|
+
expect(dropzone.querySelector("#focus")).not.toBeNull();
|
|
1144
1169
|
|
|
1145
1170
|
rerender(
|
|
1146
1171
|
<Dropzone noKeyboard={false}>
|
|
@@ -1151,32 +1176,32 @@ describe('useDropzone() hook', () => {
|
|
|
1151
1176
|
</div>
|
|
1152
1177
|
)}
|
|
1153
1178
|
</Dropzone>
|
|
1154
|
-
)
|
|
1179
|
+
);
|
|
1155
1180
|
|
|
1156
|
-
fireEvent.blur(dropzone)
|
|
1157
|
-
expect(dropzone.querySelector(
|
|
1158
|
-
})
|
|
1159
|
-
})
|
|
1181
|
+
fireEvent.blur(dropzone);
|
|
1182
|
+
expect(dropzone.querySelector("#focus")).toBeNull();
|
|
1183
|
+
});
|
|
1184
|
+
});
|
|
1160
1185
|
|
|
1161
|
-
describe(
|
|
1186
|
+
describe("onClick", () => {
|
|
1162
1187
|
let currentShowOpenFilePicker;
|
|
1163
1188
|
|
|
1164
1189
|
beforeEach(() => {
|
|
1165
|
-
currentShowOpenFilePicker = window.showOpenFilePicker
|
|
1166
|
-
})
|
|
1190
|
+
currentShowOpenFilePicker = window.showOpenFilePicker;
|
|
1191
|
+
});
|
|
1167
1192
|
|
|
1168
1193
|
afterEach(() => {
|
|
1169
1194
|
if (currentShowOpenFilePicker) {
|
|
1170
|
-
window.showOpenFilePicker = currentShowOpenFilePicker
|
|
1195
|
+
window.showOpenFilePicker = currentShowOpenFilePicker;
|
|
1171
1196
|
} else {
|
|
1172
|
-
delete window.showOpenFilePicker
|
|
1197
|
+
delete window.showOpenFilePicker;
|
|
1173
1198
|
}
|
|
1174
|
-
})
|
|
1199
|
+
});
|
|
1175
1200
|
|
|
1176
|
-
it(
|
|
1177
|
-
const activeRef = createRef()
|
|
1178
|
-
const active = <span ref={activeRef}>I am active</span
|
|
1179
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1201
|
+
it("should proxy the click event to the input", () => {
|
|
1202
|
+
const activeRef = createRef();
|
|
1203
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
1204
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1180
1205
|
|
|
1181
1206
|
const { container } = render(
|
|
1182
1207
|
<Dropzone>
|
|
@@ -1187,37 +1212,39 @@ describe('useDropzone() hook', () => {
|
|
|
1187
1212
|
</div>
|
|
1188
1213
|
)}
|
|
1189
1214
|
</Dropzone>
|
|
1190
|
-
)
|
|
1215
|
+
);
|
|
1191
1216
|
|
|
1192
|
-
const dropzone = container.querySelector(
|
|
1217
|
+
const dropzone = container.querySelector("div");
|
|
1193
1218
|
|
|
1194
|
-
fireEvent.click(dropzone)
|
|
1195
|
-
const ref = activeRef.current
|
|
1196
|
-
expect(ref).not.toBeNull()
|
|
1197
|
-
expect(dropzone).toContainElement(ref)
|
|
1198
|
-
expect(onClickSpy).toHaveBeenCalled()
|
|
1199
|
-
})
|
|
1219
|
+
fireEvent.click(dropzone);
|
|
1220
|
+
const ref = activeRef.current;
|
|
1221
|
+
expect(ref).not.toBeNull();
|
|
1222
|
+
expect(dropzone).toContainElement(ref);
|
|
1223
|
+
expect(onClickSpy).toHaveBeenCalled();
|
|
1224
|
+
});
|
|
1200
1225
|
|
|
1201
|
-
it(
|
|
1202
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1226
|
+
it("should not not proxy the click event to the input if event propagation was stopped", () => {
|
|
1227
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1203
1228
|
const { container } = render(
|
|
1204
1229
|
<Dropzone>
|
|
1205
1230
|
{({ getRootProps, getInputProps }) => (
|
|
1206
|
-
<div
|
|
1231
|
+
<div
|
|
1232
|
+
{...getRootProps({ onClick: (event) => event.stopPropagation() })}
|
|
1233
|
+
>
|
|
1207
1234
|
<input {...getInputProps()} />
|
|
1208
1235
|
</div>
|
|
1209
1236
|
)}
|
|
1210
1237
|
</Dropzone>
|
|
1211
|
-
)
|
|
1238
|
+
);
|
|
1212
1239
|
|
|
1213
|
-
const dropzone = container.querySelector(
|
|
1240
|
+
const dropzone = container.querySelector("div");
|
|
1214
1241
|
|
|
1215
|
-
fireEvent.click(dropzone)
|
|
1216
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
1217
|
-
})
|
|
1242
|
+
fireEvent.click(dropzone);
|
|
1243
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1244
|
+
});
|
|
1218
1245
|
|
|
1219
|
-
it(
|
|
1220
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1246
|
+
it("should not not proxy the click event to the input if {noClick} is true", () => {
|
|
1247
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1221
1248
|
const { container } = render(
|
|
1222
1249
|
<Dropzone noClick>
|
|
1223
1250
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -1226,16 +1253,16 @@ describe('useDropzone() hook', () => {
|
|
|
1226
1253
|
</div>
|
|
1227
1254
|
)}
|
|
1228
1255
|
</Dropzone>
|
|
1229
|
-
)
|
|
1256
|
+
);
|
|
1230
1257
|
|
|
1231
|
-
const dropzone = container.querySelector(
|
|
1258
|
+
const dropzone = container.querySelector("div");
|
|
1232
1259
|
|
|
1233
|
-
fireEvent.click(dropzone)
|
|
1234
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
1235
|
-
})
|
|
1260
|
+
fireEvent.click(dropzone);
|
|
1261
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1262
|
+
});
|
|
1236
1263
|
|
|
1237
|
-
it(
|
|
1238
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1264
|
+
it("restores click behavior if {noClick} is set back to false", () => {
|
|
1265
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1239
1266
|
const { container, rerender } = render(
|
|
1240
1267
|
<Dropzone noClick>
|
|
1241
1268
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -1244,12 +1271,12 @@ describe('useDropzone() hook', () => {
|
|
|
1244
1271
|
</div>
|
|
1245
1272
|
)}
|
|
1246
1273
|
</Dropzone>
|
|
1247
|
-
)
|
|
1274
|
+
);
|
|
1248
1275
|
|
|
1249
|
-
const dropzone = container.querySelector(
|
|
1276
|
+
const dropzone = container.querySelector("div");
|
|
1250
1277
|
|
|
1251
|
-
fireEvent.click(dropzone)
|
|
1252
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
1278
|
+
fireEvent.click(dropzone);
|
|
1279
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1253
1280
|
|
|
1254
1281
|
rerender(
|
|
1255
1282
|
<Dropzone noClick={false}>
|
|
@@ -1259,16 +1286,16 @@ describe('useDropzone() hook', () => {
|
|
|
1259
1286
|
</div>
|
|
1260
1287
|
)}
|
|
1261
1288
|
</Dropzone>
|
|
1262
|
-
)
|
|
1289
|
+
);
|
|
1263
1290
|
|
|
1264
|
-
fireEvent.click(dropzone)
|
|
1265
|
-
expect(onClickSpy).toHaveBeenCalled()
|
|
1266
|
-
})
|
|
1291
|
+
fireEvent.click(dropzone);
|
|
1292
|
+
expect(onClickSpy).toHaveBeenCalled();
|
|
1293
|
+
});
|
|
1267
1294
|
|
|
1268
1295
|
// https://github.com/react-dropzone/react-dropzone/issues/783
|
|
1269
|
-
it(
|
|
1270
|
-
const btnClickSpy = jest.fn()
|
|
1271
|
-
const inputClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1296
|
+
it("should continue event propagation if {noClick} is true", () => {
|
|
1297
|
+
const btnClickSpy = jest.fn();
|
|
1298
|
+
const inputClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1272
1299
|
const { container } = render(
|
|
1273
1300
|
<Dropzone noClick>
|
|
1274
1301
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -1278,23 +1305,25 @@ describe('useDropzone() hook', () => {
|
|
|
1278
1305
|
</div>
|
|
1279
1306
|
)}
|
|
1280
1307
|
</Dropzone>
|
|
1281
|
-
)
|
|
1308
|
+
);
|
|
1282
1309
|
|
|
1283
|
-
const dropzone = container.querySelector(
|
|
1284
|
-
const btn = container.querySelector(
|
|
1310
|
+
const dropzone = container.querySelector("div");
|
|
1311
|
+
const btn = container.querySelector("button");
|
|
1285
1312
|
|
|
1286
|
-
fireEvent.click(dropzone)
|
|
1287
|
-
expect(inputClickSpy).not.toHaveBeenCalled()
|
|
1313
|
+
fireEvent.click(dropzone);
|
|
1314
|
+
expect(inputClickSpy).not.toHaveBeenCalled();
|
|
1288
1315
|
|
|
1289
|
-
fireEvent.click(btn)
|
|
1290
|
-
expect(btnClickSpy).toHaveBeenCalled()
|
|
1291
|
-
})
|
|
1316
|
+
fireEvent.click(btn);
|
|
1317
|
+
expect(btnClickSpy).toHaveBeenCalled();
|
|
1318
|
+
});
|
|
1292
1319
|
|
|
1293
|
-
it(
|
|
1294
|
-
jest.useFakeTimers()
|
|
1320
|
+
it("should schedule input click on next tick in Edge", () => {
|
|
1321
|
+
jest.useFakeTimers();
|
|
1295
1322
|
|
|
1296
|
-
const isIeOrEdgeSpy = jest
|
|
1297
|
-
|
|
1323
|
+
const isIeOrEdgeSpy = jest
|
|
1324
|
+
.spyOn(utils, "isIeOrEdge")
|
|
1325
|
+
.mockReturnValueOnce(true);
|
|
1326
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1298
1327
|
|
|
1299
1328
|
const ui = (
|
|
1300
1329
|
<Dropzone>
|
|
@@ -1304,33 +1333,36 @@ describe('useDropzone() hook', () => {
|
|
|
1304
1333
|
</div>
|
|
1305
1334
|
)}
|
|
1306
1335
|
</Dropzone>
|
|
1307
|
-
)
|
|
1336
|
+
);
|
|
1337
|
+
|
|
1338
|
+
const { container } = render(ui);
|
|
1308
1339
|
|
|
1309
|
-
const
|
|
1340
|
+
const dropzone = container.querySelector("div");
|
|
1310
1341
|
|
|
1311
|
-
|
|
1342
|
+
fireEvent.click(dropzone);
|
|
1343
|
+
drainTimers();
|
|
1312
1344
|
|
|
1313
|
-
|
|
1314
|
-
|
|
1345
|
+
expect(onClickSpy).toHaveBeenCalled();
|
|
1346
|
+
jest.useRealTimers();
|
|
1347
|
+
isIeOrEdgeSpy.mockClear();
|
|
1348
|
+
});
|
|
1315
1349
|
|
|
1316
|
-
|
|
1317
|
-
jest.
|
|
1318
|
-
isIeOrEdgeSpy.mockClear()
|
|
1319
|
-
})
|
|
1350
|
+
it("should not use showOpenFilePicker() if supported and {useFsAccessApi} is not true", async () => {
|
|
1351
|
+
jest.useFakeTimers();
|
|
1320
1352
|
|
|
1321
|
-
|
|
1322
|
-
const
|
|
1323
|
-
const
|
|
1324
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, 'click')
|
|
1353
|
+
const activeRef = createRef();
|
|
1354
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
1355
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1325
1356
|
|
|
1326
|
-
const handlers = files.map(f => createFileSystemFileHandle(f))
|
|
1327
|
-
const
|
|
1328
|
-
|
|
1357
|
+
const handlers = files.map((f) => createFileSystemFileHandle(f));
|
|
1358
|
+
const showOpenFilePickerMock = jest
|
|
1359
|
+
.fn()
|
|
1360
|
+
.mockReturnValue(Promise.resolve(handlers));
|
|
1329
1361
|
|
|
1330
|
-
window.showOpenFilePicker = showOpenFilePickerMock
|
|
1362
|
+
window.showOpenFilePicker = showOpenFilePickerMock;
|
|
1331
1363
|
|
|
1332
|
-
const onDropSpy = jest.fn()
|
|
1333
|
-
const onFileDialogOpenSpy = jest.fn()
|
|
1364
|
+
const onDropSpy = jest.fn();
|
|
1365
|
+
const onFileDialogOpenSpy = jest.fn();
|
|
1334
1366
|
|
|
1335
1367
|
const ui = (
|
|
1336
1368
|
<Dropzone
|
|
@@ -1338,6 +1370,7 @@ describe('useDropzone() hook', () => {
|
|
|
1338
1370
|
onFileDialogOpen={onFileDialogOpenSpy}
|
|
1339
1371
|
accept="application/pdf"
|
|
1340
1372
|
multiple
|
|
1373
|
+
useFsAccessApi={false}
|
|
1341
1374
|
>
|
|
1342
1375
|
{({ getRootProps, getInputProps, isFileDialogActive }) => (
|
|
1343
1376
|
<div {...getRootProps()}>
|
|
@@ -1346,121 +1379,252 @@ describe('useDropzone() hook', () => {
|
|
|
1346
1379
|
</div>
|
|
1347
1380
|
)}
|
|
1348
1381
|
</Dropzone>
|
|
1349
|
-
)
|
|
1382
|
+
);
|
|
1350
1383
|
|
|
1351
|
-
const { container, rerender } = render(ui)
|
|
1384
|
+
const { container, rerender } = render(ui);
|
|
1352
1385
|
|
|
1353
|
-
const dropzone = container.querySelector(
|
|
1386
|
+
const dropzone = container.querySelector("div");
|
|
1354
1387
|
|
|
1355
|
-
fireEvent.click(dropzone)
|
|
1388
|
+
fireEvent.click(dropzone);
|
|
1356
1389
|
|
|
1357
|
-
await flushPromises(rerender, ui)
|
|
1390
|
+
await flushPromises(rerender, ui);
|
|
1358
1391
|
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
expect(onFileDialogOpenSpy).toHaveBeenCalled()
|
|
1392
|
+
dispatchEvt(document.body, "focus");
|
|
1393
|
+
drainTimers();
|
|
1362
1394
|
|
|
1363
|
-
|
|
1364
|
-
await flushPromises(rerender, ui)
|
|
1395
|
+
expect(onFileDialogOpenSpy).toHaveBeenCalled();
|
|
1365
1396
|
|
|
1366
|
-
expect(activeRef.current).toBeNull()
|
|
1367
|
-
expect(dropzone).not.toContainElement(activeRef.current)
|
|
1368
|
-
expect(onClickSpy).
|
|
1369
|
-
expect(showOpenFilePickerMock).
|
|
1370
|
-
|
|
1371
|
-
types: [{
|
|
1372
|
-
description: 'everything',
|
|
1373
|
-
accept: {'application/pdf': []}
|
|
1374
|
-
}]
|
|
1375
|
-
})
|
|
1376
|
-
expect(onDropSpy).toHaveBeenCalledWith(files, [], null)
|
|
1377
|
-
})
|
|
1397
|
+
expect(activeRef.current).toBeNull();
|
|
1398
|
+
expect(dropzone).not.toContainElement(activeRef.current);
|
|
1399
|
+
expect(onClickSpy).toHaveBeenCalled();
|
|
1400
|
+
expect(showOpenFilePickerMock).not.toHaveBeenCalled();
|
|
1401
|
+
expect(onDropSpy).not.toHaveBeenCalled();
|
|
1378
1402
|
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
const active = <span ref={activeRef}>I am active</span>
|
|
1403
|
+
jest.useRealTimers();
|
|
1404
|
+
});
|
|
1382
1405
|
|
|
1383
|
-
|
|
1384
|
-
|
|
1406
|
+
it("should not use showOpenFilePicker() if supported and {isSecureContext} is not true", async () => {
|
|
1407
|
+
jest.useFakeTimers();
|
|
1385
1408
|
|
|
1386
|
-
|
|
1409
|
+
const activeRef = createRef();
|
|
1410
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
1411
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1387
1412
|
|
|
1388
|
-
const
|
|
1389
|
-
const
|
|
1413
|
+
const handlers = files.map((f) => createFileSystemFileHandle(f));
|
|
1414
|
+
const showOpenFilePickerMock = jest
|
|
1415
|
+
.fn()
|
|
1416
|
+
.mockReturnValue(Promise.resolve(handlers));
|
|
1417
|
+
|
|
1418
|
+
window.showOpenFilePicker = showOpenFilePickerMock;
|
|
1419
|
+
window.isSecureContext = false;
|
|
1420
|
+
|
|
1421
|
+
const onDropSpy = jest.fn();
|
|
1422
|
+
const onFileDialogOpenSpy = jest.fn();
|
|
1390
1423
|
|
|
1391
1424
|
const ui = (
|
|
1392
|
-
<Dropzone
|
|
1393
|
-
{
|
|
1425
|
+
<Dropzone
|
|
1426
|
+
onDrop={onDropSpy}
|
|
1427
|
+
onFileDialogOpen={onFileDialogOpenSpy}
|
|
1428
|
+
accept="application/pdf"
|
|
1429
|
+
multiple
|
|
1430
|
+
>
|
|
1431
|
+
{({ getRootProps, getInputProps, isFileDialogActive }) => (
|
|
1394
1432
|
<div {...getRootProps()}>
|
|
1433
|
+
<input {...getInputProps()} />
|
|
1395
1434
|
{isFileDialogActive && active}
|
|
1396
1435
|
</div>
|
|
1397
1436
|
)}
|
|
1398
1437
|
</Dropzone>
|
|
1399
|
-
)
|
|
1438
|
+
);
|
|
1439
|
+
|
|
1440
|
+
const { container, rerender } = render(ui);
|
|
1441
|
+
|
|
1442
|
+
const dropzone = container.querySelector("div");
|
|
1443
|
+
|
|
1444
|
+
fireEvent.click(dropzone);
|
|
1400
1445
|
|
|
1401
|
-
|
|
1446
|
+
await flushPromises(rerender, ui);
|
|
1402
1447
|
|
|
1403
|
-
|
|
1448
|
+
dispatchEvt(document.body, "focus");
|
|
1449
|
+
drainTimers();
|
|
1404
1450
|
|
|
1405
|
-
|
|
1406
|
-
await flushPromises(rerender, ui)
|
|
1407
|
-
const ref = activeRef.current
|
|
1408
|
-
expect(ref).toBeNull() // We expect the dialog to be closed at this point
|
|
1409
|
-
expect(dropzone).not.toContainElement(ref)
|
|
1410
|
-
expect(showOpenFilePickerMock).toHaveBeenCalled()
|
|
1411
|
-
expect(onDropSpy).toHaveBeenCalledWith(files, [], null)
|
|
1412
|
-
expect(onFileDialogOpenSpy).toHaveBeenCalled()
|
|
1413
|
-
})
|
|
1451
|
+
expect(onFileDialogOpenSpy).toHaveBeenCalled();
|
|
1414
1452
|
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1453
|
+
expect(activeRef.current).toBeNull();
|
|
1454
|
+
expect(dropzone).not.toContainElement(activeRef.current);
|
|
1455
|
+
expect(onClickSpy).toHaveBeenCalled();
|
|
1456
|
+
expect(showOpenFilePickerMock).not.toHaveBeenCalled();
|
|
1457
|
+
expect(onDropSpy).not.toHaveBeenCalled();
|
|
1418
1458
|
|
|
1419
|
-
|
|
1459
|
+
jest.useRealTimers();
|
|
1420
1460
|
|
|
1421
|
-
window.
|
|
1461
|
+
window.isSecureContext = true;
|
|
1462
|
+
});
|
|
1422
1463
|
|
|
1423
|
-
|
|
1424
|
-
const
|
|
1464
|
+
it("should use showOpenFilePicker() if supported and {useFsAccessApi} is true, and not trigger click on input", async () => {
|
|
1465
|
+
const activeRef = createRef();
|
|
1466
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
1467
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1468
|
+
|
|
1469
|
+
const handlers = files.map((f) => createFileSystemFileHandle(f));
|
|
1470
|
+
const thenable = createThenable();
|
|
1471
|
+
const showOpenFilePickerMock = jest
|
|
1472
|
+
.fn()
|
|
1473
|
+
.mockReturnValue(thenable.promise);
|
|
1474
|
+
|
|
1475
|
+
window.showOpenFilePicker = showOpenFilePickerMock;
|
|
1476
|
+
|
|
1477
|
+
const onDropSpy = jest.fn();
|
|
1478
|
+
const onFileDialogOpenSpy = jest.fn();
|
|
1425
1479
|
|
|
1426
1480
|
const ui = (
|
|
1427
|
-
<Dropzone
|
|
1428
|
-
{
|
|
1481
|
+
<Dropzone
|
|
1482
|
+
onDrop={onDropSpy}
|
|
1483
|
+
onFileDialogOpen={onFileDialogOpenSpy}
|
|
1484
|
+
accept="application/pdf"
|
|
1485
|
+
multiple
|
|
1486
|
+
useFsAccessApi
|
|
1487
|
+
>
|
|
1488
|
+
{({ getRootProps, getInputProps, isFileDialogActive }) => (
|
|
1429
1489
|
<div {...getRootProps()}>
|
|
1490
|
+
<input {...getInputProps()} />
|
|
1430
1491
|
{isFileDialogActive && active}
|
|
1431
1492
|
</div>
|
|
1432
1493
|
)}
|
|
1433
1494
|
</Dropzone>
|
|
1434
|
-
)
|
|
1495
|
+
);
|
|
1496
|
+
|
|
1497
|
+
const { container, rerender } = render(ui);
|
|
1498
|
+
|
|
1499
|
+
const dropzone = container.querySelector("div");
|
|
1500
|
+
|
|
1501
|
+
fireEvent.click(dropzone);
|
|
1502
|
+
|
|
1503
|
+
await flushPromises(rerender, ui);
|
|
1504
|
+
|
|
1505
|
+
expect(activeRef.current).not.toBeNull();
|
|
1506
|
+
expect(dropzone).toContainElement(activeRef.current);
|
|
1507
|
+
expect(onFileDialogOpenSpy).toHaveBeenCalled();
|
|
1508
|
+
|
|
1509
|
+
thenable.done(handlers);
|
|
1510
|
+
await flushPromises(rerender, ui);
|
|
1511
|
+
|
|
1512
|
+
expect(activeRef.current).toBeNull(); // We expect the dialog to be closed at this point
|
|
1513
|
+
expect(dropzone).not.toContainElement(activeRef.current);
|
|
1514
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1515
|
+
expect(showOpenFilePickerMock).toHaveBeenCalledWith({
|
|
1516
|
+
multiple: true,
|
|
1517
|
+
types: [
|
|
1518
|
+
{
|
|
1519
|
+
description: "everything",
|
|
1520
|
+
accept: { "application/pdf": [] },
|
|
1521
|
+
},
|
|
1522
|
+
],
|
|
1523
|
+
});
|
|
1524
|
+
expect(onDropSpy).toHaveBeenCalledWith(files, [], null);
|
|
1525
|
+
});
|
|
1526
|
+
|
|
1527
|
+
test("if showOpenFilePicker() is supported and {useFsAccessApi} is true, it should work without the <input>", async () => {
|
|
1528
|
+
const activeRef = createRef();
|
|
1529
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
1530
|
+
|
|
1531
|
+
const handlers = files.map((f) => createFileSystemFileHandle(f));
|
|
1532
|
+
const showOpenFilePickerMock = jest
|
|
1533
|
+
.fn()
|
|
1534
|
+
.mockReturnValue(Promise.resolve(handlers));
|
|
1535
|
+
|
|
1536
|
+
window.showOpenFilePicker = showOpenFilePickerMock;
|
|
1537
|
+
|
|
1538
|
+
const onDropSpy = jest.fn();
|
|
1539
|
+
const onFileDialogOpenSpy = jest.fn();
|
|
1540
|
+
|
|
1541
|
+
const ui = (
|
|
1542
|
+
<Dropzone
|
|
1543
|
+
onDrop={onDropSpy}
|
|
1544
|
+
onFileDialogOpen={onFileDialogOpenSpy}
|
|
1545
|
+
useFsAccessApi
|
|
1546
|
+
>
|
|
1547
|
+
{({ getRootProps, isFileDialogActive }) => (
|
|
1548
|
+
<div {...getRootProps()}>{isFileDialogActive && active}</div>
|
|
1549
|
+
)}
|
|
1550
|
+
</Dropzone>
|
|
1551
|
+
);
|
|
1552
|
+
|
|
1553
|
+
const { container, rerender } = render(ui);
|
|
1554
|
+
|
|
1555
|
+
const dropzone = container.querySelector("div");
|
|
1556
|
+
|
|
1557
|
+
fireEvent.click(dropzone);
|
|
1558
|
+
await flushPromises(rerender, ui);
|
|
1559
|
+
const ref = activeRef.current;
|
|
1560
|
+
expect(ref).toBeNull(); // We expect the dialog to be closed at this point
|
|
1561
|
+
expect(dropzone).not.toContainElement(ref);
|
|
1562
|
+
expect(showOpenFilePickerMock).toHaveBeenCalled();
|
|
1563
|
+
expect(onDropSpy).toHaveBeenCalledWith(files, [], null);
|
|
1564
|
+
expect(onFileDialogOpenSpy).toHaveBeenCalled();
|
|
1565
|
+
});
|
|
1566
|
+
|
|
1567
|
+
test("if showOpenFilePicker() is supported and {useFsAccessApi} is true, and the user cancels it should call onFileDialogCancel", async () => {
|
|
1568
|
+
const activeRef = createRef();
|
|
1569
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
1570
|
+
|
|
1571
|
+
const showOpenFilePickerMock = jest
|
|
1572
|
+
.fn()
|
|
1573
|
+
.mockReturnValue(
|
|
1574
|
+
Promise.reject(new DOMException("user aborted request", "AbortError"))
|
|
1575
|
+
);
|
|
1576
|
+
|
|
1577
|
+
window.showOpenFilePicker = showOpenFilePickerMock;
|
|
1578
|
+
|
|
1579
|
+
const onDropSpy = jest.fn();
|
|
1580
|
+
const onFileDialogCancelSpy = jest.fn();
|
|
1581
|
+
|
|
1582
|
+
const ui = (
|
|
1583
|
+
<Dropzone
|
|
1584
|
+
onDrop={onDropSpy}
|
|
1585
|
+
onFileDialogCancel={onFileDialogCancelSpy}
|
|
1586
|
+
useFsAccessApi
|
|
1587
|
+
>
|
|
1588
|
+
{({ getRootProps, isFileDialogActive }) => (
|
|
1589
|
+
<div {...getRootProps()}>{isFileDialogActive && active}</div>
|
|
1590
|
+
)}
|
|
1591
|
+
</Dropzone>
|
|
1592
|
+
);
|
|
1435
1593
|
|
|
1436
|
-
const { container, rerender } = render(ui)
|
|
1594
|
+
const { container, rerender } = render(ui);
|
|
1437
1595
|
|
|
1438
|
-
const dropzone = container.querySelector(
|
|
1596
|
+
const dropzone = container.querySelector("div");
|
|
1439
1597
|
|
|
1440
|
-
fireEvent.click(dropzone)
|
|
1441
|
-
await flushPromises(rerender, ui)
|
|
1442
|
-
const ref = activeRef.current
|
|
1443
|
-
expect(ref).toBeNull() // We expect the dialog to be closed at this point
|
|
1444
|
-
expect(dropzone).not.toContainElement(ref)
|
|
1445
|
-
expect(showOpenFilePickerMock).toHaveBeenCalled()
|
|
1446
|
-
expect(onDropSpy).not.toHaveBeenCalled()
|
|
1447
|
-
expect(onFileDialogCancelSpy).toHaveBeenCalled()
|
|
1448
|
-
})
|
|
1598
|
+
fireEvent.click(dropzone);
|
|
1599
|
+
await flushPromises(rerender, ui);
|
|
1600
|
+
const ref = activeRef.current;
|
|
1601
|
+
expect(ref).toBeNull(); // We expect the dialog to be closed at this point
|
|
1602
|
+
expect(dropzone).not.toContainElement(ref);
|
|
1603
|
+
expect(showOpenFilePickerMock).toHaveBeenCalled();
|
|
1604
|
+
expect(onDropSpy).not.toHaveBeenCalled();
|
|
1605
|
+
expect(onFileDialogCancelSpy).toHaveBeenCalled();
|
|
1606
|
+
});
|
|
1449
1607
|
|
|
1450
|
-
test(
|
|
1451
|
-
jest.useFakeTimers()
|
|
1608
|
+
test("window focus evt is not bound if showOpenFilePicker() is supported and {useFsAccessApi} is true", async () => {
|
|
1609
|
+
jest.useFakeTimers();
|
|
1452
1610
|
|
|
1453
|
-
const activeRef = createRef()
|
|
1454
|
-
const active = <span ref={activeRef}>I am active</span
|
|
1455
|
-
const onFileDialogCancelSpy = jest.fn()
|
|
1611
|
+
const activeRef = createRef();
|
|
1612
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
1613
|
+
const onFileDialogCancelSpy = jest.fn();
|
|
1456
1614
|
|
|
1457
|
-
const thenable = createThenable()
|
|
1458
|
-
const showOpenFilePickerMock = jest
|
|
1615
|
+
const thenable = createThenable();
|
|
1616
|
+
const showOpenFilePickerMock = jest
|
|
1617
|
+
.fn()
|
|
1618
|
+
.mockReturnValue(thenable.promise);
|
|
1459
1619
|
|
|
1460
|
-
window.showOpenFilePicker = showOpenFilePickerMock
|
|
1620
|
+
window.showOpenFilePicker = showOpenFilePickerMock;
|
|
1461
1621
|
|
|
1462
1622
|
const ui = (
|
|
1463
|
-
<Dropzone
|
|
1623
|
+
<Dropzone
|
|
1624
|
+
onFileDialogCancel={onFileDialogCancelSpy}
|
|
1625
|
+
noClick
|
|
1626
|
+
useFsAccessApi
|
|
1627
|
+
>
|
|
1464
1628
|
{({ getRootProps, isFileDialogActive, open }) => (
|
|
1465
1629
|
<div {...getRootProps()}>
|
|
1466
1630
|
{isFileDialogActive && active}
|
|
@@ -1470,39 +1634,39 @@ describe('useDropzone() hook', () => {
|
|
|
1470
1634
|
</div>
|
|
1471
1635
|
)}
|
|
1472
1636
|
</Dropzone>
|
|
1473
|
-
)
|
|
1637
|
+
);
|
|
1474
1638
|
|
|
1475
|
-
const { container, rerender } = render(ui)
|
|
1639
|
+
const { container, rerender } = render(ui);
|
|
1476
1640
|
|
|
1477
|
-
const dropzone = container.querySelector(
|
|
1478
|
-
const btn = container.querySelector(
|
|
1641
|
+
const dropzone = container.querySelector("div");
|
|
1642
|
+
const btn = container.querySelector("button");
|
|
1479
1643
|
|
|
1480
|
-
btn.click()
|
|
1481
|
-
drainTimers()
|
|
1482
|
-
await flushPromises(rerender, ui)
|
|
1644
|
+
btn.click();
|
|
1645
|
+
drainTimers();
|
|
1646
|
+
await flushPromises(rerender, ui);
|
|
1483
1647
|
|
|
1484
|
-
const ref = activeRef.current
|
|
1485
|
-
expect(ref).not.toBeNull()
|
|
1486
|
-
expect(dropzone).toContainElement(ref)
|
|
1648
|
+
const ref = activeRef.current;
|
|
1649
|
+
expect(ref).not.toBeNull();
|
|
1650
|
+
expect(dropzone).toContainElement(ref);
|
|
1487
1651
|
|
|
1488
|
-
thenable.cancel(new DOMException(
|
|
1652
|
+
thenable.cancel(new DOMException("user aborted request", "AbortError"));
|
|
1489
1653
|
|
|
1490
|
-
dispatchEvt(document.body,
|
|
1491
|
-
drainTimers()
|
|
1492
|
-
await flushPromises(rerender, ui)
|
|
1654
|
+
dispatchEvt(document.body, "focus");
|
|
1655
|
+
drainTimers();
|
|
1656
|
+
await flushPromises(rerender, ui);
|
|
1493
1657
|
|
|
1494
|
-
expect(onFileDialogCancelSpy).toHaveBeenCalledTimes(1)
|
|
1495
|
-
expect(dropzone).not.toContainElement(ref)
|
|
1658
|
+
expect(onFileDialogCancelSpy).toHaveBeenCalledTimes(1);
|
|
1659
|
+
expect(dropzone).not.toContainElement(ref);
|
|
1496
1660
|
|
|
1497
|
-
jest.useRealTimers()
|
|
1498
|
-
})
|
|
1499
|
-
})
|
|
1661
|
+
jest.useRealTimers();
|
|
1662
|
+
});
|
|
1663
|
+
});
|
|
1500
1664
|
|
|
1501
|
-
describe(
|
|
1502
|
-
it(
|
|
1503
|
-
const activeRef = createRef()
|
|
1504
|
-
const active = <span ref={activeRef}>I am active</span
|
|
1505
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1665
|
+
describe("onKeyDown", () => {
|
|
1666
|
+
it("triggers the click event on the input if the SPACE/ENTER keys are pressed", () => {
|
|
1667
|
+
const activeRef = createRef();
|
|
1668
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
1669
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1506
1670
|
const { container } = render(
|
|
1507
1671
|
<Dropzone>
|
|
1508
1672
|
{({ getRootProps, getInputProps, isFileDialogActive }) => (
|
|
@@ -1512,26 +1676,26 @@ describe('useDropzone() hook', () => {
|
|
|
1512
1676
|
</div>
|
|
1513
1677
|
)}
|
|
1514
1678
|
</Dropzone>
|
|
1515
|
-
)
|
|
1679
|
+
);
|
|
1516
1680
|
|
|
1517
|
-
const dropzone = container.querySelector(
|
|
1681
|
+
const dropzone = container.querySelector("div");
|
|
1518
1682
|
|
|
1519
1683
|
fireEvent.keyDown(dropzone, {
|
|
1520
|
-
keyCode: 32
|
|
1521
|
-
})
|
|
1684
|
+
keyCode: 32,
|
|
1685
|
+
});
|
|
1522
1686
|
|
|
1523
1687
|
fireEvent.keyDown(dropzone, {
|
|
1524
|
-
keyCode: 13
|
|
1525
|
-
})
|
|
1688
|
+
keyCode: 13,
|
|
1689
|
+
});
|
|
1526
1690
|
|
|
1527
|
-
const ref = activeRef.current
|
|
1528
|
-
expect(ref).not.toBeNull()
|
|
1529
|
-
expect(dropzone).toContainElement(ref)
|
|
1530
|
-
expect(onClickSpy).toHaveBeenCalledTimes(2)
|
|
1531
|
-
})
|
|
1691
|
+
const ref = activeRef.current;
|
|
1692
|
+
expect(ref).not.toBeNull();
|
|
1693
|
+
expect(dropzone).toContainElement(ref);
|
|
1694
|
+
expect(onClickSpy).toHaveBeenCalledTimes(2);
|
|
1695
|
+
});
|
|
1532
1696
|
|
|
1533
|
-
it(
|
|
1534
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1697
|
+
it("does not trigger the click event on the input if the dropzone is not in focus", () => {
|
|
1698
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1535
1699
|
const { container } = render(
|
|
1536
1700
|
<Dropzone>
|
|
1537
1701
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -1540,39 +1704,43 @@ describe('useDropzone() hook', () => {
|
|
|
1540
1704
|
</div>
|
|
1541
1705
|
)}
|
|
1542
1706
|
</Dropzone>
|
|
1543
|
-
)
|
|
1707
|
+
);
|
|
1544
1708
|
|
|
1545
|
-
const input = container.querySelector(
|
|
1709
|
+
const input = container.querySelector("input");
|
|
1546
1710
|
|
|
1547
1711
|
fireEvent.keyDown(input, {
|
|
1548
|
-
keyCode: 32
|
|
1549
|
-
})
|
|
1712
|
+
keyCode: 32,
|
|
1713
|
+
});
|
|
1550
1714
|
|
|
1551
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
1552
|
-
})
|
|
1715
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1716
|
+
});
|
|
1553
1717
|
|
|
1554
|
-
it(
|
|
1555
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1718
|
+
it("does not trigger the click event on the input if event propagation was stopped", () => {
|
|
1719
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1556
1720
|
const { container } = render(
|
|
1557
1721
|
<Dropzone>
|
|
1558
1722
|
{({ getRootProps, getInputProps }) => (
|
|
1559
|
-
<div
|
|
1723
|
+
<div
|
|
1724
|
+
{...getRootProps({
|
|
1725
|
+
onKeyDown: (event) => event.stopPropagation(),
|
|
1726
|
+
})}
|
|
1727
|
+
>
|
|
1560
1728
|
<input {...getInputProps()} />
|
|
1561
1729
|
</div>
|
|
1562
1730
|
)}
|
|
1563
1731
|
</Dropzone>
|
|
1564
|
-
)
|
|
1732
|
+
);
|
|
1565
1733
|
|
|
1566
|
-
const dropzone = container.querySelector(
|
|
1734
|
+
const dropzone = container.querySelector("div");
|
|
1567
1735
|
|
|
1568
1736
|
fireEvent.keyDown(dropzone, {
|
|
1569
|
-
keyCode: 32
|
|
1570
|
-
})
|
|
1571
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
1572
|
-
})
|
|
1737
|
+
keyCode: 32,
|
|
1738
|
+
});
|
|
1739
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1740
|
+
});
|
|
1573
1741
|
|
|
1574
|
-
it(
|
|
1575
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1742
|
+
it("does not trigger the click event on the input if {noKeyboard} is true", () => {
|
|
1743
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1576
1744
|
const { container } = render(
|
|
1577
1745
|
<Dropzone noKeyboard>
|
|
1578
1746
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -1581,18 +1749,18 @@ describe('useDropzone() hook', () => {
|
|
|
1581
1749
|
</div>
|
|
1582
1750
|
)}
|
|
1583
1751
|
</Dropzone>
|
|
1584
|
-
)
|
|
1752
|
+
);
|
|
1585
1753
|
|
|
1586
|
-
const dropzone = container.querySelector(
|
|
1754
|
+
const dropzone = container.querySelector("div");
|
|
1587
1755
|
|
|
1588
1756
|
fireEvent.keyDown(dropzone, {
|
|
1589
|
-
keyCode: 32
|
|
1590
|
-
})
|
|
1591
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
1592
|
-
})
|
|
1757
|
+
keyCode: 32,
|
|
1758
|
+
});
|
|
1759
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1760
|
+
});
|
|
1593
1761
|
|
|
1594
|
-
it(
|
|
1595
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1762
|
+
it("restores the keydown behavior when {noKeyboard} is set back to false", () => {
|
|
1763
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1596
1764
|
const { container, rerender } = render(
|
|
1597
1765
|
<Dropzone noKeyboard>
|
|
1598
1766
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -1601,14 +1769,14 @@ describe('useDropzone() hook', () => {
|
|
|
1601
1769
|
</div>
|
|
1602
1770
|
)}
|
|
1603
1771
|
</Dropzone>
|
|
1604
|
-
)
|
|
1772
|
+
);
|
|
1605
1773
|
|
|
1606
|
-
const dropzone = container.querySelector(
|
|
1774
|
+
const dropzone = container.querySelector("div");
|
|
1607
1775
|
|
|
1608
1776
|
fireEvent.keyDown(dropzone, {
|
|
1609
|
-
keyCode: 32
|
|
1610
|
-
})
|
|
1611
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
1777
|
+
keyCode: 32,
|
|
1778
|
+
});
|
|
1779
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1612
1780
|
|
|
1613
1781
|
rerender(
|
|
1614
1782
|
<Dropzone noKeyboard={false}>
|
|
@@ -1618,16 +1786,16 @@ describe('useDropzone() hook', () => {
|
|
|
1618
1786
|
</div>
|
|
1619
1787
|
)}
|
|
1620
1788
|
</Dropzone>
|
|
1621
|
-
)
|
|
1789
|
+
);
|
|
1622
1790
|
|
|
1623
1791
|
fireEvent.keyDown(dropzone, {
|
|
1624
|
-
keyCode: 32
|
|
1625
|
-
})
|
|
1626
|
-
expect(onClickSpy).toHaveBeenCalled()
|
|
1627
|
-
})
|
|
1792
|
+
keyCode: 32,
|
|
1793
|
+
});
|
|
1794
|
+
expect(onClickSpy).toHaveBeenCalled();
|
|
1795
|
+
});
|
|
1628
1796
|
|
|
1629
|
-
it(
|
|
1630
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
1797
|
+
it("does not trigger the click event on the input for other keys", () => {
|
|
1798
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
1631
1799
|
const { container } = render(
|
|
1632
1800
|
<Dropzone>
|
|
1633
1801
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -1636,27 +1804,27 @@ describe('useDropzone() hook', () => {
|
|
|
1636
1804
|
</div>
|
|
1637
1805
|
)}
|
|
1638
1806
|
</Dropzone>
|
|
1639
|
-
)
|
|
1807
|
+
);
|
|
1640
1808
|
|
|
1641
|
-
const dropzone = container.querySelector(
|
|
1809
|
+
const dropzone = container.querySelector("div");
|
|
1642
1810
|
|
|
1643
1811
|
fireEvent.keyDown(dropzone, {
|
|
1644
|
-
keyCode: 97
|
|
1645
|
-
})
|
|
1646
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
1647
|
-
})
|
|
1648
|
-
})
|
|
1812
|
+
keyCode: 97,
|
|
1813
|
+
});
|
|
1814
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
1815
|
+
});
|
|
1816
|
+
});
|
|
1649
1817
|
|
|
1650
|
-
describe(
|
|
1651
|
-
it(
|
|
1652
|
-
const data = createDtWithFiles(files)
|
|
1818
|
+
describe("onDrag*", () => {
|
|
1819
|
+
it("invokes callbacks for the appropriate events", async () => {
|
|
1820
|
+
const data = createDtWithFiles(files);
|
|
1653
1821
|
|
|
1654
1822
|
const props = {
|
|
1655
1823
|
onDragEnter: jest.fn(),
|
|
1656
1824
|
onDragOver: jest.fn(),
|
|
1657
1825
|
onDragLeave: jest.fn(),
|
|
1658
|
-
onDrop: jest.fn()
|
|
1659
|
-
}
|
|
1826
|
+
onDrop: jest.fn(),
|
|
1827
|
+
};
|
|
1660
1828
|
|
|
1661
1829
|
const ui = (
|
|
1662
1830
|
<Dropzone {...props}>
|
|
@@ -1666,27 +1834,27 @@ describe('useDropzone() hook', () => {
|
|
|
1666
1834
|
</div>
|
|
1667
1835
|
)}
|
|
1668
1836
|
</Dropzone>
|
|
1669
|
-
)
|
|
1670
|
-
const { container, rerender } = render(ui)
|
|
1671
|
-
const dropzone = container.querySelector(
|
|
1837
|
+
);
|
|
1838
|
+
const { container, rerender } = render(ui);
|
|
1839
|
+
const dropzone = container.querySelector("div");
|
|
1672
1840
|
|
|
1673
|
-
fireDragEnter(dropzone, data)
|
|
1674
|
-
await flushPromises(rerender, ui)
|
|
1675
|
-
expect(props.onDragEnter).toHaveBeenCalled()
|
|
1841
|
+
fireDragEnter(dropzone, data);
|
|
1842
|
+
await flushPromises(rerender, ui);
|
|
1843
|
+
expect(props.onDragEnter).toHaveBeenCalled();
|
|
1676
1844
|
|
|
1677
|
-
fireDragOver(dropzone, data)
|
|
1678
|
-
expect(props.onDragOver).toHaveBeenCalled()
|
|
1845
|
+
fireDragOver(dropzone, data);
|
|
1846
|
+
expect(props.onDragOver).toHaveBeenCalled();
|
|
1679
1847
|
|
|
1680
|
-
fireDragLeave(dropzone, data)
|
|
1681
|
-
expect(props.onDragLeave).toHaveBeenCalled()
|
|
1848
|
+
fireDragLeave(dropzone, data);
|
|
1849
|
+
expect(props.onDragLeave).toHaveBeenCalled();
|
|
1682
1850
|
|
|
1683
|
-
fireDrop(dropzone, data)
|
|
1684
|
-
await flushPromises(rerender, ui)
|
|
1685
|
-
expect(props.onDrop).toHaveBeenCalled()
|
|
1686
|
-
})
|
|
1851
|
+
fireDrop(dropzone, data);
|
|
1852
|
+
await flushPromises(rerender, ui);
|
|
1853
|
+
expect(props.onDrop).toHaveBeenCalled();
|
|
1854
|
+
});
|
|
1687
1855
|
|
|
1688
|
-
it(
|
|
1689
|
-
const emptyData = createDtWithFiles([])
|
|
1856
|
+
it("invokes callbacks for the appropriate events even if it cannot access the data", async () => {
|
|
1857
|
+
const emptyData = createDtWithFiles([]);
|
|
1690
1858
|
|
|
1691
1859
|
const props = {
|
|
1692
1860
|
onDragEnter: jest.fn(),
|
|
@@ -1694,8 +1862,8 @@ describe('useDropzone() hook', () => {
|
|
|
1694
1862
|
onDragLeave: jest.fn(),
|
|
1695
1863
|
onDrop: jest.fn(),
|
|
1696
1864
|
onDropAccepted: jest.fn(),
|
|
1697
|
-
onDropRejected: jest.fn()
|
|
1698
|
-
}
|
|
1865
|
+
onDropRejected: jest.fn(),
|
|
1866
|
+
};
|
|
1699
1867
|
|
|
1700
1868
|
const ui = (
|
|
1701
1869
|
<Dropzone {...props}>
|
|
@@ -1705,35 +1873,38 @@ describe('useDropzone() hook', () => {
|
|
|
1705
1873
|
</div>
|
|
1706
1874
|
)}
|
|
1707
1875
|
</Dropzone>
|
|
1708
|
-
)
|
|
1709
|
-
const { container, rerender } = render(ui)
|
|
1710
|
-
const dropzone = container.querySelector(
|
|
1876
|
+
);
|
|
1877
|
+
const { container, rerender } = render(ui);
|
|
1878
|
+
const dropzone = container.querySelector("div");
|
|
1711
1879
|
|
|
1712
|
-
fireDragEnter(dropzone, emptyData)
|
|
1713
|
-
await flushPromises(rerender, ui)
|
|
1714
|
-
expect(props.onDragEnter).toHaveBeenCalled()
|
|
1880
|
+
fireDragEnter(dropzone, emptyData);
|
|
1881
|
+
await flushPromises(rerender, ui);
|
|
1882
|
+
expect(props.onDragEnter).toHaveBeenCalled();
|
|
1715
1883
|
|
|
1716
|
-
fireDragOver(dropzone, emptyData)
|
|
1717
|
-
expect(props.onDragOver).toHaveBeenCalled()
|
|
1884
|
+
fireDragOver(dropzone, emptyData);
|
|
1885
|
+
expect(props.onDragOver).toHaveBeenCalled();
|
|
1718
1886
|
|
|
1719
|
-
fireDragLeave(dropzone, emptyData)
|
|
1720
|
-
expect(props.onDragLeave).toHaveBeenCalled()
|
|
1887
|
+
fireDragLeave(dropzone, emptyData);
|
|
1888
|
+
expect(props.onDragLeave).toHaveBeenCalled();
|
|
1721
1889
|
|
|
1722
|
-
const data = createDtWithFiles(files)
|
|
1723
|
-
fireDrop(dropzone, data)
|
|
1724
|
-
await flushPromises(rerender, ui)
|
|
1725
|
-
expect(props.onDrop).toHaveBeenCalled()
|
|
1726
|
-
expect(props.onDropAccepted).toHaveBeenCalledWith(
|
|
1727
|
-
|
|
1728
|
-
|
|
1890
|
+
const data = createDtWithFiles(files);
|
|
1891
|
+
fireDrop(dropzone, data);
|
|
1892
|
+
await flushPromises(rerender, ui);
|
|
1893
|
+
expect(props.onDrop).toHaveBeenCalled();
|
|
1894
|
+
expect(props.onDropAccepted).toHaveBeenCalledWith(
|
|
1895
|
+
files,
|
|
1896
|
+
expect.any(Object)
|
|
1897
|
+
);
|
|
1898
|
+
expect(props.onDropRejected).not.toHaveBeenCalled();
|
|
1899
|
+
});
|
|
1729
1900
|
|
|
1730
|
-
it(
|
|
1901
|
+
it("does not invoke callbacks if no files are detected", async () => {
|
|
1731
1902
|
const data = {
|
|
1732
1903
|
dataTransfer: {
|
|
1733
1904
|
items: [],
|
|
1734
|
-
types: [
|
|
1735
|
-
}
|
|
1736
|
-
}
|
|
1905
|
+
types: ["text/html", "text/plain"],
|
|
1906
|
+
},
|
|
1907
|
+
};
|
|
1737
1908
|
|
|
1738
1909
|
const props = {
|
|
1739
1910
|
onDragEnter: jest.fn(),
|
|
@@ -1741,8 +1912,8 @@ describe('useDropzone() hook', () => {
|
|
|
1741
1912
|
onDragLeave: jest.fn(),
|
|
1742
1913
|
onDrop: jest.fn(),
|
|
1743
1914
|
onDropAccepted: jest.fn(),
|
|
1744
|
-
onDropRejected: jest.fn()
|
|
1745
|
-
}
|
|
1915
|
+
onDropRejected: jest.fn(),
|
|
1916
|
+
};
|
|
1746
1917
|
|
|
1747
1918
|
const ui = (
|
|
1748
1919
|
<Dropzone {...props}>
|
|
@@ -1752,29 +1923,29 @@ describe('useDropzone() hook', () => {
|
|
|
1752
1923
|
</div>
|
|
1753
1924
|
)}
|
|
1754
1925
|
</Dropzone>
|
|
1755
|
-
)
|
|
1756
|
-
const { container, rerender } = render(ui)
|
|
1757
|
-
const dropzone = container.querySelector(
|
|
1926
|
+
);
|
|
1927
|
+
const { container, rerender } = render(ui);
|
|
1928
|
+
const dropzone = container.querySelector("div");
|
|
1758
1929
|
|
|
1759
|
-
fireDragEnter(dropzone, data)
|
|
1760
|
-
await flushPromises(rerender, ui)
|
|
1761
|
-
expect(props.onDragEnter).not.toHaveBeenCalled()
|
|
1930
|
+
fireDragEnter(dropzone, data);
|
|
1931
|
+
await flushPromises(rerender, ui);
|
|
1932
|
+
expect(props.onDragEnter).not.toHaveBeenCalled();
|
|
1762
1933
|
|
|
1763
|
-
fireDragOver(dropzone, data)
|
|
1764
|
-
expect(props.onDragOver).not.toHaveBeenCalled()
|
|
1934
|
+
fireDragOver(dropzone, data);
|
|
1935
|
+
expect(props.onDragOver).not.toHaveBeenCalled();
|
|
1765
1936
|
|
|
1766
|
-
fireDragLeave(dropzone, data)
|
|
1767
|
-
expect(props.onDragLeave).not.toHaveBeenCalled()
|
|
1937
|
+
fireDragLeave(dropzone, data);
|
|
1938
|
+
expect(props.onDragLeave).not.toHaveBeenCalled();
|
|
1768
1939
|
|
|
1769
|
-
fireDrop(dropzone, data)
|
|
1770
|
-
await flushPromises(rerender, ui)
|
|
1771
|
-
expect(props.onDrop).not.toHaveBeenCalled()
|
|
1772
|
-
expect(props.onDropAccepted).not.toHaveBeenCalled()
|
|
1773
|
-
expect(props.onDropRejected).not.toHaveBeenCalled()
|
|
1774
|
-
})
|
|
1940
|
+
fireDrop(dropzone, data);
|
|
1941
|
+
await flushPromises(rerender, ui);
|
|
1942
|
+
expect(props.onDrop).not.toHaveBeenCalled();
|
|
1943
|
+
expect(props.onDropAccepted).not.toHaveBeenCalled();
|
|
1944
|
+
expect(props.onDropRejected).not.toHaveBeenCalled();
|
|
1945
|
+
});
|
|
1775
1946
|
|
|
1776
|
-
it(
|
|
1777
|
-
const data = createDtWithFiles(files)
|
|
1947
|
+
it("does not invoke callbacks if {noDrag} is true", async () => {
|
|
1948
|
+
const data = createDtWithFiles(files);
|
|
1778
1949
|
|
|
1779
1950
|
const props = {
|
|
1780
1951
|
onDragEnter: jest.fn(),
|
|
@@ -1782,8 +1953,8 @@ describe('useDropzone() hook', () => {
|
|
|
1782
1953
|
onDragLeave: jest.fn(),
|
|
1783
1954
|
onDrop: jest.fn(),
|
|
1784
1955
|
onDropAccepted: jest.fn(),
|
|
1785
|
-
onDropRejected: jest.fn()
|
|
1786
|
-
}
|
|
1956
|
+
onDropRejected: jest.fn(),
|
|
1957
|
+
};
|
|
1787
1958
|
|
|
1788
1959
|
const ui = (
|
|
1789
1960
|
<Dropzone {...props} noDrag>
|
|
@@ -1793,36 +1964,36 @@ describe('useDropzone() hook', () => {
|
|
|
1793
1964
|
</div>
|
|
1794
1965
|
)}
|
|
1795
1966
|
</Dropzone>
|
|
1796
|
-
)
|
|
1797
|
-
const { container, rerender } = render(ui)
|
|
1798
|
-
const dropzone = container.querySelector(
|
|
1967
|
+
);
|
|
1968
|
+
const { container, rerender } = render(ui);
|
|
1969
|
+
const dropzone = container.querySelector("div");
|
|
1799
1970
|
|
|
1800
|
-
fireDragEnter(dropzone, data)
|
|
1801
|
-
await flushPromises(rerender, ui)
|
|
1802
|
-
expect(props.onDragEnter).not.toHaveBeenCalled()
|
|
1971
|
+
fireDragEnter(dropzone, data);
|
|
1972
|
+
await flushPromises(rerender, ui);
|
|
1973
|
+
expect(props.onDragEnter).not.toHaveBeenCalled();
|
|
1803
1974
|
|
|
1804
|
-
fireDragOver(dropzone, data)
|
|
1805
|
-
expect(props.onDragOver).not.toHaveBeenCalled()
|
|
1975
|
+
fireDragOver(dropzone, data);
|
|
1976
|
+
expect(props.onDragOver).not.toHaveBeenCalled();
|
|
1806
1977
|
|
|
1807
|
-
fireDragLeave(dropzone, data)
|
|
1808
|
-
expect(props.onDragLeave).not.toHaveBeenCalled()
|
|
1978
|
+
fireDragLeave(dropzone, data);
|
|
1979
|
+
expect(props.onDragLeave).not.toHaveBeenCalled();
|
|
1809
1980
|
|
|
1810
|
-
fireDrop(dropzone, data)
|
|
1811
|
-
await flushPromises(rerender, ui)
|
|
1812
|
-
expect(props.onDrop).not.toHaveBeenCalled()
|
|
1813
|
-
expect(props.onDropAccepted).not.toHaveBeenCalled()
|
|
1814
|
-
expect(props.onDropRejected).not.toHaveBeenCalled()
|
|
1815
|
-
})
|
|
1981
|
+
fireDrop(dropzone, data);
|
|
1982
|
+
await flushPromises(rerender, ui);
|
|
1983
|
+
expect(props.onDrop).not.toHaveBeenCalled();
|
|
1984
|
+
expect(props.onDropAccepted).not.toHaveBeenCalled();
|
|
1985
|
+
expect(props.onDropRejected).not.toHaveBeenCalled();
|
|
1986
|
+
});
|
|
1816
1987
|
|
|
1817
|
-
it(
|
|
1818
|
-
const data = createDtWithFiles(files)
|
|
1988
|
+
it("restores drag behavior if {noDrag} is set back to false", async () => {
|
|
1989
|
+
const data = createDtWithFiles(files);
|
|
1819
1990
|
|
|
1820
1991
|
const props = {
|
|
1821
1992
|
onDragEnter: jest.fn(),
|
|
1822
1993
|
onDragOver: jest.fn(),
|
|
1823
1994
|
onDragLeave: jest.fn(),
|
|
1824
|
-
onDrop: jest.fn()
|
|
1825
|
-
}
|
|
1995
|
+
onDrop: jest.fn(),
|
|
1996
|
+
};
|
|
1826
1997
|
|
|
1827
1998
|
const noDragUi = (
|
|
1828
1999
|
<Dropzone {...props} noDrag>
|
|
@@ -1832,23 +2003,23 @@ describe('useDropzone() hook', () => {
|
|
|
1832
2003
|
</div>
|
|
1833
2004
|
)}
|
|
1834
2005
|
</Dropzone>
|
|
1835
|
-
)
|
|
1836
|
-
const { container, rerender } = render(noDragUi)
|
|
1837
|
-
const dropzone = container.querySelector(
|
|
2006
|
+
);
|
|
2007
|
+
const { container, rerender } = render(noDragUi);
|
|
2008
|
+
const dropzone = container.querySelector("div");
|
|
1838
2009
|
|
|
1839
|
-
fireDragEnter(dropzone, data)
|
|
1840
|
-
await flushPromises(rerender, noDragUi)
|
|
1841
|
-
expect(props.onDragEnter).not.toHaveBeenCalled()
|
|
2010
|
+
fireDragEnter(dropzone, data);
|
|
2011
|
+
await flushPromises(rerender, noDragUi);
|
|
2012
|
+
expect(props.onDragEnter).not.toHaveBeenCalled();
|
|
1842
2013
|
|
|
1843
|
-
fireDragOver(dropzone, data)
|
|
1844
|
-
expect(props.onDragOver).not.toHaveBeenCalled()
|
|
2014
|
+
fireDragOver(dropzone, data);
|
|
2015
|
+
expect(props.onDragOver).not.toHaveBeenCalled();
|
|
1845
2016
|
|
|
1846
|
-
fireDragLeave(dropzone, data)
|
|
1847
|
-
expect(props.onDragLeave).not.toHaveBeenCalled()
|
|
2017
|
+
fireDragLeave(dropzone, data);
|
|
2018
|
+
expect(props.onDragLeave).not.toHaveBeenCalled();
|
|
1848
2019
|
|
|
1849
|
-
fireDrop(dropzone, data)
|
|
1850
|
-
await flushPromises(rerender, noDragUi)
|
|
1851
|
-
expect(props.onDrop).not.toHaveBeenCalled()
|
|
2020
|
+
fireDrop(dropzone, data);
|
|
2021
|
+
await flushPromises(rerender, noDragUi);
|
|
2022
|
+
expect(props.onDrop).not.toHaveBeenCalled();
|
|
1852
2023
|
|
|
1853
2024
|
const ui = (
|
|
1854
2025
|
<Dropzone {...props} noDrag={false}>
|
|
@@ -1858,247 +2029,293 @@ describe('useDropzone() hook', () => {
|
|
|
1858
2029
|
</div>
|
|
1859
2030
|
)}
|
|
1860
2031
|
</Dropzone>
|
|
1861
|
-
)
|
|
1862
|
-
rerender(ui)
|
|
2032
|
+
);
|
|
2033
|
+
rerender(ui);
|
|
1863
2034
|
|
|
1864
|
-
fireDragEnter(dropzone, data)
|
|
1865
|
-
await flushPromises(rerender, ui)
|
|
1866
|
-
expect(props.onDragEnter).toHaveBeenCalled()
|
|
2035
|
+
fireDragEnter(dropzone, data);
|
|
2036
|
+
await flushPromises(rerender, ui);
|
|
2037
|
+
expect(props.onDragEnter).toHaveBeenCalled();
|
|
1867
2038
|
|
|
1868
|
-
fireDragOver(dropzone, data)
|
|
1869
|
-
expect(props.onDragOver).toHaveBeenCalled()
|
|
2039
|
+
fireDragOver(dropzone, data);
|
|
2040
|
+
expect(props.onDragOver).toHaveBeenCalled();
|
|
1870
2041
|
|
|
1871
|
-
fireDragLeave(dropzone, data)
|
|
1872
|
-
expect(props.onDragLeave).toHaveBeenCalled()
|
|
2042
|
+
fireDragLeave(dropzone, data);
|
|
2043
|
+
expect(props.onDragLeave).toHaveBeenCalled();
|
|
1873
2044
|
|
|
1874
|
-
fireDrop(dropzone, data)
|
|
1875
|
-
await flushPromises(rerender, ui)
|
|
1876
|
-
expect(props.onDrop).toHaveBeenCalled()
|
|
1877
|
-
})
|
|
2045
|
+
fireDrop(dropzone, data);
|
|
2046
|
+
await flushPromises(rerender, ui);
|
|
2047
|
+
expect(props.onDrop).toHaveBeenCalled();
|
|
2048
|
+
});
|
|
1878
2049
|
|
|
1879
|
-
it(
|
|
2050
|
+
it("sets {isDragActive} and {isDragAccept} if some files are accepted on dragenter", async () => {
|
|
1880
2051
|
const ui = (
|
|
1881
2052
|
<Dropzone>
|
|
1882
|
-
{({
|
|
2053
|
+
{({
|
|
2054
|
+
getRootProps,
|
|
2055
|
+
getInputProps,
|
|
2056
|
+
isDragActive,
|
|
2057
|
+
isDragAccept,
|
|
2058
|
+
isDragReject,
|
|
2059
|
+
}) => (
|
|
1883
2060
|
<div {...getRootProps()}>
|
|
1884
2061
|
<input {...getInputProps()} />
|
|
1885
|
-
{isDragActive &&
|
|
1886
|
-
{isDragAccept &&
|
|
1887
|
-
{isDragReject &&
|
|
2062
|
+
{isDragActive && "dragActive"}
|
|
2063
|
+
{isDragAccept && "dragAccept"}
|
|
2064
|
+
{isDragReject && "dragReject"}
|
|
1888
2065
|
</div>
|
|
1889
2066
|
)}
|
|
1890
2067
|
</Dropzone>
|
|
1891
|
-
)
|
|
1892
|
-
const { container, rerender } = render(ui)
|
|
1893
|
-
const dropzone = container.querySelector(
|
|
2068
|
+
);
|
|
2069
|
+
const { container, rerender } = render(ui);
|
|
2070
|
+
const dropzone = container.querySelector("div");
|
|
1894
2071
|
|
|
1895
|
-
const data = createDtWithFiles(files)
|
|
1896
|
-
fireDragEnter(dropzone, data)
|
|
1897
|
-
await flushPromises(rerender, ui)
|
|
2072
|
+
const data = createDtWithFiles(files);
|
|
2073
|
+
fireDragEnter(dropzone, data);
|
|
2074
|
+
await flushPromises(rerender, ui);
|
|
1898
2075
|
|
|
1899
|
-
expect(dropzone).toHaveTextContent(
|
|
1900
|
-
expect(dropzone).toHaveTextContent(
|
|
1901
|
-
expect(dropzone).not.toHaveTextContent(
|
|
1902
|
-
})
|
|
2076
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2077
|
+
expect(dropzone).toHaveTextContent("dragAccept");
|
|
2078
|
+
expect(dropzone).not.toHaveTextContent("dragReject");
|
|
2079
|
+
});
|
|
1903
2080
|
|
|
1904
|
-
it(
|
|
2081
|
+
it("sets {isDragActive} and {isDragReject} of some files are not accepted on dragenter", async () => {
|
|
1905
2082
|
const ui = (
|
|
1906
2083
|
<Dropzone accept="image/*">
|
|
1907
|
-
{({
|
|
2084
|
+
{({
|
|
2085
|
+
getRootProps,
|
|
2086
|
+
getInputProps,
|
|
2087
|
+
isDragActive,
|
|
2088
|
+
isDragAccept,
|
|
2089
|
+
isDragReject,
|
|
2090
|
+
}) => (
|
|
1908
2091
|
<div {...getRootProps()}>
|
|
1909
2092
|
<input {...getInputProps()} />
|
|
1910
|
-
{isDragActive &&
|
|
1911
|
-
{isDragAccept &&
|
|
1912
|
-
{isDragReject &&
|
|
2093
|
+
{isDragActive && "dragActive"}
|
|
2094
|
+
{isDragAccept && "dragAccept"}
|
|
2095
|
+
{isDragReject && "dragReject"}
|
|
1913
2096
|
</div>
|
|
1914
2097
|
)}
|
|
1915
2098
|
</Dropzone>
|
|
1916
|
-
)
|
|
1917
|
-
const { container, rerender } = render(ui)
|
|
1918
|
-
const dropzone = container.querySelector(
|
|
2099
|
+
);
|
|
2100
|
+
const { container, rerender } = render(ui);
|
|
2101
|
+
const dropzone = container.querySelector("div");
|
|
1919
2102
|
|
|
1920
|
-
const data = createDtWithFiles([...files, ...images])
|
|
1921
|
-
fireDragEnter(dropzone, data)
|
|
1922
|
-
await flushPromises(rerender, ui)
|
|
2103
|
+
const data = createDtWithFiles([...files, ...images]);
|
|
2104
|
+
fireDragEnter(dropzone, data);
|
|
2105
|
+
await flushPromises(rerender, ui);
|
|
1923
2106
|
|
|
1924
|
-
expect(dropzone).toHaveTextContent(
|
|
1925
|
-
expect(dropzone).not.toHaveTextContent(
|
|
1926
|
-
expect(dropzone).toHaveTextContent(
|
|
1927
|
-
})
|
|
2107
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2108
|
+
expect(dropzone).not.toHaveTextContent("dragAccept");
|
|
2109
|
+
expect(dropzone).toHaveTextContent("dragReject");
|
|
2110
|
+
});
|
|
1928
2111
|
|
|
1929
|
-
it(
|
|
2112
|
+
it("sets {isDragReject} if some files are too large", async () => {
|
|
1930
2113
|
const ui = (
|
|
1931
2114
|
<Dropzone maxSize={0}>
|
|
1932
2115
|
{({ getRootProps, getInputProps, isDragAccept, isDragReject }) => (
|
|
1933
2116
|
<div {...getRootProps()}>
|
|
1934
2117
|
<input {...getInputProps()} />
|
|
1935
|
-
{isDragAccept &&
|
|
1936
|
-
{isDragReject &&
|
|
2118
|
+
{isDragAccept && "dragAccept"}
|
|
2119
|
+
{isDragReject && "dragReject"}
|
|
1937
2120
|
</div>
|
|
1938
2121
|
)}
|
|
1939
2122
|
</Dropzone>
|
|
1940
|
-
)
|
|
1941
|
-
const { container, rerender } = render(ui)
|
|
1942
|
-
const dropzone = container.querySelector(
|
|
2123
|
+
);
|
|
2124
|
+
const { container, rerender } = render(ui);
|
|
2125
|
+
const dropzone = container.querySelector("div");
|
|
1943
2126
|
|
|
1944
|
-
const data = createDtWithFiles(files)
|
|
1945
|
-
fireDragEnter(dropzone, data)
|
|
1946
|
-
await flushPromises(rerender, ui)
|
|
2127
|
+
const data = createDtWithFiles(files);
|
|
2128
|
+
fireDragEnter(dropzone, data);
|
|
2129
|
+
await flushPromises(rerender, ui);
|
|
1947
2130
|
|
|
1948
|
-
expect(dropzone).not.toHaveTextContent(
|
|
1949
|
-
expect(dropzone).toHaveTextContent(
|
|
1950
|
-
})
|
|
2131
|
+
expect(dropzone).not.toHaveTextContent("dragAccept");
|
|
2132
|
+
expect(dropzone).toHaveTextContent("dragReject");
|
|
2133
|
+
});
|
|
1951
2134
|
|
|
1952
|
-
it(
|
|
2135
|
+
it("sets {isDragActive, isDragAccept, isDragReject} if any files are rejected and {multiple} is false on dragenter", async () => {
|
|
1953
2136
|
const ui = (
|
|
1954
2137
|
<Dropzone accept="image/*" multiple={false}>
|
|
1955
|
-
{({
|
|
2138
|
+
{({
|
|
2139
|
+
getRootProps,
|
|
2140
|
+
getInputProps,
|
|
2141
|
+
isDragActive,
|
|
2142
|
+
isDragAccept,
|
|
2143
|
+
isDragReject,
|
|
2144
|
+
}) => (
|
|
1956
2145
|
<div {...getRootProps()}>
|
|
1957
2146
|
<input {...getInputProps()} />
|
|
1958
|
-
{isDragActive &&
|
|
1959
|
-
{isDragAccept &&
|
|
1960
|
-
{isDragReject &&
|
|
2147
|
+
{isDragActive && "dragActive"}
|
|
2148
|
+
{isDragAccept && "dragAccept"}
|
|
2149
|
+
{isDragReject && "dragReject"}
|
|
1961
2150
|
</div>
|
|
1962
2151
|
)}
|
|
1963
2152
|
</Dropzone>
|
|
1964
|
-
)
|
|
1965
|
-
const { container, rerender } = render(ui)
|
|
1966
|
-
const dropzone = container.querySelector(
|
|
2153
|
+
);
|
|
2154
|
+
const { container, rerender } = render(ui);
|
|
2155
|
+
const dropzone = container.querySelector("div");
|
|
1967
2156
|
|
|
1968
|
-
const data = createDtWithFiles(images)
|
|
1969
|
-
fireDragEnter(dropzone, data)
|
|
1970
|
-
await flushPromises(rerender, ui)
|
|
2157
|
+
const data = createDtWithFiles(images);
|
|
2158
|
+
fireDragEnter(dropzone, data);
|
|
2159
|
+
await flushPromises(rerender, ui);
|
|
1971
2160
|
|
|
1972
|
-
expect(dropzone).toHaveTextContent(
|
|
1973
|
-
expect(dropzone).not.toHaveTextContent(
|
|
1974
|
-
expect(dropzone).toHaveTextContent(
|
|
1975
|
-
})
|
|
2161
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2162
|
+
expect(dropzone).not.toHaveTextContent("dragAccept");
|
|
2163
|
+
expect(dropzone).toHaveTextContent("dragReject");
|
|
2164
|
+
});
|
|
1976
2165
|
|
|
1977
|
-
it(
|
|
1978
|
-
const { container: overlayContainer } = render(<div />)
|
|
2166
|
+
it("keeps {isDragActive} if dragleave is triggered for some arbitrary node", async () => {
|
|
2167
|
+
const { container: overlayContainer } = render(<div />);
|
|
1979
2168
|
const ui = (
|
|
1980
2169
|
<Dropzone>
|
|
1981
|
-
{({
|
|
2170
|
+
{({
|
|
2171
|
+
getRootProps,
|
|
2172
|
+
getInputProps,
|
|
2173
|
+
isDragActive,
|
|
2174
|
+
isDragAccept,
|
|
2175
|
+
isDragReject,
|
|
2176
|
+
}) => (
|
|
1982
2177
|
<div {...getRootProps()}>
|
|
1983
2178
|
<input {...getInputProps()} />
|
|
1984
|
-
{isDragActive &&
|
|
1985
|
-
{isDragAccept &&
|
|
1986
|
-
{isDragReject &&
|
|
2179
|
+
{isDragActive && "dragActive"}
|
|
2180
|
+
{isDragAccept && "dragAccept"}
|
|
2181
|
+
{isDragReject && "dragReject"}
|
|
1987
2182
|
</div>
|
|
1988
2183
|
)}
|
|
1989
2184
|
</Dropzone>
|
|
1990
|
-
)
|
|
1991
|
-
const { container, rerender } = render(ui)
|
|
1992
|
-
const dropzone = container.querySelector(
|
|
2185
|
+
);
|
|
2186
|
+
const { container, rerender } = render(ui);
|
|
2187
|
+
const dropzone = container.querySelector("div");
|
|
1993
2188
|
|
|
1994
|
-
const data = createDtWithFiles(files)
|
|
1995
|
-
fireDragEnter(dropzone, data)
|
|
1996
|
-
await flushPromises(rerender, ui)
|
|
2189
|
+
const data = createDtWithFiles(files);
|
|
2190
|
+
fireDragEnter(dropzone, data);
|
|
2191
|
+
await flushPromises(rerender, ui);
|
|
1997
2192
|
|
|
1998
|
-
const event = new Event(
|
|
1999
|
-
Object.defineProperty(event,
|
|
2000
|
-
value: overlayContainer.querySelector(
|
|
2001
|
-
writable: false
|
|
2002
|
-
})
|
|
2003
|
-
fireEvent(dropzone, event)
|
|
2193
|
+
const event = new Event("dragleave", { bubbles: true });
|
|
2194
|
+
Object.defineProperty(event, "target", {
|
|
2195
|
+
value: overlayContainer.querySelector("div"),
|
|
2196
|
+
writable: false,
|
|
2197
|
+
});
|
|
2198
|
+
fireEvent(dropzone, event);
|
|
2004
2199
|
|
|
2005
|
-
expect(dropzone).toHaveTextContent(
|
|
2006
|
-
})
|
|
2200
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2201
|
+
});
|
|
2007
2202
|
|
|
2008
|
-
it(
|
|
2203
|
+
it("updates {isDragActive} if {accept} changes mid-drag", async () => {
|
|
2009
2204
|
const ui = (
|
|
2010
2205
|
<Dropzone accept="image/*">
|
|
2011
|
-
{({
|
|
2206
|
+
{({
|
|
2207
|
+
getRootProps,
|
|
2208
|
+
getInputProps,
|
|
2209
|
+
isDragActive,
|
|
2210
|
+
isDragAccept,
|
|
2211
|
+
isDragReject,
|
|
2212
|
+
}) => (
|
|
2012
2213
|
<div {...getRootProps()}>
|
|
2013
2214
|
<input {...getInputProps()} />
|
|
2014
|
-
{isDragActive &&
|
|
2015
|
-
{isDragAccept &&
|
|
2016
|
-
{isDragReject &&
|
|
2215
|
+
{isDragActive && "dragActive"}
|
|
2216
|
+
{isDragAccept && "dragAccept"}
|
|
2217
|
+
{isDragReject && "dragReject"}
|
|
2017
2218
|
</div>
|
|
2018
2219
|
)}
|
|
2019
2220
|
</Dropzone>
|
|
2020
|
-
)
|
|
2021
|
-
const { container, rerender } = render(ui)
|
|
2022
|
-
const dropzone = container.querySelector(
|
|
2221
|
+
);
|
|
2222
|
+
const { container, rerender } = render(ui);
|
|
2223
|
+
const dropzone = container.querySelector("div");
|
|
2023
2224
|
|
|
2024
|
-
const data = createDtWithFiles(images)
|
|
2025
|
-
fireDragEnter(dropzone, data)
|
|
2026
|
-
await flushPromises(rerender, ui)
|
|
2225
|
+
const data = createDtWithFiles(images);
|
|
2226
|
+
fireDragEnter(dropzone, data);
|
|
2227
|
+
await flushPromises(rerender, ui);
|
|
2027
2228
|
|
|
2028
|
-
expect(dropzone).toHaveTextContent(
|
|
2029
|
-
expect(dropzone).toHaveTextContent(
|
|
2030
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2229
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2230
|
+
expect(dropzone).toHaveTextContent("dragAccept");
|
|
2231
|
+
expect(dropzone).not.toHaveTextContent("dragReject");
|
|
2031
2232
|
|
|
2032
2233
|
rerender(
|
|
2033
2234
|
<Dropzone accept="text/*">
|
|
2034
|
-
{({
|
|
2235
|
+
{({
|
|
2236
|
+
getRootProps,
|
|
2237
|
+
getInputProps,
|
|
2238
|
+
isDragActive,
|
|
2239
|
+
isDragAccept,
|
|
2240
|
+
isDragReject,
|
|
2241
|
+
}) => (
|
|
2035
2242
|
<div {...getRootProps()}>
|
|
2036
2243
|
<input {...getInputProps()} />
|
|
2037
|
-
{isDragActive &&
|
|
2038
|
-
{isDragAccept &&
|
|
2039
|
-
{isDragReject &&
|
|
2244
|
+
{isDragActive && "dragActive"}
|
|
2245
|
+
{isDragAccept && "dragAccept"}
|
|
2246
|
+
{isDragReject && "dragReject"}
|
|
2040
2247
|
</div>
|
|
2041
2248
|
)}
|
|
2042
2249
|
</Dropzone>
|
|
2043
|
-
)
|
|
2250
|
+
);
|
|
2044
2251
|
|
|
2045
|
-
expect(dropzone).toHaveTextContent(
|
|
2046
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2047
|
-
expect(dropzone).toHaveTextContent(
|
|
2048
|
-
})
|
|
2252
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2253
|
+
expect(dropzone).not.toHaveTextContent("dragAccept");
|
|
2254
|
+
expect(dropzone).toHaveTextContent("dragReject");
|
|
2255
|
+
});
|
|
2049
2256
|
|
|
2050
|
-
it(
|
|
2257
|
+
it("resets {isDragActive, isDragAccept, isDragReject} on dragleave", async () => {
|
|
2051
2258
|
const ui = (
|
|
2052
2259
|
<Dropzone accept="image/*">
|
|
2053
|
-
{({
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2260
|
+
{({
|
|
2261
|
+
getRootProps,
|
|
2262
|
+
getInputProps,
|
|
2263
|
+
isDragActive,
|
|
2264
|
+
isDragAccept,
|
|
2265
|
+
isDragReject,
|
|
2266
|
+
}) => (
|
|
2267
|
+
<div {...getRootProps()}>
|
|
2268
|
+
<input {...getInputProps()} />
|
|
2269
|
+
{isDragActive && "dragActive"}
|
|
2270
|
+
{isDragAccept && "dragAccept"}
|
|
2271
|
+
{isDragReject && "dragReject"}
|
|
2059
2272
|
{!isDragActive && (
|
|
2060
|
-
<span
|
|
2273
|
+
<span
|
|
2274
|
+
id="child"
|
|
2275
|
+
data-accept={isDragAccept}
|
|
2276
|
+
data-reject={isDragReject}
|
|
2277
|
+
/>
|
|
2061
2278
|
)}
|
|
2062
2279
|
</div>
|
|
2063
2280
|
)}
|
|
2064
2281
|
</Dropzone>
|
|
2065
|
-
)
|
|
2066
|
-
const { container, rerender } = render(ui)
|
|
2067
|
-
const dropzone = container.querySelector(
|
|
2282
|
+
);
|
|
2283
|
+
const { container, rerender } = render(ui);
|
|
2284
|
+
const dropzone = container.querySelector("div");
|
|
2068
2285
|
|
|
2069
|
-
const data = createDtWithFiles(images)
|
|
2286
|
+
const data = createDtWithFiles(images);
|
|
2070
2287
|
|
|
2071
|
-
fireDragEnter(container.querySelector(
|
|
2072
|
-
fireDragEnter(dropzone, data)
|
|
2073
|
-
await flushPromises(rerender, ui)
|
|
2074
|
-
fireDragEnter(dropzone, data)
|
|
2075
|
-
await flushPromises(rerender, ui)
|
|
2288
|
+
fireDragEnter(container.querySelector("#child"), data);
|
|
2289
|
+
fireDragEnter(dropzone, data);
|
|
2290
|
+
await flushPromises(rerender, ui);
|
|
2291
|
+
fireDragEnter(dropzone, data);
|
|
2292
|
+
await flushPromises(rerender, ui);
|
|
2076
2293
|
|
|
2077
|
-
expect(dropzone).toHaveTextContent(
|
|
2078
|
-
expect(dropzone).toHaveTextContent(
|
|
2079
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2294
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2295
|
+
expect(dropzone).toHaveTextContent("dragAccept");
|
|
2296
|
+
expect(dropzone).not.toHaveTextContent("dragReject");
|
|
2080
2297
|
|
|
2081
|
-
fireDragLeave(dropzone, data)
|
|
2082
|
-
await flushPromises(rerender, ui)
|
|
2083
|
-
expect(dropzone).toHaveTextContent(
|
|
2084
|
-
expect(dropzone).toHaveTextContent(
|
|
2085
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2298
|
+
fireDragLeave(dropzone, data);
|
|
2299
|
+
await flushPromises(rerender, ui);
|
|
2300
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2301
|
+
expect(dropzone).toHaveTextContent("dragAccept");
|
|
2302
|
+
expect(dropzone).not.toHaveTextContent("dragReject");
|
|
2086
2303
|
|
|
2087
|
-
fireDragLeave(dropzone, data)
|
|
2088
|
-
await flushPromises(rerender, ui)
|
|
2089
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2090
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2091
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2304
|
+
fireDragLeave(dropzone, data);
|
|
2305
|
+
await flushPromises(rerender, ui);
|
|
2306
|
+
expect(dropzone).not.toHaveTextContent("dragActive");
|
|
2307
|
+
expect(dropzone).not.toHaveTextContent("dragAccept");
|
|
2308
|
+
expect(dropzone).not.toHaveTextContent("dragReject");
|
|
2092
2309
|
|
|
2093
|
-
const child = container.querySelector(
|
|
2094
|
-
expect(child).toHaveAttribute(
|
|
2095
|
-
expect(child).toHaveAttribute(
|
|
2096
|
-
})
|
|
2097
|
-
})
|
|
2310
|
+
const child = container.querySelector("#child");
|
|
2311
|
+
expect(child).toHaveAttribute("data-accept", "false");
|
|
2312
|
+
expect(child).toHaveAttribute("data-reject", "false");
|
|
2313
|
+
});
|
|
2314
|
+
});
|
|
2098
2315
|
|
|
2099
|
-
describe(
|
|
2100
|
-
test(
|
|
2101
|
-
const onDropSpy = jest.fn()
|
|
2316
|
+
describe("onDrop", () => {
|
|
2317
|
+
test("callback is invoked when <input> change event occurs", async () => {
|
|
2318
|
+
const onDropSpy = jest.fn();
|
|
2102
2319
|
|
|
2103
2320
|
const ui = (
|
|
2104
2321
|
<Dropzone onDrop={onDropSpy}>
|
|
@@ -2108,28 +2325,28 @@ describe('useDropzone() hook', () => {
|
|
|
2108
2325
|
</div>
|
|
2109
2326
|
)}
|
|
2110
2327
|
</Dropzone>
|
|
2111
|
-
)
|
|
2112
|
-
const { container, rerender } = render(ui)
|
|
2113
|
-
const input = container.querySelector(
|
|
2328
|
+
);
|
|
2329
|
+
const { container, rerender } = render(ui);
|
|
2330
|
+
const input = container.querySelector("input");
|
|
2114
2331
|
|
|
2115
|
-
Object.defineProperty(input,
|
|
2332
|
+
Object.defineProperty(input, "files", { value: files });
|
|
2116
2333
|
|
|
2117
|
-
dispatchEvt(input,
|
|
2118
|
-
await flushPromises(rerender, ui)
|
|
2334
|
+
dispatchEvt(input, "change");
|
|
2335
|
+
await flushPromises(rerender, ui);
|
|
2119
2336
|
|
|
2120
|
-
expect(onDropSpy).toHaveBeenCalledWith(files, [], expect.anything())
|
|
2121
|
-
})
|
|
2337
|
+
expect(onDropSpy).toHaveBeenCalledWith(files, [], expect.anything());
|
|
2338
|
+
});
|
|
2122
2339
|
|
|
2123
|
-
it(
|
|
2340
|
+
it("sets {acceptedFiles, fileRejections}", async () => {
|
|
2124
2341
|
const FileList = ({ files = [] }) => (
|
|
2125
2342
|
<ul>
|
|
2126
|
-
{files.map(file => (
|
|
2127
|
-
<li key={file.name} data-type={
|
|
2343
|
+
{files.map((file) => (
|
|
2344
|
+
<li key={file.name} data-type={"accepted"}>
|
|
2128
2345
|
{file.name}
|
|
2129
2346
|
</li>
|
|
2130
2347
|
))}
|
|
2131
2348
|
</ul>
|
|
2132
|
-
)
|
|
2349
|
+
);
|
|
2133
2350
|
|
|
2134
2351
|
const RejectedFileList = ({ fileRejections = [] }) => (
|
|
2135
2352
|
<ul>
|
|
@@ -2137,7 +2354,7 @@ describe('useDropzone() hook', () => {
|
|
|
2137
2354
|
<li key={file.name}>
|
|
2138
2355
|
<span data-type={"rejected"}>{file.name}</span>
|
|
2139
2356
|
<ul>
|
|
2140
|
-
{errors.map(e => (
|
|
2357
|
+
{errors.map((e) => (
|
|
2141
2358
|
<li key={e.code} data-type={"error"}>
|
|
2142
2359
|
{e.code}
|
|
2143
2360
|
</li>
|
|
@@ -2146,15 +2363,20 @@ describe('useDropzone() hook', () => {
|
|
|
2146
2363
|
</li>
|
|
2147
2364
|
))}
|
|
2148
2365
|
</ul>
|
|
2149
|
-
)
|
|
2150
|
-
|
|
2151
|
-
const getAcceptedFiles = node =>
|
|
2152
|
-
|
|
2153
|
-
const
|
|
2366
|
+
);
|
|
2367
|
+
|
|
2368
|
+
const getAcceptedFiles = (node) =>
|
|
2369
|
+
node.querySelectorAll(`[data-type="accepted"]`);
|
|
2370
|
+
const getRejectedFiles = (node) =>
|
|
2371
|
+
node.querySelectorAll(`[data-type="rejected"]`);
|
|
2372
|
+
const getRejectedFilesErrors = (node) =>
|
|
2373
|
+
node.querySelectorAll(`[data-type="error"]`);
|
|
2154
2374
|
const matchToFiles = (fileList, files) =>
|
|
2155
|
-
Array.from(fileList).every(
|
|
2375
|
+
Array.from(fileList).every(
|
|
2376
|
+
(item) => !!files.find((file) => file.name === item.textContent)
|
|
2377
|
+
);
|
|
2156
2378
|
const matchToErrorCode = (errorList, code) =>
|
|
2157
|
-
Array.from(errorList).every(item => item.textContent === code)
|
|
2379
|
+
Array.from(errorList).every((item) => item.textContent === code);
|
|
2158
2380
|
|
|
2159
2381
|
const ui = (
|
|
2160
2382
|
<Dropzone accept="image/*">
|
|
@@ -2166,60 +2388,68 @@ describe('useDropzone() hook', () => {
|
|
|
2166
2388
|
</div>
|
|
2167
2389
|
)}
|
|
2168
2390
|
</Dropzone>
|
|
2169
|
-
)
|
|
2170
|
-
const { container, rerender } = render(ui)
|
|
2171
|
-
const dropzone = container.querySelector(
|
|
2391
|
+
);
|
|
2392
|
+
const { container, rerender } = render(ui);
|
|
2393
|
+
const dropzone = container.querySelector("div");
|
|
2172
2394
|
|
|
2173
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2174
|
-
await flushPromises(rerender, ui)
|
|
2175
|
-
const acceptedFileList = getAcceptedFiles(dropzone)
|
|
2176
|
-
expect(acceptedFileList).toHaveLength(images.length)
|
|
2177
|
-
expect(matchToFiles(acceptedFileList, images)).toBe(true)
|
|
2395
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2396
|
+
await flushPromises(rerender, ui);
|
|
2397
|
+
const acceptedFileList = getAcceptedFiles(dropzone);
|
|
2398
|
+
expect(acceptedFileList).toHaveLength(images.length);
|
|
2399
|
+
expect(matchToFiles(acceptedFileList, images)).toBe(true);
|
|
2178
2400
|
|
|
2179
|
-
fireDrop(dropzone, createDtWithFiles(files))
|
|
2180
|
-
await flushPromises(rerender, ui)
|
|
2181
|
-
const rejectedFileList = getRejectedFiles(dropzone)
|
|
2182
|
-
expect(rejectedFileList).toHaveLength(files.length)
|
|
2183
|
-
expect(matchToFiles(rejectedFileList, files)).toBe(true)
|
|
2184
|
-
const rejectedFileErrorList = getRejectedFilesErrors(dropzone)
|
|
2185
|
-
expect(rejectedFileErrorList).toHaveLength(files.length)
|
|
2186
|
-
expect(matchToErrorCode(rejectedFileErrorList,
|
|
2187
|
-
|
|
2401
|
+
fireDrop(dropzone, createDtWithFiles(files));
|
|
2402
|
+
await flushPromises(rerender, ui);
|
|
2403
|
+
const rejectedFileList = getRejectedFiles(dropzone);
|
|
2404
|
+
expect(rejectedFileList).toHaveLength(files.length);
|
|
2405
|
+
expect(matchToFiles(rejectedFileList, files)).toBe(true);
|
|
2406
|
+
const rejectedFileErrorList = getRejectedFilesErrors(dropzone);
|
|
2407
|
+
expect(rejectedFileErrorList).toHaveLength(files.length);
|
|
2408
|
+
expect(matchToErrorCode(rejectedFileErrorList, "file-invalid-type")).toBe(
|
|
2409
|
+
true
|
|
2410
|
+
);
|
|
2411
|
+
});
|
|
2188
2412
|
|
|
2189
|
-
it(
|
|
2413
|
+
it("resets {isDragActive, isDragAccept, isDragReject}", async () => {
|
|
2190
2414
|
const ui = (
|
|
2191
2415
|
<Dropzone>
|
|
2192
|
-
{({
|
|
2416
|
+
{({
|
|
2417
|
+
getRootProps,
|
|
2418
|
+
getInputProps,
|
|
2419
|
+
isDragActive,
|
|
2420
|
+
isDragAccept,
|
|
2421
|
+
isDragReject,
|
|
2422
|
+
}) => (
|
|
2193
2423
|
<div {...getRootProps()}>
|
|
2194
2424
|
<input {...getInputProps()} />
|
|
2195
|
-
{isDragActive &&
|
|
2196
|
-
{isDragAccept &&
|
|
2197
|
-
{isDragReject &&
|
|
2425
|
+
{isDragActive && "dragActive"}
|
|
2426
|
+
{isDragAccept && "dragAccept"}
|
|
2427
|
+
{isDragReject && "dragReject"}
|
|
2198
2428
|
</div>
|
|
2199
2429
|
)}
|
|
2200
2430
|
</Dropzone>
|
|
2201
|
-
)
|
|
2202
|
-
const { container, rerender } = render(ui)
|
|
2203
|
-
const dropzone = container.querySelector(
|
|
2431
|
+
);
|
|
2432
|
+
const { container, rerender } = render(ui);
|
|
2433
|
+
const dropzone = container.querySelector("div");
|
|
2204
2434
|
|
|
2205
|
-
const data = createDtWithFiles(files)
|
|
2435
|
+
const data = createDtWithFiles(files);
|
|
2206
2436
|
|
|
2207
|
-
fireDragEnter(dropzone, data)
|
|
2208
|
-
await flushPromises(rerender, ui)
|
|
2437
|
+
fireDragEnter(dropzone, data);
|
|
2438
|
+
await flushPromises(rerender, ui);
|
|
2209
2439
|
|
|
2210
|
-
expect(dropzone).toHaveTextContent(
|
|
2211
|
-
expect(dropzone).toHaveTextContent(
|
|
2212
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2440
|
+
expect(dropzone).toHaveTextContent("dragActive");
|
|
2441
|
+
expect(dropzone).toHaveTextContent("dragAccept");
|
|
2442
|
+
expect(dropzone).not.toHaveTextContent("dragReject");
|
|
2213
2443
|
|
|
2214
|
-
fireDrop(dropzone, data)
|
|
2215
|
-
await flushPromises(rerender, ui)
|
|
2216
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2217
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2218
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2219
|
-
})
|
|
2444
|
+
fireDrop(dropzone, data);
|
|
2445
|
+
await flushPromises(rerender, ui);
|
|
2446
|
+
expect(dropzone).not.toHaveTextContent("dragActive");
|
|
2447
|
+
expect(dropzone).not.toHaveTextContent("dragAccept");
|
|
2448
|
+
expect(dropzone).not.toHaveTextContent("dragReject");
|
|
2449
|
+
});
|
|
2220
2450
|
|
|
2221
|
-
it(
|
|
2222
|
-
const onDropSpy = jest.fn()
|
|
2451
|
+
it("rejects all files if {multiple} is false and {accept} criteria is not met", async () => {
|
|
2452
|
+
const onDropSpy = jest.fn();
|
|
2223
2453
|
const ui = (
|
|
2224
2454
|
<Dropzone accept="image/*" onDrop={onDropSpy} multiple={false}>
|
|
2225
2455
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2228,27 +2458,31 @@ describe('useDropzone() hook', () => {
|
|
|
2228
2458
|
</div>
|
|
2229
2459
|
)}
|
|
2230
2460
|
</Dropzone>
|
|
2231
|
-
)
|
|
2232
|
-
const { container, rerender } = render(ui)
|
|
2233
|
-
const dropzone = container.querySelector(
|
|
2461
|
+
);
|
|
2462
|
+
const { container, rerender } = render(ui);
|
|
2463
|
+
const dropzone = container.querySelector("div");
|
|
2234
2464
|
|
|
2235
|
-
fireDrop(dropzone, createDtWithFiles(files))
|
|
2236
|
-
await flushPromises(rerender, ui)
|
|
2237
|
-
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2465
|
+
fireDrop(dropzone, createDtWithFiles(files));
|
|
2466
|
+
await flushPromises(rerender, ui);
|
|
2467
|
+
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2468
|
+
[],
|
|
2469
|
+
[
|
|
2470
|
+
{
|
|
2471
|
+
file: files[0],
|
|
2472
|
+
errors: [
|
|
2473
|
+
{
|
|
2474
|
+
code: "file-invalid-type",
|
|
2475
|
+
message: "File type must be image/*",
|
|
2476
|
+
},
|
|
2477
|
+
],
|
|
2478
|
+
},
|
|
2479
|
+
],
|
|
2480
|
+
expect.anything()
|
|
2481
|
+
);
|
|
2482
|
+
});
|
|
2249
2483
|
|
|
2250
|
-
it(
|
|
2251
|
-
const onDropSpy = jest.fn()
|
|
2484
|
+
it("rejects all files if {multiple} is false and {accept} criteria is met", async () => {
|
|
2485
|
+
const onDropSpy = jest.fn();
|
|
2252
2486
|
const ui = (
|
|
2253
2487
|
<Dropzone accept="image/*" onDrop={onDropSpy} multiple={false}>
|
|
2254
2488
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2257,132 +2491,162 @@ describe('useDropzone() hook', () => {
|
|
|
2257
2491
|
</div>
|
|
2258
2492
|
)}
|
|
2259
2493
|
</Dropzone>
|
|
2260
|
-
)
|
|
2261
|
-
const { container, rerender } = render(ui)
|
|
2262
|
-
const dropzone = container.querySelector(
|
|
2263
|
-
|
|
2264
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2265
|
-
await flushPromises(rerender, ui)
|
|
2266
|
-
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2494
|
+
);
|
|
2495
|
+
const { container, rerender } = render(ui);
|
|
2496
|
+
const dropzone = container.querySelector("div");
|
|
2497
|
+
|
|
2498
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2499
|
+
await flushPromises(rerender, ui);
|
|
2500
|
+
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2501
|
+
[],
|
|
2502
|
+
[
|
|
2503
|
+
{
|
|
2504
|
+
file: images[0],
|
|
2505
|
+
errors: [
|
|
2506
|
+
{
|
|
2507
|
+
code: "too-many-files",
|
|
2508
|
+
message: "Too many files",
|
|
2509
|
+
},
|
|
2510
|
+
],
|
|
2511
|
+
},
|
|
2512
|
+
{
|
|
2513
|
+
file: images[1],
|
|
2514
|
+
errors: [
|
|
2515
|
+
{
|
|
2516
|
+
code: "too-many-files",
|
|
2517
|
+
message: "Too many files",
|
|
2518
|
+
},
|
|
2519
|
+
],
|
|
2520
|
+
},
|
|
2521
|
+
],
|
|
2522
|
+
expect.anything()
|
|
2523
|
+
);
|
|
2524
|
+
});
|
|
2287
2525
|
|
|
2288
|
-
it(
|
|
2289
|
-
const onDropSpy = jest.fn()
|
|
2290
|
-
const onDropRejectedSpy = jest.fn()
|
|
2526
|
+
it("rejects all files if {multiple} is true and maxFiles is less than files and {accept} criteria is met", async () => {
|
|
2527
|
+
const onDropSpy = jest.fn();
|
|
2528
|
+
const onDropRejectedSpy = jest.fn();
|
|
2291
2529
|
const ui = (
|
|
2292
|
-
<Dropzone
|
|
2530
|
+
<Dropzone
|
|
2531
|
+
accept="image/*"
|
|
2532
|
+
onDrop={onDropSpy}
|
|
2533
|
+
onDropRejected={onDropRejectedSpy}
|
|
2534
|
+
multiple={true}
|
|
2535
|
+
maxFiles={1}
|
|
2536
|
+
>
|
|
2293
2537
|
{({ getRootProps, getInputProps, isDragReject, isDragAccept }) => (
|
|
2294
2538
|
<div {...getRootProps()}>
|
|
2295
2539
|
<input {...getInputProps()} />
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
</div>
|
|
2299
|
-
)}
|
|
2300
|
-
</Dropzone>
|
|
2301
|
-
)
|
|
2302
|
-
const { container, rerender } = render(ui)
|
|
2303
|
-
const dropzone = container.querySelector(
|
|
2304
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2305
|
-
await flushPromises(rerender, ui)
|
|
2306
|
-
expect(onDropRejectedSpy).toHaveBeenCalled()
|
|
2307
|
-
fireDragEnter(dropzone, createDtWithFiles(images))
|
|
2308
|
-
await flushPromises(rerender, ui)
|
|
2309
|
-
expect(dropzone).toHaveTextContent(
|
|
2310
|
-
expect(dropzone).not.toHaveTextContent(
|
|
2311
|
-
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2540
|
+
{isDragReject && "dragReject"}
|
|
2541
|
+
{isDragAccept && "dragAccept"}
|
|
2542
|
+
</div>
|
|
2543
|
+
)}
|
|
2544
|
+
</Dropzone>
|
|
2545
|
+
);
|
|
2546
|
+
const { container, rerender } = render(ui);
|
|
2547
|
+
const dropzone = container.querySelector("div");
|
|
2548
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2549
|
+
await flushPromises(rerender, ui);
|
|
2550
|
+
expect(onDropRejectedSpy).toHaveBeenCalled();
|
|
2551
|
+
fireDragEnter(dropzone, createDtWithFiles(images));
|
|
2552
|
+
await flushPromises(rerender, ui);
|
|
2553
|
+
expect(dropzone).toHaveTextContent("dragReject");
|
|
2554
|
+
expect(dropzone).not.toHaveTextContent("dragAccept");
|
|
2555
|
+
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2556
|
+
[],
|
|
2557
|
+
[
|
|
2558
|
+
{
|
|
2559
|
+
file: images[0],
|
|
2560
|
+
errors: [
|
|
2561
|
+
{
|
|
2562
|
+
code: "too-many-files",
|
|
2563
|
+
message: "Too many files",
|
|
2564
|
+
},
|
|
2565
|
+
],
|
|
2566
|
+
},
|
|
2567
|
+
{
|
|
2568
|
+
file: images[1],
|
|
2569
|
+
errors: [
|
|
2570
|
+
{
|
|
2571
|
+
code: "too-many-files",
|
|
2572
|
+
message: "Too many files",
|
|
2573
|
+
},
|
|
2574
|
+
],
|
|
2575
|
+
},
|
|
2576
|
+
],
|
|
2577
|
+
expect.anything()
|
|
2578
|
+
);
|
|
2579
|
+
});
|
|
2332
2580
|
|
|
2333
|
-
it(
|
|
2334
|
-
const onDropSpy = jest.fn()
|
|
2335
|
-
const onDropRejectedSpy = jest.fn()
|
|
2581
|
+
it("rejects all files if {multiple} is true and maxFiles has been updated so that it is less than files", async () => {
|
|
2582
|
+
const onDropSpy = jest.fn();
|
|
2583
|
+
const onDropRejectedSpy = jest.fn();
|
|
2336
2584
|
const ui = (maxFiles) => (
|
|
2337
|
-
<Dropzone
|
|
2585
|
+
<Dropzone
|
|
2586
|
+
accept="image/*"
|
|
2587
|
+
onDrop={onDropSpy}
|
|
2588
|
+
multiple={true}
|
|
2589
|
+
maxFiles={maxFiles}
|
|
2590
|
+
onDropRejected={onDropRejectedSpy}
|
|
2591
|
+
>
|
|
2338
2592
|
{({ getRootProps, getInputProps }) => (
|
|
2339
2593
|
<div {...getRootProps()}>
|
|
2340
2594
|
<input {...getInputProps()} />
|
|
2341
2595
|
</div>
|
|
2342
2596
|
)}
|
|
2343
2597
|
</Dropzone>
|
|
2344
|
-
)
|
|
2345
|
-
const { container, rerender } = render(ui(3))
|
|
2346
|
-
const dropzone = container.querySelector(
|
|
2598
|
+
);
|
|
2599
|
+
const { container, rerender } = render(ui(3));
|
|
2600
|
+
const dropzone = container.querySelector("div");
|
|
2347
2601
|
|
|
2348
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2349
|
-
await flushPromises(rerender, ui(3))
|
|
2350
|
-
expect(onDropRejectedSpy).not.toHaveBeenCalled()
|
|
2351
|
-
expect(onDropSpy).toHaveBeenCalledWith(images, [], expect.anything())
|
|
2602
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2603
|
+
await flushPromises(rerender, ui(3));
|
|
2604
|
+
expect(onDropRejectedSpy).not.toHaveBeenCalled();
|
|
2605
|
+
expect(onDropSpy).toHaveBeenCalledWith(images, [], expect.anything());
|
|
2352
2606
|
|
|
2353
2607
|
rerender(ui(1));
|
|
2354
2608
|
|
|
2355
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2356
|
-
await flushPromises(rerender, ui(1))
|
|
2609
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2610
|
+
await flushPromises(rerender, ui(1));
|
|
2357
2611
|
expect(onDropRejectedSpy).toHaveBeenCalledWith(
|
|
2358
|
-
expect.arrayContaining(
|
|
2612
|
+
expect.arrayContaining(
|
|
2613
|
+
images.map((image) =>
|
|
2614
|
+
expect.objectContaining({ errors: expect.any(Array), file: image })
|
|
2615
|
+
)
|
|
2616
|
+
),
|
|
2359
2617
|
expect.anything()
|
|
2360
|
-
)
|
|
2361
|
-
})
|
|
2618
|
+
);
|
|
2619
|
+
});
|
|
2362
2620
|
|
|
2363
|
-
it(
|
|
2364
|
-
const onDropSpy = jest.fn()
|
|
2365
|
-
const onDropRejectedSpy = jest.fn()
|
|
2621
|
+
it("accepts multiple files if {multiple} is true and {accept} criteria is met", async () => {
|
|
2622
|
+
const onDropSpy = jest.fn();
|
|
2623
|
+
const onDropRejectedSpy = jest.fn();
|
|
2366
2624
|
const ui = (
|
|
2367
|
-
<Dropzone
|
|
2625
|
+
<Dropzone
|
|
2626
|
+
accept="image/*"
|
|
2627
|
+
onDrop={onDropSpy}
|
|
2628
|
+
multiple={true}
|
|
2629
|
+
maxFiles={3}
|
|
2630
|
+
onDropRejected={onDropRejectedSpy}
|
|
2631
|
+
>
|
|
2368
2632
|
{({ getRootProps, getInputProps }) => (
|
|
2369
2633
|
<div {...getRootProps()}>
|
|
2370
2634
|
<input {...getInputProps()} />
|
|
2371
2635
|
</div>
|
|
2372
2636
|
)}
|
|
2373
2637
|
</Dropzone>
|
|
2374
|
-
)
|
|
2375
|
-
const { container, rerender } = render(ui)
|
|
2376
|
-
const dropzone = container.querySelector(
|
|
2638
|
+
);
|
|
2639
|
+
const { container, rerender } = render(ui);
|
|
2640
|
+
const dropzone = container.querySelector("div");
|
|
2377
2641
|
|
|
2378
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2379
|
-
await flushPromises(rerender, ui)
|
|
2380
|
-
expect(onDropRejectedSpy).not.toHaveBeenCalled()
|
|
2381
|
-
expect(onDropSpy).toHaveBeenCalledWith(images, [], expect.anything())
|
|
2382
|
-
})
|
|
2642
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2643
|
+
await flushPromises(rerender, ui);
|
|
2644
|
+
expect(onDropRejectedSpy).not.toHaveBeenCalled();
|
|
2645
|
+
expect(onDropSpy).toHaveBeenCalledWith(images, [], expect.anything());
|
|
2646
|
+
});
|
|
2383
2647
|
|
|
2384
|
-
it(
|
|
2385
|
-
const onDropSpy = jest.fn()
|
|
2648
|
+
it("accepts a single files if {multiple} is false and {accept} criteria is met", async () => {
|
|
2649
|
+
const onDropSpy = jest.fn();
|
|
2386
2650
|
const ui = (
|
|
2387
2651
|
<Dropzone accept="image/*" onDrop={onDropSpy} multiple={false}>
|
|
2388
2652
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2391,18 +2655,18 @@ describe('useDropzone() hook', () => {
|
|
|
2391
2655
|
</div>
|
|
2392
2656
|
)}
|
|
2393
2657
|
</Dropzone>
|
|
2394
|
-
)
|
|
2395
|
-
const { container, rerender } = render(ui)
|
|
2396
|
-
const dropzone = container.querySelector(
|
|
2658
|
+
);
|
|
2659
|
+
const { container, rerender } = render(ui);
|
|
2660
|
+
const dropzone = container.querySelector("div");
|
|
2397
2661
|
|
|
2398
|
-
const [image] = images
|
|
2399
|
-
fireDrop(dropzone, createDtWithFiles([image]))
|
|
2400
|
-
await flushPromises(rerender, ui)
|
|
2401
|
-
expect(onDropSpy).toHaveBeenCalledWith([image], [], expect.anything())
|
|
2402
|
-
})
|
|
2662
|
+
const [image] = images;
|
|
2663
|
+
fireDrop(dropzone, createDtWithFiles([image]));
|
|
2664
|
+
await flushPromises(rerender, ui);
|
|
2665
|
+
expect(onDropSpy).toHaveBeenCalledWith([image], [], expect.anything());
|
|
2666
|
+
});
|
|
2403
2667
|
|
|
2404
|
-
it(
|
|
2405
|
-
const onDropSpy = jest.fn()
|
|
2668
|
+
it("accepts all files if {multiple} is true", async () => {
|
|
2669
|
+
const onDropSpy = jest.fn();
|
|
2406
2670
|
const ui = (
|
|
2407
2671
|
<Dropzone onDrop={onDropSpy}>
|
|
2408
2672
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2411,19 +2675,19 @@ describe('useDropzone() hook', () => {
|
|
|
2411
2675
|
</div>
|
|
2412
2676
|
)}
|
|
2413
2677
|
</Dropzone>
|
|
2414
|
-
)
|
|
2415
|
-
const { container, rerender } = render(ui)
|
|
2416
|
-
const dropzone = container.querySelector(
|
|
2678
|
+
);
|
|
2679
|
+
const { container, rerender } = render(ui);
|
|
2680
|
+
const dropzone = container.querySelector("div");
|
|
2417
2681
|
|
|
2418
|
-
fireDrop(dropzone, createDtWithFiles(files))
|
|
2419
|
-
await flushPromises(rerender, ui)
|
|
2420
|
-
expect(onDropSpy).toHaveBeenCalledWith(files, [], expect.anything())
|
|
2421
|
-
})
|
|
2682
|
+
fireDrop(dropzone, createDtWithFiles(files));
|
|
2683
|
+
await flushPromises(rerender, ui);
|
|
2684
|
+
expect(onDropSpy).toHaveBeenCalledWith(files, [], expect.anything());
|
|
2685
|
+
});
|
|
2422
2686
|
|
|
2423
|
-
it(
|
|
2424
|
-
const onDropSpy = jest.fn()
|
|
2425
|
-
const activeRef = createRef()
|
|
2426
|
-
const active = <span ref={activeRef}>I am active</span
|
|
2687
|
+
it("resets {isFileDialogActive} state", async () => {
|
|
2688
|
+
const onDropSpy = jest.fn();
|
|
2689
|
+
const activeRef = createRef();
|
|
2690
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
2427
2691
|
|
|
2428
2692
|
const ui = (
|
|
2429
2693
|
<Dropzone onDrop={onDropSpy}>
|
|
@@ -2437,24 +2701,24 @@ describe('useDropzone() hook', () => {
|
|
|
2437
2701
|
</div>
|
|
2438
2702
|
)}
|
|
2439
2703
|
</Dropzone>
|
|
2440
|
-
)
|
|
2441
|
-
const { container, rerender } = render(ui)
|
|
2442
|
-
const dropzone = container.querySelector(
|
|
2443
|
-
const btn = container.querySelector(
|
|
2704
|
+
);
|
|
2705
|
+
const { container, rerender } = render(ui);
|
|
2706
|
+
const dropzone = container.querySelector("div");
|
|
2707
|
+
const btn = container.querySelector("button");
|
|
2444
2708
|
|
|
2445
|
-
btn.click()
|
|
2709
|
+
btn.click();
|
|
2446
2710
|
|
|
2447
|
-
const ref = activeRef.current
|
|
2448
|
-
expect(dropzone).toContainElement(ref)
|
|
2711
|
+
const ref = activeRef.current;
|
|
2712
|
+
expect(dropzone).toContainElement(ref);
|
|
2449
2713
|
|
|
2450
|
-
fireDrop(dropzone, createDtWithFiles(files))
|
|
2451
|
-
await flushPromises(rerender, ui)
|
|
2714
|
+
fireDrop(dropzone, createDtWithFiles(files));
|
|
2715
|
+
await flushPromises(rerender, ui);
|
|
2452
2716
|
|
|
2453
|
-
expect(dropzone).not.toContainElement(ref)
|
|
2454
|
-
})
|
|
2717
|
+
expect(dropzone).not.toContainElement(ref);
|
|
2718
|
+
});
|
|
2455
2719
|
|
|
2456
|
-
it(
|
|
2457
|
-
const onDropSpy = jest.fn()
|
|
2720
|
+
it("gets invoked with both accepted/rejected files", async () => {
|
|
2721
|
+
const onDropSpy = jest.fn();
|
|
2458
2722
|
const ui = (
|
|
2459
2723
|
<Dropzone accept="image/*" onDrop={onDropSpy}>
|
|
2460
2724
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2463,47 +2727,55 @@ describe('useDropzone() hook', () => {
|
|
|
2463
2727
|
</div>
|
|
2464
2728
|
)}
|
|
2465
2729
|
</Dropzone>
|
|
2466
|
-
)
|
|
2467
|
-
const { container, rerender } = render(ui)
|
|
2468
|
-
const dropzone = container.querySelector(
|
|
2730
|
+
);
|
|
2731
|
+
const { container, rerender } = render(ui);
|
|
2732
|
+
const dropzone = container.querySelector("div");
|
|
2469
2733
|
|
|
2470
|
-
fireDrop(dropzone, createDtWithFiles(files))
|
|
2471
|
-
await flushPromises(rerender, ui)
|
|
2472
|
-
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2734
|
+
fireDrop(dropzone, createDtWithFiles(files));
|
|
2735
|
+
await flushPromises(rerender, ui);
|
|
2736
|
+
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2737
|
+
[],
|
|
2738
|
+
[
|
|
2739
|
+
{
|
|
2740
|
+
file: files[0],
|
|
2741
|
+
errors: [
|
|
2742
|
+
{
|
|
2743
|
+
code: "file-invalid-type",
|
|
2744
|
+
message: "File type must be image/*",
|
|
2745
|
+
},
|
|
2746
|
+
],
|
|
2747
|
+
},
|
|
2748
|
+
],
|
|
2749
|
+
expect.anything()
|
|
2750
|
+
);
|
|
2751
|
+
onDropSpy.mockClear();
|
|
2752
|
+
|
|
2753
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2754
|
+
await flushPromises(rerender, ui);
|
|
2755
|
+
expect(onDropSpy).toHaveBeenCalledWith(images, [], expect.anything());
|
|
2756
|
+
onDropSpy.mockClear();
|
|
2757
|
+
|
|
2758
|
+
fireDrop(dropzone, createDtWithFiles([...files, ...images]));
|
|
2759
|
+
await flushPromises(rerender, ui);
|
|
2760
|
+
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2761
|
+
images,
|
|
2762
|
+
[
|
|
2763
|
+
{
|
|
2764
|
+
file: files[0],
|
|
2765
|
+
errors: [
|
|
2766
|
+
{
|
|
2767
|
+
code: "file-invalid-type",
|
|
2768
|
+
message: "File type must be image/*",
|
|
2769
|
+
},
|
|
2770
|
+
],
|
|
2771
|
+
},
|
|
2772
|
+
],
|
|
2773
|
+
expect.anything()
|
|
2774
|
+
);
|
|
2775
|
+
});
|
|
2504
2776
|
|
|
2505
|
-
test(
|
|
2506
|
-
const onDropAcceptedSpy = jest.fn()
|
|
2777
|
+
test("onDropAccepted callback is invoked if some files are accepted", async () => {
|
|
2778
|
+
const onDropAcceptedSpy = jest.fn();
|
|
2507
2779
|
const ui = (
|
|
2508
2780
|
<Dropzone accept="image/*" onDropAccepted={onDropAcceptedSpy}>
|
|
2509
2781
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2512,27 +2784,27 @@ describe('useDropzone() hook', () => {
|
|
|
2512
2784
|
</div>
|
|
2513
2785
|
)}
|
|
2514
2786
|
</Dropzone>
|
|
2515
|
-
)
|
|
2516
|
-
const { container, rerender } = render(ui)
|
|
2517
|
-
const dropzone = container.querySelector(
|
|
2787
|
+
);
|
|
2788
|
+
const { container, rerender } = render(ui);
|
|
2789
|
+
const dropzone = container.querySelector("div");
|
|
2518
2790
|
|
|
2519
|
-
fireDrop(dropzone, createDtWithFiles(files))
|
|
2520
|
-
await flushPromises(rerender, ui)
|
|
2521
|
-
expect(onDropAcceptedSpy).not.toHaveBeenCalled()
|
|
2522
|
-
onDropAcceptedSpy.mockClear()
|
|
2791
|
+
fireDrop(dropzone, createDtWithFiles(files));
|
|
2792
|
+
await flushPromises(rerender, ui);
|
|
2793
|
+
expect(onDropAcceptedSpy).not.toHaveBeenCalled();
|
|
2794
|
+
onDropAcceptedSpy.mockClear();
|
|
2523
2795
|
|
|
2524
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2525
|
-
await flushPromises(rerender, ui)
|
|
2526
|
-
expect(onDropAcceptedSpy).toHaveBeenCalledWith(images, expect.anything())
|
|
2527
|
-
onDropAcceptedSpy.mockClear()
|
|
2796
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2797
|
+
await flushPromises(rerender, ui);
|
|
2798
|
+
expect(onDropAcceptedSpy).toHaveBeenCalledWith(images, expect.anything());
|
|
2799
|
+
onDropAcceptedSpy.mockClear();
|
|
2528
2800
|
|
|
2529
|
-
fireDrop(dropzone, createDtWithFiles([...files, ...images]))
|
|
2530
|
-
await flushPromises(rerender, ui)
|
|
2531
|
-
expect(onDropAcceptedSpy).toHaveBeenCalledWith(images, expect.anything())
|
|
2532
|
-
})
|
|
2801
|
+
fireDrop(dropzone, createDtWithFiles([...files, ...images]));
|
|
2802
|
+
await flushPromises(rerender, ui);
|
|
2803
|
+
expect(onDropAcceptedSpy).toHaveBeenCalledWith(images, expect.anything());
|
|
2804
|
+
});
|
|
2533
2805
|
|
|
2534
|
-
test(
|
|
2535
|
-
const onDropRejectedSpy = jest.fn()
|
|
2806
|
+
test("onDropRejected callback is invoked if some files are rejected", async () => {
|
|
2807
|
+
const onDropRejectedSpy = jest.fn();
|
|
2536
2808
|
const ui = (
|
|
2537
2809
|
<Dropzone accept="image/*" onDropRejected={onDropRejectedSpy}>
|
|
2538
2810
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2541,47 +2813,53 @@ describe('useDropzone() hook', () => {
|
|
|
2541
2813
|
</div>
|
|
2542
2814
|
)}
|
|
2543
2815
|
</Dropzone>
|
|
2544
|
-
)
|
|
2545
|
-
const { container, rerender } = render(ui)
|
|
2546
|
-
const dropzone = container.querySelector(
|
|
2816
|
+
);
|
|
2817
|
+
const { container, rerender } = render(ui);
|
|
2818
|
+
const dropzone = container.querySelector("div");
|
|
2547
2819
|
|
|
2548
|
-
fireDrop(dropzone, createDtWithFiles(files))
|
|
2549
|
-
await flushPromises(rerender, ui)
|
|
2550
|
-
expect(onDropRejectedSpy).toHaveBeenCalledWith(
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
expect(onDropRejectedSpy).not.toHaveBeenCalled()
|
|
2566
|
-
onDropRejectedSpy.mockClear()
|
|
2567
|
-
|
|
2568
|
-
fireDrop(dropzone, createDtWithFiles([...files, ...images]))
|
|
2569
|
-
await flushPromises(rerender, ui)
|
|
2570
|
-
expect(onDropRejectedSpy).toHaveBeenCalledWith([
|
|
2571
|
-
{
|
|
2572
|
-
file: files[0],
|
|
2573
|
-
errors: [
|
|
2574
|
-
{
|
|
2575
|
-
code: 'file-invalid-type',
|
|
2576
|
-
message: 'File type must be image/*',
|
|
2577
|
-
}
|
|
2578
|
-
]
|
|
2579
|
-
}
|
|
2580
|
-
], expect.anything())
|
|
2581
|
-
})
|
|
2820
|
+
fireDrop(dropzone, createDtWithFiles(files));
|
|
2821
|
+
await flushPromises(rerender, ui);
|
|
2822
|
+
expect(onDropRejectedSpy).toHaveBeenCalledWith(
|
|
2823
|
+
[
|
|
2824
|
+
{
|
|
2825
|
+
file: files[0],
|
|
2826
|
+
errors: [
|
|
2827
|
+
{
|
|
2828
|
+
code: "file-invalid-type",
|
|
2829
|
+
message: "File type must be image/*",
|
|
2830
|
+
},
|
|
2831
|
+
],
|
|
2832
|
+
},
|
|
2833
|
+
],
|
|
2834
|
+
expect.anything()
|
|
2835
|
+
);
|
|
2836
|
+
onDropRejectedSpy.mockClear();
|
|
2582
2837
|
|
|
2583
|
-
|
|
2584
|
-
|
|
2838
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2839
|
+
await flushPromises(rerender, ui);
|
|
2840
|
+
expect(onDropRejectedSpy).not.toHaveBeenCalled();
|
|
2841
|
+
onDropRejectedSpy.mockClear();
|
|
2842
|
+
|
|
2843
|
+
fireDrop(dropzone, createDtWithFiles([...files, ...images]));
|
|
2844
|
+
await flushPromises(rerender, ui);
|
|
2845
|
+
expect(onDropRejectedSpy).toHaveBeenCalledWith(
|
|
2846
|
+
[
|
|
2847
|
+
{
|
|
2848
|
+
file: files[0],
|
|
2849
|
+
errors: [
|
|
2850
|
+
{
|
|
2851
|
+
code: "file-invalid-type",
|
|
2852
|
+
message: "File type must be image/*",
|
|
2853
|
+
},
|
|
2854
|
+
],
|
|
2855
|
+
},
|
|
2856
|
+
],
|
|
2857
|
+
expect.anything()
|
|
2858
|
+
);
|
|
2859
|
+
});
|
|
2860
|
+
|
|
2861
|
+
it("accepts a dropped image when Firefox provides a bogus file type", async () => {
|
|
2862
|
+
const onDropSpy = jest.fn();
|
|
2585
2863
|
const ui = (
|
|
2586
2864
|
<Dropzone accept="image/*" onDrop={onDropSpy}>
|
|
2587
2865
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2590,19 +2868,19 @@ describe('useDropzone() hook', () => {
|
|
|
2590
2868
|
</div>
|
|
2591
2869
|
)}
|
|
2592
2870
|
</Dropzone>
|
|
2593
|
-
)
|
|
2594
|
-
const { container, rerender } = render(ui)
|
|
2595
|
-
const dropzone = container.querySelector(
|
|
2871
|
+
);
|
|
2872
|
+
const { container, rerender } = render(ui);
|
|
2873
|
+
const dropzone = container.querySelector("div");
|
|
2596
2874
|
|
|
2597
|
-
const images = [createFile(
|
|
2598
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2599
|
-
await flushPromises(rerender, ui)
|
|
2875
|
+
const images = [createFile("bogus.gif", 1234, "application/x-moz-file")];
|
|
2876
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2877
|
+
await flushPromises(rerender, ui);
|
|
2600
2878
|
|
|
2601
|
-
expect(onDropSpy).toHaveBeenCalledWith(images, [], expect.anything())
|
|
2602
|
-
})
|
|
2879
|
+
expect(onDropSpy).toHaveBeenCalledWith(images, [], expect.anything());
|
|
2880
|
+
});
|
|
2603
2881
|
|
|
2604
|
-
it(
|
|
2605
|
-
const onDropSpy = jest.fn()
|
|
2882
|
+
it("filters files according to {maxSize}", async () => {
|
|
2883
|
+
const onDropSpy = jest.fn();
|
|
2606
2884
|
const ui = (
|
|
2607
2885
|
<Dropzone onDrop={onDropSpy} maxSize={1111}>
|
|
2608
2886
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2611,37 +2889,41 @@ describe('useDropzone() hook', () => {
|
|
|
2611
2889
|
</div>
|
|
2612
2890
|
)}
|
|
2613
2891
|
</Dropzone>
|
|
2614
|
-
)
|
|
2615
|
-
const { container, rerender } = render(ui)
|
|
2616
|
-
const dropzone = container.querySelector(
|
|
2892
|
+
);
|
|
2893
|
+
const { container, rerender } = render(ui);
|
|
2894
|
+
const dropzone = container.querySelector("div");
|
|
2617
2895
|
|
|
2618
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2619
|
-
await flushPromises(rerender, ui)
|
|
2896
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
2897
|
+
await flushPromises(rerender, ui);
|
|
2620
2898
|
|
|
2621
|
-
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2899
|
+
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2900
|
+
[],
|
|
2901
|
+
[
|
|
2902
|
+
{
|
|
2903
|
+
file: images[0],
|
|
2904
|
+
errors: [
|
|
2905
|
+
{
|
|
2906
|
+
code: "file-too-large",
|
|
2907
|
+
message: "File is larger than 1111 bytes",
|
|
2908
|
+
},
|
|
2909
|
+
],
|
|
2910
|
+
},
|
|
2911
|
+
{
|
|
2912
|
+
file: images[1],
|
|
2913
|
+
errors: [
|
|
2914
|
+
{
|
|
2915
|
+
code: "file-too-large",
|
|
2916
|
+
message: "File is larger than 1111 bytes",
|
|
2917
|
+
},
|
|
2918
|
+
],
|
|
2919
|
+
},
|
|
2920
|
+
],
|
|
2921
|
+
expect.anything()
|
|
2922
|
+
);
|
|
2923
|
+
});
|
|
2642
2924
|
|
|
2643
|
-
it(
|
|
2644
|
-
const onDropSpy = jest.fn()
|
|
2925
|
+
it("filters files according to {minSize}", async () => {
|
|
2926
|
+
const onDropSpy = jest.fn();
|
|
2645
2927
|
const ui = (
|
|
2646
2928
|
<Dropzone onDrop={onDropSpy} minSize={1112}>
|
|
2647
2929
|
{({ getRootProps, getInputProps }) => (
|
|
@@ -2650,38 +2932,42 @@ describe('useDropzone() hook', () => {
|
|
|
2650
2932
|
</div>
|
|
2651
2933
|
)}
|
|
2652
2934
|
</Dropzone>
|
|
2653
|
-
)
|
|
2654
|
-
const { container, rerender } = render(ui)
|
|
2655
|
-
const dropzone = container.querySelector(
|
|
2935
|
+
);
|
|
2936
|
+
const { container, rerender } = render(ui);
|
|
2937
|
+
const dropzone = container.querySelector("div");
|
|
2656
2938
|
|
|
2657
|
-
fireDrop(dropzone, createDtWithFiles(files))
|
|
2658
|
-
await flushPromises(rerender, ui)
|
|
2939
|
+
fireDrop(dropzone, createDtWithFiles(files));
|
|
2940
|
+
await flushPromises(rerender, ui);
|
|
2659
2941
|
|
|
2660
|
-
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2942
|
+
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2943
|
+
[],
|
|
2944
|
+
[
|
|
2945
|
+
{
|
|
2946
|
+
file: files[0],
|
|
2947
|
+
errors: [
|
|
2948
|
+
{
|
|
2949
|
+
code: "file-too-small",
|
|
2950
|
+
message: "File is smaller than 1112 bytes",
|
|
2951
|
+
},
|
|
2952
|
+
],
|
|
2953
|
+
},
|
|
2954
|
+
],
|
|
2955
|
+
expect.anything()
|
|
2956
|
+
);
|
|
2957
|
+
});
|
|
2958
|
+
});
|
|
2673
2959
|
|
|
2674
|
-
describe(
|
|
2960
|
+
describe("onFileDialogCancel", () => {
|
|
2675
2961
|
beforeEach(() => {
|
|
2676
|
-
jest.useFakeTimers()
|
|
2677
|
-
})
|
|
2962
|
+
jest.useFakeTimers();
|
|
2963
|
+
});
|
|
2678
2964
|
|
|
2679
2965
|
afterEach(() => {
|
|
2680
|
-
jest.useRealTimers()
|
|
2681
|
-
})
|
|
2966
|
+
jest.useRealTimers();
|
|
2967
|
+
});
|
|
2682
2968
|
|
|
2683
|
-
it(
|
|
2684
|
-
const onFileDialogCancelSpy = jest.fn()
|
|
2969
|
+
it("is not invoked every time window receives focus", () => {
|
|
2970
|
+
const onFileDialogCancelSpy = jest.fn();
|
|
2685
2971
|
|
|
2686
2972
|
render(
|
|
2687
2973
|
<Dropzone onFileDialogCancel={onFileDialogCancelSpy}>
|
|
@@ -2691,18 +2977,18 @@ describe('useDropzone() hook', () => {
|
|
|
2691
2977
|
</div>
|
|
2692
2978
|
)}
|
|
2693
2979
|
</Dropzone>
|
|
2694
|
-
)
|
|
2980
|
+
);
|
|
2695
2981
|
|
|
2696
|
-
dispatchEvt(document.body,
|
|
2697
|
-
drainTimers()
|
|
2982
|
+
dispatchEvt(document.body, "focus");
|
|
2983
|
+
drainTimers();
|
|
2698
2984
|
|
|
2699
|
-
expect(onFileDialogCancelSpy).not.toHaveBeenCalled()
|
|
2700
|
-
})
|
|
2985
|
+
expect(onFileDialogCancelSpy).not.toHaveBeenCalled();
|
|
2986
|
+
});
|
|
2701
2987
|
|
|
2702
|
-
it(
|
|
2703
|
-
const activeRef = createRef()
|
|
2704
|
-
const active = <span ref={activeRef}>I am active</span
|
|
2705
|
-
const onFileDialogCancelSpy = jest.fn()
|
|
2988
|
+
it("resets {isFileDialogActive}", () => {
|
|
2989
|
+
const activeRef = createRef();
|
|
2990
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
2991
|
+
const onFileDialogCancelSpy = jest.fn();
|
|
2706
2992
|
|
|
2707
2993
|
const { container } = render(
|
|
2708
2994
|
<Dropzone onFileDialogCancel={onFileDialogCancelSpy}>
|
|
@@ -2716,26 +3002,26 @@ describe('useDropzone() hook', () => {
|
|
|
2716
3002
|
</div>
|
|
2717
3003
|
)}
|
|
2718
3004
|
</Dropzone>
|
|
2719
|
-
)
|
|
3005
|
+
);
|
|
2720
3006
|
|
|
2721
|
-
const dropzone = container.querySelector(
|
|
2722
|
-
const btn = container.querySelector(
|
|
3007
|
+
const dropzone = container.querySelector("div");
|
|
3008
|
+
const btn = container.querySelector("button");
|
|
2723
3009
|
|
|
2724
|
-
btn.click()
|
|
2725
|
-
drainTimers()
|
|
2726
|
-
const ref = activeRef.current
|
|
2727
|
-
expect(ref).not.toBeNull()
|
|
2728
|
-
expect(dropzone).toContainElement(ref)
|
|
3010
|
+
btn.click();
|
|
3011
|
+
drainTimers();
|
|
3012
|
+
const ref = activeRef.current;
|
|
3013
|
+
expect(ref).not.toBeNull();
|
|
3014
|
+
expect(dropzone).toContainElement(ref);
|
|
2729
3015
|
|
|
2730
|
-
dispatchEvt(document.body,
|
|
2731
|
-
drainTimers()
|
|
3016
|
+
dispatchEvt(document.body, "focus");
|
|
3017
|
+
drainTimers();
|
|
2732
3018
|
|
|
2733
|
-
expect(onFileDialogCancelSpy).toHaveBeenCalled()
|
|
2734
|
-
expect(dropzone).not.toContainElement(ref)
|
|
2735
|
-
})
|
|
3019
|
+
expect(onFileDialogCancelSpy).toHaveBeenCalled();
|
|
3020
|
+
expect(dropzone).not.toContainElement(ref);
|
|
3021
|
+
});
|
|
2736
3022
|
|
|
2737
|
-
it(
|
|
2738
|
-
const onFileDialogCancelSpy = jest.fn()
|
|
3023
|
+
it("is not invoked if <input> is not rendered", () => {
|
|
3024
|
+
const onFileDialogCancelSpy = jest.fn();
|
|
2739
3025
|
const { container, rerender } = render(
|
|
2740
3026
|
<Dropzone onFileDialogCancel={onFileDialogCancelSpy}>
|
|
2741
3027
|
{({ getRootProps, getInputProps, open }) => (
|
|
@@ -2747,27 +3033,27 @@ describe('useDropzone() hook', () => {
|
|
|
2747
3033
|
</div>
|
|
2748
3034
|
)}
|
|
2749
3035
|
</Dropzone>
|
|
2750
|
-
)
|
|
3036
|
+
);
|
|
2751
3037
|
|
|
2752
|
-
const btn = container.querySelector(
|
|
2753
|
-
btn.click()
|
|
2754
|
-
drainTimers()
|
|
3038
|
+
const btn = container.querySelector("button");
|
|
3039
|
+
btn.click();
|
|
3040
|
+
drainTimers();
|
|
2755
3041
|
|
|
2756
3042
|
rerender(
|
|
2757
3043
|
<Dropzone onFileDialogCancel={onFileDialogCancelSpy}>
|
|
2758
3044
|
{({ getRootProps }) => <div {...getRootProps()} />}
|
|
2759
3045
|
</Dropzone>
|
|
2760
|
-
)
|
|
2761
|
-
drainTimers()
|
|
3046
|
+
);
|
|
3047
|
+
drainTimers();
|
|
2762
3048
|
|
|
2763
|
-
dispatchEvt(document.body,
|
|
2764
|
-
drainTimers()
|
|
3049
|
+
dispatchEvt(document.body, "focus");
|
|
3050
|
+
drainTimers();
|
|
2765
3051
|
|
|
2766
|
-
expect(onFileDialogCancelSpy).not.toHaveBeenCalled()
|
|
2767
|
-
})
|
|
3052
|
+
expect(onFileDialogCancelSpy).not.toHaveBeenCalled();
|
|
3053
|
+
});
|
|
2768
3054
|
|
|
2769
|
-
it(
|
|
2770
|
-
const onFileDialogCancelSpy = jest.fn()
|
|
3055
|
+
it("is not invoked if files were selected", () => {
|
|
3056
|
+
const onFileDialogCancelSpy = jest.fn();
|
|
2771
3057
|
|
|
2772
3058
|
const { container } = render(
|
|
2773
3059
|
<Dropzone onFileDialogCancel={onFileDialogCancelSpy}>
|
|
@@ -2780,22 +3066,22 @@ describe('useDropzone() hook', () => {
|
|
|
2780
3066
|
</div>
|
|
2781
3067
|
)}
|
|
2782
3068
|
</Dropzone>
|
|
2783
|
-
)
|
|
3069
|
+
);
|
|
2784
3070
|
|
|
2785
|
-
const input = container.querySelector(
|
|
2786
|
-
Object.defineProperty(input,
|
|
3071
|
+
const input = container.querySelector("input");
|
|
3072
|
+
Object.defineProperty(input, "files", { value: files });
|
|
2787
3073
|
|
|
2788
|
-
const btn = container.querySelector(
|
|
2789
|
-
btn.click()
|
|
2790
|
-
drainTimers()
|
|
3074
|
+
const btn = container.querySelector("button");
|
|
3075
|
+
btn.click();
|
|
3076
|
+
drainTimers();
|
|
2791
3077
|
|
|
2792
|
-
dispatchEvt(document.body,
|
|
2793
|
-
drainTimers()
|
|
3078
|
+
dispatchEvt(document.body, "focus");
|
|
3079
|
+
drainTimers();
|
|
2794
3080
|
|
|
2795
|
-
expect(onFileDialogCancelSpy).not.toHaveBeenCalled()
|
|
2796
|
-
})
|
|
3081
|
+
expect(onFileDialogCancelSpy).not.toHaveBeenCalled();
|
|
3082
|
+
});
|
|
2797
3083
|
|
|
2798
|
-
it(
|
|
3084
|
+
it("does not throw if callback is not provided", () => {
|
|
2799
3085
|
const { container } = render(
|
|
2800
3086
|
<Dropzone onFileDialogCancel={null}>
|
|
2801
3087
|
{({ getRootProps, getInputProps, open }) => (
|
|
@@ -2807,45 +3093,43 @@ describe('useDropzone() hook', () => {
|
|
|
2807
3093
|
</div>
|
|
2808
3094
|
)}
|
|
2809
3095
|
</Dropzone>
|
|
2810
|
-
)
|
|
3096
|
+
);
|
|
2811
3097
|
|
|
2812
|
-
const btn = container.querySelector(
|
|
2813
|
-
btn.click()
|
|
2814
|
-
drainTimers()
|
|
3098
|
+
const btn = container.querySelector("button");
|
|
3099
|
+
btn.click();
|
|
3100
|
+
drainTimers();
|
|
2815
3101
|
|
|
2816
3102
|
const fn = () => {
|
|
2817
|
-
dispatchEvt(document.body,
|
|
2818
|
-
drainTimers()
|
|
2819
|
-
}
|
|
2820
|
-
expect(fn).not.toThrow()
|
|
2821
|
-
})
|
|
2822
|
-
})
|
|
2823
|
-
|
|
2824
|
-
describe(
|
|
2825
|
-
it(
|
|
2826
|
-
const onFileDialogOpenSpy = jest.fn()
|
|
3103
|
+
dispatchEvt(document.body, "focus");
|
|
3104
|
+
drainTimers();
|
|
3105
|
+
};
|
|
3106
|
+
expect(fn).not.toThrow();
|
|
3107
|
+
});
|
|
3108
|
+
});
|
|
3109
|
+
|
|
3110
|
+
describe("onFileDialogOpen", () => {
|
|
3111
|
+
it("is invoked when opening the file dialog", () => {
|
|
3112
|
+
const onFileDialogOpenSpy = jest.fn();
|
|
2827
3113
|
const { container } = render(
|
|
2828
|
-
<Dropzone
|
|
2829
|
-
onFileDialogOpen={onFileDialogOpenSpy}>
|
|
3114
|
+
<Dropzone onFileDialogOpen={onFileDialogOpenSpy}>
|
|
2830
3115
|
{({ getRootProps, getInputProps }) => (
|
|
2831
3116
|
<div {...getRootProps()}>
|
|
2832
3117
|
<input {...getInputProps()} />
|
|
2833
3118
|
</div>
|
|
2834
3119
|
)}
|
|
2835
3120
|
</Dropzone>
|
|
2836
|
-
)
|
|
3121
|
+
);
|
|
2837
3122
|
|
|
2838
|
-
const dropzone = container.querySelector(
|
|
2839
|
-
fireEvent.click(dropzone)
|
|
3123
|
+
const dropzone = container.querySelector("div");
|
|
3124
|
+
fireEvent.click(dropzone);
|
|
2840
3125
|
|
|
2841
|
-
expect(onFileDialogOpenSpy).toHaveBeenCalled()
|
|
2842
|
-
})
|
|
3126
|
+
expect(onFileDialogOpenSpy).toHaveBeenCalled();
|
|
3127
|
+
});
|
|
2843
3128
|
|
|
2844
|
-
it(
|
|
2845
|
-
const onFileDialogOpenSpy = jest.fn()
|
|
3129
|
+
it("is invoked when opening the file dialog programmatically", () => {
|
|
3130
|
+
const onFileDialogOpenSpy = jest.fn();
|
|
2846
3131
|
const { container } = render(
|
|
2847
|
-
<Dropzone
|
|
2848
|
-
onFileDialogOpen={onFileDialogOpenSpy}>
|
|
3132
|
+
<Dropzone onFileDialogOpen={onFileDialogOpenSpy}>
|
|
2849
3133
|
{({ getRootProps, getInputProps, open }) => (
|
|
2850
3134
|
<div {...getRootProps()}>
|
|
2851
3135
|
<input {...getInputProps()} />
|
|
@@ -2855,18 +3139,18 @@ describe('useDropzone() hook', () => {
|
|
|
2855
3139
|
</div>
|
|
2856
3140
|
)}
|
|
2857
3141
|
</Dropzone>
|
|
2858
|
-
)
|
|
3142
|
+
);
|
|
2859
3143
|
|
|
2860
|
-
const btn = container.querySelector(
|
|
2861
|
-
btn.click()
|
|
3144
|
+
const btn = container.querySelector("button");
|
|
3145
|
+
btn.click();
|
|
2862
3146
|
|
|
2863
|
-
expect(onFileDialogOpenSpy).toHaveBeenCalled()
|
|
2864
|
-
})
|
|
2865
|
-
})
|
|
3147
|
+
expect(onFileDialogOpenSpy).toHaveBeenCalled();
|
|
3148
|
+
});
|
|
3149
|
+
});
|
|
2866
3150
|
|
|
2867
|
-
describe(
|
|
2868
|
-
it(
|
|
2869
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
3151
|
+
describe("{open}", () => {
|
|
3152
|
+
it("can open file dialog programmatically", () => {
|
|
3153
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
2870
3154
|
const { container } = render(
|
|
2871
3155
|
<Dropzone>
|
|
2872
3156
|
{({ getRootProps, getInputProps, open }) => (
|
|
@@ -2878,18 +3162,18 @@ describe('useDropzone() hook', () => {
|
|
|
2878
3162
|
</div>
|
|
2879
3163
|
)}
|
|
2880
3164
|
</Dropzone>
|
|
2881
|
-
)
|
|
3165
|
+
);
|
|
2882
3166
|
|
|
2883
|
-
const btn = container.querySelector(
|
|
3167
|
+
const btn = container.querySelector("button");
|
|
2884
3168
|
|
|
2885
|
-
btn.click()
|
|
3169
|
+
btn.click();
|
|
2886
3170
|
|
|
2887
|
-
expect(onClickSpy).toHaveBeenCalled()
|
|
2888
|
-
})
|
|
3171
|
+
expect(onClickSpy).toHaveBeenCalled();
|
|
3172
|
+
});
|
|
2889
3173
|
|
|
2890
|
-
it(
|
|
2891
|
-
const activeRef = createRef()
|
|
2892
|
-
const active = <span ref={activeRef}>I am active</span
|
|
3174
|
+
it("sets {isFileDialogActive} state", () => {
|
|
3175
|
+
const activeRef = createRef();
|
|
3176
|
+
const active = <span ref={activeRef}>I am active</span>;
|
|
2893
3177
|
const { container } = render(
|
|
2894
3178
|
<Dropzone>
|
|
2895
3179
|
{({ getRootProps, getInputProps, isFileDialogActive, open }) => (
|
|
@@ -2902,20 +3186,20 @@ describe('useDropzone() hook', () => {
|
|
|
2902
3186
|
</div>
|
|
2903
3187
|
)}
|
|
2904
3188
|
</Dropzone>
|
|
2905
|
-
)
|
|
3189
|
+
);
|
|
2906
3190
|
|
|
2907
|
-
const dropzone = container.querySelector(
|
|
2908
|
-
const btn = container.querySelector(
|
|
3191
|
+
const dropzone = container.querySelector("div");
|
|
3192
|
+
const btn = container.querySelector("button");
|
|
2909
3193
|
|
|
2910
|
-
btn.click()
|
|
3194
|
+
btn.click();
|
|
2911
3195
|
|
|
2912
|
-
const ref = activeRef.current
|
|
2913
|
-
expect(ref).not.toBeNull()
|
|
2914
|
-
expect(dropzone).toContainElement(ref)
|
|
2915
|
-
})
|
|
3196
|
+
const ref = activeRef.current;
|
|
3197
|
+
expect(ref).not.toBeNull();
|
|
3198
|
+
expect(dropzone).toContainElement(ref);
|
|
3199
|
+
});
|
|
2916
3200
|
|
|
2917
|
-
it(
|
|
2918
|
-
const onClickSpy = jest.spyOn(HTMLInputElement.prototype,
|
|
3201
|
+
it("does nothing if {disabled} is true", () => {
|
|
3202
|
+
const onClickSpy = jest.spyOn(HTMLInputElement.prototype, "click");
|
|
2919
3203
|
const { container } = render(
|
|
2920
3204
|
<Dropzone disabled>
|
|
2921
3205
|
{({ getRootProps, getInputProps, open }) => (
|
|
@@ -2927,16 +3211,16 @@ describe('useDropzone() hook', () => {
|
|
|
2927
3211
|
</div>
|
|
2928
3212
|
)}
|
|
2929
3213
|
</Dropzone>
|
|
2930
|
-
)
|
|
3214
|
+
);
|
|
2931
3215
|
|
|
2932
|
-
const btn = container.querySelector(
|
|
3216
|
+
const btn = container.querySelector("button");
|
|
2933
3217
|
|
|
2934
|
-
btn.click()
|
|
3218
|
+
btn.click();
|
|
2935
3219
|
|
|
2936
|
-
expect(onClickSpy).not.toHaveBeenCalled()
|
|
2937
|
-
})
|
|
3220
|
+
expect(onClickSpy).not.toHaveBeenCalled();
|
|
3221
|
+
});
|
|
2938
3222
|
|
|
2939
|
-
it(
|
|
3223
|
+
it("does not throw if <input> is missing", () => {
|
|
2940
3224
|
const { container } = render(
|
|
2941
3225
|
<Dropzone>
|
|
2942
3226
|
{({ getRootProps, open }) => (
|
|
@@ -2947,25 +3231,25 @@ describe('useDropzone() hook', () => {
|
|
|
2947
3231
|
</div>
|
|
2948
3232
|
)}
|
|
2949
3233
|
</Dropzone>
|
|
2950
|
-
)
|
|
3234
|
+
);
|
|
2951
3235
|
|
|
2952
|
-
const btn = container.querySelector(
|
|
3236
|
+
const btn = container.querySelector("button");
|
|
2953
3237
|
|
|
2954
|
-
const fn = () => btn.click()
|
|
2955
|
-
expect(fn).not.toThrow()
|
|
2956
|
-
})
|
|
2957
|
-
})
|
|
3238
|
+
const fn = () => btn.click();
|
|
3239
|
+
expect(fn).not.toThrow();
|
|
3240
|
+
});
|
|
3241
|
+
});
|
|
2958
3242
|
|
|
2959
|
-
describe(
|
|
2960
|
-
it(
|
|
2961
|
-
const validator = file => {
|
|
3243
|
+
describe("validator", () => {
|
|
3244
|
+
it("rejects with custom error", async () => {
|
|
3245
|
+
const validator = (file) => {
|
|
2962
3246
|
if (/dogs/i.test(file.name))
|
|
2963
|
-
return { code:
|
|
3247
|
+
return { code: "dogs-not-allowed", message: "Dogs not allowed" };
|
|
2964
3248
|
|
|
2965
3249
|
return null;
|
|
2966
|
-
}
|
|
3250
|
+
};
|
|
2967
3251
|
|
|
2968
|
-
const onDropSpy = jest.fn()
|
|
3252
|
+
const onDropSpy = jest.fn();
|
|
2969
3253
|
|
|
2970
3254
|
const ui = (
|
|
2971
3255
|
<Dropzone validator={validator} onDrop={onDropSpy} multiple={true}>
|
|
@@ -2975,131 +3259,133 @@ describe('useDropzone() hook', () => {
|
|
|
2975
3259
|
</div>
|
|
2976
3260
|
)}
|
|
2977
3261
|
</Dropzone>
|
|
2978
|
-
)
|
|
3262
|
+
);
|
|
2979
3263
|
|
|
2980
|
-
const { container, rerender } = render(ui)
|
|
2981
|
-
const dropzone = container.querySelector(
|
|
3264
|
+
const { container, rerender } = render(ui);
|
|
3265
|
+
const dropzone = container.querySelector("div");
|
|
2982
3266
|
|
|
2983
|
-
fireDrop(dropzone, createDtWithFiles(images))
|
|
2984
|
-
await flushPromises(rerender, ui)
|
|
3267
|
+
fireDrop(dropzone, createDtWithFiles(images));
|
|
3268
|
+
await flushPromises(rerender, ui);
|
|
2985
3269
|
|
|
2986
|
-
expect(onDropSpy).toHaveBeenCalledWith(
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
3270
|
+
expect(onDropSpy).toHaveBeenCalledWith(
|
|
3271
|
+
[images[0]],
|
|
3272
|
+
[
|
|
3273
|
+
{
|
|
3274
|
+
file: images[1],
|
|
3275
|
+
errors: [
|
|
3276
|
+
{
|
|
3277
|
+
code: "dogs-not-allowed",
|
|
3278
|
+
message: "Dogs not allowed",
|
|
3279
|
+
},
|
|
3280
|
+
],
|
|
3281
|
+
},
|
|
3282
|
+
],
|
|
3283
|
+
expect.anything()
|
|
3284
|
+
);
|
|
3285
|
+
});
|
|
3286
|
+
});
|
|
2999
3287
|
|
|
3000
|
-
describe(
|
|
3001
|
-
it(
|
|
3288
|
+
describe("accessibility", () => {
|
|
3289
|
+
it("sets the role attribute to button by default on the root", () => {
|
|
3002
3290
|
const { container } = render(
|
|
3003
3291
|
<Dropzone>
|
|
3004
|
-
{({ getRootProps }) => (
|
|
3005
|
-
<div id="root" {...getRootProps()} />
|
|
3006
|
-
)}
|
|
3292
|
+
{({ getRootProps }) => <div id="root" {...getRootProps()} />}
|
|
3007
3293
|
</Dropzone>
|
|
3008
|
-
)
|
|
3009
|
-
const root = container.querySelector(
|
|
3294
|
+
);
|
|
3295
|
+
const root = container.querySelector("#root");
|
|
3010
3296
|
|
|
3011
|
-
expect(root).toHaveAttribute(
|
|
3012
|
-
})
|
|
3297
|
+
expect(root).toHaveAttribute("role", "button");
|
|
3298
|
+
});
|
|
3013
3299
|
|
|
3014
|
-
test(
|
|
3300
|
+
test("users can override the default role attribute on the root", () => {
|
|
3015
3301
|
const { container } = render(
|
|
3016
3302
|
<Dropzone>
|
|
3017
3303
|
{({ getRootProps }) => (
|
|
3018
|
-
<div id="root" {...getRootProps({role:
|
|
3304
|
+
<div id="root" {...getRootProps({ role: "generic" })} />
|
|
3019
3305
|
)}
|
|
3020
3306
|
</Dropzone>
|
|
3021
|
-
)
|
|
3022
|
-
const root = container.querySelector(
|
|
3307
|
+
);
|
|
3308
|
+
const root = container.querySelector("#root");
|
|
3023
3309
|
|
|
3024
|
-
expect(root).toHaveAttribute(
|
|
3025
|
-
})
|
|
3026
|
-
})
|
|
3027
|
-
})
|
|
3310
|
+
expect(root).toHaveAttribute("role", "generic");
|
|
3311
|
+
});
|
|
3312
|
+
});
|
|
3313
|
+
});
|
|
3028
3314
|
|
|
3029
3315
|
async function flushPromises(rerender, ui) {
|
|
3030
|
-
await act(() => waitFor(() => rerender(ui)))
|
|
3316
|
+
await act(() => waitFor(() => rerender(ui)));
|
|
3031
3317
|
}
|
|
3032
3318
|
|
|
3033
3319
|
function drainTimers() {
|
|
3034
|
-
act(() => jest.runAllTimers())
|
|
3320
|
+
act(() => jest.runAllTimers());
|
|
3035
3321
|
}
|
|
3036
3322
|
|
|
3037
3323
|
function createDtWithFiles(files = []) {
|
|
3038
3324
|
return {
|
|
3039
3325
|
dataTransfer: {
|
|
3040
3326
|
files,
|
|
3041
|
-
items: files.map(file => ({
|
|
3042
|
-
kind:
|
|
3327
|
+
items: files.map((file) => ({
|
|
3328
|
+
kind: "file",
|
|
3043
3329
|
size: file.size,
|
|
3044
3330
|
type: file.type,
|
|
3045
|
-
getAsFile: () => file
|
|
3331
|
+
getAsFile: () => file,
|
|
3046
3332
|
})),
|
|
3047
|
-
types: [
|
|
3048
|
-
}
|
|
3049
|
-
}
|
|
3333
|
+
types: ["Files"],
|
|
3334
|
+
},
|
|
3335
|
+
};
|
|
3050
3336
|
}
|
|
3051
3337
|
|
|
3052
3338
|
function fireDragEnter(node, data) {
|
|
3053
|
-
dispatchEvt(node,
|
|
3339
|
+
dispatchEvt(node, "dragenter", data);
|
|
3054
3340
|
}
|
|
3055
3341
|
|
|
3056
3342
|
function fireDragOver(node, data) {
|
|
3057
|
-
dispatchEvt(node,
|
|
3343
|
+
dispatchEvt(node, "dragover", data);
|
|
3058
3344
|
}
|
|
3059
3345
|
|
|
3060
3346
|
function fireDragLeave(node, data) {
|
|
3061
|
-
dispatchEvt(node,
|
|
3347
|
+
dispatchEvt(node, "dragleave", data);
|
|
3062
3348
|
}
|
|
3063
3349
|
|
|
3064
3350
|
function fireDrop(node, data) {
|
|
3065
|
-
dispatchEvt(node,
|
|
3351
|
+
dispatchEvt(node, "drop", data);
|
|
3066
3352
|
}
|
|
3067
3353
|
|
|
3068
3354
|
// Using fireEvent.* doesn't work for our use case,
|
|
3069
3355
|
// we cannot set the event props
|
|
3070
3356
|
function dispatchEvt(node, type, data) {
|
|
3071
|
-
const event = new Event(type, { bubbles: true })
|
|
3357
|
+
const event = new Event(type, { bubbles: true });
|
|
3072
3358
|
if (data) {
|
|
3073
|
-
Object.assign(event, data)
|
|
3359
|
+
Object.assign(event, data);
|
|
3074
3360
|
}
|
|
3075
|
-
fireEvent(node, event)
|
|
3361
|
+
fireEvent(node, event);
|
|
3076
3362
|
}
|
|
3077
3363
|
|
|
3078
3364
|
function createFileSystemFileHandle(file) {
|
|
3079
|
-
return {getFile: () => Promise.resolve(file)}
|
|
3365
|
+
return { getFile: () => Promise.resolve(file) };
|
|
3080
3366
|
}
|
|
3081
3367
|
|
|
3082
3368
|
function createFile(name, size, type) {
|
|
3083
|
-
const file = new File([], name, { type })
|
|
3084
|
-
Object.defineProperty(file,
|
|
3369
|
+
const file = new File([], name, { type });
|
|
3370
|
+
Object.defineProperty(file, "size", {
|
|
3085
3371
|
get() {
|
|
3086
|
-
return size
|
|
3087
|
-
}
|
|
3088
|
-
})
|
|
3089
|
-
return file
|
|
3372
|
+
return size;
|
|
3373
|
+
},
|
|
3374
|
+
});
|
|
3375
|
+
return file;
|
|
3090
3376
|
}
|
|
3091
3377
|
|
|
3092
3378
|
function createThenable() {
|
|
3093
3379
|
let done, cancel;
|
|
3094
3380
|
|
|
3095
3381
|
const promise = new Promise((resolve, reject) => {
|
|
3096
|
-
done = resolve
|
|
3097
|
-
cancel = reject
|
|
3098
|
-
})
|
|
3382
|
+
done = resolve;
|
|
3383
|
+
cancel = reject;
|
|
3384
|
+
});
|
|
3099
3385
|
|
|
3100
3386
|
return {
|
|
3101
3387
|
promise,
|
|
3102
3388
|
done,
|
|
3103
|
-
cancel
|
|
3104
|
-
}
|
|
3389
|
+
cancel,
|
|
3390
|
+
};
|
|
3105
3391
|
}
|