将 fontawesome 添加到故事书 Angular nx

问题描述 投票:0回答:1

我有一个 ui 组件:

import { CommonModule } from '@angular/common';
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { MatRippleModule } from '@angular/material/core';
import { TranslocoModule } from '@ngneat/transloco';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import { IconProp } from '@fortawesome/fontawesome-svg-core';
/**
 * Todo - Add description
 * Todo - Add a basic button and use them in dialogs, now we use outline buttons without hover shadow
 * Also remove no-shadow class
 * https://material.angular.io/components/button/overview
 *
 *  form: for when the button is of type submit and it's outside of the form tag. Add an id to the form with the same name
 *
 * @description
 * This component is used to render a button.
 *s
 * @example
 * <vetfysio-button
 *   [label]="'Button label'"
 *   [disabled]="false"
 *   (action)="action()">
 * </vetfysio-button>
 */
@Component({
  selector: 'vh-button',
  templateUrl: './button.component.html',
  styleUrls: ['./button.component.scss'],
  standalone: true,
  imports: [MatRippleModule, CommonModule, TranslocoModule, FontAwesomeModule],
})
export class ButtonComponent {
  @Input() label!: string;
  @Input() disabled?: boolean;
  @Input() color: 'basic' | 'primary' | 'secondary' | 'warning' | 'dark' =
    'basic';
  @Input() size: 'extra-small' | 'small' | 'base' | 'large' | 'extra-large' =
    'base';
  @Input() type: string = 'button';
  @Input() rounded: boolean = false;
  @Input() outline: boolean = false;
  @Input() prefixIcon?: IconProp;
  @Input() suffixIcon?: IconProp;
  @Input() shadow: boolean = true;
  @Input() cdkFocusInitial: boolean = false;
  @Input() form?: string;

  @Output() action = new EventEmitter<void>();
}

button.component.stories.ts:

import {
  Meta,
  StoryObj,
  moduleMetadata,
  argsToTemplate,
} from '@storybook/angular';
import { provideHttpClient } from '@angular/common/http';
import { within } from '@storybook/testing-library';
import { expect } from '@storybook/jest';
import { applicationConfig } from '@storybook/angular';
import { provideTransloco } from '@ngneat/transloco';
import { TranslocoHttpLoader, translocoConf } from '@vh-components/transloco';

import { ButtonComponent } from './button.component';
import {
  FaIconLibrary,
  FontAwesomeModule,
} from '@fortawesome/angular-fontawesome';
import { APP_INITIALIZER, importProvidersFrom } from '@angular/core';
import { faCoffee } from '@fortawesome/free-solid-svg-icons';

const meta: Meta<ButtonComponent> = {
  component: ButtonComponent,
  title: 'Design system/Buttons/Button',
  tags: ['autodocs'],
  decorators: [
    moduleMetadata({
      imports: [FontAwesomeModule],
      providers: [
        {
          provide: APP_INITIALIZER,
          useFactory: (iconLibrary: FaIconLibrary) => async () => {
            // Add any icons needed here:
            iconLibrary.addIcons(faCoffee);
          },
          // When using a factory provider you need to explicitly specify its dependencies.
          deps: [FaIconLibrary],
          multi: true,
        },
      ],
    }),
    applicationConfig({
      providers: [
        provideHttpClient(),
        provideTransloco({
          config: translocoConf,
          loader: TranslocoHttpLoader,
        }),
        // importProvidersFrom(TranslocoSharedModule), // TODO Why does this not work?
      ],
    }),
  ],
  render: (args: ButtonComponent) => ({
    props: {
      ...args,
    },
    template: `
        <vh-button ${argsToTemplate(args)}></vh-button>
    `,
  }),
};
export default meta;
type Story = StoryObj<ButtonComponent>;

export const Default: Story = {
  args: {
    label: 'text1',
    disabled: false,
    color: 'primary',
    prefixIcon: 'coffee',
  },
  argTypes: {
    color: {
      control: {
        type: 'select',
      },
      options: ['basic', 'primary', 'secondary', 'warning', 'dark'],
    },
  },
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
    expect(canvas.getByText(/button works!/gi)).toBeTruthy();
  },
};

export const disabled: Story = {
  args: {
    ...Default.args,
    disabled: true,
  },
};

但是 fontawesome 在故事书中不起作用。

它正在我的角度应用程序中工作:

import { Component } from '@angular/core';
import { FaConfig, FaIconLibrary } from '@fortawesome/angular-fontawesome';
import { faCoffee } from '@fortawesome/free-solid-svg-icons';

import { NxWelcomeComponent } from './nx-welcome.component';

