How to Create a Functional Button Component in React
Great job in going through that last set of videos, where we develop the Picker component. In this video, we are going to develop the button component.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

Let's close out of all of our files, and let's create a new file in our components directory. Let's call this button.js. In here we are going to develop our component. Normally, this is how we would write our component:

large

In the button component, we're not going to write it like this. We're going to write it pretty similar, but not the class component. It's going to be more lightweight. So let's refactor it to a functional component. So let's say:

button.js

import React from 'react';

const Button = () => {
    return (
        <button className="button">
            Generate Countdown
        </button>
    )
}

export default Button;

So that is a functional component. That's all we've done. Now let's throw that into our app.js. So we have our Picker, now we just need to throw in our button. Now, since it's a functional component, we have to write this a bit differently.

Normally, we would just say <Button/> and auto-import it. Since it is a functional component we need to say: { Button() }. Calling it like a function. Now if we go to our application, this should render the button. You'll see that we have Generate Countdown.

large

Now let's make this a little more customizable. So instead of just having it say "Generate Countdown" in here, let's have it be able to pass in a title. We need a parameter for our function. Let's say:

button.js

const Button = (title) => {
    return (
        <button className="button">
            {title}
        </button>
    )
}

Now in our app.js we just need to pass this in. In ticks, I'm going to paste in { Button('Generate Countdown') }. Save that, and go back. You'll notice that it still there. You can write whatever you want in here and it will render.

If you want to write in multiple buttons or put them in different files, you can now give it different titles. Now we have three buttons. Obviously, we only want one button, but I just wanted to show you that you can make components customizable, and that way you don't have to write in code or styles over and over again.

large

Let's go to app.js. We have our button. Now let's place it on the grid because in Firefox you'll see that it is not in the right place. It's just in the next available slot.

large

Let's go ahead and place it right down here. What I want to do is take the Picker and let's move it up one. We don't have to, we can still put the generate button there, but I want to move it up one. So let's go in here, and let's go into picker.scss. Let's go to grid-row, and let's say: grid-row: 2/3;.

Let's go back to our application in Firefox, and you'll see that now it's only 2/3. You'll also see that we have that purple space there which is the padding bottom that we added, and that I talked about briefly in the last video.

large

Now let's put the generate button on row 3/4 and column 6/9. Then let's center it using justify self or Justify items. So let's go into our code tonight, let's create a new file, and let's call this button.scss. In here let's say:

button.scss

.button {
    grid-row: 4/5;
    grid-column: 5/10;
}

That won't extend it very far, but it doesn't matter because it's going to just be the size of whatever the button is once we style it. Let's go ahead and import this into our main.scss, and it should move.

main.scss

@import 'base';
@import 'clippaths';

@import 'picker';
@import 'button';

Great, it moved, but it's at the bottom. I'm not sure sure why. Let's check in Firefox. Okay, it's because we specified 4/5, we want to say 3/4. So let's go into button.scss, and let's say:

button.scss

.button {
    grid-row: 3/4;
    grid-column: 5/10;
}

Now it should be where we want it. That's looking really nice. It looks like it should be where it is.

large

Let's go ahead and apply some styles into our button, so it looks right. First thing I want to say is:

button.scss

.button {
    grid-row: 3/4;
    grid-column: 5/10;

    height: 50px;
    width: 350px;
    background-color: $color-blue-one;

    justify-self: center;
}

Now if you want you could just extend it from 6/9, but it would still be over here. You would still have to say justify-self: center. That's looking pretty nice. Let's go ahead and add in some more styles, so let's finish typing some of these styles. Now we want to put in the skew, so let's just say:

button.scss

.button {
    grid-row: 3/4;
    grid-column: 5/10;
    justify-self: center;

    height: 50px;
    width: 350px;
    background-color: $color-blue-one;
    clip-path: polygon(10% 0, 100% 0, 90% 100%, 0% 100%);
}

This is something you just have to learn by doing. I would recommend filling out a number of different skews outside of this video just to learn how this polygon function works. Let's save that, and go back to our app. You'll see it's pretty much what we want. It looks like we could maybe extend it a little bit back, but it's very close.

large

We could do:

button.scss

.button {
    grid-row: 3/4;
    grid-column: 5/10;
    justify-self: center;

    height: 50px;
    width: 350px;
    background-color: $color-blue-one;
    clip-path: polygon(5% 0, 100% 0, 95% 100%, 0% 100%);
}

