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

Prop types not being inferred correctly when using imported values #580

Closed
sebastienbarre opened this issue Apr 5, 2022 · 0 comments · Fixed by #769
Closed

Prop types not being inferred correctly when using imported values #580

sebastienbarre opened this issue Apr 5, 2022 · 0 comments · Fixed by #769
Labels

Comments

@sebastienbarre
Copy link

sebastienbarre commented Apr 5, 2022

Hi.

Per @danez suggestion in Create / use react-docgen vite plugin to show docsPage info by IanVS · Pull Request #299 · storybookjs/builder-vite, I'm opening a similar issue here.

TL;DR: PropTypes.oneOf(Object.values(foo)) does not seem to work when foo is an object containing values imported from an separate file.

I created a repo that show this behavior in Storybook (clone, npm install then npm run storybook): sebastienbarre-forks/storybook-builder-vite-react-docgen-repro

The example was lifted from storybookjs/builder-vite: Getting started with Vite and Storybook (on a new project) using build-vite README:

npm create vite@latest # follow the prompts
npx sb init --builder @storybook/builder-vite && npm run storybook

I slightly updated Button.jsx to use an object for the constants (this commit):

const sizes = {
  SMALL: "small",
  MEDIUM: "medium",
  LARGE: "large",
};

...

Button.propTypes = {
  size: PropTypes.oneOf(Object.values(sizes)),
};

...

Button.defaultProps = {
  size: sizes.MEDIUM,
};

This actually is already handled properly by react-docgen:

image

What doesn't quite work is when the constants are in a separate file. The rationale for doing this is that many of our components take props like size, shape, theme, or shade and we want the values for these props to be consistent. However, not ALL of our components support all sizes for example. In other words, we want the values of size to be consistent across all our components, but each component may support only a subset of them. Same for shapes, or shades, etc.

It looks like this (this commit):

In Size.js:

export const Size = {
  EXTRA_SMALL: "extra_small",
  SMALL: "small",
  MEDIUM: "medium",
  LARGE: "large",
  EXTRA_LARGE: "extra_large",
};

and the only change to Button is to use a subset of these sizes:

import { Size } from "./Size.js";

const sizes = {
  SMALL: Size.SMALL,
  MEDIUM: Size.MEDIUM,
  LARGE: Size.LARGE,
};

Here is what it looks like now in Storybook (notice the null):

image

Here is what it seems react-docgen generates:

Button.__docgenInfo = {
  "description": "Primary UI component for user interaction",
  "methods": [],
  "displayName": "Button",
  "props": {
    /// ...
    "size": {
      "defaultValue": {
        "value": '"medium"',
        "computed": false
      },
      "type": {
        "name": "enum",
        "value": [{
          "value": "null",
          "computed": false
        }, {
          "value": "null",
          "computed": false
        }, {
          "value": "null",
          "computed": false
        }]
      },
      "required": false,
      "description": "How large should the button be?"
    },
    /// ...
  }
};

Thank you.

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

Successfully merging a pull request may close this issue.

2 participants