Overlays & feedback
File Dropzone
Drag-and-drop upload surface with click-to-browse, type and size validation, per-file progress, and removable rows. Drop real files onto any zone, or click to pick — the demos simulate the upload so progress bars run.
npx shadcn@latest add @orbit/file-dropzoneOverview
Variants
Pick by the room the flow gives you.
File states
Every row carries its own status — the list stays honest while uploads run.
Type & size limits
accept lists the allowed extensions (empty = any type); maxMB caps each file. Rejected files render as error rows with the reason and never call onDrop.
Props
The component is controlled and owns no upload: it validates and hands you entries via onFilesChange plus the raw accepted File objects via onDrop — you upload, then drive each row's status and progress.
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "default" | "compact" | "default" | Large surface for a dedicated step, or an inline row for forms and side panels. |
| accept | string[] | ["PDF","PNG","JPG","FIG"] | Accepted extensions, uppercase. Empty array accepts any type. Also constrains the native picker. |
| maxMB | number | 10 | Per-file size limit in MB. |
| files | FileDropzoneFile[] | [] | Rows to render: { id, name, size, status?, progress?, error? } with status "uploading" | "done" | "error". |
| onFilesChange | (files) => void | — | Next full list after files were added (already validated and flagged) or removed. |
| onDrop | (files: File[]) => void | — | Raw accepted native File objects for the actual upload. Rejected files are excluded. |
| onRemove | (file) => void | — | A row's × was clicked (also reflected in onFilesChange). |
| multiple | boolean | true | Allow picking several files at once. |
| disabled | boolean | false | Blocks drop, click, and keyboard opening. |
| …rest | HTMLAttributes | — | Forwarded to the root <div>, including ref. FileDropzoneRow, formatFileSize, and fileExt are exported too. |
Usage
State the constraints up front
The caption line shows accepted types and the size cap before anyone drops a file — no surprise rejections.
Silently swallow rejected files
A file that fails validation must appear as an error row with the reason, not vanish from the drop.
Keep rows removable
A wrong file, a stalled upload — the × next to every row keeps the list under the user's control.
Rely on drag alone
Every zone is also a button: click or Enter opens the native picker, so touch and keyboard users can upload too.
Keyboard & accessibility
The zone is a focusable button (Enter/Space opens the picker) wrapping a native file input, the file list is a real list, and every remove button carries the file's name in its accessible label. Validation errors are shown inline as text, not colour alone.