Can I add pseudo element objects to Material UI custom theme config? - javascript

In my file themeConfig.js I have declared some theme variables that I use throughout my app to style various components. I need to use the scrollbar -webkit to persist a scrollbar for certain components. The -webkit styles are long and bulky, so I want to be able to add them to my themeConfig.js file. These scrollbar styles are pseudo-elements and while I can assign them, I haven't been able to figure out how to use them in themeConfig.js.
themeConfig.js
const myTheme = createMuiTheme({
layout: {
header: 64,
sideNav: 45,
mainDivHeight: 250,
...
}
})
export default myTheme
ComponentExample.js
import { makeStyles } from '#material-ui/core'
const ComponentExample = () => {
const classes = useStyles()
return (
<div className={classes.mainDiv}>I'm a div</div>
)
}
const useStyles = makeStyles(theme => ({
mainDiv: {
height: theme.layout.mainDivHeight,
overflowY: 'scroll',
'&::-webkit-scrollbar': {
width: 8,
},
'&::-webkit-scrollbar-track': {
boxShadow: 'inset 0 0 6px rgba(0,0,0,0.00)',
webkitBoxShadow: 'inset 0 0 6px rgba(0,0,0,0.00)',
},
'&::-webkit-scrollbar-thumb': {
backgroundColor: 'rgba(0,0,0,.2)',
outline: '1px solid slategrey',
borderRadius: 7,
},
}
}))
export default ComponentExample
It would be great if I could stuff this into a variable in my theme file and apply it to a component:
overflowY: 'scroll',
'&::-webkit-scrollbar': {
width: 8,
},
'&::-webkit-scrollbar-track': {
boxShadow: 'inset 0 0 6px rgba(0,0,0,0.00)',
webkitBoxShadow: 'inset 0 0 6px rgba(0,0,0,0.00)',
},
'&::-webkit-scrollbar-thumb': {
backgroundColor: 'rgba(0,0,0,.2)',
outline: '1px solid slategrey',
borderRadius: 7,
},
But the way theme styles are declared in makeStyles, there is a 1:1 property assignment and I don't know how to gracefully apply a whole style object like that to a component. Any advice is greatly appreciated!

The styles declared in makeStyles are within an object and that object can be constructed in any of the ways JavaScript supports. The way I would handle this is to put the styles that you want to use within a single object in the theme (scrollbarStyles in my example below) and then use object spread syntax in the place where you want to use it within makeStyles.
Here is a working example:
import React from "react";
import {
createMuiTheme,
ThemeProvider,
makeStyles
} from "#material-ui/core/styles";
const myTheme = createMuiTheme({
layout: {
header: 64,
sideNav: 45,
mainDivHeight: 250,
scrollbarStyles: {
overflowY: "scroll",
"&::-webkit-scrollbar": {
width: 8
},
"&::-webkit-scrollbar-track": {
boxShadow: "inset 0 0 6px rgba(0,0,0,0.00)",
webkitBoxShadow: "inset 0 0 6px rgba(0,0,0,0.00)"
},
"&::-webkit-scrollbar-thumb": {
backgroundColor: "rgba(0,0,0,.2)",
outline: "1px solid slategrey",
borderRadius: 7
}
}
}
});
const useStyles = makeStyles(theme => ({
mainDiv: {
...theme.layout.scrollbarStyles,
height: theme.layout.mainDivHeight
}
}));
function ComponentExample() {
const classes = useStyles();
return (
<div className={classes.mainDiv}>
<div style={{ margin: "50px" }}>
I'm a div with enough content to make me scroll
</div>
<div style={{ margin: "50px" }}>
I'm a div with enough content to make me scroll
</div>
<div style={{ margin: "50px" }}>
I'm a div with enough content to make me scroll
</div>
<div style={{ margin: "50px" }}>
I'm a div with enough content to make me scroll
</div>
<div style={{ margin: "50px" }}>
I'm a div with enough content to make me scroll
</div>
</div>
);
}
export default function App() {
return (
<ThemeProvider theme={myTheme}>
<ComponentExample />
</ThemeProvider>
);
}

Related

Modify material-ui Paper boxShadow and background property

I am following their documentation from Here to modify default Paper component properties.
Here is my code.
import { styled } from '#mui/material/styles';
import { Modal, Button, TextField, Grid, Paper } from '#mui/material';
const Item:any = styled(Paper)(({theme}) => ({
// ...theme.typography.body2,
root: {
boxShadow: '1px 1px 1px 1px rgba(255,255,255,0.2)',
},
padding: theme.spacing(1),
textAlign: 'center',
color: theme.palette.text.secondary,
boxShadow: '1px 1px 1px 1px rgba(255,255,255,0.2)',
'& .MuiPaper-root': {
boxShadow: '1px 1px 1px 1px rgba(255,255,255,0.2)',
}
}));
const MyComponent = (props: any) => {
return (
<Grid container>
<Grid item xs={8}>
<Item elevation={1} square variant="outlined">xs=8</Item>
</Grid>
</Grid>
)
}
What am I doing wrong here?
You should change the value of boxShadow, current value is white and is diapered, change to black like below.
Try this code, I tested, worked for me:
const Item = styled(Paper)(({theme}) => ({
padding: theme.spacing(1),
textAlign: 'center',
color: '#000',
backgroundColor: 'pink',
boxShadow:'3px 3px 5px 3px rgb(0 0 0 ,0.2)'
}));

