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

More detailed props table #1485

Merged
merged 24 commits into from
Sep 6, 2017
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
bc63adf
Detailed formatting of arrayOf, shape, oneOf
billyvg Jul 18, 2017
1d54f15
Add babel watch task
billyvg Jul 18, 2017
aa44f18
Merge branch 'master' into prop-table-detailed
ndelangen Jul 19, 2017
ba35434
Merge branch 'master' into prop-table-detailed
ndelangen Jul 28, 2017
bd7b139
Merge branch 'master' into prop-table-detailed
ndelangen Aug 18, 2017
093dd01
Merge branch 'master' into prop-table-detailed
billyvg Aug 23, 2017
7ce5673
addon info: make propTypes table better
billyvg Aug 23, 2017
2f62f90
Merge branch 'master' into prop-table-detailed
billyvg Aug 23, 2017
eda55b9
Merge branch 'release/3.3' into prop-table-detailed
ndelangen Aug 24, 2017
e5152f5
Merge branch 'release/3.3' into prop-table-detailed
ndelangen Aug 24, 2017
40a229e
cleanup deprecated tests
billyvg Aug 28, 2017
a54f714
cleanup <PrettyPropType>
billyvg Aug 28, 2017
34333bd
add: styled components
billyvg Aug 28, 2017
ff6d332
Merge branch 'release/3.3' into prop-table-detailed
ndelangen Aug 28, 2017
2fdeff5
removed in favor of glamorous component
billyvg Aug 28, 2017
4c1ce1f
Merge branch 'release/3.3' into prop-table-detailed
Hypnosphi Aug 30, 2017
81dae0b
Merge branch 'release/3.3' into prop-table-detailed
ndelangen Aug 30, 2017
738a8c5
Merge branch 'release/3.3' into prop-table-detailed
billyvg Sep 5, 2017
c90b09e
fix: add key for OneOfType
billyvg Sep 5, 2017
691771f
fix: use native buttons
billyvg Sep 5, 2017
05e43d7
Merge branch 'release/3.3' into prop-table-detailed
Hypnosphi Sep 5, 2017
569d3a2
Merge branch 'release/3.3' into prop-table-detailed
ndelangen Sep 6, 2017
e43d49b
ADD an example usage of complex PropType and add descriptions for Con…
ndelangen Sep 6, 2017
f2a9b66
Merge branch 'release/3.3' into prop-table-detailed
ndelangen Sep 6, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 30 additions & 64 deletions addons/info/src/components/PropTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

import PropTypes from 'prop-types';
import React from 'react';

import { Table, Td, Th } from '@storybook/components';
import PropVal from './PropVal';
import PrettyPropType from './types/PrettyPropType';

const PropTypesMap = new Map();

Expand All @@ -13,41 +16,10 @@ Object.keys(PropTypes).forEach(typeName => {
PropTypesMap.set(type.isRequired, typeName);
});

const stylesheet = {
propTable: {
marginLeft: -10,
borderSpacing: '10px 5px',
borderCollapse: 'separate',
},
};

const isNotEmpty = obj => obj && obj.props && Object.keys(obj.props).length > 0;

const renderDocgenPropType = propType => {
if (!propType) {
return 'unknown';
}

const name = propType.name;

switch (name) {
case 'arrayOf':
return `${propType.value.name}[]`;
case 'instanceOf':
return propType.value;
case 'union':
return propType.raw;
case 'signature':
return propType.raw;
default:
return name;
}
};

const hasDocgen = type => isNotEmpty(type.__docgenInfo);

const boolToString = value => (value ? 'yes' : 'no');

