Combining React Elements Into Widgets
Built using atoms and molecules, Organisms are the complex components that deliver specific features. They are at the core of an app that delivers a consistent UX.
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.
This lesson preview is part of the The newline Guide to React Native for JavaScript Developers using TypeScript 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 The newline Guide to React Native for JavaScript Developers using TypeScript, plus 70+ \newline books, guides and courses with the \newline Pro subscription.
[00:00 - 00:08] Widgets or organisms are the last piece that will help us define the entire design system. So let's look at what they are.
[00:09 - 00:23] As we saw earlier, the elements are the atoms and molecules that help us define the most basic elements. So widgets or organisms are complex components that provide a complete functionality or a feature.
[00:24 - 00:42] What that means is if you look at the image here, we have already built the search bar in the previous lesson where we talked about molecules and the input box with the search icon is the complete search bar. Now if you look at the image, we need to build a sort of a header.
[00:43 - 01:04] If you go back and we add this particular icon to it, which is an atom that we have created, this entire thing now becomes an organism and it serves the purpose of being the header for our app. So this can be this particular widget, the category icon widget, it has the title, it will use the icons and will add some text to it.
[01:05 - 01:25] We also have this particular section, which is a sort of a best selling products widget. So let's try to break this down into how it would combine whatever we have built so far, like the atoms and molecules to provide a complete organism and we can call it a product widget.
[01:26 - 01:32] This entire thing is going to be our organism. It can be encompassed inside a card and a card can be a general container.
[01:33 - 01:42] What that will basically do is provide the padding and the margins required. Now, if you look at the entire design, we have consistent spacing.
[01:43 - 01:53] This can be at page level and some of the cases where the widget needs to expand beyond that, it can also be a part of the element. The first thing we're going to do is we're going to take our section title.
[01:54 - 02:03] This is a molecule that you find in the application. It's the title and the subtitle component and clicking this will probably take us to a listings page, something like this.
[02:04 - 02:12] Next is going to be our image component. Like I said, that it's a good idea to encompass the native elements over a wrapper so that we can customize them.
[02:13 - 02:24] Let's say that we have these images and they are transparent and you want to do something like a light background and a dark background. Alternately or maybe at the round edges, we did not have them in the beginning.
[02:25 - 02:32] We want them at the latest stage. Having a custom component over a simple native image type is going to help us control all of that.
[02:33 - 02:40] Next we're going to have some detail section. So we're going to reuse the title and the subtitle and the price for that.
[02:41 - 02:49] Another organism that we can build is this one, the category widget. It basically is a horizontal scroll and we are going to use a flat list for this.
[02:50 - 02:57] So we'll also get introduced to flat list, which are quite a versatile way of building lists in reactative. They're very, very performant when done right.
[02:58 - 03:06] And other than that, this is quite a simple widget. So let's go ahead and dive into the code.
[03:07 - 03:18] Like I said, I have already built the section title. If you look at the home component file, we already have a section title.
[03:19 - 03:25] It basically is a customized text that has the title style applied to it. That's again coming from our typography.
[03:26 - 03:37] And if this subtitle passed to it, then we're under the subtitle. So this way, when we don't require the subtitle for this particular widget, we can choose to ignore that.
[03:38 - 03:52] And talking about that, the session title is a pretty simple style. What we're doing is we're doing a tag, tag, tag, row and then space between so that we can create this kind of layout pretty much how we would do in the web application.
[03:53 - 04:09] So apart from that, we also have these icons and I have reused the button category that we created in the previous lesson to build our camera icon that needs to go in the header. And this is the price component.
[04:10 - 04:21] And we are going to reuse our C text, the customized text and style it to what we need for price. So we mostly have all the elements that are required.
[04:22 - 04:37] Apart from that, I've also created the image wrapper that we talked about. So it's basically a wrapper over a simple image so that it works the same way across the application and some basic style added to it.
[04:38 - 04:45] So let's go ahead and start building our widget. We'll start with the product widget and then move on to building the category one.
[04:46 - 04:59] One thing that we need to change is currently if we see the entire home page is pretty static. If I add even more content to it, the page is not going to scroll for us.
[05:00 - 05:06] And that's the default behavior in any app. So it pushed the content down, but we are still not able to scroll.
[05:07 - 05:13] So for that, we need to encompass this whole page in a scroll view. So let's do that.
[05:14 - 05:27] One thing to remember here is that we will be using a flat list to build a category component. And another question that can arise is that can we not use a flat list to render this view that will help us optimize the entire page.
[05:28 - 05:37] So that is not a good idea. A scroll view actually a great use case for something like an entire screen and flat list inside a flat list is a very bad idea.
[05:38 - 05:59] It tends to throw a lot of performance issues and that should absolutely be awarded in all cases. If there does come a situation where we need to implement a flat list inside a flat list, my recommendation would be go back to the design team and find a different solution because that is not going to work well, at least on a lot of Android devices.
[06:00 - 06:03] Okay. So we change that to screw new.
[06:04 - 06:08] Let's check the impact of that. And it works fine, right?
[06:09 - 06:21] I'll remove these for now. But we do have our scrollable view.
[06:22 - 06:31] Let's start building the widget and we'll start with building this particular product widget. We can see that it's going to be reused at a lot of places.
[06:32 - 06:39] So that would be a good idea to create this particular molecule. So let's get started.
[06:40 - 07:06] What we'll do is we'll go to our widgets and let's create a new widget. And call it product display.
[07:07 - 07:11] So let's create this index file. It's common for every application.
[07:12 - 08:03] And then let's also create the component file. The first thing we'll do is import star as react from react and we can do const product display which would be of type react dot and we'll declare some props for it.
[08:04 - 08:24] And we're going to do support default product display. So let's declare some props and face props and there's decide.
[08:25 - 08:44] So what we need for the widget is we'll need the image path, title subtitling the primes. So let's declare image path image URL going to be string.
[08:45 - 08:58] We need that. We'll need the let's just call it title subtitle and price.
[08:59 - 09:21] We'll do props props. We'll leave the custom image at atom that we created.
[09:22 - 09:52] Where I equals let's just put that path for now that I copied over, we'll pass it from the parent component that calls this and we'll say return. And then we can have, if you look at this, we'll have the sort of a subtitle title and price items.
[09:53 - 10:19] So what we can do is we can just put the home component and copy those over. Let's copy the title subtitle or probability this title and party.
[10:20 - 10:29] And let's also copy the price. So the error is basically all the functional components, the class components.
[10:30 - 10:33] They need to return a single root level element. So that's what we need to do.
[10:34 - 10:43] We'll just wrap it over into our view. And this is basically a field import.
[10:44 - 10:52] So we'll do that. And it's also import global and also view.
[10:53 - 11:07] So I think that should mostly be it. So let's save that and let's try and use that on our own component.
[11:08 - 11:16] And let's just use it on the home beach. So we'll see product display.
[11:17 - 11:24] And let's mark the props as optional for now. Let's just test it out.
[11:25 - 11:41] We can pass that once the entire thing is set up and save the home page and we 'll wait for the home page to refresh. So okay, so we see the title, the subtitle and the price.
[11:42 - 11:48] We don't see the image because we have not passed a height then a bit to it. So let's do that.
[11:49 - 12:00] You can save it and 50% and height. I'll put the height as to 88.
[12:01 - 12:05] That's what this particular image has. Ideally we'll get this again.
[12:06 - 12:13] So this needs to be fixed. So as soon as we do that, we have the product widget this entire.
[12:14 - 12:24] So if you look at the code, it's quite simple, right? All we did was we accumulated the different atoms and molecules to create this particular new organism.
[12:25 - 12:39] Next let's use this organism to build our entire product widget. Again, that's going to be a very simple process.
[12:40 - 12:55] So let's go and create a new folder and let's call it product widget. And let's just copy over the index file and build.
[12:56 - 13:04] And let's also copy over the component. We've affected it.
[13:05 - 13:13] So this is going to be the product widget. So let's also export that.
[13:14 - 13:22] And what we're going to need is the product display component. So let's do that.
[13:23 - 13:40] We'll probably need two of those. And what we need to do is the section title if you'll remember that we had created this one.
[13:41 - 14:02] Let's add that section title and we'll pass title to it as best sending and sub pedal C all. The title equals C all.
[14:03 - 14:09] We can also pass an on click to it. So when we click it, we go to a particular page.
[14:10 - 14:30] Let's just say on click and we're going to declare that here. We're going to import the router.
[14:31 - 14:39] It's a simple push. We can also do navigation dot push it, but it's always good to use the router so that we have those defaults in place.
[14:40 - 15:07] And the defaults can be related to showing the header or not showing status bar or having a background color and a lot of other configurations that will be required depending on the app we're building. We'll do navigators router and we'll do router dot push and pass the component ID to it.
[15:08 - 15:15] So we'll see screen start. The listings is the dummy three screen which you'll recall from the previous modules.
[15:16 - 15:20] I have this rename it to listings. Sounds better, doesn't it?
[15:21 - 15:32] So we can pass that and as soon as we click the title, we'll land on the listings page. So in the title, we have the two products and that's most played.
[15:33 - 15:38] What we're also going to do is we're going to wrap this whole thing in the card molecule. Let's create that.
[15:39 - 16:02] It's a good idea to have that so that we are always in control of the padding and spacing that's required at a page level. So let's go to elements and let's create a new card type new file or we can call it layout so that we can do multiple of these if required.
[16:03 - 16:20] Just copy over any one of these, it can do faster. We'll call it card.
[16:21 - 16:38] Not sure if it will require any props apart from children. So there's going to be our any act element.
[16:39 - 17:00] So do a view. Human system and we pass the children to it.
[17:01 - 17:09] So if we really require any padding, it doesn't look like it. Let's just leave it at that for now.
[17:10 - 17:19] And now we'll use this in the product widget that we're trying to create. So instead of view, we will do.
[17:20 - 17:39] Okay, I think we need to export that. Card card card, right.
[17:40 - 17:45] And it's okay, it's saying that we have an area of elements. So let's do that.
[17:46 - 17:56] It's going to be one root element is the point and if you're adding an additional new over here, that would be a wasted layer. So let's do this and that would fix it.
[17:57 - 18:04] Okay, we have our card, the title and the product displays. Let's try and render this on the home page now.
[18:05 - 18:07] There's still one thing missing. These products will come vertically.
[18:08 - 18:14] We need to align them horizontally. And we'll do that.
[18:15 - 18:26] So we'll say product widget. And up to somehow it not for that.
[18:27 - 18:30] Now it should work. So let's save that.
[18:31 - 18:35] And as soon as the new refreshes, we'll have the product widget. So that is nice.
[18:36 - 18:45] The next thing we need to do is align this in a row. For this, we will just need a view.
[18:46 - 18:59] And what we're going to do is we're going to use one of the global styles to make that happen. So if the style equals global dot, this seems to be from a layout.
[19:00 - 19:11] We don't have anything right now in layout that can support this kind of a horizontal placement. So we had a curse term implementation for session title.
[19:12 - 19:21] So it's totally a choice. If we want to mark them individually or we want to use a common one, let's use a common implementation here and let's call it row.
[19:22 - 19:28] So what we're going to do is we're going to do like direction row. It's very similar to how we do in the web.
[19:29 - 19:35] So what we'll do is it will align the elements in the row. And let's also justify content.
[19:36 - 19:44] And then looking from this seems like the card is taking care of the alignment of the entire widget. So we can do space between.
[19:45 - 19:54] So we'll do space between and let's lose that. Dot row, save it.
[19:55 - 20:00] And once we have it, you'll see the two products. Now images are not working great.
[20:01 - 20:07] That is because we have not asked the individual product widget to occupy a certain space. It is two way of doing it.
[20:08 - 20:23] One is if we feel that we're going to use this product widget in different, different widths across the application, we can make that as a parameter. Or if you feel that this is always going to take a certain space on the view whenever it appears, we can directly put it in the widget.
[20:24 - 20:40] So we'll just do style and ideally we should come from the typography. But we'll just do typography dot elements dot we need to add that.
[20:41 - 20:56] So let's go ahead and add that product display. We'll say weight equals.
[20:57 - 21:21] Let's do 50% and let's lose that. Once we save and reload, we have our product widget.
[21:22 - 21:25] So now as we see that it's quite simple. Now the spacing is a little off.
[21:26 - 21:31] So that's what we need to fix. Let's also rename this to instead of see all that doesn't look great.
[21:32 - 21:47] Let's do a BOPlay speaker. So BOPlay speaker and let's fix the spacing whenever the title appears, it's supposed to have a certain space below it.
[21:48 - 22:05] So let's do that. We need some spacing at the bottom for it.
[22:06 - 22:18] So it again needs to come from typography typography dot and this is an element . So let's declare a new one over here.
[22:19 - 22:43] So we'll say section title and we'll say margin bottom 10. So let's use that.
[22:44 - 22:57] And once we save and refresh the mission have the spacing 10 is a little less, but I think that works for now. Okay, there's also need to be space between these two product images that we have.
[22:58 - 23:02] So probably that 50% was a little too much. Let's reduce that.
[23:03 - 23:30] So let's go to the typography and where we said 50% let's make it a little less , let's do a 48% and once we save, we should have that space that required. Yeah, looks more like it, right?
[23:31 - 23:37] And that's all we needed to do, right? So let's look at the product widget and see how we built it.
[23:38 - 23:51] We had a card type of an atom that allows to encompass a lot of different other atoms and molecules to form an organism. So we have that inside that we took the section title molecule, we put it there .
[23:52 - 24:04] Now we are not passing any styles or anything to it. And whatever styles that we are using inside section title is also coming from our design system that is the global layouts and global typography.
[24:05 - 24:12] Next we build the product display widget and again, it has no styles in itself. We are going to move this out into typography.
[24:13 - 24:26] Ideally, the image height and width would be set. And what other thing we can do is we have displayed these title and subtitles and the price over here.
[24:27 - 24:32] It'll totally depend upon the use case. But what we can also do is build this whole thing as a different molecule.
[24:33 - 24:41] So basically what we can have here is a sort of a price display component. So that's why simple, right?
[24:42 - 24:54] So I hope this all starting to make sense now how through this entire module, we have tried to define a typography. Then we took that typography and we created the global styles for it.
[24:55 - 25:07] And then how these typography flow from global styles into the different atoms, molecules and and help us build organisms. Next let's look at building a carousel.
[25:08 - 25:17] We'll use that for building the category widget that we have at the top. And we'll build a generic carousel so that we can take up any children and run to them.
[25:18 - 25:31] Let's say this is a simple product display module that's probably showing two products. Let's say that we wanted to build a carousel for it and just pass the product display component that we built into the carousel as children and render it.
[25:32 - 25:40] We use a flat list to build that. So flat lists are a pretty versatile solution in the reactivity world for building virtualized lists.
[25:41 - 26:01] They are pretty performant and they come with a lot of options like horizontal mode and the initial number of items to render and a lot of other things that we'll look at in detail in one of the upcoming modules about performance that's called virtual ization and how to optimize it. So for most of the use cases I do not recommend tinkering with any of these options.
[26:02 - 26:15] They are pretty great as they are with their default values. So if required and if we see performance hit we can come back to modifying these and we'll look at that in detail.
[26:16 - 26:25] So let's start what I'll do is I'll copy over the card component and reuse it to make our carousel. So let's just do that.
[26:26 - 26:50] This is under the layouts and let's just say we'll call it carousel and we'll export it and go to home component and also start displaying it. Cancel it probably require some props children.
[26:51 - 27:00] So we'll pass to it. We would use a flat list for this and what flat list basically requires two things.
[27:01 - 27:06] One is data the array to iterate over. And the second is what to render.
[27:07 - 27:20] Let's first pass data to it. For now what we'll do is we'll create the props and then pass the data to it.
[27:21 - 27:40] We need data and that will be our props.data. And the second thing that we need is render item.
[27:41 - 28:00] It's enough to actually have these two what render item is basically it just iterates over the array that we pass as data and we can tell it what we want to render. So let's say we have an image URL data or a title data we can return.
[28:01 - 28:17] See text and then we can pass item dot title. Let's say that we are getting an area of this we can pass it and it light it over this and create the flat list for us.
[28:18 - 28:38] A good use case would be to create a carousel that just also takes this render item what item do we want to render inside this and then it will render it. So we'll say data and then we'll say item and it will be a react element.
[28:39 - 29:18] And both are mandatory. So we'll just say that we need to render the item.
[29:19 - 29:27] And the error is for okay. I'll declare different props.
[29:28 - 29:41] So once we do that we save it and then we go to the phone component and we have casual it requires data and item. Let's pass that.
[29:42 - 30:00] Let's declare some data right here. Let's do carousel items equals could be an array and we can just do URL.
[30:01 - 30:15] So we'll just try to display a couple of images. Let's do that and it's going to be a carousel item and we'll quickly add in state.
[30:16 - 30:19] So it's basically it any for now. Okay.
[30:20 - 30:27] I have shortlisted a couple of images. But I'll just add them here.
[30:28 - 30:35] Okay. So that is good.
[30:36 - 30:50] We'll just go here and we'll say we want carousel item from states. And that's the data that we want to render.
[30:51 - 30:59] So we'll just say data equals carousel items. And next is what is the it that we want to render for that.
[31:00 - 31:15] Let's do another function. Let's say render carousel item and we'll get item from our index.
[31:16 - 31:18] It just loops over it. That's what we're going to get.
[31:19 - 31:41] And we'll say return see image and we'll pass the URL as item dot URL. That's what we declared here.
[31:42 - 31:45] So we'll do that. And we also need some style images.
[31:46 - 31:59] Don't render without the fixed height and a bit. So we'll say let's do it 100 and height 100.
[32:00 - 32:24] And since we're going to loop over it, it's always a good practice to this spec similar to what we do in web or in react we add a key to it. So we'll say carousel item home carousel item and then I'll just pass index to it.
[32:25 - 32:31] So that's what we are going to render. And let's pass that.
[32:32 - 32:42] It's called item equals this is what we're going to render. Okay, so let's see what's the error here.
[32:43 - 32:49] It says missing the following property is react element. I see what's wrong there.
[32:50 - 32:56] So if you look at the render item, it actually takes a list, a list render item and item type can be anything. So that's what we need to declare here.
[32:57 - 33:01] We can't just do a react element. It basically needs to come inside a.
[33:02 - 33:11] So we can just render item and that's what we are passing. And if you look at the view, it has already entered that.
[33:12 - 33:17] So we have these two images. Okay, next we want a horizontal list.
[33:18 - 33:26] So let's do that in carousel. We can go and we can make sure that we're always doing a horizontal list.
[33:27 - 33:37] So there's a property that is called horizontal and we need to set it to true. And once we do that, we have this kind of a setup, which probably need to pass more items to it.
[33:38 - 33:44] Or let's just do one more thing. Let's just say that we want a much bigger image.
[33:45 - 33:56] And for that, what we can do is we can use a property that's called dimensions. So react provides this and we can do is we can get the screens or the windows with.
[33:57 - 34:07] And if you see this, you can get the width, the height, the current font, killing that is being used if the user has actually zoomed the entire OS or the app. For some reason, we can get that.
[34:08 - 34:18] We'll just say wait and we'll just say we'll take the entire bed and let's just also increase the height a little. Save that.
[34:19 - 34:31] And once that refreshes the view, we should have our horizontal. That was simple, right?
[34:32 - 34:36] So let's look back what we did. We just created a type carousel.
[34:37 - 34:42] It basically takes data. And that's going to be an array, probably getting something like a product list from an API.
[34:43 - 34:51] And then what is it that we want to render? We have this carousel that's a organism that we have that we can reuse.
[34:52 - 35:02] So next I would encourage the users to pause the video here and build this particular organism themselves. We already have the flat list and it can be used to display these.
[35:03 - 35:19] So the recommended way would be to build a particular molecule which has this icon that we already have and just add title to it. And then we can pass the area of that entire thing to this carousel that we have already built.
[35:20 - 35:26] So I would say pause the video and try that for yourself. And I'll build that and continue the video from there.
[35:27 - 35:39] Okay, so if you have built the widget, let's continue. What I have done here is I've built this category widget and if we scroll on the UI, that's the widget that we were looking to build.
[35:40 - 35:44] That's the one. It has the title I've reused the section title molecule for that.
[35:45 - 35:55] And for the rest of it, we have used the icons and the titles. Let's just see what that we it looks like.
[35:56 - 36:05] It's quite straightforward. We already had a carousel molecule and we've added a title attribute to it so that we can support titles that was not there before.
[36:06 - 36:15] So I added a title to it and it's basically is an optional type. So if we pass the title, you'll render it and we'll render a section title for that.
[36:16 - 36:21] And then for data, we have the data over here. This can come from a configuration or from the API.
[36:22 - 36:36] And then we just say that we need to render these icons. So for icons, we have the button category that we have defined initially, the atoms and then the text.
[36:37 - 36:47] One additional thing that I have done is I have added an element section to the global type. So now we can have these being controlled by the global types and elements.
[36:48 - 37:00] And it basically tells the application that we need to enter the text in the center and then have some sort of margin that's coming from typography. So we'll say global dot elements dot category icons.
[37:01 - 37:09] And once we save it, our text will now align to the center along with the icons . So I hope you found that simple.
[37:10 - 37:33] So as we can see now our home component has all the different modules that we need, the organisms and the molecules, we have the category widget, we have the product widget, we also have the search bar icon. It's not been built into an organism where we've seen the diagram, but that should be quite straightforward.
[37:34 - 37:41] I'll go ahead and do that before the next module. The final piece of this entire thing of this entire design system is templates.
[37:42 - 38:00] And what they are is basically they tell you how the entire system that we have been so far, the accumulation of the atoms and the molecules and organisms, how they're going to come together to build a particular layout. So we'll look at that in the next module.
[38:01 - 38:06] And with that, we'll be able to complete our homepage. So thank you and see you in the next module.