diff --git a/addons/notes/README.md b/addons/notes/README.md index 94826bc20f08..dffefb10732a 100644 --- a/addons/notes/README.md +++ b/addons/notes/README.md @@ -31,17 +31,11 @@ import '@storybook/addon-notes/register'; Then write your stories like this: ```js -import React from 'react'; - import { storiesOf } from '@storybook/react'; -import { WithNotes } from '@storybook/addon-notes'; +import { withNotes } from '@storybook/addon-notes'; import Component from './Component'; storiesOf('Component', module) - .add('with some emoji', () => ( - - - - )); + .add('with some emoji', withNotes({ notes: 'A very simple component'})(() => )); ``` diff --git a/addons/notes/package.json b/addons/notes/package.json index 188ab8eafc30..b89ba06f1654 100644 --- a/addons/notes/package.json +++ b/addons/notes/package.json @@ -4,8 +4,8 @@ "description": "Write notes for your Storybook stories.", "keywords": [ "addon", - "react", - "storybook" + "storybook", + "notes" ], "license": "MIT", "main": "dist/index.js", @@ -21,18 +21,16 @@ "dependencies": { "@storybook/addons": "^3.1.2", "babel-runtime": "^6.23.0", - "prop-types": "^15.5.10" + "util-deprecate": "^1.0.2" }, "devDependencies": { - "git-url-parse": "^6.2.2", - "react": "^15.5.4", - "react-addons-test-utils": "^15.5.1", - "react-dom": "^15.5.4" + "prop-types": "^15.5.10", + "react": "^15.5.4" }, - "peerDependencies": { - "react": "*" - }, - "optionalDependencies": { - "@types/react": "^15.0.24" + "peerDependencies": { + "react": "*" + }, + "optionalDependencies": { + "@types/react": "^15.0.24" } } diff --git a/addons/notes/src/index.js b/addons/notes/src/index.js index 818e3ffb39f3..7aff6cb5cbf4 100644 --- a/addons/notes/src/index.js +++ b/addons/notes/src/index.js @@ -1,24 +1,22 @@ -import React from 'react'; -import PropTypes from 'prop-types'; +import deprecate from 'util-deprecate'; import addons from '@storybook/addons'; +import { WithNotes as ReactWithNotes } from './react'; -export class WithNotes extends React.Component { - render() { - const { children, notes } = this.props; - const channel = addons.getChannel(); +export const withNotes = ({ notes }) => { + const channel = addons.getChannel(); - // send the notes to the channel. + return getStory => () => { + // send the notes to the channel before the story is rendered channel.emit('storybook/notes/add_notes', notes); - // return children elements. - return children; - } -} - -WithNotes.propTypes = { - children: PropTypes.node, - notes: PropTypes.string, -}; -WithNotes.defaultProps = { - children: null, - notes: '', + return getStory(); + }; }; + +Object.defineProperty(exports, 'WithNotes', { + configurable: true, + enumerable: true, + get: deprecate( + () => ReactWithNotes, + '@storybook/addon-notes WithNotes Component is deprecated, use withNotes() instead. See https://github.com/storybooks/storybook/tree/master/addons/notes' + ), +}); diff --git a/addons/notes/src/react.js b/addons/notes/src/react.js new file mode 100644 index 000000000000..818e3ffb39f3 --- /dev/null +++ b/addons/notes/src/react.js @@ -0,0 +1,24 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import addons from '@storybook/addons'; + +export class WithNotes extends React.Component { + render() { + const { children, notes } = this.props; + const channel = addons.getChannel(); + + // send the notes to the channel. + channel.emit('storybook/notes/add_notes', notes); + // return children elements. + return children; + } +} + +WithNotes.propTypes = { + children: PropTypes.node, + notes: PropTypes.string, +}; +WithNotes.defaultProps = { + children: null, + notes: '', +}; diff --git a/app/vue/src/client/preview/client_api.js b/app/vue/src/client/preview/client_api.js index c930157212be..0e166971d34b 100644 --- a/app/vue/src/client/preview/client_api.js +++ b/app/vue/src/client/preview/client_api.js @@ -59,17 +59,6 @@ export default class ClientApi { throw new Error(`Story of "${kind}" named "${storyName}" already exists`); } - let component = getStory; - if (typeof getStory === 'function') { - component = getStory(); - } - - if (typeof component === 'string') { - component = { template: component }; - } else if (typeof component === 'function') { - component = { render: component }; - } - // Wrap the getStory function with each decorator. The first // decorator will wrap the story function. The second will // wrap the first decorator and so on. @@ -77,7 +66,7 @@ export default class ClientApi { const fn = decorators.reduce( (decorated, decorator) => context => decorator(() => decorated(context), context), - component + getStory ); // Add the fully decorated getStory function. diff --git a/app/vue/src/client/preview/render.js b/app/vue/src/client/preview/render.js index f69910c453c7..80894d8f2c1a 100644 --- a/app/vue/src/client/preview/render.js +++ b/app/vue/src/client/preview/render.js @@ -82,12 +82,20 @@ export function renderMain(data, storyStore) { // ReactDOM.unmountComponentAtNode(rootEl); } - // const context = { - // kind: selectedKind, - // story: selectedStory, - // }; + const context = { + kind: selectedKind, + story: selectedStory, + }; - // const element = story(context); + const element = story(context); + + + let component = element; + if (typeof component === 'string') { + component = { template: component }; + } else if (typeof component === 'function') { + component = { render: component }; + } // if (!element) { // const error = { @@ -112,7 +120,7 @@ export function renderMain(data, storyStore) { // } // ReactDOM.render(element, rootEl); - app.renderStory(story); + app.renderStory(component); return null; } diff --git a/examples/cra-storybook/.storybook/addons.js b/examples/cra-storybook/.storybook/addons.js index 09eddda4c251..3610fa6e48f6 100644 --- a/examples/cra-storybook/.storybook/addons.js +++ b/examples/cra-storybook/.storybook/addons.js @@ -1,3 +1,4 @@ import '@storybook/addon-actions/register'; import '@storybook/addon-links/register'; import '@storybook/addon-events/register'; +import '@storybook/addon-notes/register'; diff --git a/examples/cra-storybook/package.json b/examples/cra-storybook/package.json index 29ba51e8cbf3..1ec726e575b0 100644 --- a/examples/cra-storybook/package.json +++ b/examples/cra-storybook/package.json @@ -22,6 +22,7 @@ "@storybook/addon-actions": "^3.0.0", "@storybook/addon-links": "^3.0.0", "@storybook/addon-events": "^3.0.0", + "@storybook/addon-notes": "^3.0.0", "@storybook/addons": "^3.0.0", "@storybook/react": "^3.0.0", "react-scripts": "1.0.1" diff --git a/examples/cra-storybook/src/stories/index.js b/examples/cra-storybook/src/stories/index.js index e6344a41bb90..6beb3011278e 100644 --- a/examples/cra-storybook/src/stories/index.js +++ b/examples/cra-storybook/src/stories/index.js @@ -4,6 +4,7 @@ import EventEmiter from 'eventemitter3'; import { storiesOf } from '@storybook/react'; import { action } from '@storybook/addon-actions'; +import { withNotes, WithNotes } from '@storybook/addon-notes'; import { linkTo } from '@storybook/addon-links'; import WithEvents from '@storybook/addon-events'; @@ -88,3 +89,18 @@ storiesOf('WithEvents', module) ) .add('Logger', () => ); + +storiesOf('withNotes', module) + .add('with some text', withNotes({ notes: 'Hello guys' })(() =>
Hello copain
)) + .add('with some emoji', withNotes({ notes: 'My notes on emojies' })(() =>

🤔😳😯😮

)) + .add( + 'with a button and some emoji', + withNotes({ notes: 'My notes on a button with emojies' })(() => + + ) + ) + .add('with old API', () => + + + + ); diff --git a/examples/vue/.storybook/addons.js b/examples/vue/.storybook/addons.js index 6aed412d04af..b5d5f6038d54 100644 --- a/examples/vue/.storybook/addons.js +++ b/examples/vue/.storybook/addons.js @@ -1,2 +1,4 @@ import '@storybook/addon-actions/register'; import '@storybook/addon-links/register'; +import '@storybook/addon-notes/register'; + diff --git a/examples/vue/package.json b/examples/vue/package.json index 2856011ceff0..844e5ffbc210 100644 --- a/examples/vue/package.json +++ b/examples/vue/package.json @@ -8,6 +8,7 @@ "@storybook/addon-actions": "^3.0.0", "@storybook/addon-links": "^3.0.0", "@storybook/addons": "^3.0.0", + "@storybook/addon-notes": "^3.0.0", "vue-hot-reload-api": "^2.1.0", "vue-style-loader": "^3.0.1", "vue-loader": "^12.2.1" diff --git a/examples/vue/src/stories/index.js b/examples/vue/src/stories/index.js index e4945ecaec45..e315a2edb731 100644 --- a/examples/vue/src/stories/index.js +++ b/examples/vue/src/stories/index.js @@ -1,3 +1,4 @@ +import React from 'react'; import Vue from 'vue'; import Vuex from 'vuex'; import { storiesOf } from '@storybook/vue'; @@ -5,15 +6,13 @@ import { storiesOf } from '@storybook/vue'; import { action } from '@storybook/addon-actions'; import { linkTo } from '@storybook/addon-links'; +import { withNotes } from '@storybook/addon-notes'; + import MyButton from './Button.vue'; -// This does not work. We need to Vue.use or Vue.component is called before mount the root Vue -// Vue.use(Vuex); -// Vue.component('my-button', MyButton); storiesOf('Button', module) // Works if Vue.component is called in the config.js in .storybook - .add('rounded markup only', 'rounded markup only') .add('story as a function template', () => 'story as a function template') .add('story as a function renderer', () => (h) => h('div', ['story as a function renderer'])) .add('story as a function component with template', () => ({ @@ -22,7 +21,7 @@ storiesOf('Button', module) .add('story as a function component with renderer', () => ({ render: (h) => h('my-button', { props : { rounded: true }}, ['story as a function component with renderer']), })) - .add('with vuex', { + .add('with vuex',() => ({ components: { MyButton }, template: 'with vuex: {{ $store.state.count }}', store: new Vuex.Store({ @@ -39,8 +38,8 @@ storiesOf('Button', module) this.$store.commit('increment'); }, }, - }) - .add('with text', { + })) + .add('with text', () => ({ // need to register local component until we can make sur Vue.componennt si called before mounting the root Vue components: { MyButton }, template: 'with text: {{ count }}', @@ -54,24 +53,47 @@ storiesOf('Button', module) this.action(this.count); } } - }) + })); storiesOf('Other', module) - .add('button with emoji', '') - .add('p with emoji', '

🤔😳😯😮

') - .add('colorful', { + .add('button with emoji', () => '') + .add('p with emoji', () => '

🤔😳😯😮

') + .add('colorful', () => ({ render(h) { return h(MyButton, { props: { color: 'pink' } }, ['colorful']); } - }) - .add('rounded', { + })) + .add('rounded', () => ({ components: { MyButton }, template: 'rounded' - }) - .add('not rounded', { + })) + .add('not rounded', () => ({ components: { MyButton }, template: 'not rounded', methods: { action: linkTo('Button') } - }) + })) + + +storiesOf('Addon Notes', module) + .add('with some emoji', withNotes({notes: 'My notes on emojies'})(() => '

🤔😳😯😮

')) + .add('with some button', withNotes({ notes: 'My notes on some button' })(() => ({ + components: { MyButton }, + template: 'rounded' + }))) + .add('with some color', withNotes({ notes: 'Some notes on some colored component' })(() => ({ + render(h) { + return h(MyButton, { props: { color: 'pink' } }, ['colorful']); + } + }))) + .add('with some text', withNotes({ notes: 'My notes on some text' })(() => ({ + template: '
Text
' + }) + )) + .add('with some long text', withNotes({ notes: 'My notes on some long text' })( + () => '
A looooooooonnnnnnnggggggggggggg text
' + )) + .add('with some bold text', withNotes({ notes: 'My notes on some bold text' })(() => ({ + render: h => h('div', [h('strong', ['A very long text to display'])]) + }))); \ No newline at end of file