Search code examples
reactjstypescriptstorybookemotion

Component selector error with Storybook/React/Typescript and Emotion


I am trying to get Emotion to play nice with Component selectors.

But when I am doing this:

const Test = styled.div`
  color: blue;
`;

const Test2 = styled.div`
  ${Test} {
    color: red;
  }
`;

Then I get this error: Component selectors can only be used in conjunction with babel-plugin-emotion.

And I can't seem to fix it - seen similar issues on the emotion repo, but solutions there doesn't seem to work have tried @emotion/styled/macro with no luck.

Should maybe mention that I am using emotions theming also.

My .babelrc file:

{
  "presets": ["@babel/react", "@babel/preset-env", "@babel/preset-typescript"],
  "plugins": [
    "@babel/plugin-transform-runtime",
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-proposal-object-rest-spread",
    [
      "transform-inline-environment-variables",
      {
        "include": ["NODE_ENV"]
      }
    ],
    "emotion"
  ]
}

tsconfig.js:

{
  "compilerOptions": {
    "outDir": "dist",
    "module": "esnext",
    "lib": ["dom", "esnext"],
    "moduleResolution": "node",
    "jsx": "react",
    "sourceMap": true,
    "declaration": true,
    "esModuleInterop": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "suppressImplicitAnyIndexErrors": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "allowSyntheticDefaultImports": true,
    "resolveJsonModule": true
  },
  "include": ["src"],
  "exclude": ["node_modules", "dist", "**/__mocks__/*"]
}

Using babel-loader in webpack:

      {
        test: /\.(ts|js)x?$/,
        use: 'babel-loader',
        exclude: /node_modules/,
      },

And storybook main.js setup:

const path = require('path');

module.exports = {
  stories: ['../src/components/**/*.stories.tsx'],
  addons: [
    '@storybook/addon-actions',
    '@storybook/addon-links',
    '@storybook/addon-knobs',
    '@storybook/addon-actions/register',
    '@storybook/addon-viewport/register',
    '@storybook/addon-storysource',
    '@storybook/addon-backgrounds/register',
  ],
  webpackFinal: async (config) => {
    config.module.rules.push({
      test: /\.(ts|tsx)$/,
      loader: require.resolve('babel-loader'),
      options: {
        plugins: ['emotion'],
        presets: [['react-app', { flow: false, typescript: true }]],
      },
    });

    config.resolve.extensions.push('.ts', '.tsx');
    return config;
  },
};

And finally all the devPackages in package.json:

    "@babel/cli": "^7.8.4",
    "@babel/core": "^7.9.6",
    "@babel/plugin-external-helpers": "^7.8.3",
    "@babel/plugin-proposal-class-properties": "^7.8.3",
    "@babel/plugin-proposal-object-rest-spread": "^7.9.6",
    "@babel/plugin-transform-runtime": "^7.10.0",
    "@babel/preset-env": "^7.10.0",
    "@babel/preset-react": "^7.10.0",
    "@babel/preset-typescript": "^7.9.0",
    "@emotion/core": "^10.0.28",
    "@emotion/styled": "^10.0.27",
    "@storybook/addon-actions": "^6.0.21",
    "@storybook/addon-backgrounds": "^6.0.21",
    "@storybook/addon-knobs": "^6.0.21",
    "@storybook/addon-links": "^6.0.21",
    "@storybook/addon-storysource": "^6.0.21",
    "@storybook/addon-viewport": "^6.0.21",
    "@storybook/addons": "^6.0.21",
    "@storybook/react": "^6.0.21",
    "@svgr/webpack": "^5.4.0",
    "@testing-library/jest-dom": "^5.10.1",
    "@testing-library/react": "^10.0.4",
    "@types/jest": "^25.2.3",
    "@types/react": "^16.9.35",
    "@types/react-dom": "^16.9.8",
    "@types/react-test-renderer": "^16.9.2",
    "@types/styled-system": "^5.1.9",
    "@typescript-eslint/eslint-plugin": "^3.3.0",
    "@typescript-eslint/parser": "^3.3.0",
    "autoprefixer": "^9.8.0",
    "babel-jest": "^26.0.1",
    "babel-loader": "^8.1.0",
    "babel-plugin-emotion": "^10.0.33",
    "babel-plugin-external-helpers": "^6.22.0",
    "babel-plugin-macros": "^2.8.0",
    "babel-plugin-named-asset-import": "^0.3.6",
    "babel-plugin-transform-inline-environment-variables": "^0.4.3",
    "babel-preset-env": "^1.7.0",
    "babel-preset-preact": "^2.0.0",
    "babel-preset-react-app": "^9.1.2",
    "clean-webpack-plugin": "^3.0.0",
    "copy-webpack-plugin": "^6.0.1",
    "cross-env": "^7.0.2",
    "css-loader": "^3.5.3",
    "eslint": "^7.2.0",
    "eslint-config-prettier": "^6.11.0",
    "eslint-plugin-prettier": "^3.1.4",
    "eslint-plugin-react": "^7.20.5",
    "eslint-plugin-react-hooks": "^4.0.8",
    "html-webpack-plugin": "^4.3.0",
    "husky": "^4.2.5",
    "jest": "^26.0.1",
    "jest-canvas-mock": "^2.2.0",
    "jest-matchmedia-mock": "^1.0.1",
    "lint-staged": "^10.2.6",
    "node-sass": "^4.14.1",
    "postcss-loader": "^3.0.0",
    "prettier": "^2.0.5",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-spring": "^8.0.27",
    "react-test-renderer": "^16.13.1",
    "react-use-gesture": "^7.0.15",
    "sass-loader": "^8.0.2",
    "semver": "^7.3.2",
    "style-loader": "^1.2.1",
    "styled-system": "^5.1.5",
    "svg-react-loader": "^0.4.6",
    "typescript": "^3.9.3",
    "url-loader": "^4.1.0",
    "webpack": "^4.43.0",
    "webpack-bundle-analyzer": "^3.8.0",
    "webpack-cli": "^3.3.11",
    "webpack-dev-server": "^3.11.0",
    "webpack-merge": "^4.2.2"

Solution

  • Ok apparently this is a known issue when importing styled from another location, like suggested here: https://emotion.sh/docs/typescript#define-a-theme

    Conclusion: https://github.com/emotion-js/emotion/issues/1305#issuecomment-660401782