segmentio/ui-box

Integrate primitive with any CSS-in-JS library

blakeembrey opened this issue Β· 13 comments

I'd like to use Evergreen (which uses this library) with my existing CSS-in-JS solution used in a project. This is because the pipeline may already do things like extract to a CSS file, minify output, hydration, style de-duplication, etc.

One approach to solve this nicely is the React.js context API. This library could accept a custom API for working with CSS styles and provide the built-in one as the default value for the context. This would also solve #14, since every render can use a different context.

Let me know if this sounds like a reasonable approach, I'd be happy to take a first stab in a PR. It'd create nice separation for anyone wanting various features on their primitive too, such as vendor prefixing, while not bloating the core in case someone uses different libraries.

Rowno commented

Yeah, I was planning to use the context API to support async server-side rendering. The current server-side rendering support should work fine with ReactDOMServer.renderToString() though since it's synchronous.

https://github.com/segmentio/ui-box#server-side-rendering

@Rowno That's fine, I'm actually mostly interested in using evergreen-ui with my own CSS-in-JS pipeline. I figured this would be the best way to get there, and it just happens to solve #14 too πŸ˜„

Let me know if there's anything I can do to help.

Rowno commented

Evergreen also supports synchronous server-side rendering if that helps you.

https://github.com/segmentio/evergreen#how-does-server-side-rendering-ssr-work

No problem. I don’t actually care about server rendering, I just mentioned it would also solve #14. What I care about is reusing my existing CSS-in-JS solution instead of adding a new one. Using the context provider would allow someone to use their own CSS solution (that may, for instance, already be doing vendor prefixing, style deduping, etc).

Rowno commented

Oh, I'm thinking of something completely different then. I was just going to add a provider to scope the cache and stylesheet. πŸ˜…

@Rowno I see. If it's implemented at a higher level I was thinking you could abstract away the class name logic and style sheet into the provider and people could then just write something against the interface to interop with any CSS-in-JS solution. E.g. returns a class name string and the rest is internal the provider. It could take the object, do transforms on it like vendor prefixing, de-duping, etc.

@blakeembrey if you've got an idea in mind already that could solve for this it might be worth an RFC PR. What do you think?

@mshwery There's no rush from my side but I'll try to give it a shot in January.

tj commented

πŸ‘ I'm liking ui-box quite a bit for one-offs and general structure so far, but glamor seems really inflexible, you can't even select a child in a pseudo which is pretty odd.

It'd be awesome if ui-box somehow supported more complex styling. It feels hacky to introduce yet-another styling option, just for something like a hover.

Rowno commented

I'm open to suggestions for ways to support more complex styling, but I haven't been able to think of a good API yet. Related to #26

tj commented

In my case I need basically :hover > .icon { tweak } which might be difficult to express with JSX stuff.

I'll think about the API some as well, but even if ui-box was built on a nicer css-in-js solution it'd be nice knowing you could drop down to that without adding another dep, but which one is "best" would definitely be pretty subjective, personally I'd go with shadow-dom style it's probably the only future-proof solution.

@tj what styles specifically are you trying to override on the icon? I am also curious to learn more about shadow-dom styles, do you have any experience with this or good resources?

As an aside, I have been tinkering around with a new Box component that is very similar to ui-box and doesn't use glamor but just style. It's still very much in ideation phase, but feel free to check it out: https://codesandbox.io/s/rj5m0m00l4.

I wish there was a performant way to listen to hover, active, focus without adding event listeners. I created a ClickableStateBox example in the code sandbox to explore some ideas around this.

tj commented

In my case I just have an account menu with name/team/avatar, and upon hovering that entire box I just wanted to tweak the icon color, but it's a little tricky todo stuff like that without classnames.

I don't have too much experience with shadow dom / custom elements yet, it seemed a bit awkward to use since you can't have anonymous custom elements but I'll investigate that a bit soon hopefully!

Just using style sounds good to me!