Open JohnRoseDev opened 3 years ago
I'm having the same issue, i can't style my formik forms :(
same here and following the example for using css.resolve does not work either
@vercel, are you aware of this? This is a major problem for this library to be used in realistic react use cases. Everybody creates (or uses existing) wrappers and ui component libraries for their react projects, and for all these components the className is not compiled correctly by styled-jsx.
Due to this behaviour, we are forced to create wrapper components around 3rd party components causing an excessive DOM size.
@vercel, if possible please look into this as it has become antithesis to what next.js is trying to achieve.
Right now if I have a wrapper component that looks like this:
const Wrapper = (props) => {
return <div className={props.className}></div>
}
And I use it in a container:
const Container = (props) => {
return <section className='container'><Wrapper className='my-wrapper' /></section>
}
When parsed with styled-jsx the html would look something like this:
<section className='jsx-1 container'>
<div className='jsx-2 my-wrapper'></div>
</section>
So what we all are missing is the jsx-1
in the div.
I would be happy if I was able to add it manually like:
const Container = (props) => {
const cssScope = useCssScope()
return (
<section className='container'>
<Wrapper className=`${cssScope} my-wrapper` />
<style jsx>{`
.my-wrapper {
color: red;
}
`}</style>
</section>
)
}
I could do something similar with resolve
but that means I can't write my style definitions in the style tag which means they are kind of all over the place…
Right now my workaround is to use :global()
:
const Container = (props) => {
return (
<section className='container'>
<Wrapper className='my-wrapper' />
<style jsx>{`
.container :global(.my-wrapper) {
color: red;
}
`}</style>
</section>
)
}
Oh also this is not the first time this is discussed… https://github.com/vercel/styled-jsx/issues/573
Here's a simple workaround for those still struggling with this issue. Essentially we apply a classname on a wrapper element in the parent and use it in combination with the :global() selector to target the child and style from it parent. it's also a good way to override child styles from the parent.
function Child({ className='' }: { className?: string }) {
return (
<div className={`child ${className}`}>
child..
<style jsx>{`
.child {
border: 1px solid red;
width: 40px;
height: 40px;
}
`}</style>
</div>
);
}
function Parent() {
return (
<div className="parent">
<Child className="parent-child" />
<style jsx>{`
.parent :global(.parent-child) {
border: 1px solid green;
}
`}</style>
</div>
);
}
Do you want to request a feature or report a bug?
Not sure if bug or feature
What is the current behavior?
When using a native div element like
<div className='bla' />
things work as expected and a "jsx-1234 bla" class name is generated, however, if set to a wrapper component like<Container className='bla' />
, which under the hood passes className to a div, the classname is not compiled but simply stays "bla" on the div element, consequently the styles are not applied.What is the expected behavior?
I would not expect styled-jsx to be limited to native elements since building wrappers and abstractions is a very common pattern in react. I would think the "jsx-1234" should be passed down to the div element inside the wrapper component.
Environment (include versions)
Did this work in previous versions?
Not sure