cristianbote / goober

🥜 goober, a less than 1KB 🎉 css-in-js alternative with a familiar API
https://goober.rocks
MIT License
3.12k stars 118 forks source link

Classname Customization #180

Open samouri opened 3 years ago

samouri commented 3 years ago

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.

cristianbote commented 3 years ago

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:

All in all, seems really doable and I think using setup for it, will be a perfect use case 👍

cristianbote commented 3 years ago

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?

iamhosseindhv commented 3 years ago

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.

cristianbote commented 3 years ago

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 😄

iamhosseindhv commented 3 years ago

Thanks for the kind words. No problem, In notistack snackbars/notifications and their positions are customised in 3 ways:

  1. Custom component:

    enqueueSnackbar('Upload complete 📂' , {
    content: MyCustomUploadComponent,
    })
  2. Using className, style and classes 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', }}

  1. 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.

cristianbote commented 3 years ago

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?

iamhosseindhv commented 3 years ago

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:

Screenshot 2021-03-13 at 18 30 07

Here's the same elements using Goober.

Screenshot 2021-03-13 at 18 28 53

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>