I've been thinking how to make a robust implementation of this because it's a fairly common use case.
The proposed idea has a few nice properties:
- Still no true CSS selectors/class names
- Clear precedence / style resolution (this is needed because the normal JS method of resolving styles doesn't translate into CSS land)
- No brittle assumptions about component hierarchy. The correct ancestor/descendant relationship is enforced via the render prop API. (excluding portals, I suppose)
Example
I'm not totally happy with the names of things (still working on it), but hopefully the overall idea makes sense:
import {createAncestor, Descendant} from "styletron-react";
const Foo = styled("div", {color: "green"});
const HoverSource1 = createAncestor(":hover", {
color: "red"
});
const HoverSource2 = createAncestor(":hover", {
color: "purple"
});
<HoverSource1 $as="div">
{target1 => (
<HoverSource2>
{target2 => (
<div>
<Descendant $as={Foo} $combinators={[target1, target2]} />
</div>
)}
</HoverSource2>
)}
</HoverSource1>;
Concepts
- The order of the array passed to
Descendant determines the precedence of styling. As an implementation detail, we can iteratively increase the specificity of generated rules to make this happen.
- Descendent combinator styles always take precedence over "normal styles".
There's still a lot that needs to be ironed out, especially in terms of figuring out all the implementation details, but this is probably the first API that I've liked for this feature.
I've been thinking how to make a robust implementation of this because it's a fairly common use case.
The proposed idea has a few nice properties:
Example
I'm not totally happy with the names of things (still working on it), but hopefully the overall idea makes sense:
Concepts
Descendantdetermines the precedence of styling. As an implementation detail, we can iteratively increase the specificity of generated rules to make this happen.There's still a lot that needs to be ironed out, especially in terms of figuring out all the implementation details, but this is probably the first API that I've liked for this feature.