-
Notifications
You must be signed in to change notification settings - Fork 4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
perf(docs): optimize ComponentProps (#2012)
* perf(docs): optimize ComponentProps * fix(HOC): use PureComponent for pure() HOC * fix(ComponentProps): update `limit` value * feat(ComponentProps): make ComponentProps functional component, move toggleEnums logic down
- Loading branch information
1 parent
3a39d64
commit 598212f
Showing
15 changed files
with
264 additions
and
174 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
180 changes: 26 additions & 154 deletions
180
docs/app/Components/ComponentDoc/ComponentProps/ComponentProps.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,162 +1,34 @@ | ||
import _ from 'lodash' | ||
import PropTypes from 'prop-types' | ||
import React, { Component } from 'react' | ||
import React from 'react' | ||
import { Table } from 'semantic-ui-react' | ||
|
||
import { Icon, Popup, Table } from 'src' | ||
import ComponentPropsEnum from './ComponentPropsEnum' | ||
import ComponentPropsExtra from './ComponentPropsExtra' | ||
|
||
const getTagType = tag => (tag.type.type === 'AllLiteral' ? 'any' : tag.type.name) | ||
import ComponentPropsHeader from './ComponentPropsHeader' | ||
import ComponentPropsRow from './ComponentPropsRow' | ||
|
||
/** | ||
* Displays a table of a Component's PropTypes. | ||
*/ | ||
export default class ComponentProps extends Component { | ||
static propTypes = { | ||
/** | ||
* A single Component's prop info as generated by react-docgen. | ||
* @type {object} Props info object where keys are prop names and values are prop definitions. | ||
*/ | ||
props: PropTypes.object, | ||
/** | ||
* A single Component's meta info. | ||
* @type {object} Meta info object where enum prop values are defined. | ||
*/ | ||
meta: PropTypes.object, | ||
} | ||
|
||
state = { | ||
showEnumsFor: {}, | ||
} | ||
|
||
toggleEnumsFor = prop => () => { | ||
this.setState({ | ||
showEnumsFor: { | ||
...this.state.showEnumsFor, | ||
[prop]: !this.state.showEnumsFor[prop], | ||
}, | ||
}) | ||
} | ||
|
||
renderName = item => <code>{item.name}</code> | ||
|
||
renderRequired = item => item.required && ( | ||
<Popup | ||
position='right center' | ||
style={{ padding: '0.5em' }} | ||
trigger={<Icon size='small' color='red' name='asterisk' />} | ||
content='Required' | ||
size='tiny' | ||
inverted | ||
/> | ||
) | ||
|
||
renderDefaultValue = (item) => { | ||
const defaultValue = _.get(item, 'defaultValue.value') | ||
if (_.isNil(defaultValue)) return null | ||
|
||
return <code>{defaultValue}</code> | ||
} | ||
|
||
renderFunctionSignature = (item) => { | ||
const params = _.filter(item.tags, { title: 'param' }) | ||
const returns = _.find(item.tags, { title: 'returns' }) | ||
|
||
// this doesn't look like a function propType doc block | ||
// don't try to render a signature | ||
if (_.isEmpty(params) && !returns) return | ||
|
||
const paramSignature = params | ||
.map(param => `${param.name}: ${getTagType(param)}`) | ||
// prevent object properties from showing as individual params | ||
.filter(p => !_.includes(p, '.')) | ||
.join(', ') | ||
|
||
const tagDescriptionRows = _.compact([...params, returns]).map((tag) => { | ||
const name = tag.name || tag.title | ||
return ( | ||
<div key={name} style={{ display: 'flex', flexDirection: 'row' }}> | ||
<div style={{ flex: '2 2 0', padding: '0.1em 0' }}> | ||
<code>{name}</code> | ||
</div> | ||
<div style={{ flex: '5 5 0', padding: '0.1em 0' }}> | ||
{tag.description} | ||
</div> | ||
</div> | ||
) | ||
}) | ||
|
||
return ( | ||
<ComponentPropsExtra title={<pre>{item.name}({paramSignature}){returns ? `: ${getTagType(returns)}` : ''}</pre>}> | ||
{tagDescriptionRows} | ||
</ComponentPropsExtra> | ||
) | ||
} | ||
|
||
renderEnums = ({ name, type, value }) => { | ||
const { showEnumsFor } = this.state | ||
|
||
if (type !== '{enum}' || !value) return | ||
return ( | ||
<ComponentPropsEnum | ||
showAll={showEnumsFor[name]} | ||
toggle={this.toggleEnumsFor(name)} | ||
values={value} | ||
/> | ||
) | ||
} | ||
|
||
renderRow = item => ( | ||
<Table.Row key={item.name}> | ||
<Table.Cell collapsing>{this.renderName(item)}{this.renderRequired(item)}</Table.Cell> | ||
<Table.Cell collapsing>{this.renderDefaultValue(item)}</Table.Cell> | ||
<Table.Cell collapsing>{item.type}</Table.Cell> | ||
<Table.Cell> | ||
{item.description && <p>{item.description}</p>} | ||
{this.renderFunctionSignature(item)} | ||
{this.renderEnums(item)} | ||
</Table.Cell> | ||
</Table.Row> | ||
) | ||
|
||
render() { | ||
const { props: propsDefinition } = this.props | ||
|
||
const content = _.sortBy(_.map(propsDefinition, (config, name) => { | ||
const value = _.get(config, 'type.value') | ||
let type = _.get(config, 'type.name') | ||
if (type === 'union') { | ||
type = _.map(value, val => val.name).join('|') | ||
} | ||
type = type && `{${type}}` | ||
|
||
const description = _.get(config, 'docBlock.description', '') | ||
|
||
return { | ||
name, | ||
type, | ||
value, | ||
tags: _.get(config, 'docBlock.tags'), | ||
required: config.required, | ||
defaultValue: config.defaultValue, | ||
description: description && description.split('\n').map(l => ([l, <br key={l} />])), | ||
} | ||
}), 'name') | ||
|
||
return ( | ||
<Table compact='very' basic='very'> | ||
<Table.Header> | ||
<Table.Row> | ||
<Table.HeaderCell>Name</Table.HeaderCell> | ||
<Table.HeaderCell>Default</Table.HeaderCell> | ||
<Table.HeaderCell>Type</Table.HeaderCell> | ||
<Table.HeaderCell>Description</Table.HeaderCell> | ||
</Table.Row> | ||
</Table.Header> | ||
<Table.Body> | ||
{_.map(content, this.renderRow)} | ||
</Table.Body> | ||
</Table> | ||
) | ||
} | ||
const ComponentProps = ({ props: propsDefinition }) => ( | ||
<Table compact='very' basic='very'> | ||
<ComponentPropsHeader /> | ||
<Table.Body> | ||
{_.map(propsDefinition, item => <ComponentPropsRow {...item} key={item.name} />)} | ||
</Table.Body> | ||
</Table> | ||
) | ||
|
||
ComponentProps.propTypes = { | ||
/** | ||
* A single Component's prop info as generated by react-docgen. | ||
* @type {object} Props info object where keys are prop names and values are prop definitions. | ||
*/ | ||
props: PropTypes.object, | ||
/** | ||
* A single Component's meta info. | ||
* @type {object} Meta info object where enum prop values are defined. | ||
*/ | ||
meta: PropTypes.object, | ||
} | ||
|
||
export default ComponentProps |
13 changes: 13 additions & 0 deletions
13
docs/app/Components/ComponentDoc/ComponentProps/ComponentPropsDefaultValue.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import _ from 'lodash' | ||
import PropTypes from 'prop-types' | ||
import React from 'react' | ||
|
||
import { pure } from 'docs/app/HOC' | ||
|
||
const ComponentPropsDefaultValue = ({ value }) => (_.isNil(value) ? null : <code>{value}</code>) | ||
|
||
ComponentPropsDefaultValue.propTypes = { | ||
value: PropTypes.node, | ||
} | ||
|
||
export default pure(ComponentPropsDefaultValue) |
17 changes: 17 additions & 0 deletions
17
docs/app/Components/ComponentDoc/ComponentProps/ComponentPropsDescription.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import _ from 'lodash' | ||
import PropTypes from 'prop-types' | ||
import React from 'react' | ||
|
||
import { pure } from 'docs/app/HOC' | ||
|
||
const ComponentPropsDescription = ({ description }) => (_.isNil(description) ? null : ( | ||
<p> | ||
{_.map(description, line => [line, <br key={line} />])} | ||
</p> | ||
)) | ||
|
||
ComponentPropsDescription.propTypes = { | ||
description: PropTypes.arrayOf(PropTypes.string), | ||
} | ||
|
||
export default pure(ComponentPropsDescription) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
docs/app/Components/ComponentDoc/ComponentProps/ComponentPropsFunctionSignature.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import _ from 'lodash' | ||
import PropTypes from 'prop-types' | ||
import React from 'react' | ||
|
||
import { neverUpdate } from 'docs/app/HOC' | ||
import ComponentPropsExtra from './ComponentPropsExtra' | ||
|
||
const descriptionStyle = { | ||
flex: '5 5 0', | ||
padding: '0.1em 0', | ||
} | ||
|
||
const nameStyle = { | ||
flex: '2 2 0', | ||
padding: '0.1em 0', | ||
} | ||
|
||
const rowStyle = { | ||
display: 'flex', | ||
flexDirection: 'row', | ||
} | ||
|
||
const getTagType = tag => (tag.type.type === 'AllLiteral' ? 'any' : tag.type.name) | ||
|
||
const ComponentPropsFunctionSignature = ({ name, tags }) => { | ||
const params = _.filter(tags, { title: 'param' }) | ||
const returns = _.find(tags, { title: 'returns' }) | ||
|
||
// this doesn't look like a function propType doc block | ||
// don't try to render a signature | ||
if (_.isEmpty(params) && !returns) return null | ||
|
||
const paramSignature = params | ||
.map(param => `${param.name}: ${getTagType(param)}`) | ||
// prevent object properties from showing as individual params | ||
.filter(p => !_.includes(p, '.')) | ||
.join(', ') | ||
|
||
const tagDescriptionRows = _.compact([...params, returns]).map((tag) => { | ||
const title = tag.name || tag.title | ||
return ( | ||
<div key={title} style={rowStyle}> | ||
<div style={nameStyle}> | ||
<code>{title}</code> | ||
</div> | ||
<div style={descriptionStyle}> | ||
{tag.description} | ||
</div> | ||
</div> | ||
) | ||
}) | ||
|
||
return ( | ||
<ComponentPropsExtra title={<pre>{name}({paramSignature}){returns ? `: ${getTagType(returns)}` : ''}</pre>}> | ||
{tagDescriptionRows} | ||
</ComponentPropsExtra> | ||
) | ||
} | ||
|
||
ComponentPropsFunctionSignature.propTypes = { | ||
name: PropTypes.string, | ||
tags: PropTypes.object, | ||
} | ||
|
||
export default neverUpdate(ComponentPropsFunctionSignature) |
17 changes: 17 additions & 0 deletions
17
docs/app/Components/ComponentDoc/ComponentProps/ComponentPropsHeader.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import React from 'react' | ||
import { Table } from 'semantic-ui-react' | ||
|
||
import { neverUpdate } from 'docs/app/HOC' | ||
|
||
const ComponentPropsHeader = () => ( | ||
<Table.Header> | ||
<Table.Row> | ||
<Table.HeaderCell>Name</Table.HeaderCell> | ||
<Table.HeaderCell>Default</Table.HeaderCell> | ||
<Table.HeaderCell>Type</Table.HeaderCell> | ||
<Table.HeaderCell>Description</Table.HeaderCell> | ||
</Table.Row> | ||
</Table.Header> | ||
) | ||
|
||
export default neverUpdate(ComponentPropsHeader) |
30 changes: 30 additions & 0 deletions
30
docs/app/Components/ComponentDoc/ComponentProps/ComponentPropsName.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import PropTypes from 'prop-types' | ||
import React from 'react' | ||
import { Icon, Popup } from 'semantic-ui-react' | ||
|
||
import { pure } from 'docs/app/HOC' | ||
|
||
const popupStyle = { padding: '0.5em' } | ||
|
||
const ComponentPropsName = ({ name, required }) => ( | ||
<div> | ||
<code>{name}</code> | ||
{required && ( | ||
<Popup | ||
content='Required' | ||
inverted | ||
position='right center' | ||
size='tiny' | ||
style={popupStyle} | ||
trigger={<Icon color='red' name='asterisk' size='small' />} | ||
/> | ||
)} | ||
</div> | ||
) | ||
|
||
ComponentPropsName.propTypes = { | ||
name: PropTypes.string, | ||
required: PropTypes.bool, | ||
} | ||
|
||
export default pure(ComponentPropsName) |
Oops, something went wrong.