Unable to center material-ui GridList - javascript

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 :)

Related

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>
);

CSS padding is not applied to the div in react js

I have a div like this in react js which renders multiple divs and overflows :
<div
style={{
display: "flex",
padding: "1em 0.7em",
overflowX: "auto",
width: "100%",
direction: "rtl",
background: "#ef394e"
}}
>
{Array.from(Array(10).keys()).map((each, index) => (
<div
key={index}
className="swiper-slide"
style={{
background: "white",
borderRadius: "10px",
width: "270px",
margin: "0 .4em"
}}
>
<div style={{ padding: "2em 6em" }}>Hello</div>
</div>
))}
</div>
But for some reason the padding is applied to the containers right side but not the left side here are some pictures :
How can I apply padding to the array item's container div for both the left and right sides ?
It's because your div width bigger then the body,
and as result your body also have scroll.
Try add boxSizing: border-box to your parent component, and the body scroll will disappear.
const App = () => {
return (
<div
style={{
display: "flex",
padding: "1em 0em",
overflowX: "auto",
width: "100%",
direction: "rtl",
background: "#ef394e",
boxSizing: "border-box" // <--- this line
}}
>
...
</div>
);
};
It's the padding on the div. It's to little and the margin too.
import React from "react";
const App = () => {
return (
<div
style={{
display: "flex",
padding: "1em 0em",
overflowX: "auto",
width: "100%",
direction: "rtl",
background: "#ef394e"
}}
>
{Array.from(Array(10).keys()).map((each, index) => (
<div
key={index}
className="swiper-slide"
style={{
background: "white",
borderRadius: "10px",
width: "270px",
margin: "0 .4em"
}}
>
<div style={{ padding: "2em 6em" }}>Hello</div>
</div>
))}
</div>
);
};
export default App;

(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;
}

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

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>
);
}

Responsively center grid of cards on page and align cards left

I am having a grid of cards and I want to align the grid center wrt the page and align the cards left wrt to the grid, responsively adapting to different screen sizes.
Say if there are 10 cards, and the screen size is such that only 4 cards will fit on a row, then the first and second rows would have 4 cards each while the third row would have 2 cards aligned to the left. And the spacing on both sides of the grid will be evenly distributed.
I tried to wrap the Grid in a div, but it failed as the Grid was taking up 100% screen width. I tried setting the Grid width to min-content, but then there was only 1 card left on each row. If I set Grid align to center, the trailing cards on the last row would be centered.
EDIT: the following is the code I have. MyCard.tsx is the Card component while CardList.tsx is the div/Grid component.
MyCard.tsx
const useStyles = makeStyles((theme: Theme) =>
createStyles({
card: {
minWidth: 325,
marginBottom: '1vh',
marginLeft: '0.5vw',
marginRight: '0.5vw',
backgroundColor: theme.palette.background.paper,
color: theme.palette.secondary.contrastText,
boxShadow: '3px black',
},
media: {
height: 170,
},
cardContent: {
padding: '5px 15px',
height: 80,
},
})
const MyCard: React.FC<MyCardProp> = (props: MyCardProp) => {
const isDesktopOrLaptop = useMediaQuery({
query: '(min-device-width: 1224px)',
})
const theme = useTheme()
const classes = useStyles(theme
return (
<Card className={classes.card}>
<CardMedia
className={classes.media}
image={props.imageURL}
/>
<CardContent className={classes.cardContent}>
<Typography gutterBottom variant="h5" component="h2">
{props.title}
</Typography>
<Typography variant="body2" color="textSecondary" component="p">
{props.description}
</Typography>
</CardContent>
<CardActions
className={classes.bottomBar}
onClick={() => {
// Do something here.
}}
disableSpacing
>
<IconButton>
<Typography className={classes.bottomBarText} variant="h5">
{props.title}
</Typography>
<ArrowForwardIcon />
</IconButton>
</CardActions>
</Card>
)
}
CardList.tsx
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
display: "flex",
justifyContent: "center",
alignItems: "center",
},
grid: {
marginTop: 20,
overflowX: "auto",
flexGrow: 0,
},
greyText: {
color: "#666666",
ard
})
)
const CardList: React.FC<CardListProps> = (props: CardListProps) => {
const theme = useTheme()
const classes = useStyles(theme)
const cards = useSelector<RootState, Card[]>(
(state: RootState) => state.cards.data
)
return (
<div className={classes.root}>
<Grid
container
className={classes.grid}
wrap={"nowrap"}
direction={props.direction}
>
{cards.length ? (
cards.map((card, i) => {
return (
<MyCard
data={card.data}
/>
)
}) : null}
</div>
)
}
Thank you in advance for any advice.
I finally came across another post here that solved the problem.
The key is to add the following styling to the Grid container.
display: grid;
grid-template-columns: repeat(auto-fill, 100px);
grid-gap: 10px;
justify-content: center;
align-content: flex-start;
margin: 0 auto;
text-align: center;
margin-top: 10px;
In particular, grid-template-columns: repeat(auto-fill, 100px); did the trick where 100px should be the desired column width.

Categories

Resources