goober
goober copied to clipboard
Classname Customization
First off, thank you @cristianbote for creating Goober! It is really an inspiration.
Is it possible to supply a custom id generator? Similar to the createGenerateId option in jss? If not, would you be open to a contribution here? It looks like it could be solved via a change to the setup
function and piping through the id generator as an alternative to the current to-hash
function.
Hey @samouri! Thank you so much for your kind words!
That's actually a great idea! 😄 there are is though at least two other places, top of mind, where you would need to adjust the detection for appending/prepending to the stylesheet:
- inside
styled
(https://github.com/cristianbote/goober/blob/master/src/styled.js#L37) - and inside compile https://github.com/cristianbote/goober/blob/master/src/core/compile.js#L20
All in all, seems really doable and I think using setup
for it, will be a perfect use case 👍
While I was looking at emotion's keyframes
api I noticed this one as well https://emotion.sh/docs/labels. Would something like that be useful in your use case? I think using the label
could turn out the smallest approach in terms of footprint. What do you think?
Hey @cristianbote. I'm the maker of notistack. I was looking for a light-weight css-in-js solution and came across this package. At the moment this issue is the only thing preventing me from adopting goober.
Is there any plans to add this feature to the package in near future? Anything I can help with? Both of the suggestions above sound reasonable to me.
Hey @iamhosseindhv, thanks for your message. Kudos on notistack
looks awesome!
Can you make me understand how would the custom className help you in adopting goober
? Trying to figure out the use-cases 😄
Thanks for the kind words. No problem, In notistack snackbars/notifications and their positions are customised in 3 ways:
- Custom component:
enqueueSnackbar('Upload complete 📂' , {
content: MyCustomUploadComponent,
})
- Using
className
,style
andclasses
props:
// example for className
enqueueSnackbar('Upload complete', {
className: 'some-class',
})
// classes prop example
<SnackbarProvider
classes={{
// styles applied to container root element
containerRoot: 'some-class',
// styles applied to snackbars when positioned on bottom-left corner of the screen
anchorOriginBottomLeft: 'another-class',
}}
>
<MyApp />
</SnackbarProvider>
- Using CSS selectors:
containerRoot: {
'& > .MuiCollapse-container > .MuiCollapse-wrapper': {
justifyContent: 'flex-end',
},
},
It's the no.3 case that I'm trying to cover using custom classNames. Not every single div
in notistack is addressable using the classes
prop. As you can see, if it wasn't because of the selectors, people wouldn't be able to apply customisation to the wrapper
element. Hence the need for consistent classes names for such elements.
So far, we've been able to have static classNames (as opposed to hash-based classNames in goober) using Material-UI styling solution which uses jss
under the hood. Since notistack is moving away from Material-UI, we need to replicate the same behaviour using another styling solution.
Hope that's been helpful.
Thanks for the added info, I believe now it's clearer.
So, you are not trying to replace the generated className hash with a custom label, but rather have a predefined className present on each element for the users to be able to define selectors based on those?
If that's the case, the Styled
class has a static property on it, called Styled.className
, which is used if no className
is incoming from the props. So with that in mind I put together this example https://codesandbox.io/s/react-goober-forked-u9h9k?file=/src/index.js.
Is this what you were looking for?
Thanks, it does fix my concern about addressing elements using CSS selectors.
However, still from a debugging perspective and doing performance optimisation it's not ideal. Here's a screenshot of the generated code using latest notistack:
Here's the same elements using Goober.
Please ignore the excessive number of go<hash>
classNames on each element. But best case scenario it'd look something like:
<div className="go1234567 SnackbarContainer">
<div className="go7654321 SnackbarCollapse user-provided-classname"></div>
</div>