From 53e10dc949e07ef7e2507b75abe35e2f6fcc9c62 Mon Sep 17 00:00:00 2001
From: Oleg Proskurin
Date: Thu, 20 Jul 2017 14:19:04 +0300
Subject: [PATCH 01/33] Init Info Panel
---
addons/info/package.json | 4 +-
addons/info/register.js | 1 +
addons/info/src/config.js | 4 ++
addons/info/src/index.js | 17 ++++++++-
addons/info/src/manager.js | 14 +++++++
addons/info/src/panel/index.js | 38 +++++++++++++++++++
.../cra-kitchen-sink/.storybook/addons.js | 1 +
.../cra-kitchen-sink/src/stories/index.js | 3 +-
8 files changed, 78 insertions(+), 4 deletions(-)
create mode 100644 addons/info/register.js
create mode 100644 addons/info/src/config.js
create mode 100644 addons/info/src/manager.js
create mode 100644 addons/info/src/panel/index.js
diff --git a/addons/info/package.json b/addons/info/package.json
index 394881b11a77..76facf2b68dd 100644
--- a/addons/info/package.json
+++ b/addons/info/package.json
@@ -25,10 +25,10 @@
"devDependencies": {
"git-url-parse": "^6.2.2",
"react": "^15.5.4",
- "react-dom": "^15.5.4",
"react-test-renderer": "^15.5.4"
},
"peerDependencies": {
- "react": "*"
+ "react": "*",
+ "react-dom": "^15.5.4"
}
}
diff --git a/addons/info/register.js b/addons/info/register.js
new file mode 100644
index 000000000000..9232e6c069d5
--- /dev/null
+++ b/addons/info/register.js
@@ -0,0 +1 @@
+require('./dist/manager').register();
diff --git a/addons/info/src/config.js b/addons/info/src/config.js
new file mode 100644
index 000000000000..dcb93109aa18
--- /dev/null
+++ b/addons/info/src/config.js
@@ -0,0 +1,4 @@
+export const ADDON_ID = 'storybook/info';
+export const ADDON_TITLE = 'info';
+export const PANEL_ID = `${ADDON_ID}/info-panel`;
+export const EVENT_ID = `${ADDON_ID}/info-event`;
diff --git a/addons/info/src/index.js b/addons/info/src/index.js
index 3ff306f3ee55..0c0241af1361 100644
--- a/addons/info/src/index.js
+++ b/addons/info/src/index.js
@@ -1,5 +1,8 @@
import React from 'react';
+import ReactDOMServer from 'react-dom/server';
+import addons from '@storybook/addons';
import deprecate from 'util-deprecate';
+import { EVENT_ID } from './config';
import _Story from './components/Story';
import { H1, H2, H3, H4, H5, H6, Code, P, UL, A, LI } from './components/markdown';
@@ -7,6 +10,14 @@ function addonCompose(addonFn) {
return storyFn => context => addonFn(storyFn, context);
}
+const channel = addons.getChannel();
+
+function sendToPanel(infoString) {
+ channel.emit(EVENT_ID, {
+ infoString,
+ });
+}
+
export const Story = _Story;
const defaultOptions = {
@@ -76,11 +87,15 @@ export function addInfo(storyFn, context, info, _options) {
maxPropsIntoLine: options.maxPropsIntoLine,
maxPropStringLength: options.maxPropStringLength,
};
- return (
+
+ const infoContent = (
{storyFn(context)}
);
+ const infoString = ReactDOMServer.renderToString(infoContent);
+ sendToPanel(infoString);
+ return infoContent;
}
export const withInfo = (info, _options) =>
diff --git a/addons/info/src/manager.js b/addons/info/src/manager.js
new file mode 100644
index 000000000000..9afa80e25d3c
--- /dev/null
+++ b/addons/info/src/manager.js
@@ -0,0 +1,14 @@
+import React from 'react';
+import addons from '@storybook/addons';
+import InfoPanel from './panel';
+import { ADDON_ID, PANEL_ID, ADDON_TITLE } from './config';
+
+export function register() {
+ addons.register(ADDON_ID, () => {
+ const channel = addons.getChannel();
+ addons.addPanel(PANEL_ID, {
+ title: ADDON_TITLE,
+ render: () => ,
+ });
+ });
+}
diff --git a/addons/info/src/panel/index.js b/addons/info/src/panel/index.js
new file mode 100644
index 000000000000..8d3cc992c695
--- /dev/null
+++ b/addons/info/src/panel/index.js
@@ -0,0 +1,38 @@
+import React from 'react';
+import ReactDom from 'react-dom';
+import PropTypes from 'prop-types';
+import { EVENT_ID } from '../config';
+
+export default class InfoPanel extends React.Component {
+ constructor(props) {
+ super(props);
+ this.root = null;
+
+ this.onChannelData = this.onChannelData.bind(this);
+ }
+
+ componentDidMount() {
+ this.props.channel.on(EVENT_ID, this.onChannelData);
+ }
+
+ onChannelData(data) {
+ this.root.innerHTML = data.infoString;
+ ReactDom.render(null, this.root);
+ }
+
+ render() {
+ return (
+ {
+ this.root = c;
+ }}
+ >
+ Info Panel
+
+ );
+ }
+}
+
+InfoPanel.propTypes = {
+ channel: PropTypes.object, // eslint-disable-line react/forbid-prop-types
+};
diff --git a/examples/cra-kitchen-sink/.storybook/addons.js b/examples/cra-kitchen-sink/.storybook/addons.js
index 5c57d83ea6f9..1bc6246ff835 100644
--- a/examples/cra-kitchen-sink/.storybook/addons.js
+++ b/examples/cra-kitchen-sink/.storybook/addons.js
@@ -1,3 +1,4 @@
+import '@storybook/addon-info/register';
import '@storybook/addon-actions/register';
import '@storybook/addon-links/register';
import '@storybook/addon-events/register';
diff --git a/examples/cra-kitchen-sink/src/stories/index.js b/examples/cra-kitchen-sink/src/stories/index.js
index e308ad065114..d1ceda11106f 100644
--- a/examples/cra-kitchen-sink/src/stories/index.js
+++ b/examples/cra-kitchen-sink/src/stories/index.js
@@ -126,7 +126,8 @@ storiesOf('Button', module)
.add(
'with new info',
withInfo(
- 'Use the [info addon](https://github.com/storybooks/storybook/tree/master/addons/info) with its new painless API.'
+ 'Use the [info addon](https://github.com/storybooks/storybook/tree/master/addons/info) with its new painless API.',
+ { inline: true }
)(context =>
click the
label in top right for info about "{context.story}"
From 1920cf42805943291d8ef5d8b4887f7b5834b225 Mon Sep 17 00:00:00 2001
From: Oleg Proskurin
Date: Fri, 21 Jul 2017 12:04:53 +0300
Subject: [PATCH 02/33] Add react-komposer to Addon-Info
---
addons/info/package.json | 1 +
addons/info/src/manager.js | 16 ++++++---
addons/info/src/panel/empty_panel.js | 41 +++++++++++++++++++++++
addons/info/src/panel/index.js | 50 +++++++++++-----------------
4 files changed, 74 insertions(+), 34 deletions(-)
create mode 100644 addons/info/src/panel/empty_panel.js
diff --git a/addons/info/package.json b/addons/info/package.json
index 76facf2b68dd..e645c3480b2a 100644
--- a/addons/info/package.json
+++ b/addons/info/package.json
@@ -20,6 +20,7 @@
"marksy": "^2.0.0",
"prop-types": "^15.5.8",
"react-addons-create-fragment": "^15.5.3",
+ "react-komposer": "^2.0.0",
"util-deprecate": "^1.0.2"
},
"devDependencies": {
diff --git a/addons/info/src/manager.js b/addons/info/src/manager.js
index 9afa80e25d3c..1a5dfd327a92 100644
--- a/addons/info/src/manager.js
+++ b/addons/info/src/manager.js
@@ -1,14 +1,22 @@
import React from 'react';
import addons from '@storybook/addons';
+import { compose } from 'react-komposer';
import InfoPanel from './panel';
-import { ADDON_ID, PANEL_ID, ADDON_TITLE } from './config';
+import { ADDON_ID, PANEL_ID, ADDON_TITLE, EVENT_ID } from './config';
+
+function infoHandler({ api }, onData) {
+ const channel = addons.getChannel();
+ channel.on(EVENT_ID, ({ infoString }) => onData(null, { infoString }));
+ api.onStory(() => onData(null, {}));
+ onData(null, {});
+}
+const InfoContainer = compose(infoHandler)(InfoPanel);
export function register() {
- addons.register(ADDON_ID, () => {
- const channel = addons.getChannel();
+ addons.register(ADDON_ID, api => {
addons.addPanel(PANEL_ID, {
title: ADDON_TITLE,
- render: () => ,
+ render: () => ,
});
});
}
diff --git a/addons/info/src/panel/empty_panel.js b/addons/info/src/panel/empty_panel.js
new file mode 100644
index 000000000000..008360fc2820
--- /dev/null
+++ b/addons/info/src/panel/empty_panel.js
@@ -0,0 +1,41 @@
+import React from 'react';
+
+const styles = {
+ main: {
+ fontFamily:
+ '-apple-system, ".SFNSText-Regular", "San Francisco", Roboto, "Segoe UI", "Helvetica Neue", "Lucida Grande", sans-serif',
+ display: 'inline',
+ width: '100%',
+ textAlign: 'center',
+ color: 'rgb(190, 190, 190)',
+ padding: 10,
+ },
+ code: {
+ backgroundColor: 'rgba(0,0,0,0.1)',
+ border: 'solid 1px rgba(0,0,0,0.3)',
+ color: 'rgb(90, 90, 90)',
+ borderRadius: 4,
+ padding: 4,
+ },
+};
+
+function EmptyPanel() {
+ return (
+
+ INFO PANEL
+
No info provided for this story
+
+ Use withInfo()
to add info addon
+
+
+ See{' '}
+
+ storybook-addon-info
+ {' '}
+ for details
+
+
+ );
+}
+
+export default EmptyPanel;
diff --git a/addons/info/src/panel/index.js b/addons/info/src/panel/index.js
index 8d3cc992c695..0182056449a3 100644
--- a/addons/info/src/panel/index.js
+++ b/addons/info/src/panel/index.js
@@ -1,38 +1,28 @@
import React from 'react';
-import ReactDom from 'react-dom';
import PropTypes from 'prop-types';
-import { EVENT_ID } from '../config';
+import EmptyPanel from './empty_panel';
-export default class InfoPanel extends React.Component {
- constructor(props) {
- super(props);
- this.root = null;
-
- this.onChannelData = this.onChannelData.bind(this);
- }
-
- componentDidMount() {
- this.props.channel.on(EVENT_ID, this.onChannelData);
- }
+const styles = {
+ main: {
+ width: '100%',
+ padding: 8,
+ backgroundColor: '#ededed',
+ },
+};
- onChannelData(data) {
- this.root.innerHTML = data.infoString;
- ReactDom.render(null, this.root);
+const InfoPanel = ({ infoString }) => {
+ if (!infoString) {
+ return ;
}
+ const infoMarkup = {
+ __html: infoString,
+ };
- render() {
- return (
- {
- this.root = c;
- }}
- >
- Info Panel
-
- );
- }
-}
+ return
;
+};
-InfoPanel.propTypes = {
- channel: PropTypes.object, // eslint-disable-line react/forbid-prop-types
+InfoPanel.PropTypes = {
+ infoString: PropTypes.string.isRequired,
};
+
+export default InfoPanel;
From 3eabb5d35106652bce77bb2985df13ba0c5721d1 Mon Sep 17 00:00:00 2001
From: Oleg Proskurin
Date: Fri, 21 Jul 2017 13:03:47 +0300
Subject: [PATCH 03/33] Add decoratorInfo to Addon-Info
---
addons/info/src/components/Story.js | 26 +++++++-----
addons/info/src/index.js | 27 +++++++++++--
.../cra-kitchen-sink/src/stories/index.js | 40 +++++++++++++++----
3 files changed, 73 insertions(+), 20 deletions(-)
diff --git a/addons/info/src/components/Story.js b/addons/info/src/components/Story.js
index fd1fdec3238e..90832e987b2e 100644
--- a/addons/info/src/components/Story.js
+++ b/addons/info/src/components/Story.js
@@ -34,7 +34,7 @@ const stylesheet = {
},
},
info: {
- position: 'fixed',
+ position: 'relative',
background: 'white',
top: 0,
bottom: 0,
@@ -99,10 +99,10 @@ const stylesheet = {
};
export default class Story extends React.Component {
- constructor(...args) {
- super(...args);
+ constructor(props, ...args) {
+ super(props, ...args);
this.state = {
- open: false,
+ open: props.hideInfoButton,
stylesheet: this.props.styles(JSON.parse(JSON.stringify(stylesheet))),
};
this.marksy = marksy(this.props.marksyConf);
@@ -158,12 +158,16 @@ export default class Story extends React.Component {
const linkStyle = {
...stylesheet.link.base,
...stylesheet.link.topRight,
+ display: this.props.hideInfoButton && 'none',
};
const infoStyle = Object.assign({}, stylesheet.info);
if (!this.state.open) {
infoStyle.display = 'none';
}
+ const storyStyle = {
+ display: this.state.open && 'none',
+ };
const openOverlay = () => {
this.setState({ open: true });
@@ -177,12 +181,14 @@ export default class Story extends React.Component {
return (
-
- {this.props.children}
+
-
- Show Info
-
×
@@ -393,6 +399,7 @@ Story.propTypes = {
propTables: PropTypes.arrayOf(PropTypes.func),
propTablesExclude: PropTypes.arrayOf(PropTypes.func),
showInline: PropTypes.bool,
+ hideInfoButton: PropTypes.bool,
showHeader: PropTypes.bool,
showSource: PropTypes.bool,
styles: PropTypes.func.isRequired,
@@ -410,6 +417,7 @@ Story.defaultProps = {
propTables: null,
propTablesExclude: [],
showInline: false,
+ hideInfoButton: false,
showHeader: true,
showSource: true,
marksyConf: {},
diff --git a/addons/info/src/index.js b/addons/info/src/index.js
index 0c0241af1361..b9f7803ac87c 100644
--- a/addons/info/src/index.js
+++ b/addons/info/src/index.js
@@ -29,6 +29,8 @@ const defaultOptions = {
maxPropObjectKeys: 3,
maxPropArrayLength: 3,
maxPropStringLength: 50,
+ hideInfoButton: true,
+ sendToPanel: true,
};
const defaultMarksyConf = {
@@ -78,6 +80,7 @@ export function addInfo(storyFn, context, info, _options) {
showInline: Boolean(options.inline),
showHeader: Boolean(options.header),
showSource: Boolean(options.source),
+ hideInfoButton: Boolean(options.hideInfoButton),
propTables: options.propTables,
propTablesExclude: options.propTablesExclude,
styles: typeof options.styles === 'function' ? options.styles : s => s,
@@ -93,13 +96,31 @@ export function addInfo(storyFn, context, info, _options) {
{storyFn(context)}
);
- const infoString = ReactDOMServer.renderToString(infoContent);
- sendToPanel(infoString);
+ if (options.sendToPanel) {
+ const infoString = ReactDOMServer.renderToString(infoContent);
+ sendToPanel(infoString);
+ return storyFn(context);
+ }
return infoContent;
}
+const panelOptions = options => ({
+ ...options,
+ sendToPanel: true,
+ hideInfoButton: true,
+});
+
+const decoratorOptions = options => ({
+ ...options,
+ sendToPanel: false,
+ hideInfoButton: false,
+});
+
export const withInfo = (info, _options) =>
- addonCompose((storyFn, context) => addInfo(storyFn, context, info, _options));
+ addonCompose((storyFn, context) => addInfo(storyFn, context, info, panelOptions(_options)));
+
+export const decoratorInfo = (info, _options) =>
+ addonCompose((storyFn, context) => addInfo(storyFn, context, info, decoratorOptions(_options)));
export default {
addWithInfo: deprecate(function addWithInfo(storyName, info, storyFn, _options) {
diff --git a/examples/cra-kitchen-sink/src/stories/index.js b/examples/cra-kitchen-sink/src/stories/index.js
index d1ceda11106f..c7f79459cab7 100644
--- a/examples/cra-kitchen-sink/src/stories/index.js
+++ b/examples/cra-kitchen-sink/src/stories/index.js
@@ -19,7 +19,7 @@ import {
object,
} from '@storybook/addon-knobs';
import centered from '@storybook/addon-centered';
-import { withInfo } from '@storybook/addon-info';
+import { withInfo, decoratorInfo } from '@storybook/addon-info';
import { Button, Welcome } from '@storybook/react/demo';
@@ -115,16 +115,23 @@ storiesOf('Button', module)
);
})
- .addWithInfo(
- 'with some info',
- 'Use the [info addon](https://github.com/storybooks/storybook/tree/master/addons/info) with its painful API.',
- context =>
+
+
+storiesOf('App', module).add('full app', () =>
);
+
+storiesOf('Info Addon', module)
+ .add(
+ 'withInfo default',
+ withInfo(
+ 'Use the [info addon](https://github.com/storybooks/storybook/tree/master/addons/info) with its new painless API.'
+ )(context =>
click the label in top right for info about "{context.story}"
+ )
)
.add(
- 'with new info',
+ 'withInfo inline',
withInfo(
'Use the [info addon](https://github.com/storybooks/storybook/tree/master/addons/info) with its new painless API.',
{ inline: true }
@@ -134,6 +141,17 @@ storiesOf('Button', module)
)
)
+ .add(
+ 'decoratorInfo',
+ decoratorInfo(
+ 'Use the [info addon](https://github.com/storybooks/storybook/tree/master/addons/info) with its new painless API.',
+ { inline: false }
+ )(context =>
+
+ click the label in top right for info about "{context.story}"
+
+ )
+ )
.add(
'addons composition',
withInfo('see Notes panel for composition info')(
@@ -143,10 +161,16 @@ storiesOf('Button', module)
)
)
+ )
+ .addWithInfo(
+ 'deprecated addWithInfo',
+ 'Use the [info addon](https://github.com/storybooks/storybook/tree/master/addons/info) with its painful API.',
+ context =>
+
+ click the label in top right for info about "{context.story}"
+
);
-storiesOf('App', module).add('full app', () => );
-
storiesOf('Centered Button', module)
.addDecorator(centered)
.add('with text', () => Hello Button );
From ff4776c84ff14452a8129c8771336c2eab25f3d8 Mon Sep 17 00:00:00 2001
From: Oleg Proskurin
Date: Tue, 8 Aug 2017 11:24:09 +0300
Subject: [PATCH 04/33] Disable precommit
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index a3c0a1774ff0..1a47600e63c5 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,7 @@
"bootstrap:test-cra": "npm run build-packs && lerna exec --scope test-cra -- yarn install",
"build-packs": "lerna exec --scope '@storybook/*' --parallel -- ../../scripts/build-pack.sh ../../packs",
"changelog": "pr-log --sloppy",
- "precommit": "lint-staged",
+ "precommit_": "lint-staged",
"coverage": "codecov",
"danger": "danger",
"dev": "lerna exec --parallel -- babel src -d dist --ignore tests,__tests__,test.js,stories/,story.jsx --plugins \"transform-runtime\" --copy-files -w",
From 1c3d9a273c186ad7627843f6a64089eca232bd11 Mon Sep 17 00:00:00 2001
From: Oleg Proskurin
Date: Tue, 8 Aug 2017 13:24:43 +0300
Subject: [PATCH 05/33] Restore after merging
---
addons/info/src/index.js | 20 +-
addons/info/src/index.test.js | 6 +-
.../src/__snapshots__/storyshots.test.js.snap | 529 ++++++++++++++++++
.../cra-kitchen-sink/src/stories/index.js | 35 +-
4 files changed, 560 insertions(+), 30 deletions(-)
diff --git a/addons/info/src/index.js b/addons/info/src/index.js
index 1ecde106f630..2f52fd9f108a 100644
--- a/addons/info/src/index.js
+++ b/addons/info/src/index.js
@@ -33,6 +33,14 @@ const defaultMarksyConf = {
ul: UL,
};
+const channel = addons.getChannel();
+
+function sendToPanel(infoString) {
+ channel.emit(EVENT_ID, {
+ infoString,
+ });
+}
+
function addInfo(storyFn, context, infoOptions) {
const options = {
...defaultOptions,
@@ -84,18 +92,6 @@ export const withInfo = textOrOptions => {
const options = typeof textOrOptions === 'string' ? { text: textOrOptions } : textOrOptions;
return storyFn => context => addInfo(storyFn, context, options);
};
-const panelOptions = options => ({
- ...options,
- sendToPanel: true,
- hideInfoButton: true,
-});
-const decoratorOptions = options => ({
-
- ...options,
- sendToPanel: false,
- hideInfoButton: false,
-
-});
export { Story };
diff --git a/addons/info/src/index.test.js b/addons/info/src/index.test.js
index 96c1f40cdfaf..b6c807e8d453 100644
--- a/addons/info/src/index.test.js
+++ b/addons/info/src/index.test.js
@@ -24,7 +24,7 @@ const TestComponent = ({ func, obj, array, number, string, bool, empty }) =>
/* eslint-enable */
const testContext = { kind: 'addon_info', story: 'jest_test' };
-const testOptions = { propTables: false };
+const testOptions = { propTables: false, sendToPanel: false, hideInfoButton: false };
describe('addon Info', () => {
const story = context =>
@@ -42,6 +42,9 @@ describe('addon Info', () => {
const api = {
add: (name, fn) => fn(testContext),
};
+ it('should set options', () => {
+ setDefaults(testOptions);
+ });
it('should render and markdown', () => {
const Info = withInfo(
'# Test story \n## with markdown info \ncontaing **bold**, *cursive* text and `code`'
@@ -53,7 +56,6 @@ describe('addon Info', () => {
ReactDOM.render( , document.createElement('div'));
});
it('should render with missed info', () => {
- setDefaults(testOptions);
const Info = withInfo()(story);
ReactDOM.render( , document.createElement('div'));
});
diff --git a/examples/cra-kitchen-sink/src/__snapshots__/storyshots.test.js.snap b/examples/cra-kitchen-sink/src/__snapshots__/storyshots.test.js.snap
index f5e226854289..449ca7340d11 100644
--- a/examples/cra-kitchen-sink/src/__snapshots__/storyshots.test.js.snap
+++ b/examples/cra-kitchen-sink/src/__snapshots__/storyshots.test.js.snap
@@ -1670,6 +1670,535 @@ exports[`Storyshots Centered Button with text 1`] = `
`;
+exports[`Storyshots Info Addon addons composition 1`] = `
+
+ click the
+
+
+ Show Info
+
+
+ label in top right for info about "
+ addons composition
+ "
+
+`;
+
+exports[`Storyshots Info Addon decoratorInfo 1`] = `
+
+
+
+
+ click the
+
+
+ Show Info
+
+
+ label in top right for info about "
+ decoratorInfo
+ "
+
+
+
+ Show Info
+
+
+
+
+ ×
+
+
+
+
+
+ Info Addon
+
+
+ decoratorInfo
+
+
+
+
+
+ Story Source
+
+
+
+
+
+ <
+ div
+
+
+
+ >
+
+
+
+
+ click the
+
+
+
+
+ <
+ InfoButton
+
+
+
+ />
+
+
+
+
+ label in top right for info about "
+
+
+
+
+ decoratorInfo
+
+
+
+
+ "
+
+
+
+
+ </
+ div
+ >
+
+
+
+
+
+
+
+ Prop Types
+
+
+
+ "
+ InfoButton
+ " Component
+
+
+ No propTypes defined!
+
+
+
+
+
+
+
+`;
+
+exports[`Storyshots Info Addon deprecated addWithInfo 1`] = `
+
+ click the
+
+
+ Show Info
+
+
+ label in top right for info about "
+ deprecated addWithInfo
+ "
+
+`;
+
+exports[`Storyshots Info Addon withInfo default 1`] = `
+
+
+ click the
+
+
+ Show Info
+
+
+ label in top right for info about "
+ withInfo default
+ "
+
+
+
+`;
+
+exports[`Storyshots Info Addon withInfo inline 1`] = `
+
+ click the
+
+
+ Show Info
+
+
+ label in top right for info about "
+ withInfo inline
+ "
+
+
+`;
+
exports[`Storyshots Welcome to Storybook 1`] = `
);
- })
-
+ });
storiesOf('App', module).add('full app', () => );
@@ -127,18 +126,19 @@ storiesOf('Info Addon', module)
'Use the [info addon](https://github.com/storybooks/storybook/tree/master/addons/info) with its new painless API.'
)(context =>
-
- click the label in top right for info about "{context.story}"
-
+
+ click the label in top right for info about "{context.story}"
+
)
)
.add(
'withInfo inline',
- withInfo(
- 'Use the [info addon](https://github.com/storybooks/storybook/tree/master/addons/info) with its new painless API.',
- { inline: true }
- )(context =>
+ withInfo({
+ text:
+ 'Use the [info addon](https://github.com/storybooks/storybook/tree/master/addons/info) with its new painless API.',
+ inline: true,
+ })(context =>
click the label in top right for info about "{context.story}"
@@ -146,13 +146,16 @@ storiesOf('Info Addon', module)
)
.add(
'decoratorInfo',
- decoratorInfo(
- 'Use the [info addon](https://github.com/storybooks/storybook/tree/master/addons/info) with its new painless API.',
- { inline: false }
- )(context =>
-
+ withInfo({
+ text:
+ 'Use the [info addon](https://github.com/storybooks/storybook/tree/master/addons/info) with its new painless API.',
+ inline: false,
+ sendToPanel: false,
+ hideInfoButton: false,
+ })(context =>
+
click the label in top right for info about "{context.story}"
-
+
)
)
.add(
From 9137eee1c0adcad3c103a33212680d5c0b26d427 Mon Sep 17 00:00:00 2001
From: Oleg Proskurin
Date: Tue, 8 Aug 2017 21:13:33 +0300
Subject: [PATCH 06/33] Refactoring addon options
---
addons/info/src/defaults.js | 35 ++++++
addons/info/src/index.js | 116 +++++++++++-------
addons/info/src/index.test.js | 8 +-
.../cra-kitchen-sink/src/stories/index.js | 41 +++++--
4 files changed, 141 insertions(+), 59 deletions(-)
create mode 100644 addons/info/src/defaults.js
diff --git a/addons/info/src/defaults.js b/addons/info/src/defaults.js
new file mode 100644
index 000000000000..78b31109a8a6
--- /dev/null
+++ b/addons/info/src/defaults.js
@@ -0,0 +1,35 @@
+import { H1, H2, H3, H4, H5, H6, Code, P, UL, A, LI } from './components/markdown';
+
+/*
+defaultOptions should have all available options
+*/
+export const defaultOptions = {
+ info: null,
+ inline: false,
+ header: true,
+ source: true,
+ infoButton: false,
+ propTables: [],
+ propTablesExclude: null,
+ styles: s => s,
+ marksyConf: null,
+ maxPropsIntoLine: 3,
+ maxPropObjectKeys: 3,
+ maxPropArrayLength: 3,
+ maxPropStringLength: 50,
+ sendToPanel: true,
+};
+
+export const defaultMarksyConf = {
+ h1: H1,
+ h2: H2,
+ h3: H3,
+ h4: H4,
+ h5: H5,
+ h6: H6,
+ code: Code,
+ p: P,
+ a: A,
+ li: LI,
+ ul: UL,
+};
diff --git a/addons/info/src/index.js b/addons/info/src/index.js
index 2f52fd9f108a..7717d1ea5a4f 100644
--- a/addons/info/src/index.js
+++ b/addons/info/src/index.js
@@ -4,36 +4,48 @@ import addons from '@storybook/addons';
import deprecate from 'util-deprecate';
import Story from './components/Story';
import { EVENT_ID } from './config';
-import { H1, H2, H3, H4, H5, H6, Code, P, UL, A, LI } from './components/markdown';
-
-const defaultOptions = {
- inline: false,
- header: true,
- source: true,
- propTables: [],
- maxPropsIntoLine: 3,
- maxPropObjectKeys: 3,
- maxPropArrayLength: 3,
- maxPropStringLength: 50,
- hideInfoButton: true,
- sendToPanel: true,
-};
+import { defaultOptions, defaultMarksyConf } from './defaults';
+
+const channel = addons.getChannel();
-const defaultMarksyConf = {
- h1: H1,
- h2: H2,
- h3: H3,
- h4: H4,
- h5: H5,
- h6: H6,
- code: Code,
- p: P,
- a: A,
- li: LI,
- ul: UL,
+const addonOptions = {
+ globalOptions: defaultOptions,
+ localOptions: {},
+ isGlobalScope: true,
+
+ setOptions(options) {
+ if (this.isGlobalScope) {
+ this.globalOptions = {
+ ...this.globalOptions,
+ ...options,
+ };
+ return this.globalOptions;
+ }
+ this.localOptions = {
+ ...this.localOptions,
+ ...options,
+ };
+ return this.localOptions;
+ },
+
+ globalScope() {
+ this.isGlobalScope = true;
+ this.localOptions = {};
+ },
+
+ localScope() {
+ this.isGlobalScope = false;
+ this.localOptions = {};
+ },
};
-const channel = addons.getChannel();
+function catchLocalOptions(storyFn, context) {
+ addonOptions.localScope();
+ const story = storyFn(context);
+ const { localOptions, globalOptions } = addonOptions;
+ addonOptions.globalScope();
+ return { story, localOptions, globalOptions };
+}
function sendToPanel(infoString) {
channel.emit(EVENT_ID, {
@@ -42,32 +54,33 @@ function sendToPanel(infoString) {
}
function addInfo(storyFn, context, infoOptions) {
+ // Options could be overridden by setInfoOptions during storyFn execution
+ const { story, globalOptions, localOptions } = catchLocalOptions(storyFn, context);
+
const options = {
- ...defaultOptions,
+ ...globalOptions,
...infoOptions,
+ ...localOptions,
+ };
+
+ const marksyConf = {
+ ...defaultMarksyConf,
+ ...options.marksyConf,
};
// props.propTables can only be either an array of components or null
// propTables option is allowed to be set to 'false' (a boolean)
// if the option is false, replace it with null to avoid react warnings
- if (!options.propTables) {
- options.propTables = null;
- }
-
- const marksyConf = { ...defaultMarksyConf };
- if (options && options.marksyConf) {
- Object.assign(marksyConf, options.marksyConf);
- }
const props = {
- info: options.text,
+ info: options.info,
context,
showInline: Boolean(options.inline),
showHeader: Boolean(options.header),
showSource: Boolean(options.source),
- hideInfoButton: Boolean(options.hideInfoButton),
- propTables: options.propTables,
+ hideInfoButton: Boolean(!options.infoButton),
+ propTables: options.propTables || null,
propTablesExclude: options.propTablesExclude,
- styles: typeof options.styles === 'function' ? options.styles : s => s,
+ styles: typeof options.styles === 'function' && options.styles,
marksyConf,
maxPropObjectKeys: options.maxPropObjectKeys,
maxPropArrayLength: options.maxPropArrayLength,
@@ -77,19 +90,19 @@ function addInfo(storyFn, context, infoOptions) {
const infoContent = (
- {storyFn(context)}
+ {story}
);
if (options.sendToPanel) {
const infoString = ReactDOMServer.renderToString(infoContent);
sendToPanel(infoString);
- return storyFn(context);
+ return story;
}
return infoContent;
}
export const withInfo = textOrOptions => {
- const options = typeof textOrOptions === 'string' ? { text: textOrOptions } : textOrOptions;
+ const options = typeof textOrOptions === 'string' ? { info: textOrOptions } : textOrOptions;
return storyFn => context => addInfo(storyFn, context, options);
};
@@ -110,6 +123,19 @@ export default {
}, '@storybook/addon-info .addWithInfo() addon is deprecated, use withInfo() from the same package instead. \nSee https://github.com/storybooks/storybook/tree/master/addons/info'),
};
-export function setDefaults(newDefaults) {
- return Object.assign(defaultOptions, newDefaults);
+export function setInfoOptions(textOrOptions) {
+ const options = typeof textOrOptions === 'string' ? { info: textOrOptions } : textOrOptions;
+ return addonOptions.setOptions(options);
}
+
+/*
+Changes:
+- [x] options.text -> options.info (breaking)
+- [x] options.hideInfoButton -> !options.infoButton
+- [x] { defaultOptions, defaultMarksyConf } moved to default.js
+- [x] setDefaults -> setInfoOptions
+- [x] same behavior of setInfoOptions as withInfo with textOrOptions
+- [x] setInfoOptions, defaultOptions and withInfo supports the same set of options
+- [x] removed decoratorInfo (set options.sendToPanel = false to use as decorator)
+
+*/
diff --git a/addons/info/src/index.test.js b/addons/info/src/index.test.js
index b6c807e8d453..861c3f8ab47c 100644
--- a/addons/info/src/index.test.js
+++ b/addons/info/src/index.test.js
@@ -2,7 +2,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
-import AddonInfo, { withInfo, setDefaults } from './';
+import AddonInfo, { withInfo, setInfoOptions } from './';
/* eslint-disable */
const TestComponent = ({ func, obj, array, number, string, bool, empty }) =>
@@ -43,7 +43,7 @@ describe('addon Info', () => {
add: (name, fn) => fn(testContext),
};
it('should set options', () => {
- setDefaults(testOptions);
+ setInfoOptions(testOptions);
});
it('should render and markdown', () => {
const Info = withInfo(
@@ -51,8 +51,8 @@ describe('addon Info', () => {
)(story);
ReactDOM.render( , document.createElement('div'));
});
- it('should render with text options', () => {
- const Info = withInfo({ text: 'some text here' })(story);
+ it('should render with info options', () => {
+ const Info = withInfo({ info: 'some text here' })(story);
ReactDOM.render( , document.createElement('div'));
});
it('should render with missed info', () => {
diff --git a/examples/cra-kitchen-sink/src/stories/index.js b/examples/cra-kitchen-sink/src/stories/index.js
index baf1f680a8d6..e438d75f04e7 100644
--- a/examples/cra-kitchen-sink/src/stories/index.js
+++ b/examples/cra-kitchen-sink/src/stories/index.js
@@ -18,7 +18,7 @@ import {
object,
} from '@storybook/addon-knobs';
import centered from '@storybook/addon-centered';
-import { withInfo } from '@storybook/addon-info';
+import { withInfo, setInfoOptions } from '@storybook/addon-info';
import { Button, Welcome } from '@storybook/react/demo';
@@ -54,7 +54,12 @@ const InfoButton = () =>
{' '}Show Info{' '}
;
+setInfoOptions({
+ info: 'This is common info',
+});
+
storiesOf('Button', module)
+ .addDecorator((storyFn, context) => withInfo('This is **Button** info')(storyFn)(context))
.addDecorator(withKnobs)
.add('with text', () => Hello Button )
.add('with some emoji', () => 😀 😎 👍 💯 )
@@ -115,6 +120,10 @@ storiesOf('Button', module)
);
+ })
+ .add('with setInfoOptions', () => {
+ setInfoOptions('this info is **overridden** by setInfoOptions');
+ return Button with Info ;
});
storiesOf('App', module).add('full app', () => );
@@ -125,19 +134,18 @@ storiesOf('Info Addon', module)
withInfo(
'Use the [info addon](https://github.com/storybooks/storybook/tree/master/addons/info) with its new painless API.'
)(context =>
-
-
- click the label in top right for info about "{context.story}"
-
-
+
+ click the label in top right for info about "{context.story}"
+
)
)
.add(
'withInfo inline',
withInfo({
- text:
+ info:
'Use the [info addon](https://github.com/storybooks/storybook/tree/master/addons/info) with its new painless API.',
- inline: true,
+ inline: false,
+ propTables: false,
})(context =>
click the label in top right for info about "{context.story}"
@@ -147,11 +155,11 @@ storiesOf('Info Addon', module)
.add(
'decoratorInfo',
withInfo({
- text:
+ info:
'Use the [info addon](https://github.com/storybooks/storybook/tree/master/addons/info) with its new painless API.',
inline: false,
sendToPanel: false,
- hideInfoButton: false,
+ infoButton: true,
})(context =>
click the label in top right for info about "{context.story}"
@@ -177,6 +185,19 @@ storiesOf('Info Addon', module)
);
+storiesOf('Addons composition', module)
+ .addDecorator((storyFn, context) =>
+ withInfo()(withNotes('the non-trivial form of addons composition')(storyFn))(context)
+ )
+ .add('with text', () => {
+ setInfoOptions('this button contain text');
+ return Hello Button ;
+ })
+ .add('with some emoji', () => {
+ setInfoOptions('this button contain some emoji');
+ return 😀 😎 👍 💯 ;
+ });
+
storiesOf('Centered Button', module)
.addDecorator(centered)
.add('with text', () => Hello Button );
From 5fe8b8529839a342dbdc9613188da57a04914f69 Mon Sep 17 00:00:00 2001
From: Oleg Proskurin
Date: Wed, 9 Aug 2017 00:12:43 +0300
Subject: [PATCH 07/33] Change styles
---
addons/info/src/components/Node.js | 2 +-
addons/info/src/components/PropTable.js | 11 ++-
addons/info/src/components/Story.js | 33 ++++---
addons/info/src/components/markdown/code.js | 5 +-
addons/info/src/index.js | 12 ---
addons/info/src/panel/index.js | 2 +-
.../cra-kitchen-sink/src/stories/index.js | 92 ++++++++++++++++++-
7 files changed, 124 insertions(+), 33 deletions(-)
diff --git a/addons/info/src/components/Node.js b/addons/info/src/components/Node.js
index 168d1d6bef40..4ec14ff8dfbe 100644
--- a/addons/info/src/components/Node.js
+++ b/addons/info/src/components/Node.js
@@ -5,7 +5,7 @@ import Props from './Props';
const stylesheet = {
containerStyle: {},
tagStyle: {
- color: '#777',
+ color: 'hsl(0, 0%, 10%)',
},
};
diff --git a/addons/info/src/components/PropTable.js b/addons/info/src/components/PropTable.js
index fbd3f0780b85..4ee5cf166731 100644
--- a/addons/info/src/components/PropTable.js
+++ b/addons/info/src/components/PropTable.js
@@ -15,9 +15,14 @@ Object.keys(PropTypes).forEach(typeName => {
const stylesheet = {
propTable: {
- marginLeft: -10,
- borderSpacing: '10px 5px',
borderCollapse: 'separate',
+ fontSize: 13,
+ border: '1px hsl(0, 0%, 90%) solid',
+ backgroundColor: 'hsl(0, 0%, 98%)',
+ width: '100%',
+ },
+ head: {
+ textAlign: 'left',
},
};
@@ -87,7 +92,7 @@ export default function PropTable(props) {
return (
-
+
property
propType
diff --git a/addons/info/src/components/Story.js b/addons/info/src/components/Story.js
index 6d759137e5a2..699df1121e74 100644
--- a/addons/info/src/components/Story.js
+++ b/addons/info/src/components/Story.js
@@ -35,12 +35,10 @@ const stylesheet = {
},
info: {
position: 'relative',
- background: 'white',
top: 0,
bottom: 0,
left: 0,
right: 0,
- padding: '0 40px',
overflow: 'auto',
zIndex: 99999,
},
@@ -54,14 +52,14 @@ const stylesheet = {
lineHeight: 1.45,
fontSize: '15px',
border: '1px solid #eee',
- padding: '20px 40px 40px',
+ padding: '10px 20px 20px',
borderRadius: '2px',
boxShadow: '0px 2px 3px rgba(0, 0, 0, 0.05)',
backgroundColor: '#fff',
- marginTop: '50px',
},
infoContent: {
marginBottom: 0,
+ borderBottom: '1px solid #eee',
},
infoStory: {},
jsxInfoContent: {
@@ -72,30 +70,41 @@ const stylesheet = {
h1: {
margin: 0,
padding: 0,
- fontSize: '35px',
+ fontSize: '28px',
},
h2: {
margin: '0 0 10px 0',
padding: 0,
fontWeight: 400,
- fontSize: '22px',
+ fontSize: '18px',
},
body: {
borderBottom: '1px solid #eee',
- paddingTop: 10,
- marginBottom: 10,
+ paddingTop: 6,
+ marginBottom: 6,
},
},
source: {
h1: {
margin: '20px 0 0 0',
padding: '0 0 5px 0',
- fontSize: '25px',
+ fontSize: '18px',
borderBottom: '1px solid #EEE',
+ color: 'rgba(0,0,0,0.5)',
},
},
propTableHead: {
- margin: '20px 0 0 0',
+ h2: {
+ fontSize: '14px',
+ margin: '20px 0 10px 0',
+ },
+ span: {
+ backgroundColor: 'hsl(0, 0%, 92%)',
+ padding: '6px 20px',
+ minWidth: 300,
+ border: 'solid 1px hsl(0, 0%, 75%)',
+ borderRadius: 4,
+ },
},
};
@@ -356,8 +365,8 @@ export default class Story extends React.Component {
const { maxPropObjectKeys, maxPropArrayLength, maxPropStringLength } = this.props;
const propTables = array.map(type =>