Collaboration
Project Management
Finance
Dropzone
Allows users to drag-and-drop files into a container to upload or process them.
Installation
npx love-ui@latest add dropzoneUsage
import { Dropzone, DropzoneContent, DropzoneEmptyState } from "@/components/dropzone"<Dropzone onDrop={(files) => console.log(files)}>
<DropzoneEmptyState>
Drag and drop files here or click to browse
</DropzoneEmptyState>
<DropzoneContent>
{(files) => files.map((file) => <div key={file.name}>{file.name}</div>)}
</DropzoneContent>
</Dropzone>Features
- Drag and drop files to upload
- Customize the empty state and content
- Intelligently handle file types, sizes, and counts
- Show file names and sizes in a human readable format
- Handle errors and reject files
- Disable the dropzone when needed
- Customize the appearance with className
- Show file previews for images
- Replace existing files by dragging new ones
- Context provider for accessing dropzone state
Examples
With min and max sizes
"use client";
import { Dropzone, DropzoneContent, DropzoneEmptyState } from "../../../../../packages/dropzone";
import { useState } from "react";
const Example = () => {
const [files, setFiles] = useState<File[] | undefined>();
const handleDrop = (files: File[]) => {
console.log(files);
setFiles(files);
};
return (
<Dropzone
maxSize={1024 * 1024 * 10}
minSize={1024}
onDrop={handleDrop}
onError={console.error}
src={files}
>
<DropzoneEmptyState />
<DropzoneContent />
</Dropzone>
);
};
export default Example;
Multiple files
"use client";
import { Dropzone, DropzoneContent, DropzoneEmptyState } from "../../../../../packages/dropzone";
import { useState } from "react";
const Example = () => {
const [files, setFiles] = useState<File[] | undefined>();
const handleDrop = (files: File[]) => {
console.log(files);
setFiles(files);
};
return (
<Dropzone
maxFiles={3}
onDrop={handleDrop}
onError={console.error}
src={files}
>
<DropzoneEmptyState />
<DropzoneContent />
</Dropzone>
);
};
export default Example;
Images only
"use client";
import { Dropzone, DropzoneContent, DropzoneEmptyState } from "../../../../../packages/dropzone";
import { useState } from "react";
const Example = () => {
const [files, setFiles] = useState<File[] | undefined>();
const handleDrop = (files: File[]) => {
console.log(files);
setFiles(files);
};
return (
<Dropzone
accept={{ "image/*": [] }}
onDrop={handleDrop}
onError={console.error}
src={files}
>
<DropzoneEmptyState />
<DropzoneContent />
</Dropzone>
);
};
export default Example;
With custom empty state
"use client";
import { Dropzone, DropzoneContent, DropzoneEmptyState } from "../../../../../packages/dropzone";
import { UploadIcon } from "lucide-react";
import { useState } from "react";
const Example = () => {
const [files, setFiles] = useState<File[] | undefined>();
const handleDrop = (files: File[]) => {
console.log(files);
setFiles(files);
};
return (
<Dropzone onDrop={handleDrop} onError={console.error} src={files}>
<DropzoneEmptyState>
<div className="flex w-full items-center gap-4 p-8">
<div className="flex size-16 items-center justify-center rounded-lg bg-muted text-muted-foreground">
<UploadIcon size={24} />
</div>
<div className="text-left">
<p className="font-medium text-sm">Upload a file</p>
<p className="text-muted-foreground text-xs">
Drag and drop or click to upload
</p>
</div>
</div>
</DropzoneEmptyState>
<DropzoneContent />
</Dropzone>
);
};
export default Example;
Showing an image preview
"use client";
import { Dropzone, DropzoneContent, DropzoneEmptyState } from "../../../../../packages/dropzone";
import { useState } from "react";
const Example = () => {
const [files, setFiles] = useState<File[] | undefined>();
const [filePreview, setFilePreview] = useState<string | undefined>();
const handleDrop = (files: File[]) => {
console.log(files);
setFiles(files);
if (files.length > 0) {
const reader = new FileReader();
reader.onload = (e) => {
if (typeof e.target?.result === "string") {
setFilePreview(e.target?.result);
}
};
reader.readAsDataURL(files[0]);
}
};
return (
<Dropzone
accept={{ "image/*": [".png", ".jpg", ".jpeg"] }}
onDrop={handleDrop}
onError={console.error}
src={files}
>
<DropzoneEmptyState />
<DropzoneContent>
{filePreview && (
<div className="h-[102px] w-full">
<img
alt="Preview"
className="absolute top-0 left-0 h-full w-full object-cover"
src={filePreview}
/>
</div>
)}
</DropzoneContent>
</Dropzone>
);
};
export default Example;