I just learned how to create a split-screen (2 screens) component that uses "display: flex" on the parent-container and "flex: 1" on its children to produce a left-component and a right-component. Now I'm trying to create a split-screen (5 screens) component that uses "display: grid" to produce 3 columns and two rows with a left sidebar that takes up the first column and both rows and the four other screens each take up 1 column & 1 row (a top-left screen, a top-right screen, a bottom-left screen and a bottom-right screen). I'm able to display the grid with the code I have so far but I can only get the first row, first column to display any text (image below). I'm using React Router and styled-components which shouldn't be part of the problem but maybe it will help provide you with some context. There are three files: App.js (the starting point of my app's code & imports Home.js), Home.js (imports Splitscreen.js) and SplitScreen.js (contains the problematic component). I realize that I could have achieved the desired result with flexbox but I thought I would have more control using Grid. Any help would be greatly appreciated.
the screenshot of the grid created by my code:
App.js code below:
import React from "react";
import { Routes, Route } from "react-router-dom";
import styled, { createGlobalStyle } from "styled-components";
import {NoMatch} from "./pages/NoMatch";
import {Dashboard} from "./pages/Dashboard";
import {About} from "./pages/About";
import {Home} from "./pages/Home";
import { LayoutNavigation } from "./components/LayoutNavigation";
export default function App() {
return (
<>
<Routes>
<Route path="/" element={<LayoutNavigation />}>
<Route index element={<Home />} />
<Route path="about" element={<About />} />
<Route path="dashboard" element={<Dashboard />} />
<Route path="*" element={<NoMatch />} />
</Route>
</Routes>
</>
);
}
Home.js code below
import { SplitScreenQuad } from "../components/SplitScreen";
import styled from "styled-components";
const Sidebar = () => {
return (
<div>
<h1 style={{ backgroundColor: "lightblue" }}>Sidebar</h1>
</div>
);
};
const UserInputFields = () => {
<div>
<h1 style={{ backgroundColor: "lightgreen" }}>UserInputFields</h1>;
</div>;
};
const UserData = () => {
<div>
<h1 style={{ backgroundColor: "lightgreen" }}>UserData</h1>;
</div>;
};
const TableResults = () => {
<div>
<h1 style={{ backgroundColor: "pink" }}>TableResults</h1>;
</div>;
};
const ImageResults = () => {
<div>
<h1 style={{ backgroundColor: "yellow" }}>ImageResults</h1>;
</div>;
};
export const Home = () => {
return (
<>
<h1>HOME</h1>
<SplitScreenQuad
sidebar={Sidebar}
topleft={UserInputFields}
topright={UserData}
bottomleft={TableResults}
bottomright={ImageResults}
/>
</>
);
};
/*Filename: SplitScreen.js*/
import React from "react";
import styled from "styled-components";
export const SplitScreenQuad = ({
sidebar: Sidebar,
topleft: Topleft,
topright: Topright,
bottomleft: Bottomleft,
bottomright: Bottomright,
}) => {
return (
<>
<ContainerQuad>
<PaneQuad>
<Sidebar id="sidebar" />
</PaneQuad>
<PaneQuad>
<Topleft id="topleft" />
</PaneQuad>
<PaneQuad>
<Topright id="topright" />
</PaneQuad>
<PaneQuad>
<Bottomleft id="bottomleft" />
</PaneQuad>
<PaneQuad>
<Bottomright id="bottomright" />
</PaneQuad>
</ContainerQuad>
</>
);
};
const ContainerQuad = styled.div`
display: grid;
grid-template-columns: auto 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: 1rem;
background-color: lightcoral;
#sidebar {
grid-column: 1;
grid-row: 1 / span 2;
}
#topleft {
grid-column: 2;
grid-row: 1;
}
#topright {
grid-column: 3;
grid-row: 1;
}
#bottomleft {
grid-column: 2;
grid-row: 2;
}
#bottomright {
grid-column: 3;
grid-row: 2;
}
`;
const PaneQuad = styled.div``;
You're missing the return in several of your components. Additionally, you're trying to set css properties using ids that aren't being passed to the proper element.
// make sure you're returning something in these components:
const Sidebar = () => (
<div>
<h1 style={{ backgroundColor: "lightblue" }}>Sidebar</h1>
</div>
);
const UserInputFields = () => (
<div>
<h1 style={{ backgroundColor: "lightgreen" }}>UserInputFields</h1>;
</div>
);
const UserData = () => (
<div>
<h1 style={{ backgroundColor: "lightgreen" }}>UserData</h1>;
</div>
);
const TableResults = () => (
<div>
<h1 style={{ backgroundColor: "pink" }}>TableResults</h1>;
</div>
);
const ImageResults = () => (
<div>
<h1 style={{ backgroundColor: "yellow" }}>ImageResults</h1>;
</div>
);
As for the placement of the elements in the grid, no ids are needed. Just create a wrapper for the sidebar that sets its grid-row: 1 / span 2
. That's all that is needed. You don't need to specifically set the other elements in the grid. The remaining ones will auto-flow into the quad portion of the grid.
const SplitScreenQuad = ({
sidebar: Sidebar,
topleft: Topleft,
topright: Topright,
bottomleft: Bottomleft,
bottomright: Bottomright
}) => {
return (
<>
<ContainerQuad>
<SidebarPane>
<Sidebar />
</SidebarPane>
<PaneQuad>
<Topleft />
</PaneQuad>
<PaneQuad>
<Topright />
</PaneQuad>
<PaneQuad>
<Bottomleft />
</PaneQuad>
<PaneQuad>
<Bottomright />
</PaneQuad>
</ContainerQuad>
</>
);
};
// You can simplify here
const ContainerQuad = styled.div`
display: grid;
grid-template-columns: auto 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: 1rem;
background-color: lightcoral;
`;
// Only the Sidebar needs special treatment:
const SidebarPane = styled.div`
grid-row: 1 / span 2;
`;
const PaneQuad = styled.div``;