manrysj
manrysj

Reputation: 75

Customize DropZoneArea for material-ui-dropzone

I would like to customize the look of the DropZoneArea besides the simple dropZoneText and Icon props. I have successfully done it, but I get the following react warning Failed prop type: Invalid prop 'dropzoneText' of type 'object' supplied to 'DropzoneAreaBase', expected string.

I understand what the issue is, but I was wondering if anyone knew how to accurately customize it.

Default looks like: enter image description here

I want the following:

enter image description here

I was able to get it to work by overriding the the dropZoneText prop as follows:

<DropzoneArea
  filesLimit={1}
  showAlerts={false}
  classes={{ root: clsx([classes.dropZoneRoot, uploading ? classes.disableClick : null]) }}
  showPreviewsInDropzone={false}
  showFileNames={false}
  dropzoneClass={classes.dropZone}
  Icon={''}
  dropzoneText={
    <Box className={classes.customDropZone} px={16} py={6} display="flex" flexDirection="column" justifyContent="center" alignItems="center" gridGap={4}>
      {uploading && (
        <Box className={classes.customDropZoneLoader} display="flex" flexDirection="column" justifyContent="center" alignItems="center">
          <CircularProgress size="2rem" />
        </Box>
      )}
      <Typography variant="subtitle1">Drop your file here</Typography>
      <Typography>or</Typography>
      <Box mt={1}>
        <Button color="primary" variant="outlined" style={{ width: 125 }}>
          Select File
        </Button>
      </Box>
      <Box mt={1}>
        <Typography>
          Accepted file types: <br />
          <strong>.png, .jpg, .gif, .txt, .csv, .doc, .docx, .xls, .xlsx, .pdf</strong>
        </Typography>
      </Box>
      <Box mt={1}>
        <Typography>
          Maximum file size: <strong>20MB</strong>
        </Typography>
      </Box>
    </Box>
  }
  maxFileSize={20971520}
  acceptedFiles={[
    'application/pdf, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, image/jpeg, image/png, application/txt, text/tab-separated-values, text/csv, application/csv, text/x-csv, application/x-csv, text/comma-separated-values, text/x-comma-separated-values'
  ]}
  onChange={onFileDropped}
  onDropRejected={onFileRejected}
>                    
</DropzoneArea>

Does anyone know of a better way to do this and not get the warning? For what it's worth, it works perfectly fine, but just throws the warning in the console.

Upvotes: 0

Views: 3619

Answers (3)

mfalade
mfalade

Reputation: 2147

A workaround is to leverage the Icon prop on the DropzoneArea component.

The Icon prop expects a React.ComponentType while the dropzoneText expects a string - you will always get the warning if you try to render the Nodes as dropzoneText.

The workaround is:

  1. set the dropzoneText to an empty string
  2. pass all the other cool stuff that you want to render as the Icon

It is not the most semantic approach but it works.


const MyCoolContent = () => {
  return (
    <Box>
      ... all the cool stuff goes here.
    </Box>
  )
}

<DropzoneArea
  ...yourOtherProps
  dropzoneText=""
  Icon={MyCoolContent}
/>

Upvotes: 0

Thanaruby Nanthagopal
Thanaruby Nanthagopal

Reputation: 614

I have customised like the following. Hope this will help someone. (Add this to the component where you have added DropzoneArea)

 useEffect(() => {
    const container = document.getElementsByClassName(
      'dropZone',
    ) as HTMLCollectionOf<HTMLElement>;
    if (container[0]?.children[0]) {
      container[0].children[0].innerHTML =
        "<div class='new_drop_zone_wrapper'>\n" +
        "<div class='new_drop_zone_title'>Choose file or grag it here</div>\n" +
        "<div class='new_drop_zone_description'>Supports .xls or .xlsx formats</div>\n" +
        "<div class='new_drop_zone_button_wrapper'>" +
        "<div class='new_drop_zone_button'>Add File</div>" +
        '</div>' +
        '</div>';
    }
  }, []);

Upvotes: 0

Wesley LeMahieu
Wesley LeMahieu

Reputation: 2613

Unfortunately, it seems the maintainer of that repository is not capable of fixing it. https://github.com/Yuvaleros/material-ui-dropzone/issues/35 - It's a rather old repository so I doubt it would get fixed.

If you were using Typescript, you could cast the wrapper as a string to make the DropzoneArea component happy, but the issue is with the library itself not using object / ReactNode as an expected type.

If you really want to try and fix that, you could use an npm package like patch-package to fix it locally for your project. https://www.npmjs.com/package/patch-package

Upvotes: 1

Related Questions