diff --git a/BREAKING_CHANGES_IN_V10.md b/BREAKING_CHANGES_IN_V10.md index 85221e83f..6ed4cf3cb 100644 --- a/BREAKING_CHANGES_IN_V10.md +++ b/BREAKING_CHANGES_IN_V10.md @@ -1,12 +1,12 @@ # Breaking Changes -* Only supports react@16.3 and above(+ preact) -* functions in interpolations are stringified in css and cx calls(probably won't affect you very much, there's a warning about it in v9) -* `create-emotion-styled` is gone, use the new styled api and a provider -* The css prop doesn't work via the babel plugin. `jsx` can be manually imported from `@emotion/core` or [babel-plugin-jsx-pragmatic](https://github.com/jmm/babel-plugin-jsx-pragmatic) can be used. (should we make a babel preset for that?) -* MORE STUFF THAT I CAN'T REMEMBER RIGHT NOW -* emotion will not be stored on the global object so create-emotion only accepts 1 argument, the options -* channel and createBroadcast from emotion-theming no longer exist -* extractStatic is gone -* create-emotion-server accepts the cache instead of the emotion instance -* jest-emotion no longer accepts an emotion instance, only the options arg, it also requires a DOM now +- Only supports react@16.3 and above(+ preact) +- functions in interpolations are stringified in css and cx calls(probably won't affect you very much, there's a warning about it in v9) +- `create-emotion-styled` is gone, use the new styled api and a provider +- The css prop doesn't work via the babel plugin. `jsx` can be manually imported from `@emotion/core` or [babel-plugin-jsx-pragmatic](https://github.com/jmm/babel-plugin-jsx-pragmatic) can be used. (should we make a babel preset for that?) +- MORE STUFF THAT I CAN'T REMEMBER RIGHT NOW +- emotion will not be stored on the global object so create-emotion only accepts 1 argument, the options +- channel and createBroadcast from emotion-theming no longer exist +- extractStatic is gone +- create-emotion-server accepts the cache instead of the emotion instance +- jest-emotion no longer accepts an emotion instance, only the options arg, it also requires a DOM now diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3f136b72f..1383ca30b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,12 +1,12 @@ ## Prerequisites -* [Node.js](http://nodejs.org/) >= v7 must be installed. -* [Yarn](https://yarnpkg.com/en/docs/install) +- [Node.js](http://nodejs.org/) >= v7 must be installed. +- [Yarn](https://yarnpkg.com/en/docs/install) ## Installation -* Run `yarn` in the repository's root directory to install everything you need for development. -* Run `yarn build` in the root directory to build the modules. +- Run `yarn` in the repository's root directory to install everything you need for development. +- Run `yarn build` in the root directory to build the modules. > NOTE: > @@ -14,18 +14,18 @@ ## Running Tests -* `yarn test` will run the tests once. -* `yarn coverage` will run the tests and produce a coverage report in `coverage/`. -* `yarn test:watch` will run the tests on every change. +- `yarn test` will run the tests once. +- `yarn coverage` will run the tests and produce a coverage report in `coverage/`. +- `yarn test:watch` will run the tests on every change. ## Building -* Run `yarn build` in the root directory to build the modules. (Required before publishing) -* Run `yarn build PACKAGE_NAME ANOTHER_PACKAGE_NAME` to only build certain packages. -* Run `yarn build:watch` to build packages on every change. +- Run `yarn build` in the root directory to build the modules. (Required before publishing) +- Run `yarn build PACKAGE_NAME ANOTHER_PACKAGE_NAME` to only build certain packages. +- Run `yarn build:watch` to build packages on every change. ## Documentation Website Development -* Run above installation steps and then -* Run `yarn start:site` to run a development server of gatsby. -* Run `yarn build:site` to create a build of the assets for the documentation website. +- Run above installation steps and then +- Run `yarn start:site` to run a development server of gatsby. +- Run `yarn build:site` to create a build of the assets for the documentation website. diff --git a/README.md b/README.md index 2a462e69d..eda3bd2ba 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,6 @@ **Emotion 10 is currently in beta, there are many breaking changes between versions, [for docs on Emotion 9 please go to the latest v9 tag](https://github.com/emotion-js/emotion/tree/v9.2.12/docs) or https://emotion.sh** - [![Backers on Open Collective](https://opencollective.com/emotion/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/emotion/sponsors/badge.svg)](#sponsors) [![npm version](https://badge.fury.io/js/emotion.svg)](https://badge.fury.io/js/emotion) [![Build Status](https://img.shields.io/circleci/project/github/emotion-js/emotion/master.svg)](https://circleci.com/gh/emotion-js/emotion) [![codecov](https://codecov.io/gh/emotion-js/emotion/branch/master/graph/badge.svg)](https://codecov.io/gh/emotion-js/emotion) @@ -25,13 +24,13 @@ Emotion is a performant and flexible CSS-in-JS library. Building on many other C Frequently viewed docs: -* [Introduction](https://emotion.sh/docs/introduction) -* [Install](https://emotion.sh/docs/install) -* [CSS](https://emotion.sh/docs/css) -* [Styled Components](https://emotion.sh/docs/styled) -* [Composition](https://emotion.sh/docs/composition) -* [Nested Selectors](https://emotion.sh/docs/nested) -* [Media Queries](https://emotion.sh/docs/media-queries) +- [Introduction](https://emotion.sh/docs/introduction) +- [Install](https://emotion.sh/docs/install) +- [CSS](https://emotion.sh/docs/css) +- [Styled Components](https://emotion.sh/docs/styled) +- [Composition](https://emotion.sh/docs/composition) +- [Nested Selectors](https://emotion.sh/docs/nested) +- [Media Queries](https://emotion.sh/docs/media-queries) ### Quick Start @@ -87,36 +86,36 @@ Look here 👉 _[emotion babel plugin feature table and documentation](https://g ### Examples -* [emotion website](site) [[Demo Here](https://emotion.sh)] -* [next-hnpwa-guide-kit](https://github.com/tkh44/next-hnpwa-guide-kit) [[Demo Here](https://hnpwa.life)] -* [reactivesearch](https://github.com/appbaseio/reactivesearch), a react UI library for Elasticsearch [[Website](https://opensource.appbase.io/reactivesearch/)] -* [circuit-ui](https://github.com/sumup/circuit-ui), a react component library built at SumUp [[Storybook](https://sumup.github.io/circuit-ui/)] -* [govuk-react](https://github.com/penx/govuk-react/), a React component library built for UK Government departments -* **open a PR and add yours!** +- [emotion website](site) [[Demo Here](https://emotion.sh)] +- [next-hnpwa-guide-kit](https://github.com/tkh44/next-hnpwa-guide-kit) [[Demo Here](https://hnpwa.life)] +- [reactivesearch](https://github.com/appbaseio/reactivesearch), a react UI library for Elasticsearch [[Website](https://opensource.appbase.io/reactivesearch/)] +- [circuit-ui](https://github.com/sumup/circuit-ui), a react component library built at SumUp [[Storybook](https://sumup.github.io/circuit-ui/)] +- [govuk-react](https://github.com/penx/govuk-react/), a React component library built for UK Government departments +- **open a PR and add yours!** ### Ecosystem -* [stylelint](https://github.com/stylelint/stylelint) - A mighty, modern linter that helps you avoid errors and enforce conventions in your styles. -* [facepaint](https://github.com/emotion-js/facepaint) -* [emotion-vue](https://github.com/egoist/emotion-vue) -* [ember-emotion](https://github.com/alexlafroscia/ember-emotion) -* [CSS to emotion transform](https://transform.now.sh/css-to-emotion/) -* [ShevyJS](https://github.com/kyleshevlin/shevyjs) -* [design-system-utils](https://github.com/mrmartineau/design-system-utils) - Utilities to give better access to your design system. -* [polished](https://github.com/styled-components/polished) - Lightweight set of Sass/Compass-style mixins/helpers for writing styles in JavaScript. +- [stylelint](https://github.com/stylelint/stylelint) - A mighty, modern linter that helps you avoid errors and enforce conventions in your styles. +- [facepaint](https://github.com/emotion-js/facepaint) +- [emotion-vue](https://github.com/egoist/emotion-vue) +- [ember-emotion](https://github.com/alexlafroscia/ember-emotion) +- [CSS to emotion transform](https://transform.now.sh/css-to-emotion/) +- [ShevyJS](https://github.com/kyleshevlin/shevyjs) +- [design-system-utils](https://github.com/mrmartineau/design-system-utils) - Utilities to give better access to your design system. +- [polished](https://github.com/styled-components/polished) - Lightweight set of Sass/Compass-style mixins/helpers for writing styles in JavaScript. ### In the Wild -* [healthline.com](https://www.healthline.com) -* [nytimes.com](https://www.nytimes.com) -* [vault.crucible.gg](http://vault.crucible.gg/) -* [saldotuc.com](https://saldotuc.com) -* [gatsbythemes.com](https://gatsbythemes.com/) -* [blazity.com](https://blazity.com/) -* [postmates.com](https://postmates.com/) -* [thedisconnect.co](https://thedisconnect.co/one) -* [zefenify.com](https://zefenify.com/about.html) -* [sentry.io](https://sentry.io) +- [healthline.com](https://www.healthline.com) +- [nytimes.com](https://www.nytimes.com) +- [vault.crucible.gg](http://vault.crucible.gg/) +- [saldotuc.com](https://saldotuc.com) +- [gatsbythemes.com](https://gatsbythemes.com/) +- [blazity.com](https://blazity.com/) +- [postmates.com](https://postmates.com/) +- [thedisconnect.co](https://thedisconnect.co/one) +- [zefenify.com](https://zefenify.com/about.html) +- [sentry.io](https://sentry.io) ## Contributors diff --git a/docs/babel.md b/docs/babel.md index a0671b82d..23a9ce255 100644 --- a/docs/babel.md +++ b/docs/babel.md @@ -1,5 +1,5 @@ --- -title: "Babel Plugin" +title: 'Babel Plugin' --- `babel-plugin-emotion` is highly recommended. All of the options that can be provided to `babel-plugin-emotion` are documented in [`babel-plugin-emotion`'s README](https://github.com/emotion-js/emotion/tree/master/packages/babel-plugin-emotion). diff --git a/docs/class-names.md b/docs/class-names.md new file mode 100644 index 000000000..00febaa0b --- /dev/null +++ b/docs/class-names.md @@ -0,0 +1,33 @@ +--- +title: 'Class Names' +--- + +It can be useful to create to create a className that is not passed to a component, for example if a component accepts a `wrapperClassName` prop or similar. To do this, Emotion exposes a render prop component which you can pass a function which accepts `css` and `cx`. If you have used versions of Emotion prior to Emotion 10 or used vanilla Emotion, the `css` and `cx` functions work exactly like they do in versions. + +```jsx +// @live +import { ClassNames } from '@emotion/core' + +// this might be a component from npm that accepts a wrapperClassName prop +let SomeComponent = props => ( +
+ in the wrapper! +
{props.children}
+
+) + +render( + + {({ css, cx }) => ( + + from children!! + + )} + +) +``` diff --git a/docs/composition.md b/docs/composition.md index 7bddc53d2..90d552d22 100644 --- a/docs/composition.md +++ b/docs/composition.md @@ -2,11 +2,12 @@ title: "Composition" --- -Composition is one of the most powerful and useful patterns in Emotion. You can compose styles together by interpolating the class name returned from `css` in another style block. +Composition is one of the most powerful and useful patterns in Emotion. You can compose styles together by interpolating value returned from `css` in another style block. ```jsx // @live -import { css } from 'emotion' +/** @jsx jsx */ +import { jsx, css } from '@emotion/core' const base = css` color: hotpink; @@ -14,7 +15,7 @@ const base = css` render(
- What color will this be? +
+ +

