Closed idrm closed 2 years ago
Thanks for the great bug replication.
Here's the conversion data - perhaps you can guide me on what needs to be changed to get this feature working in stitches?
// in
import tw, { styled } from "twin.macro";
const StyledDiv = styled.div({
variants: {
xyz: {
true: tw`text-red-500`,
},
},
});
const IndexPage = () => (
<StyledDiv tw="text-blue-500" xyz>
Hello world
</StyledDiv>
);
// out
import { styled as _styled } from "stitches.config.js";
const StyledDiv = _styled("div", {
variants: {
xyz: {
true: {
"--tw-text-opacity": "1",
"color": "rgba(239, 68, 68, var(--tw-text-opacity))"
}
}
}
});
const _TwComponent = _styled(StyledDiv, {
"--tw-text-opacity": "1",
"color": "rgba(59, 130, 246, var(--tw-text-opacity))"
});
const IndexPage = () => /*#__PURE__*/React.createElement(_TwComponent, {
xyz: true,
"data-tw": "text-blue-500"
}, "Hello world");
The generated component code is correct, but it appears that the order of the generated CSS class rules (inside the head element) affects the final result. You can see the xyz=true
class definition show up after that of the tw="text-blue-500"
class, as well as the xyz=true
class taking precedence in the computed styles section of Chrome's dev tools in the screenshot below (taken from the Sandbox demo I linked to previously):
I modified the Sandbox demo to include a default green background styling in the component definition, as well as a yellow background override where the component is rendered. That worked as expected. The override seems to fail only in the case of variant styles.
import tw, { styled } from "twin.macro";
const StyledDiv = styled.div({
...tw`bg-green-500`,
variants: {
xyz: {
true: tw`text-red-500`
}
}
});
const IndexPage = () => (
<StyledDiv tw="text-blue-500 bg-yellow-500" xyz>
Hello world
</StyledDiv>
);
After digging inside the twin.macro source code, I believe the issue stems from how the tw
attribute is handled and the resulting order of CSS classes. If I set the moveTwPropToStyled
config option to false
(and as long as I don't mix the tw
and css
props inside the same element) I get the proper order of class rules and the desired style override. Here's a CS demonstrating that.
It's possible the issue lies with the following bug in Stitches: stitchesjs/stitches#1060
Their reproduction demo shows the same CSS rule order behavior.
I'm closing this issue since it lies with how Stitches operates.
The
tw
property fails to override a (Stitches) component's styling when that styling is inside a variant definition. E.g. the following will render the text in red instead of blue:Oddly enough, it works when I try to override using the css property instead, e.g.
Here's a replication of the issue in Sandbox (using the the current twin.macro + next.js + Stitches twin.examples repo as a starting point).
I haven't yet investigated the underlying cause, but I suspect it's something to do with CSS precedence rules.