How to override padding inherited from "# .MuiAlert-icon"?

I need to override the padding inherited from "# .MuiAlert-icon". The inspector from chrome shows
.MuiAlert-icon {
display: flex;
opacity: 0.9;
padding: 7px 0;
font-size: 22px;
margin-right: 12px;
}
I'm trying to override it using the makeStyles from material UI. Here's the code i'm trying.
import Alert from "#material-ui/lab/Alert";
import Icon from "#material-ui/core/Icon";
import { makeStyles } from "#material-ui/core";
const useStyles = makeStyles({
icon: {
overflow: 'visible',
"& .MuiAlert-icon": {
padding: 'none',
}
},
outerTheme: {
}
});
interface idVerifyProps {
status: string;
}
const IDverify = ({ status }: idVerifyProps) => {
const classes = useStyles();
const svgIcon = (
<Icon className={classes.icon}>
<img alt="edit" src="../../../checkIcon.png" />
</Icon>
);
return (
<div >
<Alert severity="error" style={{ backgroundColor: "#E6FFE9",}} icon={svgIcon}>{status}</Alert>
</div>
);
};
export default IDverify;
I don't know where the 7px padding is coming from. I'm assuming its just a default setting for whatever reason with the Icon component. I just need to set the padding to zero.
you need to use classes={{ icon: <your_class> }}
alertIcon: {
padding: 0,
},
return (
<div >
<Alert
severity="error"
style={{ backgroundColor: "#E6FFE9",}}
icon={svgIcon}
classes={{ icon: classes.alertIcon }}
>
{status}
</Alert>
</div>
);

(React) Header and Footer are not at the same width produces a Scroll X - How to remove the axe X scroll and fix the width of the footer?

I have a basic landing page with Header , Content and Footer , however the Header is smaller than the Footer (its width) and as a result the page has a Scroll along the X axe.
Here is the Code
https://9mjhi.csb.app/
App.js
import React from 'react';
import './styles.css';
import Header from './components/Header';
import Footer from './components/Footer';
const App = () => {
return (
<>
<Header />
<Footer>
<span>©</span> Some Footer goes here
</Footer>
</>
);
}
export default App;
Footer :
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles((theme) => ({
style: {
backgroundColor: "#484848",
color: "white",
borderTop: "1px solid #E7E7E7",
textAlign: "center",
padding: "20px",
position: "fixed",
left: "0",
bottom: "0",
height: "60px",
width: "100vw"
},
phantom: {
display: "block",
padding: "20px",
height: "60px",
width: "100vw"
}
}));
function Footer({ children }) {
const classes = useStyles();
return (
<div>
<div className={classes.phantom} />
<div className={classes.style}>{children}</div>
</div>
);
}
export default Footer;
Header :
import React, { useState } from "react";
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles((theme) => ({
textField: {
marginLeft: theme.spacing(1),
marginRight: theme.spacing(1)
},
container: {
display: "flex",
width: "100vw",
justifyContent: "space-evenly",
alignItems: "flex-start",
backgroundColor: "lightblue"
},
formControl: {
margin: theme.spacing(1),
minWidth: 120
},
root: {
width: "100%"
// maxWidth: 500,
},
col: {
flexDirection: "column",
justifyContent: "center",
textAlign: "center",
color: "#fff",
height: "150px"
},
error: {
color: "red",
fontSize: "12px"
}
}));
const Header = () => {
const classes = useStyles();
return (
<>
<div className={classes.container}>
<div className={classes.col}>.... Something goes here</div>
</div>
</>
);
};
export default Header;
How can we fix the scroll on the X axe and the width of the footer (match it to the header) ?
Try using CSS property overflow!
https://www.w3schools.com/cssref/pr_pos_overflow.asp
https://www.w3schools.com/cssref/css3_pr_overflow-x.asp
https://www.w3schools.com/cssref/css3_pr_overflow-y.asp
.body {
overflow-x:hidden
}
edit: this css prop must wrap the whole page
makeStyles-style-7 has fixed positioning and left is zero but you have a 8px margin for your body that's why makeStyles-container-2
also has 8px margin left.
makeStyles-phantom-8 is overflowing because of the padding.
check box-sizing
Try this:
.body {
margin: 0px;
}
.makeStyles-phantom-8 {
box-sizing: border-box;
}

