Search code examples
cssreactjsgridviewlayoutmaterial-ui

How to arrange Grid for following layout?


Overview

  • I'm attempting to arrange items on the MUI Grid.
  • There multiple rows and columns which are dynamic
  • Each row can have a fixed first column and any number of columns after that (Dynamic)
  • The dynamic part of columns are scrollable wrt each row

Requirement

  • Since first column of each row is fixed and other columns are scrollable for all rows _ I want to group these scrollable columns to a single group and implement a single scroll bar

Current enter image description here

Expected enter image description here

Current Implementation

    {<Grid container>
      {rowArray.map(x => (
        <>
          <Grid item>"Fixed Item"</Grid>
          {columnArray.map(x => (
            <Grid item>Dynamic items</Grid>
          ))}
        </>
      ))}
    </Grid>}

Solution

  • When splitting your space with Grids, always slice your screen to columns first, then divide each column to some rows.

    import { Box, Grid } from "@mui/material";
    
    const fixedItems = [
      "row 1's fixed item",
      "row 2's fixed item",
      "row 3's fixed item",
    ];
    const dynamicItems = [
      ["row 1 dynamic item 1"],
      [
        "row 2 dynamic item 1",
        "row 2 dynamic item 2",
        "row 2 dynamic item 3",
        "row 2 dynamic item 4",
        "row 2 dynamic item 5",
      ],
      ["row 3 dynamic item 1", "dynamic item 2"],
    ];
    
    const Item = (props) => {
      return (
        <Box
          sx={{
            display: "inline-block",
            backgroundColor: "cyan",
            borderRadius: 2,
            textAlign: "center",
            width: "300px",
            mx: 1,
          }}
        >
          {props.name}
        </Box>
      );
    };
    
    function Test() {
      return (
        <Box
          sx={{
            width: "90%",
            direction: "ltr",
            mx: "auto",
          }}
        >
          <Grid container spacing={1} sx={{ border: "1px solid red" }}>
            <Grid
              item
              xs={3}
              container
              spacing={1}
              sx={{
                textAlign: "center",
                border: "1px solid yellow",
              }}
            >
              {fixedItems.map((item, index) => (
                <Grid item xs={12} key={index}>
                  <Item name={item} />
                </Grid>
              ))}
            </Grid>
            <Grid
              item
              xs={9}
              container
              spacing={1}
              sx={{
                overflowX: "scroll",
                whiteSpace: "nowrap",
                border: "1px solid green",
              }}
            >
              {dynamicItems.map((item, index) => (
                <Grid item xs={12} key={index}>
                  {item.map((innerItem, innerIndex) => (
                    <Item name={innerItem} key={innerIndex} />
                  ))}
                </Grid>
              ))}
            </Grid>
          </Grid>
        </Box>
      );
    }
    export default Test;