Search code examples
angularstorybook

Angular ng-content in Storybook stories not working


Given the following component inside anchor.component.ts:

import { CommonModule } from '@angular/common';
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { RouterModule } from '@angular/router';

@Component({
  selector: 'lib-anchor',
  templateUrl: './anchor.component.html',
  styleUrls: ['./anchor.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  standalone: true,
  imports: [
    CommonModule,
    RouterModule,
  ],
  template: `
    <a [href]="link">
      <ng-content></ng-content>
    </a>
  `
})
export class LibAnchorComponent {
  @Input() link?: string;
}

And the following within anchor.component.stories.ts:

import { LibAnchorComponent } from './anchor.component';

export default {
  component: LibAnchorComponent,
};

export const Primary = {
  args: {
    link: 'https://google.com'
  },
  render: (args: any) => `<lib-anchor>hello world</lib-anchor>`
};

I thought that I would see "hello world" as the template and "https://google.com" as the href attribute value, but I see neither. This is what is rendered as the Primary story:

image of rendered html

I have tried both the CSF 2.0 and CSF 3.0 way of doing things but neither have worked for me. The code posted here is based on https://storybook.js.org/blog/component-story-format-3-0/.

What am I doing wrong?


Solution

  • I found the correct answer eventually. Turns out you have to return an object from the render method instead of a string:

    export const Primary: StoryObj<LibAnchorComponent> = {
      args: {
        link: 'https://google.com'
      },
      render: (args: any) => ({    
        template: `<lib-anchor link="${args.link}">hello world ${args.link}</lib-anchor>`
      })
    };
    

    This will correctly render both the given link and the projected content.