File tree Expand file tree Collapse file tree 2 files changed +74
-7
lines changed Expand file tree Collapse file tree 2 files changed +74
-7
lines changed Original file line number Diff line number Diff line change
1
+ import type { DragEvent , ReactNode } from "react"
2
+ import { useCallback , useRef , useState } from "react"
3
+
4
+ // Ported from https://github.com/react-dropzone/react-dropzone/issues/753#issuecomment-774782919
5
+ const useDragAndDrop = ( { callback } : { callback : ( file : FileList ) => void | Promise < void > } ) => {
6
+ const [ isDragging , setIsDragging ] = useState ( false )
7
+ const dragCounter = useRef ( 0 )
8
+
9
+ const onDrop = useCallback (
10
+ async ( event : DragEvent < HTMLLabelElement > ) => {
11
+ event . preventDefault ( )
12
+ setIsDragging ( false )
13
+ if ( event . dataTransfer && event . dataTransfer . files && event . dataTransfer . files . length > 0 ) {
14
+ dragCounter . current = 0
15
+ await callback ( event . dataTransfer . files )
16
+ event . dataTransfer . clearData ( )
17
+ }
18
+ } ,
19
+ [ callback ] ,
20
+ )
21
+
22
+ const onDragEnter = useCallback ( ( event : DragEvent ) => {
23
+ event . preventDefault ( )
24
+ dragCounter . current ++
25
+ setIsDragging ( true )
26
+ } , [ ] )
27
+
28
+ const onDragOver = useCallback ( ( event : DragEvent ) => {
29
+ event . preventDefault ( )
30
+ } , [ ] )
31
+
32
+ const onDragLeave = useCallback ( ( event : DragEvent ) => {
33
+ event . preventDefault ( )
34
+ dragCounter . current --
35
+ if ( dragCounter . current > 0 ) return
36
+ setIsDragging ( false )
37
+ } , [ ] )
38
+
39
+ return {
40
+ isDragging,
41
+
42
+ dragHandlers : {
43
+ onDrop,
44
+ onDragOver,
45
+ onDragEnter,
46
+ onDragLeave,
47
+ } ,
48
+ }
49
+ }
50
+
51
+ export const DropZone = ( {
52
+ onDrop,
53
+ children,
54
+ } : {
55
+ onDrop : ( file : FileList ) => void | Promise < void >
56
+ children ?: ReactNode
57
+ } ) => {
58
+ const { isDragging, dragHandlers } = useDragAndDrop ( { callback : onDrop } )
59
+
60
+ return (
61
+ < label
62
+ className = { `center flex h-[100px] w-full rounded-md border border-dashed ${
63
+ isDragging ? "border-blue-500 bg-blue-100" : ""
64
+ } `}
65
+ htmlFor = "upload-file"
66
+ { ...dragHandlers }
67
+ >
68
+ { children }
69
+ </ label >
70
+ )
71
+ }
Original file line number Diff line number Diff line change @@ -17,6 +17,7 @@ import { useForm } from "react-hook-form"
17
17
import { Trans , useTranslation } from "react-i18next"
18
18
import { z } from "zod"
19
19
20
+ import { DropZone } from "~/components/ui/drop-zone"
20
21
import { apiFetch } from "~/lib/api-fetch"
21
22
import { toastFetchError } from "~/lib/error-parser"
22
23
import { Queries } from "~/queries"
@@ -110,26 +111,21 @@ export function DiscoverImport({ isInit = false }: { isInit?: boolean }) {
110
111
{ isInit ? t ( "discover.import.new_import_opml" ) : t ( "discover.import.opml" ) }
111
112
</ FormLabel >
112
113
< FormControl >
113
- < label
114
- className = "center flex h-[100px] w-full rounded-md border border-dashed"
115
- htmlFor = "upload-file"
116
- >
114
+ < DropZone onDrop = { ( fileList ) => onChange ( fileList [ 0 ] ) } >
117
115
{ form . formState . dirtyFields . file ? (
118
116
< Fragment >
119
117
< i className = "i-mgc-file-upload-cute-re size-5" />
120
-
121
118
< span className = "ml-2 text-sm font-semibold opacity-80" > { value . name } </ span >
122
119
</ Fragment >
123
120
) : (
124
121
< Fragment >
125
122
< i className = "i-mgc-file-upload-cute-re size-5" />
126
-
127
123
< span className = "ml-2 text-sm opacity-80" >
128
124
{ t ( "discover.import.click_to_upload" ) }
129
125
</ span >
130
126
</ Fragment >
131
127
) }
132
- </ label >
128
+ </ DropZone >
133
129
</ FormControl >
134
130
< Input
135
131
{ ...fieldProps }
You can’t perform that action at this time.
0 commit comments