styled-components / xstyled

A utility-first CSS-in-JS framework built for React. 💅👩‍🎤⚡️
https://xstyled.dev
MIT License
2.28k stars 105 forks source link

Problem using "styled" approach when "as" prop is a React component #234

Closed Makskow closed 3 years ago

Makskow commented 3 years ago

Hi!

I've been using v2 for a while and grew quite accustomed to the "x" approach of creating and styling components. However, when building reusable components, I've began wondering about going back to the "styled" approach for these three reasons:

  1. Composing states to me seems a bit better in a CSS-like manner, such as &:hover:not(:disabled)
  2. Referring to other styled components, like & > ${SomeComponent}
  3. Writing static styles in a CSS-like manner, rather than adding more style props

My usual pattern for these reusable components looks like this:

const MyComponent = forwardRef((props, ref) => {
  // Some internal logic, transformations, etc.

  return (
    <StyledComponent ref={ref} {...props} />
  )
})

export default MyComponent

After switching this inner StyledComponent from "x" to "styled" though, I started getting errors about unrecognized props on the HTML element. This happens when I pass a React component to "as" prop (<MyComponent as={NavLink} ... />). Interestingly, it's fine when I write "as" with a tag string (<MyComponent as="a" ... />).

Screenshot 2021-04-11 at 00 00 36

When passing React component to "as" prop, is there any way of preventing style props from appearing on the final HTML element? What could it be that makes it work with internal "x" component, but not "styled" component?

If there's no way to avoid those style props reaching the HTML element with "styled" approach, do you have any recommendation for the above reasons for using "styled"? I had a look at your PR for v3, where you change how state props work. Would that make it easier to compose states and avoid overwriting? For example, I had trouble recently with hover and active style props, where hover was always overwriting active. Also, could there be any possibility of referring to StyledComponents or this concept is just not supportable with "x"?

gregberge commented 3 years ago

Hello, if you want to create your own StyledComponents that uses system, you should filter props. An example in the code :

https://github.com/gregberge/xstyled/blob/66ac294eb7fa0760bf75b1ac679e9e964397c915/packages/emotion/src/createX.ts#L35-L37