airbnb / react-with-styles

Use CSS-in-JavaScript with themes for React without being tightly coupled to one implementation

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`styles` prop validation

Andreyco opened this issue · comments

I, with many of us, use your ESLint config preset, which is great.
It happens there are rules I don't like and I override them.

I am not sure about react/forbid-prop-types rule and its setting, which is following:

'react/forbid-prop-types': ['error', { forbid: ['any', 'array', 'object'] }],

I find it very useful, but hate it when it comes to styles prop. This is no-go with default preset:

Label.propTypes = {
  styles: PropTypes.object.isRequired,
};

To validate (and satisfy ESLint) I have to use shape validation rule and write down rules for all styles passed by decorator function - repeated work here. Since styles is defined in very same file and there is very little that could go wrong, I don't feel like paying special attention to that prop.

How do you validate styles prop at AirBnb?

Thanks for answer!


Okay, to be honest I often abuse vague shape validator function, without specifying actual shape of styles prop.

Label.propTypes = {
  styles: PropTypes.shape().isRequired,
};

I think the best long-term solution is for this package to export a PropType for "styles", so that you don't have to use object or shape, and so we have an injection point to improve the validation in the future.

@ljharb are you referring to custom validator function? If not, I don't clearly understand your response.

Yes, basically. Essentially we'd export PropTypes.object for now, and then later, we might replace it with a custom one. That way you wouldn't have to put "PropTypes.object" in your own code.

Will take a look into this. Are you open to PRs?

Absolutely!

@ljharb I would also like to see this. I wonder if it would be possible to have this prop type be an extension of existing packages, like airbnb-prop-types or prop-types.

That way, you could still make the same call of PropTypes.styles instead of something like stylePropType

I think it's a bit too specific to be in a general prop-types package.

Not add it in to a prop-types package. But check for the existence of a prop-types package and attach it to that. Something like

// define new prop type here
const stylesProp = ...;

// check for existing package
import PropTypes from 'prop-types';
if (PropTypes) {
  PropTypes.styles = stylesProp;
}

I don't actually know if this is possible so if I'm proposing an impossibility, I apologize.

It's possible, but it would mutate the package for everyone else in that codebase using it; it's a horrifically bad idea to mutate anything you don't own.

We ended up composing our own PropTypes package. We house all our custom prop-types in lib/prop-types and provide an index.js with the following.

import ABNBPropTypes from 'airbnb-prop-types';
import PropTypes from 'prop-types';
import contributionMetadata from './contribution-metadata';
import contributions from './contributions';
import notification from './notification';
import userProfile from './user-profile';
import reduxStore from './redux-store';
import router from './router';
import routerMatch from './router-match';
import styles from './styles';

export default {
  ...PropTypes,
  ...ABNBPropTypes,
  contributionMetadata,
  contributions,
  notification,
  reduxStore,
  router,
  routerMatch,
  styles,
  userProfile,
};

Works like a charm and doesn't mutate anything. In the components we then simply use:

import PropTypes from 'lib/prop-types';

Actually this is now done; import { withStylesPropTypes } from 'react-with-styles' - now you never need to (nor should) explicitly specify the styles or theme props in your code.

Also possible via ViewPropTypes from React Native. See this StackOverflow answer.