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]: Show code displays <[object Object]... instead of component name #20920

Closed
konsalex opened this issue Feb 3, 2023 · 24 comments · Fixed by #26566
Closed

[Bug]: Show code displays <[object Object]... instead of component name #20920

konsalex opened this issue Feb 3, 2023 · 24 comments · Fixed by #26566

Comments

@konsalex
Copy link
Contributor

konsalex commented Feb 3, 2023

Describe the bug

Components that are wrapped with forwardRef in react are not displaying the proper name in built Storybook, whole working as expected in development mode. Example of what I mean in the image below.

image

Tried to debug by modifying and logging what is passed here: https://github.com/storybookjs/storybook/blob/next/code/renderers/react/src/docs/jsxDecorator.tsx#L108

image

and indeed the element is different in dev vs prod.

After digging with the help of @IanVS and @JReinhold found out that this might be an issue with react-docgen-typescript and tsconfig.json of the project.

To Reproduce

Visit this link: https://github.com/konsalex/design-system-newline-course/tree/storybook-v7-issue
Clone then:


// Install packages
yarn
yarn workspace @newline-ds/foundation build
yarn workspace @newline-ds/react build

// Build and run
yarn workspace @newline-ds/storybook build-storybook && live-server packages/storybook/storybook-public


### System

```shell
Environment Info:

  System:
    OS: macOS 13.0
    CPU: (10) x64 Apple M1 Max
  Binaries:
    Node: 16.19.0 - ~/Library/Caches/fnm_multishells/44085_1675428690209/bin/node
    Yarn: 3.2.1 - /usr/local/bin/yarn
    npm: 8.19.3 - ~/Library/Caches/fnm_multishells/44085_1675428690209/bin/npm
  Browsers:
    Chrome: 109.0.5414.119
    Firefox: 109.0
    Safari: 16.1

Additional context

No response

@konsalex
Copy link
Contributor Author

konsalex commented Feb 3, 2023

I think that the preserveSymlinks is the root cause in tsconfig.json

@JReinhold
Copy link
Contributor

I'm having issues trying to get the reproduction up and running, when building the Storybook I get

ERR! Error: Failed to resolve entry for package "@newline-ds/foundation". The package may have incorrect main/module/exports specified in its package.json.

I also don't consider this a minimal reproduction. I think you should be able to further reduce the complexity of this reproduction by removing anything regarding the monorepo/multi-package setup to make it laser-focused on the Storybook part. I would be surprised if any of that cross-package importing and linking was related to the actual issue.

@konsalex
Copy link
Contributor Author

konsalex commented Feb 6, 2023

Sorry for the bad reproduction.

The repo had problems indeed and the start scripts I pasted were wrong. Updated the issue description with the new scripts, and the repo to fix some initialisation issues.

Also if it helps here is a Gitpod snapshot where the issue is reproduced properly:
https://gitpod.io#snapshot/e705b55d-3d0f-4996-93e3-89b03fa30b7e

image

I also don't consider this a minimal reproduction. I think you should be able to further reduce the complexity of this reproduction by removing anything regarding the monorepo/multi-package setup to make it laser-focused on the Storybook part.

This is the whole point though @JReinhold , as it's a common practise to host a component library inside a monorepo as a single package and consume it inside another Storybook package or it is not so common? 🤔

@JReinhold
Copy link
Contributor

The repo had problems indeed and the start scripts I pasted were wrong. Updated the issue description with the new scripts, and the repo to fix some initialisation issues.

Thanks, this helped and I got it working.

This is the whole point though @JReinhold , as it's a common practise to host a component library inside a monorepo as a single package and consume it inside another Storybook package or it is not so common? 🤔

I think it's fairly common, but my point was that I'm not sure if it is related to this issue. If you remove ESLint, Prettier, Tailwind, importing from other packages and just have a plain story file with a component next to it, does it still break?

I've tried to debug this and comparing it to our "base" React-Vite example, but I still haven't figured out where things go wrong. It certainly works in some cases.

I think if you can keep removing more stuff from the reproduction until you've gotten so close to the base example that it starts working, then we can figure out what is causing this.

This is the "base" I'm referring to: https://github.com/storybookjs/sandboxes/tree/next/react-vite/default-ts/after-storybook

@konsalex
Copy link
Contributor Author

konsalex commented Feb 7, 2023

@JReinhold a component next to it could not be the case, as we need a cross package import (monorepo).

But I tried to remove everything that is unnecessary as you mentioned, now it's much thinner monorepo with only the necessary packages to work with. This is updated in the GitHub branch here: https://github.com/konsalex/design-system-newline-course/tree/storybook-v7-issue

or if you prefer a sandbox:
https://gitpod.io#snapshot/42ca6b6f-722f-47c5-a907-fcf913c35597

Also tested again if I change the "preserveSymlinks": true to false inside the Storybook's tsconfig.json what would happen, the issue goes away again.

@JReinhold
Copy link
Contributor

Did some more trial and error and I can confirm that "preserveSymlinks": false makes it work. I've also tried to minimize it, by removing the viteFinal, not importing the component from the other package but just defining the component directly in the stories file, but that still had the error.

Interestingly, if you change the component import from import { Button } from '@newline-ds/react/src/Button'; to import { Button } from '../../react/src/Button'; it actually starts working again.

Maybe this is the combination of the tsconfig and yarn workspaces hoisting dependencies that causes this.

I can't look further into this at the moment, so I recommend that you use one of the workarounds for now.

@IanVS
Copy link
Member

IanVS commented Feb 7, 2023

Vite treats source files differently from dependencies, which I'd guess is where this issue is coming from. @joshwooding this might also be something to look into in https://github.com/joshwooding/vite-plugin-react-docgen-typescript

@sriramrudraraju
Copy link

Adding displayName to the component showed me the correct thing in the storybook for me

Button.displayName = "Button"

@mnrendra
Copy link

I also got the same error when I wrapped the component using forwardRef.
When I remove the forwardRef and export the component, then the result is fine (no error like above), ex:

export default ComponentName

but when I use forwardRef to wrap the component, then the result has an error like the above, ex:

export default forwardRef(ComponentName)

@mnrendra
Copy link

Hi, might we get any update on this issue?
We're still facing the same issue with the current version v7.6.17

@mnrendra
Copy link

Adding displayName to the component showed me the correct thing in the storybook for me

Button.displayName = "Button"

Hi @sriramrudraraju how did you implement it? Can you show more by an example? Thank you

@konsalex
Copy link
Contributor Author

As simple as this @mnrendra: https://stackoverflow.com/a/43356103/3247715

const MyComponent = forwardRef(function MyInput(props, ref) {
  return (
    <p>Hello World</p>
  )
})

MyComponent.displayName = "MyComponent"

@hailwood
Copy link

Seems like .displayName is now becoming the cause of <[object Object... in v8.

@shilman
Copy link
Member

shilman commented Mar 12, 2024

@hailwood Please try configuring your Storybook to use the legacy docgen to analyze your components. Does that fix it?

// .storybook/main.js

export default {
  // stories, addons, etc.
  typescript: {
    reactDocgen: 'react-docgen-typescript'
  }
}

@hailwood
Copy link

hailwood commented Mar 12, 2024

Hey @shilman

So things get a little weird... I setup three identical buttons components.
The only differences are

NoForwardRefButton

export const NoForwardRefButton = function (
  { className, variant, size, asChild = false, ...props }: ButtonProps
) {/*...*/};

ForwardRefNoDisplayNameButton

export const ForwardRefNoDisplayNameButton = forwardRef(function (
  { className, variant, size, asChild = false, ...props }: ButtonProps,
  ref: ForwardedRef<HTMLButtonElement>,
) {/*...*/});

ForwardRefWithDisplayNameButton

export const ForwardRefWithDisplayNameButton = forwardRef(function (
  { className, variant, size, asChild = false, ...props }: ButtonProps,
  ref: ForwardedRef<HTMLButtonElement>,
) {/*...*/});

ForwardRefWithDisplayNameButton.displayName = 'MyForwardRefWithDisplayNameButton';

I then ran the build with the default options and then with react-docgen-typescript

react-docgen

NoForwardRefButton
image
ForwardRefNoDisplayNameButton
image
ForwardRefWithDisplayNameButton
image

react-docgen-typescript

NoForwardRefButton
image
ForwardRefNoDisplayNameButton
image
ForwardRefWithDisplayNameButton
image

I just did a stackblitz to check if it's still the case in 8.1 alpha, and it is -
https://stackblitz.com/edit/github-umceda?file=src%2Fstories%2FButton.tsx,.storybook%2Fmain.ts&preset=node

@andrewvo89
Copy link

andrewvo89 commented Mar 13, 2024

Can confirm this is happening on forwarded refs with .displayName set after upgrading to Storybook 8.

@tobeyboe
Copy link

tobeyboe commented Mar 13, 2024

Indeed, having the same issue after upgrading to Storybook 8 from rc.3.
Both with and without reactDocgen: "react-docgen-typescript", using webpack

Replicated with default npx create-next-app@latest and npx storybook@latest init

tested with and without (because docgen still doesnt support forwardRef) :
main.ts

  typescript: {
    reactDocgen: "react-docgen-typescript",
  }

Using Storybook Example Button.tsx

/**
 * Primary UI component for user interaction
 */
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
  (
    { primary = false, size = "medium", backgroundColor, label, ...props },
    ref
  ) => {
    const mode = primary
      ? "storybook-button--primary"
      : "storybook-button--secondary";
    return (
      <button
        ref={ref}
        type="button"
        className={["storybook-button", `storybook-button--${size}`, mode].join(
          " "
        )}
        {...props}
      >
        {label}
        <style jsx>{`
          button {
            background-color: ${backgroundColor};
          }
        `}</style>
      </button>
    );
  }
);

Button.displayName = "Button";

@janith-bl
Copy link

I have the same problem after migrating to 8.
Here is a simple example from storybook.

const meta: Meta<typeof Button> = {
  component: Button,
  //👇 Enables auto-generated documentation for the component story
  tags: ['autodocs'],
};

export default meta;
type Story = StoryObj<typeof Button>;

export const Primary: Story = {
  args: {
    variant: "default",
  },
};

Here it is the auto docs output inside the code section.
<[object Object] variant="default" />

@tobeyboe
Copy link

tobeyboe commented Mar 13, 2024

It also fails using basic Next.js components, like <Image>

Modified Button with children prop:

// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
export const Primary: Story = {
  args: {
    primary: true,
    label: "Button",
    children: (
      <Image
        src="https://via.placeholder.com/100x100"
        alt="Button Image"
        width={100}
        height={100}
      />
    ),
  },
};

Output

<Button
  label="Button"
  onClick={() => {}}
  primary
>
  <[object Object]
    alt="Button Image"
    height={100}
    src="https://via.placeholder.com/100x100"
    width={100}
  />
</Button>

@Astarosa
Copy link

Astarosa commented Mar 14, 2024

It's indeed the displayName that is causing the issue. Removing it works fine but there is obviously a bug or does the V8 implement it with custom Storybook logic based on the imported component name ? I've seen no motion of that in the migration guide.

It should not be the case because we must keep the posibility to add the displayName for devtools DOM support for example in some cases.

@yannbf
Copy link
Member

yannbf commented Mar 19, 2024

Hey everyone! This issue is solved in #26566 and will be released soon. Thanks for your patience 🙏

@Nic-S
Copy link

Nic-S commented Mar 19, 2024

Hey everyone! This issue is solved in #26566 and will be released soon. Thanks for your patience 🙏

In all stories with arguments for controls, as in the example, we still have the problem after the update.

Screenshot 2024-03-19 alle 16 50 53 Screenshot 2024-03-19 alle 16 53 03

@Astarosa
Copy link

Astarosa commented Mar 25, 2024

Hey everyone! This issue is solved in #26566 and will be released soon. Thanks for your patience 🙏

In all stories with arguments for controls, as in the example, we still have the problem after the update.

Screenshot 2024-03-19 alle 16 50 53 Screenshot 2024-03-19 alle 16 53 03

I confirm that we have the same issue using react-docgen-typescript now instead of object object we have the React.FordwardRef but only if you don't declare Button.displayName = 'Button'

Otherwise it works fine.

@drwaky
Copy link

drwaky commented Apr 5, 2024

Hey It was happening to me also at v8.0.0, but I can confirm it is fixed now after updating to v.8.0.5.
Thanks! ♥️

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

Successfully merging a pull request may close this issue.