Building with the Clarity Design System

With Angular 2 comes new features as well as new syntax for building web apps. In this walkthrough, we’re going to flex some developer UX, by building an Angular 2 app on top of VMware’s Project Clarity design system.

As with any system framework, the devil is in customizing the features for your project needs. While this walkthrough is a bit lengthy and I believe you can leverage it in the following ways:

  • skim the article top to bottom to understand the general flow of building with a design system
  • read thoroughly and follow along by implementing a project of your own using the frameworks I use in the article

So, we’ll jump in to a hands-on project of styling a simple app with Clarity.

What’s Project Clarity?

According to VMware, “Clarity is for both designers and developers.” Project Clarity is UX guidelines, HTML/CSS framework, and Angular components open sourced for use in software.

By the way, I work as a UX Engineer. If you’re curious to learn more about developing with design systems or have other comments on the UI solutions I’m showcasing here, get in touch.

Prerequisites

We’ll start by using a global install of the Angular CLI. To get the latest version, run the following command:

$ npm install -g @angular/cli@latest

Create a new project

Now that we have access to the ng command, we’ll use Angular CLI to build a new project with ng new.

$ ng new build-with-clarity

This command creates a new directory called build-with-clarity and creates the new Angular app.

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 @clr/icons @clr/angular @clr/ui @webcomponents/custom-elements@1.0.0 — save

Add Clarity to style your app

Whether you’re using css or a sass compiler, you can load the Clarity design scripts to your project with Angular CLI.

Open the angular.json file from the root of the new project and find the styles array, that currently has one entry, styles.css.

In this styles array add the file reference to the clr-icons and clr-ui css files. It will look like this:

“styles”: [

“../node_modules/@clr/icons/clr-icons.min.css”,

“../node_modules/@clr/ui/clr-ui.min.css”,

“styles.css”

],

Add the JS files

Once the styles are in place, add 2 JavaScript files to the scripts array. It will look like this:

“scripts”: [

… any existing scripts

“../node_modules/@webcomponents/custom-elements/custom-elements.min.js”,

“../node_modules/@clr/icons/clr-icons.min.js”

]

Load the Angular module

With dependencies in place, we can add the ClarityModule in the Angular AppModule to. This instantiates Clarity in the 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’;

This call to TypeScript loads 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 basic configuration is now complete. When you now serve your app using the command below you will get the default page app works! message with new sans-serif font styling. Great!

$ ng serve

Generating UI module and components

The benefit of working with a design system like Project Clarity is that it adds a consistent modern user experience your application or website, that frees up time for your team to focus on other complexities of the application.

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

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

Integrate routing with the app

Note that applications won’t include routing by default. When building out feature modules, use the Angular CLI to create a project that will use routing, set the — routing option for the project and for each NgModule.

When you create or initialize a new project with the CLI ng new command or a new app with the ng generate app command, specify the — routing option. This tells the CLI to include the @angular/router npm package and create a file named app-routing.module.ts.

$ ng generate module my-module — routing

Add feature modules

Next, we’ll create additional NgModule for the project and add routing.

For example, the following command generates an NgModule with routing.

# create the ui module with routing
 $ ng g m ui — routing

We’re going to create the default components for each module.

# 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 ng g command parameters 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.

Architecturally the scaffolding now looks something 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. Open the src/app/app.module.ts, add the import statement:

import { UiModule } from ‘./ui/ui.module’;

Add the UiModule to the imports array inside the @NgModule decorator. Just as 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

Now update 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>

From there lets create a reference for the LayoutComponent by it’s selector app-layout. 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 embeds the app content using the ng-content component.

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 creates an html template for the following:

· Defines the Header with class header-1 to set the color.

· Adds branding with 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.

Accordingly, we need to update the main components template. 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 create yet another div with the content-area class, this is where the main content of our app will be displayed. Do this using the Angular built-in ng-content component.

SidebarComponent

Lastly, 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>
 `,

That’s a wrap! A base UI built with Angular CLI and Project Clarity.

Figure: Website built with Clarity Design System

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 demo version here:

https://github.com/clevelandrachel/DesignPerformance

Project Clarity has more design system guidance on the website:

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

Any thoughts or comments, use the comments below or ping me on Twitter @clevelandrachel.

Happy coding!