Adding helper components
Get the project source code below, and follow along with the lesson material.
Download Project Source CodeTo set up the project on your local machine, please follow the directions provided in the README.md
file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.
Lesson Transcript
[00:00 - 00:21] Adding helper components. Before we implement the main functionality, we'll add the following helper components. "ButtonListFieldFormPanelText and TextBoxTSX". All of them will go into the "SRC shared folder". Define the "button" component. Create a new folder inside "SRC shared folder". Inside of it, define a new file "buttonTSX". Here we first import React, import react from react.
[00:22 - 00:46] Then we define the "props" type for the button. Type "buttonprops" equals a new type with "children" that in our case is going to be a string and any. Because unfortunately we don 't really have the "props" definition for the "blessed" button. "ExpertConced" button is going to be a function that receives children and then the rest of the props. The type of the props should be "buttonprops". From this component, we return a "blessed" button where we pass in the " children" prop as content.
[00:47 - 01:24] "Content" equals "children". I'm using the "strangler" brackets just to highlight the text. You don't have to do this if you don't want to. We pass in the "bullying flag" mouse. " High" is going to be "1" with "children" length plus "4". As you remember, "children" is a string and is going to be the text that we display inside of a "button". Plus, here I'm adding a space on each side and a "trangler" bracket. So I'm adding "plus" for symbols for those "Align" center, "Left" center, "bottom" one, "background" is going to be blue and "forground" is going to be white. Here we specify the text color. And then we pass the rest of the props. Define the list component.
[01:25 - 01:37] Still inside of the "shared folder" create a new file. "List.tsx", "impert", " react", "FC" and "forward". "Ref" from "react". Define the "ListItemType". Type "ListItem". It will have content of type string.
[01:38 - 02:24] And then define the list props. Type "ListProps" equals an object with an optional field top. That can be a string or a number "left", "right", "bottom", "height". And with, we also pass in an optional field on action. This function will receive an item of type list item and return nothing. And we also will pass the items. It's going to be an array of type string. After you have the list props, define the list component. "ExpertConstList" equals "forward ref" of type "any" and "listProps" as the props of the reference. Here passing the component will use "onAction", "items" and "rest". You don't have to specify the type of the props here because you already passed them to the forward ref function. And then we expect to get the ref. Here we return a "blastList" element, the "lastList". We pass ref to it. We need it to be able to focus on the list elements.
[02:25 - 02:53] We pass on action, on action "focused" so that it's focused by default "mouse". So that we can control it with "mouse". "keys" to control it with the keyboard. "v" to do it in "vmode". Items are the items that we want to render in this list. And we pass in the style. It's going to be an object with "bg_white", "fg_black", "selected". Here we specify the style for the selected "row" "bg_blue", "fg_white". And we set the border to be "type_line". And after all that, we pass the rest of the props.
[02:54 - 03:12] Now let's define the text component. Create file called "texttss", import, " react" from "react". Define the type "textProps" with "children" string. And then just like with the button, we use "any" to create an intersection type. "Expert", "const", "text". We're going to receive "children" and the rest.
[03:13 - 03:54] The type of the props is "textProps". And we return "blessed" text with is going to be the length of the children. "Children" length. It works because "children" is a string. " Content" is going to be "children". And we specify the style "bg_white", "fg_black". And then we pass the rest of the props. Define the textbox component. Create the textbox.tss file. "Import, react" from "react ". And we'll also need the "FC" type. Define the textbox props. Type "textboxProps". It will have "top " string or number. This is the amount of lines we take from the top to position our textbox element, bottom and left. And we'll also pass in the "on" submit. It's going to be a function that returns nothing.
[03:55 - 04:23] Now define an expert textbox. It is a functional component with textboxProps that receives the "onsubmit" prop and the rest. Return "blessed" textbox. Pass in the height. It should be one style "bg_white", "fg_black". Make it receive the keyboard keys, input "on" focus, mouse, so that it receives the mouse events and "onsubmit". Here we pass the "onsubmit" prop. And then pass the rest of the props. Define the panel component.
[04:24 - 05:39] If you've launched the application from the example folder, you saw that it rendered a window or panel on each screen. Let's define a component for it. Inside of a shared folder, create a new file, "panel.tss", "impert", "react", "props" with "children", and "forward ref " from "react". Define the panel props. Type "panel". Props is an object with "field stop". We'll need it to position the panel of type number or string, left, right, bottom, width and height. And now define the panel component. Expert const panel = "forward ref". Again, we'll need to have the ref for this element to be able to focus on it. Pass any as the type of the element and props with " children", because we'll need to render the children on this component with "panel props". Define the component that receives "children" and the rest and the ref. Return the "blessed" box. Inside of it, we'll render the children and also pass in the props. Ref = ref "focused", mouse and shadow. This will create a nice shadow by default. Border = type "line keys" to be able to intercept keyboard keys, align, center and style with "bg white", shadow. True border = "bg white", "fg black". Set the label to have "bg white" and "fg black" as well. And finally, passing the rest of props.
[05:40 - 06:11] We got to the form helper components. Those are the form component itself and also the form field component. Inside of a shared folder, create a new component form "tsx". Add the imports. We'll need react props with "children" fc react node and use ref from react. Define the types for the form. First, we need to define the form values. Expert type form values. Don't forget to export it because we'll need it in other components and it should be called form values. It's going to have text box, type string and it's going to be an array. Define the form props , type form props.
[06:12 - 08:14] On submit is going to be a function that receives values, form values and return nothing. And the children, here it's going to be a function with trigger, submit, avoid function and it should return react node. Now define the form component. Expert, const, form fc of form props and it's going to be a component that receives children and on submit. Define the form is going to be a ref, use ref, of type any and define the trigger, submit function. Const, trigger, submit equals a function where we call form, current, submit. This is why we need the form reference to be able to call submit on it. Define the use effect, react use effect where we'll have to call set timeout and then call form, current, focus. Unfortunately, we have to do this hack here. It's a hacky solution. But we do it because otherwise we wouldn't be able to focus the form. Maybe in the newer versions of react blessed, this bug will be fixed. But for now we'll have to do this little hack here. Pass in an empty array to trigger this use effect when the form is mounted. Return the blessed form with children inside of it and we pass in the trigger, submit function. Pass some props to the blessed form, top three keys focused, ref equals form and style, bg, white. Now let's define the field component, new file field tss, add the imports, we'll need react fc text box and text, define field props, type field props with label of type string, top and optional field of type number or string and the on submit function that is going to be avoid expert, the field component type fc of field props. Here we'll need the label top on submit and we return a fragment where we render text component with the label as a children top is going to be top from the props and we run through the text box, text box top equals top, left equals label length, because we need to make an offset for the label text so that the input is rendered right after the label passing down submit prop and it's going to be on submit function. We'll also need a couple of informational message components.
[08:15 - 12:11] The first one is going to be entity error component, create a new file new entity error.tsx, add the imports, we'll need panel text and bottom, we'll combine them into the entity error message, define the props type new entity error props is going to be an object with on close avoid function and error an object of type error define the component expert const new entity error it will receive the on close and the error set the type to new entity props error props inside of this component we'll need to get the ref use ref type any and we'll use this ref to subscribe to key presses we'll want to listen to enter keypress use effect here we subscribe to ref current key enter and then we call the on close function from the props and then we return so that when we unmount this component we unsubscribe from this event listener ref current on key enter on close and then return the layout is going to be a panel with text saying an error occurred and another text with the error message and also it will contain the bottom that will also allow to close the entity error panel enter okay when you press on the bottom so we add the on press handler you should also call the on close function provide the reasonable styles for this panel should have 25 padding from the top and be centered horizontally and have height of 10 lines center both text messages and the bottom let's create a new entity success component new file new entity success tss this is what we're going to show when we successfully create a pull request issue or repository we can copy the contents of the new entity error and change it a bit instead of error we'll now say success new entity success props it will receive on close title of type string and URL also of type string change the props of the component to the new entity success props and rename the component to new entity success change the props on close URL and title we will still need the ref but now we also need to define the open URL function const open URL equals use callback here we'll need to debounce opening the URL unfortunately there is another bug in blast that otherwise would call this function several times debounce open URL 100 imp reduce callback and define the debounce in the utils create new folder utils and here define a new file debounce.ts as an alternative you can get this function from the underscore i just decided to have my own implementation here because we don't need any other methods from this library this function is useful when your callback is going to be called repeatedly and sometimes too often so you want to make sure that there is some sort of cool down that is represented with this wait argument here here we define a timer and then every time this function is called the timer is cleared and there is a new timer created that will resolve with the result of calling the callback function this way you make sure that it's only going to be called once per time defined by the wait argument go back to the new entity success and import debounce we also need to use the open make sure that you pass in the URL to your use callback so that the callback that you wrap into debones is redefined and has the new URL every time the URL changes then we need to pass the open URL as a callback to the key handler and we're gonna listen to every press of the "O" letter don't forget to unsubscribe from this event here we pass on open URL and here we unsubscribe from the open URL on letter press "O" and now we want to update the layout we don't have the error message anymore and instead of the an error occurred we now render the title as we now listen not only for the enter key press but also for the "O" we add another button that says "O" colon open in the browser and here we subscribe to "OnPress" to call the open URL function all right and now we have all the helper components and we're ready to proceed with the rest of our application
This lesson preview is part of the Fullstack React with TypeScript Masterclass course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.
Get unlimited access to Fullstack React with TypeScript Masterclass, plus 70+ \newline books, guides and courses with the \newline Pro subscription.
![Thumbnail for the \newline course Fullstack React with TypeScript Masterclass](/_next/image?url=https%3A%2F%2Fs3.amazonaws.com%2Fassets.fullstack.io%2Fn%2F20220425171607321_CoverImage_FSReactWTypeScript_Masterclas.png&w=3840&q=75)