13.08. FramerX - Grid Code Component

13.08. FramerX - Grid Code Component

Hi, my name is Meng, and welcome back to another session of the Framer X course. As designers, we often work with grid layouts like this one, or a list type of layout. In Framer X, you can use the stack tool, but it does not allow you to set both the columns and the rows at the same time. Today, we're going to learn how to create this very simple grid component, but we're going to do it from scratch using a CSS grid and we will be learning how to a simple loop of an array of items. First of all, let's delete this component and create a new one. So new component, and this time it's going to be the grid, from Code, Create and Edit. Using that, let's drag and drop to here, set it to 300, by 600, like this. Let's go back here and do Option + Z to wrap and then remove the styling.

So the styling from div as well.
Instead of props.text, we're going to use children,

and if you save this, you will be able to see this dot
and connect this to the content that you want. Perfect. Let's remove the property controls for now, and then set the indentation for this and this as well. Now, we just need to be able to split this into multiple columns and rows. The first thing we need to do is to set up the props for columns and rows. So, let's start with columns. I'm going to replace the text by columns, and it's not going to be a string, it's going to be a number. The same for rows, number. Now for each of these children element is a square, and usually in a list you will have multiple instances of the same items, and then from there, you can set the CSS so that appears like a grid. Let's set the default props as well, so it's going to be columns. Right now, we're going to hard-code it, so let's say two columns and in rows, we're going to set to five. Now right after render, we're going to set the columns max is equal to this.props.columns, multiplied by this.props.rows.

So this represents the maximum number of items in our list.
The next thing we need to do is to set an array of items starting from scratch, so using these brackets, and then we're going to a for loop based on the number of items, so four var index is equal to zero, semicolon, and then index is less than the max, semicolon, and every time, do index++, which means increments it by one every single time. At the end, after the parentheses, we're going to add curly braces. So again, this is a loop starting with zero, with a maximum of columns multiplied by rows, and then each time, it's going to increment by one. Let me just increase this so that it's easier to read. Now for every time that it's looping, we're going to say items, so the array of items, .push, meaning that we're adding a new item to that pool of items, parentheses, Enter, and within this, we're going to add a new container. So for each container, we're going to return pointy brackets Item, and then within that, we're going to have curly braces this props children.

And then once I'm done with the whole thing,
I can just put items right here, so curly braces and then items. Instead of this div, I can also create a style component, so here's a trick, I can select this, and do Command + D to edit both at the same time, so now I can just delete both at the same time and put Container. Now I'm just missing two style components, the Item and the Container. First, let's import styled from styled-components,

and then define the item as well as the container,
so const Container is equal to styled.div, two back ticks. Let's do the other one at the same time, const Item is equal to styled.div, two back ticks. Before I go any further, I just want to make sure that this code is working. So I know that I should be having 10 items in total, and that I'm looping through to a maximum of 10 items,, applying it to my main container as a whole. Let's go to preview, and then minimize this. Right-click and Inspect. If you scroll down a little bit, you're going to find the item right here, and then you can see that we have 10 items. On the left side, you will only see one of them. That's because they are all on top of each other. So for example, if I go here, I delete this one, you'll see the next one and so on. What this means is that we need to apply our styling correctly so that they don't stack on each other but instead, stack next to each other. Let's start with a container. We're going to go here and set up display grid. Then we're going to set the number of columns, so grid template columns, to 1fr 1fr. Fr stands for fraction, so you would have 100% divided by two columns, which means that 1fr is equal to 50% each. If I had three times, then each of them would be 33%, so fr is a dynamic value that depends on the number of fractions in total. First, I'm going to remove third columns and I'm going to have two columns, but I can also write this in another way, so for example, I can put repeat, press Enter, and it's going to repeat two times, and each time, it's going to have 1fr like this. As you can see, have two columns now. Let's set up the number of rows. We're going to do grid template rows, to repeat, and then this time it's going to be five time, 1fr each. If you save this, you'll see that it's not changing anything, that's because the item here doesn't have a size. So let's set the size for the item. Set the width to 150 pixels and height to 112 pixels and save. Perfect. The only problem that we have now is that it doesn't seem to be resizing the actual image. Let's inspect the elements, so inspect, and then here, we see that this is our item, which is a container, so we have container which is right here, and each of these children is actually also another container, which is hard-coded to have a width, as you can see here, it has a width of 200 and a height of 200. Let's go back and specify that div. Because we're using style components we can use something like Sass where we can nest it, so we can specify the div inside the item container. So we're specifying just the div element inside item, and now, we're going to set div, curly braces, and then the width is going to be 150 as well, and height, 112, but because we're overriding something that is really important, we need to add important, and this is going to make sure that it will apply to both the width and height. Another thing we can do is to add a gap between each of the items. So we can do grid gap, one pixel, save. Now, we've been hard-coding the number of columns and rows, so we might want to make them dynamic. So for example, we know that our props contain two columns and five rows. We can pass that to the container. In Container, I'm going to add columns is equal to curly braces and then this props columns. The same for rows, so rows is equal to curly braces, this.props.rows.

