Skip to content

Commit

Permalink
Merge pull request #105 from newrelic/jerel/advanced-props
Browse files Browse the repository at this point in the history
Advanced prop type definitions
  • Loading branch information
jerelmiller authored Jun 9, 2020
2 parents b06c79f + 2e4b9d9 commit d01b3df
Show file tree
Hide file tree
Showing 12 changed files with 1,041 additions and 206 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ module.exports = {
vars: 'all',
varsIgnorePattern: '^_',
args: 'after-used',
argsIgnorePattern: '^_',
ignoreRestSiblings: false,
},
],
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"@mdx-js/mdx": "^1.6.4",
"@mdx-js/react": "^1.6.4",
"classnames": "^2.2.6",
"date-fns": "^2.14.0",
"gatsby": "^2.20.25",
"gatsby-image": "^2.3.4",
"gatsby-plugin-google-tagmanager": "^2.3.3",
Expand Down
21 changes: 14 additions & 7 deletions src/components/FunctionDefinition.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import React from 'react';
import React, { Children } from 'react';
import PropTypes from 'prop-types';
import Markdown from 'react-markdown';
import styles from './FunctionDefinition.module.scss';

const ParamDescription = ({ children, ...props }) => (
<span {...props} className={styles.paramDescription}>
{'//'} {children}
</span>
);
const ParamDescription = ({ children, ...props }) => {
if (Children.toArray(children).length === 0) {
return null;
}

return (
<span {...props} className={styles.paramDescription}>
{' //'} {children}
</span>
);
};

