A lot of my components use Angular Material's mat-icon
to display icons from an icon font and svgs from an svg icon set. In order to configure this, my app.component.ts
injects MatIconRegistry
and registers the font class and svg icon set with it. I'm struggling to understand how to make this work in Storybook. Is there a way to configure the equivalent to app.component.ts
?
Can you please share how you exactly inject this? Here is an example of how you can use a custom module metadata within your stories
Here's an example of howapp.component.ts
would use this to point <mat-icon>
component to the icon font throughout the application.
constructor(private matIconRegistry: MatIconRegistry) {
this.matIconRegistry.setDefaultFontSetClass('my-icons');
}
Then in another component I can do <mat-icon>edit</mat-icon>
.
Do you have a repo with an unworking example?
solved
Add preview-head.html in .storybook folder with material icon font in HTML
like this file
https://github.com/amorenew/travel-angular/blob/master/.storybook/preview-head.html
or
https://github.com/amcdnl/material-storybook/blob/master/.storybook/preview-head.html
then a sample to add Mat Icon Module in storybook like this file
https://github.com/amcdnl/material-storybook/blob/master/stories/button.stories.ts
@bmayen tell me if it works
Thanks for the feedback @amorenew . The problem I'm having is that I'm not using the Material icon font. If you use your own icon font and/or separate SVGs, you need to register them via MatIconRegistry service. This registration happens automatically, by default, for the Material icon font, but you need to specify it yourself for custom usage. So it's not as simple as just importing the module and using the default font in my case.
@igor-dv, sorry, the project I'm working on is under NDA. But this isn't really project-specific. The whole of the use-case is summarized in the constructor
code sample above.
I suppose this issue is really more generic than Material Icons. We also use the ngx-translate
library and there is additional configuration that needs to happen with it via a service which is injected in app.component.ts
. Same situation as Material icons config.
So, generically, the issue here is, "how do you deal with components which are dependent on services injected and configured in their parent component (the root app.component for example)?"
@bmayen
Did you added all required services and modules like the following code:
DummyDataService
is my service for data
and MatIconRegistry
is service too so it should be in decorator too.
storiesOf("Forms", module)
.addDecorator(
moduleMetadata({
declarations: [
AutocompoleteComponent,
SearchBarComponent,
SearchListComponent,
SearchListRowComponent,SampleDialog, SearchListRowHotelComponent, SearchListRowCountryComponent
],
imports: [
BrowserModule,
MaterialModule,
FormsModule,
ReactiveFormsModule,
HttpClientModule,
HttpModule,
CustomUiModule,MatIconModule
],
providers: [DummyDataService, HttpClientModule],
// bootstrap: [AppComponent],
entryComponents:[SampleDialog]
})
)
My example is simpler than that, but generally, yes. The issue is that I need to configure the MatIconRegistry service in app.component. Need to know how I can inject a service and call methods on it like so: this.matIconRegistry.setDefaultFontSetClass('my-custom-icon-font');
.
This particular use case is described here: https://material.angular.io/components/icon/overview#registering-icons. But again, this isn't unique to Angular Material Icons. ngx-translate has a similar requirement, for instance.
I was able to workaround this by creating a bootstrap.module.ts
which injects and configures these services in its constructor. This is imported by my app.module
and also passed to Storybook's moduleMetadata
.
~@bmayen could you share your solution in a gist? I am facing the same issue today and I thought I had it sorted but my icons do not show up in storybook.~
Nevermind, it was a simple import bug - was inconsisently importing MatIconRegistry
from the root and /icons
in two locations and this was, I assume, creating two registries.
@bmayen could you show some sample code of your solution? Having the same problem two years later
I was able to workaround this by creating a
bootstrap.module.ts
which injects and configures these services in its constructor. This is imported by myapp.module
and also passed to Storybook'smoduleMetadata
.
@bmayen I'm really having a hard time getting this to run. Could you please post your solution? Thaks in advance.
@zacko83 here is an example of how you can do it.
@NgModule({
imports:[
HttpClientModule
]
})
export class MatIconRegistryModule {
constructor(
private matIconRegistry: MatIconRegistry,
private domSanitizer: DomSanitizer
){
this.matIconRegistry.addSvgIcon(
"map",
this.domSanitizer.bypassSecurityTrustResourceUrl("/icons/map-icon.svg")
).addSvgIcon(
"reputation",
this.domSanitizer.bypassSecurityTrustResourceUrl("/icons/fame-icon.svg")
).addSvgIcon(
"prosperity",
this.domSanitizer.bypassSecurityTrustResourceUrl("/icons/diamond-icon.svg")
).addSvgIcon(
"experience",
this.domSanitizer.bypassSecurityTrustResourceUrl("/icons/experience-icon.svg")
).addSvgIcon(
"treasure",
this.domSanitizer.bypassSecurityTrustResourceUrl("/icons/treasure-icon.svg")
).addSvgIcon(
"level",
this.domSanitizer.bypassSecurityTrustResourceUrl("/icons/level-icon.svg")
);
}
}
after that, you should be able to import it either in an app module or in a specific story
// app.module.ts
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
BrowserAnimationsModule,
MaterialModule,
MatIconRegistryModule
],
// your.component.stories.ts
export const YourStory = () => ({
moduleMetadata: {
imports: [
MatIconRegistryModule,
// other configuration here
]
}
});
Just make sure you have set a proper output for your assets in angular.json
because then you will need to deal with two separate configurations of icons for application and for stories.
Most helpful comment
solved
Add preview-head.html in .storybook folder with material icon font in HTML
like this file
https://github.com/amorenew/travel-angular/blob/master/.storybook/preview-head.html
or
https://github.com/amcdnl/material-storybook/blob/master/.storybook/preview-head.html
then a sample to add Mat Icon Module in storybook like this file
https://github.com/amcdnl/material-storybook/blob/master/stories/button.stories.ts
@bmayen tell me if it works