react-generate-props icon indicating copy to clipboard operation
react-generate-props copied to clipboard

Allow for Generation of Custom Prop Types

Open markalfred opened this issue 6 years ago • 3 comments

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' }

markalfred avatar Jun 12 '19 21:06 markalfred

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'
} */

markalfred avatar Jun 13 '19 15:06 markalfred

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',
  }
})

markalfred avatar Jul 09 '19 01:07 markalfred

const myCheck = (props, propName, componentName) => ...
const myOtherCheck = (props, propName, componentName) => ...

generateProps.init({ myCheck, { otherCustomValidators: { myOtherCheck } } }, { 
  generators: {
    myCheck: () => 'foo',
    otherCustomValidators.myOtherCheck: () => 'bar',
  }
})

markalfred avatar Aug 13 '19 14:08 markalfred