MUI Grid item not working with overflowY: "auto" - css

I am using MUI with React and I have a <Paper> element which wraps a <Grid> with 3 children elements. When setting the overflowY property of the bottom grid item to "auto", when the content becomes too big, the scroll bar doesn't show up but it breaks the parent container. This is my code:
<Paper
elevation={0}
style={{
height: "776px",
width: 342,
overflowY: "hidden"
}}
>
<Grid
container={true}
direction="column"
style={{ overflowY: "hidden" }}
>
{
<Grid
container={true}
item={true}
style={{
flexGrow: 1,
padding: "16px",
width: "100%",
flexWrap: "nowrap",
position: "sticky",
top: 0
}}
>
{props.pageTitle && (
<Grid item={true} style={{ marginTop: 6 }}>
{!filterOpen && (
<Typography variant="h6">
<span
style={{
paddingLeft: 8
}}
>
{props.pageTitle}
</span>
</Typography>
)}
</Grid>
)}
{props.allowFilter && (
<Grid justify={"flex-end"} container={true} item={true}>
<FmsFilterBox
filterText={filterText}
onChange={setFilterText}
cssFilterBoxWidth="100%"
onFilterOpenChanged={setFilterOpen}
/>
</Grid>
)}
</Grid>
}
<Grid item={true} style={{ flexGrow: 1 }}>
<Divider style={{ width: "100%" }} />
</Grid>
<Grid
item={true}
style={{
flexGrow: 1,
overflowY: "auto"
}}
>
{props.children(filteredData)}
</Grid>
</Grid>
</Paper>
I tried everything but I can't get the scroll bar appear for the 3rd (bottom) grid item (the one rendering {props.children(filteredData)} which is a list with list items fetched from the back end).
If I remove the overflowY: "hidden" from the <Paper>, the content of the 3rd gets hidden, but still no scroll bar - please see the photos attached.
I am really out of ideas, did anyone have this issue before? Thank you.

Fixed it. Apparently I had to add a height of 100% to the upper most grid (main container) and a flex-wrap of "no-wrap".

Related

Dynamic Image List from MUI do not respect max height of the React container

I am trying to create a dynamic image list where I can change the number of images that are being displayed, where the images have to occupy the max space in the component without change the image ratio and also without make the component scrollable. The following images show the result that is expected:
Although what really happens now is, in the first case, with only 2 images, it overflows the parent component due to the spacing added between the flexbox elements.
For the 6 images example, it goes worst:
It overflows the parent even more because it ignores the component's max height and always tries to occupy the max width possible.
To reach the correct behaviour, I'm hard coding the flex-basis of the image list for each case because it is a flex item, and only that way does it not grow more than it should. Although, that is not desirable because I want to make the images grow as much as possible without depending on the screen size.
I do not understand why they ignore the parent's max height.
I do not understand why they do ignore the max height of the parent.
Main component:
<>
<Grid
container
direction="column"
wrap="nowrap"
rowSpacing={1}
sx={{ alignSelf: 'flex-end', margin: 0, height: '100%', justifyContent: 'flex-end' }}
>
<Grid
container
wrap="nowrap"
item
sx={{
alignSelf: 'flex-start',
flex: '1 0 auto',
justifyContent: 'space-between',
alignItems: 'center',
}}
>
<CustomImageList ref={ref} />
</Grid>
<Grid item>
<CustomPagination onClick={keyMap.move} />
</Grid>
<Grid width="100%" item>
<Stack
spacing={1}
direction="row"
sx={{
overflowX: 'auto',
justifyContent: 'space-between',
'& .MuiFormControl-root': { marginTop: '1px' },
}}
divider={<Divider orientation="vertical" flexItem />}
>
{Buttons.map((button) => (
<Stack spacing={1} flex={1} key={button.buttonId}>
<Stack direction="row" spacing={1}>
{button.text ? (
<ButtonText button={button} />
) : (
<Button />
)}
</Stack>
<Stack spacing={1} direction="row">
<ButtonBox button={button} />
</Stack>
</Stack>
))}
</Stack>
</Grid>
</Grid>
</>
The component CustomImageList is sketch like the next code:
<>
<Stack justifyContent="center">
<IconButton
ref={leftArrowRef}
size="large"
onClick={(e) => {
e.preventDefault();
handleClick({
key: 'ArrowLeft',
keyCode: 37,
});
}}
>
<ArrowBackIosNewIcon />
</IconButton>
</Stack>
<ImageList
sx={{
height: '100%',
alignContent: 'center'
}}
cols={imageColumnCount}
>
{images.map((image, index) =>
createOrdinaryListItem(image, index)
)}
</ImageList>
<Stack justifyContent="center">
<IconButton
onClick={(e) => {
e.preventDefault();
handleClick({
key: 'ArrowRight',
keyCode: 39,
});
}}
ref={rightArrowRef}
size="large"
>
<ArrowForwardIosIcon />
</IconButton>
</Stack>
</>
The ImageList component is a MUI ImageList
What would be the best approach to create the scenario shown in the first and second figures? I have already tried to create my component. It was a flexbox where I used the breakpoint from the grid to distribute the columns across the images. I had the same behaviour that I presented here.
Sorry about the verbose post and kinda "hard to understand" question, but I was not capable of creating a runnable script to show what is aforementioned

