In Front-End Development - 4 months, 3 weeks ago

GatsbyJS: Build a user listing web app. (Part 4)

In the final tutorial, we will learn to style our GatsbyJS site using CSS Modules.

Introduction

This was what we achieved in part 3 of the tutorial.

  1. Installed JS Search and Axios.
  2. Added a search component.
  3. Refactor our code into smaller components.

GatsbyJS Beautify

Up till now, our application looks pretty drab. 

We will include Bootstrap for the base styles and customise our site using CSS Modules.

  1. Install Bootstrap and React Bootstrap 4 components.
$ npm install --save bootstrap reactstrap

 

  1. Add a new file and name it gatsby-browser.js in our root folder.
$ touch gatsby-browser.js

What is gatsby-browser.js used for?

GatsbyJS uses this file to customise or extend default browser settings.

See the full list of Gatsby Browser APIs.

  1. Import Bootstrap in gatsby-browser.js.
import 'bootstrap/dist/css/bootstrap.min.css';

 

  1. Add Bootstrap classes to our existing components.

src/pages/index.js

export default ({ data }) => {
  return (
    <div className="container-fluid">
        <Search />
    </div>
  )
}

 

src/components/SearchContainer.js

  render() {
      const { peopleList, searchResults, searchQuery } = this.state
      const queryResults = searchQuery === "" ? peopleList : searchResults

      return (
          <div className="row">
            <div className="col-8">
            <form onSubmit={this.handleSubmit}>
            <div className="input-group my-3">
              <div className="input-group-prepend">
                <span className="input-group-text" id="inputGroup-sizing-default">Search</span>
              </div>
              <input type="text" className="form-control" id="Search" value={searchQuery}
              onChange={this.searchData}
              placeholder="Enter your search here" />
            </div>
            </form>
          </div>
            <div className="col-4 text-right my-3">
              Number of items:&nbsp;
              {queryResults.length}
            </div>
            <div className="col-12">
            <table
              className="table table-striped"
            >
              <thead className="thead-dark">
                <tr>
                  <th>
                    Name
                  </th>
                  <th>
                    Gender
                  </th>
                  <th>
                    Email
                  </th>
                  <th>
                    Number
                  </th>
                  <th>
                    Image
                  </th>
                </tr>
              </thead>
              <tbody>
                {queryResults.map(function(item, index) {
                  return (
                    <Profile props={item}  key={index} />
                  )
                })}
              </tbody>
            </table></div>
          </div>
      )
    }
  }

 

src/components/profile.js

return (
  <tr key={`row_${props.email}`}>
  <th scope="row">
    <Link to={`/details/`} state={{props}}>{props.name.title} {props.name.first} {props.name.last}</Link>
  </th>
  <td>{props.gender}</td>
  <td>{props.email}</td>
  <td>{props.phone}</td>
  <td>
    <Link to={`/details/`} state={{props}}><img src={props.picture.thumbnail} alt={`${props.name.title} ${props.name.first} ${props.name.last}`} /></Link>
  </td>
</tr>
  )
}

CSS Modules

In the past, it was a pain to maintain and organise CSS. For large projects, the chances of conflicting class names overwriting each other were common. (!important)

However, with CSS Modules support in GatsbyJS, we can structure our CSS into individual "components".

With CSS Modules, all class names are scoped locally by default. 

Even though we may have multiple CSS files with the same class names, CSS Modules will compile and generate unique class names for the application.

Let's try it out with a simple demonstration.

Add a details.module.css file in src/components.

$ touch ./src/components/details.module.css

 

We tell GatsbyJS to process this file as a CSS module by specifying module.css as the file name.

Paste the following into src/components/details.module.css.

.container {
  padding: 2rem;
}

.media {
  padding: 1rem;
  border: 1px solid grey;
}

 

Import details.module.css and add bootstrap classes to src/components/details.js.

import React from "react"
import { Link } from "gatsby"
import DetailStyles from "./details.module.css"


export default ({props}) => {
  return (
    <div className={DetailStyles.container}>
      <div className="row">
        <div className="col-12">
          <div className={`media ${DetailStyles.media}`}>
            <img src={props.picture.large} className="mr-3" alt={`${props.name.title} ${props.name.first} ${props.name.last}`} />
            <div className="media-body text-capitalize">
              <h5 className="mt-0">{props.name.title} {props.name.first} {props.name.last}</h5>
              <ul>
                <li><strong>Gender:</strong> {props.gender}</li>
                <li><strong>Email:</strong> {props.email}</li>
                <li><strong>Address:</strong> {props.location.street}, {props.location.city}, {props.location.state}</li>
              </ul>
            </div>
          </div>
        </div>
        <div className="col-12 my-3">
          <Link to="/">Back to Home</Link>
        </div>
      </div>
    </div>
  )
}

 

Notice DetailStyles.container and DetailStyles.media.

First, we import the CSS file via the regular ReactJS import method.

To invoke the classnames, we namespaced the CSS Module classes.

If you open the browser's Dev Tools, you can see the generated classnames. 

 

Rebuild the site and click on any of the users to view the update.

Conclusion

If ReactJS is a Ferrari, GatsbyJS is a Ferrari with racing upgrades.

We demonstrated how easy it was to build ReactJS web applications using GatsbyJS.

With latest web technologies supported out-of-the-box, there is little reason to use Create-React-App instead of GatsbyJS.

We can also incorporate Netlify or Surge to create a continuous deployment GatsbyJS workflow and speed up deployment.

We barely scraped the surface of GatsbyJS's full potential. See the official GatsbyJS documentation to explore further.

The full source code is available at Github.


blog comments powered by Disqus