How to style a Drawer using Material-UI v5 - reactjs

In Material-UI v4, the Drawer component could be styled this way:
<Drawer
variant="persistent"
classes={{paper: myClassNameHere}}
>
where myClassNameHere is produced by useStyles, which in turn is produced by makeStyles.
Migrating to v5's styling solution is proving tricky for this component in particular, because the styling needs to be applied to the inner Paper child component instead of to the main Drawer component itself.
Is it even possible to style Drawer at this point using the new solution?

You could pass your styled paper to the Drawer like so
import styled from "styled-components";
const MyPaper = styled.div`
//Put your styles here.
`;
const MyDrawer = () => {
return (
<Drawer
PaperProps={{ component : MyPaper }}
>
// drawer content
</Drawer>
)
}
Or you could actually pass an styled div to drawer (since paper itself displays flex, remember to pass flex:1 to fill out the space)
const MyPaper = styled.div`
flex:1;
`;
const MyDrawer = () => {
return (
<Drawer>
<MyPaper>
My Content
</MyPaper>
</Drawer>
)
}

There are many ways to do custom and inline style to MUI Drawer and one of which to do so is: to add PaperProps and put sx
<Drawer
PaperProps={{
sx: {
backgroundColor: "#05192D",
color: "blue",
fontSize: 50,
}
}}
>
...
</Drawer>
Hope this help, let's me know if your problem still persist!

Related

How to reference a styled component that is in a different dom

I like to add styling to a styled component that is in a different dom.
Like this Material-ui Menu component example, the dashboard button is highlighted gray, and the menu drop is highlighted light blue.
They are written in the same component file but they are in different dom.
I like to add styling to the Menu component from Button component.
Is that possible?
Demo sandbox: https://codesandbox.io/s/si8tr5?file=/demo.js
Menu material ui official doc: https://mui.com/material-ui/react-menu/#basic-menu
index.jsx
import * as React from 'react';
import MenuItem from '#mui/material/MenuItem';
import {DisplayMenu, DisplayButton} from './styles'
export default function BasicMenu() {
const [anchorEl, setAnchorEl] = React.useState(null);
const open = Boolean(anchorEl);
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
return (
<div>
<DisplayButton
id="basic-button"
aria-controls={open ? 'basic-menu' : undefined}
aria-haspopup="true"
aria-expanded={open ? 'true' : undefined}
onClick={handleClick}
>
Dashboard
</DisplayButton>
<DisplayMenu
id="basic-menu"
anchorEl={anchorEl}
open={open}
onClose={handleClose}
MenuListProps={{
'aria-labelledby': 'basic-button',
}}
>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem>
</DisplayMenu>
</div>
);
}
styles.js
import styled from 'styled-components';
import Button from '#mui/material/Button';
import Menu from '#mui/material/Menu';
export const DisplayMenu = styled(Menu)`
padding: 20px;
`;
DisplayMenu.displayName = 'DisplayMenu';
export const DisplayButton = styled(Button)`
margin: 10px;
${DisplayMenu}{
& .MuiPaper-root {
width: 300px;
}
}
`;
DisplayButton.displayName = 'DisplayButton';
I know just doing this below will work but this is just an example and the reality is more complicated.
I just made it simple to ask this question here.
export const DisplayMenu = styled(Menu)`
padding: 20px;
& .MuiPaper-root {
width: 300px;
}
`;
Your current code won't work because you are applying styles to descendent DisplayMenu components (DisplayButton is a sibling). I don't really think it makes sense to do this but you could select the sibling:
export const DisplayButton = styled(Button)`
margin: 10px;
& + ${DisplayMenu}{
& .MuiPaper-root {
width: 300px;
}
}
`;
I think styling DisplayMenu directly makes the most sense (your last approach).
However If this is a permutation of DisplayMenu when used with a button, I think you should consider making the wrapper div into a styled component since that allows you to apply contextual styles to the menu (change its style based on 'where' it was used):
const MenuButton = styled.div`
${DisplayMenu}{
& .MuiPaper-root {
width: 300px;
}
`
// And use this in your component
<MenuButton>
<DisplayButton {...} />
<DisplayMenu {...} />
</MenuButton>
This way we only add the width to DisplayMenu when used within the context of MenuButton

MUI: cannot apply background color to Paper component

I'm trying to style the MUI <Paper> component, however setting the background color isn't working. Following the online tutorials I'm applying the background-color CSS property to the root element of the Paper but the color remains white while other CSS properties - in this case padding and text-align work. Can someone please tell me what I am missing?
import React from 'react';
import { Paper, Typography } from '#mui/material';
import { makeStyles } from '#mui/styles';
import AccessAlarmIcon from '#mui/icons-material/AccessAlarm';
const useStyles = makeStyles({
root: {
textAlign: 'center',
padding: 15,
backgroundColor: '#37474f',
}
});
export default function Header() {
const classes = useStyles();
return(
<Paper outlined square className={classes.root}
>
<Typography variant="h2" component="h1">
Pomodoro Cl
<AccessAlarmIcon sx={{ fontSize: 45, color: 'red' }} />
ck
</Typography>
</Paper>
)
}
First of all your attribute outlined is incorrect, it should bevariant="outlined" as per the documentation.
For the background-color not working, you will need to add !important to the property so it takes precedence over mui's default styling.
Here's a working codesandbox for you: https://codesandbox.io/s/strange-smoke-y6yhv?file=/src/App.tsx

