storybookjs / storybook

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

[Bug]: Autodocs not working when a React component returns a portal #27169

Open symsmith opened 6 months ago

symsmith commented 6 months ago

Describe the bug

If a React component returns a portal created by createPortal from react-dom, Autodocs doesn’t retrieve the type information or JSDoc comments from the file.

To Reproduce

https://stackblitz.com/edit/github-cj2wcx?file=src%2Fstories%2FButtonPortal.tsx

ButtonPortal is the same component as Button, but the returned value is wrapped in createPortal. See the difference between Button/Docs and ButtonPortal/Docs

System

Local environment:

  System:
    OS: macOS 14.0
    CPU: (10) arm64 Apple M2 Pro
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.11.1 - ~/.nvm/versions/node/v20.11.1/bin/node
    Yarn: 1.22.19 - /opt/homebrew/bin/yarn
    npm: 10.2.4 - ~/.nvm/versions/node/v20.11.1/bin/npm
    pnpm: 9.1.1 - ~/Library/pnpm/pnpm <----- active
  Browsers:
    Edge: 124.0.2478.105
    Safari: 17.0
  npmPackages:
    @storybook/addon-actions: ^8.1.1 => 8.1.1 
    @storybook/addon-essentials: ^8.1.1 => 8.1.1 
    @storybook/addon-links: ^8.1.1 => 8.1.1 
    @storybook/addon-onboarding: ^8.1.1 => 8.1.1 
    @storybook/manager-api: ^8.1.1 => 8.1.1 
    @storybook/react: ^8.1.1 => 8.1.1 
    @storybook/react-vite: ^8.1.1 => 8.1.1 
    @storybook/theming: ^8.1.1 => 8.1.1 
    eslint-plugin-storybook: ^0.8.0 => 0.8.0 
    storybook: ^8.1.1 => 8.1.1 

But it works the same way on Stackblitz



### Additional context

Is this normal/documented?
github-actions[bot] commented 6 months ago

We could not detect a valid reproduction link. Make sure to follow the bug report template carefully.

Why was this issue closed?

To be able to investigate, we need access to a reproduction to identify what triggered the issue. We need a link to a public GitHub repository, Stackblitz or CodeSandbox. The easiest way to create a reproduction is with storybook.new.

The bug template that you filled out has a section called "To reproduce", which is where you should provide the link to the reproduction.

What should I do?

Depending on the reason the issue was closed, you can do the following:

In general, assume that we should not go through a lengthy onboarding process at your company code only to be able to verify an issue.

My repository is private and cannot be public

In most cases, a private repo will not be a sufficient minimal reproduction, as this codebase might contain a lot of unrelated parts that would make our investigation take longer. Please do not make it public. Instead, create a new repository using the templates above, adding the relevant code to reproduce the issue. Common things to look out for:

I did not open this issue, but it is relevant to me, what can I do to help?

Anyone experiencing the same issue is welcome to provide a minimal reproduction following the above steps by opening a new issue.

I think my reproduction is good enough, why aren't you looking into it quickly?

We look into every Storybook issue and constantly monitor open issues for new comments.

However, sometimes we might miss one or two due to the popularity/high traffic of the repository. We apologize, and kindly ask you to refrain from tagging core maintainers, as that will usually not result in increased priority.

Upvoting issues to show your interest will help us prioritize and address them as quickly as possible. That said, every issue is important to us, and if an issue gets closed by accident, we encourage you to open a new one linking to the old issue and we will look into it.

Useful Resources

shilman commented 6 months ago

This looks like a deficiency of react-docgen which is the tool we use to analyze React components by default in 8.0+.

One workaround is to use the much slower, but more accurate react-docgen-typescript instead but adding the following to .storybook/main.ts:

export default {
  // existing...
  typescript: {
    reactDocgen: 'react-docgen-typescript',
  }
};
symsmith commented 6 months ago

I found another workaround, which is to wrap the createPortal call with a fragment. I still wanted to give notice, because I scratched my head for a while before realizing what was different from my other components/stories.

Basically it looks like the component has to return a React.JSX.Element for Autodocs to work.

shilman commented 6 months ago

Thats interesting @symsmith and a better workaround (though still annoying). Hopefully we can come up with a better approach to all this soon...