Skip to Content

FileDropzone

A component that allows users to upload files via drag-and-drop or file selection.

If you want a more react-aria-componentish component, check out rac's FileTrigger and Dropzone components

Usage

import { FileDropzone } from "@opengovsg/oui"
<FileDropzone aria-label="Upload files" />

The FileDropzone component provides an accessible way for users to upload files through drag-and-drop or file selection. It supports various file types, size restrictions, and multiple file uploads.

If the component does not have a visible label (by passing a label prop), an aria-label or aria-labelledby prop must be passed instead to identify it to assistive technology.

Examples

With Label and Description

Provide clear instructions to users with labels and descriptions.

Allowed MIME Types

Use the allowedMimeTypes prop to restrict which file types can be uploaded. Wildcards are supported (e.g., image/*).

Multiple Files

Use the maxFiles prop to allow users to upload multiple files at once.

File Size Limits

Set maxFileSize and minFileSize to enforce file size restrictions. Sizes are specified in bytes.

Error Handling

The FileDropzone automatically validates files against your constraints. Use the onError callback to handle validation errors and display error messages.

Image Preview

By default, image files are shown with a small preview. Use the imagePreview prop to control the preview size or disable it entirely.

Show Rejected Files

Use showRejectedFiles to display files that failed validation along with their error messages.

Controlled

Use the value and onChange props to control the selected files programmatically.

Selected Files:

No files selected.

Custom File Rendering

Use the children render prop to customize how uploaded files are displayed.

Sizes

Use the size prop to change the size of the file dropzone.

Disabled

Use the isDisabled prop to disable the file dropzone.

Read Only

Use the isReadOnly prop to make the file dropzone read-only. Users can view uploaded files but cannot add or remove them.

Validation

The FileDropzone component automatically validates files based on:

  • MIME type: Specified via allowedMimeTypes
  • File size: Controlled by maxFileSize and minFileSize (in bytes)
  • Number of files: Limited by maxFiles

When validation fails, the component will:

  1. Trigger the onError callback with an error message (if provided)
  2. Mark rejected files with error information
  3. Display rejected files if showRejectedFiles is enabled

Accessibility

  • The component uses proper ARIA attributes for screen reader support
  • Keyboard navigation is fully supported (Enter/Space to open file selector)
  • File validation errors are communicated to assistive technology
  • Error messages are properly associated with the component

Slots

Dropzone (classNames)

  • base: The root container for the dropzone
  • group: The wrapper for the dropzone area
  • dropzone: The interactive drop target area
  • icon: The upload icon displayed in the dropzone
  • text: The instructional text in the dropzone
  • dropzoneHighlight: The highlighted "Choose files" text
  • description: The description text below the dropzone
  • errorMessage: The error message text

FileItem (itemClassNames)

  • base: The root container for the file item component
  • container: The container for the file item content (text and actionButton)
  • textContainer: The container for the file name and size text
  • imageContainer: The container for the file preview image
  • image: The file preview image
  • name: The file name text
  • size: The file size text
  • error: The file rejection error
  • actionButton: The action button for the file item

Custom Styles

You can customize the FileDropzone component by passing custom Tailwind CSS classes to the component slots via the classNames and itemClassNames prop.

<FileDropzone
  aria-label="Upload files"
  classNames={{
    dropzone: "border-dashed border-2 border-blue-500",
    icon: "text-blue-500",
    text: "text-sm",
  }}
  itemClassNames={{
    base: "flex items-center space-x-2",
    textContainer: "flex-1",
    imageContainer: "w-12 h-12",
    image: "object-cover",
    name: "font-medium",
    size: "text-sm text-gray-500",
    error: "text-red-500",
    actionButton: "text-blue-500",
  }}
/>

Props

FileDropzone

PropTypeDefaultDescription
labelReact.ReactNode-The label for the file dropzone
descriptionReact.ReactNode-The description text shown below the dropzone
errorMessageReact.ReactNode-The error message to display when validation fails
valueFileItem[]-The currently selected files (controlled)
defaultValueFileItem[][]The default files (uncontrolled)
onChange(files: FileItem[]) => void-Callback fired when the selected files change
onError(errorMessage: string) => void-Callback fired when file validation fails
onRejection(rejections: FileItem[]) => void-Callback fired when files are rejected
allowedMimeTypesstring[][] (all types allowed)Array of allowed MIME types (supports wildcards like image/*)
maxFileSizenumberNumber.POSITIVE_INFINITYMaximum file size in bytes
minFileSizenumber0Minimum file size in bytes
maxFilesnumber1Maximum number of files allowed
showFileSizeTextbooleantrueWhether to show file size information below the dropzone
showRejectedFilesbooleanfalseWhether to display rejected files in the component
hideDropzoneOnValuebooleantrue if maxFiles === 1Whether to hide the dropzone when files are uploaded
imagePreview"small" | "large" | null"small"Size of image preview, or null to disable previews
size"sm" | "md""md"The size of the component
isDisabledbooleanfalseWhether the component is disabled
isReadOnlybooleanfalseWhether the component is read-only
isInvalidbooleanfalseWhether the component should display as invalid
isRequiredbooleanfalseWhether the component is required
classNamesSlotsToClasses<FileDropzoneSlots>-Custom CSS classes for component slots
itemClassNamesSlotsToClasses<FileInfoDropzoneSlots>-Custom CSS classes for file info item slots
validatorDropzoneOptions["validator"]-Custom file validator function
children(props: FileItemsRenderProps) => ReactNode-Render prop for custom file item rendering