Inside our container, we're going to replace the two
by dollar sign, curly braces, props, arrow, props.columns. Let's do the same thing for rows, so dollar sign, curly braces, props, arrow, props.rows.

What this means is that if I add a third column right here,
it's going to immediately apply it to my UI, so I have a third one. Now the problem that I have with this is that it's adding a third column but it's not really dividing within the bounds of the container. I want to have the full width divided by the number of column so that it doesn't overlap and go outside of the bounds of the component. In order to do that, I need to know the size of the component. To get that value, I need to add right after ControlType, Size, and then in my props interface, I need to put extends Size, so that I'm getting the size of the component in addition to what I have here, and that means the width, the height and so on. First of all, let's pass also the columns and the rows value to our item style component. So I'm going to copy the columns and the rows and paste it right here, so I have the columns and the rows, which is passed as props. Then I'm also going to pass the width and the height of the container to the item, so width is equal to props.width, and then the height

is equal to this.props.height.
Now using all of this beautiful data, the width, the height of the container as well as a number of columns and a number of rows, I'm going to apply it to the style component in my styling. So here, instead of 150, while keeping the px at the end, we're going to have dollar sign, curly braces, and then we'll have props, arrow, props.width, which is the width of the whole container, divided by the number of columns, so props.columns and save. Now what we should see is the size to be perfectly divided, but we also have to apply to the div, otherwise it's just going to exceed the bounds. So let's do that. Let's copy and paste this part right before the px and replace the 150 by the exact same code. Now if you save this, voila, you see that we have these images properly sized and properly divided. Let's do the same for the height as well. I'm going to replace 112 by dollar sign, props, arrow, props.height divided by props.rows.

Just fixing the indentation.

And copy and paste
to the height in the div, and then save, perfect. So the number of rows and the number of columns is based on the numbers right here, so I update this two and then six, it should be sizing everything properly, and voila, you can see that it's doing all the calculations for me so that it's perfectly divided, awesome. So now that we can customize these numbers, why not use them as overrides. So we're going to use the Framer library. Let's use their property controls, so static propertyControls, camel case, of type PropertyControl, using a capital P at the beginning, is equal to curly braces, starting with columns,

and then colon, curly braces,
and this is where we're going to put the title as well as the type, so type, colon, and then ControlType.Number,

comma, title,
colon, and then we're going to name it Columns. Then after this, let's add a comma and then add rows,

of Type ControlType,
Number again, comma, the title is going to be Rows, and save. So here, we're basically using the same property controls that comes by default when you create a code component. In this case, we're passing down the columns props as well as the rows to the overrides so that it can be controlled in the inspector of Framer instead. So if you click on the code component, you'll find these overrides right here using the same titles, Columns and Rows, and now if I want to modify the number of columns to three, and press Enter, it's going to update like magic to my code component. I can decide to set one column, and let's say five rows, so any number that I want, it's going to automatically update the content for me. The other thing is that I can totally resize my component and everything is going to resize properly as well. So I can set it to here, and it just resized based on the container size. So let me just put it back the way it was, maybe set it to two. And of course, you can totally push this further. For example, you can add a gap override, so I can have a bigger gap and that would be customizable right here, and you would have to change the calculations by taking into consideration the gap size versus the container size and the number of columns as well as the number of rows. You can even change the radius of the image, you can apply API data instead of this one using children, you can do anything you want by using the knowledge that you have learned so far. I really hope that you've enjoyed the course so far. In the next session, we're going to learn how to create an icon library using some static data as well SVG code that is taken from Framer X. I'll see you in the next session. Thank you.


We're not around right now. But you can send us an email and we'll get back to you, asap.


©2021 RussellCoder

Log in with your credentials

Forgot your details?