Skip to content

Dropzone Button

ComponentMantine ≥ 9MantineProvider

Drag-and-drop file input with explicit accept, reject and picker behavior.

Install

One command copies the item's source into your project, where you own and edit it.

Terminal window
npx manteen add @house/dropzone-button

Dependencies

  • @mantine/core@^9npm
  • @mantine/dropzone@^9npm
  • @tabler/icons-react@^3npm

Installing this item also installs @house/mantine-ui-license from the registry.

Preview

Usage

A copy-ready example published by the registry author. Imports use the aliases Manteen configures at init.

dropzone-button.usage.tsx
import { DropzoneButton } from "@/components/ui/dropzone-button";
export function ResumeUpload() {
return (
<DropzoneButton
onDrop={(files) => console.log("accepted files", files)}
onReject={(rejections) => console.log("rejected files", rejections)}
idleLabel="Upload your resume"
acceptLabel="Drop your resume here"
rejectLabel="PDF files only, up to 30MB"
description="Drag and drop a PDF here, or click the button to browse your files."
buttonLabel="Select file"
/>
);
}

Props

Author-documented props, carried verbatim from the registry item.

PropTypeDefaultDescription
onDrop*(files: File[]) => voidCalled with the accepted files when a valid drop or file-picker selection completes.
onReject(rejections: FileRejection[]) => voidCalled with the rejected files when a drop fails validation (type or size).
acceptstring[][MIME_TYPES.pdf]Restricts accepted uploads to the given MIME types.
maxSizenumber30 * 1024 ** 2Sets the maximum accepted file size in bytes.
multiplebooleantrueAllows selecting or dropping more than one file at a time.
disabledbooleanfalseDisables both the dropzone and the trigger button.
idleLabelstring"Upload files"Sets the heading text shown while the dropzone is idle, and doubles as its accessible label.
acceptLabelstring"Drop files here"Sets the heading text shown while a dragged file is being validated as acceptable.
rejectLabelstring"These files cannot be accepted"Sets the heading text shown while a dragged file would be rejected.
descriptionstring"Drag and drop files here, or use the file picker."Renders supporting text below the heading describing how to use the dropzone.
buttonLabelstring"Select files"Sets the label of the button that opens the native file picker.

* required

Styling

No public Styles API is declared. Installed CSS remains editable because your project owns the source; internal class names are implementation details, not a customization contract.

Package-level styles, composed into the managed global stylesheet during install:

  • @mantine/dropzone/styles.css

Source

2 installable files ship with this item.

registry/mantine-ui/dropzone-button/dropzone-button.tsxcomponent · 2.8 kB · tsx
/**
* Adapted from Mantine UI's DropzoneButton at
* ffbf61c559f374a7ea28fcf00355e84dcbe9a908. MIT licensed; see
* LICENSES/MANTINE-UI.txt after installation.
*/
import { Button, Group, Text, useMantineTheme } from "@mantine/core";
import { Dropzone, type FileRejection, MIME_TYPES } from "@mantine/dropzone";
import { IconCloudUpload, IconDownload, IconX } from "@tabler/icons-react";
import { useRef } from "react";
import classes from "./dropzone-button.module.css";
export interface DropzoneButtonProps {
onDrop: (files: File[]) => void;
onReject?: (rejections: FileRejection[]) => void;
accept?: string[];
maxSize?: number;
multiple?: boolean;
disabled?: boolean;
idleLabel?: string;
acceptLabel?: string;
rejectLabel?: string;
description?: string;
buttonLabel?: string;
}
export function DropzoneButton({
onDrop,
onReject,
accept = [MIME_TYPES.pdf],
maxSize = 30 * 1024 ** 2,
multiple = true,
disabled = false,
idleLabel = "Upload files",
acceptLabel = "Drop files here",
rejectLabel = "These files cannot be accepted",
description = "Drag and drop files here, or use the file picker.",
buttonLabel = "Select files",
}: DropzoneButtonProps) {
const theme = useMantineTheme();
const openRef = useRef<() => void>(null);
return (
<div className={classes.wrapper}>
<Dropzone
openRef={openRef}
onDrop={onDrop}
onReject={onReject}
className={classes.dropzone}
radius="md"
accept={accept}
maxSize={maxSize}
multiple={multiple}
disabled={disabled}
inputProps={{ "aria-label": idleLabel }}
>
<div style={{ pointerEvents: "none" }}>
<Group justify="center">
<Dropzone.Accept>
<IconDownload size={50} color={theme.colors.blue[6]} stroke={1.5} />
</Dropzone.Accept>
<Dropzone.Reject>
<IconX size={50} color={theme.colors.red[6]} stroke={1.5} />
</Dropzone.Reject>
<Dropzone.Idle>
<IconCloudUpload size={50} stroke={1.5} className={classes.icon} />
</Dropzone.Idle>
</Group>
<Text ta="center" fw={700} fz="lg" mt="xl">
<Dropzone.Accept>{acceptLabel}</Dropzone.Accept>
<Dropzone.Reject>{rejectLabel}</Dropzone.Reject>
<Dropzone.Idle>{idleLabel}</Dropzone.Idle>
</Text>
<Text className={classes.description}>{description}</Text>
</div>
</Dropzone>
<Button
className={classes.control}
size="md"
radius="xl"
color="blue.8"
disabled={disabled}
onClick={() => openRef.current?.()}
>
{buttonLabel}
</Button>
</div>
);
}
registry/mantine-ui/dropzone-button/dropzone-button.module.cssstyle · 707 B · css
/*
* Adapted from Mantine UI's DropzoneButton at
* ffbf61c559f374a7ea28fcf00355e84dcbe9a908. MIT licensed; see
* LICENSES/MANTINE-UI.txt after installation.
*/
.wrapper {
position: relative;
margin-bottom: 30px;
}
.dropzone {
padding-bottom: 50px;
color: var(--mantine-color-bright);
border-width: 1px;
}
.icon {
color: light-dark(var(--mantine-color-gray-4), var(--mantine-color-white));
}
.control {
position: absolute;
bottom: -20px;
left: calc(50% - 125px);
width: 250px;
}
.description {
margin-top: var(--mantine-spacing-xs);
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-gray-4));
font-size: var(--mantine-font-size-sm);
text-align: center;
}

Author notes

Adapted from Mantine UI DropzoneButton at ffbf61c559…; drop/reject callbacks, constraints and user-facing text are configurable.