Dropzone Button
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.
npx manteen add @house/dropzone-buttonDependencies
@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.
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.
| Prop | Type | Default | Description |
|---|---|---|---|
onDrop* | (files: File[]) => void | — | Called with the accepted files when a valid drop or file-picker selection completes. |
onReject | (rejections: FileRejection[]) => void | — | Called with the rejected files when a drop fails validation (type or size). |
accept | string[] | [MIME_TYPES.pdf] | Restricts accepted uploads to the given MIME types. |
maxSize | number | 30 * 1024 ** 2 | Sets the maximum accepted file size in bytes. |
multiple | boolean | true | Allows selecting or dropping more than one file at a time. |
disabled | boolean | false | Disables both the dropzone and the trigger button. |
idleLabel | string | "Upload files" | Sets the heading text shown while the dropzone is idle, and doubles as its accessible label. |
acceptLabel | string | "Drop files here" | Sets the heading text shown while a dragged file is being validated as acceptable. |
rejectLabel | string | "These files cannot be accepted" | Sets the heading text shown while a dragged file would be rejected. |
description | string | "Drag and drop files here, or use the file picker." | Renders supporting text below the heading describing how to use the dropzone. |
buttonLabel | string | "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.