Skip to content
This repository was archived by the owner on Jan 5, 2023. It is now read-only.

Commit ff91b9b

Browse files
authored
Merge pull request #61 from nekitk/typescript-docgen-support
feat: support for react-docgen-typescript-loader
2 parents 6fcff43 + 3831dee commit ff91b9b

13 files changed

+286
-88
lines changed

.storybook/webpack.config.js

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
11
const path = require('path')
22

3-
module.exports = {
4-
module: {
5-
rules: [
3+
module.exports = async ({ config }) => {
4+
config.module.rules.push({
5+
test: /\.(ts|tsx)$/,
6+
use: [
67
{
7-
test: /\.(css)$/,
8-
loaders: ['style-loader', 'css-loader'],
9-
include: path.resolve(__dirname, '../')
8+
loader: 'react-docgen-typescript-loader',
9+
options: {
10+
shouldExtractLiteralValuesFromEnum: true,
11+
},
12+
},
13+
{
14+
loader: 'ts-loader',
15+
options: {
16+
transpileOnly: true,
17+
},
1018
}
11-
]
12-
}
13-
}
19+
],
20+
});
21+
22+
config.resolve.extensions.push('.ts', '.tsx');
23+
24+
return config;
25+
};

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Smart knobs addon for Storybook
22

3-
This Storybook plugin uses `@storybook/addon-knobs` but creates the knobs automatically based on PropTypes and Flow.
3+
This Storybook plugin uses `@storybook/addon-knobs` but creates the knobs automatically based on PropTypes, Flow and Typescript.
44

55
## Installation:
66

@@ -11,7 +11,8 @@ npm i storybook-addon-smart-knobs --save-dev
1111
## Usage:
1212

