Tutorial: Project Clarity and Angular CLI

beeman 🐝
6 min readFeb 6, 2017

Today we will be looking at integrating Project Clarity with Angular CLI.

What is Project Clarity? From their website:

Project Clarity is an open source design system that brings together UX guidelines, an HTML/CSS framework, and Angular 2 components. Clarity is for both designers and developers.

Prerequisites

This tutorial requires Angular CLI to be installed globally. To get the latest version, run this command:

$ npm install -g @angular/cli@latest

Scaffold a new project

Now that we have the ng command available, we will create a new Angular CLI project using ng new.

$ ng new tutorial-angular-styling-clarity

This command will create a new directory called tutorial-angular-styling-clarity and create the new Angular app in there.

Install the Clarity dependencies

Project Clarity consists of a number of dependencies that we will install using npm and save to our devDependencies:

$ npm install --save-dev clarity-icons clarity-ui clarity-angular  @webcomponents/custom-elements@1.0.0-alpha.3 mutationobserver-shim@0.3.2 

Add the CSS files

Once this is done we will configure Angular CLI to load the right scripts and CSS files.

To do so we open angular-cli.json from the root of our new project and find the styles array, that currently has one entry, styles.css.

In this styles array we add the reference to the clarity-icons and clarity-ui css files, making it look like this:

"styles": [
"../node_modules/clarity-icons/clarity-icons.min.css",
"../node_modules/clarity-ui/clarity-ui.min.css",
"styles.css"
],

Add the JS files

Now that the styles are in place, we will add 3 javascript files to the scripts array, making it look like this:

"scripts": [
"../node_modules/mutationobserver-shim/dist/mutationobserver.min.js",
"../node_modules/@webcomponents/custom-elements/custom-elements.min.js",
"../node_modules/clarity-icons/clarity-icons.min.js"
],

Load the Angular module

Now that the dependencies are all installed and configured, we can move into our Angular AppModule to configure the ClarityModule. This will make sure we can use Clarity in our app.

Open src/app/app.module.ts and add the following line at the top on the list of dependencies:

import { ClarityModule } from 'clarity-angular';

The will tell TypeScript to load the module from the clarity-angular package. To use it we will need to add the following line to the imports array inside the @NgModule decorator:

ClarityModule.forRoot(),

The base configuration is now done. When you now start your app you will see that the default app works! message got styled, sporting a fancy sans-serif font. Great!

$ ng serve

Using Project Clarity

Generating UI module and components

Project Clarity is quite an advanced framework that it allows you to quickly create a complete interface. Let’s set up some UI elements.

To quickly create a structure for our UI we will use the ng generate command, or ng g for short.

# create the ui module
$ ng g m ui
# create the layout component
$ ng g c ui/layout -is -it --spec false
# create components for header, sidebar and main view
$ ng g c ui/layout/header -is -it --spec false
$ ng g c ui/layout/sidebar -is -it --spec false
$ ng g c ui/layout/main -is -it --spec false

The parameters I use in the ng g command do the following:

-is inline style instead of separate CSS file
-it inline template instead of separate html file.
--spec false skips generating a spec file for testing.

The structure that is create now looks like this:

./src/app/ui
β”œβ”€β”€ layout
β”‚ β”œβ”€β”€ header
β”‚ β”‚ └── header.component.ts
β”‚ β”œβ”€β”€ layout.component.ts
β”‚ β”œβ”€β”€ main
β”‚ β”‚ └── main.component.ts
β”‚ └── sidebar
β”‚ └── sidebar.component.ts
└── ui.module.ts

In order to use these components in our app we need to import the newly created UiModule in AppModule. We open src/app/app.module.ts, add the import statement:

import { UiModule } from './ui/ui.module';

And add UiModule to the imports array inside the @NgModule decorator.

Because we will be using Clarity inside our UiModule we need to import it there too. We open src/app/ui/ui.module.ts , add the import statement:

import { ClarityModule } from 'clarity-angular';

And add ClarityModule to the imports array inside the @NgModule decorator, just like before but now without calling the .forChild() method.

The last thing to do inside the UiModule is add an exports array and export LayoutModule, as we will reference it in our AppComponent.

The UiModule will now look something like this:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { LayoutComponent } from './layout/layout.component';
import { HeaderComponent } from './layout/header/header.component';
import { SidebarComponent } from './layout/sidebar/sidebar.component';
import { MainComponent } from './layout/main/main.component';
import { ClarityModule } from 'clarity-angular';