const propsFromDocgen = type => {
const props = {};
const docgenInfoProps = type.__docgenInfo.props;
Expand All @@ -59,8 +31,8 @@ const propsFromDocgen = type => {

props[property] = {
property,
propType: renderDocgenPropType(propType),
required: boolToString(docgenInfoProp.required),
propType,
required: docgenInfoProp.required,
description: docgenInfoProp.description,
defaultValue: defaultValueDesc.value,
};
Expand All @@ -75,21 +47,15 @@ const propsFromPropTypes = type => {
if (type.propTypes) {
Object.keys(type.propTypes).forEach(property => {
const typeInfo = type.propTypes[property];
const required = boolToString(typeInfo.isRequired === undefined);
const description =
type.__docgenInfo && type.__docgenInfo.props && type.__docgenInfo.props[property]
? type.__docgenInfo.props[property].description
: null;
const required = typeInfo.isRequired === undefined;
const docgenInfo =
type.__docgenInfo && type.__docgenInfo.props && type.__docgenInfo.props[property];
const description = docgenInfo ? docgenInfo.description : null;
let propType = PropTypesMap.get(typeInfo) || 'other';

if (propType === 'other') {
if (
type.__docgenInfo &&
type.__docgenInfo.props &&
type.__docgenInfo.props[property] &&
type.__docgenInfo.props[property].type
) {
propType = type.__docgenInfo.props[property].type.name;
if (docgenInfo && docgenInfo.type) {
propType = docgenInfo.type.name;
}
}

Expand Down Expand Up @@ -137,40 +103,40 @@ export default function PropTable(props) {
};

return (
<table style={stylesheet.propTable}>
<Table>
<thead>
<tr>
<th>property</th>
<th>propType</th>
<th>required</th>
<th>default</th>
<th>description</th>
<Th bordered>property</Th>
<Th bordered>propType</Th>
<Th bordered>required</Th>
<Th bordered>default</Th>
<Th bordered>description</Th>
</tr>
</thead>
<tbody>
{array.map(row =>
<tr key={row.property}>
<td>
<Td bordered code>
{row.property}
</td>
<td>
{row.propType}
</td>
<td>
{row.required}
</td>
<td>
</Td>
<Td bordered code>
<PrettyPropType propType={row.propType} />
</Td>
<Td bordered>
{row.required ? 'yes' : '-'}
</Td>
<Td bordered>
{row.defaultValue === undefined
? '-'
: <PropVal val={row.defaultValue} {...propValProps} />}
</td>
<td>
</Td>
<Td bordered>
{row.description}
</td>
</Td>
</tr>
)}
</tbody>
</table>
</Table>
);
}

Expand Down
19 changes: 19 additions & 0 deletions addons/info/src/components/types/ArrayOf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';

import PrettyPropType from './PrettyPropType';
import { TypeInfo } from './proptypes';

const ArrayOf = ({ propType }) =>
<span>
<span>[</span>
<span>
<PrettyPropType propType={propType.value} />
</span>
<span>]</span>
</span>;

ArrayOf.propTypes = {
propType: TypeInfo.isRequired,
};

export default ArrayOf;
11 changes: 11 additions & 0 deletions addons/info/src/components/types/Enum.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';
import { TypeInfo } from './proptypes';

const Enum = ({ propType }) =>
<span>
{propType.value.map(({ value }) => value).join(' | ')}
</span>;

Enum.propTypes = {
propType: TypeInfo.isRequired,
};
13 changes: 13 additions & 0 deletions addons/info/src/components/types/InstanceOf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';
import { TypeInfo } from './proptypes';

const InstanceOf = ({ propType }) =>
<span>
{propType.value}
</span>;

InstanceOf.propTypes = {
propType: TypeInfo.isRequired,
};

export default InstanceOf;
8 changes: 8 additions & 0 deletions addons/info/src/components/types/Object.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from 'react';

const ObjectType = () =>
<span>
{'{}'}
</span>;

export default ObjectType;
17 changes: 17 additions & 0 deletions addons/info/src/components/types/ObjectOf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';

import PrettyPropType from './PrettyPropType';
import { TypeInfo } from './proptypes';

const ObjectOf = ({ propType }) =>
<span>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{'{[<key>]: '}
<PrettyPropType propType={propType.value} />
{'}'}
</span>;

ObjectOf.propTypes = {
propType: TypeInfo.isRequired,
};

export default ObjectOf;
8 changes: 8 additions & 0 deletions addons/info/src/components/types/ObjectType.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from 'react';

const ObjectType = () =>
<span>
{'{}'}
</span>;

export default ObjectType;
13 changes: 13 additions & 0 deletions addons/info/src/components/types/OneOf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';
import { TypeInfo } from './proptypes';

const OneOf = ({ propType }) =>
<span>
{propType.value.map(({ value }) => value).join(' | ')}
</span>;

OneOf.propTypes = {
propType: TypeInfo.isRequired,
};

export default OneOf;
22 changes: 22 additions & 0 deletions addons/info/src/components/types/OneOfType.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';

import PrettyPropType from './PrettyPropType';
import { TypeInfo } from './proptypes';

const OneOfType = ({ propType }) => {
const length = propType.value.length;
return (
<span>
{propType.value
.map((value, i) => [
<PrettyPropType propType={value} />,
i < length - 1 ? <span> | </span> : null,
])
.reduce((acc, tuple) => acc.concat(tuple), [])}
</span>
);
};
OneOfType.propTypes = {
propType: TypeInfo.isRequired,
};
export default OneOfType;
61 changes: 61 additions & 0 deletions addons/info/src/components/types/PrettyPropType.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import PropTypes from 'prop-types';
import React from 'react';

import ObjectType from './ObjectType';
import Shape from './Shape';
import OneOfType from './OneOfType';
import ArrayOf from './ArrayOf';
import ObjectOf from './ObjectOf';
import OneOf from './OneOf';
import InstanceOf from './InstanceOf';
import Signature from './Signature';

import { TypeInfo } from './proptypes';

// propType -> Component map - these are a bit more complex prop types to display
const propTypeComponentMap = new Map([
['shape', Shape],
['union', OneOfType],
['arrayOf', ArrayOf],
['objectOf', ObjectOf],
// Might be overkill to have below proptypes as separate components *shrug*
['object', ObjectType],
['enum', OneOf],
['instanceOf', InstanceOf],
['signature', Signature],
]);

const PrettyPropType = props => {
const { propType, depth } = props;
if (!propType) {
return <span>unknown</span>;
}

const { name } = propType || {};

if (propTypeComponentMap.has(name)) {
const Component = propTypeComponentMap.get(name);
return <Component propType={propType} depth={depth} />;
}

// Otherwise, propType does not have a dedicated component, display proptype name by default
return (
<span>
{name}
</span>
);
};

PrettyPropType.displayName = 'PrettyPropType';

PrettyPropType.defaultProps = {
propType: null,
depth: 1,
};

PrettyPropType.propTypes = {
propType: TypeInfo,
depth: PropTypes.number.isRequired,
};

export default PrettyPropType;
31 changes: 31 additions & 0 deletions addons/info/src/components/types/PropertyLabel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import PropTypes from 'prop-types';
import React from 'react';

const styles = {
hasProperty: {
whiteSpace: 'nowrap',
},
};

const PropertyLabel = ({ property, required }) => {
if (!property) return null;

return (
<span style={styles.hasProperty}>
{property}
{required ? '' : '?'}:{' '}
</span>
);
};

PropertyLabel.propTypes = {
property: PropTypes.string,
required: PropTypes.bool,
};

PropertyLabel.defaultProps = {
property: '',
required: false,
};

export default PropertyLabel;
Loading