Decisiv / styled-components-modifiers

A library to enable BEM flavored modifiers (and responsive modifiers) in styled components.
MIT License
298 stars 11 forks source link

Validating modifiers in a parent component throws warnings for customModifiers defined in child components #13

Closed robbie-hinman closed 6 years ago

robbie-hinman commented 6 years ago

EXPECTED BEHAVIOR

When defining a custom modifier in a child component, I would not expect to see proptype warnings from it's parent component saying those modifiers are invalid.

ACTUAL BEHAVIOR

These warnings come from parent components that use styleModifierPropTypes, that don't seem to allow for the modifiers of the children.

STEPS TO REPRODUCE

  1. Clone in a fresh component-library-starter project.
  2. Inside elements/Icon/index.js add modifier validation by importing styleModifierPropTypes and adding:
    Icon.propTypes = {
    modifiers: styleModifierPropTypes(modifierConfig),
    }
  3. Observe in console the following:

    Warning: Failed prop type: Invalid modifier left used in prop modifiers[0] and supplied to Styled(UnstyledIcon). Validation failed. in Styled(UnstyledIcon) (created by PreviewComponent) in PreviewComponent in ThemeProvider (created by ThemeWrapper)

This is because Button.Icon defines a customModifier 'left'.

Is there a recommended way to validate modifiers for components that are built off of other components?

Thanks!

andrewtpoe commented 6 years ago

We encountered a very similar issue while using this tool, and were able to get around it by creating a factory function for our styled components. It changes the syntax of how we build our components, but we think it is much easier to work with.

Our internal fix is similar to the pattern implemented in this buildStyledComponent factory function, and we are working on a blog post describing why it exists and how it works. A very similar example to the UnstyledIcon in question can be found in that app here. We really like this pattern, and have settled on it for use in our production applications going forward.

The primary cause of the error you reported here is that all of the modifiers are not available at the time the prop types are validated. They are eventually applied to the component and so should style the component as expected, it just also throws the error.

The buildStyledComponent factory function resolves this issue by ensuring all of the modifiers that should be on the component are present when the component is built.

This factory function is a little tricky, let me know if you have any questions.

andrewtpoe commented 6 years ago

Closing due to inactivity. Please reach out again if you need additional help @robbie-hinman

m0neysha commented 5 years ago

Hi @andrewtpoe, I'm experiencing the same behavior as this issue. Thank you for sharing your internal fix! I'm wondering if there are any plans for styled-components-modifiers to support this?

If not, I'll be looking into how we can implement the pattern you introduced to our tools. Thanks!

andrewtpoe commented 5 years ago

At this time there are no plans to include this behavior in styled-components-modifiers. The buildStyledComponent factory function has worked exceptionally well for us both internally and in my personal projects. The ability to use middleware has proven exceptionally useful.

Note that the demo factory function makes use of .extend, a now deprecated API in styled components. You'll need to update that if you use the pattern.