Hiding Scrollbar from Material UI Treeview, while maintaining scroll functionality

How do I maintain the vertical scroll functionality, while at the same time, hiding the scrollbar in Material UI's Treeview API? I have tried a few combinations of styling directly in the tree view and tree item components to hide the scrollbar, but neither worked for me.
<TreeView
aria-label="icon expansion"
defaultCollapseIcon={<ExpandMoreIcon />}
defaultExpandIcon={<ChevronRightIcon />}
sx={{ height: 240, flexGrow: 1, overflowY: 'auto', overflowX: 'hidden' }}
>
<StyledTreeItem
label={
<Grid container>
<Grid item xs={3}>
Watchlist
</Grid>
<Grid item xs={8}>
</Grid>
</Grid>
}
nodeId="1"
style={{ padding: '0.2vw' }}>
<Grid container style={{ width: '100%' }}>
<LiveStockTable
minHeight={500}
maxHeight={1000}
subscribedTickers={props.subscribedTickers} />
</Grid>
</StyledTreeItem>
</TreeView>
and the StyledTreeItem:
const StyledTreeItem = styled(TreeItem)<StyledTreeItemProps>({
position: "relative",
"&:before": {
pointerEvents: "none",
content: '""',
position: "absolute",
overflow: 'hidden'
},
[`& .${treeItemClasses.group}`]: {
marginLeft: 0,
paddingLeft: 0,
}
})

Material UI Paper won't render the correct background color?

I have seen numerous methods in other stackoverflow questions related to how to change the background color of a Material UI Paper component. However, I'm having a strange issue in that the color will change, but not to the correct color?
Here I am trying to make some grids that I will place widgets in. The background is a Paper component which has the same issue. All the paper components rendered do not match the color requested in the code. I have tried changing it with makeStyles() as well as directly with the style attribute:
const useStyles = makeStyles((theme) => ({
widgetPaper: {
backgroundColor: "#233044",
borderRadius: 25
},
}));
...
<Grid container spacing={0} sx={{ mt: "auto", ml: 1, width: "auto" }}>
<Grid
item
container
spacing={0}
xs={3}
align="center"
sx={{ ml: `${props.dw}px`, mt: 2 }}
>
<Grid item xs={6} align="left">
<Paper
sx={{ height: "95%", width: "99%" }}
className={classes.widgetPaper}
>
<Typography> Test1 </Typography>
</Paper>
</Grid>
<Grid item xs={6} align="right">
<Paper
style={{ backgroundColor: "#233044" }}
sx={{ height: "95%", width: "99%", borderRadius: 1 }}
>
<Typography> Test </Typography>
</Paper>
</Grid>
<Grid item xs={6} align="left">
<Paper
style={{ backgroundColor: "#233044" }}
sx={{ height: "95%", width: "99%", borderRadius: 1 }}
>
<Typography> Test </Typography>
</Paper>
</Grid>
<Grid item xs={6} align="right">
<Paper
style={{ backgroundColor: "#233044" }}
sx={{ height: "95%", width: "99%", borderRadius: 1 }}
>
<Typography> Test </Typography>
</Paper>
</Grid>
</Grid>
<Grid
item
xs={7}
align="left"
sx={{ mt: 2, ml: 1, borderRadius: 1 }}
style={{ backgroundColor: "#233044" }}
></Grid>
</Grid>
The layout renders as expected, however the colors of the paper elements are wrong. I know it is the color of the paper elements specifically, because the last grid item doesn't have Paper and it's color is correct:
In case it is relevant; at the App.js level I am using:
const darkTheme = createTheme({ palette: { mode: 'dark' } });
What is it about Paper elements specifically which is causing this? Am I making a really obvious mistake?
Thank you.

React Material UI responsive Grid with Card

