1

Introduction

I am trying to build out Angular UI components using Storybook and am running into an issue where Storybook won't render any icons in the components. I am using Angular Icons, and they render properly when the component is called in the app-component.html, but not when they are rendered within Storybook (from the card.component.stories.ts).

Attempted solutions

I've looked into this post with a similar issue in React, but had no luck with the suggested comments within it.

When I inspect the console for a possible error, I get an error telling me 'ng-icon' is not a known element. I referred to this question to try and solve this as I thought it might not be a Storybook-specific error but something else. However, the suggested answer did not fix my issue within Storybook.

I went back to the Angular Icons docs, and was able to get the icons to render in Storybook by making my component a standalone component (see here for more information on this and what Angular Icons suggests). However, this then caused all my global theming to be voided because I made the component a standalone component.

Where to go now?

So, back to square one with my issue. Not really sure where to go, but here a couple of thoughts that I had:

  1. The icons are actually compiled and rendered as SVGs. Maybe I need to toy with that idea within Storybook (this article was something I found quickly that looked like it might help)
  2. My inexperience with Angular is showing, and this is some easy fix that I don't know about ("Oh, you didn't import foo into bar, which you have to do every time you are using modules within Angular" type issue)
  3. This is a known bug (couldn't find anything saying this or anyone with a similar issue to this)

Code

Here is what my component looks like (this code is just for a proof of concept):

card.component.ts

import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-card',
  templateUrl: './card.component.html',
  styleUrls: ['./card.component.scss']
})
export class CardComponent {

  @Input() title: string = 'CardComponent';
  @Input() date: string = '1.1.23';
  @Input() status: string = 'New';
  @Input() claimer: string = 'John';
  @Input() selected: boolean = false;

  public get classes(): string {
    return this.selected ? 'selected' : 'deselected';
  }
}

card.component.html

<div class="card" [ngClass]="classes">
  <div class="card-header" [ngClass]="classes">
    <h3>{{title}}</h3>
  </div>
  <div class="card-details" [ngClass]="classes">
    <div class="column">
      <ng-icon name="bootstrapCalendar3"></ng-icon>
      <div class="column-value">{{date}}</div>
    </div>
    <!-- More of the same column element as above repeated here.
         I removed it to narrow the focus on the question. -->
    ...
  </div>
</div>

card.component.stories.ts

import { Story, Meta } from '@storybook/angular/types-6-0';
import { CardComponent } from "./card.component";

export default {
  title: "CardComponent",
  component: CardComponent,
  argTypes: {
    selected: { control: "boolean" },
    title: { control: "text" },
    date: { control: "text" },
    status: { control: "text" },
    claimer: { control: "text" },
  },
} as Meta;

const Template: Story<CardComponent> = (args: CardComponent) => ({
  props: args,
});

export const Selected = Template.bind({});

Selected.args = {
  selected: true
};

card.component.scss

Not really sure the SCSS file is super important, as it's just my specific styling for the component and not the ng-icon, so I've left it out.

app.module.ts

// There are more imports up here, but they are the 
// boilerplate Angular imports, so I've left them out to try and make this shorter
...
import { NgIconsModule } from "@ng-icons/core";
import { bootstrapCalendar3, bootstrapActivity, bootstrapStar } from "@ng-icons/bootstrap-icons";

import { CardComponent } from './components/card/card.component';

@NgModule({
  declarations: [
    AppComponent,
    CardComponent
  ],
  imports: [
    ...,
    NgIconsModule.withIcons({ bootstrapCalendar3, bootstrapActivity, bootstrapStar })
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Would love any and all help. I tried to make this clear, but again my inexperience with Angular might be showing through a lot here, so feel free to ask clarifying questions, and I can try to answer them. TYIA.

bwc
  • 1,732
  • 1
  • 14
  • 27

0 Answers0