storybook: Can't get emotion's css prop working inside storybook
Describe the bug
I can’t seem to get emotion’s css prop to work inside of Storybook. Seems like emotion is now the dominant css-in-js library, and the css prop is emotion’s recommended primary way of styling components, so I thought I was choosing a well-travelled happy path here, but I’m stuck. I’m very open to the fact that I’m doing something dumb though, of course.
In my actual project repo I’m getting the same thing described here and here. I tried all of the recommendations in both those threads, and still no joy – and it looks like I’m not the only one.
So, I created a brand new React Storybook repo to just hello-world using emotion css prop and storybook. And I can’t get that to work either! I’m wondering if someone could look at the super simple repro repo I made and tell me where I went wrong, here it is:
https://github.com/jaredh159/storybook-emotion-css
I’d be up for submitting a PR to the docs clarifying how to do this, if someone can show me where I messed up.
To Reproduce Steps to reproduce the behavior:
git clone git@github.com:jaredh159/storybook-emotion-css.gitcd storybook-emotion-css && yarn && yarn storybook- Load http://localhost:6016 and see the error 😦
TypeError: Cannot read property 'name' of null
Expand for full error message
ERROR in ./src/CssPropButton.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
TypeError: Cannot read property 'name' of null
at getDeclaratorName (/test-repo/node_modules/babel-plugin-emotion/dist/babel-plugin-emotion.cjs.dev.js:212:32)
at getIdentifierName (/test-repo/node_modules/babel-plugin-emotion/dist/babel-plugin-emotion.cjs.dev.js:267:24)
at getLabelFromPath (/test-repo/node_modules/babel-plugin-emotion/dist/babel-plugin-emotion.cjs.dev.js:190:19)
at transformExpressionWithStyles (/test-repo/node_modules/babel-plugin-emotion/dist/babel-plugin-emotion.cjs.dev.js:450:19)
at transformCssCallExpression (/test-repo/node_modules/babel-plugin-emotion/dist/babel-plugin-emotion.cjs.dev.js:708:31)
at /test-repo/node_modules/babel-plugin-emotion/dist/babel-plugin-emotion.cjs.dev.js:797:9
at Array.forEach (<anonymous>)
at /test-repo/node_modules/babel-plugin-emotion/dist/babel-plugin-emotion.cjs.dev.js:796:26
at Array.forEach (<anonymous>)
at Object.emotionCoreMacroThatsNotARealMacro [as @emotion/core] (/test-repo/node_modules/babel-plugin-emotion/dist/babel-plugin-emotion.cjs.dev.js:794:27)
at PluginPass.ImportDeclaration (/test-repo/node_modules/babel-plugin-emotion/dist/babel-plugin-emotion.cjs.dev.js:891:45)
at newFn (/test-repo/node_modules/@babel/traverse/lib/visitors.js:193:21)
at NodePath._call (/test-repo/node_modules/@babel/traverse/lib/path/context.js:53:20)
at NodePath.call (/test-repo/node_modules/@babel/traverse/lib/path/context.js:40:17)
at NodePath.visit (/test-repo/node_modules/@babel/traverse/lib/path/context.js:88:12)
at TraversalContext.visitQueue (/test-repo/node_modules/@babel/traverse/lib/context.js:118:16)
@ ./stories/index.stories.js 5:0-49 6:143-156
@ ./stories sync \.stories\.js$
@ ./.storybook/config.js
@ multi ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/config.js (webpack)-hot-middleware/client.js?reload=true
Expected behavior
I expected to be able to use the css prop from emotion within Storybook.
Code snippets
The repro repo does add a .babelrc inside the stories dir as recommended in the emotion docs and on this similar issue, like so:
{
"presets": ["@emotion/babel-preset-css-prop"]
}
I also tried this workaround, but no joy.
System:
- OS: Mac
- Device: Macbook Pro 2015
- Browser: Chrome
- Framework: React
- Version: 5.1.9
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 26
- Comments: 61 (16 by maintainers)
Commits related to this issue
- Replace @emotion/core with @emotion/css Removed because of storybook not loading when a @jsx pragma is used See https://github.com/storybookjs/storybook/issues/7540 — committed to daniel-hauser/react-organizational-chart by daniel-hauser 3 years ago
- fix styling issues in storybook https://github.com/storybookjs/storybook/issues/7540 — committed to chrisirhc/modular-ramp by chrisirhc 3 years ago
- fix bug emotion がStorybookでも動作するように https://github.com/storybookjs/storybook/issues/7540#issuecomment-934216060 — committed to warugaki-web-developer/starter-vite-react-ts by warugaki-web-developer 3 years ago
- ✅🐛 Make sure xstyled fonts are transformed and applied in storybook https://github.com/storybookjs/storybook/issues/7540#issuecomment-1061112737 — committed to D1no/curriculumvitae by D1no 2 years ago
- chore: storybook emotion 설정 - https://github.com/storybookjs/storybook/issues/7540 — committed to depromeet/www.depromeet.com by kimyouknow 10 months ago
- [Feat] Icon 컴포넌트 세팅 & storybook emotion 설정 (#251) * chore: storybook emotion 설정 - https://github.com/storybookjs/storybook/issues/7540 * feat: svg wrapper component * feat: arrow icon — committed to depromeet/www.depromeet.com by kimyouknow 10 months ago
- [feat] FAQ 컴포넌트 (#255) * chore: storybook emotion 설정 - https://github.com/storybookjs/storybook/issues/7540 * feat: svg wrapper component * feat: arrow icon * feat: typo theme * feat: ... — committed to depromeet/www.depromeet.com by kimyouknow 10 months ago
I fixed it with the settings below. Hope it helps someone.
pacakge.json
.storybook/main.js
We’ve just encountered this issue. The project uses
"typescript": "^4.3.2","@emotion/react": "^11.4.1","@storybook/react": "^6.3.8".tsconfig.json has
"jsx": "react-jsx", "jsxImportSource": "@emotion/react",settings.To fix it,
npm i -D @emotion/babel-preset-css-propand in.storybook/main.jsadd it to the default presets:So far so good.
@DominicTobias-b1 — recently upgraded to Emotion 11 with the latest storybook (6.1.xx). Here are the relevant details of my setup. We are using recent Typescript (4.1.x) + Babel (7.12.x), so YMMV depending on your setup.
I switched my components to use new “automatic” React JSX transform. I find this the only reasonable and clean way forward. Note: this requires Typescript 4.1 or higher (see https://emotion.sh/docs/emotion-11#css-prop-types)
In babel configuration add
runtimeandimportSource, and@emotion/babel-plugin. Excerpt:In Typescript configuration (tsconfig.json) add:
We keep
jsx: preserve, since we are not using Typescript to transform JSX, but Emotion babel plugin.Storybook is still using Emotion 10 and depends on the “classic” React JSX transformation so you have to add custom babel configuration under
.storybookfolder that will usebabel-preset-css-prop. Here is excerpt of.storybook/babel.config.js:Also see discussion under #13145
In my project I was able to get Storybook to recognize css-prop (without using the jsx pragma) by adding this config to
/.storybook/webpack.config.js.Line 17 - Line 19:
Also, I am including the
@emotion/babel-preset-css-propfor.tsand.tsxfilesLine 41 - Line 43:
I created a template to share my project config that uses Gatsby + TypeScript + Emotion + Storybook + React Intl + SVGR + Jest: https://github.com/duncanleung/gatsby-typescript-emotion-storybook
Here’s a link to my
webpack.config.jsthat enables@emotion/babel-preset-css-prop:For those people who want to use css prop in CRA based project with TS, modify your
.storybook/main.jsas below:There are 2 solutions:
@emotion/babel-preset-css-prop.babel-loaderto use a custom configuration.Both of these versions are super hacky and aren’t the correct solution nor will they always be guaranteed to work through Storybook upgrades.
Instead, forget the Webpack config altogether. Storybook has a native way of modifying the Babel config: https://storybook.js.org/docs/react/configure/babel
The proper option is adding Babel overrides:
Thanks @ndelangen & @nerdyman - I didn’t know you could set a
babelexport.Here’s the
.storybook/main.jsI ended up with, using Storybook6.0.12With the solutions above I get this in the DOM:
Don’t know what I’m missing. I’m using this same Babel configuration for the project build and it works fine.
It worked with the following settings. Just for reference.
.storybook/main.jsdependenciesI cannot get this to work at all. The only way I can get this to work is if I use the jsx pragma, and then, it breaks storybook’s ability to generate or infer prop descriptions for the docs. I’m not certain, but I’m assuming this is because both storybook’s doc addon and emotion want to rewrite React.createElement?
If that helps anyone, here is what worked for me (using storybook 7):
@crushjz Thanks sir, now it’s works!
Adding this in
.storybook/main.jsworked for me. Thanks for mentioning.Here’s the
.storybook/main.jsthat works for me, using Storybook5.3.19The OG post is unrelated to most of the discussion on this thread. I actually pulled his repo and fixed the error. He was exporting an anonymous component.
Error message:
TypeError: /storybook-emotion-css/src/CssPropButton.js: Cannot read property 'name' of nullOriginal CssPropButton.js:
Fixed with no error:
Unfortunately, this didn’t solve the error I am having. His build set with the
.bablercin.storybookdir is working fine.Thanks. This option seems to do the trick.
I’m seemingly bumping into this too. Also have tried all the suggested workarounds in the referenced issues.
My CSS props work just fine outside of Storybook but once I am running in storybook my css props aren’t working. Anything that’s basically just a string works but any time I am referencing props in the
css/styledtag, the css property name isn’t present.There are 2 babel configs you have to worry about. Depending on if you have JSX Pragma setup correctly and the latest babel-preset-react, it changes which you’ll want to use.
@emotion/babel-pluginis used when you’re using React v17 or higher, you’ll want this comment at the top of each file using Emotion:^^ You need this for Create-React-App.
If you have the correct react babel preset with JSX pragma set to
automatic, then using the@emotion/babel-pluginworks out-of-the-box without anyjsximport or that comment.If you have an older React, you’ll want to use
@emotion/babel-preset-css-prop. You can use both in your project, but I’d recommend figuring out how to get@emotion/babel-pluginfor all builds or simply add thejsxRuntimecomment.I know this is confusing, and I don’t fully understand it myself, but I’ve dealt with these issues on many projects.
Getting Emotion working Next.js was probably one of the hardest, but I figured out a hack-fix to make it work.
@se7entyse7en - if you link the repository or a minimal repro I will take a look for you
Perhaps we could create a storybook preset for emotion?
@JakeElder would you be interested in helping us with that?
There’s a
babelproperty inmain.jstoo that allows you to change the babel config, without having to find the exact webpack loader. That’s a bit safer, since it’s pretty fragile to find the correct loader to mutate this way.In case this helps anybody, I just upgraded to storybook 7 and the
babel-preset-css-propsolution didn’t work for me, but settingimportSource: "@emotion/react"did!I managed to make it work using TypeScript + Emotion 11 and JSX Pragma.
v4.1.411.1.5v6.1.17I’m not using Babel at all because I want to typecheck during build.
I had to change the
@babel/preset-reactruntime to be “classic” in order to use the JSX Pragma..storybook/main.js:Yes. This is probably unavoidable in some scenarios until Storybook changes. If you are transpiling with TS (not Babel) try to create custom tsconfig for storybook to disable
noUnusedLocals.@caspardue is that something we can add to Storybook’s MDX loader/compiler somehow?
Feel free to open a meeting request with me, and I can show you around the codebase, get your started: https://calendly.com/ndelangen/storybook
Here’s the docs for writing presets: https://storybook.js.org/docs/react/api/writing-presets
@ndelangen I couldn’t find an example using a custom
babelprop inmain.js. To get it working I imported Storybook’s default Babel config and added it into thebabelconfig inmain.js.This is what I ended up with:
Is there a better way to do it? It would be cool to add to the default config rather than replacing it.
🙌
require.resolve('@emotion/babel-preset-css-prop')+ blowing awaynode_modulesand rerunningyarnfixed it.Based our now working config kinda on this: https://github.com/emotion-js/emotion/issues/1359#issuecomment-509798083 but with some additional crap for resolving sass stuff (we’re in the process of migrating and our storybook stuff stopped working without anyone noticing).
Sorry for any inconvenience and thanks for the awesome library.