spartan icon indicating copy to clipboard operation
spartan copied to clipboard

cli: Spartan & NX: Storybook UI Not Applying Angular Component Configuration

Open muriukialex opened this issue 3 months ago • 2 comments

Please provide the environment you discovered this bug in.

Packages used:

Nx Angular: @nx/angular@^20.5.0 Angular Core: @angular/core@~19.2.0 Storybook: storybook@^8.4.6 Nx Storybook: @nx/storybook@^20.5.0 Spartan CLI: @spartan-ng/cli": "^0.0.1-alpha.422 Spartan brain: 0.0.1-alpha.422

Which area/package is the issue in?

Don't know / other

Description

When running Storybook with an Angular (Nx-managed) project, the MyCard component’s stories do not correctly pick up the provided configuration. The issue seems related to the @spartan-ng/ui-card-helm directives and modules not being loaded within Storybook.

The component MyCard is a standalone Angular component importing directives from @spartan-ng/ui-card-helm. Its stories are configured with moduleMetadata to import CommonModule and HlmCardModule. However, Storybook UI fails to render the component as expected, suggesting that the Spartan directives/modules are not being properly resolved within Storybook’s Angular configuration.

Additional information project main.ts file

import type { StorybookConfig } from '@storybook/angular';

const config: StorybookConfig = {
    stories: ['../**/*.@(mdx|stories.@(js|jsx|ts|tsx))'],
    addons: ['@storybook/addon-essentials', '@storybook/addon-interactions'],
    framework: {
        name: '@storybook/angular',
        options: {},
    },
};

export default config;

// To customize your webpack configuration you can use the webpackFinal field.
// Check https://storybook.js.org/docs/react/builders/webpack#extending-storybooks-webpack-config
// and https://nx.dev/recipes/storybook/custom-builder-configs

project preview.ts file

// 👇 Add these
import type { Preview } from '@storybook/angular';

// import docJson from '../documentation.json';

// setCompodocJson(docJson);

const preview: Preview = {
    tags: ['autodocs'],
    parameters: {
        docs: {
            toc: true, // 👈 Enables the table of contents
        },
    },
};
export default preview;

project tsconfig.ts file

{
    "extends": "../tsconfig.json",
    "compilerOptions": {
        "emitDecoratorMetadata": true
    },
    "exclude": ["../**/*.spec.ts"],
    "include": [
        "../src/**/*.stories.ts",
        "../src/**/*.stories.js",
        "../src/**/*.stories.jsx",
        "../src/**/*.stories.tsx",
        "../src/**/*.stories.mdx",
        "*.js",
        "*.ts"
    ]
}

mycard component stories file

import { CommonModule } from '@angular/common';
import { HlmCardModule } from '@spartan-ng/ui-card-helm';
import { type Meta, type StoryObj, moduleMetadata } from '@storybook/angular';
import { expect } from '@storybook/jest';
import { within } from '@storybook/testing-library';

import { MyCard } from './my-card.component';

const meta: Meta<MyCard> = {
    component: MyCard,
    title: 'MyCard',
    decorators: [
        // Apply metadata to all stories
        moduleMetadata({
            // import necessary ngModules or standalone components/directives
            imports: [CommonModule, HlmCardModule],
        }),
    ],
};
export default meta;
type Story = StoryObj<MyCard>;

export const Primary: Story = {
    args: {
        cardTitle: 'Sample card title',
        cardDescription: 'Sample card description',
    },

};

export const Heading: Story = {
    args: {
        cardTitle: 'Sample card title',
        cardDescription: 'Sample card description',
    },
    play: async ({ canvasElement }) => {
        const canvas = within(canvasElement);
        expect(canvas.getByText(/my card works!/gi)).toBeTruthy();
    },
};

mycard component ts

import { CommonModule } from '@angular/common';
import { Component, Input } from '@angular/core';
import {
    HlmCardContentDirective,
    HlmCardDescriptionDirective,
    HlmCardDirective,
    HlmCardFooterDirective,
    HlmCardHeaderDirective,
    HlmCardTitleDirective,
} from '@spartan-ng/ui-card-helm';

@Component({
    selector: 'my-card',
    imports: [
        CommonModule,
        HlmCardDirective,
        HlmCardTitleDirective,
        HlmCardHeaderDirective,
        HlmCardDescriptionDirective,
        HlmCardContentDirective,
        HlmCardFooterDirective,
    ],
    standalone: true,
    templateUrl: './my-card.component.html',
    styleUrl: './my-card.component.scss',
})
export class MyCard {
    /**
     * card title
     */
    @Input() cardTitle = '';

    /**
     * card title
     */
    @Input() cardDescription = '';
}

mycard component template

<div hlmCard>
    <div hlmCardHeader>
        <h3 hlmCardTitle>{{ cardTitle }}</h3>
        <p hlmCardDescription>
            {{ cardDescription }}
        </p>
    </div>

    <div hlmCardContent>
        <ng-content select="[card-body]"></ng-content>
    </div>

    <div hlmCardFooter class="flex justify-center">
        <ng-content select="[card-footer]"></ng-content>
    </div>
</div>

Please provide the exception or error you saw


Other information

Current component behavior

Image

Expected component behavior

Image

I would be willing to submit a PR to fix this issue

  • [ ] Yes
  • [ ] No

muriukialex avatar Aug 18 '25 07:08 muriukialex

@muriukialex are the tailwind classes added correctly in the html? Maybe the setup for this project is helpful: https://github.com/goetzrobin/spartan/blob/2eded311263f631c7b23970351a520c645635eb8/apps/ui-storybook

goetzrobin avatar Aug 19 '25 12:08 goetzrobin

@muriukialex are the tailwind classes added correctly in the html? Maybe the setup for this project is helpful: https://github.com/goetzrobin/spartan/blob/2eded311263f631c7b23970351a520c645635eb8/apps/ui-storybook

Hey @goetzrobin, thank you for your response. The tailwind classes are not loaded correctly within the storybook html page

This is how the live page looks likes

Image

This is how the storybook page looks likes

Image

The storybook card preview fails to load the helm card directive styles, as seen below

Image

This is how I thought it would preview as

Image

muriukialex avatar Aug 27 '25 09:08 muriukialex