storybook: [Angular] Can't seem to generate a story with ng-content and knob-passed props
I’m building out an Angular app with Storybook. I want my stories to have controllable knobs, but some of these components take ng-content
.
I’m having trouble getting these two to work together, because, from what I’ve found, passing content into a component using Storybook involves setting a template
on the story. Unfortunately, template seems to essentially overwrite Storybook’s knob-passed props.
Here’s the example:
button.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'ui-button',
templateUrl: './button.component.html',
styleUrls: ['./button.component.scss']
})
export class ButtonComponent implements OnInit {
types: String[] = [];
constructor() {}
ngOnInit(): void {}
typeClasses(): String[] {
return this.types.map(t => `button--${t}`);
}
}
button.component.html
<a class="button" [ngClass]="typeClasses()">
<ng-content></ng-content>
</a>
button.component.stories.ts
import { text, array } from '@storybook/addon-knobs';
import { ButtonComponent } from './button.component';
export default {
title: 'ButtonComponent'
};
export const dark = () => ({
moduleMetadata: {
declarations: [ButtonComponent], // Not needed when not using template
imports: []
},
// component: ButtonComponent, replaced with the below because of ng-content
template: `<ui-button>Button content</ui-button>`, // Needed to pass arbitrary child content
props: {
types: array('class', ['dark']), // Ignored, because it's not in template
}
});
Am I missing a better way to pass content in? Because I have to give a full template
, it seems that any props not passed in that template aren’t injected into the component, and so the knobs are rendered useless. This seems to mean that I should just get rid of props on all my component stories, and instead just pass them in through the template, but that would render them non-configurable in the served Storybook and defeat much of the point.
Am I doing this wrong? Is there a way to both A) pass content, and B) allow for props? The Angular Storybook guide doesn’t seem to address this.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 18
- Comments: 36 (12 by maintainers)
Any news?
LE: This seems to be working, discovered by pure luck. You can to be able to use inputs declared under props object.
Still this issue is not fixed. This is the smallest workaround I created:
In this example the content is provided to the component and all the controls are working properly. Not sure about
Actions
. For further improvement you can use helper function:and then use it in decorators like that:
The
template: ...
part can’t be right. Since you are using template literals yourpropInput
references should be expressions and thus be written like this:I don’t understand why this worked out for you actually… Now hold your horses; For me this solution, with expressions, is still not working, unfortunately.
Wasn’t it better to just expose/create a property like
ngContent
besides thetemplate
andprops
properties on the story?Ta-da!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.2.0-alpha.13 containing PR #13507 that references this issue. Upgrade today to the
@next
NPM tag to try it out!Closing this issue. Please re-open if you think there’s still more to do.
Hi gang, We’ve just released addon-controls in 6.0-beta!
Controls are portable, auto-generated knobs that are intended to replace addon-knobs long term.
Please upgrade and try them out today. Thanks for your help and support getting this stable for release!
I have no idea if this will be helpful to someone today, but I managed to get a component using
<ng-content>
working for with something similar to what’s recommended in the tuts and boilerplate examples using theMeta
approach and all with this:If you’re an Angular noob like I currently am, you’ll need to ensure your component has
selector: ag-button
or whatever name you want to be able to use that name for the web component looking markup.I have 2 ideas for this issues
1️⃣
What do you think about adding a dedicated property for this case? something like
componentTemplate
?componentTemplate
is only taken into account iftemplate
is empty.<ui-button ...input ...output></ui-button>
and declare component in Angular modulecomponentTemplate
will allow to add internal content to the componentcomponentTemplate
would be ignored.[Edit] no longer seems very relevant with https://github.com/storybookjs/storybook/pull/13383
2️⃣
use the Decorators? It is not yet taken into account by angular but I think it is possible (I am thinking of opening a PR for this subject)
if it could work the way I think it would. It could work something like this :
(only theory 🙈 ) (several decorators can be nested whether, it is a template or a component ) would solve other issues than this one
👨💻
The 1st one seems to me quite simple and quick to set up. The 2nd one is longer and more complex. I think both could be considered and that it could be complementary. 🤔
@storybookjs/angular what do you think about it?
@ThibaudAV Thank you so much, I was looking for this.
@ThibaudAV i have the missing angular snippets almost ready. The only reason why they are not up on a pull request is based on a small item that i need to take up with @shilman that is applied to both angular and Vue. Once i get the ok will push them up. Sounds good?
Stay safe
normally yes
Hi everyone! Seems like there hasn’t been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don’t have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!
For anybody who is interested in Controls but don’t know where to start, I’ve created a quick & dirty step-by-step walkthrough to go from a fresh CRA project to a working demo. Check it out:
=> Storybook Controls w/ CRA & TypeScript
There are also some “knobs to controls” migration docs in the Controls README:
=> How do I migrate from addon-knobs?
Any news on whether or not this is possible with Angular Storybook at the moment? Also created a Stack Overflow post and asked on the Storybook Discord, and haven’t gotten a sense of whether this is possible.