Spaces:
Sleeping
Sleeping
File size: 1,849 Bytes
27124e1 9d74e85 27124e1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | import { useRef, useState } from 'react'
interface FileDropZoneProps {
onFile: (text: string, filename: string) => void
accept?: string
}
export default function FileDropZone({
onFile,
accept = '.fasta,.fa,.faa,.txt,.csv',
}: FileDropZoneProps) {
const [dragging, setDragging] = useState(false)
const inputRef = useRef<HTMLInputElement>(null)
function readFile(file: File) {
const reader = new FileReader()
reader.onload = () => onFile(String(reader.result ?? ''), file.name)
reader.readAsText(file)
}
return (
<div
className={'dropzone' + (dragging ? ' dragging' : '')}
onClick={() => inputRef.current?.click()}
onDragOver={(e) => {
e.preventDefault()
setDragging(true)
}}
onDragLeave={() => setDragging(false)}
onDrop={(e) => {
e.preventDefault()
setDragging(false)
const file = e.dataTransfer.files?.[0]
if (file) readFile(file)
}}
>
<div className="dropzone-icon" aria-hidden>
<svg
width="22"
height="22"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="1.8"
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M12 15V4M8 8l4-4 4 4M4 15v3a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-3" />
</svg>
</div>
<div className="dropzone-main">
Drag & drop a file, or click to browse
</div>
<div className="dropzone-sub">FASTA (.fasta / .fa) or plain text (.txt)</div>
<input
ref={inputRef}
type="file"
accept={accept}
style={{ display: 'none' }}
onChange={(e) => {
const file = e.target.files?.[0]
if (file) readFile(file)
e.target.value = ''
}}
/>
</div>
)
}
|