I have a CustomLayout component that renders itself recursively. It looks like this:
import "./styles.css";
import GridLayout from "react-grid-layout";
import React 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] = React.useState(true);
return (
<GridLayout
className="layout"
onDragStart={onDragStart}
onDragStop={onDragStop}
layout={layout}
cols={12}
rowHeight={80}
width={1200}
isDraggable={isDraggable}
>
{layout.map((item) => {
if (item.children) {
return (
<div
onClick={(e) => console.log(e.currentTarget.textContent[0])}
key={item.i}
style={{ background: "pink", border: "1px solid black" }}
>
<CustomLayout
layout={item.children}
width={item.w * 10}
onDragStart={() => {
setIsDraggable(false);
}}
onDragStop={() => {
setIsDraggable(true);
}}
/>
</div>
);
} else {
return (
<div
key={item.i}
style={{ background: "purple" }}
// onClick={(e) => console.log(item.i)}
>
{item.i}
</div>
);
}
})}
</GridLayout>
);
}
layout is an array that looks like this:
const layout = [
{ i: "b", x: 0, y: 0, w: 3, h: 2, isResizable: true },
{ i: "c", x: 4, y: 0, w: 1, h: 2, isResizable: true },
{
i: "k",
x: 0,
y: 0,
w: 6,
h: 5,
isResizable: true,
children: [
{ i: "e", x: 0, y: 0, w: 2, h: 2, isResizable: true },
{
i: "d",
x: 2,
y: 4,
w: 3,
h: 4,
isResizable: true,
children: [
{ i: "e", x: 0, y: 0, w: 1, h: 1, isResizable: true },
{ i: "d", x: 1, y: 0, w: 1, h: 2, isResizable: true }
]
}
]
}
];
That is, the root elements of the array are displayed on the main grid, and if the element has an array of children, then a child grid is created recursively.
The question is: the main grid is 1200 px wide (width={1200}
). I want to make the child grids have a width that is calculated by the formula width={item.w * 67}
, I tried to just pass this to the child grid, but this does not work and its width is inherited from the parent. How can this logic be implemented?
P.S. Link to CodeSandbox: https://codesandbox.io/s/sleepy-brahmagupta-727w42
What you can do is instead of putting hard coded 1200 width in CustomLayout element get it through prop so you can directly choose desired width for each recursive call.
here's code
CustomLayout Component
import "./styles.css";
import GridLayout from "react-grid-layout";
import React from "react";
import "react-grid-layout/css/styles.css";
import "react-resizable/css/styles.css";
export default function CustomLayout({
layout,
onDragStart,
onDragStop,
gridWidth
}) {
const [isDraggable, setIsDraggable] = React.useState(true);
return (
<GridLayout
className="layout"
onDragStart={onDragStart}
onDragStop={onDragStop}
layout={layout}
cols={12}
rowHeight={80}
width={gridWidth}
isDraggable={isDraggable}
>
{layout.map((item) => {
if (item.children) {
return (
<div
onClick={(e) => console.log(e.currentTarget.textContent[0])}
key={item.i}
style={{ background: "pink", border: "1px solid black" }}
>
<CustomLayout
layout={item.children}
onDragStart={() => {
setIsDraggable(false);
}}
gridWidth={item.w*67}
onDragStop={() => {
setIsDraggable(true);
}}
/>
</div>
);
} else {
return (
<div
key={item.i}
style={{ background: "purple" }}
// onClick={(e) => console.log(item.i)}
>
{item.i}
</div>
);
}
})}
</GridLayout>
);
}
App Component
import "./styles.css";
import React from "react";
import "react-grid-layout/css/styles.css";
import "react-resizable/css/styles.css";
import CustomLayout from "./gridLayout";
export default function App() {
const layout = [
{ i: "b", x: 0, y: 0, w: 3, h: 2, isResizable: true },
{ i: "c", x: 4, y: 0, w: 1, h: 2, isResizable: true },
{
i: "k",
x: 0,
y: 0,
w: 6,
h: 5,
isResizable: true,
children: [
{ i: "e", x: 0, y: 0, w: 2, h: 2, isResizable: true },
{
i: "d",
x: 2,
y: 4,
w: 3,
h: 4,
isResizable: true,
children: [
{ i: "e", x: 0, y: 0, w: 5, h: 1, isResizable: true },
{ i: "d", x: 1, y: 0, w: 1, h: 2, isResizable: true }
]
}
]
}
];
return <CustomLayout layout={layout} gridWidth={1200} />;
}