Skip to content

Commit

Permalink
Use Hooks (#967)
Browse files Browse the repository at this point in the history
* Tests are broken :( but it works

* Add displayName

* Use ref

* Remove stuff

* Update react-test-renderer

* Use useContext in more places

* Fix a Global insertion order bug

* Add a test

* Fix typo

* Remove passing the theme to the css prop, Global and ClassNames

* stuff

* stuff

* changes

* Add a test back

* Fix a thing

* Update stuff

* Update things

* Drop support for innerRef entirely

* Set correct peerDeps on react + upgrade react-related devDeps

* Fix tests

* Fix linting error

* Remove custom useContext flow types

* Fix flow error

* Fix layour effect input array to include serialized.name instead of whole serialized

* Add a changeset

* Add another changeset
  • Loading branch information
emmatown committed Nov 5, 2019
1 parent 70bc4ef commit 7903605
Show file tree
Hide file tree
Showing 41 changed files with 605 additions and 659 deletions.
6 changes: 6 additions & 0 deletions .changeset/curvy-timers-decide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@emotion/styled-base': major
'@emotion/styled': major
---

Remove support for deprecated `innerRef` prop
11 changes: 11 additions & 0 deletions .changeset/two-baboons-mate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
'@emotion/core': major
'emotion-theming': major
'@emotion/native': major
'@emotion/primitives-core': major
'@emotion/primitives': major
'@emotion/styled-base': major
'@emotion/styled': major
---

Use hooks internally for improved bundle size and a better tree in React DevTools
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/--documentation-issue.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ assignees: ''

<!--
If existing documentation is available, but needs to be improved,
is wrong, or unclear, please post here the relevant
is wrong, or unclear, please post here the relevant
https://emotion.sh/docs URLs
-->
1 change: 0 additions & 1 deletion .github/ISSUE_TEMPLATE/--feature-request.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ labels: feature request, needs triage
assignees: ''
---


**The problem**

<!-- A clear and concise description of what the problem is. e.g. I'm always frustrated when [...] -->
Expand Down
7 changes: 6 additions & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,27 @@ merge of your pull request!
-->

<!-- What changes are being made? (What feature/bug is being fixed here?) -->

**What**:

<!-- Why are these changes necessary? -->

**Why**:

<!-- How were these changes implemented? -->

**How**:

<!-- Have you done all of these things? -->

**Checklist**:

<!-- add "N/A" to the end of each line that's irrelevant to your changes -->
<!-- to check an item, place an "x" in the box like so: "- [x] Documentation" -->

- [ ] Documentation
- [ ] Tests
- [ ] Code complete
- [ ] Changeset <!-- This is necessary if your changes should release any packages. Run `yarn changeset` to create a changeset -->


<!-- feel free to add additional comments -->
6 changes: 3 additions & 3 deletions docs/css-prop.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ There are 2 ways to get started with the `css` prop.

Both methods result in the same compiled code.
After adding the preset or setting the pragma as a comment, compiled jsx code will use emotion's `jsx` function instead of `React.createElement`.
| | Input | Output |

| | Input | Output |
| ------ | -------------------------- | --------------------------------------------------- |
| Before | `<img src="avatar.png" />` | `React.createElement('img', { src: 'avatar.png' })` |
| After | `<img src="avatar.png" />` | `jsx('img', { src: 'avatar.png' })` |
| After | `<img src="avatar.png" />` | `jsx('img', { src: 'avatar.png' })` |

#### Babel Preset

Expand Down
14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
"release": "yarn build && changeset publish"
},
"resolutions": {
"**/react": "16.8.1",
"**/react-dom": "16.8.1",
"**/react": "16.11.0",
"**/react-dom": "16.11.0",
"**/browserslist": "^3.2.8",
"**/graphql-type-json": "0.2.4"
},
Expand Down Expand Up @@ -174,10 +174,10 @@
"@manypkg/cli": "^0.5.2",
"@mdx-js/mdx": "^1.1.0",
"@mdx-js/react": "^1.0.27",
"@testing-library/react": "^8.0.2",
"@testing-library/react": "^9.3.2",
"@types/jest": "^23.0.2",
"@types/node": "^10.11.4",
"@types/react": "^16.8.20",
"@types/react": "^16.9.11",
"babel-check-duplicated-nodes": "^1.0.0",
"babel-core": "^6.26.3",
"babel-eslint": "^8.2.3",
Expand Down Expand Up @@ -236,9 +236,9 @@
"puppeteer": "^1.6.0",
"raf": "^3.4.0",
"razzle": "^2.4.0",
"react": "^16.5.2",
"react": "^16.11.0",
"react-art": "^16.5.2",
"react-dom": "^16.5.2",
"react-dom": "^16.11.0",
"react-helmet": "^5.2.0",
"react-icons": "^2.2.7",
"react-live": "1.10.0",
Expand All @@ -247,7 +247,7 @@
"react-primitives": "^0.7.0",
"react-router-dom": "^4.2.2",
"react-scripts": "1.1.5",
"react-test-renderer": "^16.3.2",
"react-test-renderer": "16.8.6",
"stylis": "3.5.4",
"stylis-rule-sheet": "^0.0.10",
"svg-tag-names": "^1.1.1",
Expand Down
1 change: 0 additions & 1 deletion packages/core/__tests__/class-names.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ it('should get the theme', () => {
</ClassNames>
</ThemeProvider>
)

expect(tree.toJSON()).toMatchSnapshot()
})

