We have created a service that adds our SVG files to the Angular Material Icon registry.
In this minimal version we have a single Asset
object keyed on an SVG
object container.
export const SVG:KeyAsset = {
FS_LOGO: {
name: 'fs_logo',
url: 'https://raw.githubusercontent.com/fireflysemantics/logo/master/l1.svg'
}
}
We register this asset in the MatIconRegistry
using the name
and url
properties.
import { Injectable } from '@angular/core';
import { DomSanitizer } from "@angular/platform-browser";
import { MatIconRegistry } from '@angular/material/icon';
export interface Asset {
name: string;
url: string;
}
export interface KeyAsset {
[key: string]: Asset;
}
export const SVG:KeyAsset = {
FS_LOGO: {
name: 'fs_logo',
url: 'https://raw.githubusercontent.com/fireflysemantics/logo/master/l1.svg'
}
}
@Injectable({
providedIn: 'root'
})
export class AssetService {
constructor(
private matIconRegistry: MatIconRegistry,
private domSanitizer: DomSanitizer) {
{
Object.keys(SVG).forEach(k=>{
this.matIconRegistry.addSvgIcon(
SVG[k].name,
this.domSanitizer.bypassSecurityTrustResourceUrl(SVG[k].url));
})
}
}
}
If we package this service in a library as is, it will not work.
The reason is we also have to rememember to add the HttpClientModule
as the MaterialIconRegistry
as the service depends on these modules to load and register the SVG files.
Therefore we want to create and package both the service and the module that will be imported in order to access the service.
We also want the service to be self initializing. We should only have to import and register the module
in order for the service to dynamically load the SVG
assets and make them ready for use by a MatIcon
element.
Approach
We will be producing this NPM package.
We can add this to an Angular project using the CLI
or Stackblitz and after registering the AssetsModule
.
This is the github repository containing the source code.
This is a youtube that outlines all the steps in creating the project and publishing it.
This is the module that will be packaged along with the AssetService
.
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { AssetService } from './assets.service';
import { MatIconModule } from '@angular/material/icon';
@NgModule({
declarations: [],
providers: [AssetService],
imports: [
CommonModule,
HttpClientModule,
MatIconModule
],
exports: []
})
export class AssetsModule {
constructor(private a:AssetService) {}
}
We've placed it along side the asset.service.ts
service in our Angular library. The module is exported by public-api.ts
in the Angular Package Format library. The module constructor injects the asset service, and this initializes the icon registry.
After the module is imported in our projects the mat-icon
containing the FS_LOGO
can be rendered like this:
<mat-icon [svgIcon]="SVG.FS_1_LOGO.name" style="width: 42px; height:42px; font-size: 42px"></mat-icon>
Demo
NPM Imported Module
This stackblitz depends on and imports the AssetsModule, thus demonstrating using the NPM Package:
Unpackaged Stackblitz Demo
This has the module and service locally within the Stackblitz: