Search code examples
cssreactjstypescriptreact-grid-layout

React Grid Layout Overlapping Items


How do I create a react-grid-layout with 100 grid points width and specify the width of the grid items in this so that they don't overlap?

enter image description here

(Note: reducing number of columns fixes this overlap issue, but then I don't have the 100 point resolution in width for grid placement)

import Button, { ButtonProps } from '@mui/material/Button';
import GridLayout from 'react-grid-layout';

const TempButton = (props: ButtonProps) => (
  <Button
    {...props}
    variant="outlined"
    sx={{
      width: '100%',
      height: '100%',
      '&:hover': {
        backgroundColor: 'primary.dark',
        opacity: [0.9, 0.8, 0.7],
      },
    }}
  />
);

export const DeckLayout = (props: any) => {
  const layout = [
    {
      i: '1',
      x: 0,
      y: 0,
      w: 2,
      h: 2,
    },
    {
      i: '2',
      x: 2,
      y: 0,
      w: 1,
      h: 1,
    },
    {
      i: '3',
      x: 3,
      y: 0,
      w: 2,
      h: 3,
    },
  ];

  return (
    <GridLayout className="layout" layout={layout} cols={100} rowHeight={10} width={500}>
      <div key="1">
        <TempButton>1</TempButton>
      </div>
      <div key="2">
        <TempButton>2</TempButton>
      </div>
      <div key="3">
        <TempButton>3</TempButton>
      </div>
    </GridLayout>
  );
};

Here's a sandbox

Edit: seems like it might be something with the CSS? when I modify the stock example it performs as expected:

stock layout

here's the sandbox


Solution

  • UPDATE: As posted here, in order to get exact grid unit to pixel mapping, you need to set margin={[0,0]}

    Sandbox


    Yep, combination of css and thinking issues:

    • MaterialUI has a default minWidth of 64px for a button.

    • It seems the width of the columns are calculated as (Gridlayout width) / (Gridlayout cols). So in the above example the column width is 500px/ 100 cols = 5 px/col <<< minWidth = 64px

    Fix:

    width: 100%

    height: 100%

    <GridLayout
       className="layout"
       layout={layout}
       cols={100}
       rowHeight={10}
       width={6400}
    >
    

    enter image description here

    Full fix:

    import Button, { ButtonProps } from "@mui/material/Button";
    import GridLayout from "react-grid-layout";
    
    const TempButton = (props: ButtonProps) => (
      <Button
        {...props}
        variant="outlined"
        sx={{
          padding: 0,
          "&:hover": {
            backgroundColor: "primary.dark",
            opacity: [0.9, 0.8, 0.7]
          }
        }}
      />
    );
    
    export const DeckLayout = (props: any) => {
      const layout = [
        {
          i: "1",
          x: 0,
          y: 0,
          w: 2,
          h: 2
        },
        {
          i: "2",
          x: 2,
          y: 0,
          w: 1,
          h: 1
        },
        {
          i: "3",
          x: 3,
          y: 0,
          w: 2,
          h: 3
        }
      ];
    
      return (
        <GridLayout
          className="layout"
          layout={layout}
          cols={100}
          rowHeight={10}
          width={6400}
        >
          <div key="1">
            <TempButton>1</TempButton>
          </div>
          <div key="2">
            <TempButton>2</TempButton>
          </div>
          <div key="3">
            <TempButton>3</TempButton>
          </div>
        </GridLayout>
      );
    };
    

    and sandbox