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?
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.