Skip to content
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

Emotion 11 #1606

Closed
emmatown opened this issue Nov 4, 2019 · 69 comments · Fixed by #1600
Closed

Emotion 11 #1606

emmatown opened this issue Nov 4, 2019 · 69 comments · Fixed by #1600
Milestone

Comments

@emmatown
Copy link
Member

emmatown commented Nov 4, 2019

We're planning to do a major version of Emotion soon, we don't have a definite timeline but it should be out before the end of the year, most likely earlier.

We don't currently have any massive API changes planned but there will be some package renaming which should be possible to migrate with codemods alone. (This isn't anything like the v9 -> v10 change)

The big changes that we are currently doing:

We'll update this issue for larger planned changes. For smaller changes, please see the v11 milestone. The issues on the milestone aren't necessarily going to be addressed in v11 but we'll consider them.

We are already doing pre-releases which will be available on the next dist tag on npm.

@kevinrodriguez-io
Copy link

Regarding to @emotion/native@next

For some reason I'm not getting the types folder installed on my node_modules and all my types are blank.

Is there any reason for this?

@Andarist
Copy link
Member

The version with those typings has not been published yet, I will do that in a moment.

@kevinrodriguez-io
Copy link

@Andarist Thanks a lot! The new typings are working great.

I'm getting theme intellisense by doing this:

types.ts

interface Theme {
  colors: {
    // Color palette here
  },
  fonts: {
    sansSerif: {
      thin: string,
      regular: string,
      bold: string,
      black: string
    }
  }
}

interface EmotionComponentProps {
  theme?: Theme
}

PinDot.ts

import styled from '@emotion/native'
import { EmotionComponentProps } from 'types'

interface PinDotProps extends EmotionComponentProps {
  active: boolean
}

const PinDot = styled.View<PinDotProps>(
  {
    width: 16,
    height: 16,
    borderRadius: 16,
  },
  ({ active, theme }) => ({
    backgroundColor: active
      ? theme.colors.flatPurple.light
      : theme.colors.flatWhite.dark,
  }),
)

export default PinDot

@thewavelet
Copy link

Thank you for your great awesome works! And I have two questions.
When is v11 going to release?
Can I use v11 in advance with yarn add @emotion/core@next @emotion/native@next commands?
Because I need react native typings.

@kevinrodriguez-io
Copy link

@thewavelet You can add it by using:

yarn add @emotion/react@next @emotion/native@next

You'll have to remove @emotion/core and emotion-theming, both packages are now part of @emotion/react

@Andarist
Copy link
Member

When is v11 going to release?

When it's ready 😉

@thewavelet
Copy link

Thank you! I will use emotion instead of styled-components.

@META-DREAMER
Copy link
Contributor

I'm having trouble using @emotion/native this in Expo Web / react-native-web. I get the following error when compiling the web target:

 web  Starting Webpack on port 19006 in development mode.
  build [====================] 100%

 web  Failed to compile.
.../rn-app/node_modules/@react-navigation/bottom-tabs/lib/module/views/BottomTabBar.js
Module not found: Can't resolve 'react-native-web/dist/exports/Animated' in '.../rn-app/node_modules/@react-navigation/bottom-tabs/lib/module/views'

Any guidance here?

@META-DREAMER
Copy link
Contributor

Is there plans to improve support for the css prop in @emotion/native ? Seems to be the new recommended approach instead of using the styled.View syntax.

@NoobsArePeople2
Copy link

When is v11 going to release?

When it's ready 😉

Hate to be the guy who piles on this question but I need to ask.

I'm looking at migrating a significant amount of code from Emotion 9 to Emotion 10 in the near future and would like to avoid having to then migrate to Emotion 11 after completing the first migration. It sounds like the Emotion 11 API will be very similar to 10 so the level of effort in migrating 9 --> 11 is similar to 9 --> 10.

Can you provide a ballpark estimate on delivery?

@Andarist
Copy link
Member

Andarist commented Feb 2, 2020

It's hard to tell - previously I thought that we are going to ship it in December, but now I hope for February. No promises though, we are doing it in our free time and there is no much of it lately.

V11 is pretty much done though and is published on npm, so I would encourage you to try it out - even if it's not yet marked with the "latest" tag.

The biggest leftover for v11 (which is not quite mentioned anywhere) is a stylis.js rewrite (our underlying parser). It's happening, just slowly - we are working out the plugin API (parser itself is ready).

@META-DREAMER
Copy link
Contributor

@Andarist thanks for the update and for all the hard work!

@kevinrodriguez-io
Copy link

Turns out you don't need to declare an interface and inherit it everywhere 😄 you can use Typescript's Declaration merging!

