Storybook: Addon-docs: forwardRef trips up Props block

Created on 19 Nov 2019  路  13Comments  路  Source: storybookjs/storybook

Describe the bug
When implementing a Component in the way described below, the Props block only shows the following text:

"Cannot read property 'appearance' of undefined"

To Reproduce
Declare a component in way mentioned under "Code snippets".

Expected behavior
The Props block should display the corresponding Props.

Screenshots
Screenshot 2019-11-19 at 09 21 10

Code snippets
Button.tsx

type ButtonProps = {
  appearance?: "primary" | "secondary" | "ghost";
} & JSX.IntrinsicElements["button"];

const Button: RefForwardingComponent<HTMLButtonElement, ButtonProps> = React.forwardRef(({ appearance, ...otherProps}, ref) => (
  <button>...</button>
))

Button.displayName = "Button";

Button.defaultProps = {
  appearance: "primary"
};

Button.stories.tsx

import React from "react";
import { storiesOf } from "@storybook/react";
import { Button } from "./Button";

storiesOf("Button", module)
  .addParameters({
    component: Button
  })
  .add("primary", () => (
    <Button appearance="primary">
      My primary button!
    </Button>
  ))
;

System:
Tried out with both Storybook 5.2.5 and Storybook 5.3.0-beta.1, using react-docgen-typescript-loader 3.6.0.

Using stories in the TSX file format but encountered the error also when using the JSX file format.

Component is in TSX format.

Please paste the results of npx -p @storybook/cli@next sb info here.

  System:
    OS: macOS 10.15.1
    CPU: (4) x64 Intel(R) Core(TM) i7-7567U CPU @ 3.50GHz
  Binaries:
    Node: 10.16.0 - ~/.nvm/versions/node/v10.16.0/bin/node
    npm: 6.9.0 - ~/.nvm/versions/node/v10.16.0/bin/npm
  Browsers:
    Chrome: 78.0.3904.97
    Safari: 13.0.3
  npmPackages:
    @storybook/cli: ^5.3.0-beta.1 => 5.3.0-beta.1

Additional context
Props block used to work before introducing RefForwardingComponent and React.forwardRef

Possibly related to #7933, #8445, and #4787.

props bug

Most helpful comment

Got it working 馃憣

All 13 comments

Mirror issue on react-docgen-typescript-loader side: https://github.com/strothj/react-docgen-typescript-loader/issues/76

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!

Any Leads on this, I'm Stuck too

@Zunaib this was fixed for me in Storybook 5.3

Any specific Version like 5.3.0rc ?

Tried it out with one of the late betas (.28 or so) and it still worked with the RC

@Zunaib I believe you need to install https://github.com/atanasster/webpack-react-docgen-typescript

@jonathanherdt - can you please confirm your configuration here.

Got it working 馃憣

Great - can you post your config and we can close this issue.

Okay sure.

Here is my config.js

import { withKnobs } from '@storybook/addon-knobs';
import { addDecorator, addParameters, configure } from '@storybook/react';
import requireContext from 'require-context.macro';
import '../src/styles/airokit.scss';
import airotheme from './airotheme';

addParameters({
  options: {
    theme: airotheme,
    showSearchBox: true,
    sidebarAnimations: true
  },
});

addDecorator(withKnobs);

const loader = () => {

  const allExports = [require('../src/GetStarted/GetStarted.stories.mdx')];
  const req = requireContext('../src/', true, /\.stories\.(tsx|mdx)$/);
  req.keys().forEach(fname => allExports.push(req(fname)));
  return allExports;

}
configure(loader, module);

Here are my presets.js

const path = require("path");

module.exports = [
    {
        name: "@storybook/preset-typescript",
        options: {
            tsDocgenLoaderOptions: {
                tsconfigPath: path.resolve(__dirname, "../tsconfig.json")
            },
            tsLoaderOptions: {
                configFile: path.resolve(__dirname, '../tsconfig.json'),
            },
            include: [path.resolve(__dirname, "../src")]
        }
    },
    {
        name: '@storybook/preset-scss'
    },
    {
        name: '@storybook/addon-docs/preset'
    }
];

Here is a component using ForwardRef

export const Col = forwardRef<HTMLDivElement, ColProps>(function (
  {
    ...props
  },
  ref
) {
  return (
    <div
      {...props}
      ref={ref}
    >
      {children}
    </div>
  );
});

export default Col;

Thanks - closing

Modified: I found forwardRef must write its type similar to FC in functional component, if not, it always broken like below. So I added ForwardRefExoticComponent<ButtonProps> to RefButton, the error disappears. The above example used RefForwardingComponent<HTMLButtonElement, ButtonProps> would cause type error in typescript as I suffered, may not bothering you in storybook but finally blow up in bundling, use ForwardRefExoticComponent to prevent errors with defaultProps.


I have stuck in exact same problem in v5.3.14(latest release).

image

Here's my code:

// refbutton.tsx
import React, { forwardRef } from 'react';

type ButtonProps = {
  hello?: 'primary' | 'secondary' | 'ghost';
} & JSX.IntrinsicElements['button'];


const RefButton = forwardRef<HTMLButtonElement, ButtonProps>(
  ({ hello, ...props }, ref) => (
    <button type="button" ref={ref} {...props}>
      {props.children}
      {hello}
    </button>
  ),
);

RefButton.defaultProps = {
  hello: 'primary',
};

export default RefButton;
// refbutton.stories.tsx
import React from 'react';
import { withKnobs } from '@storybook/addon-knobs';
import { withA11y } from '@storybook/addon-a11y';
import RefButton from './refbutton';


export default {
  title: 'components|buttons/RefButton',
  component: RefButton,
  decorators: [withKnobs, withA11y],
  parameters: {
    info: { inline: true },
    notes: 'test node.',
    componentSubtitle: 'forwardRef example',
  },
};

export const ButtonExample = () => <RefButton>test code</RefButton>;



md5-69ff26abda982d5bf735a52072264c85



    "@storybook/addon-a11y": "^5.3.14",
    "@storybook/addon-actions": "^5.3.14",
    "@storybook/addon-docs": "^5.3.14",
    "@storybook/addon-info": "^5.3.14",
    "@storybook/addon-knobs": "^5.3.14",
    "@storybook/addon-links": "^5.3.14",
    "@storybook/addon-notes": "^5.3.14",
    "@storybook/addons": "^5.3.14",
    "@storybook/react": "^5.3.14",

I tried to change type to interface and extends props, but still happens in forwardRef only.
(FC works gracefully!)
Is there any way to solve this? Please help.~~

Removing react-docgen-typescript-loader and adding babel-plugin-react-docgen worked for me, as documented here: https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#react-prop-tables-with-typescript

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rpersaud picture rpersaud  路  3Comments

zvictor picture zvictor  路  3Comments

shilman picture shilman  路  3Comments

miljan-aleksic picture miljan-aleksic  路  3Comments

purplecones picture purplecones  路  3Comments