Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue: Add CSF3 default render function #17279

Merged
merged 8 commits into from Jan 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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