1313
```js
14-
import React, { PropTypes } from 'react'
14+
import React from 'react'
15+
import PropTypes from 'prop-types'
1516
import { storiesOf } from '@storybook/react'
1617
import { withKnobs } from '@storybook/addon-knobs'
1718
import { withSmartKnobs } from 'storybook-addon-smart-knobs'
@@ -65,3 +66,7 @@ module.exports = (baseConfig, env, defaultConfig) => {
6566
return defaultConfig
6667
}
6768
```
69+
70+
## Typescript:
71+
72+
Use [react-docgen-typescript-loader](https://github.com/strothj/react-docgen-typescript-loader) to generate docgen info from Typescript types. This docgen info will be used to automatically create knobs.
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.SmartKnobedComponent {
1+
.PropTable {
22
border: 1px solid #999;
33
color: #333;
44
font-family: monospace;
@@ -7,17 +7,17 @@
77
text-align: left;
88
}
99

10-
.SmartKnobedComponent thead {
10+
.PropTable thead {
1111
font-style: italic;
1212
font-size: 0.85em;
1313
}
1414

15-
.SmartKnobedComponent th {
15+
.PropTable th {
1616
background-color: #eee;
1717
}
1818

19-
.SmartKnobedComponent th,
20-
.SmartKnobedComponent td {
19+
.PropTable th,
20+
.PropTable td {
2121
border: 0.05em solid #999;
2222
min-width: 1em;
2323
padding: 0.4em;

example/stories/PropTable.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import React from 'react'
2+
import PropTypes from 'prop-types'
3+
4+
import './PropTable.css'
5+
6+
export const PropTable = ({ docgenInfo, ...props }) => (
7+
<table className='PropTable'>
8+
<thead>
9+
<tr>
10+
<th>Property</th>
11+
<th>PropType</th>
12+
<th>Value</th>
13+
<th>typeof</th>
14+
</tr>
15+
</thead>
16+
<tbody>{
17+
Object.keys(props)
18+
.map(prop => (
19+
<tr key={ prop }>
20+
<th>{ prop }</th>
21+
<td>{ (docgenInfo.props[prop].type || docgenInfo.props[prop].flowType || {}).name }</td>
22+
<td>{ typeof props[prop] === 'function' ? <i>function</i> : JSON.stringify(props[prop]) || '(empty)' }</td>
23+
<td>{ typeof props[prop] }</td>
24+
</tr>
25+
))
26+
}</tbody>
27+
</table>
28+
)
29+
30+
PropTable.propTypes = {
31+
docgenInfo: PropTypes.object.isRequired
32+
}

example/stories/SmartKnobedComponent.js

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,9 @@
11
import React from 'react'
22
import PropTypes from 'prop-types'
33

4-
import './SmartKnobedComponent.css'
4+
import { PropTable } from './PropTable'
55

6-
const SmartKnobedComponent = props => (
7-
<table className='SmartKnobedComponent'>
8-
<thead>
9-
<tr>
10-
<th>Property</th>
11-
<th>PropType</th>
12-
<th>Value</th>
13-
<th>typeof</th>
14-
</tr>
15-
</thead>
16-
<tbody>
17-
{Object.keys(props).map(prop => (
18-
<tr key={ prop }>
19-
<th>{ prop }</th>
20-
<td>{ SmartKnobedComponent.__docgenInfo.props[prop].type.name }</td>
21-
<td>{ typeof props[prop] === 'function' ? <i>function</i> : JSON.stringify(props[prop]) || '(empty)' }</td>
22-
<td>{ typeof props[prop] }</td>
23-
</tr>
24-
))}
25-
</tbody>
26-
</table>
27-
)
6+
const SmartKnobedComponent = props => <PropTable { ...props } docgenInfo={ SmartKnobedComponent.__docgenInfo } />
287

298
SmartKnobedComponent.propTypes = {
309
bool: PropTypes.bool,

example/stories/SmartKnobedComponentMissingProps.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
import React from 'react'
33
import PropTypes from 'prop-types'
44

5+
import { PropTable } from './PropTable'
6+
57
const SmartKnobedComponentMissingProps = ({
68
foo = '',
79
bar = 'bar',
810
}) => (
911
<code>
1012
<p>You should see a console.warn about a prop with default value bar.</p>
11-
<p>{foo}</p>
12-
<p>{bar}</p>
13+
<PropTable foo={ foo } bar={ bar } docgenInfo={ SmartKnobedComponentMissingProps.__docgenInfo } />
1314
</code>
1415
)
1516

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// @flow
22
import React from 'react'
3-
import './SmartKnobedComponent.css'
3+
4+
import { PropTable } from './PropTable'
45

56
/* eslint-disable */
67
type PropType = {
@@ -13,27 +14,6 @@ type PropType = {
1314
}
1415
/* eslint-enable */
1516

16-
const SmartKnobedComponent = (props: PropType) => (
17-
<table className='SmartKnobedComponent'>
18-
<thead>
19-
<tr>
20-
<th>Property</th>
21-
<th>PropType</th>
22-
<th>Value</th>
23-
<th>typeof</th>
24-
</tr>
25-
</thead>
26-
<tbody>
27-
{Object.keys(props).map(prop => (
28-
<tr key={ prop }>
29-
<th>{ prop }</th>
30-
<td>{ SmartKnobedComponent.__docgenInfo.props[prop].flowType.name }</td>
31-
<td>{ typeof props[prop] === 'function' ? <i>function</i> : JSON.stringify(props[prop]) || '(empty)' }</td>
32-
<td>{ typeof props[prop] }</td>
33-
</tr>
34-
))}
35-
</tbody>
36-
</table>
37-
)
17+
const SmartKnobedComponent = (props: PropType) => <PropTable { ...props } docgenInfo={ SmartKnobedComponent.__docgenInfo } />
3818

3919
export default SmartKnobedComponent
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import * as React from 'react'
2+
3+
import {PropTable} from './PropTable'
4+
5+
interface IProps {
6+
bool: boolean;
7+
number: number;
8+
string: string;
9+
func: () => void;
10+
object: {};
11+
node: React.ReactNode;
12+
oneOf?: 'one' | 'two' | 'three';
13+
}
14+
15+
export const SmartKnobedComponentWithTypescript: React.FC<IProps> & { __docgenInfo?: any } = (props) =>
16+
<PropTable {...props} docgenInfo={SmartKnobedComponentWithTypescript.__docgenInfo} />

example/stories/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { withInfo } from '@storybook/addon-info'
77
import SmartKnobedComponent from './SmartKnobedComponent'
88
import SmartKnobedComponentMissingProps from './SmartKnobedComponentMissingProps'
99
import SmartKnobedComponentWithFlow from './SmartKnobedComponentWithFlow'
10+
import { SmartKnobedComponentWithTypescript } from './SmartKnobedComponentWithTypescript'
1011

1112
const stub = fn => fn()
1213

@@ -15,6 +16,7 @@ storiesOf('Basic', module)
1516
.addDecorator(withKnobs)
1617
.add('proptypes', () => <SmartKnobedComponent />)
1718
.add('flow', () => <SmartKnobedComponentWithFlow />)
19+
.add('typescript', () => <SmartKnobedComponentWithTypescript />)
1820
.add('nested example', () => (
1921
<div>
2022
<h1>Title</h1>

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"@storybook/addon-options": "^5.0.0",
2929
"@storybook/client-logger": "^5.0.0",
3030
"@storybook/react": "^5.0.0",
31+
"@types/react": "^16.9.1",
3132
"babel-loader": "^8.0.4",
3233
"core-js": "^3.0.1",
3334
"css-loader": "^3.1.0",
@@ -36,8 +37,11 @@
3637
"jest": "^24.7.1",
3738
"prop-types": "^15.7.2",
3839
"react": "^16.8.6",
40+
"react-docgen-typescript-loader": "^3.2.0",
3941
"react-dom": "^16.8.6",
40-
"rimraf": "^2.6.3"
42+
"rimraf": "^2.6.3",
43+
"ts-loader": "^6.0.4",
44+
"typescript": "^3.5.3"
4145
},
4246
"peerDependencies": {
4347
"@storybook/addon-knobs": "^5.0.0",

0 commit comments

Comments
 (0)