Docz: Component not render correctly using only emotion CSS props

Created on 29 Dec 2018  Â·  13Comments  Â·  Source: doczjs/docz

Bug Report

Given the following basic component code

// @flow
import React from 'react'
import { css } from '@emotion/core'

const base = css`
  color: red;
`

export const Button = ({ children }) => <button css={base}>{children}</button>

.babelrc

{
  "presets": ["@babel/preset-flow", "@emotion/babel-preset-css-prop"]
}

Expected behavior

It should render a button with red color on it. But instead the css is not loaded correctly

Additional context/Screenshots
docz example flow 2018-12-29 20-12-20
docz example flow 2018-12-29 20-12-53

Most helpful comment

I had the same problem and @mitchellhamilton one of the maintainer of Emotion helped me.

Docz appends its babel preset to the user provided config so since its babel preset includes @babel/preset-react which includes the react jsx transform which @emotion/babel-preset-css-prop also uses. So Docz's usage of the react JSX transform is used by default.

To fix this, we're including the JSX transform plugin in the plugins in our doczrc.js file.
This works because plugins in the config take precedence over plugins in presets.

plugins: [
    createPlugin({
      modifyBabelRc(babelrc) {
        return {
          ...babelrc,
          plugins: [
            ...babelrc.plugins,
            [
              '@babel/plugin-transform-react-jsx',
              { pragma: '___EmotionJSX', pragmaFrag: 'React.Fragment' },
            ],
          ],
        };
      },
    }),
  ],

Credits to @mitchellhamilton

All 13 comments

I'm also experiencing this

So, do you need to set the pragma, no?!

so, I've tested it using jsx pragma for the component, also remove @emotion/babel-preset-css-prop preset and it works fine.

but maybe it will easier if I don't have to use jsx pragma on each of my component files.

for now I'll use the pragma way.

thanks.

I'm getting issue with both the pragma and the babel preset – my issue seems to be that I'm using TypeScript, since it works fine for me just using .js files. If it helps, I can set up a demo repo.

I'm seeing the same issue but in js files, tried adding the preset by modifying babelrc in my docz config file, didn't do anything. The component that is being rendered in the playground does have the jsx pragma set at the top of the file

Same here, with a pure TS setup. From browsing emotion-js/emotion#1046 the only solution I found was to set "jsx": "preserve" in the tsconfig.json and then using /** @jsx jsx */ in any TS file.

Same here. I worked around it by removing the docz babel preset.
My docz setup is running in the same project as my webapp, so everything I need for ESNext & React etc is already configured in my project's .babelrc.

my docz.js looks like this:

module.exports = {
    modifyBabelRc: babelRc => {
        // Remove conflicting docz preset
        babelRc.presets.pop();

        // Optional: Add plugin to make docz's `parseProps` feature work
        babelRc.plugins.unshift([
            'babel-plugin-react-docgen',
            { resolver: 'findAllExportedComponentDefinitions' }
        ]);
        return babelRc;
    }
}

It would be nice if there was an option to make _babel-preset-docz_ skip some of its plugin loading if you already have babel & react configured.

I had the same problem and @mitchellhamilton one of the maintainer of Emotion helped me.

Docz appends its babel preset to the user provided config so since its babel preset includes @babel/preset-react which includes the react jsx transform which @emotion/babel-preset-css-prop also uses. So Docz's usage of the react JSX transform is used by default.

To fix this, we're including the JSX transform plugin in the plugins in our doczrc.js file.
This works because plugins in the config take precedence over plugins in presets.

plugins: [
    createPlugin({
      modifyBabelRc(babelrc) {
        return {
          ...babelrc,
          plugins: [
            ...babelrc.plugins,
            [
              '@babel/plugin-transform-react-jsx',
              { pragma: '___EmotionJSX', pragmaFrag: 'React.Fragment' },
            ],
          ],
        };
      },
    }),
  ],

Credits to @mitchellhamilton

Thanks, @ticidesign for the solution. I close this issue

~I have tried both @ticidesign and @simonflk and they do not work... I am sure I am missing something something small...~

Putting this as my .babelrc seems to work for me...

{
  "presets": ["react-app", "@emotion/babel-preset-css-prop"]
}

I did not need any of the "hacks" above. My issue was that I was importing css from emotion not @emotion/core

@ticidesign @mitchellhamilton Do you have a solution for Gatsby v2? I've tried various combinations of gatsby-node and doczrc to no avail.

Hey @gsong,

I tried a basic setup of docz with the example code provided above and it works as expected :

import React from 'react'
import { css } from '@emotion/core'

const base = css`
  color: red;
`

export const Button = ({ children }) => <button css={base}>{children}</button>

Any chance you can provide a repro repo ?

@rakannimer I think the issue was using the css prop while in a <Playground> component. I don't have a good repro repo right now.

The same issue with using the sx prop from theme-ui while inside <Playground>.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ssylvia picture ssylvia  Â·  3Comments

w0wka91 picture w0wka91  Â·  3Comments

tsnolan23 picture tsnolan23  Â·  3Comments

mariusespejo picture mariusespejo  Â·  3Comments

bichotll picture bichotll  Â·  3Comments