Skip to content

Commit

Permalink
feat: add support for component option in default export
Browse files Browse the repository at this point in the history
Fixes #10.
  • Loading branch information
tobiasdiez committed Nov 10, 2022
1 parent d862308 commit 3cf7fb0
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 17 deletions.
5 changes: 4 additions & 1 deletion README.md
Expand Up @@ -14,7 +14,10 @@ Example: `Button.stories.vue`
import Button from './Button.vue'
</script>
<template>
<Stories title="Stories in Vue format 😍">
<Stories
title="Stories in Vue format 😍"
:component="Button"
>
<Story title="Primary">
<Button
background="#ff0"
Expand Down
2 changes: 1 addition & 1 deletion examples/vite/src/components/Button.stories.vue
Expand Up @@ -3,7 +3,7 @@ import MyButton from './Button.vue'
</script>

<template>
<Stories>
<Stories :component="MyButton">
<Story title="Primary">
<MyButton label="Button" />
</Story>
Expand Down
Expand Up @@ -7,5 +7,9 @@ import Button from '../components/Button.vue'
See https://storybook.js.org/docs/vue/configure/overview#configure-story-loading
to learn how to generate automatic titles
-->
<Stories title="docs/1. Default export/native"> </Stories>
<Stories
title="docs/1. Default export/native"
:component="Button"
>
</Stories>
</template>
Expand Up @@ -7,7 +7,10 @@ import Button from '../components/Button.vue'
See https://storybook.js.org/docs/vue/configure/overview#configure-story-loading
to learn how to generate automatic titles
-->
<Stories title="docs/2. Defining stories/native">
<Stories
title="docs/2. Defining stories/native"
:component="Button"
>
<!--
👇 Instead of using named exports as in a CSF file,
a story is defined using the <Story> component.
Expand Down
Expand Up @@ -7,7 +7,10 @@ import Button from '../components/Button.vue'
See https://storybook.js.org/docs/vue/configure/overview#configure-story-loading
to learn how to generate automatic titles
-->
<Stories title="docs/3. Rename stories/native">
<Stories
title="docs/3. Rename stories/native"
:component="Button"
>
<!--
👇 Instead of using named exports as in a CSF file,
a story is defined using the <Story> component.
Expand Down
Expand Up @@ -7,7 +7,10 @@ import Button from '../components/Button.vue'
See https://storybook.js.org/docs/vue/configure/overview#configure-story-loading
to learn how to generate automatic titles
-->
<Stories title="docs/4. How to write stories/native">
<Stories
title="docs/4. How to write stories/native"
:component="Button"
>
<Story title="Primary">
<Button
background="#ff0"
Expand Down
27 changes: 23 additions & 4 deletions src/core/transform.ts
Expand Up @@ -118,21 +118,40 @@ function transformTemplate(content: string, resolvedScript?: SFCScriptBlock) {

function generateDefaultImport(root: ElementNode) {
const title = extractTitle(root)
const component = extractComponent(root)
return `export default {
${title ? `title: '${title}',` : ''}
//component: MyComponent,
${component ? `component: ${component},` : ''}
//decorators: [ ... ],
//parameters: { ... }
}
`
}

function extractTitle(node: ElementNode) {
function extractProp(node: ElementNode, name: string) {
if (node.type === 1) {
const titleProp = node.props.find((prop) => prop.name === 'title')
if (titleProp && titleProp.type === 6) return titleProp.value?.content
return node.props.find(
(prop) =>
prop.name === name ||
(prop.name === 'bind' &&
prop.type === 7 &&
prop.arg?.type === 4 &&
prop.arg?.content === name)
)
}
}
function extractTitle(node: ElementNode) {
const prop = extractProp(node, 'title')
if (prop && prop.type === 6) return prop.value?.content
}

function extractComponent(node: ElementNode) {
const prop = extractProp(node, 'component')
if (prop && prop.type === 7)
return prop.exp?.type === 4
? prop.exp?.content.replace('_ctx.', '')
: undefined
}

function generateStoryImport(
story: ElementNode,
Expand Down
30 changes: 23 additions & 7 deletions test/index.test.ts
Expand Up @@ -9,7 +9,6 @@ describe('transform', () => {
expect(result).toMatchInlineSnapshot(`
"const _sfc_main = {};
export default {
//component: MyComponent,
//decorators: [ ... ],
//parameters: { ... }
};
Expand All @@ -31,7 +30,7 @@ describe('transform', () => {
"const _sfc_main = {};
export default {
title: \\"test\\",
//component: MyComponent,
//decorators: [ ... ],
//parameters: { ... }
};
Expand All @@ -51,14 +50,35 @@ describe('transform', () => {
'"Story is missing a title"'
)
})
it('extracts component from Stories', () => {
const code =
'<script>const MyComponent = {}</script><template><Stories :component="MyComponent"><Story title="Primary">hello</Story></Stories></template>'
const result = transform(code)
expect(result).toMatchInlineSnapshot(`
"const MyComponent = {};
const _sfc_main = {};
export default {
component: MyComponent,
//decorators: [ ... ],
//parameters: { ... }
};
function renderPrimary(_ctx, _cache, $props, $setup, $data, $options) {
return \\"hello\\";
}
export const Primary = () =>
Object.assign({ render: renderPrimary }, _sfc_main);
Primary.storyName = \\"Primary\\";
"
`)
})
it('handles title with spaces', () => {
const code =
'<template><Stories><Story title="Primary story">hello</Story></Stories></template>'
const result = transform(code)
expect(result).toMatchInlineSnapshot(`
"const _sfc_main = {};
export default {
//component: MyComponent,
//decorators: [ ... ],
//parameters: { ... }
};
Expand All @@ -79,7 +99,6 @@ describe('transform', () => {
expect(result).toMatchInlineSnapshot(`
"const _sfc_main = {};
export default {
//component: MyComponent,
//decorators: [ ... ],
//parameters: { ... }
};
Expand All @@ -105,7 +124,6 @@ describe('transform', () => {
expect(result).toMatchInlineSnapshot(`
"const _sfc_main = {};
export default {
//component: MyComponent,
//decorators: [ ... ],
//parameters: { ... }
};
Expand Down Expand Up @@ -138,7 +156,6 @@ describe('transform', () => {
expect(result).toMatchInlineSnapshot(`
"const _sfc_main = {};
export default {
//component: MyComponent,
//decorators: [ ... ],
//parameters: { ... }
};
Expand Down Expand Up @@ -206,7 +223,6 @@ describe('transform', () => {
},
};
export default {
//component: MyComponent,
//decorators: [ ... ],
//parameters: { ... }
};
Expand Down

0 comments on commit 3cf7fb0

Please sign in to comment.