storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
84.67k stars 9.32k forks source link

Controls not detecting our component props from propTypes or JSDoc (typescript) types #12292

Closed haszari closed 3 years ago

haszari commented 4 years ago

Describe the bug Hi there, sorry for the vague bug!

We've recently upgrade to Storybook 6.0 and we're keen to migrate our stories from Knobs to Controls addon, and the other cool stuff in essentials based on the args pattern, e.g. automatic docs.

Our project uses React, so we're using Storybook-react. The project is WooCommerce Blocks, and there's an open PR dedicated to this: https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3046

Our components include PropTypes declarations. Example component: https://github.com/woocommerce/woocommerce-gutenberg-products-block/blob/51137ecb81da55c98cfc7bc5ed3dcd4e2aa75a8b/assets/js/base/components/quantity-selector/index.js

Note - we're planning on migrating to JSDoc typescript declarations (in our JS files - we're not using TypeScript lang). So if this is supported by Storybook we can switch to that. So far I can't get either option to work - the controls don't show up in Storybook unless I manually specify them via story.args prop.

Screen Shot 2020-08-28 at 3 07 01 PM

Our project is quite complex and we have a custom webpack config. In the related branch / PR the webpack config is overridden using webpackFinal config prop.

With --debug-webpack I've confirmed that the react-docgen plugin is in the config:

  overrides: [
        {
          test: /\.(mjs|jsx?)$/,
          plugins: [
            [
              '/Users/haszari/_automattic/merch-repos/woocommerce-blocks/node_modules/babel-plugin-react-docgen/lib/index.js',
              {
                DOC_GEN_COLLECTION_NAME: 'STORYBOOK_REACT_CLASSES'
              }
            ]

How can I debug where it's going wrong, or ensure it has access to our prop declarations?

To Reproduce Sorry – I don't have a minimal reproduce repo.

Expected behavior Hoping to get this working, again apologies for the open-ended bug report.

Ideally we can nail down the flow of data into react-docgen and document exactly what's expected here, and how to diagnose problems.

System: Please paste the results of npx sb@next info here.

Environment Info:

  System:
    OS: macOS 10.15.6
    CPU: (8) x64 Intel(R) Core(TM) i7-1068NG7 CPU @ 2.30GHz
  Binaries:
    Node: 12.18.3 - ~/.nvm/versions/node/v12.18.3/bin/node
    npm: 6.14.8 - ~/.nvm/versions/node/v12.18.3/bin/npm
  Browsers:
    Chrome: 84.0.4147.135
    Firefox: 79.0
    Safari: 13.1.2
  npmPackages:
    @storybook/addon-a11y: 6.0.20 => 6.0.20 
    @storybook/addon-essentials: 6.0.20 => 6.0.20 
    @storybook/addon-knobs: 6.0.20 => 6.0.20 
    @storybook/addon-links: 6.0.20 => 6.0.20 
    @storybook/addon-storysource: 6.0.20 => 6.0.20 
    @storybook/addons: 6.0.20 => 6.0.20 
    @storybook/react: 6.0.20 => 6.0.20 

Additional context

haszari commented 4 years ago

Here's a trimmed-down example component and story.

// index.js
/**
 * @typedef QuantitySelector
 *
 * @param {Object} props Component props.
 * @param {string} props.className CSS class(es).
 * @param {number} props.quantity Value to display.
 * @param {number} props.minimum Minimum value.
 * @param {number} props.maximum Maximum value.
 * @param {Function} props.onChange Called when the value changes.
 * @param {string} props.itemName The item/value (e.g. product) that the quantity applies to - used for an accessibility message.
 * @param {boolean} props.disabled Render the component as disabled and prevent user input.
 * @return {*} QuantitySelector component markup.
 */
const QuantitySelector = ( {
  className,
  quantity = 1,
  minimum = 1,
  maximum,
  onChange = () => null,
  itemName = '',
  disabled,
} ) => {
  // .. component implementation 
};

QuantitySelector.propTypes = {
    className: PropTypes.string,
    quantity: PropTypes.number,
    minimum: PropTypes.number,
    maximum: PropTypes.number,
    onChange: PropTypes.func,
    itemName: PropTypes.string,
    disabled: PropTypes.bool,
};

export default QuantitySelector;
// stories/index.js
import QuantitySelector from '../';

export default {
  title: 'WooCommerce Blocks/@base-components/QuantitySelector',
  component: QuantitySelector,
};

const Template = ( args ) => <QuantitySelector { ...args } />;

export const Primary = Template.bind( {} );
// Primary.args = {
//  disabled: false,
//  quantity: 1,
//  itemName: 'widgets',
// };
haszari commented 4 years ago

Update – I've pasted in a 100% TypeScript Button example (from Storybook examples) and it works correctly.

Code here: https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3046/commits/2a35668aeaf007c7c9eeefb3b936a979639ff5ea

🎉 screenshot of args working: (!)

Screen Shot 2020-08-28 at 3 41 23 PM

This is using the same webpack and other config, so I think the problem is with our JavaScript components, and how we can export the PropTypes & descriptions so args can find them. Or perhaps there's a problem with the story JavaScript not importing the proptypes.

Is there a way to use args with JavaScript components and stories? I'm keen to see a canonical example to compare with our code.

Or any ideas for where our proptypes might be getting lost.

Just confirming - args doesn't require TypeScript?

shilman commented 4 years ago

@haszari we use args with PropTypes all the time and there are numerous examples in the monorepo and probably in the Storybook design system. It's definitely an issue with your custom webpack config.

haszari commented 4 years ago

It's definitely an issue with your custom webpack config.

Highly likely! I'll keep digging, I'm guessing there's some interaction with other plugins/steps in the webpack config (babel, react). I can try disabling various plugins and ensure everything's up to date. 🤞

imeredith commented 4 years ago

I'm not sure if im having the same issue as you, but it sounds the same.

My ___docgenInfo is populated and I just tried the following which works...

MyComponentStory.argTypes = MyComponent.___docgenInfo.props

I thought it was a webpack issue but I don't think so now

shilman commented 4 years ago

@imeredith different issue. happy to help diagnose if you open a new issue with a bit more info to help see what's going on.

silouanwright commented 4 years ago

I'm also running into this issue and I can confirm the following:

Given both of those statements it's not clear to me what the actual issue is here, only that

I could assist by debugging in my local env if I could get some direction on where to start checking around.

Edit: this is "either" the babel config, or it's some sort of package conflict. I literally removed all my packages locally, swapped them in with the packages from this other repo (like 1/4th of the packages), removed my local babel.config.js file, and removed my yarn.lock and reinstalled, and that got things to start generating. Going to do more research.

shilman commented 4 years ago

@reywright if you have a simple repro, i'd love to take a look at it.

silouanwright commented 4 years ago

It's 100% the babel config file for me, FYI. Nuking that file makes everything work fine.

Edit: I'm not really sure how I'd go about recreating this "simply". I think the easiest option here would be to see an example of a babelrc file that mirrors how you're configuring it in the webpack settings. Either that, or allow an option to disable the loading of the babel file.

One other thought here: it might be helpful to include some instructions on how to merely "alter" the babel configuration in webpack. One of the dangers of this setup right now, is if someone wants to have their own custom babel config, it could diverge from storybook specific.

stale[bot] commented 4 years ago

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

yairEO commented 3 years ago

I might have a similar problem. After spending a full day researching and trying different things, nothing works and the automatic args table is not showing my components proptypes definitions.

I was mainly following these instructions: https://storybook.js.org/docs/ember/writing-docs/doc-blocks

I've put the whole code online (based on my client's complex Stroybook config), with just a little bit of cleanup, and left only one story

https://github.com/yairEO/sb-args-table-not-showing

Files of interest:

Thanks to whoever shed light onto this mystery

mbustosp commented 3 years ago

I might have a similar problem. After spending a full day researching and trying different things, nothing works and the automatic args table is not showing my components proptypes definitions.

I was mainly following these instructions: https://storybook.js.org/docs/ember/writing-docs/doc-blocks

I've put the whole code online (based on my client's complex Stroybook config), with just a little bit of cleanup, and left only one story

https://github.com/yairEO/sb-args-table-not-showing

Files of interest:

Thanks to whoever shed light onto this mystery

I faced the same issue when I added a custom babel configuration in my application. After some debugging I realized storybook could not fetch the components' proptypes because of this evaluation:

https://github.com/storybookjs/storybook/blob/7064642e1aee7786c77fe735c064c0c29dbcee01/addons/docs/src/lib/docgen/utils/docgenInfo.ts#L15

That means component.__docgenInfo is undefined or null.

How did I solve it?

Add these dependencies in your project

Add the following addon in your storybook's main.js

Add this plugin in your .babelrc

Now I haven't completely understood why storybook drops react-docgen when using a custom babel configuration file.

I hope to have shed some light ;)

image

shilman commented 3 years ago

@mbustosp potentially addressed here https://github.com/storybookjs/storybook/pull/15928

shilman commented 3 years ago

Gadzooks!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.4.0-alpha.33 containing PR #15928 that references this issue. Upgrade today to the @next NPM tag to try it out!

npx sb upgrade --prerelease

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