Tutorial: Project Clarity and Angular CLI
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
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.