Difficulty understanding the usage of `cx` between packages
Description:
I've just started migrating a project to emotion, and am struggling to understand the usage patterns of the cx function from @emotion/css, specifically around two areas.
-
Short circuiting values for conditional classNames:
cx(state && className)There's no mention of this in the documentation, only the object-based
{ [className]: state }method, but I see it is possible after testing it out. Is this considered a bad or deprecated pattern? I'm coming from another library which supports it, and prefer the approach. -
Including
SerializedStylesfrom@emotion/react'scssThis doesn't work in
cx, and forces me to usecssfrom@emotion/cssinstead, but leaves me wondering if I'm choosing the right method for adding extra classNames? It feels like the react package should be the bestcssfunction to use, since I'm styling a React component. I think I would prefer there to be a version ofcxexported from/react, which supports combiningSerializedStylesas well so that I can remove the/csspackage, if that's possible.
Overall I feel like I'm juggling between three packages (/styled, /css, /react) a little too much, which often leaves me confused. Some extra documentation around these choices would be helpful.
Edit: in case it's useful, I prefer the styled method over the css prop method.
Documentation links: https://emotion.sh/docs/@emotion/css#cx
Also weirdly looking at the node_modules/@emotion/react/types/index.d.ts it states an interface cx but it doesn't work to import cx from import {cx} from '@emotion/react';.
export interface ClassNamesContent {
css(template: TemplateStringsArray, ...args: Array<CSSInterpolation>): string
css(...args: Array<CSSInterpolation>): string
cx(...args: Array<ClassNamesArg>): string
theme: Theme
}
I would also prefer to only import one single module and then work with it the same way https://github.com/JedWatson/classnames works. So I'd rather import that for now than using three different packages of emotion.
Those types don't declare a standalone cx helper but rather a function available to render prop of the ClassNames component.
Same here, confusing on how to import cx method from @emotion/react instead of installing @emotion/css
same here
Same. Anyone can help? Itβs a pain people cannot import cx from emotion/react
I am using a hook within I need to use cx because there is a property called cellClass and i need to merge two classes. If i try use emotion/react, i can only use cx with <ClassNames> (?? no sense, i don't render nothing there ???) so i must use cx from emotion/css...
It seems like i kind an error....
I run into the the same issue. But Isn't this this supposed to be the answer? https://emotion.sh/docs/@emotion/react#cx
If you're using @emotion/react or @emotion/styled, there is no need to install the @emotion/css package at all. The cx function from @emotion/css should only be used when generating class names with @emotion/css.
You can use the css function from @emotion/react to combine multiple object styles, CSS strings, SerializedStyles, .etc. The css function and css prop also support conditional styles like this:
const baseCss = css({ color: 'blue' })
const activeCss = css({ backgroundColor: 'gray' })
function MyComponent({ active }) {
return <div css={[baseCss, active && activeCss]} />
}
The only context where cx is relevant when using @emotion/react or @emotion/styled is when using <ClassNames>, which is documented here.
I'm going to try to improve the documentation around combining CSS & conditional CSS using the css function since we don't currently have a great example of it.
Thanks all for this thread.
I add also my confusion and what I have understood about the migration from Emotion Css to Emotion React.
I landed here because I just needed to add a class string to a className from an external stylesheet (in my case for a icon class Name) and I didn't understand how to do it with Emotion React.
Before using Emotion React with Emotion CSS, I could do:
<div
className= {cx('my-icon-class-name', props.className, css`....`)}
>
</div>
Easy to read (minimal boilerplate), easy to write, great! Thanks.
It took me some time to go over to Emotion React. From what I understand,
- For the Emotion CSS cx function, you need to use the ClassName component (to integrate an external class name), this is way backward in terms of simplicity and boilerplate.
- For the Emotion CSS css function, you need to use it within the special css prop (the Emotion React css function creates an object and not a class name as the Emotion CSS css function)
I didn't see any added value of Emotion React, except Server side rendering and a sort of cascading optimization.
The css prop adds also an extra burden (typescript does not like it by default as any third-party UI library).
I'm just lost now on which option I need to take.
Quick Update: I migrated to the styled interface as:
- it's a nice way to attach css properties to a component
- it does not require any typescript configuration
- it's a defacto common standard (used by styled, mui, ...)
It would be great to have one package (or documentation) that is configured towards the styling interface.
Example:
- emotion-css
- emotion-react-css-prop
- emotion-react-styled
As a newbie, I was so confused.
And for cx, I have recreated it to concatenate classNames.
cx(...classes: (string | undefined | null)[]) {
// Filter out null and undefined values
const validClasses = classes.filter(arg => arg !== null && arg !== undefined);
// Join the non-null and non-undefined strings with a space
return validClasses.join(' ');
}
Thanks