Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Storybook v7 does not populate JSDoc annotations in ArgsTable for memoized TypeScript components #21192

Closed
giselleghadyani opened this issue Feb 21, 2023 · 7 comments

Comments

@giselleghadyani
Copy link

Describe the bug

Storybook v7 does not auto populate JSDoc annotations as ArgsTable descriptions for memoized TypeScript components.

In v6, the ArgsTable does not populate at all for memoized TS components that aren't default exports. Which was a bug in Storybook for React components in 2020 and was resolved in this commit: ee4144a.

I upgraded to v7 to see if this was fixed, and it partially of is. The ArgsTable does populate. However the JSDoc annotations still don't show up unless the original component is the default export or named export. If I memoize the component and then export as a default or named (aliased) export, then the JSDoc annotations don't show up.

The problem is not the memoization itself, but that Storybook requires the component to be exported at some point in the file without any form of alias.

There have been quite a few posts about named exports, memoization, and react-docgen vs react-docgen-typescript. What I mentioned that was happening in v6 was considered a known bug. That bug seems to be fixed in v7, but not completely.

As of right now to solve this, I have to add an additional non memoized default export that is dead/orphaned code. That export that will never be imported anywhere. It's just a hack for Storybook documentation.

I am using the latest v7, which is 7.0.0-beta.50 as of today. I am also using Windows 11, so not sure why it says Windows 10 when I run npx sb@next info.

To Reproduce

✅ Default export without memoization

This does auto populate JSDoc annotations in the ArgsTable.

// ComponentName.tsx
export type ComponentNameProps = {
  /** Description about propName. */
  propName: string,
};

const ComponentName = ({
  propName
}: (
  ComponentNameProps
)) => {
  <div />
};

export default ComponentName;
// ComponentName.stories.tsx
import {
  Meta,
  StoryObj,
} from '@storybook/react';

import ComponentName from './ComponentName';

const storybookMeta: Meta<typeof ComponentName > = {
  component: ComponentName ,
};

export default storybookMeta;

type Story = StoryObj<typeof ComponentName>

export const StoryName: Story = {
  args: {
    propName: 'propValue',
  },
};

image

✅ Named export without memoization

This does auto populate JSDoc annotations in the ArgsTable.

// ComponentName.tsx
export type ComponentNameProps = {
  /** Description about propName. */
  propName: string,
};

const ComponentName = ({
  propName
}: (
  ComponentNameProps
)) => {
  <div />
};

export { ComponentName };
// ComponentName.stories.tsx
import {
  Meta,
  StoryObj,
} from '@storybook/react';

import { ComponentName } from './ComponentName';

const storybookMeta: Meta<typeof ComponentName > = {
  component: ComponentName ,
};

export default storybookMeta;

type Story = StoryObj<typeof ComponentName>

export const StoryName: Story = {
  args: {
    propName: 'propValue',
  },
};

image

⛔ Default export with memoization

This does not populate the JSDoc annotations. This does work for React components, but just not TypeScript components.

// ComponentName.tsx
import { memo } from 'react';

export type ComponentNameProps = {
  /** Description about propName. */
  propName: string,
};

const ComponentName = ({
  propName
}: (
  ComponentNameProps
)) => {
  <div />
};

const MemoizedComponentName = memo(ComponentName);

export default MemoizedComponentName;
// ComponentName.stories.tsx
import {
  Meta,
  StoryObj,
} from '@storybook/react';

import ComponentName from './ComponentName';

const storybookMeta: Meta<typeof ComponentName > = {
  component: ComponentName ,
};

export default storybookMeta;

type Story = StoryObj<typeof ComponentName>

export const StoryName: Story = {
  args: {
    propName: 'propValue',
  },
};

image

⛔ Named export with memoization

This also does not populate JS Doc annotations in ArgsTable.

// ComponentName.tsx
import { memo } from 'react';

export type ComponentNameProps = {
  /** Description about propName. */
  propName?: string,
};

const ComponentName = ({
  propName
}: (
  ComponentNameProps
)) => {
  <div />
};

const MemoizedComponentName = memo(ComponentName);

export { MemoizedComponentName as ComponentName };
// ComponentName.stories.tsx
import {
  Meta,
  StoryObj,
} from '@storybook/react';

import { ComponentName } from './ComponentName';

const storybookMeta: Meta<typeof ComponentName > = {
  component: ComponentName ,
};

export default storybookMeta;

type Story = StoryObj<typeof ComponentName>

export const StoryName: Story = {
  args: {
    propName: 'propValue',
  },
};

image

✅ Dead export

This works, but now I'm exporting something only for the sake of getting JSDoc annotations to show up in Storybook.

// ComponentName.tsx
import { memo } from 'react';

export type ComponentNameProps = {
  /** Description about propName. */
  propName?: string,
};

const ComponentName = ({
  propName
}: (
  ComponentNameProps
)) => {
  <div />
};

const MemoizedComponentName = memo(ComponentName);

export { MemoizedComponentName as ComponentName };

// Useless export to satisfy Storybook.
export default ComponentName;
// ComponentName.stories.tsx
import {
  Meta,
  StoryObj,
} from '@storybook/react';

// Note, this is importing the memoized aliased export, not the default.
import { ComponentName } from './ComponentName';

const storybookMeta: Meta<typeof ComponentName > = {
  component: ComponentName ,
};

export default storybookMeta;

type Story = StoryObj<typeof ComponentName>

export const StoryName: Story = {
  args: {
    propName: 'propValue',
  },
};

image

System

Environment Info:

  System:
    OS: Windows 10 10.0.22621
    CPU: (32) x64 AMD Ryzen 9 5950X 16-Core Processor
  Binaries:
    Node: 16.13.0 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.5 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
    npm: 8.1.0 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Chrome: 110.0.5481.100
    Edge: Spartan (44.22621.1105.0), Chromium (110.0.1587.46)

Additional context

No response

@shilman
Copy link
Member

shilman commented Feb 22, 2023

Thanks for the detailed report. We're going to be taking a hard look at the way we extract argTypes in 7.x, so hopefully we can fix a bunch of the outstanding issues then. Cc @KrofDrakula

@michu2k
Copy link

michu2k commented Apr 8, 2023

For the record, I can confirm that in Storybook v7.0.2 the bug still exists.

Any info @shilman when this might be fixed? Thanks

@KrofDrakula
Copy link
Member

@michu2k The PR that implements a new TypeScript compiler-based analyzer as the provider for type annotations is currently a draft (#20631). The proof-of-concept works, it just needs a bit of infrastructure discussion around it before it's ready to be reviewed and merged.

@monkeystylle
Copy link

hi is there a fix on this already? or a work around?

@shilman
Copy link
Member

shilman commented Aug 23, 2023

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: 👉 #23825

@monkeystylle
Copy link

hi, for some reason the autodocs is now working properly, as we are using storybook 7.2.2 , saves me the hassle of manually adding the description of each props on stories.. when i comment on my props on main file it works now..

@shilman
Copy link
Member

shilman commented Aug 28, 2023

That's great to hear. Closing this for now. Please let me know if there's more to be done here!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants