@eureca/eureca-ui
Version:
UI component library of Eureca's user and admin apps
204 lines (187 loc) • 5.25 kB
JavaScript
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 };