Getting our hands dirty

Let’s actually write some code! Start the development server by running npm run develop. Then head over to http://localhost:8000/. We’re going to build out the landing page for our site. Go ahead and delete ./src/pages/page-2.js assuming your version of gatsby-cli generated that file, we won’t be needing it. Also, delete the <Link> component and comment out its import (we’ll use it later) to shut ESLint up in ./pages/index.js as the page it links to no longer exists.

We’re keeping ./src/layouts/index.css. I think it has some sensible CSS resets.

Styled-components

Next, let’s modify the Header.js component a bit. Change the Header title from Gatsby to our site title Polling App. Now let’s move the inline styles to be instead handled by styled-components. Your Header file should now look like this:

A couple things to note here:

1. The weird opening and closing back-ticks (``) after styled. These are just template literals; yes, the same ones used for string interpolation, just being used in a bit of a lesser known way. It enables front-end developers to use actual CSS property names as opposed to their camelCase counterparts required by javascript.

2. Because of this uncommon use of template literals, most IDEs and code editors do not have built-in syntax highlighting for the CSS defined inside the template literal strings. Here’s a link where can check if your favorite editor has a syntax highlighting plugin for styled-components.

3. The styled(Link) component: this is a higher order function that passes a generated hashed className prop to the wrapped component for the styles defined within the template literals. This can work with any 3rd party component so long as the wrapped component passes props.className to a child DOM element.

4. The background prop being passed to the HeaderContainer styled-component. This is what makes styled-components powerful. It allows you to pass in dynamic data to your components’ styles giving you flexibility with your styling that you otherwise wouldn’t have with regular CSS files.

Another thing to note is the styled-component we defined as HeaderWrapper has almost the exact same styles as the element wrapping props.children() inside ./src/layouts/index.js. This is an opportunity to keep our code dry. Create a directory called styledComponents inside the ./src/ directory. A convention I follow with styled-components is anytime I have a styled-component that is reusable, I extract it into its own file inside ./src/styledComponents/.

Since this styled-component is being used for layout, let’s put it in a file called layout.js . I think an appropriate name for this specific styled-component is Container. Cut the HeaderWrapper declaration and paste it into ./src/styledComponents/layout.js, rename it to Container, and export it:

// ./src/styledComponents/layout.js

import styled from 'styled-components'; export const Container = styled.div`

margin: 0 auto;

max-width: 960px;

padding: 1.45rem 1.0875rem;

`;

Don’t wrap styled-components defined here in a function as you might with a stateless functional component in ./src/components/. You’ll see why in a bit.

In ./src/components/Header/index.js import the newly created Container styled-component and replace the HeaderWrapper styled-component with it.

// ./src/components/Header/index.js

import { Container } from '../../styledComponents/layout';

... const Header = ({ background }) => (

<HeaderContainer background={background}>

<Container>

<Heading1>

<StyledLink to="/">Polling App</StyledLink>

</Heading1>

</Container>

</HeaderContainer>

); ...

Now, head over to ./src/layouts/index.js and import that Container styled-component we just defined from the stylesComponents/layout.js file. Notice that the <div> with the inline styles has almost the same styles as our Container component. the difference being it has a paddingTop: 0 rule set. Our Container component, however, defines padding-top with 1.45rem. We’ll override that padding-top with a handy helper method defined on all styled-components .extend. .extend… well extends the CSS defined on a component allowing you to define a base set of styles on a component, then, whenever necessary, extend those rules.

This is why we don’t wrap component in the ./src/styledComponents directory with a function. Doing so would cause all the helper methods to no longer be accessible on the component we’re importing.

While we’re at it, let’s spruce up that boring Header background-color! (Shameless plug time) — Head over to www.grabient.com and grab yourself a gradient, be sure to untick prefixes as styled-components already handles all vendor prefixes for you. Pass the gradient of your choice that should be copied into your clipboard as a background prop that we defined inside our Header component earlier.

Pulling data into components using GraphQL

Notice the title prop we’re passing to <Helmet>, recall that its value is the same value as siteMetadata.title defined in ./gatsby-config.js. Let’s reuse that value as our site’s title so that if in the future we change the title of our PWA, we only have to do so in one place. To accomplish this, we’ll make use of the gaphql function gatsby globally exposes so that developers can pull data declaratively into our components at build-time. We won’t be covering GraphQL today, however, if you’re interested in learning more, here’s an awesome resource.

Let’s update the ./src/layouts/index.js file once again:

note that the graphql function also makes use of template literal invocations to define queries and mutations.

Test it out! Watch that Gatsby.js magic update the site title as well as the Header when you save the ./gatsby-config.js with an updated title. Things like this are the reason why I love developing with Gatsby and other projects that utilize Webpack.

The Index Page

Now let’s create the landing page for our polling app. We’ll add some content that’ll really sell our polling application, after all, it’s going to be way better than anything out there already. We’ll also need a button for creating a poll.

From now on I’m not going to focus as much on styled-components or styling at all for that matter, I feel like I’ve shown you enough to give you an idea of what styled-components is capable of. To find out more head over to the styled-components website found here.

Add a Button component to a new file in ./src/styledComponents/ called theme.js:

I also suspect we’ll reuse the Heading2 component located inside the index page. Let’s create a file typography.js inside ./src/styledComponents/:

Now update the index.js page in ./src/pages/:

The NewPoll Page

Let’s go ahead and install a few dependencies we’ll need.

npm install react-sortable-hoc short-id

You may have to restart your gatsby server after installing these dependancies.

We’ll use short-id to generate ids for each new option added and eventually the id for each poll. react-sortable-hoc will be used so that the creator of a poll can change the order of his poll options if he so chooses.

Create a new index.js file inside ./src/components/NewPoll/:

To get things working, add a new.js page in ./src/pages/ that acts as the container to this component.

Head over to http://localhost:8000/new by clicking the New Poll button and checkout the new poll page functionality. In reality, all we’ve got here is a basic to-do app with some client-side CRUD operations. But we’ve made some really good progress towards the final product!

the user can create a new option by clicking the add button or hitting the enter key when inputting text.

a new option by clicking the button or hitting the key when inputting text. they can update an existing option by double clicking an option and editing the text or change its position by clicking, holding, and dragging the drag handle.

an existing option by double clicking an option and editing the text or change its position by clicking, holding, and dragging the drag handle. they can delete an option by clicking the x.

If you liked it Clap it up!

That concludes Part 1 of this tutorial. In the next part, we’ll build out the poll page, set up Firebase authentication and Firestore, deploy our app with Netlify, and finally run some lighthouse tests to see how we score on a 0 to 100 scale to determine if what we’ve created and be considered a progressive web application. That all sounds like quite a bit, but I think you’ll all be pleasantly surprised by just how easy these tasks are thanks to the tools we’re making use of.

Be sure to follow us for more blogs every Monday and Tuesday! We’ll have Part 2 out for you in no time. See ya!

John Korzhuk is a software developer and proud Unicorn. He specializes in full-stack javascript, React.js, and web development. Outside of work his interests include gaming, esports, and learning about anything that he finds interesting. You can find on twitter @johnkorzhuk.

Want to build magical experiences together? Contact us!

E-mail: adam-leonard@unicornagency.com

Twitter: @UnicornHQ

Website: http://www.unicornagency.com