Overwatch League-UI Pt 2: Project Setup

Oliver Baker
Headstorm
Published in
5 min readAug 12, 2019

Welcome to Part 2 of the Overwatch League UI tutorial! Last time, we took a high level look at the design language we want to emulate. In this post I’ll setup the four things needed to get us ready to build beautiful motion graphics:

  • A Git/NPM package: In order to keep the codesandboxes simple and focused, I’ll collect each post’s work in a git repository so that I can simply import it into future sandboxes.
  • Some Boilerplate CSS
  • Typography
  • A system for color-scheming and unit grid looking

By the end of this post, we’ll have touched on all the code necessary to build this, and have a codesandbox to demo it with all of the source code included:

Jump to the end to see the source code!

Importable NPM package

Here’s a link if you want to skip the minutia below and get straight to the juicy code! I’m starting with a create-react-library base, with some minor adjustments and imports.

Every post in this series will mark a new git tag, so that each post can reference a snapshot of the code as it was written at the time (warts and all). I’ll make a point to link to these medium pages in each README as appropriate.

Boilerplate CSS

There’s a short list of CSS I always add to projects, which make styling much easier to understand: removing the margin from the body element with margin: 0, box-sizing: border-box on every element to make padding sensible, and setting a base font-size for our rem to be based on.

body { margin: 0; }*, * *, * > * { box-sizing: border-box; }:root { font-size: 82.5% }

Typography

The official OWL broadcast uses the font “Industry”. It’s $30 on fonts.com, but I’ll be using my Adobe Typekit license to import it for the web. (don’t put your paid fonts directly into your public GitHub repo!)

To do that, I’ll export a function from the repository called linkFonts which will add the appropriate <link /> tags to the html <head />. We’ll have to run it every time the page mounts — which isn’t very elegant. Perhaps a higher ordered component will be a better solution in the future. (withFonts sounds nice)

Color Scheme

In a previous UI library where I relied on a color scheme, I built a nested lookup table. It’s a simple nested JS object, but it’s accessed through a Proxy, so that we can gracefully fail, return a default, or do some other logic when an invalid color is accessed.

Unit grid

Using the same system as the color scheme proxy, we’ll build some basic grid/baseline metrics to keep the layouts we build consistent:

These will be adjusted over time, but having the system from day one will enable us to tweak those numbers globally with little effort.

Let’s use it!

Now we have a published NPM package we can import into codesandbox. Let’s start by building a dead-simple team color chart to show off our metrics, colors, and typography.

import React from "react";
import ReactDOM from "react-dom";
import styled from "styled-components";
import { Colors, Dimensions, linkFonts } from "react-owl-ui";
import "./styles.css";

Here are the imports we’ll need to build the page. Our CSS will come from styled-components, while our colors, dimensions, and fonts will be served from our brand-new react-owl-ui package! The boilerplate css will live in styles.css for now. Let’s look at the render function of our App container next:

<TeamList>
{Object.keys(Colors).map(teamName => (
<TeamRow>
<TeamName>{teamName}</TeamName>
<TeamColor
width={Dimensions.xlarge}
color={Colors[teamName].primary}
/>
<TeamColor
width={Dimensions.large}
color={Colors[teamName].secondary}
/>
<TeamColor
width={Dimensions.medium}
color={Colors[teamName].tertiary}
/>
</TeamRow>
))}
</TeamList>

Pretty easy to follow, right? We start by mapping over each color scheme object, wrap each team in a TeamRow, and finally add the color components. Each component is named for its purpose to make it easy to see what the structure of the page is. We’re passing the colors and widths as props to TeamColor, which we’ll turn into CSS in the styled declarations here:

const TeamList = styled.div`
display: flex; // let the list be flexible
flex-flow: column wrap; // the list is a multi-columned list
height: 100vh; // it fits the window (no scrolling)
max-width: 30rem; // each column is only 30rem wide
text-transform: uppercase; // all the text will be UPPERCASE
`;
const TeamRow = styled.div`
margin: 1rem; // a bit of spacing around each team
display: flex; // items flex to fill the space
flex-flow: row nowrap; // items are laid-out horizontal
align-items: center; // items are vertically centered
justify-content: flex-start; // items are left-aligned
`;
const TeamName = styled.span`
flex: 1 0 auto; // the names can grow but not shrink
text-align: left; // they are left-aligned
margin-right: 1rem; // a bit of space from the colors
font-family: "Industry"; // they'll use the Industry font
`;
const TeamColor = styled.div`
${({ color, width }) => ` // this is how accept the props
height: 3rem; // the height of each color is fixed
width: ${width}; // use the width prop for width
background-color: ${color}; // use the color prop for BG color
`}
`;

And there you have it! Check out the example and full source-code below:

--

--

Oliver Baker
Headstorm

Team Lead at Headstorm · CSS Connoisseur · React Revolutionary