0

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: screenshot of the grid that shows up in the dev tools inspector

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``;
ahauser
  • 55
  • 5

1 Answers1

1

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``;
jme11
  • 17,134
  • 2
  • 38
  • 48
  • Thank you. I clearly need to review React component composition and how props work. I found a tutorial that advised this component structure was a "best practice" so I'm committed to figuring it out. I don't have access to my codebase today but I will implement your suggestions by Friday and report back my success(failure) as well as upvoting your comment. – ahauser Feb 01 '23 at 16:02