Unable to center material-ui GridList

I have a GridList which I am using to display Cards. These components are styled as follows:
card.js
const useStyles = makeStyles({
card: {
maxWidth: 240,
margin: 10
},
media: {
height: 100
}
})
grid.js
const useStyles = makeStyles(theme => ({
root: {
display: 'flex',
flexWrap: 'wrap',
justifyContent: 'space-around',
overflow: 'hidden'
},
gridList: {
width: '80%',
height: '100%'
}
}))
export default function CardGridList() {
const classes = useStyles()
return (
<div className={classes.root}>
<GridList className={classes.gridList} cols={4}>
<CardItem />
<CardItem />
<CardItem />
<CardItem />
<CardItem />
<CardItem />
<CardItem />
<CardItem />
</GridList>
</div>
)
}
and finally, container.js (which uses styled-components)
const ContainerWrapper = styled.div`
margin: 0 auto;
`
export default class Container extends React.Component {
render() {
return (
<ContainerWrapper>
<ThickSpace />
<CardGridList />
</ContainerWrapper>
)
}
}
However, no matter what combination of properties I try, I cannot get the cards to align in the center. I am always left with something like this:
Where the GridList is skewed off-center. I have gone through the material-ui documentation, looked at numerous explanations like this, but nothing is working. Please help!
You specify margin: 0 auto; on the top level container element, however you don't give the element any styles that make this auto margin take effect. You need to give a width gate for the element, so that way the auto margin will actually space on either side.
const ContainerWrapper = styled.div`
margin: 0 auto;
max-width: 1040px;
`
I got 1040 from the size of the card you defined. 240 width and 10 margin on each side means 20 px of space (first card 10px on right, second card 10px on the left). 260 * 4 = 1040 :)

Cant remove padding-bottom from Card Content in Material UI

When using the Card component from Material UI it seems like the CardContent has a padding-bottom of 24px that i cannot override with the following code. I can set paddingLeft, Right and Top using this method but for some reason paddingBottom won't work.
const styles = theme => ({
cardcontent: {
paddingLeft: 0,
paddingRight:0,
paddingTop:0,
paddingBottom: 0,
},
})
And then applying that style:
<CardContent className={classes.cardcontent}></CardContent>
this is what I see when previewing the elements in the browser:
.MuiCardContent-root-158:last-child {
padding-bottom: 24px;
}
.Component-cardcontent-153 {
padding-top: 0;
padding-left: 0;
padding-right: 0;
}
I can edit the pixels in the browser to 0. But I cannot figure out how to target MuiCardContent-root-158:last-child and override paddingBottom in my editor.
Here's the syntax for v3 and v4 (v5 example further down):
const styles = {
cardcontent: {
padding: 0,
"&:last-child": {
paddingBottom: 0
}
}
};
Here's a working example demonstrating this:
import React from "react";
import ReactDOM from "react-dom";
import CardContent from "#material-ui/core/CardContent";
import { withStyles } from "#material-ui/core/styles";
const styles = {
cardcontent: {
padding: 0,
"&:last-child": {
paddingBottom: 0
}
}
};
function App(props) {
return (
<div>
<CardContent
className={props.classes.cardcontent}
style={{ border: "1px solid black" }}
>
<div style={{ border: "1px solid red" }}>My Content</div>
</CardContent>
</div>
);
}
const StyledApp = withStyles(styles)(App);
const rootElement = document.getElementById("root");
ReactDOM.render(<StyledApp />, rootElement);
If you look at the CardContent source code, you can find how it defines the default styles:
export const styles = {
/* Styles applied to the root element. */
root: {
padding: 16,
'&:last-child': {
paddingBottom: 24,
},
},
};
This can be helpful in understanding how to override them.
For those using v5 of Material-UI, here's a v5 example (uses styled instead of withStyles):
import React from "react";
import ReactDOM from "react-dom";
import CardContent from "#mui/material/CardContent";
import { styled } from "#mui/material/styles";
const CardContentNoPadding = styled(CardContent)(`
padding: 0;
&:last-child {
padding-bottom: 0;
}
`);
function App(props) {
return (
<div>
<CardContentNoPadding style={{ border: "1px solid black" }}>
<div style={{ border: "1px solid red" }}>My Content</div>
</CardContentNoPadding>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
When setting the padding of Card Content to 0 via a theme override, the following works well:
overrides: {
MuiCardContent: {
root: {
padding: 0,
"&:last-child": {
paddingBottom: 0,
},
},
},
},
Here's the syntax for Mui.V5
<CardContent sx={{ p:0, '&:last-child': { pb: 0 }}}></CardContent>
add !important, it will override the root css

Categories

Resources