What color will this be?

) ``` -With Emotion though, it's much easier, all we have to change is add `css` before the template literal where we combine the classes and Emotion will use the styles that were passed to danger and base and merge them in the order that they're interpolated. +With Emotion though, we can create styles and combine them ```jsx // @live -import { css } from 'emotion' +/** @jsx jsx */ +import { css, jsx } from '@emotion/core' const danger = css` color: red; ` const base = css` - background-color: lightgray; + background-color: darkgreen; color: turquoise; ` render( -
- What color will this be? +
+
This will be turquoise
+
+ This will be also be turquoise since the base styles + overwrite the danger styles. +
+
This will be red
) ``` -> Note: -> -> This is just an example to demonstrate composition, for class name merging with emotion you should use [cx](/docs/cx.md). - ## Composing dynamic styles +## I FEEL LIKE THIS IS A REALLY SPECIFIC THING AND MORE NEEDS TO BE SAID ABOUT THE STUFF ABOVE + +## ALSO, WE PROBABLY NEED A PLACE TO TALK ABOUT PATTERNS + You can also do dynamic composition based on props and use it in `styled`. ```jsx // @live -import styled, { css } from 'react-emotion' +import styled from '@emotion/styled' +import { css } from '@emotion/core' const dynamicStyle = props => css` color: ${props.color}; ` -const Container = styled('div')` +const Container = styled.div` ${dynamicStyle}; ` render( @@ -105,14 +110,15 @@ If you're composing lots of other styles and aren't using any string styles dire ```jsx // @live -import styled, { css } from 'react-emotion' +import styled from '@emotion/styled' +import { css } from '@emotion/core' const dynamicStyle = props => css` color: ${props.color}; ` -const Container = styled('div')(dynamicStyle) +const Container = styled.div(dynamicStyle) render( diff --git a/docs/configurable-imports.md b/docs/configurable-imports.md deleted file mode 100644 index 9e717a96b..000000000 --- a/docs/configurable-imports.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: "Configurable Imports" ---- - -Because `babel-plugin-emotion` optimizes code by transforming `css` and other calls, `babel-plugin-emotion` needs to know which functions are emotion's and which are not. By default `babel-plugin-emotion` will transform all calls to functions that have the same name as emotion's exports. `babel-plugin-emotion` will transform calls with different names in two circumstances. - -## ES Module Imports - -The first circumstance when `babel-plugin-emotion` will transform different calls is when using [ES Module imports](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import), when using ES Module imports, the local name in a module is will be the one transformed by `babel-plugin-emotion`. - -```js -import something, { css as emotion } from 'react-emotion' - -const classes = emotion` - color: red; -` - -export default something.div` - background: blue; -` -``` - -## Babel Options - -`babel-plugin-emotion` also supports setting the name of emotion's exports via the `importedNames` option. ~~This is useful for targetting a prop other than `css` for processing.~~(this will change to be a separate option) - - - -```json -{ - "plugins": [ - ["emotion", { "importedNames": { "css": "emotion" } }] - ] -} -``` - -Beware that if you use the babel configuration, you must import as the same name. In the previous example, you would have to use `import { css as emotion } from 'emotion'` and use `emotion` instead of `css`. - -# Use Case - -One use case for this functionality is to migrate incrementally from a styled-jsx application. When compiling the following file with emotion and styled-jsx. - -```js -import styled, { css } from 'react-emotion' - -export default () => ( -
-

