From 7a82da80bd10977f196099b9b87b3b107c17e0f2 Mon Sep 17 00:00:00 2001 From: Dylan Piercey Date: Wed, 17 Jul 2019 15:01:47 -0700 Subject: [PATCH 1/4] feat: update Marko api to support rerendering --- app/marko/src/client/preview/render.js | 46 ++++++++++++++----- docs/src/pages/guides/guide-marko/index.md | 13 ++++-- .../src/stories/addon-actions.stories.js | 7 ++- .../src/stories/addon-knobs.stories.js | 16 +++---- .../src/stories/clickcount.stories.js | 6 +-- .../marko-cli/src/stories/hello.stories.js | 5 +- .../src/stories/stopwatch.stories.js | 5 +- .../marko-cli/src/stories/welcome.stories.js | 5 +- .../MARKO/template/stories/index.stories.js | 2 +- 9 files changed, 59 insertions(+), 46 deletions(-) diff --git a/app/marko/src/client/preview/render.js b/app/marko/src/client/preview/render.js index 9b63a431743..77bc2c0cf6c 100644 --- a/app/marko/src/client/preview/render.js +++ b/app/marko/src/client/preview/render.js @@ -2,7 +2,8 @@ import { document } from 'global'; import { stripIndents } from 'common-tags'; const rootEl = document.getElementById('root'); -let currLoadedComponent = null; // currently loaded marko widget! +let activeComponent = null; // currently loaded marko component. +let activeTemplate = null; // template for the currently loaded component. export default function renderMain({ storyFn, @@ -12,24 +13,45 @@ export default function renderMain({ showError, // forceRender, }) { - const element = storyFn(); + const config = storyFn(); - // We need to unmount the existing set of components in the DOM node. - if (currLoadedComponent) { - currLoadedComponent.destroy(); - } - - if (!element || !element.out) { + if (!config || !(config.appendTo || config.template)) { showError({ - title: `Expecting a Marko element from the story: "${selectedStory}" of "${selectedKind}".`, + title: `Expecting an object with a template property to be returned from the story: "${selectedStory}" of "${selectedKind}".`, description: stripIndents` - Did you forget to return the Marko element from the story? - Use "() => MyComp.renderSync({})" or "() => { return MyComp.renderSync({}); }" when defining the story. + Did you forget to return the template from the story? + Use "() => ({ template: MyTemplate, input: { hello: 'world' } })" when defining the story. `, }); + return; } + if (config.appendTo) { + console.warn( + '@storybook/marko: returning a rendered component for a story is deprecated, return an object with `{ template, input }` instead.' + ); + + // The deprecated API always destroys the previous component instance. + if (activeComponent) { + activeComponent.destroy(); + } + + activeComponent = config.appendTo(rootEl).getComponent(); + } else if (activeTemplate === config.template) { + // When rendering the same template with new input, we reuse the same instance. + activeComponent.input = config.input; + activeComponent.update(); + } else { + if (activeComponent) { + activeComponent.destroy(); + } + + activeTemplate = config.template; + activeComponent = activeTemplate + .renderSync(config.input) + .appendTo(rootEl) + .getComponent(); + } showMain(); - currLoadedComponent = element.appendTo(rootEl).getComponent(); } diff --git a/docs/src/pages/guides/guide-marko/index.md b/docs/src/pages/guides/guide-marko/index.md index 943efbb5529..506e40b489e 100644 --- a/docs/src/pages/guides/guide-marko/index.md +++ b/docs/src/pages/guides/guide-marko/index.md @@ -88,15 +88,18 @@ That'll load stories in `../stories/index.js`. You can choose where to place sto Now create a `../stories/index.js` file, and write your first story like this: ```js -/** @jsx m */ - -import m from 'marko'; import { storiesOf } from '@storybook/marko'; import Button from '../components/button/index.marko'; storiesOf('Button', module) - .add('with text', () => Button.renderSync({ text: 'some text'})) - .add('with emoji', () => Button.renderSync({ text: '😀 😎 👍 💯'})); + .add('with text', () => ({ + template: Button, + input: { text 'some text' } + })) + .add('with emoji', () => ({ + template: Button, + input: { text '😀 😎 👍 💯' } + })); ``` Each story is a single state of your component. In the above case, there are two stories for the demo button component: diff --git a/examples/marko-cli/src/stories/addon-actions.stories.js b/examples/marko-cli/src/stories/addon-actions.stories.js index aeb7e22788b..4158350b45b 100644 --- a/examples/marko-cli/src/stories/addon-actions.stories.js +++ b/examples/marko-cli/src/stories/addon-actions.stories.js @@ -4,8 +4,11 @@ import Button from '../components/action-button/index.marko'; export default { title: 'Addons|Actions/Button', parameters: { - component: Button, + options: { panelPosition: 'right' }, }, }; -export const Simple = () => Button.renderSync({ click: action('action logged!') }); +export const Simple = () => ({ + template: Button, + input: { click: action('action logged!') }, +}); diff --git a/examples/marko-cli/src/stories/addon-knobs.stories.js b/examples/marko-cli/src/stories/addon-knobs.stories.js index 88595ecee27..77fe8053bfd 100644 --- a/examples/marko-cli/src/stories/addon-knobs.stories.js +++ b/examples/marko-cli/src/stories/addon-knobs.stories.js @@ -5,16 +5,14 @@ export default { title: 'Addons|Knobs/Hello', decorators: [withKnobs], parameters: { - component: Hello, options: { panelPosition: 'right' }, }, }; -export const Simple = () => { - const name = text('Name', 'John Doe'); - const age = number('Age', 44); - return Hello.renderSync({ - name, - age, - }); -}; +export const Simple = () => ({ + template: Hello, + input: { + name: text('Name', 'John Doe'), + age: number('Age', 44), + }, +}); diff --git a/examples/marko-cli/src/stories/clickcount.stories.js b/examples/marko-cli/src/stories/clickcount.stories.js index 351c07daca6..d53605918f4 100644 --- a/examples/marko-cli/src/stories/clickcount.stories.js +++ b/examples/marko-cli/src/stories/clickcount.stories.js @@ -2,10 +2,6 @@ import ClickCount from '../components/click-count/index.marko'; export default { title: 'Main|ClickCount', - - parameters: { - component: ClickCount, - }, }; -export const Simple = () => ClickCount.renderSync({}); +export const Simple = () => ({ template: ClickCount }); diff --git a/examples/marko-cli/src/stories/hello.stories.js b/examples/marko-cli/src/stories/hello.stories.js index bdefe281dc1..b6cf311b31b 100644 --- a/examples/marko-cli/src/stories/hello.stories.js +++ b/examples/marko-cli/src/stories/hello.stories.js @@ -2,11 +2,8 @@ import Hello from '../components/hello/index.marko'; export default { title: 'Main|Hello', - parameters: { - component: Hello, - }, }; -export const Simple = () => Hello.renderSync({ name: 'abc', age: 20 }); +export const Simple = () => ({ template: Hello, input: { name: 'abc', age: 20 } }); export const story2 = () => 'NOT A MARKO RENDER_RESULT'; story2.story = { name: 'with ERROR!' }; diff --git a/examples/marko-cli/src/stories/stopwatch.stories.js b/examples/marko-cli/src/stories/stopwatch.stories.js index 3fc37effb06..cc29ae8863c 100644 --- a/examples/marko-cli/src/stories/stopwatch.stories.js +++ b/examples/marko-cli/src/stories/stopwatch.stories.js @@ -2,9 +2,6 @@ import StopWatch from '../components/stop-watch/index.marko'; export default { title: 'Main|StopWatch', - parameters: { - component: StopWatch, - }, }; -export const Simple = () => StopWatch.renderSync({}); +export const Simple = () => ({ template: StopWatch }); diff --git a/examples/marko-cli/src/stories/welcome.stories.js b/examples/marko-cli/src/stories/welcome.stories.js index 9cd2db67709..1ade363e8a7 100644 --- a/examples/marko-cli/src/stories/welcome.stories.js +++ b/examples/marko-cli/src/stories/welcome.stories.js @@ -2,9 +2,6 @@ import Welcome from '../components/welcome/index.marko'; export default { title: 'Main|Welcome', - parameters: { - component: Welcome, - }, }; -export const welcome = () => Welcome.renderSync({}); +export const welcome = () => ({ template: Welcome }); diff --git a/lib/cli/generators/MARKO/template/stories/index.stories.js b/lib/cli/generators/MARKO/template/stories/index.stories.js index 61ad73dd902..3e77744ee43 100644 --- a/lib/cli/generators/MARKO/template/stories/index.stories.js +++ b/lib/cli/generators/MARKO/template/stories/index.stories.js @@ -1,4 +1,4 @@ import { storiesOf } from '@storybook/marko'; import Welcome from './components/welcome/index.marko'; -storiesOf('Welcome', module).add('welcome', () => Welcome.renderSync({})); +storiesOf('Welcome', module).add('welcome', () => ({ template: Welcome })); From 6a428af795a00834cd74d649d252265dcd4d48d7 Mon Sep 17 00:00:00 2001 From: Dylan Piercey Date: Wed, 17 Jul 2019 15:50:51 -0700 Subject: [PATCH 2/4] feat: support setting Marko template as a shared parameter --- app/marko/src/client/preview/render.js | 31 +++++++++++-------- .../src/stories/addon-knobs.stories.js | 2 +- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/app/marko/src/client/preview/render.js b/app/marko/src/client/preview/render.js index 77bc2c0cf6c..31ac3e7fdbb 100644 --- a/app/marko/src/client/preview/render.js +++ b/app/marko/src/client/preview/render.js @@ -11,11 +11,12 @@ export default function renderMain({ selectedStory, showMain, showError, + parameters, // forceRender, }) { const config = storyFn(); - if (!config || !(config.appendTo || config.template)) { + if (!config || !(config.appendTo || config.template || parameters.template)) { showError({ title: `Expecting an object with a template property to be returned from the story: "${selectedStory}" of "${selectedKind}".`, description: stripIndents` @@ -37,20 +38,24 @@ export default function renderMain({ } activeComponent = config.appendTo(rootEl).getComponent(); - } else if (activeTemplate === config.template) { - // When rendering the same template with new input, we reuse the same instance. - activeComponent.input = config.input; - activeComponent.update(); } else { - if (activeComponent) { - activeComponent.destroy(); + const template = config.template || parameters.template; + + if (activeTemplate === template) { + // When rendering the same template with new input, we reuse the same instance. + activeComponent.input = config.input; + activeComponent.update(); + } else { + if (activeComponent) { + activeComponent.destroy(); + } + + activeTemplate = template; + activeComponent = activeTemplate + .renderSync(config.input) + .appendTo(rootEl) + .getComponent(); } - - activeTemplate = config.template; - activeComponent = activeTemplate - .renderSync(config.input) - .appendTo(rootEl) - .getComponent(); } showMain(); diff --git a/examples/marko-cli/src/stories/addon-knobs.stories.js b/examples/marko-cli/src/stories/addon-knobs.stories.js index 77fe8053bfd..cd376dfc3c2 100644 --- a/examples/marko-cli/src/stories/addon-knobs.stories.js +++ b/examples/marko-cli/src/stories/addon-knobs.stories.js @@ -5,12 +5,12 @@ export default { title: 'Addons|Knobs/Hello', decorators: [withKnobs], parameters: { + template: Hello, options: { panelPosition: 'right' }, }, }; export const Simple = () => ({ - template: Hello, input: { name: text('Name', 'John Doe'), age: number('Age', 44), From 3282ddd3b9189334c965a7f652de69be9bf54c51 Mon Sep 17 00:00:00 2001 From: Dylan Piercey Date: Thu, 18 Jul 2019 20:03:41 -0700 Subject: [PATCH 3/4] fix: add back component parameter option, rename template to component --- app/marko/src/client/preview/render.js | 12 ++++++------ docs/src/pages/guides/guide-marko/index.md | 4 ++-- .../marko-cli/src/stories/addon-actions.stories.js | 6 ++++-- .../marko-cli/src/stories/addon-knobs.stories.js | 2 +- examples/marko-cli/src/stories/clickcount.stories.js | 5 ++++- examples/marko-cli/src/stories/hello.stories.js | 5 ++++- examples/marko-cli/src/stories/stopwatch.stories.js | 5 ++++- examples/marko-cli/src/stories/welcome.stories.js | 5 ++++- .../MARKO/template/stories/index.stories.js | 2 +- 9 files changed, 30 insertions(+), 16 deletions(-) diff --git a/app/marko/src/client/preview/render.js b/app/marko/src/client/preview/render.js index 31ac3e7fdbb..0dbcee3920a 100644 --- a/app/marko/src/client/preview/render.js +++ b/app/marko/src/client/preview/render.js @@ -16,12 +16,12 @@ export default function renderMain({ }) { const config = storyFn(); - if (!config || !(config.appendTo || config.template || parameters.template)) { + if (!config || !(config.appendTo || config.component || parameters.component)) { showError({ - title: `Expecting an object with a template property to be returned from the story: "${selectedStory}" of "${selectedKind}".`, + title: `Expecting an object with a component property to be returned from the story: "${selectedStory}" of "${selectedKind}".`, description: stripIndents` - Did you forget to return the template from the story? - Use "() => ({ template: MyTemplate, input: { hello: 'world' } })" when defining the story. + Did you forget to return the component from the story? + Use "() => ({ component: MyComponent, input: { hello: 'world' } })" when defining the story. `, }); @@ -29,7 +29,7 @@ export default function renderMain({ } if (config.appendTo) { console.warn( - '@storybook/marko: returning a rendered component for a story is deprecated, return an object with `{ template, input }` instead.' + '@storybook/marko: returning a rendered component for a story is deprecated, return an object with `{ component, input }` instead.' ); // The deprecated API always destroys the previous component instance. @@ -39,7 +39,7 @@ export default function renderMain({ activeComponent = config.appendTo(rootEl).getComponent(); } else { - const template = config.template || parameters.template; + const template = config.component || parameters.component; if (activeTemplate === template) { // When rendering the same template with new input, we reuse the same instance. diff --git a/docs/src/pages/guides/guide-marko/index.md b/docs/src/pages/guides/guide-marko/index.md index 506e40b489e..9da8adc2cfc 100644 --- a/docs/src/pages/guides/guide-marko/index.md +++ b/docs/src/pages/guides/guide-marko/index.md @@ -93,11 +93,11 @@ import Button from '../components/button/index.marko'; storiesOf('Button', module) .add('with text', () => ({ - template: Button, + component: Button, input: { text 'some text' } })) .add('with emoji', () => ({ - template: Button, + component: Button, input: { text '😀 😎 👍 💯' } })); ``` diff --git a/examples/marko-cli/src/stories/addon-actions.stories.js b/examples/marko-cli/src/stories/addon-actions.stories.js index 4158350b45b..698e3b2f2ba 100644 --- a/examples/marko-cli/src/stories/addon-actions.stories.js +++ b/examples/marko-cli/src/stories/addon-actions.stories.js @@ -4,11 +4,13 @@ import Button from '../components/action-button/index.marko'; export default { title: 'Addons|Actions/Button', parameters: { - options: { panelPosition: 'right' }, + options: { + component: Button, + panelPosition: 'right', + }, }, }; export const Simple = () => ({ - template: Button, input: { click: action('action logged!') }, }); diff --git a/examples/marko-cli/src/stories/addon-knobs.stories.js b/examples/marko-cli/src/stories/addon-knobs.stories.js index cd376dfc3c2..e1849a60aaa 100644 --- a/examples/marko-cli/src/stories/addon-knobs.stories.js +++ b/examples/marko-cli/src/stories/addon-knobs.stories.js @@ -5,7 +5,7 @@ export default { title: 'Addons|Knobs/Hello', decorators: [withKnobs], parameters: { - template: Hello, + component: Hello, options: { panelPosition: 'right' }, }, }; diff --git a/examples/marko-cli/src/stories/clickcount.stories.js b/examples/marko-cli/src/stories/clickcount.stories.js index d53605918f4..d02fe83b40c 100644 --- a/examples/marko-cli/src/stories/clickcount.stories.js +++ b/examples/marko-cli/src/stories/clickcount.stories.js @@ -2,6 +2,9 @@ import ClickCount from '../components/click-count/index.marko'; export default { title: 'Main|ClickCount', + parameters: { + component: ClickCount, + }, }; -export const Simple = () => ({ template: ClickCount }); +export const Simple = () => ({ component: ClickCount }); diff --git a/examples/marko-cli/src/stories/hello.stories.js b/examples/marko-cli/src/stories/hello.stories.js index b6cf311b31b..f4114a7901e 100644 --- a/examples/marko-cli/src/stories/hello.stories.js +++ b/examples/marko-cli/src/stories/hello.stories.js @@ -2,8 +2,11 @@ import Hello from '../components/hello/index.marko'; export default { title: 'Main|Hello', + parameters: { + component: Hello, + }, }; -export const Simple = () => ({ template: Hello, input: { name: 'abc', age: 20 } }); +export const Simple = () => ({ input: { name: 'abc', age: 20 } }); export const story2 = () => 'NOT A MARKO RENDER_RESULT'; story2.story = { name: 'with ERROR!' }; diff --git a/examples/marko-cli/src/stories/stopwatch.stories.js b/examples/marko-cli/src/stories/stopwatch.stories.js index cc29ae8863c..1f62d6c736d 100644 --- a/examples/marko-cli/src/stories/stopwatch.stories.js +++ b/examples/marko-cli/src/stories/stopwatch.stories.js @@ -2,6 +2,9 @@ import StopWatch from '../components/stop-watch/index.marko'; export default { title: 'Main|StopWatch', + parameters: { + component: StopWatch, + }, }; -export const Simple = () => ({ template: StopWatch }); +export const Simple = () => ({ component: StopWatch }); diff --git a/examples/marko-cli/src/stories/welcome.stories.js b/examples/marko-cli/src/stories/welcome.stories.js index 1ade363e8a7..62bef2b231b 100644 --- a/examples/marko-cli/src/stories/welcome.stories.js +++ b/examples/marko-cli/src/stories/welcome.stories.js @@ -2,6 +2,9 @@ import Welcome from '../components/welcome/index.marko'; export default { title: 'Main|Welcome', + parameters: { + component: Welcome, + }, }; -export const welcome = () => ({ template: Welcome }); +export const welcome = () => ({ component: Welcome }); diff --git a/lib/cli/generators/MARKO/template/stories/index.stories.js b/lib/cli/generators/MARKO/template/stories/index.stories.js index 3e77744ee43..dd453126524 100644 --- a/lib/cli/generators/MARKO/template/stories/index.stories.js +++ b/lib/cli/generators/MARKO/template/stories/index.stories.js @@ -1,4 +1,4 @@ import { storiesOf } from '@storybook/marko'; import Welcome from './components/welcome/index.marko'; -storiesOf('Welcome', module).add('welcome', () => ({ template: Welcome })); +storiesOf('Welcome', module).add('welcome', () => ({ component: Welcome })); From 3b424c9c836754b73631c128516c85c7470126bc Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Sat, 20 Jul 2019 00:41:00 +0800 Subject: [PATCH 4/4] Update addon-actions.stories.js --- examples/marko-cli/src/stories/addon-actions.stories.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/marko-cli/src/stories/addon-actions.stories.js b/examples/marko-cli/src/stories/addon-actions.stories.js index 698e3b2f2ba..9f943b71a9e 100644 --- a/examples/marko-cli/src/stories/addon-actions.stories.js +++ b/examples/marko-cli/src/stories/addon-actions.stories.js @@ -4,13 +4,14 @@ import Button from '../components/action-button/index.marko'; export default { title: 'Addons|Actions/Button', parameters: { + component: Button, options: { - component: Button, panelPosition: 'right', }, }, }; export const Simple = () => ({ + component: Button, input: { click: action('action logged!') }, });