You'll see how that works. It's in 5% from this point, and it's over 95% from this point.

large

That looks pretty good. I'm going to make it really precise. I'm going to do like 7% and 93%, so it has that 7% from the left. That looks really good to me. Now what we need to do is just make the color white, give it some more text colors, and then a box-shadow. Let's go in here, and let's say:

button.scss

.button {
    grid-row: 3/4;
    grid-column: 5/10;
    justify-self: center;

    height: 50px;
    width: 350px;
    background-color: $color-blue-one;
    clip-path: polygon(7% 0, 100% 0, 93% 100%, 0% 100%);

    color: white;
    font-family: 'Montserrat';
    font-size: 18px;
    line-height: 22px;
}

That should clean it up a bit. That looks really good. Looks like it might be over too far to the right for some reason. It's probably because this isn't centered, and this has a specified width.

large

Let's inspect element. Hit grid. Yeah, that's exactly what I thought. You'll see how it ends right here. Kind of like if we made the row from 6/9 on this one, and didn't say justify-self is to the left: it would do that.

large

What we can do is: get rid of justify-self: center;, then go into base.scss, and in here we can say:

base.scss

.grid {
    height: 100vh;
    width: 100vw;

    display: grid;
    grid-template-rows: repeat(4, minmax(200px, 1fr));
    grid-template-columns: repeat(11, minmax(150px, 1fr));
    justify-items: center;

That way it's going to go through our grid. So in app.js, it going to go through our grid and now each one of these are centered. That might mess up our skews. Let's go ahead and check it. Yeah, it appears it messed up our skews a bit.

large

That doesn't matter though, we can just get rid of that and just set each individual item to justify-self. So let's go into our base.scss, and let's get rid of justify-items: center;. Let's copy justify-self: center; on our title here, and let's throw it into our picker.scss and button.scss.

picker.scss

.picker {
    grid-row: 5/10;
    grid-column: 2/3;
    justify-self: center;

button.scss

.button {
    grid-row: 3/4;
    grid-column: 5/10;
    justify-self: center;

That should center them pretty well. That looks great.

large

Let's go ahead and add in that box-shadow now that you see in the design. I'm going to go into the inspect mode that I have access to. I don't believe that you do. They don't specify box-shadow, but I don't want to just copy these over as we're coding it because I just want to walk you through them without copying from here. It will make it a lot easier.

Another thing they do is generate some styles, I thought it would generate a box-shadow, but I guess it doesn't from what I can see. So let's go ahead and Google box shadow. Let's select this first link.

Let's just click one of these until looks like what we want. Looks like none of these are what we want. They are all kind of bad, but we can adjust it. So on this first one, I'm just going to play around with it. Okay, I see how this works. That looks good.

This is how you should approach development. Just mess around with things. Then we can specify our rgba. This is looking close to what we want. Let's go ahead and copy this, and throw it into our application.

large

Let's go to button.scss, and let's paste it right here:

button.scss

.button {
    grid-row: 3/4;
    grid-column: 5/10;
    justify-self: center;

    height: 50px;
    width: 350px;
    background-color: $color-blue-one;
    clip-path: polygon(7% 0, 100% 0, 93% 100%, 0% 100%);

    color: white;
    font-family: 'Montserrat';
    font-size: 18px;
    line-height: 22px;

    box-shadow: 0px 0px 30px 2px rgba(0, 0, 0, .2);
}

Let's go to our application, and you'll see that we have a nice subtle box-shadow. If you want to adjust this to look more like what you want you can. Maybe like: 0.6 and 4px. You can put what you want.

button.scss

    color: white;
    font-family: 'Montserrat';
    font-size: 18px;
    line-height: 22px;

    box-shadow: 0px 0px 30px 4px rgba(0, 0, 0, .6);
}

It's very, very subtle. You might not even see it, but I can see it I like it. Let's commit our code, and then let's move on to the next video where we will build in the next component. Which is going to be the component you see when you hit generate.

You'll see in our application when we hit generate, it brings us to this, and it shows different components. What want to do is basically develop this component, hide the button temporarily, and go from there.

large

Let's commit our code. Let's say git status, git add ., and for my commit message I'm just going to say git commit -m "functional button component and styles". Then git push origin master. I'll see you in the next video.

Resources