only this paragraph will get the style :)

- {/* you can include s here that include - other

s that don't get unexpected styles! */} - -

-) -``` - -The old combination would conflict on the `css` prop that styled-jsx outputs. - -```js -import _JSXStyle from 'styled-jsx/style' -import styled, { css } from 'react-emotion' - -export default () => ( -
-

- only this paragraph will get the style :) -

- {} - <_JSXStyle - styleId={2648947580} - className={ - /*#__PURE__*/ _css( - [], - [], - function createEmotionStyledRules() { - return [ - { - 'p[data-jsx="2648947580"]': { - color: 'red' - } - } - ] - } - ) - } - /> -
-) -``` - -By adding the babel opt config rename as such. - -```js -{ - "plugins": [ - "styled-jsx/babel", - ["emotion", { "importedNames": { "css": "emotion" }}] - ] -} -``` - -We can avoid re-compiling the `css` props and instead use `emotion` for our template literals, etc. - -```js -import _JSXStyle from 'styled-jsx/style' -import styled, { css as emotion } from 'react-emotion' - -export default () => ( -
-

- only this paragraph will get the style :) -

- {} - <_JSXStyle - styleId={2648947580} - css={'p[data-jsx="2648947580"]{color:red}'} - /> -
-) -``` diff --git a/docs/css-prop.md b/docs/css-prop.md new file mode 100644 index 000000000..7cfda6e9d --- /dev/null +++ b/docs/css-prop.md @@ -0,0 +1,54 @@ +--- +title: 'The css Prop' +--- + +The primary way to style things in emotion is with the css prop, to use the css prop you need to import `jsx` from `@emotion/core` and set it as the jsx pragma by adding a comment like this `/** @jsx jsx */` + +To pass string styles, you must use `css` which is exported by `@emotion/core`, it can be used as a [tagged template literal](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) like below. + +```jsx +// @live +// this comment tells babel to convert jsx to calls to a function called jsx instead of React.createElement +/** @jsx jsx */ +import { css, jsx } from '@emotion/core' + +const color = 'darkgreen' + +render( +
+ This has a hotpink background. +
+) +``` + +You can also pass objects directly to the css prop, for more usage with objects, look at [the object styles page](/docs/object-styles.md). + +```jsx +// @live +/** @jsx jsx */ +import { jsx } from '@emotion/core' + +render( +
+ This has a hotpink background. +
+) +``` + +> Note: + +> The css prop is not compatible with `babel-plugin-transform-react-inline-elements`. If you include it in your `.babelrc` your styles won't be applied. diff --git a/docs/css.md b/docs/css.md deleted file mode 100644 index d6552336e..000000000 --- a/docs/css.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: "CSS" ---- - -The primary way to style things in emotion is with `css`, it accepts styles as a template literal, object, or array of objects and returns a class name. - -`css` can be used as a [tagged template literal](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals). - -```jsx -// @live -import { css } from 'emotion' - -const color = 'darkgreen' - -render( -
- This has a hotpink background. -
-) -``` - -`css` also accepts styles as an object, for more usage with objects, go [here](/docs/object-styles.md). - -```jsx -// @live -import { css } from 'emotion' - -render( -
- This has a hotpink background. -
-) -``` - -## CSS Prop - -> Note: - -> [The css prop requires `babel-plugin-emotion`](/packages/babel-plugin-emotion). - -With `babel-plugin-emotion`, the css prop can be used, it accepts styles like `css` and adds it to the className of the element it's on. This happens at compile time by converting the css prop to a css call and prepending it to the className of the element. It will only work if you use it as an actual JSX attribute, if it's in an object that's spread onto the element it won't work. - -```jsx -// @live -function SomeComponent(props) { - // Create styles as if you're calling css and the class will be applied to the component - return ( -
- This will be blue until hovered. -
- This font size will be 20px -
-
This is hotpink
-
- ) -} -render() -``` - -> Note: - -> The css prop is not compatible with `babel-plugin-transform-react-inline-elements`. If you include it in your `.babelrc` no transformation will take place and your styles won't be applied. diff --git a/docs/cx.md b/docs/cx.md index 6c8e77f11..b0fce46ac 100644 --- a/docs/cx.md +++ b/docs/cx.md @@ -1,14 +1,14 @@ --- -title: "cx" +title: 'cx' --- `cx` is emotion's version of the popular [`classnames` library](https://github.com/JedWatson/classnames). `cx` is useful when combining multiple class names, even class names from your stylesheets and emotion generated class names. ### Key features -* High performance integration with emotion -* Custom class names. e.g, `.my-bem--class`, are appended in order. -* Combines the actual content of emotion generated class names. Multiple emotion generated class names are input and a unique class name is output. +- High performance integration with emotion +- Custom class names. e.g, `.my-bem--class`, are appended in order. +- Combines the actual content of emotion generated class names. Multiple emotion generated class names are input and a unique class name is output. ### API @@ -16,8 +16,8 @@ title: "cx" `cx` takes any number of arguments and returns a string class name. -* Falsey values are removed from the final string. -* If an object value is encountered, any key that has a corresponding truthy value is added to the final string. +- Falsey values are removed from the final string. +- If an object value is encountered, any key that has a corresponding truthy value is added to the final string. ### Examples diff --git a/docs/docs.yaml b/docs/docs.yaml index a50a6eebd..f261d3229 100644 --- a/docs/docs.yaml +++ b/docs/docs.yaml @@ -1,25 +1,24 @@ - title: Getting Started - items: + items: - introduction - install - - css + - css-prop - styled - composition - object-styles - nested - media-queries - - inject-global + - globals - title: Advanced items: - keyframes - - cx - ssr - with-props - theming - labels - - configurable-imports - - instances + - class-names + - migrating-to-emotion-10 #- benchmarks - title: Tooling @@ -40,7 +39,7 @@ - emotion-server - emotion-theming - jest-emotion - - "@emotion/primitives" + - '@emotion/primitives' - create-emotion - create-emotion-server - preact-emotion diff --git a/docs/extract-static.md b/docs/extract-static.md index 6a5c12e77..0c3b36b96 100644 --- a/docs/extract-static.md +++ b/docs/extract-static.md @@ -1,5 +1,5 @@ --- -title: "Extract Static" +title: 'Extract Static' --- ###### [requires babel plugin](/docs/babel.md) diff --git a/docs/globals.md b/docs/globals.md new file mode 100644 index 000000000..2e88aa9fb --- /dev/null +++ b/docs/globals.md @@ -0,0 +1,22 @@ +--- +title: "Global Styles" +--- + +Sometimes it's useful to insert global css like resets or font faces. The `Global` component can be used for this. It accepts a `styles` prop which accepts the same values as the `css` prop except it inserts styles globally. Global styles are also removed when the styles change or when the Global component unmounts. + +```jsx +// @live +import { Global, css } from '@emotion/core' + +render( +
+ Everything is hotpink now! +
+) +``` diff --git a/docs/inject-global.md b/docs/inject-global.md deleted file mode 100644 index 5949f9936..000000000 --- a/docs/inject-global.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: "Global Styles" ---- - -Sometimes it's useful to insert global css like resets or font faces. `injectGlobal` can be used for this. - -```jsx -import { injectGlobal } from 'emotion' - -injectGlobal` - * { - box-sizing: border-box; - } - @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; - } -` -``` diff --git a/docs/install.md b/docs/install.md index f48323eaa..dc5b81c91 100644 --- a/docs/install.md +++ b/docs/install.md @@ -2,42 +2,46 @@ title: "Install" --- -Emotion can be used in many different ways. The easiest way to get started is to use the [`emotion` package](/packages/emotion). +Emotion can be used in many different ways. The easiest way to get started is to use the [`@emotion/core` package](/packages/@emotion/core). ```bash -yarn add emotion +# React +yarn add @emotion/core +# Preact +yarn add @emotion/preact-core ``` or if you prefer npm ```bash -npm install --save emotion +# React +npm install --save @emotion/core +# Preact +npm install --save @emotion/preact-core ``` -To use it, import what you need, for example use [css](/docs/css.md) to create class names with styles. +To use it, import what you need, for example use [jsx](/docs/jsx.md) to create class names with styles. ```jsx // @live -import { css } from 'emotion' +// this comment tells babel to convert jsx to calls to a function called jsx instead of React.createElement +/** @jsx jsx */ +import { jsx, css } from '@emotion/core' -const className = css` +const style = css` color: hotpink; ` const SomeComponent = ({ children }) => ( -
- Some hotpink text.{children} -
+
Some hotpink text.{children}
) -const anotherClassName = css({ +const anotherStyle = css({ textDecoration: 'underline' }) const AnotherComponent = () => ( -
- Some text with an underline. -
+
Some text with an underline.
) render( @@ -51,33 +55,29 @@ render( `styled` is a way to create React/Preact components that have styles attached to them. ```bash -# assuming you already have emotion installed +# assuming you already have @emotion/core installed # React -yarn add react-emotion +yarn add @emotion/styled # Preact -yarn add preact-emotion +yarn add @emotion/preact-styled ``` or if you prefer npm ```bash # React -npm install --save react-emotion +npm install --save @emotion/styled # Preact -npm install --save preact-emotion +npm install --save @emotion/preact-styled ``` -> Note: - -> All APIs from `emotion` are also exported by the `react-emotion` package. - ```jsx // @live -// change this import to preact-emotion +// change this import to @emotion/preact-styled // if you're using Preact -import styled, { css } from 'react-emotion' +import styled from '@emotion/styled' -const Button = styled('button')` +const Button = styled.button` color: hotpink; ` @@ -90,6 +90,8 @@ render() > If you're using Create React App, you can't add custom babel plugins so you can skip this section. +# IF YOU'RE LOOKING AT THIS NOW, YOU SHOULD USE @emotion/babel-plugin-core BUT IT WILL PROBABLY BE babel-plugin-emotion IN THE FUTURE + Emotion has an optional [Babel](https://babeljs.io/) plugin that optimizes styles by compressing and hoisting them and creates a better developer experience with source maps and labels. ```bash diff --git a/docs/introduction.md b/docs/introduction.md index f380f55b3..95aa936b1 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -1,20 +1,21 @@ --- -title: "Introduction" +title: 'Introduction' --- Emotion is a performant and flexible CSS-in-JS library. It's inspired by many other CSS-in-JS libraries like [glam](https://github.com/threepointone/glam/tree/e9bca3950f12503246ed7fccad5cf13e5e9c86e3), [glamor](https://github.com/threepointone/glamor), [styled-components](https://www.styled-components.com/) and [glamorous](https://glamorous.rocks/). It allows you to style applications quickly with string styles or object styles. It has predictable composition to avoid specificity issues with CSS. With source maps and labels, Emotion has a great developer experience and great performance with heavy caching and insertRule in production. -The examples in this documentation use React but Emotion is not limited to React. The exceptions to this are react-emotion and preact-emotion that export [`styled`](/docs/styled.md), they require React and Preact respectively. Everything from the `emotion` package works with any library or framework. +Emotion@10 has a React and non React-specific version, .... This documentation has lots of live examples that look like this, they're all editable so you can try emotion without installing it. Try changing the color below. ```jsx // @live -import { css } from 'emotion' +/** @jsx jsx */ +import { jsx, css } from '@emotion/core' render(
diff --git a/docs/keyframes.md b/docs/keyframes.md index 1dcecbf87..f823b8e30 100644 --- a/docs/keyframes.md +++ b/docs/keyframes.md @@ -1,12 +1,13 @@ --- -title: "Keyframes" +title: 'Keyframes' --- -If you need more control over an animation, you can use `keyframes` with the same JS interpolation as `css`. The `keyframes` function takes in a css keyframe definition and returns an animation name so that you can include it in other styles. This is similar to how `css` takes in styles and returns a className that you can use to apply the styles. +If you need more control over an animation, you can use `keyframes` with the same JS interpolation as `css`. The `keyframes` function takes in a css keyframe definition and an object which can be interpolated in styles. ```jsx // @live -import styled, { keyframes } from 'react-emotion' +/** @jsx jsx */ +import { jsx, css, keyframes } from '@emotion/core' const bounce = keyframes` from, 20%, 53%, 80%, to { @@ -26,13 +27,13 @@ const bounce = keyframes` } ` -const Avatar = styled('img')` - width: 96px; - height: 96px; - border-radius: 50%; - animation: ${bounce} 1s ease infinite; - transform-origin: center bottom; -` - -render() +render( +
+ some bouncing text! +
+) ``` diff --git a/docs/media-queries.md b/docs/media-queries.md index a6c0b5d24..3a9f36499 100644 --- a/docs/media-queries.md +++ b/docs/media-queries.md @@ -6,48 +6,78 @@ Using media queries in emotion works just like using media queries in regular cs ```jsx // @live -const Avatar = styled('img')` - width: 32px; - height: 32px; - border-radius: 50%; - - @media (min-width: 420px) { - width: 96px; - height: 96px; - } -` - -render() +/** @jsx jsx */ +import { jsx, css } from '@emotion/core' + +render( +

+ Some text! +

+) ``` -## Reusable Media Queries with Object Styles +## Reusable Media Queries -Making media queries reusable can be really useful to create responsive apps, with emotion's object styles you can move them into constants so you can refer to them instead of rewriting them each time they're used. +Media queries can be really useful to create responsive apps though repeating them is annoying and can lead to inconsistencies so instead of rewriting them each time they're used, you can move them into constants and refer to the variable each time you want to use them like this. ```jsx // @live +/** @jsx jsx */ +import { jsx, css } from '@emotion/core' + const breakpoints = [576, 768, 992, 1200] const mq = breakpoints.map( bp => `@media (min-width: ${bp}px)` ) -const styles = css({ - color: 'green', - [mq[0]]: { - color: 'gray' - }, - [mq[1]]: { - color: 'hotpink' - } -}) -render(
Some text.
) +render( +
+
+ Some text! +
+

+ Some other text! +

+
+) ``` ### facepaint While defining media queries in constants is great and is much easier than rewriting media queries each time, they're still quite verbose since usually you want to change the same property at different break points. [facepaint](https://github.com/emotion-js/facepaint) makes this easier by allowing you to define what each css property should be at each media query as an array. +> Note: + +> `facepaint` only works with object styles. + ```bash yarn add facepaint # or if you use npm @@ -56,7 +86,8 @@ npm install --save facepaint ```jsx // @live -import { css } from 'emotion' +/** @jsx jsx */ +import { jsx } from '@emotion/core' import facepaint from 'facepaint' const breakpoints = [576, 768, 992, 1200] @@ -65,59 +96,13 @@ const mq = facepaint( breakpoints.map(bp => `@media (min-width: ${bp}px)`) ) -const styles = css( - mq({ - color: ['green', 'gray', 'hotpink'] - }) -) -render(
Some text.
) -``` - -## Reusable Media Queries with String Styles - -```jsx -// @live -const breakpoints = { - // Numerical values will result in a min-width query - small: 576, - medium: 768, - large: 992, - xLarge: 1200, - // String values will be used as is - tallPhone: '(max-width: 360px) and (min-height: 740px)' -} - -const mq = Object.keys(breakpoints).reduce( - (accumulator, label) => { - let prefix = - typeof breakpoints[label] === 'string' - ? '' - : 'min-width:' - let suffix = - typeof breakpoints[label] === 'string' ? '' : 'px' - accumulator[label] = cls => - css` - @media (${prefix + breakpoints[label] + suffix}) { - ${cls}; - } - ` - return accumulator - }, - {} -) - -const paragraph = css` - font-size: 12px; - ${mq.medium(css` - font-size: 14px; - `)}; - ${mq.large(css` - font-size: 16px; - `)}; -` render( -

- This font size is different at different breakpoints. -

+
+ Some text. +
) ``` diff --git a/docs/migrating-to-emotion-10.md b/docs/migrating-to-emotion-10.md new file mode 100644 index 000000000..ad4c53530 --- /dev/null +++ b/docs/migrating-to-emotion-10.md @@ -0,0 +1,182 @@ +--- +title: 'Migrating to Emotion 10' +--- + +Emotion 10 is a large change to Emotion so it requires some changes to your code. Some of the changes can be done automatically via a codemod and the rest can be done incrementally. + +# Thinking + +The biggest change in Emotion 10 is that it doesn't let you easily access the underlying class names. Instead of thinking in class names, you have to think in terms of styles and composing them together. (you can still use classnames if you want to but it's not recommended except during migration) + +For example, in Emotion 9, you might have had two classes from `css` and compose them together with `cx` but in Emotion 10, you create 2 styles and compose them together in the css prop like this + +```jsx +// Emotion 9 +import { css, cx } from 'emotion' + +let basic = css` + color: green; +` + +let important = css` + color: hotpink; +` + +const SomeComponent = props => ( +
+) +``` + +```jsx +// Emotion 10 +/** @jsx jsx */ +import { css, jsx } from '@emotion/core' + +let basic = css` + color: green; +` + +let important = css` + color: hotpink; +` + +const SomeComponent = props => ( +
+) +``` + +# Incremental Migration + +Incremental migration is something really important to Emotion because we don't want anyone to have to rewrite their entire app. + +The upgrades to emotion 10 are split into two parts. The first part can be done automatically by a codemod. + +## Codemoddable + +- Change all react-emotion imports so that styled is imported from `@emotion/styled` and all the emotion exports are split into a second import. + +```jsx +import styled, { css } from 'react-emotion' +// ↓ ↓ ↓ ↓ ↓ ↓ +import styled from '@emotion/styled' +import { css } from 'emotion' +``` + +- Add a css call to the css prop when a template literal is used. + +```jsx +let element = ( +
+) + +// ↓ ↓ ↓ ↓ ↓ ↓ + +import { css } from '@emotion/core' + +let element = ( +
+) +``` + +- Add a `jsx` import and set jsx pragma +- Alternatively, use this TODO babel preset + +```jsx +import { css } from '@emotion/core' + +let element = ( +
+) +``` + +## Manual Steps + +- Add compat cache with provider + +This step is necessary if you still use `css`, `keyframes` or `injectGlobal` from `emotion`. Once you remove all the usages of them in your app, you can remove this. + +```jsx +import { render } from 'react-dom' +import App from './App' +import { cache } from 'emotion' +import { CacheProvider } from '@emotion/provider' + +render( + + + , + rootNode +) +``` + +## Manual Steps over time + +- Change css usage to css prop + +```jsx +import { css } from 'emotion' +let element = ( +
+) + +// ↓ ↓ ↓ ↓ ↓ ↓ +/** @jsx jsx */ +import { jsx, css } from '@emotion/core' + +let element = ( +
+) +``` + +If you have components that accepts props like `wrapperClassName` or etc. you can use the [`ClassNames` component](./class-names.md). + +```jsx +import { css } from 'emotion' +import { SomeComponent } from 'somewhere' +let element = ( + +) + +// ↓ ↓ ↓ ↓ ↓ ↓ + +import { ClassNames } from '@emotion/core' +import { SomeComponent } from 'somewhere' + +let element = ( + + {({ css }) => ( + + )} + +) +``` diff --git a/docs/nested.md b/docs/nested.md index 7961ffa11..e918899d6 100644 --- a/docs/nested.md +++ b/docs/nested.md @@ -6,7 +6,8 @@ Sometimes it's useful to nest selectors to target elements inside the current cl ```jsx // @live -import { css } from 'emotion' +/** @jsx jsx */ +import { jsx, css } from '@emotion/core' const paragraph = css` color: turquoise; @@ -16,7 +17,7 @@ const paragraph = css` } ` render( -

