ComponentsForm
File Upload
A drag-and-drop file upload zone with file validation, keyboard activation, and customizable content.
Default
Drag and drop files here, or click to browse
Accepted: image/* · Max 5MB
Multiple Files
Drag and drop files here, or click to browse
Accepted: image/*,.pdf · Max 10MB · Up to 5 files
Disabled
Drag and drop files here, or click to browse
All file types accepted · Max 10MB
Installation
npx visor add file-uploadThis copies two files into your project:
components/ui/file-upload/file-upload.tsx— the componentcomponents/ui/file-upload/file-upload.module.css— the styles
Usage
import { FileUpload } from '@/components/ui/file-upload/file-upload';
export default function Example() {
return (
<FileUpload
accept="image/*"
maxSize={5}
maxFiles={3}
onFilesChange={(files) => console.log(files)}
/>
);
}API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
accept | string | — | Accepted file types (e.g., 'image/*', '.pdf,.doc'). |
maxSize | number | 10 | Maximum file size in MB. |
maxFiles | number | 1 | Maximum number of files allowed. |
disabled | boolean | false | Disables the drop zone. |
onFilesChange | (files: File[]) => void | — | Callback when valid files are selected or dropped. |
The File Upload component is a drop zone only — it handles file selection and validation but does not manage file lists, progress tracking, or upload logic. Compose it with your own file list and upload implementation.
Accessibility
- The drop zone renders as a
<button>so it is reachable via Tab and activatable with Enter/Space - Keyboard users can open the native file picker via Enter or Space
aria-labeldefaults to "Upload files" — override it to describe the expected file type (e.g., "Upload profile photo")- Drag-over state is communicated visually via a border highlight; consider pairing with an
aria-liveregion to announce when files are accepted or rejected - Screen readers announce validation errors (wrong file type, file too large) via an
aria-live="polite"region