Dropzone

A drag-and-drop file upload zone with accessible keyboard navigation and visual feedback.

Overview

The Dropzone component provides an accessible drag-and-drop area for file uploads. Built on React Aria, it includes keyboard navigation, screen reader support, file picker integration, type/size/count validation, and visual feedback for hover, drag target, disabled, and rejected states.

Usage

Dropzone provides the upload interaction. Compose visual content inside it with Empty State sub-components.

import { Button } from "@tilt-legal/cubitt-components/button";
import {
  Dropzone,
  DropzoneAction,
  DropzoneFolderAnimation,
} from "@tilt-legal/cubitt-components/dropzone";
import {
  EmptyStateDescription,
  EmptyStateHeading,
  EmptyStateMedia,
  EmptyStateTitle,
} from "@tilt-legal/cubitt-components/empty-state";
import { CloudUpload } from "@tilt-legal/cubitt-icons/ui/outline";
<Dropzone onFileDrop={(files) => console.log(files)}>
  <EmptyStateMedia>
    <CloudUpload />
  </EmptyStateMedia>
  <EmptyStateHeading>
    <EmptyStateTitle>Drop files here</EmptyStateTitle>
    <EmptyStateDescription>or click to browse</EmptyStateDescription>
  </EmptyStateHeading>
</Dropzone>

Examples

Variants

Switch between the default, ghost, and minimal dropzone variants.

Folder Animation

Use the animated folder for drag-over feedback. File type icons are based on the parent accept prop.

Action Button

Add an explicit action inside the dropzone while preserving the full drag-and-drop target.

API Reference

Dropzone

Root component that handles drag-and-drop and file selection.

PropTypeDefaultDescription
onFileDrop(files: File[]) => void-Callback when valid files are dropped or selected
onFilesRejected(rejections: FileRejection[]) => void-Callback when files are rejected by type, size, or count validation
acceptstring | readonly string[]-MIME types or file extensions for the picker and runtime validation
multiplebooleantrueAllow multiple file selection
maxSizenumber-Maximum file size in bytes
maxFilesnumber-Maximum number of accepted files
isDisabledbooleanfalseDisable the dropzone
disableClickbooleanfalseDisable click-to-browse while preserving drag-and-drop
variant"default" | "minimal" | "ghost""default"Visual variant
getDropOperation(types) => DropOperation-Custom React Aria drop operation resolver
onDrop(e: DropEvent) => void-Raw React Aria drop event callback, called after Cubitt file parsing
childrenReactNode-Composed visual content
classNamestring-Additional CSS classes

Dropzone also accepts the remaining React Aria DropZone props, except children is owned by Cubitt's composed content API.

FileRejection

type FileRejection = {
  file: File;
  reason: "type" | "size" | "count";
  message: string;
};

DropzoneFolderAnimation

Animated folder component with documents that fan out when opened. It responds to drag events from the parent Dropzone.

PropTypeDefaultDescription
showFileTypeIconsbooleantrueShow file type icons on documents based on parent accept prop
hideFrontPanelbooleanfalseHide the front folder panel for visual debugging
classNamestring-Additional CSS classes

DropzoneAction

Wrapper for action buttons. Handles click propagation so the nested button opens the file picker without double-triggering the root.

PropTypeDefaultDescription
childrenReactNode-Button or interactive element
classNamestring-Additional CSS classes

On this page