Skip to content
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

feature: noStoriesOf loader option support for custome story #4012

Merged
merged 9 commits into from
Aug 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions addons/storysource/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,29 @@ module.exports = {
},
};
```

### injectDecorator
Tell storysource whether you need inject decorator.If false, you need to add the decorator by yourself;

Defaults: true

Usage:

```js
module.exports = {
module: {
rules: [
{
test: /\.stories\.jsx?$/,
loaders: [
{
loader: require.resolve('@storybook/addon-storysource/loader'),
options: { injectDecorator: false }
}
],
enforce: 'pre',
},
],
},
};
```
Original file line number Diff line number Diff line change
@@ -1,5 +1,216 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`inject-decorator injectDecorator option is false - angular does not inject stories decorator after the all "storiesOf" functions 1`] = `
"import { Component } from '@angular/core';
import { storiesOf } from '@storybook/angular';

@Component({
selector: 'storybook-with-ng-content',
template: \`<div style=\\"color: #1e88e5;\\"><ng-content></ng-content></div>\`,
})
class WithNgContentComponent {}

storiesOf('Custom|ng-content', module).add('Default', () => ({
template: \`<storybook-with-ng-content><h1>This is rendered in ng-content</h1></storybook-with-ng-content>\`,
moduleMetadata: {
declarations: [WithNgContentComponent],
},
}));
"
`;

exports[`inject-decorator injectDecorator option is false - ts does not inject stories decorator after the all "storiesOf" functions 1`] = `
"import { Component } from '@angular/core';
import { Store, StoreModule } from '@ngrx/store';
import { storiesOf, moduleMetadata } from '@storybook/angular';

@Component({
selector: 'storybook-comp-with-store',
template: '<div>{{this.getSotreState()}}</div>',
})
class WithStoreComponent {
private store: Store<any>;

constructor(store: Store<any>) {
this.store = store;
}

getSotreState(): string {
return this.store === undefined ? 'Store is NOT injected' : 'Store is injected';
}
}

storiesOf('ngrx|Store', module)
.addDecorator(
moduleMetadata({
imports: [StoreModule.forRoot({})],
declarations: [WithStoreComponent],
})
)
.add('With component', () => {
return {
component: WithStoreComponent,
};
});"
`;

exports[`inject-decorator injectDecorator option is false does not inject stories decorator after the all "storiesOf" functions 1`] = `
"import React from 'react';
import { storiesOf } from '@storybook/react';
import { withInfo } from '@storybook/addon-info';
import { action } from '@storybook/addon-actions';

import DocgenButton from '../components/DocgenButton';
import FlowTypeButton from '../components/FlowTypeButton';
import BaseButton from '../components/BaseButton';
import TableComponent from '../components/TableComponent';

storiesOf('Addons|Info.React Docgen', module)
.add(
'Comments from PropType declarations',
withInfo(
'Comments above the PropType declarations should be extracted from the React component file itself and rendered in the Info Addon prop table'
)(() => <DocgenButton onClick={action('clicked')} label=\\"Docgen Button\\" />)
)
.add(
'Comments from Flow declarations',
withInfo(
'Comments above the Flow declarations should be extracted from the React component file itself and rendered in the Info Addon prop table'
)(() => <FlowTypeButton onClick={action('clicked')} label=\\"Flow Typed Button\\" />)
)
.add(
'Comments from component declaration',
withInfo(
'Comments above the component declaration should be extracted from the React component file itself and rendered below the Info Addon heading'
)(() => <BaseButton onClick={action('clicked')} label=\\"Button\\" />)
);

const markdownDescription = \`
#### You can use markdown in your withInfo() description.

Sometimes you might want to manually include some code examples:
~~~js
const Button = () => <button />;
~~~

Maybe include a [link](http://storybook.js.org) to your project as well.
\`;

storiesOf('Addons|Info.Markdown', module).add(
'Displays Markdown in description',
withInfo(markdownDescription)(() => <BaseButton onClick={action('clicked')} label=\\"Button\\" />)
);

storiesOf('Addons|Info.Options.inline', module).add(
'Inlines component inside story',
withInfo({
text: 'Component should be inlined between description and PropType table',
inline: true, // Displays info inline vs click button to view
})(() => <BaseButton label=\\"Button\\" />)
);

storiesOf('Addons|Info.Options.header', module).add(
'Shows or hides Info Addon header',
withInfo({
text: 'The Info Addon header should be hidden',
header: false, // Toggles display of header with component name and description
})(() => <BaseButton label=\\"Button\\" />)
);

storiesOf('Addons|Info.Options.source', module).add(
'Shows or hides Info Addon source',
withInfo({
text: 'The Info Addon source section should be hidden',
source: false, // Displays the source of story Component
})(() => <BaseButton label=\\"Button\\" />)
);

storiesOf('Addons|Info.Options.propTables', module).add(
'Shows additional component prop tables',
withInfo({
text: 'There should be a prop table added for a component not included in the story',
propTables: [FlowTypeButton],
})(() => <BaseButton label=\\"Button\\" />)
);

storiesOf('Addons|Info.Options.propTablesExclude', module).add(
'Exclude component from prop tables',
withInfo({
text: 'This can exclude extraneous components from being displayed in prop tables.',
propTablesExclude: [FlowTypeButton],
})(() => (
<div>
<BaseButton label=\\"Button\\" />
<FlowTypeButton label=\\"Flow Typed Button\\" />
</div>
))
);

storiesOf('Addons|Info.Options.styles', module)
.add(
'Extend info styles with an object',
withInfo({
styles: {
button: {
base: {
background: 'purple',
},
},
header: {
h1: {
color: 'green',
},
},
},
})(() => <BaseButton label=\\"Button\\" />)
)
.add(
'Full control over styles using a function',
withInfo({
styles: stylesheet => ({
...stylesheet,
header: {
...stylesheet.header,
h1: {
...stylesheet.header.h1,
color: 'red',
},
},
}),
})(() => <BaseButton label=\\"Button\\" />)
);

storiesOf('Addons|Info.Options.TableComponent', module).add(
'Use a custom component for the table',
withInfo({
TableComponent,
})(() => <BaseButton label=\\"Button\\" />)
);

storiesOf('Addons|Info.Decorator', module)
.addDecorator((story, context) =>
withInfo('Info could be used as a global or local decorator as well.')(story)(context)
)
.add('Use Info as story decorator', () => <BaseButton label=\\"Button\\" />);

const hoc = WrapComponent => ({ ...props }) => <WrapComponent {...props} />;

const Input = hoc(() => <input type=\\"text\\" />);

const TextArea = hoc(({ children }) => <textarea>{children}</textarea>);

storiesOf('Addons|Info.GitHub issues', module).add(
'#1814',
withInfo('Allow Duplicate DisplayNames for HOC #1814')(() => (
<div>
<Input />
<TextArea />
</div>
))
);
"
`;

exports[`inject-decorator positive - angular calculates "adds" map 1`] = `
Object {
"Custom|ng-content@Default": Object {
Expand Down
13 changes: 13 additions & 0 deletions addons/storysource/src/loader/generate-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,19 @@ export function generateSourceWithDecorators(source, decorator, parserType) {
};
}

export function generateSourceWithoutDecorators(source, parserType) {
const parser = getParser(parserType);
const ast = parser.parse(source);

const { comments = [] } = ast;

return {
changed: true,
source,
comments,
};
}

export function generateAddsMap(source, parserType) {
const parser = getParser(parserType);
const ast = parser.parse(source);
Expand Down
6 changes: 3 additions & 3 deletions addons/storysource/src/loader/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ function transform(source) {
const addsMap = JSON.stringify(result.addsMap);

return `
var withStorySource = require('@storybook/addon-storysource').withStorySource;
var __STORY__ = ${sourceJson};
var __ADDS_MAP__ = ${addsMap};
export var withStorySource = require('@storybook/addon-storysource').withStorySource;
export var __STORY__ = ${sourceJson};
export var __ADDS_MAP__ = ${addsMap};

${result.source}
`;
Expand Down
11 changes: 6 additions & 5 deletions addons/storysource/src/loader/inject-decorator.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import defaultOptions from './default-options';

import {
generateSourceWithDecorators,
generateSourceWithoutDecorators,
generateStorySource,
generateAddsMap,
} from './generate-helpers';
Expand All @@ -17,11 +18,11 @@ function extendOptions(source, comments, filepath, options) {
}

function inject(source, decorator, filepath, options = {}) {
const { changed, source: newSource, comments } = generateSourceWithDecorators(
source,
decorator,
options.parser
);
const { injectDecorator = true } = options;
const { changed, source: newSource, comments } =
injectDecorator === true
? generateSourceWithDecorators(source, decorator, options.parser)
: generateSourceWithoutDecorators(source, options.parser);

if (!changed) {
return {
Expand Down
54 changes: 54 additions & 0 deletions addons/storysource/src/loader/inject-decorator.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,58 @@ describe('inject-decorator', () => {
expect(result.addsMap).toEqual({});
expect(result.source).toMatchSnapshot();
});

describe('injectDecorator option is false', () => {
const mockFilePath = './__mocks__/inject-decorator.stories.txt';
const source = fs.readFileSync(mockFilePath, 'utf-8');
const result = injectDecorator(
source,
ADD_DECORATOR_STATEMENT,
path.resolve(__dirname, mockFilePath),
{
injectDecorator: false,
parser: 'javascript',
}
);

it('does not inject stories decorator after the all "storiesOf" functions', () => {
expect(result.source).toMatchSnapshot();
});
});

describe('injectDecorator option is false - angular', () => {
const mockFilePath = './__mocks__/inject-decorator.angular-stories.txt';
const source = fs.readFileSync(mockFilePath, 'utf-8');
const result = injectDecorator(
source,
ADD_DECORATOR_STATEMENT,
path.resolve(__dirname, mockFilePath),
{
injectDecorator: false,
parser: 'typescript',
}
);

it('does not inject stories decorator after the all "storiesOf" functions', () => {
expect(result.source).toMatchSnapshot();
});
});

describe('injectDecorator option is false - ts', () => {
const mockFilePath = './__mocks__/inject-decorator.ts.txt';
const source = fs.readFileSync(mockFilePath, 'utf-8');
const result = injectDecorator(
source,
ADD_DECORATOR_STATEMENT,
path.resolve(__dirname, mockFilePath),
{
injectDecorator: false,
parser: 'typescript',
}
);

it('does not inject stories decorator after the all "storiesOf" functions', () => {
expect(result.source).toMatchSnapshot();
});
});
});
4 changes: 2 additions & 2 deletions lib/cli/test/snapshots/angular-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
"ts-node": "1.2.1",
"tslint": "^4.3.0",
"typescript": "~2.4.0",
"@babel/core": "^7.0.0-rc.3",
"babel-loader": "^8.0.0-beta.6",
"@babel/core": "^7.0.0",
"babel-loader": "^8.0.0",
"@storybook/angular": "^4.0.0-alpha.18",
"@storybook/addon-notes": "^4.0.0-alpha.18",
"@storybook/addon-actions": "^4.0.0-alpha.18",
Expand Down
4 changes: 2 additions & 2 deletions lib/cli/test/snapshots/marko/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
"@storybook/marko": "^4.0.0-alpha.18",
"@storybook/addon-actions": "^4.0.0-alpha.18",
"@storybook/addon-knobs": "^4.0.0-alpha.18",
"@babel/core": "^7.0.0-rc.3",
"babel-loader": "^8.0.0-beta.6"
"@babel/core": "^7.0.0",
"babel-loader": "^8.0.0"
},
"scripts": {
"storybook": "start-storybook -p 6006",
Expand Down
Loading