@NgModule({
imports: [
CommonModule,
ClarityModule,
],
declarations: [
LayoutComponent,
HeaderComponent,
SidebarComponent,
MainComponent,
],
exports: [
LayoutComponent,
]
})
export class UiModule { }

Wiring up and creating the UI Components

AppComponent

We start by updating the template of our main AppComponent , open src/app/app.component.html and change the content to this:

<app-layout>
<h1>{{title}}</h1>
</app-layout>

In there we reference the LayoutComponent by it’s selector app-layout .

LayoutComponent

Open src/app/ui/layout.component.ts and update the template:

template: `
<div class="main-container">
<app-header></app-header>
<app-main>
<ng-content></ng-content>
</app-main>
</div>
`,

This wraps our content in a div with class main-container, we then reference the HeaderComponent and the MainComponent, which we tell to embedd the app content using the ng-content component.

HeaderComponent

Open src/app/ui/layout/header/header.component.ts and update the template:

template: `
<header class="header-1">
<div class="branding">
<a class="nav-link">
<clr-icon shape="shield"></clr-icon>
<span class="title">Angular CLI</span>
</a>
</div>
<div class="header-nav">
<a class="active nav-link nav-icon">
<clr-icon shape="home"></clr-icon>
</a>
<a class=" nav-link nav-icon">
<clr-icon shape="cog"></clr-icon>
</a>
</div>
<form class="search">
<label for="search_input">
<input id="search_input" type="text" placeholder="Search for keywords...">
</label>
</form>
<div class="header-actions">
<clr-dropdown class="dropdown bottom-right">
<button class="nav-icon" clrDropdownToggle>
<clr-icon shape="user"></clr-icon>
<clr-icon shape="caret down"></clr-icon>
</button>
<div class="dropdown-menu">
<a clrDropdownItem>About</a>
<a clrDropdownItem>Preferences</a>
<a clrDropdownItem>Log out</a>
</div>
</clr-dropdown>
</div>
</header>
<nav class="subnav">
<ul class="nav">
<li class="nav-item">
<a class="nav-link active" href="#">Dashboard</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Projects</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Reports</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Users</a>
</li>
</ul>
</nav>
`,

This is quite a large snippet but it should be fairly easy to understand what it does:

  • Define the Header with class header-1 (which sets a color from 1–6).
  • Add the branding using an icon and a title.
  • Add 2 header icons, for Home and Settings.
  • Add a search box with a placeholder text.
  • Add a user icon and a dropdown with 3 items.
  • Add sub navigation with 4 links.

MainComponent

We are almost there. Open src/app/ui/layout/main/main.component.ts and update the template:

template: `
<div class="content-container">
<div class="content-area">
<ng-content></ng-content>
</div>
<app-sidebar class="sidenav"></app-sidebar>
</div>
`,

In this component we wrap the sidebar and content area in a div with the content-container class.

Below the app-sidebar selector we create yet another div with the content-area class, this is where the main content of our app will be displayed. We do this using the Angular built-in ng-content component.

SidebarComponent

The last one! Open src/app/ui/layout/sidebar/sidebar.component.ts and update the template:

template: `
<nav>
<section class="sidenav-content">
<a class="nav-link active">Overview</a>
<section class="nav-group collapsible">
<input id="tabexample1" type="checkbox">
<label for="tabexample1">Content</label>
<ul class="nav-list">
<li><a class="nav-link">Projects</a></li>
<li><a class="nav-link">Reports</a></li>
</ul>
</section>
<section class="nav-group collapsible">
<input id="tabexample2" type="checkbox">
<label for="tabexample2">System</label>
<ul class="nav-list">
<li><a class="nav-link">Users</a></li>
<li><a class="nav-link">Settings</a></li>
</ul>
</section>
</section>
</nav>
`,

And there we have it, a create base UI built with Angular CLI and Project Clarity

The result of scaffolding an app, creating a hand full of components and wiring them up.

Pretty darn cool if you ask me! Check the live version here: https://beeman.github.io/tutorial-angular-styling-clarity/

Project Clarity has a lot more to offer, and you can find it all on the website:

https://vmware.github.io/clarity/documentation

As usual the demo project can be found on my GitHub:

https://github.com/beeman/tutorial-angular-styling-clarity

In case you have any issues or questions, use the comments below or hit me up on Twitter @beeman_nl .

Happy coding!

Need help?

Need support for your Angular, Ionic, Firebase, NodeJS or TypeScript project? Looking for long-term mentorship? Feel free to book a 1-on-1 session with me on CodeMentor.

https://www.codementor.io/beeman

--

--