Skip to main content
react-md

useDropzone

function useDropzone(options: DropzoneOptions): DropzoneHookReturnValue;

The useDropzone hook can be used to handle drop events for a container element on the page. The main use case is for handling dropping files and uploading them along with the useFileUpload hook.

Example Usage

Drag and drop some files!

Or upload them manually

import { Box } from "@react-md/core/box/Box";
import { cssUtils } from "@react-md/core/cssUtils";
import { FileInput } from "@react-md/core/files/FileInput";
import { useFileUpload } from "@react-md/core/files/useFileUpload";
import { LinearProgress } from "@react-md/core/progress/LinearProgress";
import { Typography } from "@react-md/core/typography/Typography";
import { useDropzone } from "@react-md/core/useDropzone";
import UploadIcon from "@react-md/material-icons/UploadIcon";
import { cnb } from "cnbuilder";
import { type ReactElement } from "react";

import styles from "./SimpleExample.module.scss";

export default function SimpleExample(): ReactElement {
  const { onDrop, onChange, stats } = useFileUpload();
  const { isOver, isDragging, dropzoneHandlers } = useDropzone({
    onDrop,

    // if you need to do any custom drop behavior, it can be done here.
    // onDrop(event) {
    //   // custom behavior
    //   onDrop(event);
    // },

    // When this is `true`, the `isDragging` flag will not update so the
    // dropzone only interacts to `dragEnter`/`dragOver`/`dragLeave`/`drop`
    // events. So if you want to help guide the user to the dropzone by adding
    // addition styles when **any** drag event occurs, omit this option or set
    // it to `false`
    //
    // Try uncommenting this next line to see the difference when dragging files
    // into the window and the first mouse event is not over the dropzone
    // disableDragging: true,
  });
  const isUploading =
    stats.length > 0 && stats.find((stat) => stat.status !== "complete");

  return (
    <Box
      {...dropzoneHandlers}
      justify="center"
      stacked
      fullWidth
      className={cnb(
        styles.container,
        isOver && styles.dragover,
        (isOver || isDragging) && styles.dragging,
        cssUtils({ textAlign: "center" }),
      )}
    >
      {isUploading && (
        <LinearProgress
          aria-label="Uploading Files"
          className={styles.progress}
        />
      )}
      <Typography margin="none">Drag and drop some files!</Typography>
      <UploadIcon className={cnb(!isOver && styles.invisible)} />
      <Typography margin="top">Or upload them manually</Typography>
      <FileInput onChange={onChange} />
    </Box>
  );
}

Press Enter to start editing.

@use "everything";

.container {
  @include everything.icon-set-var(size, 4rem);
  @include everything.interaction-outline();

  min-height: 30vh;
  position: relative;
}

.dragging {
  @include everything.interaction-focus-styles($disable-background: true);
}

.dragover {
  @include everything.interaction-set-var(
    focus-color,
    everything.theme-get-var(success-color)
  );
}

.invisible {
  opacity: 0;
}

.progress {
  left: 0;
  position: absolute;
  right: 0;
  top: 0;
}

Press Enter to start editing.

Parameters

export interface DropzoneOptions {
  onDrop: <E extends HTMLElement>(event: DragEvent<E>) => void;

  onDragEnter?: <E extends HTMLElement>(event: DragEvent<E>) => void;
  onDragOver?: <E extends HTMLElement>(event: DragEvent<E>) => void;
  onDragLeave?: <E extends HTMLElement>(event: DragEvent<E>) => void;

  /**
   * By default, the `useDropzone` hook will listen to any `dragenter`/`dragover`
   * events on the page and enabling the {@link DragHookReturnValue.isDragging}
   * flag to show that the user is dragging _something_ and they might want to
   * drag that something into the dropzone.
   *
   * So set this option to `true` if that behavior is not required and only
   * drag events on the dropzone element need to be captured.
   *
   * @defaultValue `false`
   * @see {@link DropzoneImplementation.isDragging}
   */
  disableDragging?: boolean;
}

Returns

export interface DropzoneImplementation {
  /**
   * This will be `true` when the user is dragging something over the dropzone
   * target.
   */
  isOver: boolean;

  /**
   * This will be `true` when the user is dragging anything within the document.
   * The main use case for this is detecting when a user is dragging a file into
   * the document so you can help highlight the dropzone area.
   *
   * This will always be `false` if {@link DropzoneOptions.disableDragging} is
   * `true`.
   */
  isDragging: boolean;

  /**
   * The event handlers that should be passed to the dropzone target.
   */
  dropzoneHandlers: Required<DropzoneHandlers>;
}

See Also