From a50a8e874ac24be02dfeb068f641dbab6643a4f9 Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Fri, 28 Jul 2017 01:34:14 -0700 Subject: [PATCH 1/2] Refactoring of withX wrappers withNotes and withInfo - make signatures consistent - make string-only variant of withNotes/withInfo - simplify withInfo code --- ROADMAP.md | 15 +++--- addons/info/src/index.js | 49 ++++++++++--------- addons/info/src/index.test.js | 9 +++- addons/notes/README.md | 2 +- addons/notes/src/index.js | 6 ++- app/vue/README.md | 4 +- .../cra-kitchen-sink/src/stories/index.js | 10 ++-- .../vue-kitchen-sink/src/stories/index.js | 2 +- 8 files changed, 51 insertions(+), 46 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 61e4c1fce74..89252911547 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -10,8 +10,8 @@ - [See multiple (or all) stories in 1 preview.](#see-multiple-or-all-stories-in-1-preview) - [Deeper level hierarchy](#deeper-level-hierarchy) - [Supporting other frameworks and libraries](#supporting-other-frameworks-and-libraries) - - [Vue](#vue) (*in alpha*) - - [Angular](#angular) (*in development*) + - [Vue](#vue) + - [Angular](#angular) - [Webcomponents](#webcomponents) - [Polymer](#polymer) - [Aurelia](#aurelia) @@ -20,7 +20,7 @@ - [API for adding stories](#api-for-adding-stories) - [Documentation](#documentation) - [Better design](#better-design) - - [Record videos and write blog post on how to tweak storybook](#record-videos-and-write-blog-post-on-how-to-tweak-storybook) + - [Record videos and write blog post on how to use, tweak & develop storybook](#record-videos-and-write-blog-post-on-how-to-use-tweak--develop-storybook) ## New features @@ -110,8 +110,7 @@ We have a new logo, so next step is a overhaul of our documentation site. ### Record videos and write blog post on how to use, tweak & develop storybook -- writing addons, -- choosing the right addons. -- how to start developing on our codebase. -- how to use storybook itself and the CLI. - +- writing addons, +- choosing the right addons. +- how to start developing on our codebase. +- how to use storybook itself and the CLI. diff --git a/addons/info/src/index.js b/addons/info/src/index.js index 3ff306f3ee5..37d2b9d45fc 100644 --- a/addons/info/src/index.js +++ b/addons/info/src/index.js @@ -1,14 +1,8 @@ import React from 'react'; import deprecate from 'util-deprecate'; -import _Story from './components/Story'; +import Story from './components/Story'; import { H1, H2, H3, H4, H5, H6, Code, P, UL, A, LI } from './components/markdown'; -function addonCompose(addonFn) { - return storyFn => context => addonFn(storyFn, context); -} - -export const Story = _Story; - const defaultOptions = { inline: false, header: true, @@ -34,20 +28,10 @@ const defaultMarksyConf = { ul: UL, }; -export function addInfo(storyFn, context, info, _options) { - if (typeof storyFn !== 'function') { - if (typeof info === 'function') { - _options = storyFn; // eslint-disable-line - storyFn = info; // eslint-disable-line - info = ''; // eslint-disable-line - } else { - throw new Error('No story defining function has been specified'); - } - } - +function addInfo(storyFn, context, infoOptions) { const options = { ...defaultOptions, - ..._options, + ...infoOptions, }; // props.propTables can only be either an array of components or null @@ -62,7 +46,7 @@ export function addInfo(storyFn, context, info, _options) { Object.assign(marksyConf, options.marksyConf); } const props = { - info, + info: options.text, context, showInline: Boolean(options.inline), showHeader: Boolean(options.header), @@ -83,12 +67,29 @@ export function addInfo(storyFn, context, info, _options) { ); } -export const withInfo = (info, _options) => - addonCompose((storyFn, context) => addInfo(storyFn, context, info, _options)); +export const withInfo = textOrOptions => { + if (typeof textOrOptions === 'string') { + const text = textOrOptions; + return withInfo({ text }); + } + const options = textOrOptions; + return storyFn => context => addInfo(storyFn, context, options); +}; + +export { Story }; export default { - addWithInfo: deprecate(function addWithInfo(storyName, info, storyFn, _options) { - return this.add(storyName, withInfo(info, _options)(storyFn)); + addWithInfo: deprecate(function addWithInfo(storyName, text, storyFn, options) { + if (typeof storyFn !== 'function') { + if (typeof text === 'function') { + options = storyFn; // eslint-disable-line + storyFn = text; // eslint-disable-line + text = ''; // eslint-disable-line + } else { + throw new Error('No story defining function has been specified'); + } + } + return this.add(storyName, withInfo({ text, ...options })(storyFn)); }, '@storybook/addon-info .addWithInfo() addon is deprecated, use withInfo() from the same package instead. \nSee https://github.com/storybooks/storybook/tree/master/addons/info'), }; diff --git a/addons/info/src/index.test.js b/addons/info/src/index.test.js index afbae389ce2..96c1f40cdfa 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, addInfo } from './'; +import AddonInfo, { withInfo, setDefaults } from './'; /* eslint-disable */ const TestComponent = ({ func, obj, array, number, string, bool, empty }) => @@ -48,9 +48,14 @@ describe('addon Info', () => { )(story); ReactDOM.render(, document.createElement('div')); }); + it('should render with text options', () => { + const Info = withInfo({ text: 'some text here' })(story); + ReactDOM.render(, document.createElement('div')); + }); it('should render with missed info', () => { setDefaults(testOptions); - addInfo(null, testContext, story, testOptions); + const Info = withInfo()(story); + ReactDOM.render(, document.createElement('div')); }); it('should show deprecation warning', () => { const addWithInfo = AddonInfo.addWithInfo.bind(api); diff --git a/addons/notes/README.md b/addons/notes/README.md index dffefb10732..d3007060185 100644 --- a/addons/notes/README.md +++ b/addons/notes/README.md @@ -37,5 +37,5 @@ import { withNotes } from '@storybook/addon-notes'; import Component from './Component'; storiesOf('Component', module) - .add('with some emoji', withNotes({ notes: 'A very simple component'})(() => )); + .add('with some emoji', withNotes('A very simple component')(() => )); ``` diff --git a/addons/notes/src/index.js b/addons/notes/src/index.js index 99808f7ed40..5ab3ecc7b1f 100644 --- a/addons/notes/src/index.js +++ b/addons/notes/src/index.js @@ -2,12 +2,14 @@ import deprecate from 'util-deprecate'; import addons from '@storybook/addons'; import { WithNotes as ReactWithNotes } from './react'; -export const withNotes = ({ notes }) => { +export const withNotes = textOrOptions => { const channel = addons.getChannel(); + const text = typeof textOrOptions === 'string' ? textOrOptions : textOrOptions.text; + return getStory => context => { // send the notes to the channel before the story is rendered - channel.emit('storybook/notes/add_notes', notes); + channel.emit('storybook/notes/add_notes', text); return getStory(context); }; }; diff --git a/app/vue/README.md b/app/vue/README.md index 8b6cc94db14..6ae6a2290ad 100644 --- a/app/vue/README.md +++ b/app/vue/README.md @@ -33,8 +33,6 @@ For more information visit: [storybook.js.org](https://storybook.js.org) Storybook also comes with a lot of [addons](https://storybook.js.org/addons/introduction) and a great API to customize as you wish. You can also build a [static version](https://storybook.js.org/basics/exporting-storybook) of your storybook and deploy it anywhere you want. - ## Vue Notes -- When using global custom components or extension (e.g `Vue.use`). You will need to declare those in the `./storybook/config.js`. - +- When using global custom components or extension (e.g `Vue.use`). You will need to declare those in the `./storybook/config.js`. diff --git a/examples/cra-kitchen-sink/src/stories/index.js b/examples/cra-kitchen-sink/src/stories/index.js index d37862c93da..40c95f69a71 100644 --- a/examples/cra-kitchen-sink/src/stories/index.js +++ b/examples/cra-kitchen-sink/src/stories/index.js @@ -135,8 +135,8 @@ storiesOf('Button', module) ) .add( 'addons composition', - withInfo('see Notes panel for composition info')( - withNotes({ notes: 'Composition: Info(Notes())' })(context => + withInfo({ text: 'see Notes panel for composition info' })( + withNotes({ text: 'Composition: Info(Notes())' })(context =>
click the label in top right for info about "{context.story}"
@@ -208,11 +208,11 @@ storiesOf('WithEvents', module) .add('Logger', () => ); storiesOf('withNotes', module) - .add('with some text', withNotes({ notes: 'Hello guys' })(() =>
Hello guys
)) - .add('with some emoji', withNotes({ notes: 'My notes on emojies' })(() =>

🤔😳😯😮

)) + .add('with some text', withNotes({ text: 'Hello guys' })(() =>
Hello guys
)) + .add('with some emoji', withNotes({ text: 'My notes on emojies' })(() =>

🤔😳😯😮

)) .add( 'with a button and some emoji', - withNotes({ notes: 'My notes on a button with emojies' })(() => + withNotes({ text: 'My notes on a button with emojies' })(() => ) ) diff --git a/examples/vue-kitchen-sink/src/stories/index.js b/examples/vue-kitchen-sink/src/stories/index.js index 3e4814cf472..0562d4e8844 100644 --- a/examples/vue-kitchen-sink/src/stories/index.js +++ b/examples/vue-kitchen-sink/src/stories/index.js @@ -137,7 +137,7 @@ storiesOf('Addon Actions', module) storiesOf('Addon Notes', module) .add( 'Simple note', - withNotes({ notes: 'My notes on some bold text' })(() => ({ + withNotes({ text: 'My notes on some bold text' })(() => ({ template: '

Etiam vulputate elit eu venenatis eleifend. Duis nec lectus augue. Morbi egestas diam sed vulputate mollis. Fusce egestas pretium vehicula. Integer sed neque diam. Donec consectetur velit vitae enim varius, ut placerat arcu imperdiet. Praesent sed faucibus arcu. Nullam sit amet nibh a enim eleifend rhoncus. Donec pretium elementum leo at fermentum. Nulla sollicitudin, mauris quis semper tempus, sem metus tristique diam, efficitur pulvinar mi urna id urna.

', })) From 1810a9815387ab10296dd0efffcf5d64cf81242b Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Fri, 28 Jul 2017 09:17:39 -0700 Subject: [PATCH 2/2] Respond to review comments and update addon-info README --- addons/info/README.md | 80 ++++++++++++++----- addons/info/src/index.js | 6 +- addons/notes/src/index.js | 5 +- .../cra-kitchen-sink/src/stories/index.js | 10 +-- 4 files changed, 69 insertions(+), 32 deletions(-) diff --git a/addons/info/README.md b/addons/info/README.md index bc6c4045d84..b21ce6eef71 100644 --- a/addons/info/README.md +++ b/addons/info/README.md @@ -15,7 +15,7 @@ This addon works with Storybook for: ![Screenshot](docs/home-screenshot.png) -## Usage +## Installation Install the following npm module: @@ -23,7 +23,66 @@ Install the following npm module: npm i -D @storybook/addon-info ``` -Then set the addon in the place you configure storybook like this: +## Basic usage + +Then wrap your story with the `withInfo`, which is a function that takes either +documentation text or an options object: + +```js +import { configure, setAddon } from '@storybook/react'; +import { withInfo } from '@storybook/addon-info'; + +storiesOf('Component', module) + .add('simple info', + withInfo('doc string about my component')(() => + Click the "?" mark at top-right to view the info. + ) + ) +``` + +## Usage with options + +`withInfo` can also take an options object in case you want to configure how +the info panel looks on a per-story basis: + +```js +import { configure, setAddon } from '@storybook/react'; +import { withInfo } from '@storybook/addon-info'; + +storiesOf('Component', module) + .add('simple info', + withInfo({ + text: 'doc string about my component', + maxPropsIntoLine: 1, + maxPropObjectKeys: 10, + maxPropArrayLength: 10, + )(() => + Click the "?" mark at top-right to view the info. + ) + ) +``` + +## Global options + +To configure default options for all usage of the info option, use `setDefaults` in `.storybook/config.js`: + +```js +// config.js +import { setDefaults } from '@storybook/addon-info'; + +// addon-info +setDefaults({ + inline: true, + maxPropsIntoLine: 1, + maxPropObjectKeys: 10, + maxPropArrayLength: 10, + maxPropStringLength: 100, +}); +``` + +## Deprecated usage + +There is also a deprecated API that is slated for removal in Storybook 4.0. ```js import { configure, setAddon } from '@storybook/react'; @@ -55,23 +114,6 @@ storiesOf('Component') > Have a look at [this example](example/story.js) stories to learn more about the `addWithInfo` API. -To customize your defaults: - -```js -// config.js -import infoAddon, { setDefaults } from '@storybook/addon-info'; - -// addon-info -setDefaults({ - inline: true, - maxPropsIntoLine: 1, - maxPropObjectKeys: 10, - maxPropArrayLength: 10, - maxPropStringLength: 100, -}); -setAddon(infoAddon); -``` - ## The FAQ **Components lose their names on static build** diff --git a/addons/info/src/index.js b/addons/info/src/index.js index 37d2b9d45fc..13549749198 100644 --- a/addons/info/src/index.js +++ b/addons/info/src/index.js @@ -68,11 +68,7 @@ function addInfo(storyFn, context, infoOptions) { } export const withInfo = textOrOptions => { - if (typeof textOrOptions === 'string') { - const text = textOrOptions; - return withInfo({ text }); - } - const options = textOrOptions; + const options = typeof textOrOptions === 'string' ? { text: textOrOptions } : textOrOptions; return storyFn => context => addInfo(storyFn, context, options); }; diff --git a/addons/notes/src/index.js b/addons/notes/src/index.js index 5ab3ecc7b1f..1fd5d328fcb 100644 --- a/addons/notes/src/index.js +++ b/addons/notes/src/index.js @@ -4,12 +4,11 @@ import { WithNotes as ReactWithNotes } from './react'; export const withNotes = textOrOptions => { const channel = addons.getChannel(); - - const text = typeof textOrOptions === 'string' ? textOrOptions : textOrOptions.text; + const options = typeof textOrOptions === 'string' ? { text: textOrOptions } : textOrOptions; return getStory => context => { // send the notes to the channel before the story is rendered - channel.emit('storybook/notes/add_notes', text); + channel.emit('storybook/notes/add_notes', options.text); return getStory(context); }; }; diff --git a/examples/cra-kitchen-sink/src/stories/index.js b/examples/cra-kitchen-sink/src/stories/index.js index 40c95f69a71..eb094a0cebd 100644 --- a/examples/cra-kitchen-sink/src/stories/index.js +++ b/examples/cra-kitchen-sink/src/stories/index.js @@ -135,8 +135,8 @@ storiesOf('Button', module) ) .add( 'addons composition', - withInfo({ text: 'see Notes panel for composition info' })( - withNotes({ text: 'Composition: Info(Notes())' })(context => + withInfo('see Notes panel for composition info')( + withNotes('Composition: Info(Notes())')(context =>
click the label in top right for info about "{context.story}"
@@ -208,11 +208,11 @@ storiesOf('WithEvents', module) .add('Logger', () => ); storiesOf('withNotes', module) - .add('with some text', withNotes({ text: 'Hello guys' })(() =>
Hello guys
)) - .add('with some emoji', withNotes({ text: 'My notes on emojies' })(() =>

🤔😳😯😮

)) + .add('with some text', withNotes('Hello guys')(() =>
Hello guys
)) + .add('with some emoji', withNotes('My notes on emojies')(() =>

🤔😳😯😮

)) .add( 'with a button and some emoji', - withNotes({ text: 'My notes on a button with emojies' })(() => + withNotes('My notes on a button with emojies')(() => ) )