;"
`;
exports[`@emotion/babel-plugin object-property 1`] = `
-"// @flow
-import * as React from 'react'
+"import * as React from 'react'
import { jsx } from '@emotion/react'
import styled from '@emotion/styled'
@@ -323,7 +318,6 @@ import _styled from "@emotion/styled/base";
function _EMOTION_STRINGIFIED_CSS_ERROR__() { return "You have tried to stringify object returned from \`css\` function. It isn't supposed to be used directly (e.g. as value of the \`className\` prop), but rather handed to emotion so it can handle it (e.g. as value of \`css\` prop)."; }
-// @flow
import * as React from 'react';
import { jsx } from '@emotion/react';
const MyObject = {
@@ -338,7 +332,7 @@ const MyObject = {
} : {
name: "3sn2xs",
styles: "color:hotpink",
- map: "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm9iamVjdC1wcm9wZXJ0eS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFNYyIsImZpbGUiOiJvYmplY3QtcHJvcGVydHkuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAZmxvd1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnXG5pbXBvcnQgeyBqc3ggfSBmcm9tICdAZW1vdGlvbi9yZWFjdCdcbmltcG9ydCBzdHlsZWQgZnJvbSAnQGVtb3Rpb24vc3R5bGVkJ1xuXG5jb25zdCBNeU9iamVjdCA9IHtcbiAgTXlQcm9wZXJ0eTogc3R5bGVkLmRpdih7IGNvbG9yOiAnaG90cGluaycgfSlcbn1cblxuZnVuY3Rpb24gTG9nbyhwcm9wcykge1xuICByZXR1cm4gPE15T2JqZWN0Lk15UHJvcGVydHkgLz5cbn1cbiJdfQ== */",
+ map: "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm9iamVjdC1wcm9wZXJ0eS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFLYyIsImZpbGUiOiJvYmplY3QtcHJvcGVydHkuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCdcbmltcG9ydCB7IGpzeCB9IGZyb20gJ0BlbW90aW9uL3JlYWN0J1xuaW1wb3J0IHN0eWxlZCBmcm9tICdAZW1vdGlvbi9zdHlsZWQnXG5cbmNvbnN0IE15T2JqZWN0ID0ge1xuICBNeVByb3BlcnR5OiBzdHlsZWQuZGl2KHsgY29sb3I6ICdob3RwaW5rJyB9KVxufVxuXG5mdW5jdGlvbiBMb2dvKHByb3BzKSB7XG4gIHJldHVybiA8TXlPYmplY3QuTXlQcm9wZXJ0eSAvPlxufVxuIl19 */",
toString: _EMOTION_STRINGIFIED_CSS_ERROR__
})
};
diff --git a/packages/babel-plugin/__tests__/__snapshots__/styled.js.snap b/packages/babel-plugin/__tests__/__snapshots__/styled.js.snap
index 2fbba924f6..1ef0fcb1d1 100644
--- a/packages/babel-plugin/__tests__/__snapshots__/styled.js.snap
+++ b/packages/babel-plugin/__tests__/__snapshots__/styled.js.snap
@@ -901,15 +901,13 @@ exports[`emotion-babel-plugin styled two-consecutive-interpolations 1`] = `
import { css } from '@emotion/react'
const H1 = styled.h1\`
- \${props =>
- css\`
- color: red;
- \`}
+ \${props => css\`
+ color: red;
+ \`}
/* dummy comment */
- \${props =>
- css\`
- text-transform: uppercase;
- \`}
+ \${props => css\`
+ text-transform: uppercase;
+ \`}
\`
@@ -927,7 +925,7 @@ var _ref = process.env.NODE_ENV === "production" ? {
} : {
name: "15r1ir2-H1",
styles: "text-transform:uppercase;label:H1;",
- map: "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInR3by1jb25zZWN1dGl2ZS1pbnRlcnBvbGF0aW9ucy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFVTyIsImZpbGUiOiJ0d28tY29uc2VjdXRpdmUtaW50ZXJwb2xhdGlvbnMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgc3R5bGVkIGZyb20gJ0BlbW90aW9uL3N0eWxlZCdcbmltcG9ydCB7IGNzcyB9IGZyb20gJ0BlbW90aW9uL3JlYWN0J1xuXG5jb25zdCBIMSA9IHN0eWxlZC5oMWBcbiAgJHtwcm9wcyA9PlxuICAgIGNzc2BcbiAgICAgIGNvbG9yOiByZWQ7XG4gICAgYH1cbiAgLyogZHVtbXkgY29tbWVudCAqL1xuICAke3Byb3BzID0+XG4gICAgY3NzYFxuICAgICAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbiAgICBgfVxuYFxuIl19 */",
+ map: "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInR3by1jb25zZWN1dGl2ZS1pbnRlcnBvbGF0aW9ucy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFRZ0IiLCJmaWxlIjoidHdvLWNvbnNlY3V0aXZlLWludGVycG9sYXRpb25zLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHN0eWxlZCBmcm9tICdAZW1vdGlvbi9zdHlsZWQnXG5pbXBvcnQgeyBjc3MgfSBmcm9tICdAZW1vdGlvbi9yZWFjdCdcblxuY29uc3QgSDEgPSBzdHlsZWQuaDFgXG4gICR7cHJvcHMgPT4gY3NzYFxuICAgIGNvbG9yOiByZWQ7XG4gIGB9XG4gIC8qIGR1bW15IGNvbW1lbnQgKi9cbiAgJHtwcm9wcyA9PiBjc3NgXG4gICAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbiAgYH1cbmBcbiJdfQ== */",
toString: _EMOTION_STRINGIFIED_CSS_ERROR__
};
@@ -937,7 +935,7 @@ var _ref2 = process.env.NODE_ENV === "production" ? {
} : {
name: "1yd8rfk-H1",
styles: "color:red;label:H1;",
- map: "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInR3by1jb25zZWN1dGl2ZS1pbnRlcnBvbGF0aW9ucy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFLTyIsImZpbGUiOiJ0d28tY29uc2VjdXRpdmUtaW50ZXJwb2xhdGlvbnMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgc3R5bGVkIGZyb20gJ0BlbW90aW9uL3N0eWxlZCdcbmltcG9ydCB7IGNzcyB9IGZyb20gJ0BlbW90aW9uL3JlYWN0J1xuXG5jb25zdCBIMSA9IHN0eWxlZC5oMWBcbiAgJHtwcm9wcyA9PlxuICAgIGNzc2BcbiAgICAgIGNvbG9yOiByZWQ7XG4gICAgYH1cbiAgLyogZHVtbXkgY29tbWVudCAqL1xuICAke3Byb3BzID0+XG4gICAgY3NzYFxuICAgICAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbiAgICBgfVxuYFxuIl19 */",
+ map: "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInR3by1jb25zZWN1dGl2ZS1pbnRlcnBvbGF0aW9ucy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFJZ0IiLCJmaWxlIjoidHdvLWNvbnNlY3V0aXZlLWludGVycG9sYXRpb25zLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHN0eWxlZCBmcm9tICdAZW1vdGlvbi9zdHlsZWQnXG5pbXBvcnQgeyBjc3MgfSBmcm9tICdAZW1vdGlvbi9yZWFjdCdcblxuY29uc3QgSDEgPSBzdHlsZWQuaDFgXG4gICR7cHJvcHMgPT4gY3NzYFxuICAgIGNvbG9yOiByZWQ7XG4gIGB9XG4gIC8qIGR1bW15IGNvbW1lbnQgKi9cbiAgJHtwcm9wcyA9PiBjc3NgXG4gICAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbiAgYH1cbmBcbiJdfQ== */",
toString: _EMOTION_STRINGIFIED_CSS_ERROR__
};
@@ -946,7 +944,7 @@ const H1 = /*#__PURE__*/_styled("h1", process.env.NODE_ENV === "production" ? {
} : {
target: "e45grep0",
label: "H1"
-})(props => _ref2, props => _ref, ";" + (process.env.NODE_ENV === "production" ? "" : "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInR3by1jb25zZWN1dGl2ZS1pbnRlcnBvbGF0aW9ucy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHb0IiLCJmaWxlIjoidHdvLWNvbnNlY3V0aXZlLWludGVycG9sYXRpb25zLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHN0eWxlZCBmcm9tICdAZW1vdGlvbi9zdHlsZWQnXG5pbXBvcnQgeyBjc3MgfSBmcm9tICdAZW1vdGlvbi9yZWFjdCdcblxuY29uc3QgSDEgPSBzdHlsZWQuaDFgXG4gICR7cHJvcHMgPT5cbiAgICBjc3NgXG4gICAgICBjb2xvcjogcmVkO1xuICAgIGB9XG4gIC8qIGR1bW15IGNvbW1lbnQgKi9cbiAgJHtwcm9wcyA9PlxuICAgIGNzc2BcbiAgICAgIHRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7XG4gICAgYH1cbmBcbiJdfQ== */"));"
+})(props => _ref2, props => _ref, ";" + (process.env.NODE_ENV === "production" ? "" : "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInR3by1jb25zZWN1dGl2ZS1pbnRlcnBvbGF0aW9ucy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHb0IiLCJmaWxlIjoidHdvLWNvbnNlY3V0aXZlLWludGVycG9sYXRpb25zLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHN0eWxlZCBmcm9tICdAZW1vdGlvbi9zdHlsZWQnXG5pbXBvcnQgeyBjc3MgfSBmcm9tICdAZW1vdGlvbi9yZWFjdCdcblxuY29uc3QgSDEgPSBzdHlsZWQuaDFgXG4gICR7cHJvcHMgPT4gY3NzYFxuICAgIGNvbG9yOiByZWQ7XG4gIGB9XG4gIC8qIGR1bW15IGNvbW1lbnQgKi9cbiAgJHtwcm9wcyA9PiBjc3NgXG4gICAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbiAgYH1cbmBcbiJdfQ== */"));"
`;
exports[`emotion-babel-plugin styled with-spread 1`] = `
diff --git a/packages/babel-plugin/__tests__/css-macro/index.js b/packages/babel-plugin/__tests__/css-macro/index.js
index fae1b1815f..4d73fb4e84 100644
--- a/packages/babel-plugin/__tests__/css-macro/index.js
+++ b/packages/babel-plugin/__tests__/css-macro/index.js
@@ -1,4 +1,3 @@
-// @flow
import babelTester from 'babel-tester'
babelTester('@emotion/react - css macro', __dirname)
diff --git a/packages/babel-plugin/__tests__/css-requires-options.js b/packages/babel-plugin/__tests__/css-requires-options.js
index fd91b0c079..9173c489df 100644
--- a/packages/babel-plugin/__tests__/css-requires-options.js
+++ b/packages/babel-plugin/__tests__/css-requires-options.js
@@ -1,4 +1,3 @@
-// @flow
import nodePath from 'path'
import babelTester from 'babel-tester'
import plugin from '@emotion/babel-plugin'
diff --git a/packages/babel-plugin/__tests__/global-macro/index.js b/packages/babel-plugin/__tests__/global-macro/index.js
index f2d2067288..c3eb1874e2 100644
--- a/packages/babel-plugin/__tests__/global-macro/index.js
+++ b/packages/babel-plugin/__tests__/global-macro/index.js
@@ -1,4 +1,3 @@
-// @flow
import babelTester from 'babel-tester'
babelTester('@emotion/react - Global macro', __dirname)
diff --git a/packages/babel-plugin/__tests__/global-requires-options.js b/packages/babel-plugin/__tests__/global-requires-options.js
index e8e7cf1324..a8cd7cfad1 100644
--- a/packages/babel-plugin/__tests__/global-requires-options.js
+++ b/packages/babel-plugin/__tests__/global-requires-options.js
@@ -1,4 +1,3 @@
-// @flow
import babelTester from 'babel-tester'
import plugin from '@emotion/babel-plugin'
diff --git a/packages/babel-plugin/__tests__/styled-macro/__fixtures__/two-consecutive-interpolations.js b/packages/babel-plugin/__tests__/styled-macro/__fixtures__/two-consecutive-interpolations.js
index f932adce21..aeb9c2e2da 100644
--- a/packages/babel-plugin/__tests__/styled-macro/__fixtures__/two-consecutive-interpolations.js
+++ b/packages/babel-plugin/__tests__/styled-macro/__fixtures__/two-consecutive-interpolations.js
@@ -2,13 +2,11 @@ import styled from '@emotion/styled/macro'
import { css } from '@emotion/react'
const H1 = styled.h1`
- ${props =>
- css`
- color: red;
- `}
+ ${props => css`
+ color: red;
+ `}
/* dummy comment */
- ${props =>
- css`
- text-transform: uppercase;
- `}
+ ${props => css`
+ text-transform: uppercase;
+ `}
`
diff --git a/packages/babel-plugin/__tests__/styled-macro/__snapshots__/index.js.snap b/packages/babel-plugin/__tests__/styled-macro/__snapshots__/index.js.snap
index 75c64a11b6..d62f957786 100644
--- a/packages/babel-plugin/__tests__/styled-macro/__snapshots__/index.js.snap
+++ b/packages/babel-plugin/__tests__/styled-macro/__snapshots__/index.js.snap
@@ -878,15 +878,13 @@ exports[`@emotion/styled.macro two-consecutive-interpolations 1`] = `
import { css } from '@emotion/react'
const H1 = styled.h1\`
- \${props =>
- css\`
- color: red;
- \`}
+ \${props => css\`
+ color: red;
+ \`}
/* dummy comment */
- \${props =>
- css\`
- text-transform: uppercase;
- \`}
+ \${props => css\`
+ text-transform: uppercase;
+ \`}
\`
@@ -901,10 +899,10 @@ const H1 = /*#__PURE__*/_styled("h1", process.env.NODE_ENV === "production" ? {
target: "e45grep0",
label: "H1"
})(props => css\`
- color: red;
- \`, props => css\`
- text-transform: uppercase;
- \`, ";" + (process.env.NODE_ENV === "production" ? "" : "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInR3by1jb25zZWN1dGl2ZS1pbnRlcnBvbGF0aW9ucy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHb0IiLCJmaWxlIjoidHdvLWNvbnNlY3V0aXZlLWludGVycG9sYXRpb25zLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHN0eWxlZCBmcm9tICdAZW1vdGlvbi9zdHlsZWQvbWFjcm8nXG5pbXBvcnQgeyBjc3MgfSBmcm9tICdAZW1vdGlvbi9yZWFjdCdcblxuY29uc3QgSDEgPSBzdHlsZWQuaDFgXG4gICR7cHJvcHMgPT5cbiAgICBjc3NgXG4gICAgICBjb2xvcjogcmVkO1xuICAgIGB9XG4gIC8qIGR1bW15IGNvbW1lbnQgKi9cbiAgJHtwcm9wcyA9PlxuICAgIGNzc2BcbiAgICAgIHRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7XG4gICAgYH1cbmBcbiJdfQ== */"));"
+ color: red;
+ \`, props => css\`
+ text-transform: uppercase;
+ \`, ";" + (process.env.NODE_ENV === "production" ? "" : "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInR3by1jb25zZWN1dGl2ZS1pbnRlcnBvbGF0aW9ucy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHb0IiLCJmaWxlIjoidHdvLWNvbnNlY3V0aXZlLWludGVycG9sYXRpb25zLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHN0eWxlZCBmcm9tICdAZW1vdGlvbi9zdHlsZWQvbWFjcm8nXG5pbXBvcnQgeyBjc3MgfSBmcm9tICdAZW1vdGlvbi9yZWFjdCdcblxuY29uc3QgSDEgPSBzdHlsZWQuaDFgXG4gICR7cHJvcHMgPT4gY3NzYFxuICAgIGNvbG9yOiByZWQ7XG4gIGB9XG4gIC8qIGR1bW15IGNvbW1lbnQgKi9cbiAgJHtwcm9wcyA9PiBjc3NgXG4gICAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbiAgYH1cbmBcbiJdfQ== */"));"
`;
exports[`@emotion/styled.macro with-spread 1`] = `
diff --git a/packages/babel-plugin/__tests__/styled-macro/index.js b/packages/babel-plugin/__tests__/styled-macro/index.js
index f183501efa..26c27d241d 100644
--- a/packages/babel-plugin/__tests__/styled-macro/index.js
+++ b/packages/babel-plugin/__tests__/styled-macro/index.js
@@ -1,4 +1,3 @@
-// @flow
import babelTester from 'babel-tester'
babelTester('@emotion/styled.macro', __dirname)
diff --git a/packages/babel-plugin/__tests__/styled-requires-options.js b/packages/babel-plugin/__tests__/styled-requires-options.js
index a2d1a57e26..05e003fb36 100644
--- a/packages/babel-plugin/__tests__/styled-requires-options.js
+++ b/packages/babel-plugin/__tests__/styled-requires-options.js
@@ -1,4 +1,3 @@
-// @flow
import babelTester from 'babel-tester'
import plugin from '@emotion/babel-plugin'
diff --git a/packages/babel-plugin/__tests__/vanilla-emotion-macro/index.js b/packages/babel-plugin/__tests__/vanilla-emotion-macro/index.js
index 07961ee8fe..cdce44dffd 100644
--- a/packages/babel-plugin/__tests__/vanilla-emotion-macro/index.js
+++ b/packages/babel-plugin/__tests__/vanilla-emotion-macro/index.js
@@ -1,4 +1,3 @@
-// @flow
import babelTester from 'babel-tester'
babelTester('vanilla emotion', __dirname)
diff --git a/packages/babel-plugin/package.json b/packages/babel-plugin/package.json
index 7f8773b423..32805b41c7 100644
--- a/packages/babel-plugin/package.json
+++ b/packages/babel-plugin/package.json
@@ -1,11 +1,15 @@
{
"name": "@emotion/babel-plugin",
- "version": "11.11.0",
+ "version": "11.12.0",
"description": "A recommended babel preprocessing plugin for emotion, The Next Generation of CSS-in-JS.",
"main": "dist/emotion-babel-plugin.cjs.js",
"module": "dist/emotion-babel-plugin.esm.js",
"exports": {
".": {
+ "types": {
+ "import": "./dist/emotion-babel-plugin.cjs.mjs",
+ "default": "./dist/emotion-babel-plugin.cjs.js"
+ },
"module": "./dist/emotion-babel-plugin.esm.js",
"import": "./dist/emotion-babel-plugin.cjs.mjs",
"default": "./dist/emotion-babel-plugin.cjs.js"
@@ -20,9 +24,9 @@
"dependencies": {
"@babel/helper-module-imports": "^7.16.7",
"@babel/runtime": "^7.18.3",
- "@emotion/hash": "^0.9.1",
- "@emotion/memoize": "^0.8.1",
- "@emotion/serialize": "^1.1.2",
+ "@emotion/hash": "^0.9.2",
+ "@emotion/memoize": "^0.9.0",
+ "@emotion/serialize": "^1.2.0",
"babel-plugin-macros": "^3.1.0",
"convert-source-map": "^1.5.0",
"escape-string-regexp": "^4.0.0",
diff --git a/packages/babel-plugin/src/core-macro.js b/packages/babel-plugin/src/core-macro.js
index 77f39f1244..c7f8c76961 100644
--- a/packages/babel-plugin/src/core-macro.js
+++ b/packages/babel-plugin/src/core-macro.js
@@ -1,4 +1,3 @@
-// @flow
import {
transformExpressionWithStyles,
createTransformerMacro,
@@ -6,19 +5,15 @@ import {
addImport
} from './utils'
-export const transformCssCallExpression = ({
- state,
- babel,
- path,
- sourceMap,
- annotateAsPure = true
-}: {
+export const transformCssCallExpression = (
+ { state, babel, path, sourceMap, annotateAsPure = true } /*: {
state: *,
babel: *,
path: *,
sourceMap?: string,
annotateAsPure?: boolean
-}) => {
+} */
+) => {
let node = transformExpressionWithStyles({
babel,
state,
@@ -34,15 +29,13 @@ export const transformCssCallExpression = ({
}
}
-export const transformCsslessArrayExpression = ({
- state,
- babel,
- path
-}: {
+export const transformCsslessArrayExpression = (
+ { state, babel, path } /*: {
babel: *,
state: *,
path: *
-}) => {
+} */
+) => {
let t = babel.types
let expressionPath = path.get('value.expression')
let sourceMap =
@@ -72,17 +65,14 @@ export const transformCsslessArrayExpression = ({
}
}
-export const transformCsslessObjectExpression = ({
- state,
- babel,
- path,
- cssImport
-}: {
+export const transformCsslessObjectExpression = (
+ { state, babel, path, cssImport } /*: {
babel: *,
state: *,
path: *,
cssImport: { importSource: string, cssExport: string }
-}) => {
+} */
+) => {
let t = babel.types
let expressionPath = path.get('value.expression')
let sourceMap =
@@ -115,31 +105,25 @@ export const transformCsslessObjectExpression = ({
}
}
-let cssTransformer = ({
- state,
- babel,
- reference
-}: {
+let cssTransformer = (
+ { state, babel, reference } /*: {
state: any,
babel: any,
reference: any
-}) => {
+} */
+) => {
transformCssCallExpression({ babel, state, path: reference.parentPath })
}
-let globalTransformer = ({
- state,
- babel,
- reference,
- importSource,
- options
-}: {
+let globalTransformer = (
+ { state, babel, reference, importSource, options } /*: {
state: any,
babel: any,
reference: any,
importSource: string,
options: { cssExport?: string }
-}) => {
+} */
+) => {
const t = babel.types
if (
diff --git a/packages/babel-plugin/src/emotion-macro.js b/packages/babel-plugin/src/emotion-macro.js
index 96b5954a67..67bf2c8e13 100644
--- a/packages/babel-plugin/src/emotion-macro.js
+++ b/packages/babel-plugin/src/emotion-macro.js
@@ -1,4 +1,3 @@
-// @flow
import { transformExpressionWithStyles, createTransformerMacro } from './utils'
const isAlreadyTranspiled = path => {
@@ -30,8 +29,10 @@ const isAlreadyTranspiled = path => {
}
let createEmotionTransformer =
- (isPure: boolean) =>
- ({ state, babel, importSource, reference, importSpecifierName }: Object) => {
+ (isPure /*: boolean */) =>
+ (
+ { state, babel, importSource, reference, importSpecifierName } /*: Object */
+ ) => {
const path = reference.parentPath
if (isAlreadyTranspiled(path)) {
@@ -59,5 +60,5 @@ export let transformers = {
keyframes: createEmotionTransformer(true)
}
-export let createEmotionMacro = (importSource: string) =>
+export let createEmotionMacro = (importSource /*: string */) =>
createTransformerMacro(transformers, { importSource })
diff --git a/packages/babel-plugin/src/index.js b/packages/babel-plugin/src/index.js
index 95731cd432..74f889c391 100644
--- a/packages/babel-plugin/src/index.js
+++ b/packages/babel-plugin/src/index.js
@@ -1,4 +1,3 @@
-// @flow
import {
createEmotionMacro,
transformers as vanillaTransformers
@@ -68,13 +67,15 @@ export const macros = {
vanillaEmotion: vanillaEmotionMacro
}
+/*
export type BabelPath = any
export type EmotionBabelPluginPass = any
+*/
const AUTO_LABEL_VALUES = ['dev-only', 'never', 'always']
-export default function (babel: *, options: *) {
+export default function (babel, options) {
if (
options.autoLabel !== undefined &&
!AUTO_LABEL_VALUES.includes(options.autoLabel)
@@ -90,7 +91,7 @@ export default function (babel: *, options: *) {
return {
name: '@emotion',
// https://github.com/babel/babel/blob/0c97749e0fe8ad845b902e0b23a24b308b0bf05d/packages/babel-plugin-syntax-jsx/src/index.ts#L9-L18
- manipulateOptions(opts: *, parserOpts: *) {
+ manipulateOptions(opts, parserOpts) {
const { plugins } = parserOpts
if (
@@ -105,7 +106,7 @@ export default function (babel: *, options: *) {
plugins.push('jsx')
},
visitor: {
- ImportDeclaration(path: *, state: *) {
+ ImportDeclaration(path, state) {
const macro = state.pluginMacros[path.node.source.value]
// most of this is from https://github.com/kentcdodds/babel-plugin-macros/blob/main/src/index.js
if (macro === undefined) {
@@ -159,13 +160,13 @@ export default function (babel: *, options: *) {
isBabelMacrosCall: true
})
},
- Program(path: *, state: *) {
+ Program(path, state) {
let macros = {}
- let jsxReactImports: Array<{
+ let jsxReactImports /*: Array<{
importSource: string,
export: string,
cssExport: string
- }> = [
+ }> */ = [
{ importSource: '@emotion/react', export: 'jsx', cssExport: 'css' }
]
state.jsxReactImport = jsxReactImports[0]
@@ -209,11 +210,11 @@ export default function (babel: *, options: *) {
}
}
- let [exportTransformer, defaultOptions] =
- // $FlowFixMe
- Array.isArray(packageTransformers[exportName])
- ? packageTransformers[exportName]
- : [packageTransformers[exportName]]
+ let [exportTransformer, defaultOptions] = Array.isArray(
+ packageTransformers[exportName]
+ )
+ ? packageTransformers[exportName]
+ : [packageTransformers[exportName]]
transformers[localExportName] = [
exportTransformer,
@@ -266,7 +267,7 @@ export default function (babel: *, options: *) {
state.emotionSourceMap = true
}
},
- JSXAttribute(path: *, state: *) {
+ JSXAttribute(path, state) {
if (path.node.name.name !== 'css' || !state.transformCssProp) {
return
}
@@ -289,7 +290,7 @@ export default function (babel: *, options: *) {
}
},
CallExpression: {
- exit(path: BabelPath, state: EmotionBabelPluginPass) {
+ exit(path /*: BabelPath */, state /*: EmotionBabelPluginPass */) {
try {
if (
path.node.callee &&
diff --git a/packages/babel-plugin/src/styled-macro.js b/packages/babel-plugin/src/styled-macro.js
index 1ccde3726c..5f4094fc65 100644
--- a/packages/babel-plugin/src/styled-macro.js
+++ b/packages/babel-plugin/src/styled-macro.js
@@ -1,4 +1,3 @@
-// @flow
import {
transformExpressionWithStyles,
getStyledOptions,
@@ -13,15 +12,16 @@ const getReferencedSpecifier = (path, specifierName) => {
: specifiers.find(p => p.node.local.name === specifierName)
}
-export let styledTransformer = ({
- state,
- babel,
- path,
- importSource,
- reference,
- importSpecifierName,
- options: { styledBaseImport, isWeb }
-}: {
+export let styledTransformer = (
+ {
+ state,
+ babel,
+ path,
+ importSource,
+ reference,
+ importSpecifierName,
+ options: { styledBaseImport, isWeb }
+ } /*: {
state: Object,
babel: Object,
path: any,
@@ -29,7 +29,8 @@ export let styledTransformer = ({
importSpecifierName: string,
reference: Object,
options: { styledBaseImport?: [string, string], isWeb: boolean }
-}) => {
+} */
+) => {
let t = babel.types
let getStyledIdentifier = () => {
@@ -119,17 +120,19 @@ export let styledTransformer = ({
}
}
-export let createStyledMacro = ({
- importSource,
- originalImportSource = importSource,
- baseImportName = 'default',
- isWeb
-}: {
+export let createStyledMacro = (
+ {
+ importSource,
+ originalImportSource = importSource,
+ baseImportName = 'default',
+ isWeb
+ } /*: {
importSource: string,
originalImportSource?: string,
baseImportName?: string,
isWeb: boolean
-}) =>
+} */
+) =>
createTransformerMacro(
{
default: [
diff --git a/packages/babel-plugin/src/utils/add-import.js b/packages/babel-plugin/src/utils/add-import.js
index 4d1113ac87..393ef1fb5f 100644
--- a/packages/babel-plugin/src/utils/add-import.js
+++ b/packages/babel-plugin/src/utils/add-import.js
@@ -1,10 +1,10 @@
import { addDefault, addNamed } from '@babel/helper-module-imports'
export function addImport(
- state: any,
- importSource: string,
- importedSpecifier: string,
- nameHint?: string
+ state,
+ importSource /*: string */,
+ importedSpecifier /*: string */,
+ nameHint /* ?: string */
) {
let cacheKey = ['import', importSource, importedSpecifier].join(':')
if (state[cacheKey] === undefined) {
diff --git a/packages/babel-plugin/src/utils/get-styled-options.js b/packages/babel-plugin/src/utils/get-styled-options.js
index b37b027f28..351afad60e 100644
--- a/packages/babel-plugin/src/utils/get-styled-options.js
+++ b/packages/babel-plugin/src/utils/get-styled-options.js
@@ -1,9 +1,8 @@
-// @flow
import { getLabelFromPath } from './label'
import { getTargetClassName } from './get-target-class-name'
import createNodeEnvConditional from './create-node-env-conditional'
-const getKnownProperties = (t: *, node: *) =>
+const getKnownProperties = (t, node) =>
new Set(
node.properties
.filter(n => t.isObjectProperty(n) && !n.computed)
@@ -13,7 +12,7 @@ const getKnownProperties = (t: *, node: *) =>
const createObjectSpreadLike = (t, file, ...objs) =>
t.callExpression(file.addHelper('extends'), [t.objectExpression([]), ...objs])
-export let getStyledOptions = (t: *, path: *, state: *) => {
+export let getStyledOptions = (t, path, state) => {
const autoLabel = state.opts.autoLabel || 'dev-only'
let args = path.node.arguments
diff --git a/packages/babel-plugin/src/utils/get-target-class-name.js b/packages/babel-plugin/src/utils/get-target-class-name.js
index 9b78a9725c..5d524b9206 100644
--- a/packages/babel-plugin/src/utils/get-target-class-name.js
+++ b/packages/babel-plugin/src/utils/get-target-class-name.js
@@ -1,11 +1,10 @@
-// @flow
import findRoot from 'find-root'
import memoize from '@emotion/memoize'
import nodePath from 'path'
import hashString from '@emotion/hash'
import escapeRegexp from 'escape-string-regexp'
-let hashArray = (arr: Array
) => hashString(arr.join(''))
+let hashArray = (arr /*: Array */) => hashString(arr.join(''))
const unsafeRequire = require
@@ -15,7 +14,7 @@ const separator = new RegExp(escapeRegexp(nodePath.sep), 'g')
const normalizePath = path => nodePath.normalize(path).replace(separator, '/')
-export function getTargetClassName(state: *, t: *) {
+export function getTargetClassName(state, t) {
if (state.emotionTargetClassNameCount === undefined) {
state.emotionTargetClassNameCount = 0
}
diff --git a/packages/babel-plugin/src/utils/index.js b/packages/babel-plugin/src/utils/index.js
index a4696280b2..7ec45184f5 100644
--- a/packages/babel-plugin/src/utils/index.js
+++ b/packages/babel-plugin/src/utils/index.js
@@ -1,4 +1,3 @@
-// @flow
export { getLabelFromPath } from './label'
export { getSourceMap } from './source-maps'
export { getTargetClassName } from './get-target-class-name'
diff --git a/packages/babel-plugin/src/utils/label.js b/packages/babel-plugin/src/utils/label.js
index f20ace5a2d..5d4d1f7120 100644
--- a/packages/babel-plugin/src/utils/label.js
+++ b/packages/babel-plugin/src/utils/label.js
@@ -1,20 +1,21 @@
-// @flow
import nodePath from 'path'
+/*
type LabelFormatOptions = {
name: string,
path: string
}
+*/
const invalidClassNameCharacters = /[!"#$%&'()*+,./:;<=>?@[\]^`|}~{]/g
-const sanitizeLabelPart = (labelPart: string) =>
+const sanitizeLabelPart = (labelPart /*: string */) =>
labelPart.trim().replace(invalidClassNameCharacters, '-')
function getLabel(
- identifierName?: string,
- labelFormat?: string | (LabelFormatOptions => string),
- filename: string
+ identifierName /* ?: string */,
+ labelFormat /* ?: string | (LabelFormatOptions => string) */,
+ filename /*: string */
) {
if (!identifierName) return null
@@ -45,7 +46,7 @@ function getLabel(
.replace(/\[dirname\]/gi, sanitizeLabelPart(localDirname))
}
-export function getLabelFromPath(path: *, state: *, t: *) {
+export function getLabelFromPath(path, state, t) {
return getLabel(
getIdentifierName(path, t),
state.opts.labelFormat,
@@ -72,7 +73,6 @@ const getObjPropertyLikeName = (path, t) => {
}
function getDeclaratorName(path, t) {
- // $FlowFixMe
const parent = path.findParent(
p =>
p.isVariableDeclarator() ||
@@ -154,14 +154,13 @@ function getDeclaratorName(path, t) {
return variableDeclarator.node.id.name
}
-function getIdentifierName(path: *, t: *) {
+function getIdentifierName(path, t) {
let objPropertyLikeName = getObjPropertyLikeName(path.parentPath, t)
if (objPropertyLikeName) {
return objPropertyLikeName
}
- // $FlowFixMe
let classOrClassPropertyParent = path.findParent(
p => t.isClassProperty(p) || t.isClass(p)
)
diff --git a/packages/babel-plugin/src/utils/minify.js b/packages/babel-plugin/src/utils/minify.js
index 14281a98ed..7d5c18e79d 100644
--- a/packages/babel-plugin/src/utils/minify.js
+++ b/packages/babel-plugin/src/utils/minify.js
@@ -1,4 +1,3 @@
-// @flow
import { compile } from 'stylis'
const haveSameLocation = (element1, element2) => {
@@ -59,18 +58,17 @@ var stringifyTree = elements => {
.join('')
}
-const interleave = (strings: Array<*>, interpolations: Array<*>) =>
+const interleave = (strings /*: Array<*> */, interpolations /*: Array<*> */) =>
interpolations.reduce(
(array, interp, i) => array.concat([interp], strings[i + 1]),
[strings[0]]
)
-function getDynamicMatches(str: string) {
+function getDynamicMatches(str /*: string */) {
const re = /xxx(\d+):xxx/gm
let match
const matches = []
while ((match = re.exec(str)) !== null) {
- // so that flow doesn't complain
if (match !== null) {
matches.push({
value: match[0],
@@ -84,9 +82,9 @@ function getDynamicMatches(str: string) {
}
function replacePlaceholdersWithExpressions(
- str: string,
- expressions: Array<*>,
- t: *
+ str /*: string */,
+ expressions /*: Array<*> */,
+ t
) {
const matches = getDynamicMatches(str)
if (matches.length === 0) {
@@ -116,15 +114,17 @@ function replacePlaceholdersWithExpressions(
})
return interleave(strings, finalExpressions).filter(
- (node: { value: string }) => {
+ (node /*: { value: string } */) => {
return node.value !== ''
}
)
}
-function createRawStringFromTemplateLiteral(quasi: {
+function createRawStringFromTemplateLiteral(
+ quasi /*: {
quasis: Array<{ value: { cooked: string } }>
-}) {
+} */
+) {
let strs = quasi.quasis.map(x => x.value.cooked)
const src = strs
@@ -140,7 +140,7 @@ function createRawStringFromTemplateLiteral(quasi: {
return src
}
-export default function minify(path: *, t: *): void {
+export default function minify(path, t) {
const quasi = path.node.quasi
const raw = createRawStringFromTemplateLiteral(quasi)
const minified = stringifyTree(toInputTree(compile(raw), []))
diff --git a/packages/babel-plugin/src/utils/object-to-string.js b/packages/babel-plugin/src/utils/object-to-string.js
index a3bfa56460..f275c5b07d 100644
--- a/packages/babel-plugin/src/utils/object-to-string.js
+++ b/packages/babel-plugin/src/utils/object-to-string.js
@@ -1,10 +1,9 @@
-// @flow
import { serializeStyles } from '@emotion/serialize'
// to anyone looking at this, this isn't intended to simplify every single case
// it's meant to simplify the most common cases so i don't want to make it especially complex
// also, this will be unnecessary when prepack is ready
-export function simplifyObject(node: *, t: Object) {
+export function simplifyObject(node, t /*: Object */) {
let finalString = ''
for (let i = 0; i < node.properties.length; i++) {
let property = node.properties[i]
diff --git a/packages/babel-plugin/src/utils/source-maps.js b/packages/babel-plugin/src/utils/source-maps.js
index b499f33cca..e4926711b3 100644
--- a/packages/babel-plugin/src/utils/source-maps.js
+++ b/packages/babel-plugin/src/utils/source-maps.js
@@ -1,4 +1,3 @@
-// @flow
import { SourceMapGenerator } from 'source-map'
import convert from 'convert-source-map'
@@ -6,7 +5,7 @@ function getGeneratorOpts(file) {
return file.opts.generatorOpts ? file.opts.generatorOpts : file.opts
}
-export function makeSourceMapGenerator(file: *) {
+export function makeSourceMapGenerator(file) {
const generatorOpts = getGeneratorOpts(file)
const filename = generatorOpts.sourceFileName
const generator = new SourceMapGenerator({
@@ -19,12 +18,12 @@ export function makeSourceMapGenerator(file: *) {
}
export function getSourceMap(
- offset: {
+ offset /*: {
line: number,
column: number
- },
- state: *
-): string {
+ } */,
+ state
+) /*: string */ {
const generator = makeSourceMapGenerator(state.file)
const generatorOpts = getGeneratorOpts(state.file)
if (
diff --git a/packages/babel-plugin/src/utils/strings.js b/packages/babel-plugin/src/utils/strings.js
index 6c91c62161..5e85223e92 100644
--- a/packages/babel-plugin/src/utils/strings.js
+++ b/packages/babel-plugin/src/utils/strings.js
@@ -1,13 +1,12 @@
-// @flow
import {
getTypeScriptMakeTemplateObjectPath,
isTaggedTemplateTranspiledByBabel
} from './transpiled-output-utils'
export const appendStringReturningExpressionToArguments = (
- t: *,
- path: *,
- expression: *
+ t,
+ path,
+ expression
) => {
let lastIndex = path.node.arguments.length - 1
let last = path.node.arguments[lastIndex]
@@ -44,7 +43,7 @@ export const appendStringReturningExpressionToArguments = (
}
}
-export const joinStringLiterals = (expressions: Array<*>, t: *) => {
+export const joinStringLiterals = (expressions /*: Array<*> */, t) => {
return expressions.reduce((finalExpressions, currentExpression, i) => {
if (!t.isStringLiteral(currentExpression)) {
finalExpressions.push(currentExpression)
diff --git a/packages/babel-plugin/src/utils/transform-expression-with-styles.js b/packages/babel-plugin/src/utils/transform-expression-with-styles.js
index c47e7366e4..0e61f74730 100644
--- a/packages/babel-plugin/src/utils/transform-expression-with-styles.js
+++ b/packages/babel-plugin/src/utils/transform-expression-with-styles.js
@@ -1,5 +1,3 @@
-// @flow
-
import { serializeStyles } from '@emotion/serialize'
import minify from './minify'
import { getLabelFromPath } from './label'
@@ -14,19 +12,15 @@ import createNodeEnvConditional from './create-node-env-conditional'
const CSS_OBJECT_STRINGIFIED_ERROR =
"You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."
-export let transformExpressionWithStyles = ({
+export let transformExpressionWithStyles = (
+ { babel, state, path, shouldLabel, sourceMap = '' } /*: {
babel,
state,
path,
- shouldLabel,
- sourceMap = ''
-}: {
- babel: *,
- state: *,
- path: *,
shouldLabel: boolean,
sourceMap?: string
-}): * => {
+} */
+) => {
const autoLabel = state.opts.autoLabel || 'dev-only'
let t = babel.types
if (t.isTaggedTemplateExpression(path)) {
diff --git a/packages/babel-plugin/src/utils/transformer-macro.js b/packages/babel-plugin/src/utils/transformer-macro.js
index ea10489699..679ad1af38 100644
--- a/packages/babel-plugin/src/utils/transformer-macro.js
+++ b/packages/babel-plugin/src/utils/transformer-macro.js
@@ -1,11 +1,12 @@
-// @flow
import { createMacro } from 'babel-plugin-macros'
+/*
type Transformer = Function
+*/
export function createTransformerMacro(
- transformers: { [key: string]: Transformer | [Transformer, Object] },
- { importSource }: { importSource: string }
+ transformers /*: { [key: string]: Transformer | [Transformer, Object] } */,
+ { importSource } /*: { importSource: string } */
) {
let macro = createMacro(
({ path, source, references, state, babel, isEmotionCall }) => {
diff --git a/packages/babel-plugin/src/utils/transpiled-output-utils.js b/packages/babel-plugin/src/utils/transpiled-output-utils.js
index e6943e3b64..74187e413f 100644
--- a/packages/babel-plugin/src/utils/transpiled-output-utils.js
+++ b/packages/babel-plugin/src/utils/transpiled-output-utils.js
@@ -1,8 +1,6 @@
-// @flow
-
// this only works correctly in modules, but we don't run on scripts anyway, so it's fine
// the difference is that in modules template objects are being cached per call site
-export function getTypeScriptMakeTemplateObjectPath(path: *) {
+export function getTypeScriptMakeTemplateObjectPath(path) {
if (path.node.arguments.length === 0) {
return null
}
@@ -28,7 +26,7 @@ export function getTypeScriptMakeTemplateObjectPath(path: *) {
// we could push them to found array expressions, as we do it for TS-transpile output ¯\_(ツ)_/¯
// it seems overly complicated though - mainly because we'd also have to check against existing stuff of a particular type (source maps & labels)
// considering Babel double-transpilation as a valid use case seems rather far-fetched
-export function isTaggedTemplateTranspiledByBabel(path: *) {
+export function isTaggedTemplateTranspiledByBabel(path) {
if (path.node.arguments.length === 0) {
return false
}
diff --git a/packages/babel-preset-css-prop/CHANGELOG.md b/packages/babel-preset-css-prop/CHANGELOG.md
index 5dd14d681c..1e4635b57e 100644
--- a/packages/babel-preset-css-prop/CHANGELOG.md
+++ b/packages/babel-preset-css-prop/CHANGELOG.md
@@ -1,5 +1,13 @@
# @emotion/babel-preset-css-prop
+## 11.12.0
+
+### Patch Changes
+
+- Updated dependencies [[`ea84c40`](https://github.com/emotion-js/emotion/commit/ea84c4096d7bc28f03c4cdc1f453bb64d09dcd15)]:
+ - @emotion/babel-plugin-jsx-pragmatic@0.3.0
+ - @emotion/babel-plugin@11.12.0
+
## 11.11.0
### Patch Changes
diff --git a/packages/babel-preset-css-prop/package.json b/packages/babel-preset-css-prop/package.json
index 3ed9205ec2..de03d4ee01 100644
--- a/packages/babel-preset-css-prop/package.json
+++ b/packages/babel-preset-css-prop/package.json
@@ -1,11 +1,15 @@
{
"name": "@emotion/babel-preset-css-prop",
- "version": "11.11.0",
+ "version": "11.12.0",
"description": "A babel preset to automatically enable emotion's css prop",
"main": "dist/emotion-babel-preset-css-prop.cjs.js",
"module": "dist/emotion-babel-preset-css-prop.esm.js",
"exports": {
".": {
+ "types": {
+ "import": "./dist/emotion-babel-preset-css-prop.cjs.mjs",
+ "default": "./dist/emotion-babel-preset-css-prop.cjs.js"
+ },
"module": "./dist/emotion-babel-preset-css-prop.esm.js",
"import": "./dist/emotion-babel-preset-css-prop.cjs.mjs",
"default": "./dist/emotion-babel-preset-css-prop.cjs.js"
@@ -17,8 +21,8 @@
"dependencies": {
"@babel/plugin-transform-react-jsx": "^7.17.12",
"@babel/runtime": "^7.18.3",
- "@emotion/babel-plugin": "^11.11.0",
- "@emotion/babel-plugin-jsx-pragmatic": "^0.2.1"
+ "@emotion/babel-plugin": "^11.12.0",
+ "@emotion/babel-plugin-jsx-pragmatic": "^0.3.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0"
diff --git a/packages/cache/CHANGELOG.md b/packages/cache/CHANGELOG.md
index 7485a27a67..ebe1d82f25 100644
--- a/packages/cache/CHANGELOG.md
+++ b/packages/cache/CHANGELOG.md
@@ -1,5 +1,33 @@
# @emotion/cache
+## 11.13.0
+
+### Minor Changes
+
+- [#3198](https://github.com/emotion-js/emotion/pull/3198) [`d8ff8a5`](https://github.com/emotion-js/emotion/commit/d8ff8a5990c691017b463b3fa23a9f46ab28147b) Thanks [@Andarist](https://github.com/Andarist)! - Migrated away from relying on `process.env.NODE_ENV` checks to differentiate between production and development builds.
+
+ Development builds (and other environment-specific builds) can be used by using proper conditions (see [here](https://nodejs.org/docs/v20.15.1/api/packages.html#resolving-user-conditions)). Most modern bundlers/frameworks already preconfigure those for the user so no action has to be taken.
+
+ Default files should continue to work in all environments.
+
+- [#3215](https://github.com/emotion-js/emotion/pull/3215) [`a9f6912`](https://github.com/emotion-js/emotion/commit/a9f691299844bf6837b7ad41ee17cd912496f3d5) Thanks [@Andarist](https://github.com/Andarist)! - Added `edge-light` and `workerd` conditions to `package.json` manifest to better serve users using Vercel Edge and Cloudflare Workers.
+
+### Patch Changes
+
+- Updated dependencies [[`d8ff8a5`](https://github.com/emotion-js/emotion/commit/d8ff8a5990c691017b463b3fa23a9f46ab28147b), [`a9f6912`](https://github.com/emotion-js/emotion/commit/a9f691299844bf6837b7ad41ee17cd912496f3d5)]:
+ - @emotion/sheet@1.4.0
+ - @emotion/utils@1.4.0
+
+## 11.12.0
+
+### Patch Changes
+
+- Updated dependencies [[`7f8db2d`](https://github.com/emotion-js/emotion/commit/7f8db2d7a900bb34995db66084a99d512811e33d), [`b1d16b0`](https://github.com/emotion-js/emotion/commit/b1d16b087d057524f374e347fdfd6a03e505107a), [`16d8a8c`](https://github.com/emotion-js/emotion/commit/16d8a8c2198461c4842c73048b406c346a70aa59), [`52aadc6`](https://github.com/emotion-js/emotion/commit/52aadc6e77140867392f81545cc92e04fd84d453), [`52aadc6`](https://github.com/emotion-js/emotion/commit/52aadc6e77140867392f81545cc92e04fd84d453)]:
+ - @emotion/memoize@0.9.0
+ - @emotion/weak-memoize@0.4.0
+ - @emotion/utils@1.3.0
+ - @emotion/sheet@1.3.0
+
## 11.11.0
### Minor Changes
diff --git a/packages/cache/__tests__/hydration.js b/packages/cache/__tests__/hydration.js
index 132f26237b..98e0e0fc10 100644
--- a/packages/cache/__tests__/hydration.js
+++ b/packages/cache/__tests__/hydration.js
@@ -1,4 +1,3 @@
-// @flow
import { safeQuerySelector } from 'test-utils'
import hashString from '@emotion/hash'
import createCache from '@emotion/cache'
@@ -11,9 +10,8 @@ beforeEach(() => {
test('it works', () => {
let css = `color:hotpink;`
let hash = hashString(css)
- safeQuerySelector(
- 'body'
- ).innerHTML = ``
+ safeQuerySelector('body').innerHTML =
+ ``
let cache = createCache({ key: 'css' })
expect(cache.inserted).toEqual({ [hash]: true })
expect(document.documentElement).toMatchSnapshot()
@@ -22,9 +20,8 @@ test('it works', () => {
test('rehydrated styles to head can be flushed', () => {
let css = `color:hotpink;`
let hash = hashString(css)
- safeQuerySelector(
- 'head'
- ).innerHTML = ``
+ safeQuerySelector('head').innerHTML =
+ ``
// this moves emotion style tags at initialization time
jest.resetModules()
@@ -87,9 +84,8 @@ test('should only hydrate style elements matching the cache key', () => {
let css = `color:hotpink;`
let hash = hashString(css)
- safeQuerySelector(
- 'body'
- ).innerHTML = ``
+ safeQuerySelector('body').innerHTML =
+ ``
const cache = createCache({ key: 'custom-key' })
@@ -126,9 +122,8 @@ test('should only hydrate style elements matching the cache key', () => {
test('Existing client-side inserted styles from Emotion 10 should not be moved', () => {
// the nested nature isn't special, it's just meant to be a general "make sure they're not moved"
- safeQuerySelector(
- 'body'
- ).innerHTML = ``
+ safeQuerySelector('body').innerHTML =
+ ``
expect(document.documentElement).toMatchInlineSnapshot(`
diff --git a/packages/cache/__tests__/index.js b/packages/cache/__tests__/index.js
index 15751f2166..931c506877 100644
--- a/packages/cache/__tests__/index.js
+++ b/packages/cache/__tests__/index.js
@@ -1,4 +1,3 @@
-// @flow
/** @jsx jsx */
import 'test-utils/next-env'
import { safeQuerySelector } from 'test-utils'
@@ -12,7 +11,7 @@ test('throws correct error with invalid key', () => {
}).toThrowErrorMatchingSnapshot()
})
-it('should accept insertionPoint option', () => {
+test('should accept insertionPoint option', () => {
const head = safeQuerySelector('head')
head.innerHTML = `
@@ -35,7 +34,7 @@ it('should accept insertionPoint option', () => {
expect(document.head).toMatchSnapshot()
})
-it('should accept container option', () => {
+test('should accept container option', () => {
const body = safeQuerySelector('body')
body.innerHTML = `
diff --git a/packages/cache/package.json b/packages/cache/package.json
index 90aca4adb1..2373e67a37 100644
--- a/packages/cache/package.json
+++ b/packages/cache/package.json
@@ -1,24 +1,79 @@
{
"name": "@emotion/cache",
- "version": "11.11.0",
+ "version": "11.13.0",
"description": "emotion's cache",
"main": "dist/emotion-cache.cjs.js",
"module": "dist/emotion-cache.esm.js",
- "browser": {
- "./dist/emotion-cache.esm.js": "./dist/emotion-cache.browser.esm.js"
- },
"exports": {
".": {
- "module": {
- "worker": "./dist/emotion-cache.worker.esm.js",
- "browser": "./dist/emotion-cache.browser.esm.js",
- "default": "./dist/emotion-cache.esm.js"
+ "types": {
+ "import": "./dist/emotion-cache.cjs.mjs",
+ "default": "./dist/emotion-cache.cjs.js"
+ },
+ "development": {
+ "edge-light": {
+ "module": "./dist/emotion-cache.development.edge-light.esm.js",
+ "import": "./dist/emotion-cache.development.edge-light.cjs.mjs",
+ "default": "./dist/emotion-cache.development.edge-light.cjs.js"
+ },
+ "worker": {
+ "module": "./dist/emotion-cache.development.edge-light.esm.js",
+ "import": "./dist/emotion-cache.development.edge-light.cjs.mjs",
+ "default": "./dist/emotion-cache.development.edge-light.cjs.js"
+ },
+ "workerd": {
+ "module": "./dist/emotion-cache.development.edge-light.esm.js",
+ "import": "./dist/emotion-cache.development.edge-light.cjs.mjs",
+ "default": "./dist/emotion-cache.development.edge-light.cjs.js"
+ },
+ "browser": {
+ "module": "./dist/emotion-cache.browser.development.esm.js",
+ "import": "./dist/emotion-cache.browser.development.cjs.mjs",
+ "default": "./dist/emotion-cache.browser.development.cjs.js"
+ },
+ "module": "./dist/emotion-cache.development.esm.js",
+ "import": "./dist/emotion-cache.development.cjs.mjs",
+ "default": "./dist/emotion-cache.development.cjs.js"
+ },
+ "edge-light": {
+ "module": "./dist/emotion-cache.edge-light.esm.js",
+ "import": "./dist/emotion-cache.edge-light.cjs.mjs",
+ "default": "./dist/emotion-cache.edge-light.cjs.js"
+ },
+ "worker": {
+ "module": "./dist/emotion-cache.edge-light.esm.js",
+ "import": "./dist/emotion-cache.edge-light.cjs.mjs",
+ "default": "./dist/emotion-cache.edge-light.cjs.js"
+ },
+ "workerd": {
+ "module": "./dist/emotion-cache.edge-light.esm.js",
+ "import": "./dist/emotion-cache.edge-light.cjs.mjs",
+ "default": "./dist/emotion-cache.edge-light.cjs.js"
},
+ "browser": {
+ "module": "./dist/emotion-cache.browser.esm.js",
+ "import": "./dist/emotion-cache.browser.cjs.mjs",
+ "default": "./dist/emotion-cache.browser.cjs.js"
+ },
+ "module": "./dist/emotion-cache.esm.js",
"import": "./dist/emotion-cache.cjs.mjs",
"default": "./dist/emotion-cache.cjs.js"
},
"./package.json": "./package.json"
},
+ "imports": {
+ "#is-development": {
+ "development": "./src/conditions/true.js",
+ "default": "./src/conditions/false.js"
+ },
+ "#is-browser": {
+ "edge-light": "./src/conditions/false.js",
+ "workerd": "./src/conditions/false.js",
+ "worker": "./src/conditions/false.js",
+ "browser": "./src/conditions/true.js",
+ "default": "./src/conditions/is-browser.js"
+ }
+ },
"types": "types/index.d.ts",
"license": "MIT",
"repository": "https://github.com/emotion-js/emotion/tree/main/packages/cache",
@@ -26,28 +81,20 @@
"test:typescript": "dtslint types"
},
"dependencies": {
- "@emotion/memoize": "^0.8.1",
- "@emotion/sheet": "^1.2.2",
- "@emotion/utils": "^1.2.1",
- "@emotion/weak-memoize": "^0.3.1",
+ "@emotion/memoize": "^0.9.0",
+ "@emotion/sheet": "^1.4.0",
+ "@emotion/utils": "^1.4.0",
+ "@emotion/weak-memoize": "^0.4.0",
"stylis": "4.2.0"
},
"devDependencies": {
"@definitelytyped/dtslint": "0.0.112",
"@emotion/hash": "*",
- "typescript": "^4.5.5"
+ "typescript": "^5.4.5"
},
"files": [
"src",
"dist",
"types/*.d.ts"
- ],
- "preconstruct": {
- "exports": {
- "envConditions": [
- "browser",
- "worker"
- ]
- }
- }
+ ]
}
diff --git a/packages/cache/src/conditions/false.js b/packages/cache/src/conditions/false.js
new file mode 100644
index 0000000000..2693369b44
--- /dev/null
+++ b/packages/cache/src/conditions/false.js
@@ -0,0 +1 @@
+export default false
diff --git a/packages/cache/src/conditions/is-browser.js b/packages/cache/src/conditions/is-browser.js
new file mode 100644
index 0000000000..12bdad68fc
--- /dev/null
+++ b/packages/cache/src/conditions/is-browser.js
@@ -0,0 +1 @@
+export default typeof document !== 'undefined'
diff --git a/packages/cache/src/conditions/true.js b/packages/cache/src/conditions/true.js
new file mode 100644
index 0000000000..186b120756
--- /dev/null
+++ b/packages/cache/src/conditions/true.js
@@ -0,0 +1 @@
+export default true
diff --git a/packages/cache/src/index.js b/packages/cache/src/index.js
index 39d66bf915..efd70ae8f1 100644
--- a/packages/cache/src/index.js
+++ b/packages/cache/src/index.js
@@ -1,6 +1,5 @@
-// @flow
import { StyleSheet } from '@emotion/sheet'
-import { type EmotionCache, type SerializedStyles } from '@emotion/utils'
+/* import { type EmotionCache, type SerializedStyles } from '@emotion/utils' */
import {
serialize,
compile,
@@ -11,6 +10,8 @@ import {
} from 'stylis'
import weakMemoize from '@emotion/weak-memoize'
import memoize from '@emotion/memoize'
+import isDevelopment from '#is-development'
+import isBrowser from '#is-browser'
import {
compat,
removeLabel,
@@ -18,10 +19,9 @@ import {
incorrectImportAlarm
} from './stylis-plugins'
import { prefixer } from './prefixer'
-import type { StylisPlugin } from './types'
-
-let isBrowser = typeof document !== 'undefined'
+/* import type { StylisPlugin } from './types' */
+/*
export type Options = {
nonce?: string,
stylisPlugins?: StylisPlugin[],
@@ -31,6 +31,7 @@ export type Options = {
prepend?: boolean,
insertionPoint?: HTMLElement
}
+*/
let getServerStylisCache = isBrowser
? undefined
@@ -43,10 +44,10 @@ let getServerStylisCache = isBrowser
const defaultStylisPlugins = [prefixer]
-let createCache = (options: Options): EmotionCache => {
+let createCache = (options /*: Options */) /*: EmotionCache */ => {
let key = options.key
- if (process.env.NODE_ENV !== 'production' && !key) {
+ if (isDevelopment && !key) {
throw new Error(
"You have to configure `key` for your cache. Please make sure it's unique (and not equal to 'css') as it's used for linking styles to your cache.\n" +
`If multiple caches share the same key they might "fight" for each other's style elements.`
@@ -62,29 +63,26 @@ let createCache = (options: Options): EmotionCache => {
// document.head is a safe place to move them to(though note document.head is not necessarily the last place they will be)
// note this very very intentionally targets all style elements regardless of the key to ensure
// that creating a cache works inside of render of a React component
- Array.prototype.forEach.call(ssrStyles, (node: HTMLStyleElement) => {
+ Array.prototype.forEach.call(ssrStyles, (node /*: HTMLStyleElement */) => {
// we want to only move elements which have a space in the data-emotion attribute value
// because that indicates that it is an Emotion 11 server-side rendered style elements
// while we will already ignore Emotion 11 client-side inserted styles because of the :not([data-s]) part in the selector
// Emotion 10 client-side inserted styles did not have data-s (but importantly did not have a space in their data-emotion attributes)
// so checking for the space ensures that loading Emotion 11 after Emotion 10 has inserted some styles
// will not result in the Emotion 10 styles being destroyed
- const dataEmotionAttribute = ((node.getAttribute(
- 'data-emotion'
- ): any): string)
+ const dataEmotionAttribute = node.getAttribute('data-emotion')
if (dataEmotionAttribute.indexOf(' ') === -1) {
return
}
- ;((document.head: any): HTMLHeadElement).appendChild(node)
+ document.head.appendChild(node)
node.setAttribute('data-s', '')
})
}
const stylisPlugins = options.stylisPlugins || defaultStylisPlugins
- if (process.env.NODE_ENV !== 'production') {
- // $FlowFixMe
+ if (isDevelopment) {
if (/[^a-z-]/.test(key)) {
throw new Error(
`Emotion key must only contain lower case alphabetical characters and - but "${key}" was passed`
@@ -92,20 +90,17 @@ let createCache = (options: Options): EmotionCache => {
}
}
let inserted = {}
- let container: Node
+ let container /* : Node */
const nodesToHydrate = []
if (isBrowser) {
- container = options.container || ((document.head: any): HTMLHeadElement)
+ container = options.container || document.head
Array.prototype.forEach.call(
// this means we will ignore elements which don't have a space in them which
// means that the style elements we're looking at are only Emotion 11 server-rendered style elements
document.querySelectorAll(`style[data-emotion^="${key} "]`),
- (node: HTMLStyleElement) => {
- const attrib = ((node.getAttribute(`data-emotion`): any): string).split(
- ' '
- )
- // $FlowFixMe
+ (node /*: HTMLStyleElement */) => {
+ const attrib = node.getAttribute(`data-emotion`).split(' ')
for (let i = 1; i < attrib.length; i++) {
inserted[attrib[i]] = true
}
@@ -114,16 +109,15 @@ let createCache = (options: Options): EmotionCache => {
)
}
- let insert: (
+ let insert /*: (
selector: string,
serialized: SerializedStyles,
sheet: StyleSheet,
shouldCache: boolean
- ) => string | void
-
+ ) => string | void */
const omnipresentPlugins = [compat, removeLabel]
- if (process.env.NODE_ENV !== 'production') {
+ if (isDevelopment) {
omnipresentPlugins.push(
createUnsafeSelectorsAlarm({
get compat() {
@@ -139,7 +133,7 @@ let createCache = (options: Options): EmotionCache => {
const finalizingPlugins = [
stringify,
- process.env.NODE_ENV !== 'production'
+ isDevelopment
? element => {
if (!element.root) {
if (element.return) {
@@ -162,19 +156,16 @@ let createCache = (options: Options): EmotionCache => {
const stylis = styles => serialize(compile(styles), serializer)
insert = (
- selector: string,
- serialized: SerializedStyles,
- sheet: StyleSheet,
- shouldCache: boolean
- ): void => {
+ selector /*: string */,
+ serialized /*: SerializedStyles */,
+ sheet /*: StyleSheet */,
+ shouldCache /*: boolean */
+ ) /*: void */ => {
currentSheet = sheet
- if (
- process.env.NODE_ENV !== 'production' &&
- serialized.map !== undefined
- ) {
+ if (isDevelopment && serialized.map !== undefined) {
currentSheet = {
- insert: (rule: string) => {
- sheet.insert(rule + ((serialized.map: any): string))
+ insert: (rule /*: string */) => {
+ sheet.insert(rule + serialized.map)
}
}
}
@@ -192,9 +183,11 @@ let createCache = (options: Options): EmotionCache => {
)
const stylis = styles => serialize(compile(styles), serializer)
- // $FlowFixMe
let serverStylisCache = getServerStylisCache(stylisPlugins)(key)
- let getRules = (selector: string, serialized: SerializedStyles): string => {
+ let getRules = (
+ selector /*: string */,
+ serialized /*: SerializedStyles */
+ ) /*: string */ => {
let name = serialized.name
if (serverStylisCache[name] === undefined) {
serverStylisCache[name] = stylis(
@@ -204,11 +197,11 @@ let createCache = (options: Options): EmotionCache => {
return serverStylisCache[name]
}
insert = (
- selector: string,
- serialized: SerializedStyles,
- sheet: StyleSheet,
- shouldCache: boolean
- ): string | void => {
+ selector /*: string */,
+ serialized /*: SerializedStyles */,
+ sheet /*: StyleSheet */,
+ shouldCache /*: boolean */
+ ) /*: string | void */ => {
let name = serialized.name
let rules = getRules(selector, serialized)
if (cache.compat === undefined) {
@@ -218,12 +211,7 @@ let createCache = (options: Options): EmotionCache => {
if (shouldCache) {
cache.inserted[name] = true
}
- if (
- // using === development instead of !== production
- // because if people do ssr in tests, the source maps showing up would be annoying
- process.env.NODE_ENV === 'development' &&
- serialized.map !== undefined
- ) {
+ if (isDevelopment && serialized.map !== undefined) {
return rules + serialized.map
}
return rules
@@ -245,11 +233,11 @@ let createCache = (options: Options): EmotionCache => {
}
}
- const cache: EmotionCache = {
+ const cache /*: EmotionCache */ = {
key,
sheet: new StyleSheet({
key,
- container: ((container: any): Node),
+ container,
nonce: options.nonce,
speedy: options.speedy,
prepend: options.prepend,
diff --git a/packages/cache/src/types.js b/packages/cache/src/types.js
index 92312fb30c..f02fb33414 100644
--- a/packages/cache/src/types.js
+++ b/packages/cache/src/types.js
@@ -1,14 +1,13 @@
-// @flow
-
+/*
export type StylisElement = {
- type: string,
- value: string,
- props: Array,
- root: StylisElement | null,
- children: Array,
- line: number,
- column: number,
- length: number,
+ type: string
+ value: string
+ props: Array
+ root: StylisElement | null
+ children: Array
+ line: number
+ column: number
+ length: number
return: string
}
export type StylisPluginCallback = (
@@ -24,3 +23,4 @@ export type StylisPlugin = (
children: Array,
callback: StylisPluginCallback
) => string | void
+*/
diff --git a/packages/cache/types/index.d.ts b/packages/cache/types/index.d.ts
index 7822587db8..3bba3ded23 100644
--- a/packages/cache/types/index.d.ts
+++ b/packages/cache/types/index.d.ts
@@ -1,5 +1,8 @@
// Definitions by: Junyoung Clare Jang
// TypeScript Version: 2.2
+
+///
+
import { EmotionCache } from '@emotion/utils'
export { EmotionCache }
diff --git a/packages/cache/types/resolved-condition.ts b/packages/cache/types/resolved-condition.ts
new file mode 100644
index 0000000000..e8abb53e2b
--- /dev/null
+++ b/packages/cache/types/resolved-condition.ts
@@ -0,0 +1 @@
+export default true as boolean
diff --git a/packages/cache/types/tsconfig.json b/packages/cache/types/tsconfig.json
index 4b5665bfd1..34bf72c65b 100644
--- a/packages/cache/types/tsconfig.json
+++ b/packages/cache/types/tsconfig.json
@@ -9,7 +9,11 @@
"strict": true,
"target": "es5",
"typeRoots": ["../"],
- "types": []
+ "types": [],
+ "paths": {
+ "#is-browser": ["./types/resolved-condition.ts"],
+ "#is-development": ["./types/resolved-condition.ts"]
+ }
},
"include": ["./*.ts", "./*.tsx"]
}
diff --git a/packages/cache/types/tslint.json b/packages/cache/types/tslint.json
index daf7494d9c..9f527d6583 100644
--- a/packages/cache/types/tslint.json
+++ b/packages/cache/types/tslint.json
@@ -2,6 +2,7 @@
"extends": "@definitelytyped/dtslint/dtslint.json",
"rules": {
"array-type": [true, "generic"],
- "semicolon": false
+ "semicolon": false,
+ "unnecessary-bind": false
}
}
diff --git a/packages/css-prettifier/CHANGELOG.md b/packages/css-prettifier/CHANGELOG.md
index 67f25c409e..e35fad574f 100644
--- a/packages/css-prettifier/CHANGELOG.md
+++ b/packages/css-prettifier/CHANGELOG.md
@@ -1,5 +1,12 @@
# @emotion/css-prettifier
+## 1.1.4
+
+### Patch Changes
+
+- Updated dependencies [[`7f8db2d`](https://github.com/emotion-js/emotion/commit/7f8db2d7a900bb34995db66084a99d512811e33d)]:
+ - @emotion/memoize@0.9.0
+
## 1.1.3
### Patch Changes
diff --git a/packages/css-prettifier/package.json b/packages/css-prettifier/package.json
index ed9c3c79a5..c025d598b7 100644
--- a/packages/css-prettifier/package.json
+++ b/packages/css-prettifier/package.json
@@ -1,6 +1,6 @@
{
"name": "@emotion/css-prettifier",
- "version": "1.1.3",
+ "version": "1.1.4",
"description": "Simple Stylis-based CSS prettifier",
"keywords": [
"emotion"
@@ -10,6 +10,10 @@
"module": "dist/emotion-css-prettifier.esm.js",
"exports": {
".": {
+ "types": {
+ "import": "./dist/emotion-css-prettifier.cjs.mjs",
+ "default": "./dist/emotion-css-prettifier.cjs.js"
+ },
"module": "./dist/emotion-css-prettifier.esm.js",
"import": "./dist/emotion-css-prettifier.cjs.mjs",
"default": "./dist/emotion-css-prettifier.cjs.js"
@@ -20,7 +24,7 @@
"license": "MIT",
"repository": "https://github.com/emotion-js/emotion/tree/main/packages/css-prettifier",
"dependencies": {
- "@emotion/memoize": "^0.8.1",
+ "@emotion/memoize": "^0.9.0",
"stylis": "4.2.0"
},
"publishConfig": {
diff --git a/packages/css/CHANGELOG.md b/packages/css/CHANGELOG.md
index fd9d8c29d2..74d62e4433 100644
--- a/packages/css/CHANGELOG.md
+++ b/packages/css/CHANGELOG.md
@@ -1,5 +1,40 @@
# emotion
+## 11.13.0
+
+### Minor Changes
+
+- [#3198](https://github.com/emotion-js/emotion/pull/3198) [`d8ff8a5`](https://github.com/emotion-js/emotion/commit/d8ff8a5990c691017b463b3fa23a9f46ab28147b) Thanks [@Andarist](https://github.com/Andarist)! - Migrated away from relying on `process.env.NODE_ENV` checks to differentiate between production and development builds.
+
+ Development builds (and other environment-specific builds) can be used by using proper conditions (see [here](https://nodejs.org/docs/v20.15.1/api/packages.html#resolving-user-conditions)). Most modern bundlers/frameworks already preconfigure those for the user so no action has to be taken.
+
+ Default files should continue to work in all environments.
+
+### Patch Changes
+
+- Updated dependencies [[`d8ff8a5`](https://github.com/emotion-js/emotion/commit/d8ff8a5990c691017b463b3fa23a9f46ab28147b), [`a9f6912`](https://github.com/emotion-js/emotion/commit/a9f691299844bf6837b7ad41ee17cd912496f3d5)]:
+ - @emotion/cache@11.13.0
+ - @emotion/serialize@1.3.0
+ - @emotion/sheet@1.4.0
+ - @emotion/utils@1.4.0
+
+## 11.12.0
+
+### Minor Changes
+
+- [#2558](https://github.com/emotion-js/emotion/pull/2558) [`85772c3`](https://github.com/emotion-js/emotion/commit/85772c33ecb01c70bc8afafa627c9fb7140b593c) Thanks [@emmatown](https://github.com/emmatown)! - Source code has been migrated to TypeScript. From now on type declarations will be emitted based on that, instead of being hand-written.
+
+### Patch Changes
+
+- [#2558](https://github.com/emotion-js/emotion/pull/2558) [`85772c3`](https://github.com/emotion-js/emotion/commit/85772c33ecb01c70bc8afafa627c9fb7140b593c) Thanks [@emmatown](https://github.com/emmatown)! - Fixed `options` parameter to `createEmotion` from `@emotion/css/create-instance` incorrectly being marked as optional when it's required.
+
+- Updated dependencies [[`9ca22c6`](https://github.com/emotion-js/emotion/commit/9ca22c6c23e9effa086d161a9b0ae1c645686680), [`16d8a8c`](https://github.com/emotion-js/emotion/commit/16d8a8c2198461c4842c73048b406c346a70aa59), [`52aadc6`](https://github.com/emotion-js/emotion/commit/52aadc6e77140867392f81545cc92e04fd84d453), [`52aadc6`](https://github.com/emotion-js/emotion/commit/52aadc6e77140867392f81545cc92e04fd84d453)]:
+ - @emotion/serialize@1.2.0
+ - @emotion/utils@1.3.0
+ - @emotion/sheet@1.3.0
+ - @emotion/babel-plugin@11.12.0
+ - @emotion/cache@11.12.0
+
## 11.11.2
### Patch Changes
diff --git a/packages/css/create-instance/package.json b/packages/css/create-instance/package.json
index 203a18da18..bd294c0d39 100644
--- a/packages/css/create-instance/package.json
+++ b/packages/css/create-instance/package.json
@@ -2,7 +2,7 @@
"main": "dist/emotion-css-create-instance.cjs.js",
"module": "dist/emotion-css-create-instance.esm.js",
"umd:main": "dist/emotion-css-create-instance.umd.min.js",
- "types": "../types/create-instance",
+ "types": "dist/emotion-css-create-instance.cjs.d.ts",
"preconstruct": {
"umdName": "createEmotion"
}
diff --git a/packages/css/macro.js.flow b/packages/css/macro.js.flow
deleted file mode 100644
index 63ae97e66d..0000000000
--- a/packages/css/macro.js.flow
+++ /dev/null
@@ -1,2 +0,0 @@
-// @flow
-export * from './src/index.js'
diff --git a/packages/css/package.json b/packages/css/package.json
index caed679ae1..1a1734be0d 100644
--- a/packages/css/package.json
+++ b/packages/css/package.json
@@ -1,10 +1,10 @@
{
"name": "@emotion/css",
- "version": "11.11.2",
+ "version": "11.13.0",
"description": "The Next Generation of CSS-in-JS.",
"main": "dist/emotion-css.cjs.js",
"module": "dist/emotion-css.esm.js",
- "types": "types/index.d.ts",
+ "types": "dist/emotion-css.cjs.d.ts",
"files": [
"src",
"dist",
@@ -16,15 +16,15 @@
"test:typescript": "dtslint types"
},
"dependencies": {
- "@emotion/babel-plugin": "^11.11.0",
- "@emotion/cache": "^11.11.0",
- "@emotion/serialize": "^1.1.2",
- "@emotion/sheet": "^1.2.2",
- "@emotion/utils": "^1.2.1"
+ "@emotion/babel-plugin": "^11.12.0",
+ "@emotion/cache": "^11.13.0",
+ "@emotion/serialize": "^1.3.0",
+ "@emotion/sheet": "^1.4.0",
+ "@emotion/utils": "^1.4.0"
},
"devDependencies": {
"@definitelytyped/dtslint": "0.0.112",
- "typescript": "^4.5.5"
+ "typescript": "^5.4.5"
},
"author": "Kye Hohenberger",
"homepage": "https://emotion.sh",
@@ -43,11 +43,29 @@
"umd:main": "dist/emotion-css.umd.min.js",
"exports": {
".": {
+ "types": {
+ "import": "./dist/emotion-css.cjs.mjs",
+ "default": "./dist/emotion-css.cjs.js"
+ },
+ "development": {
+ "module": "./dist/emotion-css.development.esm.js",
+ "import": "./dist/emotion-css.development.cjs.mjs",
+ "default": "./dist/emotion-css.development.cjs.js"
+ },
"module": "./dist/emotion-css.esm.js",
"import": "./dist/emotion-css.cjs.mjs",
"default": "./dist/emotion-css.cjs.js"
},
"./create-instance": {
+ "types": {
+ "import": "./create-instance/dist/emotion-css-create-instance.cjs.mjs",
+ "default": "./create-instance/dist/emotion-css-create-instance.cjs.js"
+ },
+ "development": {
+ "module": "./create-instance/dist/emotion-css-create-instance.development.esm.js",
+ "import": "./create-instance/dist/emotion-css-create-instance.development.cjs.mjs",
+ "default": "./create-instance/dist/emotion-css-create-instance.development.cjs.js"
+ },
"module": "./create-instance/dist/emotion-css-create-instance.esm.js",
"import": "./create-instance/dist/emotion-css-create-instance.cjs.mjs",
"default": "./create-instance/dist/emotion-css-create-instance.cjs.js"
@@ -61,11 +79,17 @@
"default": "./macro.js"
}
},
+ "imports": {
+ "#is-development": {
+ "development": "./src/conditions/true.ts",
+ "default": "./src/conditions/false.ts"
+ }
+ },
"preconstruct": {
"umdName": "emotion",
"entrypoints": [
- "./index.js",
- "./create-instance.js"
+ "./index.ts",
+ "./create-instance.ts"
],
"exports": {
"extra": {
diff --git a/packages/css/src/conditions/false.ts b/packages/css/src/conditions/false.ts
new file mode 100644
index 0000000000..44fe920021
--- /dev/null
+++ b/packages/css/src/conditions/false.ts
@@ -0,0 +1 @@
+export default false as boolean
diff --git a/packages/css/src/conditions/true.ts b/packages/css/src/conditions/true.ts
new file mode 100644
index 0000000000..e8abb53e2b
--- /dev/null
+++ b/packages/css/src/conditions/true.ts
@@ -0,0 +1 @@
+export default true as boolean
diff --git a/packages/css/src/create-instance.d.ts b/packages/css/src/create-instance.d.ts
deleted file mode 100644
index 5329dce3b6..0000000000
--- a/packages/css/src/create-instance.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../types/create-instance'
-export { default } from '../types/create-instance'
diff --git a/packages/css/src/create-instance.js b/packages/css/src/create-instance.ts
similarity index 50%
rename from packages/css/src/create-instance.js
rename to packages/css/src/create-instance.ts
index 3b18761368..09b6b37789 100644
--- a/packages/css/src/create-instance.js
+++ b/packages/css/src/create-instance.ts
@@ -1,21 +1,81 @@
-// @flow
import createCache from '@emotion/cache'
-import { serializeStyles } from '@emotion/serialize'
+import {
+ serializeStyles,
+ CSSInterpolation,
+ Interpolation
+} from '@emotion/serialize'
import {
insertStyles,
getRegisteredStyles,
- type EmotionCache,
- type SerializedStyles
+ SerializedStyles,
+ RegisteredCache
} from '@emotion/utils'
-
-function insertWithoutScoping(cache, serialized: SerializedStyles) {
+import { EmotionCache, Options } from '@emotion/cache'
+import { StyleSheet } from '@emotion/sheet'
+import isDevelopment from '#is-development'
+
+export type {
+ CSSInterpolation,
+ ArrayCSSInterpolation,
+ ComponentSelector,
+ CSSObject
+} from '@emotion/serialize'
+
+function insertWithoutScoping(
+ cache: EmotionCache,
+ serialized: SerializedStyles
+) {
if (cache.inserted[serialized.name] === undefined) {
return cache.insert('', serialized, cache.sheet, true)
}
}
-function merge(registered: Object, css: (*) => string, className: string) {
- const registeredStyles = []
+export type { EmotionCache, Options }
+
+export interface ArrayClassNamesArg extends Array {}
+export type ClassNamesArg =
+ | undefined
+ | null
+ | string
+ | boolean
+ | { [className: string]: boolean | null | undefined }
+ | ArrayClassNamesArg
+
+export interface CSSStyleSheet extends StyleSheet {
+ speedy(value: boolean): void
+}
+
+export interface Emotion {
+ css(template: TemplateStringsArray, ...args: Array): string
+ css(...args: Array): string
+ cx(...classNames: Array): string
+ flush(): void
+ hydrate(ids: Array): void
+ injectGlobal(
+ template: TemplateStringsArray,
+ ...args: Array
+ ): void
+ injectGlobal(...args: Array): void
+ keyframes(
+ template: TemplateStringsArray,
+ ...args: Array
+ ): string
+ keyframes(...args: Array): string
+ sheet: CSSStyleSheet
+ cache: EmotionCache
+ merge(className: string): string
+ getRegisteredStyles(
+ registeredStyles: Array,
+ className: string
+ ): string
+}
+
+function merge(
+ registered: RegisteredCache,
+ css: Emotion['css'],
+ className: string
+) {
+ const registeredStyles: string[] = []
const rawClassName = getRegisteredStyles(
registered,
registeredStyles,
@@ -28,60 +88,29 @@ function merge(registered: Object, css: (*) => string, className: string) {
return rawClassName + css(registeredStyles)
}
-export type Interpolation = any
-export type Interpolations = Array
-
-type CreateStyles = (...args: Interpolations) => ReturnValue
-
-type ClassNameArg =
- | string
- | boolean
- | { [key: string]: boolean | void | null }
- | Array
- | void
- | null
-
-declare class StyleSheet {
- insert(rule: string): void;
- flush(): void;
- speedy(newVal: boolean): void;
- tags: Array;
- isSpeedy: number;
- ctr: number;
-}
-
-export type Emotion = {
- css: CreateStyles,
- cx: (...classNames: Array) => string,
- flush: () => void,
- hydrate: (ids: Array) => void,
- injectGlobal: CreateStyles,
- keyframes: CreateStyles,
- sheet: StyleSheet,
- cache: EmotionCache,
- merge: *,
- getRegisteredStyles: *
-}
-
-let createEmotion = (options: *): Emotion => {
+let createEmotion = (options: Options): Emotion => {
let cache = createCache(options)
- // $FlowFixMe
- cache.sheet.speedy = function (value: boolean) {
- if (process.env.NODE_ENV !== 'production' && this.ctr !== 0) {
+ ;(cache.sheet as CSSStyleSheet).speedy = function (value: boolean) {
+ if (isDevelopment && this.ctr !== 0) {
throw new Error('speedy must be changed before any rules are inserted')
}
this.isSpeedy = value
}
+
cache.compat = true
- let css = (...args) => {
+ let css: Emotion['css'] = (
+ ...args: (TemplateStringsArray | Interpolation)[]
+ ) => {
let serialized = serializeStyles(args, cache.registered, undefined)
insertStyles(cache, serialized, false)
return `${cache.key}-${serialized.name}`
}
- let keyframes = (...args) => {
+ let keyframes: Emotion['keyframes'] = (
+ ...args: (TemplateStringsArray | Interpolation)[]
+ ) => {
let serialized = serializeStyles(args, cache.registered)
let animation = `animation-${serialized.name}`
insertWithoutScoping(cache, {
@@ -91,12 +120,14 @@ let createEmotion = (options: *): Emotion => {
return animation
}
- let injectGlobal = (...args) => {
+ let injectGlobal: Emotion['injectGlobal'] = (
+ ...args: (TemplateStringsArray | Interpolation)[]
+ ) => {
let serialized = serializeStyles(args, cache.registered)
insertWithoutScoping(cache, serialized)
}
- let cx = (...args) => {
+ let cx: Emotion['cx'] = (...args) => {
return merge(cache.registered, css, classnames(args))
}
return {
@@ -104,7 +135,7 @@ let createEmotion = (options: *): Emotion => {
cx,
injectGlobal,
keyframes,
- hydrate(ids: Array) {
+ hydrate(ids) {
ids.forEach(key => {
cache.inserted[key] = true
})
@@ -114,15 +145,14 @@ let createEmotion = (options: *): Emotion => {
cache.inserted = {}
cache.sheet.flush()
},
- // $FlowFixMe
- sheet: cache.sheet,
+ sheet: cache.sheet as CSSStyleSheet,
cache,
getRegisteredStyles: getRegisteredStyles.bind(null, cache.registered),
merge: merge.bind(null, cache.registered, css)
}
}
-let classnames = args => {
+let classnames = (args: ClassNamesArg[]) => {
let cls = ''
for (let i = 0; i < args.length; i++) {
let arg = args[i]
diff --git a/packages/css/src/index.d.ts b/packages/css/src/index.d.ts
deleted file mode 100644
index 51a3b4100a..0000000000
--- a/packages/css/src/index.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from '../types'
diff --git a/packages/css/src/index.js b/packages/css/src/index.ts
similarity index 95%
rename from packages/css/src/index.js
rename to packages/css/src/index.ts
index 523fed93ef..9e4000e3d8 100644
--- a/packages/css/src/index.js
+++ b/packages/css/src/index.ts
@@ -1,4 +1,3 @@
-// @flow
import createEmotion from './create-instance'
export const {
diff --git a/packages/css/test/css.test.js b/packages/css/test/css.test.js
index b32630a6d1..7b44dab7a8 100644
--- a/packages/css/test/css.test.js
+++ b/packages/css/test/css.test.js
@@ -1,4 +1,3 @@
-// @flow
import 'test-utils/legacy-env'
import React from 'react'
import renderer from 'react-test-renderer'
diff --git a/packages/css/test/cx.test.js b/packages/css/test/cx.test.js
index fc074cbbaf..30370209ed 100644
--- a/packages/css/test/cx.test.js
+++ b/packages/css/test/cx.test.js
@@ -1,4 +1,3 @@
-// @flow
import 'test-utils/legacy-env'
import React from 'react'
import renderer from 'react-test-renderer'
diff --git a/packages/css/test/inject-global.test.js b/packages/css/test/inject-global.test.js
index 44e9d0d66e..44050042ee 100644
--- a/packages/css/test/inject-global.test.js
+++ b/packages/css/test/inject-global.test.js
@@ -1,4 +1,3 @@
-// @flow
import 'test-utils/legacy-env'
import { injectGlobal, sheet, flush, css } from '@emotion/css'
diff --git a/packages/css/test/instance/__snapshots__/inline.test.js.snap b/packages/css/test/instance/__snapshots__/inline.test.js.snap
index a37cfa6b9e..af57da0c92 100644
--- a/packages/css/test/instance/__snapshots__/inline.test.js.snap
+++ b/packages/css/test/instance/__snapshots__/inline.test.js.snap
@@ -6,12 +6,12 @@ exports[`hydration only inserts rules that are not in the critical css 1`] = `
>
@font-face{font-family:'Patrick Hand SC';font-style:normal;font-weight:400;src:local('Patrick Hand SC'),local('PatrickHandSC-Regular'),url(https://fonts.gstatic.com/s/patrickhandsc/v4/OYFWCgfCR-7uHIovjUZXsZ71Uis0Qeb9Gqo8IZV7ckE.woff2) format('woff2');unicode-range:U+0100-024f,U+1-1eff,U+20a0-20ab,U+20ad-20cf,U+2c60-2c7f,U+A720-A7FF;}@keyframes animation-i9f7qw-bounce{from,20%,53%,80%,to{animation-timing-function:cubic-bezier(0.215, 0.61, 0.355, 1);transform:translate3d(0, 0, 0);}40%,43%{animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06);transform:translate3d(0, -30px, 0);}70%{animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06);transform:translate3d(0, -15px, 0);}90%{transform:translate3d(0, -4px, 0);}}.no-prefix{display:flex;justify-content:center;}
-
-
+
-
-
+
-
-
+
Hello
diff --git a/packages/css/test/instance/__snapshots__/stream.test.js.snap b/packages/css/test/instance/__snapshots__/stream.test.js.snap
index 9f65fc6841..61851b0398 100644
--- a/packages/css/test/instance/__snapshots__/stream.test.js.snap
+++ b/packages/css/test/instance/__snapshots__/stream.test.js.snap
@@ -1,12 +1,12 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`hydration only inserts rules that are not in the critical css 1`] = `
-
-
+
-
+
-
+
Hello
diff --git a/packages/css/test/instance/css.test.js b/packages/css/test/instance/css.test.js
index 73685174d9..67a2a02ea4 100644
--- a/packages/css/test/instance/css.test.js
+++ b/packages/css/test/instance/css.test.js
@@ -1,4 +1,3 @@
-// @flow
import 'test-utils/next-env'
import React from 'react'
import renderer from 'react-test-renderer'
diff --git a/packages/css/test/instance/emotion-instance.js b/packages/css/test/instance/emotion-instance.js
index 943d712879..59a4d1f8b6 100644
--- a/packages/css/test/instance/emotion-instance.js
+++ b/packages/css/test/instance/emotion-instance.js
@@ -1,4 +1,3 @@
-// @flow
import createEmotion from '@emotion/css/create-instance'
import createEmotionServer from '@emotion/server/create-instance'
@@ -12,7 +11,6 @@ export let container
if (typeof document !== 'undefined') {
container = document.createElement('div')
- // $FlowFixMe
document.head.appendChild(container)
}
diff --git a/packages/css/test/instance/instance.test.js b/packages/css/test/instance/instance.test.js
index af9f5e668d..b3ee02629b 100644
--- a/packages/css/test/instance/instance.test.js
+++ b/packages/css/test/instance/instance.test.js
@@ -1,4 +1,3 @@
-// @flow
import createEmotion from '@emotion/css/create-instance'
import { container, css, sheet } from './emotion-instance'
diff --git a/packages/css/test/keyframes.test.js b/packages/css/test/keyframes.test.js
index fc2a5b0626..961568ca82 100644
--- a/packages/css/test/keyframes.test.js
+++ b/packages/css/test/keyframes.test.js
@@ -1,4 +1,3 @@
-// @flow
import 'test-utils/legacy-env'
import React from 'react'
import renderer from 'react-test-renderer'
diff --git a/packages/css/test/no-babel/index.test.js b/packages/css/test/no-babel/index.test.js
index 527671accf..2b0daf8e72 100644
--- a/packages/css/test/no-babel/index.test.js
+++ b/packages/css/test/no-babel/index.test.js
@@ -1,4 +1,3 @@
-// @flow
import 'test-utils/legacy-env'
import React from 'react'
import renderer from 'react-test-renderer'
@@ -228,7 +227,7 @@ describe('css', () => {
expect(tree).toMatchSnapshot()
})
test('name with class component', () => {
- class SomeComponent extends React.Component<{ className: string }> {
+ class SomeComponent extends React.Component /* <{ className: string }> */ {
render() {
return
}
diff --git a/packages/css/test/no-babel/warnings.test.js b/packages/css/test/no-babel/warnings.test.js
index 3e1e74430a..533e08a4ee 100644
--- a/packages/css/test/no-babel/warnings.test.js
+++ b/packages/css/test/no-babel/warnings.test.js
@@ -1,22 +1,20 @@
-// @flow
import 'test-utils/legacy-env'
import { css } from '@emotion/css'
-// $FlowFixMe
console.error = jest.fn()
afterEach(() => {
jest.clearAllMocks()
})
-it('warns about illegal escape sequences inside first quasi of template literal', () => {
+test('warns about illegal escape sequences inside first quasi of template literal', () => {
css`
:before {
content: '\00d7';
}
`
- expect((console.error: any).mock.calls[0]).toMatchInlineSnapshot(`
+ expect(console.error.mock.calls[0]).toMatchInlineSnapshot(`
[
"You have illegal escape sequence in your template literal, most likely inside content's property value.
Because you write your CSS inside a JavaScript string you actually have to do double escaping, so for example "content: '\\00d7';" should become "content: '\\\\00d7';".
@@ -26,7 +24,7 @@ it('warns about illegal escape sequences inside first quasi of template literal'
`)
})
-it('warns about illegal escape sequences inside non-first quasi of template literal', () => {
+test('warns about illegal escape sequences inside non-first quasi of template literal', () => {
const color = `color: hotpink`
css`
background-color: black;
@@ -36,7 +34,7 @@ it('warns about illegal escape sequences inside non-first quasi of template lite
}
`
- expect((console.error: any).mock.calls[0]).toMatchInlineSnapshot(`
+ expect(console.error.mock.calls[0]).toMatchInlineSnapshot(`
[
"You have illegal escape sequence in your template literal, most likely inside content's property value.
Because you write your CSS inside a JavaScript string you actually have to do double escaping, so for example "content: '\\00d7';" should become "content: '\\\\00d7';".
diff --git a/packages/css/test/selectivity.test.js b/packages/css/test/selectivity.test.js
index dd66dc32b0..c6782b88d2 100644
--- a/packages/css/test/selectivity.test.js
+++ b/packages/css/test/selectivity.test.js
@@ -1,4 +1,3 @@
-// @flow
import 'test-utils/legacy-env'
import { css, sheet, flush } from '@emotion/css'
diff --git a/packages/css/test/sheet.dom.test.js b/packages/css/test/sheet.dom.test.js
index d482d84c02..90833e56e1 100644
--- a/packages/css/test/sheet.dom.test.js
+++ b/packages/css/test/sheet.dom.test.js
@@ -1,4 +1,3 @@
-// @flow
import { sheet } from '@emotion/css'
const consoleError = console.error
diff --git a/packages/css/test/warnings.test.js b/packages/css/test/warnings.test.js
index 61c4235214..a692085a7b 100644
--- a/packages/css/test/warnings.test.js
+++ b/packages/css/test/warnings.test.js
@@ -1,11 +1,9 @@
-// @flow
import 'test-utils/legacy-env'
import { css } from '@emotion/css'
import createCss from '@emotion/css/create-instance'
import * as React from 'react'
import renderer from 'react-test-renderer'
-// $FlowFixMe
console.error = jest.fn()
const validValues = [
@@ -36,7 +34,7 @@ afterEach(() => {
jest.clearAllMocks()
})
-it('does not warn when valid values are passed for the content property', () => {
+test('does not warn when valid values are passed for the content property', () => {
const cls = css(validValues.map(value => ({ content: value })))
expect(console.error).not.toBeCalled()
expect(renderer.create(
).toJSON()).toMatchSnapshot()
@@ -44,7 +42,7 @@ it('does not warn when valid values are passed for the content property', () =>
const invalidValues = ['this is not valid', '']
-it('does warn when invalid values are passed for the content property', () => {
+test('does warn when invalid values are passed for the content property', () => {
invalidValues.forEach(value => {
expect(() =>
renderer.create(
)
@@ -54,20 +52,20 @@ it('does warn when invalid values are passed for the content property', () => {
})
})
-it('does warn when functions are passed to css calls', () => {
+test('does warn when functions are passed to css calls', () => {
css(() => 'color:hotpink;')
expect(console.error).toBeCalledWith(
"Functions that are interpolated in css calls will be stringified.\nIf you want to have a css call based on props, create a function that returns a css call like this\nlet dynamicStyle = (props) => css`color: ${props.color}`\nIt can be called directly with props or interpolated in a styled call like this\nlet SomeComponent = styled('div')`${dynamicStyle}`"
)
})
-it('does warn when @import rule is being inserted after order-insensitive rules', () => {
+test('does warn when @import rule is being inserted after order-insensitive rules', () => {
const { injectGlobal } = createCss({ key: 'import-after-regular' })
injectGlobal`.thing {display:flex;}`
injectGlobal`@import 'custom.css';`
- expect((console.error: any).mock.calls).toMatchInlineSnapshot(`
+ expect(console.error.mock.calls).toMatchInlineSnapshot(`
[
[
"You're attempting to insert the following rule:
diff --git a/packages/css/types/create-instance.d.ts b/packages/css/types/create-instance.d.ts
index 9e560390f1..e505b19935 100644
--- a/packages/css/types/create-instance.d.ts
+++ b/packages/css/types/create-instance.d.ts
@@ -1,55 +1,4 @@
// Definitions by: Junyoung Clare Jang
// TypeScript Version: 2.8
-
-import { EmotionCache, Options } from '@emotion/cache'
-import { CSSInterpolation } from '@emotion/serialize'
-import { StyleSheet } from '@emotion/sheet'
-
-export {
- CSSInterpolation,
- ArrayCSSInterpolation,
- ComponentSelector,
- CSSObject
-} from '@emotion/serialize'
-
-export { EmotionCache, Options }
-
-export interface ArrayClassNamesArg extends Array {}
-export type ClassNamesArg =
- | undefined
- | null
- | string
- | boolean
- | { [className: string]: boolean | null | undefined }
- | ArrayClassNamesArg
-
-export interface CSSStyleSheet extends StyleSheet {
- speedy(value: boolean): void
-}
-
-export interface Emotion {
- css(template: TemplateStringsArray, ...args: Array): string
- css(...args: Array): string
- cx(...classNames: Array): string
- flush(): void
- hydrate(ids: Array): void
- injectGlobal(
- template: TemplateStringsArray,
- ...args: Array
- ): void
- injectGlobal(...args: Array): void
- keyframes(
- template: TemplateStringsArray,
- ...args: Array
- ): string
- keyframes(...args: Array): string
- sheet: CSSStyleSheet
- cache: EmotionCache
- merge(className: string): string
- getRegisteredStyles(
- registeredStyles: Array,
- className: string
- ): string
-}
-
-export default function createEmotion(options?: Options): Emotion
+export * from '../create-instance'
+export { default } from '../create-instance'
diff --git a/packages/css/types/index.d.ts b/packages/css/types/index.d.ts
index 7efec6edee..23f9a3c26e 100644
--- a/packages/css/types/index.d.ts
+++ b/packages/css/types/index.d.ts
@@ -1,26 +1,3 @@
-// Definitions by: Junyoung Clare Jang
-// TypeScript Version: 2.8
+///
-import { Emotion } from './create-instance'
-
-export {
- ArrayClassNamesArg,
- ArrayCSSInterpolation,
- ClassNamesArg,
- ComponentSelector,
- EmotionCache,
- CSSInterpolation,
- CSSObject,
- CSSStyleSheet
-} from './create-instance'
-
-export const flush: Emotion['flush']
-export const hydrate: Emotion['hydrate']
-export const cx: Emotion['cx']
-export const merge: Emotion['merge']
-export const getRegisteredStyles: Emotion['getRegisteredStyles']
-export const css: Emotion['css']
-export const injectGlobal: Emotion['injectGlobal']
-export const keyframes: Emotion['keyframes']
-export const sheet: Emotion['sheet']
-export const cache: Emotion['cache']
+export * from '..'
diff --git a/packages/css/types/tsconfig.json b/packages/css/types/tsconfig.json
index 4b5665bfd1..66469a7f3a 100644
--- a/packages/css/types/tsconfig.json
+++ b/packages/css/types/tsconfig.json
@@ -9,7 +9,11 @@
"strict": true,
"target": "es5",
"typeRoots": ["../"],
- "types": []
+ "types": [],
+ "paths": {
+ "#is-browser": ["./src/conditions/true.ts"],
+ "#is-development": ["./src/conditions/true.ts"]
+ }
},
"include": ["./*.ts", "./*.tsx"]
}
diff --git a/packages/css/types/tslint.json b/packages/css/types/tslint.json
index af5dcd0aa0..bf5ec4e372 100644
--- a/packages/css/types/tslint.json
+++ b/packages/css/types/tslint.json
@@ -18,6 +18,7 @@
"check-typecast",
"check-type-operator",
"check-preblock"
- ]
+ ],
+ "unnecessary-bind": false
}
}
diff --git a/packages/eslint-plugin/CHANGELOG.md b/packages/eslint-plugin/CHANGELOG.md
index 5ce71f6d34..67f0734ae5 100644
--- a/packages/eslint-plugin/CHANGELOG.md
+++ b/packages/eslint-plugin/CHANGELOG.md
@@ -1,5 +1,17 @@
# @emotion/eslint-plugin
+## 11.12.0
+
+### Minor Changes
+
+- [#2568](https://github.com/emotion-js/emotion/pull/2568) [`304f7e3`](https://github.com/emotion-js/emotion/commit/304f7e3da4fb7a4c38eff0fa27cc6db417bfe10c) Thanks [@G-Rath](https://github.com/G-Rath)! - Source code has been migrated to TypeScript. From now on type declarations will be emitted based on that, instead of being hand-written.
+
+### Patch Changes
+
+- [#2568](https://github.com/emotion-js/emotion/pull/2568) [`304f7e3`](https://github.com/emotion-js/emotion/commit/304f7e3da4fb7a4c38eff0fa27cc6db417bfe10c) Thanks [@G-Rath](https://github.com/G-Rath)! - An empty css prop (`
`) will now raise an error in the `@emotion/syntax-preference` rule instead of crashing on this case.
+
+- [#2568](https://github.com/emotion-js/emotion/pull/2568) [`304f7e3`](https://github.com/emotion-js/emotion/commit/304f7e3da4fb7a4c38eff0fa27cc6db417bfe10c) Thanks [@G-Rath](https://github.com/G-Rath)! - Fixed a crash on empty css prop (`
`) in the `@emotion/jsx-import` rule.
+
## 11.11.0
### Patch Changes
diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json
index 996c688f92..8674d6f7b2 100644
--- a/packages/eslint-plugin/package.json
+++ b/packages/eslint-plugin/package.json
@@ -1,6 +1,6 @@
{
"name": "@emotion/eslint-plugin",
- "version": "11.11.0",
+ "version": "11.12.0",
"description": "ESLint rules for emotion",
"keywords": [
"eslint",
@@ -13,6 +13,10 @@
"module": "dist/emotion-eslint-plugin.esm.js",
"exports": {
".": {
+ "types": {
+ "import": "./dist/emotion-eslint-plugin.cjs.mjs",
+ "default": "./dist/emotion-eslint-plugin.cjs.js"
+ },
"module": "./dist/emotion-eslint-plugin.esm.js",
"import": "./dist/emotion-eslint-plugin.cjs.mjs",
"default": "./dist/emotion-eslint-plugin.cjs.js"
@@ -27,7 +31,12 @@
"peerDependencies": {
"eslint": "6 || 7 || 8"
},
+ "dependencies": {
+ "@typescript-eslint/utils": "^5.25.0"
+ },
"devDependencies": {
- "eslint": "^7.10.0"
+ "@types/eslint": "^7.0.0",
+ "eslint": "^8.57.0",
+ "resolve-from": "^5.0.0"
}
}
diff --git a/packages/eslint-plugin/src/index.js b/packages/eslint-plugin/src/index.ts
similarity index 94%
rename from packages/eslint-plugin/src/index.js
rename to packages/eslint-plugin/src/index.ts
index e626a190cb..3c27f57e22 100644
--- a/packages/eslint-plugin/src/index.js
+++ b/packages/eslint-plugin/src/index.ts
@@ -1,5 +1,3 @@
-// @flow
-
import importFromEmotion from './rules/import-from-emotion'
import noVanilla from './rules/no-vanilla'
import syntaxPreference from './rules/syntax-preference'
@@ -7,7 +5,7 @@ import styledImport from './rules/styled-import'
import jsxImport from './rules/jsx-import'
import pkgRenaming from './rules/pkg-renaming'
-export let rules = {
+export const rules = {
'import-from-emotion': importFromEmotion,
'no-vanilla': noVanilla,
'syntax-preference': syntaxPreference,
diff --git a/packages/eslint-plugin/src/rules/import-from-emotion.js b/packages/eslint-plugin/src/rules/import-from-emotion.js
deleted file mode 100644
index 7889e3ca5b..0000000000
--- a/packages/eslint-plugin/src/rules/import-from-emotion.js
+++ /dev/null
@@ -1,42 +0,0 @@
-export default {
- meta: {
- fixable: 'code'
- },
- create(context) {
- return {
- ImportDeclaration(node) {
- if (
- node.source.value === 'react-emotion' &&
- node.specifiers.some(x => x.type !== 'ImportDefaultSpecifier')
- ) {
- context.report({
- node: node.source,
- message: `emotion's exports should be imported directly from emotion rather than from react-emotion`,
- fix(fixer) {
- if (node.specifiers[0].type === 'ImportNamespaceSpecifier') {
- return
- }
- // default specifiers are always first
- if (node.specifiers[0].type === 'ImportDefaultSpecifier') {
- return fixer.replaceText(
- node,
- `import ${
- node.specifiers[0].local.name
- } from '@emotion/styled';\nimport { ${node.specifiers
- .filter(x => x.type === 'ImportSpecifier')
- .map(x =>
- x.local.name === x.imported.name
- ? x.local.name
- : `${x.imported.name} as ${x.local.name}`
- )
- .join(', ')} } from 'emotion';`
- )
- }
- return fixer.replaceText(node.source, "'emotion'")
- }
- })
- }
- }
- }
- }
-}
diff --git a/packages/eslint-plugin/src/rules/import-from-emotion.ts b/packages/eslint-plugin/src/rules/import-from-emotion.ts
new file mode 100644
index 0000000000..c390ff1d74
--- /dev/null
+++ b/packages/eslint-plugin/src/rules/import-from-emotion.ts
@@ -0,0 +1,69 @@
+import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/utils'
+import { createRule } from '../utils'
+
+const messages = {
+ incorrectImport: `emotion's exports should be imported directly from emotion rather than from react-emotion`
+}
+
+export default createRule({
+ name: __filename,
+ meta: {
+ docs: {
+ description: 'Ensure styled is imported from @emotion/styled',
+ recommended: false
+ },
+ fixable: 'code',
+ messages,
+ schema: [],
+ type: 'problem'
+ },
+ defaultOptions: [],
+ create(context) {
+ return {
+ ImportDeclaration(node) {
+ if (
+ node.source.value === 'react-emotion' &&
+ node.specifiers.some(
+ x => x.type !== AST_NODE_TYPES.ImportDefaultSpecifier
+ )
+ ) {
+ context.report({
+ node: node.source,
+ messageId: 'incorrectImport',
+ fix(fixer) {
+ if (
+ node.specifiers[0].type ===
+ AST_NODE_TYPES.ImportNamespaceSpecifier
+ ) {
+ return null
+ }
+ // default specifiers are always first
+ if (
+ node.specifiers[0].type ===
+ AST_NODE_TYPES.ImportDefaultSpecifier
+ ) {
+ return fixer.replaceText(
+ node,
+ `import ${
+ node.specifiers[0].local.name
+ } from '@emotion/styled';\nimport { ${node.specifiers
+ .filter(
+ (x): x is TSESTree.ImportSpecifier =>
+ x.type === AST_NODE_TYPES.ImportSpecifier
+ )
+ .map(x =>
+ x.local.name === x.imported.name
+ ? x.local.name
+ : `${x.imported.name} as ${x.local.name}`
+ )
+ .join(', ')} } from 'emotion';`
+ )
+ }
+ return fixer.replaceText(node.source, "'emotion'")
+ }
+ })
+ }
+ }
+ }
+ }
+})
diff --git a/packages/eslint-plugin/src/rules/jsx-import.js b/packages/eslint-plugin/src/rules/jsx-import.ts
similarity index 57%
rename from packages/eslint-plugin/src/rules/jsx-import.js
rename to packages/eslint-plugin/src/rules/jsx-import.ts
index 8b7cab8a65..2ee930f8d2 100644
--- a/packages/eslint-plugin/src/rules/jsx-import.js
+++ b/packages/eslint-plugin/src/rules/jsx-import.ts
@@ -1,3 +1,6 @@
+import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/utils'
+import { createRule, REPO_URL } from '../utils'
+
const JSX_ANNOTATION_REGEX = /\*?\s*@jsx\s+([^\s]+)/
const JSX_IMPORT_SOURCE_REGEX = /\*?\s*@jsxImportSource\s+([^\s]+)/
@@ -6,9 +9,34 @@ const JSX_IMPORT_SOURCE_REGEX = /\*?\s*@jsxImportSource\s+([^\s]+)/
// to
//
+ import { css }
-export default {
+declare module '@typescript-eslint/utils/dist/ts-eslint/Rule' {
+ export interface SharedConfigurationSettings {
+ react?: { pragma?: string }
+ }
+}
+
+type JSXConfig = {
+ runtime: string
+ importSource?: string
+}
+
+type RuleOptions = [(JSXConfig | string)?]
+
+const messages = {
+ cssProp: `The css prop can only be used if jsxImportSource is set to {{ importSource }}`,
+ cssPropWithPragma: `The css prop can only be used if jsx from @emotion/react is imported and it is set as the jsx pragma`,
+ templateLiterals: `Template literals should be replaced with tagged template literals using \`css\` when using the css prop`
+}
+
+export default createRule({
+ name: __filename,
meta: {
+ docs: {
+ description: 'Ensure jsx from @emotion/react is imported',
+ recommended: false
+ },
fixable: 'code',
+ messages,
schema: {
type: 'array',
items: {
@@ -29,11 +57,14 @@ export default {
},
uniqueItems: true,
minItems: 0
- }
+ },
+ type: 'problem'
},
+ defaultOptions: [],
create(context) {
const jsxRuntimeMode = context.options.find(
- option => option && option.runtime === 'automatic'
+ (option): option is JSXConfig =>
+ typeof option === 'object' && option.runtime === 'automatic'
)
if (jsxRuntimeMode) {
@@ -42,15 +73,14 @@ export default {
if (node.name.name !== 'css') {
return
}
- const importSource =
- (jsxRuntimeMode || {}).importSource || '@emotion/react'
- let jsxImportSourcePragmaNode
+ const importSource = jsxRuntimeMode?.importSource || '@emotion/react'
+ let jsxImportSourcePragmaComment: TSESTree.Comment | null = null
let jsxImportSourceMatch
let validJsxImportSource = false
let sourceCode = context.getSourceCode()
- let pragma = sourceCode.getAllComments().find(node => {
- if (JSX_IMPORT_SOURCE_REGEX.test(node.value)) {
- jsxImportSourcePragmaNode = node
+ let pragma = sourceCode.getAllComments().find(comment => {
+ if (JSX_IMPORT_SOURCE_REGEX.test(comment.value)) {
+ jsxImportSourcePragmaComment = comment
return true
}
})
@@ -65,7 +95,8 @@ export default {
if (!jsxImportSourceMatch) {
context.report({
node,
- message: `The css prop can only be used if jsxImportSource is set to ${importSource}`,
+ messageId: 'cssProp',
+ data: { importSource },
fix(fixer) {
return fixer.insertTextBefore(
sourceCode.ast.body[0],
@@ -73,13 +104,21 @@ export default {
)
}
})
- } else if (!validJsxImportSource && jsxImportSourcePragmaNode) {
+ } else if (!validJsxImportSource && jsxImportSourcePragmaComment) {
context.report({
node,
- message: `The css prop can only be used if jsxImportSource is set to ${importSource}`,
+ messageId: 'cssProp',
+ data: { importSource },
fix(fixer) {
+ /* istanbul ignore if */
+ if (jsxImportSourcePragmaComment === null) {
+ throw new Error(
+ `Unexpected null when attempting to fix ${context.getFilename()} - please file a github issue at ${REPO_URL}`
+ )
+ }
+
return fixer.replaceText(
- jsxImportSourcePragmaNode,
+ jsxImportSourcePragmaComment,
`/** @jsxImportSource ${importSource} */`
)
}
@@ -95,12 +134,12 @@ export default {
return
}
let hasJsxImport = false
- let emotionCoreNode = null
- let local = null
+ let emotionCoreNode = null as TSESTree.ImportDeclaration | null
+ let local: string | null = null
let sourceCode = context.getSourceCode()
sourceCode.ast.body.forEach(x => {
if (
- x.type === 'ImportDeclaration' &&
+ x.type === AST_NODE_TYPES.ImportDeclaration &&
(x.source.value === '@emotion/react' ||
x.source.value === '@emotion/core')
) {
@@ -108,13 +147,15 @@ export default {
if (
x.specifiers.length === 1 &&
- x.specifiers[0].type === 'ImportNamespaceSpecifier'
+ x.specifiers[0].type === AST_NODE_TYPES.ImportNamespaceSpecifier
) {
hasJsxImport = true
local = x.specifiers[0].local.name + '.jsx'
} else {
let jsxSpecifier = x.specifiers.find(
- x => x.type === 'ImportSpecifier' && x.imported.name === 'jsx'
+ x =>
+ x.type === AST_NODE_TYPES.ImportSpecifier &&
+ x.imported.name === 'jsx'
)
if (jsxSpecifier) {
hasJsxImport = true
@@ -138,10 +179,16 @@ export default {
if (!hasJsxImport || !hasSetPragma) {
context.report({
node,
- message:
- 'The css prop can only be used if jsx from @emotion/react is imported and it is set as the jsx pragma',
+ messageId: 'cssPropWithPragma',
fix(fixer) {
if (hasJsxImport) {
+ /* istanbul ignore if */
+ if (emotionCoreNode === null) {
+ throw new Error(
+ `Unexpected null when attempting to fix ${context.getFilename()} - please file a github issue at ${REPO_URL}`
+ )
+ }
+
return fixer.insertTextBefore(
emotionCoreNode,
`/** @jsx ${local} */\n`
@@ -154,7 +201,9 @@ export default {
emotionCoreNode.specifiers.length - 1
]
- if (lastSpecifier.type === 'ImportDefaultSpecifier') {
+ if (
+ lastSpecifier.type === AST_NODE_TYPES.ImportDefaultSpecifier
+ ) {
return fixer.insertTextAfter(lastSpecifier, ', { jsx }')
}
@@ -174,38 +223,48 @@ export default {
})
return
}
+
+ /* istanbul ignore if */
+ if (emotionCoreNode === null) {
+ throw new Error(
+ `Unexpected null when attempting to fix ${context.getFilename()} - please file a github issue at ${REPO_URL}`
+ )
+ }
+
+ const { specifiers } = emotionCoreNode
+ const { value } = node
+
if (
- node.value.type === 'JSXExpressionContainer' &&
- node.value.expression.type === 'TemplateLiteral'
+ value &&
+ value.type === AST_NODE_TYPES.JSXExpressionContainer &&
+ value.expression.type === AST_NODE_TYPES.TemplateLiteral
) {
- let cssSpecifier = emotionCoreNode.specifiers.find(
- x => x.imported.name === 'css'
+ let cssSpecifier = specifiers.find(
+ x =>
+ x.type === AST_NODE_TYPES.ImportSpecifier &&
+ x.imported.name === 'css'
)
context.report({
node,
- message:
- 'Template literals should be replaced with tagged template literals using `css` when using the css prop',
+ messageId: 'templateLiterals',
fix(fixer) {
if (cssSpecifier) {
return fixer.insertTextBefore(
- node.value.expression,
+ value.expression,
cssSpecifier.local.name
)
}
- let lastSpecifier =
- emotionCoreNode.specifiers[
- emotionCoreNode.specifiers.length - 1
- ]
+ let lastSpecifier = specifiers[specifiers.length - 1]
if (context.getScope().variables.some(x => x.name === 'css')) {
return [
fixer.insertTextAfter(lastSpecifier, `, css as _css`),
- fixer.insertTextBefore(node.value.expression, '_css')
+ fixer.insertTextBefore(value.expression, '_css')
]
}
return [
fixer.insertTextAfter(lastSpecifier, `, css`),
- fixer.insertTextBefore(node.value.expression, 'css')
+ fixer.insertTextBefore(value.expression, 'css')
]
}
})
@@ -213,4 +272,4 @@ export default {
}
}
}
-}
+})
diff --git a/packages/eslint-plugin/src/rules/no-vanilla.js b/packages/eslint-plugin/src/rules/no-vanilla.js
deleted file mode 100644
index 793819576a..0000000000
--- a/packages/eslint-plugin/src/rules/no-vanilla.js
+++ /dev/null
@@ -1,17 +0,0 @@
-export default {
- meta: {
- fixable: 'code'
- },
- create(context) {
- return {
- ImportDeclaration(node) {
- if (node.source.value === '@emotion/css') {
- context.report({
- node: node.source,
- message: `Vanilla emotion should not be used`
- })
- }
- }
- }
- }
-}
diff --git a/packages/eslint-plugin/src/rules/no-vanilla.ts b/packages/eslint-plugin/src/rules/no-vanilla.ts
new file mode 100644
index 0000000000..72b0524757
--- /dev/null
+++ b/packages/eslint-plugin/src/rules/no-vanilla.ts
@@ -0,0 +1,31 @@
+import { createRule } from '../utils'
+
+const messages = {
+ vanillaEmotion: 'Vanilla emotion should not be used'
+}
+
+export default createRule({
+ name: __filename,
+ meta: {
+ docs: {
+ description: 'Ensure vanilla emotion is not used',
+ recommended: false
+ },
+ messages,
+ schema: [],
+ type: 'problem'
+ },
+ defaultOptions: [],
+ create(context) {
+ return {
+ ImportDeclaration(node) {
+ if (node.source.value === '@emotion/css') {
+ context.report({
+ node: node.source,
+ messageId: 'vanillaEmotion'
+ })
+ }
+ }
+ }
+ }
+})
diff --git a/packages/eslint-plugin/src/rules/pkg-renaming.js b/packages/eslint-plugin/src/rules/pkg-renaming.js
deleted file mode 100644
index 2e6dbfaf85..0000000000
--- a/packages/eslint-plugin/src/rules/pkg-renaming.js
+++ /dev/null
@@ -1,67 +0,0 @@
-let simpleMappings = {
- '@emotion/core': '@emotion/react',
- emotion: '@emotion/css',
- 'emotion/macro': '@emotion/css/macro',
- '@emotion/styled-base': '@emotion/styled/base',
- 'jest-emotion': '@emotion/jest',
- 'babel-plugin-emotion': '@emotion/babel-plugin',
- 'eslint-plugin-emotion': '@emotion/eslint-plugin',
- 'create-emotion-server': '@emotion/server/create-instance',
- 'create-emotion': '@emotion/css/create-instance',
- 'emotion-server': '@emotion/server'
-}
-
-export default {
- meta: {
- fixable: 'code'
- },
- create(context) {
- return {
- ImportDeclaration(node) {
- let maybeMapping = simpleMappings[node.source.value]
- if (maybeMapping !== undefined) {
- context.report({
- node: node.source,
- message: `${JSON.stringify(
- node.source.value
- )} has been renamed to ${JSON.stringify(
- maybeMapping
- )}, please import it from ${JSON.stringify(maybeMapping)} instead`,
- fix: fixer => fixer.replaceText(node.source, `'${maybeMapping}'`)
- })
- }
- if (
- (node.source.value === '@emotion/css' ||
- node.source.value === '@emotion/css/macro') &&
- node.specifiers.length === 1 &&
- node.specifiers[0].type === 'ImportDefaultSpecifier'
- ) {
- let replacement =
- node.source.value === '@emotion/css'
- ? '@emotion/react'
- : '@emotion/react/macro'
- context.report({
- node: node.source,
- message: `The default export of "${node.source.value}" in Emotion 10 has been moved to a named export, \`css\`, from "${replacement}" in Emotion 11, please import it from "${replacement}"`,
- fix: fixer =>
- fixer.replaceText(
- node,
- `import { css${
- node.specifiers[0].local.name === 'css'
- ? ''
- : ` as ${node.specifiers[0].local.name}`
- } } from '${replacement}'`
- )
- })
- }
- if (node.source.value === 'emotion-theming') {
- context.report({
- node: node.source,
- message: `"emotion-theming" has been moved into "@emotion/react", please import its exports from "@emotion/react"`,
- fix: fixer => fixer.replaceText(node.source, `'@emotion/react'`)
- })
- }
- }
- }
- }
-}
diff --git a/packages/eslint-plugin/src/rules/pkg-renaming.ts b/packages/eslint-plugin/src/rules/pkg-renaming.ts
new file mode 100644
index 0000000000..9b546015dd
--- /dev/null
+++ b/packages/eslint-plugin/src/rules/pkg-renaming.ts
@@ -0,0 +1,89 @@
+import { AST_NODE_TYPES } from '@typescript-eslint/utils'
+import { createRule } from '../utils'
+
+const simpleMappings = new Map([
+ ['@emotion/core', '@emotion/react'],
+ ['emotion', '@emotion/css'],
+ ['emotion/macro', '@emotion/css/macro'],
+ ['@emotion/styled-base', '@emotion/styled/base'],
+ ['jest-emotion', '@emotion/jest'],
+ ['babel-plugin-emotion', '@emotion/babel-plugin'],
+ ['eslint-plugin-emotion', '@emotion/eslint-plugin'],
+ ['create-emotion-server', '@emotion/server/create-instance'],
+ ['create-emotion', '@emotion/css/create-instance'],
+ ['emotion-server', '@emotion/server']
+])
+
+const messages = {
+ renamePackage: `{{ beforeName }} has been renamed to {{ afterName }}, please import it from {{ afterName }} instead`,
+ exportChange: `The default export of "{{ name }}" in Emotion 10 has been moved to a named export, \`css\`, from "{{ replacement }}" in Emotion 11, please import it from "{{ replacement }}"`,
+ emotionTheming: `"emotion-theming" has been moved into "@emotion/react", please import its exports from "@emotion/react"`
+}
+
+export default createRule({
+ name: __filename,
+ meta: {
+ docs: {
+ description: 'Internal rule',
+ recommended: false
+ },
+ fixable: 'code',
+ messages,
+ schema: [],
+ type: 'problem'
+ },
+ defaultOptions: [],
+ create(context) {
+ return {
+ ImportDeclaration(node) {
+ const maybeMapping = simpleMappings.get(node.source.value)
+ if (maybeMapping !== undefined) {
+ context.report({
+ node: node.source,
+ messageId: 'renamePackage',
+ data: {
+ beforeName: JSON.stringify(node.source.value),
+ afterName: JSON.stringify(maybeMapping)
+ },
+ fix: fixer => fixer.replaceText(node.source, `'${maybeMapping}'`)
+ })
+ }
+ if (
+ (node.source.value === '@emotion/css' ||
+ node.source.value === '@emotion/css/macro') &&
+ node.specifiers.length === 1 &&
+ node.specifiers[0].type === AST_NODE_TYPES.ImportDefaultSpecifier
+ ) {
+ let replacement =
+ node.source.value === '@emotion/css'
+ ? '@emotion/react'
+ : '@emotion/react/macro'
+ context.report({
+ node: node.source,
+ messageId: 'exportChange',
+ data: {
+ name: node.source.value,
+ replacement
+ },
+ fix: fixer =>
+ fixer.replaceText(
+ node,
+ `import { css${
+ node.specifiers[0].local.name === 'css'
+ ? ''
+ : ` as ${node.specifiers[0].local.name}`
+ } } from '${replacement}'`
+ )
+ })
+ }
+ if (node.source.value === 'emotion-theming') {
+ context.report({
+ node: node.source,
+ messageId: 'emotionTheming',
+ fix: fixer => fixer.replaceText(node.source, `'@emotion/react'`)
+ })
+ }
+ }
+ }
+ }
+})
diff --git a/packages/eslint-plugin/src/rules/styled-import.js b/packages/eslint-plugin/src/rules/styled-import.js
deleted file mode 100644
index 89ccf2310a..0000000000
--- a/packages/eslint-plugin/src/rules/styled-import.js
+++ /dev/null
@@ -1,25 +0,0 @@
-export default {
- meta: {
- fixable: 'code'
- },
- create(context) {
- return {
- ImportDeclaration(node) {
- if (node.source.value === 'react-emotion') {
- let newImportPath = '@emotion/styled'
- context.report({
- node: node.source,
- message: `styled should be imported from @emotion/styled`,
- fix:
- node.specifiers.length === 1 &&
- node.specifiers[0].type === 'ImportDefaultSpecifier'
- ? fixer => {
- return fixer.replaceText(node.source, `'${newImportPath}'`)
- }
- : undefined
- })
- }
- }
- }
- }
-}
diff --git a/packages/eslint-plugin/src/rules/styled-import.ts b/packages/eslint-plugin/src/rules/styled-import.ts
new file mode 100644
index 0000000000..e9aeefbbe8
--- /dev/null
+++ b/packages/eslint-plugin/src/rules/styled-import.ts
@@ -0,0 +1,41 @@
+import { AST_NODE_TYPES } from '@typescript-eslint/utils'
+import { createRule } from '../utils'
+
+const messages = {
+ incorrectImport: 'styled should be imported from @emotion/styled'
+}
+
+export default createRule({
+ name: __filename,
+ meta: {
+ docs: {
+ description: 'Ensure styled is imported from @emotion/styled',
+ recommended: false
+ },
+ fixable: 'code',
+ messages,
+ schema: [],
+ type: 'problem'
+ },
+ defaultOptions: [],
+ create(context) {
+ return {
+ ImportDeclaration(node) {
+ if (node.source.value === 'react-emotion') {
+ let newImportPath = '@emotion/styled'
+ context.report({
+ node: node.source,
+ messageId: 'incorrectImport',
+ fix:
+ node.specifiers.length === 1 &&
+ node.specifiers[0].type === AST_NODE_TYPES.ImportDefaultSpecifier
+ ? fixer => {
+ return fixer.replaceText(node.source, `'${newImportPath}'`)
+ }
+ : undefined
+ })
+ }
+ }
+ }
+ }
+})
diff --git a/packages/eslint-plugin/src/rules/syntax-preference.js b/packages/eslint-plugin/src/rules/syntax-preference.ts
similarity index 55%
rename from packages/eslint-plugin/src/rules/syntax-preference.js
rename to packages/eslint-plugin/src/rules/syntax-preference.ts
index 891713a879..7568eb805b 100644
--- a/packages/eslint-plugin/src/rules/syntax-preference.js
+++ b/packages/eslint-plugin/src/rules/syntax-preference.ts
@@ -1,16 +1,20 @@
+import { AST_NODE_TYPES, TSESLint, TSESTree } from '@typescript-eslint/utils'
+import { createRule } from '../utils'
+
/**
* @fileoverview Choose between string or object syntax
* @author alex-pex
*/
-function isStringStyle(node) {
- if (node.tag.type === 'Identifier' && node.tag.name === 'css') {
+function isStringStyle(node: TSESTree.TaggedTemplateExpression) {
+ if (node.tag.type === AST_NODE_TYPES.Identifier && node.tag.name === 'css') {
return true
}
// shorthand notation
// eg: styled.h1` color: red; `
if (
- node.tag.type === 'MemberExpression' &&
+ node.tag.type === AST_NODE_TYPES.MemberExpression &&
+ node.tag.object.type === AST_NODE_TYPES.Identifier &&
node.tag.object.name === 'styled'
) {
// string syntax used
@@ -19,7 +23,11 @@ function isStringStyle(node) {
// full notation
// eg: styled('h1')` color: red; `
- if (node.tag.type === 'CallExpression' && node.tag.callee.name === 'styled') {
+ if (
+ node.tag.type === AST_NODE_TYPES.CallExpression &&
+ node.tag.callee.type === AST_NODE_TYPES.Identifier &&
+ node.tag.callee.name === 'styled'
+ ) {
// string syntax used
return true
}
@@ -27,15 +35,19 @@ function isStringStyle(node) {
return false
}
-function isObjectStyle(node) {
- if (node.callee.type === 'Identifier' && node.callee.name === 'css') {
+function isObjectStyle(node: TSESTree.CallExpression) {
+ if (
+ node.callee.type === AST_NODE_TYPES.Identifier &&
+ node.callee.name === 'css'
+ ) {
return true
}
// shorthand notation
// eg: styled.h1({ color: 'red' })
if (
- node.callee.type === 'MemberExpression' &&
+ node.callee.type === AST_NODE_TYPES.MemberExpression &&
+ node.callee.object.type === AST_NODE_TYPES.Identifier &&
node.callee.object.name === 'styled'
) {
// object syntax used
@@ -45,7 +57,8 @@ function isObjectStyle(node) {
// full notation
// eg: styled('h1')({ color: 'red' })
if (
- node.callee.type === 'CallExpression' &&
+ node.callee.type === AST_NODE_TYPES.CallExpression &&
+ node.callee.callee.type === AST_NODE_TYPES.Identifier &&
node.callee.callee.name === 'styled'
) {
// object syntax used
@@ -59,42 +72,42 @@ function isObjectStyle(node) {
// Rule Definition
// ------------------------------------------------------------------------------
-const MSG_PREFER_STRING_STYLE = 'Styles should be written using strings.'
-const MSG_PREFER_OBJECT_STYLE = 'Styles should be written using objects.'
-const MSG_PREFER_WRAPPING_WITH_CSS =
- 'Prefer wrapping your string styles with `css` call.'
-
-const checkExpressionPreferringObject = (context, node) => {
+const checkExpressionPreferringObject = (
+ context: RuleContext,
+ node: TSESTree.Node
+) => {
switch (node.type) {
- case 'ArrayExpression':
+ case AST_NODE_TYPES.ArrayExpression:
node.elements.forEach(element =>
checkExpressionPreferringObject(context, element)
)
return
- case 'TemplateLiteral':
+ case AST_NODE_TYPES.TemplateLiteral:
context.report({
node,
- message: MSG_PREFER_OBJECT_STYLE
+ messageId: 'preferObjectStyle'
})
return
- case 'Literal':
+ case AST_NODE_TYPES.Literal:
// validating other literal types seems out of scope of this plugin
if (typeof node.value !== 'string') {
return
}
context.report({
node,
- message: MSG_PREFER_OBJECT_STYLE
+ messageId: 'preferObjectStyle'
})
}
}
-const createPreferredObjectVisitor = context => ({
+const createPreferredObjectVisitor = (
+ context: RuleContext
+): TSESLint.RuleListener => ({
TaggedTemplateExpression(node) {
if (isStringStyle(node)) {
context.report({
node,
- message: MSG_PREFER_OBJECT_STYLE
+ messageId: 'preferObjectStyle'
})
}
},
@@ -110,24 +123,35 @@ const createPreferredObjectVisitor = context => ({
return
}
+ if (!node.value) {
+ context.report({
+ node: node,
+ messageId: 'emptyCssProp'
+ })
+ return
+ }
+
switch (node.value.type) {
- case 'Literal':
+ case AST_NODE_TYPES.Literal:
// validating other literal types seems out of scope of this plugin
if (typeof node.value.value !== 'string') {
return
}
context.report({
node: node.value,
- message: MSG_PREFER_OBJECT_STYLE
+ messageId: 'preferObjectStyle'
})
return
- case 'JSXExpressionContainer':
+ case AST_NODE_TYPES.JSXExpressionContainer:
checkExpressionPreferringObject(context, node.value.expression)
}
}
})
-const checkExpressionPreferringString = (context, node) => {
+const checkExpressionPreferringString = (
+ context: RuleContext,
+ node: TSESTree.Node
+) => {
switch (node.type) {
case 'ArrayExpression':
node.elements.forEach(element =>
@@ -137,7 +161,7 @@ const checkExpressionPreferringString = (context, node) => {
case 'ObjectExpression':
context.report({
node,
- message: MSG_PREFER_STRING_STYLE
+ messageId: 'preferStringStyle'
})
return
case 'Literal':
@@ -147,12 +171,14 @@ const checkExpressionPreferringString = (context, node) => {
}
context.report({
node,
- message: MSG_PREFER_WRAPPING_WITH_CSS
+ messageId: 'preferWrappingWithCSS'
})
}
}
-const createPreferredStringVisitor = context => ({
+const createPreferredStringVisitor = (
+ context: RuleContext
+): TSESLint.RuleListener => ({
CallExpression(node) {
if (isObjectStyle(node)) {
node.arguments.forEach(argument =>
@@ -166,38 +192,62 @@ const createPreferredStringVisitor = context => ({
return
}
+ if (!node.value) {
+ context.report({
+ node: node,
+ messageId: 'emptyCssProp'
+ })
+ return
+ }
+
switch (node.value.type) {
- case 'Literal':
+ case AST_NODE_TYPES.Literal:
// validating other literal types seems out of scope of this plugin
if (typeof node.value.value !== 'string') {
return
}
context.report({
node: node.value,
- message: MSG_PREFER_WRAPPING_WITH_CSS
+ messageId: 'preferWrappingWithCSS'
})
return
- case 'JSXExpressionContainer':
+ case AST_NODE_TYPES.JSXExpressionContainer:
checkExpressionPreferringString(context, node.value.expression)
}
}
})
-export default {
+type RuleOptions = [('string' | 'object')?]
+
+type MessageId =
+ | 'preferStringStyle'
+ | 'preferObjectStyle'
+ | 'preferWrappingWithCSS'
+ | 'emptyCssProp'
+
+type RuleContext = TSESLint.RuleContext
+
+export default createRule({
+ name: __filename,
meta: {
docs: {
- description: 'Choose between string or object styles',
- category: 'Stylistic Issues',
+ description: 'Choose between styles written as strings or objects',
recommended: false
},
- fixable: null, // or "code" or "whitespace"
+ messages: {
+ preferStringStyle: 'Styles should be written using strings.',
+ preferObjectStyle: 'Styles should be written using objects.',
+ preferWrappingWithCSS: `Prefer wrapping your string styles with \`css\` call.`,
+ emptyCssProp: `Empty \`css\` prop is not valid.`
+ },
schema: [
{
enum: ['string', 'object']
}
- ]
+ ],
+ type: 'problem'
},
-
+ defaultOptions: [],
create(context) {
const preferredSyntax = context.options[0]
@@ -210,4 +260,4 @@ export default {
return {}
}
}
-}
+})
diff --git a/packages/eslint-plugin/src/utils.ts b/packages/eslint-plugin/src/utils.ts
new file mode 100644
index 0000000000..7fbef3077c
--- /dev/null
+++ b/packages/eslint-plugin/src/utils.ts
@@ -0,0 +1,12 @@
+import { ESLintUtils } from '@typescript-eslint/utils'
+import { parse as parsePath } from 'path'
+
+const { version } = require('../package.json')
+
+export const REPO_URL = 'https://github.com/emotion-js/emotion'
+
+export const createRule = ESLintUtils.RuleCreator(name => {
+ const ruleName = parsePath(name).name
+
+ return `${REPO_URL}/blob/@emotion/eslint-plugin@${version}/packages/eslint-plugin/docs/rules/${ruleName}.md`
+})
diff --git a/packages/eslint-plugin/test/rules/import-from-emotion.test.js b/packages/eslint-plugin/test/rules/import-from-emotion.test.ts
similarity index 60%
rename from packages/eslint-plugin/test/rules/import-from-emotion.test.js
rename to packages/eslint-plugin/test/rules/import-from-emotion.test.ts
index b28f99730d..99be3a0fa0 100644
--- a/packages/eslint-plugin/test/rules/import-from-emotion.test.js
+++ b/packages/eslint-plugin/test/rules/import-from-emotion.test.ts
@@ -2,12 +2,12 @@
* @jest-environment node
*/
-import { RuleTester } from 'eslint'
-import { rules as emotionRules } from '@emotion/eslint-plugin'
+import { TSESLint } from '@typescript-eslint/utils'
+import rule from '../../src/rules/import-from-emotion'
+import { espreeParser } from '../test-utils'
-const rule = emotionRules['import-from-emotion']
-
-RuleTester.setDefaultConfig({
+const ruleTester = new TSESLint.RuleTester({
+ parser: espreeParser,
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
@@ -17,8 +17,6 @@ RuleTester.setDefaultConfig({
}
})
-const ruleTester = new RuleTester()
-
ruleTester.run('emotion jsx', rule, {
valid: [
{
@@ -31,8 +29,7 @@ ruleTester.run('emotion jsx', rule, {
code: `import { css } from 'react-emotion'`,
errors: [
{
- message:
- "emotion's exports should be imported directly from emotion rather than from react-emotion"
+ messageId: 'incorrectImport'
}
],
output: `import { css } from 'emotion'`
@@ -41,8 +38,7 @@ ruleTester.run('emotion jsx', rule, {
code: `import styled, { css } from 'react-emotion'`,
errors: [
{
- message:
- "emotion's exports should be imported directly from emotion rather than from react-emotion"
+ messageId: 'incorrectImport'
}
],
output: `import styled from '@emotion/styled';\nimport { css } from 'emotion';`
@@ -51,8 +47,7 @@ ruleTester.run('emotion jsx', rule, {
code: `import styled, { css as somethingElse } from 'react-emotion'`,
errors: [
{
- message:
- "emotion's exports should be imported directly from emotion rather than from react-emotion"
+ messageId: 'incorrectImport'
}
],
output: `import styled from '@emotion/styled';\nimport { css as somethingElse } from 'emotion';`
diff --git a/packages/eslint-plugin/test/rules/jsx-import.test.js b/packages/eslint-plugin/test/rules/jsx-import.test.ts
similarity index 71%
rename from packages/eslint-plugin/test/rules/jsx-import.test.js
rename to packages/eslint-plugin/test/rules/jsx-import.test.ts
index 6a0fa0b793..f245357e64 100644
--- a/packages/eslint-plugin/test/rules/jsx-import.test.js
+++ b/packages/eslint-plugin/test/rules/jsx-import.test.ts
@@ -2,12 +2,12 @@
* @jest-environment node
*/
-import { RuleTester } from 'eslint'
-import { rules as emotionRules } from '@emotion/eslint-plugin'
+import { TSESLint } from '@typescript-eslint/utils'
+import rule from '../../src/rules/jsx-import'
+import { espreeParser } from '../test-utils'
-const rule = emotionRules['jsx-import']
-
-RuleTester.setDefaultConfig({
+const ruleTester = new TSESLint.RuleTester({
+ parser: espreeParser,
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
@@ -17,8 +17,6 @@ RuleTester.setDefaultConfig({
}
})
-const ruleTester = new RuleTester()
-
ruleTester.run('emotion jsx', rule, {
valid: [
{
@@ -73,6 +71,14 @@ ruleTester.run('emotion jsx', rule, {
let ele =
`
+ },
+ {
+ code: `
+ /** @jsx jsx */
+ import {jsx} from '@emotion/react'
+ // it's invalid but not for this rule
+ let ele =
+ `
}
],
@@ -84,8 +90,7 @@ let ele =
`.trim(),
errors: [
{
- message:
- 'The css prop can only be used if jsx from @emotion/react is imported and it is set as the jsx pragma'
+ messageId: 'cssPropWithPragma'
}
],
output: `
@@ -101,8 +106,8 @@ let ele =
`.trim(),
errors: [
{
- message:
- 'The css prop can only be used if jsxImportSource is set to @emotion/react'
+ messageId: 'cssProp',
+ data: { importSource: '@emotion/react' }
}
],
output: `
@@ -117,8 +122,8 @@ let ele =
`.trim(),
errors: [
{
- message:
- 'The css prop can only be used if jsxImportSource is set to @iChenLei/react'
+ messageId: 'cssProp',
+ data: { importSource: '@iChenLei/react' }
}
],
output: `
@@ -134,8 +139,8 @@ let ele =
`.trim(),
errors: [
{
- message:
- 'The css prop can only be used if jsxImportSource is set to @iChenLei/react'
+ messageId: 'cssProp',
+ data: { importSource: '@iChenLei/react' }
}
],
output: `
@@ -150,8 +155,7 @@ let ele =
`.trim(),
errors: [
{
- message:
- 'The css prop can only be used if jsx from @emotion/react is imported and it is set as the jsx pragma'
+ messageId: 'cssPropWithPragma'
}
],
output: `
@@ -168,8 +172,7 @@ let ele =
`.trim(),
errors: [
{
- message:
- 'The css prop can only be used if jsx from @emotion/react is imported and it is set as the jsx pragma'
+ messageId: 'cssPropWithPragma'
}
],
output: `
@@ -186,8 +189,7 @@ let ele =
`.trim(),
errors: [
{
- message:
- 'The css prop can only be used if jsx from @emotion/react is imported and it is set as the jsx pragma'
+ messageId: 'cssPropWithPragma'
}
],
output: `
@@ -203,8 +205,7 @@ let ele =
`.trim(),
errors: [
{
- message:
- 'The css prop can only be used if jsx from @emotion/react is imported and it is set as the jsx pragma'
+ messageId: 'cssPropWithPragma'
}
],
output: `
@@ -219,8 +220,7 @@ let ele =
`.trim(),
errors: [
{
- message:
- 'The css prop can only be used if jsx from @emotion/react is imported and it is set as the jsx pragma'
+ messageId: 'cssPropWithPragma'
}
],
output: `
@@ -231,13 +231,30 @@ let ele =
},
{
code: `
+/** @jsx jsx */
+import * as emotion from '@emotion/react'
+let ele =
+ `.trim(),
+ errors: [
+ {
+ messageId: 'cssPropWithPragma'
+ }
+ ],
+ output: `
+/** @jsx jsx */
+/** @jsx emotion.jsx */
+import * as emotion from '@emotion/react'
+let ele =
+ `.trim()
+ },
+ {
+ code: `
import {jsx} from '@emotion/react'
let ele =
`.trim(),
errors: [
{
- message:
- 'The css prop can only be used if jsx from @emotion/react is imported and it is set as the jsx pragma'
+ messageId: 'cssPropWithPragma'
}
],
output: `
@@ -254,12 +271,10 @@ let ele2 =
`.trim(),
errors: [
{
- message:
- 'The css prop can only be used if jsx from @emotion/react is imported and it is set as the jsx pragma'
+ messageId: 'cssPropWithPragma'
},
{
- message:
- 'The css prop can only be used if jsx from @emotion/react is imported and it is set as the jsx pragma'
+ messageId: 'cssPropWithPragma'
}
],
output: `
@@ -278,8 +293,7 @@ let ele2 =
`.trim(),
errors: [
{
- message:
- 'Template literals should be replaced with tagged template literals using `css` when using the css prop'
+ messageId: 'templateLiterals'
}
],
output: `
@@ -297,8 +311,7 @@ let ele2 =
`.trim(),
errors: [
{
- message:
- 'Template literals should be replaced with tagged template literals using `css` when using the css prop'
+ messageId: 'templateLiterals'
}
],
output: `
@@ -316,8 +329,7 @@ let ele2 =
`.trim(),
errors: [
{
- message:
- 'Template literals should be replaced with tagged template literals using `css` when using the css prop'
+ messageId: 'templateLiterals'
}
],
output: `
diff --git a/packages/eslint-plugin/test/rules/no-vanilla.test.js b/packages/eslint-plugin/test/rules/no-vanilla.test.ts
similarity index 58%
rename from packages/eslint-plugin/test/rules/no-vanilla.test.js
rename to packages/eslint-plugin/test/rules/no-vanilla.test.ts
index cb77156431..a897ec3a70 100644
--- a/packages/eslint-plugin/test/rules/no-vanilla.test.js
+++ b/packages/eslint-plugin/test/rules/no-vanilla.test.ts
@@ -2,12 +2,12 @@
* @jest-environment node
*/
-import { RuleTester } from 'eslint'
-import { rules as emotionRules } from '@emotion/eslint-plugin'
+import { TSESLint } from '@typescript-eslint/utils'
+import rule from '../../src/rules/no-vanilla'
+import { espreeParser } from '../test-utils'
-const rule = emotionRules['no-vanilla']
-
-RuleTester.setDefaultConfig({
+const ruleTester = new TSESLint.RuleTester({
+ parser: espreeParser,
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
@@ -17,8 +17,6 @@ RuleTester.setDefaultConfig({
}
})
-const ruleTester = new RuleTester()
-
ruleTester.run('no-vanilla', rule, {
valid: [{ code: `import { css } from '@emotion/react'` }],
invalid: [
@@ -26,7 +24,7 @@ ruleTester.run('no-vanilla', rule, {
code: `import { css } from '@emotion/css'`,
errors: [
{
- message: `Vanilla emotion should not be used`
+ messageId: 'vanillaEmotion'
}
]
}
diff --git a/packages/eslint-plugin/test/rules/pkg-renaming.test.js b/packages/eslint-plugin/test/rules/pkg-renaming.test.ts
similarity index 53%
rename from packages/eslint-plugin/test/rules/pkg-renaming.test.js
rename to packages/eslint-plugin/test/rules/pkg-renaming.test.ts
index 0377b13ee4..6e7093212e 100644
--- a/packages/eslint-plugin/test/rules/pkg-renaming.test.js
+++ b/packages/eslint-plugin/test/rules/pkg-renaming.test.ts
@@ -2,10 +2,12 @@
* @jest-environment node
*/
-const { RuleTester } = require('eslint')
-const rule = require('@emotion/eslint-plugin').rules['pkg-renaming']
+import { TSESLint } from '@typescript-eslint/utils'
+import rule from '../../src/rules/pkg-renaming'
+import { espreeParser } from '../test-utils'
-RuleTester.setDefaultConfig({
+const ruleTester = new TSESLint.RuleTester({
+ parser: espreeParser,
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
@@ -15,8 +17,6 @@ RuleTester.setDefaultConfig({
}
})
-const ruleTester = new RuleTester()
-
ruleTester.run('pkg-renaming', rule, {
valid: [
{
@@ -31,8 +31,11 @@ ruleTester.run('pkg-renaming', rule, {
code: `import { css } from 'emotion'`,
errors: [
{
- message:
- '"emotion" has been renamed to "@emotion/css", please import it from "@emotion/css" instead'
+ messageId: 'renamePackage',
+ data: {
+ beforeName: '"emotion"',
+ afterName: '"@emotion/css"'
+ }
}
],
output: `import { css } from '@emotion/css'`
@@ -41,8 +44,11 @@ ruleTester.run('pkg-renaming', rule, {
code: `import { css } from '@emotion/core'`,
errors: [
{
- message:
- '"@emotion/core" has been renamed to "@emotion/react", please import it from "@emotion/react" instead'
+ messageId: 'renamePackage',
+ data: {
+ beforeName: '"@emotion/core"',
+ afterName: '"@emotion/react"'
+ }
}
],
output: `import { css } from '@emotion/react'`
@@ -51,8 +57,11 @@ ruleTester.run('pkg-renaming', rule, {
code: `import css from '@emotion/css'`,
errors: [
{
- message:
- 'The default export of "@emotion/css" in Emotion 10 has been moved to a named export, `css`, from "@emotion/react" in Emotion 11, please import it from "@emotion/react"'
+ messageId: 'exportChange',
+ data: {
+ name: '@emotion/css',
+ replacement: '@emotion/react'
+ }
}
],
output: `import { css } from '@emotion/react'`
@@ -61,8 +70,11 @@ ruleTester.run('pkg-renaming', rule, {
code: `import css from '@emotion/css/macro'`,
errors: [
{
- message:
- 'The default export of "@emotion/css/macro" in Emotion 10 has been moved to a named export, `css`, from "@emotion/react/macro" in Emotion 11, please import it from "@emotion/react/macro"'
+ messageId: 'exportChange',
+ data: {
+ name: '@emotion/css/macro',
+ replacement: '@emotion/react/macro'
+ }
}
],
output: `import { css } from '@emotion/react/macro'`
@@ -71,8 +83,7 @@ ruleTester.run('pkg-renaming', rule, {
code: `import {ThemeProvider, withTheme} from 'emotion-theming'`,
errors: [
{
- message:
- '"emotion-theming" has been moved into "@emotion/react", please import its exports from "@emotion/react"'
+ messageId: 'emotionTheming'
}
],
output: `import {ThemeProvider, withTheme} from '@emotion/react'`
diff --git a/packages/eslint-plugin/test/rules/styled-import.test.js b/packages/eslint-plugin/test/rules/styled-import.test.ts
similarity index 63%
rename from packages/eslint-plugin/test/rules/styled-import.test.js
rename to packages/eslint-plugin/test/rules/styled-import.test.ts
index 4909d2dc73..944053cd46 100644
--- a/packages/eslint-plugin/test/rules/styled-import.test.js
+++ b/packages/eslint-plugin/test/rules/styled-import.test.ts
@@ -2,12 +2,12 @@
* @jest-environment node
*/
-import { RuleTester } from 'eslint'
-import { rules as emotionRules } from '@emotion/eslint-plugin'
+import { TSESLint } from '@typescript-eslint/utils'
+import rule from '../../src/rules/styled-import'
+import { espreeParser } from '../test-utils'
-const rule = emotionRules['styled-import']
-
-RuleTester.setDefaultConfig({
+const ruleTester = new TSESLint.RuleTester({
+ parser: espreeParser,
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
@@ -17,8 +17,6 @@ RuleTester.setDefaultConfig({
}
})
-const ruleTester = new RuleTester()
-
ruleTester.run('emotion styled', rule, {
valid: [
{
@@ -35,7 +33,7 @@ import styled from 'react-emotion'
`.trim(),
errors: [
{
- message: `styled should be imported from @emotion/styled`
+ messageId: 'incorrectImport'
}
],
output: `
diff --git a/packages/eslint-plugin/test/rules/syntax-preference.test.js b/packages/eslint-plugin/test/rules/syntax-preference.test.ts
similarity index 68%
rename from packages/eslint-plugin/test/rules/syntax-preference.test.js
rename to packages/eslint-plugin/test/rules/syntax-preference.test.ts
index 58e2c9d0d1..4ea172d97a 100644
--- a/packages/eslint-plugin/test/rules/syntax-preference.test.js
+++ b/packages/eslint-plugin/test/rules/syntax-preference.test.ts
@@ -8,12 +8,12 @@
// Requirements
// ------------------------------------------------------------------------------
-import { RuleTester } from 'eslint'
-import { rules as emotionRules } from '@emotion/eslint-plugin'
+import { AST_NODE_TYPES, TSESLint } from '@typescript-eslint/utils'
+import rule from '../../src/rules/syntax-preference'
+import { espreeParser } from '../test-utils'
-const rule = emotionRules['syntax-preference']
-
-RuleTester.setDefaultConfig({
+const ruleTester = new TSESLint.RuleTester({
+ parser: espreeParser,
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
@@ -27,8 +27,6 @@ RuleTester.setDefaultConfig({
// Tests
// ------------------------------------------------------------------------------
-const ruleTester = new RuleTester()
-
ruleTester.run('syntax-preference (string)', rule, {
valid: [
// give me some code that won't trigger a warning
@@ -68,8 +66,8 @@ ruleTester.run('syntax-preference (string)', rule, {
options: ['string'],
errors: [
{
- message: 'Styles should be written using strings.',
- type: 'ObjectExpression'
+ messageId: 'preferStringStyle',
+ type: AST_NODE_TYPES.ObjectExpression
}
]
},
@@ -78,8 +76,8 @@ ruleTester.run('syntax-preference (string)', rule, {
options: ['string'],
errors: [
{
- message: 'Styles should be written using strings.',
- type: 'ObjectExpression'
+ messageId: 'preferStringStyle',
+ type: AST_NODE_TYPES.ObjectExpression
}
]
},
@@ -88,8 +86,8 @@ ruleTester.run('syntax-preference (string)', rule, {
options: ['string'],
errors: [
{
- message: 'Styles should be written using strings.',
- type: 'ObjectExpression'
+ messageId: 'preferStringStyle',
+ type: AST_NODE_TYPES.ObjectExpression
}
]
},
@@ -98,8 +96,8 @@ ruleTester.run('syntax-preference (string)', rule, {
options: ['string'],
errors: [
{
- message: 'Prefer wrapping your string styles with `css` call.',
- type: 'Literal'
+ messageId: 'preferWrappingWithCSS',
+ type: AST_NODE_TYPES.Literal
}
]
},
@@ -108,8 +106,8 @@ ruleTester.run('syntax-preference (string)', rule, {
options: ['string'],
errors: [
{
- message: 'Prefer wrapping your string styles with `css` call.',
- type: 'Literal'
+ messageId: 'preferWrappingWithCSS',
+ type: AST_NODE_TYPES.Literal
}
]
},
@@ -118,12 +116,12 @@ ruleTester.run('syntax-preference (string)', rule, {
options: ['string'],
errors: [
{
- message: 'Prefer wrapping your string styles with `css` call.',
- type: 'Literal'
+ messageId: 'preferWrappingWithCSS',
+ type: AST_NODE_TYPES.Literal
},
{
- message: 'Styles should be written using strings.',
- type: 'ObjectExpression'
+ messageId: 'preferStringStyle',
+ type: AST_NODE_TYPES.ObjectExpression
}
]
},
@@ -132,8 +130,18 @@ ruleTester.run('syntax-preference (string)', rule, {
options: ['string'],
errors: [
{
- message: 'Styles should be written using strings.',
- type: 'ObjectExpression'
+ messageId: 'preferStringStyle',
+ type: AST_NODE_TYPES.ObjectExpression
+ }
+ ]
+ },
+ {
+ code: `const Foo = () =>
`,
+ options: ['string'],
+ errors: [
+ {
+ messageId: 'emptyCssProp',
+ type: AST_NODE_TYPES.JSXAttribute
}
]
}
@@ -171,8 +179,8 @@ ruleTester.run('syntax-preference (object)', rule, {
options: ['object'],
errors: [
{
- message: 'Styles should be written using objects.',
- type: 'TaggedTemplateExpression'
+ messageId: 'preferObjectStyle',
+ type: AST_NODE_TYPES.TaggedTemplateExpression
}
]
},
@@ -181,8 +189,8 @@ ruleTester.run('syntax-preference (object)', rule, {
options: ['object'],
errors: [
{
- message: 'Styles should be written using objects.',
- type: 'TaggedTemplateExpression'
+ messageId: 'preferObjectStyle',
+ type: AST_NODE_TYPES.TaggedTemplateExpression
}
]
},
@@ -191,8 +199,8 @@ ruleTester.run('syntax-preference (object)', rule, {
options: ['object'],
errors: [
{
- message: 'Styles should be written using objects.',
- type: 'TaggedTemplateExpression'
+ messageId: 'preferObjectStyle',
+ type: AST_NODE_TYPES.TaggedTemplateExpression
}
]
},
@@ -201,8 +209,8 @@ ruleTester.run('syntax-preference (object)', rule, {
options: ['object'],
errors: [
{
- message: 'Styles should be written using objects.',
- type: 'Literal'
+ messageId: 'preferObjectStyle',
+ type: AST_NODE_TYPES.Literal
}
]
},
@@ -211,8 +219,8 @@ ruleTester.run('syntax-preference (object)', rule, {
options: ['object'],
errors: [
{
- message: 'Styles should be written using objects.',
- type: 'Literal'
+ messageId: 'preferObjectStyle',
+ type: AST_NODE_TYPES.Literal
}
]
},
@@ -221,12 +229,12 @@ ruleTester.run('syntax-preference (object)', rule, {
options: ['object'],
errors: [
{
- message: 'Styles should be written using objects.',
- type: 'Literal'
+ messageId: 'preferObjectStyle',
+ type: AST_NODE_TYPES.Literal
},
{
- message: 'Styles should be written using objects.',
- type: 'TaggedTemplateExpression'
+ messageId: 'preferObjectStyle',
+ type: AST_NODE_TYPES.TaggedTemplateExpression
}
]
},
@@ -235,12 +243,22 @@ ruleTester.run('syntax-preference (object)', rule, {
options: ['object'],
errors: [
{
- message: 'Styles should be written using objects.',
- type: 'Literal'
+ messageId: 'preferObjectStyle',
+ type: AST_NODE_TYPES.Literal
},
{
- message: 'Styles should be written using objects.',
- type: 'TaggedTemplateExpression'
+ messageId: 'preferObjectStyle',
+ type: AST_NODE_TYPES.TaggedTemplateExpression
+ }
+ ]
+ },
+ {
+ code: `const Foo = () =>
`,
+ options: ['object'],
+ errors: [
+ {
+ messageId: 'emptyCssProp',
+ type: AST_NODE_TYPES.JSXAttribute
}
]
}
diff --git a/packages/eslint-plugin/test/test-utils.ts b/packages/eslint-plugin/test/test-utils.ts
new file mode 100644
index 0000000000..551a54e9db
--- /dev/null
+++ b/packages/eslint-plugin/test/test-utils.ts
@@ -0,0 +1,6 @@
+import resolveFrom from 'resolve-from'
+
+export const espreeParser: string = resolveFrom(
+ require.resolve('eslint'),
+ 'espree'
+)
diff --git a/packages/hash/CHANGELOG.md b/packages/hash/CHANGELOG.md
index f52da41637..d8daf9c966 100644
--- a/packages/hash/CHANGELOG.md
+++ b/packages/hash/CHANGELOG.md
@@ -1,5 +1,11 @@
# @emotion/hash
+## 0.9.2
+
+### Patch Changes
+
+- [#2454](https://github.com/emotion-js/emotion/pull/2454) [`ea2c397`](https://github.com/emotion-js/emotion/commit/ea2c397bbf7d9838086ec88b3eb86db9230d32ae) Thanks [@Andarist](https://github.com/Andarist)! - Source code has been migrated to TypeScript. From now on type declarations will be emitted based on that, instead of being hand-written.
+
## 0.9.1
### Patch Changes
diff --git a/packages/hash/__tests__/index.js b/packages/hash/__tests__/index.js
index 17532e38d3..741406af32 100644
--- a/packages/hash/__tests__/index.js
+++ b/packages/hash/__tests__/index.js
@@ -1,5 +1,5 @@
import hash from '@emotion/hash'
-it('accepts a string and returns a string as a hash', () => {
+test('accepts a string and returns a string as a hash', () => {
expect(hash('something')).toBe('crsxd7')
})
diff --git a/packages/hash/package.json b/packages/hash/package.json
index c22396e494..41ad196424 100644
--- a/packages/hash/package.json
+++ b/packages/hash/package.json
@@ -1,26 +1,29 @@
{
"name": "@emotion/hash",
- "version": "0.9.1",
+ "version": "0.9.2",
"description": "A MurmurHash2 implementation",
"main": "dist/emotion-hash.cjs.js",
"module": "dist/emotion-hash.esm.js",
- "types": "types/index.d.ts",
+ "types": "dist/emotion-hash.cjs.d.ts",
"license": "MIT",
"repository": "https://github.com/emotion-js/emotion/tree/main/packages/hash",
"files": [
"src",
- "dist",
- "types/*.d.ts"
+ "dist"
],
"scripts": {
"test:typescript": "dtslint types"
},
"devDependencies": {
"@definitelytyped/dtslint": "0.0.112",
- "typescript": "^4.5.5"
+ "typescript": "^5.4.5"
},
"exports": {
".": {
+ "types": {
+ "import": "./dist/emotion-hash.cjs.mjs",
+ "default": "./dist/emotion-hash.cjs.js"
+ },
"module": "./dist/emotion-hash.esm.js",
"import": "./dist/emotion-hash.cjs.mjs",
"default": "./dist/emotion-hash.cjs.js"
diff --git a/packages/hash/src/index.d.ts b/packages/hash/src/index.d.ts
deleted file mode 100644
index 9e46093759..0000000000
--- a/packages/hash/src/index.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../types'
-export { default } from '../types'
diff --git a/packages/hash/src/index.js b/packages/hash/src/index.ts
similarity index 96%
rename from packages/hash/src/index.js
rename to packages/hash/src/index.ts
index dacf52f904..c7d19839e7 100644
--- a/packages/hash/src/index.js
+++ b/packages/hash/src/index.ts
@@ -1,9 +1,8 @@
-// @flow
/* eslint-disable */
// Inspired by https://github.com/garycourt/murmurhash-js
// Ported from https://github.com/aappleby/smhasher/blob/61a0530f28277f2e850bfc39600ce61d02b518de/src/MurmurHash2.cpp#L37-L86
-export default function murmur2(str: string) {
+export default function murmur2(str: string): string {
// 'm' and 'r' are mixing constants generated offline.
// They're not really 'magic', they just happen to work well.
diff --git a/packages/hash/types/index.d.ts b/packages/hash/types/index.d.ts
index 872aa0beff..2c736dff8d 100644
--- a/packages/hash/types/index.d.ts
+++ b/packages/hash/types/index.d.ts
@@ -1 +1 @@
-export default function murmurhash2_32_gc(str: string): string
+export { default } from '..'
diff --git a/packages/hash/types/tslint.json b/packages/hash/types/tslint.json
index cd0be207a3..9fe0947cd8 100644
--- a/packages/hash/types/tslint.json
+++ b/packages/hash/types/tslint.json
@@ -17,6 +17,7 @@
"check-preblock"
],
- "no-unnecessary-generics": false
+ "no-unnecessary-generics": false,
+ "unnecessary-bind": false
}
}
diff --git a/packages/is-prop-valid/CHANGELOG.md b/packages/is-prop-valid/CHANGELOG.md
index cc1a0c9efa..3b6e4f5ddc 100644
--- a/packages/is-prop-valid/CHANGELOG.md
+++ b/packages/is-prop-valid/CHANGELOG.md
@@ -1,5 +1,16 @@
# @emotion/is-prop-valid
+## 1.3.0
+
+### Minor Changes
+
+- [#2432](https://github.com/emotion-js/emotion/pull/2432) [`a1e881b`](https://github.com/emotion-js/emotion/commit/a1e881b7dffdfa69f5ff32a708a25213b711bd15) Thanks [@sarayourfriend](https://github.com/sarayourfriend)! - Source code has been migrated to TypeScript. From now on type declarations will be emitted based on that, instead of being hand-written.
+
+### Patch Changes
+
+- Updated dependencies [[`7f8db2d`](https://github.com/emotion-js/emotion/commit/7f8db2d7a900bb34995db66084a99d512811e33d)]:
+ - @emotion/memoize@0.9.0
+
## 1.2.2
### Patch Changes
diff --git a/packages/is-prop-valid/package.json b/packages/is-prop-valid/package.json
index e5f5991960..2435094806 100644
--- a/packages/is-prop-valid/package.json
+++ b/packages/is-prop-valid/package.json
@@ -1,10 +1,10 @@
{
"name": "@emotion/is-prop-valid",
- "version": "1.2.2",
+ "version": "1.3.0",
"description": "A function to check whether a prop is valid for HTML and SVG elements",
"main": "dist/emotion-is-prop-valid.cjs.js",
"module": "dist/emotion-is-prop-valid.esm.js",
- "types": "types/index.d.ts",
+ "types": "dist/emotion-is-prop-valid.cjs.d.ts",
"license": "MIT",
"repository": "https://github.com/emotion-js/emotion/tree/main/packages/is-prop-valid",
"scripts": {
@@ -14,19 +14,22 @@
"access": "public"
},
"dependencies": {
- "@emotion/memoize": "^0.8.1"
+ "@emotion/memoize": "^0.9.0"
},
"devDependencies": {
"@definitelytyped/dtslint": "0.0.112",
- "typescript": "^4.5.5"
+ "typescript": "^5.4.5"
},
"files": [
"src",
- "dist",
- "types/*.d.ts"
+ "dist"
],
"exports": {
".": {
+ "types": {
+ "import": "./dist/emotion-is-prop-valid.cjs.mjs",
+ "default": "./dist/emotion-is-prop-valid.cjs.js"
+ },
"module": "./dist/emotion-is-prop-valid.esm.js",
"import": "./dist/emotion-is-prop-valid.cjs.mjs",
"default": "./dist/emotion-is-prop-valid.cjs.js"
diff --git a/packages/is-prop-valid/src/index.d.ts b/packages/is-prop-valid/src/index.d.ts
deleted file mode 100644
index 9e46093759..0000000000
--- a/packages/is-prop-valid/src/index.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../types'
-export { default } from '../types'
diff --git a/packages/is-prop-valid/src/index.js b/packages/is-prop-valid/src/index.ts
similarity index 69%
rename from packages/is-prop-valid/src/index.js
rename to packages/is-prop-valid/src/index.ts
index 9763a339e7..88fb415329 100644
--- a/packages/is-prop-valid/src/index.js
+++ b/packages/is-prop-valid/src/index.ts
@@ -1,9 +1,9 @@
-// @flow
import memoize from '@emotion/memoize'
-declare var codegen: { require: string => RegExp }
+declare const codegen: { require: (path: string) => any }
-const reactPropsRegex = codegen.require('./props')
+// eslint-disable-next-line no-undef
+const reactPropsRegex: RegExp = codegen.require('./props')
// https://esbench.com/bench/5bfee68a4cd7e6009ef61d23
const isPropValid = /* #__PURE__ */ memoize(
diff --git a/packages/is-prop-valid/src/props.js b/packages/is-prop-valid/src/props.js
index d93c7022c7..2dccc9b9a4 100644
--- a/packages/is-prop-valid/src/props.js
+++ b/packages/is-prop-valid/src/props.js
@@ -1,4 +1,6 @@
-// @flow
+/**
+ * This module needs to remain pure JavaScript for codegen to work on it
+ */
const props = {
// react props
// https://github.com/facebook/react/blob/5495a7f24aef85ba6937truetrue1ce962673ca9f5fde6/src/renderers/dom/shared/hooks/ReactDOMUnknownPropertyHook.js
@@ -490,7 +492,6 @@ const props = {
class: true,
autofocus: true
}
-// eslint-disable-next-line import/no-commonjs
module.exports = `/^((${Object.keys(props).join(
'|'
)})|(([Dd][Aa][Tt][Aa]|[Aa][Rr][Ii][Aa]|x)-.*))$/`
diff --git a/packages/is-prop-valid/types/index.d.ts b/packages/is-prop-valid/types/index.d.ts
index e7d00bfdbf..5f85d28f68 100644
--- a/packages/is-prop-valid/types/index.d.ts
+++ b/packages/is-prop-valid/types/index.d.ts
@@ -1,5 +1,3 @@
-// Definitions by: Junyoung Clare Jang
// TypeScript Version: 2.1
-declare function isPropValid(prop: string): boolean
-export default isPropValid
+export { default } from '..'
diff --git a/packages/is-prop-valid/types/tslint.json b/packages/is-prop-valid/types/tslint.json
index cd0be207a3..7eb28049a9 100644
--- a/packages/is-prop-valid/types/tslint.json
+++ b/packages/is-prop-valid/types/tslint.json
@@ -17,6 +17,8 @@
"check-preblock"
],
- "no-unnecessary-generics": false
+ "no-unnecessary-generics": false,
+ "no-default-import": false,
+ "unnecessary-bind": false
}
}
diff --git a/packages/jest/CHANGELOG.md b/packages/jest/CHANGELOG.md
index 6f2a3abbfa..cccd587a35 100644
--- a/packages/jest/CHANGELOG.md
+++ b/packages/jest/CHANGELOG.md
@@ -1,5 +1,11 @@
# @emotion/jest
+## 11.13.0
+
+### Minor Changes
+
+- [#3198](https://github.com/emotion-js/emotion/pull/3198) [`d8ff8a5`](https://github.com/emotion-js/emotion/commit/d8ff8a5990c691017b463b3fa23a9f46ab28147b) Thanks [@Andarist](https://github.com/Andarist)! - Adjustments to how speedy rules are obtained by the plugin.
+
## 11.11.0
### Patch Changes
diff --git a/packages/jest/package.json b/packages/jest/package.json
index 485c305500..d0d7bef4d6 100644
--- a/packages/jest/package.json
+++ b/packages/jest/package.json
@@ -1,26 +1,42 @@
{
"name": "@emotion/jest",
- "version": "11.11.0",
+ "version": "11.13.0",
"description": "Jest utilities for emotion",
"main": "dist/emotion-jest.cjs.js",
"module": "dist/emotion-jest.esm.js",
"exports": {
".": {
+ "types": {
+ "import": "./dist/emotion-jest.cjs.mjs",
+ "default": "./dist/emotion-jest.cjs.js"
+ },
"module": "./dist/emotion-jest.esm.js",
"import": "./dist/emotion-jest.cjs.mjs",
"default": "./dist/emotion-jest.cjs.js"
},
"./enzyme": {
+ "types": {
+ "import": "./enzyme/dist/emotion-jest-enzyme.cjs.mjs",
+ "default": "./enzyme/dist/emotion-jest-enzyme.cjs.js"
+ },
"module": "./enzyme/dist/emotion-jest-enzyme.esm.js",
"import": "./enzyme/dist/emotion-jest-enzyme.cjs.mjs",
"default": "./enzyme/dist/emotion-jest-enzyme.cjs.js"
},
"./serializer": {
+ "types": {
+ "import": "./serializer/dist/emotion-jest-serializer.cjs.mjs",
+ "default": "./serializer/dist/emotion-jest-serializer.cjs.js"
+ },
"module": "./serializer/dist/emotion-jest-serializer.esm.js",
"import": "./serializer/dist/emotion-jest-serializer.cjs.mjs",
"default": "./serializer/dist/emotion-jest-serializer.cjs.js"
},
"./enzyme-serializer": {
+ "types": {
+ "import": "./enzyme-serializer/dist/emotion-jest-enzyme-serializer.cjs.mjs",
+ "default": "./enzyme-serializer/dist/emotion-jest-enzyme-serializer.cjs.js"
+ },
"module": "./enzyme-serializer/dist/emotion-jest-enzyme-serializer.esm.js",
"import": "./enzyme-serializer/dist/emotion-jest-enzyme-serializer.cjs.mjs",
"default": "./enzyme-serializer/dist/emotion-jest-enzyme-serializer.cjs.js"
@@ -41,7 +57,7 @@
},
"dependencies": {
"@babel/runtime": "^7.18.3",
- "@emotion/css-prettifier": "^1.1.3",
+ "@emotion/css-prettifier": "^1.1.4",
"chalk": "^4.1.0",
"specificity": "^0.4.1",
"stylis": "4.2.0"
@@ -60,14 +76,14 @@
},
"devDependencies": {
"@definitelytyped/dtslint": "0.0.112",
- "@emotion/css": "11.11.2",
- "@emotion/react": "11.11.4",
- "@types/jest": "^27.0.3",
+ "@emotion/css": "11.13.0",
+ "@emotion/react": "11.13.0",
+ "@types/jest": "^29.5.12",
"enzyme-to-json": "^3.6.1",
"pretty-format": "^22.4.3",
"react": "16.14.0",
"react-dom": "16.14.0",
- "typescript": "^4.5.5"
+ "typescript": "^5.4.5"
},
"author": "Kye Hohenberger",
"homepage": "https://emotion.sh",
diff --git a/packages/jest/src/create-enzyme-serializer.js b/packages/jest/src/create-enzyme-serializer.js
index c91d440922..2178056037 100644
--- a/packages/jest/src/create-enzyme-serializer.js
+++ b/packages/jest/src/create-enzyme-serializer.js
@@ -1,5 +1,4 @@
-// @flow
-import type { Options } from './create-serializer'
+/* import type { Options } from './create-serializer' */
import { createSerializer as createEmotionSerializer } from './create-serializer'
import * as enzymeTickler from './enzyme-tickler'
import { createSerializer as createEnzymeToJsonSerializer } from 'enzyme-to-json'
@@ -68,23 +67,23 @@ export function createEnzymeSerializer({
classNameReplacer,
DOMElements = true,
includeStyles = true
-}: Options = {}) {
+} /* : Options */ = {}) {
const emotionSerializer = createEmotionSerializer({
classNameReplacer,
DOMElements,
includeStyles
})
return {
- test(node: *) {
+ test(node) {
return wrappedEnzymeSerializer.test(node) || emotionSerializer.test(node)
},
serialize(
- node: *,
- config: *,
- indentation: string,
- depth: number,
- refs: *,
- printer: Function
+ node,
+ config,
+ indentation /*: string */,
+ depth /*: number */,
+ refs,
+ printer /*: Function */
) {
if (wrappedEnzymeSerializer.test(node)) {
const tickled = enzymeTickler.tickle(node)
diff --git a/packages/jest/src/create-serializer.js b/packages/jest/src/create-serializer.js
index c1c5795bb6..533b7ecf0c 100644
--- a/packages/jest/src/create-serializer.js
+++ b/packages/jest/src/create-serializer.js
@@ -1,4 +1,3 @@
-// @flow
import prettify from '@emotion/css-prettifier'
import { replaceClassNames } from './replace-class-names'
import * as enzymeTickler from './enzyme-tickler'
@@ -49,13 +48,13 @@ function deepTransform(node, transform) {
return node.map(child => deepTransform(child, transform))
}
- const transformed: any = transform(node)
+ const transformed = transform(node)
if (transformed !== node && transformed.children) {
return copyProps(transformed, {
// flatMap to allow a child of to be transformed to
children: flatMap(
- (deepTransform(transformed.children, transform): any),
+ deepTransform(transformed.children, transform),
id => id
)
})
@@ -65,18 +64,20 @@ function deepTransform(node, transform) {
}
function getPrettyStylesFromClassNames(
- classNames: Array,
- elements: Array,
- indentation: string
+ classNames /*: Array */,
+ elements /*: Array */,
+ indentation /*: string */
) {
return prettify(getStylesFromClassNames(classNames, elements), indentation)
}
+/*
export type Options = {
classNameReplacer?: (className: string, index: number) => string,
DOMElements?: boolean,
includeStyles?: boolean
}
+*/
function filterEmotionProps(props = {}) {
const {
@@ -102,9 +103,9 @@ function getLabelsFromClassName(keys, className) {
}
function isShallowEnzymeElement(
- element: any,
- keys: string[],
- labels: string[]
+ element /*: any */,
+ keys /*: string[] */,
+ labels /*: string[] */
) {
const childClassNames = (element.children || [])
.map(({ props = {} }) => props.className || '')
@@ -116,47 +117,48 @@ function isShallowEnzymeElement(
})
}
-const createConvertEmotionElements = (keys: string[]) => (node: any) => {
- if (isPrimitive(node)) {
- return node
- }
- if (isEmotionCssPropEnzymeElement(node)) {
- const className = enzymeTickler.getTickledClassName(node.props.css)
- const labels = getLabelsFromClassName(keys, className || '')
-
- if (isShallowEnzymeElement(node, keys, labels)) {
- const emotionType = node.props.__EMOTION_TYPE_PLEASE_DO_NOT_USE__
- // emotionType will be a string for DOM elements
- const type =
- typeof emotionType === 'string'
- ? emotionType
- : emotionType.displayName || emotionType.name || 'Component'
+const createConvertEmotionElements =
+ (keys /*: string[]*/) => (node /*: any*/) => {
+ if (isPrimitive(node)) {
+ return node
+ }
+ if (isEmotionCssPropEnzymeElement(node)) {
+ const className = enzymeTickler.getTickledClassName(node.props.css)
+ const labels = getLabelsFromClassName(keys, className || '')
+
+ if (isShallowEnzymeElement(node, keys, labels)) {
+ const emotionType = node.props.__EMOTION_TYPE_PLEASE_DO_NOT_USE__
+ // emotionType will be a string for DOM elements
+ const type =
+ typeof emotionType === 'string'
+ ? emotionType
+ : emotionType.displayName || emotionType.name || 'Component'
+ return {
+ ...node,
+ props: filterEmotionProps({
+ ...node.props,
+ className
+ }),
+ type
+ }
+ } else {
+ return node.children[node.children.length - 1]
+ }
+ }
+ if (isEmotionCssPropElementType(node)) {
return {
...node,
- props: filterEmotionProps({
- ...node.props,
- className
- }),
- type
+ props: filterEmotionProps(node.props),
+ type: node.props.__EMOTION_TYPE_PLEASE_DO_NOT_USE__
}
- } else {
- return node.children[node.children.length - 1]
}
- }
- if (isEmotionCssPropElementType(node)) {
- return {
- ...node,
- props: filterEmotionProps(node.props),
- type: node.props.__EMOTION_TYPE_PLEASE_DO_NOT_USE__
+ if (isReactElement(node)) {
+ return copyProps({}, node)
}
+ return node
}
- if (isReactElement(node)) {
- return copyProps({}, node)
- }
- return node
-}
-function clean(node: any, classNames: string[]) {
+function clean(node, classNames /*: string[] */) {
if (Array.isArray(node)) {
for (const child of node) {
clean(child, classNames)
@@ -186,17 +188,17 @@ export function createSerializer({
classNameReplacer,
DOMElements = true,
includeStyles = true
-}: Options = {}) {
+} /* : Options */ = {}) {
const cache = new WeakSet()
const isTransformed = val => cache.has(val)
function serialize(
- val: *,
- config: *,
- indentation: string,
- depth: number,
- refs: *,
- printer: Function
+ val,
+ config,
+ indentation /*: string */,
+ depth /*: number */,
+ refs,
+ printer /*: Function */
) {
const elements = getStyleElements()
const keys = getKeys(elements)
@@ -223,7 +225,7 @@ export function createSerializer({
}
return {
- test(val: *) {
+ test(val) {
return (
val &&
!isTransformed(val) &&
diff --git a/packages/jest/src/enzyme-serializer.js b/packages/jest/src/enzyme-serializer.js
index 78c5bba6ce..2b73962978 100644
--- a/packages/jest/src/enzyme-serializer.js
+++ b/packages/jest/src/enzyme-serializer.js
@@ -1,3 +1,2 @@
-// @flow
import { createEnzymeSerializer } from './create-enzyme-serializer'
export const { test, serialize } = createEnzymeSerializer()
diff --git a/packages/jest/src/enzyme.js b/packages/jest/src/enzyme.js
index 929a5b359f..72fdee8bd1 100644
--- a/packages/jest/src/enzyme.js
+++ b/packages/jest/src/enzyme.js
@@ -1,3 +1,2 @@
-// @flow
export { createEnzymeSerializer } from './create-enzyme-serializer'
export { matchers } from './matchers'
diff --git a/packages/jest/src/index.js b/packages/jest/src/index.js
index 0b67c3dd0d..c675404fda 100644
--- a/packages/jest/src/index.js
+++ b/packages/jest/src/index.js
@@ -1,3 +1,2 @@
-// @flow
export { createSerializer } from './create-serializer'
export { matchers } from './matchers'
diff --git a/packages/jest/src/matchers.js b/packages/jest/src/matchers.js
index 5e648fcca5..4edae6bb6c 100644
--- a/packages/jest/src/matchers.js
+++ b/packages/jest/src/matchers.js
@@ -1,4 +1,3 @@
-// @flow
import chalk from 'chalk'
import * as stylis from 'stylis'
import * as specificity from 'specificity'
@@ -40,10 +39,10 @@ function valueMatches(declaration, value) {
}
function toHaveStyleRule(
- received: *,
- property: *,
- value: *,
- options?: { target?: string | RegExp, media?: string } = {}
+ received,
+ property,
+ value,
+ options /* ?: { target?: string | RegExp, media?: string } */ = {}
) {
if (Array.isArray(received)) {
throw new Error(
diff --git a/packages/jest/src/replace-class-names.js b/packages/jest/src/replace-class-names.js
index 892b67081b..7039beb818 100644
--- a/packages/jest/src/replace-class-names.js
+++ b/packages/jest/src/replace-class-names.js
@@ -1,4 +1,3 @@
-// @flow
function defaultClassNameReplacer(className, index) {
return `emotion-${index}`
}
@@ -6,29 +5,32 @@ function defaultClassNameReplacer(className, index) {
const componentSelectorClassNamePattern = /^e[a-zA-Z0-9]+[0-9]+$/
export const replaceClassNames = (
- classNames: Array,
- styles: string,
- code: string,
- keys: Array,
- classNameReplacer: (
+ classNames /*: Array */,
+ styles /*: string */,
+ code /*: string */,
+ keys /*: Array */,
+ classNameReplacer /*: (
className: string,
index: number
- ) => string = defaultClassNameReplacer
+ ) => string */ = defaultClassNameReplacer
) => {
let index = 0
let keyPattern = new RegExp(`^(${keys.join('|')})-`)
- return classNames.reduce((acc, className) => {
- if (
- keyPattern.test(className) ||
- componentSelectorClassNamePattern.test(className)
- ) {
- const escapedRegex = new RegExp(
- className.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'),
- 'g'
- )
- return acc.replace(escapedRegex, classNameReplacer(className, index++))
- }
- return acc
- }, `${styles}${styles ? '\n\n' : ''}${code}`)
+ return classNames.reduce(
+ (acc, className) => {
+ if (
+ keyPattern.test(className) ||
+ componentSelectorClassNamePattern.test(className)
+ ) {
+ const escapedRegex = new RegExp(
+ className.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'),
+ 'g'
+ )
+ return acc.replace(escapedRegex, classNameReplacer(className, index++))
+ }
+ return acc
+ },
+ `${styles}${styles ? '\n\n' : ''}${code}`
+ )
}
diff --git a/packages/jest/src/serializer.js b/packages/jest/src/serializer.js
index 3f6afed572..941aa43682 100644
--- a/packages/jest/src/serializer.js
+++ b/packages/jest/src/serializer.js
@@ -1,3 +1,2 @@
-// @flow
import { createSerializer } from './create-serializer'
export const { test, serialize } = createSerializer()
diff --git a/packages/jest/src/utils.js b/packages/jest/src/utils.js
index 8a4cad723b..acf2f871de 100644
--- a/packages/jest/src/utils.js
+++ b/packages/jest/src/utils.js
@@ -1,4 +1,21 @@
-// @flow
+const insertedRules = new WeakMap()
+
+if (typeof CSSStyleSheet !== 'undefined') {
+ const insertRule = CSSStyleSheet.prototype.insertRule
+ CSSStyleSheet.prototype.insertRule = function (...args) {
+ let sheetRules = insertedRules.get(this)
+
+ if (!sheetRules) {
+ sheetRules = []
+ insertedRules.set(this, sheetRules)
+ }
+
+ const rule = args[0]
+ sheetRules.push(rule)
+
+ return insertRule.apply(this, args)
+ }
+}
const isBrowser = typeof document !== 'undefined'
@@ -6,11 +23,17 @@ function last(arr) {
return arr.length > 0 ? arr[arr.length - 1] : undefined
}
-export function flatMap(arr: T[], iteratee: (arg: T) => S[] | S): S[] {
+export function flatMap /* */(
+ arr /*: T[] */,
+ iteratee /*: (arg: T) => S[] | S */
+) /*: S[] */ {
return [].concat(...arr.map(iteratee))
}
-export function findLast(arr: T[], predicate: T => boolean) {
+export function findLast /* */(
+ arr /*: T[] */,
+ predicate /*: T => boolean */
+) {
for (let i = arr.length - 1; i >= 0; i--) {
if (predicate(arr[i])) {
return arr[i]
@@ -18,10 +41,10 @@ export function findLast(arr: T[], predicate: T => boolean) {
}
}
-export function findIndexFrom(
- arr: T[],
- fromIndex: number,
- predicate: T => boolean
+export function findIndexFrom /* */(
+ arr /*: T[] */,
+ fromIndex /*: number */,
+ predicate /*: T => boolean */
) {
for (let i = fromIndex; i < arr.length; i++) {
if (predicate(arr[i])) {
@@ -32,7 +55,7 @@ export function findIndexFrom(
return -1
}
-function getClassNames(selectors: any, classes?: string) {
+function getClassNames(selectors, classes /* ?: string */) {
return classes ? selectors.concat(classes.split(' ')) : selectors
}
@@ -58,7 +81,7 @@ function getClassNameProp(node) {
return (node && node.prop('className')) || ''
}
-export function unwrapFromPotentialFragment(node: *) {
+export function unwrapFromPotentialFragment(node) {
if (node.type() === Symbol.for('react.fragment')) {
const isShallow = !!node.dive
if (isShallow) {
@@ -86,25 +109,25 @@ function getClassNamesFromCheerio(selectors, node) {
return getClassNames(selectors, classes)
}
-function getClassNamesFromDOMElement(selectors, node: any) {
+function getClassNamesFromDOMElement(selectors, node) {
return getClassNames(selectors, node.getAttribute('class'))
}
-export function isReactElement(val: any): boolean {
+export function isReactElement(val) /*: boolean */ {
return (
val.$$typeof === Symbol.for('react.test.json') ||
val.$$typeof === Symbol.for('react.element')
)
}
-export function isEmotionCssPropElementType(val: any): boolean {
+export function isEmotionCssPropElementType(val) /*: boolean */ {
return (
val.$$typeof === Symbol.for('react.element') &&
val.type.displayName === 'EmotionCssPropInternal'
)
}
-export function isStyledElementType(val: any): boolean {
+export function isStyledElementType(val /* : any */) /* : boolean */ {
if (val.$$typeof !== Symbol.for('react.element')) {
return false
}
@@ -112,7 +135,7 @@ export function isStyledElementType(val: any): boolean {
return type.__emotion_real === type
}
-export function isEmotionCssPropEnzymeElement(val: any): boolean {
+export function isEmotionCssPropEnzymeElement(val /* : any */) /*: boolean */ {
return (
val.$$typeof === Symbol.for('react.test.json') &&
val.type === 'EmotionCssPropInternal'
@@ -120,7 +143,7 @@ export function isEmotionCssPropEnzymeElement(val: any): boolean {
}
const domElementPattern = /^((HTML|SVG)\w*)?Element$/
-export function isDOMElement(val: any): boolean {
+export function isDOMElement(val) /*: boolean */ {
return (
val.nodeType === 1 &&
val.constructor &&
@@ -129,15 +152,15 @@ export function isDOMElement(val: any): boolean {
)
}
-function isEnzymeElement(val: any): boolean {
+function isEnzymeElement(val) /*: boolean */ {
return typeof val.findWhere === 'function'
}
-function isCheerioElement(val: any): boolean {
+function isCheerioElement(val) /*: boolean */ {
return val.cheerio === '[cheerio object]'
}
-export function getClassNamesFromNodes(nodes: Array) {
+export function getClassNamesFromNodes(nodes /*: Array */) {
return nodes.reduce((selectors, node) => {
if (isEnzymeElement(node)) {
return getClassNamesFromEnzyme(selectors, node)
@@ -154,7 +177,7 @@ const keyframesPattern = /^@keyframes\s+(animation-[^{\s]+)+/
const removeCommentPattern = /\/\*[\s\S]*?\*\//g
-const getElementRules = (element: HTMLStyleElement): string[] => {
+const getElementRules = (element /*: HTMLStyleElement */) /*: string[] */ => {
const nonSpeedyRule = element.textContent
if (nonSpeedyRule) {
return [nonSpeedyRule]
@@ -162,7 +185,10 @@ const getElementRules = (element: HTMLStyleElement): string[] => {
if (!element.sheet) {
return []
}
- // $FlowFixMe - flow doesn't know about `cssRules` property
+ const rules = insertedRules.get(element.sheet)
+ if (rules) {
+ return rules
+ }
return [].slice.call(element.sheet.cssRules).map(cssRule => cssRule.cssText)
}
@@ -180,9 +206,9 @@ const getKeyframesMap = rules =>
}, {})
export function getStylesFromClassNames(
- classNames: Array,
- elements: Array
-): string {
+ classNames /*: Array */,
+ elements /*: Array */
+) /*: string */ {
if (!classNames.length) {
return ''
}
@@ -212,7 +238,7 @@ export function getStylesFromClassNames(
const rules = flatMap(elements, getElementRules)
let styles = rules
- .map((rule: string) => {
+ .map((rule /*: string */) => {
const match = rule.match(selectorPattern)
if (!match) {
return null
@@ -259,35 +285,30 @@ export function getStylesFromClassNames(
return (keyframesStyles + styles).replace(removeCommentPattern, '')
}
-export function getStyleElements(): Array {
+export function getStyleElements() /*: Array */ {
if (!isBrowser) {
throw new Error(
'jest-emotion requires jsdom. See https://jestjs.io/docs/en/configuration#testenvironment-string for more information.'
)
}
const elements = Array.from(document.querySelectorAll('style[data-emotion]'))
- // $FlowFixMe
return elements
}
const unique = arr => Array.from(new Set(arr))
-export function getKeys(elements: Array) {
+export function getKeys(elements /*: Array */) {
const keys = unique(
- elements.map(
- element =>
- // $FlowFixMe we know it exists since we query for elements with this attribute
- (element.getAttribute('data-emotion'): string)
- )
+ elements.map(element => element.getAttribute('data-emotion'))
).filter(Boolean)
return keys
}
export function hasClassNames(
- classNames: Array,
- selectors: Array,
- target?: string | RegExp
-): boolean {
+ classNames /*: Array */,
+ selectors /*: Array */,
+ target /* ?: string | RegExp */
+) /*: boolean */ {
// selectors is the classNames of specific css rule
return selectors.some(selector => {
// if no target, use className of the specific css rule and try to find it
@@ -307,7 +328,10 @@ export function hasClassNames(
})
}
-export function getMediaRules(rules: Array, media: string): Array {
+export function getMediaRules(
+ rules /*: Array */,
+ media /*: string */
+) /*: Array */ {
return flatMap(
rules.filter(rule => {
if (rule.type !== '@media') {
@@ -319,10 +343,10 @@ export function getMediaRules(rules: Array, media: string): Array {
)
}
-export function isPrimitive(test: any) {
+export function isPrimitive(test) {
return test !== Object(test)
}
-export function hasIntersection(left: any[], right: any[]) {
+export function hasIntersection(left /* any[] */, right /* any[] */) {
return left.some(value => right.includes(value))
}
diff --git a/packages/jest/test/matchers.test.js b/packages/jest/test/matchers.test.js
index 2ee34553b6..13ac3c955f 100644
--- a/packages/jest/test/matchers.test.js
+++ b/packages/jest/test/matchers.test.js
@@ -22,7 +22,7 @@ describe('toHaveStyleRule', () => {
width: 100%;
`
- it('matches styles on the top-most node passed in', () => {
+ test('matches styles on the top-most node passed in', () => {
const tree = renderer
.create(
@@ -40,7 +40,7 @@ describe('toHaveStyleRule', () => {
expect(svgNode).not.toHaveStyleRule('color', 'red')
})
- it('supports asymmetric matchers', () => {
+ test('supports asymmetric matchers', () => {
const tree = renderer
.create(
@@ -57,14 +57,14 @@ describe('toHaveStyleRule', () => {
expect(svgNode).toHaveStyleRule('width', expect.stringMatching(/.*%$/))
})
- it('fails if no styles are found', () => {
+ test('fails if no styles are found', () => {
const tree = renderer.create(
).toJSON()
const result = toHaveStyleRule(tree, 'color', 'red')
expect(result.pass).toBe(false)
expect(result.message()).toBe('Property not found: color')
})
- it('supports regex values', () => {
+ test('supports regex values', () => {
const tree = renderer.create(
).toJSON()
expect(tree).toHaveStyleRule('color', /red/)
})
@@ -81,7 +81,7 @@ describe('toHaveStyleRule', () => {
expect(resultPass.message()).toMatchSnapshot()
})
- it('matches styles on the focus, hover targets', () => {
+ test('matches styles on the focus, hover targets', () => {
const localDivStyle = css`
color: white;
&:hover {
@@ -104,7 +104,7 @@ describe('toHaveStyleRule', () => {
expect(tree).toHaveStyleRule('color', 'white')
})
- it('matches styles on the nested component or html element', () => {
+ test('matches styles on the nested component or html element', () => {
const Svg = styled('svg')`
width: 100%;
fill: blue;
@@ -134,7 +134,7 @@ describe('toHaveStyleRule', () => {
expect(tree).toHaveStyleRule('fill', 'green', { target: `${Svg}` })
})
- it('matches target styles by regex', () => {
+ test('matches target styles by regex', () => {
const localDivStyle = css`
a {
color: yellow;
@@ -154,7 +154,7 @@ describe('toHaveStyleRule', () => {
expect(tree).toHaveStyleRule('color', 'yellow', { target: /a$/ })
})
- it('matches proper style for css', () => {
+ test('matches proper style for css', () => {
const tree = renderer
.create(
{
expect(tree).toHaveStyleRule('color', 'hotpink')
})
- it('matches style of the media', () => {
+ test('matches style of the media', () => {
const Svg = styled('svg')`
width: 100%;
`
@@ -212,7 +212,7 @@ describe('toHaveStyleRule', () => {
})
})
- it('matches styles with target and media options', () => {
+ test('matches styles with target and media options', () => {
const localDivStyle = css`
color: white;
@media (min-width: 420px) {
@@ -240,7 +240,7 @@ describe('toHaveStyleRule', () => {
expect(tree).toHaveStyleRule('color', 'white')
})
- it('fails if option media invalid', () => {
+ test('fails if option media invalid', () => {
const Div = styled('div')`
font-size: 30px;
@media (min-width: 420px) {
@@ -257,7 +257,7 @@ describe('toHaveStyleRule', () => {
expect(result.message()).toBe('Property not found: font-size')
})
- it('matches styles for a component used as selector', () => {
+ test('matches styles for a component used as selector', () => {
const Bar = styled.div``
const Foo = styled.div`
@@ -278,7 +278,7 @@ describe('toHaveStyleRule', () => {
expect(tree.children[0]).toHaveStyleRule('color', 'hotpink')
})
- it('takes specificity into account when matching styles (basic)', () => {
+ test('takes specificity into account when matching styles (basic)', () => {
const Bar = styled.div`
color: yellow;
`
@@ -302,7 +302,7 @@ describe('toHaveStyleRule', () => {
expect(tree.children[0]).toHaveStyleRule('color', 'hotpink')
})
- it('should throw a friendly error when it receives an array', () => {
+ test('should throw a friendly error when it receives an array', () => {
const tree = renderer
.create(
<>
@@ -323,7 +323,7 @@ describe('toHaveStyleRule', () => {
)
})
;(isReact16 ? describe : describe.skip)('enzyme', () => {
- it('supports enzyme `mount` method', () => {
+ test('supports enzyme `mount` method', () => {
const Component = () => (
@@ -338,7 +338,7 @@ describe('toHaveStyleRule', () => {
expect(svgNode).not.toHaveStyleRule('color', 'red')
})
- it('supports enzyme `render` method', () => {
+ test('supports enzyme `render` method', () => {
const Component = () => (
@@ -353,7 +353,7 @@ describe('toHaveStyleRule', () => {
expect(svgNode).not.toHaveStyleRule('color', 'red')
})
- it('supports enzyme `shallow` method', () => {
+ test('supports enzyme `shallow` method', () => {
const Component = () => (
@@ -368,7 +368,7 @@ describe('toHaveStyleRule', () => {
expect(svgNode).not.toHaveStyleRule('color', 'red')
})
- it('supports styled components', () => {
+ test('supports styled components', () => {
const Div = styled('div')`
color: red;
`
diff --git a/packages/jest/test/printer.test.js b/packages/jest/test/printer.test.js
index e7f0c0837a..470075bf39 100644
--- a/packages/jest/test/printer.test.js
+++ b/packages/jest/test/printer.test.js
@@ -1,4 +1,3 @@
-// @flow
import React from 'react'
import 'test-utils/legacy-env'
import renderer from 'react-test-renderer'
@@ -23,7 +22,7 @@ describe('jest-emotion with dom elements', () => {
width: 100%;
`
- it('replaces class names and inserts styles into React test component snapshots', () => {
+ test('replaces class names and inserts styles into React test component snapshots', () => {
const tree = renderer
.create(
@@ -39,7 +38,7 @@ describe('jest-emotion with dom elements', () => {
expect(output).toMatchSnapshot()
})
- it('replaces class names and inserts styles into DOM element snapshots', () => {
+ test('replaces class names and inserts styles into DOM element snapshots', () => {
const divRef = React.createRef()
render(
@@ -66,7 +65,7 @@ describe('jest-emotion with DOM elements disabled', () => {
width: 100%;
`
- it('replaces class names and inserts styles into React test component snapshots', () => {
+ test('replaces class names and inserts styles into React test component snapshots', () => {
const tree = renderer
.create(
@@ -82,7 +81,7 @@ describe('jest-emotion with DOM elements disabled', () => {
expect(output).toMatchSnapshot()
})
- it('does not replace class names or insert styles into DOM element snapshots', () => {
+ test('does not replace class names or insert styles into DOM element snapshots', () => {
const divRef = React.createRef()
render(
@@ -151,7 +150,7 @@ describe('jest-emotion with nested selectors', () => {
}
`
- it('replaces class names and inserts styles into React test component snapshots', () => {
+ test('replaces class names and inserts styles into React test component snapshots', () => {
const tree = renderer.create(
).toJSON()
const output = prettyFormat(tree, {
diff --git a/packages/jest/test/prod.test.js b/packages/jest/test/prod.test.js
new file mode 100644
index 0000000000..4e594e3c93
--- /dev/null
+++ b/packages/jest/test/prod.test.js
@@ -0,0 +1,71 @@
+import 'test-utils/next-env'
+import renderer from 'react-test-renderer'
+/** @jsx jsx */
+import * as React from 'react'
+import { css, jsx } from '@emotion/react'
+import { matchers } from '@emotion/jest'
+
+expect.extend(matchers)
+
+gate({ development: false }, ({ test }) => {
+ test('it prints fallback values', () => {
+ const tree = renderer
+ .create(
+
+ {'emotion'}
+
+ )
+ .toJSON()
+
+ expect(tree).toMatchInlineSnapshot(`
+.emotion-0 {
+ background-color: #000;
+ background-color: #fff;
+}
+
+.emotion-1 {
+ color: hotpink;
+}
+
+
+
+ emotion
+
+
+`)
+ })
+
+ test('it prints invalid declarations', () => {
+ const tree = renderer
+ .create(
+
+ {'emotion'}
+
+ )
+ .toJSON()
+
+ expect(tree).toMatchInlineSnapshot(`
+.emotion-0 {
+ bazinga: joke;
+}
+
+.emotion-1 {
+ color: hotpink;
+}
+
+
+
+ emotion
+
+
+`)
+ })
+})
diff --git a/packages/jest/types/enzyme.d.ts b/packages/jest/types/enzyme.d.ts
index 7da6614d56..3fdd86e7fb 100644
--- a/packages/jest/types/enzyme.d.ts
+++ b/packages/jest/types/enzyme.d.ts
@@ -1,4 +1,4 @@
-// TypeScript Version: 2.9
+// TypeScript Version: 4.3
///
diff --git a/packages/jest/types/index.d.ts b/packages/jest/types/index.d.ts
index fe89575347..758379af72 100644
--- a/packages/jest/types/index.d.ts
+++ b/packages/jest/types/index.d.ts
@@ -1,5 +1,5 @@
// Definitions by: Junyoung Clare Jang
-// TypeScript Version: 2.9
+// TypeScript Version: 4.3
///
diff --git a/packages/jest/types/tslint.json b/packages/jest/types/tslint.json
index a0d50da355..9ce68d413d 100644
--- a/packages/jest/types/tslint.json
+++ b/packages/jest/types/tslint.json
@@ -4,6 +4,7 @@
"array-type": [true, "generic"],
"semicolon": false,
"file-name-casing": false,
- "strict-export-declare-modifiers": false
+ "strict-export-declare-modifiers": false,
+ "unnecessary-bind": false
}
}
diff --git a/packages/memoize/CHANGELOG.md b/packages/memoize/CHANGELOG.md
index 29b153ab48..47974e372b 100644
--- a/packages/memoize/CHANGELOG.md
+++ b/packages/memoize/CHANGELOG.md
@@ -1,5 +1,11 @@
# @emotion/memoize
+## 0.9.0
+
+### Minor Changes
+
+- [#2427](https://github.com/emotion-js/emotion/pull/2427) [`7f8db2d`](https://github.com/emotion-js/emotion/commit/7f8db2d7a900bb34995db66084a99d512811e33d) Thanks [@sarayourfriend](https://github.com/sarayourfriend)! - Source code has been migrated to TypeScript. From now on type declarations will be emitted based on that, instead of being hand-written.
+
## 0.8.1
### Patch Changes
diff --git a/packages/memoize/package.json b/packages/memoize/package.json
index d017e54bf2..ad26014903 100644
--- a/packages/memoize/package.json
+++ b/packages/memoize/package.json
@@ -1,10 +1,10 @@
{
"name": "@emotion/memoize",
- "version": "0.8.1",
+ "version": "0.9.0",
"description": "emotion's memoize utility",
"main": "dist/emotion-memoize.cjs.js",
"module": "dist/emotion-memoize.esm.js",
- "types": "types/index.d.ts",
+ "types": "dist/emotion-memoize.cjs.d.ts",
"license": "MIT",
"repository": "https://github.com/emotion-js/emotion/tree/main/packages/memoize",
"scripts": {
@@ -15,15 +15,18 @@
},
"devDependencies": {
"@definitelytyped/dtslint": "0.0.112",
- "typescript": "^4.5.5"
+ "typescript": "^5.4.5"
},
"files": [
"src",
- "dist",
- "types/*.d.ts"
+ "dist"
],
"exports": {
".": {
+ "types": {
+ "import": "./dist/emotion-memoize.cjs.mjs",
+ "default": "./dist/emotion-memoize.cjs.js"
+ },
"module": "./dist/emotion-memoize.esm.js",
"import": "./dist/emotion-memoize.cjs.mjs",
"default": "./dist/emotion-memoize.cjs.js"
diff --git a/packages/memoize/src/index.d.ts b/packages/memoize/src/index.d.ts
deleted file mode 100644
index 9e46093759..0000000000
--- a/packages/memoize/src/index.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../types'
-export { default } from '../types'
diff --git a/packages/memoize/src/index.js b/packages/memoize/src/index.js
deleted file mode 100644
index b1e3741a18..0000000000
--- a/packages/memoize/src/index.js
+++ /dev/null
@@ -1,10 +0,0 @@
-// @flow
-
-export default function memoize(fn: string => V): string => V {
- const cache = Object.create(null)
-
- return (arg: string) => {
- if (cache[arg] === undefined) cache[arg] = fn(arg)
- return cache[arg]
- }
-}
diff --git a/packages/memoize/src/index.ts b/packages/memoize/src/index.ts
new file mode 100644
index 0000000000..2f218b1c8c
--- /dev/null
+++ b/packages/memoize/src/index.ts
@@ -0,0 +1,8 @@
+export default function memoize(fn: (arg: string) => V): (arg: string) => V {
+ const cache: Record = Object.create(null)
+
+ return (arg: string) => {
+ if (cache[arg] === undefined) cache[arg] = fn(arg)
+ return cache[arg]
+ }
+}
diff --git a/packages/memoize/types/index.d.ts b/packages/memoize/types/index.d.ts
index 23f3580f10..2c736dff8d 100644
--- a/packages/memoize/types/index.d.ts
+++ b/packages/memoize/types/index.d.ts
@@ -1,3 +1 @@
-type Fn = (key: string) => T
-
-export default function memoize(fn: Fn): Fn
+export { default } from '..'
diff --git a/packages/memoize/types/tslint.json b/packages/memoize/types/tslint.json
index 2ab14e84ff..48756497b5 100644
--- a/packages/memoize/types/tslint.json
+++ b/packages/memoize/types/tslint.json
@@ -18,6 +18,8 @@
],
"no-unnecessary-generics": false,
- "strict-export-declare-modifiers": false
+ "strict-export-declare-modifiers": false,
+ "no-default-import": false,
+ "unnecessary-bind": false
}
}
diff --git a/packages/native/package.json b/packages/native/package.json
index 2b7f451299..3021231b82 100644
--- a/packages/native/package.json
+++ b/packages/native/package.json
@@ -6,6 +6,10 @@
"module": "dist/emotion-native.esm.js",
"exports": {
".": {
+ "types": {
+ "import": "./dist/emotion-native.cjs.mjs",
+ "default": "./dist/emotion-native.cjs.js"
+ },
"module": "./dist/emotion-native.esm.js",
"import": "./dist/emotion-native.cjs.mjs",
"default": "./dist/emotion-native.cjs.js"
@@ -34,7 +38,7 @@
"@types/react-native": "^0.63.2",
"react": "16.14.0",
"react-native": "^0.63.2",
- "typescript": "^4.5.5"
+ "typescript": "^5.4.5"
},
"dependencies": {
"@emotion/primitives-core": "^11.11.0"
diff --git a/packages/native/test/native-css.test.js b/packages/native/test/native-css.test.js
index ac63ae78fe..b30723d34b 100644
--- a/packages/native/test/native-css.test.js
+++ b/packages/native/test/native-css.test.js
@@ -31,7 +31,6 @@ describe('Emotion native css', () => {
// this test checks the keys instead of the objects
// because we care about the order of the keys
expect(
- // $FlowFixMe
Object.keys(
StyleSheet.flatten(
css({ color: 'green' }, `background-color:yellow;`, { flex: 2 })
@@ -39,7 +38,6 @@ describe('Emotion native css', () => {
)
).toEqual(['color', 'backgroundColor', 'flex'])
expect(
- // $FlowFixMe
Object.keys(
StyleSheet.flatten(
css([
@@ -52,7 +50,6 @@ describe('Emotion native css', () => {
)
).toEqual(['color', 'backgroundColor', 'flex'])
expect(
- // $FlowFixMe
Object.keys(
StyleSheet.flatten(
css([
@@ -68,7 +65,6 @@ describe('Emotion native css', () => {
)
).toEqual(['color', 'backgroundColor', 'flex'])
expect(
- // $FlowFixMe
Object.keys(
StyleSheet.flatten(
css([
@@ -84,7 +80,7 @@ describe('Emotion native css', () => {
).toEqual(['color', 'flex', 'backgroundColor', 'flexGrow', 'flexDirection'])
})
- it('allows function interpolations when this.mergedProps is defined', () => {
+ test('allows function interpolations when this.mergedProps is defined', () => {
expect(
StyleSheet.flatten(
css.call({ thing: true }, props => ({
@@ -94,7 +90,7 @@ describe('Emotion native css', () => {
).toEqual({ color: 'hotpink' })
})
- it('works with nested functions', () => {
+ test('works with nested functions', () => {
expect(
StyleSheet.flatten(
css.call({ thing: true }, props => () => ({
@@ -104,7 +100,7 @@ describe('Emotion native css', () => {
).toEqual({ color: 'hotpink' })
})
- it('works with functions in tagged template literals', () => {
+ test('works with functions in tagged template literals', () => {
expect(
StyleSheet.flatten(
css.call(
diff --git a/packages/native/test/native-styled.test.js b/packages/native/test/native-styled.test.js
index ec992fcecd..b5538963dd 100644
--- a/packages/native/test/native-styled.test.js
+++ b/packages/native/test/native-styled.test.js
@@ -37,7 +37,7 @@ describe('Emotion native styled', () => {
expect(tree).toMatchSnapshot()
})
- it('should work with theming from @emotion/react', () => {
+ test('should work with theming from @emotion/react', () => {
const Text = styled.Text`
color: ${props => props.theme.backgroundColor};
`
@@ -73,7 +73,7 @@ describe('Emotion native styled', () => {
expect(tree).toMatchSnapshot()
})
- it('should work with StyleSheet.create API', () => {
+ test('should work with StyleSheet.create API', () => {
const styles = StyleSheet.create({ foo: { color: 'red' } })
const Text = styled.Text`
font-size: 10px;
@@ -93,7 +93,7 @@ describe('Emotion native styled', () => {
expect(tree).toMatchSnapshot()
})
- it('should style any other component', () => {
+ test('should style any other component', () => {
const Text = styled.Text`
color: hotpink;
`
@@ -106,7 +106,7 @@ describe('Emotion native styled', () => {
expect(tree).toMatchSnapshot()
})
- it('should pass props in withComponent', () => {
+ test('should pass props in withComponent', () => {
const ViewOne = styled.View`
background-color: ${props => props.color};
`
@@ -118,7 +118,7 @@ describe('Emotion native styled', () => {
expect(treeTwo).toMatchSnapshot()
})
- it('should render ', () => {
+ test('should render ', () => {
const Image = styled.Image`
border-radius: 2px;
`
@@ -137,7 +137,7 @@ describe('Emotion native styled', () => {
expect(tree).toMatchSnapshot()
})
- it('Log error message if units are not specified when using shorthand properties', () => {
+ test('Log error message if units are not specified when using shorthand properties', () => {
const Text = styled.Text`
margin: 20px;
padding: 20;
@@ -150,7 +150,7 @@ describe('Emotion native styled', () => {
)
})
- it('should render styles correctly from all nested style factories', () => {
+ test('should render styles correctly from all nested style factories', () => {
const bgColor = color => css`
background-color: ${color};
`
diff --git a/packages/native/types/resolved-condition.ts b/packages/native/types/resolved-condition.ts
new file mode 100644
index 0000000000..e8abb53e2b
--- /dev/null
+++ b/packages/native/types/resolved-condition.ts
@@ -0,0 +1 @@
+export default true as boolean
diff --git a/packages/native/types/tsconfig.json b/packages/native/types/tsconfig.json
index 12a464ad1a..ae37b14af8 100644
--- a/packages/native/types/tsconfig.json
+++ b/packages/native/types/tsconfig.json
@@ -10,7 +10,11 @@
"target": "es5",
"typeRoots": ["../"],
"types": [],
- "skipLibCheck": true
+ "skipLibCheck": true,
+ "paths": {
+ "#is-browser": ["./types/resolved-condition.ts"],
+ "#is-development": ["./types/resolved-condition.ts"]
+ }
},
"include": ["./*.ts", "./*.tsx"]
}
diff --git a/packages/native/types/tslint.json b/packages/native/types/tslint.json
index 75c63f4883..d3d5f2c1b2 100644
--- a/packages/native/types/tslint.json
+++ b/packages/native/types/tslint.json
@@ -19,6 +19,8 @@
],
"no-null-undefined-union": false,
"no-unnecessary-generics": false,
- "strict-export-declare-modifiers": false
+ "strict-export-declare-modifiers": false,
+ "unnecessary-bind": false,
+ "ban-ts-ignore": false
}
}
diff --git a/packages/primitives-core/CHANGELOG.md b/packages/primitives-core/CHANGELOG.md
index 1f4c876907..4649e9e2fc 100644
--- a/packages/primitives-core/CHANGELOG.md
+++ b/packages/primitives-core/CHANGELOG.md
@@ -1,5 +1,25 @@
# @emotion/primitives-core
+## 11.13.0
+
+### Minor Changes
+
+- [#3198](https://github.com/emotion-js/emotion/pull/3198) [`d8ff8a5`](https://github.com/emotion-js/emotion/commit/d8ff8a5990c691017b463b3fa23a9f46ab28147b) Thanks [@Andarist](https://github.com/Andarist)! - Migrated away from relying on `process.env.NODE_ENV` checks to differentiate between production and development builds.
+
+ Development builds (and other environment-specific builds) can be used by using proper conditions (see [here](https://nodejs.org/docs/v20.15.1/api/packages.html#resolving-user-conditions)). Most modern bundlers/frameworks already preconfigure those for the user so no action has to be taken.
+
+ Default files should continue to work in all environments.
+
+## 11.12.0
+
+### Minor Changes
+
+- [#2818](https://github.com/emotion-js/emotion/pull/2818) [`8546dd0`](https://github.com/emotion-js/emotion/commit/8546dd0) Thanks [@srmagura](https://github.com/srmagura)! - Source code has been migrated to TypeScript so from now on type declarations will be available in the published package.
+
+### Patch Changes
+
+- [#3208](https://github.com/emotion-js/emotion/pull/3208) [`56109e7`](https://github.com/emotion-js/emotion/commit/56109e79adcf916144250b52ed579f13e4e6e0cf) Thanks [@Andarist](https://github.com/Andarist)! - Only forward defined `ref`s to improve compatibility with the upcoming React 19
+
## 11.11.0
### Patch Changes
diff --git a/packages/primitives-core/package.json b/packages/primitives-core/package.json
index 17e65a5622..fdb2db4153 100644
--- a/packages/primitives-core/package.json
+++ b/packages/primitives-core/package.json
@@ -1,9 +1,10 @@
{
"name": "@emotion/primitives-core",
- "version": "11.11.0",
+ "version": "11.13.0",
"description": "Shared utilities for emotion primitives and native",
"main": "dist/emotion-primitives-core.cjs.js",
"module": "dist/emotion-primitives-core.esm.js",
+ "types": "dist/emotion-primitives-core.cjs.d.ts",
"files": [
"src",
"dist"
@@ -17,7 +18,8 @@
"react": ">=16.8.0"
},
"devDependencies": {
- "@emotion/react": "11.11.4",
+ "@emotion/react": "11.13.0",
+ "@types/css-to-react-native": "^3.0.0",
"react": "16.14.0"
},
"homepage": "https://emotion.sh",
@@ -42,20 +44,25 @@
},
"exports": {
".": {
- "module": {
- "browser": "./dist/emotion-primitives-core.browser.esm.js",
- "default": "./dist/emotion-primitives-core.esm.js"
+ "types": {
+ "import": "./dist/emotion-primitives-core.cjs.mjs",
+ "default": "./dist/emotion-primitives-core.cjs.js"
},
+ "development": {
+ "module": "./dist/emotion-primitives-core.development.esm.js",
+ "import": "./dist/emotion-primitives-core.development.cjs.mjs",
+ "default": "./dist/emotion-primitives-core.development.cjs.js"
+ },
+ "module": "./dist/emotion-primitives-core.esm.js",
"import": "./dist/emotion-primitives-core.cjs.mjs",
"default": "./dist/emotion-primitives-core.cjs.js"
},
"./package.json": "./package.json"
},
- "preconstruct": {
- "exports": {
- "envConditions": [
- "browser"
- ]
+ "imports": {
+ "#is-development": {
+ "development": "./src/conditions/true.ts",
+ "default": "./src/conditions/false.ts"
}
}
}
diff --git a/packages/primitives-core/src/conditions/false.ts b/packages/primitives-core/src/conditions/false.ts
new file mode 100644
index 0000000000..2693369b44
--- /dev/null
+++ b/packages/primitives-core/src/conditions/false.ts
@@ -0,0 +1 @@
+export default false
diff --git a/packages/primitives-core/src/conditions/true.ts b/packages/primitives-core/src/conditions/true.ts
new file mode 100644
index 0000000000..186b120756
--- /dev/null
+++ b/packages/primitives-core/src/conditions/true.ts
@@ -0,0 +1 @@
+export default true
diff --git a/packages/primitives-core/src/css.js b/packages/primitives-core/src/css.ts
similarity index 75%
rename from packages/primitives-core/src/css.js
rename to packages/primitives-core/src/css.ts
index 3d993c80f1..ec431c23df 100644
--- a/packages/primitives-core/src/css.js
+++ b/packages/primitives-core/src/css.ts
@@ -1,17 +1,23 @@
-// @flow
-import transform from 'css-to-react-native'
+import transform, { Style } from 'css-to-react-native'
+import isDevelopment from '#is-development'
+import { AbstractStyleSheet } from './types'
import { interleave } from './utils'
// this is for handleInterpolation
// they're reset on every call to css
// this is done so we don't create a new
// handleInterpolation function on every css call
-let styles
-let generated = {}
+let styles: unknown[] | undefined
+let generated: Record = {}
let buffer = ''
-let lastType
-
-function handleInterpolation(interpolation: *, i: number, arr: Array<*>) {
+let lastType: string | undefined
+
+function handleInterpolation(
+ this: unknown,
+ interpolation: any,
+ i: number,
+ arr: any[]
+) {
let type = typeof interpolation
if (type === 'string') {
@@ -21,7 +27,7 @@ function handleInterpolation(interpolation: *, i: number, arr: Array<*>) {
if (type === 'function') {
if (this === undefined) {
- if (process.env.NODE_ENV !== 'production') {
+ if (isDevelopment) {
console.error(
'Interpolating functions in css calls is not allowed.\n' +
'If you want to have a css call based on props, create a function that returns a css call like this\n' +
@@ -31,15 +37,7 @@ function handleInterpolation(interpolation: *, i: number, arr: Array<*>) {
)
}
} else {
- handleInterpolation.call(
- this,
- interpolation(
- // $FlowFixMe
- this
- ),
- i,
- arr
- )
+ handleInterpolation.call(this, interpolation(this), i, arr)
}
return
}
@@ -49,7 +47,7 @@ function handleInterpolation(interpolation: *, i: number, arr: Array<*>) {
if (lastType === 'string' && (isRnStyle || isIrrelevant)) {
let converted = convertStyles(buffer)
if (converted !== undefined) {
- styles.push(converted)
+ styles!.push(converted)
}
buffer = ''
}
@@ -63,13 +61,13 @@ function handleInterpolation(interpolation: *, i: number, arr: Array<*>) {
if (arr.length - 1 === i) {
let converted = convertStyles(buffer)
if (converted !== undefined) {
- styles.push(converted)
+ styles!.push(converted)
}
buffer = ''
}
}
if (isRnStyle) {
- styles.push(interpolation)
+ styles!.push(interpolation)
}
if (Array.isArray(interpolation)) {
interpolation.forEach(handleInterpolation, this)
@@ -79,10 +77,10 @@ function handleInterpolation(interpolation: *, i: number, arr: Array<*>) {
// Use platform specific StyleSheet method for creating the styles.
// This enables us to use the css``/css({}) in any environment (Native | Sketch | Web)
-export function createCss(StyleSheet: Object) {
- return function css(...args: any) {
+export function createCss(StyleSheet: AbstractStyleSheet) {
+ return function css(this: unknown, ...args: any[]) {
const prevBuffer = buffer
- let vals
+ let vals: any[]
// these are declared earlier
// this is done so we don't create a new
@@ -94,7 +92,7 @@ export function createCss(StyleSheet: Object) {
if (args[0] == null || args[0].raw === undefined) {
vals = args
} else {
- vals = interleave(args)
+ vals = interleave(args as [any, ...any[]])
}
try {
@@ -116,7 +114,7 @@ export function createCss(StyleSheet: Object) {
let propertyValuePattern = /\s*([^\s]+)\s*:\s*(.+?)\s*$/
-function convertPropertyValue(style) {
+function convertPropertyValue(this: [string, string][], style: string): void {
// Get prop name and prop value
let match = propertyValuePattern.exec(style)
// match[2] will be " " in cases where there is no value
@@ -126,14 +124,14 @@ function convertPropertyValue(style) {
// be the whole string so we remove it
match.shift()
// yes i know this looks funny
- this.push(match)
+ this.push(match as unknown as [string, string])
}
}
-function convertStyles(str: string) {
+function convertStyles(str: string): Style | undefined {
if (str.trim() === '') return
- const stylePairs = []
+ const stylePairs: [string, string][] = []
const parsedString = str.split(';')
@@ -142,9 +140,9 @@ function convertStyles(str: string) {
try {
return transform(stylePairs)
} catch (error) {
- const msg = error.message
+ const msg = (error as { message?: string } | undefined)?.message
- if (msg.includes('Failed to parse declaration')) {
+ if (msg && msg.includes('Failed to parse declaration')) {
const values = msg
.replace('Failed to parse declaration ', '')
.replace(/"/g, '')
diff --git a/packages/primitives-core/src/index.js b/packages/primitives-core/src/index.ts
similarity index 100%
rename from packages/primitives-core/src/index.js
rename to packages/primitives-core/src/index.ts
diff --git a/packages/primitives-core/src/styled.js b/packages/primitives-core/src/styled.ts
similarity index 60%
rename from packages/primitives-core/src/styled.js
rename to packages/primitives-core/src/styled.ts
index f5771552e8..1248833dbd 100644
--- a/packages/primitives-core/src/styled.js
+++ b/packages/primitives-core/src/styled.ts
@@ -1,25 +1,31 @@
-// @flow
import * as React from 'react'
import { interleave } from './utils'
import { ThemeContext } from '@emotion/react'
import { createCss } from './css'
+import { AbstractStyleSheet } from './types'
-let testOmitPropsOnComponent = prop => prop !== 'theme' && prop !== 'as'
+let testOmitPropsOnComponent = (prop: string) =>
+ prop !== 'theme' && prop !== 'as'
-type CreateStyledOptions = {
- getShouldForwardProp: (cmp: React.ElementType) => (prop: string) => boolean
+interface CreateStyledOptions {
+ getShouldForwardProp(cmp: React.ElementType): (prop: string) => boolean
}
-type StyledOptions = {
- shouldForwardProp?: (prop: string) => boolean
+interface StyledOptions {
+ shouldForwardProp?(prop: string): boolean
+}
+
+type StyledProps = Record & {
+ as?: React.ElementType
}
export function createStyled(
- StyleSheet: Object,
- {
- getShouldForwardProp = () => testOmitPropsOnComponent
- }: CreateStyledOptions = {}
+ StyleSheet: AbstractStyleSheet,
+ options?: CreateStyledOptions
) {
+ const getShouldForwardProp =
+ options?.getShouldForwardProp ?? (() => testOmitPropsOnComponent)
+
const css = createCss(StyleSheet)
return function createEmotion(
@@ -34,18 +40,17 @@ export function createStyled(
shouldForwardProp || getShouldForwardProp(component)
let shouldUseAs = !defaultShouldForwardProp('as')
- return function createStyledComponent(...rawStyles: *) {
- let styles
+ return function createStyledComponent(...rawStyles: any[]) {
+ let styles: any[]
if (rawStyles[0] == null || rawStyles[0].raw === undefined) {
styles = rawStyles
} else {
- styles = interleave(rawStyles)
+ styles = interleave(rawStyles as [any, ...any[]])
}
// do we really want to use the same infra as the web since it only really uses theming?
- // $FlowFixMe
- let Styled = React.forwardRef((props, ref) => {
+ let Styled = React.forwardRef((props, ref) => {
const finalTag = (shouldUseAs && props.as) || component
let mergedProps = props
@@ -62,7 +67,7 @@ export function createStyled(
? getShouldForwardProp(finalTag)
: defaultShouldForwardProp
- let newProps = {}
+ let newProps: Record = {}
for (let key in props) {
if (shouldUseAs && key === 'as') continue
@@ -71,25 +76,33 @@ export function createStyled(
newProps[key] = props[key]
}
}
-
newProps.style = [css.apply(mergedProps, styles), props.style]
- newProps.ref = ref
+ if (ref) {
+ newProps.ref = ref
+ }
- // $FlowFixMe
return React.createElement(finalTag, newProps)
})
- // $FlowFixMe
- Styled.withComponent = (newComponent: React.ElementType) =>
- createEmotion(newComponent)(...styles)
Styled.displayName = `emotion(${getDisplayName(component)})`
- return Styled
+ const withComponent = (newComponent: React.ElementType) =>
+ createEmotion(newComponent)(...styles)
+
+ const castedStyled = Styled as typeof Styled & {
+ withComponent: typeof withComponent
+ }
+
+ castedStyled.withComponent = withComponent
+
+ return castedStyled
}
}
}
-const getDisplayName = primitive =>
+const getDisplayName = (
+ primitive: string | { displayName?: string; name?: string }
+) =>
typeof primitive === 'string'
? primitive
: primitive.displayName || primitive.name || 'Styled'
diff --git a/packages/primitives-core/src/types.ts b/packages/primitives-core/src/types.ts
new file mode 100644
index 0000000000..f606163c52
--- /dev/null
+++ b/packages/primitives-core/src/types.ts
@@ -0,0 +1,10 @@
+type NamedStyles = { [P in keyof T]: unknown }
+
+// This is based on the StyleSheet type from @types/react-native
+export interface AbstractStyleSheet {
+ create | NamedStyles>(
+ styles: T | NamedStyles
+ ): T
+
+ flatten(style?: unknown[]): unknown
+}
diff --git a/packages/primitives-core/src/utils.js b/packages/primitives-core/src/utils.ts
similarity index 61%
rename from packages/primitives-core/src/utils.js
rename to packages/primitives-core/src/utils.ts
index 953c2043dc..49ee502438 100644
--- a/packages/primitives-core/src/utils.js
+++ b/packages/primitives-core/src/utils.ts
@@ -1,8 +1,8 @@
-// @flow
-
-export function interleave(vals: Array<*>) {
+export function interleave(
+ vals: [TemplateStringsArray, ...unknown[]]
+): unknown[] {
let strings = vals[0]
- let finalArray = [strings[0]]
+ let finalArray: unknown[] = [strings[0]]
for (let i = 1, len = vals.length; i < len; i++) {
finalArray.push(vals[i])
if (strings[i] !== undefined) {
diff --git a/packages/primitives/CHANGELOG.md b/packages/primitives/CHANGELOG.md
index 750c5ab50d..2146ca7a45 100644
--- a/packages/primitives/CHANGELOG.md
+++ b/packages/primitives/CHANGELOG.md
@@ -1,5 +1,16 @@
# @emotion/primitives
+## 11.13.0
+
+### Minor Changes
+
+- [#3215](https://github.com/emotion-js/emotion/pull/3215) [`a9f6912`](https://github.com/emotion-js/emotion/commit/a9f691299844bf6837b7ad41ee17cd912496f3d5) Thanks [@Andarist](https://github.com/Andarist)! - Added `edge-light` and `workerd` conditions to `package.json` manifest to better serve users using Vercel Edge and Cloudflare Workers.
+
+### Patch Changes
+
+- Updated dependencies [[`d8ff8a5`](https://github.com/emotion-js/emotion/commit/d8ff8a5990c691017b463b3fa23a9f46ab28147b)]:
+ - @emotion/primitives-core@11.13.0
+
## 11.11.0
### Patch Changes
diff --git a/packages/primitives/package.json b/packages/primitives/package.json
index 7f58c1366c..3553ca13ab 100644
--- a/packages/primitives/package.json
+++ b/packages/primitives/package.json
@@ -1,6 +1,6 @@
{
"name": "@emotion/primitives",
- "version": "11.11.0",
+ "version": "11.13.0",
"main": "dist/emotion-primitives.cjs.js",
"module": "dist/emotion-primitives.esm.js",
"files": [
@@ -11,7 +11,7 @@
"dependencies": {
"@emotion/babel-plugin": "^11.11.0",
"@emotion/is-prop-valid": "^1.2.1",
- "@emotion/primitives-core": "^11.11.0"
+ "@emotion/primitives-core": "^11.13.0"
},
"peerDependencies": {
"react": ">=16.8.0",
@@ -40,15 +40,13 @@
"publishConfig": {
"access": "public"
},
- "browser": {
- "./dist/emotion-primitives.esm.js": "./dist/emotion-primitives.browser.esm.js"
- },
"exports": {
".": {
- "module": {
- "browser": "./dist/emotion-primitives.browser.esm.js",
- "default": "./dist/emotion-primitives.esm.js"
+ "types": {
+ "import": "./dist/emotion-primitives.cjs.mjs",
+ "default": "./dist/emotion-primitives.cjs.js"
},
+ "module": "./dist/emotion-primitives.esm.js",
"import": "./dist/emotion-primitives.cjs.mjs",
"default": "./dist/emotion-primitives.cjs.js"
},
@@ -59,10 +57,7 @@
"exports": {
"extra": {
"./macro": "./macro.js"
- },
- "envConditions": [
- "browser"
- ]
+ }
}
}
}
diff --git a/packages/primitives/src/conditions/false.js b/packages/primitives/src/conditions/false.js
new file mode 100644
index 0000000000..2693369b44
--- /dev/null
+++ b/packages/primitives/src/conditions/false.js
@@ -0,0 +1 @@
+export default false
diff --git a/packages/primitives/src/conditions/true.js b/packages/primitives/src/conditions/true.js
new file mode 100644
index 0000000000..186b120756
--- /dev/null
+++ b/packages/primitives/src/conditions/true.js
@@ -0,0 +1 @@
+export default true
diff --git a/packages/primitives/src/index.js b/packages/primitives/src/index.js
index 0dcb3a0d03..a7155513cc 100644
--- a/packages/primitives/src/index.js
+++ b/packages/primitives/src/index.js
@@ -1,4 +1,3 @@
-// @flow
import { StyleSheet, Text, View, Image } from 'react-primitives'
import { createCss } from '@emotion/primitives-core'
diff --git a/packages/primitives/src/styled.js b/packages/primitives/src/styled.js
index 894812d670..6e67d9b9f9 100644
--- a/packages/primitives/src/styled.js
+++ b/packages/primitives/src/styled.js
@@ -1,4 +1,3 @@
-// @flow
import * as React from 'react'
import { StyleSheet, View, Text, Image } from 'react-primitives'
import { createStyled } from '@emotion/primitives-core'
@@ -7,7 +6,7 @@ import {
testPickPropsOnOtherComponent
} from './test-props'
-function getShouldForwardProp(component: React.ElementType) {
+function getShouldForwardProp(component /*: React.ElementType */) {
switch (component) {
case View:
case Text:
@@ -22,6 +21,7 @@ function getShouldForwardProp(component: React.ElementType) {
* a function that returns a styled component which render styles on multiple targets with same code
*/
+/*
type CreateStyledComponent = (
...styles: any
) => React.StatelessFunctionalComponent & {
@@ -35,7 +35,8 @@ export type Styled = BaseStyled & {
Text: CreateStyledComponent,
Image: CreateStyledComponent
}
+*/
-let styled: Styled = createStyled(StyleSheet, { getShouldForwardProp })
+let styled /*: Styled */ = createStyled(StyleSheet, { getShouldForwardProp })
export { styled }
diff --git a/packages/primitives/src/test-props.js b/packages/primitives/src/test-props.js
index aa19f7f78f..ad72f3037a 100644
--- a/packages/primitives/src/test-props.js
+++ b/packages/primitives/src/test-props.js
@@ -1,4 +1,3 @@
-// @flow
import isPropValid from '@emotion/is-prop-valid'
const forwardableProps = {
@@ -49,7 +48,7 @@ const forwardableProps = {
textBreakStrategy: true
}
-export function testPickPropsOnPrimitiveComponent(prop: string) {
+export function testPickPropsOnPrimitiveComponent(prop /*: string */) {
return (
forwardableProps[prop] === true ||
// This will allow the standard react props
@@ -59,6 +58,6 @@ export function testPickPropsOnPrimitiveComponent(prop: string) {
)
}
-export function testPickPropsOnOtherComponent(prop: string) {
+export function testPickPropsOnOtherComponent(prop /*: string */) {
return prop !== 'theme'
}
diff --git a/packages/primitives/test/css.test.js b/packages/primitives/test/css.test.js
index 93fc9b2199..500b561b04 100644
--- a/packages/primitives/test/css.test.js
+++ b/packages/primitives/test/css.test.js
@@ -1,4 +1,3 @@
-// @flow
import { css } from '@emotion/primitives'
import { StyleSheet } from 'react-native'
@@ -29,7 +28,6 @@ test('order with string and object', () => {
// this test checks the keys instead of the objects
// because we care about the order of the keys
expect(
- // $FlowFixMe
Object.keys(
StyleSheet.flatten(
css({ color: 'green' }, `background-color:yellow;`, { flex: 2 })
@@ -37,7 +35,6 @@ test('order with string and object', () => {
)
).toEqual(['color', 'backgroundColor', 'flex'])
expect(
- // $FlowFixMe
Object.keys(
StyleSheet.flatten(
css([
@@ -50,7 +47,6 @@ test('order with string and object', () => {
)
).toEqual(['color', 'backgroundColor', 'flex'])
expect(
- // $FlowFixMe
Object.keys(
StyleSheet.flatten(
css([
@@ -66,7 +62,6 @@ test('order with string and object', () => {
)
).toEqual(['color', 'backgroundColor', 'flex'])
expect(
- // $FlowFixMe
Object.keys(
StyleSheet.flatten(
css([
@@ -82,7 +77,7 @@ test('order with string and object', () => {
).toEqual(['color', 'flex', 'backgroundColor', 'flexGrow', 'flexDirection'])
})
-it('allows function interpolations when this is defined', () => {
+test('allows function interpolations when this is defined', () => {
expect(
StyleSheet.flatten(
css.call({ thing: true }, props => ({
@@ -92,7 +87,7 @@ it('allows function interpolations when this is defined', () => {
).toEqual({ color: 'hotpink' })
})
-it('works with nested functions', () => {
+test('works with nested functions', () => {
expect(
StyleSheet.flatten(
css.call({ thing: true }, props => () => ({
@@ -102,7 +97,7 @@ it('works with nested functions', () => {
).toEqual({ color: 'hotpink' })
})
-it('works with functions in tagged template literals', () => {
+test('works with functions in tagged template literals', () => {
expect(
StyleSheet.flatten(
css.call(
diff --git a/packages/primitives/test/emotion-primitives.test.js b/packages/primitives/test/emotion-primitives.test.js
index 035b08c128..547e822ecb 100644
--- a/packages/primitives/test/emotion-primitives.test.js
+++ b/packages/primitives/test/emotion-primitives.test.js
@@ -1,4 +1,3 @@
-// @flow
import * as React from 'react'
import renderer from 'react-test-renderer'
import { Text, StyleSheet } from 'react-primitives'
@@ -17,7 +16,6 @@ describe('Emotion primitives', () => {
})
test('should throw an error when used invalid primitive', () => {
- // $FlowFixMe: expect error
expect(() => styled.TEXT({})).toThrow()
})
@@ -29,7 +27,6 @@ describe('Emotion primitives', () => {
`
const tree = renderer
.create(
- // $FlowFixMe
Emotion Primitives
@@ -38,7 +35,7 @@ describe('Emotion primitives', () => {
expect(tree).toMatchSnapshot()
})
- it('should work with theming from @emotion/react', () => {
+ test('should work with theming from @emotion/react', () => {
const Text = styled.Text`
color: ${props => props.theme.backgroundColor};
`
@@ -46,7 +43,6 @@ describe('Emotion primitives', () => {
const tree = renderer
.create(
- {/* $FlowFixMe */}
Hello World
)
@@ -55,14 +51,13 @@ describe('Emotion primitives', () => {
expect(tree).toMatchSnapshot()
})
- it('should unmount with theming', () => {
+ test('should unmount with theming', () => {
const StyledText = styled.Text`
display: ${props => props.theme.display};
`
const { container, unmount } = render(
- {/* $FlowFixMe */}
Hello World
@@ -78,7 +73,6 @@ describe('Emotion primitives', () => {
color: props.decor
}))
const tree = renderer
- // $FlowFixMe
.create(Emotion Primitives )
.toJSON()
expect(tree).toMatchSnapshot()
@@ -89,22 +83,18 @@ describe('Emotion primitives', () => {
color: hotpink;
`
const tree = renderer
- .create(
- // $FlowFixMe
- Emotion primitives
- )
+ .create(Emotion primitives )
.toJSON()
expect(tree).toMatchSnapshot()
})
- it('should work with StyleSheet.create API', () => {
+ test('should work with StyleSheet.create API', () => {
const styles = StyleSheet.create({ foo: { color: 'red' } })
const Text = styled.Text`
font-size: 10px;
`
const tree = renderer
- // $FlowFixMe
.create(Emotion Primitives )
.toJSON()
expect(tree).toMatchSnapshot()
@@ -114,28 +104,25 @@ describe('Emotion primitives', () => {
const StyledText = styled.Text`
color: ${props => props.decor};
`
- // $FlowFixMe
const Name = StyledText.withComponent(Text)
const tree = renderer.create(Mike ).toJSON()
expect(tree).toMatchSnapshot()
})
- it('should style any other component', () => {
+ test('should style any other component', () => {
const Text = styled.Text`
color: hotpink;
`
- // $FlowFixMe
const Title = () => Hello World
const StyledTitle = styled(Title)`
font-size: 20px;
font-style: ${props => props.sty};
`
- // $FlowFixMe
const tree = renderer.create( ).toJSON()
expect(tree).toMatchSnapshot()
})
- it('ref', () => {
+ test('ref', () => {
const StyledText = styled.Text`
color: hotpink;
`
@@ -147,13 +134,11 @@ describe('Emotion primitives', () => {
unmount()
})
- it('should pass props in withComponent', () => {
+ test('should pass props in withComponent', () => {
const ViewOne = styled.View`
background-color: ${props => props.color};
`
- // $FlowFixMe
const treeOne = renderer.create( )
- // $FlowFixMe
const ViewTwo = ViewOne.withComponent(Text)
const treeTwo = renderer.create( )
@@ -161,13 +146,12 @@ describe('Emotion primitives', () => {
expect(treeTwo).toMatchSnapshot()
})
- it('should render ', () => {
+ test('should render ', () => {
const Image = styled.Image`
border: 2px solid hotpink;
`
const tree = renderer
.create(
- // $FlowFixMe
{
test('custom shouldForwardProp works', () => {
const Text = styled.Text``
const Title = props =>
- // $FlowFixMe
const StyledTitle = styled(Title, {
shouldForwardProp: prop => prop !== 'color' && prop !== 'theme'
})`
diff --git a/packages/primitives/test/no-babel/basic.test.js b/packages/primitives/test/no-babel/basic.test.js
index be39d3ab15..7697ac1256 100644
--- a/packages/primitives/test/no-babel/basic.test.js
+++ b/packages/primitives/test/no-babel/basic.test.js
@@ -1,4 +1,3 @@
-// @flow
import * as React from 'react'
import styled, { css } from '@emotion/primitives'
import renderer from 'react-test-renderer'
@@ -48,7 +47,6 @@ test('should render the primitive when styles applied using object style notatio
`
const tree = renderer
.create(
- // $FlowFixMe
Emotion Primitives
diff --git a/packages/primitives/test/warnings.test.js b/packages/primitives/test/warnings.test.js
index 7aa51c2bb2..66544801c2 100644
--- a/packages/primitives/test/warnings.test.js
+++ b/packages/primitives/test/warnings.test.js
@@ -1,14 +1,12 @@
-// @flow
import { css } from '@emotion/primitives'
-// $FlowFixMe
console.error = jest.fn()
afterEach(() => {
jest.clearAllMocks()
})
-it('does warn when functions are passed to cx calls ', () => {
+test('does warn when functions are passed to cx calls ', () => {
css(() => ({}))
expect(console.error).toBeCalledWith(
'Interpolating functions in css calls is not allowed.\n' +
diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md
index c88bb256e1..a1ddd19427 100644
--- a/packages/react/CHANGELOG.md
+++ b/packages/react/CHANGELOG.md
@@ -1,5 +1,44 @@
# @emotion/react
+## 11.13.0
+
+### Minor Changes
+
+- [#3198](https://github.com/emotion-js/emotion/pull/3198) [`d8ff8a5`](https://github.com/emotion-js/emotion/commit/d8ff8a5990c691017b463b3fa23a9f46ab28147b) Thanks [@Andarist](https://github.com/Andarist)! - Migrated away from relying on `process.env.NODE_ENV` checks to differentiate between production and development builds.
+
+ Development builds (and other environment-specific builds) can be used by using proper conditions (see [here](https://nodejs.org/docs/v20.15.1/api/packages.html#resolving-user-conditions)). Most modern bundlers/frameworks already preconfigure those for the user so no action has to be taken.
+
+ Default files should continue to work in all environments.
+
+- [#3215](https://github.com/emotion-js/emotion/pull/3215) [`a9f6912`](https://github.com/emotion-js/emotion/commit/a9f691299844bf6837b7ad41ee17cd912496f3d5) Thanks [@Andarist](https://github.com/Andarist)! - Added `edge-light` and `workerd` conditions to `package.json` manifest to better serve users using Vercel Edge and Cloudflare Workers.
+
+### Patch Changes
+
+- Updated dependencies [[`d8ff8a5`](https://github.com/emotion-js/emotion/commit/d8ff8a5990c691017b463b3fa23a9f46ab28147b), [`a9f6912`](https://github.com/emotion-js/emotion/commit/a9f691299844bf6837b7ad41ee17cd912496f3d5)]:
+ - @emotion/cache@11.13.0
+ - @emotion/serialize@1.3.0
+ - @emotion/use-insertion-effect-with-fallbacks@1.1.0
+ - @emotion/utils@1.4.0
+
+## 11.12.0
+
+### Minor Changes
+
+- [#2815](https://github.com/emotion-js/emotion/pull/2815) [`65a1eea`](https://github.com/emotion-js/emotion/commit/65a1eea156a15603cd9ded42769a8ca226cf9450) Thanks [@srmagura](https://github.com/srmagura)! - Automatic labeling at runtime is now an opt-in feature. Define `globalThis.EMOTION_RUNTIME_AUTO_LABEL = true` before Emotion gets initialized to enable it.
+
+### Patch Changes
+
+- [#3206](https://github.com/emotion-js/emotion/pull/3206) [`d1994c4`](https://github.com/emotion-js/emotion/commit/d1994c460761ef37a3d12c587910c4e5b0e6f682) Thanks [@DiegoAndai](https://github.com/DiegoAndai)! - Improved compatibility with the upcoming `@types/react` for React 19 where the global `JSX` namespace doesn't exist anymore
+
+- [#3208](https://github.com/emotion-js/emotion/pull/3208) [`56109e7`](https://github.com/emotion-js/emotion/commit/56109e79adcf916144250b52ed579f13e4e6e0cf) Thanks [@Andarist](https://github.com/Andarist)! - Only forward defined `ref`s to improve compatibility with the upcoming React 19
+
+- Updated dependencies [[`9ca22c6`](https://github.com/emotion-js/emotion/commit/9ca22c6c23e9effa086d161a9b0ae1c645686680), [`b1d16b0`](https://github.com/emotion-js/emotion/commit/b1d16b087d057524f374e347fdfd6a03e505107a), [`16d8a8c`](https://github.com/emotion-js/emotion/commit/16d8a8c2198461c4842c73048b406c346a70aa59)]:
+ - @emotion/serialize@1.2.0
+ - @emotion/weak-memoize@0.4.0
+ - @emotion/utils@1.3.0
+ - @emotion/babel-plugin@11.12.0
+ - @emotion/cache@11.12.0
+
## 11.11.4
### Patch Changes
diff --git a/packages/react/__tests__/__snapshots__/server.js.snap b/packages/react/__tests__/__snapshots__/server.js.snap
index f697e11d0f..3e4665ee44 100644
--- a/packages/react/__tests__/__snapshots__/server.js.snap
+++ b/packages/react/__tests__/__snapshots__/server.js.snap
@@ -34,10 +34,10 @@ exports[`ssr global with keyframes 1`] = `
`;
exports[`ssr keyframes 1`] = `
-
-
+
`;
@@ -119,13 +119,13 @@ exports[`ssr with old api global with keyframes 1`] = `
`;
exports[`ssr with old api keyframes 1`] = `
-
-
-
+
`;
diff --git a/packages/react/__tests__/at-import.js b/packages/react/__tests__/at-import.js
index 82f8e26445..338b8077a6 100644
--- a/packages/react/__tests__/at-import.js
+++ b/packages/react/__tests__/at-import.js
@@ -1,5 +1,3 @@
-// @flow
-import 'test-utils/prod-mode'
import * as React from 'react'
/** @jsx jsx */
import { jsx } from '@emotion/react'
@@ -7,46 +5,45 @@ import { render, unmountComponentAtNode } from 'react-dom'
import { Global, css } from '@emotion/react'
beforeEach(() => {
- // $FlowFixMe
document.head.innerHTML = ''
- // $FlowFixMe
document.body.innerHTML = `
`
})
-test('basic', () => {
- render(
-
-
- {
+ test('basic', () => {
+ render(
+
+
+
- , // $FlowFixMe
- document.getElementById('root')
- )
- expect(document.head).toMatchSnapshot()
- expect(document.body).toMatchSnapshot()
- let elements = document.querySelectorAll('style')
- let rules = []
- for (let element of elements) {
- // $FlowFixMe
- for (let cssRule of element.sheet.cssRules) {
- rules.push(cssRule.cssText)
+ h1 {
+ color: hotpink;
+ }
+ `}
+ />
+ ,
+ document.getElementById('root')
+ )
+ expect(document.head).toMatchSnapshot()
+ expect(document.body).toMatchSnapshot()
+ let elements = document.querySelectorAll('style')
+ let rules = []
+ for (let element of elements) {
+ for (let cssRule of element.sheet.cssRules) {
+ rules.push(cssRule.cssText)
+ }
}
- }
- expect(rules).toMatchInlineSnapshot(`
+ expect(rules).toMatchInlineSnapshot(`
[
"@import url(https://some-url);",
"h1 {color: hotpink;}",
".css-1lrxbo5 {color: hotpink;}",
]
`)
- unmountComponentAtNode(document.getElementById('root'))
- expect(document.head).toMatchSnapshot()
- expect(document.body).toMatchSnapshot()
+ unmountComponentAtNode(document.getElementById('root'))
+ expect(document.head).toMatchSnapshot()
+ expect(document.body).toMatchSnapshot()
+ })
})
diff --git a/packages/react/__tests__/babel/__snapshots__/source-map-server.js.snap b/packages/react/__tests__/babel/__snapshots__/source-map-server.js.snap
index 66744f44d2..6dffe6e758 100644
--- a/packages/react/__tests__/babel/__snapshots__/source-map-server.js.snap
+++ b/packages/react/__tests__/babel/__snapshots__/source-map-server.js.snap
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`basic 1`] = `"
some hotpink text
"`;
+exports[`basic 1`] = `"
some hotpink text
"`;
diff --git a/packages/react/__tests__/babel/source-map-server.js b/packages/react/__tests__/babel/source-map-server.js
index 60ecf18571..47d82f307b 100644
--- a/packages/react/__tests__/babel/source-map-server.js
+++ b/packages/react/__tests__/babel/source-map-server.js
@@ -1,8 +1,7 @@
/** @jsx jsx
* @jest-environment node
*/
-// @flow
-import 'test-utils/dev-mode'
+
import { jsx } from '@emotion/react'
import { renderToString } from 'react-dom/server'
diff --git a/packages/react/__tests__/class-names.js b/packages/react/__tests__/class-names.js
index d165f3b593..c6edd021d3 100644
--- a/packages/react/__tests__/class-names.js
+++ b/packages/react/__tests__/class-names.js
@@ -1,4 +1,3 @@
-// @flow
import * as React from 'react'
import 'test-utils/next-env'
import { ClassNames, ThemeProvider } from '@emotion/react'
@@ -20,7 +19,7 @@ test('css', () => {
expect(tree.toJSON()).toMatchSnapshot()
})
-it('should get the theme', () => {
+test('should get the theme', () => {
const tree = renderer.create(
diff --git a/packages/react/__tests__/clone-element.js b/packages/react/__tests__/clone-element.js
index dedd52c62b..8a73c23938 100644
--- a/packages/react/__tests__/clone-element.js
+++ b/packages/react/__tests__/clone-element.js
@@ -1,4 +1,3 @@
-// @flow
/** @jsx jsx */
import { jsx } from '@emotion/react'
import * as React from 'react'
diff --git a/packages/react/__tests__/compat/browser.js b/packages/react/__tests__/compat/browser.js
index 450a1d2677..c4b46a1cc2 100644
--- a/packages/react/__tests__/compat/browser.js
+++ b/packages/react/__tests__/compat/browser.js
@@ -1,6 +1,4 @@
-// @flow
/** @jsx jsx */
-import 'test-utils/dev-mode'
import { throwIfFalsy } from 'test-utils'
import { jsx, CacheProvider } from '@emotion/react'
import { render } from '@testing-library/react'
diff --git a/packages/react/__tests__/compat/server.js b/packages/react/__tests__/compat/server.js
index 08218a2513..4e72d857c1 100644
--- a/packages/react/__tests__/compat/server.js
+++ b/packages/react/__tests__/compat/server.js
@@ -1,6 +1,5 @@
/** @jsx jsx
* @jest-environment node
- * @flow
*/
import { jsx, Global } from '@emotion/react'
import createEmotionServer from '@emotion/server/create-instance'
diff --git a/packages/react/__tests__/css-cache-hash.js b/packages/react/__tests__/css-cache-hash.js
index 5e1a4fd55a..f7428bf46c 100644
--- a/packages/react/__tests__/css-cache-hash.js
+++ b/packages/react/__tests__/css-cache-hash.js
@@ -1,4 +1,3 @@
-// @flow
/** @jsx jsx */
import 'test-utils/next-env'
import { jsx, css } from '@emotion/react'
diff --git a/packages/react/__tests__/css.js b/packages/react/__tests__/css.js
index 9631e612e8..c0084b03fb 100644
--- a/packages/react/__tests__/css.js
+++ b/packages/react/__tests__/css.js
@@ -1,4 +1,3 @@
-// @flow
/** @jsx jsx */
import 'test-utils/next-env'
import { safeQuerySelector } from 'test-utils'
@@ -8,22 +7,23 @@ import { render } from '@testing-library/react'
import renderer from 'react-test-renderer'
import createCache from '@emotion/cache'
-// $FlowFixMe
console.error = jest.fn()
-// $FlowFixMe
console.warn = jest.fn()
+beforeEach(() => {
+ delete globalThis.EMOTION_RUNTIME_AUTO_LABEL
+})
+
afterEach(() => {
jest.clearAllMocks()
safeQuerySelector('body').innerHTML = ''
})
-const SomeComponent = (props: { lol: true }) => (props.lol ? 'yes' : 'no')
+const SomeComponent = (props /*: { lol: true } */) => (props.lol ? 'yes' : 'no')
// test to make sure flow prop errors work.
// should probably try to make it so that components that require className props
// and have the css prop passed to them don't have type errors
-// $FlowFixMe
; // eslint-disable-line no-unused-expressions
test('thing', () => {
@@ -189,7 +189,27 @@ test('speedy option from a custom cache is inherited for styles', () =
expect(safeQuerySelector('body style').textContent).toEqual('')
})
+test('does not autoLabel without babel or EMOTION_RUNTIME_AUTO_LABEL', () => {
+ let SomeComp = props => {
+ return (
+
+ something
+
+ )
+ }
+ const tree = renderer.create( )
+
+ expect(tree.toJSON().props.className).toMatch(/css-[^-]+/)
+})
+
test('autoLabel without babel', () => {
+ globalThis.EMOTION_RUNTIME_AUTO_LABEL = true
+
let SomeComp = props => {
return (
{
})
test('autoLabel without babel (sanitized)', () => {
+ globalThis.EMOTION_RUNTIME_AUTO_LABEL = true
+
let SomeComp$ = props => {
return (
@@ -223,7 +245,7 @@ test('autoLabel without babel (sanitized)', () => {
})
test('overwrite styles from parent', () => {
- let SomeComponent = (props: Object) => (
+ let SomeComponent = (props /*: Object */) => (
{
})
test('applies class when css prop is set to nil on wrapper component', () => {
- const Button = (props: any) => (
-
- )
+ const Button = props =>
- const WrappedButton: React.StatelessFunctionalComponent
= ({
- children,
- buttonStyles
- }: {
+ const WrappedButton /*: React.StatelessFunctionalComponent */ = (
+ { children, buttonStyles } /*: {
children: React$Node,
buttonStyles?: null
- }) => {children}
+ } */
+ ) => {children}
const tree = renderer.create(
@@ -341,6 +360,6 @@ it("doesn't try to insert invalid rules caused by object style's value being fal
)
- expect((console.error: any).mock.calls).toMatchInlineSnapshot(`[]`)
- expect((console.warn: any).mock.calls).toMatchInlineSnapshot(`[]`)
+ expect(console.error.mock.calls).toMatchInlineSnapshot(`[]`)
+ expect(console.warn.mock.calls).toMatchInlineSnapshot(`[]`)
})
diff --git a/packages/react/__tests__/custom-cache.js b/packages/react/__tests__/custom-cache.js
index 2ccf1e3364..43907de7a4 100644
--- a/packages/react/__tests__/custom-cache.js
+++ b/packages/react/__tests__/custom-cache.js
@@ -1,4 +1,3 @@
-// @flow
/** @jsx jsx */
import createCache from '@emotion/cache'
import { CacheProvider, Global, jsx } from '@emotion/react'
diff --git a/packages/react/__tests__/element.js b/packages/react/__tests__/element.js
index f4a89dc897..9206e89d6b 100644
--- a/packages/react/__tests__/element.js
+++ b/packages/react/__tests__/element.js
@@ -1,6 +1,5 @@
// @flow
/** @jsx jsx */
-import 'test-utils/dev-mode'
import { render } from '@testing-library/react'
import { jsx, css, CacheProvider, ThemeProvider } from '@emotion/react'
import createCache from '@emotion/cache'
diff --git a/packages/react/__tests__/global-with-theme.js b/packages/react/__tests__/global-with-theme.js
index 32b0d46c72..ed80088dee 100644
--- a/packages/react/__tests__/global-with-theme.js
+++ b/packages/react/__tests__/global-with-theme.js
@@ -1,11 +1,8 @@
-// @flow
-import 'test-utils/dev-mode'
import * as React from 'react'
import { render } from '@testing-library/react'
import { Global, ThemeProvider } from '@emotion/react'
beforeEach(() => {
- // $FlowFixMe
document.head.innerHTML = ''
})
diff --git a/packages/react/__tests__/global.js b/packages/react/__tests__/global.js
index 2ecc075407..a9258c6e2d 100644
--- a/packages/react/__tests__/global.js
+++ b/packages/react/__tests__/global.js
@@ -1,5 +1,3 @@
-// @flow
-import 'test-utils/dev-mode'
import * as React from 'react'
import { render } from '@testing-library/react'
import {
@@ -15,7 +13,6 @@ import createCache from '@emotion/cache'
console.error = jest.fn()
beforeEach(() => {
- // $FlowFixMe
document.head.innerHTML = ''
jest.resetAllMocks()
})
@@ -76,7 +73,6 @@ test('no React hook order violations', () => {
const theme = { color: 'blue' }
const cache = createCache({ key: 'context' })
- // $FlowFixMe
const Comp = ({ flag }) => (
diff --git a/packages/react/__tests__/globals-are-the-worst.js b/packages/react/__tests__/globals-are-the-worst.js
index 33d7dd1bd3..8b6b269e95 100644
--- a/packages/react/__tests__/globals-are-the-worst.js
+++ b/packages/react/__tests__/globals-are-the-worst.js
@@ -1,5 +1,3 @@
-// @flow
-import 'test-utils/dev-mode'
import { render } from '@testing-library/react'
import * as React from 'react'
import { Global } from '@emotion/react'
diff --git a/packages/react/__tests__/import-prod.js b/packages/react/__tests__/import-prod.js
index a6ca906518..73e5f81f78 100644
--- a/packages/react/__tests__/import-prod.js
+++ b/packages/react/__tests__/import-prod.js
@@ -1,5 +1,3 @@
-// @flow
-import 'test-utils/prod-mode'
import * as React from 'react'
import * as ReactDOM from 'react-dom'
import { css, Global } from '@emotion/react'
@@ -28,68 +26,70 @@ const render = children =>
// $FlowFixMe
document.body.appendChild(el)
- if ((ReactDOM: any).createRoot) {
- const root = (ReactDOM: any).createRoot(el)
+ if (ReactDOM.createRoot) {
+ const root = ReactDOM.createRoot(el)
root.render({children}
)
} else {
ReactDOM.render(children, el, resolve)
}
})
-test('it works', async () => {
- await render(
-
-
something
+gate({ development: false }, ({ test }) => {
+ test('it works', async () => {
+ await render(
+
+ something
-
-
-
- )
- // order should be
- // 1. html { background-color: yellow; }
- // 1. @import
- // 2. body { padding: 0; }
- // 3. styled comp
+
+
+
+ )
+ // order should be
+ // 1. html { background-color: yellow; }
+ // 1. @import
+ // 2. body { padding: 0; }
+ // 3. styled comp
- // querying for style instead of [data-emotion] to appease flow
- let elements = Array.from(document.querySelectorAll('style')).filter(x =>
- x.getAttribute('data-emotion')
- )
+ // querying for style instead of [data-emotion] to appease flow
+ let elements = Array.from(document.querySelectorAll('style')).filter(x =>
+ x.getAttribute('data-emotion')
+ )
- expect(elements.map(x => x.getAttribute('data-emotion'))).toEqual([
- 'css-global',
- 'css-global',
- 'css'
- ])
+ expect(elements.map(x => x.getAttribute('data-emotion'))).toEqual([
+ 'css-global',
+ 'css-global',
+ 'css'
+ ])
- expect(elements[0].sheet).toMatchInlineSnapshot(`
+ expect(elements[0].sheet).toMatchInlineSnapshot(`
html {
background-color: yellow;
}
`)
- expect(elements[1].sheet).toMatchInlineSnapshot(`
+ expect(elements[1].sheet).toMatchInlineSnapshot(`
@import url(something.com/file.css);
body {
padding: 0;
}
`)
- expect(elements[2].sheet).toMatchInlineSnapshot(`
+ expect(elements[2].sheet).toMatchInlineSnapshot(`
.css-1lrxbo5 {
color: hotpink;
}
`)
+ })
})
diff --git a/packages/react/__tests__/keyframes.js b/packages/react/__tests__/keyframes.js
index acf849f7da..481f866e08 100644
--- a/packages/react/__tests__/keyframes.js
+++ b/packages/react/__tests__/keyframes.js
@@ -1,4 +1,3 @@
-// @flow
/** @jsx jsx */
import 'test-utils/next-env'
import { jsx, css, keyframes } from '@emotion/react'
diff --git a/packages/react/__tests__/legacy-class-name.js b/packages/react/__tests__/legacy-class-name.js
index dd1d13dbf3..82345c4203 100644
--- a/packages/react/__tests__/legacy-class-name.js
+++ b/packages/react/__tests__/legacy-class-name.js
@@ -1,4 +1,3 @@
-// @flow
/** @jsx jsx */
import 'test-utils/next-env'
import { jsx, css } from '@emotion/react'
diff --git a/packages/react/__tests__/prod.js b/packages/react/__tests__/prod.js
index 3017ad3899..ae3ec5895d 100644
--- a/packages/react/__tests__/prod.js
+++ b/packages/react/__tests__/prod.js
@@ -1,21 +1,22 @@
-import 'test-utils/prod-mode'
/** @jsx jsx */
import { css, jsx } from '@emotion/react'
import renderer from 'react-test-renderer'
-test('css works', () => {
- // css has a different return in prod so this is just making sure that isn't broken
+gate({ development: false }, ({ test }) => {
+ test('css works', () => {
+ // css has a different return in prod so this is just making sure that isn't broken
- expect(css({ color: 'hotpink' })).toMatchInlineSnapshot(`
+ expect(css({ color: 'hotpink' })).toMatchInlineSnapshot(`
{
"name": "1lrxbo5",
"next": undefined,
"styles": "color:hotpink;",
}
`)
-})
+ })
-test('props work', () => {
- let tree = renderer.create(
)
- expect(tree.toJSON().props.hidden).toBe(true)
+ test('props work', () => {
+ let tree = renderer.create(
)
+ expect(tree.toJSON().props.hidden).toBe(true)
+ })
})
diff --git a/packages/react/__tests__/ref.js b/packages/react/__tests__/ref.js
index bb9766602f..0b82cce60b 100644
--- a/packages/react/__tests__/ref.js
+++ b/packages/react/__tests__/ref.js
@@ -1,4 +1,3 @@
-// @flow
/** @jsx jsx */
import { jsx } from '@emotion/react'
import * as React from 'react'
diff --git a/packages/react/__tests__/rehydration.js b/packages/react/__tests__/rehydration.js
index f03c88846a..ae9cdc85c4 100644
--- a/packages/react/__tests__/rehydration.js
+++ b/packages/react/__tests__/rehydration.js
@@ -1,10 +1,7 @@
-// @flow
/** @jsx jsx */
import { safeQuerySelector, disableBrowserEnvTemporarily } from 'test-utils'
-// $FlowFixMe
console.error = jest.fn()
-// $FlowFixMe
console.warn = jest.fn()
afterEach(() => {
@@ -56,8 +53,8 @@ beforeEach(() => {
test("cache created in render doesn't cause a hydration mismatch", () => {
safeQuerySelector('body').innerHTML = [
'',
- '',
- '
Hello world!
',
+ '',
+ '
Hello world!
',
'
'
].join('')
@@ -87,8 +84,8 @@ test("cache created in render doesn't cause a hydration mismatch", () => {
container: safeQuerySelector('#root')
})
- expect((console.error: any).mock.calls).toMatchInlineSnapshot(`[]`)
- expect((console.warn: any).mock.calls).toMatchInlineSnapshot(`[]`)
+ expect(console.error.mock.calls).toMatchInlineSnapshot(`[]`)
+ expect(console.warn.mock.calls).toMatchInlineSnapshot(`[]`)
})
test('initializing another Emotion instance should not move already moved styles elements', () => {
@@ -144,7 +141,7 @@ test('initializing another Emotion instance should not move already moved styles
data-s=""
>
- .stl-1pdkrhd-App{color:hotpink;}
+ .stl-168r6j{color:hotpink;}
@@ -192,7 +189,7 @@ test('initializing another Emotion instance should not move already moved styles
data-s=""
>
- .stl-1pdkrhd-App{color:hotpink;}
+ .stl-168r6j{color:hotpink;}
@@ -607,13 +604,13 @@ test('duplicated global styles can be removed safely after rehydrating HTML SSRe
`)
})
-;((React: any).useId ? describe : describe.skip)('useId', () => {
+;(React.useId ? describe : describe.skip)('useId', () => {
test('no hydration mismatch for styled when using useId', async () => {
const finalHTML = await disableBrowserEnvTemporarily(() => {
resetAllModules()
const StyledDivWithId = styled(function DivWithId({ className }) {
- const id = (React: any).useId()
+ const id = React.useId()
return
})({
border: '1px solid black'
@@ -627,7 +624,7 @@ test('duplicated global styles can be removed safely after rehydrating HTML SSRe
resetAllModules()
const StyledDivWithId = styled(function DivWithId({ className }) {
- const id = (React: any).useId()
+ const id = React.useId()
return
})({
border: '1px solid black'
@@ -638,16 +635,16 @@ test('duplicated global styles can be removed safely after rehydrating HTML SSRe
container: safeQuerySelector('#root')
})
- expect((console.error: any).mock.calls).toMatchInlineSnapshot(`[]`)
- expect((console.warn: any).mock.calls).toMatchInlineSnapshot(`[]`)
+ expect(console.error.mock.calls).toMatchInlineSnapshot(`[]`)
+ expect(console.warn.mock.calls).toMatchInlineSnapshot(`[]`)
})
test('no hydration mismatch for css prop when using useId', async () => {
const finalHTML = await disableBrowserEnvTemporarily(() => {
resetAllModules()
- function DivWithId({ className }: { className?: string }) {
- const id = (React: any).useId()
+ function DivWithId({ className } /*: { className?: string }*/) {
+ const id = React.useId()
return
}
@@ -664,8 +661,8 @@ test('duplicated global styles can be removed safely after rehydrating HTML SSRe
resetAllModules()
- function DivWithId({ className }: { className?: string }) {
- const id = (React: any).useId()
+ function DivWithId({ className } /*: { className?: string }*/) {
+ const id = React.useId()
return
}
@@ -681,8 +678,8 @@ test('duplicated global styles can be removed safely after rehydrating HTML SSRe
}
)
- expect((console.error: any).mock.calls).toMatchInlineSnapshot(`[]`)
- expect((console.warn: any).mock.calls).toMatchInlineSnapshot(`[]`)
+ expect(console.error.mock.calls).toMatchInlineSnapshot(`[]`)
+ expect(console.warn.mock.calls).toMatchInlineSnapshot(`[]`)
})
test('no hydration mismatch for ClassNames when using useId', async () => {
@@ -690,7 +687,7 @@ test('duplicated global styles can be removed safely after rehydrating HTML SSRe
resetAllModules()
const DivWithId = ({ className }) => {
- const id = (React: any).useId()
+ const id = React.useId()
return
}
@@ -714,7 +711,7 @@ test('duplicated global styles can be removed safely after rehydrating HTML SSRe
resetAllModules()
const DivWithId = ({ className }) => {
- const id = (React: any).useId()
+ const id = React.useId()
return
}
@@ -736,7 +733,7 @@ test('duplicated global styles can be removed safely after rehydrating HTML SSRe
}
)
- expect((console.error: any).mock.calls).toMatchInlineSnapshot(`[]`)
- expect((console.warn: any).mock.calls).toMatchInlineSnapshot(`[]`)
+ expect(console.error.mock.calls).toMatchInlineSnapshot(`[]`)
+ expect(console.warn.mock.calls).toMatchInlineSnapshot(`[]`)
})
})
diff --git a/packages/react/__tests__/server.js b/packages/react/__tests__/server.js
index c6625a3851..02a3134eb6 100644
--- a/packages/react/__tests__/server.js
+++ b/packages/react/__tests__/server.js
@@ -1,8 +1,7 @@
/** @jsx jsx
* @jest-environment node
*/
-// @flow
-import 'test-utils/dev-mode'
+
import * as React from 'react'
import testCases from 'jest-in-case'
import {
@@ -38,16 +37,14 @@ let cases = {
},
keyframes: {
render: () => {
- const animation = keyframes(
- css`
- from {
- color: green;
- }
- to {
- color: blue;
- }
- `
- )
+ const animation = keyframes(css`
+ from {
+ color: green;
+ }
+ to {
+ color: blue;
+ }
+ `)
return (
diff --git a/packages/react/__tests__/theme-provider.dom.js b/packages/react/__tests__/theme-provider.dom.js
index 412539c751..4c56ba9846 100644
--- a/packages/react/__tests__/theme-provider.dom.js
+++ b/packages/react/__tests__/theme-provider.dom.js
@@ -1,7 +1,5 @@
-// @flow
/** @jsx jsx */
import 'test-utils/next-env'
-import 'test-utils/dev-mode'
import { render, fireEvent } from '@testing-library/react'
import { safeQuerySelector } from 'test-utils'
import * as React from 'react'
@@ -13,7 +11,7 @@ beforeEach(() => {
})
test('provider with theme value that changes', () => {
- class ThemeTest extends React.Component<*, *> {
+ class ThemeTest extends React.Component {
state = { theme: { color: 'hotpink', padding: 4 } }
render() {
return (
diff --git a/packages/react/__tests__/theme-provider.js b/packages/react/__tests__/theme-provider.js
index d9a06c0790..1e6b84bc64 100644
--- a/packages/react/__tests__/theme-provider.js
+++ b/packages/react/__tests__/theme-provider.js
@@ -1,4 +1,3 @@
-// @flow
/** @jsx jsx */
import 'test-utils/next-env'
import { ignoreConsoleErrors } from 'test-utils'
@@ -57,7 +56,6 @@ cases(
expect(() => {
renderer.create(
- {/* $FlowFixMe */}
({
diff --git a/packages/react/__tests__/use-theme.js b/packages/react/__tests__/use-theme.js
index cbf5d8ca7c..301b5c3f07 100644
--- a/packages/react/__tests__/use-theme.js
+++ b/packages/react/__tests__/use-theme.js
@@ -1,4 +1,3 @@
-// @flow
/** @jsx jsx */
import 'test-utils/next-env'
import * as renderer from 'react-test-renderer'
diff --git a/packages/react/__tests__/warnings.js b/packages/react/__tests__/warnings.js
index 5af566acc0..98083bb84f 100644
--- a/packages/react/__tests__/warnings.js
+++ b/packages/react/__tests__/warnings.js
@@ -1,4 +1,3 @@
-// @flow
/** @jsx jsx */
import 'test-utils/next-env'
import { jsx, css, Global, keyframes, ClassNames } from '@emotion/react'
@@ -6,7 +5,6 @@ import styled from '@emotion/styled'
import renderer from 'react-test-renderer'
import { render } from '@testing-library/react'
-// $FlowFixMe
console.error = jest.fn()
const validValues = [
@@ -39,7 +37,7 @@ beforeEach(() => {
jest.resetAllMocks()
})
-it('does not warn when valid values are passed for the content property', () => {
+test('does not warn when valid values are passed for the content property', () => {
const style = css(validValues.map(value => ({ content: value })))
expect(console.error).not.toBeCalled()
expect(renderer.create(
).toJSON()).toMatchSnapshot()
@@ -47,8 +45,7 @@ it('does not warn when valid values are passed for the content property', () =>
const invalidValues = ['this is not valid', '', 'element']
-it('does warn when invalid values are passed for the content property', () => {
- // $FlowFixMe
+test('does warn when invalid values are passed for the content property', () => {
invalidValues.forEach(value => {
expect(() =>
renderer.create(
)
@@ -78,7 +75,7 @@ describe('unsafe pseudo classes', () => {
color: hotpink;
}
`
- const match = (pseudoClass.match(/(:first|:nth|:nth-last)-child/): any)
+ const match = pseudoClass.match(/(:first|:nth|:nth-last)-child/)
expect(match).not.toBeNull()
expect(renderer.create(
).toJSON()).toMatchSnapshot()
expect(console.error).toBeCalledWith(
@@ -119,7 +116,7 @@ describe('unsafe pseudo classes', () => {
{ pseudoClass: `:first-child, :nth-child(3)` },
{ pseudoClass: `:first-child:nth-child(3)` }
])('$pseudoClass', ({ pseudoClass }) => {
- const match = (pseudoClass.match(/(:first|:nth|:nth-last)-child/): any)
+ const match = pseudoClass.match(/(:first|:nth|:nth-last)-child/)
expect(match).not.toBeNull()
expect(
renderer.create(
).toJSON()
@@ -145,7 +142,7 @@ describe('unsafe pseudo classes', () => {
)
.toJSON()
).toMatchSnapshot()
- expect((console.error: any).mock.calls).toMatchInlineSnapshot(`
+ expect(console.error.mock.calls).toMatchInlineSnapshot(`
[
[
"The pseudo class ":first-child" is potentially unsafe when doing server-side rendering. Try changing it to ":first-of-type".",
@@ -171,7 +168,7 @@ describe('unsafe pseudo classes', () => {
)
.toJSON()
).toMatchSnapshot()
- expect((console.error: any).mock.calls).toMatchInlineSnapshot(`
+ expect(console.error.mock.calls).toMatchInlineSnapshot(`
[
[
"The pseudo class ":first-child" is potentially unsafe when doing server-side rendering. Try changing it to ":first-of-type".",
@@ -195,7 +192,7 @@ describe('unsafe pseudo classes', () => {
)
.toJSON()
).toMatchSnapshot()
- expect((console.error: any).mock.calls).toMatchInlineSnapshot(`
+ expect(console.error.mock.calls).toMatchInlineSnapshot(`
[
[
"The pseudo class ":first-child" is potentially unsafe when doing server-side rendering. Try changing it to ":first-of-type".",
@@ -219,7 +216,7 @@ describe('unsafe pseudo classes', () => {
)
.toJSON()
).toMatchSnapshot()
- expect((console.error: any).mock.calls).toMatchInlineSnapshot(`
+ expect(console.error.mock.calls).toMatchInlineSnapshot(`
[
[
"The pseudo class ":first-child" is potentially unsafe when doing server-side rendering. Try changing it to ":first-of-type".",
@@ -242,7 +239,7 @@ describe('unsafe pseudo classes', () => {
)
.toJSON()
).toMatchSnapshot()
- expect((console.error: any).mock.calls).toMatchInlineSnapshot(`
+ expect(console.error.mock.calls).toMatchInlineSnapshot(`
[
[
"The pseudo class ":first-child" is potentially unsafe when doing server-side rendering. Try changing it to ":first-of-type".",
@@ -360,7 +357,7 @@ describe('unsafe pseudo classes', () => {
)
.toJSON()
).toMatchSnapshot()
- expect((console.error: any).mock.calls).toMatchInlineSnapshot(`
+ expect(console.error.mock.calls).toMatchInlineSnapshot(`
[
[
"The pseudo class ":first-child" is potentially unsafe when doing server-side rendering. Try changing it to ":first-of-type".",
@@ -393,7 +390,6 @@ describe('unsafe pseudo classes', () => {
test('global with css prop', () => {
let tree = renderer
.create(
- // $FlowFixMe
{
css({ '@media (min-width 800px)': undefined })
css({ '--primary-color': 'hotpink' })
css({ ':last-of-type': null })
- expect((console.error: any).mock.calls).toMatchInlineSnapshot(`
+ expect(console.error.mock.calls).toMatchInlineSnapshot(`
[
[
"Using kebab-case for css properties in objects is not supported. Did you mean backgroundColor?",
@@ -449,7 +445,7 @@ test('keyframes interpolated into plain string', () => {
renderer.create(
)
- expect((console.error: any).mock.calls).toMatchInlineSnapshot(`
+ expect(console.error.mock.calls).toMatchInlineSnapshot(`
[
[
"\`keyframes\` output got interpolated into plain string, please wrap it with \`css\`.
@@ -492,7 +488,6 @@ test('`css` opaque object passed to `cx` from ', () => {
{({ cx }) => (
', () => {
)
- expect((console.error: any).mock.calls).toMatchInlineSnapshot(`
+ expect(console.error.mock.calls).toMatchInlineSnapshot(`
[
[
"You have passed styles created with \`css\` from \`@emotion/react\` package to the \`cx\`.
@@ -526,7 +521,7 @@ test('@import nested in scoped `css`', () => {
/>
)
- expect((console.error: any).mock.calls).toMatchInlineSnapshot(`
+ expect(console.error.mock.calls).toMatchInlineSnapshot(`
[
[
"\`@import\` rules can't be nested inside other rules. Please move it to the top level and put it before regular rules. Keep in mind that they can only be used within global styles.",
@@ -548,7 +543,7 @@ test('@import prepended with other rules', () => {
/>
)
- expect((console.error: any).mock.calls).toMatchInlineSnapshot(`
+ expect(console.error.mock.calls).toMatchInlineSnapshot(`
[
[
"\`@import\` rules can't be after other rules. Please put your \`@import\` rules before your other rules.",
@@ -567,7 +562,7 @@ test('@import prepended by other @import', () => {
/>
)
- expect((console.error: any).mock.calls).toMatchInlineSnapshot(`[]`)
+ expect(console.error.mock.calls).toMatchInlineSnapshot(`[]`)
})
test('when using `jsx` multiple static children should not result in a key-related warning', () => {
@@ -577,5 +572,5 @@ test('when using `jsx` multiple static children should not result in a key-relat
)
- expect((console.error: any).mock.calls).toMatchInlineSnapshot(`[]`)
+ expect(console.error.mock.calls).toMatchInlineSnapshot(`[]`)
})
diff --git a/packages/react/__tests__/with-theme.js b/packages/react/__tests__/with-theme.js
index 4512dc47e0..643af77a92 100644
--- a/packages/react/__tests__/with-theme.js
+++ b/packages/react/__tests__/with-theme.js
@@ -1,10 +1,9 @@
-// @flow
import * as React from 'react'
import * as renderer from 'react-test-renderer'
import { withTheme, ThemeProvider } from '@emotion/react'
test('withTheme works', () => {
- class SomeComponent extends React.Component<{ theme: Object }> {
+ class SomeComponent extends React.Component /* <{ theme: Object }> */ {
render() {
return this.props.theme.color
}
@@ -22,7 +21,7 @@ test('withTheme works', () => {
})
test(`withTheme(Comp) hoists non-react static class properties`, () => {
- class ExampleComponent extends React.Component<*> {
+ class ExampleComponent extends React.Component {
static displayName = 'foo'
static someSpecialStatic = 'bar'
}
@@ -30,14 +29,13 @@ test(`withTheme(Comp) hoists non-react static class properties`, () => {
const ComponentWithTheme = withTheme(ExampleComponent)
expect(ComponentWithTheme.displayName).toBe('WithTheme(foo)')
- // $FlowFixMe hoist-non-react-statics doesn't work with AbstractComponent https://github.com/facebook/flow/issues/7612
expect(ComponentWithTheme.someSpecialStatic).toBe(
ExampleComponent.someSpecialStatic
)
})
-it('should forward the ref', () => {
- class SomeComponent extends React.Component<*> {
+test('should forward the ref', () => {
+ class SomeComponent extends React.Component {
render() {
return this.props.theme.color
}
diff --git a/packages/react/_isolated-hnrs/package.json b/packages/react/_isolated-hnrs/package.json
index a8a01ced60..72a77af979 100644
--- a/packages/react/_isolated-hnrs/package.json
+++ b/packages/react/_isolated-hnrs/package.json
@@ -2,9 +2,6 @@
"main": "dist/emotion-react-_isolated-hnrs.cjs.js",
"module": "dist/emotion-react-_isolated-hnrs.esm.js",
"umd:main": "dist/emotion-react-_isolated-hnrs.umd.min.js",
- "browser": {
- "./dist/emotion-react-_isolated-hnrs.esm.js": "./dist/emotion-react-_isolated-hnrs.browser.esm.js"
- },
"sideEffects": false,
"preconstruct": {
"umdName": "emotionHoistNonReactStatics"
diff --git a/packages/react/jsx-dev-runtime/package.json b/packages/react/jsx-dev-runtime/package.json
index 42a33d8e53..5c5a6d908b 100644
--- a/packages/react/jsx-dev-runtime/package.json
+++ b/packages/react/jsx-dev-runtime/package.json
@@ -2,9 +2,6 @@
"main": "dist/emotion-react-jsx-dev-runtime.cjs.js",
"module": "dist/emotion-react-jsx-dev-runtime.esm.js",
"umd:main": "dist/emotion-react-jsx-dev-runtime.umd.min.js",
- "browser": {
- "./dist/emotion-react-jsx-dev-runtime.esm.js": "./dist/emotion-react-jsx-dev-runtime.browser.esm.js"
- },
"types": "../types/jsx-dev-runtime",
"sideEffects": false,
"preconstruct": {
diff --git a/packages/react/jsx-runtime/package.json b/packages/react/jsx-runtime/package.json
index d57371db3a..6b6dab3eda 100644
--- a/packages/react/jsx-runtime/package.json
+++ b/packages/react/jsx-runtime/package.json
@@ -2,9 +2,6 @@
"main": "dist/emotion-react-jsx-runtime.cjs.js",
"module": "dist/emotion-react-jsx-runtime.esm.js",
"umd:main": "dist/emotion-react-jsx-runtime.umd.min.js",
- "browser": {
- "./dist/emotion-react-jsx-runtime.esm.js": "./dist/emotion-react-jsx-runtime.browser.esm.js"
- },
"types": "../types/jsx-runtime",
"sideEffects": false,
"preconstruct": {
diff --git a/packages/react/macro.js.flow b/packages/react/macro.js.flow
deleted file mode 100644
index 63ae97e66d..0000000000
--- a/packages/react/macro.js.flow
+++ /dev/null
@@ -1,2 +0,0 @@
-// @flow
-export * from './src/index.js'
diff --git a/packages/react/package.json b/packages/react/package.json
index cd2e55adc5..ea5f49bfb1 100644
--- a/packages/react/package.json
+++ b/packages/react/package.json
@@ -1,45 +1,222 @@
{
"name": "@emotion/react",
- "version": "11.11.4",
+ "version": "11.13.0",
"main": "dist/emotion-react.cjs.js",
"module": "dist/emotion-react.esm.js",
- "browser": {
- "./dist/emotion-react.esm.js": "./dist/emotion-react.browser.esm.js"
- },
"exports": {
".": {
- "module": {
- "worker": "./dist/emotion-react.worker.esm.js",
- "browser": "./dist/emotion-react.browser.esm.js",
- "default": "./dist/emotion-react.esm.js"
+ "types": {
+ "import": "./dist/emotion-react.cjs.mjs",
+ "default": "./dist/emotion-react.cjs.js"
+ },
+ "development": {
+ "edge-light": {
+ "module": "./dist/emotion-react.development.edge-light.esm.js",
+ "import": "./dist/emotion-react.development.edge-light.cjs.mjs",
+ "default": "./dist/emotion-react.development.edge-light.cjs.js"
+ },
+ "worker": {
+ "module": "./dist/emotion-react.development.edge-light.esm.js",
+ "import": "./dist/emotion-react.development.edge-light.cjs.mjs",
+ "default": "./dist/emotion-react.development.edge-light.cjs.js"
+ },
+ "workerd": {
+ "module": "./dist/emotion-react.development.edge-light.esm.js",
+ "import": "./dist/emotion-react.development.edge-light.cjs.mjs",
+ "default": "./dist/emotion-react.development.edge-light.cjs.js"
+ },
+ "browser": {
+ "module": "./dist/emotion-react.browser.development.esm.js",
+ "import": "./dist/emotion-react.browser.development.cjs.mjs",
+ "default": "./dist/emotion-react.browser.development.cjs.js"
+ },
+ "module": "./dist/emotion-react.development.esm.js",
+ "import": "./dist/emotion-react.development.cjs.mjs",
+ "default": "./dist/emotion-react.development.cjs.js"
+ },
+ "edge-light": {
+ "module": "./dist/emotion-react.edge-light.esm.js",
+ "import": "./dist/emotion-react.edge-light.cjs.mjs",
+ "default": "./dist/emotion-react.edge-light.cjs.js"
+ },
+ "worker": {
+ "module": "./dist/emotion-react.edge-light.esm.js",
+ "import": "./dist/emotion-react.edge-light.cjs.mjs",
+ "default": "./dist/emotion-react.edge-light.cjs.js"
+ },
+ "workerd": {
+ "module": "./dist/emotion-react.edge-light.esm.js",
+ "import": "./dist/emotion-react.edge-light.cjs.mjs",
+ "default": "./dist/emotion-react.edge-light.cjs.js"
+ },
+ "browser": {
+ "module": "./dist/emotion-react.browser.esm.js",
+ "import": "./dist/emotion-react.browser.cjs.mjs",
+ "default": "./dist/emotion-react.browser.cjs.js"
},
+ "module": "./dist/emotion-react.esm.js",
"import": "./dist/emotion-react.cjs.mjs",
"default": "./dist/emotion-react.cjs.js"
},
"./jsx-runtime": {
- "module": {
- "worker": "./jsx-runtime/dist/emotion-react-jsx-runtime.worker.esm.js",
- "browser": "./jsx-runtime/dist/emotion-react-jsx-runtime.browser.esm.js",
- "default": "./jsx-runtime/dist/emotion-react-jsx-runtime.esm.js"
+ "types": {
+ "import": "./jsx-runtime/dist/emotion-react-jsx-runtime.cjs.mjs",
+ "default": "./jsx-runtime/dist/emotion-react-jsx-runtime.cjs.js"
+ },
+ "development": {
+ "edge-light": {
+ "module": "./jsx-runtime/dist/emotion-react-jsx-runtime.development.edge-light.esm.js",
+ "import": "./jsx-runtime/dist/emotion-react-jsx-runtime.development.edge-light.cjs.mjs",
+ "default": "./jsx-runtime/dist/emotion-react-jsx-runtime.development.edge-light.cjs.js"
+ },
+ "worker": {
+ "module": "./jsx-runtime/dist/emotion-react-jsx-runtime.development.edge-light.esm.js",
+ "import": "./jsx-runtime/dist/emotion-react-jsx-runtime.development.edge-light.cjs.mjs",
+ "default": "./jsx-runtime/dist/emotion-react-jsx-runtime.development.edge-light.cjs.js"
+ },
+ "workerd": {
+ "module": "./jsx-runtime/dist/emotion-react-jsx-runtime.development.edge-light.esm.js",
+ "import": "./jsx-runtime/dist/emotion-react-jsx-runtime.development.edge-light.cjs.mjs",
+ "default": "./jsx-runtime/dist/emotion-react-jsx-runtime.development.edge-light.cjs.js"
+ },
+ "browser": {
+ "module": "./jsx-runtime/dist/emotion-react-jsx-runtime.browser.development.esm.js",
+ "import": "./jsx-runtime/dist/emotion-react-jsx-runtime.browser.development.cjs.mjs",
+ "default": "./jsx-runtime/dist/emotion-react-jsx-runtime.browser.development.cjs.js"
+ },
+ "module": "./jsx-runtime/dist/emotion-react-jsx-runtime.development.esm.js",
+ "import": "./jsx-runtime/dist/emotion-react-jsx-runtime.development.cjs.mjs",
+ "default": "./jsx-runtime/dist/emotion-react-jsx-runtime.development.cjs.js"
+ },
+ "edge-light": {
+ "module": "./jsx-runtime/dist/emotion-react-jsx-runtime.edge-light.esm.js",
+ "import": "./jsx-runtime/dist/emotion-react-jsx-runtime.edge-light.cjs.mjs",
+ "default": "./jsx-runtime/dist/emotion-react-jsx-runtime.edge-light.cjs.js"
+ },
+ "worker": {
+ "module": "./jsx-runtime/dist/emotion-react-jsx-runtime.edge-light.esm.js",
+ "import": "./jsx-runtime/dist/emotion-react-jsx-runtime.edge-light.cjs.mjs",
+ "default": "./jsx-runtime/dist/emotion-react-jsx-runtime.edge-light.cjs.js"
},
+ "workerd": {
+ "module": "./jsx-runtime/dist/emotion-react-jsx-runtime.edge-light.esm.js",
+ "import": "./jsx-runtime/dist/emotion-react-jsx-runtime.edge-light.cjs.mjs",
+ "default": "./jsx-runtime/dist/emotion-react-jsx-runtime.edge-light.cjs.js"
+ },
+ "browser": {
+ "module": "./jsx-runtime/dist/emotion-react-jsx-runtime.browser.esm.js",
+ "import": "./jsx-runtime/dist/emotion-react-jsx-runtime.browser.cjs.mjs",
+ "default": "./jsx-runtime/dist/emotion-react-jsx-runtime.browser.cjs.js"
+ },
+ "module": "./jsx-runtime/dist/emotion-react-jsx-runtime.esm.js",
"import": "./jsx-runtime/dist/emotion-react-jsx-runtime.cjs.mjs",
"default": "./jsx-runtime/dist/emotion-react-jsx-runtime.cjs.js"
},
"./_isolated-hnrs": {
- "module": {
- "worker": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.worker.esm.js",
- "browser": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.browser.esm.js",
- "default": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.esm.js"
+ "types": {
+ "import": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.cjs.mjs",
+ "default": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.cjs.js"
},
+ "development": {
+ "edge-light": {
+ "module": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.development.edge-light.esm.js",
+ "import": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.development.edge-light.cjs.mjs",
+ "default": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.development.edge-light.cjs.js"
+ },
+ "worker": {
+ "module": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.development.edge-light.esm.js",
+ "import": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.development.edge-light.cjs.mjs",
+ "default": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.development.edge-light.cjs.js"
+ },
+ "workerd": {
+ "module": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.development.edge-light.esm.js",
+ "import": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.development.edge-light.cjs.mjs",
+ "default": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.development.edge-light.cjs.js"
+ },
+ "browser": {
+ "module": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.browser.development.esm.js",
+ "import": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.browser.development.cjs.mjs",
+ "default": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.browser.development.cjs.js"
+ },
+ "module": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.development.esm.js",
+ "import": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.development.cjs.mjs",
+ "default": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.development.cjs.js"
+ },
+ "edge-light": {
+ "module": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.edge-light.esm.js",
+ "import": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.edge-light.cjs.mjs",
+ "default": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.edge-light.cjs.js"
+ },
+ "worker": {
+ "module": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.edge-light.esm.js",
+ "import": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.edge-light.cjs.mjs",
+ "default": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.edge-light.cjs.js"
+ },
+ "workerd": {
+ "module": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.edge-light.esm.js",
+ "import": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.edge-light.cjs.mjs",
+ "default": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.edge-light.cjs.js"
+ },
+ "browser": {
+ "module": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.browser.esm.js",
+ "import": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.browser.cjs.mjs",
+ "default": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.browser.cjs.js"
+ },
+ "module": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.esm.js",
"import": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.cjs.mjs",
"default": "./_isolated-hnrs/dist/emotion-react-_isolated-hnrs.cjs.js"
},
"./jsx-dev-runtime": {
- "module": {
- "worker": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.worker.esm.js",
- "browser": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.browser.esm.js",
- "default": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.esm.js"
+ "types": {
+ "import": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.cjs.mjs",
+ "default": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.cjs.js"
+ },
+ "development": {
+ "edge-light": {
+ "module": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.development.edge-light.esm.js",
+ "import": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.development.edge-light.cjs.mjs",
+ "default": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.development.edge-light.cjs.js"
+ },
+ "worker": {
+ "module": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.development.edge-light.esm.js",
+ "import": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.development.edge-light.cjs.mjs",
+ "default": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.development.edge-light.cjs.js"
+ },
+ "workerd": {
+ "module": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.development.edge-light.esm.js",
+ "import": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.development.edge-light.cjs.mjs",
+ "default": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.development.edge-light.cjs.js"
+ },
+ "browser": {
+ "module": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.browser.development.esm.js",
+ "import": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.browser.development.cjs.mjs",
+ "default": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.browser.development.cjs.js"
+ },
+ "module": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.development.esm.js",
+ "import": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.development.cjs.mjs",
+ "default": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.development.cjs.js"
},
+ "edge-light": {
+ "module": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.edge-light.esm.js",
+ "import": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.edge-light.cjs.mjs",
+ "default": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.edge-light.cjs.js"
+ },
+ "worker": {
+ "module": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.edge-light.esm.js",
+ "import": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.edge-light.cjs.mjs",
+ "default": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.edge-light.cjs.js"
+ },
+ "workerd": {
+ "module": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.edge-light.esm.js",
+ "import": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.edge-light.cjs.mjs",
+ "default": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.edge-light.cjs.js"
+ },
+ "browser": {
+ "module": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.browser.esm.js",
+ "import": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.browser.cjs.mjs",
+ "default": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.browser.cjs.js"
+ },
+ "module": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.esm.js",
"import": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.cjs.mjs",
"default": "./jsx-dev-runtime/dist/emotion-react-jsx-dev-runtime.cjs.js"
},
@@ -53,6 +230,19 @@
"default": "./macro.js"
}
},
+ "imports": {
+ "#is-development": {
+ "development": "./src/conditions/true.js",
+ "default": "./src/conditions/false.js"
+ },
+ "#is-browser": {
+ "edge-light": "./src/conditions/false.js",
+ "workerd": "./src/conditions/false.js",
+ "worker": "./src/conditions/false.js",
+ "browser": "./src/conditions/true.js",
+ "default": "./src/conditions/is-browser.js"
+ }
+ },
"types": "types/index.d.ts",
"files": [
"src",
@@ -71,12 +261,12 @@
},
"dependencies": {
"@babel/runtime": "^7.18.3",
- "@emotion/babel-plugin": "^11.11.0",
- "@emotion/cache": "^11.11.0",
- "@emotion/serialize": "^1.1.3",
- "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1",
- "@emotion/utils": "^1.2.1",
- "@emotion/weak-memoize": "^0.3.1",
+ "@emotion/babel-plugin": "^11.12.0",
+ "@emotion/cache": "^11.13.0",
+ "@emotion/serialize": "^1.3.0",
+ "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0",
+ "@emotion/utils": "^1.4.0",
+ "@emotion/weak-memoize": "^0.4.0",
"hoist-non-react-statics": "^3.3.1"
},
"peerDependencies": {
@@ -89,14 +279,14 @@
},
"devDependencies": {
"@definitelytyped/dtslint": "0.0.112",
- "@emotion/css": "11.11.2",
- "@emotion/css-prettifier": "1.1.3",
+ "@emotion/css": "11.13.0",
+ "@emotion/css-prettifier": "1.1.4",
"@emotion/server": "11.11.0",
- "@emotion/styled": "11.11.0",
+ "@emotion/styled": "11.13.0",
"html-tag-names": "^1.1.2",
"react": "16.14.0",
"svg-tag-names": "^1.1.1",
- "typescript": "^4.5.5"
+ "typescript": "^5.4.5"
},
"repository": "https://github.com/emotion-js/emotion/tree/main/packages/react",
"publishConfig": {
@@ -112,10 +302,6 @@
],
"umdName": "emotionReact",
"exports": {
- "envConditions": [
- "browser",
- "worker"
- ],
"extra": {
"./types/css-prop": "./types/css-prop.d.ts",
"./macro": {
diff --git a/packages/react/src/class-names.js b/packages/react/src/class-names.js
index 6252324f22..c5b35276cb 100644
--- a/packages/react/src/class-names.js
+++ b/packages/react/src/class-names.js
@@ -1,4 +1,3 @@
-// @flow
import * as React from 'react'
import {
getRegisteredStyles,
@@ -6,11 +5,13 @@ import {
registerStyles
} from '@emotion/utils'
import { serializeStyles } from '@emotion/serialize'
+import isDevelopment from '#is-development'
import { withEmotionCache } from './context'
import { ThemeContext } from './theming'
import { useInsertionEffectAlwaysWithSyncFallback } from '@emotion/use-insertion-effect-with-fallbacks'
-import { isBrowser } from './utils'
+import isBrowser from '#is-browser'
+/*
type ClassNameArg =
| string
| boolean
@@ -18,8 +19,9 @@ type ClassNameArg =
| Array
| null
| void
+*/
-let classnames = (args: Array): string => {
+let classnames = (args /*: Array */) /*: string */ => {
let len = args.length
let i = 0
let cls = ''
@@ -36,7 +38,7 @@ let classnames = (args: Array): string => {
toAdd = classnames(arg)
} else {
if (
- process.env.NODE_ENV !== 'production' &&
+ isDevelopment &&
arg.styles !== undefined &&
arg.name !== undefined
) {
@@ -67,9 +69,9 @@ let classnames = (args: Array): string => {
return cls
}
function merge(
- registered: Object,
- css: (...args: Array) => string,
- className: string
+ registered /*: Object */,
+ css /*: (...args: Array) => string */,
+ className /*: string */
) {
const registeredStyles = []
@@ -85,14 +87,6 @@ function merge(
return rawClassName + css(registeredStyles)
}
-type Props = {
- children: ({
- css: (...args: any) => string,
- cx: (...args: Array) => string,
- theme: Object
- }) => React.Node
-}
-
const Insertion = ({ cache, serializedArr }) => {
let rules = useInsertionEffectAlwaysWithSyncFallback(() => {
let rules = ''
@@ -123,13 +117,22 @@ const Insertion = ({ cache, serializedArr }) => {
return null
}
-export const ClassNames: React.AbstractComponent =
+/*
+type Props = {
+ children: ({
+ css: (...args: any) => string,
+ cx: (...args: Array) => string,
+ theme: Object
+ }) => React.Node
+} */
+
+export const ClassNames /*: React.AbstractComponent*/ =
/* #__PURE__ */ withEmotionCache((props, cache) => {
let hasRendered = false
let serializedArr = []
- let css = (...args: Array) => {
- if (hasRendered && process.env.NODE_ENV !== 'production') {
+ let css = (...args /*: Array */) => {
+ if (hasRendered && isDevelopment) {
throw new Error('css can only be used during render')
}
@@ -139,8 +142,8 @@ export const ClassNames: React.AbstractComponent =
registerStyles(cache, serialized, false)
return `${cache.key}-${serialized.name}`
}
- let cx = (...args: Array) => {
- if (hasRendered && process.env.NODE_ENV !== 'production') {
+ let cx = (...args /*: Array*/) => {
+ if (hasRendered && isDevelopment) {
throw new Error('cx can only be used during render')
}
return merge(cache.registered, css, classnames(args))
@@ -161,6 +164,6 @@ export const ClassNames: React.AbstractComponent =
)
})
-if (process.env.NODE_ENV !== 'production') {
+if (isDevelopment) {
ClassNames.displayName = 'EmotionClassNames'
}
diff --git a/packages/react/src/conditions/false.js b/packages/react/src/conditions/false.js
new file mode 100644
index 0000000000..2693369b44
--- /dev/null
+++ b/packages/react/src/conditions/false.js
@@ -0,0 +1 @@
+export default false
diff --git a/packages/react/src/conditions/is-browser.js b/packages/react/src/conditions/is-browser.js
new file mode 100644
index 0000000000..12bdad68fc
--- /dev/null
+++ b/packages/react/src/conditions/is-browser.js
@@ -0,0 +1 @@
+export default typeof document !== 'undefined'
diff --git a/packages/react/src/conditions/true.js b/packages/react/src/conditions/true.js
new file mode 100644
index 0000000000..186b120756
--- /dev/null
+++ b/packages/react/src/conditions/true.js
@@ -0,0 +1 @@
+export default true
diff --git a/packages/react/src/context.js b/packages/react/src/context.js
index e74d4de212..533e7e3b8b 100644
--- a/packages/react/src/context.js
+++ b/packages/react/src/context.js
@@ -1,11 +1,11 @@
-// @flow
-import { type EmotionCache } from '@emotion/utils'
+/* import { type EmotionCache } from '@emotion/utils' */
import * as React from 'react'
import { useContext, forwardRef } from 'react'
import createCache from '@emotion/cache'
-import { isBrowser } from './utils'
+import isDevelopment from '#is-development'
+import isBrowser from '#is-browser'
-let EmotionCacheContext: React.Context =
+let EmotionCacheContext /*: React.Context */ =
/* #__PURE__ */ React.createContext(
// we're doing this to avoid preconstruct's dead code elimination in this one case
// because this module is primarily intended for the browser and node
@@ -18,34 +18,34 @@ let EmotionCacheContext: React.Context =
: null
)
-if (process.env.NODE_ENV !== 'production') {
+if (isDevelopment) {
EmotionCacheContext.displayName = 'EmotionCacheContext'
}
export let CacheProvider = EmotionCacheContext.Provider
export let __unsafe_useEmotionCache =
- function useEmotionCache(): EmotionCache | null {
+ function useEmotionCache() /*: EmotionCache | null*/ {
return useContext(EmotionCacheContext)
}
-let withEmotionCache = function withEmotionCache>(
- func: (props: Props, cache: EmotionCache, ref: Ref) => React.Node
-): React.AbstractComponent {
- // $FlowFixMe
- return forwardRef((props: Props, ref: Ref) => {
- // the cache will never be null in the browser
- let cache = ((useContext(EmotionCacheContext): any): EmotionCache)
+let withEmotionCache =
+ function withEmotionCache /* > */(
+ func /*: (props: Props, cache: EmotionCache, ref: Ref) => React.Node */
+ ) /*: React.AbstractComponent */ {
+ return forwardRef((props /*: Props */, ref /*: Ref */) => {
+ // the cache will never be null in the browser
+ let cache = useContext(EmotionCacheContext)
- return func(props, cache, ref)
- })
-}
+ return func(props, cache, ref)
+ })
+ }
if (!isBrowser) {
- withEmotionCache = function withEmotionCache(
- func: (props: Props, cache: EmotionCache) => React.Node
- ): React.StatelessFunctionalComponent {
- return (props: Props) => {
+ withEmotionCache = function withEmotionCache /* */(
+ func /*: (props: Props, cache: EmotionCache) => React.Node */
+ ) /*: React.StatelessFunctionalComponent */ {
+ return (props /*: Props */) => {
let cache = useContext(EmotionCacheContext)
if (cache === null) {
// yes, we're potentially creating this on every render
diff --git a/packages/react/src/css.js b/packages/react/src/css.js
index ac79c1dfa3..785320e8f1 100644
--- a/packages/react/src/css.js
+++ b/packages/react/src/css.js
@@ -1,9 +1,7 @@
-// @flow
-
-import type { Interpolation, SerializedStyles } from '@emotion/utils'
+/* import type { Interpolation, SerializedStyles } from '@emotion/utils' */
import { serializeStyles } from '@emotion/serialize'
-function css(...args: Array): SerializedStyles {
+function css(...args /*: Array */) /*: SerializedStyles */ {
return serializeStyles(args)
}
diff --git a/packages/react/src/emotion-element.js b/packages/react/src/emotion-element.js
index 0ae4c4b64c..abb2a70e53 100644
--- a/packages/react/src/emotion-element.js
+++ b/packages/react/src/emotion-element.js
@@ -1,4 +1,3 @@
-// @flow
import * as React from 'react'
import { withEmotionCache } from './context'
import { ThemeContext } from './theming'
@@ -7,8 +6,10 @@ import {
insertStyles,
registerStyles
} from '@emotion/utils'
-import { hasOwn, isBrowser } from './utils'
+import { hasOwn } from './utils'
import { serializeStyles } from '@emotion/serialize'
+import isDevelopment from '#is-development'
+import isBrowser from '#is-browser'
import { getLabelFromStackTrace } from './get-label-from-stack-trace'
import { useInsertionEffectAlwaysWithSyncFallback } from '@emotion/use-insertion-effect-with-fallbacks'
@@ -16,9 +17,12 @@ let typePropName = '__EMOTION_TYPE_PLEASE_DO_NOT_USE__'
let labelPropName = '__EMOTION_LABEL_PLEASE_DO_NOT_USE__'
-export const createEmotionProps = (type: React.ElementType, props: Object) => {
+export const createEmotionProps = (
+ type /*: React.ElementType */,
+ props /*: Object */
+) => {
if (
- process.env.NODE_ENV !== 'production' &&
+ isDevelopment &&
typeof props.css === 'string' &&
// check if there is a css declaration
props.css.indexOf(':') !== -1
@@ -28,7 +32,7 @@ export const createEmotionProps = (type: React.ElementType, props: Object) => {
)
}
- let newProps: any = {}
+ let newProps /*: any */ = {}
for (let key in props) {
if (hasOwn.call(props, key)) {
@@ -38,10 +42,16 @@ export const createEmotionProps = (type: React.ElementType, props: Object) => {
newProps[typePropName] = type
- // For performance, only call getLabelFromStackTrace in development and when
- // the label hasn't already been computed
+ // Runtime labeling is an opt-in feature because:
+ // - It causes hydration warnings when using Safari and SSR
+ // - It can degrade performance if there are a huge number of elements
+ //
+ // Even if the flag is set, we still don't compute the label if it has already
+ // been determined by the Babel plugin.
if (
- process.env.NODE_ENV !== 'production' &&
+ isDevelopment &&
+ typeof globalThis !== 'undefined' &&
+ !!globalThis.EMOTION_RUNTIME_AUTO_LABEL &&
!!props.css &&
(typeof props.css !== 'object' ||
typeof props.css.name !== 'string' ||
@@ -81,8 +91,8 @@ const Insertion = ({ cache, serialized, isStringTag }) => {
return null
}
-let Emotion = /* #__PURE__ */ withEmotionCache