25

Let's see we have the simple component ToggleButton:

const ButtonComponent = Vue.component('ButtonComponent', {
  props: {
    value: Boolean
  },

  methods: {
    handleClick() {
      this.$emit('toggle');
    }
  },

  template: `
    <button 
      :class="value ? 'on' : 'off'"
      @click="handleClick"
    >
      Toggle
    </button>`
});

And the story for that component:

import ToggleButton from './ToggleButton.vue';

export default {
  title: 'ToggleButton',
  component: ToggleButton,

  argTypes: {
    onToggle: {
      action: 'toggle' // <-- instead of logging "toggle" I'd like to mutate `args.value` here
    }
  }
};

export const Default = (_args, { argTypes }) => ({
  components: { ToggleButton },
  props: Object.keys(argTypes),

  template: `
    <ToggleButton
      :value="value"
      :toggle="onToggle"
    />
  `
});

Default.args = {
  value: false
}

What I want to achieve is to handle toggle action inside the story and change value that I've used in Default.args object to change the button style by changing the class name from .off to .on.

Ky6uk
  • 1,067
  • 3
  • 16
  • 26
  • did you get this figured out by any chance? – SpaceOso Dec 11 '20 at 18:02
  • @SpaceOso unfortunately no. I have created a wrapper component just inside the story for a similar thing (control props inside the wrapper), but it's not exactly the same that I'm looking for. – Ky6uk Dec 15 '20 at 23:13
  • @Ky6uk Could you share what that component wrapper ended up looking like? I am trying to figure this out myself – Maxim Fedotov Apr 10 '21 at 13:48
  • @MaximFedotov I just created a new Vue component inside `ButtonComponent.stories.ts`, let's say `const ControlComponent = Vue.component('ControlComponent', { components: { ButtonComponent } });` with dynamic properties inside that's being mutated by `ButtonComponent`. And then have used it instead of `ButtonComponent`. – Ky6uk Apr 11 '21 at 21:00

2 Answers2

26

I had the same exact issue, and kept looking for days, till I stumbled upon this github post: https://github.com/storybookjs/storybook/issues/12006

Currently in my React (am sure vue approach will be similar), I do following:

import React from 'react';
import CheckboxGroupElement from '../CheckboxGroup';
import { STORYBOOK_CATEGORIES } from 'elements/storybook.categories';
import { useArgs } from '@storybook/client-api';

export default {
  component: CheckboxGroupElement,
  title: 'Components/CheckboxGroup',
  argTypes: {
    onChange: {
      control: 'func',
      table: {
        category: STORYBOOK_CATEGORIES.EVENTS,
      },
    },
  },
  parameters: { actions: { argTypesRegex: '^on.*' } },
};

const Template = (args) => {
  const [_, updateArgs] = useArgs();

  const handle = (e, f) => {
// inside this function I am updating arguments, but you can call it anywhere according to your demand, the key solution here is using `useArgs()`
// As you see I am updating list of options with new state here
    console.log(e, f);
    updateArgs({ ...args, options: e });
  };
  return <CheckboxGroupElement {...args} onChange={handle} />;
};

export const CheckboxGroup = Template.bind({});
CheckboxGroup.storyName = 'CheckboxGroup';
CheckboxGroup.args = {
//Here you define default args for your story (initial ones)
  controller: { label: 'Group controller' },
  options: [
    { label: 'option 1', checked: true },
    { label: 'option 2', checked: false },
    { label: 'option 3', checked: false },
  ],
  mode: 'nested',
};
ProllyGeek
  • 15,517
  • 9
  • 53
  • 72
  • 24
    This is often the way it goes with Storybook, isn’t it? You’re looking for a feature that is never mentioned in the docs only to find it either deep in their source code or in a GitHub issue. – Brandon Durham Sep 29 '21 at 16:43
  • 1
    This works great, but the args state seems to be out of sync with controls state. – T. Gaud Nov 15 '21 at 10:40
  • @T.Gaud what exactly your issue looks like? – ProllyGeek Nov 15 '21 at 11:37
  • 1
    @ProllyGeek if I change the state of my component with useArgs when an onClick is fired, the controls addon (which is included in storybook-essentials) doesn't reflect the updated state. – T. Gaud Nov 15 '21 at 15:45
  • @T.Gaud are you talking about the actions panel in canvas tab? – ProllyGeek Nov 15 '21 at 16:06
  • 1
    @ProllyGeek well yeah, but the controls tab. e.g. https://storybook.js.org/addons/@storybook/addon-controls – T. Gaud Nov 16 '21 at 09:41
0

Storybook v7

Just a update on ProllyGeek answer! on Storybook v7 it should be imported from:
import { useArgs } from '@storybook/addons'

the use still the same!

here's the docs page where it's mentioned https://storybook.js.org/docs/react/writing-stories/args

Leandro Lima
  • 298
  • 3
  • 12