In this lesson we create a full-screen percentage based layout using react-blessed
. We start with a Today component, extract out a common Box component, then start adding placeholder components in the terminal using positions via percents.
Elijah Manor: [0:01] Let's run our current app with npm start. What we have so far is a Today component showing the date, time, and weather.
[0:10] In this lesson we're going to focus on how to lay out various components in the terminal in a grid-like structure. Let's open up our code editor and pull up our dashboard.js file.
[0:23] Here, in the return of our app, you can see the existing Today component. If we go to the Today.js file, and scroll to its return we'll see the underlying box component. Where we pass data about where it should be displayed on the screen, top, left, width, and height, and some basic border styles.
[0:45] Let's first create an abstraction around box, as we create other components for our dashboard. In our components folder we'll create a box.js React component, and we'll import React from react. Then export default function Box accepting label, top, left, width, height, and children as props.
[1:14] Then inside our component, create a boxProps variable that'll contain our label, top, left, width, and height. We'll return a box and spread our boxProps. Then inside, we'll print out a JSON stringified version of top, left, width, and height. Then do a little formatting with null and two spaces.
[1:44] Then we'll go ahead and render the children as well. Then we'll come back up and add our box styling so it'll look nice. Border of type "line" and style of border foreground color of "blue." Now let's switch back to our Today component and change the lowercase Box component with our custom capital B Box component.
[2:11] Here we'll pass in the title of "Today" and update our closing tag. Before we forget, we need to import the Box component that we just referenced. Import Box from Box. Now we should be able to come back to our terminal and kick off our app with npm start.
[2:34] We'll see the Today component that we saw before but this time, it's using the custom Box component that we just made. It renders its children and displays the position props passed from the parent.
[2:48] Before we proceed with adding other steps components, we want to let our dashboard control where the components are displayed in the terminal. We'll switch back to the Today component and where we're destructuring props, we'll add top, left, width, and height.
[3:10] Then we'll create a boxProps variable and assign it to an object of top, left, width, and height, so that we can scroll down to the return and spread our boxProps into the Box component.
[3:24] We'll also remove the hardcoded top, left, width, and height props, as well as the border and style that are defined in our custom Box component.
[3:35] Now, we could come back to our dashboard component and pass the position props directly into our Today component, top of zero, left of zero, width of 50 percent, and height of 50 percent.
[3:50] Now, if we run our app again with npm start, we'll see that Today component rendered in the upper left portion of the terminal. You can see the position props rendered inside the box, top zero, left zero, width 50 percent, and height 50 percent.
[4:07] Let's focus on stubbing out some other components and laying them out in the terminal.
[4:14] First, we'll use a React fragment so that we could group our components all at the same level without wrapping them, and then we'll move our Today component inside of it.
[4:23] Now, we'll add a Box component inside the Fragment, and we'll give it a label of Recent Commits. Top of zero to be at the top of the terminal, a left of 50 percent so that it's to the right of the Today component, width of 50 percent so that it extends to the rest of the terminal width, and a height of 50 percent so that it takes up half of the vertical height.
[4:51] Before we test it out, we'll need to import the Box component. At the top, we'll import Box from components/Box. Now, we could test it out with npm start. Sure enough, our components are laid out next to each other in the terminal using the position props.
[5:10] Let's try adding another. We'll copy the Recent Commits Box component and change this label to Time Log, giving it a top of 35 percent, left of zero, width of 25 percent, and a height of 65 percent. Now, if we run our code, ah, not quite what we're wanting there.
[5:37] Looks like my percentages don't add up to 100 percent, which is pretty important for this type of layout. However, it's actually really good to know that you could overlay boxes like this. Let's go back and fix the issue.
[5:49] We'll update the height of the Today component to 35 percent, which should give enough room for our Time Log. Then we'll duplicate Time Log to create another box that will call Pomodoro and we'll adjust the left to 25 percent, so that it's to the right of the Time Log.
[6:10] Now, if we run our app with npm start we'll see that the problem that we had about overlapping boxes is now fixed. We also have a new Pomodoro section to the right of the Time Log, which gives us a nice section in the bottom right that we could fill.
[6:25] Let's go back and create another box, calling it GitHub, and setting its top to 50 percent, left to 50 percent, width of 50 percent, and height of 50 percent. Now, we could run our app for the last time and see that we have five boxes rendered in the terminal, laid out with percentages to make our dashboard.
Member comments are a way for members to communicate, interact, and ask questions about a lesson.
The instructor or someone from the community might respond to your question Here are a few basic guidelines to commenting on egghead.io
Be on-Topic
Comments are for discussing a lesson. If you're having a general issue with the website functionality, please contact us at support@egghead.io.
Avoid meta-discussion
Code Problems?
Should be accompanied by code! Codesandbox or Stackblitz provide a way to share code and discuss it in context
Details and Context
Vague question? Vague answer. Any details and context you can provide will lure more interesting answers!