emotion.d.ts

import '@emotion/react'

declare module '@emotion/react' {
  export interface Theme {
    colors: {
      primary: string
      secondary: string
      light: string
      dark: string
    }
    fonts: {
      sansSerif: {
        thin: string
        regular: string
        bold: string
        black: string
      }
    }
  }
}

@jsejcksn
Copy link

It looks like the @emotion/react umd module is still being assigned to window.emotionCore. It should be changed to window.emotionReact, yes?

@Andarist
Copy link
Member

@jsejcksn Yes, just changed it: 9e833ba . Should be available with the next release.

@chaance
Copy link

chaance commented May 5, 2020

This appears to be a catch-all issue for everything v11, so asking here: is there a reason that CreateStyled is no longer a generic interface that accepts a custom theme type def? I modified the types locally with what I think should be the intended types and can submit a PR if it's helpful, but let me know if I missed something here.

declare module '@emotion/styled' {
  // ...
  export interface BaseCreateStyled<CustomTheme extends Theme = {}> {
    <
      C extends React.ComponentType<React.ComponentProps<C>>,
      ForwardedProps extends keyof React.ComponentProps<
        C
      > = keyof React.ComponentProps<C>
    >(
      component: C,
      options: FilteringStyledOptions<PropsOf<C>, ForwardedProps>
    ): CreateStyledComponent<
      Pick<PropsOf<C>, ForwardedProps> & { theme?: CustomTheme }
    >;

    <C extends React.ComponentType<React.ComponentProps<C>>>(
      component: C,
      options?: StyledOptions<PropsOf<C>>
    ): CreateStyledComponent<PropsOf<C> & { theme?: CustomTheme }>;

    <
      Tag extends keyof JSX.IntrinsicElements,
      ForwardedProps extends keyof JSX.IntrinsicElements[Tag] = keyof JSX.IntrinsicElements[Tag]
    >(
      tag: Tag,
      options: FilteringStyledOptions<
        JSX.IntrinsicElements[Tag],
        ForwardedProps
      >
    ): CreateStyledComponent<
      { theme?: CustomTheme },
      Pick<JSX.IntrinsicElements[Tag], ForwardedProps>
    >;

    <Tag extends keyof JSX.IntrinsicElements>(
      tag: Tag,
      options?: StyledOptions<JSX.IntrinsicElements[Tag]>
    ): CreateStyledComponent<
      { theme?: CustomTheme },
      JSX.IntrinsicElements[Tag]
    >;
  }

  export type StyledTags<CustomTheme extends Theme = {}> = {
    [Tag in keyof JSX.IntrinsicElements]: CreateStyledComponent<
      { theme?: CustomTheme },
      JSX.IntrinsicElements[Tag]
    >;
  };

  export interface CreateStyled<CustomTheme extends Theme = {}>
    extends BaseCreateStyled<CustomTheme>,
      StyledTags<CustomTheme> {}

  declare const styled: CreateStyled;
  export default styled;
}

@Andarist
Copy link
Member

Andarist commented May 5, 2020

@chancestrickland we've changed how you can configure Theme type to what should (I believe) be way more convenient than the previous solution, see https://deploy-preview-1600--emotion.netlify.app/docs/typescript#define-a-theme

@chaance
Copy link

chaance commented May 5, 2020

Ah beautiful, I agree that works even better. Thanks @Andarist!

@Andarist
Copy link
Member

Andarist commented May 5, 2020

No problem, hope you enjoy Emotion 11 - we hope to ship it soon-ish (but I also thought it was going to be shipped in 2019 😅).

@andrewphillipo
Copy link

Just in case you want to generate the theme type automatically rather than having to declare it you can see my solution here: #1861 (comment)

@chaance
Copy link

chaance commented May 5, 2020

@Andarist any thoughts on still allowing the generic workaround in v11? I agree that the new solution is nicer, but are there any drawbacks to using both techniques for a less breaking change? Might be useful for migrating existing projects.

@Andarist
Copy link
Member

Please always try to share a repro case in a runnable form - either by providing a git repository to clone or a codesandbox. OSS maintainers usually can't afford the time to set up the repro, even if exact steps are given.

@ljosberinn
Copy link

ljosberinn commented Nov 12, 2020

@eddyzera you seem to be using either chakra v0 or unnecessarily added @emotion/core to a v1 project (currently, in v1, you do not need to install it separately).

  • if youre using v0, you'll have to pin emotion dependencies to 10.x, I believe /core to 10.0.27 or lower and /styled to 10.0.35 or lower
  • if youre using v1, simply remove all emotion dependencies from your package json, remove lock file, remove node_modules and reinstall. the latest rc includes emotion by default.

