Hi,
I have problem with addon-info when I use my component as an external package. There is no problem when I copy the component source into my storybook project, but when call it from node module the PropType and description does not show
My Component source code :
import React from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import BreadcrumbStyled from './style/BreadcrumbStyled';
import OlStyled from './style/OlStyled';
import LiStyled from './style/LiStyled';
class Breadcrumb extends React.Component {
render() {
const {
items, primary, secondary, info, success, danger, warning, rtl
} = this.props;
const elements = [];
for (let i = 0; i < items.length - 1; i += 1) {
elements.push(items[i]);
}
const lastElement = items[items.length - 1];
const themeProps = {
primary, secondary, info, success, danger, warning, rtl
};
return (
<BreadcrumbStyled {...this.props}>
<OlStyled {...themeProps}>
{elements.map((item, index) => {
return (
<LiStyled
key={index}
{...themeProps}
>
<Link
to={item.path
}>
{item.name}
</Link>
</LiStyled>
);
})}
<LiStyled {...themeProps}>{lastElement.name}</LiStyled>
</OlStyled>
</BreadcrumbStyled>
);
}
}
Breadcrumb.propTypes = {
/** array of objects */
items: PropTypes.array.isRequired,
/** rtl is true component show in right side of the window, default is false (from left side). */
rtl: PropTypes.bool,
/** Boolean indicating whether the component renders with Theme.primary color */
primary: PropTypes.bool,
/** Boolean indicating whether the component renders with Theme.secondary color */
secondary: PropTypes.bool,
/** Boolean indicating whether the component renders with Theme.info color */
info: PropTypes.bool,
/** Boolean indicating whether the component renders with Theme.warning color */
warning: PropTypes.bool,
/** Boolean indicating whether the component renders with Theme.danger color */
danger: PropTypes.bool,
/** Boolean indicating whether the component renders with Theme.success color */
success: PropTypes.bool,
/** The inline-styles for the root element. */
style: PropTypes.object,
/** The className for the root element. */
className: PropTypes.string,
/** The color renders with Theme.foreColor . */
foreColor: PropTypes.string
};
Breadcrumb.defaultProps = {
rtl: false,
primary: false,
secondary: false,
info: false,
warning: false,
danger: false,
success: false,
style: {},
className: '',
foreColor: ''
};
export default Breadcrumb;
I tried both compiling and installing from npm and linking to source code in github, there was no different.
Same thing is happening to me, looks like it's because in the PrettyPropType
component...
https://github.com/storybooks/storybook/blob/master/addons/info/src/components/types/PrettyPropType.js#L34
The propType
prop can be an object or a string and that prop is always destructured above. I will make a PR to fix this.
Sorry actually the root cause of the issue looks to be related to..
https://github.com/storybooks/babel-plugin-react-docgen/issues/33
I had trouble with getting this to work while using Typescript :-) Even though it is fairly easy to use Typescript with storybook it seams to break addon-info's propTypes and description. However, defaultProps and property still works :-)
Any updates on this. I'm also facing this problem. :(
In my case the issue is only for stateless functional components defined as a regular function declaration, example...
import React, { PropTypes } from 'react'
const Child = () => (
<div>Sample</div>
)
function FuncDeclaration({ children }) {
return (
<div>
{children}
<Child />
</div>
)
}
FuncDeclaration.propTypes = {
children: PropTypes.node
}
export default FuncDeclaration
The issue has to do with babel-plugin-react-docgen. I created a PR in the babel-plugin-react-docgen repo to address my issue in particular...
https://github.com/storybooks/babel-plugin-react-docgen/pull/41/files
The issue for me is the method of import. It seems that destructuring the import is causing propType and Description table headers to go missing.
This does not work:
import {Input} from '../lib/elements/Forms';
This does:
import Input from '../lib/elements/form/Input';
I'm having this problem with components that use CSS-Modules :confused: (more specifically React CSS-Modules)
@kgwebsites That didn't solve my problem
Hi, I'm seeing a similar issue, and I've narrowed it down to a case where I have multiple exports
Given this:
import React from 'react';
import PropTypes from 'prop-types';
class Test extends React.PureComponent {
render() {
return <button>test</button>;
}
}
Test.propTypes = {
/** Some description here */
randomProp: PropTypes.string
};
export default Test;
export const Test2 = () => <div>Hi</div>;
The description will not show up for randomProp
. HOWEVER, if I comment out the last line, as such:
// export const Test2 = () => <div>Hi</div>;
Then the description for randomProp
will show up. This is even if my Story does not import Test2
at all.
I don't know if there are other situations where descriptions won't show up, but the scenario I described above is definitely reproducible.
Incidentally, a use case for my code having a default export as well as other exports is to have a Redux-connected component as well as its unconnected component available for testing.
Another curious case.
Docgen works for this:
import React from 'react';
import PropTypes from 'prop-types';
const Test = () => <button>A button</button>;
Test.propTypes = {
/** Another label */
randomProp: PropTypes.string
};
export default Test;
But this doesn't:
import React from 'react';
import PropTypes from 'prop-types';
export const Test = () => <button>A button</button>;
Test.propTypes = {
/** Another label */
randomProp: PropTypes.string
};
Of course, in the storybook, I'm using import Test from 'Test';
in the first scenario and import { Test } from 'Test';
in the second.
I use my component as an external package
@AhmadBehzadi You probably need to remove this package from babel-loader exclude
, so that docgen plugin gets applied to it. Alternatively, you can include babel-plugin-react-docgen
in babel config for the component package
@denchen can you please open a separate issue? Looks like you are not importing your component as an external package, are you?
I'm experiencing this issue as well. It looks in the prop table my propType is coming in as a string, but PrettyPropType is trying to destructure it into {name}.
@Hypnosphi I opened a new issue at #3059. My component is not an external package.
I had a similar issue: propTypes and descriptions appear if I use a functional component, but doesn't work if I use a class component (only properties names are displayed).
I'm having the same issue.
This is my current setup that already fails.
Do not however that the defaultProps and isRequired are getting picked up, so no idea what I'm doing wrong.
import React from 'react';
import PropTypes from 'prop-types';
const Test = ({ name }) => {
return <div>Hello {name}</div>;
};
Test.propTypes = {
/** This should be the description */
name: PropTypes.string.isRequired,
};
Test.defaultProps = {
name: 'mars',
};
export default Test;
import React from 'react';
import { storiesOf } from '@storybook/react';
import Test from 'Framework/Test';
import '../assets/stylesheets/kayzrfont.css';
import { withInfo } from '@storybook/addon-info';
storiesOf('Test', module).add(
'Default',
withInfo(`
description or documentation about my component, supports markdown
~~~js
<Button>Click Here</Button>
~~~
`)(() => <Test name="world" />),
);
If you need any more info @Hypnosphi, don't hesitate to ping me!
Well if you put .isRequired on a PropType, you cannot declare a defaultProp
On Mar 12, 2018, at 8:26 AM, Jasper Dansercoer notifications@github.com wrote:
I'm having the same issue.
This is my current setup that already fails.
Do not however that the defaultProps and isRequired are getting picked up, so no idea what I'm doing wrong.
Test Component
import React from 'react';
import PropTypes from 'prop-types';const Test = ({ name }) => {
returnHello {name};
};Test.propTypes = {
/** This should be the description */
name: PropTypes.string.isRequired,
};Test.defaultProps = {
name: 'mars',
};export default Test;
Index.jsimport React from 'react';
import { storiesOf } from '@storybook/react';
import Test from 'Framework/Test';
import '../assets/stylesheets/kayzrfont.css';
import { withInfo } from '@storybook/addon-info';storiesOf('Test', module).add(
'Default',
withInfo(`
description or documentation about my component, supports markdown~~~js <Button>Click Here</Button> ~~~ `)(() => <Test name="world" />),
);
Storybook outputIf you need any more info @Hypnosphi, don't hesitate to ping me!
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
@kgwebsites I know, but it was just to illustrate the point that those settings do work. If I only declare one of them, the propType and description column still won't work.
I'm facing this problem too!
I think I am facing the same issue. I am not using defaultProps in my components, and some of set correctly the propTable in the info section, but with others I cant see the description neither the proptype :/
Trying to find some behaviour..
thanks!
EDIT: ok, found something strange.
As I am using redux, some of my components have
export ComponenName
export default connect(null, null)(ComponentName)
When this happens, the proptypes arent show correctly. If I delete the default export, it will work.
We do not support multiple exports within the same file with Info documentation at the moment. It's a limitation with our babel plugin and the way react-docgen
works.
https://github.com/storybooks/babel-plugin-react-docgen/pull/46
Thanks for your response. What i am doing now is generating the .__docgen manually.
I remove the default export, add a console.log(JSON.Stringify(myComponent.__docgeninfo)) in the storybook and then copy this log, and add It again as myComponent.__docgeninfo = JSON.parse(logText).
Then I add again the default export to the original component file.
It's a bit weird but it works :)
Edit: Just to clarify for future readers. Here is my workarround:
stories.add(
'default',
withInfo({
text: `
<div>
<h2>My component description with nice html</h2>
<p>
A description
</p>
</div>
`,
})(() => {
console.log(JSON.stringify(MyComponent.__docgenInfo))
return <MyComponent/>
})
)
stories.add(
'default',
withInfo({
text: `
<div>
<h2>My component description with nice html</h2>
<p>
A description
</p>
</div>
`,
})(() => {
if (!MyComponent.__docgenInfo) {
MyComponent.__docgenInfo = THE_JSON_PARSED_OUTPUT
}
return <MyComponent/>
})
)
Obviously this is not automated, but for that of us that have tests and also redux connected components, it's a way of having the proptypes in the storybook. The if clause remains because maybe in the future the babel-plugin-react-docgen could export proptypes from Components with 2 exports.
If you change the component, you will have to modify the storybook also at the same time. But it will be a minor change.
Hope this could help somebody.
Thanks again
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!
No, this is everything but stale. The real issue wasn't answered in @danielduan's reply.
Please try it with 3.4.1
AFAIK there were some huge fixes in that field
Still nothing.
Still fails with this component.
import React from 'react';
import PropTypes from 'prop-types';
const Test = ({ name }) => {
return <div>Hello {name}</div>;
};
Test.propTypes = {
/** This should be the description */
name: PropTypes.string.isRequired,
};
Test.defaultProps = {
name: 'mars',
};
export default Test;
EDIT: Again, the combination of defaultProps
and isRequired
is purely to demonstrate that they both work. Removing one of those, still doesn't make the description
or propType
show up.
I also have the same issue. So the problem is actual.
☝️ also have this issue
Can you guys create new issues in the babel plugin repo with some examples of components that don't get detected? https://github.com/storybooks/babel-plugin-react-docgen
There are many different variants as to how people compose and export stateless components, and it's hard to track every single case. This is compounded by the fact that Facebook's react-docgen
uses a different AST walker than Babel so we can't directly use their walkers.
As a bonus, I would love PRs to that repository to fix individual issues. It's pretty time consuming to test each individual case and I'm always looking for more help. Thanks!
As a temporary workaround, you can define your own info by using Component.__docgenInfo = {}
. Take a look at the format react-docgen
generates.
I fixed this by 'extending' the PropTable
component from storybook/addon-info.
import React from 'react';
import PropTable from '@storybook/addon-info/dist/components/PropTable';
const PropTypesTable = ({ propDefinitions, ...props }) => {
propDefinitions.forEach((def) => {
if (typeof def.propType === 'string') {
def.propType = { name: def.propType };
}
});
return <PropTable propDefinitions={propDefinitions} {...props} />;
};
export default PropTypesTable;
Then override the TableComponent in storybook/config.js
import { setDefaults } from '@storybook/addon-info';
setDefaults({
TableComponent: PropTypesTable, // Override the component used to render the props table
});
@mcissel Nice! That works, thank you!
It started working properly for me when I installed:
Niecnasowa, worked for me, thanks :)
Maybe when your package resides in node_modules
or outside project directory then weback treats those files on import as production builds which results in omitting comments and propTypes ?
My solution was to make symlink to my module (which was outside project directory) and then import components from that directory.
This approach requires disabling symlinks in webpack resolver config:
const path = require("path");
module.exports = (storybookBaseConfig, configType, defaultConfig) => {
defaultConfig.resolve.symlinks = false;
return defaultConfig;
};
With this configuration my module written in ES6 syntax is fully parseable by webpack, propTypes and descriptions are visible in storybook and app is reloaded on every file change in module directory.
It seems I as well have this issue. I have it with pure components and higher order functions. Hopefully some resolution will be found in future versions of the addon.
Edit: it appears that my problem is caused by the fact that my component is not directly returning jsx but instead returning a function call which then returns the jsx.
So this doesn't work (not tested pseudo component)
function myComponent({firstProp, secondProp}) {
return functionCall(firstProp, secondProp);
};
function functionCall(firstProp, secondProp) {
return <div>{firstProp} {secondProp}</div>;
}
````
But this works
function myComponent({firstProp, secondProp}) {
return
In many cases the first one is the desired use case and in any case storybook should not define how code is structured in a project.
op's example is added to https://github.com/storybooks/babel-plugin-react-docgen/pull/54 and fixed
@danielduan I see this issue is closed, has it been released in version 3.4.10?
I am still seeing the problem in both 3.4.8 and 3.4.10. I have not yet tried any of the 4.x betas.
@niecnasowa your solution worked for me.
Still had this issue even with the latest versions (see list below). @niecnasowa's solution worked for me - I simply added babel-plugin-react-docgen (add to .babelrc "plugins": ["react-docgen"])
without having to add react-docgen
Package Version info:
"@storybook/addon-actions": "^4.1.2",
"@storybook/addon-centered": "^4.1.2",
"@storybook/addon-info": "^4.1.2",
"@storybook/addon-knobs": "^4.1.2",
"@storybook/addon-links": "^4.1.2",
"@storybook/addon-options": "^4.1.2",
"@storybook/addons": "^4.1.2",
"@storybook/cli": "^4.1.2",
"@storybook/react": "^4.1.2",
Code example that was failing:
export default class SomeComponent extends PureComponent {
static propTypes = {
/** Test comment. */
foo: PropTypes.string
};
}
@niecnasowa Worked for me. 👍 Note that if you have more plugins in .babelrc
the "react-docgen" must be first.
It still does not work for me with docgen
It still does not work for me with docgen @niecnasowa
This does not work for me @niecnasowa
{
"presets": [
"@babel/preset-react",
["@babel/preset-env", { "useBuiltIns": "entry", "corejs": 3 }]
],
"plugins": [
"react-docgen",
"@babel/plugin-proposal-class-properties",
"babel-plugin-module-resolver"
]
}
In my case, I currently added the storybook to main project. My solution is extends a custom webpack config file inside storybook folder and replace jsx rules with this code and its work.
const path = require('path');
const webpack = require('webpack');
const custom = require('../webpack.config.js');
module.exports = ({ config, mode }) => {
const rules = custom.module.rules.filter(rule => rule.loader === 'babel-loader')
return {
...config,
module: {
...config.module,
rules: [
...rules ,
{
test: /\.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
cacheDirectory: true,
presets: ['@babel/preset-react'],
plugins: ["babel-plugin-react-docgen"]
},
},
]
},
};
};
Addon-info
is being superceded by addon-docs
, which fixes a bunch of bugs and is easier to maintain. Please give it a try! https://medium.com/storybookjs/storybook-docspage-e185bc3622bf
We had this problem as well on components that had JSS. Because of the JSS wrapper, the columns for propType and description were empty. By exporting the 'raw' component and use that in the story, the problem was solved.
Addon-info
is being superceded by addon-docs
, which fixes a bunch of bugs and is easier to maintain. Please give it a try! https://medium.com/storybookjs/storybook-docspage-e185bc3622bf
Most helpful comment
It started working properly for me when I installed: