Material UI Drawer overflow causing scrollbar on body - reactjs

I'm using a clipped under the app bar drawer with a canvas as the primary content. I have three collapsible cards in the drawer and when all set to be open by default, it shows a vertical scrollbar on the body and white space below the html element with the body element. If you close all three of the cards the scroll goes away. If you reopen the cards, the scroll doesn't appear. The issue only seems to occur when the page is loaded with all three cards open.
Our short term solution is to load the page with only two cards open, but I want to note even with two open, the drawer content extends below the window with no scroll. The CSS for the drawer shouldn't be the issue either. Anyone else experience this issue?
drawerPaper: {
position: 'relative',
width: 400,
overflowX: 'hidden',
overflowY: 'hidden',
'&:hover': {
overflowY: 'auto',
},
'&::-webkit-scrollbar': {
display: 'none',
},
},
<MuiThemeProvider theme={this.state.useDarkTheme ? darkTheme : lightTheme}>
<div className={classes.root}>
<AppBar position="absolute" className={classes.appBar}>
<Toolbar>
<div className={classes.flex}>
<Typography className={classes.headerTextColor} variant="title">
Title
</Typography>
{sealedBy}
</div>
<HeaderTools />
<Tooltip id="toggle-icon" title="Toggle light/dark theme">
<IconButton className={classes.headerTextColor} onClick={this.toggleTheme}>
<BrightnessMediumIcon />
</IconButton>
</Tooltip>
</Toolbar>
{spinner}
</AppBar>
<Drawer
variant="permanent"
classes={{
paper: classes.drawerPaper,
}}
>
<div className={classes.fixedWidth}>
<div className={classes.toolbar} />
<DocumentTools />
<SealingTools />
<AnnotationTools />
</div>
</Drawer>
<main className={classes.content}>
<div className={classes.toolbar} />
<DrawingCanvas />
</main>
</div>
</MuiThemeProvider>

You need to add height: 100% css property on some container components, and to styles to drawerPaper need add too.
I have setup here, its working, but probably depends on container components:
drawerPaper: {
width: 250,
overflow: "auto",
height: "100%",
[theme.breakpoints.up("md")]: {
overflow: "auto",
width: drawerWidth,
position: "relative",
height: "100%"
}
}

Related

Drawer MUI component persistent animation is super slow (sometimes) || React with MUI