+

Some text. A link with a bottom border.

) @@ -26,7 +27,8 @@ You can use `&` to select the current class nested in another element: ```jsx // @live -import { css } from 'emotion' +/** @jsx jsx */ +import { jsx, css } from '@emotion/core' const paragraph = css` color: turquoise; @@ -38,40 +40,13 @@ const paragraph = css` render(
-

+

This is green since it's inside a header

-

+

This is turquoise since it's not inside a header.

) ``` - -To nest a class selector using the class generated with `css` you can interpolate it but this is **strongly** recommended against and should only be used in rare circumstances because it will break when used with [composition](/docs/composition.md). - -```jsx -// @live -import { css } from 'emotion' - -const link = css` - color: hotpink; -` - -const paragraph = css` - color: gray; - - .${link} { - border-bottom: 1px solid currentColor; - } -` -render( -
-

- Some text with a - link. -

-
-) -``` diff --git a/docs/object-styles.md b/docs/object-styles.md index 9db53a832..0b8767ced 100644 --- a/docs/object-styles.md +++ b/docs/object-styles.md @@ -1,34 +1,37 @@ --- -title: "Object Styles" +title: 'Object Styles' --- -Writing styles with objects is a powerful pattern built directly into the core of emotion. Instead of writing css properties in `kebab-case` like regular css, you write them in `camelCase`, for example `background-color` would be `backgroundColor`. Object styles work with all functions that accept string styles. (`css`, `styled`, `keyframes` and `injectGlobal`) +Writing styles with objects is a powerful pattern built directly into the core of emotion. Instead of writing css properties in `kebab-case` like regular css, you write them in `camelCase`, for example `background-color` would be `backgroundColor`. Object styles are especially useful with the css prop because you don't need a css call like with string styles but object styles can also be used with styled. ### Examples -#### With `css` +#### With the css prop ```jsx // @live -import { css } from 'emotion' +/** @jsx jsx */ +import { jsx } from '@emotion/core' -const className = css({ - color: 'darkorchid', - backgroundColor: 'lightgray' -}) - -render(
This is darkorchid.
) +render( +
+ This is darkorchid. +
+) ``` #### With `styled` -`styled` is a thin wrapper around `css` and accepts the same arguments. [More ways to use `styled` can be found here](/docs/styled.md). - ```jsx // @live -import styled from 'react-emotion' +import styled from '@emotion/styled' -const Button = styled('button')( +const Button = styled.button( { color: 'darkorchid' }, @@ -48,18 +51,20 @@ render( ```jsx // @live -import { css } from 'emotion' - -const className = css({ - color: 'darkorchid', - '& .name': { - color: 'orange' - } -}) +/* @jsx jsx */ +import { jsx } from '@emotion/core' render( -
- This is darkorchid.
This is orange
+
+ This is darkorchid. +
This is orange
) ``` @@ -68,17 +73,18 @@ render( ```jsx // @live -import { css } from 'emotion' - -const className = css({ - color: 'darkorchid', - '@media(min-width: 420px)': { - color: 'orange' - } -}) +/** @jsx jsx */ +import { jsx } from '@emotion/core' render( -
+
This is orange on a big screen and darkorchid on a small screen.
@@ -91,92 +97,86 @@ When numbers are the value of a css property, `px` is appended to the number unl ```jsx // @live -import { css } from 'emotion' - -const className = css({ - padding: 8, - zIndex: 200 -}) +/** @jsx jsx */ +import { jsx } from '@emotion/core' render( -
+
This has 8px of padding and a z-index of 200.
) ``` -### Multiple Arguments +### Arrays + +Nested arrays are flattened. ```jsx // @live -import { css } from 'emotion' - -const className = css( - { - color: 'darkorchid' - }, - { - backgroundColor: 'hotpink' - }, - { - padding: 8 - } -) +/** @jsx jsx */ +import { jsx } from '@emotion/core' render( -
+
This is darkorchid with a hotpink background and 8px of padding.
) ``` -### Arrays +### Fallbacks -Nested arrays are flattened. +Define fallback values for browsers that don't support features with arrays. ```jsx // @live -import { css } from 'emotion' - -const className = css([ - { - color: 'darkorchid' - }, - { - backgroundColor: 'hotpink' - }, - { - padding: 8 - } -]) +/** @jsx jsx */ +import { jsx } from '@emotion/core' render( -
- This is darkorchid with a hotpink background and 8px of - padding. +
+ This has a gradient background in browsers that support + gradients and is red in browsers that don't support + gradients
) ``` -### Fallbacks +### With `css` -Define fallback values for browsers that don't support features with arrays. +You can also use `css` with object styles. ```jsx // @live -import { css } from 'emotion' +/** @jsx jsx */ +import { jsx, css } from '@emotion/core' -const className = css({ - background: ['red', 'linear-gradient(#e66465, #9198e5)'], - height: 100 +const hotpink = css({ + color: 'hotpink' }) render( -
- This has a gradient background in browsers that support - gradients and is red in browsers that don't support - gradients +
+

