diff --git a/packages/pretty-proptypes/src/index.js b/packages/pretty-proptypes/src/index.js index de0504d9..1a157662 100644 --- a/packages/pretty-proptypes/src/index.js +++ b/packages/pretty-proptypes/src/index.js @@ -3,3 +3,4 @@ export { default } from './Props'; export { default as PropsTable } from './PropsTable'; export { default as components } from './components'; export { default as HybridLayout } from './HybridLayout'; +export { default as usePropsExplorer } from './usePropsExplorer'; diff --git a/packages/pretty-proptypes/src/usePropsExplorer/index.js b/packages/pretty-proptypes/src/usePropsExplorer/index.js new file mode 100644 index 00000000..c9162415 --- /dev/null +++ b/packages/pretty-proptypes/src/usePropsExplorer/index.js @@ -0,0 +1,31 @@ +import getPropTypes from '../getPropTypes'; + +const getProps = props => { + if (props && props.component) { + return getPropTypes(props.component); + } + return null; +}; + +export default function usePropsExplorer(props) { + const { component } = props; + if (component) { + /* $FlowFixMe the component prop is typed as a component because + that's what people pass to Props and the ___types property shouldn't + exist in the components types so we're just going to ignore this error */ + if (component.___types) { + props = { type: 'program', component: component.___types }; + } else { + /* eslint-disable-next-line no-console */ + console.error( + 'A component was passed to but it does not have types attached.\n' + + 'babel-plugin-extract-react-types may not be correctly installed.\n' + + ' will fallback to the props prop to display types.' + ); + } + } + + let propTypes = getProps(props) || null; + + return propTypes; +} diff --git a/stories/usePropsExplorer.stories.js b/stories/usePropsExplorer.stories.js new file mode 100644 index 00000000..b52b71fa --- /dev/null +++ b/stories/usePropsExplorer.stories.js @@ -0,0 +1,72 @@ +// @flow +import React from 'react'; + +import { usePropsExplorer } from 'pretty-proptypes'; +import FlowComponent from './FlowComponent'; +import TypeScriptComponent from './TypeScriptComponent'; + +export default { + title: 'Example/usePropsExplorer' +}; + +const Template = args => { + const propTypes = usePropsExplorer({ component: args.component }); + + return ( +
+

usePropsExplorer

+ +

+ The usePropsExplorer hook takes a component and will return all prop types for said + component. This gives the consumer 100% freedom on how to handle the prop types. +

+ + + + + + + + + + + + + {propTypes.map(prop => ( + + + + + + + + ))} + +
+ Prop name + + Required? + + Type + + Default + Description
{prop.key.name}{prop.optional ? 'no' : 'yes'}{prop.value.kind}{prop.default ? prop.default.value : ''} + {prop.leadingComments + ? prop.leadingComments.reduce((acc, { value }) => acc.concat(`\n${value}`), '') + : ''} +
+
+ ); +}; + +export const Flow = Template.bind({}); + +Flow.args = { + component: FlowComponent +}; + +export const TypeScript = Template.bind({}); + +TypeScript.args = { + component: TypeScriptComponent +};