v1 will most likely add @emotion/react as well as a few others as peer dependencies, but for the time being this will fix it.

@Fabrus98
Copy link

@ljosberinn hi, i just got the error
./node_modules/@chakra-ui/core/dist/es/Accordion/index.js Module not found: Can't resolve '@emotion/core' in 'C:\Users\Administrateur\Desktop\ItalianHUBot\dashboard-client\node_modules\@chakra-ui\core\dist\es\Accordion'
trying to use @chakra-ui. I don't know how to fix it, i'm learning use react.js.
Hope someone could help me, thanks.

@Andarist
Copy link
Member

Either install @emotion/core or upgrade your Chakra version to v1

@ljosberinn
Copy link

@Fabrus98 please file an issue in the chakra-ui repository, not here. alternatively, join our Chakra discord for faster triaging: https://discord.gg/vw7tQnvp

@Vadorequest
Copy link

Vadorequest commented Jan 10, 2021

I'm a bit lost by reading https://emotion.sh/docs/emotion-11, I'm migrating from v10 to v11, using Next.js.

Here is a simple component:

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

import AnimatedLoader from '../svg/AnimatedLoader';

type Props = {}

const Loader: React.FunctionComponent<Props> = (props): JSX.Element => {
  return (
    <div
      css={css`
        justify-content: center;
        text-align: center;
        margin-left: auto;
        margin-right: auto;
      `}
    >
      <AnimatedLoader />
    </div>
  );
};

export default Loader;

It compiles properly and displays correctly, but in WebStorm, I get a TS2322: Type '{ children: Element; css: SerializedStyles; }' is not assignable to type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'.   Property 'css' does not exist on type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'. error message.

image

Here is my babel.config.js:

/**
 * Babel configuration for Next.js
 * 
 * @see https://nextjs.org/docs/advanced-features/customizing-babel-config Official doc reference v10
 * @see https://github.com/vercel/next.js/blob/canary/packages/next/build/babel/preset.ts You can take a look at this file to learn about the presets included by next/babel.
 * @see https://emotion.sh/docs/css-prop##babel-preset Configuring Emotion 11
 * @example https://github.com/vercel/next.js/tree/canary/examples/with-custom-babel-config Next.js official example of customizing Babel
 */
module.exports = {
  presets: [
    [
      "next/babel",
      {
        "preset-react": {
          "runtime": "automatic",
          "importSource": "@emotion/react"
        }
      }
    ]
  ],
  plugins: ["@emotion/babel-plugin"],
};

I'm especially confused about the @jsx jsx stuff.

I removed it at some point back in v10, and it worked okay, I was using @emotion/babel-preset-css-prop. I've removed @emotion/babel-preset-css-prop today as it seems it shouldn't be kept anymore. See https://emotion.sh/docs/@emotion/babel-preset-css-prop.

image

My understanding is I'm trying to use the "automatic" mode. I followed the doc at https://emotion.sh/docs/css-prop##babel-preset and modified my above-mentioned Babel config.

What am I missing? Automatic mode is enabled, I don't use the JSX Pragma, I've migrated to the new @emotion/react, applied the codemod v11 and ran them. 🤔

⚠️ Edit: It works locally, but fails to build on Vercel.

image


Commits:

PR: UnlyEd/next-right-now#241

@Vadorequest
Copy link

Vadorequest commented Jan 10, 2021

It seems adding /// <reference types="@emotion/react/types/css-prop" /> to next-env.d.ts file fixes the issue. See https://emotion.sh/docs/emotion-11#css-prop-types

Commit: UnlyEd/next-right-now@2a3c89d

(but I still have other TS issues due to how the theme has changed in v11, still on it)


Edit: Migrated the theme successfully. See commit UnlyEd/next-right-now@6cc3c7e

@Vadorequest
Copy link

Eventually, I had to downgrade to Emotion 10.

The main reason is the babel changes you recommend are far from being compatible with all other vendors, and in my case it broke Cypress entirely. (for other people, it seems it broke MDX)
See vercel/next.js#20952

So, short feedback, but this upgrade was awful from a developer experience standpoint. Not only was it complicated and affected many things (babel, theme, TS types) but in the end I couldn't even benefit from it and had to revert. 😖

I think you should mention in https://emotion.sh/docs/css-prop#babel-preset using the Babel preset might affect other 3rd party libs (e.g: MDX, Cypress), and using JSX pragma is safer for now.

In my case, it was impossible to know it wouldn't work with Cypress until the very end. I wish other people don't run into this.

@Andarist
Copy link
Member

