-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A hook version of <ClassNames> for power users #1853
Comments
<ClassNames>
for power users
Hi @oztune it might (or might not) be interesting to you, but I have written a hook that does this already. For my use-case server side rendering wasn't needed, but if you are able to get access to an import { CSSInterpolation, serializeStyles } from '@emotion/serialize'
import { insertStyles } from '@emotion/utils'
import { useCallback } from 'react'
import { useEmotionCache } from 'ds/styled' // see below
/**
* **This hook only works for browser rendering!** (I wrote it for separating
* modal behaviour from modal styles).
*/
export function useCssClassName(): (...args: Array<CSSInterpolation>) => string {
const cache = useEmotionCache()
return useCallback(
(...args) => {
if (!cache) {
if (process.env.NODE_ENV === 'production') {
return 'emotion-cache-missing'
}
throw new Error('No emotion cache found!')
}
const serialized = serializeStyles(args, cache.registered)
insertStyles(cache, serialized, false)
return cache.key + '-' + serialized.name
},
[cache],
)
} The import React from 'react'
import { EmotionCache, withEmotionCache } from '@emotion/react'
const CacheContext = createContext<EmotionCache|undefined>(undefined)
export const useEmotionCache = () => useContext(CacheContext)
// We wrap our App with this
export const CacheProvider = withEmotionCache((
{ children }: { children: React.ReactNode },
cache: EmotionCache
) => {
return (
<CacheContext.Provider value={cache}>
{children}
</CacheContext.Provider>
)
}) |
@grncdr Wow that's all I ever wanted, you're the man! |
+1 this would be nice |
I actually have a similar solution but just for a I asked in the Emotion Slack workspace whether it's worth an upstream PR to add this to Emotion's We have a similar situation in the https://github.com/WordPress/Gutenberg repository:
Furthermore, we utilize iframes in Gutenberg and need a solution that hooks into the Emotion cache. We're in a similar situation here as well:
A TypeScript version of the hook exists here: https://github.com/WordPress/gutenberg/pull/33172/files#diff-f2e01286efb7fd67eb692fb1528160c4450145949d6e4f7daf5b1c6a205453d4 Like I said in Slack, happy to open a PR to add this functionality to Note: My approach, I believe, is rather naïve so I'm hoping for feedback from maintainers about whether this approach is viable and if there are modifications that need to be made. All my research into the Emotion source code says that it should be possible to accomplish things this way and I can't pinpoint any real issues with what I've done but I'd expect there to be at least some performance considerations that I haven't taken into account. |
I don't think a more complex return type is out of the question for this kind of hook. Lots of headless component libraries are returning lots of data from hooks so I think returning both the classname and the stylesheet within either an array or object would be fine. This also gives users the option to not use the included stylesheet if not using SSR.
|
Preface: I know this topic has already been brought up a few times (#1295, #967, #1321) but I have a use-case that I haven't seen mentioned before, and a proposed solution that side-steps the inherent complexity of this problem, while giving power-users what they need.
The problem
createCache
. So we don't need (or want) the functionality of adding sibling<style>
tags.The main issue as I understand it is that most people are going to need the version of Emotion that adds
<style>
tags next to the component that rendered them, so a hook is out of the question as it can't do that (at least not in a clean way). And exposing a hook that's only useful if you roll your own server-side rendering isn't ideal...Proposed solution
So I propose that instead of Emotion supplying users with a potentially confusing hook API, just expose some of the functionality that would be needed to create it (the guts of
ClassNames
) and let us power-users roll our own. That way we're not leading less-informed users astray from the pit of success, but also letting more advanced users integrate Emotion into their existing stack without pain.I'd be happy to take a stab at a PR that makes the minimal changes necessary to move this problem into 'user-land'. Is that something you'd be willing to consider merging?
The text was updated successfully, but these errors were encountered: