From 71bce16a00f0bc4fe7c067277053f09773b0e554 Mon Sep 17 00:00:00 2001 From: "Leo Y. Li" Date: Thu, 25 Apr 2019 14:31:22 -0400 Subject: [PATCH 1/5] FIX addon-contexts: allow `props` to map on VueComponent contexts --- addons/contexts/src/preview/frameworks/vue.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/addons/contexts/src/preview/frameworks/vue.ts b/addons/contexts/src/preview/frameworks/vue.ts index 9a62f38bef10..ac3eb6587c26 100644 --- a/addons/contexts/src/preview/frameworks/vue.ts +++ b/addons/contexts/src/preview/frameworks/vue.ts @@ -14,9 +14,14 @@ export const renderVue: Render = (contextNodes, propsMap, getStor name: ID, data: () => reactiveProps, render: createElement => - getRendererFrom((component, props, children) => - createElement(component, { props }, [children]) - )(contextNodes, reactiveProps, () => createElement(getStoryVNode())), + getRendererFrom((Component, props, children) => { + const { key, ref, style, classNames, ...rest } = props || Object(); + const contextData = + Component instanceof Object + ? { key, ref, style, class: classNames, props: rest } // component as a Vue object + : { key, ref, style, class: classNames, attrs: rest }; // component as a HTML tag string + return createElement(Component, contextData, [children]); + })(contextNodes, reactiveProps, () => createElement(getStoryVNode())), }); }; From 74f0f7c8b5a737531d61c638a7c38431093de72b Mon Sep 17 00:00:00 2001 From: "Leo Y. Li" Date: Thu, 25 Apr 2019 14:32:14 -0400 Subject: [PATCH 2/5] ADD addon-contexts: example for vue-kitchen-sink --- .../vue-kitchen-sink/.storybook/addons.js | 1 + examples/vue-kitchen-sink/package.json | 1 + .../src/stories/addon-contexts.stories.js | 144 ++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 examples/vue-kitchen-sink/src/stories/addon-contexts.stories.js diff --git a/examples/vue-kitchen-sink/.storybook/addons.js b/examples/vue-kitchen-sink/.storybook/addons.js index ff96ea46a3bd..e60f3addddd7 100644 --- a/examples/vue-kitchen-sink/.storybook/addons.js +++ b/examples/vue-kitchen-sink/.storybook/addons.js @@ -6,3 +6,4 @@ import '@storybook/addon-knobs/register'; import '@storybook/addon-viewport/register'; import '@storybook/addon-options/register'; import '@storybook/addon-backgrounds/register'; +import '@storybook/addon-contexts/register'; diff --git a/examples/vue-kitchen-sink/package.json b/examples/vue-kitchen-sink/package.json index 35c822f1f82d..d385ffb334e1 100644 --- a/examples/vue-kitchen-sink/package.json +++ b/examples/vue-kitchen-sink/package.json @@ -18,6 +18,7 @@ "@storybook/addon-actions": "5.1.0-alpha.34", "@storybook/addon-backgrounds": "5.1.0-alpha.34", "@storybook/addon-centered": "5.1.0-alpha.34", + "@storybook/addon-contexts": "5.1.0-alpha.34", "@storybook/addon-knobs": "5.1.0-alpha.34", "@storybook/addon-links": "5.1.0-alpha.34", "@storybook/addon-notes": "5.1.0-alpha.34", diff --git a/examples/vue-kitchen-sink/src/stories/addon-contexts.stories.js b/examples/vue-kitchen-sink/src/stories/addon-contexts.stories.js new file mode 100644 index 000000000000..d6d415a4a96d --- /dev/null +++ b/examples/vue-kitchen-sink/src/stories/addon-contexts.stories.js @@ -0,0 +1,144 @@ +import { storiesOf } from '@storybook/vue'; +import { withContexts } from '@storybook/addon-contexts/vue'; + +// Example A: Simple CSS Theming +const topLevelContexts = [ + { + icon: 'sidebaralt', + title: 'CSS Themes', + components: ['div'], + params: [ + { + name: 'Desert', + props: { + style: { color: 'brown', background: '#F4A261', height: '100vh', padding: '10px' }, + }, + }, + { + name: 'Ocean', + props: { + style: { color: 'white', background: '#173F5F', height: '100vh', padding: '10px' }, + }, + default: true, + }, + ], + }, +]; + +const storyLevelContexts = [ + { + title: 'CSS Themes', + params: [ + { + name: 'Forest', + props: { + style: { color: 'teal', background: '#00b894', height: '100vh', padding: '10px' }, + }, + }, + ], + }, +]; + +const stories = storiesOf('Addon|Contexts', module).addDecorator(withContexts(topLevelContexts)); + +stories.add( + 'Simple CSS Theming', + () => ({ + template: + "I'm a children of the injected 'div' (where provides a theming context).", + }), + { + contexts: storyLevelContexts, + } +); + +// Example B: Language (React Contexts API) +const createContext = initialValue => { + const uid = `_${Date.now()}${Math.random()}`; + return { + Provider: { + name: `Context.Provider`, + props: ['value'], + provide() { + return this.value === undefined + ? undefined + : { + [uid]: () => this.value, + }; + }, + template: ` +
+ +
+ `, + }, + Consumer: { + name: `Context.Consumer`, + inject: { + [uid]: { + default: () => () => + initialValue instanceof Object ? { ...initialValue } : { value: initialValue }, + }, + }, + computed: { + value() { + return this[uid](); + }, + }, + template: ` +
+ +
+ `, + }, + }; +}; + +const NaiveIntlContext = createContext({ + locale: 'unknown', + greeting: 'NULL', +}); + +stories.add( + 'Languages', + () => ({ + components: { 'NaiveIntlContext.Consumer': NaiveIntlContext.Consumer }, + template: ` + + Your locale is {{ locale }}, so I say {{ greeting }}! + + `, + }), + { + contexts: [ + { + icon: 'globe', + title: 'Languages', + components: [NaiveIntlContext.Provider], + params: [ + { + name: 'English', + props: { + value: { locale: 'en', greeting: 'Hello' }, + }, + }, + { + name: 'French', + props: { + value: { locale: 'fr', greeting: 'Bonjour' }, + }, + }, + { + name: 'Chinese', + props: { + value: { locale: 'cn', greeting: '你好' }, + }, + }, + ], + options: { + cancelable: true, + }, + }, + ], + } +); From cefcc2eb7ae97c6b101b42ad6e9bba700bc04f7e Mon Sep 17 00:00:00 2001 From: "Leo Y. Li" Date: Thu, 25 Apr 2019 14:48:37 -0400 Subject: [PATCH 3/5] ADD addon-contexts: fix typos --- examples/vue-kitchen-sink/src/stories/addon-contexts.stories.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/vue-kitchen-sink/src/stories/addon-contexts.stories.js b/examples/vue-kitchen-sink/src/stories/addon-contexts.stories.js index d6d415a4a96d..6aa46012d4a8 100644 --- a/examples/vue-kitchen-sink/src/stories/addon-contexts.stories.js +++ b/examples/vue-kitchen-sink/src/stories/addon-contexts.stories.js @@ -52,7 +52,7 @@ stories.add( } ); -// Example B: Language (React Contexts API) +// Example B: Language (Vue provide/inject API) const createContext = initialValue => { const uid = `_${Date.now()}${Math.random()}`; return { From 3e6e3e8c0866afad09c2d36ef2999ce667544e31 Mon Sep 17 00:00:00 2001 From: "Leo Y. Li" Date: Thu, 25 Apr 2019 14:51:13 -0400 Subject: [PATCH 4/5] ADD addon-contexts: correct the function name in Vue --- addons/contexts/src/preview/frameworks/vue.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/contexts/src/preview/frameworks/vue.ts b/addons/contexts/src/preview/frameworks/vue.ts index ac3eb6587c26..0e5513f85f9b 100644 --- a/addons/contexts/src/preview/frameworks/vue.ts +++ b/addons/contexts/src/preview/frameworks/vue.ts @@ -7,7 +7,7 @@ import { ID } from '../../shared/constants'; * This is the framework specific bindings for Vue. * '@storybook/vue' expects the returning object from a decorator to be a 'VueComponent'. */ -export const renderVue: Render = (contextNodes, propsMap, getStoryVNode) => { +export const renderVue: Render = (contextNodes, propsMap, getStoryComponent) => { const { getRendererFrom, updateReactiveSystem } = ContextsPreviewAPI(); const reactiveProps = updateReactiveSystem(propsMap); return Vue.extend({ @@ -21,7 +21,7 @@ export const renderVue: Render = (contextNodes, propsMap, getStor ? { key, ref, style, class: classNames, props: rest } // component as a Vue object : { key, ref, style, class: classNames, attrs: rest }; // component as a HTML tag string return createElement(Component, contextData, [children]); - })(contextNodes, reactiveProps, () => createElement(getStoryVNode())), + })(contextNodes, reactiveProps, () => createElement(getStoryComponent())), }); }; From c1bcdb1a7a3d4dd9979df4b7fe76274911a6c5da Mon Sep 17 00:00:00 2001 From: "Leo Y. Li" Date: Thu, 25 Apr 2019 15:04:15 -0400 Subject: [PATCH 5/5] ADD addon-contexts: snapshot files --- .../addon-contexts.stories.storyshot | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 examples/vue-kitchen-sink/src/stories/__snapshots__/addon-contexts.stories.storyshot diff --git a/examples/vue-kitchen-sink/src/stories/__snapshots__/addon-contexts.stories.storyshot b/examples/vue-kitchen-sink/src/stories/__snapshots__/addon-contexts.stories.storyshot new file mode 100644 index 000000000000..6dc9d78191d9 --- /dev/null +++ b/examples/vue-kitchen-sink/src/stories/__snapshots__/addon-contexts.stories.storyshot @@ -0,0 +1,23 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots Addon|Contexts Languages 1`] = ` +
+
+ + Your locale is unknown, so I say NULL! + +
+
+`; + +exports[`Storyshots Addon|Contexts Simple CSS Theming 1`] = ` +
+ + I'm a children of the injected 'div' (where provides a theming context). + +
+`;