The TypeScript page of our docs mentions what has to be done to make the css prop work out of the box - TS 4.1 is required for it to work.

As to next.js - I've successfully used Emotion 11 in next.js project and I didn't really have to configure anything in a special - apart from next/babel preset. If this doesn't work for you maybe you are using some older version of next.js?

Not sure what's going with Cypress - would have to get a repro case and clear instructions on how to run a particular project so I could take a look. Cypress is not really responsible directly for anything related to JSX, TS etc - the whole thing is outsourced to webpack (in older versions to browserify). So the only logical explanation for this would be that something is misconfigured but since it's often a delicate interplay between various tools I can't just know what's going on given the provided information.

@Vadorequest
Copy link

The TypeScript page of our docs mentions what has to be done to make the css prop work out of the box - TS 4.1 is required for it to work.

Thanks for pointing this out, it's not mentioned in https://emotion.sh/docs/emotion-11#typescript and I had missed it.

I'm using Next.js 10, and the latest version of Cypress.

I made a reproduction at UnlyEd/next-right-now#247 after I reverted the Emotion 11 upgrade, to do it in a separate piece of work. The issue is mentioned at cypress-io/cypress#14471

I'll try using the jsxImportSource you mentioned, maybe that's the root cause for there Webpack compilation issue.

@Vadorequest
Copy link

Vadorequest commented Jan 11, 2021

