|
9 | 9 | isIeOrEdge, |
10 | 10 | isPropagationStopped, |
11 | 11 | onDocumentDragOver, |
12 | | - TOO_MANY_FILES_REJECTION |
| 12 | + TOO_MANY_FILES_REJECTION, |
13 | 13 | } from "./../utils/index"; |
14 | 14 | import { onMount, onDestroy, createEventDispatcher } from "svelte"; |
15 | 15 |
|
|
33 | 33 | export let containerStyles = ""; |
34 | 34 | export let disableDefaultStyles = false; |
35 | 35 | export let name = ""; |
| 36 | + export let inputRef; |
| 37 | + export let required = false; |
36 | 38 | const dispatch = createEventDispatcher(); |
37 | 39 |
|
| 40 | + console.log("yeeehaaaa here is the local UPDATED version!"); |
38 | 41 | //state |
39 | 42 |
|
40 | 43 | let state = { |
|
45 | 48 | isDragReject: false, |
46 | 49 | draggedFiles: [], |
47 | 50 | acceptedFiles: [], |
48 | | - fileRejections: [] |
| 51 | + fileRejections: [], |
49 | 52 | }; |
50 | 53 |
|
51 | 54 | let rootRef; |
52 | | - let inputRef; |
53 | 55 |
|
54 | 56 | function resetState() { |
55 | 57 | state.isFileDialogActive = false; |
|
112 | 114 | dragTargetsRef = [...dragTargetsRef, event.target]; |
113 | 115 |
|
114 | 116 | if (isEvtWithFiles(event)) { |
115 | | - Promise.resolve(getFilesFromEvent(event)).then(draggedFiles => { |
| 117 | + Promise.resolve(getFilesFromEvent(event)).then((draggedFiles) => { |
116 | 118 | if (isPropagationStopped(event) && !noDragEventsBubbling) { |
117 | 119 | return; |
118 | 120 | } |
|
121 | 123 | state.isDragActive = true; |
122 | 124 |
|
123 | 125 | dispatch("dragenter", { |
124 | | - dragEvent: event |
| 126 | + dragEvent: event, |
125 | 127 | }); |
126 | 128 | }); |
127 | 129 | } |
|
139 | 141 |
|
140 | 142 | if (isEvtWithFiles(event)) { |
141 | 143 | dispatch("dragover", { |
142 | | - dragEvent: event |
| 144 | + dragEvent: event, |
143 | 145 | }); |
144 | 146 | } |
145 | 147 |
|
|
152 | 154 |
|
153 | 155 | // Only deactivate once the dropzone and all children have been left |
154 | 156 | const targets = dragTargetsRef.filter( |
155 | | - target => rootRef && rootRef.contains(target) |
| 157 | + (target) => rootRef && rootRef.contains(target) |
156 | 158 | ); |
157 | 159 | // Make sure to remove a target present multiple times only once |
158 | 160 | // (Firefox may fire dragenter/dragleave multiple times on the same element) |
|
170 | 172 |
|
171 | 173 | if (isEvtWithFiles(event)) { |
172 | 174 | dispatch("dragleave", { |
173 | | - dragEvent: event |
| 175 | + dragEvent: event, |
174 | 176 | }); |
175 | 177 | } |
176 | 178 | } |
|
183 | 185 |
|
184 | 186 | if (isEvtWithFiles(event)) { |
185 | 187 | dispatch("filedropped", { |
186 | | - event |
187 | | - }) |
188 | | - Promise.resolve(getFilesFromEvent(event)).then(files => { |
| 188 | + event, |
| 189 | + }); |
| 190 | + Promise.resolve(getFilesFromEvent(event)).then((files) => { |
189 | 191 | if (isPropagationStopped(event) && !noDragEventsBubbling) { |
190 | 192 | return; |
191 | 193 | } |
192 | 194 |
|
193 | 195 | const acceptedFiles = []; |
194 | 196 | const fileRejections = []; |
195 | 197 |
|
196 | | - files.forEach(file => { |
| 198 | + files.forEach((file) => { |
197 | 199 | const [accepted, acceptError] = fileAccepted(file, accept); |
198 | 200 | const [sizeMatch, sizeError] = fileMatchSize(file, minSize, maxSize); |
199 | 201 | if (accepted && sizeMatch) { |
200 | 202 | acceptedFiles.push(file); |
201 | 203 | } else { |
202 | | - const errors = [acceptError, sizeError].filter(e => e); |
| 204 | + const errors = [acceptError, sizeError].filter((e) => e); |
203 | 205 | fileRejections.push({ file, errors }); |
204 | 206 | } |
205 | 207 | }); |
206 | 208 |
|
207 | 209 | if (!multiple && acceptedFiles.length > 1) { |
208 | 210 | // Reject everything and empty accepted files |
209 | | - acceptedFiles.forEach(file => { |
| 211 | + acceptedFiles.forEach((file) => { |
210 | 212 | fileRejections.push({ file, errors: [TOO_MANY_FILES_REJECTION] }); |
211 | 213 | }); |
212 | 214 | acceptedFiles.splice(0); |
213 | 215 | } |
214 | 216 |
|
| 217 | + // Files dropped keep input in sync |
| 218 | + if (event.dataTransfer) { |
| 219 | + inputRef.files = event.dataTransfer?.files; |
| 220 | + } |
| 221 | +
|
215 | 222 | state.acceptedFiles = acceptedFiles; |
216 | 223 | state.fileRejections = fileRejections; |
217 | 224 |
|
218 | 225 | dispatch("drop", { |
219 | 226 | acceptedFiles, |
220 | 227 | fileRejections, |
221 | | - event |
| 228 | + event, |
222 | 229 | }); |
223 | 230 |
|
224 | 231 | if (fileRejections.length > 0) { |
225 | 232 | dispatch("droprejected", { |
226 | 233 | fileRejections, |
227 | | - event |
| 234 | + event, |
228 | 235 | }); |
229 | 236 | } |
230 | 237 |
|
231 | 238 | if (acceptedFiles.length > 0) { |
232 | 239 | dispatch("dropaccepted", { |
233 | 240 | acceptedFiles, |
234 | | - event |
| 241 | + event, |
235 | 242 | }); |
236 | 243 | } |
237 | 244 | }); |
|
305 | 312 | } |
306 | 313 | </script> |
307 | 314 |
|
308 | | -<style> |
309 | | - .dropzone { |
310 | | - flex: 1; |
311 | | - display: flex; |
312 | | - flex-direction: column; |
313 | | - align-items: center; |
314 | | - padding: 20px; |
315 | | - border-width: 2px; |
316 | | - border-radius: 2px; |
317 | | - border-color: #eeeeee; |
318 | | - border-style: dashed; |
319 | | - background-color: #fafafa; |
320 | | - color: #bdbdbd; |
321 | | - outline: none; |
322 | | - transition: border 0.24s ease-in-out; |
323 | | - } |
324 | | - .dropzone:focus { |
325 | | - border-color: #2196f3; |
326 | | - } |
327 | | -</style> |
328 | | - |
329 | 315 | <div |
330 | 316 | bind:this={rootRef} |
331 | 317 | tabindex="0" |
|
339 | 325 | on:dragenter={composeDragHandler(onDragEnterCb)} |
340 | 326 | on:dragover={composeDragHandler(onDragOverCb)} |
341 | 327 | on:dragleave={composeDragHandler(onDragLeaveCb)} |
342 | | - on:drop={composeDragHandler(onDropCb)}> |
| 328 | + on:drop={composeDragHandler(onDropCb)} |
| 329 | +> |
343 | 330 | <input |
344 | 331 | {accept} |
345 | 332 | {multiple} |
| 333 | + {required} |
346 | 334 | type="file" |
347 | | - name={name} |
| 335 | + {name} |
348 | 336 | autocomplete="off" |
349 | 337 | tabindex="-1" |
| 338 | + on:blur |
350 | 339 | on:change={onDropCb} |
351 | 340 | on:click={onInputElementClick} |
| 341 | + on:invalid |
352 | 342 | bind:this={inputRef} |
353 | | - style="display: none;" /> |
| 343 | + style="display: none;" |
| 344 | + /> |
354 | 345 | <slot> |
355 | 346 | <p>Drag 'n' drop some files here, or click to select files</p> |
356 | 347 | </slot> |
357 | 348 | </div> |
| 349 | +
|
| 350 | +<style> |
| 351 | + .dropzone { |
| 352 | + flex: 1; |
| 353 | + display: flex; |
| 354 | + flex-direction: column; |
| 355 | + align-items: center; |
| 356 | + padding: 20px; |
| 357 | + border-width: 2px; |
| 358 | + border-radius: 2px; |
| 359 | + border-color: #eeeeee; |
| 360 | + border-style: dashed; |
| 361 | + background-color: #fafafa; |
| 362 | + color: #bdbdbd; |
| 363 | + outline: none; |
| 364 | + transition: border 0.24s ease-in-out; |
| 365 | + } |
| 366 | + .dropzone:focus { |
| 367 | + border-color: #2196f3; |
| 368 | + } |
| 369 | +</style> |
0 commit comments