javascriptreactjsreact-grid-layout

Moving elements in react-grid-layout


I'm creating a React project in which I use react-grid-layout. I'm creating multiple grids inside each other using recursion. The component looks like this:

import "./styles.css";
import GridLayout from "react-grid-layout";
import { useState } from "react";
import "react-grid-layout/css/styles.css";
import "react-resizable/css/styles.css";

export default function CustomLayout({ layout, onDragStart, onDragStop }) {
  const [isDraggable, setIsDraggable] = useState(true);

  return (
    <GridLayout
      className="layout"
      onDragStart={onDragStart}
      onDragStop={onDragStop}
      layout={layout}
      cols={24}
      rowHeight={80}
      width={1600}
      isDraggable={isDraggable}
    >
      {layout.map((item) => {
        if (item.children) {
          return (
            <div
              key={item.i}
              style={{ background: "pink", border: "1px solid black" }}
            >
              <CustomLayout
                layout={item.children}
                onDragStart={() => {
                  setIsDraggable(false);
                }}
                onDragStop={() => {
                  setIsDraggable(true);
                }}
              />
            </div>
          );
        } else {
          return (
            <div key={item.i} style={{ background: "purple" }}>
              {item.i}
            </div>
          );
        }
      })}
    </GridLayout>
  );
}

I was able to add the functionality to make elements on the child grids draggable (using [isDraggable, setIsDraggable]), but the problem is: if I move an element on the third level grid, I won't be able to move an element on the main grid until I move element on the second level grid. How can this behavior be corrected?
P.S. you can interact with my code here


Solution

  • Well, i figured it out:

    import "./styles.css";
    import GridLayout from "react-grid-layout";
    import { useState } from "react";
    import "react-grid-layout/css/styles.css";
    import "react-resizable/css/styles.css";
    
    export default function CustomLayout({ layout, onDragStart, onDragStop }) {
    
      return (
        <GridLayout
          className="layout"
          onDragStart={(a, b, c, d, e) => e.stopPropagation()}
          onDragStop={onDragStop}
          layout={layout}
          cols={24}
          rowHeight={80}
          width={1600}
        >
          {layout.map((item) => {
            if (item.children) {
              return (
                <div
                  key={item.i}
                  style={{ background: "pink", border: "1px solid black" }}
                >
                  <CustomLayout
                    layout={item.children}
                  />
                </div>
              );
            } else {
              return (
                <div key={item.i} style={{ background: "purple" }}>
                  {item.i}
                </div>
              );
            }
          })}
        </GridLayout>
      );
    }
    

    You have to add onDragStart={(a, b, c, d, e) => e.stopPropagation()} with e being fifth param, otherwise it won't work.
    Furthermore, you no longer need isDraggable state