Angular Material and semantic icon identifiers

Photo by Harpal Singh on Unsplash

What we have:

  • Angular Material project,
  • with one or more icon libraries included as dependencies,
  • maybe some custom icons and/or icon fonts added as assets,
  • and icons used like this:
<span class="material-icons">arrow_circle_down</span>
<mat-icon fontSet="fa" fontIcon="fa-trash”></mat-icon>
<mat-icon fontSet=“custom-iconfont”>R</mat-icon>
  • and if you pass icons around as parameters to your components, things can get ugly:
export interface MenuItem {
caption: string;
link: string;
fontSet?: string;
fontIcon?: string;
iconContent?: string;
}

What we want to have:

  • semantically meaningful and uniform way to refer to icons in our code,
  • using single string as an identifier, e.g. in template:
<mat-icon fontIcon="add-to-basket"></mat-icon>
  • or in TypeScript:
export interface MenuItem {
caption: string;
link: string;
icon: string;
}

How to achieve that:

  • assign meaningful names to all icons in the app,
  • add all of them to a single CSS “namespace”,
  • make that “namespace” a default one for <mat-icon>.

And now step-by-step, using Font Awesome and SCSS as an example:

  1. Add npm package:
npm i -D @fortawesome/fontawesome-free

2. Add new entry to all asset sections of angular.json:

"assets": [
{
"glob": "**/*",
"input": "./node_modules/@fortawesome/fontawesome-free/webfonts/",
"output": "./assets/fa"
}
]

3. Import Font Awesome source into main project stylesheet (or create a separate file with and then import it from src/style.scss):

@import '~@fortawesome/fontawesome-free/scss/fontawesome', '~@fortawesome/fontawesome-free/scss/solid';$fa-font-path: "../assets/fa";

4. Define your icons using nice, descriptive names which are relevant to your app, and place them into some “namespace”:

.your-namespace {
&.add-new-item {
@extend .fa, .fa-plus;
}
&.remove-item {
@extend .fa, .fa-trash;
}
}

5. Repeat steps 1–4 for any other icon set you need to use, be it some NPM package, or icon font provided by designer. (Note: if your icons are provided as .svg files, you can combine them into a single font, using tools like https://icomoon.io/app/.)

6. Make that namespace default, e.g. from AppModule:

class AppModule {
constructor(registry: MatIconRegistry) {
registry.setDefaultFontSetClass(‘your-namespace’);
}
}

7. And now you can use it in templates like this:

<mat-icon fontIcon="add-new-item"></mat-icon>

And I think that looks good.

--

--

--

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Code splitting with React

Odoo13 writing to one2many and many2many field — Unpacking

Deploying a Node app with TimelineJS on AWS — part 4 of 4 (deploying on AWS EC2)

Task:- 7.1

Pass Variables As Values and As References in JavaScript

Using Fetch With An API

April 2018 Release Updates from the Node.js Project

Easily Create StockCharts for your Dashboards using CanvasJS

CanvasJS JavaScript StockCharts

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Alex Kunin

Alex Kunin

More from Medium

Why Should You Learn Angular?

Extending Angular CLI

Angular 12 @Input And @Output

Getting started with Angular Testing: Cypress