308

Dropzone

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

Upload your files
Attach the documents you would like to share.

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.