-
-
Notifications
You must be signed in to change notification settings - Fork 9.3k
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
Add support for Vue SFC syntax to stories #9768
Comments
@visualjerk this looks awesome! Related: #7729 @Aaron-Pool has thought about this problem quite a bit and might be able to give pointers. |
Yeah, so there's two major parts of trying to get this feature implemented
As for 1, I think we could use Babel macros to run just the contents of a story block (with a comment to trigger the macro, or something similar) through the Vue sfc compiler and Vue Babel preset. 2 is much trickier. And would be editor dependent. But for vscode, at least, I'm pretty confident it would be possible to write an extension that could detect |
Thanks for the insights @Aaron-Pool Regarding 1: Do you already have plans to work on that? If not, I would be glad to help implementing it. Regarding 2: At least for syntax highlighting in VS Code the |
@visualjerk I've had "plans" to work on it for a while now, but my day job has been eating up most of coding creative energy as of late. I'd be glad to offer guidance and help with any technical hurdles if you started a PR though 👌 And glad to know the current MDX plugin does a decent job already, I though I remembered it not knowing how to handle a non-root |
It sounds a great idea. @visualjerk
See this article for more details Note: The cons is the story source is not pertinent (displayed via story-source / docs addon). The article explains how to load the SFC vue story but i have tried without success. |
@rdhainaut will try to get an |
@rdhainaut thanks for pointing out that solution. Maybe we will give it a try and see how it works with multiple stories in one docs file. @Aaron-Pool After working on the feature request for a while I can give a quick update: 1. ImplementationThe current implementation uses babel parser, which unfortunately does not support custom plugins: https://babeljs.io/docs/en/babel-parser#will-the-babel-parser-support-a-plugin-system So it looks like we need a solution that handles SFC stories before babel parser does. A possible approach would be to detect SFC stories and transform them to JSX stories. Afterwards babel can handle them just fine. Additionally we would have to keep the original SFC story code and put it into the 2. Developer experienceI was wrong 😄 While the mdx extension mentioned above works fine for simple code snippets, it breaks with things like However we could provide a different syntax for SFC stories that works like a charm: <Story name="to storybook" height="300px">
```vue
<template>
<button>click me {{ name }}</button>
</template>
<script>
export default {
data() {
return {
name: 'foo'
}
}
}
</script>
```
</Story> |
If anybody here hasn't seen it, I recently made source snippet customizable, which could be used to improve the |
@visualjerk Is there any standard/precedent for this |
@graup thanks for the reference. I think https://github.com/mdx-js/mdx/tree/master/packages/vue-loader is the converse of what we want. It takes MDX and loads it into a Vue component. We want to load MDX into a React component since Storybook Docs is implemented in React. I'm also not sure whether @visualjerk 's approach is the best one, but it seems very reasonable at first glance. Definitely open for discussion. |
@shilman you're right, I confused the purpose of @mdx-js/vue-loader. Here's another idea instead of |
@graup I think the reason he went with the notated template string was because this gives us a lot of the DX provided by the markdown syntax highlighter for free (in most code editors, at least) 🤷♂️ |
If we want a different syntax, and a decent developer experience, we're going to need to work the MDX syntax highlighting extension and add some additional functionality to detect story block |
@graup Initially I was aiming for a solution similar to the one you proposed. But as @Aaron-Pool pointed out the syntax highlighting with this approach was not great. Having the fenced code block with |
Any news on this? The current approach of wirting the template in inline string
Right now as shown above, it's possible to export a .vue file in .stories.js like import MyVueStoryForButtonWithOverflowingContent from '@/button/stories/OverflowingContent.vue`
export const ButtonWithOverflowingContent = () => MyVueStoryForButtonWithOverflowingContent; Assuming that right now you use the inline template string approach, you probably have one template, but then you reuse it eg. 5 times to show different scenarios eg. const Template = (args, {argTypes}) => {
props: Object.keys(argTypes),
template: `<my-button v-bind="$props">{{text}}</my-button>
}
export const Basic = Template.bind({}).args = {text: 'Hello', disabled: false}
export const Disabled = Template.bind({}).args = {text: 'Hello', disabled: true}
//add some 5 more cases here with the way current .story.vue components work, you can't really reuse the template from above (say you've created an SFC that just contains Sure you can do It'd be perfect if it was possible to write |
I was also getting a bit frustrated by the missing support for native vue stories and thus wrote a simple storybook addon that enables idiomatic vue stories. The package is still in an early stage, but please feel free to play around with it: https://github.com/tobiasdiez/storybook-vue-addon <script setup lang="ts">
import Button from './Button.vue'
</script>
<template>
<Stories
title="Stories in Vue format 😍"
:component="Button"
>
<Story title="Example">
<Button
background="#ff0"
label="😄👍😍💯"
/>
</Story>
</Stories>
</template> |
@tobiasdiez Omg, that looks so good. That (or something like it) should become the official way to do Storybook stories in Vue. The |
@tobiasdiez honestly massive props for this addon! ❤️ both the TS & MDX format felt so clunky and boilerplate'y and not at all Vuey... Oh, but this * chef's kiss * |
This should be the default way to write Vue stories in Storybook! |
If anyone is looking for an alternative to string template, you can use JSX in a separated file and just import your stories in the main story file. Use vitejs/plugin-vue-jsx to support .jsx files. Here's an example: import { defineComponent } from "vue";
import AppButton from "@/components/button/AppButton.vue";
const ButtonDefault = defineComponent({
render ({ $attrs }) {
// Here we can use JSX as we want, way better DX than string template
return <AppButton {...args} />
}
})
// OR
const ButtonDefault = defineComponent({
setup (_, { attrs }) {
return () => <AppButton {...attrs} />
}
})
// Here you'll use the default story structure
export default {
render: (args) => ({
components: {
ButtonDefault
},
setup () {
return { args }
},
// Then just use the .jsx component here.
template: '<ButtonDefault v-bind="args" />'
})
} // Now import the file
import ButtonDefault from './ButtonDefault.tsx'
// ...your meta story here...
export const Default = ButtonDefault Since @floroz lib looks deprecated. There's a fork of his lib also, but in the current date, it seems to be in early stages: https://storybook.js.org/addons/storybook-vue-csf-addon |
Is your feature request related to a problem? Please describe.
When writing a story for Vue components inside mdx files, it differs from the way one would write the code inside a .vue file.
Also when reading the story source inside storybook, the code differs from the code one would normally put inside a .vue file.
So there is this mental switch developers have to do, when using storybook as their component documentation. This is especially troublesome for new developers, which in many teams are the main target group of the documentation.
Describe the solution you'd like
In addition to writing a Vue story like this:
It would be nice to add support for stories in this format:
Are you able to assist bring the feature to reality?
yes
The text was updated successfully, but these errors were encountered: