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

PoC: Create new usePropsExplorer hook #182

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions packages/pretty-proptypes/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
31 changes: 31 additions & 0 deletions packages/pretty-proptypes/src/usePropsExplorer/index.js
Original file line number Diff line number Diff line change
@@ -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) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Hey @davidfloegel: Love your work ❤️. Sorry for jumping like this. One question around naming here. Not sure if we really call this a hook or a util? 🤔

Copy link
Author

Choose a reason for hiding this comment

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

Hey dude! Thanks :)

Yeah, I did like the idea of this being a hook but in the end I think it doesn't have to be.

Daniel had a good point though about just exposing the getPropTypes function - so maybe that's more than enough

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 <Props> but it does not have types attached.\n' +
'babel-plugin-extract-react-types may not be correctly installed.\n' +
'<Props> will fallback to the props prop to display types.'
);
}
}

let propTypes = getProps(props) || null;
Comment on lines +12 to +28
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice man ❤️. BTW is it possible to simplify this with optional chaining and probably we can return earlier if everything works and print error at last & return null then? 🤔


return propTypes;
}
72 changes: 72 additions & 0 deletions stories/usePropsExplorer.stories.js
Original file line number Diff line number Diff line change
@@ -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 (
<div>
<h1>usePropsExplorer</h1>

<p>
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.
</p>

<table style={{ width: '100%' }}>
<thead>
<tr>
<th align="left" width="200">
Prop name
</th>
<th align="left" width="150">
Required?
</th>
<th align="left" width="150">
Type
</th>
<th align="left" width="200">
Default
</th>
<th align="left">Description</th>
</tr>
</thead>
<tbody>
{propTypes.map(prop => (
<tr key={prop.key.name}>
<td>{prop.key.name}</td>
<td>{prop.optional ? 'no' : 'yes'}</td>
<td>{prop.value.kind}</td>
<td>{prop.default ? prop.default.value : ''}</td>
<td>
{prop.leadingComments
? prop.leadingComments.reduce((acc, { value }) => acc.concat(`\n${value}`), '')
: ''}
</td>
</tr>
))}
</tbody>
</table>
</div>
);
};

export const Flow = Template.bind({});

Flow.args = {
component: FlowComponent
};

export const TypeScript = Template.bind({});

TypeScript.args = {
component: TypeScriptComponent
};