diff --git a/.changeset/config.json b/.changeset/config.json index 0a20a0773..a352515c1 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://unpkg.com/@changesets/config@0.2.1/schema.json", + "$schema": "https://unpkg.com/@changesets/config@1.3.0/schema.json", "changelog": [ "@changesets/changelog-github", { "repo": "emotion-js/emotion" } @@ -8,6 +8,7 @@ "linked": [ [ "@emotion/core", + "@emotion/react", "@emotion/styled", "@emotion/styled-base", "@emotion/cache", @@ -15,14 +16,18 @@ "create-emotion", "emotion", "emotion-server", + "@emotion/server", "create-emotion-server", "babel-plugin-emotion", + "@emotion/babel-plugin", "@emotion/babel-preset-css-prop", "jest-emotion", + "@emotion/jest", "@emotion/native", "@emotion/primitives", "@emotion/primitives-core", "eslint-plugin-emotion", + "@emotion/eslint-plugin", "emotion-theming" ] ], diff --git a/.circleci/config.yml b/.circleci/config.yml index fb8cfcd4f..7730d3b32 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,7 +2,7 @@ version: 2 jobs: flow: docker: - - image: circleci/node:10.13.0-browsers + - image: circleci/node:10.16.3-browsers working_directory: ~/repo steps: - checkout @@ -25,7 +25,7 @@ jobs: test: docker: - - image: circleci/node:10.13.0 + - image: circleci/node:10.16.3 working_directory: ~/repo steps: - checkout @@ -48,7 +48,7 @@ jobs: test_dist: docker: - - image: circleci/node:10.13.0 + - image: circleci/node:10.16.3 working_directory: ~/repo steps: - checkout @@ -66,7 +66,7 @@ jobs: lint_and_typescript: docker: - - image: circleci/node:10.13.0 + - image: circleci/node:10.16.3 working_directory: ~/repo steps: - checkout @@ -77,6 +77,7 @@ jobs: - v4-dependencies- - run: yarn install --pure-lockfile - run: yarn lint:check + - run: yarn test:typescript workflows: version: 2 diff --git a/.codesandbox/ci.json b/.codesandbox/ci.json new file mode 100644 index 000000000..14352fc9f --- /dev/null +++ b/.codesandbox/ci.json @@ -0,0 +1,4 @@ +{ + "packages": ["packages/*"], + "sandboxes": ["pk1qjqpw67"] +} diff --git a/.flowconfig b/.flowconfig index 2b17eb2da..a4493837b 100644 --- a/.flowconfig +++ b/.flowconfig @@ -1,5 +1,5 @@ [version] -0.110.0 +0.128.0 [ignore] .*/node_modules/config-chain/.* @@ -20,8 +20,5 @@ [declarations] .*/node_modules/react-native/.* - [options] -suppress_comment=.*\\$FlowFixMe -suppress_comment=.*\\$FlowExpectError sharedmemory.hash_table_pow=21 diff --git a/.flowconfig-ci b/.flowconfig-ci index 83001e2f6..97256ad2e 100644 --- a/.flowconfig-ci +++ b/.flowconfig-ci @@ -1,5 +1,5 @@ [version] -0.110.0 +0.128.0 [ignore] .*/node_modules/config-chain/.* @@ -23,7 +23,5 @@ [options] -suppress_comment=.*\\$FlowFixMe -suppress_comment=.*\\$FlowExpectError server.max_workers=1 sharedmemory.hash_table_pow=21 diff --git a/.github/ISSUE_TEMPLATE/--bug-report.md b/.github/ISSUE_TEMPLATE/--bug-report.md index 2e8b9e6dc..12495f83e 100644 --- a/.github/ISSUE_TEMPLATE/--bug-report.md +++ b/.github/ISSUE_TEMPLATE/--bug-report.md @@ -41,7 +41,7 @@ assignees: '' **Environment information:** - + - `react` version: -- `emotion` version: +- `@emotion/react` version: diff --git a/.github/ISSUE_TEMPLATE/--documentation-issue.md b/.github/ISSUE_TEMPLATE/--documentation-issue.md index f6287ec84..18b401494 100644 --- a/.github/ISSUE_TEMPLATE/--documentation-issue.md +++ b/.github/ISSUE_TEMPLATE/--documentation-issue.md @@ -24,6 +24,6 @@ assignees: '' diff --git a/.github/ISSUE_TEMPLATE/--feature-request.md b/.github/ISSUE_TEMPLATE/--feature-request.md index a7369d6b7..1e5662df3 100644 --- a/.github/ISSUE_TEMPLATE/--feature-request.md +++ b/.github/ISSUE_TEMPLATE/--feature-request.md @@ -6,7 +6,6 @@ labels: feature request, needs triage assignees: '' --- - **The problem** diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index eeb8e591b..9c0e1e1d9 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -15,22 +15,27 @@ merge of your pull request! --> + **What**: + **Why**: + **How**: + **Checklist**: + + - [ ] Documentation - [ ] Tests - [ ] Code complete - [ ] Changeset - diff --git a/.prettierrc.yaml b/.prettierrc.yaml index c00fa2d41..afa0c8ad2 100644 --- a/.prettierrc.yaml +++ b/.prettierrc.yaml @@ -4,3 +4,6 @@ overrides: - files: "docs/*.md" options: printWidth: 60 +- files: "*.js" + options: + parser: flow diff --git a/README.md b/README.md index d65fb9550..bde863d51 100644 --- a/README.md +++ b/README.md @@ -37,12 +37,12 @@ Frequently viewed docs: Get up and running with a single import. ```bash -npm install --save @emotion/core +npm install --save @emotion/react ``` ```jsx /** @jsx jsx */ -import { jsx } from '@emotion/core' +import { jsx } from '@emotion/react' let SomeComponent = props => { return ( @@ -60,7 +60,7 @@ let SomeComponent = props => { The babel plugin is not required, but enables some optimizations and customizations that could be beneficial for your project. -Look here 👉 _[emotion babel plugin feature table and documentation](https://github.com/emotion-js/emotion/tree/master/packages/babel-plugin-emotion)_ +Look here 👉 _[emotion babel plugin feature table and documentation](https://github.com/emotion-js/emotion/tree/master/packages/babel-plugin)_ ### Demo Sandbox diff --git a/__mocks__/react-primitives.js b/__mocks__/react-primitives.js index fcbd9ef14..83501e477 100644 --- a/__mocks__/react-primitives.js +++ b/__mocks__/react-primitives.js @@ -1,8 +1,2 @@ // @flow -/* eslint-env jest */ -module.exports = { - ...jest.requireActual('react-primitives'), - View: 'View', - Image: 'Image', - Text: 'Text' -} +export * from 'react-primitives/lib/index.web' diff --git a/babel.config.js b/babel.config.js index 3656dc20f..05e09be18 100644 --- a/babel.config.js +++ b/babel.config.js @@ -34,7 +34,9 @@ module.exports = api => { filename && isTestFile(filename) && filename.includes('automatic-runtime'), - presets: [[emotionDevPreset, { runtime: 'automatic' }]] + presets: [ + [emotionDevPreset, { runtime: 'automatic', useEmotionPlugin: true }] + ] }, { test: filename => @@ -42,7 +44,10 @@ module.exports = api => { isTestFile(filename) && filename.includes('automatic-dev-runtime'), presets: [ - [emotionDevPreset, { runtime: 'automatic', development: true }] + [ + emotionDevPreset, + { runtime: 'automatic', development: true, useEmotionPlugin: true } + ] ] } ] diff --git a/docs/babel-macros.mdx b/docs/babel-macros.mdx index 1130f96d1..9831e1d0c 100644 --- a/docs/babel-macros.mdx +++ b/docs/babel-macros.mdx @@ -4,14 +4,14 @@ title: 'Babel Macros' [Create React App recently added support for Babel Macros](https://reactjs.org/blog/2018/10/01/create-react-app-v2.html) which makes it possible to run Babel transforms without changing a Babel config. -Most of Emotion's Babel Macros are available by adding `/macro` to the end of the import you'd normally use. (assuming you're using Create React App v2 or you've added babel-plugin-macros to your .babelrc) For example, to use the macro for styled, use `@emotion/styled/macro`. The one exception to this is `@emotion/core`, `@emotion/core` doesn't have a Babel Macro because Babel Macros doesn't support macros for custom JSX pragmas. There is a Babel macro available for `css` from `@emotion/core` if you import it from `@emotion/css/macro` though. +All of Emotion's Babel Macros are available by adding `/macro` to the end of the import you'd normally use. (assuming you're using Create React App v2 or you've added babel-plugin-macros to your .babelrc) For example, to use the macro for styled, use `@emotion/styled/macro`. ```jsx import styled from '@emotion/styled/macro' -import css from '@emotion/css/macro' -import { css, keyframes, injectGlobal } from 'emotion/macro' +import { jsx, css, Global, keyframes } from '@emotion/react/macro' +import { css, keyframes, injectGlobal } from '@emotion/css/macro' ``` > Note > -> There are some optimisations which aren't possible with Babel Macros, so if it's possible, we still recommend using babel-plugin-emotion +> There are some optimisations which aren't possible with Babel Macros, so if it's possible, we still recommend using @emotion/babel-plugin diff --git a/docs/babel.mdx b/docs/babel.mdx index 4ea2e9972..a15cd4f8f 100644 --- a/docs/babel.mdx +++ b/docs/babel.mdx @@ -2,7 +2,7 @@ title: 'Babel Plugin' --- -`babel-plugin-emotion` is highly recommended. All of the options that can be provided to `babel-plugin-emotion` are documented in [`babel-plugin-emotion`'s README](https://github.com/emotion-js/emotion/tree/master/packages/babel-plugin-emotion). +`@emotion/babel-plugin` is highly recommended. All of the options that can be provided to `@emotion/babel-plugin` are documented in [`@emotion/babel-plugin`'s README](https://github.com/emotion-js/emotion/tree/master/packages/babel-plugin). ### Install diff --git a/docs/cache-provider.mdx b/docs/cache-provider.mdx index 8691993bc..81340018a 100644 --- a/docs/cache-provider.mdx +++ b/docs/cache-provider.mdx @@ -7,24 +7,17 @@ It can be useful to customize emotion's options - i.e. to add custom Stylis plug ```jsx // @live /** @jsx jsx */ -import { CacheProvider, jsx, css } from '@emotion/core' +import { CacheProvider, jsx, css } from '@emotion/react' import createCache from '@emotion/cache' +import { prefixer } from 'stylis' const myCache = createCache({ key: 'my-prefix-key', stylisPlugins: [ - /* your plugins here */ + customPlugin, + // has to be included manually when customizing `stylisPlugins` if you want to have vendor prefixes added automatically + prefixer ], - // prefix based on the css property - prefix: key => { - switch (key) { - case 'flex': - return false - case 'transform': - default: - return true - } - } }) render( diff --git a/docs/class-names.mdx b/docs/class-names.mdx index 8e60b4813..884ea69e0 100644 --- a/docs/class-names.mdx +++ b/docs/class-names.mdx @@ -6,7 +6,7 @@ It can be useful to create a className that is not passed to a component, for ex ```jsx // @live -import { ClassNames } from '@emotion/core' +import { ClassNames } from '@emotion/react' // this might be a component from npm that accepts a wrapperClassName prop let SomeComponent = props => ( diff --git a/docs/composition.mdx b/docs/composition.mdx index d0ff2d9f9..b1eef27a9 100644 --- a/docs/composition.mdx +++ b/docs/composition.mdx @@ -7,7 +7,7 @@ Composition is one of the most powerful and useful patterns in Emotion. You can ```jsx // @live /** @jsx jsx */ -import { jsx, css } from '@emotion/core' +import { jsx, css } from '@emotion/react' const base = css` color: hotpink; @@ -55,7 +55,7 @@ With Emotion though, you can create styles and combine them. ```jsx // @live /** @jsx jsx */ -import { css, jsx } from '@emotion/core' +import { css, jsx } from '@emotion/react' const danger = css` color: red; diff --git a/docs/css-prop.mdx b/docs/css-prop.mdx index 019aacf4a..30aac161d 100644 --- a/docs/css-prop.mdx +++ b/docs/css-prop.mdx @@ -14,10 +14,10 @@ There are 2 ways to get started with the `css` prop. Both methods result in the same compiled code. After adding the preset or setting the pragma as a comment, compiled jsx code will use emotion's `jsx` function instead of `React.createElement`. -| | Input | Output | +| | Input | Output | | ------ | -------------------------- | --------------------------------------------------- | | Before | `` | `React.createElement('img', { src: 'avatar.png' })` | -| After | `` | `jsx('img', { src: 'avatar.png' })` | +| After | `` | `jsx('img', { src: 'avatar.png' })` | #### Babel Preset @@ -34,7 +34,7 @@ Use the [JSX Pragma](#jsx-pragma) method instead. > [Full `@emotion/babel-preset-css-prop` documentation](https://emotion.sh/docs/@emotion/babel-preset-css-prop) -If you are using the compatible React version (`>=16.14.0`) and a compatible version of `@emotion/core` (`>=10.1.0`) then you can opt into using [the new JSX runtimes](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) by using such configuration: +If you are using the compatible React version (`>=16.14.0`) then you can opt into using [the new JSX runtimes](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) by using such configuration: **.babelrc** @@ -43,10 +43,10 @@ If you are using the compatible React version (`>=16.14.0`) and a compatible ver "presets": [ [ "@babel/preset-react", - { "runtime": "automatic", "importSource": "@emotion/core" } + { "runtime": "automatic", "importSource": "@emotion/react" } ] ], - "plugins": [["babel-plugin-emotion", { "cssPropOptimization": true }]] + "plugins": ["@emotion/babel-plugin"] } ``` @@ -62,12 +62,12 @@ In case you want to use the new JSX runtimes with [Next.js](https://nextjs.org/) { "preset-react": { "runtime": "automatic", - "importSource": "@emotion/core" + "importSource": "@emotion/react" } } ] ], - "plugins": [["babel-plugin-emotion", { "cssPropOptimization": true }]] + "plugins": ["@emotion/babel-plugin"] } ``` @@ -82,15 +82,15 @@ This option works best for testing out the `css` prop feature or in projects whe Similar to a comment containing linter configuration, this configures the [jsx babel plugin](https://babeljs.io/docs/en/babel-plugin-transform-react-jsx) to use the `jsx` function instead of `React.createElement`. -If you are using a zero-config tool with automatic detection of which runtime (classic vs. automatic) should be used and you are already using a React version that has [the new JSX runtimes](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) (hence `runtime: 'automatic'` being configured automatically for you) such as Create React App 4 then `/** @jsx jsx */` pragma might not work and you should use `/** @jsxImportSource @emotion/core */` instead. Keep in mind that this also requires a compatible version of `@emotion/core` which is `^10.1.0`. +If you are using a zero-config tool with automatic detection of which runtime (classic vs. automatic) should be used and you are already using a React version that has [the new JSX runtimes](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) (hence `runtime: 'automatic'` being configured automatically for you) such as Create React App 4 then `/** @jsx jsx */` pragma might not work and you should use `/** @jsxImportSource @emotion/react */` instead. > [JSX Pragma Babel Documentation](https://babeljs.io/docs/en/babel-plugin-transform-react-jsx#pragma) -#### Import the `jsx` function from `@emotion/core` +#### Import the `jsx` function from `@emotion/react` ```js /** @jsx jsx */ -import { jsx } from '@emotion/core' +import { jsx } from '@emotion/react' ``` Note that excluding this will cause your css to render as `[Object Object]`. @@ -106,7 +106,7 @@ The `css` prop accepts object styles directly and does not require an additional ```jsx // @live /** @jsx jsx */ -import { jsx } from '@emotion/core' +import { jsx } from '@emotion/react' render(
Note: > -> **`css` from `@emotion/core` does not return the computed class name string.** The function returns an object containing the computed name and flattened styles. The returned object is understood by emotion at a low level and can be composed with other emotion based styles inside of the `css` prop, other `css` calls, or the `styled` API. +> **`css` from `@emotion/react` does not return the computed class name string.** The function returns an object containing the computed name and flattened styles. The returned object is understood by emotion at a low level and can be composed with other emotion based styles inside of the `css` prop, other `css` calls, or the `styled` API. You can also pass in your css as variables, which allows for composition (read more about this [here](https://emotion.sh/docs/composition)). @@ -167,7 +167,7 @@ The `P` component in this example has its default styles overridden in the `Arti ```js /** @jsx jsx */ -import { jsx } from '@emotion/core' +import { jsx } from '@emotion/react' const P = props => (

(

(MyComponent)({})` you should now be writing `styled(MyComponent)({})` + +If you encounter build issues after upgrade, try removing any manually specified generic types and let them be inferred. + +## Theme type + +It's now easier to provide a type for `Theme`. Instead of creating custom instances (like before) you can augment the builtin `Theme` interface like this: + +```ts +import '@emotion/react' + +declare module '@emotion/react' { + export interface Theme { + primaryColor: string + secondaryColor: string + } +} +``` + +## css prop types + +The way in which we provide TypeScript support for the `css` prop has changed. Based on the usage of our JSX factories, we can add support for `css` prop only for components that support `className` prop (as our JSX factory functions take the provided `css` prop, resolve it and pass the generated `className` to the rendered component). + +For the classic runtime this has been implemented using technique described [here](https://www.typescriptlang.org/docs/handbook/jsx.html#factory-functions). What is important - we no longer extend any global interfaces, so people shouldn't bump anymore into type conflicts for the `css` prop when using different libraries with `css` prop support, such as `styled-components`. + +For the automatic runtime this has been implemented by exporting `JSX` namespace from the appropriate entries but this is only supported in **TypeScript 4.1 or higher**. + +However, if you are stuck with older version of TypeScript or using the classic runtime implicitly by using our `@emotion/babel-preset-css-prop` then it's not possible to leverage leverage `css` prop support being added conditionally based on a type of rendered component. For those cases we have added a special file that can be imported once to add support for the `css` prop globally, for all components. Use it like this: + +```ts +/// +``` + +In this particular case we are forced to extend the existing `React.Attributes` interface. Previously we've been extending both `React.DOMAttributes` and `JSX.IntrinsicAttributes`. This change is really minor and shouldn't affect any consuming code. + +# Stylis v4 + +The parser we use ([Stylis](https://github.com/thysultan/stylis.js)) got upgraded. It fixes some long-standing parsing edge cases while being smaller and faster 🚀 + +It has been completely rewritten and comes with some breaking changes. The most notable ones that might affect Emotion users are: + +- plugins written for the former Stylis v3 are not compatible with the new version. To learn more on how to write a plugin for Stylis v4 you can check out its [README](https://github.com/thysultan/stylis.js#middleware) and the source code of core plugins. +- vendor-prefixing was previously customizable using `prefix` option. This was always limited to turning off all of some of the prefixes as all available prefixes were on by default. The `prefix` option is gone and to customize which prefixes are applied you need to fork (copy-paste) the prefixer plugin and adjust it to your needs. While this being somewhat more problematic to setup at first we believe that the vast majority of users were not customizing this anyway. By not including the possibility to customize this through an extra option the final solution is more performant because there is no extra overhead of checking if a particular property should be prefixed or not. +- the prefixer is now just a plugin which happens to be included in the default `stylisPlugins`. If you plan to use custom `stylisPlugins` and you want to have your styles prefixed automatically you must include prefixer in your custom `stylisPlugins`. You can import `prefixer` from the `stylis` module to do that. +- `@import` rules are no longer special-cased. The responsibility to put them first has been moved to the author of the styles. They also can't be nested within other rules now. It's only possible to write them at the top level of global styles. + +# Emotion's caches + +The `key` option is now required when creating a custom instance of a cache. Please make sure it's unique (and not equal to `'css'`) as it's used for linking styles to your cache. If multiple caches share the same key they might "fight" for each other's style elements. + +The new `prepend` option can make Emotion add style tags at the beginning of the specified DOM container instead of the end. + +# Other + +There are a lot of less substantial changes than what has been described here, some of them might even be breaking changes but are not relevant to the majority of users. Therefore to learn more about all of the changes please read through the full list of changes contained in the respective changelogs: + +[`@emotion/babel-plugin`](https://github.com/emotion-js/emotion/blob/master/packages/babel-plugin/CHANGELOG.md#1100) +[`@emotion/babel-preset-css-prop`](https://github.com/emotion-js/emotion/blob/master/packages/babel-preset-css-prop/CHANGELOG.md#1100) +[`@emotion/cache`](https://github.com/emotion-js/emotion/blob/master/packages/cache/CHANGELOG.md#1100) +[`@emotion/css`](https://github.com/emotion-js/emotion/blob/master/packages/css/CHANGELOG.md#1100) +[`@emotion/eslint-plugin`](https://github.com/emotion-js/emotion/blob/master/packages/eslint-plugin/CHANGELOG.md#1100) +[`@emotion/is-prop-valid`](https://github.com/emotion-js/emotion/blob/master/packages/is-prop-valid/CHANGELOG.md#100) +[`@emotion/jest`](https://github.com/emotion-js/emotion/blob/master/packages/jest/CHANGELOG.md#1100) +[`@emotion/native`](https://github.com/emotion-js/emotion/blob/master/packages/native/CHANGELOG.md#1100) +[`@emotion/primitives-core`](https://github.com/emotion-js/emotion/blob/master/packages/primitives-core/CHANGELOG.md#1100) +[`@emotion/primitives`](https://github.com/emotion-js/emotion/blob/master/packages/primitives/CHANGELOG.md#1100) +[`@emotion/react`](https://github.com/emotion-js/emotion/blob/master/packages/react/CHANGELOG.md#1100) +[`@emotion/serialize`](https://github.com/emotion-js/emotion/blob/master/packages/serialize/CHANGELOG.md#100) +[`@emotion/server`](https://github.com/emotion-js/emotion/blob/master/packages/server/CHANGELOG.md#1100) +[`@emotion/sheet`](https://github.com/emotion-js/emotion/blob/master/packages/sheet/CHANGELOG.md#100) +[`@emotion/styled`](https://github.com/emotion-js/emotion/blob/master/packages/styled/CHANGELOG.md#1100) +[`@emotion/utils`](https://github.com/emotion-js/emotion/blob/master/packages/utils/CHANGELOG.md#100) diff --git a/docs/flow.mdx b/docs/flow.mdx new file mode 100644 index 000000000..60ccc5579 --- /dev/null +++ b/docs/flow.mdx @@ -0,0 +1,115 @@ +--- +title: 'Flow' +--- + +Emotion is built with Flow, so it exports type definitions for most of its packages, +including `@emotion/styled`. + +## @emotion/styled + +The styled package can be used to define styled components in two ways, by calling `styled()`, +or by using the `styled.*` shortcuts. + +Unfortunately, Flow doesn't currently support generic types on tagged templates, this means if +you'd like to explictly type a styled component props, you will have to use one of the following +alternatives: + +```jsx +import styled from '@emotion/styled' + +// Option A +const A = styled('div')` + color: red; +` + +// Option B +const B = styled.div({ + color: 'red', +}) +``` + +Styled components are annotated the same way normal React components are: + +```jsx +import styled from '@emotion/styled' + +type Props = { a: string } +const Link = styled('a')` + color: red; +` + +const App = () => Click me +``` + +Just like for normal React components, you don't need to provide type annotations +for your styled components if you don't plan to export them from your module: + +```jsx +import styled from '@emotion/styled' + +const Internal = styled.div` + color: red; +` +``` + +Be aware, Flow infers the return type of your components by referencing their return type, +this means you will need to annotate the properties of the root component in the case below: + +```jsx + +const Container = styled.div` + ^^^^^^^^^^^ Missing type annotation for P. P is a type parameter declared in function type [1] and was implicitly instantiated at +encaps tag [2]. + color: red; +` + +export const App = () => +``` + +You can use `React$ElementConfig` to obtain the props type of a HTML tag, or of +any existing React component: + +```jsx +import type { ElementConfig } from 'react' + +type Props = ElementConfig<'div'> +const Container = styled('div')` + color: red; +` + +export const App = () => +``` + + +```jsx +import type { ElementConfig } from 'react' +import styled from '@emotion/styled' + +const Container = styled>('div')` + background-color: yellow; +` + +const App = () => ( + {() => 10} + ^^^^^^^^^^ Cannot create Container element because in property children: + • Either inexact function [1] is incompatible with exact React.Element [2]. + • Or function [1] is incompatible with React.Portal [3]. + • Or property @@iterator is missing in function [1] but exists in $Iterable [4]. +) +``` + +Alternatively, you can define the return type of your component, so that +Flow doesn't need to infer it reading the props type of the internal component: + +```jsx +import type { Node } from 'react' + +const Container = styled.div` + color: red; +` + +export const App = (): Node => +``` + + + diff --git a/docs/globals.mdx b/docs/globals.mdx index e8f730661..65c9cbf15 100644 --- a/docs/globals.mdx +++ b/docs/globals.mdx @@ -6,7 +6,7 @@ Sometimes you might want to insert global css like resets or font faces. You can ```jsx // @live -import { Global, css } from '@emotion/core' +import { Global, css } from '@emotion/react' render(

diff --git a/docs/install.mdx b/docs/install.mdx index 3bc69fda7..e5208bd84 100644 --- a/docs/install.mdx +++ b/docs/install.mdx @@ -2,16 +2,16 @@ title: 'Install' --- -There are lots of ways to use Emotion, if you're using React, the easiest way to get started is to use the [`@emotion/core` package](/packages/@emotion/core). If you're not using React, you should use [the `emotion` package](#vanilla). +There are lots of ways to use Emotion, if you're using React, the easiest way to get started is to use the [`@emotion/react` package](/packages/@emotion/react). If you're not using React, you should use [the `emotion` package](#vanilla). ```bash -yarn add @emotion/core +yarn add @emotion/react ``` or if you prefer npm ```bash -npm install --save @emotion/core +npm install --save @emotion/react ``` To use it, import what you need, for example use [the css prop](/docs/css-prop.md) to create class names with styles. @@ -20,7 +20,7 @@ To use it, import what you need, for example use [the css prop](/docs/css-prop.m // @live // this comment tells babel to convert jsx to calls to a function called jsx instead of React.createElement /** @jsx jsx */ -import { jsx, css } from '@emotion/core' +import { jsx, css } from '@emotion/react' const style = css` color: hotpink; @@ -52,7 +52,7 @@ render( `styled` is a way to create React components that have styles attached to them. ```bash -# assuming you already have @emotion/core installed +# assuming you already have @emotion/react installed yarn add @emotion/styled ``` @@ -73,7 +73,7 @@ const Button = styled.button` render() ``` -## With [`babel-plugin-emotion`](/packages/babel-plugin-emotion) +## With [`@emotion/babel-plugin`](/packages/@emotion/babel-plugin) > Note: > @@ -82,13 +82,13 @@ render() Emotion has an optional [Babel](https://babeljs.io/) plugin that optimizes styles by compressing and hoisting them and creates a better developer experience with source maps and labels. ```bash -yarn add --dev babel-plugin-emotion +yarn add --dev @emotion/babel-plugin ``` or if you prefer npm ```bash -npm install --save-dev babel-plugin-emotion +npm install --save-dev @emotion/babel-plugin ``` ## .babelrc @@ -97,7 +97,7 @@ _`"emotion"` must be the **first plugin** in your babel config `plugins` list._ ```json { - "plugins": ["emotion"] + "plugins": ["@emotion"] } ``` @@ -107,38 +107,23 @@ If you are using Babel's env option emotion must also be first for each environm { "env": { "production": { - "plugins": ["emotion", ...otherBabelPlugins] + "plugins": ["@emotion", ...otherBabelPlugins] } }, - "plugins": ["emotion"] -} -``` - -## Recommended config - -```json -{ - "env": { - "production": { - "plugins": ["emotion"] - }, - "development": { - "plugins": [["emotion", { "sourceMap": true }]] - } - } + "plugins": ["@emotion"] } ``` # Vanilla -If you're not using React, you can use vanilla Emotion from the `emotion` package. Most of the documentation here focuses on the React-specific version of Emotion, but most of the concepts in the React-specific version also apply to vanilla Emotion. +If you're not using React, you can use vanilla Emotion from the `@emotion/css` package. Most of the documentation here focuses on the React-specific version of Emotion, but most of the concepts in the React-specific version also apply to vanilla Emotion. ```bash -yarn add emotion +yarn add @emotion/css ``` ```jsx -import { css } from 'emotion' +import { css } from '@emotion/css' const app = document.getElementById('root') const myClassName = css` diff --git a/docs/instances.mdx b/docs/instances.mdx deleted file mode 100644 index 631ea2b5e..000000000 --- a/docs/instances.mdx +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: 'Instances' ---- - -emotion allows creating custom instances of emotion to provide special options. Instances are created with the [`create-emotion`](https://github.com/emotion-js/emotion/tree/master/packages/create-emotion) and [`create-emotion-server`](https://github.com/emotion-js/emotion/tree/master/packages/create-emotion-server) packages which create instances of `emotion` and `emotion-server` respectively. They are documented in their own respective READMEs linked above. - -The instances' paths should be added as an option to `babel-plugin-emotion` [as shown in `babel-plugin-emotion`'s README](https://github.com/emotion-js/emotion/tree/master/packages/babel-plugin-emotion#instances). diff --git a/docs/introduction.mdx b/docs/introduction.mdx index d3287a173..9b04638c0 100644 --- a/docs/introduction.mdx +++ b/docs/introduction.mdx @@ -11,26 +11,24 @@ There are two primary methods of using Emotion. The first is framework agnostic ### Framework Agnostic ```bash -npm i emotion +npm i @emotion/css ``` -**[`emotion` documentation](https://emotion.sh/docs/emotion)** +**[`@emotion/css` documentation](https://emotion.sh/docs/@emotion/css)** -The [emotion](https://www.npmjs.com/package/emotion) package is framework agnostic and the simplest way to use Emotion. +The [@emotion/css](https://www.npmjs.com/package/@emotion/css) package is framework agnostic and the simplest way to use Emotion. - Requires no additional setup, babel plugin, or other config changes. - Has support for auto vendor-prefixing, nested selectors, and media queries. -- Works in situations where configuration is restricted or not possible such as with [Create React App](https://facebook.github.io/create-react-app) - - You simply prefer to use the `css` function to generate class names and `cx` to compose them. - Server side rendering requires [additional work to set up](/docs/ssr.md#api) ```jsx // @live -import { css, cx } from 'emotion' +import { css, cx } from '@emotion/css' const color = 'white' @@ -54,10 +52,10 @@ render( ### React ```bash -npm i @emotion/core +npm i @emotion/react ``` -The ["@emotion/core"](https://www.npmjs.com/package/@emotion/core) package requires React and is recommended for users of that framework if possible. +The ["@emotion/react"](https://www.npmjs.com/package/@emotion/react) package requires React and is recommended for users of that framework if possible. - Best when using React with a build environment that can be configured. @@ -76,13 +74,13 @@ The ["@emotion/core"](https://www.npmjs.com/package/@emotion/core) package requi - ESLint plugins available to ensure proper patterns and configuration are set. -**[`@emotion/core` css prop documentation](/docs/css-prop.md)** +**[`@emotion/react` css prop documentation](/docs/css-prop.md)** ```jsx // @live // this comment tells babel to convert jsx to calls to a function called jsx instead of React.createElement /** @jsx jsx */ -import { css, jsx } from '@emotion/core' +import { css, jsx } from '@emotion/react' const color = 'white' @@ -104,7 +102,7 @@ render( ``` ```bash -npm i @emotion/styled @emotion/core +npm i @emotion/styled @emotion/react ``` The [@emotion/styled](https://www.npmjs.com/package/@emotion/styled) package is for those who prefer to use the `styled.div` style API for creating components. @@ -130,6 +128,10 @@ const Button = styled.button` render() ``` +### Browser requirements + +Emotion supports all popular browsers, including Internet Explorer 11. + ### Libraries that Inspired Us - ["original" glam](https://github.com/threepointone/glam/tree/e9bca3950f12503246ed7fccad5cf13e5e9c86e3) diff --git a/docs/keyframes.mdx b/docs/keyframes.mdx index 49e7a951c..916267ba4 100644 --- a/docs/keyframes.mdx +++ b/docs/keyframes.mdx @@ -2,12 +2,12 @@ title: 'Keyframes' --- -You can define animations using the `keyframes` helper from `@emotion/core`. `keyframes` takes in a css keyframe definition and returns an object you can use in styles. You can use strings or objects just like `css`. +You can define animations using the `keyframes` helper from `@emotion/react`. `keyframes` takes in a css keyframe definition and returns an object you can use in styles. You can use strings or objects just like `css`. ```jsx // @live /** @jsx jsx */ -import { jsx, css, keyframes } from '@emotion/core' +import { jsx, css, keyframes } from '@emotion/react' const bounce = keyframes` from, 20%, 53%, 80%, to { diff --git a/docs/labels.mdx b/docs/labels.mdx index f051613c8..f94de377e 100644 --- a/docs/labels.mdx +++ b/docs/labels.mdx @@ -2,12 +2,12 @@ title: 'Labels' --- -Emotion adds a css property called `label`, the value of it is appended to the end of the class name, so it's more readable than a hash. `babel-plugin-emotion` adds these labels automatically based on the variable name and other information, so they don't need to be manually specified. +Emotion adds a css property called `label`, the value of it is appended to the end of the class name, so it's more readable than a hash. `@emotion/babel-plugin` adds these labels automatically based on the variable name and other information, so they don't need to be manually specified. ```jsx // @live /** @jsx jsx */ -import { css, jsx } from '@emotion/core' +import { css, jsx } from '@emotion/react' let style = css` color: hotpink; diff --git a/docs/media-queries.mdx b/docs/media-queries.mdx index 67ca85d04..6528d5bb6 100644 --- a/docs/media-queries.mdx +++ b/docs/media-queries.mdx @@ -7,7 +7,7 @@ Using media queries in emotion works just like using media queries in regular cs ```jsx // @live /** @jsx jsx */ -import { jsx, css } from '@emotion/core' +import { jsx, css } from '@emotion/react' render(

Note: > -> `babel-plugin-emotion` is required for source maps +> `@emotion/babel-plugin` is required for source maps -emotion supports source maps for styles authored in javascript. +Emotion supports source maps for styles authored in JavaScript. ![source-map-demo](https://user-images.githubusercontent.com/662750/30778580-78fbeae4-a096-11e7-82e1-120b6984e875.gif) Required For Source Maps: -1. `babel-plugin-emotion` must be in your Babel setup. [[documentation]](./install.md) +1. `@emotion/babel-plugin` must be in your Babel setup. [[documentation]](./install.md) 2. `process.env.NODE_ENV` must be any value except `"production"` > Note: > -> Source maps are on by default in babel-plugin-emotion but they will be removed in production builds +> Source maps are on by default in @emotion/babel-plugin but they will be removed in production builds diff --git a/docs/ssr.mdx b/docs/ssr.mdx index 56e470066..d08f2ee31 100644 --- a/docs/ssr.mdx +++ b/docs/ssr.mdx @@ -6,7 +6,7 @@ Server side rendering in Emotion 10 has two approaches, each with their own trad ## Default Approach -Server side rendering works out of the box in Emotion 10 and above if you're only using `@emotion/core` and `@emotion/styled`. This means you can call React's [`renderToString`](https://reactjs.org/docs/react-dom-server.html#rendertostring) or [`renderToNodeStream`](https://reactjs.org/docs/react-dom-server.html#rendertonodestream) methods directly without any extra configuration. +Server side rendering works out of the box in Emotion 10 and above if you're only using `@emotion/react` and `@emotion/styled`. This means you can call React's [`renderToString`](https://reactjs.org/docs/react-dom-server.html#rendertostring) or [`renderToNodeStream`](https://reactjs.org/docs/react-dom-server.html#rendertonodestream) methods directly without any extra configuration. ```jsx import { renderToString } from 'react-dom/server' @@ -36,12 +36,13 @@ You can also use the advanced integration, it requires more work but does not ha ### On server ```jsx -import { CacheProvider } from '@emotion/core' +import { CacheProvider } from '@emotion/react' import { renderToString } from 'react-dom/server' -import createEmotionServer from 'create-emotion-server' +import createEmotionServer from '@emotion/server/create-instance' import createCache from '@emotion/cache' -const cache = createCache() +const key = 'custom' +const cache = createCache({ key }) const { extractCritical } = createEmotionServer(cache) let element = ( @@ -62,7 +63,7 @@ res My site - +

${html}
@@ -97,7 +98,7 @@ This returns a string of html that inlines the critical css required right befor ```jsx import { renderToString } from 'react-dom/server' -import { renderStylesToString } from 'emotion-server' +import { renderStylesToString } from '@emotion/server' import App from './App' const html = renderStylesToString(renderToString()) @@ -109,7 +110,7 @@ This returns a [Node Stream Writable](https://nodejs.org/api/stream.html#stream_ ```jsx import { renderToNodeStream } from 'react-dom/server' -import { renderStylesToNodeStream } from 'emotion-server' +import { renderStylesToNodeStream } from '@emotion/server' import App from './App' const stream = renderToNodeStream().pipe(renderStylesToNodeStream()) @@ -121,7 +122,7 @@ This returns an object with the properties `html`, `ids` and `css`. It removes u ```jsx import { renderToString } from 'react-dom/server' -import { extractCritical } from 'emotion-server' +import { extractCritical } from '@emotion/server' import App from './App' const { html, ids, css } = extractCritical(renderToString()) @@ -132,7 +133,7 @@ const { html, ids, css } = extractCritical(renderToString()) `hydrate` should be called on the client with the `ids` that `extractCritical` returns. If you don't call it then emotion will reinsert all the rules. `hydrate` is **only** required for `extractCritical`, **not** for `renderStylesToString` or `renderStylesToNodeStream`, hydration occurs automatically with `renderStylesToString` and `renderStylesToNodeStream`. ```jsx -import { hydrate } from 'emotion' +import { hydrate } from '@emotion/css' hydrate(ids) ``` @@ -174,16 +175,6 @@ export const createMyCache = () => stylisPlugins: [ /* your plugins here */ ], - // prefix based on the css property - prefix: key => { - switch (key) { - case 'flex': - return false - case 'transform': - default: - return true - } - } }) export const myCache = createMyCache() @@ -192,7 +183,7 @@ export const myCache = createMyCache() gatsby-ssr.js ```jsx -import { CacheProvider } from '@emotion/core' +import { CacheProvider } from '@emotion/react' import { createMyCache } from './create-emotion-cache' @@ -204,7 +195,7 @@ export const wrapRootElement = ({ element }) => ( gatsby-browser.js ```jsx -import { CacheProvider } from '@emotion/core' +import { CacheProvider } from '@emotion/react' import { myCache } from './create-emotion-cache' @@ -215,7 +206,7 @@ export const wrapRootElement = ({ element }) => ( > Note: > -> While Emotion 10 and above supports SSR out of the box, it's still recommended to use gatsby-plugin-emotion as gatsby-plugin-emotion will enable babel-plugin-emotion and other potential future optimisations. +> While Emotion 10 and above supports SSR out of the box, it's still recommended to use gatsby-plugin-emotion as gatsby-plugin-emotion will enable @emotion/babel-plugin and other potential future optimisations. ## Puppeteer @@ -242,7 +233,7 @@ if (root.hasChildNodes()) { disable-speedy.js ```js -import { sheet } from 'emotion' +import { sheet } from '@emotion/css' // Check if the root node has any children to detect if the app has been preprendered // speedy is disabled when the app is being prerendered so that styles render into the DOM diff --git a/docs/styled.mdx b/docs/styled.mdx index 68a57716b..4a23643d4 100644 --- a/docs/styled.mdx +++ b/docs/styled.mdx @@ -87,7 +87,7 @@ render( ### Targeting another emotion component -Similar to [styled-components](https://www.styled-components.com/docs/faqs#can-i-refer-to-other-components), emotion allows for emotion components to be targeted like regular CSS selectors when using [babel-plugin-emotion](/packages/babel-plugin-emotion.md). +Similar to [styled-components](https://www.styled-components.com/docs/faqs#can-i-refer-to-other-components), emotion allows for emotion components to be targeted like regular CSS selectors when using [@emotion/babel-plugin](/packages/babel-plugin). ```jsx // @live @@ -159,7 +159,7 @@ This API was inspired by [glamorous](https://github.com/paypal/glamorous). ❤ ### Customizing prop forwarding -By default, Emotion passes all props to custom components and only props that are valid html attributes for string tags. You can customize this by passing a custom `shouldForwardProp` function. You can also use `@emotion/is-prop-valid` (which is used by emotion internally) to filter out props that are not valid as html attributes. +By default, Emotion passes all props (except for `theme`) to custom components and only props that are valid html attributes for string tags. You can customize this by passing a custom `shouldForwardProp` function. You can also use `@emotion/is-prop-valid` (which is used by emotion internally) to filter out props that are not valid as html attributes. ```jsx // @live @@ -183,7 +183,7 @@ You can create dynamic styles that are based on props and use them in styles. ```jsx // @live import styled from '@emotion/styled' -import { css } from '@emotion/core' +import { css } from '@emotion/react' const dynamicStyle = props => css` diff --git a/docs/testing.mdx b/docs/testing.mdx index 4540df5e3..bb3c2c64c 100644 --- a/docs/testing.mdx +++ b/docs/testing.mdx @@ -6,37 +6,59 @@ Adding [snapshot tests with Jest](https://facebook.github.io/jest/docs/en/snapsh By diffing the serialized value of your React tree Jest can show you what changed in your app and allow you to fix it or update the snapshot. -By default snapshots with emotion show generated class names. Adding [jest-emotion](https://github.com/emotion-js/emotion/tree/master/packages/jest-emotion) allows you to output the actual styles being applied. +By default snapshots with emotion show generated class names. Adding [@emotion/jest](https://github.com/emotion-js/emotion/tree/master/packages/jest) allows you to output the actual styles being applied. ### Installation ```bash -npm install --save-dev jest-emotion +npm install --save-dev @emotion/jest ``` -Add the snapshot serializer in your [`setupTestFrameworkScriptFile`](http://facebook.github.io/jest/docs/en/configuration.html#setuptestframeworkscriptfile-string) _or_ at the top of your test file. +Add the `"@emotion/jest/serializer"` to the [`snapshotSerializers`](https://jestjs.io/docs/en/configuration#snapshotserializers-arraystring) option. + +```json +{ + "snapshotSerializers": ["@emotion/jest/serializer"] +} +``` + +Or use `expect.addSnapshotSerializer` to add it. + +```javascript +import { createSerializer } from '@emotion/jest' + +expect.addSnapshotSerializer(createSerializer()) +``` + +When using Enzyme, you can add `"@emotion/jest/enzyme-serializer"` instead. + +```json +{ + "snapshotSerializers": ["@emotion/jest/enzyme-serializer"] +} +``` + +Or use `expect.addSnapshotSerializer` to add it like this: + ```javascript -import * as emotion from 'emotion' -import { createSerializer } from 'jest-emotion' +import { createEnzymeSerializer } from '@emotion/jest/enzyme-serializer' // also adds the enzyme-to-json serializer -expect.addSnapshotSerializer(createSerializer(emotion)) +expect.addSnapshotSerializer(createEnzymeSerializer()) ``` ### Writing a test -Writing a test with `jest-emotion` involves creating a snapshot from the `react-test-renderer` or `enzyme-to-json`'s resulting JSON. +Writing a test with `@emotion/jest` involves creating a snapshot from the `react-test-renderer` or `enzyme-to-json`'s resulting JSON. ```jsx import React from 'react' -import serializer from 'jest-emotion' /** @jsx jsx */ -import { jsx } from '@emotion/core' +import { jsx } from '@emotion/react' import renderer from 'react-test-renderer' -expect.addSnapshotSerializer(serializer) const Button = props => (