Fix TextField Alignment in React - css

I need to fix a simple problem in the styling of my React App. I wonder why the CVC TextField in my react app doesn't align to the Card Number.
Pls check this codesandbox link
CLICK HERE
<div style={{ display: 'flex' }}>
<TextField
variant="outlined"
label="Expiration Month"
name="expiryMonth"
type="text"
value={values.expiryMonth}
onChange={handleChange}
onBlur={handleBlur}
helperText={touched.expiryMonth ? errors.expiryMonth : ''}
error={touched.expiryMonth && Boolean(errors.expiryMonth)}
fullWidth
className={classes.margin}
style={{ flex: 1 }}
/>
<TextField
variant="outlined"
label="Expiration Year"
name="expiryYear"
type="text"
value={values.expiryYear}
onChange={handleChange}
onBlur={handleBlur}
helperText={touched.expiryYear ? errors.expiryYear : ''}
error={touched.expiryYear && Boolean(errors.expiryYear)}
fullWidth
className={classes.margin}
style={{ flex: 1 }}
/>
<TextField
variant="outlined"
label="CVC"
name="cvc"
type="number"
value={values.cvc}
onChange={handleChange}
onBlur={handleBlur}
helperText={touched.cvc ? errors.cvc : ''}
error={touched.cvc && Boolean(errors.cvc)}
fullWidth
className={classes.margin}
style={{ flex: 1 }}
/>
</div>;

By default, each TextField has a margin of 8px due to which, the flex row of three text field(month, year and CVV) has 8 px gap with their children.
there are multiple fixes, the first one is
<div style={{ display: "flex", width="calc(100% + 16px)" }}>
This will force the row to take 16px more than 100% because we have 8px margin on TextField on both side so it will help us to overcome 8px margin on both side
another solution would be to add a negative margin of 16px on right side
<div style={{ display: "flex", margin: "-16px" }}>
I would recommend you to use Grid component from MUI because it will also help you to achieve responsive design, below is the code with Grid as a container, to make it responsive you will need to wrap each child component TextField in Grid item component
<Grid
style={{ display: "flex", margin: 0 }}
container
direction="row"
justify="center"
alignItems="center"
spacing={2}
>
Sand-box-project-1
Sand-box-project-2

Related

How to make a grid column the same height as the element above it and pushed left

I'm using material UI and I have a grid sitting on top of a Paper element. The first column in the grid is a text input field that I'd to be the same height as the paper and I'd like it pushed left so that it shares the left border with the paper element but I'm not sure how to achieve this affect, I've tried setting 0 margins, changing the position, and messing with the height and width to no affect.
Code pen: https://codesandbox.io/s/laughing-ardinghelli-7cutft?file=/src/App.js
code
import * as React from "react";
import { styled } from "#mui/material/styles";
import Grid from "#mui/material/Grid";
import Paper from "#mui/material/Paper";
import { TextField } from "#mui/material";
export default function ComplexGrid() {
return (
<Paper
sx={{
p: 2,
margin: "auto",
maxWidth: 500,
flexGrow: 1,
backgroundColor: "#1A2027"
}}
>
<Grid container spacing={2}>
<Grid item xs={4} sx={{ alignSelf: "flex-start" }}>
<TextField
id="outlined-basic"
label=""
variant="outlined"
sx={{
backgroundColor: "white",
padding: "0",
flex: 0
}}
/>
</Grid>
<Grid sx={{ alignSelf: "flex-end", color: "white" }} item xs={6}>
<span>test v. test</span>
</Grid>
</Grid>
</Paper>
);
}
edit: I found that if I disable padding-left for all the classes MuiGrid-root.Muigrid-item in inspect element it will push it to the left, but I only want to disable the padding for this first grid item. Overriding it with sx={{paddingLeft: 0}} doesn't seem to do anything
edit2: setting sx={{paddingLeft: "0 !important", paddingTop: "0 !important"}} has gotten the position I wanted, now I just want it to stretch to the size of the paper
The padding: 2 on my paper was the issue, removing this gave me a text input field the same size as my paper

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

Material UI how to justify content inside FormControlLabel

