Building Out an Arrow Component in React
Welcome back to the course in this video we're going to develop the arrow component
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

Welcome back to the course in this video we're going to develop the arrow component. Let's go ahead and create a new file in our components directory, and we'll call it arrow.js, and we'll make it a class component. First we import react, then we bring in our class.

arrow.js

import React, { Component } from 'react';

class Arrow extends Component {
  render() {
    return (
      <div>

      </div>
    )
  }
}

Now we'll give the div a className, and to make it so we can pass in a custom name for the component, we'll use some string interpolation, as well as pass in a default value of arrow.

arrow.js

import React, { Component } from 'react';

class Arrow extends Component {
  render() {
    return (
      <div className={`${this.props.classname} arrow`}>

      </div>
    )
  }
}

Now we don't want to put anything in here, but we still have to export it.

arrow.js

import React, { Component } from 'react';

class Arrow extends Component {
  render() {
    return (
      <div className={`${this.props.classname} arrow`}>

      </div>
    )
  }
}

export default Arrow;

Next we're going to create a new file in our style directory, and name it arrow.scss. From there we'll open up our libraryCourse.js component and we'll import our new component, as well as call it inside of our libraryCourse component itself. We're also going to give the call a className of library-course__arrow for styling later. Here's what your file should look like:

libraryCourse.js

import React, { Component } from "react";

import Icon from "../icon";
import Arrow from "../arrow";

class LibraryCourse extends Component {
  render() {
        return (
            <div className="library-course">
                <label className="library-course__title">Problem Solving</label>
                { Icon('fas fa-check', 'library-course__icon') }
                <Arrow className="library-course__arrow" />
                {/* action button component */}
                <div className="library-course__description">
                    <label>Course Description</label>
                    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam fringilla facilisis mi, non pellentesque metus consectetur vel. Quisque dictum, lectus vitae dignissim tincidunt, sapien nibh placerat diam, quis blandit enim nulla in felis.</p>
                </div>
            </div>
        )
    }
}

export default LibraryCourse;

After we finish there, we need to import our new SCSS file in our main.scss. So we add @import 'arrow'; at the top.

main.scss

large

Now we'll style it with some super simple styles. All we have to do is add some borders around and below it, and then adjust the width and height.
For help with the arrow, we can go to CSS-Tricks (link below)

arrow.scss

.arrow {
  border-left: 15px solid transparent;
  border-right: 15px solid transparent;
  border-bottom: 15px solid blue;

  height: 0;
  width: 0;
}

We also need to call the arrow inside of our libraryCourse.scss file.

libraryCourse.scss

.library-course {
    display: grid;
    grid-template-columns: repeat(auto-fit, 1fr);
    grid-template-rows: 1fr 1fr;

    &__title {
        grid-row: 1/2;
    }
    &__arrow {
        grid-row: 1/2;
    }
    &__description {
        grid-row: 2/3;
    }
}

If we open up our browser we can see that it's there, but it appears that our libraryCourse grid isn't showing up. As we look through it, it seems that we forgot to import our libraryCourse.scss into our main.scss. To fix this we need to simply add @import 'libraryCourse'; at the top of main.scss. Also we need to position our icon inside of our grid, so let's add that to libraryCourse.scss.

libraryCourse.scss

.library-course {
    display: grid;
    grid-template-columns: repeat(auto-fit, 1fr);
    grid-template-rows: 1fr 1fr;

    &__title {
        grid-row: 1/2;
    }
    &__icon {
        grid-row: 1/2;
    }
    &__arrow {
        grid-row: 1/2;
    }
    &__description {
        grid-row: 2/3;
    }
}

Looking at it in our browser page now, we have our elements, but we need to have our icon close to the title. When we inspect our grid, we can see that our first column is huge.

large

It looks like we'll have to build a flex-box grid to have our elements right next to each other. To do this, let's open up our libraryCourse.js file, and we'll put a div inplace of our label and icon components, and we'll give it a className of library-course__title-arrow, and then paste our label and component inside. Your file should look like this :

libraryCourse.js

import React, { Component } from "react";

import Icon from "../icon";
import Arrow from "../arrow";

class LibraryCourse extends Component {
  render() {
    return (
      <div className="library-course">
        <div className="library-course__title-arrow">
          <label className="library-course__title">Problem Solving</label>
          {Icon("fas fa-check", "library-course__icon")}
        </div>
        <Arrow className="library-course__arrow" /> 
        {/* action button component */}
        <div className="library-course__description">
          <label>Course Description</label>
          <p>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam
            fringilla facilisis mi, non pellentesque metus consectetur vel.
            Quisque dictum, lectus vitae dignissim tincidunt, sapien nibh
            placerat diam, quis blandit enim nulla in felis.
          </p>
        </div>
      </div>
    );
  }
}

export default LibraryCourse;

Save that file, then we open up our libraryCourse.scss file and update it to say:

libraryCourse.scss

.library-course {
    display: grid;
    grid-template-columns: repeat(auto-fit, 1fr);
    grid-template-rows: 1fr 1fr;

    &__title-arrow {
        grid-row: 1/2;
        display: flex;
    }
    &__arrow {
        grid-row: 1/2;
    }
    &__description {
        grid-row: 2/3;
    }
}

When we use display: flex; it defaults to displaying on a row, which is why we didn't have to use flex-direction.

Now this is looking good, but it's a little hard to tell the different courses apart from each other, so I want to add a background. So in libraryCourse.scss we'll add background: cornflowerblue; and save it.

libraryCourse.scss

.library-course {
    display: grid;
    grid-template-columns: repeat(auto-fit, 1fr);
    grid-template-rows: 1fr 1fr;
    background: cornflowerblue;

    &__title-arrow {
        grid-row: 1/2;
        display: flex;
    }
    &__arrow {
        grid-row: 1/2;
    }
    &__description {
        grid-row: 2/3;
    }
}

Looking at the browser again, it's still a little hard to see, but what we can do is give it a grid gap. By looking at the design, we can see that there is a twenty-two pixel grid gap between each of the items, so that's what we want to add. In our library.scss we want to add grid-row-gap: 22px;.

library.scss

.library {
    grid-column: library-s/library-e;

    display: grid;
    grid-template-rows: [title-s] 100px [title-e courses-s] repeat(auto-fit, 1fr) [courses-e];
    grid-row-gap: 22px;

    &__title {
        // grid-row: title-s/title-e;
    }
}

Now when we check our browser, we have this awesome little grid gap between our items.

Before we end this video, let's check our design to see what we want to do next. Our next item is to build the add button with its hover effect. Let's commit our code.

git status
git add .
git commit -m "fixed grid and added arrow component"
git push

See you in the next video.

Resources

Code at this stage

CSS-Tricks