From 4e1c94c9a7bb403e479aec60660ebe2ab1c94b27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Thu, 12 Nov 2020 01:19:28 +0100 Subject: [PATCH] Emotion 11 post (#2089) * Emotion 11 post * Apply suggestions from code review * Update docs/emotion-11.mdx * Fix docs build * update changeset file * Align changeset files to latest changes in the Emotion 11 post Co-authored-by: Mitchell Hamilton --- .changeset/angry-rats-type.md | 5 -- .changeset/four-cars-tell.md | 4 +- .changeset/gorgeous-steaks-report.md | 2 +- .changeset/long-apes-admire.md | 30 ++------ .changeset/moody-ravens-deny.md | 10 ++- .changeset/sweet-hotels-return.md | 2 +- .changeset/warm-ties-drop.md | 4 +- docs/docs.yaml | 6 +- docs/emotion-11.mdx | 108 +++++++++++++++++++++++++++ site/src/components/SiteHeader.js | 4 +- 10 files changed, 137 insertions(+), 38 deletions(-) delete mode 100644 .changeset/angry-rats-type.md create mode 100644 docs/emotion-11.mdx diff --git a/.changeset/angry-rats-type.md b/.changeset/angry-rats-type.md deleted file mode 100644 index c2f6bd774..000000000 --- a/.changeset/angry-rats-type.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@emotion/native': patch ---- - -Add type definitions to published files for NPM diff --git a/.changeset/four-cars-tell.md b/.changeset/four-cars-tell.md index 7294fa626..4c1d0afba 100644 --- a/.changeset/four-cars-tell.md +++ b/.changeset/four-cars-tell.md @@ -3,9 +3,11 @@ '@emotion/styled': major --- -Reworked TypeScript definitions so it's easier to provide a type for Theme. Instead of creating custom instances (like before) you can augment builtin Theme interface like this: +It's now easier to provide a type for `Theme`. Instead of creating custom instances (like before) you can augment the builtin `Theme` interface like this: ```ts +import '@emotion/react' + declare module '@emotion/react' { export interface Theme { primaryColor: string diff --git a/.changeset/gorgeous-steaks-report.md b/.changeset/gorgeous-steaks-report.md index 2df79ac6f..2ebd5d14d 100644 --- a/.changeset/gorgeous-steaks-report.md +++ b/.changeset/gorgeous-steaks-report.md @@ -3,4 +3,4 @@ '@emotion/sheet': minor --- -Accept new `prepend` option to allow for adding style tags at the beginning of the specified DOM container. +The new `prepend` option can make Emotion add style tags at the beginning of the specified DOM container instead of the end. diff --git a/.changeset/long-apes-admire.md b/.changeset/long-apes-admire.md index e4e398299..c4b21dcbe 100644 --- a/.changeset/long-apes-admire.md +++ b/.changeset/long-apes-admire.md @@ -3,27 +3,13 @@ '@emotion/styled': major --- -TypeScript types have been restructured. These changes: +TypeScript types have been significantly restructured. These changes: -- Reduce build times when using emotion -- In many cases remove the need for manually specifying generic parameters for your emotion components. +- reduce build times when using Emotion, especially in larger projects +- it's no longer necessary to manually specify generic parameters for your Emotion components in many cases +- union types as props are better supported and should be inferred properly +- the `css` function has been restricted to prevent passing invalid types +- `styled`'s generic parameter has been changed, if you were specifying the `ComponentType` you will need to remove that generic parameter +- `styled` no longer takes a second `ExtraProps` parameter - instead of that move it to after the `styled` call. So instead of writing `styled(MyComponent)({})` you should now be writing `styled(MyComponent)({})` -If you encounter build issues after upgrade, try removing any manually specified generic types and let them be inferred. Otherwise refer to the breaking changes list below. - -## Improvements - -- Union types as props are better supported and should be inferred properly -- Build times should be reduced significantly in larger projects. - -## Breaking changes - -- `withTheme` can now have the Theme type specified when calling it. For example `withTheme(MyComponent)` - - **Breaking change:** Generic argument changed, if you were specifying the ComponentType you will need to remove the generic parameter. Recommend following example setup in the TypeScript docs under theming section - -- `css` function has been restricted to prevent passing of invalid types -- `CreateStyled` functions no longer take a second `ExtraProps` argument. Instead move it to after the create styled call. For example - - `styled(MyComponent)({})` - to - `styled(MyComponent)({})` +If you encounter build issues after upgrade, try removing any manually specified generic types and let them be inferred. diff --git a/.changeset/moody-ravens-deny.md b/.changeset/moody-ravens-deny.md index 15cd7545e..87cb8de4f 100644 --- a/.changeset/moody-ravens-deny.md +++ b/.changeset/moody-ravens-deny.md @@ -2,12 +2,16 @@ '@emotion/react': patch --- -The way in which we provide TypeScript support for `css` prop has changed. Based on usage of our jsx pragma we are able to add support for `css` prop only for components that support `className` prop (as our `jsx` factory function takes provided `css` prop, resolves it and pass the generated `className` to the rendered component). This has been implemented using technique described [here](https://www.typescriptlang.org/docs/handbook/jsx.html#factory-functions). What is important - we no longer extend any global interfaces, so people shouldn't bump anymore into type conflicts for the `css` prop when using different libraries with the `css` prop support, such as `styled-components`. +The way in which we provide TypeScript support for the `css` prop has changed. Based on the usage of our JSX factories, we can add support for `css` prop only for components that support `className` prop (as our JSX factory functions take the provided `css` prop, resolve it and pass the generated `className` to the rendered component). -However, it's not possible to leverage `css` prop support being added conditionally based on a type of rendered component when one is not using our jsx pragma. For those cases when people use our pragma implicitly (for example when using our `@emotion/babel-preset-css-prop`) we have added special file that can be imported once to add support for the `css` prop globally, for all components. Use it like this: +For the classic runtime this has been implemented using technique described [here](https://www.typescriptlang.org/docs/handbook/jsx.html#factory-functions). What is important - we no longer extend any global interfaces, so people shouldn't bump anymore into type conflicts for the `css` prop when using different libraries with `css` prop support, such as `styled-components`. + +For the automatic runtime this has been implemented by exporting `JSX` namespace from the appropriate entries but this is only supported in **TypeScript 4.1 or higher**. + +However, if you are stuck with older version of TypeScript or using the classic runtime implicitly by using our `@emotion/babel-preset-css-prop` then it's not possible to leverage leverage `css` prop support being added conditionally based on a type of rendered component. For those cases we have added a special file that can be imported once to add support for the `css` prop globally, for all components. Use it like this: ```ts -import {} from '@emotion/react/types/css-prop' +/// ``` In this particular case we are forced to extend the existing `React.Attributes` interface. Previously we've been extending both `React.DOMAttributes` and `JSX.IntrinsicAttributes`. This change is really minor and shouldn't affect any consuming code. diff --git a/.changeset/sweet-hotels-return.md b/.changeset/sweet-hotels-return.md index a277b80d4..5494a366c 100644 --- a/.changeset/sweet-hotels-return.md +++ b/.changeset/sweet-hotels-return.md @@ -2,4 +2,4 @@ '@emotion/css': major --- -From now on `key` option is required when creating a custom instance. Please make sure it's unique (and not equal to `"css"`) as it's used for linking styles to your cache. If multiple caches share the same key they might "fight" for each other's style elements. +The `key` option is now required when creating a custom instance of a cache. Please make sure it's unique (and not equal to `'css'`) as it's used for linking styles to your cache. If multiple caches share the same key they might "fight" for each other's style elements. diff --git a/.changeset/warm-ties-drop.md b/.changeset/warm-ties-drop.md index e2d73d2ea..c80928b0d 100644 --- a/.changeset/warm-ties-drop.md +++ b/.changeset/warm-ties-drop.md @@ -7,9 +7,9 @@ The parser we use ([Stylis](https://github.com/thysultan/stylis.js)) got upgraded. It fixes some long-standing parsing edge cases while being smaller and faster 🚀 -It has been completely rewritten and comes with some breaking changes. Most notable ones that might affect Emotion users are: +It has been completely rewritten and comes with some breaking changes. The most notable ones that might affect Emotion users are: - plugins written for the former Stylis v3 are not compatible with the new version. To learn more on how to write a plugin for Stylis v4 you can check out its [README](https://github.com/thysultan/stylis.js#middleware) and the source code of core plugins. - vendor-prefixing was previously customizable using `prefix` option. This was always limited to turning off all of some of the prefixes as all available prefixes were on by default. The `prefix` option is gone and to customize which prefixes are applied you need to fork (copy-paste) the prefixer plugin and adjust it to your needs. While this being somewhat more problematic to setup at first we believe that the vast majority of users were not customizing this anyway. By not including the possibility to customize this through an extra option the final solution is more performant because there is no extra overhead of checking if a particular property should be prefixed or not. -- Prefixer is now just a plugin which happens to be put in default `stylisPlugins`. If you plan to use custom `stylisPlugins` and you want to have your styles prefixed automatically you must include prefixer in your custom `stylisPlugins`. You can import `prefixer` from the `stylis` module to do that. +- the prefixer is now just a plugin which happens to be included in the default `stylisPlugins`. If you plan to use custom `stylisPlugins` and you want to have your styles prefixed automatically you must include prefixer in your custom `stylisPlugins`. You can import `prefixer` from the `stylis` module to do that. - `@import` rules are no longer special-cased. The responsibility to put them first has been moved to the author of the styles. They also can't be nested within other rules now. It's only possible to write them at the top level of global styles. diff --git a/docs/docs.yaml b/docs/docs.yaml index df6539607..b105ffae6 100644 --- a/docs/docs.yaml +++ b/docs/docs.yaml @@ -20,7 +20,6 @@ - labels - class-names - cache-provider - - migrating-to-emotion-10 #- benchmarks - title: Tooling @@ -46,3 +45,8 @@ - '@emotion/native' - '@emotion/primitives' - '@emotion/babel-preset-css-prop' + +- title: Posts + items: + - emotion-11 + - migrating-to-emotion-10 diff --git a/docs/emotion-11.mdx b/docs/emotion-11.mdx new file mode 100644 index 000000000..c22a2c3c8 --- /dev/null +++ b/docs/emotion-11.mdx @@ -0,0 +1,108 @@ +--- +title: 'Emotion 11' +--- + +Emotion 11 is a slight evolution over the Emotion 10. It focuses mainly on the developer experience, TS types improvements, switches internals to hooks and to the new version of the parser that we use: [Stylis](https://github.com/thysultan/stylis.js). + +# Package renaming + +One of the most significant changes is that most of the user-facing packages have been renamed: +- `@emotion/core` → `@emotion/react` +- `emotion` → `@emotion/css` +- `emotion-theming` → moved into ` @emotion/react` +- `emotion-server` → `@emotion/server` +- `create-emotion` → `@emotion/css/create-instance` +- `create-emotion-server` → `@emotion/server/create-instance` +- `babel-plugin-emotion` → `@emotion/babel-plugin` +- `eslint-plugin-emotion` → `@emotion/eslint-plugin` +- `jest-emotion` → `@emotion/jest` + +Most of this renaming can be done automatically via a codemod by running the `@emotion/pkg-renaming` rule from `@emotion/eslint-plugin` with `--fix` over your codebase. + +# Hooks + +Use hooks internally for improved bundle size and a better tree in React DevTools 🎉. + +# TypeScript + +## Types overhaul + +TypeScript types have been significantly restructured. + +- reduce build times when using Emotion, especially in larger projects +- it's no longer necessary to manually specify generic parameters for your Emotion components in many cases +- union types as props are better supported and should be inferred properly +- the `css` function has been restricted to prevent passing invalid types +- `styled`'s generic parameter has been changed, if you were specifying the `ComponentType` you will need to remove that generic parameter +- `styled` no longer takes a second `ExtraProps` parameter - instead of that move it to after the `styled` call. So instead of writing `styled(MyComponent)({})` you should now be writing `styled(MyComponent)({})` + +If you encounter build issues after upgrade, try removing any manually specified generic types and let them be inferred. + +## Theme type + +It's now easier to provide a type for `Theme`. Instead of creating custom instances (like before) you can augment the builtin `Theme` interface like this: + +```ts +import '@emotion/react' + +declare module '@emotion/react' { + export interface Theme { + primaryColor: string + secondaryColor: string + } +} +``` + +## css prop types + +The way in which we provide TypeScript support for the `css` prop has changed. Based on the usage of our JSX factories, we can add support for `css` prop only for components that support `className` prop (as our JSX factory functions take the provided `css` prop, resolve it and pass the generated `className` to the rendered component). + +For the classic runtime this has been implemented using technique described [here](https://www.typescriptlang.org/docs/handbook/jsx.html#factory-functions). What is important - we no longer extend any global interfaces, so people shouldn't bump anymore into type conflicts for the `css` prop when using different libraries with `css` prop support, such as `styled-components`. + +For the automatic runtime this has been implemented by exporting `JSX` namespace from the appropriate entries but this is only supported in **TypeScript 4.1 or higher**. + +However, if you are stuck with older version of TypeScript or using the classic runtime implicitly by using our `@emotion/babel-preset-css-prop` then it's not possible to leverage leverage `css` prop support being added conditionally based on a type of rendered component. For those cases we have added a special file that can be imported once to add support for the `css` prop globally, for all components. Use it like this: + +```ts +/// +``` + +In this particular case we are forced to extend the existing `React.Attributes` interface. Previously we've been extending both `React.DOMAttributes` and `JSX.IntrinsicAttributes`. This change is really minor and shouldn't affect any consuming code. + +# Stylis v4 + +The parser we use ([Stylis](https://github.com/thysultan/stylis.js)) got upgraded. It fixes some long-standing parsing edge cases while being smaller and faster 🚀 + +It has been completely rewritten and comes with some breaking changes. The most notable ones that might affect Emotion users are: + +- plugins written for the former Stylis v3 are not compatible with the new version. To learn more on how to write a plugin for Stylis v4 you can check out its [README](https://github.com/thysultan/stylis.js#middleware) and the source code of core plugins. +- vendor-prefixing was previously customizable using `prefix` option. This was always limited to turning off all of some of the prefixes as all available prefixes were on by default. The `prefix` option is gone and to customize which prefixes are applied you need to fork (copy-paste) the prefixer plugin and adjust it to your needs. While this being somewhat more problematic to setup at first we believe that the vast majority of users were not customizing this anyway. By not including the possibility to customize this through an extra option the final solution is more performant because there is no extra overhead of checking if a particular property should be prefixed or not. +- the prefixer is now just a plugin which happens to be included in the default `stylisPlugins`. If you plan to use custom `stylisPlugins` and you want to have your styles prefixed automatically you must include prefixer in your custom `stylisPlugins`. You can import `prefixer` from the `stylis` module to do that. +- `@import` rules are no longer special-cased. The responsibility to put them first has been moved to the author of the styles. They also can't be nested within other rules now. It's only possible to write them at the top level of global styles. + +# Emotion's caches + +The `key` option is now required when creating a custom instance of a cache. Please make sure it's unique (and not equal to `'css'`) as it's used for linking styles to your cache. If multiple caches share the same key they might "fight" for each other's style elements. + +The new `prepend` option can make Emotion add style tags at the beginning of the specified DOM container instead of the end. + +# Other + +There are a lot of less substantial changes than what has been described here, some of them might even be breaking changes but are not relevant to the majority of users. Therefore to learn more about all of the changes please read through the full list of changes contained in the respective changelogs: + +[`@emotion/babel-plugin`](https://github.com/emotion-js/emotion/blob/master/packages/babel-plugin/CHANGELOG.md#1100) +[`@emotion/babel-preset-css-prop`](https://github.com/emotion-js/emotion/blob/master/packages/babel-preset-css-prop/CHANGELOG.md#1100) +[`@emotion/cache`](https://github.com/emotion-js/emotion/blob/master/packages/cache/CHANGELOG.md#1100) +[`@emotion/css`](https://github.com/emotion-js/emotion/blob/master/packages/css/CHANGELOG.md#1100) +[`@emotion/eslint-plugin`](https://github.com/emotion-js/emotion/blob/master/packages/eslint-plugin/CHANGELOG.md#1100) +[`@emotion/is-prop-valid`](https://github.com/emotion-js/emotion/blob/master/packages/is-prop-valid/CHANGELOG.md#100) +[`@emotion/jest`](https://github.com/emotion-js/emotion/blob/master/packages/jest/CHANGELOG.md#1100) +[`@emotion/native`](https://github.com/emotion-js/emotion/blob/master/packages/native/CHANGELOG.md#1100) +[`@emotion/primitives-core`](https://github.com/emotion-js/emotion/blob/master/packages/primitives-core/CHANGELOG.md#1100) +[`@emotion/primitives`](https://github.com/emotion-js/emotion/blob/master/packages/primitives/CHANGELOG.md#1100) +[`@emotion/react`](https://github.com/emotion-js/emotion/blob/master/packages/react/CHANGELOG.md#1100) +[`@emotion/serialize`](https://github.com/emotion-js/emotion/blob/master/packages/serialize/CHANGELOG.md#100) +[`@emotion/server`](https://github.com/emotion-js/emotion/blob/master/packages/server/CHANGELOG.md#1100) +[`@emotion/sheet`](https://github.com/emotion-js/emotion/blob/master/packages/sheet/CHANGELOG.md#100) +[`@emotion/styled`](https://github.com/emotion-js/emotion/blob/master/packages/styled/CHANGELOG.md#1100) +[`@emotion/utils`](https://github.com/emotion-js/emotion/blob/master/packages/utils/CHANGELOG.md#100) diff --git a/site/src/components/SiteHeader.js b/site/src/components/SiteHeader.js index 621ca29c1..5bcc857e8 100644 --- a/site/src/components/SiteHeader.js +++ b/site/src/components/SiteHeader.js @@ -154,8 +154,8 @@ export default function SiteHeader() {
  • - - v9 Docs + + v10 Docs