I'm trying to align the label and the radio button inside a FormControlLabel component so that the label consumes the same width regardless of the text inside of it. Here's what it currently looks like:
Here's the code I have:
<RadioGroup row>
<FormControl>
<FormControlLabel
value={first_column_day}
control={
<Radio
value={first_column_day}
/>
}
label={<Typography variant={"subtitle2"}>{first_column_day}</Typography>}
labelPlacement="start"
/>
</FormControl>
<FormControl>
<FormControlLabel
value={second_column_day}
control={
<Radio
value={second_column_day}
/>
}
label={<Typography variant={"subtitle2"}>{second_column_day}</Typography>}
labelPlacement="start"
/>
</FormControl>
</RadioGroup>
I tried adding justifyContent for FormControl:
<FormControl style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between' }}>
I also tried wrapping Typography in a div:
<div><Typography variant={"subtitle2"}>{first_column_day}</Typography></div>
But those didn't work. So far the only thing that worked is adding a fixed width to the Typography like so:
<Typography style={{ width: 75 }} variant={"subtitle2"}>{first_column_day}</Typography>
But I don't really like doing that because it's not responsive. Setting the width to 100% doesn't work either.
You can add min-width to FormControlLabel component if you need alignment like below without losing responsiveness -
Working Sandbox here - https://codesandbox.io/s/material-demo-3u8i2?file=/demo.js

MUI Grid item not working with overflowY: "auto"

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".

How to center a button in Material-UI

I couldn't figure out how to center buttons in Material-UI. This is the code I have:
function BigCard(props) {
const { classes } = props;
return (
<div>
<Card className={classes.card}>
<CardContent>
<Typography variant="display1" className={classes.title}>
Start Funding!
</Typography>
</CardContent>
<CardActions >
<Button size="small" color="primary" className={classes.actions}>
Share
</Button>
<Button size="small" color="primary">
Learn More
</Button>
</CardActions>
</Card>
</div>
);
How can I center my button?
You can use Box element
<Box textAlign='center'>
<Button variant='contained'>
My button
</Button>
</Box>
you could use the override with classes in the material ui doc,
FIRST WAY
You can do something like :
//Add your justify css in your styles const
const styles = {
...
root: {
justifyContent: 'center'
}
};
And use the classes props to add this to your CardActions component :
<CardActions classes={{root: classes.root}}>
SECOND WAY (easier)
OR You can use the style directly on your component, but i advise you to train how to use classes if you're working alot with material-ui
Just do something like :
<CardActions style={{justifyContent: 'center'}}>
For use cases that avoid defining css
<Grid container justify="center">
{props.children}
</Grid>
Here is how I did it with Material - UI
import {Typography, Button} from '#material-ui/core';
<Typography align='center'>
<Button
color='primary'
size='large'
type='submit'
variant='contained'
>
Sign Up
</Button>
</Typography>
Quick and dirty:
<Button style={{margin: '0 auto', display: "flex"}}>
NEXT
</Button>
From MUI v5, you can apply the custom styles using the sx props. Because CardActions layout is already flex, you only need to set its justify-content to center.
Using sx instead of inline styles like the other answer help reduce the CSS specificity, and make it easier to override the CSS in the future
<CardActions sx={{ justifyContent: "center" }}>
<Button size="small">Learn More</Button>
</CardActions>
Live Demo
What I tried is below and is also shown in official videos of material ui on youtube.
<Grid item xs={12} sm={12} md={4} lg={4}
style={{
textAlign:'center' // this does the magic
}}
>
<Button>
NEXT
</Button>
</Grid>
Thanks and best wishes
You have to use two properties: display and justify-content
<CardActions display='flex' justifyContent='center'>
This will centre your button horizontally
<Button
size="medium"
variant="contained"
color="primary"
style={{
display: "flex",
flexDirection: "row",
justifyContent:"center",
backgroundColor: purple[500],
'&:hover': {
backgroundColor: purple[700],
},
}}
>
Get Hired
</Button>
The easiest way is to use a Box wrapping around the button
<Box
sx={{
display: 'flex',
flexDirection: { xs: 'column', md: 'row' },
alignItems: 'center',
justifyContent: 'center',
}}
>
<Button>Click me</Button>
</Box>
This may sound counter-intuitive but what worked for my case (slightly different than yours) was to use the fullWidth attribute in the Button element.
Here is my scenario (MUI v5):
<Grid container alignItems={'center'} >
<Grid item>
<Button fullWidth variant='contained' >Click Me!</Button>
</Grid>
</Grid>
wrap element in this center
.center{
width: 100%;
height: 100%;
display: flex;
justify-content: center;
}

Resources