Layouts laid out (ft. React TypeScript)

Nidhi Pai
4 min readAug 24, 2021
Image courtesy: 99designs

One of the building blocks of a GUI is a layout; it could be a single layout, a double layout or multiple layouts as well. While scouring the net for solutions on creating one, I found it rather difficult to come across a react-typescript approach to building layouts. Hence, when I felt I had compiled a decent reusable solution, I thought I could share it across. In this article, I will walk you through my layout development process along with all the crests and troughs I surfed past.

The desired output.

**Since this article highlights the building of a layout, it presumes at least a beginner level comprehension of React-Typescript.**

Let’s talk about file structure before getting to the crux.
There are usually three types of CSS as listed below:
- Inline CSS
- Internal or Embedded CSS
- External CSS
Throughout this project, I have chosen to go with External CSS since it facilitates the distinction in files. External CSS will contain only style property with the help of tag attributes. For brevity, I use:
1. one-column.tsx for wrapping the display content along with the styles into a single layout.
2. one-column.styles.ts for the css (and sass)
A similar pattern is established for two or more panelled screens.
All the screen information will be coded in respective folders and contained in screens .

...
layouts/
nav-panel.styles.ts
nav-panel.tsx
one-column.styles.ts
one-column.tsx
two-columns.styles.ts
two-columns.tsx
...
routes/
index.tsx
screens/
screen-two/
content-panel/
index.tsx
layout.tsx
...

Our one-column.tsx will look like this:

import React from ‘react’;
import { ThemeProvider } from ‘react-jss’;
import theme from ‘../app-theme’;
import useStyles from ‘./one-column.style’;
export interface Props {
contentPanel: React.ReactElement;
}
const OneColLayoutThemeWrapper: React.FC<Props> = (props) => (<ThemeProvider theme={theme}>
<OneColLayout {…props} />
</ThemeProvider>);
const OneColLayout: React.FC<Props> = (props) => {
const styles = useStyles();
return <div className={styles.mainLayout}>
{props.contentPanel}
</div>;
};
export default OneColLayoutThemeWrapper;

What I do here is use ThemeProvider to utilise the preset theme for the single layout and wrap the OneColLayout in it. OneColLayout implies that it will be of type React Functional Component, and it takes in props of type Props. The content that is to be displayed across the screen comes passed in through props. To dive further into the app-theme, check out this GitHub repo.

The included css attributes (one-column.styles.ts) look a little like this:

import { ITheme } from “../app-theme”;
const { createUseStyles } = require(“react-jss”);
export default createUseStyles((theme: ITheme) => ({
mainLayout: {
minWidth:"1920px",
minHeight: "1080px",
fontSize: "25pt",
backgroundColor: theme.palette.shade1,
}
}))

This can be modified further according to what is the need of the hour. I usually head towards display: flex or centring of the component since a popular use case of the single layout is usually a login/register page.

The purpose of this screen is to display a single line for demo purposes, so this is added in the content-panel/index.tsx

export interface Props {}const ContentPanel: React.FC<Props> = (props) => {
return <div>Wubba Lubba Dub Dub</div>;
};
export default ContentPanel;

To easily incorporate this change into routes/index , I have added the following in the layout. This fits the styles, the skeleton and the components all together as a single layout screen.

export interface Props {}const ScreenOneLayout: React.FC<Props> = (props) => {
return <OneColLayoutThemeWrapper
contentPanel={<ContentPanel />}
/>
};
export default ScreenOneLayout;

EZ!
Heading to the double layout screen, consider a layout as follows:

Here, the first column corresponds to the navigation panel and the second column corresponds to the content panel. Our two-columns.tsx will be moulded to contain two columns, therefore:

export interface Props {
columnOne: React.ReactElement;
columnTwo: React.ReactElement;
}
const TwoColsLayoutThemeWrapper: React.FC<Props> = (props) =>
(<ThemeProvider theme={theme}>
<TwoColsLayout {...props} />
</ThemeProvider>
);
const TwoColsLayout: React.FC<Props> = (props) => {
const styles = useStyles();
return (
<div className={styles.twoColumns}>
<div className={styles.firstColumn}>{props.columnOne} </div>.
<div className={styles.secondColumn}>{props.columnTwo}</div>
</div>
);
};
export default TwoColsLayoutThemeWrapper;

I decided to go with the flex way to portray the column display on the screen hence, the two-columns.styles.ts includes a few attributes for the second and the first column as well.

twoColumns: {
display: "flex",
flexDirection: "row",
width: "100%",
minHeight: "100vh"
},
firstColumn: {
minWidth:"300px",
minHeight: "1080px",
backgroundColor: theme.palette.shade4,
display: "inline-block",
color: theme.white.accent1
},
secondColumn: {
width:"1620px",
color: theme.palette.shade4,
backgroundColor: theme.white.accent1,
padding:"25px 45px 25px 45px",
}

Coming to the content panel, we go by the same road taken in the case of content-panel/index.tsx of the single screen modifying it as per our requirements. To wrap it all, I use layout.tsx to portray the following:

const ScreenTwoLayout: React.FC<Props> = (props) => {
return (
<TwoColsLayoutThemeWrapper
columnOne={<NavPanel />}
columnTwo={<ContentPanel />}
/>
)};

In a similar fashion, we can keep adding columns/rows to each screen with very few lines of code and minimum confusion. I’ve added a demo for a three-panelled screen in the GitHub Repository. Hope this helped y’all repeat and complete the layouts in your GUI!

Thank you for reading this far!

--

--

Nidhi Pai

I'm a computer science engineer with a keen interest in Statistics, Data science and the world of UI/UX Design. I love to read books and explore new tech.