changing background color in drawer - MUI

i cannot change backgroundColor in Drawer component. I do as I found in other refs and it is not working for me. I created two classes
import { makeStyles } from '#mui/styles'
import { Drawer, Typography } from '#mui/material';
const drawerWidth = 240;
const useStyles = makeStyles({
drawer: {
width: drawerWidth,
},
drawerPaper: {
width: drawerWidth,
backgroundColor: "#fcba03"
},
});
export default function Sidebar() {
const classes=useStyles()
return (
<>
<Drawer
className={classes.drawer}
variant="permanent"
anchor="left"
classes={{paper: classes.drawerPaper},
{root:classes.drawerRoot}}
>
<div>
<Typography variant='h5'> Home </Typography>
</div>
</Drawer>
</>
)
}
thanks for answer!
You're not passing the classes in correct way. The classes prop expects an object with keys containing the class names from makeStyle hook. The correct syntax should be like
classes={{ paper: classes.drawerPaper, root: classes.drawerRoot }}
The updated code could be
import { makeStyles } from "#mui/styles";
import { Drawer, Typography } from "#mui/material";
const drawerWidth = 240;
const useStyles = makeStyles({
drawer: {
width: drawerWidth
},
drawerPaper: {
"&&": {
width: drawerWidth,
backgroundColor: "#fcba03"
}
}
});
export default function Sidebar() {
const classes = useStyles();
return (
<>
<Drawer
className={classes.drawer}
variant="permanent"
anchor="left"
classes={{ paper: classes.drawerPaper, root: classes.drawerRoot }}
>
<div>
<Typography variant="h5"> Home </Typography>
</div>
</Drawer>
</>
);
}
Note: && is added to increase the specificity of the applied styles to the paper.
Also, the support of makeStyles is going to be a legacy solution at sometime in future. If possible, you should probably look at the newer styling option provided in the mui v5.
Yes, this "improved" props like p, px, my, bgcolor etc are on the component listed above, but MUI expose for each of their components, a sx prop, that is an object that accept this kind of prop ! Also, I don't know if it could help, but you still can customize MUI components from the theme object if you want this style to be applied on all components occurences

Styles are not getting overriten in the styled component in react

I am new to the reac, Here I am using the material UI .
I have designed following styled component.
const StyledDefaultText = styled(Typography)<ISortBySelector>(({ fontSize }) => ({
fontSize: fontSize ? fontSize : '12px',
fontWeight: 'bold',
letterSpacing: fontSize ? '0.14px' : '0.09px',
color: '#000000'
}))
Now, Here I have added this styles still this component loads with the default styles which are there for the typography. It does not apply the styles which are there in the style component.
Can any one help me with this ?
The problem is, that your styles are loaded before the styles of the material-ui library (last one wins). You can fix it like this:
import { StylesProvider } from '#material-ui/core/styles';
<StylesProvider injectFirst>
{/* Your component tree.
Now, you can override Material-UI's styles. */}
</StylesProvider>
See: https://material-ui.com/guides/interoperability/#controlling-priority-%EF%B8%8F-3

How to hide/show elements at certain breakpoints with Material UI?

I want to show/hide elements on certain break points, like what I would do with Bootstraph or Zurb Foundation.
I see in the documentation here https://material-ui.com/system/display/#api we add
display={{ xs: 'block', md: 'none' }}
to our elements. I have done this, but I don't get any results - no hiding/showing elements, no errors, no compilation problems.
Would anyone know how this is done?
My code is:
import React from 'react'
import PropTypes from 'prop-types'
import makeStyles from '#material-ui/core/styles/makeStyles'
import Button from '#material-ui/core/Button'
const useStyles = makeStyles(styles)
const PhoneActionLink = ({ children, prefix, href, value, display, isFirst, ...other }) => {
const classes = useStyles()
return (
<Button
display={{ xs: 'block', md: 'none' }}
{...other}
>
{children}
</Button>
</div>
)
}
Here you go with a solution
import React from 'react'
import PropTypes from 'prop-types'
import makeStyles from '#material-ui/core/styles/makeStyles'
import Box from '#material-ui/core/Box'
import Button from '#material-ui/core/Button'
const useStyles = makeStyles(styles)
const PhoneActionLink = ({ children, prefix, href, value, display, isFirst, ...other }) => {
const classes = useStyles()
return (
<Box component="Button" display={{ xs: 'block', md: 'none' }} m={1}>
{children}
</Box>
)
}
Wrap the Button component within Box component.
The answer strictly depends on the version of MUI you're using.
The accepted answer should work for MUI v4 and prior versions, but didn't work for me (MUI v5).
I dug into the documentation From the official MUI website and found that the following code works for me:
<Box sx={{ display: { xs: 'block', md:'none' } }}>
{children}
</Box>
I'm guessing that the sx attribute allows you to modify some of the CSS properties based off specific breakpoints.
I'm no expert so I can't fully explain the solution, but I'm hoping that this solution helps another person out there.
Along with the other solutions, you could also use the component. Although it's deprecated now.

Resources