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

xstyled props overridden by styled-component props #340

Closed mleralec closed 2 years ago

mleralec commented 2 years ago

🐛 Bug Report

on xstyled v3.* (works on v2.5) xstyled props overridden by styled-component props

To Reproduce

const App = () => <Test backgroundColor="tomato">Hello World</Test>;

const Box = (props) => <x.div {...props} />;

const Test = styled(Box)`
  background-color: olive;
`;

The result here is the background color of Test is olive. (tomato on @xstyled/styled-components 2.5.0)

Expected behavior

The background color of Test should be tomato.

Link to repl or repo

https://codesandbox.io/s/thirsty-williams-fzgjj?file=/src/App.js

Environment

@xstyled/styled-components: 3.3.0
agriffis commented 2 years ago

Hi @mleralec. This isn't a bug, the thing to know is that wrappers always win.

I wrote a longer explanation at https://github.com/gregberge/xstyled/issues/287#issuecomment-870496934

agriffis commented 2 years ago

@mleralec I just wanted to follow up since you noted this changed between v2 and v3.

That's correct. v2 used specificity which meant that wrapped components could override wrappers. This changed in v3 to use rule ordering, see #240 and #244. It makes the system much more predictable and composable.

For your case, you have a couple options:

  1. Add ${system} to Test
const Box = (props) => <x.div {...props} />;

const Test = styled(Box)`
  background-color: olive;
  ${system};
`;
  1. OR, use styled.box which does this for you. This really makes more sense for the simple test case, though it might be different in your application:
const Test = styled.box`
  background-color: olive;
`;

// which is a shortcut for styled.div with system
const Test = styled.div`
  background-color: olive;
  ${system}
`;

I hope that helps!