diff options
Diffstat (limited to 'src/components/Image')
-rw-r--r-- | src/components/Image/Image.tsx | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/src/components/Image/Image.tsx b/src/components/Image/Image.tsx index de67c6a..7736e8a 100644 --- a/src/components/Image/Image.tsx +++ b/src/components/Image/Image.tsx @@ -1,4 +1,7 @@ -import React from 'react'; +import React, { useState, useCallback } from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import CircularProgress from '@material-ui/core/CircularProgress'; +import ErrorIcon from '@material-ui/icons/BrokenImage'; interface PropTypes { src?: string; @@ -6,8 +9,56 @@ interface PropTypes { className?: string; } +const useStyles = makeStyles(theme => ({ + container: { + width: '100%', + height: '100%', + display: 'flex', + alignItems: 'center', + justifyContent: 'center' + } +})); + +type Status = 'success' |'loading' | 'error'; + const Image: React.FC<PropTypes> = ({ src, alt, className }) => { - return <img src={src} alt={alt} className={className} />; + const classes = useStyles(); + const [status, setStatus] = useState<Status>('loading'); + + const handleLoad = useCallback((): void => { + setStatus('success'); + }, [setStatus]); + + const handleError = useCallback((): void => { + setStatus('error'); + }, [setStatus]); + + const image = ( + <img + src={src} + alt={alt} + className={className} + style={{ display: status === 'success' ? 'inline' : 'none' }} + onLoad={handleLoad} + onError={handleError} + /> + ); + + return ( + <> + {src && image} + { + status !== 'success' && ( + <div className={classes.container}> + { + (status === 'error' || !src) + ? <ErrorIcon fontSize="large" /> + : <CircularProgress color="primary" /> + } + </div> + )} + </> + ); }; export default Image; |