FileUpload
fileupload-1779394025632.tsx
'use client'
import { useState, useRef } from 'react'
export default function FileUpload() {
const [files, setFiles] = useState([])
const [dragging, setDragging] = useState(false)
const inputRef = useRef(null)
const addFiles = (newFiles) => {
const arr = Array.from(newFiles).map(f => ({ name:f.name, size:f.size, progress:0 }))
setFiles(prev => [...prev, ...arr])
arr.forEach((_, i) => {
let p = 0
const t = setInterval(() => {
p += Math.random() * 20
if (p >= 100) { p = 100; clearInterval(t) }
setFiles(prev => prev.map((f, j) => j === prev.length - arr.length + i ? { ...f, progress:Math.round(p) } : f))
}, 200)
})
}
const fmt = (bytes) => bytes < 1024 ? bytes + 'B' : bytes < 1048576 ? (bytes/1024).toFixed(1) + 'KB' : (bytes/1048576).toFixed(1) + 'MB'
return (
<div style={{ maxWidth:'400px' }}>
<div
onDragOver={e => { e.preventDefault(); setDragging(true) }}
onDragLeave={() => setDragging(false)}
onDrop={e => { e.preventDefault(); setDragging(false); addFiles(e.dataTransfer.files) }}
onClick={() => inputRef.current?.click()}
style={{
border:'2px dashed ' + (dragging ? '#6d28d9' : '#cbd5e1'),
borderRadius:'14px', padding:'32px 20px', textAlign:'center',
background:dragging ? '#f5f3ff' : '#f8fafc', cursor:'pointer', transition:'all 0.2s',
}}
>
<div style={{ fontSize:'36px', marginBottom:'8px' }}>📁</div>
<div style={{ fontWeight:600, color:'#374151', marginBottom:'4px' }}>Drop files here</div>
<div style={{ fontSize:'13px', color:'#94a3b8' }}>or click to browse</div>
<input ref={inputRef} type="file" multiple hidden onChange={e => addFiles(e.target.files)} />
</div>
{files.length > 0 && (
<div style={{ marginTop:'12px', display:'flex', flexDirection:'column', gap:'8px' }}>
{files.map((f, i) => (
<div key={i} style={{ background:'#fff', borderRadius:'10px', padding:'10px 14px', boxShadow:'0 1px 6px rgba(0,0,0,0.06)' }}>
<div style={{ display:'flex', justifyContent:'space-between', marginBottom:'6px' }}>
<span style={{ fontSize:'13px', fontWeight:500, color:'#1e293b' }}>{f.name}</span>
<span style={{ fontSize:'12px', color:'#94a3b8' }}>{f.progress}%</span>
</div>
<div style={{ height:'4px', background:'#e2e8f0', borderRadius:'2px' }}>
<div style={{ height:'100%', borderRadius:'2px', background:'#6d28d9', width:f.progress+'%', transition:'width 0.2s' }} />
</div>
<div style={{ fontSize:'11px', color:'#94a3b8', marginTop:'4px' }}>{fmt(f.size)}</div>
</div>
))}
</div>
)}
</div>
)
}Component info
CategoryInputs & Forms
Frameworkreact
TierFREE
Views0
Copies0
About
Drag-and-drop file upload zone with progress and file list
More from Inputs & Forms
'use client';
import { useState, useEffect } from 'react';
interface Tag {
id: number;
name: string;
}
const TagInput = () => {
const [tags, setTags] = useState<Tag[]>([]);
const [inputValue, setInputValue] = useState('');
const [suggestTagInput
Inputs & Forms
'use client';
import React, { useState } from 'react';
interface File {
name: string;
size: number;
progress: number;
}
const FileUpload = () => {
const [dragOver, setDragOver] = useState(false);
const [files, setFiles] = useState<File[]FileUpload
Inputs & Forms
import React, { useState } from 'react';
const OTPInput = () => {
const [otp, setOtp] = useState(new Array(6).fill(''));
const [activeIndex, setActiveIndex] = useState(0);
const handleChange = (e, index) => {
const value = e.target.value;OTPInput
Inputs & Forms
'use client';
import React, { useState } from 'react';
interface RangeSliderProps {
min: number;
max: number;
defaultValue: [number, number];
}
const RangeSlider: React.FC<RangeSliderProps> = ({ min, max, defaultValue }) => {
const [minValRangeSlider
Inputs & Forms