Skip to content

Commit

Permalink
Merge pull request #17279 from storybookjs/csf3-vue-default-render-fn
Browse files Browse the repository at this point in the history
Vue: Add CSF3 default render function
  • Loading branch information
shilman committed Jan 24, 2022
2 parents dc8eafd + f7df112 commit 0300858
Show file tree
Hide file tree
Showing 12 changed files with 84 additions and 43 deletions.
4 changes: 2 additions & 2 deletions app/vue/src/client/preview/index.ts
Expand Up @@ -5,7 +5,7 @@ import { ClientStoryApi, Loadable } from '@storybook/addons';
import './globals';
import { IStorybookSection } from './types';
import { VueFramework } from './types-6-0';
import { renderToDOM } from './render';
import { renderToDOM, render } from './render';
import { decorateStory } from './decorateStory';

const framework = 'vue';
Expand All @@ -20,7 +20,7 @@ interface ClientApi extends ClientStoryApi<VueFramework['storyResult']> {
load: (...args: any[]) => void;
}

const api = start(renderToDOM, { decorateStory });
const api = start(renderToDOM, { decorateStory, render });

export const storiesOf: ClientApi['storiesOf'] = (kind, m) => {
return (api.clientApi.storiesOf(kind, m) as ReturnType<ClientApi['storiesOf']>).addParameters({
Expand Down
36 changes: 36 additions & 0 deletions app/vue/src/client/preview/render.ts
@@ -1,6 +1,8 @@
/* eslint-disable no-underscore-dangle */
import dedent from 'ts-dedent';
import Vue from 'vue';
import { RenderContext } from '@storybook/store';
import { ArgsStoryFn } from '@storybook/csf';
import { VueFramework } from './types-6-0';

export const COMPONENT = 'STORYBOOK_COMPONENT';
Expand All @@ -19,6 +21,40 @@ const root = new Vue({
},
});

export const render: ArgsStoryFn<VueFramework> = (props, context) => {
const { id, component: Component } = context;
const component = Component as VueFramework['component'] & {
__docgenInfo?: { displayName: string };
props: Record<string, any>;
};

if (!component) {
throw new Error(
`Unable to render story ${id} as the component annotation is missing from the default export`
);
}

let componentName = 'component';

// if there is a name property, we either use it or preprend with sb- in case it's an invalid name
if (component.name) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore isReservedTag is an internal function from Vue, might be changed in future releases
const isReservedTag = Vue.config.isReservedTag && Vue.config.isReservedTag(component.name);

componentName = isReservedTag ? `sb-${component.name}` : component.name;
} else if (component.__docgenInfo?.displayName) {
// otherwise, we use the displayName from docgen, if present
componentName = component.__docgenInfo?.displayName;
}

return {
props: component.props,
components: { [componentName]: component },
template: `<${componentName} v-bind="$props" />`,
};
};

export function renderToDOM(
{
title,
Expand Down
7 changes: 6 additions & 1 deletion examples/vue-kitchen-sink/src/stories/Button.vue
Expand Up @@ -6,7 +6,9 @@
@click="onClick"
@dblclick="onDoubleClick"
>
<slot />!
<slot>
{{label}}!
</slot>
</button>
</template>

Expand All @@ -23,6 +25,9 @@
color: {
type: String,
default: '#42b983'
},
label: {
type: String
}
},
Expand Down
Expand Up @@ -5,8 +5,7 @@ exports[`Storyshots Addon/Actions Action and method 1`] = `
class="button"
style="color: rgb(66, 185, 131); border-color: #42b983;"
>
Click me to log the action!

Click me to log the action
</button>
`;

Expand All @@ -15,8 +14,7 @@ exports[`Storyshots Addon/Actions Action only 1`] = `
class="button"
style="color: rgb(66, 185, 131); border-color: #42b983;"
>
Click me to log the action!

Click me to log the action
</button>
`;

Expand All @@ -25,8 +23,7 @@ exports[`Storyshots Addon/Actions Multiple actions 1`] = `
class="button"
style="color: rgb(66, 185, 131); border-color: #42b983;"
>
(Double) click me to log the action!

(Double) click me to log the action
</button>
`;

Expand All @@ -35,7 +32,6 @@ exports[`Storyshots Addon/Actions Multiple actions, object 1`] = `
class="button"
style="color: rgb(66, 185, 131); border-color: #42b983;"
>
(Double) click me to log the action!

(Double) click me to log the action
</button>
`;
Expand Up @@ -8,8 +8,7 @@ exports[`Storyshots Addon/Controls Rounded 1`] = `
class="button rounded"
style="color: rgb(255, 0, 0); border-color: #f00;"
>
A Button with rounded edges!

A Button with rounded edges
</button>
</div>
`;
Expand All @@ -22,8 +21,7 @@ exports[`Storyshots Addon/Controls Square 1`] = `
class="button"
style="color: rgb(0, 0, 255); border-color: #00f;"
>
A Button with square edges!

A Button with square edges
</button>
</div>
`;
Expand Up @@ -5,7 +5,6 @@ exports[`Storyshots Addon/Links Go to welcome 1`] = `
class="button rounded"
style="color: rgb(66, 185, 131); border-color: #42b983;"
>
This buttons links to Welcome!

This buttons links to Welcome
</button>
`;
Expand Up @@ -5,7 +5,6 @@ exports[`Storyshots Core/Template string only 1`] = `
class="button"
style="color: rgb(66, 185, 131); border-color: #42b983;"
>
A Button with square edges!

A Button with square edges
</button>
`;
Expand Up @@ -11,8 +11,7 @@ exports[`Storyshots Custom/Decorator for Vue Render 1`] = `
class="button"
style="color: pink; border-color: pink;"
>
renders component: MyButton!

renders component: MyButton
</button>
</div>
</div>
Expand All @@ -29,8 +28,7 @@ exports[`Storyshots Custom/Decorator for Vue Template 1`] = `
class="button"
style="color: rgb(66, 185, 131); border-color: #42b983;"
>
MyButton with template!

MyButton with template
</button>
</div>
</div>
Expand Down
Expand Up @@ -5,8 +5,7 @@ exports[`Storyshots Custom/Method for rendering Vue JSX 1`] = `
class="button"
style="color: rgb(66, 185, 131); border-color: #42b983;"
>
MyButton rendered with JSX!

MyButton rendered with JSX
</button>
`;

Expand All @@ -31,16 +30,15 @@ exports[`Storyshots Custom/Method for rendering Vue Template 1`] = `
exports[`Storyshots Custom/Method for rendering Vue pre-registered component 1`] = `
<p>
<em>
This component was pre-registered in .storybook/config.js
This component was pre-registered in .storybook/preview.js
</em>
<br />

<button
class="button"
style="color: rgb(66, 185, 131); border-color: #42b983;"
>
MyButton rendered in a template!

MyButton rendered in a template
</button>
</p>
`;
Expand All @@ -50,8 +48,7 @@ exports[`Storyshots Custom/Method for rendering Vue render + component 1`] = `
class="button"
style="color: pink; border-color: pink;"
>
renders component: MyButton!

renders component: MyButton
</button>
`;

Expand All @@ -60,8 +57,7 @@ exports[`Storyshots Custom/Method for rendering Vue template + component 1`] = `
class="button"
style="color: rgb(66, 185, 131); border-color: #42b983;"
>
MyButton rendered in a template!

MyButton rendered in a template
</button>
`;

Expand All @@ -76,8 +72,7 @@ exports[`Storyshots Custom/Method for rendering Vue template + methods 1`] = `
class="button rounded"
style="color: rgb(66, 185, 131); border-color: #42b983;"
>
MyButton rendered in a template + props & methods!

MyButton rendered in a template + props & methods
</button>
</p>
`;
Expand All @@ -87,8 +82,7 @@ exports[`Storyshots Custom/Method for rendering Vue vuex + actions 1`] = `
class="button"
style="color: rgb(66, 185, 131); border-color: #42b983;"
>
with vuex: 0!

with vuex: 0
</button>
`;

Expand All @@ -97,7 +91,6 @@ exports[`Storyshots Custom/Method for rendering Vue whatever you want 1`] = `
class="button"
style="color: rgb(66, 185, 131); border-color: #42b983;"
>
with awesomeness: 0!

with awesomeness: 0
</button>
`;
Expand Up @@ -5,8 +5,7 @@ exports[`Storyshots Button Rounded 1`] = `
class="button rounded"
style="color: rgb(255, 0, 0); border-color: #f00;"
>
A Button with rounded edges!

A Button with rounded edges
</button>
`;

Expand All @@ -15,7 +14,17 @@ exports[`Storyshots Button Square 1`] = `
class="button"
style="color: rgb(0, 0, 255); border-color: #00f;"
>
A Button with square edges!
A Button with square edges
</button>
`;

exports[`Storyshots Button With Default Render 1`] = `
<button
class="button rounded"
style="color: rgb(255, 187, 170); border-color: #fba;"
>

Button with default render!

</button>
`;
Expand Up @@ -27,3 +27,11 @@ Square.args = {
color: '#00f',
label: 'A Button with square edges',
};

export const WithDefaultRender = {
args: {
rounded: true,
color: '#fba',
label: 'Button with default render',
},
};
Expand Up @@ -100,12 +100,12 @@ export const WhateverYouWant = () => ({
WhateverYouWant.storyName = 'whatever you want';

export const PreRegisteredComponent = () => ({
/* By pre-registering component in config.js,
/* By pre-registering component in preview.js,
* the need to register all components with each story is removed.
* You'll only need the template */
template: `
<p>
<em>This component was pre-registered in .storybook/config.js</em><br/>
<em>This component was pre-registered in .storybook/preview.js</em><br/>
<my-button>MyButton rendered in a template</my-button>
</p>`,
});
Expand Down

0 comments on commit 0300858

Please sign in to comment.