@eureca/eureca-ui
Version:
UI component library of Eureca's user and admin apps
171 lines (151 loc) • 4.26 kB
JavaScript
import React, { useState, useCallback } from 'react';
import PropTypes from 'prop-types';
import { Document, Page, pdfjs } from 'react-pdf';
import { Box, Typography } from '@material-ui/core';
import { useTheme } from '@material-ui/core/styles';
import { FiChevronLeft, FiChevronRight } from 'react-icons/fi';
import { colors } from '../../theme/colors';
import { useWindowSize } from '../../hooks/useWindowSizeSSR';
import { Flex } from '../Flex/';
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;
function PDFViewer({ pdf }) {
const theme = useTheme();
const size = useWindowSize();
const [pageNumber, setPageNumber] = useState(1);
const [numPages, setNumPages] = useState(null);
const [pdfWidth, setPdfWidth] = useState(0);
const barRef = useCallback(
value => {
if (value !== null && size !== null) {
setPdfWidth(value.clientWidth);
}
},
[size]
);
const onDocumentLoadSuccess = document => {
const { numPages } = document;
setPageNumber(1);
setNumPages(numPages);
};
const styles = {
pagination: {
position: 'sticky',
top: '0px',
zIndex: 500,
},
icon: {
cursor: 'pointer',
color: colors.white,
},
ScrollPage: {
overflowX: 'hidden',
overflowY: 'auto',
},
pageNumbers: {
color: colors.white,
},
error: {
color: colors.error1,
},
};
const noDataState = (
<Flex justifyCenter alignCenter p={4}>
<Typography variant="h3">Nenhum arquivo PDF especificado.</Typography>
</Flex>
);
const docErrorState = (
<Flex justifyCenter alignCenter p={4}>
<Typography variant="h3" style={styles.error}>
Algo deu errado e o PDF não foi carregado.
</Typography>
</Flex>
);
const docLoadingState = (
<Flex justifyCenter alignCenter p={4}>
<Typography>Carregando o PDF.</Typography>
</Flex>
);
const pageErrorState = (
<Flex justifyCenter alignCenter p={4}>
<Typography variant="h3" style={styles.error}>
Algo deu errado e a página não foi carregada.
</Typography>
</Flex>
);
const pageLoadingState = (
<Flex justifyCenter alignCenter p={4}>
<Typography>Carregando a página.</Typography>
</Flex>
);
return (
<>
<Flex
width="initial"
directionRow
justifyFlexStart
alignCenter
minHeight={theme.spacing(8)}
px={3}
bgcolor={colors.gray2}
ref={barRef}
style={styles.pagination}
>
{pageNumber > 1 && (
<Flex
justifyCenter
alignCenter
width={`${theme.spacing(4)}px`}
height={`${theme.spacing(4)}px`}
mr={2}
>
<FiChevronLeft
onClick={() => setPageNumber(pageNumber - 1)}
size={22}
style={styles.icon}
/>
</Flex>
)}
<Box ml={pageNumber === 1 ? 6 : 0}>
<Typography variant="body1" style={styles.pageNumbers}>
{`${pageNumber || (numPages ? 1 : '')}/${numPages || ''}`}
</Typography>
</Box>
{pageNumber !== numPages && (
<Flex
justifyCenter
alignCenter
width={`${theme.spacing(4)}px`}
height={`${theme.spacing(4)}px`}
ml={2}
>
<FiChevronRight
onClick={() => setPageNumber(pageNumber + 1)}
size={22}
style={styles.icon}
/>
</Flex>
)}
</Flex>
<Flex justifyCenter alignCenter style={styles.ScrollPage}>
<Document
file={pdf}
error={docErrorState}
loading={docLoadingState}
onLoadSuccess={onDocumentLoadSuccess}
noData={noDataState}
>
<Page
width={pdfWidth}
loading={pageLoadingState}
error={pageErrorState}
pageNumber={pageNumber}
/>
</Document>
</Flex>
</>
);
}
PDFViewer.propTypes = {
pdf: PropTypes.oneOfType([PropTypes.string, PropTypes.node]).isRequired,
};
export { PDFViewer };