storybook icon indicating copy to clipboard operation
storybook copied to clipboard

addon-docs: Description from docgen doesn't work when using React.memo

Open siminino opened this issue 2 years ago • 2 comments

Describe the bug I am trying show the description from a memoized component in docs page. Running react-docgen cli is possible to confirm that description it's being exported as expected, but it is not displayed at docs page.

To Reproduce Add description to any component and export it memoized. Ex:

/**
 * This is a Button Wrapper
 */
const Button = props => <button {...props} />

export default React.memo(Button)

System System: OS: macOS 12.3.1 CPU: (8) arm64 Apple M1 Pro Binaries: Node: 16.13.1 - ~/.nvm/versions/node/v16.13.1/bin/node Yarn: 1.22.18 - ~/.nvm/versions/node/v16.13.1/bin/yarn npm: 6.14.6 - ~/projects/sandbox/node_modules/.bin/npm Browsers: Chrome: 101.0.4951.54 Safari: 15.4 npmPackages: @storybook/addon-essentials: ^6.4.22 => 6.4.22 @storybook/react: ^6.4.22 => 6.4.22 @storybook/storybook-deployer: ^2.8.10 => 2.8.10

Cause of the issue The props are extracted properly by a conditional that checks if the component is memoized in docs/extractProps. In case, it uses component.type instead. The same conditional was not implemented for description. Description Block calls extractComponentDescription that always use the component to obtain the description.

Workaround Set Component.type on CSF export at story file. Ex:

export default {
  title: 'Button',
  component: Button.type,
}

siminino avatar May 04 '22 17:05 siminino

+1, same issue

a690700752 avatar May 10 '22 06:05 a690700752

export default {
  title: 'Button',
  component: Button.type,
}

How we can use this with Meta in MDX, it doesn't work for me

abder avatar Sep 15 '22 13:09 abder

Component.type doesn't work for me unfortunately using

"@storybook/addon-actions": "^7.0.6",
"@storybook/addon-docs": "^7.0.6",
"@storybook/addon-essentials": "^7.0.6",
"@storybook/addon-links": "^7.0.6",
"@storybook/addon-mdx-gfm": "^7.0.6",
"@storybook/react": "^7.0.6",
"@storybook/react-webpack5": "^7.0.6",
"storybook": "^7.0.6",

iwan-uschka avatar Apr 21 '23 16:04 iwan-uschka

Seeing some issue in 7.0.7. Also, when using React.memo the default values for props that normally show up in controls, as well as docstrings in the props that also show up in controls block are missing.

toakleaf avatar May 01 '23 15:05 toakleaf

Can you try out the following canary in your project and let me know whether it resolves any of your issues (or generates new ones)? We're looking to switch the default docgen from react-docgen-typescript to react-docgen, which is much faster and may also fix some long-standing bugs. Many thanks!

Note that the change is currently only for Vite projects. Instructions in the "how to test" section: 👉 https://github.com/storybookjs/storybook/pull/23825

shilman avatar Aug 23 '23 06:08 shilman

Just created a vite (5.0.8) project and added storybook (7.6.8) to it (including addon-docs). Unfortunately the issue still persists.

iwan-uschka avatar Jan 12 '24 21:01 iwan-uschka

Same when using React.forwardRef. I was able to get the props table like described in https://github.com/storybookjs/storybook/issues/9511#issuecomment-953244988 but not the description.

iwan-uschka avatar Apr 03 '24 12:04 iwan-uschka

I was able to get the props table and the description rendered in storybook for components wrapped with memo() or forwardRef() by exporting a helper from the component file containing the types and docs like

export interface ComponentProps {
  // ...
}

/**
 * Documentation goes here.
 */
export const __StorybookHelper_Component: typeof Component = () => null;
// 👆 this is new

const Component = (props: ComponentProps) => {
  // ...
}

export default memo(Component);// the same for forwardRef(Component)

and using both exports in the story like

import Component, {
  __StorybookHelper_Component,
} from '@repo/ui/path/to/Component';

import type { ComponentProps } from '@repo/ui/path/to/Component';

export default {
  component: __StorybookHelper_Component,
} as Meta;

const Template: StoryFn<ComponentProps> = componentProps => (
  <Component {...componentProps} />
);

export const Default: StoryFn<ComponentProps> = Template.bind({});

I consider this a workaround because of this additional export.

iwan-uschka avatar Apr 03 '24 15:04 iwan-uschka