aboutsummaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
authoreug-vs <eug-vs@keemail.me>2020-08-14 16:16:01 +0300
committereug-vs <eug-vs@keemail.me>2020-08-14 16:16:01 +0300
commitc5cacacfadf12c9321e932ce2fc3fa669b4c8807 (patch)
treeef6607d54f752c246c2bcfe4931bb14ae67a6a13 /src/components
parentfc95e83e704ec054f551bae587a8a6e5bcaf4135 (diff)
downloadwhich-ui-c5cacacfadf12c9321e932ce2fc3fa669b4c8807.tar.gz
feat: handle loading and error states in Image
Diffstat (limited to 'src/components')
-rw-r--r--src/components/Image/Image.tsx55
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;