-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFileUploader.tsx
More file actions
72 lines (65 loc) · 2.03 KB
/
FileUploader.tsx
File metadata and controls
72 lines (65 loc) · 2.03 KB
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
70
71
72
import { UploadCloud } from 'lucide-react';
import { useRef, useState } from 'react';
interface Props {
onFileRead: (content: string, filename?: string) => void;
disabled?: boolean;
}
const FileUploader = ({ onFileRead, disabled }: Props) => {
const inputRef = useRef<HTMLInputElement | null>(null);
const [dragOver, setDragOver] = useState(false);
const readFile = (file: File) => {
const reader = new FileReader();
reader.onload = () => {
const result = String(reader.result || '');
onFileRead(result, file.name);
};
reader.readAsText(file);
};
const handleFiles = (files: FileList | null) => {
if (!files || files.length === 0) return;
readFile(files[0]);
};
return (
<div>
<input
ref={inputRef}
type="file"
accept=".js,.ts,.jsx,.tsx,.py,.java,.cs,.cpp,.txt"
className="hidden"
onChange={(e) => handleFiles(e.target.files)}
disabled={disabled}
/>
<button
type="button"
onClick={() => inputRef.current?.click()}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
inputRef.current?.click();
}
}}
onDragOver={(e) => {
e.preventDefault();
if (!disabled) setDragOver(true);
}}
onDragLeave={() => setDragOver(false)}
onDrop={(e) => {
e.preventDefault();
setDragOver(false);
if (disabled) return;
handleFiles(e.dataTransfer.files);
}}
disabled={disabled}
className={`flex items-center gap-2 px-3 py-1.5 rounded-lg transition-colors text-sm font-medium ${
disabled
? 'opacity-50 pointer-events-none'
: 'hover:bg-slate-800 cursor-pointer'
} ${dragOver ? 'bg-slate-800' : ''}`}
>
<UploadCloud size={16} className="text-slate-300" role="img" />
<span>{disabled ? 'Upload (disabled)' : 'Upload / Drop'}</span>
</button>
</div>
);
};
export default FileUploader;