How can I add style prop as control in Storybook?

Viewed 2756

I am building a design system library in React and TypeScript using Storybook. Most components support setting custom styles using the style prop. I am trying to reflect this in Storybook using the Controls feature.

Consider the following Button story with a variant and an attempt to add a style prop:

// Button.stories.js

import { Button } from './button';

export default {
  component: Button,
  title: 'Button',
  argTypes: {
    variant: {
      control: {
        type: 'radio',
        options: ['primary', 'secondary']
      }
    },
    style: {
      control: {
        type: 'text'
      },
      defaultValue: '{marginBottom: 10}'
    }
  }
};

What is the correct control type I should use when the type of the style props is React.CSSProperties? What is the correct format for the defaultValue?

3 Answers

As suggested in docs:

By default, Storybook will choose a control for each arg based on the initial value of the arg.

To use auto-detected controls with React, you must fill in the component field in your story metadata:

For example:

import { Button } from './Button';

export default {
  title: 'Button',
  component: Button, // Here
};

Storybook uses this to auto-generate the ArgTypes for your component based on either PropTypes (using react-docgen) or TypeScript types (using react-docgen-typescript).

Hence, to auto-generate the style control, you can write:

export default {
  component: Button, // This is must
  title: 'Button',
  argTypes: {
    variant: {
      control: {
        type: 'radio',
        options: ['primary', 'secondary']
      }
    },
    style: {                             // Remove the control type
      defaultValue: { marginBottom: 10 } // Keep it as object
    }
  }
};

Here is a snapshot:

control style

Here's an updated version of @AjeetShah's answer, if the above doesn't work for you.

button.stories.jsx

export default {
  component: Button, 
  title: 'Button',
    argTypes{
       style: {
        name: 'style',
        defaultValue: {},
        type: { name: 'style', required: false },
        table: {
          type: {
            summary: 'StyleProp',
            detail: null,
          },
          defaultValue: { summary: '' },
        },
        control: {
          type: 'object',
        },
      }
    }
  }

Screenshot of the above using an sx prop

package.json

"@storybook/addon-essentials": "6.3.12",
"@storybook/react": "6.3.12"

.storybook/main.js

module.exports = {
  stories: [
    '../path/to/my/stories/*.stories.jsx',
  ],
  addons: [
    '@storybook/addon-essentials',
  ],
}
argTypes: {
  style: { control: 'object' }
}
Related