Expand Down
1 change: 0 additions & 1 deletion packages/core/__tests__/css.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ test('theming with the css prop', () => {
<div css={theme => ({ color: theme.primary })} />
</ThemeProvider>
)

expect(tree.toJSON()).toMatchSnapshot()
})

Expand Down
33 changes: 33 additions & 0 deletions packages/core/__tests__/global-insertion-after-others.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/** @jsx jsx */
import { jsx, Global } from '@emotion/core'
import { render } from '@testing-library/react'

let getDataAttributes = () =>
Array.from(document.querySelectorAll('style[data-emotion]'), x =>
x.getAttribute('data-emotion')
)

test('Global style element insertion after insertion of other styles', () => {
let Comp = ({ second }) => (
<div>
<div
css={{
color: 'green'
}}
/>
{second && (
<Global
styles={{
html: {
backgroundColor: 'hotpink'
}
}}
/>
)}
</div>
)
let { rerender } = render(<Comp />)
expect(getDataAttributes()).toEqual(['css'])
rerender(<Comp second />)
expect(getDataAttributes()).toEqual(['css-global', 'css'])
})
6 changes: 3 additions & 3 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,17 @@
"@emotion/utils": "0.11.2"
},
"peerDependencies": {
"react": ">=16.3.0"
"react": ">=16.8.0"
},
"devDependencies": {
"@emotion/styled": "^11.0.0-next.1",
"@types/react": "^16.8.20",
"@types/react": "^16.9.11",
"dtslint": "^0.3.0",
"emotion": "^11.0.0-next.0",
"emotion-server": "^11.0.0-next.0",
"emotion-theming": "^11.0.0-next.1",
"html-tag-names": "^1.1.2",
"react": "^16.5.2",
"react": "^16.11.0",
"svg-tag-names": "^1.1.1"
},
"repository": "https://github.com/emotion-js/emotion/tree/master/packages/core",
Expand Down
109 changes: 54 additions & 55 deletions packages/core/src/class-names.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// @flow
import * as React from 'react'
import { useContext } from 'react'
import { getRegisteredStyles, insertStyles } from '@emotion/utils'
import { serializeStyles } from '@emotion/serialize'
import { withEmotionCache, ThemeContext } from './context'
Expand Down Expand Up @@ -71,65 +72,63 @@ function merge(

type Props = {
children: ({
css: (...args: Array<any>) => string,
css: (...args: any) => string,
cx: (...args: Array<ClassNameArg>) => string,
theme: Object
}) => React.Node
}

export const ClassNames = withEmotionCache<Props>((props, context) => {
return (
<ThemeContext.Consumer>
{theme => {
let rules = ''
let serializedHashes = ''
let hasRendered = false
export const ClassNames: React.AbstractComponent<Props> = withEmotionCache(
(props, cache) => {
let rules = ''
let serializedHashes = ''
let hasRendered = false

let css = (...args: Array<any>) => {
if (hasRendered && process.env.NODE_ENV !== 'production') {
throw new Error('css can only be used during render')
}
let serialized = serializeStyles(args, context.registered)
if (isBrowser) {
insertStyles(context, serialized, false)
} else {
let res = insertStyles(context, serialized, false)
if (res !== undefined) {
rules += res
}
}
if (!isBrowser) {
serializedHashes += ` ${serialized.name}`
}
return `${context.key}-${serialized.name}`
}
let cx = (...args: Array<ClassNameArg>) => {
if (hasRendered && process.env.NODE_ENV !== 'production') {
throw new Error('cx can only be used during render')
}
return merge(context.registered, css, classnames(args))
}
let content = { css, cx, theme }
let ele = props.children(content)
hasRendered = true
if (!isBrowser && rules.length !== 0) {
return (
<React.Fragment>
<style
{...{
[`data-emotion-${context.key}`]: serializedHashes.substring(
1
),
dangerouslySetInnerHTML: { __html: rules },
nonce: context.sheet.nonce
}}
/>
{ele}
</React.Fragment>
)
let css = (...args: Array<any>) => {
if (hasRendered && process.env.NODE_ENV !== 'production') {
throw new Error('css can only be used during render')
}
let serialized = serializeStyles(args, cache.registered)
if (isBrowser) {
insertStyles(cache, serialized, false)
} else {
let res = insertStyles(cache, serialized, false)
if (res !== undefined) {
rules += res
}
return ele
}}
</ThemeContext.Consumer>
)
})
}
if (!isBrowser) {
serializedHashes += ` ${serialized.name}`
}
return `${cache.key}-${serialized.name}`
}
let cx = (...args: Array<ClassNameArg>) => {
if (hasRendered && process.env.NODE_ENV !== 'production') {
throw new Error('cx can only be used during render')
}
return merge(cache.registered, css, classnames(args))
}
let content = {
css,
cx,
theme: useContext(ThemeContext)
}
let ele = props.children(content)
hasRendered = true
if (!isBrowser && rules.length !== 0) {
return (
<React.Fragment>
<style
{...{
[`data-emotion-${cache.key}`]: serializedHashes.substring(1),
dangerouslySetInnerHTML: { __html: rules },
nonce: cache.sheet.nonce
}}
/>
{ele}
</React.Fragment>
)
}
return ele
}
)

0 comments on commit 7903605

Please sign in to comment.