Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically mutate "args" in Storybook v6 from the component's action?

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.

like image 314
Ky6uk Avatar asked Sep 02 '20 14:09

Ky6uk


People also ask

Which add on allows storybook users to change the data within a component?

The React Context addon allows you to provide and manipulate context inside Storybook.

What is ArgTypes storybook?

ArgTypes are a first-class feature in Storybook for specifying the behaviour of Args. By specifying the type of an arg, you constrain the values that it can take and provide information about args that are not explicitly set (i.e., not required).

What is Template bind in storybook?

💡 Template. bind({}) is a standard JavaScript technique for making a copy of a function. We use this technique to allow each exported story to set its own properties, but use the same implementation. Arguments or args for short, allow us to live-edit our components with the controls addon without restarting Storybook.

How do you add controls on storybook?

To use the Controls addon, you need to write your stories using args. Storybook will automatically generate UI controls based on your args and what it can infer about your component. Still, you can configure the controls further using argTypes, see below.


1 Answers

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',
};
like image 138
ProllyGeek Avatar answered Oct 12 '22 23:10

ProllyGeek