rebassjs/rebass

Issues with "as" vs "is" props in V3

Closed this issue · 23 comments

I noticed that the docs recommend using as to change the underlying tag emitted. However, if I use as instead of is, then all of the styled-system helpers are removed, and the values are passed directly to the DOM.

i.e. this works

const Code = props => 
  <Text
    is='code'
    fontFamily='mono'
  />

However, if we swap is with as, fontFamily now gets passed as font-family as an attribute on the tag directly. I get

  <code font-family="mono" class="random-gen-class-name"></code>

What version of styled-components are you using?

4.1.3.

Some background: I'm trying to make a component lib in it's own package. I'm using x0 to dev, which is where I'm seeing this behavior (haven't tried anywhere else yet).

I've patched x0 to support the latest babel (so I could use the styled-components babel plugin).

Main dependencies are:

"rebass": "^3.0.1",
"styled-components": "^4.1.3"

I know that x0 has rebass and probably styled-components as dependencies. I don't know if maybe those are also conflicting?

I'm getting the same issue:

"babel-plugin-styled-components": "1.10.0",
"styled-components": "4.1.3",
"rebass": "3.0.1",

In my case, swapping as for is does not seem to have an effect. With as or is in place, none of the system helper props work.

Also worth noting, this only seems to be an issue for me if there is a css prop.

eg:

This works as expected

<Box as="aside" p={5} m={5} />

So does this:

<Box p={5} m={5} css="overflow: hidden;" />

But when both css and as are applied, the p and m are not applied (neither are any other helper props from styled-system).

<Box as="aside" p={5} m={5} css="overflow: hidden;" />

@mrfelton I've been experiencing similar unexpected outputs when using the "as" prop in addition to extending a rebass component (using styled(Component)), as well as the case you mentioned. I've grown to fear the as prop, and regrettably as a result my website has turned out to be quite the div soup.

I know that x0 has rebass and probably styled-components as dependencies. I don't know if maybe those are also conflicting?

Those cross dependencies are (almost) definitely affecting the output. I'd recommend trying either with a basic webpack setup or using something like Gatsby or Next.js. It might also be worth trying the Emotion version out if possible as that library tends to have fewer issues with npm dependencies

As far as the font-family attribute goes, I think that is one of the props that styled-components whitelists as valid HTML – see this issue: styled-components/styled-components#439

@jxnblk do you have any ideas what's causing this or how to resolve? Removing all as props from our codebase isn't a great option.

The best way to handle this currently is to use Emotion and the shouldForwardProp API. There's a utility here for styled-system props https://github.com/styled-system/extras/tree/master/packages/should-forward-prop

This is a long-standing issue in styled-components that still hasn't been resolved, see styled-components/styled-components#439

Thanks, but switching from styled-components to emotion is also not a good option!

I totally get that, but the issue is really a styled-components issue and trying to solve it in user land has historically caused a lot of other issues

@jxnblk yeah, understood.

For now, we just keep our dependencies pinned to the following versions:

rebass@3.0.0-9
babel-plugin-styled-components@1.8.0

These do not suffer from the issue (rebass@3.0.0-9 uses it's own css prop handling rather than relying on styled-components)

For now, we just keep our dependencies pinned to the following versions

Maybe this should be either documented in the rebass docs or the as change reverted until styled-components fixes their issue?

trying to solve it in user land has historically caused a lot of other issues

Or do the other issues with providing as in the API again outweigh this? What are the issues @jxnblk?

@jxnblk Does the fix in styled-components/styled-components#2573 provide what you need to resolve this issue? Or, would that fix by itself resolve this?

aroc commented

@mrfelton's solution worked for me (pinning the versions to the ones he suggests).

The latest versions of styled-components, babel-plugin-styled-components and rebass work cleanly together now, so this appears to no longer be an issue.

Oh cool, which versions are those? Do you know where the fix came from?

I guess if we can identify that the original problem is indeed fixed with some commit on one or more of those projects, then this issue can be closed.

which versions are those

latest:

"babel-plugin-styled-components": "1.10.0",
"styled-components": "4.3.1",
"rebass": "3.1.1",

Do you know where the fix came from?

See my previous comment in this thread - #571 (comment)

Note, you will need to convert your css props to use the new styled-components native css prop format.

Thanks for the info! This will be very helpful for anyone else running into this issue.

the new styled-components native css prop format

Not sure if I'm sure what you mean here. Do you have a link for this?

https://www.styled-components.com/docs/api#css-prop

This is different from the old rebass css prop.

Old style (expects css object):

css={{
  'background-color': 'red',
  'border': '1px solid green';
}}

New style (allows you to write actual css):

css={`
  background-color: red;
  border: 1px solid green;
`}

Closing this since I think the original issue has been covered

The best way to handle this currently is to use Emotion and the shouldForwardProp API. There's a utility here for styled-system props styled-system/extras:packages/should-forward-prop@master

This is a long-standing issue in styled-components that still hasn't been resolved, see styled-components/styled-components#439

This has now been resolved! styled-components@5.1.0 has Emotion-style shouldForwardProp support:

https://github.com/styled-components/styled-components/releases/tag/v5.1.0

Original PR:

styled-components/styled-components#3006


I've opened #953 to investigate using this new API in Rebass.