fbredius/storybook

View on GitHub
examples/vue-kitchen-sink/src/stories/addon-docs.stories.mdx

Summary

Maintainability
Test Coverage
import { Story, Canvas, Meta } from '@storybook/addon-docs';
import { stripIndents } from 'common-tags';
import MyButton from './Button.vue';

# Storybook Docs for Vue

Storybook supports every major view layer:
React, Vue, Angular, Ember, React Native, etc.

Storybook Docs does too.

<Story id="welcome--welcome" />

Let's check out a Vue prototype to see how this works.

## Component Declaration

Just like in React, we first declare our component.

<Meta title="Addon/Docs" />

This declaration doesn't show up in the MDX output.

## SB5 "Classic" Vue Stories

Next let's declare some stories.

But first let's review how it's done in SB5 for Vue.

```js
import MyButton from './Button.vue';
storiesOf('Button', module).add('rounded', () => ({
  template: '<my-button :rounded="true">A Button with rounded edges</my-button>',
}));
```

## MDX Stories

Similarly, here's how we do it in the Docs MDX format:

<Story name="rounded">
  {{
    template: '<my-button :rounded="true">A Button with rounded edges</my-button>',
  }}
</Story>

This isn't the final syntax, but it gets the job done.

## Another one

Let's add another one. The UI updates automatically as you'd expect.

<Story name="square">
  {{
    template: '<my-button :rounded="false">A Button with square edges</my-button>',
  }}
</Story>

## Longform docs

And—just like in the React case—we're generating long-form docs as we go.

The primary difference is that for Vue Docs we generate an iframe per story, by default. If you prefer your stories to be rendered inline, see the next section.

## Inline Stories

The default configuration for `addon-docs/vue` implements the `prepareForInline` parameter using [@egoist/vue-to-react](https://github.com/egoist/vue-to-react). This means you can set use `addParameters({ docs: { inlineStories: true } });` to set stories to be inline _globally_. If some of your stories rely on being within an iframe, you can instead selectively change certain stories to be inline through the `inline` prop on the `<Story>` block, or set stories to be rendered inline globally and set the `inline` prop to be false on the `<Story>` block for any stories that need to exist within an iframe.

To provide a tangible example of the inline/iframe rendering contexts, here's the same story rendered both ways.

<Canvas>
  <Story id="app--app" inline={true} />
</Canvas>

<Canvas>
  <Story id="app--app" height="200px" />
</Canvas>

The biggest win here is that we don't have to worry about setting the height anymore. The story can calculate its height like any other inline element. As you can see, several of the stories on this page are quite small, but take up `500px`, because that's the default story height, and we didn't tweak the story to be an explicit height. Another huge gain here is in terms of performance. Using an iframe to render a single element is definitely unnecessary in most cases and, as you may have noticed while reading this page, can _really_ cause page performance to suffer.

## Previews

Just like in React, we can easily reference other stories in our docs:

<Story id="nonexistent-story" />

## More info

For more info, check out the [Storybook Docs Technical Canvas](https://docs.google.com/document/d/1un6YX7xDKEKl5-MVb-egnOYN8dynb5Hf7mq0hipk8JE/edit?usp=sharing).

We want your feedback to help make this more useful.

Follow us on Twitter for more short demos & project updates! ❤️📈🛠