-
-
Notifications
You must be signed in to change notification settings - Fork 9.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add moduleMetdata decorator for supplying common Angular metadata #2959
Changes from 5 commits
e29d0e7
e8f08e0
07172c3
d2bbf3a
37a904c
e8117fd
fc05a7c
648e6e0
1ee3e0a
246fc20
76ebe43
6dbdb59
770678a
b650ca5
36bace3
613b4cb
4f135ec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
export { storiesOf, setAddon, addDecorator, configure, getStorybook } from './preview'; | ||
|
||
export { moduleMetadata } from './preview/angular/decorators'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import { moduleMetadata } from './decorators'; | ||
|
||
class MockModule {} | ||
class MockModuleTwo {} | ||
class MockService {} | ||
class MockComponent {} | ||
|
||
describe('moduleMetadata', () => { | ||
it('should add metadata to a story without it', () => { | ||
const result = moduleMetadata({ | ||
imports: [MockModule], | ||
providers: [MockService], | ||
})(() => ({ | ||
component: MockComponent, | ||
})); | ||
|
||
expect(result).toEqual({ | ||
component: MockComponent, | ||
moduleMetadata: { | ||
declarations: [], | ||
entryComponents: [], | ||
imports: [MockModule], | ||
schemas: [], | ||
providers: [MockService], | ||
}, | ||
}); | ||
}); | ||
|
||
it('should combine with individual metadata on a story', () => { | ||
const result = moduleMetadata({ | ||
imports: [MockModule], | ||
})(() => ({ | ||
component: MockComponent, | ||
moduleMetadata: { | ||
imports: [MockModuleTwo], | ||
providers: [MockService], | ||
}, | ||
})); | ||
|
||
expect(result).toEqual({ | ||
component: MockComponent, | ||
moduleMetadata: { | ||
declarations: [], | ||
entryComponents: [], | ||
imports: [MockModule, MockModuleTwo], | ||
schemas: [], | ||
providers: [MockService], | ||
}, | ||
}); | ||
}); | ||
|
||
it('should return the original metadata if passed null', () => { | ||
const result = moduleMetadata(null)(() => ({ | ||
component: MockComponent, | ||
moduleMetadata: { | ||
providers: [MockService], | ||
}, | ||
})); | ||
|
||
expect(result).toEqual({ | ||
component: MockComponent, | ||
moduleMetadata: { | ||
declarations: [], | ||
entryComponents: [], | ||
imports: [], | ||
schemas: [], | ||
providers: [MockService], | ||
}, | ||
}); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { NgModuleMetadata } from './types'; | ||
|
||
export const moduleMetadata = (metadata: Partial<NgModuleMetadata>) => (storyFn: () => any) => { | ||
const story = storyFn(); | ||
const storyMetadata = story.moduleMetadata || {}; | ||
metadata = metadata || {}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can the default be introduced in the method signature? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's how I did it originally, but default params affect undefined or no value, but not null. So I'd need to add a check for null and assignment to |
||
|
||
return { | ||
...story, | ||
moduleMetadata: { | ||
declarations: [...(metadata.declarations || []), ...(storyMetadata.declarations || [])], | ||
entryComponents: [ | ||
...(metadata.entryComponents || []), | ||
...(storyMetadata.entryComponents || []), | ||
], | ||
imports: [...(metadata.imports || []), ...(storyMetadata.imports || [])], | ||
schemas: [...(metadata.schemas || []), ...(storyMetadata.schemas || [])], | ||
providers: [...(metadata.providers || []), ...(storyMetadata.providers || [])], | ||
}, | ||
}; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
import { storiesOf } from '@storybook/angular'; | ||
import { storiesOf, moduleMetadata } from '@storybook/angular'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think better having a separate example of this usage, also because it's necessary to check it in conjunction with addon-knobs. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added. Seems to work fine with |
||
import { withKnobs, text } from '@storybook/addon-knobs/angular'; | ||
|
||
import { NameComponent } from './moduleMetadata/name.component'; | ||
|
@@ -64,3 +64,40 @@ storiesOf('Custom ngModule metadata', module) | |
}, | ||
}; | ||
}); | ||
|
||
storiesOf('Common ngModule metadata', module) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree, it'd be better to have a separate example that shows:
We don't have official docs for most of this and we usually point people to the examples so we try to keep as many as we can with all the use cases There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess I'm not really seeing what value these examples would have? All this decorator does is allow you to declare a set of metadata that is shared amongst your subsequent stories. Whether you're using knobs, template, component, etc. is completely orthogonal to it. Since there is already examples of those things, I'm not sure how duplicating them here would really help understanding it? Wouldn't it make more sense to modify all the other examples to use this decorator where appropriate, i.e. instead of supplying duplicate metadata, as in
|
||
.addDecorator( | ||
moduleMetadata({ | ||
imports: [], | ||
schemas: [], | ||
declarations: [ServiceComponent], | ||
providers: [DummyService], | ||
}) | ||
) | ||
.add('simple', () => ({ | ||
component: ServiceComponent, | ||
props: { | ||
name: 'Static name', | ||
}, | ||
})) | ||
.add('template', () => ({ | ||
template: | ||
'<storybook-simple-service-component [name]="name"></storybook-simple-service-component>', | ||
props: { | ||
name: 'Static name', | ||
}, | ||
})) | ||
.addDecorator(withKnobs) | ||
.add('with knobs', () => ({ | ||
template: ` | ||
<storybook-name [field]="field"></storybook-name> | ||
<storybook-simple-service-component [name]="name"></storybook-simple-service-component> | ||
`, | ||
props: { | ||
field: text('field', 'foobar'), | ||
name: 'Static name', | ||
}, | ||
moduleMetadata: { | ||
declarations: [NameComponent, CustomPipePipe], | ||
}, | ||
})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we also need to support an arrays concatenation...
for example:
I would expect to have both
FooModule
andBarModule
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have modified it to combine rather than override.