@Component({
  standalone: true,
  imports: [NxWelcomeComponent],
  selector: 'vh-components-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent {
  title = 'vh-components';

  constructor(library: FaIconLibrary, faConfig: FaConfig) {
    faConfig.fixedWidth = true;
    library.addIcons(faCoffee);
  }
}

Package.json:

{
  "name": "@vh-components/source",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {
    "start": "nx serve",
    "build": "nx build",
    "test": "nx test",
    "storybook": "nx run vh-components:storybook"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "~16.2.0",
    "@angular/cdk": "^16.2.12",
    "@angular/common": "~16.2.0",
    "@angular/compiler": "~16.2.0",
    "@angular/core": "~16.2.0",
    "@angular/forms": "~16.2.0",
    "@angular/material": "^16.2.12",
    "@angular/platform-browser": "~16.2.0",
    "@angular/platform-browser-dynamic": "~16.2.0",
    "@angular/router": "~16.2.0",
    "@fortawesome/angular-fontawesome": "^0.13.0",
    "@fortawesome/fontawesome-svg-core": "^6.5.0",
    "@fortawesome/free-solid-svg-icons": "^6.5.0",
    "@ngneat/transloco": "^6.0.0",
    "@nx/angular": "17.0.3",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "rxjs": "~7.8.0",
    "tslib": "^2.3.0",
    "zone.js": "~0.13.0"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~16.2.0",
    "@angular-devkit/core": "~16.2.0",
    "@angular-devkit/schematics": "~16.2.0",
    "@angular-eslint/eslint-plugin": "~16.0.0",
    "@angular-eslint/eslint-plugin-template": "~16.0.0",
    "@angular-eslint/template-parser": "~16.0.0",
    "@angular/cli": "~16.2.0",
    "@angular/compiler-cli": "~16.2.0",
    "@angular/language-service": "~16.2.0",
    "@nx/eslint": "17.0.3",
    "@nx/eslint-plugin": "17.0.3",
    "@nx/jest": "17.0.3",
    "@nx/js": "17.0.3",
    "@nx/storybook": "17.0.3",
    "@nx/web": "17.0.3",
    "@nx/workspace": "17.0.3",
    "@schematics/angular": "~16.2.0",
    "@storybook/addon-essentials": "^7.5.1",
    "@storybook/addon-interactions": "^7.5.1",
    "@storybook/addon-storysource": "^7.5.1",
    "@storybook/angular": "^7.5.1",
    "@storybook/core-server": "^7.5.1",
    "@storybook/jest": "~0.1.0",
    "@storybook/test-runner": "^0.13.0",
    "@storybook/testing-library": "~0.2.0",
    "@swc-node/register": "~1.6.7",
    "@swc/core": "~1.3.85",
    "@tailwindcss/typography": "^0.5.10",
    "@types/jest": "^29.4.0",
    "@types/node": "16.11.7",
    "@typescript-eslint/eslint-plugin": "^5.60.1",
    "@typescript-eslint/parser": "^5.60.1",
    "autoprefixer": "^10.4.0",
    "eslint": "~8.46.0",
    "eslint-config-prettier": "^9.0.0",
    "jest": "^29.4.1",
    "jest-environment-jsdom": "^29.4.1",
    "jest-preset-angular": "~13.1.0",
    "jsonc-eslint-parser": "^2.1.0",
    "ng-packagr": "~16.2.0",
    "nx": "17.0.3",
    "postcss": "^8.4.5",
    "postcss-import": "~14.1.0",
    "postcss-preset-env": "~7.5.0",
    "postcss-url": "~10.1.3",
    "prettier": "^2.6.2",
    "storybook-addon-pseudo-states": "^2.1.2",
    "tailwindcss": "^3.3.5",
    "ts-jest": "^29.1.0",
    "ts-node": "10.9.1",
    "typescript": "~5.1.3"
  }
}

项目.json

{
  "name": "vh-components",
  "$schema": "node_modules/nx/schemas/project-schema.json",
  "projectType": "application",
  "prefix": "vh-components",
  "sourceRoot": "./src",
  "tags": [],
  "targets": {
    "build": {
      "executor": "@angular-devkit/build-angular:browser",
      "outputs": ["{options.outputPath}"],
      "options": {
        "outputPath": "dist/vh-components",
        "index": "./src/index.html",
        "main": "./src/main.ts",
        "polyfills": ["zone.js"],
        "tsConfig": "./tsconfig.app.json",
        "assets": ["./src/favicon.ico", "./src/assets"],
        "styles": ["./src/styles.scss"],
        "scripts": []
      },
      "configurations": {
        "production": {
          "budgets": [
            {
              "type": "initial",
              "maximumWarning": "500kb",
              "maximumError": "1mb"
            },
            {
              "type": "anyComponentStyle",
              "maximumWarning": "2kb",
              "maximumError": "4kb"
            }
          ],
          "outputHashing": "all"
        },
        "development": {
          "buildOptimizer": false,
          "optimization": false,
          "vendorChunk": true,
          "extractLicenses": false,
          "sourceMap": true,
          "namedChunks": true
        }
      },
      "defaultConfiguration": "production"
    },
    "serve": {
      "executor": "@angular-devkit/build-angular:dev-server",
      "configurations": {
        "production": {
          "browserTarget": "vh-components:build:production"
        },
        "development": {
          "browserTarget": "vh-components:build:development"
        }
      },
      "defaultConfiguration": "development"
    },
    "extract-i18n": {
      "executor": "@angular-devkit/build-angular:extract-i18n",
      "options": {
        "browserTarget": "vh-components:build"
      }
    },
    "lint": {
      "executor": "@nx/eslint:lint",
      "outputs": ["{options.outputFile}"],
      "options": {
        "lintFilePatterns": ["./src/**/*.ts", "./src/**/*.html"]
      }
    },
    "test": {
      "executor": "@nx/jest:jest",
      "outputs": ["{workspaceRoot}/coverage/{projectName}"],
      "options": {
        "jestConfig": "jest.config.app.ts",
        "passWithNoTests": true
      },
      "configurations": {
        "ci": {
          "ci": true,
          "codeCoverage": true
        }
      }
    },
    "storybook": {
      "executor": "@storybook/angular:start-storybook",
      "options": {
        "port": 4400,
        "configDir": "./.storybook",
        "browserTarget": "vh-components:build",
        "compodoc": false,
        "assets": [
          "src/favicon.ico",
          "src/assets"
        ]
      },
      "configurations": {
        "ci": {
          "quiet": true
        }
      }
    },
    "build-storybook": {
      "executor": "@storybook/angular:build-storybook",
      "outputs": ["{options.outputDir}"],
      "options": {
        "outputDir": "dist/storybook/vh-components",
        "configDir": "./.storybook",
        "browserTarget": "vh-components:build",
        "compodoc": false,
        "assets": [
          "src/favicon.ico",
          "src/assets"
        ]
      },
      "configurations": {
        "ci": {
          "quiet": true
        }
      }
    },
    "test-storybook": {
      "executor": "nx:run-commands",
      "options": {
        "command": "test-storybook -c ./.storybook --url=http://localhost:4400"
      }
    },
    "static-storybook": {
      "executor": "@nx/web:file-server",
      "options": {
        "buildTarget": "vh-components:build-storybook",
        "staticFilePath": "dist/storybook/vh-components"
      },
      "configurations": {
        "ci": {
          "buildTarget": "vh-components:build-storybook:ci"
        }
      }
    }
  }
}

angular typescript font-awesome storybook nomachine-nx
1个回答
0
投票

尝试对您的故事文件进行以下更改。设置 Angular 模块时,您需要导入独立组件。与在另一个组件中使用该组件的方式相同。

import {
  Meta,
  StoryObj,
  moduleMetadata,
  argsToTemplate,
} from '@storybook/angular';
import { provideHttpClient } from '@angular/common/http';
import { within } from '@storybook/testing-library';
import { expect } from '@storybook/jest';
import { applicationConfig } from '@storybook/angular';
import { provideTransloco } from '@ngneat/transloco';
import { TranslocoHttpLoader, translocoConf } from '@vh-components/transloco';

import { ButtonComponent } from './button.component';
import {
  FaIconLibrary,
  FontAwesomeModule,
} from '@fortawesome/angular-fontawesome';
import { APP_INITIALIZER, importProvidersFrom } from '@angular/core';
import { faCoffee } from '@fortawesome/free-solid-svg-icons';

const meta: Meta<ButtonComponent> = {
  component: ButtonComponent,
  title: 'Design system/Buttons/Button',
  tags: ['autodocs'],
  decorators: [
    moduleMetadata({
      imports: [ButtonComponent], // <== Here
      providers: [
        {
          provide: APP_INITIALIZER,
          useFactory: (iconLibrary: FaIconLibrary) => async () => {
            // Add any icons needed here:
            iconLibrary.addIcons(faCoffee);
          },
          // When using a factory provider you need to explicitly specify its dependencies.
          deps: [FaIconLibrary],
          multi: true,
        },
      ],
    }),
    applicationConfig({
      providers: [
        provideHttpClient(),
        provideTransloco({
          config: translocoConf,
          loader: TranslocoHttpLoader,
        }),
        // importProvidersFrom(TranslocoSharedModule), // TODO Why does this not work?
      ],
    }),
  ],
  render: (args: ButtonComponent) => ({
    props: {
      ...args,
    },
    template: `
        <vh-button ${argsToTemplate(args)}></vh-button>
    `,
  }),
};
export default meta;
type Story = StoryObj<ButtonComponent>;

export const Default: Story = {
  args: {
    label: 'text1',
    disabled: false,
    color: 'primary',
    prefixIcon: 'coffee',
  },
  argTypes: {
    color: {
      control: {
        type: 'select',
      },
      options: ['basic', 'primary', 'secondary', 'warning', 'dark'],
    },
  },
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
    expect(canvas.getByText(/button works!/gi)).toBeTruthy();
  },
};

export const disabled: Story = {
  args: {
    ...Default.args,
    disabled: true,
  },
};
© www.soinside.com 2019 - 2024. All rights reserved.