A dropzone is an area into which one or multiple objects can be dragged and dropped.
"use client";
import { FileIcon } from "lucide-react";About#
The <Dropzone /> component is built on top of react-dropzone.
Installation#
pnpm dlx shadcn@latest add junwen-k/ui-x/dropzone
Usage#
import {
Empty,
EmptyDescription,
EmptyHeader,
EmptyMedia,
EmptyTitle,
} from "@/components/ui/empty";
import {
Dropzone,
DropzoneInput,
DropzoneUploadIcon,
DropzoneZone,
} from "@/components/ui/dropzone";<Dropzone
accept={{
"image/*": [".jpg", ".png"],
"application/pdf": [".pdf"],
}}
onDropAccepted={setFiles}
>
<DropzoneZone>
<DropzoneInput />
<Empty>
<EmptyHeader>
<EmptyMedia variant="icon">
<DropzoneUploadIcon />
</EmptyMedia>
<EmptyTitle>Drop files here or click to upload</EmptyTitle>
<EmptyDescription>
You can upload files up to 10MB in size. Supported formats: JPG, PNG,
PDF.
</EmptyDescription>
</EmptyHeader>
</Empty>
</DropzoneZone>
</Dropzone>Examples#
Default#
"use client";
import { FileIcon } from "lucide-react";Trigger#
import { Button } from "@/components/ui/button";
import {
Empty,Form#
Drag and drop is supported.
"use client";
import { FileIcon, XIcon } from "lucide-react";Accessibility#
The zone is focusable and opens the file dialog with Enter or Space, so the drag-and-drop interaction always has a keyboard equivalent. Make sure the zone contains visible text describing what to upload (such as <EmptyTitle /> and <EmptyDescription />) — the upload icon alone is not an accessible name. Drag states are conveyed with color and iconography via the <DropzoneUploadIcon /> swap; keep the title text meaningful so the state change is not communicated by color alone.
API Reference#
Styled wrappers around the Dropzone primitive — see the primitive page for the full prop tables. The zone's title and description are composed with shadcn/ui's Empty component rather than a Dropzone-specific part.
Dropzone#
Wraps Root and accepts all react-dropzone options (accept, maxFiles, onDropAccepted, …).
DropzoneZone#
Wraps Zone with dashed-border styling that reacts to the drag state data attributes.
DropzoneInput#
Wraps Input, the visually hidden file input.
DropzoneUploadIcon#
Swaps the icon based on the drag state — an upload icon by default, a check when the drag is accepted and a ban icon when rejected. Render it inside <EmptyMedia variant="icon" />. Accepts the same props as a Lucide icon.
DropzoneTrigger#
Wraps Trigger for opening the file dialog from a button outside the zone.
DropzoneAccepted, DropzoneRejected#
Wrap Accepted and Rejected, render-prop parts receiving the accepted files or rejections.