material-ui-dropzone

repository·master·Indexed 19 days ago

https://github.com/yuvaleros/material-ui-dropzone

A React component library for file-upload dropzones styled with Material-UI and built on top of react-dropzone. It provides components like DropzoneArea for inline uploads and DropzoneDialog for modal-based uploads, featuring file previews, snackbar notifications, drag-and-drop visual effects, and support for custom theming via MuiDropzoneArea, MuiDropzonePreviewList, and MuiDropzoneSnackbar namespaces.

Tokens
10.7K
Snippets
35
Records
40
Agent score
63%

What's inside material-ui-dropzone

  1. Overview of material-ui-dropzone

    master

    material-ui-dropzone is a collection of React components built on top of Material-UI and the react-dropzone library. It provides specialized components for file uploading, specifically offering:

    • A standard file-upload dropzone area.
    • A file-upload dropzone contained within a dialog.

    Key features include visual feedback for "File Allowed" vs "File Not Allowed" states, file previews, and integrated alerts.

  2. Understand the FileObject data contract

    master

    When working with DropzoneAreaBase, files are managed as FileObject entities rather than raw File objects. This allows the component to provide pre-read data (like base64 strings for image previews) alongside the original file.

    A FileObject follows this shape:

    {
      file: File; // The original browser File object
      data: any;  // The read content of the file (e.g., a base64 string)
    }
    /**
     * @typedef {
     *   {file: File, data: any}
     * }
     * FileObject
     */
  3. Restrict accepted files to images

    master

    Use the acceptedFiles prop to pass an array of MIME types (e.g., ['image/*']) to restrict what files the user can upload. You can also customize the dropzone instruction text using dropzoneText.

    <DropzoneAreaBase
      acceptedFiles={['image/*']}
      dropzoneText={"Drag and drop an image here or click"}
      onChange={(files) => console.log('Files:', files)}
      onAlert={(message, variant) => console.log(`${variant}: ${message}`)}
    />
  4. Customize Preview Icons with getPreviewIcon

    master

    The getPreviewIcon prop accepts a function that determines which icon to display for a specific file. This function receives fileObject (containing the native file object) and classes (the component's internal CSS classes).

    This is useful for showing different icons for PDFs, Videos, Audio, or Word documents based on their MIME type.

    import React, { useState } from 'react';
    import { AttachFile, AudioTrack, Description, PictureAsPdf, Theaters } from '@mui/icons-material';
    
    const handlePreviewIcon = (fileObject, classes) => {
      const {type} = fileObject.file
      const iconProps = {
        className : classes.image,
      }
    
      if (type.startsWith("video/")) return <Theaters {...iconProps} />
      if (type.startsWith("audio/")) return <AudioTrack {...iconProps} />
    
      switch (type) {
        case "application/msword":
        case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
          return <Description {...iconProps} />
        case "application/pdf":
          return <PictureAsPdf {...iconProps} />
        default:
          return <AttachFile {...iconProps} />
      }
    }
    
    const [fileObjects, setFileObjects] = useState([]);
    
    <DropzoneAreaBase
      fileObjects={fileObjects}
      onAdd={newFileObjs => {
        console.log('onAdd', newFileObjs);
        setFileObjects([].concat(fileObjects, newFileObjs));
      }}
      onDelete={deleteFileObj => {
        console.log('onDelete', deleteFileObj);
      }}
      getPreviewIcon={handlePreviewIcon}
    />
  5. Use DropzoneDialog for file uploads

    master

    DropzoneDialog is a component that provides a dialog interface for users to select and preview files. It can be controlled via an open state and provides an onSave callback containing the selected files.

    Common Props

    • acceptedFiles: An array of strings defining allowed file types (e.g., ['image/*']).
    • maxFileSize: Maximum allowed file size in bytes.
    • open: Boolean controlling the visibility of the dialog.
    • onClose: Callback function triggered when the dialog is closed.
    • onSave: Callback function triggered when the user submits the files. Receives the selected files as an argument.
    • showPreviews: Boolean to enable or disable file previews.
    • showFileNamesInPreview: Boolean to show file names within the preview area.
    • cancelButtonText: Custom text for the cancel button.
    • submitButtonText: Custom text for the submit button.
    import Button from '@mui/material/Button';
    
    const [open, setOpen] = React.useState(false);
    
    <div
    >
      <Button variant="contained" color="primary" onClick={() => setOpen(true)}>
        Add Image
      </Button>
    
      <DropzoneDialog
        acceptedFiles={['image/*']}
        cancelButtonText={"cancel"}
        submitButtonText={"submit"}
        maxFileSize={5000000}
        open={open}
        onClose={() => setOpen(false)}
        onSave={(files) => {
          console.log('Files:', files);
          setOpen(false);
        }}
        showPreviews={true}
        showFileNamesInPreview={true}
      />
    </div>
  6. Configure the Reset button

    master

    The reset prop allows you to add a button to clear the dropzone.

    • Functional Reset: Pass an object with an onClick handler: reset={{ onClick: () => ... }}.
    • Custom Reset Button: Pass any valid React node (like a <button>) to the reset prop to completely customize the reset UI.
    // Functional Reset
    <DropzoneAreaBase
      onAdd={(fileObjs) => console.log('Added Files:', fileObjs)}
      onDelete={(fileObj) => console.log('Removed File:', fileObj)}
      onAlert={(message, variant) => console.log(`${variant}: ${message}`)}
      reset={{
        onClick: () => console.log('reset'),
      }}
    />
    
    // Custom Reset Button
    <DropzoneAreaBase
      onAdd={(fileObjs) => console.log('Added Files:', fileObjs)}
      onDelete={(fileObj) => console.log('Removed File:', fileObj)}
      onAlert={(message, variant) => console.log(`${variant}: ${message}`)}
      reset={<button style={{ margin: '20px 0' }} onClick={() => console.log('reset')}>reset</button>}
    />