OmniOwl
OmniOwl

Reputation: 5709

Trouble with Grid Layout in React Material UI

I'm trying to achieve a specific layout using the Material UI Grid Component, but I just cannot for the life of me get it right.

I have a Dialog where I want the Layout to end up like this:

enter image description here

Where the blue box contains some information about a project, the green box will contain some sort of media and the yellow box will contain a descriptive text.

But currently, with this code, it ends up like this:

<Grid xl={12}>
    <Grid spacing={0} xs={2}>
        <Grid container direction="column">
            <Grid item xs={1}>
                { this.getGridItems("Platforms", data["platforms"].split(','), true) }
            </Grid>
            <Grid item xs={1}>
                { this.getGridItems("Engines", data["engines"].split(','), true) }
            </Grid>
            <Grid item xs={1}>
                { this.getGridItems("Frameworks", data["frameworks"].split(','), true) }
            </Grid>
            <Grid item xs={1}>
                { this.getGridItems("Languages", data["languages"].split(',')) }
            </Grid>
            <Grid item xs={1}>
                { this.getGridItems("Roles", data["roles"].split(',')) }
            </Grid>
        </Grid>
    </Grid>
    <Grid spacing={0} xl={10}>
        <Grid container>
            <Grid item xl={9}>
                <h1>Image Goes Here</h1>
            </Grid>
            <Grid item xl={3}>
                <h1>Description</h1>
                { data["description"] }
            </Grid>
        </Grid>
    </Grid>
</Grid>

enter image description here

I cannot quite figure out where I went wrong as I can't wrap my head around how the Grid layout works. Please help?

If it's necessary, here is the code for getGridItems():

getGridItems = (header, data, chips) => {
    let list = [];
    let fontSize = 11;
    list.push(
        <h5>{ header }</h5>
    );
    if(data.length > 0 && data[0] !== '') {
        if(chips !== undefined && true) {
            data.forEach(value => {
                let chipData = ChipConstants[value];
                list.push(
                    <Grid item xs>
                        <Chip
                            style={{ fontSize: fontSize}}
                            avatar={
                                <Avatar
                                    style={{ width: 24, height: 24 }}
                                    alt={chipData["avatar"]["alt"]}
                                    src={require("../img/avatars/"+chipData["avatar"]["img"])}
                                />}
                            label={chipData["avatar"]["alt"]}
                            className={styles.chip}
                        />
                    </Grid>
                );
            });
        } else {
            data.forEach(value => {
                list.push(
                    <Grid item xs style={{ fontSize: fontSize}}>
                        { value }
                    </Grid>
                );
            });
        }
    } else {
        list.push(
            <Grid item xs style={{ fontSize: fontSize}}>
                None
            </Grid>
        );
    }
    return list;
};

Upvotes: 1

Views: 4756

Answers (1)

Ryan Cogswell
Ryan Cogswell

Reputation: 81146

I'm not really seeing how your current code relates to what you want, so instead of trying to correct your current code, I'll just provide a starting point that provides the basic structure of what you want.

If you have specific questions about how the Grid in my code works, I'll elaborate as needed.

index.js

import React from "react";
import ReactDOM from "react-dom";
import CssBaseline from "@material-ui/core/CssBaseline";
import Button from "@material-ui/core/Button";
import MyDialog from "./MyDialog";

class App extends React.Component {
  state = {
    open: false
  };

  handleClickOpen = () => {
    this.setState({ open: true });
  };

  handleClose = () => {
    this.setState({ open: false });
  };
  render() {
    return (
      <>
        <CssBaseline />
        <Button variant="contained" onClick={this.handleClickOpen}>
          Open Dialog
        </Button>
        <MyDialog open={this.state.open} handleClose={this.handleClose} />
      </>
    );
  }
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

MyDialog.js

import React from "react";
import Grid from "@material-ui/core/Grid";
import Dialog from "@material-ui/core/Dialog";
import IconButton from "@material-ui/core/IconButton";
import CloseIcon from "@material-ui/icons/Close";
import { withStyles } from "@material-ui/core/styles";
const styles = {
  root: {
    height: "100%"
  },
  project: {
    backgroundColor: "lightblue",
    height: "100%"
  },
  right: {
    height: "100%"
  },
  media: {
    backgroundColor: "lightgreen",
    height: "70%"
  },
  desc: {
    backgroundColor: "yellow",
    height: "30%"
  }
};
const MyDialog = props => {
  return (
    <Dialog fullScreen open={props.open} onClose={props.handleClose}>
      <Grid container className={props.classes.root}>
        <Grid item xs={3} className={props.classes.project}>
          <IconButton
            color="inherit"
            onClick={props.handleClose}
            aria-label="Close"
          >
            <CloseIcon />
          </IconButton>
          Project
        </Grid>
        <Grid item xs={9}>
          <Grid container direction="column" className={props.classes.right}>
            <Grid item className={props.classes.media}>
              Media
            </Grid>
            <Grid item className={props.classes.desc}>
              Description
            </Grid>
          </Grid>
        </Grid>
      </Grid>
    </Dialog>
  );
};
export default withStyles(styles)(MyDialog);

Here it is in a CodeSandbox you can experiment with:

Edit 42qk97mpz9

Upvotes: 4

Related Questions