This is hotpink

) ``` @@ -187,7 +187,8 @@ render( ```jsx // @live -import { css } from 'emotion' +/** @jsx jsx */ +import { jsx, css } from '@emotion/core' const hotpink = css({ color: 'hotpink' @@ -207,11 +208,11 @@ const hotpinkWithBlackBackground = css( render(
-

This is hotpink

- -

+

This has a black background and is hotpink. Try moving where hotpink is in the css call and see if the color changes. diff --git a/docs/ssr.md b/docs/ssr.md index fd00b857b..3a8402115 100644 --- a/docs/ssr.md +++ b/docs/ssr.md @@ -2,6 +2,37 @@ title: "Server Side Rendering" --- +Server side rendering works out of the box in emotion 10 and above + +```jsx +import { renderToString } from 'react-dom/server' +import App from './App' + +let html = renderToString() +``` + +## Using Emotion 10 with the old SSR APIs + +It's still possible to use emotion 10 with the SSR api's in previous versions of emotion. It primarily exists for compatibility reasons. + +```jsx +import createEmotionServer from 'create-emotion-server' +import createCache from '@emotion/cache' +import { renderToString } from 'react-dom/server' + +let cache = createCache() + +let { renderStylesToString } = createEmotionServer(cache) + +let element = ( + + + +) + +let html = renderStylesToString(renderToString(element)) +``` + ## API ### renderStylesToString diff --git a/docs/styled.md b/docs/styled.md index cd62813be..17544214d 100644 --- a/docs/styled.md +++ b/docs/styled.md @@ -1,8 +1,8 @@ --- -title: "Styled Components" +title: 'Styled Components' --- -`styled` is a way to create React or Preact components that have styles attached to them. It's available from [react-emotion](/packages/react-emotion) and [preact-emotion](/packages/preact-emotion). `styled` was heavily inspired by [styled-components](https://www.styled-components.com/) and [glamorous](https://glamorous.rocks/) +`styled` is a way to create React or Preact components that have styles attached to them. It's available from [@emotion/styled](/packages/@emotion/styled) and [@emotion/preact-styled](/packages/@emotion/preact-styled). `styled` was heavily inspired by [styled-components](https://www.styled-components.com/) and [glamorous](https://glamorous.rocks/) ### Styling elements and components @@ -10,9 +10,9 @@ title: "Styled Components" ```jsx // @live -import styled from 'react-emotion' +import styled from '@emotion/styled' -const Button = styled('button')` +const Button = styled.button` color: turquoise; ` @@ -25,14 +25,14 @@ Any interpolations or arguments that are functions in `styled` are called with ` ```jsx // @live -import styled from 'react-emotion' +import styled from '@emotion/styled' -const Button = styled('button')` +const Button = styled.button` color: ${props => props.primary ? 'hotpink' : 'turquoise'}; ` -const Container = styled('div')(props => ({ +const Container = styled.div(props => ({ display: 'flex', flexDirection: props.column && 'column' })) @@ -51,7 +51,7 @@ render( ```jsx // @live -import styled from 'react-emotion' +import styled from '@emotion/styled' const Basic = ({ className }) => (