I am trying to create a responsive grid layout using cards that should have the same height including an image. I am using React and Material-UI.
I am fiddling around now for hours and cannot come up with a solution. The "flex" part seems super unintuitive to me. Please help.
It is a very small and simple code piece:
const useStyles = makeStyles((theme: Theme) =>
createStyles({
cardGrid: {
flexGrow: 1,
paddingTop: 16,
},
card: {
flex: 1,
height: '100%',
backgroundColor: 'red',
},
cardActionArea: {
flex: 1,
height: '100%',
backgroundColor: 'green',
},
cardMedia: {
height: '0',
paddingTop: '56.25%', // 16:9
},
cardContent: {
flex: 1,
backgroundColor: blue[600],
},
cardContentTitle: {
flex: 1,
backgroundColor: blue[400],
},
cardContentRating: {
backgroundColor: blue[300],
},
cardContentDistance: {
backgroundColor: blue[200],
}
}),
);
// ...
<Container className={classes.cardGrid} maxWidth="xl">
<Grid
container
direction="row"
justify="space-evenly"
alignItems="stretch"
spacing={2}
>
{
dataList.map(data => (
<Grid item
key={`GridItem-${data.id}`} xs={12} sm={6} md={4} lg={2} xl={1}
>
<Card className={classes.card}
onClick={handleCardClick}
key={`OverviewItem-${data.id}`}
>
<CardActionArea className={classes.cardActionArea}>
{
data.previewURL &&
<CardMedia
className={classes.cardMedia}
image={data.previewURL}
title={data.title}
/>
}
<CardContent className={classes.cardContent}>
<Typography gutterBottom variant="h5" className={classes.cardContentTitle}>
{data.title}
</Typography>
<Typography className={classes.cardContentRating}>
Some text
</Typography>
<Typography className={classes.cardContentDistance}>
Some other text
</Typography>
</CardContent>
</CardActionArea>
</Card>
</Grid>
))
}
</Grid>
</Container>
What I am trying to achieve:
Image should be at the top of each card
"Some text" and "Some other text" should get moved to the bottom
It seems like I have to write "flex:1" and "height:'100%'" multiple times when going down the tree and at some point it breaks completely like in following screenshot:
With the code snippet from above it looks like this:
What is the magic to simply expand the childs of a Grid Item to its maximum height and to still be able to align them as I want.
E.g. the entire card should stretch over the area of the Grid Item and the title part below the image should expand to move the image to the top and "Some text" and "Some other text" to the bottom.
Any hints/ideas are appreciated!
I was able to achieve what I wanted without a Card and without the image. But making the tree bigger and therefore the nesting deeper, breaks everything and I don't understand why.
Here is the simple snippet and the result:
<Container className={classes.cardGrid} maxWidth="xl">
<Grid
container
direction="row"
justify="space-evenly"
alignItems="stretch"
spacing={2}
>
{
toiletOverviews.map(data => (
<Grid item
key={`GridItem-${data.id}`} xs={12} sm={6} md={4} lg={2} xl={1}
>
<Box
display="flex"
flexDirection="column"
style={{height: '100%', backgroundColor: 'purple'}}
>
<Typography
variant="h5"
style={{flex:1, backgroundColor: blue[800]}}
>
{data.title}
</Typography>
<Typography
style={{backgroundColor: blue[600]}}
>
Some text
</Typography>
<Typography
style={{backgroundColor: blue[400]}}
>
Some other text
</Typography>
</Box>
</Grid>
))
}
</Grid>
</Container>
I figured it out! The important part that I did not know is that display:"flex" is only applied to the current element and its direct children. For childrens of its childrens it will not be applied.
The solution now is to correctly apply it to all necessary elements. The sideeffect was that the image was no longer displayed. It had a width/height of zero. The fix here is to add width:"100%" to the CardMedia element.

Using Material-UI's Grid component, how do I get one cell to take up the remaining horizontal width?

I'm trying to use material-ui's Grid component in my React 16.13.0 application. I want to have a row with three items. The first two items should only take up as much space as they need to (I don't want to hard code pixel values if possible). I would like the third item to take up the remaining horizontal space and float the furthest to the rigth (I discovered React doesn't like "float: right" as a style, though). I have this
const styles = (theme) => ({
root: {
textAlign: "left",
margin: theme.spacing(2),
paddingBottom: theme.spacing(1),
color: theme.color.secondary,
},
cardHeader: {
paddingBottom: theme.spacing(0),
},
cardContent: {
width: "100%",
paddingBottom: theme.spacing(1),
},
rowBody: {
width: "100%",
flexWrap: "nowrap",
alignItems: "center",
},
});
...
<CardContent className={classes.cardContent}>
<Grid container className={classes.rowBody}>
<Grid item>
<img height="20" src={require('../../img/apple.svg')} alt="" />
</Grid>
<Grid item>
{title}
</Grid>
<Grid item>
<InfoIcon />
</Grid>
</Grid>
But unfortunately, this renders everything bunched up together
How can I adjust the styles to do what I want?
Edit: This is what is displayed based on the answer given by #Mohsen007 ...
Follow the code below:
rowBody: {
width: "100%",
flexWrap: "nowrap",
alignItems: "center",
display: "flex",
},
<Grid container className={classes.rowBody}>
<Grid item>
<img height="20" src={require('../../img/apple.svg')} alt="" />
</Grid>
<Grid item style={{flex: 1,}}>
{title}
</Grid>
<Grid item>
<InfoIcon />
</Grid>
</Grid>

Resources