Search code examples
javascriptreactjsflowtypestorybook

Can I create a Knob in React Storybook to modify an array with 4 values where each value has a select dropdown?


I'm using React Storybook (https://github.com/storybooks/storybook/tree/next/app/react) to write stories for my ui components, and I use the knobs addon (https://github.com/storybooks/storybook/tree/next/addons/knobs) to create realtime editable props...

My application is written using flow-types so my props are types, I have defined this type to work with my theme:

export type BoxModel =
  | [ThemeSpacing | 0]
  | [ThemeSpacing | 0, ThemeSpacing | 0]
  | [ThemeSpacing | 0, ThemeSpacing | 0, ThemeSpacing | 0]
  | [ThemeSpacing | 0, ThemeSpacing | 0, ThemeSpacing | 0, ThemeSpacing | 0];

so the idea is I can define padding or margin on a component using an array of my theme values

this is my theme:

spacing: {
    xxSmall: '2px',
    xSmall: '4px',
    small: '8px',
    medium: '12px',
    larger: '16px',
    large: '24px',
    xLarge: '32px',
    xxLarge: '48px',
},

props of my component (several of them)

export type LinkStyleProps = {
  theme?: Theme,
  padding?: BoxModel,
  margin?: BoxModel,
};

So I can basically define margin & padding on my component using an array like ['small', 'medium', 'xsmall'] etc... a lot of like css shorthand

Is there a way to create a Knob that can have this array & have each field selectable via a select?


Solution

  • It is definitely possible to do that with Storybook knobs. You can use something like the example below. You can do additional logic to build the array with fewer than 4 elements if you want as well, you would just need an option in the select to indicate that and dynamically build the array.

    storiesOf("YourComponent", module)
      .add("with knobs", () => {
        const options = {
          none: '0',
          xxSmall: 'xxSmall',
          xSmall: 'xSmall',
          small: 'small',
          // etc.
        };
        const top = select('Top', options, '0');
        const right = select('Right', options, '0');
        const bottom = select('Bottom', options, '0');
        const left = select('Left', options, '0');
        return <YourComponent yourProp={[top, right, bottom, left]} />;
      });