It seems replacing cypress/tsconfig.json jsx: "react" option by "jsxImportSource": "@emotion/react" fixed the Webpack compilation issue when running Cypress.
See commit 914996e (#247)

I'm confused whether this is the right setting or if this should happen in tsconfig.json (instead of cypress/tsconfig.json). I wonder if part of the issue isn't because the cypress/tsconfig.json extends from tsconfig.json.


I also tried using "jsxImportSource": "@emotion/react" in main tsconfig.json, and it works too locally (but fails on Vercel). When I do that, I can remove /// <reference types="@emotion/react/types/css-prop" /> from my next-env.d.ts file.
See commit a6a0aff (#247)

The reason it fails is weird. Out of all my files using css={css...} only one fail, using:

    <Text
      css={css`
        margin: 30px;
    `}
    >
      {`
        This component is a template meant to be duplicated to quickly get started with new React components.

        Feel free to adapt it at your convenience
      `}
    </Text>

I believe the error is mine here, because the Text component doesn't describe a css property. I guess its Props should extend some native HTML element, but since the said HTML element (wrapper) is dynamic, I'm not sure how it should be described.


So, to summarize, this issue could have been avoided by specifying in https://emotion.sh/docs/emotion-11#typescript we had to use "jsxImportSource": "@emotion/react" in the tsconfig.json, as specified in https://emotion.sh/docs/typescript#css-prop. That's the requirement to avoid having to add /// <reference types="@emotion/react/types/css-prop" /> ourselves, and it also fixes my Cypress issue. 🎉

I encountered an additional bug with the Text component, but it's a migration issue from something that used to work. (and which does work when manually importing /// <reference types="@emotion/react/types/css-prop" />.

See UnlyEd/next-right-now#247

@Vadorequest
Copy link

Vadorequest commented Jan 11, 2021

I tried adding Storybook to my project and the css has bitten me again.

"@storybook/theming@6.1.11":
  version "6.1.11"
  resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-6.1.11.tgz#0e757e0562aedefc96bd1d12714d4c8e92823467"
  integrity sha512-zRChacVgKoU2BmpvwK1ntiF3KIpc8QblJT7IGiKfP/BNpy9gNeXbLPLk3g/tkHszOvVYtkaZhEXni4Od8tqy1A==
  dependencies:
    "@emotion/core" "^10.1.1"
    "@emotion/is-prop-valid" "^0.8.6"
    "@emotion/styled" "^10.0.23"
    "@storybook/client-logger" "6.1.11"
    core-js "^3.0.1"
    deep-object-diff "^1.1.0"
    emotion-theming "^10.0.19"
    global "^4.3.2"
    memoizerific "^1.11.3"
    polished "^3.4.4"
    resolve-from "^5.0.0"
    ts-dedent "^2.0.0"

Because Storybook seem to use Emotion 10, it imports packages that enter in conflict with my Emotion 11 configuration. (I wouldn't have thought about that until I read #971 (comment))

What's the recommendation when importing packages using Emotion 10 while using Emotion 11 ?

@ljosberinn
Copy link

Over in the Chakra repository we had this issue too and solved it like this: https://github.com/chakra-ui/chakra-ui/blob/master/.storybook/main.js

This is however a Storybook issue, not emotion.

@Vadorequest
Copy link

Vadorequest commented Jan 11, 2021

Thanks! It seems you're overriding webpack aliases by using webpack aliasing to use Emotion 11 when Emotion 10 is being used. (I'll give a try in a similar way to https://github.com/UnlyEd/next-right-now/blob/f24da10646f1a8225fed537337193fd0707f7ac1/next.config.js#L253)

Although, I don't see why it'd be a Storybook issue, they haven't updated yet to v11, but Storybook shouldn't stop to work because someone upgraded their own Emotion version. I mean, if I had opened an issue there, wouldn't they tell me it's an issue with Emotion itself? 🤔 (I might miss something here)


Edit: I think the error I encounter is different from yours, it doesn't seem to be a compilation error. (Next.js compiles and works properly both on Vercel and locally), the error only appears in the WebStorm IDE.

image

@Andarist
Copy link
Member

The shouldnt tell u that this is out issue - its true that your update should not mess things up but it has done it because they use custom webpack aliases. And that's the problem - they shouldnt be doing that in the first place.

As to the IDE problem - have u configured tsconfig with jsxImportSource?

@DominicTobias-b1
Copy link

DominicTobias-b1 commented Jan 22, 2021

I like this idea of declaration merging, however having trouble in CRA when other definitions are in the d.ts as soon as there is an import in there.

Edit: Made good progress by wrapping global stuff in declare global, the hash.js is the only one that's still broken now:

/// <reference types="react-scripts" />

import '@emotion/react'
import { Theme as DefaultTheme } from './global/theme'
declare module '@emotion/react' {
  export interface Theme extends DefaultTheme {}
}

// FIXME: Stops working as soon as this file contains an import
declare module 'hash.js/lib/hash/sha/256' {
  import { sha256 } from 'hash.js'
  export = sha256
}

declare module '*.wasm' {
  const content: any
  export default content
}

declare global {
  type WindowStorage = Storage
  interface Window {
    __ENV__?: any
    __REDUX_DEVTOOLS_EXTENSION__?: any
  }
  interface PromiseConstructor {
    allSettled: any
  }
}

@giannif
Copy link

giannif commented Feb 22, 2021

As a package maintainer, should I upgrade to Emotion v11? My theme is null when using Storybook, because it's v10, causing my package to break in that context.

I'm trying to decide, do I upgrade and roll my own ThemeProvider so I can be sure my package works in all environments? Or leave my package at v10, risking breaking projects that use my package that use Emotion v11?

Any help on the best approach here would be appreciated

@Andarist
Copy link
Member

The Storybook issue shouldn't be a deciding factor IMHO - it really shouldn't happen and it's a problem with their setup, it's a bug in their code so to speak.

I'm trying to decide, do I upgrade and roll my own ThemeProvider so I can be sure my package works in all environments? Or leave my package at v10, risking breaking projects that use my package that use Emotion v11?

This is a somewhat hard question to answer right away - I would appreciate it if you could share some more light on how your library is being used. What APIs does it expose to your users and if they are aware of it being Emotion-based - do they primarily use a mixture of your and our APIs or are they limited to your APIs only and they can use a separate Emotion version on their own?

@giannif
Copy link

giannif commented Feb 25, 2021

@Andarist thanks for the insight. My users have no awareness of Emotion, they render a UI in our react package or vanilla js (which uses Preact under the hood), and don't interact with Emotion APIs.

If only Storybook's setup is the issue here, then I'm not going to worry about my Emotion v10 breaking the host app (which was my biggest concern). I'll probably leave my version at v10 for a bit since I'm on to something else, and upgrade in a few months. Thanks for the help!

@anilanar
Copy link

Can you even have multiple versions of emotion bundled together? If yes, all good. If not, then @giannif is subject to problems if the host app uses emotion, but another version. The only way to fix that would be to make emotion a peer dependency with a specific version.

@pleunv
Copy link

pleunv commented Feb 25, 2021

Do keep in mind that, when hiding emotion from consumers of your lib, they might still want/need a way to provide a nonce for CSP purposes, or a custom key in order to avoid conflicts if they use emotion internally as well. I think in general it's probably not a bad idea to support users passing in a custom emotion cache. Of course, if they then run a different version and provide an incompatible (?) cache they might be in trouble.

@Andarist
Copy link
Member

@pleunv Yep, totally agree - this is why @emotion/react has a lazy API that doesn't give you string class names. The CacheProvider API is powerful to handle those use cases for consumers without much trouble.

It's best if both sides use the same version of Emotion but things should work if they mix major versions - running 2 instances of let's say Emotion 11 is not supported though. If some scenario doesn't work when mixing 2 major versions then it is a bug in Emotion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.