Search code examples
vue.jsstorybook

Storybook.js (Vue) Docs Template Output


Using StoryBook.js, when I navigate to a component, view its "Docs" and click the "Show Code" button, why do I get code that looks like this...

(args, { argTypes }) => ({
    components: { Button },
    props: Object.keys(argTypes),
    template: '<Button v-bind="$props" />',
})

...as opposed to this...

<Button type="button" class="btn btn-primary">Label</Button>

Screenshot From My StoryBook

Button.vue

<template>
  <button
    :type="type"
    :class="'btn btn-' + (outlined ? 'outline-' : '') + variant"
    :disabled="disabled">Label</button>
</template>

<script>
export default {
  name: "Button",
  props: {
    disabled: {
      type: Boolean,
      default: false,
    },
    outlined: {
      type: Boolean,
      default: false,
    },
    type: {
      type: String,
      default: 'button',
    },
    variant: {
      type: String,
      default: 'primary',
      validator(value) {
        return ['primary', 'success', 'warning', 'danger'].includes(value)
      }
    }
  }
}
</script>

Button.stories.js

import Button from '../components/Button'

export default {
    title: 'Button',
    component: Button,
    parameters: {
      componentSubtitle: 'Click to perform an action or submit a form.',
    },
    argTypes: {
        disabled: {
            description: 'Make a button appear to be inactive and un-clickable.',
        },
        outlined: {
            description: 'Add a border to the button and remove the fill colour.',
        },
        type: {
            options: ['button', 'submit'],
            control: { type: 'inline-radio' },
            description: 'Use "submit" when you want to submit a form. Use "button" otherwise.',
        },
        variant: {
            options: ['primary', 'success'],
            control: { type: 'select' },
            description: 'Bootstrap theme colours.',
        },
    },
}

const Template = (args, { argTypes }) => ({
    components: { Button },
    props: Object.keys(argTypes),
    template: '<Button v-bind="$props" />',
})

export const Filled = Template.bind({})
Filled.args = { disabled: false, outlined: false, type: 'button', variant: 'primary' }

export const Outlined = Template.bind({})
Outlined.args = { disabled: false, outlined: true, type: 'button', variant: 'primary' }

export const Disabled = Template.bind({})
Disabled.args = { disabled: true, outlined: false, type: 'button', variant: 'primary' }

I thought I followed their guides to the letter, but I just can't understand why the code output doesn't look the way I expect it to.

I simply want any of my colleagues using this to be able to copy the code from the template and paste it into their work if they want to use the component without them having to be careful what they select from the code output.


Solution

  • For anyone else who encounters this issue, I discovered that this is a known issue for StoryBook with Vue 3.

    As mine is currently a green-field project at the time of writing this, I put a temporary workaround in place by downgrading Vue to ^2.6.

    This is OK for me. I'm using the options API to build my components anyway so I'll happily upgrade to Vue ^3 when Storybook resolve the above linked issue.

    enter image description here