storybook: Props not showing in the DocsPage when they're imported from another file into the component (Vue)

Describe the bug I have a component where the props are in a different JavaScript file because it’s used for multiple button components but the props aren’t rendered in the docs, am i doing something wrong?

To Reproduce Steps to reproduce the behavior:

  1. Run storybook with the 3 example files below

Expected behavior Props being rendered in the DocsPage

Screenshots image

image

Code snippets

// ButtonBrops.js
export default {
    label: {
        type: String,
        default: 'Button',
    },
};
// Button.vue
<template>
    <button @click="clickButton">{{ label }}</button>
</template>

<script>
    import ButtonProps from './ButtonProps';

    export default {
        name: 'button',
        props: ButtonProps,
        methods: {
            clickButton() {
                this.$emit('click-button');
            },
        },
    };
</script>
// Button.stories.mdx
import { Meta, Props } from '@storybook/addon-docs/blocks';
import Button from './Button.vue';

<Meta title='Components/Button' component={Button} />

## Props, Events & Slots
<Props of={ Button } />

System:

Environment Info:

  System:
    OS: Linux 5.4 Ubuntu 19.10 (Eoan Ermine)
    CPU: (8) x64 Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz
  Binaries:
    Node: 12.13.0 - ~/.nvm/versions/node/v12.13.0/bin/node
    npm: 6.12.0 - ~/.nvm/versions/node/v12.13.0/bin/npm
  Browsers:
    Chrome: 84.0.4147.125
    Firefox: 78.0.2
  npmPackages:
    @storybook/addon-actions: ^6.0.16 => 6.0.16
    @storybook/addon-docs:  ^6.0.16 => 6.0.16
    @storybook/addon-essentials:  ^6.0.16 => 6.0.16
    @storybook/addon-links:  ^6.0.16 => 6.0.16
    @storybook/vue:  ^6.0.16 => 6.0.16 

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 6
  • Comments: 19 (8 by maintainers)

Most upvoted comments

Curious if there has been any progress or plans for this? My use case is exactly as described above – reusing props by spreading them in from another file. Mixins aren’t an option because we’re using script setup and the composition API. The docs are fantastic, and this would be a pretty awesome addition to make our docs more complete!

Hello @puyt, Thank you @shilman,

It is indeed a known limitation of vue-docgen-api. The library does not resolve variables in props. Since it is a static analyzer of the code, not its runtime, it often can’t guess what variables will contain.

Though, @puyt you make me think of a scenario where it would make sense to have the props as a separate object. Tell me if you have another scenario where it would be necessary.

Here it is:

Button.vue has 3 props color, size and variant. We then make an ActionButton.vue, who encapsulates the button and keeps all it’s props using v-bind. The props validations now have to be defined at 2 levels, and copied and pasted.

It would be better to have them defined once and imported.

This sounds feasible but not easy.

For reference here are other issues related to resolving non-explicit prop types: https://github.com/vue-styleguidist/vue-styleguidist/issues/923 https://github.com/vue-styleguidist/vue-styleguidist/issues/881

It is possible with a little elbow grease. I am planning support for this and advanced typescript types for 5.0.

I know how to do it, I have no idea when it is going to be done.

It is progressing though. I am about to share the first RFC for a breaking change on advanced types (union, intersection, interfaces,… )

Hello @gburning,

The problem of dealing with runtime generated is a little deeper than just extracting those props. It also asks the question “Where do I add the comments to describe each prop?” or “What if I have to redocument a specific case in a component?”. If you prefer mixins to generated props, you will get all those questions answered and will still keep the DRY code.

So my question is what would be wrong with using a set of mixins in this use case? How can I help you adopt them?

I hope you understand what I mean, if not join me on discord. I know I can be unclear and take shortcuts.

Cheers

Vue mixins is an old fashion mode to compose complex vue component, now Vue recommends composition-api to write component, Vue 2 with @vue/composition-api or Vue 2.7 later and Vue 3 native support, so props mixins will be deprecated sometimes later, instead import props from another file will be the primary mode. So new vue developers just maybe don’t use mixins anymore.

Sorry to revive an old thread but was there ever any progress on this @elevatebart?

I appreciate that parsing extracted props is not a core feature for vue-docgen-api but if there was a gist or perhaps some sort of plugin to do this I think that might be useful. It does seem like a fairly commonly requested feature (https://github.com/storybookjs/storybook/issues?q=vue+mixin+props).

I have a bunch of component types (form controls, button components) that have common props that I’d like to selectively share between them (all control components have to support a “label” prop but only some might support a “icon” or “placeholder” prop). Mixins don’t work for this as it’s all or nothing. They also obscure the source of the props and make code readability a lot worse in my opinion.

So, if anyone has made any progress on this I’d greatly appreciate it.

Just wanted to add a similar usecase:

When sharing component functionality with the composition api, quite often prop definitions also need to be shared.

Example:

import { boxProps, useBox } from '@components/box'

export const tabbableProps = {
  ...boxProps,
  disabled: {
    type: Boolean,
    default: false,
  },
  focusable: {
    type: Boolean,
    default: false,
  },
}

export function useTabbable(props, context) {
  const box = useBox(props, context)
  ...
}

export const Tabbable = {
  props: tabbableProps,
  setup: useTabbable,
}

If you were to use a mixin for these props instead of an object, docgen would be able to pick it up out of the box. I hope it helps you at all 😉