typescript - Importarea modulelor de pictograme în Angular Storybook
Introducere
Încerc să construiesc componente UI Angular folosind Storybook și mă confrunt cu o problemă în care Storybook nu afișează nicio pictogramă în componente. Folosesc Angular Icons și acestea se redau corect atunci când componenta este apelată în app-component.html, dar nu atunci când sunt afișate în Storybook (din card.component.stories.ts).
Soluții încercate
Am analizat această postare cu o problemă similară în React, dar nu am avut noroc cu comentariile sugerate din ea.
Când inspectez consola pentru o posibilă eroare, primesc o eroare care îmi spune 'ng-icon' nu este un element cunoscut. M-am referit la această întrebare pentru a încerca să rezolv acest lucru, deoarece am crezut că s-ar putea să nu fie o eroare specifică Storybook, ci altceva. Totuși, răspunsul sugerat nu a rezolvat problema mea în Storybook.
M-am întors la documentația Angular Icons și am reușit să afișez icoanele în Storybook făcând componenta mea o componentă independentă (vedeți aici pentru mai multe informații despre acest lucru și ce sugerează Angular Icons). Cu toate acestea, acest lucru a făcut ca toată tematica mea globală să fie anulată deoarece am făcut componenta o componentă independentă.
Unde să mergem acum?
Așadar, m-am întors la punctul de plecare cu problema mea. Nu sunt foarte sigur încotro să merg, dar iată câteva gânduri pe care le-am avut:
- Pictogramele sunt, de fapt, compilate și generate ca SVG-uri. Poate trebuie să mă joc puțin cu această idee în Storybook (acest articol a fost ceva ce am găsit rapid și care părea că ar putea ajuta)
- Lipsa mea de experiență cu Angular se vede, și aceasta este o problemă ușoară de rezolvat pe care nu o știu ("Oh, nu ai importat
fooînbar, lucru pe care trebuie să-l faci de fiecare dată când folosești module în Angular" tip de problemă) - Aceasta este o eroare cunoscută (nu am găsit nimic care să spună asta sau pe cineva cu o problemă similară)
Cod
Iată cum arată componenta mea (acest cod este doar pentru un 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
Nu sunt chiar sigur că fișierul SCSS este foarte important, deoarece este doar stilizarea mea specifică pentru componentă și nu pentru ng-icon, așa că l-am omis.
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 { }
Aș aprecia orice ajutor. Am încercat să fac acest lucru clar, dar din nou lipsa mea de experiență cu Angular s-ar putea să fie vizibilă aici, așa că nu ezitați să puneți întrebări pentru clarificare, și pot încerca să răspund la ele. Mulțumesc anticipat.
Răspuns #1
Testat pe "@storybook/angular": "^8.0.6"
Cred că <ng-icon /> nu este recunoscut pentru că NgIconsModule nu este importat în story, așa că nu poate să se potrivească cu niciun component pentru selectorul specificat.
Așa cum este descris în acest tutorial, poți importa modul în poveștile tale folosind opțiunea decorators și funcția ajutătoare moduleMetadata după cum urmează:
import { Meta, moduleMetadata, StoryObj } from "@storybook/angular"
import { NgIconsModule } from "@ng-icons/core"
import { bootstrapCalendar3, bootstrapActivity, bootstrapStar } from "@ng-icons/bootstrap-icons";
import { CardComponent } from "./card.component"
const meta: Meta<CardComponent> = {
/* --- Will import NgIconsModule for all stories in this file --- */
decorators: [
moduleMetadata({
imports: [NgIconsModule.withIcons({ bootstrapCalendar3, bootstrapActivity, bootstrapStar })],
}),
],
/* --- */
component: CardComponent,
argTypes: {
selected: { control: "boolean" },
title: { control: "text" },
date: { control: "text" },
status: { control: "text" },
claimer: { control: "text" },
},
}
export default meta
type Story = StoryObj<CardComponent>
export const Selected: Story = {
/* --- Will import NgIconsModule only for this story ---
decorators: [
moduleMetadata({
imports: [NgIconsModule.withIcons({ bootstrapCalendar3, bootstrapActivity, bootstrapStar })],
}),
],
--- */
args: { selected: true }
}