Drag-and-drop file drop area with a built-in trigger, accept and size validation, and an onFilesAccepted callback.
Description
Dropzone is a drag-and-drop (or click) file drop area with a built-in trigger and an auto-derived description. It validates files against accept and maxSize, emits the accepted File objects through onFilesAccepted, and surfaces rejections inline.
On its own it is a lightweight file picker: give it an onFilesAccepted and do whatever you want with the files. Dropped inside Create UI Pro's FileUpload, it inherits accept, maxSize, multiple, and disabled from the parent and feeds accepted files straight into the upload list — no wiring needed.
Reach for it for attachment inputs, image and avatar pickers, and import flows. For a bare hidden file input with no drop area, a plain Field with a native input is enough.
Installation
Anatomy
Render Dropzone on its own and handle the accepted files:
Compose your own content by passing children — the drop behaviour and validation stay intact:
Usage
onFilesAccepted receives the files that passed validation; onFileReject fires per rejected file with the reason. When accept or maxSize reject a file, the dropzone also shows the message inline and derives its default description from accept and maxSize.
Examples
Sizes
Three layouts via size: sm (a dense single row), md (a compact inline bar), and lg (the default tall stack).
Labels
Swap just the copy without composing children by passing title and description. Compose children (including DropzoneTrigger for the button text) when you need full control over the layout.
Custom content
Pass children to supply your own icon, title, description, separator, and trigger.
Error
Force the error appearance with error and errorMessage; it is also derived automatically from rejected files.
Disabled
Set disabled to dim the area and turn off drag and click.
Accessibility
The drop area opens the file picker on click for pointer users; keyboard users reach the picker through the built-in trigger button. The hidden <input type="file"> carries accept and multiple.
ARIA notes:
- The area sets
aria-disabledwhen disabled andaria-invalidin the error state, withdata-statereflectingidle,dragging,error, ordisabled. - Clicks on nested buttons, links, labels, and inputs do not re-open the picker.
Styling
Tailwind override: pass className to merge Tailwind classes with the component's CVA classes (via cn()):
Data slots and attributes: the component sets these for CSS targeting.
data-slot="dropzone"withdata-state="idle" | "dragging" | "error" | "disabled"anddata-sizeon the drop area.data-slot="dropzone-trigger"on the picker button.data-slot="dropzone-icon",-title,-description,-header,-heading,-separatoron the content parts.
Target the dragging state in CSS:
Related Components
- File Upload: Create UI Pro's per-file upload list that composes
Dropzonefor its drop area. - Button: the trigger button.
- Field: the form-field wrapper for plain inputs.
API Reference
Dropzone
The drop area with a built-in trigger and auto-derived description. Renders a <div data-slot="dropzone"> and extends React.ComponentProps<"div">.
When rendered inside a provider (such as FileUpload), each of accept, maxSize, multiple, disabled, onFilesAccepted, and onFileReject falls back to the context value when the prop is omitted. size never comes from context — it is always the prop (default lg).
Props
Variants
DropzoneTrigger
A button that opens the file picker, usable on its own or inside a Dropzone. Nested in a Dropzone, it reuses that area's hidden input; standalone (for example inside FileUpload with no drop area), it owns its own input and reads config from context. Extends the Button component's props (React.ComponentProps<typeof Button>) plus optional accept, maxSize, multiple, onFilesAccepted, and onFileReject for standalone use. Defaults to variant="neutral-solid" and size="lg".
useDropzone
The headless hook behind Dropzone, for fully custom drop areas. It owns the hidden input, drag tracking, and accept/size validation.
Options
Returns
Composition parts
Lower-level slots for custom drop areas. Each renders a styled <div> (or <p>) with a data-slot and merges className via cn().