I want to change the paragraph element with className="details" to an input field(editable) when user clicks on className="edit-icon" image within same grid container. How could I do that ?
import React from 'react';
import Grid from '#material-ui/core/Grid';
const Settings = () => {
return (
<div>
<Grid container>
<Grid item xs={4}>
<p className="details-label">NAME</p>
</Grid>
<Grid item xs={4}>
<p className="details">Lorem Ipsum</p>
</Grid>
<Grid item xs={4}>
<img className="edit-icon" src="icon_edit.png"/>
</Grid>
</Grid>
<Grid container>
<Grid item xs={4}>
<p className="details-label">Phone</p>
</Grid>
<Grid item xs={4}>
<p className="details">+123456789</p>
</Grid>
<Grid item xs={4}>
<img className="edit-icon" src="icon_edit.png"/>
</Grid>
</Grid>
</div>
);
};
export default Settings;
Here's one solution:
If you want each container to be editable on click independently, I would separate the code into multiple components:
import React, { useState } from 'react';
import Grid from '#material-ui/core/Grid';
const Container = ({ attr, val }) => {
const [isEditable, setIsEditable] = useState(false)
return (
<Grid container>
<Grid item xs={4}>
<p className="details-label">{attr}</p>
</Grid>
<Grid item xs={4}>
{isEditable ? <input type="text" defaultValue={val} /> : <p className="details">{val}</p>}
</Grid>
<Grid item xs={4}>
<img onClick={() => setIsEditable(!isEditable)} className="edit-icon"
src="icon_edit.png"/>
</Grid>
</Grid>
)
}
const Settings = (props) => {
return (
<div>
<p>Settings</p>
<Container attr="NAME" val="John Doe" />
<Container attr="Phone" val="+123456789"/>
</div>
);
};
export default Settings;
I'd suggest you do this declaratively now that you're using React.
Here's a Codesandbox if you want to play around.
Also note you must set your defaultValue to the same p value, for better UX. It works well for multiple grid containers.
import React from 'react';
import React, { useState } from 'react';
import Grid from '#material-ui/core/Grid';
const Settings = () => {
const [editable, setEditable] = useState(0);
return (
<div>
<Grid container>
<Grid item xs={4}>
<p className="details-label">NAME</p>
</Grid>
<Grid item xs={4}>
{ editable ? <input type="text" defaultValue="Lorem Ipsum"> :
<p className="details">Lorem Ipsum</p> }
</Grid>
<Grid item xs={4}>
<img className="edit-icon" src="icon_edit.png"/>
</Grid>
</Grid>
<Grid container>
<Grid item xs={4}>
<p className="details-label">Phone</p>
</Grid>
<Grid item xs={4}>
{ editable ? <input type="text" defaultValue="+123456789"> :
<p className="details">Lorem Ipsum</p> }
</Grid>
<Grid item xs={4}>
<img className="edit-icon" src="icon_edit.png"/>
</Grid>
</Grid>
</div>
);
};
export default Settings;
Piggybacking off of Pranav Rustagi's answer, it can be edited to keep the content of the paragraph, by passing it as the value attribute of the input element.
var imageCollection = document.querySelectorAll("[className='edit-icon']");
for (var i = 0; i < imageCollection.length; i++) {
imageCollection[i].onclick = function() {
let parent = this.parentElement.previousElementSibling;
let paragraphValue = parent.children[0].innerHTML;
parent.innerHTML = '';
let input = document.createElement("input");
input.type = "text";
input.value = paragraphValue;
parent.appendChild(input);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div>
<Grid container>
<Grid item xs={4}>
<p className="details-label">NAME</p>
</Grid>
<Grid item xs={4}>
<p className="details">Lorem Ipsum</p>
</Grid>
<Grid item xs={4}>
<img className="edit-icon" src="icon_edit.png"/>
</Grid>
</Grid>
<Grid container>
<Grid item xs={4}>
<p className="details-label">Phone</p>
</Grid>
<Grid item xs={4}>
<p className="details">+123456789</p>
</Grid>
<Grid item xs={4}>
<img className="edit-icon" src="icon_edit.png"/>
</Grid>
</Grid>
</div>
Related
I'm new to reactjs. I have created a dropdown for a company list and want to get values. I still couldn't be able to get values from the dropdown. I've tried several methods of retrieving data but not able to do that. can anyone help me to get values? Here is some of my code.
<Grid container spacing={3}>
<Grid item xs={12} sm={6}>
<SoftBox mb={1} ml={0.5} lineHeight={0} display="inline-block">
<SoftTypography
component="label"
variant="caption"
fontWeight="bold"
textTransform="capitalize">
Country
</SoftTypography>
</SoftBox>
<Select input={<SoftInput />} value={country} onChange={handleSetCountry}>
<MenuItem value="...">country</MenuItem>
<MenuItem value="10">Hello 10</MenuItem>
<MenuItem value="11">Hello 11</MenuItem>
<MenuItem value="12">Hello 12</MenuItem>
</Select>
</Grid>
Here is my whole code.
/**
=========================================================
* Soft UI Dashboard PRO React - v4.0.0
=========================================================
* Product Page: https://material-ui.com/store/items/soft-ui-pro-dashboard/
* Copyright 2022 Creative Tim (https://www.creative-tim.com)
Coded by www.creative-tim.com
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
import { useState } from "react";
// prop-type is a library for typechecking of props
import PropTypes from "prop-types";
// #mui material components
import Grid from "#mui/material/Grid";
import Select from "#mui/material/Select";
import MenuItem from "#mui/material/MenuItem";
// Soft UI Dashboard PRO React components
import Switch from "#mui/material/Switch";
import SoftBox from "components/SoftBox";
import SoftTypography from "components/SoftTypography";
import SoftInput from "components/SoftInput";
// NewUser page components
import FormField from "layouts/pages/new/new-company/components/FormField";
import { DateTimePicker } from "#material-ui/pickers";
import { distance } from "chroma-js";
function General({ formData }) {
const [country, setCountry] = useState("...");
const handleSetCountry = (event) => setCountry(event.target.value);
const { formField, values, errors, touched } = formData;
const { comNumber, address1, address2, city, state, postcode, additional, phone, phone1, fax, web } = formField;
const { comNumber: comNumberV, address1: address1V, address2: address2V, city: cityV, state: stateV, postcode: postcodeV, additional: additionalV,
phone: phoneV, phone1: phone1V, fax: faxV, web: webV} = values;
const [selectedDate, handleDateChange] = useState(new Date());
const [rememberMe, setRememberMe] = useState(false);
const handleSetRememberMe = () => setRememberMe(!rememberMe);
return (
<SoftBox>
<SoftTypography variant="h5" fontWeight="bold">
General
</SoftTypography>
<SoftBox mt={1.625}>
<Grid container spacing={3}>
<Grid item xs={12} sm={6}>
<FormField
type={comNumber.type}
label={comNumber.label}
name={comNumber.name}
value={comNumberV}
placeholder={comNumber.placeholder}
error={errors.comNumber && touched.comNumber}
success={comNumberV.length > 0 && !errors.comNumber}
/>
</Grid>
<Grid item xs={12} sm={6}>
<FormField
type={address1.type}
label={address1.label}
name={address1.name}
value={address1V}
placeholder={address1.placeholder}
/>
</Grid>
</Grid>
<Grid container spacing={3}>
<Grid item xs={12} sm={6}>
<FormField
type={address2.type}
label={address2.label}
name={address2.name}
value={address2V}
placeholder={address2.placeholder}
/></Grid>
<Grid item xs={12} sm={6}>
<FormField
type={city.type}
label={city.label}
name={city.name}
value={cityV}
placeholder={city.placeholder}
/>
{/* <FormField
type={city.type}
label={city.label}
name={city.name}
value={cityV}
placeholder={city.placeholder}
error={errors.city && touched.city}
success={cityV.length > 0 && !errors.city}
/> */}
</Grid>
</Grid>
{/* <Grid item xs={6} sm={3}>
<SoftBox mb={1} ml={0.5} lineHeight={0} display="inline-block">
<SoftTypography
component="label"
variant="caption"
fontWeight="bold"
textTransform="capitalize"
>
State
</SoftTypography>
</SoftBox>
<Select input={<SoftInput />} value={state} onChange={handleSetState}>
<MenuItem value="...">state</MenuItem>
<MenuItem value="10">Hello 10</MenuItem>
<MenuItem value="11">Hello 11</MenuItem>
<MenuItem value="12">Hello 12</MenuItem>
</Select>
</Grid>
<Grid item xs={6} sm={3}>
<FormField
type={zip.type}
label={zip.label}
name={zip.name}
value={zipV}
placeholder={zip.placeholder}
error={errors.zip && touched.zip}
success={zipV.length > 0 && !errors.zip}
/>
</Grid>
</Grid> */}
<Grid container spacing={3}>
<Grid item xs={12} sm={6}>
<FormField
type={state.type}
label={state.label}
name={state.name}
value={stateV}
placeholder={state.placeholder}
/>
</Grid>
<Grid item xs={12} sm={6}>
<FormField
type={postcode.type}
label={postcode.label}
name={postcode.name}
value={postcodeV}
placeholder={postcode.placeholder}
error={errors.postcode && touched.postcode}
success={postcodeV.length > 0 && !errors.postcode}
/>
</Grid>
</Grid>
<Grid container spacing={3}>
<Grid item xs={12} sm={6}>
<SoftBox mb={1} ml={0.5} lineHeight={0} display="inline-block">
<SoftTypography
component="label"
variant="caption"
fontWeight="bold"
textTransform="capitalize">
Country
</SoftTypography>
</SoftBox>
<Select input={<SoftInput />} value={country} onChange={handleSetCountry}>
<MenuItem value="...">country</MenuItem>
<MenuItem value="10">Hello 10</MenuItem>
<MenuItem value="11">Hello 11</MenuItem>
<MenuItem value="12">Hello 12</MenuItem>
</Select>
</Grid>
<Grid item xs={12} sm={6}>
<FormField
type={additional.type}
label={additional.label}
name={additional.name}
value={additionalV}
placeholder={additional.placeholder}
/>
</Grid>
</Grid>
<Grid container spacing={3}>
<Grid item xs={12} sm={6}>
<FormField
type={phone.type}
label={phone.label}
name={phone.name}
value={phoneV}
placeholder={phone.placeholder}
error={errors.phone && touched.phone}
success={phoneV.length > 0 && !errors.phone}
/>
</Grid>
<Grid item xs={12} sm={6}>
<FormField
type={phone1.type}
label={phone1.label}
name={phone1.name}
value={phone1V}
placeholder={phone1.placeholder}
error={errors.phone1 && touched.phone1}
success={phone1V.length > 0 && !errors.phone1}
/>
</Grid>
</Grid>
<Grid container spacing={3}>
<Grid item xs={12} sm={6}>
<FormField
type={fax.type}
label={fax.label}
name={fax.name}
value={faxV}
placeholder={fax.placeholder}
/>
</Grid>
<Grid item xs={12} sm={6}>
<FormField
type={web.type}
label={web.label}
name={web.name}
value={webV}
placeholder={web.placeholder}
/>
</Grid>
</Grid>
{/* <Grid container spacing={3}>
<Grid item xs={12} >
<FormField
type={distance.type}
label={distance.label}
name={distance.name}
value={distanceV}
placeholder={distance.placeholder}
/>
</Grid>
</Grid>
<SoftBox display="flex" alignItems="center">
<Switch checked={rememberMe} onChange={handleSetRememberMe} />
<SoftTypography
variant="button"
fontWeight="regular"
onClick={handleSetRememberMe}
sx={{ cursor: "pointer", userSelect: "none" }}
>
Company Opted Out From Surveys
</SoftTypography>
</SoftBox> */}
</SoftBox>
</SoftBox>
);
}
// typechecking props for Address
General.propTypes = {
formData: PropTypes.oneOfType([PropTypes.object, PropTypes.func]).isRequired,
};
export default General;
I need to get dropdown values. Can anyone help me to solve this?
First of all, you should really create a small example in Codesandbox and post it here...
Anyway,
As far as I can see you have two different dropdowns/select components (state and country).
You get no value from neither of them ? The Country one seems to be okay, but the State is missing its event handler (?).
What does a simple console.log output show?:
const handleSetCountry = (event) => {
console.log(event.target.value);
setCountry(event.target.value);
}
Also, try without the
input={<SoftInput />}
and see what happens
I have 3 components on my react page
PageHeader,SideMenu & FeatureList (which is made up of Display Cards) here are the components below:-
App.js
import './App.css';
import { Grid } from '#mui/material';
import SideMenu from './components/home/SideMenu';
import Features from './components/home/Features';
import PageHeader from './components/home/PageHeader';
function App() {
return (
<Grid container spacing={10}>
<Grid item xs={3}>
<PageHeader></PageHeader>
<SideMenu></SideMenu>
</Grid>
<Grid item xs={8}>
<Features></Features>
</Grid>
</Grid>
// <div>
// <PageHeader></PageHeader>
// <SideMenu></SideMenu>
// <Features></Features>
// </div>
);
}
export default App;
PageHeader.js
import * as React from 'react';
import AppBar from '#mui/material/AppBar';
import Box from '#mui/material/Box';
import Toolbar from '#mui/material/Toolbar';
import Typography from '#mui/material/Typography';
import Button from '#mui/material/Button';
import IconButton from '#mui/material/IconButton';
import MenuIcon from '#mui/icons-material/Menu';
import { Grid } from '#mui/material';
var LOGGED_IN = false
const getButtons = (LOGGED_IN) => {
if (LOGGED_IN) {
return <Grid container>
<Grid item xs={7}></Grid>
<Grid item xs={2} >
<Button color="inherit">
<Typography variant="h6" component="div">
Profile
</Typography>
</Button>
</Grid>
<Grid item xs={2} >
<Button color="inherit">
<Typography variant="h6" component="div">
Logout
</Typography>
</Button>
</Grid>
</Grid>
}
else
return <Grid container>
<Grid item xs={9}></Grid>
<Grid item xs={2}>
<Button color="inherit">
<Typography variant="h6" component="div">
Login
</Typography>
</Button>
</Grid>
</Grid>
}
const drawerWidth = 240
export default function PageHeader(props) {
return (
<Grid item container>
<Grid container>
<AppBar
sx={{
width: { sm: `calc(100% - ${drawerWidth}px)` },
ml: { sm: `${drawerWidth}px` },
}}
>
<Toolbar>
<Grid item xs={4}>
<Typography variant="h3" component="div">
Stonks!
</Typography>
</Grid>
{getButtons(LOGGED_IN)}
</Toolbar>
</AppBar>
</Grid>
</Grid>
);
}
SideMenu.js
import * as React from 'react';
import { Divider, Drawer, Grid, List, ListItem, ListItemIcon, ListItemText } from '#mui/material';
import { styled, useTheme } from '#mui/material/styles';
import BusinessIcon from '#mui/icons-material/Business';
import ShowChartIcon from '#mui/icons-material/ShowChart';
import AppsIcon from '#mui/icons-material/Apps';
import SupervisedUserCircleIcon from '#mui/icons-material/SupervisedUserCircle';
import InfoIcon from '#mui/icons-material/Info';
import CreateIcon from '#mui/icons-material/Create';
const DrawerHeader = styled('div')(({ theme }) => ({
...theme.mixins.toolbar,
}))
const drawerWidth = 240
export default function SideMenu(props) {
const theme = useTheme();
const [open, setOpen] = React.useState(true)
const handleDrawerOpen = () => {
setOpen(true)
}
const handleDrawerClose = () => {
setOpen(false)
}
return (
<Grid container spacing={2}>
<Grid item xs={12} container direction="column">
<Drawer
sx={{
width: drawerWidth,
flexShrink: 0,
boxSizing: 'border-box',
'& .MuiDrawer-paper': {
width: drawerWidth,
boxSizing: 'border-box',
},
}}
variant="persistent"
anchor="left"
open={true}
>
<Grid item xs={0} container display='flex' alignItems='center' justifyContent='flex-end'>
<DrawerHeader display='flex'>
</DrawerHeader>
</Grid>
<Grid item xs={0}>
<Divider />
</Grid>
<Grid item container direction='column'>
<List>
{
['Companies', 'Exchanges', 'Sectors', 'Users'].map((text) => (
<Grid item xs={12}>
<ListItem button key={text}>
<ListItemIcon>
{(() => {
switch (text) {
case 'Companies':
return <BusinessIcon />
case 'Exchanges':
return <ShowChartIcon />
case 'Sectors':
return <AppsIcon />
case 'Users':
return <SupervisedUserCircleIcon />
}
})()}
{/* <MenuIcon /> */}
</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
</Grid>
))
}
</List>
</Grid>
<Grid item>
<Divider />
</Grid>
<Grid item container direction='column'>
<List>
{
['About', 'Creators'].map((text) => (
<Grid item xs={12}>
<ListItem button key={text}>
<ListItemIcon>
{(() => {
switch (text) {
case 'About':
return <InfoIcon />
case 'Creators':
return <CreateIcon />
}
})()}
{/* <MenuIcon /> */}
</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
</Grid>
))
}
</List>
</Grid>
</Drawer>
</Grid>
</Grid>
);
}
Features.js
import { Grid } from "#mui/material";
import React from "react";
import DisplayCard from "./DisplayCard";
import company from '../../static/company.jpg'
import stock_exchange from '../../static/stock_exchange.jpg'
import sector from '../../static/sector.png'
import user from '../../static/user.png'
export default function Features(props) {
return (
<Grid container spacing={3}>
<Grid item md={3}>
<DisplayCard name="Companies" brief="View All the Registerd Companies and Click on them to explore each of them in
detail" image={company}></DisplayCard>
</Grid>
<Grid item md={3}>
<DisplayCard name="Stock Exchanges" brief="View All the Registerd Stock Exchanges and Click on them to explore each of them in
detail" image={stock_exchange}></DisplayCard>
</Grid>
<Grid item md={3}>
<DisplayCard name="Sectors" brief="View All the Registerd Sectors and Click on them to explore each of them in
detail" image={sector}></DisplayCard>
</Grid>
<Grid item md={3}>
<DisplayCard name="Users" brief="View All the Registerd Users and Click on them to explore each of them in
detail" image={user}></DisplayCard>
</Grid>
</Grid>
)
}
DispalyCard.js
import React from "react";
import Card from '#mui/material/Card';
import CardContent from '#mui/material/CardContent';
import CardMedia from '#mui/material/CardMedia';
import Typography from '#mui/material/Typography';
import { Button, CardActionArea, CardActions, Grid } from '#mui/material';
export default function DisplayCard(props) {
return (
<Grid container spacing={2}>
<Card sx={{ border: "groove", maxWidth: 300, maxHeight: 400 }}>
<CardActionArea >
<Grid item xs={12}>
<CardMedia
component='img'
height='140'
image={props.image}
width='inherit'
/>
</Grid>
<Grid item container>
<CardContent>
<Grid item xs={12}>
<Typography gutterBottom variant='h4' component='div'>
{props.name}
</Typography>
</Grid>
<Grid item xs={12}>
<Typography variant='body2' color='text.secondary'>
{props.brief}
</Typography>
</Grid>
</CardContent>
</Grid>
</CardActionArea>
<Grid>
<CardActions>
<Button size='small' color='primary'>
Click Here
</Button>
</CardActions>
</Grid>
</Card >
</Grid >
);
}
Currently my output is
As u can see the Feature Cards are getting overlapped by the Header
I want to make them not overlap but I have tried a lot of things but as I am a beginner in Grid & Flexbox im not able to make it correct
Any help will be appreciated.
It looks like you have your header set to position: fixed which removes it from the normal flow of the page. There may be a more elegant solution but so far the best solution for me has been adding the following to my CSS:
body {
padding-top: *height of header*;
}
I'm sending my react-hook-form field to another function component as a children. After pressing Submit Button, the field refreshes and the value inputed is deleted. What is the problem?
CodeSandBox example is here
My file App.js:
import React from "react";
import "./styles.css";
import { useForm } from "react-hook-form";
import { Box, Button, Grid, TextField } from "#material-ui/core";
export default function App() {
const { register, handleSubmit } = useForm();
function onSubmit(data) {
console.log(data);
}
function FieldComponent(props) {
const { title, children } = props;
return (
<Grid container alignItems="center">
<Grid item xs={3}>
<Box py={5}>
<div fontWeight="bold" fontSize="16">
{title}
</div>
</Box>
</Grid>
<Grid item xs={9}>
<Box py={5}>{children}</Box>
</Grid>
</Grid>
);
}
return (
<div className="App">
<Grid container>
<Grid item xs={12}>
<FieldComponent title="name">
<TextField variant="outlined" name="name" inputRef={register} />
</FieldComponent>
</Grid>
<Grid item xs={12}>
<Button variant="outlined" onClick={handleSubmit(onSubmit)}>
Submit
</Button>
</Grid>
</Grid>
</div>
);
}
It's always a good idea to move your sub-component into its own, otherwise, each re-render will mount and unmount your component.
function FieldComponent(props) {
const { title, children } = props;
return (
<Grid container alignItems="center">
<Grid item xs={3}>
<Box py={5}>
<div fontWeight="bold" fontSize="16">
{title}
</div>
</Box>
</Grid>
<Grid item xs={9}>
<Box py={5}>{children}</Box>
</Grid>
</Grid>
);
}
export default function App() {
const { register, handleSubmit } = useForm();
function onSubmit(data) {
console.log(data);
}
return (
<div className="App">
<Grid container>
<Grid item xs={12}>
<FieldComponent title="name">
<TextField variant="outlined" name="name" inputRef={register} />
</FieldComponent>
</Grid>
<Grid item xs={12}>
<Button variant="outlined" onClick={handleSubmit(onSubmit)}>
Submit
</Button>
</Grid>
</Grid>
</div>
);
}
https://codesandbox.io/s/agitated-darkness-leg7z?file=/src/App.js
I'm learning using Material UI Grid and I want to add a blank column (like padding from the right of the first element) on the right side of a column without using padding.
Consider the code :
import React from 'react';
import Grid from "#material-ui/core/Grid";
import Paper from "#material-ui/core/Paper";
import { makeStyles } from '#material-ui/core/styles';
const ExampleGridComponent = () => {
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1,
},
paper: {
padding: theme.spacing(2),
textAlign: 'center',
color: theme.palette.text.secondary,
},
}));
const classes = useStyles();
return (
<Grid container spacing={3}>
<Grid item xs={12}>
<Paper className={classes.paper}>xs=12</Paper>
</Grid>
<Grid item xs={12} sm={6}>
<Paper className={classes.paper}>xs=12 sm=6</Paper>
</Grid>
<Grid item xs={12} sm={6}>
<Paper className={classes.paper}>xs=12 sm=6</Paper>
</Grid>
<Grid item xs={6} sm={3}>
<Paper className={classes.paper}>xs=6 sm=3</Paper>
</Grid>
<Grid item xs={6} sm={3}>
<Paper className={classes.paper}>xs=6 sm=3</Paper>
</Grid>
<Grid item xs={6} sm={3}>
<Paper className={classes.paper}>xs=6 sm=3</Paper>
</Grid>
<Grid item xs={6} sm={3}>
<Paper className={classes.paper}>xs=6 sm=3</Paper>
</Grid>
</Grid>)
}
export default ExampleGridComponent;
It look like this :
How can we put a blank column on the right of all the elements (brown color in the picture) ?
Wrap your item grids with row and column.
<Grid container spacing={3}>
<Grid item xs={9}>
<Grid container>
<Grid item xs={12}>
<Paper className={classes.paper}>xs=12</Paper>
</Grid>
<Grid item xs={12} sm={6}>
<Paper className={classes.paper}>xs=12 sm=6</Paper>
</Grid>
<Grid item xs={12} sm={6}>
<Paper className={classes.paper}>xs=12 sm=6</Paper>
</Grid>
<Grid item xs={6} sm={3}>
<Paper className={classes.paper}>xs=6 sm=3</Paper>
</Grid>
<Grid item xs={6} sm={3}>
<Paper className={classes.paper}>xs=6 sm=3</Paper>
</Grid>
<Grid item xs={6} sm={3}>
<Paper className={classes.paper}>xs=6 sm=3</Paper>
</Grid>
<Grid item xs={6} sm={3}>
<Paper className={classes.paper}>xs=6 sm=3</Paper>
</Grid>
</Grid>
</Grid>
<Grid item xs={3}>
</Grid>
</Grid>
Refer to:
Document of Material UI Grid
Nested grid items: issue
import React from "react";
import "./styles.css";
import Grid from "#material-ui/core/Grid";
import Paper from "#material-ui/core/Paper";
import { makeStyles } from "#material-ui/core/styles";
const App = () => {
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1
},
paper: {
padding: theme.spacing(2),
textAlign: "center",
color: theme.palette.text.secondary
}
}));
const classes = useStyles();
return (
<>
<Grid container>
<Grid item xs={8}>
<Grid container spacing={3}>
<Grid item xs={12}>
<Paper className={classes.paper}>xs=12</Paper>
</Grid>
<Grid item xs={12} sm={6}>
<Paper className={classes.paper}>xs=12 sm=6</Paper>
</Grid>
<Grid item xs={12} sm={6}>
<Paper className={classes.paper}>xs=12 sm=6</Paper>
</Grid>
<Grid item xs={6} sm={3}>
<Paper className={classes.paper}>xs=6 sm=3</Paper>
</Grid>
<Grid item xs={6} sm={3}>
<Paper className={classes.paper}>xs=6 sm=3</Paper>
</Grid>
<Grid item xs={6} sm={3}>
<Paper className={classes.paper}>xs=6 sm=3</Paper>
</Grid>
<Grid item xs={6} sm={3}>
<Paper className={classes.paper}>xs=6 sm=3</Paper>
</Grid>
</Grid>
</Grid>
<Grid item xs={4}>
<Grid item xs={12}>
</Grid>
</Grid>
</Grid>
</>
);
};
export default App;
I'm trying to achieve a two column layout, both of them equal height and each taking half of the screen. Picture explains it better, here is one.
The not working code is as follows:
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import CssBaseline from "#material-ui/core/CssBaseline";
import Grid from "#material-ui/core/Grid";
import Paper from "#material-ui/core/Paper";
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1,
alignItems: "stretch"
},
column: {
flexDirection: "column"
},
paper: {
padding: theme.spacing(2),
textAlign: "center",
color: theme.palette.text.secondary
}
}));
export default props => {
const classes = useStyles();
return (
<>
<CssBaseline />
<Grid container className={classes.root}>
{/* COLUMN ONE */}
<Grid container item className={classes.column}>
<Grid item xs={6}>
<Paper className={classes.paper}>1: xs=6</Paper>
</Grid>
<Grid item xs={6}>
<Paper className={classes.paper}>1: xs=6</Paper>
</Grid>
<Grid container item>
<Grid item xs={3}>
<Paper className={classes.paper}>1: xs=3 left</Paper>
</Grid>
<Grid item xs={3}>
<Paper className={classes.paper}>1: xs=3 right</Paper>
</Grid>
</Grid>
</Grid>
{/* COLUMN TWO */}
<Grid container item className={classes.column}>
<Grid item xs={6}>
<Paper className={classes.paper}>2: xs=6</Paper>
</Grid>
<Grid item xs={6}>
<Paper className={classes.paper}>2: xs=6</Paper>
</Grid>
</Grid>
</Grid>
</>
);
};
Obligatory codesandbox is here.
Could someone explain me what am I doing wrong here?
There's a bug with Material UI way of laying out nested grid containers, here. The workaround - found by #londonoliver - is to nest containers inside the grid items:
<Grid container direction="row">
<Grid item>
<Grid container direction="column">
<Grid item>1</Grid>
<Grid item>2</Grid>
</Grid>
</Grid>
<Grid item>
<Grid container direction="column">
<Grid item>3</Grid>
<Grid item>4</Grid>
</Grid>
</Grid>
</Grid>