I'm building this app, and, as you can see, we have a left drawer and a main component in the right direction.
And when I close that drawer, the main component will move a little bit in order to occupy the rest of the space.
But, when there's too much data in the table, the animation is going to be super slow and it doesn't look nice.
This is the code, here, we have that left drawer and the main component
{/* Side panel */}
<LeftDrawer />
{/* Main content */}
<SinAsignarHero />
This is only the left drawer, that has an open prop that will receive a boolean from a redux reducer
<Drawer
sx={{
width: 260,
flexShrink: 0,
background: '#fafafa',
'& .MuiDrawer-paper': {
width: 260,
background: '#fafafa',
border: '0px',
boxShadow: '0px 8px 7px #0000003D',
boxSizing: 'border-box',
top: 'auto',
zIndex: 1,
},
}}
open={isOpen}
variant="persistent"
anchor="left"
>
{appOptions &&
appOptions.menus.map(({ id, nombre, sub_menu }) => {
return (
<Fragment key={id}>
<AppOptions nombre={nombre} sub_menu={sub_menu && sub_menu} />
</Fragment>
);
})}
</Drawer>
And the main component that will execute the animation to occupy the whole space with the same boolean from redux
const MainContent = styled('main', { shouldForwardProp: (prop) => prop !== 'open' })<{
open?: boolean;
}>(({ theme, open }) => ({
background: '#fafafa',
height: '90.7vh',
overflowX: 'hidden',
flexGrow: 1,
padding: '40px 53px 0px 53px',
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
marginLeft: `-260px`,
...(open && {
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
marginLeft: 0,
}),
}));
return (
<MainContent open={isDrawerOpen}>
<SinAsignarTitle setCount={setCount} setHasMore={setHasMore} />
<TableContainer component={Paper} sx={{ maxHeight: '73vh', borderRadius: '5px' }}>
{scrollData.length ? (
<>
<InfiniteScroll
dataLength={scrollData.length}
next={getMoreData}
hasMore={hasMore}
loader={<div></div>}
scrollableTarget="TableContainer"
>
<TableContainer
component={Paper}
sx={{ maxHeight: '73vh', borderRadius: '5px' }}
id="TableContainer"
>
<Table stickyHeader sx={{ minWidth: 800 }}>
{/* Table header */}
<SinAsignarHead setCount={setCount} setHasMore={setHasMore} />
{/* Hero content */}
<SinAsignarContent recogidas={scrollData} />
</Table>
</TableContainer>
</InfiniteScroll>
</>
) : (
<NotFound />
)}
</TableContainer>
</MainContent>
So, when there isn't that much data in the table, it is not that slow, but, I want the animation to be fast always.
This is pretty much what I would love to accomplish
https://mui.com/components/drawers/#persistent-drawer
If you go to the sandbox of that example, and you add too much text, the animation is still fine, I don't know if maybe there are too many things going on when there's too much data so it's harder for my left drawer and main component to make the animations as fast as possible. Is there something I can do in order to fix this ?¿
Try virtualized table.
Virtualization helps with performance issues.
https://mui.com/components/tables/#virtualized-table

Grid properties on second child element of Accordion not working

Here I have defined the parent element display:"Grid" and with my child element have defined the gridColumnStart as below. It's working fine with the first element but not with the second child element. Below have attached my code.
return (
<Accordion
sx={{
display: "grid",
gridTemplateColumns: "1fr 2fr 1fr"
}}
>
<AccordionSummary
sx={{
gridColumnStart: "2",
gridColumnEnd: "4"
}}
expandIcon={<ExpandMoreIcon />}
aria-controls="panel1a-content"
id="panel1a-header"
>
<div>
<Typography variant="h1" sx={{ fontSize: "40px" }}>
{props.Title}
</Typography>
<Typography variant="subtitle1">{props.Description}</Typography>
<Button
size="small"
variant="outlined"
sx={{
width: "140px",
textAlign: "center",
marginTop: "10px",
color: "#2196F3",
borderColor: "#2196F3"
}}
>
More details
</Button>
</div>
</AccordionSummary>
<AccordionDetails
sx={{
gridColumnStart: "2",
gridColumnEnd: "3"
}}
>
{props.children}
</AccordionDetails>
</Accordion>
);
So here gridColumnStart and End working with AccordionSummary but not with AccordionDetails.
This is how it looks but I wanted the text to be in the middle. Not sure if the approach I'm heading towards is correct. Would appreciate if someone could help me.
This is a simplified Accordion definition:
<AccordionRoot>
<AccordionSummary />
<TransitionComponent>
<div>
<AccordionDetail />
</div>
</TransitionComponent>
</AccordionRoot>
The reason your AccordionDetail styles doesn't work is because it's applied to the children of the grid item instead of the grid item itself. To fix it, you need to set the grid properties directly in the child of the grid container which is TransitionComponent, if you inspect the element you can see the class name of the DOM elelment is MuiCollapse-root:
<Accordion
sx={{
display: "grid",
gridTemplateColumns: "1fr 2fr 1fr",
"& .MuiCollapse-root": {
gridColumnStart: "2",
gridColumnEnd: "3"
}
}}
>

SwipeableDrawer with button on swipeableArea MaterialUi

I'm trying to create a swipeableDrawer like that.
I want a button on my swipeableDrawer which I could click to dispatch an action.
But I can't click the button and swipe the swipeable drawer at the same time.
I want it.
<Global styles={{
'#swipeable .MuiPaper-root': {
height: `calc(78% - ${drawerBleeding}px)`,
overflow: 'visible',
},
}}/>
<SwipeableDrawer
id={'swipeable'}
anchor="bottom"
open={open}
onClose={toggleDrawer(false)}
onOpen={toggleDrawer(true)}
swipeAreaWidth={100}
disableSwipeToOpen={false}
ModalProps={{
keepMounted: true,
}}>
<>
<Card>
<CardContent>
<div className="row">
<div className="col-12">
{!ricalcolaPremioBTNEnabled ?
<Button className={buttonClasses.root}
onClick={() => history.push(INFO_PERSONALI_PATH)}>CONTINUA</Button> :
<Button className={buttonClasses.root}
disabled={!ricalcolaPremioBTNEnabled}
onClick={handleRicalcolaPremio}>RICALCOLA</Button>}
</div>
</div>
</CardContent>
</Card>
</>
<div style={{height: '100%', marginTop: '3vw', overflowY: 'auto', overflowX: 'hidden'}}>
<div className="row p-3">
Content of swipeable drawer
</div>
</div>
</SwipeableDrawer>
</Global>
How can I fix it?
Your button just probably inherits the pointer-events: none CSS from the <SwipeableDrawer/>.
You can override this CSS but you may encounter this issue

react-infinite-scroll not working inside Material UI Drawer

I am currently using react-infinite-scroll-component to paginate the comments from a certain post. There is a button in the comment section which shows a drawer that is supposed to show the paginated comments. The problem is, the react-infinite-scroll-component doesn't work, as it does not fire
the "next" function.
Here is the code:
<div>
<Drawer
anchor={"bottom"}
open={open}
onClose={handleDrawer}
style={{ height: "100vh", overflow: "auto", margin: "0px 4px" }}
>
<Toolbar>
<Typography variant="h4" style={{ flexGrow: 1 }}>
Comments
</Typography>
<IconButton onClick={handleDrawer}>
<CloseIcon />
</IconButton>
</Toolbar>
<Divider />
<br />
<CommentForm
comment={comment}
handleChange={handleChange}
handleSubmit={handleSubmit}
/>
<InfiniteScroll
dataLength={page}
next={More}
hasMore={hasMore}
loader={
<>
<br />
<CircularProgress />
</>
}
style={{
overflow: "hidden",
}}
scrollThreshold={1}
>
<CommentList comments={comments} id={session.id} />
</InfiniteScroll>
</Drawer>
</div>
The drawer is mostly similar to Youtube's comment drawer on the mobile app. Is there anything I am missing here?
Probably, the problem is the relation with Drawer and Infinite Scroll height. The height of Infinite Scroll is not reaching the right point to trigger next function. If you provide the demo in Codesandbox would be easier to understand.
Fixed height of infinite scroll container
<Box sx={{ height: 500 }}>
<InfiniteScroll
dataLength={page}
next={More}
hasMore={hasMore}
loader={
<>
<br />
<CircularProgress />
</>
}
style={{
overflow: "hidden",
}}
scrollThreshold={1}
>
<CommentList comments={comments} id={session.id} />
</InfiniteScroll>
</Box>

Conflict between components div background and actual background color

I have a listview within a div that changes the background color based on day / night mode. The background in the index.html is set to white and is set to stretch to 100% of the height which works for day mode. The issue is in night mode when I add elements to the listview it eventually starts showing a white bar at the bottom that increases in size for every element I add. I'm assuming the 100% height the background is set for isn't dynamic which is causing the issue when I add items to the listview. Any ideas on how to work around this?
How the div renders
nightMode is a state that changes the color between white and black for night mode.
return (
<div style={{height: '100%', padding: 50, flexDirection: 'column', backgroundColor: nightMode.background}}>
<div style = {{paddingTop: 40}}>
<List>
{todos.map((value, index) => {
return(
<ListItem key={todos.id}>
<ListItemIcon>
<Checkbox
edge="start"
checked={false}
onChange={() => removeTodo(index)}
tabIndex={-1}
disableRipple
/>
</ListItemIcon>
<ListItemText disableTypography style={{fontFamily: 'Work Sans', fontSize: 35, color: nightMode.listText}} primary={value.text}/>
</ListItem>
);
})}
<Snackbar open={open} autoHideDuration={6000} onClose={handleClose}>
<Alert onClose={handleClose} severity="success">
Task Finished!
</Alert>
</Snackbar>
</List>
</div>
Index.html that creates the background at 100% height
<style>
html,
body,
#root {
height: 100%;
}
body {
margin: 0;
background-color: #ffffff; /**This section is causing the issue**/
font-family: "Roboto", sans-serif;
}
I removed:
#root {
height: 100%;
}
and the color scaled for the whole page. Hopefully there are no issues with this solution.
why not update body background-color;
document.body.style.backgroundColor = nightMode.background;
return (<div></div>)

Resources