Components referencing themselves
fabiospampinato opened this issue · 6 comments
For some components of mine I need to have them reference themselves, with styled-components
I could write something like this to do that:
const Component = styled.div`
&${() => Component} {
color: pink;
}
`;
But with goober that patterns seems unsupported. Moreover I will most probably need to reference components from other components, so I'd expect something like ${Component}
to give me the unique class associated with that component.
What's the equivalent way of doing that with goober?
Adding a .toString = () => 'random-class-here'
to components made with goober seems to work pretty well actually 🤔 would that be the recommended way to do this? Any issues that I might encounter with that?
I think that might not work properly for components that extend other components 🤔
I think this might work:
// Adding a className explicitly, so that it gets added to the DOM
Component1.className = 'class1';
// Added a toString method, so that components can be referenced elsewhere
Component1.toString = () => 'class1';
// Then when a component extends another one a new class is simply appended
Component2.className = 'class1 class2';
Component2.toString = () => 'class1 class2';
Slight update, since it's problematic to return multiple class from toString
and it's more convenient to return them with the dot for easier interpolation:
// Adding a className explicitly, so that it gets added to the DOM
Component1.className = 'class1';
// Added a toString method, so that components can be referenced elsewhere
Component1.toString = () => '.class1';
// Then when a component extends another one a new class is simply appended
Component2.className = 'class1 class2';
Component2.toString = () => '.class2';
Heya @fabiospampinato thanks for opening this issue.
Nifty little findings you got there! The .toString
method seems interesting. Now goober does support self-referencing notation with the &
sign. No need to do the inline function &{() => Component}
. Take a look at this snippet:
const Foo = styled("div")`
background: silver;
padding: 1em;
border-radius: 2px;
// The `&` is a self-referencing symbol and will be replaced by this component unique className
& {
background: red;
}
`;
const WrappedFoo = styled("div")`
margin: 1em;
padding: 1em;
border: 1px solid tomato;
${Foo} {
background: dodgerblue;
}
`;
const App = () => {
return (
<>
<Styles />
<Foo>foo</Foo>
<WrappedFoo>
This is the wrapper
<Foo>content</Foo>
</WrappedFoo>
</>
);
};
You can see it live here as well https://codesandbox.io/s/sweet-sound-nvtn4w
Does this answer your question?
@cristianbote using &
works, but it's a little constraining in some situations, for example if I have to and prefer to write selectors like this now I can't reference the parent component anymore:
&.something {
& {
/* no way to reference the parent, Foo, not Foo.something */
}
}
Potentially that's a limitation that can be worked around by rewriting the code like this:
&.something & {
/* works */
}
And that would be ok in simple snippets like that, but I think it would get really messy potentially with other code 🤔