UNPKG

@eureca/eureca-ui

Version:

UI component library of Eureca's user and admin apps

204 lines (187 loc) 5.25 kB
import React, { useCallback, useState, useEffect, useRef } from 'react'; import { useDropzone } from 'react-dropzone'; import PropTypes from 'prop-types'; import { FiImage, FiCheck, FiX } from 'react-icons/fi'; import { Typography, Box } from '@material-ui/core'; import { Flex } from '../Flex'; import { colors } from '../../theme/colors'; function Dropzone({ handleUploadImage, startFile, fileCallback, openFileDialog, size, mimeType }) { const [files, setFiles] = useState(startFile || undefined); const firstRender = useRef(true); const onDrop = useCallback( acceptedFiles => { const reader = new FileReader(); reader.onabort = () => console.error('Leitura do arquivo foi abortada.'); reader.onerror = () => console.error('Leitura do arquivo falhou.'); reader.onload = () => { if (handleUploadImage) { handleUploadImage(acceptedFiles.map(file => URL.createObjectURL(file))); } if (fileCallback) { fileCallback(acceptedFiles.map(file => file)); } setFiles(acceptedFiles.map(file => URL.createObjectURL(file))); }; acceptedFiles.forEach(file => reader.readAsBinaryString(file)); }, [fileCallback, handleUploadImage] ); const { getRootProps, getInputProps, open, isDragAccept, isDragReject, isDragActive, rejectedFiles, } = useDropzone({ accept: mimeType, onDrop, multiple: false, minSize: 0, maxSize: size, }); const isFileTooLarge = rejectedFiles.length > 0 && rejectedFiles[0].size > size; const filteredProps = Object.assign({}, getRootProps()); delete filteredProps.ref; useEffect(() => { if (firstRender.current) { firstRender.current = false; } else { open(); } }, [open, openFileDialog]); useEffect(() => { setFiles(startFile); }, [startFile]); useEffect( () => () => { URL.revokeObjectURL(files); }, [files] ); const styles = { dropzoneExt: { position: 'relative', width: '100%', height: 232, backgroundColor: colors.gray4, }, icon: { color: colors.gray2, fontSize: 35, }, iconAccept: { color: colors.green2, }, iconReject: { color: colors.error1, }, text: { fontWeight: 400, color: colors.gray3, textAlign: 'center', }, textAccept: { color: colors.green2, }, textReject: { color: colors.error1, }, preview: { cursor: 'pointer', position: 'absolute', width: '100%', height: 232, background: `url(${files}) ${colors.gray4} no-repeat`, backgroundSize: 'contain', backgroundPosition: 'center', borderRadius: 4, }, }; return ( <> <Flex alignCenter justifyCenter style={styles.dropzoneExt} {...filteredProps}> {files && ( <Flex alignCenter justifySpaceBetween key={files} onClick={e => e.stopPropagation()} style={styles.preview} /> )} {isDragAccept && ( <> <Box mb={2}> <FiCheck size={104} color={colors.green2} /> </Box> <Typography variant="body2" style={{ ...styles.text, ...styles.textAccept }}> Solte o arquivo aqui! </Typography> </> )} {isDragReject && ( <> <Box mb={2}> <FiX size={104} color={colors.error1} /> </Box> <Typography variant="body2" style={{ ...styles.text, ...styles.textReject }}> Formato não aceito. </Typography> </> )} {!isDragActive && ( <> <input {...getInputProps()} /> <Box mb={2}> <FiImage size={104} color={colors.gray3} /> </Box> <Flex alignCenter width={80}> <Typography variant="body2" style={styles.text}> Arraste e solte a imagem aqui ou </Typography> </Flex> <Box p={1} mt={1} textAlign="center" width={136} bgcolor={colors.gray3} borderRadius={4} style={{ cursor: 'pointer' }} > <Typography variant="body2" style={{ color: colors.white }}> Escolher arquivo </Typography> </Box> </> )} {isFileTooLarge && ( <> <Typography variant="body2" style={styles.text}> Tamanho do arquivo maior que o limite. </Typography> </> )} </Flex> </> ); } Dropzone.defaultProps = { size: null, mimeType: '', startFile: '', handleUploadImage: () => {}, fileCallback: () => {}, openFileDialog: false, }; Dropzone.propTypes = { size: PropTypes.number.isRequired, mimeType: PropTypes.string.isRequired, startFile: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.string), PropTypes.string]), handleUploadImage: PropTypes.func, fileCallback: PropTypes.func, openFileDialog: PropTypes.bool, }; export { Dropzone };