Storybook: [addon-controls] Story canvas isn't updated on Controls prop change for Vue component

Created on 5 Jun 2020  路  20Comments  路  Source: storybookjs/storybook

Describe the bug
@[email protected] with docs and controls addons.
Story canvas isn't updated when I change prop value in Controls tab. Story uses correct prop value after manually re-rendering Canvas tab (change story in left menu or change tab to Docs and back).

To Reproduce
In vue-kitchen-sink:

  1. Install @storybook/[email protected]
  2. Run yarn storybook
  3. Go to Button > Rounded
  4. Change rounded prop in Controls tabs

No effect.

  1. Change tab to Docs and back to Canvas
    Component is rendered with selected prop values

Expected behavior
Component should be updated immediately

Screenshots
not-rerendered

Code snippets

import MyButton from '../Button.vue';

export default {
  title: 'Button',
  component: MyButton,
};

export const Rounded = (args) => ({
  components: { MyButton },
  template: '<my-button :color="color" :rounded="rounded">A Button with rounded edges</my-button>',
  data() {
    return args;
  },
});
Rounded.argTypes = {
  rounded: { defaultValue: true },
  color: { control: { type: 'color' }, defaultValue: '#f00' },
};

The same happens for MDX <Story> component:

<Story name='args'
    args={{rounded: false}}
>
    {(args) => {
        console.log(args);
        // works on args change
        return {
            components: { MyButton },
            data() {
                console.log('data', args);
                // works only on component render
                return args;
            },
            template: '<my-button :rounded="rounded">A Button with rounded edges</my-button>',
        };
    }}
</Story>

System:

Environment Info:

  System:
    OS: Linux 5.4 Ubuntu 20.04 LTS (Focal Fossa)
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
  Binaries:
    Node: 13.13.0 - ~/.nvm/versions/node/v13.13.0/bin/node
    Yarn: 1.22.4 - ~/.nvm/versions/node/v13.13.0/bin/yarn
    npm: 6.14.4 - ~/.nvm/versions/node/v13.13.0/bin/npm
  Browsers:
    Chrome: 83.0.4103.61
    Firefox: 76.0.1
  npmPackages:
    @storybook/addon-a11y: 6.0.0-beta.21 => 6.0.0-beta.21 
    @storybook/addon-actions: 6.0.0-beta.21 => 6.0.0-beta.21 
    @storybook/addon-backgrounds: 6.0.0-beta.21 => 6.0.0-beta.21 
    @storybook/addon-controls: 6.0.0-beta.21 => 6.0.0-beta.21 
    @storybook/addon-docs: 6.0.0-beta.21 => 6.0.0-beta.21 
    @storybook/addon-knobs: 6.0.0-beta.21 => 6.0.0-beta.21 
    @storybook/addon-links: 6.0.0-beta.21 => 6.0.0-beta.21 
    @storybook/addon-storyshots: 6.0.0-beta.21 => 6.0.0-beta.21 
    @storybook/addon-storysource: 6.0.0-beta.21 => 6.0.0-beta.21 
    @storybook/addon-viewport: 6.0.0-beta.21 => 6.0.0-beta.21 
    @storybook/addons: 6.0.0-beta.21 => 6.0.0-beta.21 
    @storybook/source-loader: 6.0.0-beta.21 => 6.0.0-beta.21 
    @storybook/vue: 6.0.0-beta.21 => 6.0.0-beta.21 
controls vue bug has workaround

Most helpful comment

Here's the most recent version of the Vue story based on the previous set of changes. Please check it out if you're tracking this issue:

https://github.com/storybookjs/storybook/blob/next/examples/vue-kitchen-sink/src/stories/components/button.stories.js#L1-L28

All 20 comments

@kvas-damian I'm not sure if the argTypes.defaultValue has the desired effect here,
I think you need to setup your default values following the docs:

Rounded.args = {
  rounded: true,
  color: '#f00',
};

your MDX seems to do that, but with rounded: false :-?

I'm experiencing the same issue trying to get addon-controls working in Vue.

import MyButton from './MyButton';

export default {
  title: 'Button',
  component: MyButton,
  argTypes: {
    color: { control: { type: 'color' } }
  }
};

export const WithControls = (args) => ({
  components: { MyButton },
  template: '<my-button :color="color" :rounded="rounded">Hello Button</my-button>',
  data() {
    return args;
  },
});

https://github.com/Martskin/storybook-vue-playground/blob/master/stories/1-Button.stories.js

https://storybook-vue-playground.netlify.app/

Great Caesar's ghost!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.0.0-beta.23 containing PR #11076 that references this issue. Upgrade today to try it out!

You can find this prerelease on the @next NPM tag.

