I'm trying to display a grid of Avatar images. While in a transition state I would like for a skeleton representation of the Image to appear. For that I'm using @material-ui/lab/Skeleton
.
The problem I'm having is that, because my images are set to autoscale within a grid using height: auto, width: 100%
, and the height/length of the content displayed under the image varies, there is no set height val that I can pass over to the skeleton component.
You can see the problem this causes if you scale down the width of the sandbox screen. The grid item's height increases causing the circle skeleton to begin morphing into an oval.
Is there a solution here that might give me behavior similar to the image's height: auto, width: 100%
?
The full code of what I have so far is below and in the sandbox here: https://codesandbox.io/s/skeleton-scaling-y00cd.
import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Avatar from "@material-ui/core/Avatar";
import Skeleton from "@material-ui/lab/Skeleton";
import Typography from "@material-ui/core/Typography";
import clsx from "clsx";
import Grid from "@material-ui/core/Grid";
const useStyles = makeStyles(theme => ({
root: {
textAlign: "center",
height: "100%",
width: "100%"
},
title: {
marginTop: theme.spacing(1)
},
avatarRoot: {
// width: '100%',
// height: 'auto',
// minHeight: '273px',
},
withTitle: {
margin: "auto"
},
img: {},
content: {
lineHeight: "1.4em"
},
link: {
color: "inherit",
textDecoration: "none"
},
icon: {},
fillContainer: {
height: `auto`,
width: `100%`,
fontSize: "4em"
},
container: {
marginTop: "250px"
},
fallback: {
height: "75%",
width: "auto"
},
loader: {},
avatarLoader: {
height: "75%",
width: "100%"
},
titleLoader: {
width: "60%",
margin: "auto",
marginTop: "8px",
height: "5%"
},
contentLoader: {
width: "40%",
margin: "auto",
marginTop: "8px",
height: "5%"
},
testImg: {
borderRadius: "100%",
height: "auto",
width: "100%"
},
isLoading: {
display: "none"
},
imgContainer: {
paddingTop: "100%",
borderRadius: "100%",
backgroundPosition: "center",
backgroundSize: "contain",
backgroundImage: "url(https://via.placeholder.com/500)"
}
}));
export default function ImageAvatars() {
const classes = useStyles();
return (
<div className={classes.root}>
<Grid container spacing={1} className={classes.container}>
<Grid container item xs={3} spacing={0} direction="column">
<Avatar
src={"https://via.placeholder.com/500"}
variant="circle"
className={clsx(classes.avatarRoot, {
[classes.isLoading]: false,
[classes.withTitle]: true,
[classes.fallback]: false,
[classes.fillContainer]: true
})}
/>
<Typography className={classes.title}>MUI Avatar</Typography>
<Typography className={classes.content}>test test test</Typography>
</Grid>
<Grid container item xs={3} spacing={0} direction="column">
<div className={classes.imgContainer} />
<div>
<Typography className={classes.title}>background image</Typography>
<Typography className={classes.content}>test test test</Typography>
</div>
</Grid>
<Grid container item xs={3} spacing={0} direction="column">
<img
className={classes.testImg}
src={"https://via.placeholder.com/500"}
alt={"test"}
/>
<div>
<Typography className={classes.title}>image el</Typography>
<Typography className={classes.content}>test test test</Typography>
</div>
</Grid>
<Grid container item xs={3} spacing={0} direction="column">
<Skeleton
variant="circle"
className={clsx(classes.avatarLoader, classes.avatarRoot)}
/>
<Skeleton className={clsx(classes.titleLoader, classes.title)} />
<Skeleton className={clsx(classes.contentLoader, classes.content)} />
</Grid>
</Grid>
</div>
);
}