Some text
) @@ -69,11 +69,12 @@ Sometimes you want to create some styles with one component but then use those s ```jsx // @live -// Create a section element -const Section = styled('section')` +import styled from '@emotion/styled' + +const Section = styled.section` background: #333; ` -// Create an aside element with the same styles as Section +// this component has the same styles as Section but it renders an aside const Aside = Section.withComponent('aside') render(
@@ -89,11 +90,13 @@ Similar to [styled-components](https://www.styled-components.com/docs/faqs#can-i ```jsx // @live -const Child = styled('div')` +import styled from '@emotion/styled' + +const Child = styled.div` color: red; ` -const Parent = styled('div')` +const Parent = styled.div` ${Child} { color: green; } @@ -112,11 +115,13 @@ Component selectors can also be used with object styles. ```jsx // @live -const Child = styled('div')({ +import styled from '@emotion/styled' + +const Child = styled.div({ color: 'red' }) -const Parent = styled('div')({ +const Parent = styled.div({ [Child]: { color: 'green' } @@ -132,72 +137,11 @@ render( ) ``` -### Pass refs down using `innerRef` - -Sometimes you need to get a [ref](https://reactjs.org/docs/refs-and-the-dom.html) but passing `ref` to a styled component will return a ref to the styled component, not the component that it renders which is generally the one you want. You can pass `innerRef` instead of `ref` to get the ref of the component that styled renders. - -```jsx -// @live -const Input = styled('input')` - color: hotpink; -` - -const Button = styled('button')` - color: green; -` - -function TextInput(props) { - let textInput = null - function handleClick() { - textInput.focus() - } - return ( -
- { - textInput = input - }} - /> - -
- ) -} -render() -``` - -### Element Shorthand - -> Note: - -> `babel-plugin-emotion` is required for the element shorthand - -Instead of using the function call syntax(`styled('div')`), you can use create components by using a property, where the property refers to an HTML tag(`styled.div`). - -```jsx -// @live -const DivWithoutShorthand = styled('div')` - color: green; -` - -const DivWithShorthand = styled.div` - color: hotpink; -` - -render( - - This is green.{' '} - This is hotpink. - -) -``` - ### Object styles ```jsx // @live -import styled from 'react-emotion' +import styled from '@emotion/styled' const H1 = styled.h1( { @@ -209,8 +153,23 @@ const H1 = styled.h1( render(

