Replace mat-icon with SVG graphic
You can use angular-svg-icon
The angular-svg-icon is an Angular 7 service and component that provides a means to inline SVG files to allow for them to be easily styled by CSS and code.
The service provides an icon registery that loads and caches a SVG indexed by its url. The component is responsible for displaying the SVG. After getting the svg from the registry it clones the SVGElement and the SVG to the component's inner HTML.
For more information: https://www.npmjs.com/package/angular-svg-icon
Unfotunatley this does not exactly solve your problem, because you will need to use the argument svgIcon
on the mat-icon
element instead of using the innerText
of mat-icon
but otherwise it works:
- You have to allow to angular to import from svg's by declaring the module.
- To import/inline the icons into javascript, you will have to override the loader. This can be achieved through using the
raw-loader
. - Now you will be able to import the svg into angular and register them through the
MatIconRegistry
;
As an example:
// src/typings.d.ts
declare module '*.svg' {
const svg: string;
export default svg;
}
// src/app/app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { DomSanitizer } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { MatIconModule, MatIconRegistry } from '@angular/material';
import { AppComponent } from './app.component';
import { HelloComponent } from './hello.component';
import thumbsUp from '!!raw-loader!./thumbs-up.svg';
@NgModule({
imports: [
BrowserModule,
FormsModule,
MatIconModule
],
declarations: [ AppComponent, HelloComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule {
constructor(iconRegistry: MatIconRegistry, sanitizer: DomSanitizer) {
iconRegistry.addSvgIconLiteral(
'thumbsUp', sanitizer.bypassSecurityTrustHtml(thumbsUp));
}
}
// src/app/app.component.html
<mat-icon svgIcon="thumbsUp"></mat-icon>
// src/app/thumbs-up.svg
<svg>...</svg>
Another approach would be to install @mdi/svg
npm install @mdi/svg
and then follow the steps above, with the difference to import each necessary icon as well, e.g. expand_more
and chevron_right
so in src/app/app.module.ts
// src/app/app.module.ts
...
import expandMore from '!!raw-loader!@mdi/svg/svg/chevron-down.svg';
import chevronRight from '!!raw-loader!@mdi/svg/svg/chevron-right.svg';
...
export class WeddingDayModule {
constructor(
private iconRegistry: MatIconRegistry,
private sanitizer: DomSanitizer
) {
iconRegistry
.addSvgIconLiteral('chevron_right', sanitizer.bypassSecurityTrustHtml(chevronRight))
.addSvgIconLiteral('expand_more', sanitizer.bypassSecurityTrustHtml(expandMore));
}
}
And in the html just as a simplification... but you will get the idea...
//src/app/app.component.html
...
<mat-icon [svgIcon]="expanded ? 'chevron_right' : 'expand_more'" (click)="expanded = !expanded"></mat-icon>
...
the down side with this approach is, that you will have to register all the icons you want to use... But at least you stay in the same domain of change. Instead of using the ligatures you can change them all through the svgIcon
and you get more icons than just the icons the outdated material-design-icons
library holds.
I hope that helps