mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-02 05:03:44 +08:00
#7192 ✂ I have removed the storysource older loader
This commit is contained in:
parent
3b2ef9bc80
commit
053aa06bc6
@ -424,7 +424,7 @@ Publish failed
|
||||
- Addon-docs: Docs page bugfix
|
||||
- Addon-docs: Fix source block for legacy stories
|
||||
|
||||
NOTE: use `@storybook/addon-storysource/loader` with option `injectParameters: true` for legacy source
|
||||
NOTE: use `@storybook/source-loader` with option `injectParameters: true` for legacy source
|
||||
|
||||
## 5.2.0-alpha.6 (May 14, 2019)
|
||||
|
||||
|
@ -26,7 +26,7 @@ Use this hook to a custom webpack.config. This will generate a decorator call in
|
||||
module.exports = function({ config }) {
|
||||
config.module.rules.push({
|
||||
test: /\.stories\.jsx?$/,
|
||||
loaders: [require.resolve('@storybook/addon-storysource/loader')],
|
||||
loaders: [require.resolve('@storybook/source-loader')],
|
||||
enforce: 'pre',
|
||||
});
|
||||
|
||||
@ -56,7 +56,7 @@ module.exports = function({ config }) {
|
||||
test: /\.stories\.jsx?$/,
|
||||
loaders: [
|
||||
{
|
||||
loader: require.resolve('@storybook/addon-storysource/loader'),
|
||||
loader: require.resolve('@storybook/source-loader'),
|
||||
options: { parser: 'typescript' },
|
||||
},
|
||||
],
|
||||
@ -91,7 +91,7 @@ module.exports = function({ config }) {
|
||||
test: /\.stories\.jsx?$/,
|
||||
loaders: [
|
||||
{
|
||||
loader: require.resolve('@storybook/addon-storysource/loader'),
|
||||
loader: require.resolve('@storybook/source-loader'),
|
||||
options: {
|
||||
prettierConfig: {
|
||||
printWidth: 100,
|
||||
@ -125,7 +125,7 @@ module.exports = function({ config }) {
|
||||
test: /\.stories\.jsx?$/,
|
||||
loaders: [
|
||||
{
|
||||
loader: require.resolve('@storybook/addon-storysource/loader'),
|
||||
loader: require.resolve('@storybook/source-loader'),
|
||||
options: {
|
||||
uglyCommentsRegex: [/^eslint-.*/, /^global.*/],
|
||||
},
|
||||
@ -152,7 +152,7 @@ module.exports = function({ config }) {
|
||||
test: /\.stories\.jsx?$/,
|
||||
loaders: [
|
||||
{
|
||||
loader: require.resolve('@storybook/addon-storysource/loader'),
|
||||
loader: require.resolve('@storybook/source-loader'),
|
||||
options: { injectDecorator: false },
|
||||
},
|
||||
],
|
||||
|
@ -1 +1 @@
|
||||
module.exports = require('./dist/loader');
|
||||
module.exports = require('@storybook/source-loader');
|
||||
|
@ -35,7 +35,8 @@
|
||||
"regenerator-runtime": "^0.12.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*"
|
||||
"react": "*",
|
||||
"@storybook/source-loader": "*"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@ -66,9 +66,8 @@ export default class StoryPanel extends Component {
|
||||
this.selectedStoryRef = ref;
|
||||
};
|
||||
|
||||
listener = ({ source, currentLocation, locationsMap }) => {
|
||||
listener = ({ edition: { source }, location: { currentLocation, locationsMap } }) => {
|
||||
const locationsKeys = getLocationKeys(locationsMap);
|
||||
|
||||
this.setState({
|
||||
source,
|
||||
currentLocation,
|
||||
|
@ -1,3 +1,3 @@
|
||||
export const ADDON_ID = 'storybook/storysource';
|
||||
export const ADDON_ID = 'storybook/source-loader';
|
||||
export const PANEL_ID = `${ADDON_ID}/panel`;
|
||||
export const EVENT_ID = `${ADDON_ID}/set`;
|
||||
|
@ -1,732 +0,0 @@
|
||||
// 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 - flow does not inject stories decorator after the all "storiesOf" functions 1`] = `
|
||||
"// @flow
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { withInfo } from '@storybook/addon-info';
|
||||
|
||||
import TableComponent from '../components/TableComponent';
|
||||
|
||||
import type { JssClasses } from '../types';
|
||||
|
||||
type State = {
|
||||
value: any,
|
||||
};
|
||||
|
||||
type Props = {
|
||||
classes: JssClasses,
|
||||
name: string,
|
||||
};
|
||||
|
||||
class Table extends React.Component<Props, State> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
value: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
state: State;
|
||||
|
||||
render() {
|
||||
return <TableComponent />;
|
||||
}
|
||||
}
|
||||
|
||||
const stories = storiesOf('Table', module);
|
||||
stories.add('Flow Class', withInfo('Lorum Ipsum Nem')(() => <Table />));
|
||||
"
|
||||
`;
|
||||
|
||||
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 {
|
||||
"endLoc": Object {
|
||||
"col": 2,
|
||||
"line": 17,
|
||||
},
|
||||
"startLoc": Object {
|
||||
"col": 43,
|
||||
"line": 12,
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`inject-decorator positive - angular injects 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).addDecorator(withStorySource(__STORY__, __ADDS_MAP__)).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 positive - flow calculates "adds" map 1`] = `Object {}`;
|
||||
|
||||
exports[`inject-decorator positive - flow injects stories decorator after the all "storiesOf" functions 1`] = `
|
||||
"// @flow
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { withInfo } from '@storybook/addon-info';
|
||||
|
||||
import TableComponent from '../components/TableComponent';
|
||||
|
||||
import type { JssClasses } from '../types';
|
||||
|
||||
type State = {
|
||||
value: any,
|
||||
};
|
||||
|
||||
type Props = {
|
||||
classes: JssClasses,
|
||||
name: string,
|
||||
};
|
||||
|
||||
class Table extends React.Component<Props, State> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
value: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
state: State;
|
||||
|
||||
render() {
|
||||
return <TableComponent />;
|
||||
}
|
||||
}
|
||||
|
||||
const stories = storiesOf('Table', module).addDecorator(withStorySource(__STORY__, __ADDS_MAP__));
|
||||
stories.add('Flow Class', withInfo('Lorum Ipsum Nem')(() => <Table />));
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`inject-decorator positive - ts calculates "adds" map 1`] = `
|
||||
Object {
|
||||
"ngrx-store--with-component": Object {
|
||||
"endLoc": Object {
|
||||
"col": 3,
|
||||
"line": 32,
|
||||
},
|
||||
"startLoc": Object {
|
||||
"col": 7,
|
||||
"line": 28,
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`inject-decorator positive - ts injects 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(withStorySource(__STORY__, __ADDS_MAP__))
|
||||
.addDecorator(
|
||||
moduleMetadata({
|
||||
imports: [StoreModule.forRoot({})],
|
||||
declarations: [WithStoreComponent],
|
||||
})
|
||||
)
|
||||
.add('With component', () => {
|
||||
return {
|
||||
component: WithStoreComponent,
|
||||
};
|
||||
});"
|
||||
`;
|
||||
|
||||
exports[`inject-decorator positive calculates "adds" map 1`] = `
|
||||
Object {
|
||||
"addons-info-decorator--use-info-as-story-decorator": Object {
|
||||
"endLoc": Object {
|
||||
"col": 73,
|
||||
"line": 137,
|
||||
},
|
||||
"startLoc": Object {
|
||||
"col": 7,
|
||||
"line": 137,
|
||||
},
|
||||
},
|
||||
"addons-info-github-issues--1814": Object {
|
||||
"endLoc": Object {
|
||||
"col": 4,
|
||||
"line": 152,
|
||||
},
|
||||
"startLoc": Object {
|
||||
"col": 2,
|
||||
"line": 146,
|
||||
},
|
||||
},
|
||||
"addons-info-markdown--displays-markdown-in-description": Object {
|
||||
"endLoc": Object {
|
||||
"col": 96,
|
||||
"line": 44,
|
||||
},
|
||||
"startLoc": Object {
|
||||
"col": 2,
|
||||
"line": 43,
|
||||
},
|
||||
},
|
||||
"addons-info-options-header--shows-or-hides-info-addon-header": Object {
|
||||
"endLoc": Object {
|
||||
"col": 41,
|
||||
"line": 60,
|
||||
},
|
||||
"startLoc": Object {
|
||||
"col": 2,
|
||||
"line": 56,
|
||||
},
|
||||
},
|
||||
"addons-info-options-inline--inlines-component-inside-story": Object {
|
||||
"endLoc": Object {
|
||||
"col": 41,
|
||||
"line": 52,
|
||||
},
|
||||
"startLoc": Object {
|
||||
"col": 2,
|
||||
"line": 48,
|
||||
},
|
||||
},
|
||||
"addons-info-options-proptables--shows-additional-component-prop-tables": Object {
|
||||
"endLoc": Object {
|
||||
"col": 41,
|
||||
"line": 76,
|
||||
},
|
||||
"startLoc": Object {
|
||||
"col": 2,
|
||||
"line": 72,
|
||||
},
|
||||
},
|
||||
"addons-info-options-proptablesexclude--exclude-component-from-prop-tables": Object {
|
||||
"endLoc": Object {
|
||||
"col": 4,
|
||||
"line": 89,
|
||||
},
|
||||
"startLoc": Object {
|
||||
"col": 2,
|
||||
"line": 80,
|
||||
},
|
||||
},
|
||||
"addons-info-options-source--shows-or-hides-info-addon-source": Object {
|
||||
"endLoc": Object {
|
||||
"col": 41,
|
||||
"line": 68,
|
||||
},
|
||||
"startLoc": Object {
|
||||
"col": 2,
|
||||
"line": 64,
|
||||
},
|
||||
},
|
||||
"addons-info-options-styles--extend-info-styles-with-an-object": Object {
|
||||
"endLoc": Object {
|
||||
"col": 43,
|
||||
"line": 108,
|
||||
},
|
||||
"startLoc": Object {
|
||||
"col": 4,
|
||||
"line": 94,
|
||||
},
|
||||
},
|
||||
"addons-info-options-styles--full-control-over-styles-using-a-function": Object {
|
||||
"endLoc": Object {
|
||||
"col": 43,
|
||||
"line": 123,
|
||||
},
|
||||
"startLoc": Object {
|
||||
"col": 4,
|
||||
"line": 111,
|
||||
},
|
||||
},
|
||||
"addons-info-options-tablecomponent--use-a-custom-component-for-the-table": Object {
|
||||
"endLoc": Object {
|
||||
"col": 41,
|
||||
"line": 130,
|
||||
},
|
||||
"startLoc": Object {
|
||||
"col": 2,
|
||||
"line": 127,
|
||||
},
|
||||
},
|
||||
"addons-info-react-docgen--comments-from-component-declaration": Object {
|
||||
"endLoc": Object {
|
||||
"col": 70,
|
||||
"line": 28,
|
||||
},
|
||||
"startLoc": Object {
|
||||
"col": 4,
|
||||
"line": 25,
|
||||
},
|
||||
},
|
||||
"addons-info-react-docgen--comments-from-flow-declarations": Object {
|
||||
"endLoc": Object {
|
||||
"col": 85,
|
||||
"line": 22,
|
||||
},
|
||||
"startLoc": Object {
|
||||
"col": 4,
|
||||
"line": 19,
|
||||
},
|
||||
},
|
||||
"addons-info-react-docgen--comments-from-proptype-declarations": Object {
|
||||
"endLoc": Object {
|
||||
"col": 79,
|
||||
"line": 16,
|
||||
},
|
||||
"startLoc": Object {
|
||||
"col": 4,
|
||||
"line": 13,
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`inject-decorator positive injects 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).addDecorator(withStorySource(__STORY__, __ADDS_MAP__))
|
||||
.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).addDecorator(withStorySource(__STORY__, __ADDS_MAP__)).add(
|
||||
'Displays Markdown in description',
|
||||
withInfo(markdownDescription)(() => <BaseButton onClick={action('clicked')} label=\\"Button\\" />)
|
||||
);
|
||||
|
||||
storiesOf('Addons|Info.Options.inline', module).addDecorator(withStorySource(__STORY__, __ADDS_MAP__)).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).addDecorator(withStorySource(__STORY__, __ADDS_MAP__)).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).addDecorator(withStorySource(__STORY__, __ADDS_MAP__)).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).addDecorator(withStorySource(__STORY__, __ADDS_MAP__)).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).addDecorator(withStorySource(__STORY__, __ADDS_MAP__)).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).addDecorator(withStorySource(__STORY__, __ADDS_MAP__))
|
||||
.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).addDecorator(withStorySource(__STORY__, __ADDS_MAP__)).add(
|
||||
'Use a custom component for the table',
|
||||
withInfo({
|
||||
TableComponent,
|
||||
})(() => <BaseButton label=\\"Button\\" />)
|
||||
);
|
||||
|
||||
storiesOf('Addons|Info.Decorator', module).addDecorator(withStorySource(__STORY__, __ADDS_MAP__))
|
||||
.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).addDecorator(withStorySource(__STORY__, __ADDS_MAP__)).add(
|
||||
'#1814',
|
||||
withInfo('Allow Duplicate DisplayNames for HOC #1814')(() => (
|
||||
<div>
|
||||
<Input />
|
||||
<TextArea />
|
||||
</div>
|
||||
))
|
||||
);
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`inject-decorator stories with ugly comments in ts should delete ugly comments from the generated story source 1`] = `
|
||||
"import React from 'react';
|
||||
|
||||
@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';
|
||||
}
|
||||
}
|
||||
|
||||
import { storiesOf } from '@storybook/react';
|
||||
|
||||
const x = 0;
|
||||
|
||||
storiesOf('Foo', module).add('bar', () => <div>baz</div>);
|
||||
|
||||
/*
|
||||
This is actually a good comment that will help
|
||||
users to understand what's going on here.
|
||||
*/
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`inject-decorator stories with ugly comments should delete ugly comments from the generated story source 1`] = `
|
||||
"import React from 'react';
|
||||
|
||||
import { storiesOf } from '@storybook/react';
|
||||
|
||||
const x = 0;
|
||||
|
||||
storiesOf('Foo', module).add('bar', () => <div>baz</div>);
|
||||
|
||||
/*
|
||||
This is actually a good comment that will help
|
||||
users to understand what's going on here.
|
||||
*/
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`inject-decorator will not change the source when there are no "storiesOf" functions 1`] = `
|
||||
"while(true) {
|
||||
console.log(\\"it's a kind of magic\\");
|
||||
}"
|
||||
`;
|
@ -1,12 +0,0 @@
|
||||
const defaultOptions = {
|
||||
prettierConfig: {
|
||||
printWidth: 100,
|
||||
tabWidth: 2,
|
||||
bracketSpacing: true,
|
||||
trailingComma: 'es5',
|
||||
singleQuote: true,
|
||||
},
|
||||
uglyCommentsRegex: [/^eslint-.*/, /^global.*/],
|
||||
};
|
||||
|
||||
export default defaultOptions;
|
@ -1,99 +0,0 @@
|
||||
import prettier from 'prettier';
|
||||
import { patchNode } from './parse-helpers';
|
||||
import { splitSTORYOF, findAddsMap } from './traverse-helpers';
|
||||
import getParser from './parsers';
|
||||
|
||||
function isUglyComment(comment, uglyCommentsRegex) {
|
||||
return uglyCommentsRegex.some(regex => regex.test(comment));
|
||||
}
|
||||
|
||||
function generateSourceWithoutUglyComments(source, { comments, uglyCommentsRegex }) {
|
||||
let lastIndex = 0;
|
||||
const parts = [source];
|
||||
|
||||
comments
|
||||
.filter(comment => isUglyComment(comment.value.trim(), uglyCommentsRegex))
|
||||
.map(patchNode)
|
||||
.forEach(comment => {
|
||||
parts.pop();
|
||||
|
||||
const start = source.slice(lastIndex, comment.start);
|
||||
const end = source.slice(comment.end);
|
||||
|
||||
parts.push(start, end);
|
||||
lastIndex = comment.end;
|
||||
});
|
||||
|
||||
return parts.join('');
|
||||
}
|
||||
|
||||
function prettifyCode(source, { prettierConfig, parser, filepath }) {
|
||||
let config = prettierConfig;
|
||||
|
||||
if (!config.parser) {
|
||||
if (parser) {
|
||||
config = {
|
||||
...prettierConfig,
|
||||
parser: parser === 'javascript' ? 'babel' : parser,
|
||||
};
|
||||
} else if (filepath) {
|
||||
config = {
|
||||
...prettierConfig,
|
||||
filepath,
|
||||
};
|
||||
} else {
|
||||
config = {
|
||||
...prettierConfig,
|
||||
parser: 'babel',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return prettier.format(source, config);
|
||||
}
|
||||
|
||||
export function generateSourceWithDecorators(source, decorator, parserType) {
|
||||
const parser = getParser(parserType);
|
||||
const ast = parser.parse(source);
|
||||
|
||||
const { comments = [] } = ast;
|
||||
|
||||
const parts = splitSTORYOF(ast, source);
|
||||
|
||||
const newSource = parts.join(decorator);
|
||||
|
||||
return {
|
||||
changed: parts.length > 1,
|
||||
source: newSource,
|
||||
comments,
|
||||
};
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return findAddsMap(ast);
|
||||
}
|
||||
|
||||
export function generateStorySource({ source, ...options }) {
|
||||
let storySource = source;
|
||||
|
||||
storySource = generateSourceWithoutUglyComments(storySource, options);
|
||||
storySource = prettifyCode(storySource, options);
|
||||
|
||||
return storySource;
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
import { getOptions } from 'loader-utils';
|
||||
import injectDecorator from './inject-decorator';
|
||||
|
||||
const ADD_DECORATOR_STATEMENT = '.addDecorator(withStorySource(__STORY__, __ADDS_MAP__))';
|
||||
|
||||
function transform(source) {
|
||||
const options = getOptions(this) || {};
|
||||
const result = injectDecorator(source, ADD_DECORATOR_STATEMENT, this.resourcePath, options);
|
||||
|
||||
if (!result.changed) {
|
||||
return source;
|
||||
}
|
||||
|
||||
const sourceJson = JSON.stringify(result.storySource)
|
||||
.replace(/\u2028/g, '\\u2028')
|
||||
.replace(/\u2029/g, '\\u2029');
|
||||
|
||||
const addsMap = JSON.stringify(result.addsMap);
|
||||
|
||||
return `
|
||||
export var withStorySource = require('@storybook/addon-storysource').withStorySource;
|
||||
export var __STORY__ = ${sourceJson};
|
||||
export var __ADDS_MAP__ = ${addsMap};
|
||||
|
||||
${result.source}
|
||||
`;
|
||||
}
|
||||
|
||||
export default transform;
|
@ -1,46 +0,0 @@
|
||||
import defaultOptions from './default-options';
|
||||
|
||||
import {
|
||||
generateSourceWithDecorators,
|
||||
generateSourceWithoutDecorators,
|
||||
generateStorySource,
|
||||
generateAddsMap,
|
||||
} from './generate-helpers';
|
||||
|
||||
function extendOptions(source, comments, filepath, options) {
|
||||
return {
|
||||
...defaultOptions,
|
||||
...options,
|
||||
source,
|
||||
comments,
|
||||
filepath,
|
||||
};
|
||||
}
|
||||
|
||||
function inject(source, decorator, filepath, options = {}) {
|
||||
const { injectDecorator = true } = options;
|
||||
const { changed, source: newSource, comments } =
|
||||
injectDecorator === true
|
||||
? generateSourceWithDecorators(source, decorator, options.parser)
|
||||
: generateSourceWithoutDecorators(source, options.parser);
|
||||
|
||||
if (!changed) {
|
||||
return {
|
||||
source: newSource,
|
||||
addsMap: {},
|
||||
changed,
|
||||
};
|
||||
}
|
||||
|
||||
const storySource = generateStorySource(extendOptions(source, comments, filepath, options));
|
||||
const addsMap = generateAddsMap(storySource, options.parser);
|
||||
|
||||
return {
|
||||
source: newSource,
|
||||
storySource,
|
||||
addsMap,
|
||||
changed,
|
||||
};
|
||||
}
|
||||
|
||||
export default inject;
|
@ -1,216 +0,0 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import injectDecorator from './inject-decorator';
|
||||
|
||||
const ADD_DECORATOR_STATEMENT = '.addDecorator(withStorySource(__STORY__, __ADDS_MAP__))';
|
||||
|
||||
describe('inject-decorator', () => {
|
||||
describe('positive', () => {
|
||||
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),
|
||||
{ parser: 'javascript' }
|
||||
);
|
||||
|
||||
it('returns "changed" flag', () => {
|
||||
expect(result.changed).toBeTruthy();
|
||||
});
|
||||
|
||||
it('injects stories decorator after the all "storiesOf" functions', () => {
|
||||
expect(result.source).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('calculates "adds" map', () => {
|
||||
expect(result.addsMap).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('positive - 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),
|
||||
{ parser: 'typescript' }
|
||||
);
|
||||
|
||||
it('returns "changed" flag', () => {
|
||||
expect(result.changed).toBeTruthy();
|
||||
});
|
||||
|
||||
it('injects stories decorator after the all "storiesOf" functions', () => {
|
||||
expect(result.source).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('calculates "adds" map', () => {
|
||||
expect(result.addsMap).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('positive - flow', () => {
|
||||
const mockFilePath = './__mocks__/inject-decorator.flow-stories.txt';
|
||||
const source = fs.readFileSync(mockFilePath, 'utf-8');
|
||||
const result = injectDecorator(
|
||||
source,
|
||||
ADD_DECORATOR_STATEMENT,
|
||||
path.resolve(__dirname, mockFilePath),
|
||||
{ parser: 'flow' }
|
||||
);
|
||||
|
||||
it('returns "changed" flag', () => {
|
||||
expect(result.changed).toBeTruthy();
|
||||
});
|
||||
|
||||
it('injects stories decorator after the all "storiesOf" functions', () => {
|
||||
expect(result.source).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('calculates "adds" map', () => {
|
||||
expect(result.addsMap).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('positive - 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),
|
||||
{ parser: 'typescript' }
|
||||
);
|
||||
|
||||
it('returns "changed" flag', () => {
|
||||
expect(result.changed).toBeTruthy();
|
||||
});
|
||||
|
||||
it('injects stories decorator after the all "storiesOf" functions', () => {
|
||||
expect(result.source).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('calculates "adds" map', () => {
|
||||
expect(result.addsMap).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('stories with ugly comments', () => {
|
||||
const mockFilePath = './__mocks__/inject-decorator.ugly-comments-stories.txt';
|
||||
const source = fs.readFileSync(mockFilePath, 'utf-8');
|
||||
const result = injectDecorator(
|
||||
source,
|
||||
ADD_DECORATOR_STATEMENT,
|
||||
path.resolve(__dirname, mockFilePath),
|
||||
{ parser: 'javascript' }
|
||||
);
|
||||
|
||||
it('should delete ugly comments from the generated story source', () => {
|
||||
expect(result.storySource).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('stories with ugly comments in ts', () => {
|
||||
const mockFilePath = './__mocks__/inject-decorator.ts.ugly-comments-stories.txt';
|
||||
const source = fs.readFileSync(mockFilePath, 'utf-8');
|
||||
const result = injectDecorator(
|
||||
source,
|
||||
ADD_DECORATOR_STATEMENT,
|
||||
path.resolve(__dirname, mockFilePath),
|
||||
{ parser: 'typescript' }
|
||||
);
|
||||
|
||||
it('should delete ugly comments from the generated story source', () => {
|
||||
expect(result.storySource).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
it('will not change the source when there are no "storiesOf" functions', () => {
|
||||
const mockFilePath = './__mocks__/inject-decorator.no-stories.txt';
|
||||
const source = fs.readFileSync(mockFilePath, 'utf-8');
|
||||
|
||||
const result = injectDecorator(
|
||||
source,
|
||||
ADD_DECORATOR_STATEMENT,
|
||||
path.resolve(__dirname, mockFilePath)
|
||||
);
|
||||
|
||||
expect(result.changed).toBeFalsy();
|
||||
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 - flow', () => {
|
||||
const mockFilePath = './__mocks__/inject-decorator.flow-stories.txt';
|
||||
const source = fs.readFileSync(mockFilePath, 'utf-8');
|
||||
const result = injectDecorator(
|
||||
source,
|
||||
ADD_DECORATOR_STATEMENT,
|
||||
path.resolve(__dirname, mockFilePath),
|
||||
{
|
||||
injectDecorator: false,
|
||||
parser: 'flow',
|
||||
}
|
||||
);
|
||||
|
||||
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();
|
||||
});
|
||||
});
|
||||
});
|
@ -1,110 +0,0 @@
|
||||
const { toId } = require('@storybook/router/utils');
|
||||
|
||||
const STORIES_OF = 'storiesOf';
|
||||
|
||||
function pushParts(source, parts, from, to) {
|
||||
const start = source.slice(from, to);
|
||||
parts.push(start);
|
||||
|
||||
const end = source.slice(to);
|
||||
parts.push(end);
|
||||
}
|
||||
|
||||
function getKindFromStoryOfNode(object) {
|
||||
if (object.arguments.length < 1) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const kindArgument = object.arguments[0];
|
||||
|
||||
if (kindArgument.type === 'Literal' || kindArgument.type === 'StringLiteral') {
|
||||
return kindArgument.value;
|
||||
}
|
||||
|
||||
if (kindArgument.type === 'TemplateLiteral') {
|
||||
// we can generate template, but it will not be a real value
|
||||
// until the full template compilation. probably won't fix.
|
||||
return '';
|
||||
}
|
||||
|
||||
// other options may include some complex usages.
|
||||
return '';
|
||||
}
|
||||
|
||||
function findRelatedKind(object) {
|
||||
if (!object || !object.callee) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (object.callee.name === STORIES_OF) {
|
||||
return getKindFromStoryOfNode(object);
|
||||
}
|
||||
|
||||
return findRelatedKind(object.callee.object);
|
||||
}
|
||||
|
||||
export function patchNode(node) {
|
||||
if (node.range && node.range.length === 2 && node.start === undefined && node.end === undefined) {
|
||||
const [start, end] = node.range;
|
||||
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
node.start = start;
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
node.end = end;
|
||||
}
|
||||
|
||||
if (!node.range && node.start !== undefined && node.end !== undefined) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
node.range = [node.start, node.end];
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
export function handleADD(node, parent, adds) {
|
||||
if (!node.property || !node.property.name || node.property.name.indexOf('add') !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const addArgs = parent.arguments;
|
||||
|
||||
if (!addArgs || addArgs.length < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
const storyName = addArgs[0];
|
||||
const lastArg = addArgs[addArgs.length - 1];
|
||||
|
||||
if (storyName.type !== 'Literal' && storyName.type !== 'StringLiteral') {
|
||||
// if story name is not literal, it's much harder to extract it
|
||||
return;
|
||||
}
|
||||
|
||||
const kind = findRelatedKind(node.object) || '';
|
||||
if (kind && storyName.value) {
|
||||
const key = toId(kind, storyName.value);
|
||||
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
adds[key] = {
|
||||
// Debug: code: source.slice(storyName.start, lastArg.end),
|
||||
startLoc: {
|
||||
col: storyName.loc.start.column,
|
||||
line: storyName.loc.start.line,
|
||||
},
|
||||
endLoc: {
|
||||
col: lastArg.loc.end.column,
|
||||
line: lastArg.loc.end.line,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function handleSTORYOF(node, parts, source, lastIndex) {
|
||||
if (!node.callee || !node.callee.name || node.callee.name !== STORIES_OF) {
|
||||
return lastIndex;
|
||||
}
|
||||
|
||||
parts.pop();
|
||||
pushParts(source, parts, lastIndex, node.end);
|
||||
return node.end;
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
function getParser(type) {
|
||||
if (type === 'javascript' || !type) {
|
||||
// eslint-disable-next-line global-require
|
||||
return require('./parser-js').default;
|
||||
}
|
||||
|
||||
if (type === 'typescript') {
|
||||
// eslint-disable-next-line global-require
|
||||
return require('./parser-ts').default;
|
||||
}
|
||||
|
||||
if (type === 'flow') {
|
||||
// eslint-disable-next-line global-require
|
||||
return require('./parser-flow').default;
|
||||
}
|
||||
|
||||
throw new Error(`Parser of type "${type}" is not supported`);
|
||||
}
|
||||
|
||||
export default getParser;
|
@ -1,9 +0,0 @@
|
||||
import parseFlow from 'prettier/parser-flow';
|
||||
|
||||
function parse(source) {
|
||||
return parseFlow.parsers.flow.parse(source);
|
||||
}
|
||||
|
||||
export default {
|
||||
parse,
|
||||
};
|
@ -1,9 +0,0 @@
|
||||
import parseJs from 'prettier/parser-babylon';
|
||||
|
||||
function parse(source) {
|
||||
return parseJs.parsers.babel.parse(source);
|
||||
}
|
||||
|
||||
export default {
|
||||
parse,
|
||||
};
|
@ -1,9 +0,0 @@
|
||||
import parseTs from 'prettier/parser-typescript';
|
||||
|
||||
function parse(source) {
|
||||
return parseTs.parsers.typescript.parse(source);
|
||||
}
|
||||
|
||||
export default {
|
||||
parse,
|
||||
};
|
@ -1,38 +0,0 @@
|
||||
import { handleADD, handleSTORYOF, patchNode } from './parse-helpers';
|
||||
|
||||
const estraverse = require('estraverse');
|
||||
|
||||
export function splitSTORYOF(ast, source) {
|
||||
let lastIndex = 0;
|
||||
const parts = [source];
|
||||
|
||||
estraverse.traverse(ast, {
|
||||
fallback: 'iteration',
|
||||
enter: node => {
|
||||
patchNode(node);
|
||||
|
||||
if (node.type === 'CallExpression') {
|
||||
lastIndex = handleSTORYOF(node, parts, source, lastIndex);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
return parts;
|
||||
}
|
||||
|
||||
export function findAddsMap(ast) {
|
||||
const adds = {};
|
||||
|
||||
estraverse.traverse(ast, {
|
||||
fallback: 'iteration',
|
||||
enter: (node, parent) => {
|
||||
patchNode(node);
|
||||
|
||||
if (node.type === 'MemberExpression') {
|
||||
handleADD(node, parent, adds);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
return adds;
|
||||
}
|
@ -5,7 +5,7 @@ module.exports = async ({ config }: { config: any }) => {
|
||||
test: [/\.stories\.tsx?$/, /index\.ts$/],
|
||||
loaders: [
|
||||
{
|
||||
loader: require.resolve('@storybook/addon-storysource/loader'),
|
||||
loader: require.resolve('@storybook/source-loader'),
|
||||
options: {
|
||||
parser: 'typescript',
|
||||
},
|
||||
|
@ -47,6 +47,7 @@
|
||||
"@storybook/addon-storysource": "5.2.0-alpha.35",
|
||||
"@storybook/addons": "5.2.0-alpha.35",
|
||||
"@storybook/angular": "5.2.0-alpha.35",
|
||||
"@storybook/source-loader": "5.2.0-alpha.35",
|
||||
"@types/core-js": "^2.5.0",
|
||||
"@types/jest": "^24.0.11",
|
||||
"@types/node": "~12.0.2",
|
||||
|
@ -3,7 +3,7 @@ const path = require('path');
|
||||
module.exports = async ({ config }) => {
|
||||
config.module.rules.push({
|
||||
test: [/\.stories\.js$/, /index\.js$/],
|
||||
loaders: [require.resolve('@storybook/addon-storysource/loader')],
|
||||
loaders: [require.resolve('@storybook/source-loader')],
|
||||
include: [path.resolve(__dirname, '../')],
|
||||
enforce: 'pre',
|
||||
});
|
||||
|
@ -3,7 +3,7 @@ const path = require('path');
|
||||
module.exports = async ({ config }) => {
|
||||
config.module.rules.push({
|
||||
test: [/\.stories\.js$/, /index\.js$/],
|
||||
loaders: [require.resolve('@storybook/addon-storysource/loader')],
|
||||
loaders: [require.resolve('@storybook/source-loader')],
|
||||
include: [path.resolve(__dirname, '../stories')],
|
||||
enforce: 'pre',
|
||||
});
|
||||
|
@ -3,7 +3,7 @@ const path = require('path');
|
||||
module.exports = async ({ config }) => {
|
||||
config.module.rules.push({
|
||||
test: [/\.stories\.js$/],
|
||||
loaders: [require.resolve('@storybook/addon-storysource/loader')],
|
||||
loaders: [require.resolve('@storybook/source-loader')],
|
||||
include: [path.resolve(__dirname, '../src')],
|
||||
enforce: 'pre',
|
||||
});
|
||||
|
@ -3,7 +3,7 @@ const path = require('path');
|
||||
module.exports = async ({ config }) => {
|
||||
config.module.rules.push({
|
||||
test: [/\.stories\.js$/],
|
||||
loaders: [require.resolve('@storybook/addon-storysource/loader')],
|
||||
loaders: [require.resolve('@storybook/source-loader')],
|
||||
include: [path.resolve(__dirname, '../src')],
|
||||
enforce: 'pre',
|
||||
});
|
||||
|
@ -4,7 +4,7 @@ const webpack = require('webpack');
|
||||
module.exports = async ({ config }) => {
|
||||
config.module.rules.push({
|
||||
test: [/\.stories\.js$/, /index\.js$/],
|
||||
loaders: [require.resolve('@storybook/addon-storysource/loader')],
|
||||
loaders: [require.resolve('@storybook/source-loader')],
|
||||
include: [path.resolve(__dirname, '../src')],
|
||||
enforce: 'pre',
|
||||
});
|
||||
|
@ -3,7 +3,7 @@ const path = require('path');
|
||||
module.exports = ({ config }) => {
|
||||
config.module.rules.push({
|
||||
test: [/\.stories\.js$/],
|
||||
loaders: [require.resolve('@storybook/addon-storysource/loader')],
|
||||
loaders: [require.resolve('@storybook/source-loader')],
|
||||
include: [path.resolve(__dirname, '../src')],
|
||||
enforce: 'pre',
|
||||
});
|
||||
|
@ -5,7 +5,7 @@ module.exports = {
|
||||
rules: [
|
||||
{
|
||||
test: [/\.stories\.js$/, /index\.js$/],
|
||||
loaders: [require.resolve('@storybook/addon-storysource/loader')],
|
||||
loaders: [require.resolve('@storybook/source-loader')],
|
||||
include: [path.resolve(__dirname, '../src')],
|
||||
enforce: 'pre',
|
||||
},
|
||||
|
@ -3,7 +3,7 @@ const path = require('path');
|
||||
module.exports = async ({ config }) => {
|
||||
config.module.rules.push({
|
||||
test: [/\.stories\.js$/, /index\.js$/],
|
||||
loaders: [require.resolve('@storybook/addon-storysource/loader')],
|
||||
loaders: [require.resolve('@storybook/source-loader')],
|
||||
include: [path.resolve(__dirname, '../src')],
|
||||
enforce: 'pre',
|
||||
});
|
||||
|
@ -3,7 +3,7 @@ const path = require('path');
|
||||
module.exports = async ({ config }) => {
|
||||
config.module.rules.push({
|
||||
test: [/\.stories\.js$/, /index\.js$/],
|
||||
loaders: [require.resolve('@storybook/addon-storysource/loader')],
|
||||
loaders: [require.resolve('@storybook/source-loader')],
|
||||
include: [path.resolve(__dirname, '../src')],
|
||||
enforce: 'pre',
|
||||
});
|
||||
|
@ -8,7 +8,7 @@ module.exports = async ({ config }) => {
|
||||
});
|
||||
config.module.rules.push({
|
||||
test: [/\.stories\.js$/, /index\.js$/],
|
||||
loaders: [require.resolve('@storybook/addon-storysource/loader')],
|
||||
loaders: [require.resolve('@storybook/source-loader')],
|
||||
include: [path.resolve(__dirname, '../src')],
|
||||
enforce: 'pre',
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user