FileUpload provides a complete file upload experience with drag-and-drop, file validation, progress tracking, and visual feedback for upload states.
Installation
npm install @soft-ui/react
Usage
import { FileUpload } from "@soft-ui/react/file-upload"
function Example() {
return (
<FileUpload
label="Drag and drop or browse"
hint="Supports PDF, DOC, and images up to 10MB"
accept=".pdf,.doc,.docx,image/*"
/>
)
}
API Reference
FileUpload
label
string
default:"'Drag and drop or browse'"
Label text shown in the dropzone
Helper text shown below the label
Accepted file types (e.g., "image/*,.pdf"). Supports:
- MIME types:
"image/png"
- MIME wildcards:
"image/*"
- Extensions:
".pdf,.docx"
Allow multiple files to be selected
Whether the upload is disabled
Controlled files array. Each file has:
file: File object
state: "uploaded" | "uploading" | "error" | "warning"
progress: number (0-100)
onFilesChange
(files: FileUploadFile[]) => void
Callback when files change (for controlled mode)
Callback when new files are added
FileItem
Individual file display with state indicators.
state
'uploaded' | 'uploading' | 'error' | 'warning'
default:"'uploaded'"
Current state of the file:
uploaded: Green checkmark (success)
uploading: Animated spinner with progress bar
error: Red error icon
warning: Yellow warning icon
Upload progress (0-100). Only shown when state="uploading"
Override file size display (defaults to file.size)
Callback when remove button is clicked
Examples
Basic Upload
<FileUpload
label="Upload documents"
hint="PDF or Word documents only"
accept=".pdf,.doc,.docx"
/>
Image Upload Only
<FileUpload
label="Upload photos"
hint="PNG, JPG, or GIF up to 5MB"
accept="image/*"
/>
Single File Upload
<FileUpload
label="Upload your resume"
hint="PDF format only"
accept=".pdf"
multiple={false}
/>
Controlled with Upload Simulation
function ControlledUpload() {
const [files, setFiles] = useState<FileUploadFile[]>([])
const handleFilesAdded = (newFiles: File[]) => {
// Start uploads
const uploadFiles = newFiles.map((file) => ({
file,
state: "uploading" as const,
progress: 0,
}))
setFiles([...files, ...uploadFiles])
// Simulate upload progress
uploadFiles.forEach((_, index) => {
const interval = setInterval(() => {
setFiles((current) => {
const fileIndex = current.length - uploadFiles.length + index
const updated = [...current]
const currentProgress = updated[fileIndex].progress
if (currentProgress >= 100) {
updated[fileIndex] = {
...updated[fileIndex],
state: "uploaded",
progress: 100,
}
clearInterval(interval)
} else {
updated[fileIndex] = {
...updated[fileIndex],
progress: currentProgress + 10,
}
}
return updated
})
}, 200)
})
}
return (
<FileUpload
files={files}
onFilesChange={setFiles}
onFilesAdded={handleFilesAdded}
/>
)
}
Different File States
import { FileItem } from "@soft-ui/react/file-upload"
const demoFiles = [
{ file: new File([], "uploaded.pdf"), state: "uploaded", progress: 100 },
{ file: new File([], "uploading.pdf"), state: "uploading", progress: 45 },
{ file: new File([], "failed.pdf"), state: "error", progress: 0 },
{ file: new File([], "warning.pdf"), state: "warning", progress: 100 },
]
<div className="space-y-2">
{demoFiles.map((fileData) => (
<FileItem
key={fileData.file.name}
{...fileData}
onRemove={() => console.log("Remove", fileData.file.name)}
/>
))}
</div>
Disabled State
<FileUpload
label="Upload disabled"
hint="This upload is currently disabled"
disabled
/>