strothj / react-docgen-typescript-loader

Webpack loader to generate docgen information from Typescript React components.
Other
360 stars 47 forks source link

Docs work with Component, but not FC #74

Closed awdyson closed 4 years ago

awdyson commented 4 years ago

The code below works. However, if I switch to a functional component (commented out) I no longer see a table in Prop Types. Just ran yarn upgradeInteractive --latest on everything. I've also tried a variety of approaches (e.g. using FunctionalComponent instead and glob importing React).

Component:

import { customJsx } from '@monorepo/core';
import { Component } from 'react';

interface Props {
  /**
   * Value to display, either empty (" ") or "X" / "O".
   *
   * @default " "
   **/
  value?: ' ' | 'X' | 'O';
}

// /**
//  * TicTacToe game cell. Displays a clickable button when the value is " ",
//  * otherwise displays "X" or "O".
//  */
// const Test: FC<Props> = ({ value }: Props) => {
//   return <button> ah hh {value}</button>;
// };

/**
 * TicTacToe game cell. Displays a clickable button when the value is " ",
 * otherwise displays "X" or "O".
 */
class Test extends Component<Props> {
  render() {
    return <button> ah hh {this.props.value}</button>;
  }
}

export { Test };

Story:

import { customJsx } from '@monorepo/core';
// import { Test } from '@monorepo/ui_kit';
import { storiesOf } from '@storybook/react';

import { Test } from '../../../../ui_kit/src/components/elements/test';

const stories = storiesOf('Components', module);
stories.add('Test', () => <Test value="X" />, { info: { inline: true } });

Also a bonus question: I'm working in a yarn workspaces monorepo. In the story above, I need to import the .ts files directly to have this library work. Is there a way to make this work using .js and .d.ts files?

awdyson commented 4 years ago

Setting Test.displayName = 'Test'; doesn't help, but hard-coding componentNameResolver to return "Test" does. Trying to figure out if I can get that value dynamically now

awdyson commented 4 years ago

Apparently FunctionComponents use the default export to get the component: https://github.com/styleguidist/react-docgen-typescript/blob/8cff36bb45d4ca8f56ee32a10c6c6580529f0dfd/src/parser.ts#L949

awdyson commented 4 years ago

I'm a bit confused by this all, but if anyone finds this thread, this works: export const Test: FC<Props> = ...

awdyson commented 4 years ago

Regarding the bonus question about JS and declaration files, I added a typescript field to my monorepo library package.json, targeting my Typescript source. Then I set resolve.mainFields to ['typescript', 'module', 'main'] in .storybook/webpack.config.js.

I don't love this solution, so if anyone has suggestions, I'm all ears.

mattrothenberg commented 4 years ago

Weird, I can replicate this one too.

The following does not work.

import * as React from 'react';
export const PrimaryButton: React.FC<Props> = ...

But this does work.

import * as React from 'react';
import { FunctionComponent } from 'react';

export const PrimaryButton: FunctionComponent<Props> = ...

🤔

markrebec commented 4 years ago

From what I've read in a few other issues this seems to be related to the allowSyntheticDefaultImports typescript compiler option. Setting that to true and making sure the loader was pointing to the right config did the trick for me.

Try enabling that option in your typescript config, and make sure you're pointing to the right tsconfig.json for the loader in your storybook webpack config. For example I'm using the following in my .storybook/webpack.config.js to point storybook at the same root tsconfig.json that my project is using:

    test: /\.(ts|tsx)$/,
    use: [
      'babel-loader',
      {
        loader: 'react-docgen-typescript-loader',
        options: {
          tsconfigPath: path.resolve(__dirname, '../tsconfig.json')
        }
      }
    ]
awdyson commented 4 years ago

Closing this as I went a different route with my documentation approach. Can't confirm the solution @markrebec posted above, but some people seem satisfied 👍