Description
Summary
One of the "killer features" of styled-components, IMO, is the ability to reference one component's class within another component definition.
For example:
const Figure = styled.figure`...`
const Link = styled.a`
color: blue;
${Figure} & {
color: inherit;
}
`
It would be great if we could do the same thing in Pigment CSS!
Here's what I tried to do:
export default function Home() {
return (
<>
<Wrapper>
<Button>Inside</Button>
</Wrapper>
<Button>Outside</Button>
</>
);
}
const Wrapper = styled('div')``;
const Button = styled('button')({
color: 'red',
[`${Wrapper} &`]: {
color: 'blue',
},
});
This doesn't work, because Wrapper
gets stringified to [object Object]
.
I know that Linaria supports this behaviour, which also uses wyw-in-js, so I know this is possible, but I'm afraid I have no idea how they're accomplishing it 😬.
Repro
Motivation
I know that this might seem like a pretty niche concern, but this pattern is so so important.
A lot of teams solve this by creating a "variant" of a component. For example, maybe we create a FigureLink
styled component:
const Link = styled('a')({
color: 'blue',
});
const FigureLink = styled(Link)({
color: 'inherit',
});
The problem is that this requires the developer to remember to use FigureLink
each and every time they have a link inside a figure. It requires superhuman discipline. Most likely, we'll wind up with a mismatched UI, where some links use FigureLink
and others use Link
.
Alternatively, we could style based on tag, like:
const Figure = styled('figure')({
'& a': {
color: 'inherit',
}
});
The trouble with this approach is that it "reaches in" to the Link component and meddles with its internal styles. It also means that the styles for the Link component will be sprinkled all across the codebase, making it very difficult to understand the ways in which styles can change.
With the "cross-reference" thing, all of the styles for Link are gathered in 1 place.
Search keywords: Pigment CSS