FileUploadDropzone
FileUploadDropzone - A drag-and-drop zone for file uploads. Use with the useFileUpload hook for full functionality.
Usage
import { FileMetadata, FileUploadActions, FileUploadDropzone, FileUploadItem, FileUploadList, FileUploadOptions, FileUploadState, FileUploadTrigger, FileWithPreview, formatBytes, useFileUpload } from "@desk/ui/components/file-upload";Best practices
FileUploadDropzoneis presentational — wire it to theuseFileUploadhook for the actual file input, drag state, and file list; it stores nothing itself.Forward the hook's
handleDragEnter/Leave/Over/Dropand drag state intodraggingso the drag styling matches the real drop-target state.Keep
title/description(accepted types, size limit) accurate — they are the zone's only affordance copy; override the whole body viachildrenwhen needed.
Props
FileUploadDropzone
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | Children to render inside (overrides default content) | |
| className | string | Additional class names | |
| description | string | Secondary description text | |
| disabled | boolean | Whether the dropzone is disabled | |
| icon | LucideIcon | Icon to display (default: CloudUpload) | |
| dragging | boolean | Whether files are currently being dragged over | |
| onClick | () => void | Click handler to open file dialog | |
| onDragEnter | (e: DragEvent<HTMLElement>) => void | Drag event handlers from useFileUpload | |
| onDragLeave | (e: DragEvent<HTMLElement>) => void | ||
| onDragOver | (e: DragEvent<HTMLElement>) => void | ||
| onDrop | (e: DragEvent<HTMLElement>) => void | ||
| ref | Ref<HTMLButtonElement> | Ref for the dropzone element | |
| title | string | Primary text |
FileUploadItem
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | undefined | Additional class names | |
| error | string | undefined | Error message if upload failed | |
| complete | boolean | undefined | Whether upload is complete | |
| name | string | File name | |
| onRemove | (() => void) | undefined | Callback when remove button is clicked | |
| previewUrl | string | undefined | Preview URL for images | |
| progress | number | undefined | Upload progress (0-100), undefined means not uploading | |
| size | number | File size in bytes | |
| type | string | File MIME type |
FileUploadList
| Prop | Type | Default | Description |
|---|---|---|---|
| animated | boolean | Whether the list should animate | |
| className | string | Additional class names | |
| completed | Record<string, boolean> | Completed files (keyed by file id) | |
| errors | Record<string, string> | Errors for each file (keyed by file id) | |
| files | FileWithPreview[] | Array of files to display | |
| onRemove | (id: string) => void | Callback when a file's remove button is clicked | |
| orientation | Orientation | Orientation of the list | |
| progress | Record<string, number> | Upload progress for each file (keyed by file id) | |
| renderItem | (file: FileWithPreview) => ReactNode | Render custom item content |
FileUploadTrigger
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | Custom children (overrides default button content) | |
| onClick | () => void | Click handler to open file dialog | |
| ref | Ref<HTMLButtonElement> | Ref for the button element | |
| uploading | boolean | Whether files are currently being uploaded | |
| uploadingLabel | string | Custom label when uploading | |
| asChild | boolean | undefined | false | Merge props and styling onto the single child element via Slot. |
| tone | "neutral" | "brand" | "danger" | null | undefined | ||
| radius | "rounded" | "square" | "full" | null | undefined | ||
| size | ButtonSizeProp | "base" | Size token; |
| dot | string | undefined | CSS colour for a status dot; empty/undefined renders no dot. | |
| loading | boolean | undefined | false | Show a spinner and disable interaction. |
| square | boolean | null | undefined | ||
| icon | IconComponent | undefined | Leading icon (Lucide or SVG component); with no children it becomes an icon-only button. | |
| emphasis | "link" | "outline" | "solid" | "ghost" | "soft" | "transparent" | null | undefined | ||
| asInput | boolean | null | undefined | ||
| align | "center" | "end" | "start" | null | undefined | ||
| pressed | boolean | null | undefined | ||
| testId | string | ||
| suffixIcon | IconComponent | undefined | Trailing icon (Lucide or SVG component) rendered at the end. | |
| loadingLabel | string | undefined | Label shown in place of | |
| iconClassName | string | undefined | Extra classes for the leading icon. | |
| suffixIconClassName | string | undefined | Extra classes for the trailing icon. | |
| dotPlacement | "end" | "start" | undefined | "start" | Dot position relative to content. |
| expandable | boolean | undefined | false | Icon-only at rest; expands on hover/focus-visible to reveal the label
to the right of the icon. Collapsed geometry equals the matching icon-*
size, expanded equals the text button of that size — so pass a text
size ( |
| focused | boolean | undefined | Force the focus ring on — for documentation/testing only. | |
| hovered | boolean | undefined | Force the hover state on — for documentation/testing only. |
Also exports
- interface
FileMetadata - interface
FileUploadActions - interface
FileUploadOptions - interface
FileUploadState - interface
FileWithPreview - const
formatBytes - const
useFileUpload