This is lightgreen.

) ``` -This API was inspired by [glamorous](https://github.com/paypal/glamorous). +This API was inspired by [glamorous](https://github.com/paypal/glamorous). ❤️ + +### Customizing prop forwarding -### withConfig is not a function error +By default, Emotion will pass all props to custom components and only props that are valid html attributes for string tags. This is can be customized by passing a custom `shouldForwardProp` function. You can also use `@emotion/is-prop-valid` to filter out props that are not valid as html attributes, it is what emotion uses internally. -This error is caused by using the shorthand syntax for styled such as `styled.div` without the Babel plugin. To fix this, [install `babel-plugin-emotion`](/docs/babel.md) +```jsx +// @live +import isPropValid from '@emotion/is-prop-valid' +import styled from '@emotion/styled' + +const H1 = styled('h1', { + shouldForwardProp: prop => + isPropValid(prop) && prop !== 'color' +})(props => ({ + color: 'hotpink' +})) + +render(

This is lightgreen.

) +``` diff --git a/docs/testing.md b/docs/testing.md index f271e25e1..4540df5e3 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -1,5 +1,5 @@ --- -title: "Snapshot Testing" +title: 'Snapshot Testing' --- Adding [snapshot tests with Jest](https://facebook.github.io/jest/docs/en/snapshot-testing.html) is a great way to help avoid unintended changes to your app's UI. @@ -31,16 +31,21 @@ Writing a test with `jest-emotion` involves creating a snapshot from the `react- ```jsx import React from 'react' -import * as emotion from 'emotion' -import { createSerializer } from 'jest-emotion' -import styled from 'react-emotion' +import serializer from 'jest-emotion' +/** @jsx jsx */ +import { jsx } from '@emotion/core' import renderer from 'react-test-renderer' -expect.addSnapshotSerializer(createSerializer(emotion)) +expect.addSnapshotSerializer(serializer) -const Button = styled('div')` - color: hotpink; -` +const Button = props => ( +