ParamDescription.propTypes = {
children: PropTypes.node,
Expand All @@ -24,7 +30,8 @@ const FunctionDefinition = ({ params, returnValue }) => {
<span className={styles.paramName}>
{param.type.startsWith('...') ? `...${param.name}` : param.name}:{' '}
</span>
<span className={styles.type}>{param.type} </span>
<span className={styles.type}>{param.type}</span>
{i !== params.length - 1 && ', '}
<Markdown
source={param.description}
renderers={{
Expand Down
7 changes: 2 additions & 5 deletions src/components/FunctionDefinition.module.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.container {
font-family: 'Menlo', 'Consolas', monospace;
font-family: var(--code-font);
font-size: 0.875rem;
line-height: 1.5;
}
Expand All @@ -9,11 +9,8 @@
}

.param {
margin-left: 1rem;
}

.paramName {
color: var(--color-neutrals-700);
margin-left: 1rem;
}

.paramDescription {
Expand Down
115 changes: 107 additions & 8 deletions src/components/PropList.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,70 @@
import React from 'react';
import cx from 'classnames';
import PropTypes from 'prop-types';
import ReactMarkdown from 'react-markdown';
import FunctionDefinition from './FunctionDefinition';
import Markdown from 'react-markdown';
import ReferenceExample from './ReferenceExample';
import styles from './PropList.module.scss';
import { format } from 'date-fns';

const PropTypeInfo = ({ type }) => {
switch (type.raw) {
case 'func':
return (
<FunctionDefinition
returnValue={type.meta.returnValue}
params={type.meta.params}
/>
);
case 'arrayOf': {
const { itemTypes } = type.meta;

return itemTypes.raw === 'oneOf' ? (
<div className={styles.listLike}>
<div>{'<Array of'}</div>
<div className={styles.arg}>
<PropTypeInfo type={itemTypes} />
</div>
<div>{'>'}</div>
</div>
) : (
<PropTypeInfo type={itemTypes} />
);
}
case 'oneOf':
return (
<div className={styles.listLike}>
<div>{'<One of'}</div>
<div className={styles.arg}>
{type.meta.constants.map((constant) => (
<div key={constant}>{constant},</div>
))}
</div>
<div>{'>'}</div>
</div>
);
case 'oneOfType':
return type.meta.types.map((type, idx) => (
<PropTypeInfo key={idx} type={type} />
));
case 'shape':
return (
<div className={styles.shape}>
<h4>shape</h4>
<PropList propTypes={type.meta.types} />
</div>
);
default:
return null;
}
};

PropTypeInfo.propTypes = {
type: PropTypes.shape({
raw: PropTypes.string.isRequired,
meta: PropTypes.object,
}),
};

const PropList = ({ propTypes }) => {
if (propTypes.length === 0) {
Expand All @@ -11,26 +74,55 @@ const PropList = ({ propTypes }) => {
return (
<div>
{propTypes.map(
({ name, description, isRequired, type, defaultValue }) => {
({
name,
description,
deprecation,
examples,
isRequired,
type,
defaultValue,
}) => {
return (
<div key={name} className={styles.container}>
<div className={styles.info}>
<h3>
{name}{' '}
{name}
{isRequired && (
<span className={styles.required}>required</span>
<span className={styles.flagged}>required</span>
)}
{deprecation && (
<span className={styles.flagged}>deprecated</span>
)}
</h3>
<div className={styles.type}>{type}</div>
<div className={styles.type}>{type.name}</div>
{defaultValue !== undefined && (
<div className={styles.default}>
<p>DEFAULT</p>
<p>{String(defaultValue)}</p>
</div>
)}
</div>
<div className={styles.details}>
<ReactMarkdown source={description} />
<div className={styles.propInfo}>
{deprecation && (
<div className={styles.deprecation}>
<div className={styles.deprecationDate}>
Due {format(new Date(deprecation.date), 'MMMM do, yyyy')}
</div>
<Markdown
className={styles.markdownContainer}
source={deprecation.description}
/>
</div>
)}
<Markdown
className={cx(styles.details, styles.markdownContainer)}
source={description}
/>
<PropTypeInfo type={type} />
{examples.map((example, idx) => (
<ReferenceExample key={idx} example={example} />
))}
</div>
</div>
);
Expand All @@ -45,8 +137,15 @@ PropList.propTypes = {
PropTypes.shape({
name: PropTypes.string.isRequired,
description: PropTypes.string,
deprecation: PropTypes.shape({
date: PropTypes.number,
description: PropTypes.string,
}),
isRequired: PropTypes.bool,
type: PropTypes.string,
type: PropTypes.shape({
...PropTypeInfo.propTypes.type,
name: PropTypes.string.isRequired,
}),
defaultValue: PropTypes.string,
})
),
Expand Down
68 changes: 58 additions & 10 deletions src/components/PropList.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,76 @@
.info {
width: 30%;

.type {
color: var(--color-neutrals-600);
h3 {
margin-top: 0;
}
}

.default {
margin-top: 2rem;
color: var(--color-neutrals-700);
.default {
margin-top: 2rem;
color: var(--color-neutrals-700);

p:first-of-type {
font-size: 0.75rem;
}
p:first-of-type {
font-size: 0.75rem;
}
}

.type {
color: var(--color-neutrals-600);
}

.deprecation {
padding: 0.25rem;
background: var(--color-red-100);
margin-bottom: 1rem;
}

.deprecationDate {
color: var(--color-red-400);
font-weight: 600;
margin-bottom: 1rem;
}

.propInfo {
width: 70%;
}

.markdownContainer > *:first-child {
margin-top: 0;
}

.details {
font-size: 1.25rem;
width: 70%;

&:not(:last-child):not(:empty) {
margin-bottom: 1rem;
}
}

.required {
.flagged {
font-size: 0.75rem;
color: var(--color-red-400);
text-transform: uppercase;
margin-left: 0.5rem;
}

.arg {
padding-left: 1rem;
}

.listLike {
font-family: var(--code-font);
font-size: 0.875rem;
color: var(--color-neutrals-600);
}

.shape {
&:not(:last-child) {
margin-bottom: 2rem;
}

h4 {
margin-top: 0;
color: var(--color-neutrals-600);
}
}
1 change: 1 addition & 0 deletions src/components/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
--primary-font-family: 'open sans', sans-serif;
--secondary-font-family: 'effra', sans-serif;
--tertiary-font-family: 'Ovo', serif;
--code-font: 'Menlo', 'Consolas', monospace;
}

/*-- Reset --*/
Expand Down
Loading

0 comments on commit d01b3df

Please sign in to comment.