react-generate-props
react-generate-props copied to clipboard
Allow for Generation of Custom Prop Types
Airbnb created a number of custom prop types (https://github.com/airbnb/prop-types), and we should allow for the generation of these (and any other) custom types. For instance, using their empty validator:
const customGenerators = { empty: () => null }
generateProps.init({ generators: customGenerators })
// Note: init doesn't currently take any options
import { empty } from 'airbnb-prop-types'
Component.propTypes = { alwaysEmpty: empty.isRequired }
generateProps(Component)
// => Current: {}
// => Proposed: { alwaysEmpty: null }
A real world example that I'd like right now:
generateProps.init({ generators: { dateString: () => moment().format() } })
import { dateString } from 'lib/custom-prop-types'
Component.propTypes = { insertedAt: dateString.isRequired }
generateProps(Component)
// => Current: {}
// => Proposed: { insertedAt: '2019-06-12T17:23:27-04:00' }
Letting init take generators would allow for "global" custom generators too. Maybe allow for all options to be defaulted.
const generators = {
string: propName => {
switch (propName) {
case 'insertedAt': return moment('01/01/2001', 'MM/DD/YYYY').format();
case 'updatedAt': return moment().format();
default: return propName;
}
}
generateProps.init({ generators, optional: true })
Component.propTypes = {
insertedAt: string.isRequired,
updatedAt: string,
name: string.isRequired,
}
generateProps(Component)
// => Current: { insertedAt: 'insertedAt', name: 'name' }
// => Proposed:
/* {
insertedAt: '2001-01-01T00:00:00-05:00',
updatedAt: '2019-06-13T11:21:11-04:00',
name: 'name'
} */
A wrinkle: because we need to wrapPropTypes, we need to know, during initialization, that these custom props exist. That might mean something like
import propTypes from 'prop-types'
import customPropTypes from 'lib/custom-prop-types'
generateProps.init(
[propTypes, customPropTypes],
{ generators: { empty: () => null } }
)
There might be overlaps in prop names there, though, so maybe...
generateProps.init({
generators: [
[propTypes.string, () => 'string'],
[customPropTypes.string, () => 'custom string'],
]
})
or just allow for namespacing...
generateProps.init({ propTypes, customPropTypes }, {
generators: {
propTypes.string: () => 'string',
customPropTypes.string: () => 'custom string',
}
})
const myCheck = (props, propName, componentName) => ...
const myOtherCheck = (props, propName, componentName) => ...
generateProps.init({ myCheck, { otherCustomValidators: { myOtherCheck } } }, {
generators: {
myCheck: () => 'foo',
otherCustomValidators.myOtherCheck: () => 'bar',
}
})