Closing this issue. Please re-open if you think there's still more to do.

I took a different approach this time, based on the knobs examples. Feedback welcome on the PR: https://github.com/storybookjs/storybook/pull/11115

Ooh-la-la!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.0.0-beta.24 containing PR #11115 that references this issue. Upgrade today to try it out!

You can find this prerelease on the @next NPM tag.

Closing this issue. Please re-open if you think there's still more to do.

Docs page controls broken, re-opening. Ugh. Cc @backbone87

Good golly!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.0.0-beta.26 containing PR #11138 that references this issue. Upgrade today to try it out!

You can find this prerelease on the @next NPM tag.

Closing this issue. Please re-open if you think there's still more to do.

Here's the most recent version of the Vue story based on the previous set of changes. Please check it out if you're tracking this issue:

https://github.com/storybookjs/storybook/blob/next/examples/vue-kitchen-sink/src/stories/components/button.stories.js#L1-L28

@shilman I think we still have this problem when we create MDX stories:

Add

<Story name='args'
    args={{rounded: false}}
>
    {(args) => {
        console.log(args);
        // works on args change
        return {
            components: { MyButton },
            data() {
                console.log('data', args);
                // works only on component render
                return args;
            },
            template: '<my-button :rounded="rounded">A Button with rounded edges</my-button>',
        };
    }}
</Story>

in https://github.com/storybookjs/storybook/blob/next/examples/vue-kitchen-sink/src/stories/addon-docs.stories.mdx to verify that. For me canvas isn't updated.

Ok, I see the problem. I have to pass args via props, not data. Thanks for help

@shilman I'm running into Canvas not updating as well on info @storybook/vue v6.0.21

I may be doing this in a non-supported way, but, the way I'm structuring stories is via example.stories.mdx and building out .vue single file components, then importing them into the example.stories.mdx file.

This appears to work fine on the docs side, I can update a control and it will update the component in the docs, however, when moving over to Canvas, the updates from the docs side are there but doing any updates in the Control panel on Canvas wont update the component, but, if I switch over to docs with the updates, the component on the docs side has the updates from Canvas side, and if I switch immediately back to Canvas after that, the updates are there.

Basically I'm just trying to avoid doing inline templates (which do update for both Docs and Canvas) and not having the extra overhead of defining the component in components:{...}, then writing out the component in the template string, then binding all the props. Using the render function all this is removed and I can just use the example.vue and any other .vue file as-is and pass the props object in like so:


... other imports ...

import StackedBasic from "./StackedBasic.vue";
import StackedBasicSrc from "!!html-loader!./StackedBasic.vue";

... define default arg types ...

<Meta title="Components/Cards/Stacked" argTypes={defaultArgTypes} />
// helper function
export const WrapComponent = (Component, props) => ({
    props: Object.keys(props),
    render: (h) => h(Component, { props }),
});

### Basic Card

<Canvas>
    <Story
        name="Basic Card"
        height="500px"
        parameters={{ storySource: { source: StackedBasicSrc } }}
        args={{ shadow: "shadow-md", title: "Card Titled" }}
    >
        {(args) => WrapComponent(StackedBasic, args)}
    </Story>
</Canvas>

<ArgsTable story="Basic Card" />

With this setup, we can build out multiple component examples as normal .vue files and reuse the WrapComponent passing in props in one go, which is handy since we can also use html-loader to pull in the source for the example and show it in the "show code" panel for a full view into the vue component usage.

The only problem is that Canvas doesn't update when controls are changed :(

Any help here would be much appreciated!

@subhaze sorry my vue knowledge is pretty poor. maybe @backbone87 or @Aaron-Pool can give a hand?

OK thanks, I just wasn't sure if it was a limitation or expected behavior on Storybooks side to where you have to define components via template: '<component-here :a-prop="aProp" /> instead of a render function render: (h) => h(ComponentHere, {props}) for Canvas to update the component when changing control values.

I don't know the details, but we basically declare the names of the props we want like this:

https://github.com/storybookjs/storybook/blob/next/examples/vue-kitchen-sink/src/stories/addon-controls.stories.js#L19

Then @storybook/vue reactively updates those props behind the scenes when the arg values change. We have examples of consuming those props using a template. I don't know enough about vue to know whether anything special is needed for render functions.

Sorry I just want to make sure, do you already have workaround on this @subhaze ?
Currently I have the same exact problem as yours, even though I define components via template: '<component-here :a-prop="aProp" />.

@rezkypg sadly no, I've been noticing at times stories not updating on control changes; A refresh works at times. But as my work around I'm just using a helper function that takes props and generates a template string with all the props in-lined.

Hoo I see. Thanks for the info @subhaze

Was this page helpful?
0 / 5 - 0 ratings